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
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};
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>&, \
Declaration of the Tpetra::CrsGraph class.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Import KokkosSparse::OrdinalTraits, a traits class for "invalid" (flag) values of integer types,...
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
Declaration and definition of Tpetra::Details::castAwayConstDualView, an implementation detail of Tpe...
Functions that wrap Kokkos::create_mirror_view, in order to avoid deep copies when not necessary,...
Declaration and definition of Tpetra::Details::getEntryOnHost.
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.
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.
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.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Teuchos::RCP< const map_type > getColMap() const override
Returns the Map that describes the column distribution in this graph.
global_ordinal_type packet_type
Type of each entry of the DistObject communication buffer.
typename dist_object_type::buffer_device_type buffer_device_type
Kokkos::Device specialization for communication buffers.
local_graph_device_type getLocalGraphDevice() const
Get the local graph.
"Local" part of Map suitable for Kokkos kernels.
LocalOrdinal local_ordinal_type
The type of local indices.
GlobalOrdinal global_ordinal_type
The type of global indices.
Compute the number of packets and offsets for the pack procedure.
int getError() const
Host function for getting the error.
Implementation details of Tpetra.
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.
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.
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...
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.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
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.
Traits class for packing / unpacking data of type T.