40 #ifndef TPETRA_DETAILS_PACKCRSGRAPH_DEF_HPP 41 #define TPETRA_DETAILS_PACKCRSGRAPH_DEF_HPP 43 #include "TpetraCore_config.h" 44 #include "Teuchos_Array.hpp" 45 #include "Teuchos_ArrayView.hpp" 80 #ifndef DOXYGEN_SHOULD_SKIP_THIS 83 #endif // DOXYGEN_SHOULD_SKIP_THIS 90 namespace PackCrsGraphImpl {
98 template<
class OutputOffsetsViewType,
100 class InputOffsetsViewType,
101 class InputLocalRowIndicesViewType,
102 class InputLocalRowPidsViewType,
104 #ifdef HAVE_TPETRA_DEBUG 108 #endif // HAVE_TPETRA_DEBUG 112 typedef typename OutputOffsetsViewType::non_const_value_type output_offset_type;
113 typedef typename CountsViewType::non_const_value_type count_type;
114 typedef typename InputOffsetsViewType::non_const_value_type input_offset_type;
115 typedef typename InputLocalRowIndicesViewType::non_const_value_type local_row_index_type;
116 typedef typename InputLocalRowPidsViewType::non_const_value_type local_row_pid_type;
118 typedef typename OutputOffsetsViewType::device_type device_type;
119 static_assert (std::is_same<
typename CountsViewType::device_type::execution_space,
120 typename device_type::execution_space>::value,
121 "OutputOffsetsViewType and CountsViewType must have the same execution space.");
122 static_assert (Kokkos::Impl::is_view<OutputOffsetsViewType>::value,
123 "OutputOffsetsViewType must be a Kokkos::View.");
124 static_assert (std::is_same<typename OutputOffsetsViewType::value_type, output_offset_type>::value,
125 "OutputOffsetsViewType must be a nonconst Kokkos::View.");
126 static_assert (std::is_integral<output_offset_type>::value,
127 "The type of each entry of OutputOffsetsViewType must be a built-in integer type.");
128 static_assert (Kokkos::Impl::is_view<CountsViewType>::value,
129 "CountsViewType must be a Kokkos::View.");
130 static_assert (std::is_same<typename CountsViewType::value_type, output_offset_type>::value,
131 "CountsViewType must be a nonconst Kokkos::View.");
132 static_assert (std::is_integral<count_type>::value,
133 "The type of each entry of CountsViewType must be a built-in integer type.");
134 static_assert (Kokkos::Impl::is_view<InputOffsetsViewType>::value,
135 "InputOffsetsViewType must be a Kokkos::View.");
136 static_assert (std::is_integral<input_offset_type>::value,
137 "The type of each entry of InputOffsetsViewType must be a built-in integer type.");
138 static_assert (Kokkos::Impl::is_view<InputLocalRowIndicesViewType>::value,
139 "InputLocalRowIndicesViewType must be a Kokkos::View.");
140 static_assert (std::is_integral<local_row_index_type>::value,
141 "The type of each entry of InputLocalRowIndicesViewType must be a built-in integer type.");
144 const CountsViewType& counts,
145 const InputOffsetsViewType& rowOffsets,
146 const InputLocalRowIndicesViewType& lclRowInds,
147 const InputLocalRowPidsViewType& lclRowPids) :
148 outputOffsets_ (outputOffsets),
150 rowOffsets_ (rowOffsets),
151 lclRowInds_ (lclRowInds),
152 lclRowPids_ (lclRowPids),
156 const size_t numRowsToPack =
static_cast<size_t> (lclRowInds_.extent (0));
158 if (numRowsToPack != static_cast<size_t> (counts_.extent (0))) {
159 std::ostringstream os;
160 os <<
"lclRowInds.extent(0) = " << numRowsToPack
161 <<
" != counts.extent(0) = " << counts_.extent (0)
163 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument, os.str ());
165 if (static_cast<size_t> (numRowsToPack + 1) !=
166 static_cast<size_t> (outputOffsets_.extent (0))) {
167 std::ostringstream os;
168 os <<
"lclRowInds.extent(0) + 1 = " << (numRowsToPack + 1)
169 <<
" != outputOffsets.extent(0) = " << outputOffsets_.extent (0)
171 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument, os.str ());
176 KOKKOS_INLINE_FUNCTION
void 177 operator() (
const local_row_index_type& curInd,
178 output_offset_type& update,
179 const bool final)
const 182 if (curInd < static_cast<local_row_index_type> (0)) {
190 if (curInd >= static_cast<local_row_index_type> (outputOffsets_.extent (0))) {
195 outputOffsets_(curInd) = update;
198 if (curInd < static_cast<local_row_index_type> (counts_.extent (0))) {
199 const auto lclRow = lclRowInds_(curInd);
200 if (static_cast<size_t> (lclRow + 1) >= static_cast<size_t> (rowOffsets_.extent (0)) ||
201 static_cast<local_row_index_type> (lclRow) <
static_cast<local_row_index_type
> (0)) {
209 const count_type count =
210 static_cast<count_type
> (rowOffsets_(lclRow+1) - rowOffsets_(lclRow));
214 const count_type numEntToPack = (count == 0)
215 ? static_cast<count_type>(0)
216 : count * (1 + (lclRowPids_.size() > 0 ? 1 : 0));
219 counts_(curInd) = numEntToPack;
221 update += numEntToPack;
231 auto error_h = Kokkos::create_mirror_view (error_);
237 OutputOffsetsViewType outputOffsets_;
238 CountsViewType counts_;
239 typename InputOffsetsViewType::const_type rowOffsets_;
240 typename InputLocalRowIndicesViewType::const_type lclRowInds_;
241 typename InputLocalRowPidsViewType::const_type lclRowPids_;
242 Kokkos::View<int, device_type> error_;
254 template<
class OutputOffsetsViewType,
255 class CountsViewType,
256 class InputOffsetsViewType,
257 class InputLocalRowIndicesViewType,
258 class InputLocalRowPidsViewType>
259 typename CountsViewType::non_const_value_type
261 const CountsViewType& counts,
262 const InputOffsetsViewType& rowOffsets,
263 const InputLocalRowIndicesViewType& lclRowInds,
264 const InputLocalRowPidsViewType& lclRowPids)
267 CountsViewType,
typename InputOffsetsViewType::const_type,
268 typename InputLocalRowIndicesViewType::const_type,
269 typename InputLocalRowPidsViewType::const_type> functor_type;
270 typedef typename CountsViewType::non_const_value_type count_type;
271 typedef typename OutputOffsetsViewType::size_type size_type;
272 typedef typename OutputOffsetsViewType::execution_space execution_space;
273 typedef typename functor_type::local_row_index_type LO;
274 typedef Kokkos::RangePolicy<execution_space, LO> range_type;
275 const char prefix[] =
"computeNumPacketsAndOffsets: ";
277 count_type count = 0;
278 const count_type numRowsToPack = lclRowInds.extent (0);
280 if (numRowsToPack == 0) {
284 TEUCHOS_TEST_FOR_EXCEPTION
285 (rowOffsets.extent (0) <=
static_cast<size_type
> (1),
286 std::invalid_argument, prefix <<
"There is at least one row to pack, " 287 "but the graph has no rows. lclRowInds.extent(0) = " <<
288 numRowsToPack <<
", but rowOffsets.extent(0) = " <<
289 rowOffsets.extent (0) <<
" <= 1.");
290 TEUCHOS_TEST_FOR_EXCEPTION
291 (outputOffsets.extent (0) !=
292 static_cast<size_type
> (numRowsToPack + 1), std::invalid_argument,
293 prefix <<
"Output dimension does not match number of rows to pack. " 294 <<
"outputOffsets.extent(0) = " << outputOffsets.extent (0)
295 <<
" != lclRowInds.extent(0) + 1 = " 296 <<
static_cast<size_type
> (numRowsToPack + 1) <<
".");
297 TEUCHOS_TEST_FOR_EXCEPTION
298 (counts.extent (0) != numRowsToPack, std::invalid_argument,
299 prefix <<
"counts.extent(0) = " << counts.extent (0)
300 <<
" != numRowsToPack = " << numRowsToPack <<
".");
302 functor_type f (outputOffsets, counts, rowOffsets, lclRowInds, lclRowPids);
303 Kokkos::parallel_scan (range_type (0, numRowsToPack + 1), f);
306 const int errCode = f.getError ();
307 TEUCHOS_TEST_FOR_EXCEPTION
308 (errCode != 0, std::runtime_error, prefix <<
"parallel_scan error code " 309 << errCode <<
" != 0.");
313 for (LO k = 0; k < numRowsToPack; ++k) {
316 if (outputOffsets(numRowsToPack) != total) {
317 if (errStr.get () == NULL) {
318 errStr = std::unique_ptr<std::ostringstream> (
new std::ostringstream ());
320 std::ostringstream& os = *errStr;
322 <<
"outputOffsets(numRowsToPack=" << numRowsToPack <<
") " 323 << outputOffsets(numRowsToPack) <<
" != sum of counts = " 324 << total <<
"." << std::endl;
325 if (numRowsToPack != 0) {
327 if (numRowsToPack < static_cast<LO> (10)) {
328 os <<
"outputOffsets: [";
329 for (LO i = 0; i <= numRowsToPack; ++i) {
330 os << outputOffsets(i);
331 if (static_cast<LO> (i + 1) <= numRowsToPack) {
335 os <<
"]" << std::endl;
337 for (LO i = 0; i < numRowsToPack; ++i) {
339 if (static_cast<LO> (i + 1) < numRowsToPack) {
343 os <<
"]" << std::endl;
346 os <<
"outputOffsets(" << (numRowsToPack-1) <<
") = " 347 << outputOffsets(numRowsToPack-1) <<
"." << std::endl;
350 count = outputOffsets(numRowsToPack);
351 return {
false, errStr};
353 #endif // HAVE_TPETRA_DEBUG 357 using Tpetra::Details::getEntryOnHost;
358 return static_cast<count_type
> (getEntryOnHost (outputOffsets,
373 template<
class Packet,
375 class BufferDeviceType,
381 const Kokkos::View<Packet*, BufferDeviceType>& exports,
382 const InputLidsType& lids_in,
383 const InputPidsType& pids_in,
385 const size_t num_ent,
386 const bool pack_pids)
388 using LO =
typename LocalMapType::local_ordinal_type;
389 using GO =
typename LocalMapType::global_ordinal_type;
393 return static_cast<size_t>(0);
396 size_t num_ent_packed = num_ent;
398 num_ent_packed += num_ent;
403 for (
size_t k = 0; k < num_ent; ++k) {
404 const LO lid = lids_in[k];
405 const GO gid = col_map.getGlobalElement (lid);
406 exports(offset+k) = gid;
410 for (
size_t k = 0; k < num_ent; ++k) {
411 const LO lid = lids_in[k];
412 const int pid = pids_in[lid];
413 exports(offset+num_ent+k) =
static_cast<GO
>(pid);
417 return num_ent_packed;
420 template<
class Packet,
423 class BufferDeviceType>
424 struct PackCrsGraphFunctor {
425 using local_graph_type = LocalGraph;
427 using LO =
typename local_map_type::local_ordinal_type;
428 using GO =
typename local_map_type::global_ordinal_type;
430 using num_packets_per_lid_view_type =
431 Kokkos::View<const size_t*, BufferDeviceType>;
432 using offsets_view_type = Kokkos::View<const size_t*, BufferDeviceType>;
433 using exports_view_type = Kokkos::View<Packet*, BufferDeviceType>;
434 using export_lids_view_type =
436 using source_pids_view_type =
440 typename num_packets_per_lid_view_type::non_const_value_type;
441 using offset_type =
typename offsets_view_type::non_const_value_type;
442 using value_type = Kokkos::pair<int, LO>;
444 static_assert (std::is_same<LO, typename local_graph_type::data_type>::value,
445 "local_map_type::local_ordinal_type and " 446 "local_graph_type::data_type must be the same.");
448 local_graph_type local_graph;
449 local_map_type local_col_map;
450 exports_view_type exports;
451 num_packets_per_lid_view_type num_packets_per_lid;
452 export_lids_view_type export_lids;
453 source_pids_view_type source_pids;
454 offsets_view_type offsets;
457 PackCrsGraphFunctor(
const local_graph_type& local_graph_in,
458 const local_map_type& local_col_map_in,
459 const exports_view_type& exports_in,
460 const num_packets_per_lid_view_type& num_packets_per_lid_in,
461 const export_lids_view_type& export_lids_in,
462 const source_pids_view_type& source_pids_in,
463 const offsets_view_type& offsets_in,
464 const bool pack_pids_in) :
465 local_graph (local_graph_in),
466 local_col_map (local_col_map_in),
467 exports (exports_in),
468 num_packets_per_lid (num_packets_per_lid_in),
469 export_lids (export_lids_in),
470 source_pids (source_pids_in),
471 offsets (offsets_in),
472 pack_pids (pack_pids_in)
474 const LO numRows = local_graph_in.numRows ();
476 static_cast<LO
> (local_graph.row_map.extent (0));
477 TEUCHOS_TEST_FOR_EXCEPTION
478 (numRows != 0 && rowMapDim != numRows + static_cast<LO> (1),
479 std::logic_error,
"local_graph.row_map.extent(0) = " 480 << rowMapDim <<
" != numRows (= " << numRows <<
" ) + 1.");
483 KOKKOS_INLINE_FUNCTION
void init (value_type& dst)
const 485 using ::Tpetra::Details::OrdinalTraits;
486 dst = Kokkos::make_pair (0, OrdinalTraits<LO>::invalid ());
489 KOKKOS_INLINE_FUNCTION
void 490 join (
volatile value_type& dst,
const volatile value_type& src)
const 494 if (src.first != 0 && dst.first == 0) {
499 KOKKOS_INLINE_FUNCTION
500 void operator() (
const LO i, value_type& dst)
const 502 const size_t offset = offsets[i];
503 const LO export_lid = export_lids[i];
504 const size_t buf_size = exports.size();
505 const size_t num_packets_this_lid = num_packets_per_lid(i);
506 const size_t num_ent =
507 static_cast<size_t> (local_graph.row_map[export_lid+1]
508 - local_graph.row_map[export_lid]);
518 if (export_lid >= static_cast<LO>(local_graph.numRows())) {
519 if (dst.first != 0) {
520 dst = Kokkos::make_pair (1, i);
524 else if ((offset > buf_size || offset + num_packets_this_lid > buf_size)) {
525 if (dst.first != 0) {
526 dst = Kokkos::make_pair (2, i);
536 const auto row_beg = local_graph.row_map[export_lid];
537 const auto row_end = local_graph.row_map[export_lid + 1];
538 auto lids_in = Kokkos::subview (local_graph.entries,
539 Kokkos::make_pair (row_beg, row_end));
540 size_t num_ent_packed_this_row =
541 packRow (local_col_map, exports, lids_in,
542 source_pids, offset, num_ent, pack_pids);
543 if (num_ent_packed_this_row != num_packets_this_lid) {
544 if (dst.first != 0) {
545 dst = Kokkos::make_pair (3, i);
558 template<
class Packet,
561 class BufferDeviceType>
565 const Kokkos::View<Packet*, BufferDeviceType>& exports,
568 >::input_array_type& num_packets_per_lid,
570 typename LocalMap::local_ordinal_type
571 >::input_array_type& export_lids,
574 >::input_array_type& source_pids,
575 const Kokkos::View<const size_t*, BufferDeviceType>& offsets,
576 const bool pack_pids)
578 using LO =
typename LocalMap::local_ordinal_type;
579 using execution_space =
typename LocalGraph::device_type::execution_space;
580 using range_type = Kokkos::RangePolicy<execution_space, LO>;
581 const char prefix[] =
"Tpetra::Details::PackCrsGraphImpl::do_pack: ";
583 if (export_lids.extent (0) != 0) {
584 TEUCHOS_TEST_FOR_EXCEPTION
585 (static_cast<size_t> (offsets.extent (0)) !=
586 static_cast<size_t> (export_lids.extent (0) + 1),
587 std::invalid_argument, prefix <<
"offsets.extent(0) = " 588 << offsets.extent (0) <<
" != export_lids.extent(0) (= " 589 << export_lids.extent (0) <<
") + 1.");
590 TEUCHOS_TEST_FOR_EXCEPTION
591 (export_lids.extent (0) != num_packets_per_lid.extent (0),
592 std::invalid_argument, prefix <<
"export_lids.extent(0) = " <<
593 export_lids.extent (0) <<
" != num_packets_per_lid.extent(0) = " 594 << num_packets_per_lid.extent (0) <<
".");
598 TEUCHOS_TEST_FOR_EXCEPTION
599 (pack_pids && exports.extent (0) != 0 &&
600 source_pids.extent (0) == 0, std::invalid_argument, prefix <<
601 "pack_pids is true, and exports.extent(0) = " <<
602 exports.extent (0) <<
" != 0, meaning that we need to pack at " 603 "least one graph entry, but source_pids.extent(0) = 0.");
606 using pack_functor_type =
607 PackCrsGraphFunctor<Packet, LocalGraph,
LocalMap,
609 pack_functor_type f (local_graph, local_map, exports,
610 num_packets_per_lid, export_lids,
611 source_pids, offsets, pack_pids);
613 typename pack_functor_type::value_type result;
614 range_type range (0, num_packets_per_lid.extent (0));
615 Kokkos::parallel_reduce (range, f, result);
617 if (result.first != 0) {
620 std::ostringstream os;
621 if (result.first == 1) {
622 os <<
"invalid local row index";
624 else if (result.first == 2) {
625 os <<
"invalid offset";
627 TEUCHOS_TEST_FOR_EXCEPTION
628 (
true, std::runtime_error, prefix <<
"PackCrsGraphFunctor " 629 "reported error code " << result.first <<
" (" << os.str ()
630 <<
") for the first bad row " << result.second <<
".");
660 template<
typename LO,
typename GO,
typename NT>
671 >& num_packets_per_lid,
680 size_t& constant_num_packets,
681 const bool pack_pids,
686 using packet_type =
typename crs_graph_type::packet_type;
687 using buffer_device_type =
typename crs_graph_type::buffer_device_type;
688 using execution_space =
typename buffer_device_type::execution_space;
689 using exports_view_type = Kokkos::DualView<packet_type*, buffer_device_type>;
690 using local_graph_type =
typename crs_graph_type::local_graph_type;
692 const char prefix[] =
"Tpetra::Details::packCrsGraph: ";
693 constexpr
bool debug =
false;
696 local_map_type local_col_map = sourceGraph.
getColMap ()->getLocalMap ();
701 constant_num_packets = 0;
703 const size_t num_export_lids (export_lids.extent (0));
704 TEUCHOS_TEST_FOR_EXCEPTION
705 (num_export_lids !=
size_t (num_packets_per_lid.extent (0)),
706 std::invalid_argument, prefix <<
"num_export_lids.extent(0) = " 707 << num_export_lids <<
" != num_packets_per_lid.extent(0) = " 708 << num_packets_per_lid.extent (0) <<
".");
709 if (num_export_lids != 0) {
710 TEUCHOS_TEST_FOR_EXCEPTION
711 (num_packets_per_lid.data () ==
nullptr, std::invalid_argument,
712 prefix <<
"num_export_lids = "<< num_export_lids <<
" != 0, but " 713 "num_packets_per_lid.data() = " 714 << num_packets_per_lid.data () <<
" == NULL.");
717 if (num_export_lids == 0) {
718 exports = exports_view_type (
"exports", 0);
723 View<size_t*, buffer_device_type> offsets (
"offsets", num_export_lids + 1);
729 local_graph.row_map, export_lids, export_pids);
732 if (count >
size_t (exports.extent (0))) {
733 exports = exports_view_type (
"exports", count);
735 std::ostringstream os;
736 os <<
"*** exports resized to " << count << std::endl;
737 std::cerr << os.str ();
741 std::ostringstream os;
742 os <<
"*** count: " << count <<
", exports.extent(0): " 743 << exports.extent (0) << std::endl;
744 std::cerr << os.str ();
750 TEUCHOS_TEST_FOR_EXCEPTION
751 (pack_pids && exports.extent (0) != 0 &&
752 export_pids.extent (0) == 0, std::invalid_argument, prefix <<
753 "pack_pids is true, and exports.extent(0) = " <<
754 exports.extent (0) <<
" != 0, meaning that we need to pack at least " 755 "one graph entry, but export_pids.extent(0) = 0.");
757 exports.modify_device ();
758 auto exports_d = exports.view_device ();
759 do_pack<packet_type, local_graph_type, local_map_type, buffer_device_type>
760 (local_graph, local_col_map, exports_d, num_packets_per_lid,
761 export_lids, export_pids, offsets, pack_pids);
767 template<
typename LO,
typename GO,
typename NT>
771 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
772 const Teuchos::ArrayView<const LO>& exportLIDs,
773 size_t& constantNumPackets,
776 using Kokkos::HostSpace;
777 using Kokkos::MemoryUnmanaged;
780 using packet_type =
typename crs_graph_type::packet_type;
781 using BDT =
typename crs_graph_type::buffer_device_type;
788 View<size_t*, BDT> num_packets_per_lid_d =
790 numPacketsPerLID.getRawPtr (),
791 numPacketsPerLID.size (),
false,
792 "num_packets_per_lid");
795 View<const LO*, BDT> export_lids_d =
797 exportLIDs.getRawPtr (),
798 exportLIDs.size (),
true,
800 View<const int*, BDT> export_pids_d;
801 Kokkos::DualView<packet_type*, BDT> exports_dv;
802 constexpr
bool pack_pids =
false;
806 typename decltype (num_packets_per_lid_d)::non_const_value_type,
808 "num_packets_per_lid_d's non_const_value_type should be size_t.");
811 typename decltype (num_packets_per_lid_d)::device_type,
813 "num_packets_per_lid_d's BDT should be size_t.");
816 typename decltype (export_lids_d)::device_type,
818 "export_lids_d's device_type should be BDT.");
821 typename decltype (export_pids_d)::non_const_value_type,
823 "export_pids_d's non_const_value_type should be int.");
826 typename decltype (export_pids_d)::device_type,
828 "export_pids_d's device_type should be BDT.");
830 PackCrsGraphImpl::packCrsGraph
831 (sourceGraph, exports_dv, num_packets_per_lid_d, export_lids_d,
832 export_pids_d, constantNumPackets, pack_pids, distor);
836 View<size_t*, HostSpace, MemoryUnmanaged>
837 num_packets_per_lid_h (numPacketsPerLID.getRawPtr (),
838 numPacketsPerLID.size ());
846 if (static_cast<size_t> (exports.size ()) !=
847 static_cast<size_t> (exports_dv.extent (0))) {
848 exports.resize (exports_dv.extent (0));
850 View<packet_type*, HostSpace, MemoryUnmanaged>
851 exports_h (exports.getRawPtr (), exports.size ());
857 template<
typename LO,
typename GO,
typename NT>
860 const Kokkos::DualView<
864 const Kokkos::DualView<
874 > num_packets_per_lid,
875 size_t& constant_num_packets,
876 const bool pack_pids,
881 using BDT =
typename crs_graph_type::buffer_device_type;
882 using PT =
typename crs_graph_type::packet_type;
883 using exports_dual_view_type = Kokkos::DualView<PT*, BDT>;
884 using LGT =
typename crs_graph_type::local_graph_type;
885 using LMT =
typename crs_graph_type::map_type::local_map_type;
886 const char prefix[] =
"Tpetra::Details::packCrsGraphNew: ";
889 const LMT local_col_map = sourceGraph.
getColMap ()->getLocalMap ();
894 constant_num_packets = 0;
896 const size_t num_export_lids =
897 static_cast<size_t> (export_lids.extent (0));
898 TEUCHOS_TEST_FOR_EXCEPTION
900 static_cast<size_t> (num_packets_per_lid.extent (0)),
901 std::invalid_argument, prefix <<
"num_export_lids.extent(0) = " 902 << num_export_lids <<
" != num_packets_per_lid.extent(0) = " 903 << num_packets_per_lid.extent (0) <<
".");
904 TEUCHOS_TEST_FOR_EXCEPTION
905 (num_export_lids != 0 &&
906 num_packets_per_lid.view_device ().data () ==
nullptr,
907 std::invalid_argument, prefix <<
"num_export_lids = "<< num_export_lids
908 <<
" != 0, but num_packets_per_lid.view_device().data() = nullptr.");
910 if (num_export_lids == 0) {
911 exports = exports_dual_view_type ();
916 using offsets_type = Kokkos::View<size_t*, BDT>;
917 offsets_type offsets (
"offsets", num_export_lids + 1);
921 num_packets_per_lid.clear_sync_state ();
922 num_packets_per_lid.modify_device ();
923 using PackCrsGraphImpl::computeNumPacketsAndOffsets;
925 computeNumPacketsAndOffsets (offsets, num_packets_per_lid.view_device (),
927 export_lids.view_device (),
928 export_pids.view_device ());
931 if (count > static_cast<size_t> (exports.extent (0))) {
932 exports = exports_dual_view_type (
"exports", count);
938 TEUCHOS_TEST_FOR_EXCEPTION
939 (pack_pids && exports.extent (0) != 0 &&
940 export_pids.extent (0) == 0, std::invalid_argument, prefix <<
941 "pack_pids is true, and exports.extent(0) = " <<
942 exports.extent (0) <<
" != 0, meaning that we need to pack at least " 943 "one graph entry, but export_pids.extent(0) = 0.");
945 exports.modify_device ();
946 using PackCrsGraphImpl::do_pack;
947 do_pack<PT, LGT, LMT, BDT> (local_graph, local_col_map,
948 exports.view_device (),
949 num_packets_per_lid.view_device (),
950 export_lids.view_device (),
951 export_pids.view_device (),
955 template<
typename LO,
typename GO,
typename NT>
963 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
964 const Teuchos::ArrayView<const LO>& exportLIDs,
965 const Teuchos::ArrayView<const int>& sourcePIDs,
966 size_t& constantNumPackets,
969 using Kokkos::HostSpace;
970 using Kokkos::MemoryUnmanaged;
973 using buffer_device_type =
typename crs_graph_type::buffer_device_type;
979 View<size_t*, buffer_device_type> num_packets_per_lid_d =
981 numPacketsPerLID.getRawPtr (),
982 numPacketsPerLID.size (),
false,
983 "num_packets_per_lid");
987 View<const LO*, buffer_device_type> export_lids_d =
989 exportLIDs.getRawPtr (),
990 exportLIDs.size (),
true,
994 View<const int*, buffer_device_type> export_pids_d =
996 sourcePIDs.getRawPtr (),
997 sourcePIDs.size (),
true,
999 constexpr
bool pack_pids =
true;
1000 PackCrsGraphImpl::packCrsGraph
1001 (sourceGraph, exports_dv, num_packets_per_lid_d, export_lids_d,
1002 export_pids_d, constantNumPackets, pack_pids, distor);
1006 View<size_t*, HostSpace, MemoryUnmanaged> num_packets_per_lid_h
1007 (numPacketsPerLID.getRawPtr (), numPacketsPerLID.size ());
1014 #define TPETRA_DETAILS_PACKCRSGRAPH_INSTANT( LO, GO, NT ) \ 1016 Details::packCrsGraph<LO, GO, NT> ( \ 1017 const CrsGraph<LO, GO, NT>&, \ 1018 Teuchos::Array<CrsGraph<LO,GO,NT>::packet_type>&, \ 1019 const Teuchos::ArrayView<size_t>&, \ 1020 const Teuchos::ArrayView<const LO>&, \ 1024 Details::packCrsGraphNew<LO, GO, NT> ( \ 1025 const CrsGraph<LO, GO, NT>&, \ 1026 const Kokkos::DualView< \ 1028 CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1029 const Kokkos::DualView< \ 1031 CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1033 CrsGraph<LO,GO,NT>::packet_type*, \ 1034 CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1037 CrsGraph<LO,GO,NT>::buffer_device_type>, \ 1042 Details::packCrsGraphWithOwningPIDs<LO, GO, NT> ( \ 1043 const CrsGraph<LO, GO, NT>&, \ 1044 Kokkos::DualView<CrsGraph<LO,GO,NT>::packet_type*, CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1045 const Teuchos::ArrayView<size_t>&, \ 1046 const Teuchos::ArrayView<const LO>&, \ 1047 const Teuchos::ArrayView<const int>&, \ 1051 #endif // TPETRA_DETAILS_PACKCRSGRAPH_DEF_HPP Namespace Tpetra contains the class and methods constituting the Tpetra library.
Impl::CreateMirrorViewFromUnmanagedHostArray< ValueType, OutputDeviceType >::output_view_type create_mirror_view_from_raw_host_array(const OutputDeviceType &, ValueType *inPtr, const size_t inSize, const bool copy=true, const char label[]="")
Variant of Kokkos::create_mirror_view that takes a raw host 1-d array as input.
Import KokkosSparse::OrdinalTraits, a traits class for "invalid" (flag) values of integer types...
Teuchos::RCP< const map_type > getColMap() const override
Returns the Map that describes the column distribution in this graph.
Traits class for packing / unpacking data of type T.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
Declaration of the Tpetra::CrsGraph class.
"Local" part of Map suitable for Kokkos kernels.
Implementation details of Tpetra.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
Compute the number of packets and offsets for the pack procedure.
local_graph_type getLocalGraph() const
Get the local graph.
int getError() const
Host function for getting the error.
Sets up and executes a communication plan for a Tpetra DistObject.
KOKKOS_FUNCTION size_t packRow(const LocalMapType &col_map, const Kokkos::View< Packet *, BufferDeviceType > &exports, const InputLidsType &lids_in, const InputPidsType &pids_in, const size_t offset, const size_t num_ent, const bool pack_pids)
Packs a single row of the CrsGraph.
void packCrsGraph(const CrsGraph< LO, GO, NT > &sourceGraph, Teuchos::Array< typename CrsGraph< LO, GO, NT >::packet_type > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, const Teuchos::ArrayView< const LO > &exportLIDs, size_t &constantNumPackets, Distributor &distor)
Pack specified entries of the given local sparse graph for communication.
CountsViewType::non_const_value_type computeNumPacketsAndOffsets(const OutputOffsetsViewType &outputOffsets, const CountsViewType &counts, const InputOffsetsViewType &rowOffsets, const InputLocalRowIndicesViewType &lclRowInds, const InputLocalRowPidsViewType &lclRowPids)
Compute the number of packets and offsets for the pack procedure.
typename dist_object_type::buffer_device_type buffer_device_type
Kokkos::Device specialization for communication buffers.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
void do_pack(const LocalGraph &local_graph, const LocalMap &local_map, const Kokkos::View< Packet *, BufferDeviceType > &exports, const typename PackTraits< size_t >::input_array_type &num_packets_per_lid, const typename PackTraits< typename LocalMap::local_ordinal_type >::input_array_type &export_lids, const typename PackTraits< int >::input_array_type &source_pids, const Kokkos::View< const size_t *, BufferDeviceType > &offsets, const bool pack_pids)
Perform the pack operation for the graph.
Declaration and definition of Tpetra::Details::castAwayConstDualView, an implementation detail of Tpe...
void packCrsGraphNew(const CrsGraph< LO, GO, NT > &sourceGraph, const Kokkos::DualView< const LO *, typename CrsGraph< LO, GO, NT >::buffer_device_type > &exportLIDs, const Kokkos::DualView< const int *, typename CrsGraph< LO, GO, NT >::buffer_device_type > &exportPIDs, Kokkos::DualView< typename CrsGraph< LO, GO, NT >::packet_type *, typename CrsGraph< LO, GO, NT >::buffer_device_type > &exports, Kokkos::DualView< size_t *, typename CrsGraph< LO, GO, NT >::buffer_device_type > numPacketsPerLID, size_t &constantNumPackets, const bool pack_pids, Distributor &distor)
Pack specified entries of the given local sparse graph for communication, for "new" DistObject interf...
Declaration and definition of Tpetra::Details::getEntryOnHost.
global_ordinal_type packet_type
Type of each entry of the DistObject communication buffer.
void packCrsGraphWithOwningPIDs(const CrsGraph< LO, GO, NT > &sourceGraph, Kokkos::DualView< typename CrsGraph< LO, GO, NT >::packet_type *, typename CrsGraph< LO, GO, NT >::buffer_device_type > &exports_dv, const Teuchos::ArrayView< size_t > &numPacketsPerLID, const Teuchos::ArrayView< const LO > &exportLIDs, const Teuchos::ArrayView< const int > &sourcePIDs, size_t &constantNumPackets, Distributor &distor)
Pack specified entries of the given local sparse graph for communication.
Functions that wrap Kokkos::create_mirror_view, in order to avoid deep copies when not necessary...
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.