95 typedef typename Teuchos::ScalarTraits<Scalar>::coordinateType coordinate_type;
96 typedef Xpetra::MultiVector<coordinate_type, LO, GO, NO> RealValuedMultiVector;
97 typedef Xpetra::MultiVectorFactory<coordinate_type, LO, GO, NO> RealValuedMultiVectorFactory;
99 const ParameterList& pL = GetParameterList();
100 std::string nspName =
"Nullspace";
101 if (pL.isParameter(
"Nullspace name")) nspName = pL.get<std::string>(
"Nullspace name");
103 RCP<Matrix> Ptentative;
104 auto A = Get<RCP<Matrix>>(fineLevel,
"A");
105 auto aggregates = Get<RCP<Aggregates>>(fineLevel,
"Aggregates");
108 if (aggregates->GetNumGlobalAggregatesComputeIfNeeded() == 0) {
109 Ptentative = Teuchos::null;
110 Set(coarseLevel,
"P", Ptentative);
114 auto amalgInfo = Get<RCP<AmalgamationInfo>>(fineLevel,
"UnAmalgamationInfo");
115 auto fineNullspace = Get<RCP<MultiVector>>(fineLevel, nspName);
116 auto coarseMap = Get<RCP<const Map>>(fineLevel,
"CoarseMap");
117 RCP<RealValuedMultiVector> fineCoords;
118 if (bTransferCoordinates_) {
119 fineCoords = Get<RCP<RealValuedMultiVector>>(fineLevel,
"Coordinates");
124 RCP<const Teuchos::Comm<int>> nodeComm = Get<RCP<const Teuchos::Comm<int>>>(fineLevel,
"Node Comm");
125 Set<RCP<const Teuchos::Comm<int>>>(coarseLevel,
"Node Comm", nodeComm);
129 TEUCHOS_TEST_FOR_EXCEPTION(A->getDomainMap()->getLocalNumElements() != fineNullspace->getMap()->getLocalNumElements(),
132 RCP<MultiVector> coarseNullspace;
133 RCP<RealValuedMultiVector> coarseCoords;
135 if (bTransferCoordinates_) {
136 RCP<const Map> coarseCoordMap;
139 if (rcp_dynamic_cast<const StridedMap>(coarseMap) != Teuchos::null)
140 blkSize = rcp_dynamic_cast<const StridedMap>(coarseMap)->getFixedBlockSize();
145 coarseCoordMap = coarseMap;
151 coarseCoords = RealValuedMultiVectorFactory::Build(coarseCoordMap, fineCoords->getNumVectors(),
false);
154 auto uniqueMap = fineCoords->getMap();
155 RCP<RealValuedMultiVector> ghostedCoords = fineCoords;
156 if (aggregates->AggregatesCrossProcessors()) {
157 auto nonUniqueMap = aggregates->GetMap();
158 auto importer = ImportFactory::Build(uniqueMap, nonUniqueMap);
160 ghostedCoords = RealValuedMultiVectorFactory::Build(nonUniqueMap, fineCoords->getNumVectors(),
false);
161 ghostedCoords->doImport(*fineCoords, *importer, Xpetra::INSERT);
166 auto aggGraph = aggregates->GetGraph();
167 auto numAggs = aggGraph.numRows();
169 auto fineCoordsView = fineCoords->getLocalViewDevice(Tpetra::Access::ReadOnly);
170 auto coarseCoordsView = coarseCoords->getLocalViewDevice(Tpetra::Access::OverwriteAll);
176 const auto dim = fineCoords->getNumVectors();
178 typename AppendTrait<
decltype(fineCoordsView), Kokkos::RandomAccess>::type fineCoordsRandomView = fineCoordsView;
179 for (
size_t j = 0; j < dim; j++) {
180 Kokkos::parallel_for(
181 "MueLu::TentativeP::BuildCoords", Kokkos::RangePolicy<LocalOrdinal, execution_space>(0, numAggs),
182 KOKKOS_LAMBDA(
const LO i) {
186 auto aggregate = aggGraph.rowConst(i);
188 coordinate_type sum = 0.0;
189 for (
size_t colID = 0; colID < static_cast<size_t>(aggregate.length); colID++)
190 sum += fineCoordsRandomView(aggregate(colID), j);
192 coarseCoordsView(i, j) = sum / aggregate.length;
198 if (!aggregates->AggregatesCrossProcessors()) {
199 if (Xpetra::Helpers<SC, LO, GO, NO>::isTpetraBlockCrs(A)) {
200 BuildPuncoupledBlockCrs(coarseLevel, A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace,
203 BuildPuncoupled(coarseLevel, A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace, coarseLevel.
GetLevelID());
206 BuildPcoupled(A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace);
216 if (A->IsView(
"stridedMaps") ==
true)
217 Ptentative->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), coarseMap);
219 if (bTransferCoordinates_) {
220 Set(coarseLevel,
"Coordinates", coarseCoords);
222 Set(coarseLevel,
"Nullspace", coarseNullspace);
223 Set(coarseLevel,
"P", Ptentative);
225 if (pL.get<
bool>(
"sa: keep tentative prolongator")) {
231 RCP<ParameterList> params = rcp(
new ParameterList());
232 params->set(
"printLoadBalancingInfo",
true);
240 RCP<AmalgamationInfo> amalgInfo, RCP<MultiVector> fineNullspace,
241 RCP<const Map> coarseMap, RCP<Matrix>& Ptentative,
242 RCP<MultiVector>& coarseNullspace,
const int levelID)
const {
243 auto rowMap = A->getRowMap();
244 auto colMap = A->getColMap();
246 const size_t numRows = rowMap->getLocalNumElements();
247 const size_t NSDim = fineNullspace->getNumVectors();
249 typedef KokkosKernels::ArithTraits<SC> ATS;
250 using impl_SC =
typename ATS::val_type;
251 using impl_ATS = KokkosKernels::ArithTraits<impl_SC>;
252 const impl_SC zero = impl_ATS::zero();
253 const impl_SC one = impl_ATS::one();
255 const LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
260 aggGraph = aggregates->GetGraph();
262 auto aggRows = aggGraph.row_map;
263 auto aggCols = aggGraph.entries;
275 "MueLu: TentativePFactory_kokkos: for now works only with good maps "
276 "(i.e. \"matching\" row and column maps)");
290 amalgInfo->GetStridingInformation(fullBlockSize, blockID, stridingOffset, stridedBlockSize, indexBase);
291 GO globalOffset = amalgInfo->GlobalOffset();
294 auto procWinner = aggregates->GetProcWinner()->getLocalViewDevice(Tpetra::Access::ReadOnly);
295 auto vertex2AggId = aggregates->GetVertex2AggId()->getLocalViewDevice(Tpetra::Access::ReadOnly);
296 const size_t numAggregates = aggregates->GetNumAggregates();
298 int myPID = aggregates->GetMap()->getComm()->getRank();
303 typedef typename Aggregates::aggregates_sizes_type::non_const_type AggSizeType;
304 AggSizeType aggDofSizes;
306 if (stridedBlockSize == 1) {
310 aggDofSizes = AggSizeType(
"agg_dof_sizes", numAggregates + 1);
312 auto sizesConst = aggregates->ComputeAggregateSizes();
313 Kokkos::deep_copy(Kokkos::subview(aggDofSizes, Kokkos::make_pair(
static_cast<size_t>(1), numAggregates + 1)), sizesConst);
319 aggDofSizes = AggSizeType(
"agg_dof_sizes", numAggregates + 1);
321 auto nodeMap = aggregates->GetMap()->getLocalMap();
322 auto dofMap = colMap->getLocalMap();
324 Kokkos::parallel_for(
325 "MueLu:TentativePF:Build:compute_agg_sizes",
range_type(0, numAggregates),
326 KOKKOS_LAMBDA(
const LO agg) {
327 auto aggRowView = aggGraph.rowConst(agg);
330 for (LO colID = 0; colID < aggRowView.length; colID++) {
331 GO nodeGID = nodeMap.getGlobalElement(aggRowView(colID));
333 for (LO k = 0; k < stridedBlockSize; k++) {
334 GO dofGID = (nodeGID - indexBase) * fullBlockSize + k + indexBase + globalOffset + stridingOffset;
336 if (dofMap.getLocalElement(dofGID) != INVALID)
340 aggDofSizes(agg + 1) = size;
348 Kokkos::parallel_reduce(
"MueLu:TentativePF:Build:max_agg_size",
range_type(0, aggDofSizes.extent(0)), reduceMax, maxAggSize);
352 Kokkos::parallel_scan(
353 "MueLu:TentativePF:Build:aggregate_sizes:stage1_scan",
range_type(0, numAggregates + 1),
354 KOKKOS_LAMBDA(
const LO i, LO& update,
const bool& final_pass) {
355 update += aggDofSizes(i);
357 aggDofSizes(i) = update;
362 Kokkos::View<LO*, DeviceType> agg2RowMapLO(Kokkos::ViewAllocateWithoutInitializing(
"agg2row_map_LO"), numRows);
366 AggSizeType aggOffsets(Kokkos::ViewAllocateWithoutInitializing(
"aggOffsets"), numAggregates);
367 Kokkos::deep_copy(aggOffsets, Kokkos::subview(aggDofSizes, Kokkos::make_pair(
static_cast<size_t>(0), numAggregates)));
369 Kokkos::parallel_for(
370 "MueLu:TentativePF:Build:createAgg2RowMap",
range_type(0, vertex2AggId.extent(0)),
371 KOKKOS_LAMBDA(
const LO lnode) {
372 if (procWinner(lnode, 0) == myPID) {
374 auto aggID = vertex2AggId(lnode, 0);
376 auto offset = Kokkos::atomic_fetch_add(&aggOffsets(aggID), stridedBlockSize);
380 for (LO k = 0; k < stridedBlockSize; k++)
381 agg2RowMapLO(offset + k) = lnode * stridedBlockSize + k;
388 coarseNullspace = MultiVectorFactory::Build(coarseMap, NSDim,
true);
391 auto fineNS = fineNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
392 auto coarseNS = coarseNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
396 typedef typename Xpetra::Matrix<SC, LO, GO, NO>::local_matrix_device_type local_matrix_type;
397 typedef typename local_matrix_type::row_map_type::non_const_type rows_type;
398 typedef typename local_matrix_type::index_type::non_const_type cols_type;
399 typedef typename local_matrix_type::values_type::non_const_type vals_type;
402 typedef Kokkos::View<int[10], DeviceType> status_type;
403 status_type status(
"status");
405 typename AppendTrait<
decltype(fineNS), Kokkos::RandomAccess>::type fineNSRandom = fineNS;
408 const ParameterList& pL = GetParameterList();
409 const bool& doQRStep = pL.get<
bool>(
"tentative: calculate qr");
411 GetOStream(
Runtime1) <<
"TentativePFactory : bypassing local QR phase" << std::endl;
413 GetOStream(
Warnings0) <<
"TentativePFactor : for nontrivial nullspace, this may degrade performance" << std::endl;
416 size_t nnzEstimate = numRows * NSDim;
417 rows_type rowsAux(Kokkos::ViewAllocateWithoutInitializing(
"Ptent_aux_rows"), numRows + 1);
418 cols_type colsAux(Kokkos::ViewAllocateWithoutInitializing(
"Ptent_aux_cols"), nnzEstimate);
419 vals_type valsAux(
"Ptent_aux_vals", nnzEstimate);
420 rows_type rows(
"Ptent_rows", numRows + 1);
427 Kokkos::parallel_for(
428 "MueLu:TentativePF:BuildPuncoupled:for1",
range_type(0, numRows + 1),
429 KOKKOS_LAMBDA(
const LO row) {
430 rowsAux(row) = row * NSDim;
432 Kokkos::deep_copy(colsAux, INVALID);
447 const Kokkos::TeamPolicy<execution_space> policy(numAggregates, 1);
450 Kokkos::parallel_for(
451 "MueLu:TentativePF:BuildUncoupled:main_loop", policy,
452 KOKKOS_LAMBDA(
const typename Kokkos::TeamPolicy<execution_space>::member_type& thread) {
453 auto agg = thread.league_rank();
456 LO aggSize = aggRows(agg + 1) - aggRows(agg);
461 auto norm = impl_ATS::magnitude(zero);
466 for (
decltype(aggSize) k = 0; k < aggSize; k++) {
467 auto dnorm = impl_ATS::magnitude(fineNSRandom(agg2RowMapLO(aggRows(agg) + k), 0));
468 norm += dnorm * dnorm;
474 statusAtomic(1) =
true;
479 coarseNS(agg, 0) = norm;
482 for (
decltype(aggSize) k = 0; k < aggSize; k++) {
483 LO localRow = agg2RowMapLO(aggRows(agg) + k);
484 impl_SC localVal = fineNSRandom(agg2RowMapLO(aggRows(agg) + k), 0) / norm;
486 rows(localRow + 1) = 1;
487 colsAux(localRow) = agg;
488 valsAux(localRow) = localVal;
492 typename status_type::host_mirror_type statusHost = Kokkos::create_mirror_view(status);
493 Kokkos::deep_copy(statusHost, status);
494 for (
decltype(statusHost.size()) i = 0; i < statusHost.size(); i++)
496 std::ostringstream oss;
497 oss <<
"MueLu::TentativePFactory::MakeTentative: ";
499 case 0: oss <<
"!goodMap is not implemented";
break;
500 case 1: oss <<
"fine level NS part has a zero column";
break;
506 Kokkos::parallel_for(
507 "MueLu:TentativePF:BuildUncoupled:main_loop_noqr", policy,
508 KOKKOS_LAMBDA(
const typename Kokkos::TeamPolicy<execution_space>::member_type& thread) {
509 auto agg = thread.league_rank();
512 LO aggSize = aggRows(agg + 1) - aggRows(agg);
515 coarseNS(agg, 0) = one;
518 for (
decltype(aggSize) k = 0; k < aggSize; k++) {
519 LO localRow = agg2RowMapLO(aggRows(agg) + k);
520 impl_SC localVal = fineNSRandom(agg2RowMapLO(aggRows(agg) + k), 0);
522 rows(localRow + 1) = 1;
523 colsAux(localRow) = agg;
524 valsAux(localRow) = localVal;
529 Kokkos::parallel_reduce(
530 "MueLu:TentativeP:CountNNZ",
range_type(0, numRows + 1),
531 KOKKOS_LAMBDA(
const LO i,
size_t& nnz_count) {
532 nnz_count += rows(i);
550 Kokkos::TeamPolicy<execution_space> policy(numAggregates, 1);
552 decltype(aggDofSizes ),
decltype(maxAggSize),
decltype(agg2RowMapLO),
553 decltype(statusAtomic),
decltype(rows),
decltype(rowsAux),
decltype(colsAux),
555 int scratchLevel = -1;
557 using shared_matrix =
typename LocalQrFunctorType::shared_matrix;
558 using shared_vector =
typename LocalQrFunctorType::shared_vector;
560 int n = fineNSRandom.extent(1);
561 int size = shared_matrix::shmem_size(m, n) +
562 shared_matrix::shmem_size(m, m) +
563 shared_vector::shmem_size(m) +
564 shared_vector::shmem_size(n);
566 if (size < policy.scratch_size_max((
int)0))
568 else if (size < policy.scratch_size_max((
int)1))
571 throw Exceptions::RuntimeError(
"Neither L0 scratch memory (max size " + std::to_string(policy.scratch_size_max((
int)0)) +
572 "), nor L1 scratch memory (max size " + std::to_string(policy.scratch_size_max((
int)1)) +
573 ") is large enough for requested allocation of size " + std::to_string(size));
574 policy.set_scratch_size(scratchLevel, Kokkos::PerTeam(size));
576 LocalQrFunctorType localQRFunctor(fineNSRandom, coarseNS, aggDofSizes, maxAggSize, agg2RowMapLO, statusAtomic,
577 rows, rowsAux, colsAux, valsAux, doQRStep, scratchLevel);
579 Kokkos::parallel_reduce(
"MueLu:TentativePF:BuildUncoupled:main_qr_loop", policy, localQRFunctor, nnz);
582 typename status_type::host_mirror_type statusHost = Kokkos::create_mirror_view(status);
583 Kokkos::deep_copy(statusHost, status);
584 for (
decltype(statusHost.size()) i = 0; i < statusHost.size(); i++)
586 std::ostringstream oss;
587 oss <<
"MueLu::TentativePFactory::MakeTentative: ";
589 case 0: oss <<
"!goodMap is not implemented";
break;
590 case 1: oss <<
"fine level NS part has a zero column";
break;
603 if (nnz != nnzEstimate) {
608 Kokkos::parallel_scan(
609 "MueLu:TentativePF:Build:compress_rows",
range_type(0, numRows + 1),
610 KOKKOS_LAMBDA(
const LO i, LO& upd,
const bool&
final) {
620 cols = cols_type(
"Ptent_cols", nnz);
621 vals = vals_type(
"Ptent_vals", nnz);
626 Kokkos::parallel_for(
627 "MueLu:TentativePF:Build:compress_cols_vals",
range_type(0, numRows),
628 KOKKOS_LAMBDA(
const LO i) {
629 LO rowStart = rows(i);
632 for (
auto j = rowsAux(i); j < rowsAux(i + 1); j++)
633 if (colsAux(j) != INVALID) {
634 cols(rowStart + lnnz) = colsAux(j);
635 vals(rowStart + lnnz) = valsAux(j);
647 GetOStream(
Runtime1) <<
"TentativePFactory : aggregates do not cross process boundaries" << std::endl;
653 local_matrix_type lclMatrix = local_matrix_type(
"A", numRows, coarseMap->getLocalNumElements(), nnz, vals, rows, cols);
656 RCP<ParameterList> FCparams;
657 if (pL.isSublist(
"matrixmatrix: kernel params"))
658 FCparams = rcp(
new ParameterList(pL.sublist(
"matrixmatrix: kernel params")));
660 FCparams = rcp(
new ParameterList);
663 FCparams->set(
"compute global constants", FCparams->get(
"compute global constants",
false));
664 FCparams->set(
"Timer Label", std::string(
"MueLu::TentativeP-") +
toString(levelID));
666 auto PtentCrs = CrsMatrixFactory::Build(lclMatrix, rowMap, coarseMap, coarseMap, A->getDomainMap());
667 Ptentative = rcp(
new CrsMatrixWrap(PtentCrs));
674 RCP<AmalgamationInfo> amalgInfo, RCP<MultiVector> fineNullspace,
675 RCP<const Map> coarsePointMap, RCP<Matrix>& Ptentative,
676 RCP<MultiVector>& coarseNullspace,
const int levelID)
const {
686 RCP<const Map> rowMap = A->getRowMap();
687 RCP<const Map> rangeMap = A->getRangeMap();
688 RCP<const Map> colMap = A->getColMap();
690 const size_t numFineBlockRows = rowMap->getLocalNumElements();
694 const LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
696 typedef KokkosKernels::ArithTraits<SC> ATS;
697 using impl_SC =
typename ATS::val_type;
698 using impl_ATS = KokkosKernels::ArithTraits<impl_SC>;
699 const impl_SC one = impl_ATS::one();
702 const size_t NSDim = fineNullspace->getNumVectors();
703 auto aggSizes = aggregates->ComputeAggregateSizes();
708 aggGraph = aggregates->GetGraph();
710 auto aggRows = aggGraph.row_map;
711 auto aggCols = aggGraph.entries;
717 const size_t numCoarseBlockRows = coarsePointMap->getLocalNumElements() / NSDim;
718 RCP<const Map> coarseBlockMap = MapFactory::Build(coarsePointMap->lib(),
719 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
721 coarsePointMap->getIndexBase(),
722 coarsePointMap->getComm());
724 const ParameterList& pL = GetParameterList();
734 "MueLu: TentativePFactory_kokkos: for now works only with good maps "
735 "(i.e. \"matching\" row and column maps)");
749 amalgInfo->GetStridingInformation(fullBlockSize, blockID, stridingOffset, stridedBlockSize, indexBase);
753 auto procWinner = aggregates->GetProcWinner()->getLocalViewDevice(Tpetra::Access::ReadOnly);
754 auto vertex2AggId = aggregates->GetVertex2AggId()->getLocalViewDevice(Tpetra::Access::ReadOnly);
755 const size_t numAggregates = aggregates->GetNumAggregates();
757 int myPID = aggregates->GetMap()->getComm()->getRank();
762 typedef typename Aggregates::aggregates_sizes_type::non_const_type AggSizeType;
763 AggSizeType aggDofSizes;
769 aggDofSizes = AggSizeType(
"agg_dof_sizes", numAggregates + 1);
771 Kokkos::deep_copy(Kokkos::subview(aggDofSizes, Kokkos::make_pair(
static_cast<size_t>(1), numAggregates + 1)), aggSizes);
778 Kokkos::parallel_reduce(
"MueLu:TentativePF:Build:max_agg_size",
range_type(0, aggDofSizes.extent(0)), reduceMax, maxAggSize);
782 Kokkos::parallel_scan(
783 "MueLu:TentativePF:Build:aggregate_sizes:stage1_scan",
range_type(0, numAggregates + 1),
784 KOKKOS_LAMBDA(
const LO i, LO& update,
const bool& final_pass) {
785 update += aggDofSizes(i);
787 aggDofSizes(i) = update;
792 Kokkos::View<LO*, DeviceType> aggToRowMapLO(Kokkos::ViewAllocateWithoutInitializing(
"aggtorow_map_LO"), numFineBlockRows);
796 AggSizeType aggOffsets(Kokkos::ViewAllocateWithoutInitializing(
"aggOffsets"), numAggregates);
797 Kokkos::deep_copy(aggOffsets, Kokkos::subview(aggDofSizes, Kokkos::make_pair(
static_cast<size_t>(0), numAggregates)));
799 Kokkos::parallel_for(
800 "MueLu:TentativePF:Build:createAgg2RowMap",
range_type(0, vertex2AggId.extent(0)),
801 KOKKOS_LAMBDA(
const LO lnode) {
802 if (procWinner(lnode, 0) == myPID) {
804 auto aggID = vertex2AggId(lnode, 0);
806 auto offset = Kokkos::atomic_fetch_add(&aggOffsets(aggID), stridedBlockSize);
810 for (LO k = 0; k < stridedBlockSize; k++)
811 aggToRowMapLO(offset + k) = lnode * stridedBlockSize + k;
818 coarseNullspace = MultiVectorFactory::Build(coarsePointMap, NSDim,
true);
821 auto fineNS = fineNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
822 auto coarseNS = coarseNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
824 typedef typename Xpetra::Matrix<SC, LO, GO, NO>::local_matrix_device_type local_matrix_type;
825 typedef typename local_matrix_type::row_map_type::non_const_type rows_type;
826 typedef typename local_matrix_type::index_type::non_const_type cols_type;
830 typedef Kokkos::View<int[10], DeviceType> status_type;
831 status_type status(
"status");
833 typename AppendTrait<
decltype(fineNS), Kokkos::RandomAccess>::type fineNSRandom = fineNS;
837 GetOStream(
Runtime1) <<
"TentativePFactory : bypassing local QR phase" << std::endl;
843 rows_type ia(Kokkos::ViewAllocateWithoutInitializing(
"BlockGraph_rowptr"), numFineBlockRows + 1);
844 cols_type ja(Kokkos::ViewAllocateWithoutInitializing(
"BlockGraph_colind"), numFineBlockRows);
846 Kokkos::parallel_for(
847 "MueLu:TentativePF:BlockCrs:graph_init",
range_type(0, numFineBlockRows),
848 KOKKOS_LAMBDA(
const LO j) {
852 if (j == (LO)numFineBlockRows - 1)
853 ia[numFineBlockRows] = numFineBlockRows;
857 const Kokkos::TeamPolicy<execution_space> policy(numAggregates, 1);
858 Kokkos::parallel_for(
859 "MueLu:TentativePF:BlockCrs:fillGraph", policy,
860 KOKKOS_LAMBDA(
const typename Kokkos::TeamPolicy<execution_space>::member_type& thread) {
861 auto agg = thread.league_rank();
862 Xpetra::global_size_t offset = agg;
865 LO aggSize = aggRows(agg + 1) - aggRows(agg);
867 for (LO j = 0; j < aggSize; j++) {
869 const LO localRow = aggToRowMapLO[aggDofSizes[agg] + j];
870 const size_t rowStart = ia[localRow];
871 ja[rowStart] = offset;
881 rows_type i_temp(Kokkos::ViewAllocateWithoutInitializing(
"BlockGraph_rowptr"), numFineBlockRows + 1);
883 Kokkos::parallel_scan(
884 "MueLu:TentativePF:BlockCrs:compress_rows",
range_type(0, numFineBlockRows),
885 KOKKOS_LAMBDA(
const LO i, LO& upd,
const bool&
final) {
888 for (
auto j = ia[i]; j < ia[i + 1]; j++)
889 if (ja[j] != INVALID)
891 if (
final && i == (LO)numFineBlockRows - 1)
892 i_temp[numFineBlockRows] = upd;
896 cols_type j_temp(Kokkos::ViewAllocateWithoutInitializing(
"BlockGraph_colind"), nnz);
898 Kokkos::parallel_for(
899 "MueLu:TentativePF:BlockCrs:compress_cols",
range_type(0, numFineBlockRows),
900 KOKKOS_LAMBDA(
const LO i) {
901 size_t rowStart = i_temp[i];
903 for (
auto j = ia[i]; j < ia[i + 1]; j++)
904 if (ja[j] != INVALID) {
905 j_temp[rowStart + lnnz] = ja[j];
914 RCP<CrsGraph> BlockGraph = CrsGraphFactory::Build(rowMap, coarseBlockMap, ia, ja);
918 RCP<ParameterList> FCparams;
919 if (pL.isSublist(
"matrixmatrix: kernel params"))
920 FCparams = rcp(
new ParameterList(pL.sublist(
"matrixmatrix: kernel params")));
922 FCparams = rcp(
new ParameterList);
924 FCparams->set(
"compute global constants", FCparams->get(
"compute global constants",
false));
925 std::string levelIDs =
toString(levelID);
926 FCparams->set(
"Timer Label", std::string(
"MueLu::TentativeP-") + levelIDs);
927 RCP<const Export> dummy_e;
928 RCP<const Import> dummy_i;
929 BlockGraph->expertStaticFillComplete(coarseBlockMap, rowMap, dummy_i, dummy_e, FCparams);
939 RCP<Xpetra::CrsMatrix<SC, LO, GO, NO>> P_xpetra = Xpetra::CrsMatrixFactory<SC, LO, GO, NO>::BuildBlock(BlockGraph, coarsePointMap, rangeMap, NSDim);
940 RCP<Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO>> P_tpetra = rcp_dynamic_cast<Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO>>(P_xpetra);
941 if (P_tpetra.is_null())
throw std::runtime_error(
"BuildPUncoupled: Matrix factory did not return a Tpetra::BlockCrsMatrix");
942 RCP<CrsMatrixWrap> P_wrap = rcp(
new CrsMatrixWrap(P_xpetra));
944 auto values = P_tpetra->getTpetra_BlockCrsMatrix()->getValuesDeviceNonConst();
945 const LO stride = NSDim * NSDim;
947 Kokkos::parallel_for(
948 "MueLu:TentativePF:BlockCrs:main_loop_noqr", policy,
949 KOKKOS_LAMBDA(
const typename Kokkos::TeamPolicy<execution_space>::member_type& thread) {
950 auto agg = thread.league_rank();
953 LO aggSize = aggRows(agg + 1) - aggRows(agg);
954 Xpetra::global_size_t offset = agg * NSDim;
957 for (LO j = 0; j < aggSize; j++) {
958 LO localBlockRow = aggToRowMapLO(aggRows(agg) + j);
959 LO rowStart = localBlockRow * stride;
960 for (LO r = 0; r < (LO)NSDim; r++) {
961 LO localPointRow = localBlockRow * NSDim + r;
962 for (LO c = 0; c < (LO)NSDim; c++) {
963 values[rowStart + r * NSDim + c] = fineNSRandom(localPointRow, c);
969 for (LO j = 0; j < (LO)NSDim; j++)
970 coarseNS(offset + j, j) = one;