Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_AlgHybridD1-2GL.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef _ZOLTAN2_DISTANCE1_2GHOSTLAYER_HPP_
11 #define _ZOLTAN2_DISTANCE1_2GHOSTLAYER_HPP_
12 
13 #include <vector>
14 #include <unordered_map>
15 #include <iostream>
16 #include <queue>
17 #ifdef _WIN32
18 #include <time.h>
19 #else
20 #include <sys/time.h>
21 #endif
22 
23 #include "Zoltan2_Algorithm.hpp"
24 #include "Zoltan2_GraphModel.hpp"
26 #include "Zoltan2_Util.hpp"
27 #include "Zoltan2_TPLTraits.hpp"
28 #include "Zoltan2_AlltoAll.hpp"
29 #include "Zoltan2_AlgHybrid2GL.hpp"
30 
31 #include "Tpetra_Core.hpp"
32 #include "Teuchos_RCP.hpp"
33 #include "Tpetra_Import.hpp"
34 #include "Tpetra_FEMultiVector.hpp"
35 
36 #include "KokkosKernels_Handle.hpp"
37 #include "KokkosKernels_IOUtils.hpp"
38 #include "KokkosGraph_Distance1Color.hpp"
39 #include "KokkosGraph_Distance1ColorHandle.hpp"
40 
44 
45 
46 namespace Zoltan2{
47 
48 template <typename Adapter>
50  public:
51  using lno_t = typename Adapter::lno_t;
52  using gno_t = typename Adapter::gno_t;
53  using offset_t = typename Adapter::offset_t;
54  using scalar_t = typename Adapter::scalar_t;
56  using map_t = Tpetra::Map<lno_t,gno_t>;
57  using femv_scalar_t = int;
58  using femv_t = Tpetra::FEMultiVector<femv_scalar_t, lno_t, gno_t>;
59  using device_type = typename femv_t::device_type;
60  using execution_space = typename device_type::execution_space;
61  using memory_space = typename device_type::memory_space;
62  using host_exec = typename femv_t::host_view_type::device_type::execution_space;
63  using host_mem = typename femv_t::host_view_type::device_type::memory_space;
64 
65  private:
66 
67  template <class ExecutionSpace, typename MemorySpace>
68  void localColoring(const size_t nVtx,
69  Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> adjs_view,
70  Kokkos::View<offset_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> offset_view,
71  Teuchos::RCP<femv_t> femv,
72  Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace> > vertex_list,
73  size_t vertex_list_size = 0,
74  bool use_vertex_based_coloring=false){
75  using KernelHandle = KokkosKernels::Experimental::KokkosKernelsHandle
76  <offset_t, lno_t, lno_t, ExecutionSpace, MemorySpace, MemorySpace>;
77  using lno_row_view_t = Kokkos::View<offset_t*,Kokkos::Device<ExecutionSpace, MemorySpace>>;
78  using lno_nnz_view_t = Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>>;
79  KernelHandle kh;
80 
81  //pick which KokkosKernels algorithm to use.
82  //this boolean's value is based on max degree.
83  if(use_vertex_based_coloring){
84  kh.create_graph_coloring_handle(KokkosGraph::COLORING_VBBIT);
85  } else {
86  kh.create_graph_coloring_handle(KokkosGraph::COLORING_EB);
87  }
88 
89  //vertex_list_size indicates whether we have provided a list of vertices to recolor
90  //only makes a difference if the algorithm to be used is VBBIT
91  if(vertex_list_size != 0){
92  kh.get_graph_coloring_handle()->set_vertex_list(vertex_list, vertex_list_size);
93  }
94 
95  //the verbose argument should carry through the local coloring
96  kh.set_verbose(this->verbose);
97 
98  //set initial colors to be the colors from the femv
99  auto femvColors = femv->template getLocalView<Kokkos::Device<ExecutionSpace,MemorySpace> >(Tpetra::Access::ReadWrite);
100  auto sv = subview(femvColors, Kokkos::ALL, 0);
101  kh.get_graph_coloring_handle()->set_vertex_colors(sv);
102 
103  //if running verbosely, also report local color timing breakdown
104  kh.get_graph_coloring_handle()->set_tictoc(this->verbose);
105 
106  //call coloring
107  KokkosGraph::Experimental::graph_color_symbolic
108  <KernelHandle, lno_row_view_t, lno_nnz_view_t> (&kh,
109  nVtx,
110  nVtx,
111  offset_view,
112  adjs_view);
113 
114 
115  //output total time and #iterations
116  if(this->verbose){
117  std::cout<<"\nKokkosKernels Coloring: "
118  <<kh.get_graph_coloring_handle()->get_overall_coloring_time()
119  <<" iterations: "
120  <<kh.get_graph_coloring_handle()->get_num_phases()
121  <<"\n\n";
122  }
123  }
124 
125  virtual void colorInterior(const size_t nVtx,
126  Kokkos::View<lno_t*,device_type > adjs_view,
127  Kokkos::View<offset_t*,device_type > offset_view,
128  Teuchos::RCP<femv_t> femv,
129  Kokkos::View<lno_t*, device_type > vertex_list,
130  size_t vertex_list_size = 0,
131  bool recolor=false){
132 
133  this->localColoring<execution_space, memory_space>(nVtx,
134  adjs_view,
135  offset_view,
136  femv,
137  vertex_list,
138  vertex_list_size,
139  recolor);
140  }
141 
142  virtual void colorInterior_serial(const size_t nVtx,
143  typename Kokkos::View<lno_t*, device_type >::HostMirror adjs_view,
144  typename Kokkos::View<offset_t*,device_type >::HostMirror offset_view,
145  Teuchos::RCP<femv_t> femv,
146  typename Kokkos::View<lno_t*, device_type>::HostMirror vertex_list,
147  size_t vertex_list_size = 0,
148  bool recolor=false) {
149  this->localColoring<host_exec, host_mem>(nVtx,
150  adjs_view,
151  offset_view,
152  femv,
153  vertex_list,
154  vertex_list_size,
155  recolor);
156  }
157 
158  public:
159  template <class ExecutionSpace, typename MemorySpace>
160  void detectD1Conflicts(const size_t n_local,
161  Kokkos::View<offset_t*,
162  Kokkos::Device<ExecutionSpace, MemorySpace>> dist_offsets,
163  Kokkos::View<lno_t*,
164  Kokkos::Device<ExecutionSpace, MemorySpace>> dist_adjs,
165  Kokkos::View<int*,
166  Kokkos::Device<ExecutionSpace, MemorySpace>> femv_colors,
167  Kokkos::View<lno_t*,
168  Kokkos::Device<ExecutionSpace, MemorySpace>> boundary_verts_view,
169  Kokkos::View<lno_t*,
170  Kokkos::Device<ExecutionSpace, MemorySpace> > verts_to_recolor_view,
171  Kokkos::View<int*,
172  Kokkos::Device<ExecutionSpace, MemorySpace>,
173  Kokkos::MemoryTraits<Kokkos::Atomic> > verts_to_recolor_size_atomic,
174  Kokkos::View<lno_t*,
175  Kokkos::Device<ExecutionSpace, MemorySpace> > verts_to_send_view,
176  Kokkos::View<size_t*,
177  Kokkos::Device<ExecutionSpace, MemorySpace>,
178  Kokkos::MemoryTraits<Kokkos::Atomic> > verts_to_send_size_atomic,
179  Kokkos::View<size_t*, Kokkos::Device<ExecutionSpace, MemorySpace> > recoloringSize,
180  Kokkos::View<int*,
181  Kokkos::Device<ExecutionSpace, MemorySpace> > rand,
182  Kokkos::View<gno_t*,
183  Kokkos::Device<ExecutionSpace, MemorySpace> > gid,
184  Kokkos::View<gno_t*,
185  Kokkos::Device<ExecutionSpace, MemorySpace> > ghost_degrees,
186  bool recolor_degrees){
187  size_t local_recoloring_size;
188  Kokkos::RangePolicy<ExecutionSpace> policy(n_local,rand.size());
189  Kokkos::parallel_reduce("D1-2GL Conflict Detection",policy, KOKKOS_LAMBDA (const int& i, size_t& recoloring_size){
190  lno_t localIdx = i;
191  int currColor = femv_colors(localIdx);
192  int currDegree = ghost_degrees(i-n_local);
193  for(offset_t j = dist_offsets(i); j < dist_offsets(i+1); j++){
194  int nborColor = femv_colors(dist_adjs(j));
195  int nborDegree = 0;
196  if((size_t)dist_adjs(j) < n_local) nborDegree = dist_offsets(dist_adjs(j)+1) - dist_offsets(dist_adjs(j));
197  else nborDegree = ghost_degrees(dist_adjs(j) - n_local);
198  if(currColor == nborColor ){
199  if(currDegree < nborDegree && recolor_degrees){
200  femv_colors(localIdx) = 0;
201  recoloring_size++;
202  break;
203  }else if(nborDegree < currDegree && recolor_degrees){
204  femv_colors(dist_adjs(j)) = 0;
205  recoloring_size++;
206  }else if(rand(localIdx) > rand(dist_adjs(j))){
207  recoloring_size++;
208  femv_colors(localIdx) = 0;
209  break;
210  }else if(rand(dist_adjs(j)) > rand(localIdx)){
211  recoloring_size++;
212  femv_colors(dist_adjs(j)) = 0;
213  } else {
214  if (gid(localIdx) >= gid(dist_adjs(j))){
215  femv_colors(localIdx) = 0;
216  recoloring_size++;
217  break;
218  } else {
219  femv_colors(dist_adjs(j)) = 0;
220  recoloring_size++;
221  }
222  }
223  }
224  }
225  },local_recoloring_size);
226  Kokkos::deep_copy(recoloringSize, local_recoloring_size);
227  Kokkos::fence();
228  Kokkos::parallel_for("rebuild verts_to_send and verts_to_recolor",
229  Kokkos::RangePolicy<ExecutionSpace>(0,femv_colors.size()),
230  KOKKOS_LAMBDA (const size_t& i){
231  if(femv_colors(i) == 0){
232  if(i < n_local){
233  verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
234  }
235  verts_to_recolor_view(verts_to_recolor_size_atomic(0)++) = i;
236  }
237  });
238  Kokkos::fence();
239 
240  }
241 
242  virtual void detectConflicts(const size_t n_local,
243  Kokkos::View<offset_t*, device_type > dist_offsets_dev,
244  Kokkos::View<lno_t*, device_type > dist_adjs_dev,
245  Kokkos::View<int*,device_type > femv_colors,
246  Kokkos::View<lno_t*, device_type > boundary_verts_view,
247  Kokkos::View<lno_t*,
248  device_type > verts_to_recolor_view,
249  Kokkos::View<int*,
250  device_type,
251  Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_recolor_size_atomic,
252  Kokkos::View<lno_t*,
253  device_type > verts_to_send_view,
254  Kokkos::View<size_t*,
255  device_type,
256  Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_send_size_atomic,
257  Kokkos::View<size_t*, device_type> recoloringSize,
258  Kokkos::View<int*,
259  device_type> rand,
260  Kokkos::View<gno_t*,
261  device_type> gid,
262  Kokkos::View<gno_t*,
263  device_type> ghost_degrees,
264  bool recolor_degrees){
265  this->detectD1Conflicts<execution_space, memory_space>(n_local,
266  dist_offsets_dev,
267  dist_adjs_dev,
268  femv_colors,
269  boundary_verts_view,
270  verts_to_recolor_view,
271  verts_to_recolor_size_atomic,
272  verts_to_send_view,
273  verts_to_send_size_atomic,
274  recoloringSize,
275  rand,
276  gid,
277  ghost_degrees,
278  recolor_degrees);
279  }
280 
281  virtual void detectConflicts_serial(const size_t n_local,
282  typename Kokkos::View<offset_t*, device_type >::HostMirror dist_offsets_host,
283  typename Kokkos::View<lno_t*, device_type >::HostMirror dist_adjs_host,
284  typename Kokkos::View<int*,device_type >::HostMirror femv_colors,
285  typename Kokkos::View<lno_t*, device_type >::HostMirror boundary_verts_view,
286  typename Kokkos::View<lno_t*,device_type>::HostMirror verts_to_recolor,
287  typename Kokkos::View<int*,device_type>::HostMirror verts_to_recolor_size,
288  typename Kokkos::View<lno_t*,device_type>::HostMirror verts_to_send,
289  typename Kokkos::View<size_t*,device_type>::HostMirror verts_to_send_size,
290  typename Kokkos::View<size_t*, device_type>::HostMirror recoloringSize,
291  typename Kokkos::View<int*, device_type>::HostMirror rand,
292  typename Kokkos::View<gno_t*,device_type>::HostMirror gid,
293  typename Kokkos::View<gno_t*,device_type>::HostMirror ghost_degrees,
294  bool recolor_degrees) {
295  this->detectD1Conflicts<host_exec, host_mem >(n_local,
296  dist_offsets_host,
297  dist_adjs_host,
298  femv_colors,
299  boundary_verts_view,
300  verts_to_recolor,
301  verts_to_recolor_size,
302  verts_to_send,
303  verts_to_send_size,
304  recoloringSize,
305  rand,
306  gid,
307  ghost_degrees,
308  recolor_degrees);
309 
310  }
311 
312  virtual void constructBoundary(const size_t n_local,
313  Kokkos::View<offset_t*, device_type> dist_offsets_dev,
314  Kokkos::View<lno_t*, device_type> dist_adjs_dev,
315  typename Kokkos::View<offset_t*, device_type>::HostMirror dist_offsets_host,
316  typename Kokkos::View<lno_t*, device_type>::HostMirror dist_adjs_host,
317  Kokkos::View<lno_t*, device_type>& boundary_verts,
318  Kokkos::View<lno_t*,
319  device_type > verts_to_send_view,
320  Kokkos::View<size_t*,
321  device_type,
322  Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_send_size_atomic){
323 
324  Kokkos::parallel_for("constructBoundary",
325  Kokkos::RangePolicy<execution_space, int>(0,n_local),
326  KOKKOS_LAMBDA(const int& i){
327  for(offset_t j = dist_offsets_dev(i); j < dist_offsets_dev(i+1); j++){
328  if((size_t)dist_adjs_dev(j) >= n_local){
329  verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
330  break;
331  }
332  bool found = false;
333  for(offset_t k = dist_offsets_dev(dist_adjs_dev(j)); k < dist_offsets_dev(dist_adjs_dev(j)+1); k++){
334  if((size_t)dist_adjs_dev(k) >= n_local){
335  verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
336  found = true;
337  break;
338  }
339  }
340  if(found) break;
341  }
342  });
343  Kokkos::fence();
344  }
345 
346 
347  public:
349  const RCP<const base_adapter_t> &adapter_,
350  const RCP<Teuchos::ParameterList> &pl_,
351  const RCP<Environment> &env_,
352  const RCP<const Teuchos::Comm<int> > &comm_)
353  : AlgTwoGhostLayer<Adapter>(adapter_,pl_,env_,comm_){
354  }
355 
356 
357 
358 }; //end class
359 
360 
361 
362 }//end namespace Zoltan2
363 
364 #endif
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Tpetra::FEMultiVector< femv_scalar_t, lno_t, gno_t > femv_t
typename Adapter::gno_t gno_t
virtual void constructBoundary(const size_t n_local, Kokkos::View< offset_t *, device_type > dist_offsets_dev, Kokkos::View< lno_t *, device_type > dist_adjs_dev, typename Kokkos::View< offset_t *, device_type >::HostMirror dist_offsets_host, typename Kokkos::View< lno_t *, device_type >::HostMirror dist_adjs_host, Kokkos::View< lno_t *, device_type > &boundary_verts, Kokkos::View< lno_t *, device_type > verts_to_send_view, Kokkos::View< size_t *, device_type, Kokkos::MemoryTraits< Kokkos::Atomic >> verts_to_send_size_atomic)
typename Adapter::lno_t lno_t
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
typename Adapter::offset_t offset_t
virtual void detectConflicts_serial(const size_t n_local, typename Kokkos::View< offset_t *, device_type >::HostMirror dist_offsets_host, typename Kokkos::View< lno_t *, device_type >::HostMirror dist_adjs_host, typename Kokkos::View< int *, device_type >::HostMirror femv_colors, typename Kokkos::View< lno_t *, device_type >::HostMirror boundary_verts_view, typename Kokkos::View< lno_t *, device_type >::HostMirror verts_to_recolor, typename Kokkos::View< int *, device_type >::HostMirror verts_to_recolor_size, typename Kokkos::View< lno_t *, device_type >::HostMirror verts_to_send, typename Kokkos::View< size_t *, device_type >::HostMirror verts_to_send_size, typename Kokkos::View< size_t *, device_type >::HostMirror recoloringSize, typename Kokkos::View< int *, device_type >::HostMirror rand, typename Kokkos::View< gno_t *, device_type >::HostMirror gid, typename Kokkos::View< gno_t *, device_type >::HostMirror ghost_degrees, bool recolor_degrees)
typename femv_t::host_view_type::device_type::memory_space host_mem
AlgDistance1TwoGhostLayer(const RCP< const base_adapter_t > &adapter_, const RCP< Teuchos::ParameterList > &pl_, const RCP< Environment > &env_, const RCP< const Teuchos::Comm< int > > &comm_)
virtual void detectConflicts(const size_t n_local, Kokkos::View< offset_t *, device_type > dist_offsets_dev, Kokkos::View< lno_t *, device_type > dist_adjs_dev, Kokkos::View< int *, device_type > femv_colors, Kokkos::View< lno_t *, device_type > boundary_verts_view, Kokkos::View< lno_t *, device_type > verts_to_recolor_view, Kokkos::View< int *, device_type, Kokkos::MemoryTraits< Kokkos::Atomic >> verts_to_recolor_size_atomic, Kokkos::View< lno_t *, device_type > verts_to_send_view, Kokkos::View< size_t *, device_type, Kokkos::MemoryTraits< Kokkos::Atomic >> verts_to_send_size_atomic, Kokkos::View< size_t *, device_type > recoloringSize, Kokkos::View< int *, device_type > rand, Kokkos::View< gno_t *, device_type > gid, Kokkos::View< gno_t *, device_type > ghost_degrees, bool recolor_degrees)
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
void detectD1Conflicts(const size_t n_local, Kokkos::View< offset_t *, Kokkos::Device< ExecutionSpace, MemorySpace >> dist_offsets, Kokkos::View< lno_t *, Kokkos::Device< ExecutionSpace, MemorySpace >> dist_adjs, Kokkos::View< int *, Kokkos::Device< ExecutionSpace, MemorySpace >> femv_colors, Kokkos::View< lno_t *, Kokkos::Device< ExecutionSpace, MemorySpace >> boundary_verts_view, Kokkos::View< lno_t *, Kokkos::Device< ExecutionSpace, MemorySpace > > verts_to_recolor_view, Kokkos::View< int *, Kokkos::Device< ExecutionSpace, MemorySpace >, Kokkos::MemoryTraits< Kokkos::Atomic > > verts_to_recolor_size_atomic, Kokkos::View< lno_t *, Kokkos::Device< ExecutionSpace, MemorySpace > > verts_to_send_view, Kokkos::View< size_t *, Kokkos::Device< ExecutionSpace, MemorySpace >, Kokkos::MemoryTraits< Kokkos::Atomic > > verts_to_send_size_atomic, Kokkos::View< size_t *, Kokkos::Device< ExecutionSpace, MemorySpace > > recoloringSize, Kokkos::View< int *, Kokkos::Device< ExecutionSpace, MemorySpace > > rand, Kokkos::View< gno_t *, Kokkos::Device< ExecutionSpace, MemorySpace > > gid, Kokkos::View< gno_t *, Kokkos::Device< ExecutionSpace, MemorySpace > > ghost_degrees, bool recolor_degrees)
typename femv_t::device_type device_type
Traits class to handle conversions between gno_t/lno_t and TPL data types (e.g., ParMETIS&#39;s idx_t...
typename femv_t::host_view_type::device_type::execution_space host_exec
Defines the ColoringSolution class.
Defines the GraphModel interface.
A gathering of useful namespace methods.
typename Adapter::base_adapter_t base_adapter_t
typename device_type::execution_space execution_space
Tpetra::Map< lno_t, gno_t > map_t
typename Adapter::scalar_t scalar_t
typename device_type::memory_space memory_space
AlltoAll communication methods.