Avoid using ArrayHandle for message exchange.
Minimizing the need to have complex serialization code in vtkm/cont. This is first step in moving DIY serialization code out of vtkm/cont. We need to move that to filter so we can leverage policy correctly serialize fields.
This commit is contained in:
parent
d3120dc72c
commit
74c07af9d7
@ -46,29 +46,5 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(const vtkm::cont::MultiBl
|
||||
return vtkm::cont::detail::FieldRangeComputeImpl(
|
||||
multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace detail
|
||||
{
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> MergeRanges(const vtkm::cont::ArrayHandle<vtkm::Range>& a,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Range>& b)
|
||||
{
|
||||
const auto num_vals_a = a.GetNumberOfValues();
|
||||
const auto num_vals_b = b.GetNumberOfValues();
|
||||
if (num_vals_b == 0)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
if (num_vals_a == 0)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
vtkm::cont::Algorithm::Transform(a, b, result, vtkm::Add());
|
||||
return result;
|
||||
}
|
||||
} // namespace detail
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -29,10 +29,6 @@ namespace cont
|
||||
namespace detail
|
||||
{
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> MergeRanges(const vtkm::cont::ArrayHandle<vtkm::Range>& a,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Range>& b);
|
||||
|
||||
template <typename TypeList, typename StorageList>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
|
||||
const vtkm::cont::DataSet& dataset,
|
||||
@ -63,15 +59,30 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
|
||||
TypeList,
|
||||
StorageList)
|
||||
{
|
||||
return std::accumulate(
|
||||
std::vector<vtkm::Range> result_vector = std::accumulate(
|
||||
multiblock.begin(),
|
||||
multiblock.end(),
|
||||
vtkm::cont::ArrayHandle<vtkm::Range>(),
|
||||
[&](const vtkm::cont::ArrayHandle<vtkm::Range>& val, const vtkm::cont::DataSet& dataset) {
|
||||
auto cur_range =
|
||||
std::vector<vtkm::Range>(),
|
||||
[&](const std::vector<vtkm::Range>& accumulated_value, const vtkm::cont::DataSet& dataset) {
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> block_range =
|
||||
vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList(), StorageList());
|
||||
return vtkm::cont::detail::MergeRanges(val, cur_range);
|
||||
|
||||
std::vector<vtkm::Range> result = accumulated_value;
|
||||
|
||||
// if the current block has more components than we have seen so far,
|
||||
// resize the result to fit all components.
|
||||
result.resize(std::max(result.size(), static_cast<size_t>(block_range.GetNumberOfValues())));
|
||||
|
||||
auto portal = block_range.GetPortalConstControl();
|
||||
std::transform(vtkm::cont::ArrayPortalToIteratorBegin(portal),
|
||||
vtkm::cont::ArrayPortalToIteratorEnd(portal),
|
||||
result.begin(),
|
||||
result.begin(),
|
||||
std::plus<vtkm::Range>());
|
||||
return result;
|
||||
});
|
||||
|
||||
return vtkm::cont::make_ArrayHandle(result_vector, vtkm::CopyFlag::On);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <vtkm/cont/FieldRangeGlobalCompute.h>
|
||||
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/diy/Serialization.h>
|
||||
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
@ -32,6 +31,9 @@ VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
@ -72,25 +74,30 @@ vtkm::cont::ArrayHandle<vtkm::Range> MergeRangesGlobal(
|
||||
return ranges;
|
||||
}
|
||||
|
||||
using ArrayHandleT = vtkm::cont::ArrayHandle<vtkm::Range>;
|
||||
std::vector<vtkm::Range> v_ranges(static_cast<size_t>(ranges.GetNumberOfValues()));
|
||||
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(ranges.GetPortalConstControl()),
|
||||
vtkm::cont::ArrayPortalToIteratorEnd(ranges.GetPortalConstControl()),
|
||||
v_ranges.begin());
|
||||
|
||||
using VectorOfRangesT = std::vector<vtkm::Range>;
|
||||
|
||||
diy::Master master(comm,
|
||||
1,
|
||||
-1,
|
||||
[]() -> void* { return new ArrayHandleT(); },
|
||||
[](void* ptr) { delete static_cast<ArrayHandleT*>(ptr); });
|
||||
[]() -> void* { return new VectorOfRangesT(); },
|
||||
[](void* ptr) { delete static_cast<VectorOfRangesT*>(ptr); });
|
||||
|
||||
diy::ContiguousAssigner assigner(/*num ranks*/ comm.size(), /*global-num-blocks*/ comm.size());
|
||||
diy::RegularDecomposer<diy::DiscreteBounds> decomposer(
|
||||
/*dim*/ 1, diy::interval(0, comm.size() - 1), comm.size());
|
||||
decomposer.decompose(comm.rank(), assigner, master);
|
||||
assert(master.size() == 1); // each rank will have exactly 1 block.
|
||||
*master.block<ArrayHandleT>(0) = ranges;
|
||||
*master.block<VectorOfRangesT>(0) = v_ranges;
|
||||
|
||||
diy::RegularAllReducePartners all_reduce_partners(decomposer, /*k*/ 2);
|
||||
|
||||
auto callback =
|
||||
[](ArrayHandleT* data, const diy::ReduceProxy& srp, const diy::RegularMergePartners&) {
|
||||
[](VectorOfRangesT* data, const diy::ReduceProxy& srp, const diy::RegularMergePartners&) {
|
||||
const auto selfid = srp.gid();
|
||||
// 1. dequeue.
|
||||
std::vector<int> incoming;
|
||||
@ -99,9 +106,17 @@ vtkm::cont::ArrayHandle<vtkm::Range> MergeRangesGlobal(
|
||||
{
|
||||
if (gid != selfid)
|
||||
{
|
||||
ArrayHandleT message;
|
||||
VectorOfRangesT message;
|
||||
srp.dequeue(gid, message);
|
||||
*data = vtkm::cont::detail::MergeRanges(*data, message);
|
||||
|
||||
// if the number of components we've seen so far is less than those
|
||||
// in the received message, resize so we can accommodate all components
|
||||
// in the message. If the message has fewer components, it has no
|
||||
// effect.
|
||||
data->resize(std::max(data->size(), message.size()));
|
||||
|
||||
std::transform(
|
||||
message.begin(), message.end(), data->begin(), data->begin(), std::plus<vtkm::Range>());
|
||||
}
|
||||
}
|
||||
// 2. enqueue
|
||||
@ -117,7 +132,8 @@ vtkm::cont::ArrayHandle<vtkm::Range> MergeRangesGlobal(
|
||||
|
||||
diy::reduce(master, assigner, all_reduce_partners, callback);
|
||||
assert(master.size() == 1); // each rank will have exactly 1 block.
|
||||
return *master.block<ArrayHandleT>(0);
|
||||
|
||||
return vtkm::cont::make_ArrayHandle(*master.block<VectorOfRangesT>(0), vtkm::CopyFlag::On);
|
||||
}
|
||||
} // namespace detail
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user