vtk-m ArrayHandle + basic holds control data by StorageBasicBase

By making the array handle hold the control side data by the parent storage
class we remove significant code generation.
This commit is contained in:
Robert Maynard 2018-02-12 13:09:43 -05:00
parent b1d0060dff
commit 22f9ae3d24
5 changed files with 160 additions and 159 deletions

@ -54,6 +54,19 @@ namespace cont
namespace internal
{
TypelessExecutionArray::TypelessExecutionArray(void*& array,
void*& arrayEnd,
void*& arrayCapacity,
const void* arrayControl,
const void* arrayControlCapacity)
: Array(array)
, ArrayEnd(arrayEnd)
, ArrayCapacity(arrayCapacity)
, ArrayControl(arrayControl)
, ArrayControlCapacity(arrayControlCapacity)
{
}
ExecutionArrayInterfaceBasicBase::ExecutionArrayInterfaceBasicBase(StorageBasicBase& storage)
: ControlStorage(storage)
{
@ -63,6 +76,23 @@ ExecutionArrayInterfaceBasicBase::~ExecutionArrayInterfaceBasicBase()
{
}
ArrayHandleImpl::~ArrayHandleImpl()
{
if (this->ExecutionArrayValid && this->ExecutionInterface != nullptr &&
this->ExecutionArray != nullptr)
{
TypelessExecutionArray execArray(this->ExecutionArray,
this->ExecutionArrayEnd,
this->ExecutionArrayCapacity,
this->ControlArray->GetBasePointer(),
this->ControlArray->GetCapacityPointer());
this->ExecutionInterface->Free(execArray);
}
delete this->ControlArray;
delete this->ExecutionInterface;
}
} // end namespace internal
#define _VTKM_ARRAYHANDLE_INSTANTIATE(Type) \

@ -78,8 +78,8 @@ void TestPrepareForInput(bool managed)
vtkm::cont::ArrayHandle<ValueType> handle = CreateArrayHandle<ValueType>(32, managed);
handle.PrepareForInput(vtkm::cont::DeviceAdapterTagCuda());
ValueType* contArray = handle.Internals->ControlArray.GetArray();
ValueType* execArray = handle.Internals->ExecutionArray;
void* contArray = handle.Internals->ControlArray->GetBasePointer();
void* execArray = handle.Internals->ExecutionArray;
VTKM_TEST_ASSERT(contArray != nullptr, "No control array after PrepareForInput.");
VTKM_TEST_ASSERT(execArray != nullptr, "No execution array after PrepareForInput.");
VTKM_TEST_ASSERT(CudaAllocator::IsDevicePointer(execArray),
@ -102,8 +102,8 @@ void TestPrepareForInPlace(bool managed)
vtkm::cont::ArrayHandle<ValueType> handle = CreateArrayHandle<ValueType>(32, managed);
handle.PrepareForInPlace(vtkm::cont::DeviceAdapterTagCuda());
ValueType* contArray = handle.Internals->ControlArray.GetArray();
ValueType* execArray = handle.Internals->ExecutionArray;
void* contArray = handle.Internals->ControlArray->GetBasePointer();
void* execArray = handle.Internals->ExecutionArray;
VTKM_TEST_ASSERT(contArray != nullptr, "No control array after PrepareForInPlace.");
VTKM_TEST_ASSERT(execArray != nullptr, "No execution array after PrepareForInPlace.");
VTKM_TEST_ASSERT(CudaAllocator::IsDevicePointer(execArray),
@ -127,8 +127,8 @@ void TestPrepareForOutput(bool managed)
vtkm::cont::ArrayHandle<ValueType> handle = CreateArrayHandle<ValueType>(32, managed);
handle.PrepareForOutput(32, vtkm::cont::DeviceAdapterTagCuda());
ValueType* contArray = handle.Internals->ControlArray.GetArray();
ValueType* execArray = handle.Internals->ExecutionArray;
void* contArray = handle.Internals->ControlArray->GetBasePointer();
void* execArray = handle.Internals->ExecutionArray;
VTKM_TEST_ASSERT(contArray != nullptr, "No control array after PrepareForOutput.");
VTKM_TEST_ASSERT(execArray != nullptr, "No execution array after PrepareForOutput.");
VTKM_TEST_ASSERT(CudaAllocator::IsDevicePointer(execArray),
@ -151,12 +151,12 @@ void TestReleaseResourcesExecution(bool managed)
vtkm::cont::ArrayHandle<ValueType> handle = CreateArrayHandle<ValueType>(32, managed);
handle.PrepareForInput(vtkm::cont::DeviceAdapterTagCuda());
ValueType* origArray = handle.Internals->ExecutionArray;
void* origArray = handle.Internals->ExecutionArray;
handle.ReleaseResourcesExecution();
ValueType* contArray = handle.Internals->ControlArray.GetArray();
ValueType* execArray = handle.Internals->ExecutionArray;
void* contArray = handle.Internals->ControlArray->GetBasePointer();
void* execArray = handle.Internals->ExecutionArray;
VTKM_TEST_ASSERT(contArray != nullptr, "No control array after ReleaseResourcesExecution.");
VTKM_TEST_ASSERT(execArray == nullptr,
@ -178,10 +178,10 @@ void TestRoundTrip(bool managed)
vtkm::cont::ArrayHandle<ValueType> handle = CreateArrayHandle<ValueType>(32, managed);
handle.PrepareForOutput(32, vtkm::cont::DeviceAdapterTagCuda());
ValueType* origContArray = handle.Internals->ControlArray.GetArray();
void* origContArray = handle.Internals->ControlArray->GetBasePointer();
{
ValueType* contArray = handle.Internals->ControlArray.GetArray();
ValueType* execArray = handle.Internals->ExecutionArray;
void* contArray = handle.Internals->ControlArray->GetBasePointer();
void* execArray = handle.Internals->ExecutionArray;
VTKM_TEST_ASSERT(contArray != nullptr, "No control array after PrepareForOutput.");
VTKM_TEST_ASSERT(execArray != nullptr, "No execution array after PrepareForOutput.");
VTKM_TEST_ASSERT(CudaAllocator::IsDevicePointer(execArray),
@ -222,8 +222,8 @@ void TestRoundTrip(bool managed)
}
{
ValueType* contArray = handle.Internals->ControlArray.GetArray();
ValueType* execArray = handle.Internals->ExecutionArray;
void* contArray = handle.Internals->ControlArray->GetBasePointer();
void* execArray = handle.Internals->ExecutionArray;
VTKM_TEST_ASSERT(contArray != nullptr, "No control array after GetPortalConst.");
VTKM_TEST_ASSERT(execArray == nullptr, "Execution array not cleared after GetPortalConst.");
VTKM_TEST_ASSERT(CudaAllocator::IsDevicePointer(contArray),

@ -36,22 +36,14 @@ namespace internal
{
/// Type-agnostic container for an execution memory buffer.
struct VTKM_ALWAYS_EXPORT TypelessExecutionArray
struct VTKM_CONT_EXPORT TypelessExecutionArray
{
VTKM_CONT
TypelessExecutionArray(void*& array,
void*& arrayEnd,
void*& arrayCapacity,
const void* arrayControl,
const void* arrayControlCapacity)
: Array(array)
, ArrayEnd(arrayEnd)
, ArrayCapacity(arrayCapacity)
, ArrayControl(arrayControl)
, ArrayControlCapacity(arrayControlCapacity)
{
}
const void* arrayControlCapacity);
void*& Array;
void*& ArrayEnd;
void*& ArrayCapacity;
@ -136,6 +128,47 @@ protected:
template <typename DeviceTag>
struct ExecutionArrayInterfaceBasic;
struct VTKM_CONT_EXPORT ArrayHandleImpl
{
template <typename T>
ArrayHandleImpl(T)
: ControlArrayValid(false)
, ControlArray(new vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>())
, ExecutionInterface(nullptr)
, ExecutionArrayValid(false)
, ExecutionArray(nullptr)
, ExecutionArrayEnd(nullptr)
, ExecutionArrayCapacity(nullptr)
{
}
template <typename T>
ArrayHandleImpl(const vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>& storage)
: ControlArrayValid(true)
, ControlArray(new vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>(storage))
, ExecutionInterface(nullptr)
, ExecutionArrayValid(false)
, ExecutionArray(nullptr)
, ExecutionArrayEnd(nullptr)
, ExecutionArrayCapacity(nullptr)
{
}
~ArrayHandleImpl();
ArrayHandleImpl(const ArrayHandleImpl&) = delete;
void operator=(const ArrayHandleImpl&) = delete;
bool ControlArrayValid;
StorageBasicBase* ControlArray;
ExecutionArrayInterfaceBasicBase* ExecutionInterface;
bool ExecutionArrayValid;
void* ExecutionArray;
void* ExecutionArrayEnd;
void* ExecutionArrayCapacity;
};
} // end namespace internal
/// Specialization of ArrayHandle for Basic storage. The goal here is to reduce
@ -156,7 +189,6 @@ public:
using ValueType = T;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
struct InternalStruct;
template <typename DeviceTag>
struct ExecutionTypes
@ -169,7 +201,6 @@ public:
VTKM_CONT ArrayHandle(const Thisclass& src);
VTKM_CONT ArrayHandle(const Thisclass&& src);
VTKM_CONT ArrayHandle(const StorageType& storage);
VTKM_CONT ArrayHandle(const std::shared_ptr<InternalStruct>& i);
VTKM_CONT ~ArrayHandle();
@ -216,60 +247,7 @@ public:
VTKM_CONT void SyncControlArray() const;
VTKM_CONT void ReleaseResourcesExecutionInternal();
struct VTKM_ALWAYS_EXPORT InternalStruct
{
InternalStruct()
: ControlArrayValid(false)
, ExecutionInterface(nullptr)
, ExecutionArrayValid(false)
, ExecutionArray(nullptr)
, ExecutionArrayEnd(nullptr)
, ExecutionArrayCapacity(nullptr)
{
}
InternalStruct(const StorageType& storage)
: ControlArrayValid(true)
, ControlArray(storage)
, ExecutionInterface(nullptr)
, ExecutionArrayValid(false)
, ExecutionArray(nullptr)
, ExecutionArrayEnd(nullptr)
, ExecutionArrayCapacity(nullptr)
{
}
~InternalStruct()
{
if (this->ExecutionArrayValid && this->ExecutionInterface != nullptr &&
this->ExecutionArray != nullptr)
{
internal::TypelessExecutionArray execArray(
reinterpret_cast<void*&>(this->ExecutionArray),
reinterpret_cast<void*&>(this->ExecutionArrayEnd),
reinterpret_cast<void*&>(this->ExecutionArrayCapacity),
this->ControlArray.GetBasePointer(),
this->ControlArray.GetCapacityPointer());
this->ExecutionInterface->Free(execArray);
}
delete this->ExecutionInterface;
}
InternalStruct(const InternalStruct&) = delete;
void operator=(const InternalStruct&) = delete;
bool ControlArrayValid;
StorageType ControlArray;
internal::ExecutionArrayInterfaceBasicBase* ExecutionInterface;
bool ExecutionArrayValid;
ValueType* ExecutionArray;
ValueType* ExecutionArrayEnd;
ValueType* ExecutionArrayCapacity;
};
std::shared_ptr<InternalStruct> Internals;
std::shared_ptr<internal::ArrayHandleImpl> Internals;
};
} // end namespace cont

@ -27,10 +27,9 @@ namespace vtkm
{
namespace cont
{
template <typename T>
ArrayHandle<T, StorageTagBasic>::ArrayHandle()
: Internals(new InternalStruct)
: Internals(new internal::ArrayHandleImpl(T{}))
{
}
@ -48,13 +47,7 @@ ArrayHandle<T, StorageTagBasic>::ArrayHandle(const Thisclass&& src)
template <typename T>
ArrayHandle<T, StorageTagBasic>::ArrayHandle(const StorageType& storage)
: Internals(new InternalStruct(storage))
{
}
template <typename T>
ArrayHandle<T, StorageTagBasic>::ArrayHandle(const std::shared_ptr<InternalStruct>& i)
: Internals(i)
: Internals(new internal::ArrayHandleImpl(storage))
{
}
@ -109,7 +102,7 @@ typename ArrayHandle<T, StorageTagBasic>::StorageType& ArrayHandle<T, StorageTag
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
{
return this->Internals->ControlArray;
return *(static_cast<StorageType*>(this->Internals->ControlArray));
}
else
{
@ -125,7 +118,7 @@ ArrayHandle<T, StorageTagBasic>::GetStorage() const
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
{
return this->Internals->ControlArray;
return *(static_cast<const StorageType*>(this->Internals->ControlArray));
}
else
{
@ -145,7 +138,8 @@ ArrayHandle<T, StorageTagBasic>::GetPortalControl()
// array will become invalid. Play it safe and release the execution
// resources. (Use the const version to preserve the execution array.)
this->ReleaseResourcesExecutionInternal();
return this->Internals->ControlArray.GetPortal();
StorageType* privStorage = static_cast<StorageType*>(this->Internals->ControlArray);
return privStorage->GetPortal();
}
else
{
@ -162,7 +156,8 @@ ArrayHandle<T, StorageTagBasic>::GetPortalConstControl() const
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
{
return this->Internals->ControlArray.GetPortalConst();
StorageType* privStorage = static_cast<StorageType*>(this->Internals->ControlArray);
return privStorage->GetPortalConst();
}
else
{
@ -176,12 +171,12 @@ vtkm::Id ArrayHandle<T, StorageTagBasic>::GetNumberOfValues() const
{
if (this->Internals->ControlArrayValid)
{
return this->Internals->ControlArray.GetNumberOfValues();
return this->Internals->ControlArray->GetNumberOfValues();
}
else if (this->Internals->ExecutionArrayValid)
{
return static_cast<vtkm::Id>(this->Internals->ExecutionArrayEnd -
this->Internals->ExecutionArray);
return static_cast<vtkm::Id>(static_cast<T*>(this->Internals->ExecutionArrayEnd) -
static_cast<T*>(this->Internals->ExecutionArray));
}
else
{
@ -193,7 +188,7 @@ template <typename T>
void ArrayHandle<T, StorageTagBasic>::Allocate(vtkm::Id numberOfValues)
{
this->ReleaseResourcesExecutionInternal();
this->Internals->ControlArray.AllocateValues(numberOfValues, sizeof(T));
this->Internals->ControlArray->AllocateValues(numberOfValues, sizeof(T));
this->Internals->ControlArrayValid = true;
}
@ -210,11 +205,12 @@ void ArrayHandle<T, StorageTagBasic>::Shrink(vtkm::Id numberOfValues)
{
if (this->Internals->ControlArrayValid)
{
this->Internals->ControlArray.Shrink(numberOfValues);
this->Internals->ControlArray->Shrink(numberOfValues);
}
if (this->Internals->ExecutionArrayValid)
{
this->Internals->ExecutionArrayEnd = this->Internals->ExecutionArray + numberOfValues;
this->Internals->ExecutionArrayEnd =
static_cast<T*>(this->Internals->ExecutionArray) + numberOfValues;
}
}
else if (numberOfValues == originalNumberOfValues)
@ -253,7 +249,7 @@ void ArrayHandle<T, StorageTagBasic>::ReleaseResources()
if (this->Internals->ControlArrayValid)
{
this->Internals->ControlArray.ReleaseResources();
this->Internals->ControlArray->ReleaseResources();
this->Internals->ControlArrayValid = false;
}
}
@ -264,7 +260,7 @@ typename ArrayHandle<T, StorageTagBasic>::template ExecutionTypes<DeviceAdapterT
ArrayHandle<T, StorageTagBasic>::PrepareForInput(DeviceAdapterTag device) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
InternalStruct* priv = const_cast<InternalStruct*>(this->Internals.get());
internal::ArrayHandleImpl* priv = const_cast<internal::ArrayHandleImpl*>(this->Internals.get());
this->PrepareForDevice(device);
const vtkm::Id numVals = this->GetNumberOfValues();
@ -276,29 +272,29 @@ ArrayHandle<T, StorageTagBasic>::PrepareForInput(DeviceAdapterTag device) const
// Initialize an empty array if needed:
if (!this->Internals->ControlArrayValid)
{
this->Internals->ControlArray.Allocate(0);
priv->ControlArray->AllocateValues(0, sizeof(T));
this->Internals->ControlArrayValid = true;
}
internal::TypelessExecutionArray execArray(
reinterpret_cast<void*&>(priv->ExecutionArray),
reinterpret_cast<void*&>(priv->ExecutionArrayEnd),
reinterpret_cast<void*&>(priv->ExecutionArrayCapacity),
this->Internals->ControlArray.GetBasePointer(),
this->Internals->ControlArray.GetCapacityPointer());
internal::TypelessExecutionArray execArray(priv->ExecutionArray,
priv->ExecutionArrayEnd,
priv->ExecutionArrayCapacity,
priv->ControlArray->GetBasePointer(),
priv->ControlArray->GetCapacityPointer());
priv->ExecutionInterface->Allocate(execArray, numVals, sizeof(T));
priv->ExecutionInterface->CopyFromControl(
priv->ControlArray.GetArray(), priv->ExecutionArray, numBytes);
priv->ControlArray->GetBasePointer(), priv->ExecutionArray, numBytes);
this->Internals->ExecutionArrayValid = true;
}
this->Internals->ExecutionInterface->UsingForRead(
priv->ControlArray.GetArray(), priv->ExecutionArray, numBytes);
priv->ControlArray->GetBasePointer(), priv->ExecutionArray, numBytes);
return PortalFactory<DeviceAdapterTag>::CreatePortalConst(this->Internals->ExecutionArray,
this->Internals->ExecutionArrayEnd);
return PortalFactory<DeviceAdapterTag>::CreatePortalConst(
static_cast<T*>(this->Internals->ExecutionArray),
static_cast<T*>(this->Internals->ExecutionArrayEnd));
}
template <typename T>
@ -307,7 +303,7 @@ typename ArrayHandle<T, StorageTagBasic>::template ExecutionTypes<DeviceAdapterT
ArrayHandle<T, StorageTagBasic>::PrepareForOutput(vtkm::Id numVals, DeviceAdapterTag device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
InternalStruct* priv = const_cast<InternalStruct*>(this->Internals.get());
internal::ArrayHandleImpl* priv = const_cast<internal::ArrayHandleImpl*>(this->Internals.get());
this->PrepareForDevice(device);
@ -316,22 +312,23 @@ ArrayHandle<T, StorageTagBasic>::PrepareForOutput(vtkm::Id numVals, DeviceAdapte
// the execution environment.
this->Internals->ControlArrayValid = false;
internal::TypelessExecutionArray execArray(reinterpret_cast<void*&>(priv->ExecutionArray),
reinterpret_cast<void*&>(priv->ExecutionArrayEnd),
reinterpret_cast<void*&>(priv->ExecutionArrayCapacity),
this->Internals->ControlArray.GetBasePointer(),
this->Internals->ControlArray.GetCapacityPointer());
internal::TypelessExecutionArray execArray(priv->ExecutionArray,
priv->ExecutionArrayEnd,
priv->ExecutionArrayCapacity,
priv->ControlArray->GetBasePointer(),
priv->ControlArray->GetCapacityPointer());
this->Internals->ExecutionInterface->Allocate(execArray, numVals, sizeof(T));
const vtkm::UInt64 numBytes = sizeof(T) * static_cast<vtkm::UInt64>(numVals);
this->Internals->ExecutionInterface->UsingForWrite(
priv->ControlArray.GetArray(), priv->ExecutionArray, numBytes);
priv->ControlArray->GetBasePointer(), priv->ExecutionArray, numBytes);
this->Internals->ExecutionArrayValid = true;
return PortalFactory<DeviceAdapterTag>::CreatePortal(this->Internals->ExecutionArray,
this->Internals->ExecutionArrayEnd);
return PortalFactory<DeviceAdapterTag>::CreatePortal(
static_cast<T*>(this->Internals->ExecutionArray),
static_cast<T*>(this->Internals->ExecutionArrayEnd));
}
template <typename T>
@ -340,7 +337,7 @@ typename ArrayHandle<T, StorageTagBasic>::template ExecutionTypes<DeviceAdapterT
ArrayHandle<T, StorageTagBasic>::PrepareForInPlace(DeviceAdapterTag device)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
InternalStruct* priv = const_cast<InternalStruct*>(this->Internals.get());
internal::ArrayHandleImpl* priv = const_cast<internal::ArrayHandleImpl*>(this->Internals.get());
this->PrepareForDevice(device);
const vtkm::Id numVals = this->GetNumberOfValues();
@ -351,33 +348,33 @@ ArrayHandle<T, StorageTagBasic>::PrepareForInPlace(DeviceAdapterTag device)
// Initialize an empty array if needed:
if (!this->Internals->ControlArrayValid)
{
this->Internals->ControlArray.Allocate(0);
priv->ControlArray->AllocateValues(0, sizeof(T));
this->Internals->ControlArrayValid = true;
}
internal::TypelessExecutionArray execArray(
reinterpret_cast<void*&>(this->Internals->ExecutionArray),
reinterpret_cast<void*&>(this->Internals->ExecutionArrayEnd),
reinterpret_cast<void*&>(this->Internals->ExecutionArrayCapacity),
this->Internals->ControlArray.GetBasePointer(),
this->Internals->ControlArray.GetCapacityPointer());
internal::TypelessExecutionArray execArray(this->Internals->ExecutionArray,
this->Internals->ExecutionArrayEnd,
this->Internals->ExecutionArrayCapacity,
priv->ControlArray->GetBasePointer(),
priv->ControlArray->GetCapacityPointer());
priv->ExecutionInterface->Allocate(execArray, numVals, sizeof(T));
priv->ExecutionInterface->CopyFromControl(
priv->ControlArray.GetArray(), priv->ExecutionArray, numBytes);
priv->ControlArray->GetBasePointer(), priv->ExecutionArray, numBytes);
this->Internals->ExecutionArrayValid = true;
}
priv->ExecutionInterface->UsingForReadWrite(
priv->ControlArray.GetArray(), priv->ExecutionArray, numBytes);
priv->ControlArray->GetBasePointer(), priv->ExecutionArray, numBytes);
// Invalidate the control array, since we expect the values to be modified:
this->Internals->ControlArrayValid = false;
return PortalFactory<DeviceAdapterTag>::CreatePortal(this->Internals->ExecutionArray,
this->Internals->ExecutionArrayEnd);
return PortalFactory<DeviceAdapterTag>::CreatePortal(
static_cast<T*>(this->Internals->ExecutionArray),
static_cast<T*>(this->Internals->ExecutionArrayEnd));
}
template <typename T>
@ -385,8 +382,7 @@ template <typename DeviceAdapterTag>
void ArrayHandle<T, StorageTagBasic>::PrepareForDevice(DeviceAdapterTag) const
{
DeviceAdapterId devId = DeviceAdapterTraits<DeviceAdapterTag>::GetId();
InternalStruct* priv = const_cast<InternalStruct*>(this->Internals.get());
internal::ArrayHandleImpl* priv = const_cast<internal::ArrayHandleImpl*>(this->Internals.get());
// Check if the current device matches the last one and sync through
// the control environment if the device changes.
if (this->Internals->ExecutionInterface)
@ -400,12 +396,11 @@ void ArrayHandle<T, StorageTagBasic>::PrepareForDevice(DeviceAdapterTag) const
{
// Update the device allocator:
this->SyncControlArray();
internal::TypelessExecutionArray execArray(
reinterpret_cast<void*&>(priv->ExecutionArray),
reinterpret_cast<void*&>(priv->ExecutionArrayEnd),
reinterpret_cast<void*&>(priv->ExecutionArrayCapacity),
this->Internals->ControlArray.GetBasePointer(),
this->Internals->ControlArray.GetCapacityPointer());
internal::TypelessExecutionArray execArray(priv->ExecutionArray,
priv->ExecutionArrayEnd,
priv->ExecutionArrayCapacity,
priv->ControlArray->GetBasePointer(),
priv->ControlArray->GetCapacityPointer());
priv->ExecutionInterface->Free(execArray);
delete priv->ExecutionInterface;
priv->ExecutionInterface = nullptr;
@ -417,7 +412,7 @@ void ArrayHandle<T, StorageTagBasic>::PrepareForDevice(DeviceAdapterTag) const
VTKM_ASSERT(!priv->ExecutionArrayValid);
priv->ExecutionInterface =
new internal::ExecutionArrayInterfaceBasic<DeviceAdapterTag>(this->Internals->ControlArray);
new internal::ExecutionArrayInterfaceBasic<DeviceAdapterTag>(*this->Internals->ControlArray);
}
template <typename T>
@ -434,15 +429,15 @@ void ArrayHandle<T, StorageTagBasic>::SyncControlArray() const
{
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct* priv = const_cast<InternalStruct*>(this->Internals.get());
internal::ArrayHandleImpl* priv = const_cast<internal::ArrayHandleImpl*>(this->Internals.get());
if (this->Internals->ExecutionArrayValid)
{
const vtkm::Id numValues =
static_cast<vtkm::Id>(this->Internals->ExecutionArrayEnd - this->Internals->ExecutionArray);
const vtkm::UInt64 numBytes = sizeof(T) * static_cast<vtkm::UInt64>(numValues);
priv->ControlArray.Allocate(numValues);
const vtkm::Id numVals = static_cast<vtkm::Id>(static_cast<T*>(priv->ExecutionArrayEnd) -
static_cast<T*>(priv->ExecutionArray));
const vtkm::UInt64 numBytes = sizeof(T) * static_cast<vtkm::UInt64>(numVals);
priv->ControlArray->AllocateValues(numVals, sizeof(T));
priv->ExecutionInterface->CopyToControl(
priv->ExecutionArray, priv->ControlArray.GetArray(), numBytes);
priv->ExecutionArray, static_cast<T*>(priv->ControlArray->GetBasePointer()), numBytes);
priv->ControlArrayValid = true;
}
else
@ -450,7 +445,7 @@ void ArrayHandle<T, StorageTagBasic>::SyncControlArray() const
// This array is in the null state (there is nothing allocated), but
// the calling function wants to do something with the array. Put this
// class into a valid state by allocating an array of size 0.
priv->ControlArray.Allocate(0);
priv->ControlArray->AllocateValues(0, sizeof(T));
priv->ControlArrayValid = true;
}
}
@ -461,12 +456,11 @@ void ArrayHandle<T, StorageTagBasic>::ReleaseResourcesExecutionInternal()
{
if (this->Internals->ExecutionArrayValid)
{
internal::TypelessExecutionArray execArray(
reinterpret_cast<void*&>(this->Internals->ExecutionArray),
reinterpret_cast<void*&>(this->Internals->ExecutionArrayEnd),
reinterpret_cast<void*&>(this->Internals->ExecutionArrayCapacity),
this->Internals->ControlArray.GetBasePointer(),
this->Internals->ControlArray.GetCapacityPointer());
internal::TypelessExecutionArray execArray(this->Internals->ExecutionArray,
this->Internals->ExecutionArrayEnd,
this->Internals->ExecutionArrayCapacity,
this->Internals->ControlArray->GetBasePointer(),
this->Internals->ControlArray->GetCapacityPointer());
this->Internals->ExecutionInterface->Free(execArray);
this->Internals->ExecutionArrayValid = false;
}

@ -177,7 +177,6 @@ private:
template <typename T>
void operator()(const T t) const
{
std::cout << "TransferFunctor" << std::endl;
const std::size_t Size = 10;
GLuint GLHandle;
//verify that T is able to be transfer to openGL.
@ -197,7 +196,7 @@ private:
//verify the results match what is in the array handle
temp.SyncControlArray();
T* expectedValues = temp.Internals->ControlArray.StealArray();
T* expectedValues = temp.GetStorage().GetArray();
for (std::size_t i = 0; i < Size; ++i)
{
@ -214,7 +213,7 @@ private:
returnedValues = CopyGLBuffer(GLHandle, t);
//verify the results match what is in the array handle
temp.SyncControlArray();
expectedValues = temp.Internals->ControlArray.StealArray();
expectedValues = temp.GetStorage().GetArray();
for (std::size_t i = 0; i < Size * 2; ++i)
{