EpetraExt Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
example/matlab/cxx_main.cpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ***********************************************************************
4 //
5 // EpetraExt: Epetra Extended - Linear Algebra Services Package
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //@HEADER
42 */
43 
44 #include "Epetra_ConfigDefs.h"
45 
46 #ifdef EPETRA_MPI
47 #include "mpi.h"
48 #include "Epetra_MpiComm.h"
49 #else
50 #include "Epetra_SerialComm.h"
51 #endif
52 
53 #include "Epetra_Comm.h"
54 #include "Epetra_Map.h"
55 #include "Epetra_BlockMap.h"
56 #include "Epetra_MultiVector.h"
57 #include "Epetra_Vector.h"
62 #include "Epetra_DataAccess.h"
63 #include "Epetra_CrsMatrix.h"
64 
65 #include "EpetraExt_MatlabEngine.h" // contains the EpetraExt_MatlabEngine class
66 
67 int main(int argc, char *argv[]) {
68 
69 // standard Epetra MPI/Serial Comm startup
70 #ifdef EPETRA_MPI
71  MPI_Init(&argc,&argv);
72  Epetra_MpiComm comm (MPI_COMM_WORLD);
73 #else
74  Epetra_SerialComm comm;
75 #endif
76 
77  int MyPID = comm.MyPID();
78  int ierr = 0;
79  bool verbose = (0 == MyPID);
80  bool reportErrors = (0 == MyPID);
81  // setup MatlabEngine
82  if (verbose) cout << "going to startup a matlab process...\n";
84  if (verbose) cout << "matlab started\n";
85 
86  // setup an array of doubles to be used for the examples
87  int M = 20;
88  int numGlobalElements = M * comm.NumProc();
89  int N = 3;
90  int numMyEntries = M * N;
91  double* A = new double[numMyEntries];
92  double* Aptr = A;
93  int startValue = numMyEntries * MyPID;
94 
95  for(int col=0; col < N; col++) {
96  for(int row=0; row < M; row++) {
97  *Aptr++ = startValue++;
98  }
99  }
100 
101  // setup an array of ints to be used for the examples
102  int* intA = new int[numMyEntries];
103  int* intAptr = intA;
104  int intStartValue = numMyEntries * MyPID;
105  for(int i=0; i < M*N; i++) {
106  *intAptr++ = intStartValue++;
107  }
108 
109  // construct a map to be used by distributed objects
110  Epetra_Map map (numGlobalElements, 0, comm);
111 
112  // CrsMatrix example
113  // constructs a globally distributed CrsMatrix and then puts it into Matlab
114  if (verbose) cout << " constructing CrsMatrix...\n";
115  Epetra_CrsMatrix crsMatrix (Copy, map, N);
116  int* indices = new int[N];
117  for (int col=0; col < N; col++) {
118  indices[col] = col;
119  }
120 
121  double value = startValue;
122  double* values = new double[numMyEntries];
123  int minMyGID = map.MinMyGID();
124  for (int row=0; row < M; row++) {
125  for (int col=0; col < N; col++) {
126  values[col] = value++;
127  }
128 
129  crsMatrix.InsertGlobalValues(minMyGID + row, N, values, indices);
130  }
131 
132  crsMatrix.FillComplete();
133  if (verbose) cout << " CrsMatrix constructed\n";
134  if (verbose) cout << " putting CrsMatrix into Matlab as CRSM\n";
135  ierr = engine.PutRowMatrix(crsMatrix, "CRSM", false);
136  if (ierr) {
137  if (reportErrors) cout << "There was an error in engine.PutRowMatrix(crsMatrix, \"CRSM\", false): " << ierr << endl;
138  }
139 
140  // BlockMap example
141  // puts a map into Matlab
142  if (verbose) cout << " putting Map into Matlab as MAP\n";
143  ierr = engine.PutBlockMap(map, "MAP", false);
144  if (ierr) {
145  if (reportErrors) cout << "There was an error in engine.PutBlockMap(map, \"MAP\", false);: " << ierr << endl;
146  }
147 
148  // MultiVector example
149  // constructs a globally distributed MultiVector and then puts it into Matlab
150  if (verbose) cout << " constructing MultiVector...\n";
151  Epetra_MultiVector multiVector (Copy, map, A, M, N);
152  if (verbose) cout << " MultiVector constructed\n";
153  if (verbose) cout << " putting MultiVector into Matlab as MV\n";
154  ierr = engine.PutMultiVector(multiVector, "MV");
155  if (ierr) {
156  if (reportErrors) cout << "There was an error in engine.PutMultiVector(multiVector, \"MV\"): " << ierr << endl;
157  }
158 
159  // SerialDenseMatrix example
160  // constructs a SerialDenseMatrix on every PE
161  if (verbose) cout << " constructing a SerialDenseMatrix...\n";
162  Epetra_SerialDenseMatrix sdMatrix (Copy, A, M, M, N);
163  if (verbose) cout << " SerialDenseMatrix constructed\n";
164  if (verbose) cout << " putting SerialDenseMatrix from PE0 into Matlab as SDM_PE0\n";
165  // since the third parameter is left out, the SerialDenseMatrix from PE0 is used by default
166  ierr = engine.PutSerialDenseMatrix(sdMatrix, "SDM_PE0");
167  if (ierr) {
168  if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdMatrix, \"SDM_PE0\"): " << ierr << endl;
169  }
170  if (comm.NumProc() > 1) {
171  if (verbose) cout << " putting SerialDenseMatrix from PE1 into Matlab as SDM_PE1\n";
172  // specifying 1 as the third parameter will put the SerialDenseMatrix from PE1 into Matlab
173  ierr = engine.PutSerialDenseMatrix(sdMatrix, "SDM_PE1", 1);
174  if (ierr) {
175  if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdMatrix, \"SDM_PE1\", 1): " << ierr << endl;
176  }
177  }
178 
179 
180  // SerialDenseVector example
181  // constructs a SerialDenseVector on every PE
182  if (verbose) cout << " constructing a SerialDenseVector...\n";
183  Epetra_SerialDenseVector sdVector (Copy, A, M);
184  if (verbose) cout << " SerialDenseVector constructed\n";
185  // since the third parameter is left out, the SerialDenseMatrix from PE0 is used by default
186  if (verbose) cout << " putting SerialDenseVector from PE0 into Matlab as SDV_PE0\n";
187  ierr = engine.PutSerialDenseMatrix(sdVector, "SDV_PE0");
188  if (ierr) {
189  if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdVector, \"SDV_PE0\"): " << ierr << endl;
190  }
191  if (comm.NumProc() > 1) {
192  if (verbose) cout << " putting SerialDenseVector from PE1 into Matlab as SDV_PE1\n";
193  // specifying 1 as the third parameter will put the SerialDenseVector from PE1 into Matlab
194  ierr = engine.PutSerialDenseMatrix(sdVector, "SDV_PE1", 1);
195  if (ierr) {
196  if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(sdMatrix, \"SDV_PE1\", 1): " << ierr << endl;
197  }
198  }
199 
200  // IntSerialDenseMatrix example
201  // constructs a IntSerialDenseMatrix on every PE
202  if (verbose) cout << " constructing a IntSerialDenseMatrix...\n";
203  Epetra_IntSerialDenseMatrix isdMatrix (Copy, intA, M, M, N);
204  if (verbose) cout << " IntSerialDenseMatrix constructed\n";
205  // since the third parameter is left out, the IntSerialDenseMatrix from PE0 is used by default
206  if (verbose) cout << " putting IntSerialDenseMatrix from PE0 into Matlab as ISDM_PE0\n";
207  ierr = engine.PutIntSerialDenseMatrix(isdMatrix, "ISDM_PE0");
208  if (ierr) {
209  if (reportErrors) cout << "There was an error in engine.PutIntSerialDenseMatrix(isdMatrix, \"ISDM_PE0\"): " << ierr << endl;
210  }
211  if (comm.NumProc() > 1) {
212  if (verbose) cout << " putting IntSerialDenseMatrix from PE1 into Matlab as ISDM_PE1\n";
213  // specifying 1 as the third parameter will put the IntSerialDenseMatrix from PE1 into Matlab
214  ierr = engine.PutIntSerialDenseMatrix(isdMatrix, "ISDM_PE1", 1);
215  if (ierr) {
216  if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(isdMatrix, \"ISDM_PE1\", 1): " << ierr << endl;
217  }
218  }
219 
220 
221  // IntSerialDenseVector example
222  // constructs a IntSerialDenseVector on every PE
223  if (verbose) cout << " constructing a IntSerialDenseVector...\n";
224  Epetra_IntSerialDenseVector isdVector (Copy, intA, M);
225  if (verbose) cout << " IntSerialDenseVector constructed\n";
226  // since the third parameter is left out, the IntSerialDenseVector from PE0 is used by default
227  if (verbose) cout << " putting IntSerialDenseVector from PE0 into Matlab as ISDV_PE0\n";
228  ierr = engine.PutIntSerialDenseMatrix(isdVector, "ISDV_PE0");
229  if (ierr) {
230  if (reportErrors) cout << "There was an error in engine.PutIntSerialDenseMatrix(isdVector, \"ISDV_PE0\"): " << ierr << endl;
231  }
232  if (comm.NumProc() > 1) {
233  if (verbose) cout << " putting IntSerialDenseVector from PE1 into Matlab as ISDV_PE1\n";
234  // specifying 1 as the third parameter will put the IntSerialDenseVector from PE1 into Matlab
235  ierr = engine.PutIntSerialDenseMatrix(isdVector, "ISDV_PE1", 1);
236  if (ierr) {
237  if (reportErrors) cout << "There was an error in engine.PutSerialDenseMatrix(isdVector, \"ISDV_PE1\", 1): " << ierr << endl;
238  }
239  }
240 
241  // entering a while loop on PE0 will keep the Matlab workspace alive
242  /*
243  if (MyPID == 0)
244  while(1) {
245  // do nothing
246  }
247  */
248 
249  const int bufSize = 200;
250  char s [bufSize];
251  const int matlabBufferSize = 1024 * 16;
252  char matlabBuffer [matlabBufferSize];
253 
254  // send some commands to Matlab and output the result to stdout
255  engine.EvalString("whos", matlabBuffer, matlabBufferSize);
256  if (verbose) cout << matlabBuffer << endl;
257  engine.EvalString("SDV_PE0", matlabBuffer, matlabBufferSize);
258  if (verbose) cout << matlabBuffer << endl;
259  if (comm.NumProc() > 1) {
260  engine.EvalString("SDV_PE1", matlabBuffer, matlabBufferSize);
261  if (verbose) cout << matlabBuffer << endl;
262  }
263 
264  // the following allows user interaction with Matlab
265  if (MyPID == 0)
266  while(1) {
267  // Prompt the user and get a string
268  printf(">> ");
269  if (fgets(s, bufSize, stdin) == NULL) {
270  printf("Bye\n");
271  break ;
272  }
273  printf ("command :%s:\n", s) ;
274 
275  // send the command to MATLAB
276  // output goes to stdout
277  ierr = engine.EvalString(s, matlabBuffer, matlabBufferSize);
278  if (ierr != 0) {
279  printf("there was an error: %d", ierr);
280  ierr = 0;
281  }
282  else {
283  printf("Matlab Output:\n%s", matlabBuffer);
284  }
285  }
286 
287  if (verbose) cout << endl << " all done\n";
288 
289 // standard finalizer for Epetra MPI Comms
290 #ifdef EPETRA_MPI
291  MPI_Finalize();
292 #endif
293 
294  // we need to delete engine because the MatlabEngine finalizer shuts down the Matlab process associated with this example
295  // if we don't delete the Matlab engine, then this example application will not shut down properly
296  delete &engine;
297  return(0);
298 }
int PutIntSerialDenseMatrix(const Epetra_IntSerialDenseMatrix &A, const char *variableName, int proc=0)
Puts a copy of the IntSerialDenseMatrix into the Matlab workspace.
int PutBlockMap(const Epetra_BlockMap &blockMap, const char *variableName, bool transA)
Puts a copy of the BlockMap or Map into the Matlab workspace.
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
int PutSerialDenseMatrix(const Epetra_SerialDenseMatrix &A, const char *variableName, int proc=0)
Puts a copy of the SerialDenseMatrix into the Matlab workspace.
int MyPID() const
int FillComplete(bool OptimizeDataStorage=true)
int main(int argc, char **argv)
Definition: HDF5_IO.cpp:67
const int N
int NumProc() const
int MinMyGID() const
int PutRowMatrix(const Epetra_RowMatrix &A, const char *variableName, bool transA)
Puts a copy of the serial or distributed RowMatrix into the Matlab workspace.
int PutMultiVector(const Epetra_MultiVector &A, const char *variableName)
Puts a copy of the serial or distributed MultiVector into the Matlab workspace.
int EvalString(char *command, char *outputBuffer=NULL, int outputBufferSize=-1)
Sends a command to Matlab.
A class which provides data and command access to Matlab from Epetra.