44 #include "Thyra_TestingTools.hpp"
45 #include "Thyra_LinearOpTester.hpp"
46 #include "Thyra_LinearOpWithSolveTester.hpp"
48 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
49 #include "Thyra_DefaultSpmdVectorSpace.hpp"
50 #include "Thyra_MultiVectorStdOps.hpp"
51 #include "Epetra_SerialComm.h"
52 #include "Epetra_LocalMap.h"
53 #include "Epetra_CrsMatrix.h"
54 #include "Epetra_MultiVector.h"
55 #include "Epetra_Vector.h"
63 # include "Epetra_MpiComm.h"
72 void print_performance_stats(
73 const int num_time_samples
74 ,
const double raw_epetra_time
75 ,
const double thyra_wrapped_time
82 <<
"\nAverage times (out of " << num_time_samples <<
" samples):\n"
83 <<
" Raw Epetra = " << (raw_epetra_time/num_time_samples) << std::endl
84 <<
" Thyra Wrapped Epetra = " << (thyra_wrapped_time/num_time_samples) << std::endl
85 <<
"\nRelative performance of Thyra wrapped verses raw Epetra:\n"
86 <<
" ( raw epetra time / thyra wrapped time ) = ( " << raw_epetra_time <<
" / " << thyra_wrapped_time <<
" ) = "
87 << (raw_epetra_time/thyra_wrapped_time) << std::endl;
91 double sum(
const Epetra_MultiVector &ev )
93 std::vector<double> meanValues(ev.NumVectors());
94 ev.MeanValue(&meanValues[0]);
96 for(
int i = 0; i < ev.NumVectors(); ++i ) sum += meanValues[i];
97 return (ev.Map().NumGlobalElements()*sum);
115 int main(
int argc,
char* argv[] )
120 typedef double Scalar;
130 using Teuchos::arcpFromArray;
132 using Teuchos::rcp_static_cast;
133 using Teuchos::rcp_const_cast;
136 using Thyra::passfail;
137 using Thyra::NOTRANS;
153 RCP<Teuchos::FancyOStream>
154 out = Teuchos::VerboseObjectBase::getDefaultOStream();
164 int local_dim = 1000;
166 double max_rel_err = 1e-13;
167 double max_rel_warn = 1e-15;
169 double max_flop_rate = 1.0;
173 CommandLineProcessor clp;
174 clp.throwExceptions(
false);
175 clp.addOutputSetupOptions(
true);
176 clp.setOption(
"verbose",
"quiet", &verbose,
"Determines if any output is printed or not." );
177 clp.setOption(
"dump-all",
"no-dump", &dumpAll,
"Determines if quantities are dumped or not." );
178 clp.setOption(
"local-dim", &local_dim,
"Number of vector elements per process." );
179 clp.setOption(
"num-mv-cols", &num_mv_cols,
"Number columns in each multi-vector (>=4)." );
180 clp.setOption(
"max-rel-err-tol", &max_rel_err,
"Maximum relative error tolerance for tests." );
181 clp.setOption(
"max-rel-warn-tol", &max_rel_warn,
"Maximum relative warning tolerance for tests." );
182 clp.setOption(
"scalar", &scalar,
"A scalar used in all computations." );
183 clp.setOption(
"max-flop-rate", &max_flop_rate,
"Approx flop rate used for loop timing." );
185 clp.setOption(
"use-mpi",
"no-use-mpi", &useMPI,
"Actually use MPI or just run independent serial programs." );
187 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
188 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL )
return parse_return;
191 num_mv_cols < 4, std::logic_error
192 ,
"Error, num-mv-cols must be >= 4!"
203 mpiComm = MPI_COMM_WORLD;
204 MPI_Comm_size( mpiComm, &numProc );
205 MPI_Comm_rank( mpiComm, &procRank );
208 mpiComm = MPI_COMM_NULL;
217 <<
"\n*** (A) Creating two vector spaces (an Epetra-based and a non-Epetra-based)"
224 RCP<const Epetra_Comm> epetra_comm;
225 RCP<const Epetra_Map> epetra_map;
226 RCP<const Thyra::VectorSpaceBase<Scalar> > epetra_vs;
227 RCP<const Thyra::VectorSpaceBase<Scalar> > non_epetra_vs;
234 if(verbose) *out <<
"\nCreating vector space using Epetra_MpiComm ...\n";
235 epetra_comm =
rcp(
new Epetra_MpiComm(mpiComm));
236 epetra_map =
rcp(
new Epetra_Map(-1,local_dim,0,*epetra_comm));
239 if(verbose) *out <<
"\nCreating Thyra::DefaultSpmdVectorSpace ...\n";
241 new Thyra::DefaultSpmdVectorSpace<Scalar>(
253 if(verbose) *out <<
"\nCreating vector space using Epetra_SerialComm ...\n";
254 epetra_comm =
rcp(
new Epetra_SerialComm);
255 epetra_map =
rcp(
new Epetra_LocalMap(local_dim,0,*epetra_comm));
258 if(verbose) *out <<
"\nCreating Thyra::DefaultSpmdVectorSpace ...\n";
259 non_epetra_vs = Thyra::defaultSpmdVectorSpace<Scalar>(local_dim);
262 #endif // end create vector spacdes [Doxygen looks for this!]
265 const int global_dim = local_dim * numProc;
267 const int global_dim = local_dim;
272 <<
"\nscalar = " << scalar
273 <<
"\nlocal_dim = " << local_dim
274 <<
"\nglobal_dim = " << global_dim
275 <<
"\nnum_mv_cols = " << num_mv_cols
276 <<
"\nepetra_vs.dim() = " << epetra_vs->dim()
277 <<
"\nnon_epetra_vs.dim() = " << non_epetra_vs->dim()
284 RCP<Thyra::VectorBase<Scalar> >
285 ev1 = createMember(epetra_vs),
286 ev2 = createMember(epetra_vs);
287 RCP<Thyra::VectorBase<Scalar> >
288 nev1 = createMember(non_epetra_vs),
289 nev2 = createMember(non_epetra_vs);
291 RCP<Thyra::MultiVectorBase<Scalar> >
292 eV1 = createMembers(epetra_vs,num_mv_cols),
293 eV2 = createMembers(epetra_vs,num_mv_cols);
294 RCP<Thyra::MultiVectorBase<Scalar> >
295 neV1 = createMembers(non_epetra_vs,num_mv_cols),
296 neV2 = createMembers(non_epetra_vs,num_mv_cols);
301 <<
"\n*** (B) Testing Epetra and non-Epetra Thyra wrapped objects"
313 if(verbose) *out <<
"\n*** (B.0) Testing idempotency of transformation: RCP<const Epetra_Map> => RCP<const VectorSpaceBase<double> => RCP<const Epetra_Map> \n";
314 RCP<const Epetra_Map> epetra_map_from_vs =
get_Epetra_Map(epetra_vs);
316 result = epetra_map->SameAs(*epetra_map_from_vs);
317 if(!result) success =
false;
324 if(verbose) *out <<
"\n*** (B.1) Testing individual vector/multi-vector RTOps\n";
326 Thyra::assign( ev1.ptr(), 0.0 );
327 Thyra::assign( ev2.ptr(), scalar );
328 Thyra::assign( nev1.ptr(), 0.0 );
329 Thyra::assign( nev2.ptr(), scalar );
330 Thyra::assign( eV1.ptr(), 0.0 );
331 Thyra::assign( eV2.ptr(), scalar );
332 Thyra::assign( neV1.ptr(), 0.0 );
333 Thyra::assign( neV2.ptr(), scalar );
336 ev1_nrm = Thyra::norm_1(*ev1),
337 ev2_nrm = Thyra::norm_1(*ev2),
338 eV1_nrm = Thyra::norm_1(*eV1),
339 eV2_nrm = Thyra::norm_1(*eV2),
340 nev1_nrm = Thyra::norm_1(*nev1),
341 nev2_nrm = Thyra::norm_1(*nev2),
342 neV1_nrm = Thyra::norm_1(*neV1),
343 neV2_nrm = Thyra::norm_1(*neV2);
345 const std::string s1_n =
"fabs(scalar)*global_dim";
346 const Scalar s1 = fabs(scalar)*global_dim;
348 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;
349 if(verbose && dumpAll) *out <<
"\nev1 =\n" << *ev1;
350 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;
351 if(verbose && dumpAll) *out <<
"\nev2 =\n" << *ev2;
352 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;
353 if(verbose && dumpAll) *out <<
"\nnev2 =\n" << *ev1;
354 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;
355 if(verbose && dumpAll) *out <<
"\nnev2 =\n" << *nev2;
356 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;
357 if(verbose && dumpAll) *out <<
"\neV1 =\n" << *eV1;
358 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;
359 if(verbose && dumpAll) *out <<
"\neV2 =\n" << *eV2;
360 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;
361 if(verbose && dumpAll) *out <<
"\nneV1 =\n" << *neV1;
362 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;
363 if(verbose && dumpAll) *out <<
"\nneV2 =\n" << *neV2;
365 if(verbose) *out <<
"\n*** (B.2) Test RTOps with two or more arguments\n";
367 if(verbose) *out <<
"\nPerforming ev1 = ev2 ...\n";
369 Thyra::assign( ev1.ptr(), *ev2 );
372 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;
373 if(verbose && dumpAll) *out <<
"\nev1 =\n" << *ev1;
375 if(verbose) *out <<
"\nPerforming eV1 = eV2 ...\n";
377 Thyra::assign( eV1.ptr(), *eV2 );
380 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;
381 if(verbose && dumpAll) *out <<
"\neV1 =\n" << *eV1;
383 if(verbose) *out <<
"\nPerforming ev1 = nev2 ...\n";
385 Thyra::assign( ev1.ptr(), *nev2 );
388 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;
389 if(verbose && dumpAll) *out <<
"\nev1 =\n" << *ev1;
391 if(verbose) *out <<
"\nPerforming nev1 = ev2 ...\n";
393 Thyra::assign( nev1.ptr(), *ev2 );
396 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;
397 if(verbose && dumpAll) *out <<
"\nnev1 =\n" << *nev1;
399 if(verbose) *out <<
"\nPerforming nev1 = nev2 ...\n";
401 Thyra::assign( nev1.ptr(), *nev2 );
404 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;
405 if(verbose && dumpAll) *out <<
"\nnev1 =\n" << *nev1;
407 if(verbose) *out <<
"\nPerforming eV1 = neV2 ...\n";
409 Thyra::assign( eV1.ptr(), *neV2 );
412 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;
413 if(verbose && dumpAll) *out <<
"\neV1 =\n" << *eV1;
415 if(verbose) *out <<
"\nPerforming neV1 = eV2 ...\n";
417 Thyra::assign( neV1.ptr(), *eV2 );
420 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;
421 if(verbose && dumpAll) *out <<
"\nneV1 =\n" << *neV1;
423 if(verbose) *out <<
"\nPerforming neV1 = neV2 ...\n";
425 Thyra::assign( neV1.ptr(), *neV2 );
428 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;
429 if(verbose && dumpAll) *out <<
"\nneV1 =\n" << *neV1;
431 Thyra::LinearOpTester<Scalar> linearOpTester;
432 linearOpTester.set_all_warning_tol(max_rel_warn);
433 linearOpTester.set_all_error_tol(max_rel_err);
434 linearOpTester.dump_all(dumpAll);
436 Thyra::LinearOpWithSolveTester<Scalar> linearOpWithSolveTester;
437 linearOpWithSolveTester.set_all_solve_tol(max_rel_err);
438 linearOpWithSolveTester.set_all_slack_error_tol(max_rel_err);
439 linearOpWithSolveTester.set_all_slack_warning_tol(max_rel_warn);
440 linearOpWithSolveTester.dump_all(dumpAll);
443 if(verbose) *out <<
"\n*** (B.3) Test Vector linear operator interface\n";
445 if(verbose) *out <<
"\nChecking *out linear operator interface of ev1 ...\n";
446 result = linearOpTester.check(*ev1,out.ptr());
447 if(!result) success =
false;
449 if(verbose) *out <<
"\nChecking *out linear operator interface of nev1 ...\n";
450 result = linearOpTester.check(*nev1,out.ptr());
451 if(!result) success =
false;
454 if(verbose) *out <<
"\n*** (B.4) Test MultiVector linear operator interface\n";
456 if(verbose) *out <<
"\nChecking *out linear operator interface of eV1 ...\n";
457 result = linearOpTester.check(*eV1,out.ptr());
458 if(!result) success =
false;
460 if(verbose) *out <<
"\nChecking *out linear operator interface of neV1 ...\n";
461 result = linearOpTester.check(*neV1,out.ptr());
462 if(!result) success =
false;
464 const std::string s2_n =
"scalar^2*global_dim*num_mv_cols";
465 const Scalar s2 = scalar*scalar*global_dim*num_mv_cols;
467 RCP<Thyra::MultiVectorBase<Scalar> >
468 T = createMembers(eV1->domain(),num_mv_cols);
471 if(verbose) *out <<
"\n*** (B.5) Test MultiVector::apply(...)\n";
473 if(verbose) *out <<
"\nPerforming eV1'*eV2 ...\n";
475 apply( *eV1,
TRANS, *eV2, T.ptr() );
478 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;
479 if(verbose && dumpAll) *out <<
"\neV1'*eV2 =\n" << *T;
481 if(verbose) *out <<
"\nPerforming neV1'*eV2 ...\n";
483 apply( *neV1,
TRANS, *eV2, T.ptr() );
486 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;
487 if(verbose && dumpAll) *out <<
"\nneV1'*eV2 =\n" << *T;
489 if(verbose) *out <<
"\nPerforming eV1'*neV2 ...\n";
491 apply( *eV1,
TRANS, *neV2, T.ptr() );
494 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;
495 if(verbose && dumpAll) *out <<
"\neV1'*neV2 =\n" << *T;
497 if(verbose) *out <<
"\nPerforming neV1'*neV2 ...\n";
499 apply( *neV1,
TRANS, *neV2, T.ptr() );
502 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;
503 if(verbose && dumpAll) *out <<
"\nneV1'*neV2 =\n" << *T;
506 if(verbose) *out <<
"\n*** (B.6) Creating a diagonal Epetra_Operator Op\n";
508 RCP<Epetra_Operator> epetra_op;
512 RCP<Epetra_CrsMatrix>
513 epetra_mat =
rcp(
new Epetra_CrsMatrix(::
Copy,*epetra_map,1));
514 Scalar values[1] = { scalar };
516 const int IB = epetra_map->IndexBase(), offset = procRank*local_dim;
517 for(
int k = 0; k < local_dim; ++k ) {
518 indices[0] = offset + k + IB;
519 epetra_mat->InsertGlobalValues(
526 epetra_mat->FillComplete();
527 epetra_op = epetra_mat;
530 RCP<const Thyra::LinearOpBase<Scalar> >
531 Op = Thyra::epetraLinearOp(epetra_op);
533 if(verbose && dumpAll) *out <<
"\nOp=\n" << *Op;
536 if(verbose) *out <<
"\n*** (B.6b) Going through partial then full initialization of EpetraLinearOp ...\n";
540 <<
"\nChecking isFullyUninitialized(*nonconstEpetraLinearOp())==true : ";
541 RCP<Thyra::EpetraLinearOp>
542 thyraEpetraOp = Thyra::nonconstEpetraLinearOp();
543 result = isFullyUninitialized(*thyraEpetraOp);
544 if(!result) success =
false;
545 if(verbose) *out << Thyra::passfail(result) << endl;
551 <<
"\nthyraEpetraOp = partialNonconstEpetraLinearOp(...)\n";
552 RCP<Thyra::EpetraLinearOp> thyraEpetraOp =
553 Thyra::partialNonconstEpetraLinearOp(
554 epetra_vs, epetra_vs, epetra_op
558 <<
"\nChecking isPartiallyInitialized(*thyraEpetraOp)==true : ";
559 result = isPartiallyInitialized(*thyraEpetraOp);
560 if(!result) success =
false;
561 if(verbose) *out << Thyra::passfail(result) << endl;
564 <<
"\nthyraEpetraOp->setFullyInitialized(true)\n";
565 thyraEpetraOp->setFullyInitialized(
true);
568 <<
"\nChecking isFullyInitialized(*thyraEpetraOp)==true : ";
569 result = isFullyInitialized(*thyraEpetraOp);
570 if(!result) success =
false;
571 if(verbose) *out << Thyra::passfail(result) << endl;
576 if(verbose) *out <<
"\n*** (B.7) Test EpetraLinearOp linear operator interface\n";
578 if(verbose) *out <<
"\nChecking *out linear operator interface of Op ...\n";
579 result = linearOpTester.check(*Op,out.ptr());
580 if(!result) success =
false;
582 RCP<Thyra::VectorBase<Scalar> >
583 ey = createMember(epetra_vs);
584 RCP<Thyra::MultiVectorBase<Scalar> >
585 eY = createMembers(epetra_vs,num_mv_cols);
586 RCP<Thyra::VectorBase<Scalar> >
587 ney = createMember(non_epetra_vs);
588 RCP<Thyra::MultiVectorBase<Scalar> >
589 neY = createMembers(non_epetra_vs,num_mv_cols);
592 if(verbose) *out <<
"\n*** (B.8) Mix and match vector and Multi-vectors with Epetra opeator\n";
594 const std::string s3_n =
"2*scalar^2*global_dim";
595 const Scalar s3 = 2*scalar*scalar*global_dim;
597 if(verbose) *out <<
"\nPerforming ey = 2*Op*ev1 ...\n";
599 apply( *Op,
NOTRANS, *ev1, ey.ptr(), 2.0 );
602 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;
604 if(verbose) *out <<
"\nPerforming eY = 2*Op*eV1 ...\n";
606 apply( *Op,
NOTRANS, *eV1, eY.ptr(), 2.0 );
609 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;
611 if(verbose) *out <<
"\nPerforming ney = 2*Op*ev1 ...\n";
613 apply( *Op,
NOTRANS, *ev1, ney.ptr(), 2.0 );
616 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;
618 if(verbose) *out <<
"\nPerforming neY = 2*Op*eV1 ...\n";
620 apply( *Op,
NOTRANS, *eV1, neY.ptr(), 2.0 );
623 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;
625 if(verbose) *out <<
"\nPerforming ey = 2*Op*nev1 ...\n";
627 apply( *Op,
NOTRANS, *nev1, ey.ptr(), 2.0 );
630 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;
632 if(verbose) *out <<
"\nPerforming eY = 2*Op*neV1 ...\n";
634 apply( *Op,
NOTRANS, *neV1, eY.ptr(), 2.0 );
637 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;
639 if(verbose) *out <<
"\nPerforming ney = 2*Op*nev1 ...\n";
641 apply( *Op,
NOTRANS, *nev1, ney.ptr(), 2.0 );
644 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;
646 if(verbose) *out <<
"\nPerforming ney = 2*Op*nev1 through MultiVector interface ...\n";
648 apply( *Op,
NOTRANS,
static_cast<const Thyra::MultiVectorBase<Scalar>&
>(*nev1), Ptr<Thyra::MultiVectorBase<Scalar> >(ney.ptr()), 2.0 );
651 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;
653 if(verbose) *out <<
"\nPerforming neY = 2*Op*neV1 ...\n";
655 apply( *Op,
NOTRANS, *neV1, neY.ptr(), 2.0 );
658 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;
661 if(verbose) *out <<
"\n*** (B.9) Testing Multi-vector views with Epetra operator\n";
663 const Thyra::Range1D col_rng(0,1);
666 RCP<const Thyra::MultiVectorBase<Scalar> >
667 eV1_v1 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(eV1)->subView(col_rng),
668 eV1_v2 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(eV1)->subView(cols);
669 RCP<const Thyra::MultiVectorBase<Scalar> >
670 neV1_v1 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(neV1)->subView(col_rng),
671 neV1_v2 = rcp_static_cast<
const Thyra::MultiVectorBase<Scalar> >(neV1)->subView(cols);
672 if(verbose && dumpAll) {
673 *out <<
"\neV1_v1=\n" << *eV1_v1;
674 *out <<
"\neV1_v2=\n" << *eV1_v2;
675 *out <<
"\nneV1_v1=\n" << *neV1_v1;
676 *out <<
"\nneV1_v2=\n" << *neV1_v2;
679 if(verbose) *out <<
"\nPerforming eY_v1 = 2*Op*eV1_v1 ...\n";
681 apply( *Op,
NOTRANS, *eV1_v1, eY->subView(col_rng).ptr(), 2.0 );
684 if(verbose && dumpAll) *out <<
"\neV_v1=\n" << *eY->subView(col_rng);
685 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;
687 if(verbose) *out <<
"\nPerforming eY_v2 = 2*Op*eV1_v2 ...\n";
689 apply( *Op,
NOTRANS, *eV1_v2, eY->subView(cols).ptr(), 2.0 );
692 if(verbose && dumpAll) *out <<
"\neV_v2=\n" << *eY->subView(cols);
693 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 <<
"\nPerforming neY_v1 = 2*Op*eV1_v1 ...\n";
697 apply( *Op,
NOTRANS, *eV1_v1, neY->subView(col_rng).ptr(), 2.0 );
700 if(verbose && dumpAll) *out <<
"\neV_v1=\n" << *eY->subView(col_rng);
701 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;
703 if(verbose) *out <<
"\nPerforming eY_v1 = 2*Op*neV1_v1 ...\n";
705 apply( *Op,
NOTRANS, *neV1_v1, eY->subView(col_rng).ptr(), 2.0 );
708 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;
710 if(verbose) *out <<
"\nPerforming neY_v2 = 2*Op*eV1_v2 ...\n";
712 apply( *Op,
NOTRANS, *eV1_v2, neY->subView(cols).ptr(), 2.0 );
715 if(verbose && dumpAll) *out <<
"\neV_v2=\n" << *eY->subView(cols);
716 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;
718 if(verbose) *out <<
"\nPerforming eY_v2 = 2*Op*neV1_v2 ...\n";
720 apply( *Op,
NOTRANS, *neV1_v2, eY->subView(cols).ptr(), 2.0 );
723 if(verbose && dumpAll) *out <<
"\neV_v2=\n" << *eY->subView(cols);
724 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;
727 if(verbose) *out <<
"\n*** (B.10) Testing Vector and MultiVector view creation functions\n";
731 const std::string s_n =
"fabs(scalar)*num_mv_cols";
732 const Scalar s = fabs(scalar)*num_mv_cols;
734 Array<Scalar> t_raw_values( num_mv_cols );
736 arcpFromArray(t_raw_values), 1 );
738 std::fill_n( t_raw_values.begin(), t_raw_values.size(), ST::zero() );
739 Thyra::assign( createMemberView(T->range(),t_raw).ptr(), scalar );
741 Scalar t_nrm = Thyra::norm_1(*t_view);
742 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;
743 if(verbose && dumpAll) *out <<
"\nt_view =\n" << *t_view;
756 Array<Scalar> T_raw_values( num_mv_cols * num_mv_cols );
758 arcpFromArray(T_raw_values), num_mv_cols );
760 std::fill_n( T_raw_values.begin(), T_raw_values.size(), ST::zero() );
761 Thyra::assign( createMembersView(T->range(),T_raw).ptr(), scalar );
764 Scalar T_nrm = Thyra::norm_1(*T_view);
765 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;
766 if(verbose && dumpAll) *out <<
"\nT_view =\n" << *T_view;
782 if(verbose) *out <<
"\n*** (B.11) Testing Epetra_Vector and Epetra_MultiVector wrappers\n";
787 mpi_vs = Teuchos::rcp_dynamic_cast<
const Thyra::SpmdVectorSpaceBase<Scalar> >(epetra_vs,
true);
789 if(verbose) *out <<
"\nCreating temporary Epetra_Vector et1 and Epetra_MultiVector eT1 objects ...\n";
793 eT1 =
Teuchos::rcp(
new Epetra_MultiVector(*epetra_map,num_mv_cols));
795 if(verbose) *out <<
"\nCreating non-const VectorBase t1 and MultiVectorBase T1 objects from et1 and eT2 ...\n";
801 if(verbose) *out <<
"\nPerforming t1 = ev1 ...\n";
802 assign( t1.
ptr(), *ev1 );
804 "sum(t1)",Thyra::sum(*t1),
"sum(ev1)",sum(*ev1)
805 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
808 if(verbose) *out <<
"\nPerforming T1 = eV1 ...\n";
809 assign( T1.
ptr(), *eV1 );
811 "norm_1(T1)",Thyra::norm_1(*T1),
"norm_1(eV1)",norm_1(*eV1)
812 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
815 if(verbose) *out <<
"\nChecking that t1 and T1 yield the same objects as et1 and eT2 ...\n";
819 result = et1_v.
get() == et1.
get();
820 if(verbose) *out <<
"\net1_v.get() = " << et1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
821 if(!result) success =
false;
825 result = et1_v.
get() == et1.
get();
826 if(verbose) *out <<
"\net1_v.get() = " << et1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
827 if(!result) success =
false;
831 result = eT1_v.
get() == eT1.
get();
832 if(verbose) *out <<
"\neT1_v.get() = " << eT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
833 if(!result) success =
false;
837 result = eT1_v.
get() == eT1.
get();
838 if(verbose) *out <<
"\neT1_v.get() = " << eT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
839 if(!result) success =
false;
841 if(verbose) *out <<
"\nCreating const VectorBase ct1 and MultiVectorBase cT1 objects from et1 and eT2 ...\n";
843 ct1 =
create_Vector(Teuchos::rcp_implicit_cast<const Epetra_Vector>(et1),mpi_vs);
845 cT1 =
create_MultiVector(Teuchos::rcp_implicit_cast<const Epetra_MultiVector>(eT1),mpi_vs);
848 "sum(ct1)",Thyra::sum(*ct1),
"sum(ev1)",sum(*ev1)
849 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
853 "norm_1(cT1)",Thyra::norm_1(*cT1),
"norm_1(eV1)",norm_1(*eV1)
854 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
857 if(verbose) *out <<
"\nChecking that ct1 and cT1 yield the same objects as et1 and eT2 ...\n";
861 result = cet1_v.
get() == et1.
get();
862 if(verbose) *out <<
"\ncet1_v.get() = " << cet1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
863 if(!result) success =
false;
867 result = cet1_v.
get() == et1.
get();
868 if(verbose) *out <<
"\ncet1_v.get() = " << cet1_v.
get() <<
" == et1.get() = " << et1.
get() <<
" : " <<
passfail(result) << endl;
869 if(!result) success =
false;
873 result = ceT1_v.
get() == eT1.
get();
874 if(verbose) *out <<
"\nceT1_v.get() = " << ceT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
875 if(!result) success =
false;
879 result = ceT1_v.
get() == eT1.
get();
880 if(verbose) *out <<
"\nceT1_v.get() = " << ceT1_v.
get() <<
" == eT1.get() = " << eT1.
get() <<
" : " <<
passfail(result) << endl;
881 if(!result) success =
false;
883 if(verbose) *out <<
"\nCreating non-const Epetra_Vector ett1 and Epetra_MultiVector etT1 objects from clones of t1 and T2 ...\n";
889 if(verbose) *out <<
"\nChecking that ett1 and etT1 yield objects with the same value as et1 and eT2 ...\n";
892 "sum(ett1)",sum(*ett1),
"sum(et1)",sum(*et1)
893 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
897 "sum(etT1)",sum(*etT1),
"sum(eT1)",sum(*eT1)
898 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
901 if(verbose) *out <<
"\nCreating const Epetra_Vector cett1 and Epetra_MultiVector cetT1 objects from clones of t1 and T2 ...\n";
903 cett1 =
get_Epetra_Vector(*epetra_map,Teuchos::rcp_implicit_cast<
const Thyra::VectorBase<Scalar> >(t1->clone_v()));
905 cetT1 =
get_Epetra_MultiVector(*epetra_map,Teuchos::rcp_implicit_cast<
const Thyra::MultiVectorBase<Scalar> >(T1->clone_mv()));
907 if(verbose) *out <<
"\nChecking that cett1 and cetT1 yield objects with the same value as et1 and eT2 ...\n";
910 "sum(cett1)",sum(*cett1),
"sum(et1)",sum(*et1)
911 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
915 "sum(cetT1)",sum(*cetT1),
"sum(eT1)",sum(*eT1)
916 ,
"max_rel_err",max_rel_err,
"max_rel_warn",max_rel_warn,out.ptr())
922 if(verbose) *out <<
"\n*** (B.12) Test DiagonalEpetraLinearOpWithSolveFactory \n";
926 if(verbose) *out <<
"\nUsing DiagonalEpetraLinearOpWithSolveFactory to create diagLOWS from Op ...\n";
931 diagLOWS = Thyra::linearOpWithSolve<double>(diagLOWSFactory,Op);
933 if(verbose) *out <<
"\nTesting LinearOpBase interface of diagLOWS ...\n";
935 result = linearOpTester.check(*diagLOWS, out.
ptr());
936 if(!result) success =
false;
938 if(verbose) *out <<
"\nTesting LinearOpWithSolveBase interface of diagLOWS ...\n";
940 result = linearOpWithSolveTester.check(*diagLOWS, &*out);
941 if(!result) success =
false;
949 <<
"\n*** (C) Comparing the speed of Thyra adapted Epetra objects verses raw Epetra objects"
973 double raw_epetra_time, thyra_wrapped_time;
976 if(verbose) *out <<
"\n*** (C.1) Comparing the speed of RTOp verses raw Epetra_Vector operations\n";
978 const double flop_adjust_factor_1 = 3.0;
979 const int num_time_loops_1 = int( max_flop_rate / ( flop_adjust_factor_1 * local_dim * num_mv_cols ) ) + 1;
988 *out <<
"\nPerforming eeV1 = eeV2 (using raw Epetra_MultiVector::operator=(...)) " << num_time_loops_1 <<
" times ...\n";
990 for(
int k = 0; k < num_time_loops_1; ++k ) {
995 if(verbose) *out <<
" total time = " << raw_epetra_time <<
" sec\n";
1001 *out <<
"\nPerforming eV1 = eV2 (using Thyra::SpmdMultiVectorBase::applyOp(...)) " << num_time_loops_1 <<
" times ...\n";
1003 for(
int k = 0; k < num_time_loops_1; ++k ) {
1004 Thyra::assign( eV1.ptr(), *eV2 );
1008 if(verbose) *out <<
" total time = " << thyra_wrapped_time <<
" sec\n";
1010 print_performance_stats( num_time_loops_1, raw_epetra_time, thyra_wrapped_time, verbose, *out );
1026 <<
"\n*** (C.2) Comparing Thyra::SpmdMultiVectorBase::apply() verses raw Epetra_MultiVector::Multiply()\n";
1030 const double flop_adjust_factor_2 = 2.0;
1031 const int num_time_loops_2 = int( max_flop_rate / ( flop_adjust_factor_2* local_dim * num_mv_cols * num_mv_cols ) ) + 1;
1039 Epetra_LocalMap eT_map((
int) T->range()->dim(),0,*epetra_comm);
1040 Epetra_MultiVector eT(eT_map,T->domain()->dim());
1043 *out <<
"\nPerforming eeV1'*eeV2 (using raw Epetra_MultiVector::Multiply(...)) " << num_time_loops_2 <<
" times ...\n";
1045 for(
int k = 0; k < num_time_loops_2; ++k ) {
1046 eT.Multiply(
'T',
'N', 1.0, *eeV1, *eeV2, 0.0 );
1050 if(verbose) *out <<
" total time = " << raw_epetra_time <<
" sec\n";
1055 *out <<
"\nPerforming eV1'*eV2 (using Thyra::SpmdMultiVectorBase::apply(...)) " << num_time_loops_2 <<
" times ...\n";
1057 for(
int k = 0; k < num_time_loops_2; ++k ) {
1058 apply( *eV1,
TRANS, *eV2, T.ptr() );
1062 if(verbose) *out <<
" total time = " << thyra_wrapped_time <<
" sec\n";
1064 print_performance_stats( num_time_loops_2, raw_epetra_time, thyra_wrapped_time, verbose, *out );
1075 if(verbose) *out <<
"\n*** (C.3) Comparing Thyra::EpetraLinearOp::apply() verses raw Epetra_Operator::apply()\n";
1079 const double flop_adjust_factor_3 = 10.0;
1080 const int num_time_loops_3 = int( max_flop_rate / ( flop_adjust_factor_3 * local_dim * num_mv_cols ) ) + 1;
1089 *out <<
"\nPerforming eeY = eOp*eeV1 (using raw Epetra_Operator::apply(...)) " << num_time_loops_3 <<
" times ...\n";
1094 epetra_op->SetUseTranspose(
false);
1095 for(
int k = 0; k < num_time_loops_3; ++k ) {
1096 epetra_op->Apply( *eeV1, *eeY );
1102 if(verbose) *out <<
" total time = " << raw_epetra_time <<
" sec\n";
1110 *out <<
"\nPerforming eY = Op*eV1 (using Thyra::EpetraLinearOp::apply(...)) " << num_time_loops_3 <<
" times ...\n";
1115 for(
int k = 0; k < num_time_loops_3; ++k ) {
1116 apply( *Op,
NOTRANS, *eV1, eY.ptr() );
1121 if(verbose) *out <<
" total time = " << thyra_wrapped_time <<
" sec\n";
1126 print_performance_stats( num_time_loops_3, raw_epetra_time, thyra_wrapped_time, verbose, *out );
1138 if(success) *out <<
"\nCongratulations! All of the tests seem to have run sucessfully!\n";
1139 else *out <<
"\nOh no! at least one of the tests did not check out!\n";
1142 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[])
double totalElapsedTime(bool readCurrentTime=false) const
Create a DefaultDiagonalLinearOpWithSolve out of a diagonal Epetra_RowMatrix object.
bool testRelErr(const std::string &v1_name, const Scalar &v1, const std::string &v2_name, const Scalar &v2, const std::string &maxRelErr_error_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &maxRelErr_error, const std::string &maxRelErr_warning_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &maxRelErr_warning, const Ptr< std::ostream > &out)
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()