mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-06 02:18:58 +00:00
ad1e7b5bdb
This mechanism sets up CMake variables that allow a user to select which modules/libraries to create. Dependencies will be tracked down to ensure that all of a module's dependencies are also enabled. The modules are also arranged into groups. Groups allow you to set the enable flag for a group of modules at once. Thus, if you have several modules that are likely to be used together, you can create a group for them. This can be handy in converting user-friendly CMake options (such as `VTKm_ENABLE_RENDERING`) to the modules that enable that by pointing to the appropriate group.
257 lines
8.3 KiB
C++
257 lines
8.3 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt for details.
|
|
//
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
//============================================================================
|
|
|
|
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
|
|
#include <vtkm/cont/internal/Buffer.h>
|
|
|
|
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
|
|
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
|
|
namespace
|
|
{
|
|
|
|
using T = vtkm::FloatDefault;
|
|
constexpr vtkm::Id ARRAY_SIZE = 20;
|
|
|
|
using PortalType = vtkm::cont::internal::ArrayPortalFromIterators<T*>;
|
|
using PortalTypeConst = vtkm::cont::internal::ArrayPortalFromIterators<const T*>;
|
|
|
|
struct TestMetaData
|
|
{
|
|
vtkm::Id Value = 0;
|
|
};
|
|
|
|
constexpr vtkm::Id METADATA_VALUE = 42;
|
|
|
|
bool CheckMetaData(const vtkm::cont::internal::Buffer& buffer)
|
|
{
|
|
return buffer.GetMetaData<TestMetaData>().Value == METADATA_VALUE;
|
|
}
|
|
|
|
PortalType MakePortal(void* buffer, vtkm::Id numValues)
|
|
{
|
|
return PortalType(static_cast<T*>(buffer),
|
|
static_cast<T*>(buffer) + static_cast<std::size_t>(numValues));
|
|
};
|
|
|
|
PortalTypeConst MakePortal(const void* buffer, vtkm::Id numValues)
|
|
{
|
|
return PortalTypeConst(static_cast<const T*>(buffer),
|
|
static_cast<const T*>(buffer) + static_cast<std::size_t>(numValues));
|
|
};
|
|
|
|
void VectorDeleter(void* container)
|
|
{
|
|
std::vector<T>* v = reinterpret_cast<std::vector<T>*>(container);
|
|
delete v;
|
|
}
|
|
|
|
void VectorReallocator(void*& memory,
|
|
void*& container,
|
|
vtkm::BufferSizeType oldSize,
|
|
vtkm::BufferSizeType newSize)
|
|
{
|
|
std::vector<T>* v = reinterpret_cast<std::vector<T>*>(container);
|
|
VTKM_TEST_ASSERT(v->size() == static_cast<std::size_t>(oldSize));
|
|
VTKM_TEST_ASSERT(v->empty() || (memory == v->data()));
|
|
|
|
v->resize(static_cast<std::size_t>(newSize));
|
|
memory = v->data();
|
|
}
|
|
struct VectorDeleter
|
|
{
|
|
std::shared_ptr<std::vector<T>> Data;
|
|
|
|
VectorDeleter(vtkm::Id numValues)
|
|
: Data(new std::vector<T>(static_cast<size_t>(numValues)))
|
|
{
|
|
}
|
|
|
|
template <typename U>
|
|
void operator()(U* p)
|
|
{
|
|
if (this->Data)
|
|
{
|
|
VTKM_TEST_ASSERT(reinterpret_cast<T*>(p) == this->Data->data());
|
|
this->Data.reset();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
void DoTest()
|
|
{
|
|
constexpr vtkm::Id BUFFER_SIZE = ARRAY_SIZE * static_cast<vtkm::Id>(sizeof(T));
|
|
constexpr vtkm::cont::DeviceAdapterTagSerial device;
|
|
|
|
vtkm::cont::internal::Buffer buffer;
|
|
|
|
{
|
|
TestMetaData metadata;
|
|
metadata.Value = METADATA_VALUE;
|
|
buffer.SetMetaData(metadata);
|
|
VTKM_TEST_ASSERT(CheckMetaData(buffer));
|
|
}
|
|
|
|
std::cout << "Copy uninitialized buffer" << std::endl;
|
|
{
|
|
vtkm::cont::internal::Buffer copy;
|
|
copy.DeepCopyFrom(buffer);
|
|
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == 0);
|
|
VTKM_TEST_ASSERT(CheckMetaData(copy));
|
|
}
|
|
|
|
std::cout << "Initialize buffer" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
buffer.SetNumberOfBytes(BUFFER_SIZE, vtkm::CopyFlag::Off, token);
|
|
}
|
|
|
|
VTKM_TEST_ASSERT(buffer.GetNumberOfBytes() == BUFFER_SIZE);
|
|
|
|
std::cout << "Copy sized but uninitialized buffer" << std::endl;
|
|
{
|
|
vtkm::cont::internal::Buffer copy;
|
|
copy.DeepCopyFrom(buffer);
|
|
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE);
|
|
VTKM_TEST_ASSERT(CheckMetaData(copy));
|
|
VTKM_TEST_ASSERT(!copy.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(!copy.IsAllocatedOnDevice(device));
|
|
}
|
|
|
|
std::cout << "Fill up values on host" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
SetPortal(MakePortal(buffer.WritePointerHost(token), ARRAY_SIZE));
|
|
}
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(!buffer.IsAllocatedOnDevice(device));
|
|
|
|
std::cout << "Check values on host" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
CheckPortal(MakePortal(buffer.ReadPointerHost(token), ARRAY_SIZE));
|
|
}
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(!buffer.IsAllocatedOnDevice(device));
|
|
|
|
std::cout << "Copy buffer with host data" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
vtkm::cont::internal::Buffer copy;
|
|
copy.DeepCopyFrom(buffer);
|
|
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE);
|
|
VTKM_TEST_ASSERT(CheckMetaData(copy));
|
|
VTKM_TEST_ASSERT(copy.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(!copy.IsAllocatedOnDevice(device));
|
|
CheckPortal(MakePortal(buffer.ReadPointerHost(token), ARRAY_SIZE));
|
|
}
|
|
|
|
std::cout << "Check values on device" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
CheckPortal(MakePortal(buffer.ReadPointerDevice(device, token), ARRAY_SIZE));
|
|
}
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnDevice(device));
|
|
|
|
std::cout << "Resize array and access write on device" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
buffer.SetNumberOfBytes(BUFFER_SIZE / 2, vtkm::CopyFlag::On, token);
|
|
VTKM_TEST_ASSERT(buffer.GetNumberOfBytes() == BUFFER_SIZE / 2);
|
|
CheckPortal(MakePortal(buffer.WritePointerDevice(device, token), ARRAY_SIZE / 2));
|
|
}
|
|
VTKM_TEST_ASSERT(!buffer.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnDevice(device));
|
|
|
|
std::cout << "Resize array and access write on host" << std::endl;
|
|
// Note that this is a weird corner case where the array was resized while saving the data
|
|
// and then requested on another device.
|
|
{
|
|
vtkm::cont::Token token;
|
|
buffer.SetNumberOfBytes(BUFFER_SIZE * 2, vtkm::CopyFlag::On, token);
|
|
VTKM_TEST_ASSERT(buffer.GetNumberOfBytes() == BUFFER_SIZE * 2);
|
|
// Although the array is twice ARRAY_SIZE, the valid values are only ARRAY_SIZE/2
|
|
CheckPortal(MakePortal(buffer.WritePointerHost(token), ARRAY_SIZE / 2));
|
|
}
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(!buffer.IsAllocatedOnDevice(device));
|
|
|
|
std::cout << "Fill buffer" << std::endl;
|
|
{
|
|
constexpr vtkm::BufferSizeType fillValueSize = static_cast<vtkm::BufferSizeType>(sizeof(T));
|
|
vtkm::cont::Token token;
|
|
T fillValue1 = 1.234f;
|
|
T fillValue2 = 5.678f;
|
|
buffer.Fill(&fillValue1, fillValueSize, 0, BUFFER_SIZE * 2, token);
|
|
buffer.Fill(&fillValue2, fillValueSize, BUFFER_SIZE / 2, BUFFER_SIZE, token);
|
|
const T* array = reinterpret_cast<const T*>(buffer.ReadPointerHost(token));
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE / 2; ++index)
|
|
{
|
|
VTKM_TEST_ASSERT(array[index] == fillValue1);
|
|
}
|
|
for (vtkm::Id index = ARRAY_SIZE / 2; index < ARRAY_SIZE; ++index)
|
|
{
|
|
VTKM_TEST_ASSERT(array[index] == fillValue2);
|
|
}
|
|
for (vtkm::Id index = ARRAY_SIZE; index < ARRAY_SIZE * 2; ++index)
|
|
{
|
|
VTKM_TEST_ASSERT(array[index] == fillValue1);
|
|
}
|
|
}
|
|
|
|
std::cout << "Reset with device data" << std::endl;
|
|
std::vector<T> v(ARRAY_SIZE);
|
|
void* devicePointer = v.data();
|
|
SetPortal(MakePortal(devicePointer, ARRAY_SIZE));
|
|
buffer.Reset(vtkm::cont::internal::BufferInfo(device,
|
|
devicePointer,
|
|
new std::vector<T>(std::move(v)),
|
|
BUFFER_SIZE,
|
|
VectorDeleter,
|
|
VectorReallocator));
|
|
VTKM_TEST_ASSERT(buffer.GetNumberOfBytes() == BUFFER_SIZE);
|
|
VTKM_TEST_ASSERT(!buffer.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(buffer.IsAllocatedOnDevice(device));
|
|
|
|
std::cout << "Make sure device pointer is as expected" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
VTKM_TEST_ASSERT(buffer.WritePointerDevice(device, token) == devicePointer);
|
|
}
|
|
|
|
std::cout << "Copy buffer with device data" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
vtkm::cont::internal::Buffer copy;
|
|
copy.DeepCopyFrom(buffer);
|
|
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE);
|
|
VTKM_TEST_ASSERT(CheckMetaData(copy));
|
|
VTKM_TEST_ASSERT(!copy.IsAllocatedOnHost());
|
|
VTKM_TEST_ASSERT(copy.IsAllocatedOnDevice(device));
|
|
CheckPortal(MakePortal(buffer.ReadPointerDevice(device, token), ARRAY_SIZE));
|
|
}
|
|
|
|
std::cout << "Pull data to host" << std::endl;
|
|
{
|
|
vtkm::cont::Token token;
|
|
CheckPortal(MakePortal(buffer.ReadPointerHost(token), ARRAY_SIZE));
|
|
}
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
int UnitTestBuffer(int argc, char* argv[])
|
|
{
|
|
return vtkm::cont::testing::Testing::Run(DoTest, argc, argv);
|
|
}
|