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