From 866e1d7d5b08076286a58a8e490b7ce2d2e19382 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Fri, 19 Jul 2019 22:23:54 -0600 Subject: [PATCH] Update comparison for virtual and multiplexer arrays Previously the "dynamic" array was taken from a VariantArrayHandle. However, the VariantArrayHandle will actually cast to a basic array, so the comparison is not particularly fair. Change that to an ArrayHandleVirtual so that it is actually calling through a virtual method. Also make 2 versions of the multiplexer test. The first version has an array that is at the 1st index and the second is at the last index. This tests whether the compiled code has to do lots of actual comparisons to get to the last index. --- benchmarking/BenchmarkFieldAlgorithms.cxx | 233 +++++++++++++++++----- vtkm/ListTag.h | 2 +- 2 files changed, 181 insertions(+), 54 deletions(-) diff --git a/benchmarking/BenchmarkFieldAlgorithms.cxx b/benchmarking/BenchmarkFieldAlgorithms.cxx index f10cb58ef..eb94d497f 100644 --- a/benchmarking/BenchmarkFieldAlgorithms.cxx +++ b/benchmarking/BenchmarkFieldAlgorithms.cxx @@ -13,11 +13,11 @@ #include #include +#include #include #include #include #include -#include #include #include @@ -293,6 +293,40 @@ private: const T2* Function2; }; +struct PassThroughFunctor +{ + template + VTKM_EXEC_CONT T operator()(const T& x) const + { + return x; + } +}; + +template +using ArrayHandlePassThrough = + vtkm::cont::ArrayHandleTransform; + +template +using BMArrayHandleMultiplexer = + vtkm::ListTagApply, + ArrayHandlePassThrough>, + vtkm::cont::ArrayHandleMultiplexer>; + +template +BMArrayHandleMultiplexer make_ArrayHandleMultiplexer0(const ArrayHandleType& array) +{ + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + return BMArrayHandleMultiplexer(array); +} + +template +BMArrayHandleMultiplexer make_ArrayHandleMultiplexerN(const ArrayHandleType& array) +{ + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + return BMArrayHandleMultiplexer(ArrayHandlePassThrough(array)); +} + struct ValueTypes : vtkm::ListTagBase { }; @@ -309,12 +343,6 @@ class BenchmarkFieldAlgorithms using Timer = vtkm::cont::Timer; - using ValueVariantHandle = vtkm::cont::VariantArrayHandleBase; - using InterpVariantHandle = vtkm::cont::VariantArrayHandleBase; - using EdgeIdVariantHandle = vtkm::cont::VariantArrayHandleBase; - - using ValueMultiplexerHandle = vtkm::cont::ArrayHandleMultiplexer; - private: template struct BenchBlackScholes @@ -397,39 +425,66 @@ private: VTKM_CONT vtkm::Float64 operator()() { - ValueVariantHandle dstocks(this->StockPrice); - ValueVariantHandle dstrikes(this->OptionStrike); - ValueVariantHandle doptions(this->OptionYears); - - return this->Run(dstocks, dstrikes, doptions); + return this->Run(vtkm::cont::make_ArrayHandleVirtual(this->StockPrice), + vtkm::cont::make_ArrayHandleVirtual(this->OptionStrike), + vtkm::cont::make_ArrayHandleVirtual(this->OptionYears)); } virtual std::string Type() const { return std::string("Dynamic"); } }; template - struct BenchBlackScholesMultiplexer : public BenchBlackScholes + struct BenchBlackScholesMultiplexer0 : public BenchBlackScholes { VTKM_CONT vtkm::Float64 operator()() { - ValueMultiplexerHandle mstocks( - vtkm::cont::make_ArrayHandleCast(this->StockPrice)); - ValueMultiplexerHandle mstrikes( - vtkm::cont::make_ArrayHandleCast(this->OptionStrike)); - ValueMultiplexerHandle moptions( - vtkm::cont::make_ArrayHandleCast(this->OptionYears)); - - return this->Run(mstocks, mstrikes, moptions); + return this->Run(make_ArrayHandleMultiplexer0(this->StockPrice), + make_ArrayHandleMultiplexer0(this->OptionStrike), + make_ArrayHandleMultiplexer0(this->OptionYears)); } - virtual std::string Type() const { return std::string("Multiplexer"); } + virtual std::string Type() const + { + std::stringstream desc; + desc << "Multiplexer-" + << make_ArrayHandleMultiplexer0(this->StockPrice) + .GetStorage() + .GetArrayHandleVariant() + .GetIndex(); + return desc.str(); + } + }; + + template + struct BenchBlackScholesMultiplexerN : public BenchBlackScholes + { + + VTKM_CONT + vtkm::Float64 operator()() + { + return this->Run(make_ArrayHandleMultiplexerN(this->StockPrice), + make_ArrayHandleMultiplexerN(this->OptionStrike), + make_ArrayHandleMultiplexerN(this->OptionYears)); + } + + virtual std::string Type() const + { + std::stringstream desc; + desc << "Multiplexer-" + << make_ArrayHandleMultiplexerN(this->StockPrice) + .GetStorage() + .GetArrayHandleVariant() + .GetIndex(); + return desc.str(); + } }; VTKM_MAKE_BENCHMARK(BlackScholes, BenchBlackScholes); VTKM_MAKE_BENCHMARK(BlackScholesDynamic, BenchBlackScholesDynamic); - VTKM_MAKE_BENCHMARK(BlackScholesMultiplexer, BenchBlackScholesMultiplexer); + VTKM_MAKE_BENCHMARK(BlackScholesMultiplexer0, BenchBlackScholesMultiplexer0); + VTKM_MAKE_BENCHMARK(BlackScholesMultiplexerN, BenchBlackScholesMultiplexerN); template struct BenchMath @@ -490,13 +545,11 @@ private: VTKM_CONT vtkm::Float64 operator()() { - using MathTypes = vtkm::ListTagBase, vtkm::Vec>; - vtkm::cont::ArrayHandle temp1; vtkm::cont::ArrayHandle temp2; - vtkm::cont::VariantArrayHandleBase dinput(this->InputHandle); - ValueVariantHandle dtemp1(temp1); - ValueVariantHandle dtemp2(temp2); + auto dinput = vtkm::cont::make_ArrayHandleVirtual(this->InputHandle); + auto dtemp1 = vtkm::cont::make_ArrayHandleVirtual(temp1); + auto dtemp2 = vtkm::cont::make_ArrayHandleVirtual(temp2); Timer timer{ DeviceAdapter() }; timer.Start(); @@ -514,7 +567,7 @@ private: }; template - struct BenchMathMultiplexer : public BenchMath + struct BenchMathMultiplexer0 : public BenchMath { VTKM_CONT @@ -522,10 +575,9 @@ private: { vtkm::cont::ArrayHandle temp1; vtkm::cont::ArrayHandle temp2; - vtkm::cont::ArrayHandleMultiplexer> mInput( - vtkm::cont::make_ArrayHandleCast>(this->InputHandle)); - ValueMultiplexerHandle mTemp1(vtkm::cont::make_ArrayHandleCast(temp1)); - ValueMultiplexerHandle mTemp2(vtkm::cont::make_ArrayHandleCast(temp2)); + auto mInput = make_ArrayHandleMultiplexer0(this->InputHandle); + auto mTemp1 = make_ArrayHandleMultiplexer0(temp1); + auto mTemp2 = make_ArrayHandleMultiplexer0(temp2); Timer timer{ DeviceAdapter() }; timer.Start(); @@ -539,12 +591,59 @@ private: return timer.GetElapsedTime(); } - virtual std::string Type() const { return std::string("Multiplexer"); } + virtual std::string Type() const + { + std::stringstream desc; + desc << "Multiplexer-" + << make_ArrayHandleMultiplexer0(this->InputHandle) + .GetStorage() + .GetArrayHandleVariant() + .GetIndex(); + return desc.str(); + } + }; + + template + struct BenchMathMultiplexerN : public BenchMath + { + + VTKM_CONT + vtkm::Float64 operator()() + { + vtkm::cont::ArrayHandle temp1; + vtkm::cont::ArrayHandle temp2; + auto mInput = make_ArrayHandleMultiplexerN(this->InputHandle); + auto mTemp1 = make_ArrayHandleMultiplexerN(temp1); + auto mTemp2 = make_ArrayHandleMultiplexerN(temp2); + + Timer timer{ DeviceAdapter() }; + timer.Start(); + + vtkm::worklet::Invoker invoke(DeviceAdapter{}); + invoke(Mag{}, mInput, mTemp1); + invoke(Sin{}, mTemp1, mTemp2); + invoke(Square{}, mTemp2, mTemp1); + invoke(Cos{}, mTemp1, mTemp2); + + return timer.GetElapsedTime(); + } + + virtual std::string Type() const + { + std::stringstream desc; + desc << "Multiplexer-" + << make_ArrayHandleMultiplexerN(this->InputHandle) + .GetStorage() + .GetArrayHandleVariant() + .GetIndex(); + return desc.str(); + } }; VTKM_MAKE_BENCHMARK(Math, BenchMath); VTKM_MAKE_BENCHMARK(MathDynamic, BenchMathDynamic); - VTKM_MAKE_BENCHMARK(MathMultiplexer, BenchMathMultiplexer); + VTKM_MAKE_BENCHMARK(MathMultiplexer0, BenchMathMultiplexer0); + VTKM_MAKE_BENCHMARK(MathMultiplexerN, BenchMathMultiplexerN); template struct BenchFusedMath @@ -603,35 +702,60 @@ private: VTKM_CONT vtkm::Float64 operator()() { - using MathTypes = vtkm::ListTagBase, vtkm::Vec>; - - vtkm::cont::VariantArrayHandleBase dinput(this->InputHandle); - - return this->Run(dinput); + return this->Run(vtkm::cont::make_ArrayHandleVirtual(this->InputHandle)); } virtual std::string Type() const { return std::string("Dynamic"); } }; template - struct BenchFusedMathMultiplexer : public BenchFusedMath + struct BenchFusedMathMultiplexer0 : public BenchFusedMath { VTKM_CONT vtkm::Float64 operator()() { - vtkm::cont::ArrayHandleMultiplexer> mInput( - vtkm::cont::make_ArrayHandleCast>(this->InputHandle)); - - return this->Run(mInput); + return this->Run(make_ArrayHandleMultiplexer0(this->InputHandle)); } - virtual std::string Type() const { return std::string("Multiplexer"); } + virtual std::string Type() const + { + std::stringstream desc; + desc << "Multiplexer-" + << make_ArrayHandleMultiplexer0(this->InputHandle) + .GetStorage() + .GetArrayHandleVariant() + .GetIndex(); + return desc.str(); + } + }; + + template + struct BenchFusedMathMultiplexerN : public BenchFusedMath + { + + VTKM_CONT + vtkm::Float64 operator()() + { + return this->Run(make_ArrayHandleMultiplexerN(this->InputHandle)); + } + + virtual std::string Type() const + { + std::stringstream desc; + desc << "Multiplexer-" + << make_ArrayHandleMultiplexerN(this->InputHandle) + .GetStorage() + .GetArrayHandleVariant() + .GetIndex(); + return desc.str(); + } }; VTKM_MAKE_BENCHMARK(FusedMath, BenchFusedMath); VTKM_MAKE_BENCHMARK(FusedMathDynamic, BenchFusedMathDynamic); - VTKM_MAKE_BENCHMARK(FusedMathMultiplexer, BenchFusedMathMultiplexer); + VTKM_MAKE_BENCHMARK(FusedMathMultiplexer0, BenchFusedMathMultiplexer0); + VTKM_MAKE_BENCHMARK(FusedMathMultiplexerN, BenchFusedMathMultiplexerN); template struct BenchEdgeInterp @@ -718,9 +842,9 @@ private: VTKM_CONT vtkm::Float64 operator()() { - InterpVariantHandle dfield(this->FieldHandle); - ValueVariantHandle dweight(this->WeightHandle); - EdgeIdVariantHandle dedges(this->EdgePairHandle); + auto dfield = vtkm::cont::make_ArrayHandleVirtual(this->FieldHandle); + auto dweight = vtkm::cont::make_ArrayHandleVirtual(this->WeightHandle); + auto dedges = vtkm::cont::make_ArrayHandleVirtual(this->EdgePairHandle); vtkm::cont::ArrayHandle result; Timer timer{ DeviceAdapter() }; @@ -940,7 +1064,8 @@ public: std::cout << DIVIDER << "\nBenchmarking BlackScholes\n"; VTKM_RUN_BENCHMARK(BlackScholes, ValueTypes(), id); VTKM_RUN_BENCHMARK(BlackScholesDynamic, ValueTypes(), id); - VTKM_RUN_BENCHMARK(BlackScholesMultiplexer, ValueTypes(), id); + VTKM_RUN_BENCHMARK(BlackScholesMultiplexer0, ValueTypes(), id); + VTKM_RUN_BENCHMARK(BlackScholesMultiplexerN, ValueTypes(), id); } if (benchmarks & MATH) @@ -948,7 +1073,8 @@ public: std::cout << DIVIDER << "\nBenchmarking Multiple Math Worklets\n"; VTKM_RUN_BENCHMARK(Math, ValueTypes(), id); VTKM_RUN_BENCHMARK(MathDynamic, ValueTypes(), id); - VTKM_RUN_BENCHMARK(MathMultiplexer, ValueTypes(), id); + VTKM_RUN_BENCHMARK(MathMultiplexer0, ValueTypes(), id); + VTKM_RUN_BENCHMARK(MathMultiplexerN, ValueTypes(), id); } if (benchmarks & FUSED_MATH) @@ -956,7 +1082,8 @@ public: std::cout << DIVIDER << "\nBenchmarking Single Fused Math Worklet\n"; VTKM_RUN_BENCHMARK(FusedMath, ValueTypes(), id); VTKM_RUN_BENCHMARK(FusedMathDynamic, ValueTypes(), id); - VTKM_RUN_BENCHMARK(FusedMathMultiplexer, ValueTypes(), id); + VTKM_RUN_BENCHMARK(FusedMathMultiplexer0, ValueTypes(), id); + VTKM_RUN_BENCHMARK(FusedMathMultiplexerN, ValueTypes(), id); } if (benchmarks & INTERPOLATE_FIELD) diff --git a/vtkm/ListTag.h b/vtkm/ListTag.h index 6f4b3fa91..e3cd8a094 100644 --- a/vtkm/ListTag.h +++ b/vtkm/ListTag.h @@ -84,7 +84,7 @@ struct ListTagApplyImpl, Target> /// template class Target> using ListTagApply = - typename detail::ListTagApplyImpl, Target>; + typename detail::ListTagApplyImpl, Target>::type; /// A special tag for a list that represents holding all potential values ///