vtk-m/vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h
Haocheng LIU 7d226a4666 Add a common API for CoordinateSystem to unload execution resources
This commit also fixes a bug that ArrayTransfer of ArrayHandleVirtualCoordinate
does not release execution resources properly.
2018-05-30 17:25:54 -04:00

154 lines
5.2 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.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h
#define vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace cont
{
namespace testing
{
namespace
{
struct CopyWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn<FieldCommon> in, FieldOut<FieldCommon> out);
using ExecutionSignature = _2(_1);
template <typename T>
VTKM_EXEC T operator()(const T& in) const
{
return in;
}
};
// A dummy worklet
struct DoubleWorklet : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<FieldCommon> in);
typedef void ExecutionSignature(_1);
using InputDomain = _1;
template <typename T>
VTKM_EXEC void operator()(T& in) const
{
in = in * 2;
}
};
template <typename T, typename S, typename DeviceAdapter>
inline void TestVirtualAccess(const vtkm::cont::ArrayHandle<T, S>& in,
vtkm::cont::ArrayHandle<T>& out,
DeviceAdapter)
{
vtkm::worklet::DispatcherMapField<CopyWorklet, DeviceAdapter>().Invoke(
vtkm::cont::ArrayHandleVirtualCoordinates(in), vtkm::cont::ArrayHandleVirtualCoordinates(out));
VTKM_TEST_ASSERT(test_equal_portals(in.GetPortalConstControl(), out.GetPortalConstControl()),
"Input and output portals don't match");
}
} // anonymous namespace
template <typename DeviceAdapter>
class TestingArrayHandleVirtualCoordinates
{
private:
using ArrayHandleRectilinearCoords =
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
static void TestAll()
{
using PointType = vtkm::Vec<vtkm::FloatDefault, 3>;
static constexpr vtkm::Id length = 64;
vtkm::cont::ArrayHandle<PointType> out;
std::cout << "Testing basic ArrayHandle as input\n";
vtkm::cont::ArrayHandle<PointType> a1;
a1.Allocate(length);
for (vtkm::Id i = 0; i < length; ++i)
{
a1.GetPortalControl().Set(i, TestValue(i, PointType()));
}
TestVirtualAccess(a1, out, DeviceAdapter{});
std::cout << "Testing ArrayHandleUniformPointCoordinates as input\n";
auto t = vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(4, 4, 4));
TestVirtualAccess(t, out, DeviceAdapter{});
std::cout << "Testing ArrayHandleCartesianProduct as input\n";
vtkm::cont::ArrayHandle<vtkm::FloatDefault> c1, c2, c3;
c1.Allocate(length);
c2.Allocate(length);
c3.Allocate(length);
for (vtkm::Id i = 0; i < length; ++i)
{
auto p = a1.GetPortalConstControl().Get(i);
c1.GetPortalControl().Set(i, p[0]);
c2.GetPortalControl().Set(i, p[1]);
c3.GetPortalControl().Set(i, p[2]);
}
TestVirtualAccess(
vtkm::cont::make_ArrayHandleCartesianProduct(c1, c2, c3), out, DeviceAdapter{});
std::cout << "Testing resources releasing on ArrayHandleVirtualCoordinates\n";
vtkm::cont::ArrayHandleVirtualCoordinates virtualC =
vtkm::cont::ArrayHandleVirtualCoordinates(a1);
vtkm::worklet::DispatcherMapField<DoubleWorklet, DeviceAdapter>().Invoke(a1);
virtualC.ReleaseResourcesExecution();
VTKM_TEST_ASSERT(a1.GetNumberOfValues() == length,
"ReleaseResourcesExecution"
" should not change the number of values on the Arrayhandle");
VTKM_TEST_ASSERT(
virtualC.GetNumberOfValues() == length,
"ReleaseResources"
" should set the number of values on the ArrayHandleVirtualCoordinates to be 0");
virtualC.ReleaseResources();
VTKM_TEST_ASSERT(a1.GetNumberOfValues() == 0,
"ReleaseResources"
" should set the number of values on the Arrayhandle to be 0");
}
public:
static int Run() { return vtkm::cont::testing::Testing::Run(TestAll); }
};
}
}
} // vtkm::cont::testing
#endif // vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h