VTK-m  2.0
BoundsMap.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 
11 #ifndef vtk_m_filter_flow_internal_BoundsMap_h
12 #define vtk_m_filter_flow_internal_BoundsMap_h
13 
14 #include <vtkm/Bounds.h>
16 #include <vtkm/cont/DataSet.h>
18 #include <vtkm/cont/Field.h>
20 
21 #include <vtkm/thirdparty/diy/diy.h>
22 
23 #ifdef VTKM_ENABLE_MPI
24 #include <mpi.h>
25 #include <vtkm/thirdparty/diy/mpi-cast.h>
26 #endif
27 
28 #include <vector>
29 
30 namespace vtkm
31 {
32 namespace filter
33 {
34 namespace flow
35 {
36 namespace internal
37 {
38 
39 class VTKM_ALWAYS_EXPORT BoundsMap
40 {
41 public:
42  BoundsMap()
43  : LocalNumBlocks(0)
44  , TotalNumBlocks(0)
45  {
46  }
47 
48  BoundsMap(const vtkm::cont::DataSet& dataSet)
49  : LocalNumBlocks(1)
50  , TotalNumBlocks(0)
51  {
52  this->Init({ dataSet });
53  }
54 
55  BoundsMap(const std::vector<vtkm::cont::DataSet>& dataSets)
56  : LocalNumBlocks(static_cast<vtkm::Id>(dataSets.size()))
57  , TotalNumBlocks(0)
58  {
59  this->Init(dataSets);
60  }
61 
62  BoundsMap(const vtkm::cont::PartitionedDataSet& pds)
63  : LocalNumBlocks(pds.GetNumberOfPartitions())
64  , TotalNumBlocks(0)
65  {
66  this->Init(pds.GetPartitions());
67  }
68 
69  vtkm::Id GetLocalBlockId(vtkm::Id idx) const
70  {
71  VTKM_ASSERT(idx >= 0 && idx < this->LocalNumBlocks);
72  return this->LocalIDs[static_cast<std::size_t>(idx)];
73  }
74 
75  int FindRank(vtkm::Id blockId) const
76  {
77  auto it = this->BlockToRankMap.find(blockId);
78  if (it == this->BlockToRankMap.end())
79  return -1;
80  return it->second;
81  }
82 
83  std::vector<vtkm::Id> FindBlocks(const vtkm::Vec3f& p) const { return this->FindBlocks(p, -1); }
84 
85  std::vector<vtkm::Id> FindBlocks(const vtkm::Vec3f& p,
86  const std::vector<vtkm::Id>& ignoreBlocks) const
87  {
88  vtkm::Id ignoreID = (ignoreBlocks.empty() ? -1 : ignoreBlocks[0]);
89  return FindBlocks(p, ignoreID);
90  }
91 
92  std::vector<vtkm::Id> FindBlocks(const vtkm::Vec3f& p, vtkm::Id ignoreBlock) const
93  {
94  std::vector<vtkm::Id> blockIDs;
95  if (this->GlobalBounds.Contains(p))
96  {
97  vtkm::Id blockId = 0;
98  for (auto& it : this->BlockBounds)
99  {
100  if (blockId != ignoreBlock && it.Contains(p))
101  blockIDs.emplace_back(blockId);
102  blockId++;
103  }
104  }
105 
106  return blockIDs;
107  }
108 
109  vtkm::Id GetTotalNumBlocks() const { return this->TotalNumBlocks; }
110  vtkm::Id GetLocalNumBlocks() const { return this->LocalNumBlocks; }
111 
112 private:
113  void Init(const std::vector<vtkm::cont::DataSet>& dataSets)
114  {
115  vtkm::cont::AssignerPartitionedDataSet assigner(this->LocalNumBlocks);
116  this->TotalNumBlocks = assigner.nblocks();
117  std::vector<int> ids;
118 
119  vtkmdiy::mpi::communicator Comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
120  assigner.local_gids(Comm.rank(), ids);
121  for (const auto& i : ids)
122  this->LocalIDs.emplace_back(static_cast<vtkm::Id>(i));
123 
124  for (vtkm::Id id = 0; id < this->TotalNumBlocks; id++)
125  this->BlockToRankMap[id] = assigner.rank(static_cast<int>(id));
126  this->Build(dataSets);
127  }
128 
129  void Build(const std::vector<vtkm::cont::DataSet>& dataSets)
130  {
131  std::vector<vtkm::Float64> vals(static_cast<std::size_t>(this->TotalNumBlocks * 6), 0);
132  std::vector<vtkm::Float64> vals2(vals.size());
133 
134  for (std::size_t i = 0; i < this->LocalIDs.size(); i++)
135  {
136  const vtkm::cont::DataSet& ds = dataSets[static_cast<std::size_t>(i)];
138 
139  std::size_t idx = static_cast<std::size_t>(this->LocalIDs[i] * 6);
140  vals[idx++] = bounds.X.Min;
141  vals[idx++] = bounds.X.Max;
142  vals[idx++] = bounds.Y.Min;
143  vals[idx++] = bounds.Y.Max;
144  vals[idx++] = bounds.Z.Min;
145  vals[idx++] = bounds.Z.Max;
146  }
147 
148 #ifdef VTKM_ENABLE_MPI
149  vtkmdiy::mpi::communicator Comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
150  MPI_Comm mpiComm = vtkmdiy::mpi::mpi_cast(Comm.handle());
151  MPI_Allreduce(vals.data(), vals2.data(), vals.size(), MPI_DOUBLE, MPI_SUM, mpiComm);
152 #else
153  vals2 = vals;
154 #endif
155 
156  this->BlockBounds.resize(static_cast<std::size_t>(this->TotalNumBlocks));
157  this->GlobalBounds = vtkm::Bounds();
158  std::size_t idx = 0;
159  for (auto& block : this->BlockBounds)
160  {
161  block = vtkm::Bounds(vals2[idx + 0],
162  vals2[idx + 1],
163  vals2[idx + 2],
164  vals2[idx + 3],
165  vals2[idx + 4],
166  vals2[idx + 5]);
167  this->GlobalBounds.Include(block);
168  idx += 6;
169  }
170  }
171 
172  vtkm::Id LocalNumBlocks;
173  std::vector<vtkm::Id> LocalIDs;
174  std::map<vtkm::Id, vtkm::Int32> BlockToRankMap;
175  vtkm::Id TotalNumBlocks;
176  std::vector<vtkm::Bounds> BlockBounds;
177  vtkm::Bounds GlobalBounds;
178 };
179 
180 }
181 }
182 }
183 } // namespace vtkm::filter::flow::internal
184 
185 #endif //vtk_m_filter_flow_internal_BoundsMap_h
AssignerPartitionedDataSet.h
vtkm::cont::EnvironmentTracker::GetCommunicator
static const VTKM_CONT vtkmdiy::mpi::communicator & GetCommunicator()
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::PartitionedDataSet::GetPartitions
const VTKM_CONT std::vector< vtkm::cont::DataSet > & GetPartitions() const
Get an STL vector of all DataSet objects stored in PartitionedDataSet.
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
vtkm::cont::AssignerPartitionedDataSet
Assigner for PartitionedDataSet partitions.
Definition: AssignerPartitionedDataSet.h:49
vtkm::cont::DataSet
Definition: DataSet.h:34
EnvironmentTracker.h
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
Bounds.h
vtkm::cont::DataSet::GetCoordinateSystem
VTKM_CONT vtkm::cont::CoordinateSystem GetCoordinateSystem(vtkm::Id index=0) const
vtkm::cont::CoordinateSystem::GetBounds
VTKM_CONT vtkm::Bounds GetBounds() const
Definition: CoordinateSystem.h:123
vtkm::Bounds
Represent an axis-aligned 3D bounds in space.
Definition: Bounds.h:29
vtkm::Vec< vtkm::FloatDefault, 3 >
vtkm::Range::Min
vtkm::Float64 Min
Definition: Range.h:33
PartitionedDataSet.h
Field.h
vtkm::Bounds::X
vtkm::Range X
Definition: Bounds.h:31
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
DataSet.h
vtkm::cont::PartitionedDataSet
Definition: PartitionedDataSet.h:25