Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_ShyLUBasker_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Amesos2: Templated Direct Sparse Solver Package
6 // Copyright 2011 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //
42 // @HEADER
43 
54 #ifndef AMESOS2_SHYLUBASKER_DEF_HPP
55 #define AMESOS2_SHYLUBASKER_DEF_HPP
56 
57 #include <Teuchos_Tuple.hpp>
58 #include <Teuchos_ParameterList.hpp>
59 #include <Teuchos_StandardParameterEntryValidators.hpp>
60 
63 
64 namespace Amesos2 {
65 
66 
67 template <class Matrix, class Vector>
68 ShyLUBasker<Matrix,Vector>::ShyLUBasker(
69  Teuchos::RCP<const Matrix> A,
70  Teuchos::RCP<Vector> X,
71  Teuchos::RCP<const Vector> B )
72  : SolverCore<Amesos2::ShyLUBasker,Matrix,Vector>(A, X, B)
73  , is_contiguous_(true)
74 {
75 
76  //Nothing
77 
78  // Override some default options
79  // TODO: use data_ here to init
80 #if defined(HAVE_AMESOS2_KOKKOS) && defined(KOKKOS_ENABLE_OPENMP)
81  /*
82  static_assert(std::is_same<kokkos_exe,Kokkos::OpenMP>::value,
83  "Kokkos node type not supported by experimental ShyLUBasker Amesos2");
84  */
85  typedef Kokkos::OpenMP Exe_Space;
86 
87  ShyLUbasker = new ::BaskerNS::BaskerTrilinosInterface<local_ordinal_type, shylubasker_dtype, Exe_Space>();
88  ShyLUbasker->Options.no_pivot = BASKER_FALSE;
89  ShyLUbasker->Options.static_delayed_pivot = 0;
90  ShyLUbasker->Options.symmetric = BASKER_FALSE;
91  ShyLUbasker->Options.realloc = BASKER_TRUE;
92  ShyLUbasker->Options.verbose = BASKER_FALSE;
93  ShyLUbasker->Options.prune = BASKER_TRUE;
94  ShyLUbasker->Options.btf_matching = 2; // use cardinary matching from Trilinos, globally
95  ShyLUbasker->Options.blk_matching = 1; // use max-weight matching from Basker on each diagonal block
96  ShyLUbasker->Options.matrix_scaling = 0; // use matrix scaling on a big A block
97  ShyLUbasker->Options.min_block_size = 0; // no merging small blocks
98  ShyLUbasker->Options.amd_dom = BASKER_TRUE; // use block-wise AMD
99  ShyLUbasker->Options.use_metis = BASKER_TRUE; // use scotch/metis for ND (TODO: should METIS optional?)
100  ShyLUbasker->Options.use_nodeNDP = BASKER_TRUE; // use nodeNDP to compute ND partition
101  ShyLUbasker->Options.run_nd_on_leaves = BASKER_TRUE; // run ND on the final leaf-nodes
102  ShyLUbasker->Options.run_amd_on_leaves = BASKER_FALSE; // run AMD on the final leaf-nodes
103  ShyLUbasker->Options.transpose = BASKER_FALSE;
104  ShyLUbasker->Options.replace_tiny_pivot = BASKER_FALSE;
105  ShyLUbasker->Options.verbose_matrix_out = BASKER_FALSE;
106 
107  ShyLUbasker->Options.user_fill = (double)BASKER_FILL_USER;
108  ShyLUbasker->Options.use_sequential_diag_facto = BASKER_FALSE;
109 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
110  num_threads = Kokkos::OpenMP::max_hardware_threads();
111 #else
112  num_threads = Kokkos::OpenMP::impl_max_hardware_threads();
113 #endif
114 
115 #else
116  TEUCHOS_TEST_FOR_EXCEPTION(1 != 0,
117  std::runtime_error,
118  "Amesos2_ShyLUBasker Exception: Do not have supported Kokkos node type (OpenMP) enabled for ShyLUBasker");
119 #endif
120 }
121 
122 
123 template <class Matrix, class Vector>
124 ShyLUBasker<Matrix,Vector>::~ShyLUBasker( )
125 {
126  /* ShyLUBasker will cleanup its own internal memory*/
127 #if defined(HAVE_AMESOS2_KOKKOS) && defined(KOKKOS_ENABLE_OPENMP)
128  ShyLUbasker->Finalize();
129  delete ShyLUbasker;
130 #endif
131 }
132 
133 template <class Matrix, class Vector>
134 bool
136  return (this->root_ && (this->matrixA_->getComm()->getSize() == 1) && is_contiguous_);
137 }
138 
139 template<class Matrix, class Vector>
140 int
142 {
143  /* TODO: Define what it means for ShyLUBasker
144  */
145 #ifdef HAVE_AMESOS2_TIMERS
146  Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_);
147 #endif
148 
149  return(0);
150 }
151 
152 
153 template <class Matrix, class Vector>
154 int
156 {
157 
158  int info = 0;
159  if(this->root_)
160  {
161  ShyLUbasker->SetThreads(num_threads);
162 
163 
164  // NDE: Special case
165  // Rather than going through the Amesos2 machinery to convert the matrixA_ CRS pointer data to CCS and store in Teuchos::Arrays,
166  // in this special case we pass the CRS raw pointers directly to ShyLUBasker which copies+transposes+sorts the data for CCS format
167  // loadA_impl is essentially an empty function in this case, as the raw pointers are handled here and similarly in Symbolic
168 
169  if ( single_proc_optimization() ) {
170 
171  host_ordinal_type_array sp_rowptr;
172  host_ordinal_type_array sp_colind;
173  // this needs to be checked during loadA_impl...
174  this->matrixA_->returnRowPtr_kokkos_view(sp_rowptr);
175  TEUCHOS_TEST_FOR_EXCEPTION(sp_rowptr.data() == nullptr,
176  std::runtime_error, "Amesos2 Runtime Error: sp_rowptr returned null ");
177  this->matrixA_->returnColInd_kokkos_view(sp_colind);
178  TEUCHOS_TEST_FOR_EXCEPTION(sp_colind.data() == nullptr,
179  std::runtime_error, "Amesos2 Runtime Error: sp_colind returned null ");
180 
181  host_value_type_array hsp_values;
182  this->matrixA_->returnValues_kokkos_view(hsp_values);
183  shylubasker_dtype * sp_values = function_map::convert_scalar(hsp_values.data());
184  //shylubasker_dtype * sp_values = function_map::convert_scalar(nzvals_view_.data());
185  TEUCHOS_TEST_FOR_EXCEPTION(sp_values == nullptr,
186  std::runtime_error, "Amesos2 Runtime Error: sp_values returned null ");
187 
188  // In this case, colptr_, rowind_, nzvals_ are invalid
189  info = ShyLUbasker->Symbolic(this->globalNumRows_,
190  this->globalNumCols_,
191  this->globalNumNonZeros_,
192  sp_rowptr.data(),
193  sp_colind.data(),
194  sp_values,
195  true);
196 
197  TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
198  std::runtime_error, "Error in ShyLUBasker Symbolic");
199  }
200  else
201  { //follow original code path if conditions not met
202  // In this case, loadA_impl updates colptr_, rowind_, nzvals_
203  shylubasker_dtype * sp_values = function_map::convert_scalar(nzvals_view_.data());
204  info = ShyLUbasker->Symbolic(this->globalNumRows_,
205  this->globalNumCols_,
206  this->globalNumNonZeros_,
207  colptr_view_.data(),
208  rowind_view_.data(),
209  sp_values);
210 
211  TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
212  std::runtime_error, "Error in ShyLUBasker Symbolic");
213  }
214  } // end if (this->root_)
215  /*No symbolic factoriztion*/
216 
217  /* All processes should have the same error code */
218  Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info);
219  return(info);
220 }
221 
222 
223 template <class Matrix, class Vector>
224 int
226 {
227  using Teuchos::as;
228 
229  int info = 0;
230  if ( this->root_ ){
231  { // Do factorization
232 #ifdef HAVE_AMESOS2_TIMERS
233  Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_);
234 #endif
235 
236 
237  // NDE: Special case
238  // Rather than going through the Amesos2 machinery to convert the matrixA_ CRS pointer data to CCS and store in Teuchos::Arrays,
239  // in this special case we pass the CRS raw pointers directly to ShyLUBasker which copies+transposes+sorts the data for CCS format
240  // loadA_impl is essentially an empty function in this case, as the raw pointers are handled here and similarly in Symbolic
241 
242  if ( single_proc_optimization() ) {
243 
244  host_ordinal_type_array sp_rowptr;
245  host_ordinal_type_array sp_colind;
246  this->matrixA_->returnRowPtr_kokkos_view(sp_rowptr);
247  TEUCHOS_TEST_FOR_EXCEPTION(sp_rowptr.data() == nullptr,
248  std::runtime_error, "Amesos2 Runtime Error: sp_rowptr returned null ");
249  this->matrixA_->returnColInd_kokkos_view(sp_colind);
250  TEUCHOS_TEST_FOR_EXCEPTION(sp_colind.data() == nullptr,
251  std::runtime_error, "Amesos2 Runtime Error: sp_colind returned null ");
252 
253  host_value_type_array hsp_values;
254  this->matrixA_->returnValues_kokkos_view(hsp_values);
255  shylubasker_dtype * sp_values = function_map::convert_scalar(hsp_values.data());
256  //shylubasker_dtype * sp_values = function_map::convert_scalar(nzvals_view_.data());
257 
258  TEUCHOS_TEST_FOR_EXCEPTION(sp_values == nullptr,
259  std::runtime_error, "Amesos2 Runtime Error: sp_values returned null ");
260 
261  // In this case, colptr_, rowind_, nzvals_ are invalid
262  info = ShyLUbasker->Factor( this->globalNumRows_,
263  this->globalNumCols_,
264  this->globalNumNonZeros_,
265  sp_rowptr.data(),
266  sp_colind.data(),
267  sp_values);
268 
269  TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
270  std::runtime_error, "Error ShyLUBasker Factor");
271  }
272  else
273  {
274  // In this case, loadA_impl updates colptr_, rowind_, nzvals_
275  shylubasker_dtype * sp_values = function_map::convert_scalar(nzvals_view_.data());
276  info = ShyLUbasker->Factor(this->globalNumRows_,
277  this->globalNumCols_,
278  this->globalNumNonZeros_,
279  colptr_view_.data(),
280  rowind_view_.data(),
281  sp_values);
282 
283  TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
284  std::runtime_error, "Error ShyLUBasker Factor");
285  }
286 
287  //ShyLUbasker->DEBUG_PRINT();
288 
289  local_ordinal_type blnnz = local_ordinal_type(0);
290  local_ordinal_type bunnz = local_ordinal_type(0);
291  ShyLUbasker->GetLnnz(blnnz); // Add exception handling?
292  ShyLUbasker->GetUnnz(bunnz);
293 
294  // This is set after numeric factorization complete as pivoting can be used;
295  // In this case, a discrepancy between symbolic and numeric nnz total can occur.
296  this->setNnzLU( as<size_t>( blnnz + bunnz ) );
297 
298  } // end scope for timer
299  } // end if (this->root_)
300 
301  /* All processes should have the same error code */
302  Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info);
303 
304  //global_size_type info_st = as<global_size_type>(info);
305  /* TODO : Proper error messages*/
306  TEUCHOS_TEST_FOR_EXCEPTION(info == -1,
307  std::runtime_error,
308  "ShyLUBasker: Could not alloc space for L and U");
309  TEUCHOS_TEST_FOR_EXCEPTION(info == -2,
310  std::runtime_error,
311  "ShyLUBasker: Could not alloc needed work space");
312  TEUCHOS_TEST_FOR_EXCEPTION(info == -3,
313  std::runtime_error,
314  "ShyLUBasker: Could not alloc additional memory needed for L and U");
315  TEUCHOS_TEST_FOR_EXCEPTION(info > 0,
316  std::runtime_error,
317  "ShyLUBasker: Zero pivot found at: " << info );
318 
319  return(info);
320 }
321 
322 
323 template <class Matrix, class Vector>
324 int
326  const Teuchos::Ptr<MultiVecAdapter<Vector> > X,
327  const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const
328 {
329 #ifdef HAVE_AMESOS2_TIMERS
330  Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
331 #endif
332 
333  int ierr = 0; // returned error code
334 
335  using Teuchos::as;
336 
337  const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
338  const size_t nrhs = X->getGlobalNumVectors();
339 
340  const bool ShyluBaskerTransposeRequest = this->control_.useTranspose_;
341  const bool initialize_data = true;
342  const bool do_not_initialize_data = false;
343 
344  if ( single_proc_optimization() && nrhs == 1 ) {
345 
346  // no msp creation
347  Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
348  host_solve_array_t>::do_get(initialize_data, B, bValues_, as<size_t>(ld_rhs));
349 
350  Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
351  host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_, as<size_t>(ld_rhs));
352 
353  } // end if ( single_proc_optimization() && nrhs == 1 )
354  else {
355 
356  Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
357  host_solve_array_t>::do_get(initialize_data, B, bValues_,
358  as<size_t>(ld_rhs),
359  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
360  this->rowIndexBase_);
361 
362  // See Amesos2_Tacho_def.hpp for notes on why we 'get' x here.
363  Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
364  host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_,
365  as<size_t>(ld_rhs),
366  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
367  this->rowIndexBase_);
368  }
369 
370  if ( this->root_ ) { // do solve
371  shylubasker_dtype * pxValues = function_map::convert_scalar(xValues_.data());
372  shylubasker_dtype * pbValues = function_map::convert_scalar(bValues_.data());
373  if (!ShyluBaskerTransposeRequest)
374  ierr = ShyLUbasker->Solve(nrhs, pbValues, pxValues);
375  else
376  ierr = ShyLUbasker->Solve(nrhs, pbValues, pxValues, true);
377  }
378 
379  /* All processes should have the same error code */
380  Teuchos::broadcast(*(this->getComm()), 0, &ierr);
381 
382  TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0,
383  std::runtime_error,
384  "Encountered zero diag element at: " << ierr);
385  TEUCHOS_TEST_FOR_EXCEPTION( ierr == -1,
386  std::runtime_error,
387  "Could not alloc needed working memory for solve" );
388 
389  Util::put_1d_data_helper_kokkos_view<
390  MultiVecAdapter<Vector>,host_solve_array_t>::do_put(X, xValues_,
391  as<size_t>(ld_rhs),
392  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
393 
394  return(ierr);
395 }
396 
397 
398 template <class Matrix, class Vector>
399 bool
401 {
402  // The ShyLUBasker can only handle square for right now
403  return( this->globalNumRows_ == this->globalNumCols_ );
404 }
405 
406 
407 template <class Matrix, class Vector>
408 void
409 ShyLUBasker<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList )
410 {
411  using Teuchos::RCP;
412  using Teuchos::getIntegralValue;
413  using Teuchos::ParameterEntryValidator;
414 
415  RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
416 
417  if(parameterList->isParameter("IsContiguous"))
418  {
419  is_contiguous_ = parameterList->get<bool>("IsContiguous");
420  }
421 
422  if(parameterList->isParameter("num_threads"))
423  {
424  num_threads = parameterList->get<int>("num_threads");
425  }
426  if(parameterList->isParameter("pivot"))
427  {
428  ShyLUbasker->Options.no_pivot = (!parameterList->get<bool>("pivot"));
429  }
430  if(parameterList->isParameter("delayed pivot"))
431  {
432  ShyLUbasker->Options.static_delayed_pivot = (parameterList->get<int>("delayed pivot"));
433  }
434  if(parameterList->isParameter("pivot_tol"))
435  {
436  ShyLUbasker->Options.pivot_tol = parameterList->get<double>("pivot_tol");
437  }
438  if(parameterList->isParameter("symmetric"))
439  {
440  ShyLUbasker->Options.symmetric = parameterList->get<bool>("symmetric");
441  }
442  if(parameterList->isParameter("realloc"))
443  {
444  ShyLUbasker->Options.realloc = parameterList->get<bool>("realloc");
445  }
446  if(parameterList->isParameter("verbose"))
447  {
448  ShyLUbasker->Options.verbose = parameterList->get<bool>("verbose");
449  }
450  if(parameterList->isParameter("verbose_matrix"))
451  {
452  ShyLUbasker->Options.verbose_matrix_out = parameterList->get<bool>("verbose_matrix");
453  }
454  if(parameterList->isParameter("btf"))
455  {
456  ShyLUbasker->Options.btf = parameterList->get<bool>("btf");
457  }
458  if(parameterList->isParameter("use_metis"))
459  {
460  ShyLUbasker->Options.use_metis = parameterList->get<bool>("use_metis");
461  }
462  if(parameterList->isParameter("use_nodeNDP"))
463  {
464  ShyLUbasker->Options.use_nodeNDP = parameterList->get<bool>("use_nodeNDP");
465  }
466  if(parameterList->isParameter("run_nd_on_leaves"))
467  {
468  ShyLUbasker->Options.run_nd_on_leaves = parameterList->get<bool>("run_nd_on_leaves");
469  }
470  if(parameterList->isParameter("run_amd_on_leaves"))
471  {
472  ShyLUbasker->Options.run_amd_on_leaves = parameterList->get<bool>("run_amd_on_leaves");
473  }
474  if(parameterList->isParameter("amd_on_blocks"))
475  {
476  ShyLUbasker->Options.amd_dom = parameterList->get<bool>("amd_on_blocks");
477  }
478  if(parameterList->isParameter("transpose"))
479  {
480  // NDE: set transpose vs non-transpose mode as bool; track separate shylubasker objects
481  const auto transpose = parameterList->get<bool>("transpose");
482  if (transpose == true)
483  this->control_.useTranspose_ = true;
484  }
485  if(parameterList->isParameter("use_sequential_diag_facto"))
486  {
487  ShyLUbasker->Options.use_sequential_diag_facto = parameterList->get<bool>("use_sequential_diag_facto");
488  }
489  if(parameterList->isParameter("user_fill"))
490  {
491  ShyLUbasker->Options.user_fill = parameterList->get<double>("user_fill");
492  }
493  if(parameterList->isParameter("prune"))
494  {
495  ShyLUbasker->Options.prune = parameterList->get<bool>("prune");
496  }
497  if(parameterList->isParameter("replace_tiny_pivot"))
498  {
499  ShyLUbasker->Options.replace_tiny_pivot = parameterList->get<bool>("replace_tiny_pivot");
500  }
501  if(parameterList->isParameter("btf_matching"))
502  {
503  ShyLUbasker->Options.btf_matching = parameterList->get<int>("btf_matching");
504  if (ShyLUbasker->Options.btf_matching == 1 || ShyLUbasker->Options.btf_matching == 2) {
505  ShyLUbasker->Options.matching = true;
506  } else {
507  ShyLUbasker->Options.matching = false;
508  }
509  }
510  if(parameterList->isParameter("blk_matching"))
511  {
512  ShyLUbasker->Options.blk_matching = parameterList->get<int>("blk_matching");
513  }
514  if(parameterList->isParameter("matrix_scaling"))
515  {
516  ShyLUbasker->Options.matrix_scaling = parameterList->get<int>("matrix_scaling");
517  }
518  if(parameterList->isParameter("min_block_size"))
519  {
520  ShyLUbasker->Options.min_block_size = parameterList->get<int>("min_block_size");
521  }
522 }
523 
524 template <class Matrix, class Vector>
525 Teuchos::RCP<const Teuchos::ParameterList>
527 {
528  using Teuchos::ParameterList;
529 
530  static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
531 
532  if( is_null(valid_params) )
533  {
534  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
535  pl->set("IsContiguous", true,
536  "Are GIDs contiguous");
537  pl->set("num_threads", 1,
538  "Number of threads");
539  pl->set("pivot", false,
540  "Should not pivot");
541  pl->set("delayed pivot", 0,
542  "Apply static delayed pivot on a big block");
543  pl->set("pivot_tol", .0001,
544  "Tolerance before pivot, currently not used");
545  pl->set("symmetric", false,
546  "Should Symbolic assume symmetric nonzero pattern");
547  pl->set("realloc" , false,
548  "Should realloc space if not enough");
549  pl->set("verbose", false,
550  "Information about factoring");
551  pl->set("verbose_matrix", false,
552  "Give Permuted Matrices");
553  pl->set("btf", true,
554  "Use BTF ordering");
555  pl->set("prune", false,
556  "Use prune on BTF blocks (Not Supported)");
557  pl->set("btf_matching", 2,
558  "Matching option for BTF: 0 = none, 1 = Basker, 2 = Trilinos (default), (3 = MC64 if enabled)");
559  pl->set("blk_matching", 1,
560  "Matching optioon for block: 0 = none, 1 or anything else = Basker (default), (2 = MC64 if enabled)");
561  pl->set("matrix_scaling", 0,
562  "Use matrix scaling to biig A BTF block: 0 = no-scaling, 1 = symmetric diagonal scaling, 2 = row-max, and then col-max scaling");
563  pl->set("min_block_size", 0,
564  "Size of the minimum diagonal blocks");
565  pl->set("replace_tiny_pivot", false,
566  "Replace tiny pivots during the numerical factorization");
567  pl->set("use_metis", true,
568  "Use METIS for ND");
569  pl->set("use_nodeNDP", true,
570  "Use nodeND to compute ND partition");
571  pl->set("run_nd_on_leaves", false,
572  "Run ND on the final leaf-nodes for ND factorization");
573  pl->set("run_amd_on_leaves", false,
574  "Run AMD on the final leaf-nodes for ND factorization");
575  pl->set("amd_on_blocks", true,
576  "Run AMD on each diagonal blocks");
577  pl->set("transpose", false,
578  "Solve the transpose A");
579  pl->set("use_sequential_diag_facto", false,
580  "Use sequential algorithm to factor each diagonal block");
581  pl->set("user_fill", (double)BASKER_FILL_USER,
582  "User-provided padding for the fill ratio");
583  valid_params = pl;
584  }
585  return valid_params;
586 }
587 
588 
589 template <class Matrix, class Vector>
590 bool
592 {
593  using Teuchos::as;
594  if(current_phase == SOLVE) return (false);
595 
596  #ifdef HAVE_AMESOS2_TIMERS
597  Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
598  #endif
599 
600 
601  // NDE: Can clean up duplicated code with the #ifdef guards
602  if ( single_proc_optimization() ) {
603  // NDE: Nothing is done in this special case - CRS raw pointers are passed to SHYLUBASKER and transpose of copies handled there
604  // In this case, colptr_, rowind_, nzvals_ are invalid
605  }
606  else
607  {
608 
609  // Only the root image needs storage allocated
610  if( this->root_ ){
611  Kokkos::resize(nzvals_view_, this->globalNumNonZeros_);
612  Kokkos::resize(rowind_view_, this->globalNumNonZeros_);
613  Kokkos::resize(colptr_view_, this->globalNumCols_ + 1); //this will be wrong for case of gapped col ids, e.g. 0,2,4,9; num_cols = 10 ([0,10)) but num GIDs = 4...
614  }
615 
616  local_ordinal_type nnz_ret = 0;
617  {
618  #ifdef HAVE_AMESOS2_TIMERS
619  Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
620  #endif
621 
623  MatrixAdapter<Matrix>, host_value_type_array, host_ordinal_type_array, host_ordinal_type_array>
624  ::do_get(this->matrixA_.ptr(), nzvals_view_, rowind_view_, colptr_view_, nnz_ret,
625  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
626  ARBITRARY,
627  this->rowIndexBase_); // copies from matrixA_ to ShyLUBasker ConcreteSolver cp, ri, nzval members
628  }
629 
630  if( this->root_ ){
631  TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<local_ordinal_type>(this->globalNumNonZeros_),
632  std::runtime_error,
633  "Amesos2_ShyLUBasker loadA_impl: Did not get the expected number of non-zero vals");
634  }
635 
636  } //end alternative path
637  return true;
638 }
639 
640 
641 template<class Matrix, class Vector>
642 const char* ShyLUBasker<Matrix,Vector>::name = "ShyLUBasker";
643 
644 
645 } // end namespace Amesos2
646 
647 #endif // AMESOS2_SHYLUBASKER_DEF_HPP
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:648
int solve_impl(const Teuchos::Ptr< MultiVecAdapter< Vector > > X, const Teuchos::Ptr< const MultiVecAdapter< Vector > > B) const
ShyLUBasker specific solve.
Definition: Amesos2_ShyLUBasker_def.hpp:325
EPhase
Used to indicate a phase in the direct solution.
Definition: Amesos2_TypeDecl.hpp:65
Amesos2 interface to the Baker package.
Definition: Amesos2_ShyLUBasker_decl.hpp:76
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition: Amesos2_ShyLUBasker_def.hpp:526
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition: Amesos2_ShyLUBasker_def.hpp:141
void transpose(ArrayView< Scalar > vals, ArrayView< GlobalOrdinal > indices, ArrayView< GlobalSizeT > ptr, ArrayView< Scalar > trans_vals, ArrayView< GlobalOrdinal > trans_indices, ArrayView< GlobalSizeT > trans_ptr)
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition: Amesos2_ShyLUBasker_def.hpp:400
Amesos2 ShyLUBasker declarations.
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition: Amesos2_ShyLUBasker_def.hpp:591
A Matrix adapter interface for Amesos2.
Definition: Amesos2_MatrixAdapter_decl.hpp:76
int numericFactorization_impl()
ShyLUBasker specific numeric factorization.
Definition: Amesos2_ShyLUBasker_def.hpp:225
A templated MultiVector class adapter for Amesos2.
Definition: Amesos2_MultiVecAdapter_decl.hpp:176
bool single_proc_optimization() const
can we optimize size_type and ordinal_type for straight pass through, also check that is_contiguous_ ...
Definition: Amesos2_ShyLUBasker_def.hpp:135