Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_AlgHybridD2.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_DISTANCE2_HPP_
11 #define _ZOLTAN2_DISTANCE2_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 
30 
31 #include "Tpetra_Core.hpp"
32 #include "Teuchos_RCP.hpp"
33 #include "Tpetra_Import.hpp"
34 #include "Tpetra_FEMultiVector.hpp"
35 
36 #include "Kokkos_Core.hpp"
37 #include "KokkosSparse_CrsMatrix.hpp"
38 #include "KokkosKernels_Handle.hpp"
39 #include "KokkosKernels_IOUtils.hpp"
40 #include "KokkosGraph_Distance2Color.hpp"
41 #include "KokkosGraph_Distance2ColorHandle.hpp"
42 
46 
47 
48 namespace Zoltan2{
49 
50 template <typename Adapter>
51 class AlgDistance2 : public AlgTwoGhostLayer<Adapter> {
52 
53  public:
54 
55  using lno_t = typename Adapter::lno_t;
56  using gno_t = typename Adapter::gno_t;
57  using offset_t = typename Adapter::offset_t;
58  using scalar_t = typename Adapter::scalar_t;
60  using map_t = Tpetra::Map<lno_t,gno_t>;
61  using femv_scalar_t = int;
62  using femv_t = Tpetra::FEMultiVector<femv_scalar_t, lno_t, gno_t>;
63  using device_type = typename femv_t::device_type;
64  using execution_space = typename device_type::execution_space;
65  using memory_space = typename device_type::memory_space;
66  using host_exec = typename femv_t::host_view_type::device_type::execution_space;
67  using host_mem = typename femv_t::host_view_type::device_type::memory_space;
68 
69  private:
70 
71  //This is both the serial and parallel local coloring.
72  template <class ExecutionSpace, typename MemorySpace>
73  void localColoring(const size_t nVtx,
74  Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> adjs_view,
75  Kokkos::View<offset_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> offset_view,
76  Teuchos::RCP<femv_t> femv,
77  Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace> > vertex_list,
78  size_t vertex_list_size = 0,
79  bool use_vertex_based_coloring = false){
80  using KernelHandle = KokkosKernels::Experimental::KokkosKernelsHandle
81  <offset_t, lno_t, lno_t, ExecutionSpace, MemorySpace, MemorySpace>;
82  KernelHandle kh;
83 
84  //Instead of switching between vertex-based and net-based algorithms,
85  //we only use the net-based algorithm, as it is faster than its
86  //vertex-based counterpart.
87  kh.create_distance2_graph_coloring_handle(KokkosGraph::COLORING_D2_NB_BIT);
88 
89  //vertex_list_size indicates whether we have provided a list of vertices to recolor
90  //NB_BIT does not make use of this argument currently.
91  if(vertex_list_size != 0){
92  kh.get_distance2_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 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_distance2_graph_coloring_handle()->set_vertex_colors(sv);
102 
103  //call coloring
104  KokkosGraph::Experimental::graph_color_distance2(&kh, nVtx, offset_view, adjs_view);
105 
106 
107  //output total time
108  if(this->verbose){
109  std::cout<<"\nKokkosKernels Coloring: "
110  <<kh.get_distance2_graph_coloring_handle()->get_overall_coloring_time()
111  <<"\n";
112  }
113  }
114 
115  //Entry point for device-based coloring
116  virtual void colorInterior(const size_t nVtx,
117  Kokkos::View<lno_t*,device_type> adjs_view,
118  Kokkos::View<offset_t*, device_type> offset_view,
119  Teuchos::RCP<femv_t> femv,
120  Kokkos::View<lno_t*, device_type> vertex_list,
121  size_t vertex_list_size = 0,
122  bool recolor=false){
123 
124  this->localColoring<execution_space, memory_space>(nVtx,
125  adjs_view,
126  offset_view,
127  femv,
128  vertex_list,
129  vertex_list_size,
130  recolor);
131  }
132 
133  //Entry point for serial coloring
134  virtual void colorInterior_serial(const size_t nVtx,
135  typename Kokkos::View<lno_t*, device_type>::HostMirror adjs_view,
136  typename Kokkos::View<offset_t*, device_type>::HostMirror offset_view,
137  Teuchos::RCP<femv_t> femv,
138  typename Kokkos::View<lno_t*, device_type>::HostMirror vertex_list,
139  size_t vertex_list_size = 0,
140  bool recolor=false){
141  this->localColoring<host_exec, host_mem>(nVtx,
142  adjs_view,
143  offset_view,
144  femv,
145  vertex_list,
146  vertex_list_size,
147  recolor);
148  }
149  public:
150  //this function must be public due to Cuda Lambda restrictions.
151  //It is both the serial and parallel conflict detection function.
152  template< class ExecutionSpace, typename MemorySpace>
153  void detectD2Conflicts(const size_t n_local,
154  Kokkos::View<offset_t*, Kokkos::Device<ExecutionSpace,MemorySpace>> dist_offsets,
155  Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> dist_adjs,
156  Kokkos::View<int*, Kokkos::Device<ExecutionSpace, MemorySpace>> femv_colors,
157  Kokkos::View<lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> boundary_verts_view,
158  Kokkos::View<lno_t*,
159  Kokkos::Device<ExecutionSpace, MemorySpace> > verts_to_recolor_view,
160  Kokkos::View<int*,
161  Kokkos::Device<ExecutionSpace, MemorySpace>,
162  Kokkos::MemoryTraits<Kokkos::Atomic> > verts_to_recolor_size_atomic,
163  Kokkos::View<lno_t*,
164  Kokkos::Device<ExecutionSpace, MemorySpace> > verts_to_send_view,
165  Kokkos::View<size_t*,
166  Kokkos::Device<ExecutionSpace, MemorySpace>,
167  Kokkos::MemoryTraits<Kokkos::Atomic> > verts_to_send_size_atomic,
168  Kokkos::View<size_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> recoloringSize,
169  Kokkos::View<int*, Kokkos::Device<ExecutionSpace, MemorySpace>> rand,
170  Kokkos::View<gno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> gid,
171  Kokkos::View<gno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> ghost_degrees,
172  bool recolor_degrees){
173  Kokkos::RangePolicy<ExecutionSpace> policy(0, boundary_verts_view.extent(0));
174  size_t local_recoloring_size;
175  Kokkos::parallel_reduce("D2 conflict detection",policy, KOKKOS_LAMBDA(const uint64_t& i,size_t& recoloring_size){
176  //we only detect conflicts for vertices in the boundary
177  const size_t curr_lid = boundary_verts_view(i);
178  const int curr_color = femv_colors(curr_lid);
179  const size_t vid_d1_adj_begin = dist_offsets(curr_lid);
180  const size_t vid_d1_adj_end = dist_offsets(curr_lid+1);
181  const size_t curr_degree = vid_d1_adj_end - vid_d1_adj_begin;
182  for(size_t vid_d1_adj = vid_d1_adj_begin; vid_d1_adj < vid_d1_adj_end; vid_d1_adj++){
183  //check all distance-1 neighbors for conflicts
184  size_t vid_d1 = dist_adjs(vid_d1_adj);
185  size_t vid_d1_degree = 0;
186  //calculate the degree for degree-base recoloring
187  if(vid_d1 < n_local){
188  vid_d1_degree = dist_offsets(vid_d1+1) - dist_offsets(vid_d1);
189  } else {
190  vid_d1_degree = ghost_degrees(vid_d1-n_local);
191  }
192  if( vid_d1 != curr_lid && femv_colors(vid_d1) == curr_color){
193  if(curr_degree < vid_d1_degree && recolor_degrees){
194  femv_colors(curr_lid) = 0;
195  recoloring_size++;
196  break;//----------------------------------------------------
197  } else if (vid_d1_degree < curr_degree && recolor_degrees){//|
198  femv_colors(vid_d1) = 0; //|
199  recoloring_size++; //|
200  } else if(rand(curr_lid) < rand(vid_d1)){ //|
201  femv_colors(curr_lid) = 0; //|
202  recoloring_size++; //|
203  break;//---------------------------------------------------|
204  } else if(rand(vid_d1) < rand(curr_lid)){ //|
205  femv_colors(vid_d1) = 0; //|
206  recoloring_size++; //|
207  } else{ //|
208  if(gid(curr_lid) >= gid(vid_d1)){ //|
209  femv_colors(curr_lid) = 0; //|
210  recoloring_size++; //|
211  break;//-------------------------------------------------|
212  } else { // v
213  femv_colors(vid_d1) = 0; //If we uncolor the vertex whose
214  recoloring_size++; //neighbors we're checking, each
215  } //subsquent conflict check will
216  } //not do anything productive.
217  }
218  size_t d2_adj_begin = 0;
219  size_t d2_adj_end = 0;
220  d2_adj_begin = dist_offsets(vid_d1);
221  d2_adj_end = dist_offsets(vid_d1+1);
222 
223  //If we find a conflict that uncolors curr_lid, then we can safely stop
224  //detecting further conflicts. Since this is a nested loop, we need to
225  //break twice, using the found boolean.
226  bool found = false;
227  for(size_t vid_d2_adj = d2_adj_begin; vid_d2_adj < d2_adj_end; vid_d2_adj++){
228  //check all distance-2 neighbors for conflicts
229  const size_t vid_d2 = dist_adjs(vid_d2_adj);
230  size_t vid_d2_degree = 0;
231  //calculate the degree for degree-based recoloring
232  if(vid_d2 < n_local){
233  vid_d2_degree = dist_offsets(vid_d2+1) - dist_offsets(vid_d2);
234  } else {
235  vid_d2_degree = ghost_degrees(vid_d2-n_local);
236  }
237  if(curr_lid != vid_d2 && femv_colors(vid_d2) == curr_color){
238  if(curr_degree < vid_d2_degree && recolor_degrees){
239  found = true;
240  femv_colors(curr_lid) = 0;
241  recoloring_size++;
242  break;//---------------------------------------------------
243  } else if(vid_d2_degree < curr_degree && recolor_degrees){//|
244  femv_colors(vid_d2) = 0; //|
245  recoloring_size++; //|
246  } else if(rand(curr_lid) < rand(vid_d2)){ //|
247  found = true; //|
248  femv_colors(curr_lid) = 0; //|
249  recoloring_size++; //|
250  break;//--------------------------------------------------|
251  } else if(rand(vid_d2) < rand(curr_lid)){ //|
252  femv_colors(vid_d2) = 0; //|
253  recoloring_size++; //|
254  } else { //|
255  if(gid(curr_lid) >= gid(vid_d2)){ //|
256  found = true; //|
257  femv_colors(curr_lid) = 0; //|
258  recoloring_size++; //|
259  break;//------------------------------------------------|
260  } else { //|
261  femv_colors(vid_d2) = 0; //|
262  recoloring_size++;// v
263  }// If we uncolor the vertex whose neighbors we're
264  } // checking, each subsequent conflict check will
265  } // not do anything productive. We need this------
266  } // to completely move on to the next vertex. |
267  if(found) break;//<--------------------------------------------------
268  }
269  },local_recoloring_size);
270  Kokkos::deep_copy(recoloringSize,local_recoloring_size);
271  Kokkos::fence();
272 
273  //update the verts_to_send and verts_to_recolor views.
274  Kokkos::parallel_for("rebuild verts_to_send and verts_to_recolor",
275  Kokkos::RangePolicy<ExecutionSpace>(0,femv_colors.size()),
276  KOKKOS_LAMBDA(const uint64_t& i){
277  if(femv_colors(i) == 0){
278  //we only send vertices owned by the current process
279  if(i < n_local){
280  verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
281  }
282  //we need to recolor all vertices, for consistency.
283  verts_to_recolor_view(verts_to_recolor_size_atomic(0)++) = i;
284  }
285  });
286  Kokkos::fence();
287 
288  }
289 
290  //Entry point for parallel conflict detection
291  virtual void detectConflicts(const size_t n_local,
292  Kokkos::View<offset_t*, device_type > dist_offsets_dev,
293  Kokkos::View<lno_t*, device_type > dist_adjs_dev,
294  Kokkos::View<int*,device_type > femv_colors,
295  Kokkos::View<lno_t*, device_type > boundary_verts_view,
296  Kokkos::View<lno_t*,
297  device_type > verts_to_recolor_view,
298  Kokkos::View<int*,
299  device_type,
300  Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_recolor_size_atomic,
301  Kokkos::View<lno_t*,
302  device_type > verts_to_send_view,
303  Kokkos::View<size_t*,
304  device_type,
305  Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_send_size_atomic,
306  Kokkos::View<size_t*, device_type> recoloringSize,
307  Kokkos::View<int*,
308  device_type> rand,
309  Kokkos::View<gno_t*,
310  device_type> gid,
311  Kokkos::View<gno_t*,
312  device_type> ghost_degrees,
313  bool recolor_degrees){
314 
315  this->detectD2Conflicts<execution_space, memory_space>(n_local,
316  dist_offsets_dev,
317  dist_adjs_dev,
318  femv_colors,
319  boundary_verts_view,
320  verts_to_recolor_view,
321  verts_to_recolor_size_atomic,
322  verts_to_send_view,
323  verts_to_send_size_atomic,
324  recoloringSize,
325  rand,
326  gid,
327  ghost_degrees,
328  recolor_degrees);
329  }
330  //Entry point for serial conflict detection
331  virtual void detectConflicts_serial(const size_t n_local,
332  typename Kokkos::View<offset_t*, device_type >::HostMirror dist_offsets_host,
333  typename Kokkos::View<lno_t*, device_type >::HostMirror dist_adjs_host,
334  typename Kokkos::View<int*,device_type >::HostMirror femv_colors,
335  typename Kokkos::View<lno_t*, device_type >::HostMirror boundary_verts_view,
336  typename Kokkos::View<lno_t*,device_type>::HostMirror verts_to_recolor,
337  typename Kokkos::View<int*,device_type>::HostMirror verts_to_recolor_size,
338  typename Kokkos::View<lno_t*,device_type>::HostMirror verts_to_send,
339  typename Kokkos::View<size_t*,device_type>::HostMirror verts_to_send_size,
340  typename Kokkos::View<size_t*, device_type>::HostMirror recoloringSize,
341  typename Kokkos::View<int*, device_type>::HostMirror rand,
342  typename Kokkos::View<gno_t*,device_type>::HostMirror gid,
343  typename Kokkos::View<gno_t*,device_type>::HostMirror ghost_degrees,
344  bool recolor_degrees) {
345  this->detectD2Conflicts<host_exec, host_mem>(n_local,
346  dist_offsets_host,
347  dist_adjs_host,
348  femv_colors,
349  boundary_verts_view,
350  verts_to_recolor,
351  verts_to_recolor_size,
352  verts_to_send,
353  verts_to_send_size,
354  recoloringSize,
355  rand,
356  gid,
357  ghost_degrees,
358  recolor_degrees);
359 
360  }
361 
362  virtual void constructBoundary(const size_t n_local,
363  Kokkos::View<offset_t*, device_type> dist_offsets_dev,
364  Kokkos::View<lno_t*, device_type> dist_adjs_dev,
365  typename Kokkos::View<offset_t*, device_type>::HostMirror dist_offsets_host,
366  typename Kokkos::View<lno_t*, device_type>::HostMirror dist_adjs_host,
367  Kokkos::View<lno_t*, device_type>& boundary_verts,
368  Kokkos::View<lno_t*,
369  device_type > verts_to_send_view,
370  Kokkos::View<size_t*,
371  device_type,
372  Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_send_size_atomic){
373  //count the number of boundary vertices to correctly allocate
374  //the boundary vertex view on device.
375  gno_t boundary_size_temp = 0;
376  for(size_t i = 0; i < n_local; i++){
377  for(offset_t j = dist_offsets_host(i); j < dist_offsets_host(i+1); j++){
378  if((size_t)dist_adjs_host(j) >= n_local){
379  boundary_size_temp++;
380  break;
381  }
382  bool found = false;
383  for(offset_t k = dist_offsets_host(dist_adjs_host(j)); k < dist_offsets_host(dist_adjs_host(j)+1); k++){
384  if((size_t)dist_adjs_host(k) >= n_local){
385  boundary_size_temp++;
386  found = true;
387  break;
388  }
389  }
390  if(found) break;
391  }
392  }
393 
394  //create a host mirror to fill in the list of boundary vertices
395  boundary_verts = Kokkos::View<lno_t*, device_type>("boundary verts",boundary_size_temp);
396  typename Kokkos::View<lno_t*, device_type>::HostMirror boundary_verts_host = Kokkos::create_mirror_view(boundary_verts);
397 
398  //reset the boundary size count to use as an index to construct the view
399  boundary_size_temp = 0;
400 
401  //a boundary vertex is any vertex within two edges of a ghost vertex.
402  for(size_t i = 0; i < n_local; i++){
403  for(offset_t j = dist_offsets_host(i); j < dist_offsets_host(i+1); j++){
404  if((size_t)dist_adjs_host(j) >= n_local){
405  boundary_verts_host(boundary_size_temp++) = i;
406  break;
407  }
408  bool found = false;
409  for(offset_t k = dist_offsets_host(dist_adjs_host(j)); k < dist_offsets_host(dist_adjs_host(j)+1); k++){
410  if((size_t)dist_adjs_host(k) >= n_local){
411  boundary_verts_host(boundary_size_temp++) = i;
412  found = true;
413  break;
414  }
415  }
416  if(found) break;
417  }
418  }
419  //copy the boundary to the device view
420  Kokkos::deep_copy(boundary_verts, boundary_verts_host);
421 
422  //initialize the list of verts to send
423  Kokkos::parallel_for("init verts to send",
424  Kokkos::RangePolicy<execution_space, int>(0,n_local),
425  KOKKOS_LAMBDA(const int& i){
426  for(offset_t j = dist_offsets_dev(i); j < dist_offsets_dev(i+1); j++){
427  if((size_t)dist_adjs_dev(j) >= n_local){
428  verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
429  break;
430  }
431  bool found = false;
432  for(offset_t k = dist_offsets_dev(dist_adjs_dev(j)); k < dist_offsets_dev(dist_adjs_dev(j)+1); k++){
433  if((size_t)dist_adjs_dev(k) >= n_local){
434  verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
435  found = true;
436  break;
437  }
438  }
439  if(found) break;
440  }
441  });
442  Kokkos::fence();
443  }
444 
445  public:
447  const RCP<const base_adapter_t> &adapter_,
448  const RCP<Teuchos::ParameterList> &pl_,
449  const RCP<Environment> &env_,
450  const RCP<const Teuchos::Comm<int> > &comm_)
451  : AlgTwoGhostLayer<Adapter>(adapter_,pl_,env_,comm_){}
452 
453 }; //end class
454 
455 
456 }//end namespace Zoltan2
457 
458 #endif
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Tpetra::FEMultiVector< femv_scalar_t, lno_t, gno_t > femv_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::gno_t gno_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 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(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)
typename femv_t::host_view_type::device_type::memory_space host_mem
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
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
AlgDistance2(const RCP< const base_adapter_t > &adapter_, const RCP< Teuchos::ParameterList > &pl_, const RCP< Environment > &env_, const RCP< const Teuchos::Comm< int > > &comm_)
Defines the ColoringSolution class.
Defines the GraphModel interface.
void detectD2Conflicts(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)
A gathering of useful namespace methods.
typename Adapter::base_adapter_t base_adapter_t
typename Adapter::lno_t lno_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.
typename Adapter::offset_t offset_t