Commit 634f523d authored by Haocheng LIU's avatar Haocheng LIU

Merge benchmark executables into a device dependent shared library

VTK-m has been updated to replace old per device benchmark executables with a device
dependent shared library so that it's able to accept a device adapter at runtime through
the "--device=" argument.
parent c27a3366
This diff is collapsed.
This diff is collapsed.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB #ifdef VTKM_ENABLE_TBB
#include <tbb/task_scheduler_init.h> #include <tbb/task_scheduler_init.h>
#endif // TBB #endif // TBB
...@@ -58,7 +58,7 @@ const size_t COL_WIDTH = 32; ...@@ -58,7 +58,7 @@ const size_t COL_WIDTH = 32;
template <typename ValueType, typename DeviceAdapter> template <typename ValueType, typename DeviceAdapter>
struct MeasureCopySpeed struct MeasureCopySpeed
{ {
using Algo = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>; using Algo = vtkm::cont::Algorithm;
vtkm::cont::ArrayHandle<ValueType> Source; vtkm::cont::ArrayHandle<ValueType> Source;
vtkm::cont::ArrayHandle<ValueType> Destination; vtkm::cont::ArrayHandle<ValueType> Destination;
...@@ -106,19 +106,17 @@ void PrintDivider(std::ostream& out) ...@@ -106,19 +106,17 @@ void PrintDivider(std::ostream& out)
out << "|-" << fillStr << "-|-" << fillStr << "-|" << std::endl; out << "|-" << fillStr << "-|-" << fillStr << "-|" << std::endl;
} }
template <typename ValueType> template <typename ValueType, typename DeviceAdapter>
void BenchmarkValueType() void BenchmarkValueType(vtkm::cont::DeviceAdapterId id)
{ {
PrintRow(std::cout, PrintRow(std::cout, vtkm::testing::TypeName<ValueType>::Name(), id.GetName());
vtkm::testing::TypeName<ValueType>::Name(),
vtkm::cont::DeviceAdapterTraits<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::GetName());
PrintDivider(std::cout); PrintDivider(std::cout);
Benchmarker bench(15, 100); Benchmarker bench(15, 100);
for (vtkm::UInt64 size = COPY_SIZE_MIN; size <= COPY_SIZE_MAX; size <<= COPY_SIZE_INC) for (vtkm::UInt64 size = COPY_SIZE_MIN; size <= COPY_SIZE_MAX; size <<= COPY_SIZE_INC)
{ {
MeasureCopySpeed<ValueType, VTKM_DEFAULT_DEVICE_ADAPTER_TAG> functor(size); MeasureCopySpeed<ValueType, DeviceAdapter> functor(size);
bench.Reset(); bench.Reset();
std::string speedStr; std::string speedStr;
...@@ -142,22 +140,58 @@ void BenchmarkValueType() ...@@ -142,22 +140,58 @@ void BenchmarkValueType()
} }
} // end namespace vtkm::benchmarking } // end namespace vtkm::benchmarking
namespace
{
using namespace vtkm::benchmarking;
struct BenchmarkValueTypeFunctor
{
template <typename DeviceAdapter>
bool operator()(DeviceAdapter id)
{
BenchmarkValueType<vtkm::UInt8, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 3>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 4>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::UInt32, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt32, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::UInt64, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt64, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Float32, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::Float32, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Float64, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::Float64, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float32>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float64>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float32>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float64>, DeviceAdapter>(id);
return true;
}
};
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
vtkm::cont::InitLogging(argc, argv); auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
using namespace vtkm::benchmarking;
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB #ifdef VTKM_ENABLE_TBB
int numThreads = tbb::task_scheduler_init::automatic; int numThreads = tbb::task_scheduler_init::automatic;
#endif // TBB #endif // TBB
if (argc == 3) if (config.Arguments.size() == 2)
{ {
if (std::string(argv[1]) == "NumThreads") if (std::string(config.Arguments[0]) == "NumThreads")
{ {
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB #ifdef VTKM_ENABLE_TBB
std::istringstream parse(argv[2]); std::istringstream parse(config.Arguments[1]);
parse >> numThreads; parse >> numThreads;
std::cout << "Selected " << numThreads << " TBB threads." << std::endl; std::cout << "Selected " << numThreads << " TBB threads." << std::endl;
#else #else
...@@ -166,35 +200,11 @@ int main(int argc, char* argv[]) ...@@ -166,35 +200,11 @@ int main(int argc, char* argv[])
} }
} }
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB #ifdef VTKM_ENABLE_TBB
// Must not be destroyed as long as benchmarks are running: // Must not be destroyed as long as benchmarks are running:
tbb::task_scheduler_init init(numThreads); tbb::task_scheduler_init init(numThreads);
#endif // TBB #endif // TBB
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG; BenchmarkValueTypeFunctor functor;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker(); vtkm::cont::TryExecuteOnDevice(config.Device, functor);
tracker.ForceDevice(Device{});
BenchmarkValueType<vtkm::UInt8>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 2>>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 3>>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 4>>();
BenchmarkValueType<vtkm::UInt32>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt32, 2>>();
BenchmarkValueType<vtkm::UInt64>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt64, 2>>();
BenchmarkValueType<vtkm::Float32>();
BenchmarkValueType<vtkm::Vec<vtkm::Float32, 2>>();
BenchmarkValueType<vtkm::Float64>();
BenchmarkValueType<vtkm::Vec<vtkm::Float64, 2>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float32>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float64>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float32>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float64>>();
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -47,7 +47,7 @@ namespace vtkm ...@@ -47,7 +47,7 @@ namespace vtkm
namespace benchmarking namespace benchmarking
{ {
template <typename Precision> template <typename Precision, typename DeviceAdapter>
struct BenchRayTracing struct BenchRayTracing
{ {
vtkm::rendering::raytracing::RayTracer Tracer; vtkm::rendering::raytracing::RayTracer Tracer;
...@@ -118,9 +118,7 @@ struct BenchRayTracing ...@@ -118,9 +118,7 @@ struct BenchRayTracing
VTKM_CONT VTKM_CONT
vtkm::Float64 operator()() vtkm::Float64 operator()()
{ {
vtkm::cont::Timer timer{ DeviceAdapter() };
vtkm::cont::Timer timer;
timer.Start(); timer.Start();
RayCamera.CreateRays(Rays, Coords.GetBounds()); RayCamera.CreateRays(Rays, Coords.GetBounds());
...@@ -147,12 +145,9 @@ VTKM_MAKE_BENCHMARK(RayTracing, BenchRayTracing); ...@@ -147,12 +145,9 @@ VTKM_MAKE_BENCHMARK(RayTracing, BenchRayTracing);
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
vtkm::cont::InitLogging(argc, argv); auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
VTKM_RUN_BENCHMARK(RayTracing, vtkm::ListTagBase<vtkm::Float32>()); VTKM_RUN_BENCHMARK(RayTracing, vtkm::ListTagBase<vtkm::Float32>(), config.Device);
return 0; return 0;
} }
...@@ -135,7 +135,6 @@ struct ValueTypes ...@@ -135,7 +135,6 @@ struct ValueTypes
/// This class runs a series of micro-benchmarks to measure /// This class runs a series of micro-benchmarks to measure
/// performance of different field operations /// performance of different field operations
template <class DeviceAdapterTag>
class BenchmarkTopologyAlgorithms class BenchmarkTopologyAlgorithms
{ {
using StorageTag = vtkm::cont::StorageTagBasic; using StorageTag = vtkm::cont::StorageTagBasic;
...@@ -177,7 +176,7 @@ private: ...@@ -177,7 +176,7 @@ private:
T next() { return distribution(rng); } T next() { return distribution(rng); }
}; };
template <typename Value> template <typename Value, typename DeviceAdapter>
struct BenchCellToPointAvg struct BenchCellToPointAvg
{ {
std::vector<Value> input; std::vector<Value> input;
...@@ -205,11 +204,10 @@ private: ...@@ -205,11 +204,10 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)); cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<Value, StorageTag> result; vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() }; Timer timer{ DeviceAdapter() };
timer.Start(); timer.Start();
vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher; vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, cellSet, result); dispatcher.Invoke(this->InputHandle, cellSet, result);
return timer.GetElapsedTime(); return timer.GetElapsedTime();
...@@ -229,8 +227,8 @@ private: ...@@ -229,8 +227,8 @@ private:
} }
}; };
template <typename Value> template <typename Value, typename DeviceAdapter>
struct BenchCellToPointAvgDynamic : public BenchCellToPointAvg<Value> struct BenchCellToPointAvgDynamic : public BenchCellToPointAvg<Value, DeviceAdapter>
{ {
VTKM_CONT VTKM_CONT
...@@ -242,11 +240,10 @@ private: ...@@ -242,11 +240,10 @@ private:
ValueVariantHandle dinput(this->InputHandle); ValueVariantHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result; vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() }; Timer timer{ DeviceAdapter() };
timer.Start(); timer.Start();
vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher; vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, cellSet, result); dispatcher.Invoke(dinput, cellSet, result);
return timer.GetElapsedTime(); return timer.GetElapsedTime();
...@@ -258,7 +255,7 @@ private: ...@@ -258,7 +255,7 @@ private:
VTKM_MAKE_BENCHMARK(CellToPointAvg, BenchCellToPointAvg); VTKM_MAKE_BENCHMARK(CellToPointAvg, BenchCellToPointAvg);
VTKM_MAKE_BENCHMARK(CellToPointAvgDynamic, BenchCellToPointAvgDynamic); VTKM_MAKE_BENCHMARK(CellToPointAvgDynamic, BenchCellToPointAvgDynamic);
template <typename Value> template <typename Value, typename DeviceAdapter>
struct BenchPointToCellAvg struct BenchPointToCellAvg
{ {
std::vector<Value> input; std::vector<Value> input;
...@@ -286,11 +283,10 @@ private: ...@@ -286,11 +283,10 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)); cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<Value, StorageTag> result; vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() }; Timer timer{ DeviceAdapter() };
timer.Start(); timer.Start();
vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher; vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, cellSet, result); dispatcher.Invoke(this->InputHandle, cellSet, result);
return timer.GetElapsedTime(); return timer.GetElapsedTime();
...@@ -310,8 +306,8 @@ private: ...@@ -310,8 +306,8 @@ private:
} }
}; };
template <typename Value> template <typename Value, typename DeviceAdapter>
struct BenchPointToCellAvgDynamic : public BenchPointToCellAvg<Value> struct BenchPointToCellAvgDynamic : public BenchPointToCellAvg<Value, DeviceAdapter>
{ {
VTKM_CONT VTKM_CONT
...@@ -323,11 +319,10 @@ private: ...@@ -323,11 +319,10 @@ private:
ValueVariantHandle dinput(this->InputHandle); ValueVariantHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result; vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() }; Timer timer{ DeviceAdapter() };
timer.Start(); timer.Start();
vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher; vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, cellSet, result); dispatcher.Invoke(dinput, cellSet, result);
return timer.GetElapsedTime(); return timer.GetElapsedTime();
...@@ -339,7 +334,7 @@ private: ...@@ -339,7 +334,7 @@ private:
VTKM_MAKE_BENCHMARK(PointToCellAvg, BenchPointToCellAvg); VTKM_MAKE_BENCHMARK(PointToCellAvg, BenchPointToCellAvg);
VTKM_MAKE_BENCHMARK(PointToCellAvgDynamic, BenchPointToCellAvgDynamic); VTKM_MAKE_BENCHMARK(PointToCellAvgDynamic, BenchPointToCellAvgDynamic);
template <typename Value> template <typename Value, typename DeviceAdapter>
struct BenchClassification struct BenchClassification
{ {
std::vector<Value> input; std::vector<Value> input;
...@@ -371,12 +366,11 @@ private: ...@@ -371,12 +366,11 @@ private:
ValueVariantHandle dinput(this->InputHandle); ValueVariantHandle dinput(this->InputHandle);
Timer timer{ DeviceAdapterTag() }; Timer timer{ DeviceAdapter() };
timer.Start(); timer.Start();
Classification<Value> worklet(this->IsoValue); Classification<Value> worklet(this->IsoValue);
vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet); vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, cellSet, result); dispatcher.Invoke(dinput, cellSet, result);
return timer.GetElapsedTime(); return timer.GetElapsedTime();
...@@ -396,8 +390,8 @@ private: ...@@ -396,8 +390,8 @@ private:
} }
}; };
template <typename Value> template <typename Value, typename DeviceAdapter>
struct BenchClassificationDynamic : public BenchClassification<Value> struct BenchClassificationDynamic : public BenchClassification<Value, DeviceAdapter>
{ {
VTKM_CONT VTKM_CONT
vtkm::Float64 operator()() vtkm::Float64 operator()()
...@@ -406,12 +400,11 @@ private: ...@@ -406,12 +400,11 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)); cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag> result; vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag> result;
Timer timer{ DeviceAdapterTag() }; Timer timer{ DeviceAdapter() };
timer.Start(); timer.Start();
Classification<Value> worklet(this->IsoValue); Classification<Value> worklet(this->IsoValue);
vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet); vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, cellSet, result); dispatcher.Invoke(this->InputHandle, cellSet, result);
timer.Stop(); timer.Stop();
...@@ -425,29 +418,29 @@ private: ...@@ -425,29 +418,29 @@ private:
VTKM_MAKE_BENCHMARK(ClassificationDynamic, BenchClassificationDynamic); VTKM_MAKE_BENCHMARK(ClassificationDynamic, BenchClassificationDynamic);
public: public:
static VTKM_CONT int Run(int benchmarks) static VTKM_CONT int Run(int benchmarks, vtkm::cont::DeviceAdapterId id)
{ {
std::cout << DIVIDER << "\nRunning Topology Algorithm benchmarks\n"; std::cout << DIVIDER << "\nRunning Topology Algorithm benchmarks\n";
if (benchmarks & CELL_TO_POINT) if (benchmarks & CELL_TO_POINT)
{ {
std::cout << DIVIDER << "\nBenchmarking Cell To Point Average\n"; std::cout << DIVIDER << "\nBenchmarking Cell To Point Average\n";
VTKM_RUN_BENCHMARK(CellToPointAvg, ValueTypes()); VTKM_RUN_BENCHMARK(CellToPointAvg, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CellToPointAvgDynamic, ValueTypes()); VTKM_RUN_BENCHMARK(CellToPointAvgDynamic, ValueTypes(), id);
} }
if (benchmarks & POINT_TO_CELL) if (benchmarks & POINT_TO_CELL)
{ {
std::cout << DIVIDER << "\nBenchmarking Point to Cell Average\n"; std::cout << DIVIDER << "\nBenchmarking Point to Cell Average\n";
VTKM_RUN_BENCHMARK(PointToCellAvg, ValueTypes()); VTKM_RUN_BENCHMARK(PointToCellAvg, ValueTypes(), id);
VTKM_RUN_BENCHMARK(PointToCellAvgDynamic, ValueTypes()); VTKM_RUN_BENCHMARK(PointToCellAvgDynamic, ValueTypes(), id);
} }
if (benchmarks & MC_CLASSIFY) if (benchmarks & MC_CLASSIFY)
{ {
std::cout << DIVIDER << "\nBenchmarking Hex/Voxel MC Classification\n"; std::cout << DIVIDER << "\nBenchmarking Hex/Voxel MC Classification\n";
VTKM_RUN_BENCHMARK(Classification, ValueTypes()); VTKM_RUN_BENCHMARK(Classification, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ClassificationDynamic, ValueTypes()); VTKM_RUN_BENCHMARK(ClassificationDynamic, ValueTypes(), id);
} }
return 0; return 0;
...@@ -460,18 +453,19 @@ public: ...@@ -460,18 +453,19 @@ public:
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
vtkm::cont::InitLogging(argc, argv); auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
int benchmarks = 0; int benchmarks = 0;
if (argc < 2) if (!config.Arguments.size())
{ {
benchmarks = vtkm::benchmarking::ALL; benchmarks = vtkm::benchmarking::ALL;
} }
else else
{ {
for (int i = 1; i < argc; ++i) for (size_t i = 0; i < config.Arguments.size(); ++i)
{ {
std::string arg = argv[i]; std::string arg = config.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) { std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c))); return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
}); });
...@@ -489,16 +483,13 @@ int main(int argc, char* argv[]) ...@@ -489,16 +483,13 @@ int main(int argc, char* argv[])
} }
else else
{ {
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl; std::cout << "Unrecognized benchmark: " << config.Arguments[i] << std::endl;
return 1; return 1;
} }
} }
} }
//now actually execute the benchmarks //now actually execute the benchmarks
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
return vtkm::benchmarking::BenchmarkTopologyAlgorithms<Device>::Run(benchmarks); return vtkm::benchmarking::BenchmarkTopologyAlgorithms::Run(benchmarks, config.Device);
} }
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include <vtkm/ListTag.h> #include <vtkm/ListTag.h>
#include <vtkm/Math.h> #include <vtkm/Math.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/testing/Testing.h> #include <vtkm/cont/testing/Testing.h>
#include <algorithm> #include <algorithm>
...@@ -83,17 +85,18 @@ ...@@ -83,17 +85,18 @@
/* /*
* Use the VTKM_MAKE_BENCHMARK macro to define a maker functor for your benchmark. * Use the VTKM_MAKE_BENCHMARK macro to define a maker functor for your benchmark.
* This is used to allow you to template the benchmark functor on the type being benchmarked * This is used to allow you to template the benchmark functor on the type being benchmarked
* so you can write init code in the constructor. Then the maker will return a constructed * and the device adapter so you can write init code in the constructor. Then the maker will
* instance of your benchmark for the type being benchmarked. The VA_ARGS are used to * return a constructed instance of your benchmark for the type being benchmarked.
* pass any extra arguments needed by your benchmark * The VA_ARGS are used to pass any extra arguments needed by your benchmark
*/ */
#define VTKM_MAKE_BENCHMARK(Name, Bench, ...) \ #define VTKM_MAKE_BENCHMARK(Name, Bench, ...) \
struct MakeBench##Name \ struct MakeBench##Name \
{ \ { \
template <typename Value> \ template <typename Value, typename DeviceAdapter> \
VTKM_CONT Bench<Value> operator()(const Value vtkmNotUsed(v)) const \ VTKM_CONT Bench<Value, DeviceAdapter> operator()(const Value vtkmNotUsed(v), \
DeviceAdapter vtkmNotUsed(id)) const \
{ \ { \
return Bench<Value>(__VA_ARGS__); \ return Bench<Value, DeviceAdapter>(__VA_ARGS__); \
} \ } \
} }
...@@ -102,8 +105,8 @@ ...@@ -102,8 +105,8 @@
* You must have previously defined a maker functor with VTKM_MAKE_BENCHMARK that this * You must have previously defined a maker functor with VTKM_MAKE_BENCHMARK that this
* macro will look for and use * macro will look for and use
*/ */
#define VTKM_RUN_BENCHMARK(Name, Types) \ #define VTKM_RUN_BENCHMARK(Name, Types, Id) \
vtkm::benchmarking::BenchmarkTypes(MakeBench##Name(), (Types)) vtkm::benchmarking::BenchmarkTypes(MakeBench##Name(), (Types), (Id))
namespace vtkm namespace vtkm
{ {
...@@ -223,7 +226,7 @@ vtkm::Float64 MedianAbsDeviation(const std::vector<vtkm::Float64>& samples) ...@@ -223,7 +226,7 @@ vtkm::Float64 MedianAbsDeviation(const std::vector<vtkm::Float64>& samples)
* in seconds, this lets us avoid including any per-run setup time in the benchmark. * in seconds, this lets us avoid including any per-run setup time in the benchmark.
* However any one-time setup should be done in the functor's constructor * However any one-time setup should be done in the functor's constructor
*/ */
class Benchmarker struct Benchmarker
{ {
std::vector<vtkm::Float64> Samples; std::vector<vtkm::Float64> Samples;
std::string BenchmarkName; std::string BenchmarkName;
...@@ -286,11 +289,13 @@ public: ...@@ -286,11 +289,13 @@ public:
<< "\tmax = " << this->Samples.back() << "s\n"; << "\tmax = " << this->Samples.back() << "s\n";
} }
template <typename Functor> template <typename DeviceAdapter, typename MakerFunctor, typename T>
VTKM_CONT void operator()(Functor func) VTKM_CONT bool operator()(DeviceAdapter id, MakerFunctor&& makerFunctor, T t)
{ {
auto func = makerFunctor(t, id);
this->GatherSamples(func); this->GatherSamples(func);
this->PrintSummary(); this->PrintSummary();
return true;
} }
VTKM_CONT const std::vector<vtkm::Float64>& GetSamples() const { return this->Samples; } VTKM_CONT const std::vector<vtkm::Float64>& GetSamples() const { return this->Samples; }
...@@ -315,13 +320,14 @@ public: ...@@ -315,13 +320,14 @@ public:
} }
template <typename T> template <typename T>
VTKM_CONT void operator()(T t) const VTKM_CONT void operator()(T t, vtkm::cont::DeviceAdapterId id) const
{ {
std::cout << "*** " << vtkm::testing::TypeName<T>::Name() << " ***************" << std::endl; std::cout << "*** " << vtkm::testing::TypeName<T>::Name() << " on device " << id.GetName()
<< " ***************" << std::endl;
Benchmarker bench; Benchmarker bench;
try try
{ {
bench(Maker(t)); vtkm::cont::TryExecuteOnDevice(id, bench, Maker, t);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
...@@ -333,9 +339,10 @@ public: ...@@ -333,9 +339,10 @@ public:
}; };
template <class MakerFunctor, class TypeList> template <class MakerFunctor, class TypeList>
VTKM_CONT void BenchmarkTypes(const MakerFunctor& maker, TypeList) VTKM_CONT void BenchmarkTypes(MakerFunctor&& maker, TypeList, vtkm::cont::DeviceAdapterId id)
{ {
vtkm::ListForEach(InternalPrintTypeAndBench<MakerFunctor>(maker), TypeList()); vtkm::ListForEach(
InternalPrintTypeAndBench<MakerFunctor>(std::forward<MakerFunctor>(maker)), TypeList(), id);
} }
} }
} }
......
...@@ -17,43 +17,32 @@ ...@@ -17,43 +17,32 @@
## Laboratory (LANL), the U.S. Government retains certain rights in ## Laboratory (LANL), the U.S. Government retains certain rights in
## this software.