From a815fd1942735d21fc9b898bf11db99525a16cef Mon Sep 17 00:00:00 2001
From: Kenneth Moreland
Date: Fri, 24 Feb 2017 12:00:42 -0700
Subject: [PATCH] Fix TBB reduce when reducing 1 value
The first thing the TBB functor for reduce does is to reduce the first
two values. This is a problem when trying to "reduce" an array of size
1. You can potentially get a seg-fault when getting the second value.
Added a special case when reducing a range of size 1.
---
vtkm/cont/tbb/internal/FunctorsTBB.h | 61 ++++++++++++++++++++--------
1 file changed, 44 insertions(+), 17 deletions(-)
diff --git a/vtkm/cont/tbb/internal/FunctorsTBB.h b/vtkm/cont/tbb/internal/FunctorsTBB.h
index 17c67c7f8..463f43ce5 100644
--- a/vtkm/cont/tbb/internal/FunctorsTBB.h
+++ b/vtkm/cont/tbb/internal/FunctorsTBB.h
@@ -117,29 +117,56 @@ struct ReduceBody
typename InputIteratorsType::IteratorType inIter =
inputIterators.GetBegin() + static_cast(range.begin());
- T temp = this->BinaryOperation(*inIter, *(inIter+1));
- ++inIter; ++inIter;
- for (vtkm::Id index = range.begin()+2; index != range.end(); ++index, ++inIter)
+ if (range.size() > 1)
+ {
+ T temp = this->BinaryOperation(*inIter, *(inIter+1));
+ ++inIter; ++inIter;
+ for (vtkm::Id index = range.begin()+2; index != range.end(); ++index, ++inIter)
{
- temp = this->BinaryOperation(temp, *inIter);
+ temp = this->BinaryOperation(temp, *inIter);
}
- //determine if we also have to add the initial value to temp
- if(range.begin() == 0)
- {
- temp = this->BinaryOperation(temp,this->InitialValue);
- }
+ //determine if we also have to add the initial value to temp
+ if(range.begin() == 0)
+ {
+ temp = this->BinaryOperation(temp,this->InitialValue);
+ }
- //Now we can save temp back to sum, taking into account if
- //this task has been called before, and the sum value needs
- //to also be reduced.
- if(this->FirstCall)
- {
- this->Sum = temp;
+ //Now we can save temp back to sum, taking into account if
+ //this task has been called before, and the sum value needs
+ //to also be reduced.
+ if(this->FirstCall)
+ {
+ this->Sum = temp;
+ }
+ else
+ {
+ this->Sum = this->BinaryOperation(this->Sum,temp);
+ }
}
- else
+ else if (range.size() == 1)
{
- this->Sum = this->BinaryOperation(this->Sum,temp);
+ if (range.begin() == 0)
+ {
+ T temp = this->BinaryOperation(*inIter, this->InitialValue);
+ if (!this->FirstCall)
+ {
+ temp = this->BinaryOperation(this->Sum, temp);
+ }
+ this->Sum = temp;
+ }
+ else if (!this->FirstCall)
+ {
+ this->Sum = this->BinaryOperation(this->Sum, *inIter);
+ }
+ else
+ {
+ // We are in a place where we have only 1 thing to "reduce," and I
+ // have no idea what to do here since the reduction is a binary
+ // operation. I can't just copy it to the Sum because they may
+ // be different types. Hopefully this cannot happen with TBB.
+ VTKM_ASSERT(false && "Panic! Asked to reduce 1 value.");
+ }
}
this->FirstCall = false;
--
GitLab