~ubuntu-branches/ubuntu/utopic/adios/utopic

« back to all changes in this revision

Viewing changes to wrappers/matlab/adiosopenc.c

  • Committer: Package Import Robot
  • Author(s): Alastair McKinstry
  • Date: 2013-12-09 15:21:31 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20131209152131-jtd4fpmdv3xnunnm
Tags: 1.5.0-1
* New upstream.
* Standards-Version: 3.9.5
* Include latest config.{sub,guess} 
* New watch file.
* Create libadios-bin for binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * ADIOS is freely available under the terms of the BSD license described
 
3
 * in the COPYING file in the top level directory of this source distribution.
 
4
 *
 
5
 * Copyright (c) 2008 - 2009.  UT-BATTELLE, LLC. All rights reserved.
 
6
 */
 
7
 
 
8
/*=================================================================
 
9
 * adiosopenc.c - Open an ADIOS file
 
10
 *
 
11
 * Input: File, Verbose
 
12
 *    File:     string (name) or int64 (handler)
 
13
 *    Verbose:  numeric (double)
 
14
 *
 
15
 * Output: Information structure
 
16
 *     Name        file path
 
17
 *     FileHandler int64 file handler
 
18
 *     TimeStart   First timestep in file (usually = 1)
 
19
 *     TimeSteps   Number of timesteps in file, always at least 1
 
20
 *     Groups      Adios groups in the file. Usually 1 group is in a file.
 
21
 *                 This is a structure array of 
 
22
 *
 
23
 *        Name          group name
 
24
 *        GroupHandler  int64 group handler
 
25
 *        Variables     structure array of variables
 
26
 *           Name          path of variable
 
27
 *           Type          Matlab type class of data
 
28
 *           Dims          Array of dimensions
 
29
 *           Timedim       The time dimension, 0 if there is no time varying 
 
30
 *                         part of the variable
 
31
 *           GlobalMin     global minimum  of the variable (1-by-1 mxArray)
 
32
 *           GlobalMax     global maximum of the variable
 
33
 *           
 
34
 *        Attributes  structure array of attributes
 
35
 *           Name          path of attribute
 
36
 *           Type          Matlab type class of data
 
37
 *           Value         attribute value (mxArray)
 
38
 *
 
39
 *
 
40
 *
 
41
 * $Revision: 1.0 $  $Date: 2009/08/05 12:53:41 $
 
42
 * Author: Norbert Podhorszki <pnorbert@ornl.gov>
 
43
 *=================================================================*/
 
44
 
 
45
#include <string.h>              /* memcpy */
 
46
#include "mex.h"
 
47
#include "adios_types.h"
 
48
#include "adios_read.h"
 
49
#include "adios_types.h"
 
50
 
 
51
static int verbose=0;
 
52
 
 
53
mxClassID adiostypeToMatlabClass(int type, mxComplexity *complexity );
 
54
mxArray* valueToMatlabValue( void * data, mxClassID mxtype, mxComplexity complexFlag);
 
55
void errorCheck(int nlhs, int nrhs, const mxArray *prhs[]);
 
56
char* getString(const mxArray *mxstr);
 
57
static void swap_order(int n, uint64_t *array);
 
58
 
 
59
 
 
60
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
 
61
    char *fname;                                 /* file name */
 
62
    int status;
 
63
    char msg[512];                               /* error messages from function calls */
 
64
    int32_t *int32p;
 
65
 
 
66
    ADIOS_FILE *fp;                             /* File handler structure */
 
67
    ADIOS_GROUP *gp;                            /* Group handler structure */
 
68
    ADIOS_VARINFO *vinfo;                       /* Variable info structure */
 
69
    int mpi_comm_dummy;                         /* ADIOS read API needs an MPI communicator */
 
70
    int32_t timedim;                            /* time dimension is translated C 0.. -> Matlab 1.. */
 
71
    int asize;                                  /* Attribute size info */
 
72
    enum ADIOS_DATATYPES adiostype;             /* Attribute type info */
 
73
    void *data;                                 /* Attributes return their values */
 
74
    mwSize mDims[] = {1};                       /* dimensions to create a scalar mxArray */  
 
75
 
 
76
    int gi,vi,ai, i;                            /* loop variables for groups, vars and attrs */
 
77
    mxArray *arr;                               /* temp array for constructions */
 
78
    mxArray *groups, *vars, *attrs;             /* struct arrays under top struct */
 
79
    mxClassID mxtype;                           /* matlab type (of vars and attrs) */
 
80
    mxComplexity complexFlag; 
 
81
 
 
82
    /* Output structure definition */
 
83
    const char *top_field_names[] = {"Name", "FileHandler", "TimeStart", "TimeSteps", "Groups"}; /* top level struct fields */
 
84
    mwSize ntopfields = 5;
 
85
    mwSize top_struct_dims[] = {1,1};   /* dimensions for top level struct array: 1-by-1 */
 
86
    int top_field_Name;
 
87
    int top_field_FileHandler;
 
88
    int top_field_TimeStart;
 
89
    int top_field_TimeSteps;
 
90
    int top_field_Groups;
 
91
 
 
92
    const char *group_field_names[] = {"Name", "GroupHandler", "Variables", "Attributes"}; /* group level struct fields */
 
93
    mwSize ngroupfields = 4;
 
94
    mwSize group_struct_dims[2];        /* dimensions for group level struct array: 1-by-sth */
 
95
    int group_field_Name;
 
96
    int group_field_GroupHandler;
 
97
    int group_field_Variables;
 
98
    int group_field_Attributes;
 
99
 
 
100
    const char *var_field_names[] = {"Name","Type","Dims", "Timedim", "GlobalMin", "GlobalMax"}; /* variable level struct fields */
 
101
    mwSize nvarfields = 6;
 
102
    mwSize var_struct_dims[2];        /* dimensions for variable level struct array: 1-by-sth */
 
103
    int var_field_Name;
 
104
    int var_field_Type;
 
105
    int var_field_Dims;
 
106
    int var_field_Timedim;
 
107
    int var_field_GlobalMin;
 
108
    int var_field_GlobalMax;
 
109
 
 
110
    const char *attr_field_names[] = {"Name","Type","Value"}; /* attribute level struct fields */
 
111
    mwSize nattrfields = 3;
 
112
    mwSize attr_struct_dims[2];        /* dimensions for attribute level struct array: 1-by-sth */
 
113
    int attr_field_Name;
 
114
    int attr_field_Type;
 
115
    int attr_field_Value;
 
116
 
 
117
    errorCheck(nlhs, nrhs, prhs);
 
118
 
 
119
    /*mexPrintf("nrhs=%d  nlhs=%d\n", nrhs, nlhs);*/
 
120
    
 
121
    /***********************/
 
122
    /* 0. get verbose parameter first */
 
123
    verbose = (int)mxGetScalar(prhs[1]);
 
124
    if (verbose) mexPrintf("Verbosity level: %d\n", verbose);
 
125
 
 
126
    /* 1. get file handler */
 
127
    if (mxIsChar(prhs[0])) {
 
128
        fname = getString( (mxArray *)prhs[0]);
 
129
        if (verbose) mexPrintf("File name: \"%s\"\n", fname);
 
130
    } 
 
131
 
 
132
    /**************************************/
 
133
    /* Open ADIOS file now and get groups */
 
134
    fp = adios_fopen (fname, mpi_comm_dummy);
 
135
    if (fp == NULL) {
 
136
       mexErrMsgIdAndTxt("MATLAB:adiosopenc:open",adios_errmsg());
 
137
    }
 
138
    if (verbose) mexPrintf("Number of adios groups: %d, fp=%lld\n", fp->groups_count, (int64_t) fp);
 
139
 
 
140
    /******************************/
 
141
    /* Create top level structure */
 
142
    if (verbose) mexPrintf("Create top struct array, 1-by-1\n");
 
143
    plhs[0] = mxCreateStructArray(2, top_struct_dims, ntopfields, top_field_names);
 
144
    top_field_Name = mxGetFieldNumber(plhs[0],"Name");
 
145
    top_field_FileHandler = mxGetFieldNumber(plhs[0],"FileHandler");
 
146
    top_field_TimeStart = mxGetFieldNumber(plhs[0],"TimeStart");
 
147
    top_field_TimeSteps = mxGetFieldNumber(plhs[0],"TimeSteps");
 
148
    top_field_Groups = mxGetFieldNumber(plhs[0],"Groups");
 
149
    mxSetFieldByNumber(plhs[0],0,top_field_Name,mxCreateString(fname));
 
150
    arr = valueToMatlabValue(&fp, mxINT64_CLASS, mxREAL);
 
151
    mxSetFieldByNumber(plhs[0],0,top_field_FileHandler,arr);
 
152
    arr = mxCreateNumericMatrix( 1, 1, mxINT32_CLASS, mxREAL);
 
153
    *(int32_t *)mxGetData(arr) = fp->tidx_start;
 
154
    mxSetFieldByNumber(plhs[0],0,top_field_TimeStart,arr);
 
155
    arr = mxCreateNumericMatrix( 1, 1, mxINT32_CLASS, mxREAL);
 
156
    *(int32_t *)mxGetData(arr) = fp->ntimesteps;
 
157
    mxSetFieldByNumber(plhs[0],0,top_field_TimeSteps,arr);
 
158
    /* Create top.Groups structure array */
 
159
    if (verbose) mexPrintf("Create top.Groups struct array, 1-by-%d\n",fp->groups_count);
 
160
    group_struct_dims[0] = 1;
 
161
    group_struct_dims[1] = fp->groups_count;
 
162
    groups = mxCreateStructArray(2, group_struct_dims, ngroupfields, group_field_names);
 
163
    mxSetFieldByNumber(plhs[0],0,top_field_Groups,groups);
 
164
 
 
165
 
 
166
    /****************************/
 
167
    /* Fill in Groups structure */
 
168
    group_field_Name = mxGetFieldNumber(groups,"Name");
 
169
    group_field_GroupHandler = mxGetFieldNumber(groups,"GroupHandler");
 
170
    group_field_Variables = mxGetFieldNumber(groups,"Variables");
 
171
    group_field_Attributes = mxGetFieldNumber(groups,"Attributes");
 
172
 
 
173
    for (gi = 0; gi < fp->groups_count; gi++) {
 
174
        /* Get info of one group: handler, list of vars, list of attrs */
 
175
        if (verbose) mexPrintf("Group %s: get info\n", fp->group_namelist[gi]);
 
176
        gp = adios_gopen_byid(fp, gi);
 
177
        if (gp == NULL) {
 
178
           mexErrMsgIdAndTxt("MATLAB:adiosopenc:groupinfo",adios_errmsg());
 
179
        }
 
180
        if (verbose) mexPrintf("    %d variables and %d attributes\n", gp->vars_count, gp->attrs_count);
 
181
        /* Group fields for gi-th group */
 
182
        mxSetFieldByNumber(groups,gi,group_field_Name,mxCreateString(fp->group_namelist[gi]));
 
183
        mexPrintf("Group gp=%lld id=%d vcnt=%d\n", (int64_t)gp, gp->grpid, gp->vars_count);
 
184
        arr = valueToMatlabValue(&gp, mxINT64_CLASS, mxREAL);
 
185
        mxSetFieldByNumber(groups,gi,group_field_GroupHandler,arr);
 
186
        /* Create top.Groups.Variables structure array */
 
187
        var_struct_dims[0] = 1;
 
188
        var_struct_dims[1] = gp->vars_count;
 
189
        vars = mxCreateStructArray(2, var_struct_dims, nvarfields, var_field_names);
 
190
        mxSetFieldByNumber(groups,gi,group_field_Variables,vars);
 
191
        var_field_Name = mxGetFieldNumber(vars,"Name");
 
192
        var_field_Type = mxGetFieldNumber(vars,"Type");
 
193
        var_field_Dims = mxGetFieldNumber(vars,"Dims");
 
194
        var_field_Timedim = mxGetFieldNumber(vars,"Timedim");
 
195
        var_field_GlobalMin = mxGetFieldNumber(vars,"GlobalMin");
 
196
        var_field_GlobalMax = mxGetFieldNumber(vars,"GlobalMax");
 
197
        /* Create top.Groups.Attributes structure array */
 
198
        attr_struct_dims[0] = 1;
 
199
        attr_struct_dims[1] = gp->attrs_count;
 
200
        attrs = mxCreateStructArray(2, attr_struct_dims, nattrfields, attr_field_names);
 
201
        mxSetFieldByNumber(groups,gi,group_field_Attributes,attrs);
 
202
        attr_field_Name = mxGetFieldNumber(attrs,"Name");
 
203
        attr_field_Type = mxGetFieldNumber(attrs,"Type");
 
204
        attr_field_Value = mxGetFieldNumber(attrs,"Value");
 
205
 
 
206
        /******************************/
 
207
        /* Add variables to the group */
 
208
 
 
209
        if (verbose>1) mexPrintf("    Variables\n");
 
210
        for (vi=0; vi < gp->vars_count; vi++) {
 
211
            vinfo = adios_inq_var_byid( gp, vi);
 
212
            if (vinfo == NULL) {
 
213
               mexErrMsgIdAndTxt("MATLAB:adiosopenc:varinfo",adios_errmsg());
 
214
            }
 
215
            /* Flip dimensions from ADIOS-read-api/C/row-major order to Matlab/Fortran/column-major order */
 
216
            swap_order(vinfo->ndim, vinfo->dims);
 
217
 
 
218
            if (verbose>1) {
 
219
                mexPrintf("      %s: ndims=%d, adios type=%s, timedim=%d dimensions [", 
 
220
                gp->var_namelist[vi], vinfo->ndim, adios_type_to_string(vinfo->type), vinfo->timedim);
 
221
                for (i=0; i<vinfo->ndim; i++)
 
222
                    mexPrintf("%lld ", vinfo->dims[i]);
 
223
                mexPrintf("]\n");
 
224
            }
 
225
            /* field NAME */
 
226
            mxSetFieldByNumber(vars,vi,var_field_Name,mxCreateString(gp->var_namelist[vi]));
 
227
            /* field TYPE */
 
228
            mxtype = adiostypeToMatlabClass(vinfo->type, &complexFlag);
 
229
            arr = mxCreateNumericMatrix( 1, 1, mxtype, complexFlag);
 
230
            mxSetFieldByNumber(vars,vi,var_field_Type,mxCreateString(mxGetClassName(arr)));
 
231
            mxDestroyArray(arr);
 
232
            /* field DIMS */
 
233
            if (vinfo->ndim > 0) {
 
234
                arr = mxCreateNumericMatrix( 1, vinfo->ndim, mxINT32_CLASS, mxREAL);
 
235
                int32p = (int32_t *)mxGetData(arr);
 
236
                for (i=0; i<vinfo->ndim; i++) 
 
237
                    int32p[i] = (int32_t) vinfo->dims[i];
 
238
            } else {
 
239
                arr = mxCreateNumericMatrix( 0, 0, mxINT32_CLASS, mxREAL);
 
240
            }
 
241
            mxSetFieldByNumber(vars,vi,var_field_Dims,arr);
 
242
 
 
243
            /* field TIMEDIM */
 
244
            /* Timedim is -1,0...ndim-1 in C, 0,1..ndim in Matlab */
 
245
            timedim = vinfo->timedim + 1;
 
246
            arr = valueToMatlabValue((void *)(&timedim), mxINT32_CLASS, mxREAL);
 
247
            mxSetFieldByNumber(vars,vi,var_field_Timedim,arr);
 
248
 
 
249
            /* field GLOBALMIN */
 
250
            arr = valueToMatlabValue(vinfo->gmin, mxtype, complexFlag);
 
251
            mxSetFieldByNumber(vars,vi,var_field_GlobalMin,arr);
 
252
 
 
253
            /* field GLOBALMAX */
 
254
            arr = valueToMatlabValue(vinfo->gmax, mxtype, complexFlag);
 
255
            mxSetFieldByNumber(vars,vi,var_field_GlobalMax,arr);
 
256
 
 
257
            adios_free_varinfo(vinfo);
 
258
        }
 
259
 
 
260
 
 
261
 
 
262
        /******************************/
 
263
        /* Add attributes to the group */
 
264
 
 
265
        if (verbose>1) mexPrintf("    Attributes\n");
 
266
        for (ai=0; ai < gp->attrs_count; ai++) {
 
267
            status = adios_get_attr_byid( gp, ai, &adiostype, &asize, &data);
 
268
            if (status != 0) {
 
269
               mexErrMsgIdAndTxt("MATLAB:adiosopenc:varinfo",adios_errmsg());
 
270
            }
 
271
            if (verbose>1) 
 
272
                mexPrintf("      %s: adios type=%s, size=%d\n", 
 
273
                gp->attr_namelist[ai], adios_type_to_string(adiostype), asize);
 
274
            /* field NAME */
 
275
            mxSetFieldByNumber(attrs,ai,attr_field_Name,mxCreateString(gp->attr_namelist[ai]));
 
276
            /* field TYPE */
 
277
            mxtype = adiostypeToMatlabClass(adiostype, &complexFlag);
 
278
            arr = mxCreateNumericMatrix( 1, 1, mxtype, complexFlag);
 
279
            mxSetFieldByNumber(attrs,ai,attr_field_Type,mxCreateString(mxGetClassName(arr)));
 
280
            mxDestroyArray(arr);
 
281
            /* field VALUE */
 
282
            arr = valueToMatlabValue(data, mxtype, complexFlag);
 
283
            mxSetFieldByNumber(attrs,ai,attr_field_Value,arr);
 
284
 
 
285
            free(data); /* we do not store attribute values yet */
 
286
 
 
287
        }
 
288
 
 
289
        if (verbose>1) mexPrintf("    finished defining group\n");
 
290
    }
 
291
 
 
292
 
 
293
    if (verbose) mexPrintf("return from adiosopenc\n");
 
294
}
 
295
 
 
296
mxArray * valueToMatlabValue( void * data, mxClassID mxtype, mxComplexity complexFlag)
 
297
{
 
298
    /* copies values in all cases, so one can free(data) later */
 
299
    mxArray *arr;
 
300
    if (data == NULL) {
 
301
        arr = mxCreateString("undefined");
 
302
    } else if (mxtype == mxCHAR_CLASS) {
 
303
        arr = mxCreateString((char *)data);
 
304
    } else if (complexFlag == mxCOMPLEX) {
 
305
        arr = mxCreateDoubleMatrix( 1, 1, mxCOMPLEX);
 
306
        if (mxtype == mxSINGLE_CLASS) {
 
307
            *(double *)mxGetPr(arr) = ((float *)data)[0];
 
308
            *(double *)mxGetPi(arr) = ((float *)data)[1];
 
309
        } else {
 
310
            *(double *)mxGetPr(arr) = ((double *)data)[0];
 
311
            *(double *)mxGetPi(arr) = ((double *)data)[1];
 
312
        }
 
313
    } else {
 
314
        arr = mxCreateNumericMatrix( 1, 1, mxtype, mxREAL);
 
315
        memcpy( mxGetData(arr), data, mxGetElementSize(arr));
 
316
    }
 
317
    return arr;
 
318
}
 
319
 
 
320
void errorCheck(int nlhs, int nrhs, const mxArray *prhs[]){
 
321
    /* Assume that we are called from adiosread.m which checks the arguments already */
 
322
    /* Check for proper number of arguments. */
 
323
    
 
324
    if ( nrhs != 2 ) {
 
325
        mexErrMsgIdAndTxt("MATLAB:adiosopenc:rhs","This function needs exactly 2 arguments: File, Verbose");
 
326
    }
 
327
    
 
328
    if ( !mxIsChar(prhs[0]) ) {
 
329
        mexErrMsgIdAndTxt("MATLAB:adiosopenc:rhs","First arg must be a string.");
 
330
    } 
 
331
    
 
332
    if ( !mxIsNumeric(prhs[1]) ) {
 
333
        mexErrMsgIdAndTxt("MATLAB:adiosopenc:rhs","Second arg must be a number.");
 
334
    } 
 
335
    
 
336
    if ( nlhs > 1 ) {
 
337
        mexErrMsgIdAndTxt("MATLAB:adiosopenc:lhs","Too many output arguments.");
 
338
    }
 
339
    
 
340
#if !defined(MX_COMPAT_32)
 
341
    /* Make sure that it is safe to cast dim to mwSize when using largeArrayDims.*/
 
342
    if ( dim > MWSIZE_MAX ) {
 
343
        mexErrMsgIdAndTxt("MATLAB:adiosopenc:dimensionTooLarge",
 
344
                          "The input dimension, %.0f, is larger than the maximum value of mwSize, %u, when built with largeArrayDims.", dim, MWSIZE_MAX);
 
345
    }
 
346
#endif
 
347
 }
 
348
 
 
349
 
 
350
/** Make a C char* string from a Matlab string */
 
351
char* getString(const mxArray *mxstr) 
 
352
{
 
353
    mwSize buflen;
 
354
    char   *str;
 
355
    /* Allocate enough memory to hold the converted string. */
 
356
    buflen = mxGetNumberOfElements(mxstr) + 1;
 
357
    str = mxCalloc(buflen, sizeof(char));
 
358
    /* Copy the string data from string_array_ptr and place it into buf. */
 
359
    if (mxGetString(mxstr, str, buflen) != 0)
 
360
        mexErrMsgTxt("Could not convert string data from the file name.");
 
361
    return str;
 
362
}
 
363
 
 
364
/** return the appropriate class for an adios type (and complexity too) */
 
365
mxClassID adiostypeToMatlabClass(enum ADIOS_DATATYPES type, mxComplexity *complexity ) 
 
366
{
 
367
    *complexity = mxREAL;
 
368
    switch( type ) {
 
369
        case adios_unsigned_byte:
 
370
            return mxUINT8_CLASS;
 
371
        case adios_byte:
 
372
            return mxINT8_CLASS;
 
373
        case adios_string:
 
374
            return mxCHAR_CLASS;
 
375
               
 
376
        case adios_unsigned_short:
 
377
            return mxUINT16_CLASS;
 
378
        case adios_short:
 
379
            return mxINT16_CLASS;
 
380
 
 
381
        case adios_unsigned_integer:
 
382
            return mxUINT32_CLASS;
 
383
        case adios_integer:
 
384
            return mxINT32_CLASS;
 
385
 
 
386
        case adios_unsigned_long:
 
387
            return mxUINT64_CLASS;
 
388
        case adios_long:
 
389
            return mxINT64_CLASS;
 
390
 
 
391
        case adios_real: 
 
392
            return mxSINGLE_CLASS;
 
393
        case adios_double:
 
394
            return mxDOUBLE_CLASS;
 
395
             
 
396
        case adios_complex:     /* 8 bytes */
 
397
            *complexity = mxCOMPLEX;
 
398
            return mxSINGLE_CLASS;
 
399
        case adios_double_complex: /*  16 bytes */
 
400
            *complexity = mxCOMPLEX;
 
401
            return mxDOUBLE_CLASS;
 
402
 
 
403
        case adios_long_double: /* 16 bytes */
 
404
        default:
 
405
            mexErrMsgIdAndTxt("MATLAB:adiosopenc.c:dimensionTooLarge",
 
406
                 "Adios type %d (%s) not supported in visit.\n",
 
407
                 type, adios_type_to_string(type));
 
408
            break;
 
409
    }
 
410
    return 0; /* just to avoid warnings. never executed */
 
411
}
 
412
 
 
413
 
 
414
/* Reverse the order in an array in place.
 
415
   use swapping from Matlab/Fortran/column-major order to ADIOS-read-api/C/row-major order and back
 
416
*/
 
417
static void swap_order(int n, uint64_t *array)
 
418
{
 
419
    int i, tmp;
 
420
    for (i=0; i<n/2; i++) {
 
421
        tmp = array[i];
 
422
        array[i] = array[n-1-i];
 
423
        array[n-1-i] = tmp;
 
424
    }
 
425
}
 
426
 
 
427