Zoltan2
Loading...
Searching...
No Matches
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"
26#include "Zoltan2_Util.hpp"
27#include "Zoltan2_TPLTraits.hpp"
28#include "Zoltan2_AlltoAll.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
46namespace Zoltan2{
47
48template <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;
55 using base_adapter_t = typename Adapter::base_adapter_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 >::host_mirror_type adjs_view,
144 typename Kokkos::View<offset_t*,device_type >::host_mirror_type offset_view,
145 Teuchos::RCP<femv_t> femv,
146 typename Kokkos::View<lno_t*, device_type>::host_mirror_type 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*,
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*,
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 >::host_mirror_type dist_offsets_host,
283 typename Kokkos::View<lno_t*, device_type >::host_mirror_type dist_adjs_host,
284 typename Kokkos::View<int*,device_type >::host_mirror_type femv_colors,
285 typename Kokkos::View<lno_t*, device_type >::host_mirror_type boundary_verts_view,
286 typename Kokkos::View<lno_t*,device_type>::host_mirror_type verts_to_recolor,
287 typename Kokkos::View<int*,device_type>::host_mirror_type verts_to_recolor_size,
288 typename Kokkos::View<lno_t*,device_type>::host_mirror_type verts_to_send,
289 typename Kokkos::View<size_t*,device_type>::host_mirror_type verts_to_send_size,
290 typename Kokkos::View<size_t*, device_type>::host_mirror_type recoloringSize,
291 typename Kokkos::View<int*, device_type>::host_mirror_type rand,
292 typename Kokkos::View<gno_t*,device_type>::host_mirror_type gid,
293 typename Kokkos::View<gno_t*,device_type>::host_mirror_type 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>::host_mirror_type dist_offsets_host,
316 typename Kokkos::View<lno_t*, device_type>::host_mirror_type 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*,
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
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.
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)
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)
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 >::host_mirror_type dist_offsets_host, typename Kokkos::View< lno_t *, device_type >::host_mirror_type 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::base_adapter_t base_adapter_t
typename femv_t::host_view_type::device_type::execution_space host_exec
AlgDistance1TwoGhostLayer(const RCP< const base_adapter_t > &adapter_, const RCP< Teuchos::ParameterList > &pl_, const RCP< Environment > &env_, const RCP< const Teuchos::Comm< int > > &comm_)
typename device_type::memory_space memory_space
virtual void detectConflicts_serial(const size_t n_local, typename Kokkos::View< offset_t *, device_type >::host_mirror_type dist_offsets_host, typename Kokkos::View< lno_t *, device_type >::host_mirror_type dist_adjs_host, typename Kokkos::View< int *, device_type >::host_mirror_type femv_colors, typename Kokkos::View< lno_t *, device_type >::host_mirror_type boundary_verts_view, typename Kokkos::View< lno_t *, device_type >::host_mirror_type verts_to_recolor, typename Kokkos::View< int *, device_type >::host_mirror_type verts_to_recolor_size, typename Kokkos::View< lno_t *, device_type >::host_mirror_type verts_to_send, typename Kokkos::View< size_t *, device_type >::host_mirror_type verts_to_send_size, typename Kokkos::View< size_t *, device_type >::host_mirror_type recoloringSize, typename Kokkos::View< int *, device_type >::host_mirror_type rand, typename Kokkos::View< gno_t *, device_type >::host_mirror_type gid, typename Kokkos::View< gno_t *, device_type >::host_mirror_type ghost_degrees, bool recolor_degrees)
typename device_type::execution_space execution_space
typename femv_t::host_view_type::device_type::memory_space host_mem
Created by mbenlioglu on Aug 31, 2020.