Deduce device adapter tag in interop::TransferToOpenGL.

This commit is contained in:
Allison Vacanti 2017-08-11 15:36:24 -04:00
parent 1f451d538b
commit fcee1cd5e9
6 changed files with 121 additions and 0 deletions

@ -463,6 +463,17 @@ public:
}
}
/// Returns the DeviceAdapterId for the current device. If there is no device
/// with an up-to-date copy of the data, VTKM_DEVICE_ADAPTER_UNDEFINED is
/// returned.
VTKM_CONT
DeviceAdapterId GetDeviceAdapterId() const
{
return this->Internals->ExecutionArrayValid
? this->Internals->ExecutionArray->GetDeviceAdapterId()
: VTKM_DEVICE_ADAPTER_UNDEFINED;
}
struct VTKM_ALWAYS_EXPORT InternalStruct
{
StorageType ControlArray;

@ -194,6 +194,8 @@ public:
template <typename DeviceAdapterTag>
VTKM_CONT void PrepareForDevice(DeviceAdapterTag) const;
VTKM_CONT DeviceAdapterId GetDeviceAdapterId() const;
VTKM_CONT void SyncControlArray() const;
VTKM_CONT void ReleaseResourcesExecutionInternal();

@ -435,6 +435,13 @@ void ArrayHandle<T, StorageTagBasic>::PrepareForDevice(DeviceAdapterTag) const
new internal::ExecutionArrayInterfaceBasic<DeviceAdapterTag>(this->Internals->ControlArray);
}
template <typename T>
DeviceAdapterId ArrayHandle<T, StorageTagBasic>::GetDeviceAdapterId() const
{
return this->Internals->ExecutionArrayValid ? this->Internals->ExecutionInterface->GetDeviceId()
: VTKM_DEVICE_ADAPTER_UNDEFINED;
}
template <typename T>
void ArrayHandle<T, StorageTagBasic>::SyncControlArray() const
{

@ -157,6 +157,9 @@ public:
return this->IsDeviceAdapterImpl(vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId());
}
VTKM_CONT
DeviceAdapterId GetDeviceAdapterId() const { return this->GetDeviceAdapterIdImpl(); }
protected:
virtual vtkm::Id GetNumberOfValuesImpl() const = 0;
@ -174,6 +177,8 @@ protected:
virtual bool IsDeviceAdapterImpl(const vtkm::cont::DeviceAdapterId& id) const = 0;
virtual DeviceAdapterId GetDeviceAdapterIdImpl() const = 0;
private:
template <typename DeviceAdapter>
VTKM_CONT void VerifyDeviceAdapter(DeviceAdapter device) const
@ -261,6 +266,12 @@ protected:
return id == vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId();
}
VTKM_CONT
DeviceAdapterId GetDeviceAdapterIdImpl() const
{
return vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId();
}
private:
ArrayTransferType Transfer;
};

@ -21,9 +21,15 @@
#define vtk_m_interop_TransferToOpenGL_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/interop/BufferState.h>
#include <vtkm/interop/internal/TransferToOpenGL.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
namespace vtkm
{
namespace interop
@ -50,6 +56,54 @@ VTKM_CONT void TransferToOpenGL(vtkm::cont::ArrayHandle<ValueType, StorageTag> h
vtkm::interop::internal::TransferToOpenGL<ValueType, DeviceAdapterTag> toGL(state);
return toGL.Transfer(handle);
}
/// Dispatch overload for TransferToOpenGL that deduces the DeviceAdapter for
/// the given ArrayHandle.
///
/// \overload
///
template <typename ValueType, class StorageTag>
VTKM_CONT void TransferToOpenGL(vtkm::cont::ArrayHandle<ValueType, StorageTag> handle,
BufferState& state)
{
vtkm::cont::DeviceAdapterId devId = handle.GetDeviceAdapterId();
switch (devId)
{
case VTKM_DEVICE_ADAPTER_SERIAL:
TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagSerial());
break;
#ifdef VTKM_ENABLE_TBB
case VTKM_DEVICE_ADAPTER_TBB:
TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagTBB());
break;
#endif
#ifdef VTKM_CUDA
case VTKM_DEVICE_ADAPTER_CUDA:
TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagCuda());
break;
#endif
default:
// Print warning on debug builds, then fallthrough to host case.
#ifndef NDEBUG
std::cerr << __FILE__ << ":" << __LINE__ << ": "
<< "Unrecognized DeviceAdapterId encountered: " << devId << "\n";
#endif // NDEBUG
/* Fallthrough */
case VTKM_DEVICE_ADAPTER_UNDEFINED:
// GetDeviceAdapterId returns UNDEFINED when memory is on the host.
// Try TBB if enabled and serial otherwise.
#ifdef VTKM_ENABLE_TBB
TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagTBB());
#else
TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagSerial());
#endif
break;
}
}
}
}

@ -88,6 +88,24 @@ private:
std::cout << bvError.GetMessage() << std::endl;
VTKM_TEST_ASSERT(true == false, "Got an unexpected Bad Value error transferring to openGL");
}
// Test device adapter deduction:
try
{
vtkm::interop::BufferState state(handle);
vtkm::interop::TransferToOpenGL(array, state);
}
catch (vtkm::cont::ErrorBadAllocation& error)
{
std::cout << error.GetMessage() << std::endl;
VTKM_TEST_ASSERT(true == false,
"Got an unexpected Out Of Memory error transferring to openGL");
}
catch (vtkm::cont::ErrorBadValue& bvError)
{
std::cout << bvError.GetMessage() << std::endl;
VTKM_TEST_ASSERT(true == false, "Got an unexpected Bad Value error transferring to openGL");
}
}
template <typename ArrayHandleType>
@ -109,6 +127,24 @@ private:
std::cout << bvError.GetMessage() << std::endl;
VTKM_TEST_ASSERT(true == false, "Got an unexpected Bad Value error transferring to openGL");
}
// Test device adapter deduction
try
{
vtkm::interop::BufferState state(handle, type);
vtkm::interop::TransferToOpenGL(array, state);
}
catch (vtkm::cont::ErrorBadAllocation& error)
{
std::cout << error.GetMessage() << std::endl;
VTKM_TEST_ASSERT(true == false,
"Got an unexpected Out Of Memory error transferring to openGL");
}
catch (vtkm::cont::ErrorBadValue& bvError)
{
std::cout << bvError.GetMessage() << std::endl;
VTKM_TEST_ASSERT(true == false, "Got an unexpected Bad Value error transferring to openGL");
}
}
//bring the data back from openGL and into a std vector. Will bind the