vtk-m/vtkm/cont/testing/TestingVirtualObjectHandle.h
Kenneth Moreland cb3bb43ff9 Completely deprecate virtual methods
Deprecate `VirtualObjectHandle` and all other classes that are used to
implement objects with virtual methods in the execution environment.

Additionally, the code is updated so that if the
`VTKm_NO_DEPRECATED_VIRTUAL` flag is set none of the code is compiled at
all. This opens us up to opportunities that do not work with virtual
methods such as backends that do not support virtual methods and dynamic
libraries for CUDA.
2021-04-28 07:28:32 -06:00

233 lines
6.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.
//============================================================================
#ifndef vtk_m_cont_testing_TestingVirtualObjectHandle_h
#define vtk_m_cont_testing_TestingVirtualObjectHandle_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/cont/testing/Testing.h>
#ifdef VTKM_NO_DEPRECATED_VIRTUAL
#error "This test should be disabled if the VTKm_NO_DEPRECATED_VIRTUAL is true."
#endif //VTKM_NO_DEPRECATED_VIRTUAL
VTKM_DEPRECATED_SUPPRESS_BEGIN
#define ARRAY_LEN 8
namespace vtkm
{
namespace cont
{
namespace testing
{
namespace virtual_object_detail
{
class Transformer : public vtkm::VirtualObjectBase
{
public:
VTKM_EXEC
virtual vtkm::FloatDefault Eval(vtkm::FloatDefault val) const = 0;
};
class Square : public Transformer
{
public:
VTKM_EXEC
vtkm::FloatDefault Eval(vtkm::FloatDefault val) const override { return val * val; }
};
class Multiply : public Transformer
{
public:
VTKM_CONT
void SetMultiplicand(vtkm::FloatDefault val)
{
this->Multiplicand = val;
this->Modified();
}
VTKM_CONT
vtkm::FloatDefault GetMultiplicand() const { return this->Multiplicand; }
VTKM_EXEC
vtkm::FloatDefault Eval(vtkm::FloatDefault val) const override
{
return val * this->Multiplicand;
}
private:
vtkm::FloatDefault Multiplicand = 0.0f;
};
class TransformerFunctor
{
public:
TransformerFunctor() = default;
explicit TransformerFunctor(const Transformer* impl)
: Impl(impl)
{
}
VTKM_EXEC
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const { return this->Impl->Eval(val); }
private:
const Transformer* Impl;
};
} // virtual_object_detail
template <typename DeviceAdapterList>
class TestingVirtualObjectHandle
{
private:
using FloatArrayHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
using ArrayTransform =
vtkm::cont::ArrayHandleTransform<FloatArrayHandle, virtual_object_detail::TransformerFunctor>;
using TransformerHandle = vtkm::cont::VirtualObjectHandle<virtual_object_detail::Transformer>;
class TestStage1
{
public:
TestStage1(const FloatArrayHandle& input, TransformerHandle& handle)
: Input(&input)
, Handle(&handle)
{
}
template <typename DeviceAdapter>
void operator()(DeviceAdapter device) const
{
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
std::cout << "\tDeviceAdapter: " << vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< std::endl;
for (int n = 0; n < 2; ++n)
{
vtkm::cont::Token token;
virtual_object_detail::TransformerFunctor tfnctr(
this->Handle->PrepareForExecution(device, token));
ArrayTransform transformed(*this->Input, tfnctr);
FloatArrayHandle output;
Algorithm::Copy(transformed, output);
auto portal = output.ReadPortal();
for (vtkm::Id i = 0; i < ARRAY_LEN; ++i)
{
vtkm::FloatDefault expected = TestValue(i, vtkm::FloatDefault{});
expected = expected * expected;
VTKM_TEST_ASSERT(
test_equal(portal.Get(i), expected), "Expected ", expected, " but got ", portal.Get(i));
}
std::cout << "\tSuccess." << std::endl;
if (n == 0)
{
std::cout << "\tReleaseResources and test again..." << std::endl;
this->Handle->ReleaseExecutionResources();
}
}
}
private:
const FloatArrayHandle* Input;
TransformerHandle* Handle;
};
class TestStage2
{
public:
TestStage2(const FloatArrayHandle& input,
virtual_object_detail::Multiply& mul,
TransformerHandle& handle)
: Input(&input)
, Mul(&mul)
, Handle(&handle)
{
}
template <typename DeviceAdapter>
void operator()(DeviceAdapter device) const
{
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
std::cout << "\tDeviceAdapter: " << vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< std::endl;
this->Mul->SetMultiplicand(2);
for (int n = 0; n < 2; ++n)
{
vtkm::cont::Token token;
virtual_object_detail::TransformerFunctor tfnctr(
this->Handle->PrepareForExecution(device, token));
ArrayTransform transformed(*this->Input, tfnctr);
FloatArrayHandle output;
Algorithm::Copy(transformed, output);
auto portal = output.ReadPortal();
for (vtkm::Id i = 0; i < ARRAY_LEN; ++i)
{
vtkm::FloatDefault expected =
TestValue(i, vtkm::FloatDefault{}) * this->Mul->GetMultiplicand();
VTKM_TEST_ASSERT(
test_equal(portal.Get(i), expected), "Expected ", expected, " but got ", portal.Get(i));
}
std::cout << "\tSuccess." << std::endl;
if (n == 0)
{
std::cout << "\tUpdate and test again..." << std::endl;
this->Mul->SetMultiplicand(3);
}
}
}
private:
const FloatArrayHandle* Input;
virtual_object_detail::Multiply* Mul;
TransformerHandle* Handle;
};
public:
static void Run()
{
vtkm::cont::ArrayHandle<vtkm::FloatDefault> input;
input.Allocate(ARRAY_LEN);
SetPortal(input.WritePortal());
TransformerHandle handle;
std::cout << "Testing with concrete type 1 (Square)..." << std::endl;
virtual_object_detail::Square sqr;
handle.Reset(&sqr, false, DeviceAdapterList());
vtkm::ListForEach(TestStage1(input, handle), DeviceAdapterList());
std::cout << "ReleaseResources..." << std::endl;
handle.ReleaseResources();
std::cout << "Testing with concrete type 2 (Multiply)..." << std::endl;
virtual_object_detail::Multiply mul;
handle.Reset(&mul, false, DeviceAdapterList());
vtkm::ListForEach(TestStage2(input, mul, handle), DeviceAdapterList());
}
};
}
}
} // vtkm::cont::testing
VTKM_DEPRECATED_SUPPRESS_END
#endif