EpetraExt Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
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
67int 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
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}
Copy
A class which provides data and command access to Matlab from Epetra.
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 PutSerialDenseMatrix(const Epetra_SerialDenseMatrix &A, const char *variableName, int proc=0)
Puts a copy of the SerialDenseMatrix 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 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.
int EvalString(char *command, char *outputBuffer=NULL, int outputBufferSize=-1)
Sends a command to Matlab.
int MinMyGID() const
int FillComplete(bool OptimizeDataStorage=true)
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
int NumProc() const
int MyPID() const
int main(int argc, char *argv[])