Kokkos Node API and Local Linear Algebra Kernels Version of the Day
Tsqr_ParTest.hpp
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //          Kokkos: Node API and Parallel Node Kernels
00005 //              Copyright (2008) Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 // 
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00038 // 
00039 // ************************************************************************
00040 //@HEADER
00041 
00042 #ifndef __TSQR_Test_DistTest_hpp
00043 #define __TSQR_Test_DistTest_hpp
00044 
00045 #include <Tsqr_ConfigDefs.hpp>
00046 #include <Tsqr_Random_NormalGenerator.hpp>
00047 #include <Tsqr_verifyTimerConcept.hpp>
00048 
00049 #include <Tsqr_generateStack.hpp>
00050 #include <Tsqr_DistTsqr.hpp>
00051 #include <Tsqr_GlobalTimeStats.hpp>
00052 #include <Tsqr_GlobalVerify.hpp>
00053 #include <Tsqr_printGlobalMatrix.hpp>
00054 
00055 #include <algorithm>
00056 #include <iomanip>
00057 #include <iostream>
00058 #include <vector>
00059 
00060 
00061 namespace TSQR {
00062   namespace Test {
00063 
00067     template<class Ordinal, class Scalar>
00068     class DistTsqrVerifier {
00069       TSQR::Random::NormalGenerator<Ordinal, Scalar> gen_;
00070       Teuchos::RCP<MessengerBase<Ordinal> > const ordinalComm_;
00071       Teuchos::RCP<MessengerBase<Scalar> > const scalarComm_;
00072       std::string scalarTypeName_;
00073       std::ostream& out_;
00074       std::ostream& err_;
00075       const bool testFactorExplicit_, testFactorImplicit_;
00076       const bool humanReadable_, printMatrices_, debug_;
00077 
00078     public:
00079       typedef Ordinal ordinal_type;
00080       typedef Scalar scalar_type;
00081       typedef typename Teuchos::ScalarTraits<scalar_type>::magnitudeType magnitude_type;
00082       typedef typename std::vector<magnitude_type> result_type;
00083       typedef Matrix<ordinal_type, scalar_type> matrix_type;
00084       
00105       DistTsqrVerifier (const Teuchos::RCP<MessengerBase<Ordinal> >& ordinalComm,
00106       const Teuchos::RCP<MessengerBase<Scalar> >& scalarComm,
00107       const std::vector<int>& seed,
00108       const std::string& scalarTypeName,
00109       std::ostream& out,
00110       std::ostream& err,
00111       const bool testFactorExplicit,
00112       const bool testFactorImplicit,
00113       const bool humanReadable,
00114       const bool printMatrices,
00115       const bool debug) :
00116   gen_ (seed), 
00117   ordinalComm_ (ordinalComm),
00118   scalarComm_ (scalarComm),
00119   scalarTypeName_ (scalarTypeName), 
00120   out_ (out), 
00121   err_ (err),
00122   testFactorExplicit_ (testFactorExplicit),
00123   testFactorImplicit_ (testFactorImplicit),
00124   humanReadable_ (humanReadable), 
00125   printMatrices_ (printMatrices),
00126   debug_ (debug)
00127       {}
00128 
00150       DistTsqrVerifier (const Teuchos::RCP<MessengerBase<Ordinal> >& ordinalComm,
00151       const Teuchos::RCP<MessengerBase<Scalar> >& scalarComm,
00152       const std::string& scalarTypeName,
00153       std::ostream& out,
00154       std::ostream& err,
00155       const bool testFactorExplicit,
00156       const bool testFactorImplicit,
00157       const bool humanReadable,
00158       const bool printMatrices,
00159       const bool debug) :
00160   ordinalComm_ (ordinalComm),
00161   scalarComm_ (scalarComm),
00162   scalarTypeName_ (scalarTypeName), 
00163   out_ (out), 
00164   err_ (err),
00165   testFactorExplicit_ (testFactorExplicit),
00166   testFactorImplicit_ (testFactorImplicit),
00167   humanReadable_ (humanReadable), 
00168   printMatrices_ (printMatrices),
00169   debug_ (debug)
00170       {}
00171 
00178       void 
00179       getSeed (std::vector<int>& seed) const
00180       {
00181   gen_.getSeed (seed);
00182       }
00183 
00188       void 
00189       verify (const Ordinal numCols, 
00190         const std::string& additionalFieldNames,
00191         const std::string& additionalData,
00192         const bool printFieldNames)
00193       {
00194   using std::endl;
00195 
00196   const int myRank = scalarComm_->rank();
00197   if (debug_)
00198     {
00199       scalarComm_->barrier();
00200       if (myRank == 0)
00201         err_ << "Verifying DistTsqr:" << endl;
00202       scalarComm_->barrier();
00203     }
00204 
00205   // Generate test problem.
00206   Matrix< Ordinal, Scalar > A_local, Q_local, R;
00207   testProblem (A_local, Q_local, R, numCols);
00208   if (debug_)
00209     {
00210       scalarComm_->barrier();
00211       if (myRank == 0)
00212         err_ << "-- Generated test problem." << endl;
00213       scalarComm_->barrier();
00214     }
00215 
00216   // Set up TSQR implementation.
00217   DistTsqr<Ordinal, Scalar> par;
00218   par.init (scalarComm_);
00219   if (debug_)
00220     {
00221       scalarComm_->barrier();
00222       if (myRank == 0)
00223         err_ << "-- DistTsqr object initialized" << endl << endl;
00224     }
00225 
00226   // Whether we've printed field names (i.e., column headers)
00227   // yet.  Only matters for non-humanReadable output.
00228   bool printedFieldNames = false;
00229 
00230   // Test DistTsqr::factor() and DistTsqr::explicit_Q().
00231   if (testFactorImplicit_)
00232     {
00233       // Factor the matrix A (copied into R, which will be
00234       // overwritten on output)
00235       typedef typename DistTsqr<Ordinal, Scalar>::FactorOutput 
00236         factor_output_type;
00237       factor_output_type factorOutput = par.factor (R.view());
00238       if (debug_)
00239         {
00240     scalarComm_->barrier();
00241     if (myRank == 0)
00242       err_ << "-- Finished DistTsqr::factor" << endl;
00243         }
00244       // Compute the explicit Q factor
00245       par.explicit_Q (numCols, Q_local.get(), Q_local.lda(), factorOutput);
00246       if (debug_)
00247         {
00248     scalarComm_->barrier();
00249     if (myRank == 0)
00250       err_ << "-- Finished DistTsqr::explicit_Q" << endl;
00251         }
00252       // Verify the factorization
00253       result_type result = 
00254         global_verify (numCols, numCols, A_local.get(), A_local.lda(),
00255            Q_local.get(), Q_local.lda(), R.get(), R.lda(), 
00256            scalarComm_.get());
00257       if (debug_)
00258         {
00259     scalarComm_->barrier();
00260     if (myRank == 0)
00261       err_ << "-- Finished global_verify" << endl;
00262         }
00263       reportResults ("DistTsqr", numCols, result, 
00264          additionalFieldNames, additionalData,
00265          printFieldNames && (! printedFieldNames));
00266       if (printFieldNames && (! printedFieldNames))
00267         printedFieldNames = true;
00268     }
00269 
00270   // Test DistTsqr::factorExplicit()
00271   if (testFactorExplicit_)
00272     {
00273       // Factor the matrix and compute the explicit Q factor, both
00274       // in a single operation.
00275       par.factorExplicit (R.view(), Q_local.view());
00276       if (debug_)
00277         {
00278     scalarComm_->barrier();
00279     if (myRank == 0)
00280       err_ << "-- Finished DistTsqr::factorExplicit" << endl;
00281         }
00282 
00283       if (printMatrices_)
00284         {
00285     if (myRank == 0)
00286       err_ << std::endl << "Computed Q factor:" << std::endl;
00287     printGlobalMatrix (err_, Q_local, scalarComm_.get(), ordinalComm_.get());
00288     if (myRank == 0)
00289       {
00290         err_ << std::endl << "Computed R factor:" << std::endl;
00291         print_local_matrix (err_, R.nrows(), R.ncols(), R.get(), R.lda());
00292         err_ << std::endl;
00293       }
00294         }
00295 
00296       // Verify the factorization
00297       result_type result = 
00298         global_verify (numCols, numCols, A_local.get(), A_local.lda(),
00299            Q_local.get(), Q_local.lda(), R.get(), R.lda(), 
00300            scalarComm_.get());
00301       if (debug_)
00302         {
00303     scalarComm_->barrier();
00304     if (myRank == 0)
00305       err_ << "-- Finished global_verify" << endl;
00306         }
00307       reportResults ("DistTsqrRB", numCols, result, 
00308          additionalFieldNames, additionalData,
00309          printFieldNames && (! printedFieldNames));
00310       if (printFieldNames && (! printedFieldNames))
00311         printedFieldNames = true;
00312     }
00313       }
00314 
00315     private:
00322       void 
00323       reportResults (const std::string& method, 
00324          const Ordinal numCols, 
00325          const result_type& result,
00326          const std::string& additionalFieldNames,
00327          const std::string& additionalData,
00328          const bool printFieldNames)
00329       {
00330   using std::endl;
00331 
00332   const int numProcs = scalarComm_->size();
00333   const int myRank = scalarComm_->rank();
00334 
00335   if (myRank == 0)
00336     {
00337       if (humanReadable_)
00338         {
00339     out_ << method << " accuracy results:" << endl
00340          << "Scalar type = " << scalarTypeName_ << endl
00341          << "Number of columns = " << numCols << endl
00342          << "Number of (MPI) processes = " << numProcs << endl
00343          << "Absolute residual $\\| A - Q R \\|_2: "
00344          << result[0] << endl
00345          << "Absolute orthogonality $\\| I - Q^* Q \\|_2$: " 
00346          << result[1] << endl
00347          << "Test matrix norm $\\| A \\|_F$: "
00348          << result[2] << endl;
00349         }
00350       else
00351         {
00352     // Use scientific notation for floating-point numbers
00353     out_ << std::scientific;
00354 
00355     if (printFieldNames)
00356       {
00357         out_ << "%method,scalarType,numCols,numProcs"
00358           ",absFrobResid,absFrobOrthog,frobA";
00359         if (! additionalFieldNames.empty())
00360           out_ << "," << additionalFieldNames;
00361         out_ << endl;
00362       }
00363 
00364     out_ << method
00365          << "," << scalarTypeName_
00366          << "," << numCols
00367          << "," << numProcs
00368          << "," << result[0]
00369          << "," << result[1]
00370          << "," << result[2];
00371     if (! additionalData.empty())
00372       out_ << "," << additionalData;
00373     out_ << endl;
00374         }
00375     }
00376       }
00377 
00378       void 
00379       testProblem (Matrix< Ordinal, Scalar >& A_local,
00380        Matrix< Ordinal, Scalar >& Q_local,
00381        Matrix< Ordinal, Scalar >& R,
00382        const Ordinal numCols)
00383       {
00384   const Ordinal numRowsLocal = numCols;
00385 
00386   // A_local: Space for the matrix A to factor -- local to each
00387   //   processor.
00388   //
00389   // A_global: Global matrix (only nonempty on Proc 0); only
00390   //   used temporarily.
00391   Matrix< Ordinal, Scalar > A_global;
00392 
00393   // This modifies A_local on all procs, and A_global on Proc 0.
00394   par_tsqr_test_problem (gen_, A_local, A_global, numCols, scalarComm_);
00395   
00396   if (printMatrices_)
00397     {
00398       const int myRank = scalarComm_->rank();
00399 
00400       if (myRank == 0)
00401         err_ << "Input matrix A:" << std::endl;
00402       printGlobalMatrix (err_, A_local, scalarComm_.get(), ordinalComm_.get());
00403       if (myRank == 0)
00404         err_ << std::endl;
00405     }
00406 
00407   // Copy the test problem input into R, since the factorization
00408   // will overwrite it in place with the final R factor.
00409   R.reshape (numCols, numCols);
00410   R.fill (Scalar(0));
00411   R.copy (A_local);
00412 
00413   // Prepare space in which to construct the explicit Q factor
00414   // (local component on this processor)
00415   Q_local.reshape (numRowsLocal, numCols);
00416   Q_local.fill (Scalar(0));
00417       }
00418     };
00419 
00420 
00424     template< class Ordinal, class Scalar, class TimerType >
00425     class DistTsqrBenchmarker {
00426       TSQR::Random::NormalGenerator< Ordinal, Scalar > gen_;
00427       Teuchos::RCP< MessengerBase< Scalar > > scalarComm_;
00428       Teuchos::RCP< MessengerBase< double > > doubleComm_; 
00429       std::string scalarTypeName_;
00430 
00431       std::ostream& out_;
00432       std::ostream& err_;
00433       const bool testFactorExplicit_, testFactorImplicit_;
00434       const bool humanReadable_, debug_;
00435 
00436     public:
00437       typedef Ordinal ordinal_type;
00438       typedef Scalar scalar_type;
00439       typedef typename Teuchos::ScalarTraits< scalar_type >::magnitudeType magnitude_type;
00440       typedef TimerType timer_type;
00441 
00465       DistTsqrBenchmarker (const Teuchos::RCP< MessengerBase< Scalar > >& scalarComm,
00466          const Teuchos::RCP< MessengerBase< double > >& doubleComm,
00467          const std::vector<int>& seed,
00468          const std::string& scalarTypeName,
00469          std::ostream& out,
00470          std::ostream& err,
00471          const bool testFactorExplicit,
00472          const bool testFactorImplicit,
00473          const bool humanReadable,
00474          const bool debug) :
00475   gen_ (seed), 
00476   scalarComm_ (scalarComm),
00477   doubleComm_ (doubleComm),
00478   scalarTypeName_ (scalarTypeName), 
00479   out_ (out), 
00480   err_ (err),
00481   testFactorExplicit_ (testFactorExplicit),
00482   testFactorImplicit_ (testFactorImplicit),
00483   humanReadable_ (humanReadable), 
00484   debug_ (debug)
00485       {}
00486 
00511       DistTsqrBenchmarker (const Teuchos::RCP< MessengerBase< Scalar > >& scalarComm,
00512          const Teuchos::RCP< MessengerBase< double > >& doubleComm,
00513          const std::string& scalarTypeName,
00514          std::ostream& out,
00515          std::ostream& err,
00516          const bool testFactorExplicit,
00517          const bool testFactorImplicit,
00518          const bool humanReadable,
00519          const bool debug) :
00520   scalarComm_ (scalarComm),
00521   doubleComm_ (doubleComm),
00522   scalarTypeName_ (scalarTypeName), 
00523   out_ (out), 
00524   err_ (err),
00525   testFactorExplicit_ (testFactorExplicit),
00526   testFactorImplicit_ (testFactorImplicit),
00527   humanReadable_ (humanReadable), 
00528   debug_ (debug)
00529       {}
00530 
00537       void 
00538       getSeed (std::vector<int>& seed) const
00539       {
00540   gen_.getSeed (seed);
00541       }
00542 
00549       void 
00550       benchmark (const int numTrials, 
00551      const Ordinal numCols,
00552      const std::string& additionalFieldNames,
00553      const std::string& additionalData,
00554      const bool printFieldNames)
00555       {
00556   using std::endl;
00557 
00558   // Set up test problem.
00559   Matrix< Ordinal, Scalar > A_local, Q_local, R;
00560   testProblem (A_local, Q_local, R, numCols);
00561 
00562   // Set up TSQR implementation.
00563   DistTsqr<Ordinal, Scalar> par;
00564   par.init (scalarComm_);
00565 
00566   // Whether we've printed field names (i.e., column headers)
00567   // yet.  Only matters for non-humanReadable output.
00568   bool printedFieldNames = false;
00569 
00570   if (testFactorImplicit_)
00571     {
00572       std::string timerName ("DistTsqr");
00573       typedef typename DistTsqr<Ordinal, Scalar>::FactorOutput 
00574         factor_output_type;
00575 
00576       // Throw away some number of runs, because some MPI libraries
00577       // (recent versions of OpenMPI at least) do autotuning for the
00578       // first few collectives calls.
00579       const int numThrowAwayRuns = 5;
00580       for (int runNum = 0; runNum < numThrowAwayRuns; ++runNum)
00581         {
00582     // Factor the matrix A (copied into R, which will be
00583     // overwritten on output)
00584     factor_output_type factorOutput = par.factor (R.view());
00585     // Compute the explicit Q factor
00586     par.explicit_Q (numCols, Q_local.get(), Q_local.lda(), factorOutput);
00587         }
00588 
00589       // Now do the actual timing runs.  Benchmark DistTsqr
00590       // (factor() and explicit_Q()) for numTrials trials.
00591       timer_type timer (timerName);
00592       timer.start();
00593       for (int trialNum = 0; trialNum < numTrials; ++trialNum)
00594         {
00595     // Factor the matrix A (copied into R, which will be
00596     // overwritten on output)
00597     factor_output_type factorOutput = par.factor (R.view());
00598     // Compute the explicit Q factor
00599     par.explicit_Q (numCols, Q_local.get(), Q_local.lda(), factorOutput);
00600         }
00601       // Cumulative timing on this MPI process.
00602       // "Cumulative" means the elapsed time of numTrials executions.
00603       const double localCumulativeTiming = timer.stop();
00604 
00605       // reportResults() must be called on all processes, since this
00606       // figures out the min and max timings over all processes.
00607       reportResults (timerName, numTrials, numCols, localCumulativeTiming, 
00608          additionalFieldNames, additionalData,
00609          printFieldNames && (! printedFieldNames));
00610       if (printFieldNames && (! printedFieldNames))
00611         printedFieldNames = true;
00612     }
00613 
00614   if (testFactorExplicit_)
00615     {
00616       std::string timerName ("DistTsqrRB");
00617 
00618       // Throw away some number of runs, because some MPI libraries
00619       // (recent versions of OpenMPI at least) do autotuning for the
00620       // first few collectives calls.
00621       const int numThrowAwayRuns = 5;
00622       for (int runNum = 0; runNum < numThrowAwayRuns; ++runNum)
00623         {
00624     par.factorExplicit (R.view(), Q_local.view());
00625         }
00626 
00627       // Benchmark DistTsqr::factorExplicit() for numTrials trials.
00628       timer_type timer (timerName);
00629       timer.start();
00630       for (int trialNum = 0; trialNum < numTrials; ++trialNum)
00631         {
00632     par.factorExplicit (R.view(), Q_local.view());
00633         }
00634       // Cumulative timing on this MPI process.
00635       // "Cumulative" means the elapsed time of numTrials executions.
00636       const double localCumulativeTiming = timer.stop();
00637 
00638       // Report cumulative (not per-invocation) timing results
00639       reportResults (timerName, numTrials, numCols, localCumulativeTiming, 
00640          additionalFieldNames, additionalData,
00641          printFieldNames && (! printedFieldNames));
00642       if (printFieldNames && (! printedFieldNames))
00643         printedFieldNames = true;
00644 
00645       // Per-invocation timings (for factorExplicit() benchmark
00646       // only).  localTimings were computed on this MPI process;
00647       // globalTimings are statistical summaries of those over
00648       // all MPI processes.  We only collect that data for
00649       // factorExplicit().
00650       std::vector< TimeStats > localTimings;
00651       std::vector< TimeStats > globalTimings;
00652       par.getFactorExplicitTimings (localTimings);
00653       for (std::vector< TimeStats >::size_type k = 0; k < localTimings.size(); ++k)
00654         globalTimings.push_back (globalTimeStats (doubleComm_, localTimings[k]));
00655       std::vector< std::string > timingLabels;
00656       par.getFactorExplicitTimingLabels (timingLabels);
00657 
00658       if (humanReadable_)
00659         out_ << timerName << " per-invocation benchmark results:" << endl;
00660 
00661       const std::string labelLabel ("label,scalarType");
00662       for (std::vector< std::string >::size_type k = 0; k < timingLabels.size(); ++k)
00663         {
00664     // Only print column headers (i.e., field names) once, if at all.
00665     const bool printHeaders = (k == 0) && printFieldNames;
00666     globalTimings[k].print (out_, humanReadable_, 
00667           timingLabels[k] + "," + scalarTypeName_, 
00668           labelLabel, printHeaders);
00669         }
00670     }
00671       }
00672 
00673     private:
00686       void 
00687       reportResults (const std::string& method,
00688          const int numTrials,
00689          const ordinal_type numCols,
00690          const double localTiming,
00691          const std::string& additionalFieldNames,
00692          const std::string& additionalData,
00693          const bool printFieldNames)
00694       {
00695   using std::endl;
00696 
00697   // Find min and max timing over all MPI processes
00698   TimeStats localStats;
00699   localStats.update (localTiming);
00700   TimeStats globalStats = globalTimeStats (doubleComm_, localStats);
00701 
00702   // Only Rank 0 prints the final results.
00703   const bool printResults = (doubleComm_->rank() == 0);
00704   if (printResults)
00705     {
00706       const int numProcs = doubleComm_->size();
00707       if (humanReadable_)
00708         {
00709     out_ << method << " cumulative benchmark results (total time over all trials):" << endl
00710          << "Scalar type = " << scalarTypeName_ << endl
00711          << "Number of columns = " << numCols << endl
00712          << "Number of (MPI) processes = " << numProcs << endl
00713          << "Number of trials = " << numTrials << endl
00714          << "Min timing (in seconds) = " << globalStats.min() << endl
00715          << "Mean timing (in seconds) = " << globalStats.mean() << endl
00716          << "Max timing (in seconds) = " << globalStats.max() << endl
00717          << endl;
00718         }
00719       else
00720         {
00721     // Use scientific notation for floating-point numbers
00722     out_ << std::scientific;
00723 
00724     if (printFieldNames)
00725       {
00726         out_ << "%method,scalarType,numCols,numProcs,numTrials"
00727        << ",minTiming,meanTiming,maxTiming";
00728         if (! additionalFieldNames.empty())
00729           out_ << "," << additionalFieldNames;
00730         out_ << endl;
00731       }
00732 
00733     out_ << method
00734          << "," << scalarTypeName_
00735          << "," << numCols
00736          << "," << numProcs
00737          << "," << numTrials
00738          << "," << globalStats.min()
00739          << "," << globalStats.mean()
00740          << "," << globalStats.max();
00741     if (! additionalData.empty())
00742       out_ << "," << additionalData;
00743     out_ << endl;
00744         }
00745     }
00746       }
00747 
00748       void 
00749       testProblem (Matrix< Ordinal, Scalar >& A_local,
00750        Matrix< Ordinal, Scalar >& Q_local,
00751        Matrix< Ordinal, Scalar >& R,
00752        const Ordinal numCols)
00753       {
00754   const Ordinal numRowsLocal = numCols;
00755 
00756   // A_local: Space for the matrix A to factor -- local to each
00757   //   processor.
00758   //
00759   // A_global: Global matrix (only nonempty on Proc 0); only
00760   //   used temporarily.
00761   Matrix< Ordinal, Scalar > A_global;
00762 
00763   // This modifies A_local on all procs, and A_global on Proc 0.
00764   par_tsqr_test_problem (gen_, A_local, A_global, numCols, scalarComm_);
00765 
00766   // Copy the test problem input into R, since the factorization
00767   // will overwrite it in place with the final R factor.
00768   R.reshape (numCols, numCols);
00769   R.copy (A_local);
00770 
00771   // Prepare space in which to construct the explicit Q factor
00772   // (local component on this processor)
00773   Q_local.reshape (numRowsLocal, numCols);
00774   Q_local.fill (Scalar(0));
00775       }
00776 
00779       static void
00780       conceptChecks () 
00781       {
00782   verifyTimerConcept< timer_type >();
00783       }
00784     };
00785 
00786 
00787   } // namespace Test
00788 } // namespace TSQR
00789 
00790 #endif // __TSQR_Test_DistTest_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends