//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ #ifndef vtk_m_cont_testing_TestingSerialization_h #define vtk_m_cont_testing_TestingSerialization_h #include #include #include #include #include namespace vtkm { namespace cont { namespace testing { namespace serialization { //----------------------------------------------------------------------------- static std::default_random_engine generator; template class UniformRandomValueGenerator { private: using DistributionType = typename std::conditional::value, std::uniform_int_distribution, std::uniform_real_distribution>::type; public: UniformRandomValueGenerator() : Distribution(-127, 127) { } UniformRandomValueGenerator(T min, T max) : Distribution(static_cast(min), static_cast(max)) { } T operator()() { return static_cast(this->Distribution(generator)); } private: DistributionType Distribution; }; template ::HasMultipleComponents> struct BaseScalarType; template struct BaseScalarType { using Type = T; }; template struct BaseScalarType { using Type = typename BaseScalarType::ComponentType>::Type; }; template using BaseScalarType_t = typename BaseScalarType::Type; template struct RandomValue_ { static T Make(UniformRandomValueGenerator& rangen) { return static_cast(rangen()); } }; template struct RandomValue_> { using VecType = vtkm::Vec; static VecType Make(UniformRandomValueGenerator>& rangen) { VecType val{}; for (vtkm::IdComponent i = 0; i < NumComponents; ++i) { val[i] = RandomValue_::Make(rangen); } return val; } }; template struct RandomValue : RandomValue_ { using RandomValue_::Make; static T Make(BaseScalarType_t min, BaseScalarType_t max) { auto rangen = UniformRandomValueGenerator>(min, max); return Make(rangen); } static T Make() { auto rangen = UniformRandomValueGenerator>(); return Make(rangen); } }; template struct RandomArrayHandle { static vtkm::cont::ArrayHandle Make(UniformRandomValueGenerator>& rangen, vtkm::Id length) { vtkm::cont::ArrayHandle a; a.Allocate(length); for (vtkm::Id i = 0; i < length; ++i) { a.GetPortalControl().Set(i, RandomValue::Make(rangen)); } return a; } static vtkm::cont::ArrayHandle Make(vtkm::Id length, BaseScalarType_t min, BaseScalarType_t max) { auto rangen = UniformRandomValueGenerator>(min, max); return Make(rangen, length); } static vtkm::cont::ArrayHandle Make(vtkm::Id length) { auto rangen = UniformRandomValueGenerator>(); return Make(rangen, length); } }; //----------------------------------------------------------------------------- template struct Block { T send; T received; }; template void TestSerialization(const T& obj, const TestEqualFunctor& test) { auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator(); vtkmdiy::Master master(comm); auto nblocks = comm.size(); vtkmdiy::RoundRobinAssigner assigner(comm.size(), nblocks); std::vector gids; assigner.local_gids(comm.rank(), gids); VTKM_ASSERT(gids.size() == 1); auto gid = gids[0]; Block block; block.send = obj; vtkmdiy::Link* link = new vtkmdiy::Link; vtkmdiy::BlockID neighbor; // send neighbor neighbor.gid = (gid < (nblocks - 1)) ? (gid + 1) : 0; neighbor.proc = assigner.rank(neighbor.gid); link->add_neighbor(neighbor); // recv neighbor neighbor.gid = (gid > 0) ? (gid - 1) : (nblocks - 1); neighbor.proc = assigner.rank(neighbor.gid); link->add_neighbor(neighbor); master.add(gid, &block, link); // compute, exchange, compute master.foreach ([](Block* b, const vtkmdiy::Master::ProxyWithLink& cp) { cp.enqueue(cp.link()->target(0), b->send); }); master.exchange(); master.foreach ([](Block* b, const vtkmdiy::Master::ProxyWithLink& cp) { cp.dequeue(cp.link()->target(1).gid, b->received); }); comm.barrier(); test(block.send, block.received); } } } } } // vtkm::cont::testing::serialization #endif // vtk_m_cont_testing_TestingSerialization_h