EpetraExt Package Browser (Single Doxygen Collection) Development
example/matlab/cxx_main.cpp
Go to the documentation of this file.
00001 /*@HEADER
00002 // ***********************************************************************
00003 // 
00004 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00005 //                 Copyright (2001) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 //@HEADER
00028 */
00029 
00030 #include "Epetra_ConfigDefs.h"
00031 
00032 #ifdef EPETRA_MPI
00033 #include "mpi.h"
00034 #include "Epetra_MpiComm.h"
00035 #else
00036 #include "Epetra_SerialComm.h"
00037 #endif
00038 
00039 #include "Epetra_Comm.h"
00040 #include "Epetra_Map.h"
00041 #include "Epetra_BlockMap.h"
00042 #include "Epetra_MultiVector.h"
00043 #include "Epetra_Vector.h"
00044 #include "Epetra_SerialDenseMatrix.h"
00045 #include "Epetra_SerialDenseVector.h"
00046 #include "Epetra_IntSerialDenseMatrix.h"
00047 #include "Epetra_IntSerialDenseVector.h"
00048 #include "Epetra_DataAccess.h"
00049 #include "Epetra_CrsMatrix.h"
00050 
00051 #include "EpetraExt_MatlabEngine.h" // contains the EpetraExt_MatlabEngine class
00052 
00053 int main(int argc, char *argv[]) {
00054 
00055 // standard Epetra MPI/Serial Comm startup  
00056 #ifdef EPETRA_MPI
00057   MPI_Init(&argc,&argv);
00058   Epetra_MpiComm comm (MPI_COMM_WORLD);
00059 #else
00060   Epetra_SerialComm comm;
00061 #endif
00062   
00063   int MyPID = comm.MyPID();
00064   int ierr = 0;
00065   bool verbose = (0 == MyPID);
00066   bool reportErrors = (0 == MyPID);
00067   // setup MatlabEngine
00068   if (verbose) cout << "going to startup a matlab process...\n";
00069   EpetraExt::EpetraExt_MatlabEngine engine (comm);
00070   if (verbose) cout << "matlab started\n";
00071   
00072   // setup an array of doubles to be used for the examples
00073   int M = 20;
00074   int numGlobalElements = M * comm.NumProc();
00075   int N = 3;
00076   int numMyEntries = M * N;
00077   double* A = new double[numMyEntries];
00078   double* Aptr = A;
00079   int startValue = numMyEntries * MyPID;
00080 
00081   for(int col=0; col < N; col++) {
00082   for(int row=0; row < M; row++) {
00083           *Aptr++ = startValue++;
00084       }
00085   }
00086 
00087   // setup an array of ints to be used for the examples
00088   int* intA = new int[numMyEntries];
00089   int* intAptr = intA;
00090   int intStartValue = numMyEntries * MyPID;
00091   for(int i=0; i < M*N; i++) {
00092       *intAptr++ = intStartValue++;
00093   }
00094   
00095   // construct a map to be used by distributed objects
00096   Epetra_Map map (numGlobalElements, 0, comm);
00097   
00098   // CrsMatrix example
00099   // constructs a globally distributed CrsMatrix and then puts it into Matlab
00100   if (verbose) cout << " constructing CrsMatrix...\n";
00101   Epetra_CrsMatrix crsMatrix (Copy, map, N);
00102   int* indices = new int[N];
00103   for (int col=0; col < N; col++) {
00104     indices[col] = col;   
00105   }
00106   
00107   double value = startValue;
00108   double* values = new double[numMyEntries];
00109   int minMyGID = map.MinMyGID();
00110   for (int row=0; row < M; row++) {
00111     for (int col=0; col < N; col++) {
00112       values[col] = value++;
00113     }
00114       
00115     crsMatrix.InsertGlobalValues(minMyGID + row, N, values, indices);
00116   }
00117   
00118   crsMatrix.FillComplete();
00119   if (verbose) cout << " CrsMatrix constructed\n";
00120   if (verbose) cout << " putting CrsMatrix into Matlab as CRSM\n";
00121   ierr = engine.PutRowMatrix(crsMatrix, "CRSM", false);
00122   if (ierr) {
00123     if (reportErrors) cout << "There was an error in engine.PutRowMatrix(crsMatrix, \"CRSM\", false): " << ierr << endl;
00124   }
00125   
00126   // BlockMap example
00127   // puts a map into Matlab
00128   if (verbose) cout << " putting Map into Matlab as MAP\n";
00129   ierr = engine.PutBlockMap(map, "MAP", false);
00130   if (ierr) {
00131     if (reportErrors) cout << "There was an error in engine.PutBlockMap(map, \"MAP\", false);: " << ierr << endl;
00132   }
00133   
00134   // MultiVector example
00135   // constructs a globally distributed MultiVector and then puts it into Matlab
00136   if (verbose) cout << " constructing MultiVector...\n";
00137   Epetra_MultiVector multiVector (Copy, map, A, M, N);
00138   if (verbose) cout << " MultiVector constructed\n";
00139   if (verbose) cout << " putting MultiVector into Matlab as MV\n";
00140   ierr = engine.PutMultiVector(multiVector, "MV");
00141   if (ierr) {
00142     if (reportErrors) cout << "There was an error in engine.PutMultiVector(multiVector, \"MV\"): " << ierr << endl;
00143   }
00144   
00145   // SerialDenseMatrix example
00146   // constructs a SerialDenseMatrix on every PE
00147   if (verbose) cout << " constructing a SerialDenseMatrix...\n";
00148   Epetra_SerialDenseMatrix sdMatrix (Copy, A, M, M, N);
00149   if (verbose) cout << " SerialDenseMatrix constructed\n";
00150   if (verbose) cout << " putting SerialDenseMatrix from PE0 into Matlab as SDM_PE0\n";
00151   // since the third parameter is left out, the SerialDenseMatrix from PE0 is used by default
00152   ierr = engine.PutSerialDenseMatrix(sdMatrix, "SDM_PE0");
00153   if (ierr) {
00154     if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdMatrix, \"SDM_PE0\"): " << ierr << endl;
00155   }
00156   if (comm.NumProc() > 1) {
00157     if (verbose) cout << " putting SerialDenseMatrix from PE1 into Matlab as SDM_PE1\n";
00158     // specifying 1 as the third parameter will put the SerialDenseMatrix from PE1 into Matlab
00159     ierr = engine.PutSerialDenseMatrix(sdMatrix, "SDM_PE1", 1);
00160     if (ierr) {
00161       if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdMatrix, \"SDM_PE1\", 1): " << ierr << endl;
00162     }
00163   }
00164   
00165 
00166   // SerialDenseVector example
00167   // constructs a SerialDenseVector on every PE
00168   if (verbose) cout << " constructing a SerialDenseVector...\n";
00169   Epetra_SerialDenseVector sdVector (Copy, A, M);
00170   if (verbose) cout << " SerialDenseVector constructed\n";
00171   // since the third parameter is left out, the SerialDenseMatrix from PE0 is used by default
00172   if (verbose) cout << " putting SerialDenseVector from PE0 into Matlab as SDV_PE0\n";
00173   ierr = engine.PutSerialDenseMatrix(sdVector, "SDV_PE0");
00174   if (ierr) {
00175     if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdVector, \"SDV_PE0\"): " << ierr << endl;
00176   }
00177   if (comm.NumProc() > 1) {
00178     if (verbose) cout << " putting SerialDenseVector from PE1 into Matlab as SDV_PE1\n";
00179     // specifying 1 as the third parameter will put the SerialDenseVector from PE1 into Matlab
00180     ierr = engine.PutSerialDenseMatrix(sdVector, "SDV_PE1", 1);
00181     if (ierr) {
00182       if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdMatrix, \"SDV_PE1\", 1): " << ierr << endl;
00183     }
00184   }
00185 
00186   // IntSerialDenseMatrix example
00187   // constructs a IntSerialDenseMatrix on every PE
00188   if (verbose) cout << " constructing a IntSerialDenseMatrix...\n";
00189   Epetra_IntSerialDenseMatrix isdMatrix (Copy, intA, M, M, N);
00190   if (verbose) cout << " IntSerialDenseMatrix constructed\n";
00191   // since the third parameter is left out, the IntSerialDenseMatrix from PE0 is used by default
00192   if (verbose) cout << " putting IntSerialDenseMatrix from PE0 into Matlab as ISDM_PE0\n";
00193   ierr = engine.PutIntSerialDenseMatrix(isdMatrix, "ISDM_PE0");
00194   if (ierr) {
00195     if (reportErrors) cout << "There was an error in engine.PutIntSerialDenseMatrix(isdMatrix, \"ISDM_PE0\"): " << ierr << endl;
00196   }
00197   if (comm.NumProc() > 1) {
00198     if (verbose) cout << " putting IntSerialDenseMatrix from PE1 into Matlab as ISDM_PE1\n";
00199     // specifying 1 as the third parameter will put the IntSerialDenseMatrix from PE1 into Matlab
00200     ierr = engine.PutIntSerialDenseMatrix(isdMatrix, "ISDM_PE1", 1);
00201     if (ierr) {
00202       if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(isdMatrix, \"ISDM_PE1\", 1): " << ierr << endl;
00203     }
00204   }
00205 
00206 
00207   // IntSerialDenseVector example
00208   // constructs a IntSerialDenseVector on every PE
00209   if (verbose) cout << " constructing a IntSerialDenseVector...\n";
00210   Epetra_IntSerialDenseVector isdVector (Copy, intA, M);
00211   if (verbose) cout << " IntSerialDenseVector constructed\n";
00212   // since the third parameter is left out, the IntSerialDenseVector from PE0 is used by default
00213   if (verbose) cout << " putting IntSerialDenseVector from PE0 into Matlab as ISDV_PE0\n";
00214   ierr = engine.PutIntSerialDenseMatrix(isdVector, "ISDV_PE0");
00215   if (ierr) {
00216     if (reportErrors) cout << "There was an error in engine.PutIntSerialDenseMatrix(isdVector, \"ISDV_PE0\"): " << ierr << endl;
00217   }
00218   if (comm.NumProc() > 1) {
00219     if (verbose) cout << " putting IntSerialDenseVector from PE1 into Matlab as ISDV_PE1\n";
00220     // specifying 1 as the third parameter will put the IntSerialDenseVector from PE1 into Matlab
00221     ierr = engine.PutIntSerialDenseMatrix(isdVector, "ISDV_PE1", 1);
00222     if (ierr) {
00223       if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(isdVector, \"ISDV_PE1\", 1): " << ierr << endl;
00224     }
00225   }
00226   
00227   // entering a while loop on PE0 will keep the Matlab workspace alive
00228   /*
00229   if (MyPID == 0)
00230   while(1) {
00231     // do nothing
00232   }
00233   */
00234 
00235   const int bufSize = 200;
00236   char s [bufSize];
00237   const int matlabBufferSize = 1024 * 16;
00238   char matlabBuffer [matlabBufferSize];
00239   
00240   // send some commands to Matlab and output the result to stdout
00241   engine.EvalString("whos", matlabBuffer, matlabBufferSize);
00242   if (verbose) cout << matlabBuffer << endl;
00243   engine.EvalString("SDV_PE0", matlabBuffer, matlabBufferSize);
00244   if (verbose) cout << matlabBuffer << endl;
00245   if (comm.NumProc() > 1) {
00246     engine.EvalString("SDV_PE1", matlabBuffer, matlabBufferSize);
00247     if (verbose) cout << matlabBuffer << endl;
00248   }
00249   
00250   // the following allows user interaction with Matlab
00251   if (MyPID == 0)
00252   while(1) {
00253       // Prompt the user and get a string
00254       printf(">> ");
00255       if (fgets(s, bufSize, stdin) == NULL) {
00256           printf("Bye\n");
00257           break ;
00258       }
00259       printf ("command :%s:\n", s) ;
00260       
00261       // send the command to MATLAB
00262       // output goes to stdout
00263       ierr = engine.EvalString(s, matlabBuffer, matlabBufferSize);
00264       if (ierr != 0) {
00265           printf("there was an error: %d", ierr);
00266       ierr = 0;
00267       }
00268       else {
00269           printf("Matlab Output:\n%s", matlabBuffer);
00270       }
00271   }
00272   
00273   if (verbose) cout << endl << " all done\n";
00274 
00275 // standard finalizer for Epetra MPI Comms
00276 #ifdef EPETRA_MPI
00277   MPI_Finalize();
00278 #endif
00279 
00280   // we need to delete engine because the MatlabEngine finalizer shuts down the Matlab process associated with this example
00281   // if we don't delete the Matlab engine, then this example application will not shut down properly
00282   delete &engine;
00283   return(0);
00284 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines