1#ifndef _ZOLTAN2_PDISTANCE2_HPP_
2#define _ZOLTAN2_PDISTANCE2_HPP_
5#include <unordered_map>
22#include "Tpetra_Core.hpp"
23#include "Teuchos_RCP.hpp"
24#include "Tpetra_Import.hpp"
25#include "Tpetra_FEMultiVector.hpp"
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"
41template <
typename Adapter>
51 using map_t = Tpetra::Map<lno_t,gno_t>;
53 using femv_t = Tpetra::FEMultiVector<femv_scalar_t, lno_t, gno_t>;
57 using host_exec =
typename Kokkos::View<device_type>::HostMirror::execution_space;
58 using host_mem =
typename Kokkos::View<device_type>::HostMirror::memory_space;
61 template<
class ExecutionSpace,
typename MemorySpace>
62 void localColoring(
const size_t nVtx,
63 Kokkos::View<
lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> adjs_view,
64 Kokkos::View<
offset_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> offset_view,
65 Teuchos::RCP<femv_t> femv,
66 Kokkos::View<
lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> vertex_list,
67 size_t vertex_list_size = 0,
68 bool use_vertex_based_coloring =
false){
69 using KernelHandle = KokkosKernels::Experimental::KokkosKernelsHandle
76 kh.create_distance2_graph_coloring_handle(KokkosGraph::COLORING_D2_NB_BIT);
80 if(vertex_list_size != 0){
81 kh.get_distance2_graph_coloring_handle()->set_vertex_list(vertex_list, vertex_list_size);
85 kh.get_distance2_graph_coloring_handle()->set_verbose(this->
verbose);
88 auto femvColors = femv->template getLocalView<Kokkos::Device<ExecutionSpace,MemorySpace> >(Tpetra::Access::ReadWrite);
89 auto sv = subview(femvColors,Kokkos::ALL, 0);
90 kh.get_distance2_graph_coloring_handle()->set_vertex_colors(sv);
93 KokkosGraph::Experimental::bipartite_color_rows(&kh, nVtx, nVtx, offset_view, adjs_view,
true);
98 std::cout<<
"\nKokkosKernels Coloring: "
99 <<kh.get_distance2_graph_coloring_handle()->get_overall_coloring_time()
105 virtual void colorInterior(
const size_t nVtx,
106 Kokkos::View<lno_t*, device_type> adjs_view,
107 Kokkos::View<offset_t*, device_type> offset_view,
108 Teuchos::RCP<femv_t> femv,
109 Kokkos::View<lno_t*, device_type> vertex_list,
110 size_t vertex_list_size=0,
112 this->localColoring<execution_space, memory_space>(nVtx,
121 virtual void colorInterior_serial(
const size_t nVtx,
122 typename Kokkos::View<lno_t*, device_type >::HostMirror adjs_view,
123 typename Kokkos::View<offset_t*,device_type >::HostMirror offset_view,
124 Teuchos::RCP<femv_t> femv,
125 typename Kokkos::View<lno_t*, device_type>::HostMirror vertex_list,
126 size_t vertex_list_size = 0,
127 bool recolor=
false) {
128 this->localColoring<host_exec, host_mem>(nVtx,
139 template <
class ExecutionSpace,
typename MemorySpace>
141 Kokkos::View<
offset_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> dist_offsets,
142 Kokkos::View<
lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> dist_adjs,
143 Kokkos::View<
int*, Kokkos::Device<ExecutionSpace, MemorySpace>> femv_colors,
144 Kokkos::View<
lno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> boundary_verts_view,
146 Kokkos::Device<ExecutionSpace, MemorySpace> > verts_to_recolor_view,
148 Kokkos::Device<ExecutionSpace, MemorySpace>,
149 Kokkos::MemoryTraits<Kokkos::Atomic> > verts_to_recolor_size_atomic,
151 Kokkos::Device<ExecutionSpace, MemorySpace> > verts_to_send_view,
152 Kokkos::View<
size_t*,
153 Kokkos::Device<ExecutionSpace, MemorySpace>,
154 Kokkos::MemoryTraits<Kokkos::Atomic> > verts_to_send_size_atomic,
155 Kokkos::View<
size_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> recoloringSize,
156 Kokkos::View<
int*, Kokkos::Device<ExecutionSpace, MemorySpace>> rand,
157 Kokkos::View<
gno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> gid,
158 Kokkos::View<
gno_t*, Kokkos::Device<ExecutionSpace, MemorySpace>> ghost_degrees,
159 bool recolor_degrees){
161 Kokkos::RangePolicy<ExecutionSpace> policy(0,boundary_verts_view.extent(0));
162 size_t local_recoloring_size;
163 Kokkos::parallel_reduce(
"PD2 conflict detection",policy, KOKKOS_LAMBDA(
const uint64_t& i,
size_t& recoloring_size){
165 const size_t curr_lid = boundary_verts_view(i);
166 const int curr_color = femv_colors(curr_lid);
167 const size_t vid_d1_adj_begin = dist_offsets(curr_lid);
168 const size_t vid_d1_adj_end = dist_offsets(curr_lid+1);
169 const size_t curr_degree = vid_d1_adj_end - vid_d1_adj_begin;
170 for(
size_t vid_d1_adj = vid_d1_adj_begin; vid_d1_adj < vid_d1_adj_end; vid_d1_adj++){
172 size_t vid_d1 = dist_adjs(vid_d1_adj);
173 size_t d2_adj_begin = dist_offsets(vid_d1);
174 size_t d2_adj_end = dist_offsets(vid_d1+1);
180 for(
size_t vid_d2_adj = d2_adj_begin; vid_d2_adj < d2_adj_end; vid_d2_adj++){
181 const size_t vid_d2 = dist_adjs(vid_d2_adj);
182 size_t vid_d2_degree = 0;
185 if(vid_d2 < n_local){
186 vid_d2_degree = dist_offsets(vid_d2+1) - dist_offsets(vid_d2);
188 vid_d2_degree = ghost_degrees(vid_d2-n_local);
191 if(curr_lid != vid_d2 && femv_colors(vid_d2) == curr_color){
192 if(curr_degree < vid_d2_degree && recolor_degrees){
194 femv_colors(curr_lid) = 0;
197 }
else if(vid_d2_degree < curr_degree && recolor_degrees){
198 femv_colors(vid_d2) = 0;
200 }
else if(rand(curr_lid) < rand(vid_d2)){
202 femv_colors(curr_lid) = 0;
205 }
else if(rand(vid_d2) < rand(curr_lid)){
206 femv_colors(vid_d2) = 0;
209 if(gid(curr_lid) >= gid(vid_d2)){
211 femv_colors(curr_lid) = 0;
215 femv_colors(vid_d2) = 0;
223 },local_recoloring_size);
224 Kokkos::deep_copy(recoloringSize, local_recoloring_size);
227 Kokkos::parallel_for(
"rebuild verts_to_send and verts_to_recolor",
228 Kokkos::RangePolicy<ExecutionSpace>(0,femv_colors.size()),
229 KOKKOS_LAMBDA(
const uint64_t& i){
230 if(femv_colors(i) == 0){
233 verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
236 verts_to_recolor_view(verts_to_recolor_size_atomic(0)++) = i;
244 Kokkos::View<offset_t*, device_type > dist_offsets_dev,
245 Kokkos::View<lno_t*, device_type > dist_adjs_dev,
246 Kokkos::View<int*,device_type > femv_colors,
247 Kokkos::View<lno_t*, device_type > boundary_verts_view,
252 Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_recolor_size_atomic,
255 Kokkos::View<
size_t*,
257 Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_send_size_atomic,
258 Kokkos::View<size_t*, device_type> recoloringSize,
265 bool recolor_degrees){
267 this->detectPD2Conflicts<execution_space, memory_space>(n_local,
272 verts_to_recolor_view,
273 verts_to_recolor_size_atomic,
275 verts_to_send_size_atomic,
284 typename Kokkos::View<offset_t*, device_type >::HostMirror dist_offsets_host,
285 typename Kokkos::View<lno_t*, device_type >::HostMirror dist_adjs_host,
286 typename Kokkos::View<int*,device_type >::HostMirror femv_colors,
287 typename Kokkos::View<lno_t*, device_type >::HostMirror boundary_verts_view,
288 typename Kokkos::View<lno_t*,device_type>::HostMirror verts_to_recolor,
289 typename Kokkos::View<int*,device_type>::HostMirror verts_to_recolor_size,
290 typename Kokkos::View<lno_t*,device_type>::HostMirror verts_to_send,
291 typename Kokkos::View<size_t*,device_type>::HostMirror verts_to_send_size,
292 typename Kokkos::View<size_t*, device_type>::HostMirror recoloringSize,
293 typename Kokkos::View<int*, device_type>::HostMirror rand,
294 typename Kokkos::View<gno_t*,device_type>::HostMirror gid,
295 typename Kokkos::View<gno_t*,device_type>::HostMirror ghost_degrees,
296 bool recolor_degrees) {
298 this->detectPD2Conflicts<host_exec, host_mem>(n_local,
304 verts_to_recolor_size,
315 Kokkos::View<offset_t*, device_type> dist_offsets_dev,
316 Kokkos::View<lno_t*, device_type> dist_adjs_dev,
317 typename Kokkos::View<offset_t*, device_type>::HostMirror dist_offsets_host,
318 typename Kokkos::View<lno_t*, device_type>::HostMirror dist_adjs_host,
319 Kokkos::View<lno_t*, device_type>& boundary_verts,
322 Kokkos::View<
size_t*,
324 Kokkos::MemoryTraits<Kokkos::Atomic>> verts_to_send_size_atomic){
327 gno_t boundary_size_temp = 0;
328 for(
size_t i = 0; i < n_local; i++){
329 for(
offset_t j = dist_offsets_host(i); j < dist_offsets_host(i+1); j++){
330 if((
size_t)dist_adjs_host(j) >= n_local){
331 boundary_size_temp++;
335 for(
offset_t k = dist_offsets_host(dist_adjs_host(j)); k < dist_offsets_host(dist_adjs_host(j)+1); k++){
336 if((
size_t)dist_adjs_host(k) >= n_local){
337 boundary_size_temp++;
347 boundary_verts = Kokkos::View<lno_t*, device_type>(
"boundary verts",boundary_size_temp);
348 typename Kokkos::View<lno_t*, device_type>::HostMirror boundary_verts_host = Kokkos::create_mirror_view(boundary_verts);
351 boundary_size_temp = 0;
353 for(
size_t i = 0; i < n_local; i++){
354 for(
offset_t j = dist_offsets_host(i); j < dist_offsets_host(i+1); j++){
355 if((
size_t)dist_adjs_host(j) >= n_local){
356 boundary_verts_host(boundary_size_temp++) = i;
360 for(
offset_t k = dist_offsets_host(dist_adjs_host(j)); k < dist_offsets_host(dist_adjs_host(j)+1); k++){
361 if((
size_t)dist_adjs_host(k) >= n_local){
362 boundary_verts_host(boundary_size_temp++) = i;
371 Kokkos::deep_copy(boundary_verts, boundary_verts_host);
374 Kokkos::parallel_for(n_local, KOKKOS_LAMBDA(
const int& i){
375 for(
offset_t j = dist_offsets_dev(i); j < dist_offsets_dev(i+1); j++){
376 if((
size_t)dist_adjs_dev(j) >= n_local){
377 verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
381 for(
offset_t k = dist_offsets_dev(dist_adjs_dev(j)); k < dist_offsets_dev(dist_adjs_dev(j)+1); k++){
382 if((
size_t)dist_adjs_dev(k) >= n_local){
383 verts_to_send_view(verts_to_send_size_atomic(0)++) = i;
398 const RCP<const base_adapter_t> &adapter_,
399 const RCP<Teuchos::ParameterList> &pl_,
400 const RCP<Environment> &env_,
401 const RCP<
const Teuchos::Comm<int> > &comm_)
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.
void detectPD2Conflicts(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)
AlgPartialDistance2(const RCP< const base_adapter_t > &adapter_, const RCP< Teuchos::ParameterList > &pl_, const RCP< Environment > &env_, const RCP< const Teuchos::Comm< int > > &comm_)
typename Adapter::lno_t lno_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)
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::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)
Tpetra::Map<>::memory_space memory_space
typename Kokkos::View< device_type >::HostMirror::execution_space host_exec
Tpetra::Map<>::device_type device_type
Tpetra::Map<>::execution_space execution_space
typename Adapter::base_adapter_t base_adapter_t
typename Adapter::gno_t gno_t
typename Adapter::scalar_t scalar_t
typename Adapter::offset_t offset_t
Tpetra::FEMultiVector< femv_scalar_t, lno_t, gno_t > femv_t
typename Kokkos::View< device_type >::HostMirror::memory_space host_mem
typename Adapter::lno_t lno_t
Tpetra::Map< lno_t, gno_t > map_t
map_t::local_ordinal_type lno_t
map_t::global_ordinal_type gno_t
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Created by mbenlioglu on Aug 31, 2020.