12 #include "Thyra_TestingTools.hpp"
13 #include "Thyra_LinearOpTester.hpp"
14 #include "Thyra_LinearOpWithSolveTester.hpp"
16 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
17 #include "Thyra_DefaultSpmdVectorSpace.hpp"
18 #include "Thyra_MultiVectorStdOps.hpp"
19 #include "Epetra_SerialComm.h"
20 #include "Epetra_LocalMap.h"
21 #include "Epetra_CrsMatrix.h"
22 #include "Epetra_MultiVector.h"
23 #include "Epetra_Vector.h"
31 # include "Epetra_MpiComm.h"
40 void print_performance_stats(
41 const int num_time_samples
42 ,
const double raw_epetra_time
43 ,
const double thyra_wrapped_time
50 <<
"\nAverage times (out of " << num_time_samples <<
" samples):\n"
51 <<
" Raw Epetra = " << (raw_epetra_time/num_time_samples) << std::endl
52 <<
" Thyra Wrapped Epetra = " << (thyra_wrapped_time/num_time_samples) << std::endl
53 <<
"\nRelative performance of Thyra wrapped verses raw Epetra:\n"
54 <<
" ( raw epetra time / thyra wrapped time ) = ( " << raw_epetra_time <<
" / " << thyra_wrapped_time <<
" ) = "
55 << (raw_epetra_time/thyra_wrapped_time) << std::endl;
59 double sum(
const Epetra_MultiVector &ev )
61 std::vector<double> meanValues(ev.NumVectors());
62 ev.MeanValue(&meanValues[0]);
64 for(
int i = 0; i < ev.NumVectors(); ++i ) sum += meanValues[i];
65 return (ev.Map().NumGlobalElements()*sum);
83 int main(
int argc,
char* argv[] )
88 typedef double Scalar;
98 using Teuchos::arcpFromArray;
100 using Teuchos::rcp_static_cast;
101 using Teuchos::rcp_const_cast;
104 using Thyra::passfail;
105 using Thyra::NOTRANS;
121 RCP<Teuchos::FancyOStream>
122 out = Teuchos::VerboseObjectBase::getDefaultOStream();
132 int local_dim = 1000;
134 double max_rel_err = 1e-13;
135 double max_rel_warn = 1e-15;
137 double max_flop_rate = 1.0;
141 CommandLineProcessor clp;
142 clp.throwExceptions(
false);
143 clp.addOutputSetupOptions(
true);
144 clp.setOption(
"verbose",
"quiet", &verbose,
"Determines if any output is printed or not." );
145 clp.setOption(
"dump-all",
"no-dump", &dumpAll,
"Determines if quantities are dumped or not." );
146 clp.setOption(
"local-dim", &local_dim,
"Number of vector elements per process." );
147 clp.setOption(
"num-mv-cols", &num_mv_cols,
"Number columns in each multi-vector (>=4)." );
148 clp.setOption(
"max-rel-err-tol", &max_rel_err,
"Maximum relative error tolerance for tests." );
149 clp.setOption(
"max-rel-warn-tol", &max_rel_warn,
"Maximum relative warning tolerance for tests." );
150 clp.setOption(
"scalar", &scalar,
"A scalar used in all computations." );
151 clp.setOption(
"max-flop-rate", &max_flop_rate,
"Approx flop rate used for loop timing." );
153 clp.setOption(
"use-mpi",
"no-use-mpi", &useMPI,
"Actually use MPI or just run independent serial programs." );
155 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
156 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL )
return parse_return;
159 num_mv_cols < 4, std::logic_error
160 ,
"Error, num-mv-cols must be >= 4!"
171 mpiComm = MPI_COMM_WORLD;
172 MPI_Comm_size( mpiComm, &numProc );
173 MPI_Comm_rank( mpiComm, &procRank );
176 mpiComm = MPI_COMM_NULL;
185 <<
"\n*** (A) Creating two vector spaces (an Epetra-based and a non-Epetra-based)"
192 RCP<const Epetra_Comm> epetra_comm;
193 RCP<const Epetra_Map> epetra_map;
194 RCP<const Thyra::VectorSpaceBase<Scalar> > epetra_vs;
195 RCP<const Thyra::VectorSpaceBase<Scalar> > non_epetra_vs;
202 if(verbose) *out <<
"\nCreating vector space using Epetra_MpiComm ...\n";
203 epetra_comm =
rcp(
new Epetra_MpiComm(mpiComm));
204 epetra_map =
rcp(
new Epetra_Map(-1,local_dim,0,*epetra_comm));
207 if(verbose) *out <<
"\nCreating Thyra::DefaultSpmdVectorSpace ...\n";
209 new Thyra::DefaultSpmdVectorSpace<Scalar>(
221 if(verbose) *out <<
"\nCreating vector space using Epetra_SerialComm ...\n";
222 epetra_comm =
rcp(
new Epetra_SerialComm);
223 epetra_map =
rcp(
new Epetra_LocalMap(local_dim,0,*epetra_comm));
226 if(verbose) *out <<
"\nCreating Thyra::DefaultSpmdVectorSpace ...\n";
227 non_epetra_vs = Thyra::defaultSpmdVectorSpace<Scalar>(local_dim);
230 #endif // end create vector spacdes [Doxygen looks for this!]
233 const int global_dim = local_dim * numProc;
235 const int global_dim = local_dim;
240 <<
"\nscalar = " << scalar
241 <<
"\nlocal_dim = " << local_dim
242 <<
"\nglobal_dim = " << global_dim
243 <<
"\nnum_mv_cols = " << num_mv_cols
244 <<
"\nepetra_vs.dim() = " << epetra_vs->dim()
245 <<
"\nnon_epetra_vs.dim() = " << non_epetra_vs->dim()
252 RCP<Thyra::VectorBase<Scalar> >
253 ev1 = createMember(epetra_vs),
254 ev2 = createMember(epetra_vs);
255 RCP<Thyra::VectorBase<Scalar> >
256 nev1 = createMember(non_epetra_vs),
257 nev2 = createMember(non_epetra_vs);
259 RCP<Thyra::MultiVectorBase<Scalar> >
260 eV1 = createMembers(epetra_vs,num_mv_cols),
261 eV2 = createMembers(epetra_vs,num_mv_cols);
262 RCP<Thyra::MultiVectorBase<Scalar> >
263 neV1 = createMembers(non_epetra_vs,num_mv_cols),
264 neV2 = createMembers(non_epetra_vs,num_mv_cols);
269 <<
"\n*** (B) Testing Epetra and non-Epetra Thyra wrapped objects"
281 if(verbose) *out <<
"\n*** (B.0) Testing idempotency of transformation: RCP<const Epetra_Map> => RCP<const VectorSpaceBase<double> => RCP<const Epetra_Map> \n";
282 RCP<const Epetra_Map> epetra_map_from_vs =
get_Epetra_Map(epetra_vs);
284 result = epetra_map->SameAs(*epetra_map_from_vs);
285 if(!result) success =
false;
292 if(verbose) *out <<
"\n*** (B.1) Testing individual vector/multi-vector RTOps\n";
294 Thyra::assign( ev1.ptr(), 0.0 );
295 Thyra::assign( ev2.ptr(), scalar );
296 Thyra::assign( nev1.ptr(), 0.0 );
297 Thyra::assign( nev2.ptr(), scalar );
298 Thyra::assign( eV1.ptr(), 0.0 );
299 Thyra::assign( eV2.ptr(), scalar );
300 Thyra::assign( neV1.ptr(), 0.0 );
301 Thyra::assign( neV2.ptr(), scalar );
304 ev1_nrm = Thyra::norm_1(*ev1),
305 ev2_nrm = Thyra::norm_1(*ev2),
306 eV1_nrm = Thyra::norm_1(*eV1),
307 eV2_nrm = Thyra::norm_1(*eV2),
308 nev1_nrm = Thyra::norm_1(*nev1),
309 nev2_nrm = Thyra::norm_1(*nev2),
310 neV1_nrm = Thyra::norm_1(*neV1),
311 neV2_nrm = Thyra::norm_1(*neV2);
313 const std::string s1_n =
"fabs(scalar)*global_dim";
314 const Scalar s1 = fabs(scalar)*global_dim;
316 if(!
testRelErr(
"Thyra::norm_1(ev1)",ev1_nrm,
"0",Scalar(0),
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
317 if(verbose && dumpAll) *out <<
"\nev1 =\n" << *ev1;
318 if(!
testRelErr(
"Thyra::norm_1(ev2)",ev2_nrm,s1_n,s1,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
319 if(verbose && dumpAll) *out <<
"\nev2 =\n" << *ev2;
320 if(!
testRelErr(
"Thyra::norm_1(nev1)",nev1_nrm,
"0",Scalar(0),
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
321 if(verbose && dumpAll) *out <<
"\nnev2 =\n" << *ev1;
322 if(!
testRelErr(
"Thyra::norm_1(nev2)",nev2_nrm,s1_n,s1,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
323 if(verbose && dumpAll) *out <<
"\nnev2 =\n" << *nev2;
324 if(!
testRelErr(
"Thyra::norm_1(eV1)",eV1_nrm,
"0",Scalar(0),
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
325 if(verbose && dumpAll) *out <<
"\neV1 =\n" << *eV1;
326 if(!
testRelErr(
"Thyra::norm_1(eV2)",eV2_nrm,s1_n,s1,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
327 if(verbose && dumpAll) *out <<
"\neV2 =\n" << *eV2;
328 if(!
testRelErr(
"Thyra::norm_1(neV1)",neV1_nrm,
"0",Scalar(0),
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
329 if(verbose && dumpAll) *out <<
"\nneV1 =\n" << *neV1;
330 if(!
testRelErr(
"Thyra::norm_1(neV2)",neV2_nrm,s1_n,s1,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
331 if(verbose && dumpAll) *out <<
"\nneV2 =\n" << *neV2;
333 if(verbose) *out <<
"\n*** (B.2) Test RTOps with two or more arguments\n";
335 if(verbose) *out <<
"\nPerforming ev1 = ev2 ...\n";
337 Thyra::assign( ev1.ptr(), *ev2 );
340 if(!
testRelErr(
"Thyra::norm_1(ev1)",Thyra::norm_1(*ev1),
"Thyra::norm_1(ev2)",ev2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
341 if(verbose && dumpAll) *out <<
"\nev1 =\n" << *ev1;
343 if(verbose) *out <<
"\nPerforming eV1 = eV2 ...\n";
345 Thyra::assign( eV1.ptr(), *eV2 );
348 if(!
testRelErr(
"Thyra::norm_1(eV1)",Thyra::norm_1(*eV1),
"Thyra::norm_1(eV2)",eV2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
349 if(verbose && dumpAll) *out <<
"\neV1 =\n" << *eV1;
351 if(verbose) *out <<
"\nPerforming ev1 = nev2 ...\n";
353 Thyra::assign( ev1.ptr(), *nev2 );
356 if(!
testRelErr(
"Thyra::norm_1(ev1)",Thyra::norm_1(*ev1),
"Thyra::norm_1(nev2)",nev2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
357 if(verbose && dumpAll) *out <<
"\nev1 =\n" << *ev1;
359 if(verbose) *out <<
"\nPerforming nev1 = ev2 ...\n";
361 Thyra::assign( nev1.ptr(), *ev2 );
364 if(!
testRelErr(
"Thyra::norm_1(nev1)",Thyra::norm_1(*nev1),
"Thyra::norm_1(ev2)",ev2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
365 if(verbose && dumpAll) *out <<
"\nnev1 =\n" << *nev1;
367 if(verbose) *out <<
"\nPerforming nev1 = nev2 ...\n";
369 Thyra::assign( nev1.ptr(), *nev2 );
372 if(!
testRelErr(
"Thyra::norm_1(nev1)",Thyra::norm_1(*nev1),
"Thyra::norm_1(nev2)",nev2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
373 if(verbose && dumpAll) *out <<
"\nnev1 =\n" << *nev1;
375 if(verbose) *out <<
"\nPerforming eV1 = neV2 ...\n";
377 Thyra::assign( eV1.ptr(), *neV2 );
380 if(!
testRelErr(
"Thyra::norm_1(eV1)",Thyra::norm_1(*eV1),
"Thyra::norm_1(neV2)",neV2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
381 if(verbose && dumpAll) *out <<
"\neV1 =\n" << *eV1;
383 if(verbose) *out <<
"\nPerforming neV1 = eV2 ...\n";
385 Thyra::assign( neV1.ptr(), *eV2 );
388 if(!
testRelErr(
"Thyra::norm_1(neV1)",Thyra::norm_1(*neV1),
"Thyra::norm_1(eV2)",eV2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
389 if(verbose && dumpAll) *out <<
"\nneV1 =\n" << *neV1;
391 if(verbose) *out <<
"\nPerforming neV1 = neV2 ...\n";
393 Thyra::assign( neV1.ptr(), *neV2 );
396 if(!
testRelErr(
"Thyra::norm_1(neV1)",Thyra::norm_1(*neV1),
"Thyra::norm_1(neV2)",neV2_nrm,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
397 if(verbose && dumpAll) *out <<
"\nneV1 =\n" << *neV1;
399 Thyra::LinearOpTester<Scalar> linearOpTester;
400 linearOpTester.set_all_warning_tol(max_rel_warn);
401 linearOpTester.set_all_error_tol(max_rel_err);
402 linearOpTester.dump_all(dumpAll);
404 Thyra::LinearOpWithSolveTester<Scalar> linearOpWithSolveTester;
405 linearOpWithSolveTester.set_all_solve_tol(max_rel_err);
406 linearOpWithSolveTester.set_all_slack_error_tol(max_rel_err);
407 linearOpWithSolveTester.set_all_slack_warning_tol(max_rel_warn);
408 linearOpWithSolveTester.dump_all(dumpAll);
411 if(verbose) *out <<
"\n*** (B.3) Test Vector linear operator interface\n";
413 if(verbose) *out <<
"\nChecking *out linear operator interface of ev1 ...\n";
414 result = linearOpTester.check(*ev1,out.ptr());
415 if(!result) success =
false;
417 if(verbose) *out <<
"\nChecking *out linear operator interface of nev1 ...\n";
418 result = linearOpTester.check(*nev1,out.ptr());
419 if(!result) success =
false;
422 if(verbose) *out <<
"\n*** (B.4) Test MultiVector linear operator interface\n";
424 if(verbose) *out <<
"\nChecking *out linear operator interface of eV1 ...\n";
425 result = linearOpTester.check(*eV1,out.ptr());
426 if(!result) success =
false;
428 if(verbose) *out <<
"\nChecking *out linear operator interface of neV1 ...\n";
429 result = linearOpTester.check(*neV1,out.ptr());
430 if(!result) success =
false;
432 const std::string s2_n =
"scalar^2*global_dim*num_mv_cols";
433 const Scalar s2 = scalar*scalar*global_dim*num_mv_cols;
435 RCP<Thyra::MultiVectorBase<Scalar> >
436 T = createMembers(eV1->domain(),num_mv_cols);
439 if(verbose) *out <<
"\n*** (B.5) Test MultiVector::apply(...)\n";
441 if(verbose) *out <<
"\nPerforming eV1'*eV2 ...\n";
443 apply( *eV1,
TRANS, *eV2, T.ptr() );
446 if(!
testRelErr(
"Thyra::norm_1(eV1'*eV2)",Thyra::norm_1(*T),s2_n,s2,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
447 if(verbose && dumpAll) *out <<
"\neV1'*eV2 =\n" << *T;
449 if(verbose) *out <<
"\nPerforming neV1'*eV2 ...\n";
451 apply( *neV1,
TRANS, *eV2, T.ptr() );
454 if(!
testRelErr(
"Thyra::norm_1(neV1'*eV2)",Thyra::norm_1(*T),s2_n,s2,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
455 if(verbose && dumpAll) *out <<
"\nneV1'*eV2 =\n" << *T;
457 if(verbose) *out <<
"\nPerforming eV1'*neV2 ...\n";
459 apply( *eV1,
TRANS, *neV2, T.ptr() );
462 if(!
testRelErr(
"Thyra::norm_1(eV1'*neV2)",Thyra::norm_1(*T),s2_n,s2,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
463 if(verbose && dumpAll) *out <<
"\neV1'*neV2 =\n" << *T;
465 if(verbose) *out <<
"\nPerforming neV1'*neV2 ...\n";
467 apply( *neV1,
TRANS, *neV2, T.ptr() );
470 if(!
testRelErr(
"Thyra::norm_1(neV1'*neV2)",Thyra::norm_1(*T),s2_n,s2,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
471 if(verbose && dumpAll) *out <<
"\nneV1'*neV2 =\n" << *T;
474 if(verbose) *out <<
"\n*** (B.6) Creating a diagonal Epetra_Operator Op\n";
476 RCP<Epetra_Operator> epetra_op;
480 RCP<Epetra_CrsMatrix>
481 epetra_mat =
rcp(
new Epetra_CrsMatrix(::
Copy,*epetra_map,1));
482 Scalar values[1] = { scalar };
484 const int IB = epetra_map->IndexBase(), offset = procRank*local_dim;
485 for(
int k = 0; k < local_dim; ++k ) {
486 indices[0] = offset + k + IB;
487 epetra_mat->InsertGlobalValues(
494 epetra_mat->FillComplete();
495 epetra_op = epetra_mat;
498 RCP<const Thyra::LinearOpBase<Scalar> >
499 Op = Thyra::epetraLinearOp(epetra_op);
501 if(verbose && dumpAll) *out <<
"\nOp=\n" << *Op;
504 if(verbose) *out <<
"\n*** (B.6b) Going through partial then full initialization of EpetraLinearOp ...\n";
508 <<
"\nChecking isFullyUninitialized(*nonconstEpetraLinearOp())==true : ";
509 RCP<Thyra::EpetraLinearOp>
510 thyraEpetraOp = Thyra::nonconstEpetraLinearOp();
511 result = isFullyUninitialized(*thyraEpetraOp);
512 if(!result) success =
false;
513 if(verbose) *out << Thyra::passfail(result) << endl;
519 <<
"\nthyraEpetraOp = partialNonconstEpetraLinearOp(...)\n";
520 RCP<Thyra::EpetraLinearOp> thyraEpetraOp =
521 Thyra::partialNonconstEpetraLinearOp(
522 epetra_vs, epetra_vs, epetra_op
526 <<
"\nChecking isPartiallyInitialized(*thyraEpetraOp)==true : ";
527 result = isPartiallyInitialized(*thyraEpetraOp);
528 if(!result) success =
false;
529 if(verbose) *out << Thyra::passfail(result) << endl;
532 <<
"\nthyraEpetraOp->setFullyInitialized(true)\n";
533 thyraEpetraOp->setFullyInitialized(
true);
536 <<
"\nChecking isFullyInitialized(*thyraEpetraOp)==true : ";
537 result = isFullyInitialized(*thyraEpetraOp);
538 if(!result) success =
false;
539 if(verbose) *out << Thyra::passfail(result) << endl;
544 if(verbose) *out <<
"\n*** (B.7) Test EpetraLinearOp linear operator interface\n";
546 if(verbose) *out <<
"\nChecking *out linear operator interface of Op ...\n";
547 result = linearOpTester.check(*Op,out.ptr());
548 if(!result) success =
false;
550 RCP<Thyra::VectorBase<Scalar> >
551 ey = createMember(epetra_vs);
552 RCP<Thyra::MultiVectorBase<Scalar> >
553 eY = createMembers(epetra_vs,num_mv_cols);
554 RCP<Thyra::VectorBase<Scalar> >
555 ney = createMember(non_epetra_vs);
556 RCP<Thyra::MultiVectorBase<Scalar> >
557 neY = createMembers(non_epetra_vs,num_mv_cols);
560 if(verbose) *out <<
"\n*** (B.8) Mix and match vector and Multi-vectors with Epetra opeator\n";
562 const std::string s3_n =
"2*scalar^2*global_dim";
563 const Scalar s3 = 2*scalar*scalar*global_dim;
565 if(verbose) *out <<
"\nPerforming ey = 2*Op*ev1 ...\n";
567 apply( *Op,
NOTRANS, *ev1, ey.ptr(), 2.0 );
570 if(!
testRelErr(
"Thyra::norm_1(ey)",Thyra::norm_1(*ey),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
572 if(verbose) *out <<
"\nPerforming eY = 2*Op*eV1 ...\n";
574 apply( *Op,
NOTRANS, *eV1, eY.ptr(), 2.0 );
577 if(!
testRelErr(
"Thyra::norm_1(eY)",Thyra::norm_1(*eY),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
579 if(verbose) *out <<
"\nPerforming ney = 2*Op*ev1 ...\n";
581 apply( *Op,
NOTRANS, *ev1, ney.ptr(), 2.0 );
584 if(!
testRelErr(
"Thyra::norm_1(ney)",Thyra::norm_1(*ney),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
586 if(verbose) *out <<
"\nPerforming neY = 2*Op*eV1 ...\n";
588 apply( *Op,
NOTRANS, *eV1, neY.ptr(), 2.0 );
591 if(!
testRelErr(
"Thyra::norm_1(neY)",Thyra::norm_1(*neY),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
593 if(verbose) *out <<
"\nPerforming ey = 2*Op*nev1 ...\n";
595 apply( *Op,
NOTRANS, *nev1, ey.ptr(), 2.0 );
598 if(!
testRelErr(
"Thyra::norm_1(ey)",Thyra::norm_1(*ey),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
600 if(verbose) *out <<
"\nPerforming eY = 2*Op*neV1 ...\n";
602 apply( *Op,
NOTRANS, *neV1, eY.ptr(), 2.0 );
605 if(!
testRelErr(
"Thyra::norm_1(eY)",Thyra::norm_1(*eY),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
607 if(verbose) *out <<
"\nPerforming ney = 2*Op*nev1 ...\n";
609 apply( *Op,
NOTRANS, *nev1, ney.ptr(), 2.0 );
612 if(!
testRelErr(
"Thyra::norm_1(ney)",Thyra::norm_1(*ney),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
614 if(verbose) *out <<
"\nPerforming ney = 2*Op*nev1 through MultiVector interface ...\n";
616 apply( *Op,
NOTRANS,
static_cast<const Thyra::MultiVectorBase<Scalar>&
>(*nev1), Ptr<Thyra::MultiVectorBase<Scalar> >(ney.ptr()), 2.0 );
619 if(!
testRelErr(
"Thyra::norm_1(ney)",Thyra::norm_1(*ney),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
621 if(verbose) *out <<
"\nPerforming neY = 2*Op*neV1 ...\n";
623 apply( *Op,
NOTRANS, *neV1, neY.ptr(), 2.0 );
626 if(!
testRelErr(
"Thyra::norm_1(neY)",Thyra::norm_1(*neY),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
629 if(verbose) *out <<
"\n*** (B.9) Testing Multi-vector views with Epetra operator\n";
631 const Thyra::Range1D col_rng(0,1);
634 RCP<const Thyra::MultiVectorBase<Scalar> >
635 eV1_v1 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(eV1)->subView(col_rng),
636 eV1_v2 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(eV1)->subView(cols);
637 RCP<const Thyra::MultiVectorBase<Scalar> >
638 neV1_v1 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(neV1)->subView(col_rng),
639 neV1_v2 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(neV1)->subView(cols);
640 if(verbose && dumpAll) {
641 *out <<
"\neV1_v1=\n" << *eV1_v1;
642 *out <<
"\neV1_v2=\n" << *eV1_v2;
643 *out <<
"\nneV1_v1=\n" << *neV1_v1;
644 *out <<
"\nneV1_v2=\n" << *neV1_v2;
647 if(verbose) *out <<
"\nPerforming eY_v1 = 2*Op*eV1_v1 ...\n";
649 apply( *Op,
NOTRANS, *eV1_v1, eY->subView(col_rng).ptr(), 2.0 );
652 if(verbose && dumpAll) *out <<
"\neV_v1=\n" << *eY->subView(col_rng);
653 if(!
testRelErr(
"Thyra::norm_1(eY_v1)",Thyra::norm_1(*eY->subView(col_rng)),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
655 if(verbose) *out <<
"\nPerforming eY_v2 = 2*Op*eV1_v2 ...\n";
657 apply( *Op,
NOTRANS, *eV1_v2, eY->subView(cols).ptr(), 2.0 );
660 if(verbose && dumpAll) *out <<
"\neV_v2=\n" << *eY->subView(cols);
661 if(!
testRelErr(
"Thyra::norm_1(eY_v2)",Thyra::norm_1(*eY->subView(cols)),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
663 if(verbose) *out <<
"\nPerforming neY_v1 = 2*Op*eV1_v1 ...\n";
665 apply( *Op,
NOTRANS, *eV1_v1, neY->subView(col_rng).ptr(), 2.0 );
668 if(verbose && dumpAll) *out <<
"\neV_v1=\n" << *eY->subView(col_rng);
669 if(!
testRelErr(
"Thyra::norm_1(neY_v1)",Thyra::norm_1(*neY->subView(col_rng)),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
671 if(verbose) *out <<
"\nPerforming eY_v1 = 2*Op*neV1_v1 ...\n";
673 apply( *Op,
NOTRANS, *neV1_v1, eY->subView(col_rng).ptr(), 2.0 );
676 if(!
testRelErr(
"Thyra::norm_1(eY_v1)",Thyra::norm_1(*eY->subView(col_rng)),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
678 if(verbose) *out <<
"\nPerforming neY_v2 = 2*Op*eV1_v2 ...\n";
680 apply( *Op,
NOTRANS, *eV1_v2, neY->subView(cols).ptr(), 2.0 );
683 if(verbose && dumpAll) *out <<
"\neV_v2=\n" << *eY->subView(cols);
684 if(!
testRelErr(
"Thyra::norm_1(neY_v2)",Thyra::norm_1(*neY->subView(cols)),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
686 if(verbose) *out <<
"\nPerforming eY_v2 = 2*Op*neV1_v2 ...\n";
688 apply( *Op,
NOTRANS, *neV1_v2, eY->subView(cols).ptr(), 2.0 );
691 if(verbose && dumpAll) *out <<
"\neV_v2=\n" << *eY->subView(cols);
692 if(!
testRelErr(
"Thyra::norm_1(eY_v2)",Thyra::norm_1(*eY->subView(cols)),s3_n,s3,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
695 if(verbose) *out <<
"\n*** (B.10) Testing Vector and MultiVector view creation functions\n";
699 const std::string s_n =
"fabs(scalar)*num_mv_cols";
700 const Scalar s = fabs(scalar)*num_mv_cols;
702 Array<Scalar> t_raw_values( num_mv_cols );
704 arcpFromArray(t_raw_values), 1 );
706 std::fill_n( t_raw_values.begin(), t_raw_values.size(), ST::zero() );
707 Thyra::assign( createMemberView(T->range(),t_raw).ptr(), scalar );
709 Scalar t_nrm = Thyra::norm_1(*t_view);
710 if(!
testRelErr(
"Thyra::norm_1(t_view)",t_nrm,s_n,s,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
711 if(verbose && dumpAll) *out <<
"\nt_view =\n" << *t_view;
714 std::fill_n( t_raw_values.begin(), t_raw_values.size(), ST::zero() );
715 Thyra::assign( T->range().ptr()->Thyra::VectorSpaceBase<Scalar>::createMemberView(t_raw), scalar );
717 t_nrm = Thyra::norm_1(*t_view);
718 if(!
testRelErr(
"Thyra::norm_1(t_view)",t_nrm,s_n,s,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
719 if(verbose && dumpAll) *out <<
"\nt_view =\n" << *t_view;
722 Array<Scalar> T_raw_values( num_mv_cols * num_mv_cols );
724 arcpFromArray(T_raw_values), num_mv_cols );
726 std::fill_n( T_raw_values.begin(), T_raw_values.size(), ST::zero() );
727 Thyra::assign( createMembersView(T->range(),T_raw).ptr(), scalar );
730 Scalar T_nrm = Thyra::norm_1(*T_view);
731 if(!
testRelErr(
"Thyra::norm_1(T_view)",T_nrm,s_n,s,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
732 if(verbose && dumpAll) *out <<
"\nT_view =\n" << *T_view;
735 std::fill_n( T_raw_values.begin(), T_raw_values.size(), ST::zero() );
736 Thyra::assign( T->range().ptr()->Thyra::VectorSpaceBase<Scalar>::createMembersView(T_raw), scalar );
738 T_nrm = Thyra::norm_1(*T_view);
739 if(!
testRelErr(
"Thyra::norm_1(T_view)",T_nrm,s_n,s,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())) success=
false;
740 if(verbose && dumpAll) *out <<
"\nT_view =\n" << *T_view;
746 if(verbose) *out <<
"\n*** (B.11) Testing Epetra_Vector and Epetra_MultiVector wrappers\n";
751 mpi_vs = Teuchos::rcp_dynamic_cast<
const Thyra::SpmdVectorSpaceBase<Scalar> >(epetra_vs,
true);
753 if(verbose) *out <<
"\nCreating temporary Epetra_Vector et1 and Epetra_MultiVector eT1 objects ...\n";
757 eT1 =
Teuchos::rcp(
new Epetra_MultiVector(*epetra_map,num_mv_cols));
759 if(verbose) *out <<
"\nCreating non-const VectorBase t1 and MultiVectorBase T1 objects from et1 and eT2 ...\n";
765 if(verbose) *out <<
"\nPerforming t1 = ev1 ...\n";
766 assign( t1.
ptr(), *ev1 );
768 "sum(t1)",Thyra::sum(*t1),
"sum(ev1)",sum(*ev1)
769 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
772 if(verbose) *out <<
"\nPerforming T1 = eV1 ...\n";
773 assign( T1.
ptr(), *eV1 );
775 "norm_1(T1)",Thyra::norm_1(*T1),
"norm_1(eV1)",norm_1(*eV1)
776 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
779 if(verbose) *out <<
"\nChecking that t1 and T1 yield the same objects as et1 and eT2 ...\n";
783 result = et1_v.
get() == et1.
get();
784 if(verbose) *out <<
"\net1_v.get() = " << et1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
785 if(!result) success =
false;
789 result = et1_v.
get() == et1.
get();
790 if(verbose) *out <<
"\net1_v.get() = " << et1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
791 if(!result) success =
false;
795 result = eT1_v.
get() == eT1.
get();
796 if(verbose) *out <<
"\neT1_v.get() = " << eT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
797 if(!result) success =
false;
801 result = eT1_v.
get() == eT1.
get();
802 if(verbose) *out <<
"\neT1_v.get() = " << eT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
803 if(!result) success =
false;
805 if(verbose) *out <<
"\nCreating const VectorBase ct1 and MultiVectorBase cT1 objects from et1 and eT2 ...\n";
807 ct1 =
create_Vector(Teuchos::rcp_implicit_cast<const Epetra_Vector>(et1),mpi_vs);
809 cT1 =
create_MultiVector(Teuchos::rcp_implicit_cast<const Epetra_MultiVector>(eT1),mpi_vs);
812 "sum(ct1)",Thyra::sum(*ct1),
"sum(ev1)",sum(*ev1)
813 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
817 "norm_1(cT1)",Thyra::norm_1(*cT1),
"norm_1(eV1)",norm_1(*eV1)
818 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
821 if(verbose) *out <<
"\nChecking that ct1 and cT1 yield the same objects as et1 and eT2 ...\n";
825 result = cet1_v.
get() == et1.
get();
826 if(verbose) *out <<
"\ncet1_v.get() = " << cet1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
827 if(!result) success =
false;
831 result = cet1_v.
get() == et1.
get();
832 if(verbose) *out <<
"\ncet1_v.get() = " << cet1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
833 if(!result) success =
false;
837 result = ceT1_v.
get() == eT1.
get();
838 if(verbose) *out <<
"\nceT1_v.get() = " << ceT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
839 if(!result) success =
false;
843 result = ceT1_v.
get() == eT1.
get();
844 if(verbose) *out <<
"\nceT1_v.get() = " << ceT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
845 if(!result) success =
false;
847 if(verbose) *out <<
"\nCreating non-const Epetra_Vector ett1 and Epetra_MultiVector etT1 objects from clones of t1 and T2 ...\n";
853 if(verbose) *out <<
"\nChecking that ett1 and etT1 yield objects with the same value as et1 and eT2 ...\n";
856 "sum(ett1)",sum(*ett1),
"sum(et1)",sum(*et1)
857 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
861 "sum(etT1)",sum(*etT1),
"sum(eT1)",sum(*eT1)
862 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
865 if(verbose) *out <<
"\nCreating const Epetra_Vector cett1 and Epetra_MultiVector cetT1 objects from clones of t1 and T2 ...\n";
867 cett1 =
get_Epetra_Vector(*epetra_map,Teuchos::rcp_implicit_cast<
const Thyra::VectorBase<Scalar> >(t1->clone_v()));
869 cetT1 =
get_Epetra_MultiVector(*epetra_map,Teuchos::rcp_implicit_cast<
const Thyra::MultiVectorBase<Scalar> >(T1->clone_mv()));
871 if(verbose) *out <<
"\nChecking that cett1 and cetT1 yield objects with the same value as et1 and eT2 ...\n";
874 "sum(cett1)",sum(*cett1),
"sum(et1)",sum(*et1)
875 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
879 "sum(cetT1)",sum(*cetT1),
"sum(eT1)",sum(*eT1)
880 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
886 if(verbose) *out <<
"\n*** (B.12) Test DiagonalEpetraLinearOpWithSolveFactory \n";
890 if(verbose) *out <<
"\nUsing DiagonalEpetraLinearOpWithSolveFactory to create diagLOWS from Op ...\n";
895 diagLOWS = Thyra::linearOpWithSolve<double>(diagLOWSFactory,Op);
897 if(verbose) *out <<
"\nTesting LinearOpBase interface of diagLOWS ...\n";
899 result = linearOpTester.check(*diagLOWS, out.
ptr());
900 if(!result) success =
false;
902 if(verbose) *out <<
"\nTesting LinearOpWithSolveBase interface of diagLOWS ...\n";
904 result = linearOpWithSolveTester.check(*diagLOWS, &*out);
905 if(!result) success =
false;
913 <<
"\n*** (C) Comparing the speed of Thyra adapted Epetra objects verses raw Epetra objects"
937 double raw_epetra_time, thyra_wrapped_time;
940 if(verbose) *out <<
"\n*** (C.1) Comparing the speed of RTOp verses raw Epetra_Vector operations\n";
942 const double flop_adjust_factor_1 = 3.0;
943 const int num_time_loops_1 = int( max_flop_rate / ( flop_adjust_factor_1 * local_dim * num_mv_cols ) ) + 1;
952 *out <<
"\nPerforming eeV1 = eeV2 (using raw Epetra_MultiVector::operator=(...)) " << num_time_loops_1 <<
" times ...\n";
954 for(
int k = 0; k < num_time_loops_1; ++k ) {
959 if(verbose) *out <<
" total time = " << raw_epetra_time <<
" sec\n";
965 *out <<
"\nPerforming eV1 = eV2 (using Thyra::SpmdMultiVectorBase::applyOp(...)) " << num_time_loops_1 <<
" times ...\n";
967 for(
int k = 0; k < num_time_loops_1; ++k ) {
968 Thyra::assign( eV1.ptr(), *eV2 );
972 if(verbose) *out <<
" total time = " << thyra_wrapped_time <<
" sec\n";
974 print_performance_stats( num_time_loops_1, raw_epetra_time, thyra_wrapped_time, verbose, *out );
990 <<
"\n*** (C.2) Comparing Thyra::SpmdMultiVectorBase::apply() verses raw Epetra_MultiVector::Multiply()\n";
994 const double flop_adjust_factor_2 = 2.0;
995 const int num_time_loops_2 = int( max_flop_rate / ( flop_adjust_factor_2* local_dim * num_mv_cols * num_mv_cols ) ) + 1;
1003 Epetra_LocalMap eT_map((
int) T->range()->dim(),0,*epetra_comm);
1004 Epetra_MultiVector eT(eT_map,T->domain()->dim());
1007 *out <<
"\nPerforming eeV1'*eeV2 (using raw Epetra_MultiVector::Multiply(...)) " << num_time_loops_2 <<
" times ...\n";
1009 for(
int k = 0; k < num_time_loops_2; ++k ) {
1010 eT.Multiply(
'T',
'N', 1.0, *eeV1, *eeV2, 0.0 );
1014 if(verbose) *out <<
" total time = " << raw_epetra_time <<
" sec\n";
1019 *out <<
"\nPerforming eV1'*eV2 (using Thyra::SpmdMultiVectorBase::apply(...)) " << num_time_loops_2 <<
" times ...\n";
1021 for(
int k = 0; k < num_time_loops_2; ++k ) {
1022 apply( *eV1,
TRANS, *eV2, T.ptr() );
1026 if(verbose) *out <<
" total time = " << thyra_wrapped_time <<
" sec\n";
1028 print_performance_stats( num_time_loops_2, raw_epetra_time, thyra_wrapped_time, verbose, *out );
1039 if(verbose) *out <<
"\n*** (C.3) Comparing Thyra::EpetraLinearOp::apply() verses raw Epetra_Operator::apply()\n";
1043 const double flop_adjust_factor_3 = 10.0;
1044 const int num_time_loops_3 = int( max_flop_rate / ( flop_adjust_factor_3 * local_dim * num_mv_cols ) ) + 1;
1053 *out <<
"\nPerforming eeY = eOp*eeV1 (using raw Epetra_Operator::apply(...)) " << num_time_loops_3 <<
" times ...\n";
1058 epetra_op->SetUseTranspose(
false);
1059 for(
int k = 0; k < num_time_loops_3; ++k ) {
1060 epetra_op->Apply( *eeV1, *eeY );
1066 if(verbose) *out <<
" total time = " << raw_epetra_time <<
" sec\n";
1074 *out <<
"\nPerforming eY = Op*eV1 (using Thyra::EpetraLinearOp::apply(...)) " << num_time_loops_3 <<
" times ...\n";
1079 for(
int k = 0; k < num_time_loops_3; ++k ) {
1080 apply( *Op,
NOTRANS, *eV1, eY.ptr() );
1085 if(verbose) *out <<
" total time = " << thyra_wrapped_time <<
" sec\n";
1090 print_performance_stats( num_time_loops_3, raw_epetra_time, thyra_wrapped_time, verbose, *out );
1102 if(success) *out <<
"\nCongratulations! All of the tests seem to have run sucessfully!\n";
1103 else *out <<
"\nOh no! at least one of the tests did not check out!\n";
1106 return (success ? 0 : -1);
RCP< Epetra_MultiVector > get_Epetra_MultiVector(const Epetra_Map &map, const RCP< MultiVectorBase< double > > &mv)
Get a non-const Epetra_MultiVector view from a non-const MultiVectorBase object if possible...
RCP< const Epetra_Map > get_Epetra_Map(const VectorSpaceBase< double > &vs, const RCP< const Epetra_Comm > &comm)
Get (or create) an Epetra_Map object given an VectorSpaceBase object an optionally an extra Epetra_Co...
RCP< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Create an VectorSpaceBase object given an Epetra_Map object.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
const std::string passfail(const bool result)
RCP< MultiVectorBase< double > > create_MultiVector(const RCP< Epetra_MultiVector > &epetra_mv, const RCP< const VectorSpaceBase< double > > &range=Teuchos::null, const RCP< const VectorSpaceBase< double > > &domain=Teuchos::null)
Create a non-const MultiVectorBase object from a non-const Epetra_MultiVector object.
void start(bool reset=false)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
RCP< VectorBase< double > > create_Vector(const RCP< Epetra_Vector > &epetra_v, const RCP< const VectorSpaceBase< double > > &space=Teuchos::null)
Create a non-const VectorBase object from a non-const Epetra_Vector object.
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
T_To & dyn_cast(T_From &from)
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
RCP< Epetra_Vector > get_Epetra_Vector(const Epetra_Map &map, const RCP< VectorBase< double > > &v)
Get a non-const Epetra_Vector view from a non-const VectorBase object if possible.
int main(int argc, char *argv[])
bool testRelErr(const std::string &v1_name, const T1 &v1, const std::string &v2_name, const T2 &v2, const std::string &maxRelErr_error_name, const typename TestRelErr< T1, T2 >::magnitudeType &maxRelErr_error, const std::string &maxRelErr_warning_name, const typename TestRelErr< T1, T2 >::magnitudeType &maxRelErr_warning, const Ptr< std::ostream > &out)
double totalElapsedTime(bool readCurrentTime=false) const
Create a DefaultDiagonalLinearOpWithSolve out of a diagonal Epetra_RowMatrix object.
RCP< const Teuchos::Comm< Ordinal > > create_Comm(const RCP< const Epetra_Comm > &epetraComm)
Given an Epetra_Comm object, return an equivalent Teuchos::Comm object.
static void zeroOutTimers()