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.
5
* Copyright (c) 2008 - 2009. UT-BATTELLE, LLC. All rights reserved.
9
/**************************************************/
10
/* Read method for DIMES memory-to-memory coupling */
11
/**************************************************/
15
//#include <errno.h> /* ENOMEM */
19
#include "adios_types.h"
20
#include "adios_read.h"
21
#include "adios_read_hooks.h"
22
#include "adios_error.h"
33
#define DBG_PRINTF printf
35
#define DBG_PRINTF(a,...)
38
#define MAX_DIMES_NAMELEN 128
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 */
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
50
static int dimes_sync_id = 0;
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);
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.
62
int adios_read_dimes_init(MPI_Comm comm)
64
int nproc, drank, dpeers;
67
MPI_Comm_rank(comm, &rank);
68
MPI_Comm_size(comm, &nproc);
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);
75
DBG_PRINTF("-- %s, rank %d: connect to dimes with nproc=%d and appid=%d\n",
76
__func__,rank,nproc,appid);
78
//int num_total_peers = 64+16+1;
79
err = dimes_init(nproc,nproc,appid);
81
adios_error (err_connection_failed, "Failed to connect with DIMES index srv\n");
82
return -err_connection_failed;
85
globals_adios_set_dimes_connected_from_reader();
89
int adios_read_dimes_finalize()
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() )
97
DBG_PRINTF("-- %s: disconnected from dimes index srv\n",__func__);
100
globals_adios_set_dimes_disconnected_from_reader();
104
ADIOS_FILE *adios_read_dimes_fopen(const char *fname, MPI_Comm comm)
107
struct adios_read_DIMES_data_struct *ds;
112
ds = (struct adios_read_DIMES_data_struct *)malloc(sizeof(struct adios_read_DIMES_data_struct));
114
adios_error (err_no_memory, "Cannot allocate memory for file info.");
118
/*fill out dimes method specific struct*/
119
ds->fname = strdup(fname);
120
#ifdef DIMES_DO_VERSIONING
121
ds->access_version = number_of_fopens;
123
ds->access_version = 0;
126
MPI_Comm_rank(comm, &ds->mpi_rank);
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))
132
ds->disconnect_at_fclose = 1;
134
ds->disconnect_at_fclose = 0;
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};
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);
147
err = adios_read_dimes_get(dimes_fname, time_index_type, ds, offset, readsize, &time_index);
149
adios_error (err_file_not_found_error, "Data of '%s' does not exist in DIMES\n", dimes_fname);
153
DBG_PRINTF("-- %s, rank %d: data of '%s' exists, time index = %d\n", __func__, ds->mpi_rank, dimes_fname, time_index);
156
fp = (ADIOS_FILE *) malloc (sizeof (ADIOS_FILE));
158
adios_error (err_no_memory, "Cannot allocate memory for file info.");
162
/* fill out ADIOS_FILE struct */
163
fp->fh = (uint64_t) ds;
164
fp->groups_count = 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);
180
strcpy(fp->group_namelist[i],"dimes");
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
190
int adios_read_dimes_fclose(ADIOS_FILE *fp)
192
struct adios_read_DIMES_data_struct *ds =(struct adios_read_DIMES_data_struct *)fp->fh;
197
DBG_PRINTF("-- %s, rank %d: fp=%x\n", __func__, ds->mpi_rank, fp);
199
unsigned int version;
200
#ifdef DIMES_DO_VERSIONING
201
version = number_of_fopens;
202
dimes_sync_id = version;
207
dimes_sync(dimes_sync_id);
210
/*Disconnect from DIMES index srv if we connected in fopen()*/
211
if(ds && ds->disconnect_at_fclose){
212
adios_read_dimes_finalize();
215
free_namelist ((fp->group_namelist),fp->groups_count);
216
if (ds->fname) { free(ds->fname); ds->fname = 0; }
222
/* This function can be called if user places
223
the wrong sequences of dims for a var
225
void adios_read_dimes_reset_dimension_order (ADIOS_FILE *fp, int is_fortran)
230
ADIOS_GROUP * adios_read_dimes_gopen (ADIOS_FILE *fp, const char * grpname)
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);
236
ADIOS_GROUP * adios_read_dimes_gopen_byid (ADIOS_FILE *fp, int grpid)
238
struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) fp->fh;
241
/* DIMES has no groups, so any grpid is accepted and the same empty stuff is returned */
244
gp = (ADIOS_GROUP *) malloc(sizeof(ADIOS_GROUP));
246
adios_error (err_no_memory, "Could not allocate memory for group info");
250
/* fill out ADIOS_GROUP struct */
252
gp->gh = (uint64_t) 0;
256
gp->var_namelist = 0;
257
gp->attr_namelist = 0;
262
int adios_read_dimes_gclose (ADIOS_GROUP *gp)
264
struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) gp->fp->fh;
268
free_namelist ((gp->var_namelist),gp->vars_count);
269
free_namelist ((gp->attr_namelist),gp->attrs_count);
274
int adios_read_dimes_get_attr (ADIOS_GROUP * gp, const char * attrname, enum ADIOS_DATATYPES * type,
275
int * size, void ** data)
277
/* DIMES does not support attributes */
278
adios_error (err_invalid_attrname, "DIMES read method does not support attributes!");
280
*type = adios_unknown;
285
int adios_read_dimes_get_attr_byid (ADIOS_GROUP * gp, int attrid,
286
enum ADIOS_DATATYPES * type, int * size, void ** data)
288
/* DIMES does not support attributes */
289
adios_error (err_invalid_attrid, "DIMES read method does not support attributes!");
291
*type = adios_unknown;
297
ADIOS_VARINFO * adios_read_dimes_inq_var (ADIOS_GROUP *gp, const char * varname)
299
/* DIMES has no inquiry capability, report somthing dummy */
300
return adios_read_dimes_inq_var_byid(gp, 0);
303
ADIOS_VARINFO * adios_read_dimes_inq_var_byid (ADIOS_GROUP *gp, int varid)
305
struct adios_read_DIMES_data_struct * ds = (struct adios_read_DIMES_data_struct *) gp->fp->fh;
310
vi = (ADIOS_VARINFO *) malloc(sizeof(ADIOS_VARINFO));
312
adios_error (err_no_memory, "Could not allocate memory for variable info.");
316
/* DIMES has no inquiry capability, report somthing dummy */
318
vi->type = adios_unknown;
331
void adios_read_dimes_free_varinfo (ADIOS_VARINFO *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);
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)
348
int elemsize = common_read_type_size(vartype, NULL);
351
int xl,yl,zl,xu,yu,zu;
352
//Flip 1st and 2nd dimension
356
xu = offset[1]+readsize[1]-1;
357
yu = offset[0]+readsize[0]-1;
358
zu = offset[2]+readsize[2]-1;
364
xu = offset[0]+readsize[0]-1;
365
yu = offset[1]+readsize[1]-1;
366
zu = offset[2]+readsize[2]-1;
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);
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);
375
err = dimes_get(varname,ds->access_version,elemsize,xl,yl,zl,xu,yu,zu,data);
379
adios_error (err_corrupted_variable,"DIMES failed to read variable %s.", varname);
380
return -err_corrupted_variable;
386
int64_t adios_read_dimes_read_var (ADIOS_GROUP * gp, const char * varname,
387
const uint64_t * start, const uint64_t * count,
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;
397
char dimes_name[MAX_DIMES_NAMELEN];
399
/*DIMES uses integers for boundaries */
401
for (i=0; i<3; i++) {
402
offset[i] = (int) start[i];
404
readsize[i] = (int) count[i];
406
total_size = total_size * count[i];
409
/* Get type information for the variable from DataSpaces:
410
type variable name = TYPE@<filename>/<varname>
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);
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));
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);
423
total_size *= elemsize;
426
snprintf(dimes_name, MAX_DIMES_NAMELEN, "%s/%s", ds->fname, varname);
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]);
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);
440
int64_t adios_read_dimes_read_var_byid (ADIOS_GROUP * gp,
442
const uint64_t * start,
443
const uint64_t * count,
446
adios_error (err_invalid_varid, "DIMES does not know variable indicies, only variable names can be used.");
447
return -err_invalid_varid;
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)
454
adios_error (err_operation_not_supported, "adios_read_local_var() is not supported with DIMES method.");