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" 85 namespace PackCrsGraphImpl {
93 template<
class OutputOffsetsViewType,
95 class InputOffsetsViewType,
96 class InputLocalRowIndicesViewType,
97 class InputLocalRowPidsViewType,
99 #ifdef HAVE_TPETRA_DEBUG 103 #endif // HAVE_TPETRA_DEBUG 107 typedef typename OutputOffsetsViewType::non_const_value_type output_offset_type;
108 typedef typename CountsViewType::non_const_value_type count_type;
109 typedef typename InputOffsetsViewType::non_const_value_type input_offset_type;
110 typedef typename InputLocalRowIndicesViewType::non_const_value_type local_row_index_type;
111 typedef typename InputLocalRowPidsViewType::non_const_value_type local_row_pid_type;
113 typedef typename OutputOffsetsViewType::device_type device_type;
114 static_assert (std::is_same<
typename CountsViewType::device_type::execution_space,
115 typename device_type::execution_space>::value,
116 "OutputOffsetsViewType and CountsViewType must have the same execution space.");
117 static_assert (Kokkos::Impl::is_view<OutputOffsetsViewType>::value,
118 "OutputOffsetsViewType must be a Kokkos::View.");
119 static_assert (std::is_same<typename OutputOffsetsViewType::value_type, output_offset_type>::value,
120 "OutputOffsetsViewType must be a nonconst Kokkos::View.");
121 static_assert (std::is_integral<output_offset_type>::value,
122 "The type of each entry of OutputOffsetsViewType must be a built-in integer type.");
123 static_assert (Kokkos::Impl::is_view<CountsViewType>::value,
124 "CountsViewType must be a Kokkos::View.");
125 static_assert (std::is_same<typename CountsViewType::value_type, output_offset_type>::value,
126 "CountsViewType must be a nonconst Kokkos::View.");
127 static_assert (std::is_integral<count_type>::value,
128 "The type of each entry of CountsViewType must be a built-in integer type.");
129 static_assert (Kokkos::Impl::is_view<InputOffsetsViewType>::value,
130 "InputOffsetsViewType must be a Kokkos::View.");
131 static_assert (std::is_integral<input_offset_type>::value,
132 "The type of each entry of InputOffsetsViewType must be a built-in integer type.");
133 static_assert (Kokkos::Impl::is_view<InputLocalRowIndicesViewType>::value,
134 "InputLocalRowIndicesViewType must be a Kokkos::View.");
135 static_assert (std::is_integral<local_row_index_type>::value,
136 "The type of each entry of InputLocalRowIndicesViewType must be a built-in integer type.");
139 const CountsViewType& counts,
140 const InputOffsetsViewType& rowOffsets,
141 const InputLocalRowIndicesViewType& lclRowInds,
142 const InputLocalRowPidsViewType& lclRowPids) :
143 outputOffsets_ (outputOffsets),
145 rowOffsets_ (rowOffsets),
146 lclRowInds_ (lclRowInds),
147 lclRowPids_ (lclRowPids),
151 const size_t numRowsToPack =
static_cast<size_t> (lclRowInds_.extent (0));
153 if (numRowsToPack != static_cast<size_t> (counts_.extent (0))) {
154 std::ostringstream os;
155 os <<
"lclRowInds.extent(0) = " << numRowsToPack
156 <<
" != counts.extent(0) = " << counts_.extent (0)
158 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument, os.str ());
160 if (static_cast<size_t> (numRowsToPack + 1) !=
161 static_cast<size_t> (outputOffsets_.extent (0))) {
162 std::ostringstream os;
163 os <<
"lclRowInds.extent(0) + 1 = " << (numRowsToPack + 1)
164 <<
" != outputOffsets.extent(0) = " << outputOffsets_.extent (0)
166 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument, os.str ());
171 KOKKOS_INLINE_FUNCTION
void 172 operator() (
const local_row_index_type& curInd,
173 output_offset_type& update,
174 const bool final)
const 177 if (curInd < static_cast<local_row_index_type> (0)) {
185 if (curInd >= static_cast<local_row_index_type> (outputOffsets_.extent (0))) {
190 outputOffsets_(curInd) = update;
193 if (curInd < static_cast<local_row_index_type> (counts_.extent (0))) {
194 const auto lclRow = lclRowInds_(curInd);
195 if (static_cast<size_t> (lclRow + 1) >= static_cast<size_t> (rowOffsets_.extent (0)) ||
196 static_cast<local_row_index_type> (lclRow) <
static_cast<local_row_index_type
> (0)) {
204 const count_type count =
205 static_cast<count_type
> (rowOffsets_(lclRow+1) - rowOffsets_(lclRow));
209 const count_type numEntToPack = (count == 0)
210 ? static_cast<count_type>(0)
211 : count * (1 + (lclRowPids_.size() > 0 ? 1 : 0));
214 counts_(curInd) = numEntToPack;
216 update += numEntToPack;
226 auto error_h = Kokkos::create_mirror_view (error_);
232 OutputOffsetsViewType outputOffsets_;
233 CountsViewType counts_;
234 typename InputOffsetsViewType::const_type rowOffsets_;
235 typename InputLocalRowIndicesViewType::const_type lclRowInds_;
236 typename InputLocalRowPidsViewType::const_type lclRowPids_;
237 Kokkos::View<int, device_type> error_;
249 template<
class OutputOffsetsViewType,
250 class CountsViewType,
251 class InputOffsetsViewType,
252 class InputLocalRowIndicesViewType,
253 class InputLocalRowPidsViewType>
254 typename CountsViewType::non_const_value_type
256 const CountsViewType& counts,
257 const InputOffsetsViewType& rowOffsets,
258 const InputLocalRowIndicesViewType& lclRowInds,
259 const InputLocalRowPidsViewType& lclRowPids)
262 CountsViewType,
typename InputOffsetsViewType::const_type,
263 typename InputLocalRowIndicesViewType::const_type,
264 typename InputLocalRowPidsViewType::const_type> functor_type;
265 typedef typename CountsViewType::non_const_value_type count_type;
266 typedef typename OutputOffsetsViewType::size_type size_type;
267 typedef typename OutputOffsetsViewType::execution_space execution_space;
268 typedef typename functor_type::local_row_index_type LO;
269 typedef Kokkos::RangePolicy<execution_space, LO> range_type;
270 const char prefix[] =
"computeNumPacketsAndOffsets: ";
272 count_type count = 0;
273 const count_type numRowsToPack = lclRowInds.extent (0);
275 if (numRowsToPack == 0) {
279 TEUCHOS_TEST_FOR_EXCEPTION
280 (rowOffsets.extent (0) <=
static_cast<size_type
> (1),
281 std::invalid_argument, prefix <<
"There is at least one row to pack, " 282 "but the graph has no rows. lclRowInds.extent(0) = " <<
283 numRowsToPack <<
", but rowOffsets.extent(0) = " <<
284 rowOffsets.extent (0) <<
" <= 1.");
285 TEUCHOS_TEST_FOR_EXCEPTION
286 (outputOffsets.extent (0) !=
287 static_cast<size_type
> (numRowsToPack + 1), std::invalid_argument,
288 prefix <<
"Output dimension does not match number of rows to pack. " 289 <<
"outputOffsets.extent(0) = " << outputOffsets.extent (0)
290 <<
" != lclRowInds.extent(0) + 1 = " 291 <<
static_cast<size_type
> (numRowsToPack + 1) <<
".");
292 TEUCHOS_TEST_FOR_EXCEPTION
293 (counts.extent (0) != numRowsToPack, std::invalid_argument,
294 prefix <<
"counts.extent(0) = " << counts.extent (0)
295 <<
" != numRowsToPack = " << numRowsToPack <<
".");
297 functor_type f (outputOffsets, counts, rowOffsets, lclRowInds, lclRowPids);
298 Kokkos::parallel_scan (range_type (0, numRowsToPack + 1), f);
301 const int errCode = f.getError ();
302 TEUCHOS_TEST_FOR_EXCEPTION
303 (errCode != 0, std::runtime_error, prefix <<
"parallel_scan error code " 304 << errCode <<
" != 0.");
308 for (LO k = 0; k < numRowsToPack; ++k) {
311 if (outputOffsets(numRowsToPack) != total) {
312 if (errStr.get () == NULL) {
313 errStr = std::unique_ptr<std::ostringstream> (
new std::ostringstream ());
315 std::ostringstream& os = *errStr;
317 <<
"outputOffsets(numRowsToPack=" << numRowsToPack <<
") " 318 << outputOffsets(numRowsToPack) <<
" != sum of counts = " 319 << total <<
"." << std::endl;
320 if (numRowsToPack != 0) {
322 if (numRowsToPack < static_cast<LO> (10)) {
323 os <<
"outputOffsets: [";
324 for (LO i = 0; i <= numRowsToPack; ++i) {
325 os << outputOffsets(i);
326 if (static_cast<LO> (i + 1) <= numRowsToPack) {
330 os <<
"]" << std::endl;
332 for (LO i = 0; i < numRowsToPack; ++i) {
334 if (static_cast<LO> (i + 1) < numRowsToPack) {
338 os <<
"]" << std::endl;
341 os <<
"outputOffsets(" << (numRowsToPack-1) <<
") = " 342 << outputOffsets(numRowsToPack-1) <<
"." << std::endl;
345 count = outputOffsets(numRowsToPack);
346 return {
false, errStr};
348 #endif // HAVE_TPETRA_DEBUG 352 using Tpetra::Details::getEntryOnHost;
353 return static_cast<count_type
> (getEntryOnHost (outputOffsets,
368 template<
class Packet,
370 class BufferDeviceType,
376 const Kokkos::View<Packet*, BufferDeviceType>& exports,
377 const InputLidsType& lids_in,
378 const InputPidsType& pids_in,
380 const size_t num_ent,
381 const bool pack_pids)
383 using LO =
typename LocalMapType::local_ordinal_type;
384 using GO =
typename LocalMapType::global_ordinal_type;
388 return static_cast<size_t>(0);
391 size_t num_ent_packed = num_ent;
393 num_ent_packed += num_ent;
398 for (
size_t k = 0; k < num_ent; ++k) {
399 const LO lid = lids_in[k];
400 const GO gid = col_map.getGlobalElement (lid);
401 exports(offset+k) = gid;
405 for (
size_t k = 0; k < num_ent; ++k) {
406 const LO lid = lids_in[k];
407 const int pid = pids_in[lid];
408 exports(offset+num_ent+k) =
static_cast<GO
>(pid);
412 return num_ent_packed;
415 template<
class Packet,
418 class BufferDeviceType>
419 struct PackCrsGraphFunctor {
420 using local_graph_type = LocalGraph;
425 using num_packets_per_lid_view_type =
426 Kokkos::View<const size_t*, BufferDeviceType>;
427 using offsets_view_type = Kokkos::View<const size_t*, BufferDeviceType>;
428 using exports_view_type = Kokkos::View<Packet*, BufferDeviceType>;
429 using export_lids_view_type =
431 using source_pids_view_type =
435 typename num_packets_per_lid_view_type::non_const_value_type;
436 using offset_type =
typename offsets_view_type::non_const_value_type;
437 using value_type = Kokkos::pair<int, LO>;
439 static_assert (std::is_same<LO, typename local_graph_type::data_type>::value,
440 "local_map_type::local_ordinal_type and " 441 "local_graph_type::data_type must be the same.");
443 local_graph_type local_graph;
444 local_map_type local_col_map;
445 exports_view_type exports;
446 num_packets_per_lid_view_type num_packets_per_lid;
447 export_lids_view_type export_lids;
448 source_pids_view_type source_pids;
449 offsets_view_type offsets;
452 PackCrsGraphFunctor(
const local_graph_type& local_graph_in,
453 const local_map_type& local_col_map_in,
454 const exports_view_type& exports_in,
455 const num_packets_per_lid_view_type& num_packets_per_lid_in,
456 const export_lids_view_type& export_lids_in,
457 const source_pids_view_type& source_pids_in,
458 const offsets_view_type& offsets_in,
459 const bool pack_pids_in) :
460 local_graph (local_graph_in),
461 local_col_map (local_col_map_in),
462 exports (exports_in),
463 num_packets_per_lid (num_packets_per_lid_in),
464 export_lids (export_lids_in),
465 source_pids (source_pids_in),
466 offsets (offsets_in),
467 pack_pids (pack_pids_in)
469 const LO numRows = local_graph_in.numRows ();
471 static_cast<LO
> (local_graph.row_map.extent (0));
472 TEUCHOS_TEST_FOR_EXCEPTION
473 (numRows != 0 && rowMapDim != numRows + static_cast<LO> (1),
474 std::logic_error,
"local_graph.row_map.extent(0) = " 475 << rowMapDim <<
" != numRows (= " << numRows <<
" ) + 1.");
478 KOKKOS_INLINE_FUNCTION
void init (value_type& dst)
const 480 using ::Tpetra::Details::OrdinalTraits;
481 dst = Kokkos::make_pair (0, OrdinalTraits<LO>::invalid ());
484 KOKKOS_INLINE_FUNCTION
void 485 join (
volatile value_type& dst,
const volatile value_type& src)
const 489 if (src.first != 0 && dst.first == 0) {
494 KOKKOS_INLINE_FUNCTION
495 void operator() (
const LO i, value_type& dst)
const 497 const size_t offset = offsets[i];
498 const LO export_lid = export_lids[i];
499 const size_t buf_size = exports.size();
500 const size_t num_packets_this_lid = num_packets_per_lid(i);
501 const size_t num_ent =
502 static_cast<size_t> (local_graph.row_map[export_lid+1]
503 - local_graph.row_map[export_lid]);
513 if (export_lid >= static_cast<LO>(local_graph.numRows())) {
514 if (dst.first != 0) {
515 dst = Kokkos::make_pair (1, i);
519 else if ((offset > buf_size || offset + num_packets_this_lid > buf_size)) {
520 if (dst.first != 0) {
521 dst = Kokkos::make_pair (2, i);
531 const auto row_beg = local_graph.row_map[export_lid];
532 const auto row_end = local_graph.row_map[export_lid + 1];
533 auto lids_in = Kokkos::subview (local_graph.entries,
534 Kokkos::make_pair (row_beg, row_end));
535 size_t num_ent_packed_this_row =
536 packRow (local_col_map, exports, lids_in,
537 source_pids, offset, num_ent, pack_pids);
538 if (num_ent_packed_this_row != num_packets_this_lid) {
539 if (dst.first != 0) {
540 dst = Kokkos::make_pair (3, i);
553 template<
class Packet,
556 class BufferDeviceType>
560 const Kokkos::View<Packet*, BufferDeviceType>& exports,
563 >::input_array_type& num_packets_per_lid,
566 >::input_array_type& export_lids,
569 >::input_array_type& source_pids,
570 const Kokkos::View<const size_t*, BufferDeviceType>& offsets,
571 const bool pack_pids)
574 using execution_space =
typename LocalGraph::device_type::execution_space;
575 using range_type = Kokkos::RangePolicy<execution_space, LO>;
576 const char prefix[] =
"Tpetra::Details::PackCrsGraphImpl::do_pack: ";
578 if (export_lids.extent (0) != 0) {
579 TEUCHOS_TEST_FOR_EXCEPTION
580 (static_cast<size_t> (offsets.extent (0)) !=
581 static_cast<size_t> (export_lids.extent (0) + 1),
582 std::invalid_argument, prefix <<
"offsets.extent(0) = " 583 << offsets.extent (0) <<
" != export_lids.extent(0) (= " 584 << export_lids.extent (0) <<
") + 1.");
585 TEUCHOS_TEST_FOR_EXCEPTION
586 (export_lids.extent (0) != num_packets_per_lid.extent (0),
587 std::invalid_argument, prefix <<
"export_lids.extent(0) = " <<
588 export_lids.extent (0) <<
" != num_packets_per_lid.extent(0) = " 589 << num_packets_per_lid.extent (0) <<
".");
593 TEUCHOS_TEST_FOR_EXCEPTION
594 (pack_pids && exports.extent (0) != 0 &&
595 source_pids.extent (0) == 0, std::invalid_argument, prefix <<
596 "pack_pids is true, and exports.extent(0) = " <<
597 exports.extent (0) <<
" != 0, meaning that we need to pack at " 598 "least one graph entry, but source_pids.extent(0) = 0.");
601 using pack_functor_type =
602 PackCrsGraphFunctor<Packet, LocalGraph,
LocalMap,
604 pack_functor_type f (local_graph, local_map, exports,
605 num_packets_per_lid, export_lids,
606 source_pids, offsets, pack_pids);
608 typename pack_functor_type::value_type result;
609 range_type range (0, num_packets_per_lid.extent (0));
610 Kokkos::parallel_reduce (range, f, result);
612 if (result.first != 0) {
615 std::ostringstream os;
616 if (result.first == 1) {
617 os <<
"invalid local row index";
619 else if (result.first == 2) {
620 os <<
"invalid offset";
622 TEUCHOS_TEST_FOR_EXCEPTION
623 (
true, std::runtime_error, prefix <<
"PackCrsGraphFunctor " 624 "reported error code " << result.first <<
" (" << os.str ()
625 <<
") for the first bad row " << result.second <<
".");
655 template<
typename LO,
typename GO,
typename NT>
666 >& num_packets_per_lid,
675 size_t& constant_num_packets,
676 const bool pack_pids)
680 using packet_type =
typename crs_graph_type::packet_type;
681 using buffer_device_type =
typename crs_graph_type::buffer_device_type;
682 using exports_view_type = Kokkos::DualView<packet_type*, buffer_device_type>;
683 using local_graph_device_type =
typename crs_graph_type::local_graph_device_type;
685 const char prefix[] =
"Tpetra::Details::packCrsGraph: ";
686 constexpr
bool debug =
false;
689 local_map_type local_col_map = sourceGraph.
getColMap ()->getLocalMap ();
694 constant_num_packets = 0;
696 const size_t num_export_lids (export_lids.extent (0));
697 TEUCHOS_TEST_FOR_EXCEPTION
698 (num_export_lids !=
size_t (num_packets_per_lid.extent (0)),
699 std::invalid_argument, prefix <<
"num_export_lids.extent(0) = " 700 << num_export_lids <<
" != num_packets_per_lid.extent(0) = " 701 << num_packets_per_lid.extent (0) <<
".");
702 if (num_export_lids != 0) {
703 TEUCHOS_TEST_FOR_EXCEPTION
704 (num_packets_per_lid.data () ==
nullptr, std::invalid_argument,
705 prefix <<
"num_export_lids = "<< num_export_lids <<
" != 0, but " 706 "num_packets_per_lid.data() = " 707 << num_packets_per_lid.data () <<
" == NULL.");
710 if (num_export_lids == 0) {
711 exports = exports_view_type (
"exports", 0);
716 View<size_t*, buffer_device_type> offsets (
"offsets", num_export_lids + 1);
722 local_graph.row_map, export_lids, export_pids);
725 if (count >
size_t (exports.extent (0))) {
726 exports = exports_view_type (
"exports", count);
728 std::ostringstream os;
729 os <<
"*** exports resized to " << count << std::endl;
730 std::cerr << os.str ();
734 std::ostringstream os;
735 os <<
"*** count: " << count <<
", exports.extent(0): " 736 << exports.extent (0) << std::endl;
737 std::cerr << os.str ();
743 TEUCHOS_TEST_FOR_EXCEPTION
744 (pack_pids && exports.extent (0) != 0 &&
745 export_pids.extent (0) == 0, std::invalid_argument, prefix <<
746 "pack_pids is true, and exports.extent(0) = " <<
747 exports.extent (0) <<
" != 0, meaning that we need to pack at least " 748 "one graph entry, but export_pids.extent(0) = 0.");
750 exports.modify_device ();
751 auto exports_d = exports.view_device ();
752 do_pack<packet_type, local_graph_device_type, local_map_type, buffer_device_type>
753 (local_graph, local_col_map, exports_d, num_packets_per_lid,
754 export_lids, export_pids, offsets, pack_pids);
760 template<
typename LO,
typename GO,
typename NT>
764 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
765 const Teuchos::ArrayView<const LO>& exportLIDs,
766 size_t& constantNumPackets)
768 using Kokkos::HostSpace;
769 using Kokkos::MemoryUnmanaged;
772 using packet_type =
typename crs_graph_type::packet_type;
773 using BDT =
typename crs_graph_type::buffer_device_type;
780 View<size_t*, BDT> num_packets_per_lid_d =
782 numPacketsPerLID.getRawPtr (),
783 numPacketsPerLID.size (),
false,
784 "num_packets_per_lid");
787 View<const LO*, BDT> export_lids_d =
789 exportLIDs.getRawPtr (),
790 exportLIDs.size (),
true,
792 View<const int*, BDT> export_pids_d;
793 Kokkos::DualView<packet_type*, BDT> exports_dv;
794 constexpr
bool pack_pids =
false;
798 typename decltype (num_packets_per_lid_d)::non_const_value_type,
800 "num_packets_per_lid_d's non_const_value_type should be size_t.");
803 typename decltype (num_packets_per_lid_d)::device_type,
805 "num_packets_per_lid_d's BDT should be size_t.");
808 typename decltype (export_lids_d)::device_type,
810 "export_lids_d's device_type should be BDT.");
813 typename decltype (export_pids_d)::non_const_value_type,
815 "export_pids_d's non_const_value_type should be int.");
818 typename decltype (export_pids_d)::device_type,
820 "export_pids_d's device_type should be BDT.");
822 PackCrsGraphImpl::packCrsGraph
823 (sourceGraph, exports_dv, num_packets_per_lid_d, export_lids_d,
824 export_pids_d, constantNumPackets, pack_pids);
828 View<size_t*, HostSpace, MemoryUnmanaged>
829 num_packets_per_lid_h (numPacketsPerLID.getRawPtr (),
830 numPacketsPerLID.size ());
838 if (static_cast<size_t> (exports.size ()) !=
839 static_cast<size_t> (exports_dv.extent (0))) {
840 exports.resize (exports_dv.extent (0));
842 View<packet_type*, HostSpace, MemoryUnmanaged>
843 exports_h (exports.getRawPtr (), exports.size ());
849 template<
typename LO,
typename GO,
typename NT>
852 const Kokkos::DualView<
856 const Kokkos::DualView<
866 > num_packets_per_lid,
867 size_t& constant_num_packets,
868 const bool pack_pids)
872 using BDT =
typename crs_graph_type::buffer_device_type;
873 using PT =
typename crs_graph_type::packet_type;
874 using exports_dual_view_type = Kokkos::DualView<PT*, BDT>;
875 using LGT =
typename crs_graph_type::local_graph_device_type;
876 using LMT =
typename crs_graph_type::map_type::local_map_type;
877 const char prefix[] =
"Tpetra::Details::packCrsGraphNew: ";
880 const LMT local_col_map = sourceGraph.
getColMap ()->getLocalMap ();
885 constant_num_packets = 0;
887 const size_t num_export_lids =
888 static_cast<size_t> (export_lids.extent (0));
889 TEUCHOS_TEST_FOR_EXCEPTION
891 static_cast<size_t> (num_packets_per_lid.extent (0)),
892 std::invalid_argument, prefix <<
"num_export_lids.extent(0) = " 893 << num_export_lids <<
" != num_packets_per_lid.extent(0) = " 894 << num_packets_per_lid.extent (0) <<
".");
895 TEUCHOS_TEST_FOR_EXCEPTION
896 (num_export_lids != 0 &&
897 num_packets_per_lid.view_device ().data () ==
nullptr,
898 std::invalid_argument, prefix <<
"num_export_lids = "<< num_export_lids
899 <<
" != 0, but num_packets_per_lid.view_device().data() = nullptr.");
901 if (num_export_lids == 0) {
902 exports = exports_dual_view_type ();
907 using offsets_type = Kokkos::View<size_t*, BDT>;
908 offsets_type offsets (
"offsets", num_export_lids + 1);
912 num_packets_per_lid.clear_sync_state ();
913 num_packets_per_lid.modify_device ();
914 using PackCrsGraphImpl::computeNumPacketsAndOffsets;
916 computeNumPacketsAndOffsets (offsets, num_packets_per_lid.view_device (),
918 export_lids.view_device (),
919 export_pids.view_device ());
922 if (count > static_cast<size_t> (exports.extent (0))) {
923 exports = exports_dual_view_type (
"exports", count);
929 TEUCHOS_TEST_FOR_EXCEPTION
930 (pack_pids && exports.extent (0) != 0 &&
931 export_pids.extent (0) == 0, std::invalid_argument, prefix <<
932 "pack_pids is true, and exports.extent(0) = " <<
933 exports.extent (0) <<
" != 0, meaning that we need to pack at least " 934 "one graph entry, but export_pids.extent(0) = 0.");
936 exports.modify_device ();
937 using PackCrsGraphImpl::do_pack;
938 do_pack<PT, LGT, LMT, BDT> (local_graph, local_col_map,
939 exports.view_device (),
940 num_packets_per_lid.view_device (),
941 export_lids.view_device (),
942 export_pids.view_device (),
946 template<
typename LO,
typename GO,
typename NT>
954 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
955 const Teuchos::ArrayView<const LO>& exportLIDs,
956 const Teuchos::ArrayView<const int>& sourcePIDs,
957 size_t& constantNumPackets)
959 using Kokkos::HostSpace;
960 using Kokkos::MemoryUnmanaged;
963 using buffer_device_type =
typename crs_graph_type::buffer_device_type;
969 View<size_t*, buffer_device_type> num_packets_per_lid_d =
971 numPacketsPerLID.getRawPtr (),
972 numPacketsPerLID.size (),
false,
973 "num_packets_per_lid");
977 View<const LO*, buffer_device_type> export_lids_d =
979 exportLIDs.getRawPtr (),
980 exportLIDs.size (),
true,
984 View<const int*, buffer_device_type> export_pids_d =
986 sourcePIDs.getRawPtr (),
987 sourcePIDs.size (),
true,
989 constexpr
bool pack_pids =
true;
990 PackCrsGraphImpl::packCrsGraph
991 (sourceGraph, exports_dv, num_packets_per_lid_d, export_lids_d,
992 export_pids_d, constantNumPackets, pack_pids);
996 View<size_t*, HostSpace, MemoryUnmanaged> num_packets_per_lid_h
997 (numPacketsPerLID.getRawPtr (), numPacketsPerLID.size ());
1004 #define TPETRA_DETAILS_PACKCRSGRAPH_INSTANT( LO, GO, NT ) \ 1006 Details::packCrsGraph<LO, GO, NT> ( \ 1007 const CrsGraph<LO, GO, NT>&, \ 1008 Teuchos::Array<CrsGraph<LO,GO,NT>::packet_type>&, \ 1009 const Teuchos::ArrayView<size_t>&, \ 1010 const Teuchos::ArrayView<const LO>&, \ 1013 Details::packCrsGraphNew<LO, GO, NT> ( \ 1014 const CrsGraph<LO, GO, NT>&, \ 1015 const Kokkos::DualView< \ 1017 CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1018 const Kokkos::DualView< \ 1020 CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1022 CrsGraph<LO,GO,NT>::packet_type*, \ 1023 CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1026 CrsGraph<LO,GO,NT>::buffer_device_type>, \ 1030 Details::packCrsGraphWithOwningPIDs<LO, GO, NT> ( \ 1031 const CrsGraph<LO, GO, NT>&, \ 1032 Kokkos::DualView<CrsGraph<LO,GO,NT>::packet_type*, CrsGraph<LO,GO,NT>::buffer_device_type>&, \ 1033 const Teuchos::ArrayView<size_t>&, \ 1034 const Teuchos::ArrayView<const LO>&, \ 1035 const Teuchos::ArrayView<const int>&, \ 1038 #endif // TPETRA_DETAILS_PACKCRSGRAPH_DEF_HPP Namespace Tpetra contains the class and methods constituting the Tpetra library.
GlobalOrdinal global_ordinal_type
The type of global indices.
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.
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)
Pack specified entries of the given local sparse graph for communication.
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...
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)
Pack specified entries of the given local sparse graph for communication.
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.
int getError() const
Host function for getting the error.
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 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)
Pack specified entries of the given local sparse graph for communication, for "new" DistObject interf...
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.
local_graph_device_type getLocalGraphDevice() const
Get the local graph.
Declaration and definition of Tpetra::Details::castAwayConstDualView, an implementation detail of Tpe...
Declaration and definition of Tpetra::Details::getEntryOnHost.
global_ordinal_type packet_type
Type of each entry of the DistObject communication buffer.
LocalOrdinal local_ordinal_type
The type of local indices.
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.