141#ifdef HAVE_AMESOS2_TIMERS
142 Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_);
145 if (data_.numeric_ != NULL) {
146 ::KLU2::klu_free_numeric<klu2_dtype, local_ordinal_type>
147 (&(data_.numeric_), &(data_.common_));
150 if ( single_proc_optimization() ) {
151 host_ordinal_type_array host_row_ptr_view;
152 host_ordinal_type_array host_cols_view;
153 this->matrixA_->returnRowPtr_kokkos_view(host_row_ptr_view);
154 this->matrixA_->returnColInd_kokkos_view(host_cols_view);
155 this->matrixA_->returnValues_kokkos_view(host_nzvals_view_);
156 klu2_dtype * pValues = function_map::convert_scalar(host_nzvals_view_.data());
157 data_.numeric_ = ::KLU2::klu_factor<klu2_dtype, local_ordinal_type>
158 (host_row_ptr_view.data(), host_cols_view.data(), pValues,
159 data_.symbolic_, &(data_.common_));
162 klu2_dtype * pValues = function_map::convert_scalar(host_nzvals_view_.data());
163 data_.numeric_ = ::KLU2::klu_factor<klu2_dtype, local_ordinal_type>
164 (host_col_ptr_view_.data(), host_rows_view_.data(), pValues,
165 data_.symbolic_, &(data_.common_));
173 if(data_.numeric_ ==
nullptr) {
175 if(debug_level_ > 0) {
176 std::cout <<
" ** Amesos2::KLU2::numericFactorization failed with status = ";
177 if(data_.common_.status == KLU_OK)
178 std::cout <<
"KLU_OK **\n";
179 else if (data_.common_.status == KLU_SINGULAR)
180 std::cout <<
"KLU_SINGULAR **\n";
181 else if (data_.common_.status == KLU_OUT_OF_MEMORY)
182 std::cout <<
"KLU_OUT_OF_MEMORY **\n";
183 else if (data_.common_.status == KLU_INVALID)
184 std::cout <<
"KLU_INVALID **\n";
185 else if (data_.common_.status == KLU_TOO_LARGE)
186 std::cout <<
"KLU_TOO_LARGE **\n";
193 this->setNnzLU( as<size_t>((data_.numeric_)->lnz) + as<size_t>((data_.numeric_)->unz) );
200 Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info);
202 TEUCHOS_TEST_FOR_EXCEPTION(info > 0, std::runtime_error,
203 "KLU2 numeric factorization failed(info="+std::to_string(info)+
")");
217 const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
218 const size_t nrhs = X->getGlobalNumVectors();
219 if (debug_level_ > 0) {
220 if (this->root_) std::cout <<
"\n == Amesos2_KLU2::solve_impl ==" << std::endl;
221 if (debug_level_ == 1) {
224 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
225 if (!is_null(B->getMap())) B->getMap()->describe(*fancy, Teuchos::VERB_EXTREME);
226 std::cout << std::endl;
227 B->describe(*fancy, Teuchos::VERB_EXTREME);
233 bool use_gather = use_gather_;
234 use_gather = (use_gather && this->matrixA_->getComm()->getSize() > 1);
235 use_gather = (use_gather && (std::is_same<vector_scalar_type, float>::value ||
236 std::is_same<vector_scalar_type, double>::value));
238#ifdef HAVE_AMESOS2_TIMERS
239 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_);
241 const bool initialize_data =
true;
242 const bool do_not_initialize_data =
false;
243 if ( single_proc_optimization() && nrhs == 1 ) {
245 bDidAssignB = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
246 host_solve_array_t>::do_get(initialize_data, B, bValues_, as<size_t>(ld_rhs));
248 bDidAssignX = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
249 host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_, as<size_t>(ld_rhs));
253 int rval = B->gather(bValues_, this->perm_g2l, this->recvCountRows, this->recvDisplRows,
256 X->gather(xValues_, this->perm_g2l, this->recvCountRows, this->recvDisplRows,
266 if (distributionMap_.is_null()) {
268 distributionMap_ = Util::getDistributionMap<
269 typename MVA::local_ordinal_t,
typename MVA::global_ordinal_t,
270 typename MVA::global_size_t,
typename MVA::node_t>(
271 dist, B->getGlobalLength(), B->getComm(),
272 this->rowIndexBase_, B->getMap());
274 auto distMapPtr = Teuchos::ptrInArg(*distributionMap_);
275 bDidAssignB = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
276 host_solve_array_t>::do_get(initialize_data, B, bValues_,
277 as<size_t>(ld_rhs), distMapPtr, dist);
279 bDidAssignX = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
280 host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_,
281 as<size_t>(ld_rhs), distMapPtr, dist);
291 Kokkos::deep_copy(xValues_, bValues_);
299 klu2_dtype * pxValues = function_map::convert_scalar(xValues_.data());
300 klu2_dtype * pbValues = function_map::convert_scalar(bValues_.data());
304 TEUCHOS_TEST_FOR_EXCEPTION(pbValues ==
nullptr,
305 std::runtime_error,
"Amesos2 Runtime Error: b_vector returned null ");
307 TEUCHOS_TEST_FOR_EXCEPTION(pxValues ==
nullptr,
308 std::runtime_error,
"Amesos2 Runtime Error: x_vector returned null ");
311 if ( single_proc_optimization() && nrhs == 1 ) {
312#ifdef HAVE_AMESOS2_TIMERS
313 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
321 ::KLU2::klu_tsolve2<klu2_dtype, local_ordinal_type>
322 (data_.symbolic_, data_.numeric_,
323 (local_ordinal_type)this->globalNumCols_,
324 (local_ordinal_type)nrhs,
325 pbValues, pxValues, &(data_.common_)) ;
328 ::KLU2::klu_solve2<klu2_dtype, local_ordinal_type>
329 (data_.symbolic_, data_.numeric_,
330 (local_ordinal_type)this->globalNumCols_,
331 (local_ordinal_type)nrhs,
332 pbValues, pxValues, &(data_.common_)) ;
343#ifdef HAVE_AMESOS2_TIMERS
344 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
351 if ( single_proc_optimization() ) {
352 ::KLU2::klu_tsolve<klu2_dtype, local_ordinal_type>
353 (data_.symbolic_, data_.numeric_,
354 (local_ordinal_type)this->globalNumCols_,
355 (local_ordinal_type)nrhs,
356 pxValues, &(data_.common_)) ;
359 ::KLU2::klu_solve<klu2_dtype, local_ordinal_type>
360 (data_.symbolic_, data_.numeric_,
361 (local_ordinal_type)this->globalNumCols_,
362 (local_ordinal_type)nrhs,
363 pxValues, &(data_.common_)) ;
371 if ( single_proc_optimization() ) {
372 ::KLU2::klu_solve<klu2_dtype, local_ordinal_type>
373 (data_.symbolic_, data_.numeric_,
374 (local_ordinal_type)this->globalNumCols_,
375 (local_ordinal_type)nrhs,
376 pxValues, &(data_.common_)) ;
379 ::KLU2::klu_tsolve<klu2_dtype, local_ordinal_type>
380 (data_.symbolic_, data_.numeric_,
381 (local_ordinal_type)this->globalNumCols_,
382 (local_ordinal_type)nrhs,
383 pxValues, &(data_.common_)) ;
393#ifdef HAVE_AMESOS2_TIMERS
394 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
397 int rval = X->scatter(xValues_, this->perm_g2l, this->recvCountRows, this->recvDisplRows,
399 if (rval != 0) use_gather =
false;
403 if (!distributionMap_.is_null()) {
404 Util::put_1d_data_helper_kokkos_view<
406 as<size_t>(ld_rhs), Teuchos::ptrInArg(*distributionMap_), dist);
408 Util::put_1d_data_helper_kokkos_view<
410 as<size_t>(ld_rhs), dist, this->rowIndexBase_);
414 if (debug_level_ > 0) {
415 if (debug_level_ == 1) {
418 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
419 if (!is_null(X->getMap())) X->getMap()->describe(*fancy, Teuchos::VERB_EXTREME);
420 std::cout << std::endl;
421 X->describe(*fancy, Teuchos::VERB_EXTREME);
511#ifdef HAVE_AMESOS2_TIMERS
512 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
515 if(current_phase == SOLVE)
return(
false);
516 if (debug_level_ > 0 && current_phase == NUMFACT) {
518 std::cout <<
"\n == Amesos2_KLU2::loadA_impl";
519 if (current_phase == PREORDERING) std::cout <<
"(PreOrder)";
520 if (current_phase == SYMBFACT) std::cout <<
"(SymFact)";
521 if (current_phase == NUMFACT) std::cout <<
"(NumFact)";
522 std::cout <<
" ==" << std::endl;
524 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
525 this->matrixA_->describe(*fancy, (debug_level_ == 1 ? Teuchos::VERB_LOW : Teuchos::VERB_EXTREME));
528 if ( single_proc_optimization() ) {
535 if (host_nzvals_view_.extent(0) != this->globalNumNonZeros_)
536 Kokkos::resize(host_nzvals_view_, this->globalNumNonZeros_);
537 if (host_rows_view_.extent(0) != this->globalNumNonZeros_)
538 Kokkos::resize(host_rows_view_, this->globalNumNonZeros_);
539 if (host_col_ptr_view_.extent(0) != (this->globalNumRows_ + 1))
540 Kokkos::resize(host_col_ptr_view_, this->globalNumRows_ + 1);
542 local_ordinal_type nnz_ret = -1;
543 bool use_gather = use_gather_;
544 use_gather = (use_gather && this->matrixA_->getComm()->getSize() > 1);
545 use_gather = (use_gather && (std::is_same<scalar_type, float>::value || std::is_same<scalar_type, double>::value));
547#ifdef HAVE_AMESOS2_TIMERS
548 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
551 bool column_major =
true;
552 if (!is_contiguous_) {
553 auto contig_mat = this->matrixA_->reindex(this->contig_rowmap_, this->contig_colmap_, current_phase);
554 nnz_ret = contig_mat->gather(host_nzvals_view_, host_rows_view_, host_col_ptr_view_, this->perm_g2l, this->recvCountRows, this->recvDisplRows, this->recvCounts, this->recvDispls,
555 this->transpose_map, this->nzvals_t, column_major, current_phase);
557 nnz_ret = this->matrixA_->gather(host_nzvals_view_, host_rows_view_, host_col_ptr_view_, this->perm_g2l, this->recvCountRows, this->recvDisplRows, this->recvCounts, this->recvDispls,
558 this->transpose_map, this->nzvals_t, column_major, current_phase);
562 if (nnz_ret < 0) use_gather =
false;
567 ::do_get(this->matrixA_.ptr(), host_nzvals_view_, host_rows_view_, host_col_ptr_view_, nnz_ret,
570 this->rowIndexBase_);
575 if (use_gather || this->root_) {
576 TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<local_ordinal_type>(this->globalNumNonZeros_),
578 "Amesos2_KLU2 loadA_impl: Did not get the expected number of non-zero vals("
579 +std::to_string(nnz_ret)+
" vs "+std::to_string(this->globalNumNonZeros_)+
")");