Remove ArrayHandle CopyInto

Fixes #170
This commit is contained in:
Sujin Philip 2017-10-27 10:42:22 -04:00
parent 069ec23f21
commit 5842da4921
14 changed files with 13 additions and 201 deletions

@ -360,12 +360,6 @@ public:
///
VTKM_CONT vtkm::Id GetNumberOfValues() const;
/// Copies data into the given iterator for the control environment. This
/// method can skip copying into an internally managed control array.
///
template <typename IteratorType, typename DeviceAdapterTag>
VTKM_CONT void CopyInto(IteratorType dest, DeviceAdapterTag) const;
/// \brief Allocates an array large enough to hold the given number of values.
///
/// The allocation may be done on an already existing array, but can wipe out

@ -152,45 +152,6 @@ vtkm::Id ArrayHandle<T, S>::GetNumberOfValues() const
}
}
template <typename T, typename S>
template <typename IteratorType, typename DeviceAdapterTag>
void ArrayHandle<T, S>::CopyInto(IteratorType dest, DeviceAdapterTag) const
{
using pointer_type = typename std::iterator_traits<IteratorType>::pointer;
using value_type = typename std::remove_pointer<pointer_type>::type;
static_assert(!std::is_const<value_type>::value, "CopyInto requires a non const iterator.");
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (!this->Internals->ControlArrayValid && !this->Internals->ExecutionArrayValid)
{
throw vtkm::cont::ErrorBadValue("ArrayHandle has no data to copy into Iterator.");
}
if (!this->Internals->ControlArrayValid &&
this->Internals->ExecutionArray->IsDeviceAdapter(DeviceAdapterTag()))
{
/// Dynamically cast ArrayHandleExecutionManagerBase into a concrete
/// class and call CopyInto. The dynamic conversion will be sucessful
/// becuase the check to ensure the ExecutionArray is of the type
/// DeviceAdapterTag has already passed
using ConcreteType =
vtkm::cont::internal::ArrayHandleExecutionManager<T, StorageTag, DeviceAdapterTag>;
ConcreteType* ConcreteExecutionArray =
dynamic_cast<ConcreteType*>(this->Internals->ExecutionArray.get());
ConcreteExecutionArray->CopyInto(dest);
}
else
{
PortalConstControl portal = this->GetPortalConstControl();
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(portal),
vtkm::cont::ArrayPortalToIteratorEnd(portal),
dest);
}
}
template <typename T, typename S>
void ArrayHandle<T, S>::Shrink(vtkm::Id numberOfValues)
{

@ -144,17 +144,6 @@ public:
throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output.");
}
template <class IteratorTypeControl>
VTKM_CONT void CopyInto(IteratorTypeControl dest) const
{
using PortalType = typename StorageType::PortalConstType;
PortalType portal = this->Storage->GetPortalConst();
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(portal),
vtkm::cont::ArrayPortalToIteratorEnd(portal),
dest);
}
VTKM_CONT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{

@ -215,16 +215,6 @@ public:
}
}
/// Copies the data currently in the device array into the given iterators.
/// Although the iterator is supposed to be from the control environment,
/// thrust can generally handle iterators for a device as well.
///
template <class IteratorTypeControl>
VTKM_CONT void CopyInto(IteratorTypeControl dest) const
{
::thrust::copy(this->Begin, this->End, dest);
}
/// Resizes the device vector.
///
VTKM_CONT void Shrink(vtkm::Id numberOfValues)

@ -177,9 +177,6 @@ public:
VTKM_CONT PortalConstControl GetPortalConstControl() const;
VTKM_CONT vtkm::Id GetNumberOfValues() const;
template <typename IteratorType, typename DeviceAdapterTag>
VTKM_CONT void CopyInto(IteratorType dest, DeviceAdapterTag) const;
VTKM_CONT void Allocate(vtkm::Id numberOfValues);
VTKM_CONT void Shrink(vtkm::Id numberOfValues);
VTKM_CONT void ReleaseResourcesExecution();

@ -189,43 +189,6 @@ vtkm::Id ArrayHandle<T, StorageTagBasic>::GetNumberOfValues() const
}
}
template <typename T>
template <typename IteratorType, typename DeviceAdapterTag>
void ArrayHandle<T, StorageTagBasic>::CopyInto(IteratorType dest, DeviceAdapterTag) const
{
using pointer_type = typename std::iterator_traits<IteratorType>::pointer;
using value_type = typename std::remove_pointer<pointer_type>::type;
static_assert(!std::is_const<value_type>::value, "CopyInto requires a non const iterator.");
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (!this->Internals->ControlArrayValid && !this->Internals->ExecutionArrayValid)
{
throw vtkm::cont::ErrorBadValue("ArrayHandle has no data to copy into Iterator.");
}
// If we can copy directly from the execution environment, do so.
DeviceAdapterId devId = DeviceAdapterTraits<DeviceAdapterTag>::GetId();
if (!this->Internals->ControlArrayValid && std::is_pointer<IteratorType>::value &&
this->Internals->ExecutionInterface &&
this->Internals->ExecutionInterface->GetDeviceId() == devId)
{
vtkm::UInt64 numBytes = static_cast<vtkm::UInt64>(sizeof(ValueType)) *
static_cast<vtkm::UInt64>(this->GetNumberOfValues());
this->Internals->ExecutionInterface->CopyToControl(
this->Internals->ExecutionArray, dest, numBytes);
}
else
{
// Otherwise copy from control.
PortalConstControl portal = this->GetPortalConstControl();
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(portal),
vtkm::cont::ArrayPortalToIteratorEnd(portal),
dest);
}
}
template <typename T>
void ArrayHandle<T, StorageTagBasic>::Allocate(vtkm::Id numberOfValues)
{

@ -217,12 +217,6 @@ public:
{
}
template <class IteratorTypeControl>
VTKM_CONT void CopyInto(IteratorTypeControl dest) const
{
this->Transfer.CopyInto(dest);
}
protected:
VTKM_CONT
vtkm::Id GetNumberOfValuesImpl() const { return this->Transfer.GetNumberOfValues(); }

@ -125,15 +125,6 @@ public:
VTKM_CONT
void RetrieveOutputData(vtkm::cont::internal::Storage<T, StorageTag>* storage) const;
/// Similar to RetrieveOutputData except that instead of writing to the
/// controlArray itself, it writes to the given control environment
/// iterator. This allows the user to retrieve data without necessarily
/// allocating an array in the ArrayContainerControl (assuming that control
/// and exeuction have seperate memory spaces).
///
template <class IteratorTypeControl>
VTKM_CONT void CopyInto(IteratorTypeControl dest) const;
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The

@ -93,18 +93,6 @@ public:
VTKM_ASSERT(storage == this->Storage);
}
/// This methods copies data from the execution array into the given
/// iterator.
///
template <class IteratorTypeControl>
VTKM_CONT void CopyInto(IteratorTypeControl dest) const
{
using IteratorType = typename StorageType::PortalConstType::IteratorType;
IteratorType beginIterator = this->Storage->GetPortalConst().GetIteratorBegin();
std::copy(beginIterator, beginIterator + this->Storage->GetNumberOfValues(), dest);
}
/// Shrinks the storage.
///
VTKM_CONT

@ -132,18 +132,6 @@ public:
this->ArrayManager.RetrieveOutputData(storage);
}
/// Similar to RetrieveOutputData except that instead of writing to the
/// controlArray itself, it writes to the given control environment
/// iterator. This allows the user to retrieve data without necessarily
/// allocating an array in the ArrayContainerControl (assuming that control
/// and exeuction have seperate memory spaces).
///
template <class IteratorTypeControl>
VTKM_CONT void CopyInto(IteratorTypeControl dest) const
{
this->ArrayManager.CopyInto(dest);
}
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The

@ -220,42 +220,6 @@ private:
//can just make sure the allocation didn't throw an exception
}
std::cout << "Check CopyInto from control array" << std::endl;
{ //Release the execution resources so that data is only
//in the control environment
arrayHandle.ReleaseResourcesExecution();
//Copy data from handle into iterator
T array[ARRAY_SIZE];
arrayHandle.CopyInto(array, DeviceAdapterTag());
array_handle_testing::CheckValues(array, array + ARRAY_SIZE, T());
}
std::cout << "Check CopyInto from execution array" << std::endl;
{ //Copy the data to the execution environment
vtkm::cont::ArrayHandle<T> result;
DispatcherPassThrough().Invoke(arrayHandle, result);
//Copy data from handle into iterator
T array[ARRAY_SIZE];
result.CopyInto(array, DeviceAdapterTag());
array_handle_testing::CheckValues(array, array + ARRAY_SIZE, T());
}
if (!std::is_same<DeviceAdapterTag, vtkm::cont::DeviceAdapterTagSerial>::value)
{
std::cout << "Check using different device adapter" << std::endl;
//Copy the data to the execution environment
vtkm::cont::ArrayHandle<T> result;
DispatcherPassThrough().Invoke(arrayHandle, result);
//CopyInto allows you to copy the data even
//if you request it from a different device adapter
T array[ARRAY_SIZE];
result.CopyInto(array, vtkm::cont::DeviceAdapterTagSerial());
array_handle_testing::CheckValues(array, array + ARRAY_SIZE, T());
}
{ //as output with a length larger than the memory provided by the user
//this should fail
bool gotException = false;

@ -264,9 +264,6 @@ void TestNormalFunctorInvoke()
std::cout << "Testing normal worklet invoke." << std::endl;
vtkm::Id inputTestValues[3] = { 5, 5, 6 };
vtkm::Id outputTestValues[3] = { static_cast<vtkm::Id>(0xDEADDEAD),
static_cast<vtkm::Id>(0xDEADDEAD),
static_cast<vtkm::Id>(0xDEADDEAD) };
vtkm::cont::ArrayHandle<vtkm::Id> input = vtkm::cont::make_ArrayHandle(inputTestValues, 3);
vtkm::cont::ArrayHandle<vtkm::Id> output;
@ -289,10 +286,8 @@ void TestNormalFunctorInvoke()
input.SyncControlArray();
output.SyncControlArray();
output.CopyInto(outputTestValues, DeviceAdapter());
VTKM_TEST_ASSERT(inputTestValues[1] == 5, "Input value changed.");
VTKM_TEST_ASSERT(outputTestValues[1] == inputTestValues[1] + 100 + 30,
VTKM_TEST_ASSERT(output.GetPortalConstControl().Get(1) == inputTestValues[1] + 100 + 30,
"Output value not set right.");
std::cout << " Try return value." << std::endl;
@ -312,10 +307,8 @@ void TestNormalFunctorInvoke()
input.SyncControlArray();
output.SyncControlArray();
output.CopyInto(outputTestValues, DeviceAdapter());
VTKM_TEST_ASSERT(inputTestValues[2] == 6, "Input value changed.");
VTKM_TEST_ASSERT(outputTestValues[2] == inputTestValues[2] + 200 + 30 * 2,
VTKM_TEST_ASSERT(output.GetPortalConstControl().Get(2) == inputTestValues[2] + 200 + 30 * 2,
"Output value not set right.");
}

@ -209,9 +209,9 @@ public:
//transfer the data.
//the primary concern that we have at this point is data locality and
//the type of storage. Our options include using CopyInto and provide a
//temporary location for the values to reside before we give it to openGL
//this works for all storage types.
//the type of storage. Our options include using DeviceAdapterAlgorithm::Copy
//and provide a temporary location for the values to reside before we give it
//to openGL this works for all storage types.
//
//Second option is to call PrepareForInput and get a PortalConst in the
//exection environment.
@ -220,7 +220,8 @@ public:
//a unneeded copy.
//
//The end result is that we have CopyFromHandle which does number two
//from StorageTagBasic, and does the CopyInto for everything else
//from StorageTagBasic, and does the DeviceAdapterAlgorithm::Copy for everything
//else
detail::CopyFromHandle(handle, this->State, DeviceAdapterTag());
}

@ -60,13 +60,12 @@ void CheckOutputCellSet(const vtkm::cont::CellSetExplicit<>& cellSet,
VTKM_TEST_ASSERT(pointIds4[2] == 3, "Wrong point id for cell");
VTKM_TEST_ASSERT(pointIds4[3] == 4, "Wrong point id for cell");
vtkm::Float32 fieldValues[5];
field.CopyInto(fieldValues, VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
VTKM_TEST_ASSERT(test_equal(fieldValues[0], TestValue(0, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldValues[1], TestValue(2, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldValues[2], TestValue(4, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldValues[3], TestValue(6, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldValues[4], TestValue(8, vtkm::Float32())), "Bad field");
auto fieldPortal = field.GetPortalConstControl();
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(0), TestValue(0, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(1), TestValue(2, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(2), TestValue(4, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(3), TestValue(6, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(4), TestValue(8, vtkm::Float32())), "Bad field");
}
void RunTest()