Merge topic 'virtual-methods'

4049b5b2 Add ClipWithImplicitFunction Filter
82d02e46 Modify ImplicitFunctions to use Virtual Methods
968960c1 Add Virtual Methods Framework

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Kenneth Moreland <kmorel@sandia.gov>
Merge-request: !750
This commit is contained in:
Sujin Philip 2017-05-02 20:11:49 +00:00 committed by Kitware Robot
commit e9898cc5cf
52 changed files with 2652 additions and 774 deletions

@ -34,7 +34,6 @@ set(headers
Bounds.h
CellShape.h
CellTraits.h
ImplicitFunctions.h
ListTag.h
Math.h
Matrix.h

@ -1,450 +0,0 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_ImplicitFunctions_h
#define vtk_m_ImplicitFunctions_h
#include <vtkm/Types.h>
#include <vtkm/Math.h>
#include <vtkm/VectorAnalysis.h>
#include <iostream>
namespace vtkm {
/// \brief Implicit function for a plane
class Plane
{
public:
VTKM_CONT
Plane()
: Origin(FloatDefault(0)),
Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1))
{ }
VTKM_CONT
explicit Plane(const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(FloatDefault(0)),
Normal(normal)
{ }
VTKM_CONT
Plane(const vtkm::Vec<FloatDefault, 3> &origin,
const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(origin), Normal(normal)
{ }
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetOrigin() const
{
return this->Origin;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetNormal() const
{
return this->Normal;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Origin[0]) * this->Normal[0]) +
((y - this->Origin[1]) * this->Normal[1]) +
((z - this->Origin[2]) * this->Normal[2]);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const
{
return this->Normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const
{
return this->Normal;
}
private:
vtkm::Vec<FloatDefault, 3> Origin;
vtkm::Vec<FloatDefault, 3> Normal;
};
/// \brief Implicit function for a sphere
class Sphere
{
public:
VTKM_CONT
Sphere() : Radius(FloatDefault(0.2)), Center(FloatDefault(0))
{ }
VTKM_CONT
explicit Sphere(FloatDefault radius) : Radius(radius), Center(FloatDefault(0))
{ }
VTKM_CONT
Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius)
: Radius(radius), Center(center)
{ }
VTKM_EXEC_CONT
FloatDefault GetRadius() const
{
return this->Radius;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetCenter() const
{
return this->Center;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Center[0]) * (x - this->Center[0]) +
(y - this->Center[1]) * (y - this->Center[1]) +
(z - this->Center[2]) * (z - this->Center[2])) -
(this->Radius * this->Radius);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return FloatDefault(2) * (x - this->Center);
}
private:
FloatDefault Radius;
vtkm::Vec<FloatDefault, 3> Center;
};
/// \brief Implicit function for a box
class Box
{
public:
VTKM_CONT
Box() : MinPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(0), FloatDefault(0), FloatDefault(0))),
MaxPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(1), FloatDefault(1), FloatDefault(1)))
{ }
VTKM_CONT
Box(vtkm::Vec<FloatDefault, 3> minPoint, vtkm::Vec<FloatDefault, 3> maxPoint)
: MinPoint(minPoint), MaxPoint(maxPoint)
{ }
VTKM_CONT
Box(FloatDefault xmin, FloatDefault xmax,
FloatDefault ymin, FloatDefault ymax,
FloatDefault zmin, FloatDefault zmax)
{
MinPoint[0] = xmin; MaxPoint[0] = xmax;
MinPoint[1] = ymin; MaxPoint[1] = ymax;
MinPoint[2] = zmin; MaxPoint[2] = zmax;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetMinPoint() const
{
return this->MinPoint;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetMaxPoint() const
{
return this->MaxPoint;
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
FloatDefault minDistance = vtkm::NegativeInfinity32();
FloatDefault diff, t, dist;
FloatDefault distance = FloatDefault(0.0);
vtkm::IdComponent inside = 1;
for (vtkm::IdComponent d = 0; d < 3; d++)
{
diff = this->MaxPoint[d] - this->MinPoint[d];
if (diff != FloatDefault(0.0))
{
t = (x[d] - this->MinPoint[d]) / diff;
// Outside before the box
if (t < FloatDefault(0.0))
{
inside = 0;
dist = this->MinPoint[d] - x[d];
}
// Outside after the box
else if (t > FloatDefault(1.0))
{
inside = 0;
dist = x[d] - this->MaxPoint[d];
}
else
{
// Inside the box in lower half
if (t <= FloatDefault(0.5))
{
dist = MinPoint[d] - x[d];
}
// Inside the box in upper half
else
{
dist = x[d] - MaxPoint[d];
}
if (dist > minDistance)
{
minDistance = dist;
}
}
}
else
{
dist = vtkm::Abs(x[d] - MinPoint[d]);
if (dist > FloatDefault(0.0))
{
inside = 0;
}
}
if (dist > FloatDefault(0.0))
{
distance += dist*dist;
}
}
distance = vtkm::Sqrt(distance);
if (inside)
{
return minDistance;
}
else
{
return distance;
}
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Value(vtkm::Vec<vtkm::FloatDefault,3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
vtkm::IdComponent minAxis = 0;
FloatDefault dist = 0.0;
FloatDefault minDist = vtkm::Infinity32();
vtkm::Vec<vtkm::IdComponent,3> location;
vtkm::Vec<FloatDefault,3> normal;
vtkm::Vec<FloatDefault,3> inside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> outside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> center((this->MaxPoint[0] + this->MinPoint[0]) * FloatDefault(0.5),
(this->MaxPoint[1] + this->MinPoint[1]) * FloatDefault(0.5),
(this->MaxPoint[2] + this->MinPoint[2]) * FloatDefault(0.5));
// Compute the location of the point with respect to the box
// Point will lie in one of 27 separate regions around or within the box
// Gradient vector is computed differently in each of the regions.
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (x[d] < this->MinPoint[d])
{
// Outside the box low end
location[d] = 0;
outside[d] = -1.0;
}
else if (x[d] > this->MaxPoint[d])
{
// Outside the box high end
location[d] = 2;
outside[d] = 1.0;
}
else
{
location[d] = 1;
if (x[d] <= center[d])
{
// Inside the box low end
dist = x[d] - this->MinPoint[d];
inside[d] = -1.0;
}
else
{
// Inside the box high end
dist = this->MaxPoint[d] - x[d];
inside[d] = 1.0;
}
if (dist < minDist) // dist is negative
{
minDist = dist;
minAxis = d;
}
}
}
vtkm::Id indx = location[0] + 3*location[1] + 9*location[2];
switch (indx)
{
// verts - gradient points away from center point
case 0: case 2: case 6: case 8: case 18: case 20: case 24: case 26:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = x[d] - center[d];
}
vtkm::Normalize(normal);
break;
// edges - gradient points out from axis of cube
case 1: case 3: case 5: case 7:
case 9: case 11: case 15: case 17:
case 19: case 21: case 23: case 25:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (outside[d] != 0.0)
{
normal[d] = x[d] - center[d];
}
else
{
normal[d] = 0.0;
}
}
vtkm::Normalize(normal);
break;
// faces - gradient points perpendicular to face
case 4: case 10: case 12: case 14: case 16: case 22:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = outside[d];
}
break;
// interior - gradient is perpendicular to closest face
case 13:
normal[0] = normal[1] = normal[2] = 0.0;
normal[minAxis] = inside[minAxis];
break;
default:
VTKM_ASSERT(false);
break;
}
return normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
private:
vtkm::Vec<FloatDefault, 3> MinPoint;
vtkm::Vec<FloatDefault, 3> MaxPoint;
};
/// \brief A function object that evaluates the contained implicit function
template <typename ImplicitFunction>
class ImplicitFunctionValue
{
public:
VTKM_CONT
ImplicitFunctionValue()
: Function()
{ }
VTKM_CONT
explicit ImplicitFunctionValue(const ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC_CONT
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Value(x);
}
VTKM_EXEC_CONT
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Value(x, y, z);
}
private:
ImplicitFunction Function;
};
/// \brief A function object that computes the gradient of the contained implicit
/// function and the specified point.
template <typename ImplicitFunction>
class ImplicitFunctionGradient
{
public:
VTKM_CONT
ImplicitFunctionGradient()
: Function()
{ }
VTKM_CONT
explicit ImplicitFunctionGradient(const ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC_CONT
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Gradient(x);
}
VTKM_EXEC_CONT
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Gradient(x, y, z);
}
private:
ImplicitFunction Function;
};
} // namespace vtkm
#endif // vtk_m_ImplicitFunctions_h

@ -25,6 +25,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/worklet/WorkletMapField.h>
@ -48,12 +49,14 @@ const static std::string DIVIDER(40, '-');
enum BenchmarkName {
BLACK_SCHOLES = 1,
MATH = 1 << 1,
FUSED_MATH = 1 << 3,
INTERPOLATE_FIELD = 1 << 4,
FUSED_MATH = 1 << 2,
INTERPOLATE_FIELD = 1 << 3,
IMPLICIT_FUNCTION = 1 << 4,
ALL = BLACK_SCHOLES |
MATH |
FUSED_MATH |
INTERPOLATE_FIELD
INTERPOLATE_FIELD |
IMPLICIT_FUNCTION
};
template<typename T>
@ -268,6 +271,51 @@ public:
}
};
template <typename ImplicitFunction>
class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
EvaluateImplicitFunction(const ImplicitFunction &function)
: Function(function)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function.Value(point);
}
private:
ImplicitFunction Function;
};
template <typename T1, typename T2>
class Evaluate2ImplicitFunctions : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
Evaluate2ImplicitFunctions(const T1 &f1, const T2 &f2)
: Function1(f1), Function2(f2)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function1.Value(point) + this->Function2.Value(point);
}
private:
T1 Function1;
T2 Function2;
};
struct ValueTypes : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>{};
struct InterpValueTypes : vtkm::ListTagBase<vtkm::Float32,
@ -657,6 +705,177 @@ private:
VTKM_MAKE_BENCHMARK(EdgeInterpDynamic, BenchEdgeInterpDynamic);
struct ImplicitFunctionBenchData
{
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> Points;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Result;
vtkm::cont::Sphere Sphere1, Sphere2;
};
static ImplicitFunctionBenchData MakeImplicitFunctionBenchData()
{
vtkm::Id count = ARRAY_SIZE;
vtkm::FloatDefault bounds[6] = { -2.0f, 2.0f, -2.0f, 2.0f, -2.0f, 2.0f };
ImplicitFunctionBenchData data;
data.Points.Allocate(count);
data.Result.Allocate(count);
std::default_random_engine rangen;
std::uniform_real_distribution<vtkm::FloatDefault> distx(bounds[0], bounds[1]);
std::uniform_real_distribution<vtkm::FloatDefault> disty(bounds[2], bounds[3]);
std::uniform_real_distribution<vtkm::FloatDefault> distz(bounds[4], bounds[5]);
auto portal = data.Points.GetPortalControl();
for (vtkm::Id i = 0; i < count; ++i)
{
portal.Set(i, vtkm::make_Vec(distx(rangen), disty(rangen), distz(rangen)));
}
data.Sphere1 = vtkm::cont::Sphere({0.22f, 0.33f, 0.44f}, 0.55f);
data.Sphere2 = vtkm::cont::Sphere({0.22f, 0.33f, 0.11f}, 0.77f);
return data;
}
template<typename Value>
struct BenchImplicitFunction
{
BenchImplicitFunction()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = EvaluateImplicitFunction<vtkm::cont::Sphere>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1);
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function (vtkm::cont::Sphere) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
template<typename Value>
struct BenchDynamicImplicitFunction
{
BenchDynamicImplicitFunction()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = EvaluateImplicitFunction<vtkm::exec::ImplicitFunction>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1.PrepareForExecution(DeviceAdapterTag()));
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function (DynamicImplicitFunction) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
template<typename Value>
struct Bench2ImplicitFunctions
{
Bench2ImplicitFunctions()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = Evaluate2ImplicitFunctions<vtkm::cont::Sphere, vtkm::cont::Sphere>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1, Internal.Sphere2);
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function 2x(vtkm::cont::Sphere) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
template<typename Value>
struct Bench2DynamicImplicitFunctions
{
Bench2DynamicImplicitFunctions()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = Evaluate2ImplicitFunctions<vtkm::exec::ImplicitFunction,
vtkm::exec::ImplicitFunction>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1.PrepareForExecution(DeviceAdapterTag()),
Internal.Sphere2.PrepareForExecution(DeviceAdapterTag()));
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function 2x(DynamicImplicitFunction) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
VTKM_MAKE_BENCHMARK(ImplicitFunction, BenchImplicitFunction);
VTKM_MAKE_BENCHMARK(ImplicitFunctionDynamic, BenchDynamicImplicitFunction);
VTKM_MAKE_BENCHMARK(ImplicitFunction2, Bench2ImplicitFunctions);
VTKM_MAKE_BENCHMARK(ImplicitFunctionDynamic2, Bench2DynamicImplicitFunctions);
public:
@ -687,6 +906,16 @@ public:
VTKM_RUN_BENCHMARK(EdgeInterpDynamic, InterpValueTypes());
}
if (benchmarks & IMPLICIT_FUNCTION) {
using FloatDefaultType = vtkm::ListTagBase<vtkm::FloatDefault>;
std::cout << "\nBenchmarking Implicit Function\n";
VTKM_RUN_BENCHMARK(ImplicitFunction, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunctionDynamic, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunction2, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunctionDynamic2, FloatDefaultType());
}
return 0;
}
};
@ -723,6 +952,10 @@ int main(int argc, char *argv[])
{
benchmarks |= vtkm::benchmarking::INTERPOLATE_FIELD;
}
else if (arg == "implicit_function")
{
benchmarks |= vtkm::benchmarking::IMPLICIT_FUNCTION;
}
else
{
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl;

@ -64,6 +64,7 @@ set(headers
ErrorExecution.h
ErrorInternal.h
Field.h
ImplicitFunction.h
RuntimeDeviceInformation.h
RuntimeDeviceTracker.h
Storage.h
@ -72,11 +73,13 @@ set(headers
StorageListTag.h
Timer.h
TryExecute.h
VirtualObjectCache.h
)
set(header_impls
ArrayHandle.hxx
CellSetStructured.hxx
ImplicitFunction.hxx
StorageBasic.hxx
)
@ -87,6 +90,7 @@ set(sources
CoordinateSystem.cxx
DynamicArrayHandle.cxx
Field.cxx
ImplicitFunction.cxx
internal/SimplePolymorphicContainer.cxx
StorageBasic.cxx
)

@ -1,30 +1,28 @@
//=============================================================================
//
//============================================================================
// 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 2015 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
// Copyright 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//
//=============================================================================
//============================================================================
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/testing/TestingImplicitFunctions.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
namespace vtkm {
namespace cont {
ImplicitFunction::~ImplicitFunction() = default;
int UnitTestImplicitFunctions(int, char *[])
{
return vtkm::cont::testing::Testing::Run(
vtkm::testing::TestingImplicitFunctions<vtkm::cont::DeviceAdapterTagSerial>::Run);
}
} // vtkm::cont

@ -0,0 +1,341 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_ImplicitFunction_h
#define vtk_m_cont_ImplicitFunction_h
#include <vtkm/exec/ImplicitFunction.h>
#include <vtkm/cont/VirtualObjectCache.h>
#include <memory>
namespace vtkm {
namespace cont {
class VTKM_CONT_EXPORT ImplicitFunction
{
public:
virtual ~ImplicitFunction();
template<typename DeviceAdapter>
vtkm::exec::ImplicitFunction PrepareForExecution(DeviceAdapter device) const
{
if (!this->Cache->GetValid())
{
this->SetDefaultDevices();
}
return this->Cache->GetVirtualObject(device);
}
void Modified()
{
this->Cache->SetRefreshFlag(true);
}
protected:
using CacheType = vtkm::cont::VirtualObjectCache<vtkm::exec::ImplicitFunction>;
ImplicitFunction() : Cache(new CacheType)
{
}
ImplicitFunction(ImplicitFunction &&other)
: Cache(std::move(other.Cache))
{
}
ImplicitFunction& operator=(ImplicitFunction &&other)
{
if (this != &other)
{
this->Cache = std::move(other.Cache);
}
return *this;
}
virtual void SetDefaultDevices() const = 0;
std::unique_ptr<CacheType> Cache;
};
template<typename Derived>
class VTKM_ALWAYS_EXPORT ImplicitFunctionImpl : public ImplicitFunction
{
public:
template<typename DeviceAdapterList>
void ResetDevices(DeviceAdapterList devices)
{
this->Cache->Bind(static_cast<const Derived*>(this), devices);
}
protected:
ImplicitFunctionImpl() = default;
ImplicitFunctionImpl(const ImplicitFunctionImpl &) : ImplicitFunction()
{
}
// Cannot default due to a bug in VS2013
ImplicitFunctionImpl(ImplicitFunctionImpl &&other)
: ImplicitFunction(std::move(other))
{
}
ImplicitFunctionImpl& operator=(const ImplicitFunctionImpl &)
{
return *this;
}
// Cannot default due to a bug in VS2013
ImplicitFunctionImpl& operator=(ImplicitFunctionImpl &&other)
{
ImplicitFunction::operator=(std::move(other));
return *this;
}
void SetDefaultDevices() const override
{
this->Cache->Bind(static_cast<const Derived*>(this));
}
};
//============================================================================
// ImplicitFunctions:
//============================================================================
/// \brief Implicit function for a box
class VTKM_ALWAYS_EXPORT Box : public ImplicitFunctionImpl<Box>
{
public:
Box() : MinPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(0), FloatDefault(0), FloatDefault(0))),
MaxPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(1), FloatDefault(1), FloatDefault(1)))
{ }
Box(vtkm::Vec<FloatDefault, 3> minPoint, vtkm::Vec<FloatDefault, 3> maxPoint)
: MinPoint(minPoint), MaxPoint(maxPoint)
{ }
Box(FloatDefault xmin, FloatDefault xmax,
FloatDefault ymin, FloatDefault ymax,
FloatDefault zmin, FloatDefault zmax)
{
MinPoint[0] = xmin; MaxPoint[0] = xmax;
MinPoint[1] = ymin; MaxPoint[1] = ymax;
MinPoint[2] = zmin; MaxPoint[2] = zmax;
}
void SetMinPoint(const vtkm::Vec<FloatDefault, 3> &point)
{
this->MinPoint = point;
this->Modified();
}
void SetMaxPoint(const vtkm::Vec<FloatDefault, 3> &point)
{
this->MaxPoint = point;
this->Modified();
}
const vtkm::Vec<FloatDefault, 3>& GetMinPoint() const
{
return this->MinPoint;
}
const vtkm::Vec<FloatDefault, 3>& GetMaxPoint() const
{
return this->MaxPoint;
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const;
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Value(vtkm::Vec<vtkm::FloatDefault,3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const;
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
private:
vtkm::Vec<FloatDefault, 3> MinPoint;
vtkm::Vec<FloatDefault, 3> MaxPoint;
};
//============================================================================
/// \brief Implicit function for a plane
class VTKM_ALWAYS_EXPORT Plane : public ImplicitFunctionImpl<Plane>
{
public:
Plane()
: Origin(FloatDefault(0)),
Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1))
{ }
explicit Plane(const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(FloatDefault(0)),
Normal(normal)
{ }
Plane(const vtkm::Vec<FloatDefault, 3> &origin,
const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(origin), Normal(normal)
{ }
void SetOrigin(const vtkm::Vec<FloatDefault, 3> &origin)
{
this->Origin = origin;
this->Modified();
}
void SetNormal(const vtkm::Vec<FloatDefault, 3> &normal)
{
this->Normal = normal;
this->Modified();
}
const vtkm::Vec<FloatDefault, 3>& GetOrigin() const
{
return this->Origin;
}
const vtkm::Vec<FloatDefault, 3>& GetNormal() const
{
return this->Normal;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Origin[0]) * this->Normal[0]) +
((y - this->Origin[1]) * this->Normal[1]) +
((z - this->Origin[2]) * this->Normal[2]);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const
{
return this->Normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const
{
return this->Normal;
}
private:
vtkm::Vec<FloatDefault, 3> Origin;
vtkm::Vec<FloatDefault, 3> Normal;
};
//============================================================================
/// \brief Implicit function for a sphere
class VTKM_ALWAYS_EXPORT Sphere : public ImplicitFunctionImpl<Sphere>
{
public:
Sphere() : Radius(FloatDefault(0.2)), Center(FloatDefault(0))
{ }
explicit Sphere(FloatDefault radius) : Radius(radius), Center(FloatDefault(0))
{ }
Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius)
: Radius(radius), Center(center)
{ }
void SetRadius(FloatDefault radius)
{
this->Radius = radius;
this->Modified();
}
void GetCenter(const vtkm::Vec<FloatDefault, 3> &center)
{
this->Center = center;
this->Modified();
}
FloatDefault GetRadius() const
{
return this->Radius;
}
const vtkm::Vec<FloatDefault, 3>& GetCenter() const
{
return this->Center;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Center[0]) * (x - this->Center[0]) +
(y - this->Center[1]) * (y - this->Center[1]) +
(z - this->Center[2]) * (z - this->Center[2])) -
(this->Radius * this->Radius);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return FloatDefault(2) * (x - this->Center);
}
private:
FloatDefault Radius;
vtkm::Vec<FloatDefault, 3> Center;
};
}
} // vtkm::cont
#include <vtkm/cont/ImplicitFunction.hxx>
#endif // vtk_m_cont_ImplicitFunction_h

@ -0,0 +1,204 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/VectorAnalysis.h>
namespace vtkm {
namespace cont {
//============================================================================
VTKM_EXEC_CONT
inline FloatDefault
Box::Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
FloatDefault minDistance = vtkm::NegativeInfinity32();
FloatDefault diff, t, dist;
FloatDefault distance = FloatDefault(0.0);
vtkm::IdComponent inside = 1;
for (vtkm::IdComponent d = 0; d < 3; d++)
{
diff = this->MaxPoint[d] - this->MinPoint[d];
if (diff != FloatDefault(0.0))
{
t = (x[d] - this->MinPoint[d]) / diff;
// Outside before the box
if (t < FloatDefault(0.0))
{
inside = 0;
dist = this->MinPoint[d] - x[d];
}
// Outside after the box
else if (t > FloatDefault(1.0))
{
inside = 0;
dist = x[d] - this->MaxPoint[d];
}
else
{
// Inside the box in lower half
if (t <= FloatDefault(0.5))
{
dist = MinPoint[d] - x[d];
}
// Inside the box in upper half
else
{
dist = x[d] - MaxPoint[d];
}
if (dist > minDistance)
{
minDistance = dist;
}
}
}
else
{
dist = vtkm::Abs(x[d] - MinPoint[d]);
if (dist > FloatDefault(0.0))
{
inside = 0;
}
}
if (dist > FloatDefault(0.0))
{
distance += dist*dist;
}
}
distance = vtkm::Sqrt(distance);
if (inside)
{
return minDistance;
}
else
{
return distance;
}
}
//============================================================================
VTKM_EXEC_CONT
inline vtkm::Vec<FloatDefault, 3>
Box::Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
vtkm::IdComponent minAxis = 0;
FloatDefault dist = 0.0;
FloatDefault minDist = vtkm::Infinity32();
vtkm::Vec<vtkm::IdComponent,3> location;
vtkm::Vec<FloatDefault,3> normal;
vtkm::Vec<FloatDefault,3> inside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> outside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> center((this->MaxPoint[0] + this->MinPoint[0]) * FloatDefault(0.5),
(this->MaxPoint[1] + this->MinPoint[1]) * FloatDefault(0.5),
(this->MaxPoint[2] + this->MinPoint[2]) * FloatDefault(0.5));
// Compute the location of the point with respect to the box
// Point will lie in one of 27 separate regions around or within the box
// Gradient vector is computed differently in each of the regions.
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (x[d] < this->MinPoint[d])
{
// Outside the box low end
location[d] = 0;
outside[d] = -1.0;
}
else if (x[d] > this->MaxPoint[d])
{
// Outside the box high end
location[d] = 2;
outside[d] = 1.0;
}
else
{
location[d] = 1;
if (x[d] <= center[d])
{
// Inside the box low end
dist = x[d] - this->MinPoint[d];
inside[d] = -1.0;
}
else
{
// Inside the box high end
dist = this->MaxPoint[d] - x[d];
inside[d] = 1.0;
}
if (dist < minDist) // dist is negative
{
minDist = dist;
minAxis = d;
}
}
}
vtkm::Id indx = location[0] + 3*location[1] + 9*location[2];
switch (indx)
{
// verts - gradient points away from center point
case 0: case 2: case 6: case 8: case 18: case 20: case 24: case 26:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = x[d] - center[d];
}
vtkm::Normalize(normal);
break;
// edges - gradient points out from axis of cube
case 1: case 3: case 5: case 7:
case 9: case 11: case 15: case 17:
case 19: case 21: case 23: case 25:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (outside[d] != 0.0)
{
normal[d] = x[d] - center[d];
}
else
{
normal[d] = 0.0;
}
}
vtkm::Normalize(normal);
break;
// faces - gradient points perpendicular to face
case 4: case 10: case 12: case 14: case 16: case 22:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = outside[d];
}
break;
// interior - gradient is perpendicular to closest face
case 13:
normal[0] = normal[1] = normal[2] = 0.0;
normal[minAxis] = inside[minAxis];
break;
default:
VTKM_ASSERT(false);
break;
}
return normal;
}
}
} // vtkm::cont

@ -0,0 +1,333 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_VirtualObjectCache_h
#define vtk_m_cont_VirtualObjectCache_h
#include <vtkm/cont/DeviceAdapterListTag.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
#include <array>
#include <type_traits>
#define VTKM_MAX_DEVICE_ADAPTER_ID 8
namespace vtkm {
namespace cont {
/// \brief Implements VTK-m's execution side <em> Virtual Methods </em>
/// functionality.
///
/// The template parameter \c VirtualObject is the class that acts as the
/// interface. Following is a method for implementing such classes:
/// 1. Create a <tt>const void*<\tt> member variable that will hold a
/// reference to the target class.
/// 2. For each virtual-like method:
/// a. Create a typedef for a function with the same signature,
/// except for an extra <tt>const void*<\tt> argument.
/// b. Create a function pointer member variable with the type of the
/// associated typedef from 2a.
/// c. Create an implementation of the method, that calls the associated
/// function pointer with the void pointer to the target class as one of
/// the arguments.
/// 3. Create the following template function:
/// <tt>
/// template<typename TargetClass>
/// VTKM_EXEC void Bind(const TargetClass *deviceTarget);
/// </tt>
/// This function should set the void pointer from 1 to \c deviceTarget,
/// and assign the function pointers from 2b to functions that cast their
/// first argument to <tt>const TargetClass*<\tt> and call the corresponding
/// member function on it.
///
/// Both \c VirtualObject and target class objects should be bitwise copyable.
///
/// \sa vtkm::exec::ImplicitFunction, vtkm::cont::ImplicitFunction
///
template<typename VirtualObject>
class VirtualObjectCache
{
public:
VirtualObjectCache()
: Target(nullptr),
CurrentDevice(VTKM_DEVICE_ADAPTER_UNDEFINED),
DeviceState(nullptr),
RefreshFlag(false)
{
}
~VirtualObjectCache()
{
this->Reset();
}
VirtualObjectCache(const VirtualObjectCache &other)
: Target(other.Target),
Transfers(other.Transfers),
CurrentDevice(VTKM_DEVICE_ADAPTER_UNDEFINED),
DeviceState(nullptr),
RefreshFlag(false)
{
}
VirtualObjectCache& operator=(const VirtualObjectCache &other)
{
if (this != &other)
{
this->Target = other.Target;
this->Transfers = other.Transfers;
this->CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
this->DeviceState = nullptr;
this->RefreshFlag = false;
this->Object = VirtualObject();
}
return *this;
}
VirtualObjectCache(VirtualObjectCache &&other)
: Target(other.Target),
Transfers(other.Transfers),
CurrentDevice(other.CurrentDevice),
DeviceState(other.DeviceState),
RefreshFlag(other.RefreshFlag),
Object(other.Object)
{
other.CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
other.DeviceState = nullptr;
}
VirtualObjectCache& operator=(VirtualObjectCache &&other)
{
if (this != &other)
{
this->Target = other.Target;
this->Transfers = std::move(other.Transfers);
this->CurrentDevice = other.CurrentDevice;
this->DeviceState = other.DeviceState;
this->RefreshFlag = other.RefreshFlag;
this->Object = std::move(other.Object);
other.CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
other.DeviceState = nullptr;
}
return *this;
}
/// Reset to the default constructed state
void Reset()
{
this->ReleaseResources();
this->Target = nullptr;
this->Transfers.fill(TransferInterface());
}
void ReleaseResources()
{
if (this->CurrentDevice > 0)
{
this->GetCurrentTransfer().Cleanup(this->DeviceState);
this->CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
this->DeviceState = nullptr;
this->RefreshFlag = false;
this->Object = VirtualObject();
}
}
/// Get if in a valid state (a target is bound)
bool GetValid() const
{
return this->Target != nullptr;
}
// Set/Get if the cached virtual object should be refreshed to the current
// state of the target
void SetRefreshFlag(bool value)
{
this->RefreshFlag = value;
}
bool GetRefreshFlag() const
{
return this->RefreshFlag;
}
/// Bind to \c target. The lifetime of target is expected to be managed
/// externally, and should be valid for as long as it is bound.
/// Also accepts a list-tag of device adapters where the virtual
/// object may be used (default = \c VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG).
///
template<typename TargetClass,
typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
void Bind(const TargetClass *target,
DeviceAdapterList devices = DeviceAdapterList())
{
this->Reset();
this->Target = target;
vtkm::ListForEach(
CreateTransferInterface<TargetClass>(this->Transfers.data()),
devices);
}
/// Get a \c VirtualObject for \c DeviceAdapter.
/// VirtualObjectCache and VirtualObject are analogous to ArrayHandle and Portal
/// The returned VirtualObject will be invalidated if:
/// 1. A new VirtualObject is requested for a different DeviceAdapter
/// 2. VirtualObjectCache is destroyed
/// 3. Reset or ReleaseResources is called
///
template<typename DeviceAdapter>
VirtualObject GetVirtualObject(DeviceAdapter)
{
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
if (!this->GetValid())
{
throw vtkm::cont::ErrorBadValue("No target object bound");
}
vtkm::cont::DeviceAdapterId deviceId = DeviceInfo::GetId();
if (deviceId < 0 || deviceId >= VTKM_MAX_DEVICE_ADAPTER_ID)
{
std::string msg =
"Device '" + DeviceInfo::GetName() + "' has invalid ID of " +
std::to_string(deviceId) + "(VTKM_MAX_DEVICE_ADAPTER_ID = " +
std::to_string(VTKM_MAX_DEVICE_ADAPTER_ID) + ")";
throw vtkm::cont::ErrorBadType(msg);
}
if (this->CurrentDevice != deviceId)
{
this->ReleaseResources();
std::size_t idx = static_cast<std::size_t>(deviceId);
TransferInterface &transfer = this->Transfers[idx];
if (!TransferInterfaceValid(transfer))
{
std::string msg = DeviceInfo::GetName() +
" was not in the list specified in Bind";
throw vtkm::cont::ErrorBadType(msg);
}
this->CurrentDevice = deviceId;
this->DeviceState = transfer.Create(this->Object, this->Target);
}
else if (this->RefreshFlag)
{
this->GetCurrentTransfer().Update(this->DeviceState, this->Target);
}
this->RefreshFlag = false;
return this->Object;
}
private:
struct TransferInterface
{
using CreateSig = void*(VirtualObject &, const void *);
using UpdateSig = void(void *, const void *);
using CleanupSig = void(void *);
CreateSig *Create = nullptr;
UpdateSig *Update = nullptr;
CleanupSig *Cleanup = nullptr;
};
static bool TransferInterfaceValid(const TransferInterface &t)
{
return t.Create != nullptr;
}
TransferInterface& GetCurrentTransfer()
{
return this->Transfers[static_cast<std::size_t>(this->CurrentDevice)];
}
template<typename TargetClass>
class CreateTransferInterface
{
private:
template<typename DeviceAdapter>
using EnableIfValid =
std::enable_if<vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
template<typename DeviceAdapter>
using EnableIfInvalid =
std::enable_if<!vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
public:
CreateTransferInterface(TransferInterface *transfers)
: Transfers(transfers)
{ }
// Use SFINAE to create entries for valid device adapters only
template<typename DeviceAdapter>
typename EnableIfValid<DeviceAdapter>::type operator()(DeviceAdapter) const
{
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
if (DeviceInfo::GetId() >= 0 &&
DeviceInfo::GetId() < VTKM_MAX_DEVICE_ADAPTER_ID)
{
using TransferImpl =
internal::VirtualObjectTransfer<VirtualObject, TargetClass, DeviceAdapter>;
std::size_t id = static_cast<std::size_t>(DeviceInfo::GetId());
TransferInterface &transfer = this->Transfers[id];
transfer.Create = &TransferImpl::Create;
transfer.Update = &TransferImpl::Update;
transfer.Cleanup = &TransferImpl::Cleanup;
}
else
{
std::string msg =
"Device '" + DeviceInfo::GetName() + "' has invalid ID of " +
std::to_string(DeviceInfo::GetId()) + "(VTKM_MAX_DEVICE_ADAPTER_ID = " +
std::to_string(VTKM_MAX_DEVICE_ADAPTER_ID) + ")";
throw vtkm::cont::ErrorBadType(msg);
}
}
template<typename DeviceAdapter>
typename EnableIfInvalid<DeviceAdapter>::type operator()(DeviceAdapter) const
{ }
private:
TransferInterface *Transfers;
};
const void *Target;
std::array<TransferInterface, VTKM_MAX_DEVICE_ADAPTER_ID> Transfers;
vtkm::cont::DeviceAdapterId CurrentDevice;
void *DeviceState;
bool RefreshFlag;
VirtualObject Object;
};
}
} // vtkm::cont
#undef VTKM_MAX_DEVICE_ADAPTER_ID
#endif // vtk_m_cont_VirtualObjectCache_h

@ -30,6 +30,7 @@
#include <vtkm/cont/cuda/internal/ArrayManagerExecutionCuda.h>
#include <vtkm/cont/cuda/internal/DeviceAdapterAlgorithmCuda.h>
#include <vtkm/cont/cuda/internal/VirtualObjectTransferCuda.h>
#endif
#endif //vtk_m_cont_cuda_DeviceAdapterCuda_h

@ -26,6 +26,7 @@ set(headers
DeviceAdapterTagCuda.h
MakeThrustIterator.h
ThrustExceptionHandler.h
VirtualObjectTransferCuda.h
)
vtkm_declare_headers(CUDA ${headers} TESTABLE ${VTKm_ENABLE_CUDA})

@ -0,0 +1,78 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_VirtualObjectTransferCuda_h
#define vtk_m_cont_cuda_internal_VirtualObjectTransferCuda_h
#include <vtkm/cont/cuda/ErrorCuda.h>
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
namespace vtkm {
namespace cont {
namespace internal {
namespace detail {
template<typename VirtualObject, typename TargetClass>
__global__
void CreateKernel(VirtualObject *object, const TargetClass *target)
{
object->Bind(target);
}
} // detail
template<typename VirtualObject, typename TargetClass>
struct VirtualObjectTransfer<VirtualObject, TargetClass,
vtkm::cont::DeviceAdapterTagCuda>
{
static void* Create(VirtualObject &object, const void *target)
{
TargetClass *cutarget;
VTKM_CUDA_CALL(cudaMalloc(&cutarget, sizeof(TargetClass)));
VTKM_CUDA_CALL(cudaMemcpy(cutarget, target, sizeof(TargetClass), cudaMemcpyHostToDevice));
VirtualObject *cuobject;
VTKM_CUDA_CALL(cudaMalloc(&cuobject, sizeof(VirtualObject)));
detail::CreateKernel<<<1, 1>>>(cuobject, cutarget);
VTKM_CUDA_CHECK_ASYNCHRONOUS_ERROR();
VTKM_CUDA_CALL(cudaMemcpy(&object, cuobject, sizeof(VirtualObject), cudaMemcpyDeviceToHost));
VTKM_CUDA_CALL(cudaFree(cuobject));
return cutarget;
}
static void Update(void *deviceState, const void *target)
{
VTKM_CUDA_CALL(cudaMemcpy(deviceState, target, sizeof(TargetClass), cudaMemcpyHostToDevice));
}
static void Cleanup(void *deviceState)
{
VTKM_CUDA_CALL(cudaFree(deviceState));
}
};
}
}
} // vtkm::cont::internal
#endif // vtk_m_cont_cuda_internal_VirtualObjectTransferCuda_h

@ -25,6 +25,8 @@ set(unit_tests
UnitTestCudaDataSetExplicit.cu
UnitTestCudaDataSetSingleType.cu
UnitTestCudaDeviceAdapter.cu
UnitTestCudaImplicitFunction.cu
UnitTestCudaMath.cu
UnitTestCudaVirtualObjectCache.cu
)
vtkm_unit_tests(CUDA SOURCES ${unit_tests})

@ -0,0 +1,37 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingImplicitFunction.h>
namespace {
void TestImplicitFunctions()
{
vtkm::cont::testing::TestingImplicitFunction testing;
testing.Run(vtkm::cont::DeviceAdapterTagCuda());
}
} // anonymous namespace
int UnitTestCudaImplicitFunction(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestImplicitFunctions);
}

@ -0,0 +1,39 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingVirtualObjectCache.h>
namespace {
void TestVirtualObjectCache()
{
using DeviceAdapterList =
vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagSerial,
vtkm::cont::DeviceAdapterTagCuda>;
vtkm::cont::testing::TestingVirtualObjectCache<DeviceAdapterList>::Run();
}
} // anonymous namespace
int UnitTestCudaVirtualObjectCache(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestVirtualObjectCache);
}

@ -36,6 +36,8 @@ set(headers
IteratorFromArrayPortal.h
SimplePolymorphicContainer.h
StorageError.h
VirtualObjectTransfer.h
VirtualObjectTransferShareWithControl.h
)
vtkm_declare_headers(${headers})

@ -0,0 +1,53 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_internal_VirtualObjectTransfer_h
#define vtk_m_cont_internal_VirtualObjectTransfer_h
namespace vtkm {
namespace cont {
namespace internal {
template <typename VirtualObject, typename TargetClass, typename DeviceAdapter>
struct VirtualObjectTransfer
#ifdef VTKM_DOXYGEN_ONLY
{
/// Takes a void* to host copy of the target object, transfers it to the
/// device, binds it to the VirtualObject, and returns a void* to an internal
/// state structure.
///
static void* Create(VirtualObject &object, const void *hostTarget);
/// Performs cleanup of the device state used to track the VirtualObject on
/// the device.
///
static void Cleanup(void *deviceState);
/// Update the device state with the state of target
static void Update(void *deviceState, const void *target);
}
#endif
;
}
}
} // vtkm::cont::internal
#endif // vtkm_cont_internal_VirtualObjectTransfer_h

@ -0,0 +1,51 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_internal_VirtualObjectTransferShareWithControl_h
#define vtk_m_cont_internal_VirtualObjectTransferShareWithControl_h
namespace vtkm {
namespace cont {
namespace internal {
template<typename VirtualObject, typename TargetClass>
struct VirtualObjectTransferShareWithControl
{
static void* Create(VirtualObject &object, const void *target)
{
static int dummyState = 0;
object.Bind(static_cast<const TargetClass*>(target));
return &dummyState;
}
static void Update(void*, const void*)
{
}
static void Cleanup(void*)
{
}
};
}
}
} // vtkm::cont::internal
#endif // vtk_m_cont_internal_VirtualObjectTransferShareWithControl_h

@ -23,5 +23,6 @@
#include <vtkm/cont/serial/internal/DeviceAdapterTagSerial.h>
#include <vtkm/cont/serial/internal/ArrayManagerExecutionSerial.h>
#include <vtkm/cont/serial/internal/DeviceAdapterAlgorithmSerial.h>
#include <vtkm/cont/serial/internal/VirtualObjectTransferSerial.h>
#endif //vtk_m_cont_serial_DeviceAdapterSerial_h

@ -22,6 +22,7 @@ set(headers
ArrayManagerExecutionSerial.h
DeviceAdapterAlgorithmSerial.h
DeviceAdapterTagSerial.h
VirtualObjectTransferSerial.h
)
vtkm_declare_headers(${headers})

@ -0,0 +1,43 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_serial_internal_VirtualObjectTransferSerial_h
#define vtk_m_cont_serial_internal_VirtualObjectTransferSerial_h
#include <vtkm/cont/serial/internal/DeviceAdapterTagSerial.h>
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
#include <vtkm/cont/internal/VirtualObjectTransferShareWithControl.h>
namespace vtkm {
namespace cont {
namespace internal {
template<typename VirtualObject, typename TargetClass>
struct VirtualObjectTransfer<
VirtualObject, TargetClass, vtkm::cont::DeviceAdapterTagSerial> :
public VirtualObjectTransferShareWithControl<VirtualObject, TargetClass>
{
};
}
}
} // vtkm::cont::internal
#endif // vtk_m_cont_serial_internal_VirtualObjectTransferSerial_h

@ -25,5 +25,7 @@ set(unit_tests
UnitTestSerialDataSetExplicit.cxx
UnitTestSerialDataSetSingleType.cxx
UnitTestSerialDeviceAdapter.cxx
UnitTestSerialImplicitFunction.cxx
UnitTestSerialVirtualObjectCache.cxx
)
vtkm_unit_tests(TBB SOURCES ${unit_tests})

@ -0,0 +1,38 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingImplicitFunction.h>
namespace {
void TestImplicitFunctions()
{
vtkm::cont::testing::TestingImplicitFunction testing;
testing.Run(vtkm::cont::DeviceAdapterTagSerial());
}
} // anonymous namespace
int UnitTestSerialImplicitFunction(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestImplicitFunctions);
}

@ -0,0 +1,37 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingVirtualObjectCache.h>
namespace {
void TestVirtualObjectCache()
{
using DeviceAdapterList = vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagSerial>;
vtkm::cont::testing::TestingVirtualObjectCache<DeviceAdapterList>::Run();
}
} // anonymous namespace
int UnitTestSerialVirtualObjectCache(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestVirtualObjectCache);
}

@ -25,6 +25,7 @@
#ifdef VTKM_ENABLE_TBB
#include <vtkm/cont/tbb/internal/ArrayManagerExecutionTBB.h>
#include <vtkm/cont/tbb/internal/DeviceAdapterAlgorithmTBB.h>
#include <vtkm/cont/tbb/internal/VirtualObjectTransferTBB.h>
#endif
#endif //vtk_m_cont_tbb_DeviceAdapterTBB_h

@ -23,6 +23,7 @@ set(headers
DeviceAdapterAlgorithmTBB.h
DeviceAdapterTagTBB.h
FunctorsTBB.h
VirtualObjectTransferTBB.h
)
if (VTKm_ENABLE_TBB)

@ -0,0 +1,43 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_tbb_internal_VirtualObjectTransferTBB_h
#define vtk_m_cont_tbb_internal_VirtualObjectTransferTBB_h
#include <vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h>
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
#include <vtkm/cont/internal/VirtualObjectTransferShareWithControl.h>
namespace vtkm {
namespace cont {
namespace internal {
template<typename VirtualObject, typename TargetClass>
struct VirtualObjectTransfer<
VirtualObject, TargetClass, vtkm::cont::DeviceAdapterTagTBB> :
public VirtualObjectTransferShareWithControl<VirtualObject, TargetClass>
{
};
}
}
} // vtkm::cont::internal
#endif // vtk_m_cont_tbb_internal_VirtualObjectTransferTBB_h

@ -25,5 +25,7 @@ set(unit_tests
UnitTestTBBDataSetExplicit.cxx
UnitTestTBBDataSetSingleType.cxx
UnitTestTBBDeviceAdapter.cxx
UnitTestTBBImplicitFunction.cxx
UnitTestTBBVirtualObjectCache.cxx
)
vtkm_unit_tests(TBB SOURCES ${unit_tests})

@ -0,0 +1,37 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingImplicitFunction.h>
namespace {
void TestImplicitFunctions()
{
vtkm::cont::testing::TestingImplicitFunction testing;
testing.Run(vtkm::cont::DeviceAdapterTagTBB());
}
} // anonymous namespace
int UnitTestTBBImplicitFunction(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestImplicitFunctions);
}

@ -0,0 +1,39 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingVirtualObjectCache.h>
namespace {
void TestVirtualObjectCache()
{
using DeviceAdapterList =
vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagSerial,
vtkm::cont::DeviceAdapterTagTBB>;
vtkm::cont::testing::TestingVirtualObjectCache<DeviceAdapterList>::Run();
}
} // anonymous namespace
int UnitTestTBBVirtualObjectCache(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestVirtualObjectCache);
}

@ -28,6 +28,8 @@ set(headers
TestingDataSetExplicit.h
TestingDataSetSingleType.h
TestingFancyArrayHandles.h
TestingImplicitFunction.h
TestingVirtualObjectCache.h
)
vtkm_declare_headers(${headers})

@ -38,6 +38,7 @@
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
#include <vtkm/cont/testing/Testing.h>
@ -311,6 +312,59 @@ public:
vtkm::exec::AtomicArray<T,DeviceAdapterTag> AArray;
};
class VirtualObjectTransferKernel
{
public:
struct Interface
{
using FooSig = vtkm::Id (const void*);
template<typename T>
VTKM_EXEC
void Bind(const T *target)
{
this->Target = target;
this->FooPtr = [](const void* t){ return static_cast<const T*>(t)->Foo(); };
}
VTKM_EXEC
vtkm::Id Foo() const
{
return this->FooPtr(this->Target);
}
const void *Target;
FooSig *FooPtr;
};
struct Concrete
{
vtkm::Id Foo() const
{
return this->Value;
}
vtkm::Id Value = 0;
};
VirtualObjectTransferKernel(const Interface &vo, IdArrayHandle &result)
: Virtual(vo), Result(result.PrepareForInPlace(DeviceAdapterTag()))
{ }
VTKM_EXEC
void operator()(vtkm::Id) const
{
this->Result.Set(0, this->Virtual.Foo());
}
VTKM_CONT void SetErrorMessageBuffer(
const vtkm::exec::internal::ErrorMessageBuffer&)
{ }
private:
Interface Virtual;
IdPortalType Result;
};
private:
@ -472,6 +526,41 @@ private:
VTKM_TEST_ASSERT(valid_runtime, "runtime detection failed for device");
}
VTKM_CONT
static void TestVirtualObjectTransfer()
{
using VirtualObject = typename VirtualObjectTransferKernel::Interface;
using TargetType = typename VirtualObjectTransferKernel::Concrete;
using Transfer = vtkm::cont::internal::VirtualObjectTransfer<
VirtualObject, TargetType, DeviceAdapterTag>;
IdArrayHandle result;
result.Allocate(1);
result.GetPortalControl().Set(0, 0);
TargetType target;
target.Value = 5;
VirtualObject vo;
void* state = Transfer::Create(vo, &target);
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing VirtualObjectTransfer" << std::endl;
Algorithm::Schedule(VirtualObjectTransferKernel(vo, result), 1);
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(0) == 5,
"Did not get expected result");
target.Value = 10;
Transfer::Update(state, &target);
Algorithm::Schedule(VirtualObjectTransferKernel(vo, result), 1);
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(0) == 10,
"Did not get expected result");
Transfer::Cleanup(state);
}
static VTKM_CONT void TestAlgorithmSchedule()
{
std::cout << "-------------------------------------------" << std::endl;
@ -2133,6 +2222,7 @@ private:
TestOutOfMemory();
TestTimer();
TestRuntime();
TestVirtualObjectTransfer();
TestAlgorithmSchedule();
TestErrorExecution();

@ -0,0 +1,187 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_TestingImplicitFunction_h
#define vtk_m_cont_testing_TestingImplicitFunction_h
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapterListTag.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/internal/Configure.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <array>
namespace vtkm {
namespace cont {
namespace testing {
namespace implicit_function_detail {
class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
EvaluateImplicitFunction(const vtkm::exec::ImplicitFunction &function)
: Function(function)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function.Value(point);
}
private:
vtkm::exec::ImplicitFunction Function;
};
template <typename DeviceAdapter>
void EvaluateOnCoordinates(vtkm::cont::CoordinateSystem points,
const vtkm::cont::ImplicitFunction &function,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> &values,
DeviceAdapter device)
{
typedef vtkm::worklet::DispatcherMapField<EvaluateImplicitFunction, DeviceAdapter>
EvalDispatcher;
EvaluateImplicitFunction eval(function.PrepareForExecution(device));
EvalDispatcher(eval).Invoke(points, values);
}
template <std::size_t N>
bool TestArrayEqual(const vtkm::cont::ArrayHandle<vtkm::FloatDefault> &result,
const std::array<vtkm::FloatDefault, N> &expected)
{
if (result.GetNumberOfValues() != N)
{
return false;
}
vtkm::cont::ArrayHandle<vtkm::FloatDefault>::PortalConstControl portal =
result.GetPortalConstControl();
for (std::size_t i = 0; i < N; ++i)
{
if (!test_equal(portal.Get(static_cast<vtkm::Id>(i)), expected[i]))
{
return false;
}
}
return true;
}
} // anonymous namespace
class TestingImplicitFunction
{
public:
TestingImplicitFunction()
: Input(vtkm::cont::testing::MakeTestDataSet().Make3DExplicitDataSet2())
{
}
template<typename DeviceAdapter>
void Run(DeviceAdapter device)
{
this->TestSphere(device);
this->TestPlane(device);
this->TestBox(device);
}
private:
template <typename DeviceAdapter>
void TestSphere(DeviceAdapter device)
{
std::cout << "Testing vtkm::cont::Sphere on "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< "\n";
vtkm::cont::Sphere sphere({0.0f, 0.0f, 0.0f}, 1.0f);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), sphere, values, device);
std::array<vtkm::FloatDefault, 8> expected =
{ {-1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 1.0f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected),
"Result does not match expected values");
}
template <typename DeviceAdapter>
void TestPlane(DeviceAdapter device)
{
std::cout << "Testing vtkm::cont::Plane on "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< "\n";
vtkm::cont::Plane plane({0.5f, 0.5f, 0.5f}, {1.0f, 0.0f, 1.0f});
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), plane, values, device);
std::array<vtkm::FloatDefault, 8> expected1 =
{ {-1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected1),
"Result does not match expected values");
plane.SetNormal({-1.0f, 0.0f, -1.0f});
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), plane, values, device);
std::array<vtkm::FloatDefault, 8> expected2 =
{ {1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected2),
"Result does not match expected values");
}
template <typename DeviceAdapter>
void TestBox(DeviceAdapter device)
{
std::cout << "Testing vtkm::cont::Box on "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< "\n";
vtkm::cont::Box box({0.0f, -0.5f, -0.5f}, {1.5f, 1.5f, 0.5f});
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), box, values, device);
std::array<vtkm::FloatDefault, 8> expected =
{ {0.0f, -0.5f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.5f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected),
"Result does not match expected values");
}
vtkm::cont::DataSet Input;
};
}
}
} // vtmk::cont::testing
#endif //vtk_m_cont_testing_TestingImplicitFunction_h

@ -0,0 +1,220 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_TestingVirtualObjectCache_h
#define vtk_m_cont_testing_TestingVirtualObjectCache_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/VirtualObjectCache.h>
#include <vtkm/Types.h>
#define ARRAY_LEN 8
namespace vtkm {
namespace cont {
namespace testing {
namespace virtual_object_detail
{
class Transformer
{
public:
template<typename T>
VTKM_EXEC void Bind(const T *target)
{
this->Concrete = target;
this->Caller =
[](const void *concrete, vtkm::FloatDefault val) {
return static_cast<const T*>(concrete)->operator()(val);
};
}
VTKM_EXEC
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const
{
return this->Caller(this->Concrete, val);
}
private:
using Signature = vtkm::FloatDefault (const void*, vtkm::FloatDefault);
const void *Concrete;
Signature *Caller;
};
struct Square
{
VTKM_EXEC
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const
{
return val * val;
}
};
struct Multiply
{
VTKM_EXEC
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const
{
return val * this->Multiplicand;
}
vtkm::FloatDefault Multiplicand;
};
} // virtual_object_detail
template<typename DeviceAdapterList>
class TestingVirtualObjectCache
{
private:
using FloatArrayHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
using ArrayTransform =
vtkm::cont::ArrayHandleTransform<vtkm::FloatDefault,
FloatArrayHandle,
virtual_object_detail::Transformer>;
using TransformerCache =
vtkm::cont::VirtualObjectCache<virtual_object_detail::Transformer>;
class TestStage1
{
public:
TestStage1(const FloatArrayHandle &input, TransformerCache &manager)
: Input(&input), Manager(&manager)
{ }
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)
{
ArrayTransform transformed(*this->Input, this->Manager->GetVirtualObject(device));
FloatArrayHandle output;
Algorithm::Copy(transformed, output);
auto portal = output.GetPortalConstControl();
for (vtkm::Id i = 0; i < ARRAY_LEN; ++i)
{
VTKM_TEST_ASSERT(portal.Get(i) == FloatDefault(i*i),
"\tIncorrect result");
}
std::cout << "\tSuccess." << std::endl;
if (n == 0)
{
std::cout << "\tReleaseResources and test again..." << std::endl;
this->Manager->ReleaseResources();
}
}
}
private:
const FloatArrayHandle *Input;
TransformerCache *Manager;
};
class TestStage2
{
public:
TestStage2(const FloatArrayHandle &input, virtual_object_detail::Multiply &mul,
TransformerCache &manager)
: Input(&input), Mul(&mul), Manager(&manager)
{ }
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->Multiplicand = 2;
this->Manager->SetRefreshFlag(true);
for (int n = 0; n < 2; ++n)
{
ArrayTransform transformed(*this->Input, this->Manager->GetVirtualObject(device));
FloatArrayHandle output;
Algorithm::Copy(transformed, output);
auto portal = output.GetPortalConstControl();
for (vtkm::Id i = 0; i < ARRAY_LEN; ++i)
{
VTKM_TEST_ASSERT(portal.Get(i) == FloatDefault(i) * this->Mul->Multiplicand,
"\tIncorrect result");
}
std::cout << "\tSuccess." << std::endl;
if (n == 0)
{
std::cout << "\tUpdate and test again..." << std::endl;
this->Mul->Multiplicand = 3;
this->Manager->SetRefreshFlag(true);
}
}
}
private:
const FloatArrayHandle *Input;
virtual_object_detail::Multiply *Mul;
TransformerCache *Manager;
};
public:
static void Run()
{
vtkm::cont::ArrayHandle<vtkm::FloatDefault> input;
input.Allocate(ARRAY_LEN);
auto portal = input.GetPortalControl();
for (vtkm::Id i = 0; i < ARRAY_LEN; ++i)
{
portal.Set(i, vtkm::FloatDefault(i));
}
TransformerCache manager;
std::cout << "Testing with concrete type 1 (Square)..." << std::endl;
virtual_object_detail::Square sqr;
manager.Bind(&sqr, DeviceAdapterList());
vtkm::ListForEach(TestStage1(input, manager), DeviceAdapterList());
std::cout << "Reset..." << std::endl;
manager.Reset();
std::cout << "Testing with concrete type 2 (Multiply)..." << std::endl;
virtual_object_detail::Multiply mul;
manager.Bind(&mul, DeviceAdapterList());
vtkm::ListForEach(TestStage2(input, mul, manager), DeviceAdapterList());
}
};
}
}
} // vtkm::cont::testing
#endif

@ -95,10 +95,16 @@ public:
: Superclass(storage) { }
};
template<typename VirtualObject, typename TargetClass>
struct VirtualObjectTransfer<
VirtualObject, TargetClass, vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral> :
public VirtualObjectTransferShareWithControl<VirtualObject, TargetClass>
{
};
}
}
} // namespace vtkm::cont::testing
} // namespace vtkm::cont::internal
int UnitTestDeviceAdapterAlgorithmGeneral(int, char *[])
{

@ -30,6 +30,7 @@ set(headers
ExecutionObjectBase.h
ExecutionWholeArray.h
FunctorBase.h
ImplicitFunction.h
Jacobian.h
ParametricCoordinates.h
)

@ -0,0 +1,143 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_exec_ImplicitFunction_h
#define vtk_m_exec_ImplicitFunction_h
#include <vtkm/Types.h>
namespace vtkm {
namespace exec {
class VTKM_ALWAYS_EXPORT ImplicitFunction
{
public:
ImplicitFunction()
: Function(nullptr), ValueCaller(nullptr), GradientCaller(nullptr)
{ }
VTKM_EXEC
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->ValueCaller(this->Function, x, y, z);
}
VTKM_EXEC
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->ValueCaller(this->Function, x[0], x[1], x[2]);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y,
FloatDefault z) const
{
return this->GradientCaller(this->Function, x, y, z);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->GradientCaller(this->Function, x[0], x[1], x[2]);
}
template<typename T>
VTKM_EXEC
void Bind(const T *function)
{
this->Function = function;
this->ValueCaller =
[](const void *t, FloatDefault x, FloatDefault y, FloatDefault z) {
return static_cast<const T*>(t)->Value(x, y, z);
};
this->GradientCaller =
[](const void *t, FloatDefault x, FloatDefault y, FloatDefault z) {
return static_cast<const T*>(t)->Gradient(x, y, z);
};
}
private:
using ValueCallerSig =
FloatDefault(const void*, FloatDefault, FloatDefault, FloatDefault);
using GradientCallerSig =
vtkm::Vec<FloatDefault, 3>(const void*, FloatDefault, FloatDefault, FloatDefault);
const void *Function;
ValueCallerSig *ValueCaller;
GradientCallerSig *GradientCaller;
};
/// \brief A function object that evaluates the contained implicit function
class VTKM_ALWAYS_EXPORT ImplicitFunctionValue
{
public:
ImplicitFunctionValue() = default;
explicit ImplicitFunctionValue(const vtkm::exec::ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Value(x);
}
VTKM_EXEC
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Value(x, y, z);
}
private:
vtkm::exec::ImplicitFunction Function;
};
/// \brief A function object that computes the gradient of the contained implicit
/// function and the specified point.
class VTKM_ALWAYS_EXPORT ImplicitFunctionGradient
{
public:
ImplicitFunctionGradient() = default;
explicit ImplicitFunctionGradient(const vtkm::exec::ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Gradient(x);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Gradient(x, y, z);
}
private:
vtkm::exec::ImplicitFunction Function;
};
}
} // vtkm::exec
#endif // vtk_m_exec_ImplicitFunction_h

@ -21,7 +21,8 @@
set(headers
CellAverage.h
CleanGrid.h
Clip.h
ClipWithField.h
ClipWithImplicitFunction.h
ContourTreeUniform.h
ExternalFaces.h
FieldMetadata.h
@ -53,7 +54,8 @@ set(headers
set(header_template_sources
CellAverage.hxx
CleanGrid.hxx
Clip.hxx
ClipWithField.h
ClipWithImplicitFunction.hxx
ContourTreeUniform.hxx
ExternalFaces.hxx
FilterCell.hxx

@ -18,8 +18,8 @@
// this software.
//============================================================================
#ifndef vtk_m_filter_Clip_h
#define vtk_m_filter_Clip_h
#ifndef vtk_m_filter_ClipWithField_h
#define vtk_m_filter_ClipWithField_h
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/worklet/Clip.h>
@ -27,11 +27,11 @@
namespace vtkm {
namespace filter {
class Clip : public vtkm::filter::FilterDataSetWithField<Clip>
class ClipWithField : public vtkm::filter::FilterDataSetWithField<ClipWithField>
{
public:
VTKM_CONT
Clip();
ClipWithField();
VTKM_CONT
void SetClipValue(vtkm::Float64 value){ this->ClipValue = value; }
@ -64,7 +64,7 @@ private:
};
template<>
class FilterTraits<Clip>
class FilterTraits<ClipWithField>
{ //currently the Clip filter only works on scalar data.
public:
typedef TypeListTagScalarAll InputFieldTypeList;
@ -75,6 +75,6 @@ public:
} // namespace vtkm::filter
#include <vtkm/filter/Clip.hxx>
#include <vtkm/filter/ClipWithField.hxx>
#endif // vtk_m_filter_Clip_h
#endif // vtk_m_filter_ClipWithField_h

@ -31,8 +31,8 @@ namespace filter {
//-----------------------------------------------------------------------------
inline VTKM_CONT
Clip::Clip():
vtkm::filter::FilterDataSetWithField<Clip>(),
ClipWithField::ClipWithField():
vtkm::filter::FilterDataSetWithField<ClipWithField>(),
ClipValue(0),
Worklet()
{
@ -45,11 +45,12 @@ template<typename T,
typename DerivedPolicy,
typename DeviceAdapter>
inline VTKM_CONT
vtkm::filter::ResultDataSet Clip::DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
vtkm::filter::ResultDataSet ClipWithField::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
{
if(fieldMeta.IsPointField() == false)
{
@ -95,11 +96,12 @@ template<typename T,
typename DerivedPolicy,
typename DeviceAdapter>
inline VTKM_CONT
bool Clip::DoMapField(vtkm::filter::ResultDataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
bool ClipWithField::DoMapField(
vtkm::filter::ResultDataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
if(fieldMeta.IsPointField() == false)
{

@ -0,0 +1,76 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_filter_ClipWithImplicitFunction_h
#define vtk_m_filter_ClipWithImplicitFunction_h
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/Clip.h>
#include <memory>
namespace vtkm {
namespace filter {
class ClipWithImplicitFunction : public vtkm::filter::FilterDataSet<ClipWithImplicitFunction>
{
public:
template <typename ImplicitFunctionType, typename DerivedPolicy>
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType> &func,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
template <typename ImplicitFunctionType>
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType> &func)
{
this->Function = func;
}
std::shared_ptr<vtkm::cont::ImplicitFunction> GetImplicitFunction() const
{
return this->Function;
}
template<typename DerivedPolicy, typename DeviceAdapter>
vtkm::filter::ResultDataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
//Map a new field onto the resulting dataset after running the filter.
//This call is only valid after Execute has been called.
template<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
bool DoMapField(vtkm::filter::ResultDataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
std::shared_ptr<vtkm::cont::ImplicitFunction> Function;
vtkm::worklet::Clip Worklet;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/ClipWithImplicitFunction.hxx>
#endif // vtk_m_filter_ClipWithImplicitFunction_h

@ -0,0 +1,104 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
namespace vtkm {
namespace filter {
//-----------------------------------------------------------------------------
template <typename ImplicitFunctionType, typename DerivedPolicy>
inline
void ClipWithImplicitFunction::SetImplicitFunction(
const std::shared_ptr<ImplicitFunctionType> &func,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
func->ResetDevice(DerivedPolicy::DeviceAdapterList);
this->Function = func;
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy,
typename DeviceAdapter>
inline vtkm::filter::ResultDataSet ClipWithImplicitFunction::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
{
//get the cells and coordinates of the dataset
const vtkm::cont::DynamicCellSet& cells =
input.GetCellSet(this->GetActiveCellSetIndex());
const vtkm::cont::CoordinateSystem& inputCoords =
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex());
vtkm::cont::CellSetExplicit<> outputCellSet =
this->Worklet.Run( vtkm::filter::ApplyPolicy(cells, policy),
*this->Function,
inputCoords,
device
);
// compute output coordinates
vtkm::cont::CoordinateSystem outputCoords;
outputCoords.SetData(this->Worklet.ProcessField(inputCoords, device));
//create the output data
vtkm::cont::DataSet output;
output.AddCellSet( outputCellSet );
output.AddCoordinateSystem( outputCoords );
vtkm::filter::ResultDataSet result(output);
return result;
}
//-----------------------------------------------------------------------------
template<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
inline bool ClipWithImplicitFunction::DoMapField(
vtkm::filter::ResultDataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
if(fieldMeta.IsPointField() == false)
{
//not a point field, we can't map it
return false;
}
vtkm::cont::DynamicArrayHandle output =
this->Worklet.ProcessField( input, device);
//use the same meta data as the input so we get the same field name, etc.
result.GetDataSet().AddField( fieldMeta.AsField(output) );
return true;
}
}
}

@ -21,7 +21,8 @@
set(unit_tests
UnitTestCellAverageFilter.cxx
UnitTestCleanGrid.cxx
UnitTestClipFilter.cxx
UnitTestClipWithFieldFilter.cxx
UnitTestClipWithImplicitFunctionFilter.cxx
UnitTestContourTreeUniformFilter.cxx
UnitTestExternalFacesFilter.cxx
UnitTestFieldMetadata.cxx

@ -18,7 +18,7 @@
// this software.
//============================================================================
#include <vtkm/filter/Clip.h>
#include <vtkm/filter/ClipWithField.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/testing/Testing.h>
@ -67,7 +67,7 @@ void TestClipExplicit()
vtkm::cont::DataSet ds = MakeTestDatasetExplicit();
vtkm::filter::ResultDataSet result;
vtkm::filter::Clip clip;
vtkm::filter::ClipWithField clip;
clip.SetClipValue(0.5);
result = clip.Execute( ds, std::string("scalars"));
@ -110,7 +110,7 @@ void TestClip()
}
int UnitTestClipFilter(int, char *[])
int UnitTestClipWithFieldFilter(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestClip);
}

@ -0,0 +1,112 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/filter/ClipWithImplicitFunction.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
namespace {
typedef vtkm::Vec<vtkm::FloatDefault, 3> Coord3D;
vtkm::cont::DataSet MakeTestDatasetStructured()
{
static const vtkm::Id xdim = 3, ydim = 3;
static const vtkm::Id2 dim(xdim, ydim);
static const vtkm::Id numVerts = xdim * ydim;
vtkm::Float32 scalars[numVerts];
for (vtkm::Id i = 0; i < numVerts; ++i)
{
scalars[i] = 1.0f;
}
scalars[4] = 0.0f;
vtkm::cont::DataSet ds;
vtkm::cont::DataSetBuilderUniform builder;
ds = builder.Create(dim);
vtkm::cont::DataSetFieldAdd fieldAdder;
fieldAdder.AddPointField(ds, "scalars", scalars, numVerts);
return ds;
}
void TestClipStructured()
{
std::cout << "Testing ClipWithImplicitFunction Filter on Structured data"
<< std::endl;
vtkm::cont::DataSet ds = MakeTestDatasetStructured();
vtkm::Vec<vtkm::FloatDefault, 3> center(1, 1, 0);
vtkm::FloatDefault radius(0.5);
auto sphere = std::make_shared<vtkm::cont::Sphere>(center, radius);
vtkm::filter::ResultDataSet result;
vtkm::filter::ClipWithImplicitFunction clip;
clip.SetImplicitFunction(sphere);
result = clip.Execute(ds);
clip.MapFieldOntoOutput(result, ds.GetField("scalars"));
const vtkm::cont::DataSet& outputData = result.GetDataSet();
VTKM_TEST_ASSERT(outputData.GetNumberOfCellSets() == 1,
"Wrong number of cellsets in the output dataset");
VTKM_TEST_ASSERT(outputData.GetNumberOfCoordinateSystems() == 1,
"Wrong number of coordinate systems in the output dataset");
VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 1,
"Wrong number of fields in the output dataset");
VTKM_TEST_ASSERT(outputData.GetCellSet().GetNumberOfCells() == 12,
"Wrong number of cells in the output dataset");
vtkm::cont::DynamicArrayHandle temp = outputData.GetField("scalars").GetData();
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
temp.CopyTo(resultArrayHandle);
VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 13,
"Wrong number of points in the output dataset");
vtkm::Float32 expected[13] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25,
0.25 };
for (int i = 0; i < 13; ++i)
{
VTKM_TEST_ASSERT(
test_equal(resultArrayHandle.GetPortalConstControl().Get(i), expected[i]),
"Wrong result for ClipWithImplicitFunction fliter on sturctured quads data");
}
}
void TestClip()
{
//todo: add more clip tests
TestClipStructured();
}
} // anonymous namespace
int UnitTestClipWithImplicitFunctionFilter(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestClip);
}

@ -20,7 +20,6 @@
set(headers
Testing.h
TestingImplicitFunctions.h
TestingMath.h
OptionParser.h
VecTraitsTests.h
@ -34,7 +33,6 @@ set(unit_tests
UnitTestBounds.cxx
UnitTestCellShape.cxx
UnitTestExceptions.cxx
UnitTestImplicitFunctions.cxx
UnitTestListTag.cxx
UnitTestMath.cxx
UnitTestMatrix.cxx

@ -1,213 +0,0 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_testing_TestingImplicitFunctions_h
#define vtk_m_testing_TestingImplicitFunctions_h
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/Math.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <random>
namespace vtkm {
namespace testing {
namespace {
inline vtkm::FloatDefault GetRandomValue()
{
static std::mt19937 gen;
std::uniform_real_distribution<vtkm::FloatDefault> dist(-7.0, 7.0);
return dist(gen);
}
}
template<typename DeviceAdapter>
struct TestingImplicitFunctions
{
typedef vtkm::Vec<vtkm::FloatDefault, 3> FVec3;
template<typename ImplicitFunction>
class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
EvaluateImplicitFunction(const ImplicitFunction &function)
: Function(function)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function.Value(point);
}
private:
ImplicitFunction Function;
};
static void TestBoxValue()
{
typedef EvaluateImplicitFunction<vtkm::Box> EvalWorklet;
typedef vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapter>
EvalDispatcher;
FVec3 half(vtkm::Abs(GetRandomValue()), vtkm::Abs(GetRandomValue()), vtkm::Abs(GetRandomValue()));
FVec3 minPoint(GetRandomValue(), GetRandomValue(), GetRandomValue());
FVec3 maxPoint(minPoint[0] + 2.f * half[0], minPoint[1] + 2.f * half[1], minPoint[2] + 2.f * half[2]);
vtkm::Box box(minPoint, maxPoint);
FVec3 data[8] = { minPoint,
maxPoint,
minPoint + FVec3(FloatDefault(0), half[1], half[2]),
minPoint + FVec3(half[0], FloatDefault(0), half[2]),
minPoint + FVec3(half[0], half[1], FloatDefault(0)),
minPoint + half,
minPoint - half,
maxPoint + half
};
vtkm::cont::ArrayHandle<FVec3> points = vtkm::cont::make_ArrayHandle(data, 8);
EvalWorklet eval(box);
vtkm::cont::ArrayHandle<FloatDefault> values;
EvalDispatcher(eval).Invoke(points, values);
vtkm::cont::ArrayHandle<FloatDefault>::PortalConstControl portal =
values.GetPortalConstControl();
bool success = test_equal(portal.Get(0), FloatDefault(0.0) ) &&
test_equal(portal.Get(1), FloatDefault(0.0) ) &&
test_equal(portal.Get(2), FloatDefault(0.0) ) &&
test_equal(portal.Get(3), FloatDefault(0.0) ) &&
test_equal(portal.Get(4), FloatDefault(0.0) ) &&
(portal.Get(5) < 0.0) &&
(portal.Get(6) > 0.0) &&
(portal.Get(7) > 0.0);
VTKM_TEST_ASSERT(success, "Box: did not get expected results.");
}
static void TestSphereValue()
{
typedef EvaluateImplicitFunction<vtkm::Sphere> EvalWorklet;
typedef vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapter>
EvalDispatcher;
FVec3 center(GetRandomValue(), GetRandomValue(), GetRandomValue());
FloatDefault radius = vtkm::Abs(GetRandomValue());
vtkm::Sphere sphere(center, radius);
FloatDefault r = radius;
FVec3 cube[8] = { center + FVec3(0, 0, 0),
center + FVec3(r, 0, 0),
center + FVec3(0, r, 0),
center + FVec3(r, r, 0),
center + FVec3(0, 0, r),
center + FVec3(r, 0, r),
center + FVec3(0, r, r),
center + FVec3(r, r, r)
};
vtkm::cont::ArrayHandle<FVec3> points = vtkm::cont::make_ArrayHandle(cube, 8);
EvalWorklet eval(sphere);
vtkm::cont::ArrayHandle<FloatDefault> values;
EvalDispatcher(eval).Invoke(points, values);
vtkm::cont::ArrayHandle<FloatDefault>::PortalConstControl portal =
values.GetPortalConstControl();
bool success = (portal.Get(0) == -(r*r)) &&
test_equal(portal.Get(1), FloatDefault(0.0) ) &&
test_equal(portal.Get(2), FloatDefault(0.0) ) &&
test_equal(portal.Get(4), FloatDefault(0.0) ) &&
(portal.Get(3) > 0.0) &&
(portal.Get(5) > 0.0) &&
(portal.Get(6) > 0.0) &&
(portal.Get(7) > 0.0);
VTKM_TEST_ASSERT(success, "Sphere: did not get expected results.");
}
static void TestPlaneValue()
{
typedef EvaluateImplicitFunction<vtkm::Plane> EvalWorklet;
typedef vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapter>
EvalDispatcher;
FVec3 origin(GetRandomValue(), GetRandomValue(), GetRandomValue());
FVec3 normal(GetRandomValue(), GetRandomValue(), GetRandomValue());
vtkm::Plane plane(origin, normal);
FloatDefault t[] = { -2.0, -1.0, 0.0, 1.0, 2.0 };
vtkm::cont::ArrayHandle<FVec3> points;
points.Allocate(5);
for (int i = 0; i < 5; ++i)
{
points.GetPortalControl().Set(i, origin + (t[i] * normal));
}
EvalWorklet eval(plane);
vtkm::cont::ArrayHandle<FloatDefault> values;
EvalDispatcher(eval).Invoke(points, values);
vtkm::cont::ArrayHandle<FloatDefault>::PortalConstControl portal =
values.GetPortalConstControl();
bool success = (portal.Get(0) < 0.0) &&
(portal.Get(1) < 0.0) &&
test_equal(portal.Get(2), FloatDefault(0.0) ) &&
(portal.Get(3) > 0.0) &&
(portal.Get(4) > 0.0);
VTKM_TEST_ASSERT(success, "Plane: did not get expected results.");
}
static void Run()
{
for (int i = 0; i < 50; ++i)
{
TestSphereValue();
}
for (int i = 0; i < 50; ++i)
{
TestPlaneValue();
}
for (int i = 0; i < 50; ++i)
{
TestBoxValue();
}
}
};
}
} // namespace vtkm::testing
#endif // vtk_m_testing_TestingImplicitFunctions_h

@ -29,8 +29,8 @@
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/exec/FunctorBase.h>
@ -177,22 +177,6 @@ struct EdgeInterpolation
};
VTKM_EXEC_CONT
std::ostream& operator<<(std::ostream &out, const ClipStats &val)
{
return out << std::endl << "{ Cells: " << val.NumberOfCells
<< ", Indices: " << val.NumberOfIndices
<< ", NewPoints: " << val.NumberOfNewPoints << " }";
}
VTKM_EXEC_CONT
std::ostream& operator<<(std::ostream &out, const EdgeInterpolation &val)
{
return out << std::endl << "{ Vertex1: " << val.Vertex1
<< ", Vertex2: " << val.Vertex2
<< ", Weight: " << val.Weight << " }";
}
class Clip
{
public:
@ -529,13 +513,13 @@ public:
return output;
}
template<typename ImplicitFunction, typename DeviceAdapter>
template<typename DeviceAdapter>
class ClipWithImplicitFunction
{
public:
VTKM_CONT
ClipWithImplicitFunction(Clip *clipper, const vtkm::cont::DynamicCellSet &cellSet,
ImplicitFunction function, vtkm::cont::CellSetExplicit<> *result)
const vtkm::exec::ImplicitFunction &function, vtkm::cont::CellSetExplicit<> *result)
: Clipper(clipper), CellSet(&cellSet), Function(function), Result(result)
{ }
@ -543,43 +527,42 @@ public:
VTKM_CONT
void operator()(const ArrayHandleType &handle) const
{
// Evaluate the implicit function on the input coordinates using
// ArrayHandleTransform
vtkm::cont::ArrayHandleTransform<
vtkm::FloatDefault,
ArrayHandleType,
vtkm::ImplicitFunctionValue<ImplicitFunction> > clipScalars(handle,
this->Function);
vtkm::exec::ImplicitFunctionValue> clipScalars(handle, this->Function);
*this->Result = this->Clipper->Run(*this->CellSet,
clipScalars,
0.0,
DeviceAdapter());
// Clip at locations where the implicit function evaluates to 0
*this->Result = this->Clipper->Run(*this->CellSet,
clipScalars,
0.0,
DeviceAdapter());
}
private:
Clip *Clipper;
const vtkm::cont::DynamicCellSet *CellSet;
const vtkm::ImplicitFunctionValue<ImplicitFunction> Function;
const vtkm::exec::ImplicitFunctionValue Function;
vtkm::cont::CellSetExplicit<> *Result;
};
template <typename CellSetList,
typename ImplicitFunction,
typename DeviceAdapter>
vtkm::cont::CellSetExplicit<>
Run(const vtkm::cont::DynamicCellSetBase<CellSetList> &cellSet,
const ImplicitFunction &clipFunction,
const vtkm::cont::ImplicitFunction &clipFunction,
const vtkm::cont::CoordinateSystem &coords,
DeviceAdapter device)
{
(void) device;
vtkm::cont::CellSetExplicit<> output;
ClipWithImplicitFunction<ImplicitFunction,
DeviceAdapter> clip(this,
cellSet,
clipFunction,
&output);
CastAndCall(coords, clip);
ClipWithImplicitFunction<DeviceAdapter> clip(this,
cellSet,
clipFunction.PrepareForExecution(device),
&output);
CastAndCall(coords, clip);
return output;
}

@ -28,7 +28,7 @@
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/cont/ImplicitFunction.h>
namespace vtkm {
namespace worklet {
@ -40,7 +40,6 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Worklet to identify cells within volume of interest
template <typename ImplicitFunction>
class ExtractCellsByVOI : public vtkm::worklet::WorkletMapPointToCell
{
public:
@ -53,7 +52,7 @@ public:
ExtractCellsByVOI() : Function() {}
VTKM_CONT
explicit ExtractCellsByVOI(const ImplicitFunction &function)
explicit ExtractCellsByVOI(const vtkm::exec::ImplicitFunction &function)
: Function(function) {}
template <typename ConnectivityInVec, typename InVecFieldPortalType>
@ -76,7 +75,7 @@ public:
}
private:
ImplicitFunction Function;
vtkm::exec::ImplicitFunction Function;
};
////////////////////////////////////////////////////////////////////////////////////
@ -99,22 +98,20 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Extract cells by implicit function permutes input data
template <typename CellSetType,
typename ImplicitFunction,
typename DeviceAdapter>
vtkm::cont::CellSetPermutation<CellSetType> Run(
const CellSetType &cellSet,
const vtkm::cont::CoordinateSystem &coordinates,
const ImplicitFunction &implicitFunction,
DeviceAdapter)
const vtkm::cont::ImplicitFunction &implicitFunction,
DeviceAdapter device)
{
typedef vtkm::cont::CellSetPermutation<CellSetType> OutputType;
// Worklet output will be a boolean passFlag array
typedef ExtractCellsByVOI<ImplicitFunction> ExtractCellsWorklet;
vtkm::cont::ArrayHandle<bool> passFlags;
ExtractCellsWorklet worklet(implicitFunction);
DispatcherMapTopology<ExtractCellsWorklet, DeviceAdapter> dispatcher(worklet);
ExtractCellsByVOI worklet(implicitFunction.PrepareForExecution(device));
DispatcherMapTopology<ExtractCellsByVOI, DeviceAdapter> dispatcher(worklet);
dispatcher.Invoke(cellSet,
coordinates,
passFlags);

@ -26,7 +26,7 @@
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/cont/ImplicitFunction.h>
namespace vtkm {
namespace worklet {
@ -38,7 +38,6 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Worklet to identify points within volume of interest
template<typename ImplicitFunction>
class ExtractPointsByVOI : public vtkm::worklet::WorkletMapCellToPoint
{
public:
@ -48,7 +47,7 @@ public:
typedef _3 ExecutionSignature(_2);
VTKM_CONT
ExtractPointsByVOI(const ImplicitFunction &function) :
ExtractPointsByVOI(const vtkm::exec::ImplicitFunction &function) :
Function(function) {}
VTKM_EXEC
@ -62,7 +61,7 @@ public:
}
private:
ImplicitFunction Function;
vtkm::exec::ImplicitFunction Function;
};
////////////////////////////////////////////////////////////////////////////////////
@ -90,23 +89,20 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Extract points by implicit function
template <typename CellSetType,
typename ImplicitFunction,
typename DeviceAdapter>
vtkm::cont::CellSetSingleType<> Run(
const CellSetType &cellSet,
const vtkm::cont::CoordinateSystem &coordinates,
const ImplicitFunction &implicitFunction,
DeviceAdapter)
const vtkm::cont::ImplicitFunction &implicitFunction,
DeviceAdapter device)
{
typedef typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
// Worklet output will be a boolean passFlag array
vtkm::cont::ArrayHandle<bool> passFlags;
// Worklet output will be a boolean passFlag array
typedef ExtractPointsByVOI<ImplicitFunction> ExtractPointsWorklet;
ExtractPointsWorklet worklet(implicitFunction);
DispatcherMapTopology<ExtractPointsWorklet, DeviceAdapter> dispatcher(worklet);
ExtractPointsByVOI worklet(implicitFunction.PrepareForExecution(device));
DispatcherMapTopology<ExtractPointsByVOI, DeviceAdapter> dispatcher(worklet);
dispatcher.Invoke(cellSet, coordinates, passFlags);
vtkm::cont::ArrayHandleCounting<vtkm::Id> indices =

@ -30,8 +30,8 @@
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/ImplicitFunctions.h>
#include <vector>
@ -230,7 +230,7 @@ void TestClippingWithImplicitFunction()
{
vtkm::Vec<vtkm::FloatDefault, 3> center(1, 1, 0);
vtkm::FloatDefault radius(0.5);
vtkm::Sphere sphere(center, radius);
vtkm::cont::Sphere sphere(center, radius);
vtkm::cont::DataSet ds = MakeTestDatasetStructured();

@ -95,7 +95,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(0.5f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(2.0f, 2.0f, 2.0f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output data set with cell set containing extracted cells and all points
vtkm::worklet::ExtractGeometry extractGeometry;
@ -215,7 +215,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(1.0f, 1.0f, 1.0f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(3.0f, 3.0f, 3.0f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractGeometry extractGeometry;
@ -255,7 +255,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
vtkm::FloatDefault radius(1.8f);
vtkm::Sphere sphere(center, radius);
vtkm::cont::Sphere sphere(center, radius);
// Output data set with cell set containing extracted cells
vtkm::worklet::ExtractGeometry extractGeometry;

@ -78,7 +78,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(1.f, 1.f, 1.f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(3.f, 3.f, 3.f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
@ -108,7 +108,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
vtkm::FloatDefault radius(1.8f);
vtkm::Sphere sphere(center, radius);
vtkm::cont::Sphere sphere(center, radius);
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
@ -138,7 +138,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(0.f, 0.f, 0.f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(1.f, 1.f, 1.f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;