00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "EpetraExt_MatlabEngine.h"
00030 #include "EpetraExt_PutMultiVector.h"
00031 #include "EpetraExt_PutRowMatrix.h"
00032 #include "EpetraExt_PutBlockMap.h"
00033
00034 #include "Epetra_Comm.h"
00035 #include "Epetra_MultiVector.h"
00036 #include "Epetra_SerialDenseMatrix.h"
00037 #include "Epetra_IntSerialDenseMatrix.h"
00038 #include "Epetra_IntVector.h"
00039 #include "Epetra_RowMatrix.h"
00040 #include "Epetra_DataAccess.h"
00041 #include "Epetra_Import.h"
00042 #include "Epetra_Export.h"
00043 #include "Epetra_CombineMode.h"
00044 #include "Epetra_CrsMatrix.h"
00045 #include "Epetra_Map.h"
00046 #include "Epetra_CrsMatrix.h"
00047
00048 using namespace EpetraExt;
00049 namespace EpetraExt {
00050
00051
00052 EpetraExt_MatlabEngine::EpetraExt_MatlabEngine (const Epetra_Comm& Comm):Comm_(Comm) {
00053 if (Comm_.MyPID() == 0) {
00054
00055 Engine_ = engOpen(NULL);
00056 }
00057 }
00058
00059
00060 EpetraExt_MatlabEngine::~EpetraExt_MatlabEngine (void) {
00061 if (Comm_.MyPID() == 0) {
00062
00063 engClose(Engine_);
00064 }
00065 }
00066
00067
00068 int EpetraExt_MatlabEngine::EvalString (char* command, char* outputBuffer, int outputBufferSize) {
00069
00070 if (Comm_.MyPID() == 0) {
00071 if (outputBuffer != NULL) {
00072 if (engOutputBuffer(Engine_, outputBuffer, outputBufferSize)) {
00073 return(-4);
00074 }
00075 }
00076 if (engEvalString(Engine_, command)) {
00077 return(-3);
00078 }
00079 }
00080
00081 return(0);
00082 }
00083
00084
00085 int EpetraExt_MatlabEngine::PutMultiVector(const Epetra_MultiVector& A, const char * variableName) {
00086 mxArray* matlabA = 0;
00087 double* pr = 0;
00088 if (Comm_.MyPID() == 0) {
00089 matlabA = mxCreateDoubleMatrix(A.GlobalLength(), A.NumVectors(), mxREAL);
00090 pr = mxGetPr(matlabA);
00091 }
00092
00093 if (Matlab::CopyMultiVector(&pr, A)) {
00094 mxDestroyArray(matlabA);
00095 return(-2);
00096 }
00097
00098 if (Comm_.MyPID() == 0)
00099 if (PutIntoMatlab(variableName, matlabA)) {
00100 mxDestroyArray(matlabA);
00101 return(-1);
00102 }
00103
00104 mxDestroyArray(matlabA);
00105 return(0);
00106 }
00107
00108
00109 int EpetraExt_MatlabEngine::PutRowMatrix(const Epetra_RowMatrix& A, const char* variableName, bool transA) {
00110 mxArray* matlabA = 0;
00111 if (Comm_.MyPID() == 0) {
00112
00113 matlabA = mxCreateSparse(A.OperatorDomainMap().MaxAllGID() - A.OperatorDomainMap().MinAllGID()+1, A.OperatorRangeMap().MaxAllGID() - A.OperatorRangeMap().MinAllGID() + 1, A.NumGlobalNonzeros(), mxREAL);
00114 }
00115
00116
00117
00118 if (Matlab::CopyRowMatrix(matlabA, A)) {
00119 mxDestroyArray(matlabA);
00120 return(-2);
00121 }
00122
00123
00124 if (Comm_.MyPID() == 0) {
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 if (PutIntoMatlab(variableName, matlabA)) {
00136 mxDestroyArray(matlabA);
00137 return(-1);
00138 }
00139
00140 if (!transA) {
00141 char* buff = new char[128];;
00142 sprintf(buff, "%s = %s'", variableName, variableName);
00143 if (EvalString(buff)) {
00144 mxDestroyArray(matlabA);
00145 return(-3);
00146 }
00147 }
00148 }
00149
00150
00151 mxDestroyArray(matlabA);
00152
00153 return(0);
00154 }
00155
00156
00157 int EpetraExt_MatlabEngine::PutCrsGraph(const Epetra_CrsGraph& A, const char* variableName, bool transA) {
00158 return(-9999);
00159 }
00160
00161
00162 int EpetraExt_MatlabEngine::PutSerialDenseMatrix(const Epetra_SerialDenseMatrix& A, const char* variableName, int proc) {
00163 if (proc == 0) {
00164 if (Comm_.MyPID() == 0) {
00165 mxArray* matlabA = 0;
00166
00167 int numRows = A.M();
00168 int numCols = A.N();
00169
00170 matlabA = mxCreateDoubleMatrix(numRows, numCols, mxREAL);
00171
00172 int row;
00173 int col;
00174 double* targetPtr = 0;
00175 double* sourcePtr = 0;
00176 double* source = (double*)A.A();
00177 double* target = (double*)mxGetPr(matlabA);
00178 int source_LDA = A.LDA();
00179 int target_LDA = A.LDA();
00180 for (col = 0; col < numCols; col++) {
00181 targetPtr = target + (col * target_LDA);
00182 sourcePtr = source + (col * source_LDA);
00183 for (row = 0; row < numRows; row++) {
00184 *targetPtr++ = *sourcePtr++;
00185 }
00186 }
00187
00188 if (PutIntoMatlab(variableName, matlabA)) {
00189 mxDestroyArray(matlabA);
00190 return(-1);
00191 }
00192
00193 mxDestroyArray(matlabA);
00194 }
00195
00196 return(0);
00197 }
00198 else {
00199 Epetra_MultiVector* tempMultiVector = 0;
00200 if (proc == Comm_.MyPID()) {
00201 int* numVectors = new int[1];
00202 int* temp = new int[1];
00203 temp[0] = A.N();
00204 Comm_.MaxAll (temp, numVectors, 1);
00205 const Epetra_BlockMap tempBlockMap (-1, A.LDA(), 1, 0, Comm_);
00206 tempMultiVector = new Epetra_MultiVector (View, tempBlockMap, A.A(), A.LDA(), A.N());
00207 }
00208 else {
00209 int* numVectors = new int[1];
00210 int* temp = new int[1];
00211 temp[0] = 0;
00212 Comm_.MaxAll (temp, numVectors, 1);
00213 const Epetra_BlockMap tempBlockMap (-1, 0, 1, 0, Comm_);
00214 tempMultiVector = new Epetra_MultiVector (tempBlockMap, numVectors[0], false);
00215 }
00216
00217 return(PutMultiVector(*tempMultiVector, variableName));
00218 }
00219 }
00220
00221
00222 int EpetraExt_MatlabEngine::PutIntSerialDenseMatrix(const Epetra_IntSerialDenseMatrix& A, const char* variableName, int proc) {
00223 mxArray* matlabA = 0;
00224
00225 if (proc == 0) {
00226 if (Comm_.MyPID() == 0) {
00227 int numRows = A.M();
00228 int numCols = A.N();
00229
00230 matlabA = mxCreateDoubleMatrix(numRows, numCols, mxREAL);
00231
00232 int row;
00233 int col;
00234 double* targetPtr = 0;
00235 int* sourcePtr = 0;
00236 int* source = (int*)A.A();
00237 double* target = (double*)mxGetPr(matlabA);
00238 int source_LDA = A.LDA();
00239 int target_LDA = A.LDA();
00240 for (col = 0; col < numCols; col++) {
00241 targetPtr = target + (col * target_LDA);
00242 sourcePtr = source + (col * source_LDA);
00243 for (row = 0; row < numRows; row++) {
00244 *targetPtr++ = *sourcePtr++;
00245 }
00246 }
00247
00248 if (PutIntoMatlab(variableName, matlabA)) {
00249 mxDestroyArray(matlabA);
00250 return(-1);
00251 }
00252 }
00253 }
00254 else {
00255 int* numVectors = new int[2];
00256 if (proc == Comm_.MyPID()) {
00257 int* temp = new int[2];
00258 temp[0] = A.N();
00259 temp[1] = A.M();
00260 Comm_.MaxAll (temp, numVectors, 2);
00261 }
00262 else {
00263 int* temp = new int[2];
00264 temp[0] = 0;
00265 temp[1] = 0;
00266 Comm_.MaxAll (temp, numVectors, 2);
00267 }
00268
00269 int numRows = numVectors[1];
00270 int numCols = numVectors[0];
00271 double* targetPtr = 0;
00272 int* sourcePtr = 0;
00273 int row;
00274 double* target = 0;
00275 const Epetra_BlockMap* tgBlockMap = 0;
00276 if (Comm_.MyPID() == 0) {
00277 matlabA = mxCreateDoubleMatrix(numRows, numCols, mxREAL);
00278 target = (double*)mxGetPr(matlabA);
00279 tgBlockMap = new Epetra_BlockMap(-1, numRows, 1, 0, Comm_);
00280 }
00281 else {
00282 tgBlockMap = new Epetra_BlockMap(-1, 0, 1, 0, Comm_);
00283 }
00284
00285 const Epetra_BlockMap* srcBlockMap = 0;
00286 Epetra_IntVector* srcIntVector = 0;
00287 Epetra_IntVector tgIntVector (*tgBlockMap, false);
00288 if (proc == Comm_.MyPID()) {
00289 srcBlockMap = new Epetra_BlockMap(-1, A.LDA(), 1, 0, Comm_);
00290 }
00291 else {
00292 srcBlockMap = new Epetra_BlockMap(-1, 0, 1, 0, Comm_);
00293 }
00294
00295 Epetra_Import importer (*tgBlockMap, *srcBlockMap);
00296
00297 for(int i=0; i < numVectors[0]; i++) {
00298 if (proc == Comm_.MyPID()) {
00299 srcIntVector = new Epetra_IntVector(View, *srcBlockMap, (int*)A[i]);
00300 }
00301 else {
00302 srcIntVector = new Epetra_IntVector(*srcBlockMap, false);
00303 }
00304
00305 tgIntVector.Import(*srcIntVector, importer, Insert);
00306 if (Comm_.MyPID() == 0) {
00307 targetPtr = target + (i * numRows);
00308 sourcePtr = (int*)tgIntVector.Values();
00309 for (row = 0; row < numRows; row++) {
00310 *targetPtr++ = *sourcePtr++;
00311 }
00312 }
00313 }
00314
00315 if (PutIntoMatlab(variableName, matlabA)) {
00316 mxDestroyArray(matlabA);
00317 return(-1);
00318 }
00319 }
00320
00321 mxDestroyArray(matlabA);
00322 return(0);
00323 }
00324
00325
00326 int EpetraExt_MatlabEngine::PutBlockMap(const Epetra_BlockMap& blockMap, const char* variableName, bool transA) {
00327 mxArray* matlabA = 0;
00328 if (Comm_.MyPID() == 0) {
00329 int M = blockMap.NumGlobalElements();
00330 int N = 1;
00331
00332 if (blockMap.MaxElementSize()>1) N = 2;
00333
00334 matlabA = mxCreateSparse(N, M, M*N, mxREAL);
00335 int* matlabAcolumnIndicesPtr = mxGetJc(matlabA);
00336 matlabAcolumnIndicesPtr += M;
00337 *matlabAcolumnIndicesPtr = M*N;
00338 }
00339
00340 if (Matlab::CopyBlockMap(matlabA, blockMap)) {
00341 mxDestroyArray(matlabA);
00342 return(-2);
00343 }
00344
00345 if (Comm_.MyPID() == 0) {
00346 if (PutIntoMatlab(variableName, matlabA)) {
00347 mxDestroyArray(matlabA);
00348 return(-1);
00349 }
00350
00351 if (!transA) {
00352 char* buff = new char[128];;
00353 sprintf(buff, "%s = %s'", variableName, variableName);
00354 if (EvalString(buff)) {
00355 mxDestroyArray(matlabA);
00356 return(-3);
00357 }
00358 }
00359 }
00360
00361 mxDestroyArray(matlabA);
00362 return(0);
00363 }
00364
00365
00366 int EpetraExt_MatlabEngine::PutIntoMatlab(const char* variableName, mxArray* matlabA) {
00367 if (Comm_.MyPID() != 0) {
00368 return(0);
00369 }
00370 #ifdef USE_ENGPUTARRAY
00371
00372 mxSetName(matlabA, variableName);
00373 return(engPutArray(Engine_, matlabA));
00374 #else
00375
00376 return(engPutVariable(Engine_, variableName, matlabA));
00377 #endif
00378 }
00379
00380
00381 int EpetraExt_MatlabEngine::GetMultiVector(const char* variableName, Epetra_MultiVector& A) {
00382 mxArray* matlabA = 0;
00383 int ierr = 0;
00384 if (ierr = GetmxArray(variableName, &matlabA)) {
00385 mxDestroyArray(matlabA);
00386 return(ierr);
00387 }
00388
00389 bool isSparse = false;
00390 int numRows = 0;
00391 int numCols = 0;
00392 int numNonZeros = 0;
00393
00394 if (ierr = GetmxArrayDimensions(matlabA, isSparse, numRows, numCols, numNonZeros)) {
00395 mxDestroyArray(matlabA);
00396 return(ierr);
00397 }
00398
00399 if ((Comm_.MyPID() == 0) && isSparse) {
00400 mxDestroyArray(matlabA);
00401 return(-7);
00402 }
00403
00404
00405 Epetra_Map tempMap (-1, numRows, 0, Comm_);
00406
00407 int numVectors = 0;
00408 Comm_.MaxAll (&numCols, &numVectors, 1);
00409 double* tempValues = 0;
00410 if (Comm_.MyPID() == 0) {
00411 tempValues = mxGetPr(matlabA);
00412 }
00413 Epetra_MultiVector tempMV (View, tempMap, tempValues, numRows, numVectors);
00414 Epetra_Export exporter (tempMap, A.Map());
00415 A.Export(tempMV, exporter, Insert);
00416
00417 mxDestroyArray(matlabA);
00418 return(0);
00419 }
00420
00421
00422 int EpetraExt_MatlabEngine::GetSerialDenseMatrix(const char* variableName, Epetra_SerialDenseMatrix& A, int proc) {
00423 int ierr = 0;
00424 int numMyGIDs = 0;
00425 if (Comm_.MyPID() == proc) {
00426 numMyGIDs = A.M();
00427 }
00428 Epetra_Map tempMap (-1, numMyGIDs, 0, Comm_);
00429 Epetra_MultiVector tempMV (View, tempMap, A.A(), numMyGIDs, A.N());
00430
00431 if (ierr = GetMultiVector(variableName, tempMV)) {
00432 return(ierr);
00433 }
00434
00435 if (Comm_.MyPID() == proc) {
00436 double* aValues = A.A();
00437 double* mvValues = tempMV.Values();
00438 for(int i=0; i < A.M() * A.N(); i++) {
00439 *aValues++ = *mvValues++;
00440 }
00441 }
00442
00443 return(0);
00444 }
00445
00446
00447 int EpetraExt_MatlabEngine::GetIntSerialDenseMatrix(const char* variableName, Epetra_IntSerialDenseMatrix& A, int proc) {
00448 int ierr = 0;
00449 int numMyGIDs = 0;
00450 double* values = 0;
00451 if (Comm_.MyPID() == proc) {
00452 numMyGIDs = A.M();
00453 int* aValues = A.A();
00454 values = new double[A.M() * A.N()];
00455 for (int i=0; i < A.M() * A.N(); i++) {
00456 *values++ = *aValues++;
00457 }
00458 }
00459 Epetra_Map tempMap (-1, numMyGIDs, 0, Comm_);
00460 Epetra_MultiVector tempMV (View, tempMap, values, numMyGIDs, A.N());
00461
00462 if (ierr = GetMultiVector(variableName, tempMV)) {
00463 return(ierr);
00464 }
00465
00466 if (Comm_.MyPID() == proc) {
00467 int* aValues = A.A();
00468 double* mvValues = tempMV.Values();
00469 for(int i=0; i < A.M() * A.N(); i++) {
00470 *aValues++ = *mvValues++;
00471 }
00472 }
00473
00474 return(0);
00475 }
00476
00477
00478 int EpetraExt_MatlabEngine::GetCrsMatrix(const char* inVariableName, Epetra_CrsMatrix& A, bool getTrans) {
00479 const char* variableName;
00480
00481 if (!getTrans) {
00482 int inVariableNameLength = strlen(inVariableName);
00483 char* buff = new char[inVariableNameLength*2 + 11];
00484 sprintf(buff, "TRANS_%s = %s'", inVariableName, inVariableName);
00485 if (EvalString(buff)) {
00486 return(-3);
00487 }
00488 char* tempStr = new char[inVariableNameLength + 7];
00489 sprintf(tempStr, "TRANS_%s", inVariableName);
00490 variableName = tempStr;
00491 }
00492 else {
00493 variableName = inVariableName;
00494 }
00495
00496 mxArray* matlabA = 0;
00497 int ierr = 0;
00498 if (ierr = GetmxArray(variableName, &matlabA)) {
00499 mxDestroyArray(matlabA);
00500 return(ierr);
00501 }
00502
00503 if (!getTrans) {
00504 char* buff = new char[strlen(variableName) + 7];
00505 sprintf(buff, "clear %s", variableName);
00506 if (EvalString(buff)) {
00507 return(-3);
00508 }
00509 }
00510
00511 bool isSparse = false;
00512 int numRows = 0;
00513 int numCols = 0;
00514 int numNonZeros = 0;
00515
00516
00517
00518 if (ierr = GetmxArrayDimensions(matlabA, isSparse, numCols, numRows, numNonZeros)) {
00519 mxDestroyArray(matlabA);
00520 return(ierr);
00521 }
00522
00523 if ((Comm_.MyPID() == 0) && !isSparse) {
00524 mxDestroyArray(matlabA);
00525 return(-8);
00526 }
00527
00528
00529 Epetra_Map tempMap (-1, numRows, 0, Comm_);
00530
00531 int numVectors = 0;
00532 Comm_.MaxAll (&numCols, &numVectors, 1);
00533 Epetra_CrsMatrix tempCRSM (View, tempMap, numVectors);
00534 if (Comm_.MyPID() == 0) {
00535 int* rowIndex = mxGetJc(matlabA);
00536 int* colIndex = mxGetIr(matlabA);
00537 double* values = mxGetPr(matlabA);
00538 int numCols = 0;
00539 for(int row = 0; row < numRows; row++) {
00540 numCols = *(rowIndex+1) - *rowIndex;
00541 if (numCols > 0) {
00542 int* indices = new int[numCols];
00543 int* indicesPtr = indices;
00544 for(int col=0; col < numCols; col++) {
00545 *indicesPtr++ = *colIndex++;
00546 }
00547 tempCRSM.InsertGlobalValues(row, numCols, values, indices);
00548 }
00549 values += numCols;
00550 rowIndex++;
00551 }
00552 }
00553
00554 tempCRSM.FillComplete();
00555 Epetra_Export exporter (tempMap, A.RowMatrixRowMap());
00556 A.Export(tempCRSM, exporter, Insert);
00557
00558 mxDestroyArray(matlabA);
00559 return(0);
00560 }
00561
00562
00563 int EpetraExt_MatlabEngine::GetmxArrayDimensions(mxArray* matlabA, bool& isSparse, int& numRows, int& numCols, int& numNonZeros) {
00564 if (Comm_.MyPID() == 0) {
00565 if (mxGetNumberOfDimensions(matlabA) > 2) {
00566 return(-6);
00567 }
00568
00569 const int* dimensions = mxGetDimensions(matlabA);
00570 numRows = dimensions[0];
00571 numCols = dimensions[1];
00572 isSparse = mxIsSparse(matlabA);
00573
00574 if (isSparse) {
00575 numNonZeros = mxGetNzmax(matlabA);
00576 }
00577 else {
00578 numNonZeros = numRows * numCols;
00579 }
00580 }
00581
00582 return(0);
00583 }
00584
00585
00586 int EpetraExt_MatlabEngine::GetmxArray(const char* variableName, mxArray** matlabA) {
00587 if (Comm_.MyPID() == 0) {
00588 #ifdef USE_ENGPUTARRAY
00589
00590 *matlabA = engGetArray(Engine_, variableName);
00591 #else
00592
00593 *matlabA = engGetVariable(Engine_, variableName);
00594 #endif
00595 if (matlabA == NULL) {
00596 return(-5);
00597 }
00598 }
00599
00600 return(0);
00601 }
00602
00603 }