275 using Teuchos::Array;
276 using Teuchos::ArrayView;
279 using Teuchos::REDUCE_SUM;
280 using Teuchos::reduceAll;
282 size_t NumIn, NumL, NumU;
285 constructOverlapGraph();
288 const int MaxNumIndices = OverlapGraph_->getLocalMaxNumRowEntries ();
292 const int NumMyRows = OverlapGraph_->getRowMap ()->getLocalNumElements ();
294 using device_type =
typename node_type::device_type;
295 using execution_space =
typename device_type::execution_space;
296 using dual_view_type = Kokkos::DualView<size_t*,device_type>;
297 dual_view_type numEntPerRow_dv(
"numEntPerRow",NumMyRows);
298 Tpetra::Details::WrappedDualView<dual_view_type> numEntPerRow(numEntPerRow_dv);
300 const auto overalloc = Overalloc_;
301 const auto levelfill = LevelFill_;
304 auto numEntPerRow_d = numEntPerRow.getDeviceView(Tpetra::Access::OverwriteAll);
305 auto localOverlapGraph = OverlapGraph_->getLocalGraphDevice();
306 Kokkos::parallel_for(
"CountOverlapGraphRowEntries",
307 Kokkos::RangePolicy<execution_space>(0, NumMyRows),
308 KOKKOS_LAMBDA(
const int i)
311 int RowMaxNumIndices = localOverlapGraph.rowConst(i).length;
312 numEntPerRow_d(i) = (levelfill == 0) ? RowMaxNumIndices
313 : Kokkos::ceil(
static_cast<double>(RowMaxNumIndices)
314 * Kokkos::pow(overalloc, levelfill));
322 Teuchos::ArrayView<const size_t> a_numEntPerRow(numEntPerRow.getHostView(Tpetra::Access::ReadOnly).data(),NumMyRows);
324 OverlapGraph_->getRowMap (),
327 OverlapGraph_->getRowMap (),
330 Array<local_ordinal_type> L (MaxNumIndices);
331 Array<local_ordinal_type> U (MaxNumIndices);
337 for (
int i = 0; i< NumMyRows; ++i) {
338 local_inds_host_view_type my_indices;
339 OverlapGraph_->getLocalRowView (i, my_indices);
346 NumIn = my_indices.size();
348 for (
size_t j = 0; j < NumIn; ++j) {
349 const local_ordinal_type k = my_indices[j];
373 L_Graph_->insertLocalIndices (i, NumL, L.data());
376 U_Graph_->insertLocalIndices (i, NumU, U.data());
380 if (LevelFill_ > 0) {
382 RCP<const map_type> L_DomainMap = OverlapGraph_->getRowMap ();
383 RCP<const map_type> L_RangeMap = Graph_->getRangeMap ();
384 RCP<const map_type> U_DomainMap = Graph_->getDomainMap ();
385 RCP<const map_type> U_RangeMap = OverlapGraph_->getRowMap ();
386 RCP<Teuchos::ParameterList> params = Teuchos::parameterList ();
387 params->set (
"Optimize Storage",
false);
388 L_Graph_->fillComplete (L_DomainMap, L_RangeMap, params);
389 U_Graph_->fillComplete (U_DomainMap, U_RangeMap, params);
390 L_Graph_->resumeFill ();
391 U_Graph_->resumeFill ();
397 int MaxRC = NumMyRows;
398 std::vector<std::vector<int> > Levels(MaxRC);
399 std::vector<int> LinkList(MaxRC);
400 std::vector<int> CurrentLevel(MaxRC);
401 Array<local_ordinal_type> CurrentRow (MaxRC + 1);
402 std::vector<int> LevelsRowU(MaxRC);
405 for (
int i = 0; i < NumMyRows; ++i) {
410 size_t LenL = L_Graph_->getNumEntriesInLocalRow(i);
411 size_t LenU = U_Graph_->getNumEntriesInLocalRow(i);
412 size_t Len = LenL + LenU + 1;
413 CurrentRow.resize(Len);
414 nonconst_local_inds_host_view_type CurrentRow_view(CurrentRow.data(),CurrentRow.size());
415 L_Graph_->getLocalRowCopy(i, CurrentRow_view, LenL);
416 CurrentRow[LenL] = i;
418 ArrayView<local_ordinal_type> URowView = CurrentRow.view (LenL+1,LenU);
419 nonconst_local_inds_host_view_type URowView_v(URowView.data(),URowView.size());
422 U_Graph_->getLocalRowCopy (i, URowView_v, LenU);
427 for (
size_t j=0; j<Len-1; j++) {
428 LinkList[CurrentRow[j]] = CurrentRow[j+1];
429 CurrentLevel[CurrentRow[j]] = 0;
432 LinkList[CurrentRow[Len-1]] = NumMyRows;
433 CurrentLevel[CurrentRow[Len-1]] = 0;
437 First = CurrentRow[0];
440 int PrevInList = Next;
441 int NextInList = LinkList[Next];
444 local_inds_host_view_type IndicesU;
445 U_Graph_->getLocalRowView (RowU, IndicesU);
447 int LengthRowU = IndicesU.size ();
453 for (ii = 0; ii < LengthRowU; ) {
454 int CurInList = IndicesU[ii];
455 if (CurInList < NextInList) {
457 int NewLevel = CurrentLevel[RowU] + Levels[RowU][ii+1] + 1;
458 if (NewLevel <= LevelFill_) {
459 LinkList[PrevInList] = CurInList;
460 LinkList[CurInList] = NextInList;
461 PrevInList = CurInList;
462 CurrentLevel[CurInList] = NewLevel;
466 else if (CurInList == NextInList) {
467 PrevInList = NextInList;
468 NextInList = LinkList[PrevInList];
469 int NewLevel = CurrentLevel[RowU] + Levels[RowU][ii+1] + 1;
470 CurrentLevel[CurInList] = std::min (CurrentLevel[CurInList],
475 PrevInList = NextInList;
476 NextInList = LinkList[PrevInList];
479 Next = LinkList[Next];
483 CurrentRow.resize(0);
489 CurrentRow.push_back(Next);
490 Next = LinkList[Next];
496 L_Graph_->removeLocalIndices (i);
497 if (CurrentRow.size() > 0) {
498 L_Graph_->insertLocalIndices (i, CurrentRow.size(),CurrentRow.data());
503 TEUCHOS_TEST_FOR_EXCEPTION(
504 Next != i, std::runtime_error,
505 "Ifpack2::IlukGraph::initialize: FATAL: U has zero diagonal")
507 LevelsRowU[0] = CurrentLevel[Next];
508 Next = LinkList[Next];
511 CurrentRow.resize(0);
514 while (Next < NumMyRows) {
515 LevelsRowU[LenU+1] = CurrentLevel[Next];
516 CurrentRow.push_back (Next);
518 Next = LinkList[Next];
525 U_Graph_->removeLocalIndices (i);
527 U_Graph_->insertLocalIndices (i, CurrentRow.size(),CurrentRow.data());
531 Levels[i] = std::vector<int> (LenU+1);
532 for (
size_t jj=0; jj<LenU+1; jj++) {
533 Levels[i][jj] = LevelsRowU[jj];
537 catch (std::runtime_error &e) {
539 auto numEntPerRow_d = numEntPerRow.getDeviceView(Tpetra::Access::OverwriteAll);
540 Kokkos::parallel_for(
"CountOverlapGraphRowEntries",
541 Kokkos::RangePolicy<execution_space>(0, NumMyRows),
542 KOKKOS_LAMBDA(
const int i)
544 const auto numRowEnt = numEntPerRow_d(i);
545 numEntPerRow_d(i) = ceil(
static_cast<double>((numRowEnt != 0 ? numRowEnt : 1)) * overalloc);
548 const int localInsertError = insertError ? 1 : 0;
549 int globalInsertError = 0;
550 reduceAll (* (OverlapGraph_->getRowMap ()->getComm ()), REDUCE_SUM, 1,
551 &localInsertError, &globalInsertError);
552 insertError = globalInsertError > 0;
554 }
while (insertError);
557 RCP<const map_type> L_DomainMap = OverlapGraph_->getRowMap ();
558 RCP<const map_type> L_RangeMap = Graph_->getRangeMap ();
559 RCP<const map_type> U_DomainMap = Graph_->getDomainMap ();
560 RCP<const map_type> U_RangeMap = OverlapGraph_->getRowMap ();
561 L_Graph_->fillComplete (L_DomainMap, L_RangeMap);
562 U_Graph_->fillComplete (U_DomainMap, U_RangeMap);
564 reduceAll<int, size_t> (* (L_DomainMap->getComm ()), REDUCE_SUM, 1,
565 &NumMyDiagonals_, &NumGlobalDiagonals_);