00001
00011
00012
00013
00014 #include <stdio.h>
00015 #include <string.h>
00016
00017 #include <matrix.h>
00018 #include <mex.h>
00019
00020 #include "grpc.h"
00021 #include "comm_data.h"
00022 #include "matlab_gs.h"
00023
00024 #define MAX_FILES_IN_PACKEDFILE 1024
00025
00026 typedef enum {DO_NOT_ALLOC, MAYBE_ALLOC} gs_alloc_t;
00027
00028 #define COPY_A_TO_B(TYPEA, a, aoffset, TYPEB, b, boffset, size) do {int ss = 0; \
00029 TYPEA* ss_a = (TYPEA*) a; \
00030 TYPEB* ss_b = (TYPEB*) b; \
00031 ss_a+=aoffset; ss_b+=boffset; \
00032 for (ss = 0; ss < size; ss++) \
00033 *((ss_b)++) = (TYPEB) *((ss_a)++);\
00034 } while (0)
00035
00036
00037 #define COPY_MXARRAY_TO_GSCOMPLEX(MX_DATA_T, mxr, mxi, mxoffset, GS_COMPLEX_T, gs_cplx, gsoffset, GS_DATA_T, size) \
00038 do {int ss = 0; \
00039 MX_DATA_T* ss_mxr = (MX_DATA_T*) mxr; \
00040 MX_DATA_T* ss_mxi = (MX_DATA_T*) mxi; \
00041 GS_COMPLEX_T* ss_gs_cplx = (GS_COMPLEX_T*) gs_cplx; \
00042 ss_mxr+=mxoffset; ss_mxi+=mxoffset; ss_gs_cplx+=gsoffset; \
00043 for (ss = 0; ss < size; ss++) { \
00044 ss_gs_cplx[ss].r = (GS_DATA_T) *((ss_mxr)++); \
00045 if (mxi == NULL) \
00046 ss_gs_cplx[ss].i = (GS_DATA_T) 0.0; \
00047 else \
00048 ss_gs_cplx[ss].i = (GS_DATA_T) *((ss_mxi)++); \
00049 } \
00050 } while (0)
00051
00052
00064 void *matlab_gs_calloc(size_t N, size_t S)
00065 {
00066 void *ptr;
00067
00068 ptr = calloc(N, S);
00069 if (ptr == NULL) {
00070 ERRPRINTF("Matlab is out of memory in GridSolve client\n");
00071 return NULL;
00072 }
00073
00074 return ptr;
00075 }
00076
00084 void *matlab_gs_free(void *ptr)
00085 {
00086
00087 if ( ptr ) free(ptr);
00088 return NULL;
00089 }
00090
00100 int matlab_gs_arg_is_sparse_index_or_pointer(gs_argument_t *argp, gs_problem_t *problem)
00101 {
00102 int arg_is_sparse_attr = 0;
00103 gs_argument_t* arg_attr = NULL;
00104
00105 for (arg_attr = problem->arglist; arg_attr != NULL; arg_attr = arg_attr->next)
00106 if ((arg_attr->objecttype == GS_SPARSEMATRIX) &&
00107 (!strcmp(argp->name, arg_attr->sparse_attr.indices) ||
00108 !strcmp(argp->name, arg_attr->sparse_attr.pointer))) {
00109 arg_is_sparse_attr = 1;
00110 break;
00111 }
00112 return arg_is_sparse_attr;
00113 }
00114
00115
00127 static mxArray *matlab_gs_create_matrix(
00128 int objecttype, int M, int N, int nnz, int datatype)
00129 {
00130 mxComplexity realorcomplex = mxREAL;
00131 mxClassID classid = mxDOUBLE_CLASS;
00132 mxArray *ptr;
00133
00134 switch (datatype) {
00135 case GS_INT:
00136 case GS_FLOAT:
00137 case GS_DOUBLE:
00138 classid = mxDOUBLE_CLASS;
00139 realorcomplex = mxREAL;
00140 break;
00141 case GS_SCOMPLEX:
00142 case GS_DCOMPLEX:
00143 classid = mxDOUBLE_CLASS;
00144 realorcomplex = mxCOMPLEX;
00145 break;
00146 case GS_CHAR:
00147 break;
00148 case GS_BAD_DTYPE:
00149 return NULL;
00150 break;
00151 default:
00152 return NULL;
00153 break;
00154 }
00155
00156 if (objecttype == GS_SPARSEMATRIX) {
00157 ptr = mxCreateSparse(M, N ,nnz, realorcomplex);
00158 } else {
00159 ptr = mxCreateNumericMatrix(M, N, classid, realorcomplex);
00160 }
00161 return ptr;
00162 }
00163
00164
00178 static int transfer_mx_to_gs_int(mxClassID mxclassid, void *pr, int poffset, void** datapp, int doffset, int nelem, gs_alloc_t allocp)
00179 {
00180
00181 if (allocp != DO_NOT_ALLOC)
00182 if ((*datapp = (int*)matlab_gs_calloc(nelem, sizeof(int)))==NULL) return -1;
00183
00184 if (mxclassid == mxDOUBLE_CLASS)
00185 COPY_A_TO_B(double, pr, poffset, int, *datapp, doffset, nelem);
00186 else if (mxclassid == mxSINGLE_CLASS)
00187 COPY_A_TO_B(float, pr, poffset, int, *datapp, doffset, nelem);
00188 else if (mxclassid == mxINT8_CLASS)
00189 COPY_A_TO_B(int8_t, pr, poffset, int, *datapp, doffset, nelem);
00190 else if (mxclassid == mxUINT8_CLASS)
00191 COPY_A_TO_B(uint8_t, pr, poffset, int, *datapp, doffset, nelem);
00192 else if (mxclassid == mxINT16_CLASS)
00193 COPY_A_TO_B(int16_t, pr, poffset, int, *datapp, doffset, nelem);
00194 else if (mxclassid == mxUINT16_CLASS)
00195 COPY_A_TO_B(uint16_t, pr, poffset, int, *datapp, doffset, nelem);
00196 else if (mxclassid == mxINT32_CLASS)
00197 COPY_A_TO_B(int32_t, pr, poffset, int, *datapp, doffset, nelem);
00198 else if (mxclassid == mxUINT32_CLASS)
00199 COPY_A_TO_B(uint32_t, pr, poffset, int, *datapp, doffset, nelem);
00200 else if (mxclassid == mxCHAR_CLASS)
00201 COPY_A_TO_B(char, pr, poffset, int, *datapp, doffset, nelem);
00202
00203
00204
00205
00206 else {
00207 ERRPRINTF("Could not convert matlab data to GridSolve data type (int)\n");
00208 return -1;
00209 }
00210 return 1;
00211 }
00212
00226 static int transfer_mx_to_gs_double(mxClassID mxclassid, void *pr, int poffset, void** datapp, int doffset, int nelem, gs_alloc_t allocp)
00227 {
00228
00229 if (allocp != DO_NOT_ALLOC)
00230 if ((*datapp = (double*)matlab_gs_calloc(nelem, sizeof(double)))==NULL) return -1;
00231
00232 if (mxclassid == mxDOUBLE_CLASS)
00233 COPY_A_TO_B(double, pr, poffset, double, *datapp, doffset, nelem);
00234 else if (mxclassid == mxSINGLE_CLASS)
00235 COPY_A_TO_B(float, pr, poffset, double, *datapp, doffset, nelem);
00236 else if (mxclassid == mxINT8_CLASS)
00237 COPY_A_TO_B(int8_t, pr, poffset, double, *datapp, doffset, nelem);
00238 else if (mxclassid == mxUINT8_CLASS)
00239 COPY_A_TO_B(uint8_t, pr, poffset, double, *datapp, doffset, nelem);
00240 else if (mxclassid == mxINT16_CLASS)
00241 COPY_A_TO_B(int16_t, pr, poffset, double, *datapp, doffset, nelem);
00242 else if (mxclassid == mxUINT16_CLASS)
00243 COPY_A_TO_B(uint16_t, pr, poffset, double, *datapp, doffset, nelem);
00244 else if (mxclassid == mxINT32_CLASS)
00245 COPY_A_TO_B(int32_t, pr, poffset, double, *datapp, doffset, nelem);
00246 else if (mxclassid == mxUINT32_CLASS)
00247 COPY_A_TO_B(uint32_t, pr, poffset, double, *datapp, doffset, nelem);
00248
00249
00250
00251
00252 else {
00253 ERRPRINTF("Could not convert matlab data to GridSolve data type (double)\n");
00254 return -1;
00255 }
00256
00257 return 1;
00258 }
00259
00273 static int transfer_mx_to_gs_float(mxClassID mxclassid, void *pr, int poffset, void** datapp, int doffset, int nelem, gs_alloc_t allocp)
00274 {
00275
00276 if (allocp != DO_NOT_ALLOC)
00277 if ((*datapp = (double*)matlab_gs_calloc(nelem, sizeof(float)))==NULL) return -1;
00278
00279 if (mxclassid == mxDOUBLE_CLASS)
00280 COPY_A_TO_B(double, pr, poffset, float, *datapp, doffset, nelem);
00281 else if (mxclassid == mxSINGLE_CLASS)
00282 COPY_A_TO_B(float, pr, poffset, float, *datapp, doffset, nelem);
00283 else if (mxclassid == mxINT8_CLASS)
00284 COPY_A_TO_B(int8_t, pr, poffset, float, *datapp, doffset, nelem);
00285 else if (mxclassid == mxUINT8_CLASS)
00286 COPY_A_TO_B(uint8_t, pr, poffset, float, *datapp, doffset, nelem);
00287 else if (mxclassid == mxINT16_CLASS)
00288 COPY_A_TO_B(int16_t, pr, poffset, float, *datapp, doffset, nelem);
00289 else if (mxclassid == mxUINT16_CLASS)
00290 COPY_A_TO_B(uint16_t, pr, poffset, float, *datapp, doffset, nelem);
00291 else if (mxclassid == mxINT32_CLASS)
00292 COPY_A_TO_B(int32_t, pr, poffset, float, *datapp, doffset, nelem);
00293 else if (mxclassid == mxUINT32_CLASS)
00294 COPY_A_TO_B(uint32_t, pr, poffset, float, *datapp, doffset, nelem);
00295
00296
00297
00298
00299 else {
00300 ERRPRINTF("Could not convert matlab data to GridSolve data type (float)\n");
00301 return -1;
00302 }
00303 return 1;
00304 }
00305
00306
00321 static int transfer_mx_to_gs_scomplex(mxClassID mxclassid, void *pr, void *pi, int poffset, void** datapp, int doffset, int nelem, gs_alloc_t allocp)
00322 {
00323
00324 if (allocp != DO_NOT_ALLOC)
00325 if ((*datapp = (gs_scomplex*)matlab_gs_calloc(nelem, sizeof(gs_scomplex)))==NULL) return -1;
00326
00327 if (mxclassid == mxDOUBLE_CLASS)
00328 COPY_MXARRAY_TO_GSCOMPLEX(double, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00329 else if (mxclassid == mxSINGLE_CLASS)
00330 COPY_MXARRAY_TO_GSCOMPLEX(float, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00331 else if (mxclassid == mxINT8_CLASS)
00332 COPY_MXARRAY_TO_GSCOMPLEX(int8_t, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00333 else if (mxclassid == mxUINT8_CLASS)
00334 COPY_MXARRAY_TO_GSCOMPLEX(uint8_t, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00335 else if (mxclassid == mxINT16_CLASS)
00336 COPY_MXARRAY_TO_GSCOMPLEX(int16_t, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00337 else if (mxclassid == mxUINT16_CLASS)
00338 COPY_MXARRAY_TO_GSCOMPLEX(uint16_t, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00339 else if (mxclassid == mxINT32_CLASS)
00340 COPY_MXARRAY_TO_GSCOMPLEX(int32_t, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00341 else if (mxclassid == mxUINT32_CLASS)
00342 COPY_MXARRAY_TO_GSCOMPLEX(uint32_t, pr, pi, poffset, gs_scomplex, *datapp, doffset, float, nelem);
00343
00344
00345
00346
00347 else {
00348 ERRPRINTF("Could not convert matlab data to GridSolve data type (single precision complex)\n");
00349 return -1;
00350 }
00351 return 1;
00352 }
00353
00354
00369 static int transfer_mx_to_gs_dcomplex(mxClassID mxclassid, void *pr, void *pi, int poffset, void** datapp, int doffset, int nelem, gs_alloc_t allocp)
00370 {
00371
00372 if (allocp != DO_NOT_ALLOC)
00373 if ((*datapp = (gs_dcomplex*)matlab_gs_calloc(nelem, sizeof(gs_dcomplex)))==NULL) return -1;
00374
00375 if (mxclassid == mxDOUBLE_CLASS)
00376 COPY_MXARRAY_TO_GSCOMPLEX(double, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00377 else if (mxclassid == mxSINGLE_CLASS)
00378 COPY_MXARRAY_TO_GSCOMPLEX(float, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00379 else if (mxclassid == mxINT8_CLASS)
00380 COPY_MXARRAY_TO_GSCOMPLEX(int8_t, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00381 else if (mxclassid == mxUINT8_CLASS)
00382 COPY_MXARRAY_TO_GSCOMPLEX(uint8_t, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00383 else if (mxclassid == mxINT16_CLASS)
00384 COPY_MXARRAY_TO_GSCOMPLEX(int16_t, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00385 else if (mxclassid == mxUINT16_CLASS)
00386 COPY_MXARRAY_TO_GSCOMPLEX(uint16_t, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00387 else if (mxclassid == mxINT32_CLASS)
00388 COPY_MXARRAY_TO_GSCOMPLEX(int32_t, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00389 else if (mxclassid == mxUINT32_CLASS)
00390 COPY_MXARRAY_TO_GSCOMPLEX(uint32_t, pr, pi, poffset, gs_dcomplex, *datapp, doffset, double, nelem);
00391
00392
00393
00394
00395 else {
00396 ERRPRINTF("Could not convert matlab data to GridSolve data type (double precision complex)\n");
00397 return -1;
00398 }
00399 return 1;
00400 }
00401
00402
00413 static mxArray *transfer_gs_to_mx(gs_argument_t *argp)
00414 {
00415 int nelements, N, M, j;
00416 mxArray *mxarray;
00417 void *datap;
00418
00419 if (argp->inout==GS_VAROUT)
00420 datap = *((void **)argp->data);
00421 else
00422 datap = argp->data;
00423
00424 nelements = argp->rows*argp->cols;
00425 M = argp->rows;
00426 N = argp->cols;
00427
00428 switch (argp->datatype) {
00429 case GS_DOUBLE:
00430 if ((mxarray = matlab_gs_create_matrix(argp->objecttype, M, N, nelements, argp->datatype)) == NULL) goto error_output;
00431 for (j=0; j<nelements; j++)
00432 mxGetPr(mxarray)[j] = ((double*)((double *)datap))[j];
00433 break;
00434 case GS_INT:
00435 if ((mxarray = matlab_gs_create_matrix(argp->objecttype, M, N, nelements, argp->datatype)) == NULL) goto error_output;
00436 for (j=0; j<nelements; j++)
00437 mxGetPr(mxarray)[j] = (double)(((int*)(datap))[j]);
00438 break;
00439 case GS_FLOAT:
00440 if ((mxarray = matlab_gs_create_matrix(argp->objecttype, M, N, nelements, argp->datatype)) == NULL) goto error_output;
00441 for (j=0; j<nelements; j++)
00442 mxGetPr(mxarray)[j] = (double)(((float*)(datap))[j]);
00443 break;
00444 case GS_SCOMPLEX:
00445 if ((mxarray = matlab_gs_create_matrix(argp->objecttype, M, N, nelements, argp->datatype)) == NULL) goto error_output;
00446 for (j=0; j<nelements; j++) {
00447 mxGetPr(mxarray)[j] = (double)(((gs_scomplex*)(datap))[j].r);
00448 mxGetPi(mxarray)[j] = (double)(((gs_scomplex*)(datap))[j].i);
00449 }
00450 break;
00451 case GS_DCOMPLEX:
00452 if ((mxarray = matlab_gs_create_matrix(argp->objecttype, M, N, nelements, argp->datatype)) == NULL) goto error_output;
00453 for (j=0; j<nelements; j++) {
00454 mxGetPr(mxarray)[j] = (double)(((gs_dcomplex*)(datap))[j].r);
00455 mxGetPi(mxarray)[j] = (double)(((gs_dcomplex*)(datap))[j].i);
00456 }
00457 break;
00458 case GS_CHAR:
00459 {
00460 mxChar *charData;
00461 int dims[2] = {argp->rows, argp->cols};
00462 if ((mxarray = mxCreateCharArray(2, dims)) == NULL) goto error_output;
00463 charData = (mxChar *)mxGetData(mxarray);
00464 for(j=0; j<argp->rows*argp->cols; j++)
00465 charData[j] = (mxChar)((char*)datap)[j];
00466 break;
00467 }
00468 default:
00469 ERRPRINTF("Unknown datatype %d\n", argp->datatype);
00470 goto error_output;
00471 break;
00472 }
00473 return mxarray;
00474
00475 error_output:
00476 ERRPRINTF("GridSolve: Error transfering GridSolve output (arg %s type %s) to Matlab", argp->name, gs_c_datatype[argp->datatype]);
00477 return NULL;
00478
00479
00480 }
00481
00482
00492 static int arg_data_same_as_mx_dat(const mxArray *mxarray, gs_argument_t *argp)
00493 {
00494 int gsdatatype = argp->datatype;
00495 mxClassID mxclassid = mxGetClassID(mxarray);
00496
00497 if (argp->inout != GS_IN) return 0;
00498
00499 if (mxclassid==mxDOUBLE_CLASS && gsdatatype==GS_DOUBLE)
00500 return 1;
00501 else if (mxclassid==mxSINGLE_CLASS && gsdatatype==GS_FLOAT)
00502 return 1;
00503 else if (mxclassid==mxINT32_CLASS && gsdatatype==GS_INT)
00504 return 1;
00505 else
00506 return 0;
00507 }
00508
00509
00535 static int matlab_gs_sparse_matcsc_to_csr(
00536 int m, int n, int nnz,
00537 int mxclassid, void *ar, void *ai, int *colind, int *rowptr,
00538 int gsdatatype, void *gsat, int *rowind, int *colptr)
00539 {
00540 register int i, j, col, relpos;
00541 int *marker;
00542
00543 marker = (int *) matlab_gs_calloc(n, sizeof(int));
00544 if (marker == NULL) return -1;
00545
00546
00547 for (i = 0; i < m; ++i)
00548 for (j = rowptr[i]; j < rowptr[i+1]; ++j)
00549 ++marker[colind[j]];
00550
00551 colptr[0] = 0;
00552
00553 for (j = 0; j < n; ++j) {
00554 colptr[j+1] = colptr[j] + marker[j];
00555 marker[j] = colptr[j];
00556 }
00557
00558
00559 for (i = 0; i < m; ++i) {
00560 for (j = rowptr[i]; j < rowptr[i+1]; ++j) {
00561 col = colind[j];
00562 relpos = marker[col];
00563 rowind[relpos] = i;
00564
00565
00566 switch(gsdatatype) {
00567 case GS_INT:
00568
00569 if (transfer_mx_to_gs_int(mxclassid, ar, j, &gsat, relpos, 1, DO_NOT_ALLOC) == -1) goto error;
00570 break;
00571 case GS_FLOAT:
00572 if (transfer_mx_to_gs_float(mxclassid, ar, j, &gsat, relpos, 1, DO_NOT_ALLOC) == -1) goto error;
00573 break;
00574 case GS_DOUBLE:
00575 if (transfer_mx_to_gs_double(mxclassid, ar, j, &gsat, relpos, 1, DO_NOT_ALLOC) == -1) goto error;
00576 break;
00577 case GS_SCOMPLEX:
00578 if (transfer_mx_to_gs_scomplex(mxclassid, ar, ai, j, &gsat, relpos, 1, DO_NOT_ALLOC) == -1) goto error;
00579 break;
00580 case GS_DCOMPLEX:
00581 if (transfer_mx_to_gs_dcomplex(mxclassid, ar, ai, j, &gsat, relpos, 1, DO_NOT_ALLOC) == -1) goto error;
00582 break;
00583 default:
00584 ERRPRINTF("GridSolve sparse of datatype (%s) not supported \n", gs_c_datatype[gsdatatype]);
00585
00586 return -1;
00587 break;
00588 }
00589
00590 ++marker[col];
00591 }
00592 }
00593 marker = matlab_gs_free(marker);
00594 return 0;
00595
00596 error:
00597 ERRPRINTF("Could not convert matlab data to GridSolve sparse CSR format (%s)\n", gs_c_datatype[gsdatatype]);
00598 return -1;
00599 }
00600
00626 static int matlab_gs_sparse_csr_to_matcsc(
00627 int m, int n, int nnz,
00628 int datatype, void *a, int *colind, int *rowptr,
00629 double *at, double *ati, int *rowind, int *colptr)
00630 {
00631 register int i, j, col, relpos;
00632 int *marker;
00633
00634 marker = (int *)matlab_gs_calloc(n, sizeof(int));
00635 if (marker == NULL) return -1;
00636
00637
00638 for (i = 0; i < m; ++i)
00639 for (j = rowptr[i]; j < rowptr[i+1]; ++j) ++marker[colind[j]];
00640
00641 colptr[0] = 0;
00642
00643 for (j = 0; j < n; ++j) {
00644 colptr[j+1] = colptr[j] + marker[j];
00645 marker[j] = colptr[j];
00646 }
00647
00648
00649 for (i = 0; i < m; ++i) {
00650 for (j = rowptr[i]; j < rowptr[i+1]; ++j) {
00651 col = colind[j];
00652 relpos = marker[col];
00653 rowind[relpos] = i;
00654
00655 switch(datatype) {
00656 case GS_INT:
00657 ((double *)at)[relpos] = (double)((int *)a)[j];
00658 break;
00659 case GS_FLOAT:
00660 ((double *)at)[relpos] = (double)((float *)a)[j];
00661 break;
00662 case GS_DOUBLE:
00663 ((double *)at)[relpos] = ((double *)a)[j];
00664 break;
00665 case GS_SCOMPLEX:
00666 ((double *)at)[relpos] = (double)(((gs_scomplex *)a)[j].r);
00667 ((double *)ati)[relpos] = (double)(((gs_scomplex *)a)[j].i);
00668 break;
00669 case GS_DCOMPLEX:
00670 ((double *)at)[relpos] = (double)((gs_dcomplex *)a)[j].r;
00671 ((double *)ati)[relpos] = (double)((gs_dcomplex *)a)[j].i;
00672 break;
00673 default:
00674 ERRPRINTF("GridSolve sparse of datatype (%s) not supported \n", gs_c_datatype[datatype]);
00675
00676 return -1;
00677 break;
00678 }
00679 ++marker[col];
00680 }
00681 }
00682 marker = matlab_gs_free(marker);
00683 return 0;
00684 }
00685
00686
00702 static int matlab_gs_setup_scalar_arguments(
00703 gs_problem_t* problem, int nlhs, mxArray *plhs[],
00704 int nrhs, const mxArray *prhs[])
00705 {
00706 gs_argument_t* argp = NULL;
00707 double *pr = NULL;
00708 double *pi = NULL;
00709 int irhs = 0;
00710
00711 for (argp=problem->arglist,irhs=2; argp!=NULL && irhs<=nrhs; argp=argp->next) {
00712
00713
00714 if (matlab_gs_arg_is_sparse_index_or_pointer(argp, problem)) {
00715 DBGPRINTF("Skipping sparse attribute: %s \n", argp->name);
00716 continue;
00717 }
00718
00719
00720 if (argp->inout==GS_IN || argp->inout==GS_INOUT ) {
00721 switch (argp->objecttype) {
00722 case GS_SCALAR:
00723 DBGPRINTF("Transfer scalar Matlab arg %d (%s %d) to GridSolve arg (%s %s)\n", irhs-2, mxGetClassName(prhs[irhs]), mxGetNumberOfElements(prhs[irhs]),argp->name, gs_c_datatype[argp->datatype]);
00724 if (mxGetNumberOfElements(prhs[irhs])!=1) { DBGPRINTF("numelements mismatch\n"); goto error; }
00725 pr = mxGetPr(prhs[irhs]);
00726 pi = mxGetPi(prhs[irhs]);
00727 argp->data = &(argp->scalar_val);
00728 switch (argp->datatype) {
00729 case GS_DOUBLE:
00730 if (transfer_mx_to_gs_double(mxGetClassID(prhs[irhs]), pr, 0, (void **)&(argp->data), 0, 1, DO_NOT_ALLOC)<0) goto error;
00731 break;
00732 case GS_INT:
00733 if (transfer_mx_to_gs_int(mxGetClassID(prhs[irhs]), pr, 0, (void **)&(argp->data), 0, 1, DO_NOT_ALLOC)<0) goto error;
00734 break;
00735 case GS_FLOAT:
00736 if (transfer_mx_to_gs_float(mxGetClassID(prhs[irhs]), pr, 0, (void **)&(argp->data), 0, 1, DO_NOT_ALLOC)<0) goto error;
00737 break;
00738 case GS_SCOMPLEX:
00739 if (transfer_mx_to_gs_scomplex(mxGetClassID(prhs[irhs]), pr, pi, 0, (void **)&(argp->data), 0, 1, DO_NOT_ALLOC)<0) goto error;
00740 break;
00741 case GS_DCOMPLEX:
00742 if (transfer_mx_to_gs_dcomplex(mxGetClassID(prhs[irhs]), pr, pi, 0, (void **)&(argp->data), 0, 1, DO_NOT_ALLOC)<0) goto error;
00743 break;
00744 case GS_CHAR:
00745 argp->scalar_val.char_val = (char)mxGetScalar(prhs[irhs]);
00746 break;
00747 default:
00748 argp->data = NULL;
00749 ERRPRINTF("GridSolve datatype (%s) is not handled yet\n", gs_c_datatype[argp->datatype]);
00750 goto error;
00751 break;
00752 }
00753 break;
00754 default:
00755 DBGPRINTF("Vector, matrix or other non-scalar input (rhs arg %d name %s )\n", irhs-2, argp->name);
00756 break;
00757 }
00758 irhs++;
00759
00760 } else if (argp->inout==GS_OUT) {
00761
00762 switch (argp->objecttype) {
00763 case GS_SCALAR:
00764 DBGPRINTF("Scalar output (name %s)\n", argp->name);
00765 argp->data = &(argp->scalar_val);
00766 break;
00767 default:
00768 DBGPRINTF("Non scalar output (arg %d name %s )\n", irhs-2, argp->name);
00769 break;
00770 }
00771
00772 } else if (argp->inout==GS_VAROUT) {
00773
00774 switch (argp->objecttype) {
00775 case GS_SCALAR:
00776 ERRPRINTF("GridSolve scalars arguments cannot be marked as VAROUT in the interface (matlab input arg %d)\n", irhs-2);
00777 goto error;
00778 break;
00779 default:
00780 DBGPRINTF("Non scalar varout (arg %d name %s )\n", irhs-2, argp->name);
00781 break;
00782 }
00783
00784 } else if (argp->inout==GS_WORKSPACE) {
00785
00786 argp->data = NULL;
00787
00788 } else {
00789 ERRPRINTF("GridSolve interface in/out type is unknown (not IN, OUT, INOUT, or VAROUT or WORKSPACE) (matlab input argument %d) \n", irhs-2);
00790 goto error;
00791 }
00792 }
00793 return 0;
00794
00795 error:
00796 ERRPRINTF("GridSolve: Scalar argument conversion problem: Matlab arg num %d (type %s size %d) could not be converted to GridSolve arg (name %s type %s)\n", irhs-2, mxGetClassName(prhs[irhs]), mxGetNumberOfElements(prhs[irhs]),argp->name, gs_c_datatype[argp->datatype]);
00797 return -1;
00798 }
00799
00800
00818 int
00819 matlab_gs_setup_args(gs_problem_t* problem, int nlhs, mxArray *plhs[],
00820 int nrhs, const mxArray *prhs[])
00821 {
00822 gs_argument_t* argp = NULL;
00823 double *pr = NULL;
00824 double *pi = NULL;
00825 mxChar *mxcharp = NULL;
00826 int nelements;
00827 int i,j,m,n,irhs=0;
00828 char buffer[256];
00829 FILE *fp;
00830 char *tmpname;
00831 char **filenames = NULL;
00832 gs_argument_t* arg_indices = NULL;
00833 gs_argument_t* arg_pointer = NULL;
00834 int *ir = NULL;
00835 int *jc = NULL;
00836 int nnz;
00837
00838 if (problem==NULL) goto error_unknown;
00839
00840
00841
00842
00843 if (matlab_gs_setup_scalar_arguments(problem, nlhs, plhs, nrhs, prhs) < 0) goto error_scalar;
00844
00845
00846 if (gs_receiver_compute_arg_sizes(problem, GS_IN) < 0) {
00847 ERRPRINTF("GridSolve: Could not compute argument sizes");
00848 return -1;
00849 }
00850
00851
00852 DBGPRINTF("For each argument, check datatype, attach data for non-scalar args\n");
00853 for (argp=problem->arglist,irhs=2; argp!=NULL && irhs<=nrhs; argp=argp->next) {
00854
00855
00856
00857
00858
00859 if (matlab_gs_arg_is_sparse_index_or_pointer(argp, problem)) {
00860 DBGPRINTF("Skipping sparse attribute: %s \n", argp->name);
00861 continue;
00862 }
00863
00864
00865 if (argp->inout==GS_IN || argp->inout==GS_INOUT) {
00866
00867
00868 m = mxGetM(prhs[irhs]);
00869 n = mxGetN(prhs[irhs]);
00870 pr = mxGetPr(prhs[irhs]);
00871 pi = mxGetPi(prhs[irhs]);
00872
00873
00874 switch (argp->objecttype) {
00875
00876 case GS_SCALAR:
00877
00878 break;
00879
00880 case GS_SPARSEMATRIX:
00881 DBGPRINTF("Transfer mx (rhs %d) to gs (%s [%d,%d] %s %s %s) \n", irhs-2, argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype]); fflush(0);
00882 nnz = mxGetNzmax(prhs[irhs]);
00883
00884 arg_indices = gs_arg_lookup_by_name(argp->sparse_attr.indices, problem->arglist);
00885 arg_pointer = gs_arg_lookup_by_name(argp->sparse_attr.pointer, problem->arglist);
00886 if (arg_indices==NULL || arg_pointer==NULL) return -1;
00887
00888 if ((arg_indices->data = matlab_gs_calloc(nnz, sizeof(int))) == NULL) return -1;
00889 if ((arg_pointer->data = matlab_gs_calloc(n+1, sizeof(int))) == NULL) return -1;
00890 if ((argp->data = matlab_gs_calloc(nnz, gs_datatype_sizeof(argp->datatype))) == NULL) return -1;
00891
00892 ir = mxGetIr(prhs[irhs]);
00893 jc = mxGetJc(prhs[irhs]);
00894 if (matlab_gs_sparse_matcsc_to_csr(m, n, nnz, mxGetClassID(prhs[irhs]), pr, pi, ir, jc, argp->datatype, argp->data, arg_indices->data, arg_pointer->data) == -1) goto error_input;
00895 break;
00896
00897 case GS_MATRIX:
00898 case GS_VECTOR:
00899 DBGPRINTF("Transfer mx (rhs %d) to gs (%s [%d,%d] %s %s %s) \n", irhs-2, argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype]); fflush(0);
00900 nelements = argp->rows*argp->cols;
00901
00902 if (arg_data_same_as_mx_dat(prhs[irhs], argp)) {
00903
00904
00905 argp->data = pr;
00906 } else {
00907
00908 switch (argp->datatype) {
00909 case GS_DOUBLE:
00910 if (transfer_mx_to_gs_double(mxGetClassID(prhs[irhs]), pr, 0, &argp->data, 0, nelements, MAYBE_ALLOC) < 0) goto error_input;
00911 break;
00912 case GS_INT:
00913 if (transfer_mx_to_gs_int(mxGetClassID(prhs[irhs]), pr, 0, &argp->data, 0, nelements, MAYBE_ALLOC) < 0) goto error_input;
00914 break;
00915 case GS_FLOAT:
00916 if (transfer_mx_to_gs_float(mxGetClassID(prhs[irhs]), pr, 0, &argp->data, 0, nelements, MAYBE_ALLOC) < 0) goto error_input;
00917 break;
00918 case GS_SCOMPLEX:
00919 if (transfer_mx_to_gs_scomplex(mxGetClassID(prhs[irhs]), pr, pi, 0, &argp->data, 0, nelements, MAYBE_ALLOC) < 0) goto error_input;
00920 break;
00921 case GS_DCOMPLEX:
00922 if (transfer_mx_to_gs_dcomplex(mxGetClassID(prhs[irhs]), pr, pi, 0, &argp->data, 0, nelements, MAYBE_ALLOC) < 0) goto error_input;
00923 break;
00924 case GS_CHAR:
00925 if ((argp->data = (void*)matlab_gs_calloc(nelements, gs_datatype_sizeof(argp->datatype)))==NULL) goto error_input;
00926 for (j=0; j<nelements; j++) ((char*)argp->data)[j] = (char)((mxChar*)mxGetData(prhs[irhs]))[j];
00927 break;
00928 default:
00929 DBGPRINTF("Datatype not handled\n");
00930 break;
00931 }
00932 }
00933 break;
00934
00935 case GS_FILE:
00936 DBGPRINTF("Transfer mx (rhs %d) to gs (%s [%d,%d] %s %s %s) \n", irhs-2, argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype]); fflush(0);
00937 if (!mxIsChar(prhs[irhs])) {
00938 ERRPRINTF("Arg %s is of class %s but should be a string\n", argp->name, mxGetClassName(prhs[irhs]));
00939 goto error_input;
00940 }
00941 if ((argp->data = (char *)matlab_gs_calloc(m*n+1, sizeof(char))) == NULL) return -1;
00942 mxGetString(prhs[irhs], argp->data, n*m+1);
00943 break;
00944
00945 case GS_PACKEDFILE:
00946 DBGPRINTF("Transfer mx (rhs %d) to gs (%s [%d,%d] %s %s %s) \n", irhs-2, argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype]); fflush(0);
00947 if (!mxIsChar(prhs[irhs])) {
00948 ERRPRINTF("Arg %s is of class %s but should be a matrix of strings\n", argp->name, mxGetClassName(prhs[irhs]));
00949 goto error_input;
00950 }
00951 mxcharp = (mxChar*)mxGetPr(prhs[irhs]);
00952 if ((filenames = (char **)matlab_gs_calloc(m, sizeof(char*))) == NULL) return -1;
00953 for (i=0; i<m; i++) {
00954 if ((filenames[i] = (char *)matlab_gs_calloc(n+1, sizeof(char))) == NULL) return -1;
00955
00956 for (j=0; j<n; j++) filenames[i][j] = (char)((char)mxcharp[i+j*m]);
00957
00958 filenames[i][n] = ' ';
00959
00960 for (j=n; j>0; j++)
00961 if (filenames[i][j] == ' ')
00962 filenames[i][j] = '\0';
00963 else break;
00964 DBGPRINTF("Packed input/inout file %d **%s** \n", i, filenames[i]);
00965 }
00966 argp->data = filenames;
00967 break;
00968
00969 default:
00970 ERRPRINTF("Unknown objectype\n");
00971 goto error_input;
00972 break;
00973
00974 }
00975
00976
00977 irhs++;
00978
00979
00980
00981
00982 } else if (argp->inout==GS_WORKSPACE) {
00983
00984
00985
00986 argp->data = NULL;
00987
00988
00989 } else if (argp->inout==GS_OUT) {
00990
00991
00992 DBGPRINTF("Handling GS_OUT: %s %s %s %s \n", argp->name, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype]); fflush(0);
00993
00994
00995 switch (argp->objecttype) {
00996
00997 case GS_SCALAR:
00998 break;
00999
01000 case GS_SPARSEMATRIX:
01001 DBGPRINTF("Attaching output sparse attributes \n");
01002
01003 arg_indices = gs_arg_lookup_by_name(argp->sparse_attr.indices, problem->arglist);
01004 arg_pointer = gs_arg_lookup_by_name(argp->sparse_attr.pointer, problem->arglist);
01005 if (arg_indices==NULL || arg_pointer==NULL) goto error_output;
01006
01007 if ((arg_indices->data = matlab_gs_calloc(argp->sparse_attr.nnz, sizeof(int))) == NULL) goto error_memory;
01008 if ((arg_pointer->data = matlab_gs_calloc(argp->sparse_attr.cols_val_saved+1, sizeof(int))) == NULL) goto error_memory;
01009 if ((argp->data = matlab_gs_calloc(argp->sparse_attr.nnz, gs_datatype_sizeof(argp->datatype))) == NULL) goto error_memory;
01010 break;
01011
01012 case GS_VECTOR:
01013 case GS_MATRIX:
01014
01015 nelements = argp->rows*argp->cols;
01016 if ((argp->data = (double*)matlab_gs_calloc(nelements, gs_datatype_sizeof(argp->datatype)))==NULL) goto error_memory;
01017 break;
01018
01019 case GS_FILE:
01020
01021
01022
01023 snprintf(buffer, 256, "./%s_%s_XXXXXX", problem->name, argp->name);
01024 tmpname = mktemp(buffer);
01025 if (tmpname == NULL) { ERRPRINTF("Could not make tmp file\n"); goto error_output; }
01026 fp = fopen(tmpname, "w");
01027 if (fp == NULL) { ERRPRINTF("Could not make tmp file\n"); goto error_output; }
01028 fclose(fp);
01029 argp->data = strdup(buffer);
01030 if (argp->data==NULL) goto error_memory;
01031 DBGPRINTF("output file name %s\n", (char*)argp->data);
01032 break;
01033
01034 case GS_PACKEDFILE:
01035
01036
01037
01038 nelements = argp->rows*argp->cols;
01039 filenames = (char **)matlab_gs_calloc(MAX_FILES_IN_PACKEDFILE, sizeof(char*));
01040
01041 if (filenames==NULL) goto error_memory;
01042 for (i=0; i<nelements; i++) {
01043 snprintf(buffer, 256, "./%s_%s_%d_XXXXXX", problem->name, argp->name, i+1);
01044 tmpname = mktemp(buffer);
01045 if (tmpname == NULL) { ERRPRINTF("Could not make tmp file\n"); goto error_output; }
01046 fp = fopen(tmpname, "w");
01047 if (fp == NULL) { ERRPRINTF("Could not make tmp file\n"); goto error_output; }
01048 fclose(fp);
01049 filenames[i] = strdup(buffer);
01050 if (filenames[i]==NULL) goto error_memory;
01051 DBGPRINTF("packed output filename %d %s\n", i, filenames[i]);
01052 }
01053 argp->data = filenames;
01054 break;
01055
01056 default:
01057 DBGPRINTF("Object type not handled %d\n", argp->objecttype);
01058 break;
01059 }
01060
01061
01062
01063 } else if (argp->inout==GS_VAROUT) {
01064
01065
01066 switch (argp->objecttype) {
01067 case GS_SPARSEMATRIX:
01068 ERRPRINTF("VAROUT SPARSEMATIX is not supported \n");
01069 return -1;
01070 break;
01071 default:
01072
01073 argp->data = (char **)matlab_gs_calloc(1,sizeof(char*));
01074 if (!argp->data) goto error_memory;
01075 break;
01076 }
01077
01078
01079 } else {
01080
01081
01082 ERRPRINTF("Unknown inout mode\n");
01083 return -1;
01084 }
01085
01086 }
01087 DBGPRINTF("Done\n");
01088 return 0;
01089
01090
01091 error_scalar:
01092 ERRPRINTF("GridSolve: Could not transfer scalar arguments");
01093 return -1;
01094
01095 error_input:
01096 ERRPRINTF("GridSolve: Data conversion problem between matlab input data (arg %d type %s) and GridSolve (arg %s type %s)", irhs-2, mxGetClassName(prhs[irhs]), argp->name, gs_c_datatype[argp->datatype]);
01097 return -1;
01098
01099 error_output:
01100 ERRPRINTF("GridSolve: Data preparation problem for GridSolve output (arg %s type %s)", argp->name, gs_c_datatype[argp->datatype]);
01101 return -1;
01102
01103 error_memory:
01104 ERRPRINTF("GridSolve: Memory allocation problem for GridSolve argument (arg %s type %s)", argp->name, gs_c_datatype[argp->datatype]);
01105 return -1;
01106
01107 error_unknown:
01108 ERRPRINTF("GridSolve: Unknown error occured");
01109 return -1;
01110
01111 }
01112
01113
01126 int
01127 matlab_gs_get_output(gs_problem_t* problem, int nlhs, mxArray *plhs[],
01128 int nrhs, const mxArray *prhs[])
01129 {
01130 gs_argument_t *argp = NULL;
01131 gs_argument_t *arg_pointer = NULL;
01132 gs_argument_t *arg_indices = NULL;
01133 gs_argument_t *row_arg, *col_arg;
01134 int M, N, ilhs;
01135
01136 DBGPRINTF("Transferring output arguments to matlab\n");
01137 for (argp=problem->arglist,ilhs=0; argp!=NULL && ilhs<nlhs; argp=argp->next) {
01138
01139 if (argp->inout==GS_OUT || argp->inout==GS_INOUT || argp->inout==GS_VAROUT) {
01140
01141
01142
01143
01144 if (matlab_gs_arg_is_sparse_index_or_pointer(argp, problem)) {
01145 DBGPRINTF("Skipping sparse attribute: %s \n", argp->name);
01146 continue;
01147 }
01148
01149 switch (argp->objecttype) {
01150
01151 case GS_FILE:
01152 DBGPRINTF("Transfer GS_FILE %s using filename %s\n", argp->name, (char *)argp->data);
01153 plhs[ilhs] = mxCreateString((char*)argp->data);
01154 break;
01155
01156 case GS_PACKEDFILE:
01157 DBGPRINTF("Transfer GS_PACKEDFILE\n");
01158 plhs[ilhs] = mxCreateCharMatrixFromStrings(argp->rows, (const char**)argp->data);
01159 break;
01160
01161 case GS_SPARSEMATRIX:
01162 DBGPRINTF("Transfer gs (%s [%d,%d] %s %s %s) to mx (ilhs %d) \n", argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype], ilhs); fflush(0);
01163 if (argp->inout==GS_VAROUT) { ERRPRINTF("VAROUT SPARSEMATRIX not supported\n"); goto error_output; }
01164
01165 arg_indices = gs_arg_lookup_by_name(argp->sparse_attr.indices, problem->arglist);
01166 arg_pointer = gs_arg_lookup_by_name(argp->sparse_attr.pointer, problem->arglist);
01167 M = argp->sparse_attr.rows_val_saved;
01168 N = argp->sparse_attr.cols_val_saved;
01169
01170 if ((plhs[ilhs] = matlab_gs_create_matrix(argp->objecttype, M, N, argp->sparse_attr.nnz, argp->datatype)) == NULL) goto error_output;
01171 if (matlab_gs_sparse_csr_to_matcsc(M, N, argp->sparse_attr.nnz, argp->datatype, argp->data, arg_indices->data, arg_pointer->data, mxGetPr(plhs[ilhs]), mxGetPi(plhs[ilhs]), mxGetIr(plhs[ilhs]), mxGetJc(plhs[ilhs])) == -1) goto error_output;
01172 break;
01173
01174 case GS_SCALAR:
01175 DBGPRINTF("Transfer gs (%s [%d,%d] %s %s %s) to mx (ilhs %d) \n", argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype], ilhs); fflush(0);
01176 plhs[ilhs] = transfer_gs_to_mx(argp);
01177 if (plhs[ilhs] == NULL) return -1;
01178 break;
01179
01180 case GS_VECTOR:
01181 case GS_MATRIX:
01182 DBGPRINTF("Transfer gs (%s [%d,%d] %s %s %s) to mx (ilhs %d) \n", argp->name, argp->rows, argp->cols, gs_inout[argp->inout], gs_objecttype[argp->objecttype], gs_c_datatype[argp->datatype], ilhs); fflush(0);
01183 if (argp->inout==GS_VAROUT) {
01184
01185
01186 argp->rows = 1;
01187 argp->cols = 1;
01188 row_arg = gs_arg_lookup_by_name(argp->rowexp, problem->arglist);
01189 if (row_arg==NULL || row_arg->inout!=GS_OUT || row_arg->datatype!=GS_INT
01190 || row_arg->objecttype!=GS_SCALAR) goto error_output;
01191 argp->rows = row_arg->scalar_val.int_val;
01192 col_arg = gs_arg_lookup_by_name(argp->colexp, problem->arglist);
01193 if (col_arg==NULL)
01194 argp->cols = 1;
01195 else {
01196 if ( col_arg->inout!=GS_OUT || col_arg->datatype!=GS_INT
01197 || col_arg->objecttype!=GS_SCALAR) goto error_output;
01198 argp->cols = col_arg->scalar_val.int_val;
01199 }
01200 }
01201 plhs[ilhs] = transfer_gs_to_mx(argp);
01202 if (plhs[ilhs] == NULL) return -1;
01203 break;
01204
01205 default:
01206 DBGPRINTF("Unknown object type name %s type %d\n", argp->name, argp->objecttype);
01207 goto error_output;
01208 break;
01209 }
01210
01211
01212 ilhs++;
01213
01214 }
01215 }
01216
01217 return 0;
01218
01219 error_output:
01220 ERRPRINTF("GridSolve: Could not transfer output to Matlab (output arg %d) for GridSolve output (arg %s type %s)", ilhs, argp->name, gs_c_datatype[argp->datatype]);
01221 return -1;
01222
01223 }
01224
01225
01238 int
01239 matlab_gs_free_input_args(gs_problem_t* problem, int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
01240 {
01241 int irhs, i;
01242 gs_argument_t* argp = NULL;
01243 if (problem==NULL) return 0;
01244
01245 DBGPRINTF("Freeing input args\n");
01246
01247 for (argp=problem->arglist,irhs=2; argp!=NULL && irhs<=nrhs; argp=argp->next) {
01248 if (argp->inout==GS_IN) {
01249 switch(argp->objecttype) {
01250 case GS_SCALAR:
01251 break;
01252 case GS_VECTOR:
01253 case GS_MATRIX:
01254 if (arg_data_same_as_mx_dat(prhs[irhs], argp))
01255 argp->data = NULL;
01256 else
01257 argp->data = matlab_gs_free(argp->data);
01258 break;
01259 case GS_SPARSEMATRIX:
01260 argp->data = matlab_gs_free(argp->data);
01261 break;
01262 case GS_FILE:
01263 argp->data = matlab_gs_free(argp->data);
01264 break;
01265 case GS_PACKEDFILE:
01266 for (i=0; i<argp->rows*argp->cols; i++)
01267 matlab_gs_free(((char **)argp->data)[i]);
01268 argp->data = matlab_gs_free(argp->data);
01269 break;
01270 default:
01271 break;
01272 }
01273
01274
01275
01276 if (!matlab_gs_arg_is_sparse_index_or_pointer(argp, problem))
01277 irhs++;
01278 }
01279 }
01280
01281 DBGPRINTF("Finished\n");
01282 return 0;
01283
01284 }
01285
01286
01298 int
01299 matlab_gs_free_args(gs_problem_t* problem, int nlhs, mxArray *plhs[],
01300 int nrhs, const mxArray *prhs[])
01301 {
01302 int ilhs = 0;
01303 int i;
01304 gs_argument_t* argp = NULL;
01305
01306 if (problem==NULL) return 0;
01307
01308 DBGPRINTF("Freeing all output args\n");
01309
01310 for (argp=problem->arglist,ilhs=0; argp!=NULL && ilhs<nlhs; argp=argp->next) {
01311 if (argp->inout==GS_INOUT || argp->inout==GS_OUT || argp->inout==GS_VAROUT ) {
01312 switch(argp->objecttype) {
01313 case GS_SCALAR:
01314 break;
01315 case GS_VECTOR:
01316 case GS_MATRIX:
01317 argp->data = matlab_gs_free(argp->data);
01318 break;
01319 case GS_SPARSEMATRIX:
01320 argp->data = matlab_gs_free(argp->data);
01321 break;
01322 case GS_FILE:
01323 argp->data = matlab_gs_free(argp->data);
01324 break;
01325 case GS_PACKEDFILE:
01326 for (i=0; i<argp->rows*argp->cols; i++)
01327 matlab_gs_free(((char **)argp->data)[i]);
01328 argp->data = matlab_gs_free(argp->data);
01329 break;
01330 default:
01331 break;
01332
01333 }
01334 }
01335 }
01336
01337 DBGPRINTF("Finished\n");
01338 return 0;
01339
01340 }
01341