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

« back to all changes in this revision

Viewing changes to src/read_dimes.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
 
/**************************************************/
10
 
/* Read method for DIMES memory-to-memory coupling */
11
 
/**************************************************/
12
 
 
13
 
#include <stdlib.h>
14
 
#include <string.h>
15
 
//#include <errno.h>  /* ENOMEM */
16
 
#include "adios.h"
17
 
#include "bp_utils.h"
18
 
#include "bp_types.h"
19
 
#include "adios_types.h"
20
 
#include "adios_read.h"
21
 
#include "adios_read_hooks.h"
22
 
#include "adios_error.h"
23
 
#include "futils.h"
24
 
#include "globals.h"
25
 
 
26
 
#include "dimes.h"
27
 
 
28
 
#ifdef DMALLOC
29
 
#include "dmalloc.h"
30
 
#endif
31
 
 
32
 
#if 1
33
 
#define DBG_PRINTF printf
34
 
#else
35
 
#define DBG_PRINTF(a,...)
36
 
#endif
37
 
 
38
 
#define MAX_DIMES_NAMELEN 128
39
 
 
40
 
/*#define DIMES_DO_VERSIONING define it at configure as -DDIMES_DO_VERSIONING in CFLAGS*/
41
 
static int number_of_fopens = 0;/* for versioning, works only if one file is fopened (in a loop) in the application */
42
 
 
43
 
struct adios_read_DIMES_data_struct{
44
 
        char *fname; //path of file
45
 
        int access_version; //counting the access
46
 
        int disconnect_at_fclose; //disconnect from DIMES in fclose()
47
 
        int mpi_rank; //for debug prints
48
 
};
49
 
 
50
 
static int dimes_sync_id = 0;
51
 
 
52
 
//Declarations
53
 
static int adios_read_dimes_get(const char * varname, enum ADIOS_DATATYPES vartype, 
54
 
                                struct adios_read_DIMES_data_struct * ds, 
55
 
                                int * offset, int * readsize, void * data);     
56
 
                                                                
57
 
/*
58
 
        If init is used, we connect to DIMES index srv here,
59
 
        otherwise we connect in fopen. If multiple fopen/fclose cycles
60
 
        are used, init/finalize must be used too to avoid multiple connect/disconnect in fopen/fclose.
61
 
*/
62
 
int adios_read_dimes_init(MPI_Comm comm)
63
 
{
64
 
    int  nproc, drank, dpeers;
65
 
    int  rank, err;
66
 
    int  appid, was_set;
67
 
    MPI_Comm_rank(comm, &rank);
68
 
    MPI_Comm_size(comm, &nproc);
69
 
        
70
 
    /* Connect to DIMES index srv, but only if we are not yet connected (from Write API) */
71
 
    if(!globals_adios_is_dimes_connected()) {
72
 
        appid = globals_adios_get_application_id(&was_set);
73
 
        if(!was_set)
74
 
                appid = 2;
75
 
        DBG_PRINTF("-- %s, rank %d: connect to dimes with nproc=%d and appid=%d\n",
76
 
                __func__,rank,nproc,appid);
77
 
 
78
 
        //int num_total_peers = 64+16+1;
79
 
        err = dimes_init(nproc,nproc,appid);
80
 
        if(err < 0){
81
 
                adios_error (err_connection_failed, "Failed to connect with DIMES index srv\n");
82
 
                return -err_connection_failed;
83
 
        }
84
 
   }
85
 
   globals_adios_set_dimes_connected_from_reader();
86
 
   return 0;
87
 
}
88
 
 
89
 
int adios_read_dimes_finalize()
90
 
{
91
 
        //disconnect from DIMES index srv only if the reader is connected(the writer not anymore)
92
 
        if(globals_adios_is_dimes_connected_from_reader() &&
93
 
                !globals_adios_is_dimes_connected_from_both() )
94
 
        {
95
 
                dimes_barrier();
96
 
                dimes_finalize();
97
 
                DBG_PRINTF("-- %s: disconnected from dimes index srv\n",__func__);
98
 
        }
99
 
 
100
 
        globals_adios_set_dimes_disconnected_from_reader();
101
 
        return 0;
102
 
}
103
 
 
104
 
ADIOS_FILE *adios_read_dimes_fopen(const char *fname, MPI_Comm comm)
105
 
{
106
 
        ADIOS_FILE * fp;
107
 
        struct adios_read_DIMES_data_struct *ds;
108
 
        int i;
109
 
                
110
 
        adios_errno = 0;
111
 
        
112
 
        ds = (struct adios_read_DIMES_data_struct *)malloc(sizeof(struct adios_read_DIMES_data_struct));
113
 
        if(!ds){
114
 
                adios_error (err_no_memory, "Cannot allocate memory for file info.");
115
 
                return NULL;
116
 
        }
117
 
        
118
 
        /*fill out dimes method specific struct*/
119
 
        ds->fname = strdup(fname);
120
 
#ifdef DIMES_DO_VERSIONING
121
 
        ds->access_version = number_of_fopens;
122
 
#else
123
 
        ds->access_version = 0;
124
 
#endif
125
 
 
126
 
        MPI_Comm_rank(comm, &ds->mpi_rank);
127
 
        
128
 
        /*if not connected to DIMES index srv, connect now*/
129
 
        if(!globals_adios_is_dimes_connected_from_reader()){
130
 
                if(!adios_read_dimes_init(comm))
131
 
                        return NULL;
132
 
                ds->disconnect_at_fclose = 1;
133
 
        } else {
134
 
                ds->disconnect_at_fclose = 0;
135
 
        }
136
 
        
137
 
        /*Try to get variable with fname. If it does not exists, we get an error, which means data
138
 
        does not exist. So we return an error just like with real files*/
139
 
        int offset[] = {0,0,0}, readsize[3] = {1,1,1};
140
 
        int time_index;
141
 
        int err;
142
 
        enum ADIOS_DATATYPES time_index_type = adios_integer;
143
 
        char dimes_fname[MAX_DIMES_NAMELEN];
144
 
        snprintf(dimes_fname, MAX_DIMES_NAMELEN, "FILE@%s",fname);
145
 
        DBG_PRINTF("-- %s, rank %d: Get variable %s\n", __func__, ds->mpi_rank, dimes_fname);
146
 
        
147
 
        err = adios_read_dimes_get(dimes_fname, time_index_type, ds, offset, readsize, &time_index);
148
 
        if (err) {
149
 
                adios_error (err_file_not_found_error, "Data of '%s' does not exist in DIMES\n", dimes_fname);
150
 
                free(ds);
151
 
                return NULL;
152
 
        } else {
153
 
                DBG_PRINTF("-- %s, rank %d: data of '%s' exists, time index = %d\n", __func__, ds->mpi_rank, dimes_fname, time_index);
154
 
        }
155
 
 
156
 
        fp = (ADIOS_FILE *) malloc (sizeof (ADIOS_FILE));
157
 
        if (!fp) {
158
 
                adios_error (err_no_memory, "Cannot allocate memory for file info.");
159
 
                return NULL;
160
 
        }
161
 
 
162
 
        /* fill out ADIOS_FILE struct */
163
 
        fp->fh = (uint64_t) ds;
164
 
        fp->groups_count = 1;
165
 
        fp->vars_count = 0;
166
 
        fp->attrs_count = 0;
167
 
        fp->tidx_start = 0;
168
 
        fp->ntimesteps = 1;
169
 
        fp->file_size = 0;
170
 
        fp->version = 1;
171
 
        fp->endianness = 0; /* FIXME: not always Little Endian. Does it matter? */
172
 
        alloc_namelist (&fp->group_namelist,fp->groups_count); 
173
 
        for (i=0;i<fp->groups_count;i++) {
174
 
                if (!fp->group_namelist[i]) {
175
 
                        adios_error (err_no_memory, "Could not allocate buffer for %d strings in adios_fopen()", fp->groups_count);
176
 
                        adios_read_dimes_fclose(fp);
177
 
                        return NULL;
178
 
                }
179
 
                else  {
180
 
                        strcpy(fp->group_namelist[i],"dimes");
181
 
                }
182
 
        }
183
 
        DBG_PRINTF("-- %s, rank %d: done fp=%x, fp->fh=%x\n", __func__, ds->mpi_rank, fp, fp->fh);
184
 
#ifdef DIMES_DO_VERSIONING
185
 
        number_of_fopens++;
186
 
#endif
187
 
        return fp;      
188
 
}
189
 
 
190
 
int adios_read_dimes_fclose(ADIOS_FILE *fp)
191
 
{
192
 
        struct adios_read_DIMES_data_struct *ds =(struct adios_read_DIMES_data_struct *)fp->fh;
193
 
        int i,j;
194
 
        
195
 
        adios_errno = 0;
196
 
        
197
 
        DBG_PRINTF("-- %s, rank %d: fp=%x\n", __func__, ds->mpi_rank, fp);
198
 
 
199
 
        unsigned int version;   
200
 
#ifdef DIMES_DO_VERSIONING
201
 
        version = number_of_fopens;
202
 
        dimes_sync_id = version;
203
 
#else
204
 
        version = 0;
205
 
        dimes_sync_id++;
206
 
#endif
207
 
        dimes_sync(dimes_sync_id);
208
 
        //dimes_notify(1);      
209
 
 
210
 
        /*Disconnect from DIMES index srv if we connected in fopen()*/
211
 
        if(ds && ds->disconnect_at_fclose){
212
 
                adios_read_dimes_finalize();
213
 
        }
214
 
        
215
 
        free_namelist ((fp->group_namelist),fp->groups_count);
216
 
        if (ds->fname) { free(ds->fname); ds->fname = 0; }
217
 
        free(ds);
218
 
        free(fp);
219
 
        return 0;
220
 
}
221
 
 
222
 
/* This function can be called if user places 
223
 
   the wrong sequences of dims for a var 
224
 
*/
225
 
void adios_read_dimes_reset_dimension_order (ADIOS_FILE *fp, int is_fortran)
226
 
{
227
 
    /* unimplemented */
228
 
}
229
 
 
230
 
ADIOS_GROUP * adios_read_dimes_gopen (ADIOS_FILE *fp, const char * grpname)
231
 
{
232
 
    /* DIMES has no groups, so any grpname is accepted and the same empty stuff is returned */
233
 
    return adios_read_dimes_gopen_byid(fp, 0);
234
 
}
235
 
 
236
 
ADIOS_GROUP * adios_read_dimes_gopen_byid (ADIOS_FILE *fp, int grpid)
237
 
{
238
 
    struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) fp->fh;
239
 
    ADIOS_GROUP * gp;
240
 
 
241
 
    /* DIMES has no groups, so any grpid is accepted and the same empty stuff is returned */
242
 
 
243
 
    adios_errno = 0;
244
 
    gp = (ADIOS_GROUP *) malloc(sizeof(ADIOS_GROUP));
245
 
    if (!gp) {
246
 
        adios_error (err_no_memory, "Could not allocate memory for group info");
247
 
        return NULL;
248
 
    }
249
 
 
250
 
    /* fill out ADIOS_GROUP struct */
251
 
    gp->grpid = grpid;
252
 
    gp->gh = (uint64_t) 0;
253
 
    gp->fp = fp;
254
 
    gp->vars_count = 0;
255
 
    gp->attrs_count = 0;
256
 
    gp->var_namelist = 0;
257
 
    gp->attr_namelist = 0;
258
 
    
259
 
    return gp;
260
 
}
261
 
 
262
 
int adios_read_dimes_gclose (ADIOS_GROUP *gp)
263
 
{
264
 
    struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) gp->fp->fh;
265
 
 
266
 
    adios_errno = 0;
267
 
 
268
 
    free_namelist ((gp->var_namelist),gp->vars_count);
269
 
    free_namelist ((gp->attr_namelist),gp->attrs_count);
270
 
    free(gp);
271
 
    return 0;
272
 
}
273
 
 
274
 
int adios_read_dimes_get_attr (ADIOS_GROUP * gp, const char * attrname, enum ADIOS_DATATYPES * type,
275
 
                    int * size, void ** data)
276
 
{
277
 
    /* DIMES does not support attributes */
278
 
    adios_error (err_invalid_attrname, "DIMES read method does not support attributes!");
279
 
    *size = 0;
280
 
    *type = adios_unknown;
281
 
    *data = 0;
282
 
    return adios_errno;
283
 
}
284
 
 
285
 
int adios_read_dimes_get_attr_byid (ADIOS_GROUP * gp, int attrid, 
286
 
                    enum ADIOS_DATATYPES * type, int * size, void ** data)
287
 
{
288
 
    /* DIMES does not support attributes */
289
 
    adios_error (err_invalid_attrid, "DIMES read method does not support attributes!");
290
 
    *size = 0;
291
 
    *type = adios_unknown;
292
 
    *data = 0;
293
 
    return adios_errno;
294
 
}
295
 
 
296
 
 
297
 
ADIOS_VARINFO * adios_read_dimes_inq_var (ADIOS_GROUP *gp, const char * varname) 
298
 
{
299
 
    /* DIMES has no inquiry capability, report somthing dummy */
300
 
    return adios_read_dimes_inq_var_byid(gp, 0);
301
 
}
302
 
 
303
 
ADIOS_VARINFO * adios_read_dimes_inq_var_byid (ADIOS_GROUP *gp, int varid)
304
 
{
305
 
    struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) gp->fp->fh;
306
 
    ADIOS_VARINFO * vi;
307
 
    int i,k;
308
 
 
309
 
    adios_errno = 0;
310
 
    vi = (ADIOS_VARINFO *) malloc(sizeof(ADIOS_VARINFO));
311
 
    if (!vi) {
312
 
        adios_error (err_no_memory, "Could not allocate memory for variable info.");
313
 
        return NULL;
314
 
    }
315
 
 
316
 
    /* DIMES has no inquiry capability, report somthing dummy */
317
 
    vi->varid = varid;
318
 
    vi->type = adios_unknown;
319
 
    vi->ndim = 0;
320
 
    vi->dims = NULL;
321
 
    vi->timedim = -1;
322
 
    vi->value = NULL;
323
 
    vi->gmin = NULL;
324
 
    vi->gmax = NULL;
325
 
    vi->mins = NULL;
326
 
    vi->maxs = NULL;
327
 
    
328
 
    return vi;
329
 
}
330
 
 
331
 
void adios_read_dimes_free_varinfo (ADIOS_VARINFO *vp)
332
 
{
333
 
    if (vp) {
334
 
        if (vp->dims)   free(vp->dims);
335
 
        if (vp->value)  free(vp->value);
336
 
        if (vp->gmin && vp->gmin != vp->value)   free(vp->gmin);
337
 
        if (vp->gmax && vp->gmax != vp->value)   free(vp->gmax);
338
 
        if (vp->mins)   free(vp->mins);
339
 
        if (vp->maxs)   free(vp->maxs);
340
 
        free(vp);
341
 
    }
342
 
}
343
 
 
344
 
static int adios_read_dimes_get(const char *varname, enum ADIOS_DATATYPES vartype,
345
 
                                                        struct adios_read_DIMES_data_struct *ds,
346
 
                                                        int *offset, int *readsize, void *data)
347
 
{
348
 
        int elemsize = common_read_type_size(vartype, NULL);
349
 
        int err;
350
 
        
351
 
        int xl,yl,zl,xu,yu,zu;
352
 
        //Flip 1st and 2nd dimension
353
 
        xl = offset[1];
354
 
        yl = offset[0];
355
 
        zl = offset[2];
356
 
        xu = offset[1]+readsize[1]-1;
357
 
        yu = offset[0]+readsize[0]-1;
358
 
        zu = offset[2]+readsize[2]-1;
359
 
 
360
 
        /*
361
 
        xl = offset[0];
362
 
        yl = offset[1];
363
 
        zl = offset[2];
364
 
        xu = offset[0]+readsize[0]-1;
365
 
        yu = offset[1]+readsize[1]-1;
366
 
        zu = offset[2]+readsize[2]-1;
367
 
        */
368
 
 
369
 
        DBG_PRINTF("-- %s, rank %d: get data: varname=%s version=%d,lb=(%d,%d,%d) ub=(%d,%d,%d)}\n",
370
 
                        __func__, ds->mpi_rank, varname, ds->access_version, xl,yl,zl,xu,yu,zu);
371
 
        
372
 
        if(xl==0 && yl==0 && zl==0 && xu==0 && yu==0 && zu==0){
373
 
                err = dimes_get_scalar(varname,ds->access_version,elemsize,0,0,0,0,0,0,data);
374
 
        } else {
375
 
                err = dimes_get(varname,ds->access_version,elemsize,xl,yl,zl,xu,yu,zu,data);
376
 
        }
377
 
        
378
 
        if(err) {
379
 
                adios_error (err_corrupted_variable,"DIMES failed to read variable %s.", varname);
380
 
                return -err_corrupted_variable;
381
 
        }
382
 
        
383
 
        return 0;       
384
 
}
385
 
 
386
 
int64_t adios_read_dimes_read_var (ADIOS_GROUP * gp, const char * varname,
387
 
                        const uint64_t * start, const uint64_t * count,
388
 
                        void * data)
389
 
{
390
 
    int64_t total_size;
391
 
    int offset[3], readsize[3], Toffset[3], Treadsize[3];
392
 
    struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) gp->fp->fh;
393
 
    enum ADIOS_DATATYPES vartype;
394
 
    int elemsize;
395
 
    int err;
396
 
    int i;
397
 
    char dimes_name[MAX_DIMES_NAMELEN];
398
 
 
399
 
    /*DIMES uses integers for boundaries */
400
 
    total_size = 1;
401
 
    for (i=0; i<3; i++) {
402
 
        offset[i]    = (int) start[i];
403
 
        Toffset[i]   = 0;
404
 
        readsize[i]  = (int) count[i];
405
 
        Treadsize[i] = 1;
406
 
        total_size   = total_size * count[i];
407
 
    }
408
 
 
409
 
    /* Get type information for the variable from DataSpaces:
410
 
       type variable name = TYPE@<filename>/<varname>
411
 
    */
412
 
    snprintf(dimes_name, MAX_DIMES_NAMELEN, "TYPE@%s/%s", ds->fname, varname);
413
 
    err = adios_read_dimes_get(dimes_name, adios_integer, ds, Toffset, Treadsize, &vartype);
414
 
    if (err)
415
 
        return err;
416
 
    DBG_PRINTF("-- %s, rank %d: get type: varname=%s type=%d (%s)}\n",
417
 
        __func__, ds->mpi_rank, dimes_name, vartype, common_read_type_to_string(vartype));
418
 
 
419
 
    elemsize = common_read_type_size(vartype, NULL);
420
 
    DBG_PRINTF("-- %s, rank %d: get data: varname=%s type=%d (%s) elemsize=%d}\n",
421
 
        __func__, ds->mpi_rank, dimes_name, vartype, common_read_type_to_string(vartype), elemsize);
422
 
 
423
 
    total_size *= elemsize; 
424
 
 
425
 
    //Get data
426
 
    snprintf(dimes_name, MAX_DIMES_NAMELEN, "%s/%s", ds->fname, varname);
427
 
    /*
428
 
    DBG_PRINTF("-- %s, rank %d: get data: varname=%s start=(%lld,%lld,%lld) count=(%lld,%lld,%lld)}\n",
429
 
        __func__, ds->mpi_rank, dimes_name, start[0], start[1], start[2], count[0], count[1], count[2]);
430
 
    */
431
 
    DBG_PRINTF("-- %s, rank %d: get data: varname=%s offset=(%d,%d,%d) readsize=(%d,%d,%d)}\n",
432
 
        __func__, ds->mpi_rank, dimes_name, offset[0], offset[1], offset[2], readsize[0], readsize[1], readsize[2]);
433
 
    err = adios_read_dimes_get(dimes_name, vartype, ds, offset, readsize, data);
434
 
    if (err)
435
 
        return err;
436
 
 
437
 
    return total_size;
438
 
}
439
 
 
440
 
int64_t adios_read_dimes_read_var_byid (ADIOS_GROUP    * gp,
441
 
                             int              varid,
442
 
                             const uint64_t  * start,
443
 
                             const uint64_t  * count,
444
 
                             void           * data)
445
 
{
446
 
    adios_error (err_invalid_varid, "DIMES does not know variable indicies, only variable names can be used.");
447
 
    return -err_invalid_varid;
448
 
}                                                       
449
 
 
450
 
int64_t adios_read_dimes_read_local_var (ADIOS_GROUP * gp, const char * varname,
451
 
                                      int vidx, const uint64_t * start,
452
 
                                      const uint64_t * count, void * data)
453
 
{  
454
 
    adios_error (err_operation_not_supported, "adios_read_local_var() is not supported with DIMES method.");
455
 
    return -adios_errno;
456
 
}