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.
17
#include "common_adios.h"
18
#include "adios_transport_hooks.h"
19
#include "adios_bp_v1.h"
20
#include "adios_internals.h"
21
#include "adios_internals_mxml.h"
28
extern struct adios_transport_struct * adios_transports;
30
///////////////////////////////////////////////////////////////////////////////
31
int common_adios_init (const char * config)
33
// parse the config file
34
return adios_parse_config (config);
37
///////////////////////////////////////////////////////////////////////////////
38
// all XML file pieces will be provided by another series of calls
39
int common_adios_init_noxml ()
41
return adios_local_config ();
44
///////////////////////////////////////////////////////////////////////////////
45
int common_adios_finalize (int mype)
47
struct adios_method_list_struct * m;
49
for (m = adios_get_methods (); m; m = m->next)
51
if ( m->method->m != ADIOS_METHOD_UNKNOWN
52
&& m->method->m != ADIOS_METHOD_NULL
53
&& adios_transports [m->method->m].adios_finalize_fn
56
adios_transports [m->method->m].adios_finalize_fn (mype, m->method);
65
///////////////////////////////////////////////////////////////////////////////
66
int common_adios_allocate_buffer (enum ADIOS_BUFFER_ALLOC_WHEN adios_buffer_alloc_when
67
,uint64_t buffer_size)
69
adios_buffer_size_requested_set (buffer_size * 1024 * 1024);
70
adios_buffer_alloc_when_set (adios_buffer_alloc_when);
72
return adios_set_buffer_size ();
75
///////////////////////////////////////////////////////////////////////////////
76
int common_adios_open (int64_t * fd, const char * group_name
77
,const char * name, const char * file_mode, void * comm
81
struct adios_file_struct * fd_p = (struct adios_file_struct *)
82
malloc (sizeof (struct adios_file_struct));
83
struct adios_group_struct * g = 0;
84
struct adios_method_list_struct * methods = 0;
85
enum ADIOS_METHOD_MODE mode;
87
adios_common_get_group (&group_id, group_name);
88
g = (struct adios_group_struct *) group_id;
91
if (!strcasecmp (file_mode, "r"))
92
mode = adios_mode_read;
94
if (!strcasecmp (file_mode, "w"))
95
mode = adios_mode_write;
97
if (!strcasecmp (file_mode, "a"))
98
mode = adios_mode_append;
100
if (!strcasecmp (file_mode, "u"))
101
mode = adios_mode_update;
104
fprintf (stderr, "adios_open: unknown file mode: %s\n"
113
fd_p->name = strdup (name);
114
fd_p->subfile_index = -1; // subfile index is by default -1
120
fd_p->bytes_written = 0;
121
fd_p->buffer_size = 0;
122
fd_p->vars_start = 0;
123
fd_p->vars_written = 0;
124
fd_p->write_size_bytes = 0;
125
fd_p->base_offset = 0;
126
fd_p->pg_start_in_file = 0;
128
if (mode != adios_mode_read)
133
if ( methods->method->m != ADIOS_METHOD_UNKNOWN
134
&& methods->method->m != ADIOS_METHOD_NULL
135
&& adios_transports [methods->method->m].adios_open_fn
138
adios_transports [methods->method->m].adios_open_fn
139
(fd_p, methods->method, comm);
142
methods = methods->next;
145
*fd = (int64_t) fd_p;
150
///////////////////////////////////////////////////////////////////////////////
151
int common_adios_group_size (int64_t fd_p
153
,uint64_t * total_size
156
struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
159
fprintf (stderr, "Invalid handle passed to adios_group_size\n");
163
struct adios_method_list_struct * m = fd->group->methods;
164
if (m && m->next == NULL && m->method->m == ADIOS_METHOD_NULL)
166
// nothing to do so just return
167
fd->shared_buffer = adios_flag_no;
168
fd->write_size_bytes = 0;
174
fd->write_size_bytes = data_size;
176
uint64_t overhead = adios_calc_overhead_v1 (fd);
178
*total_size = data_size + overhead;
180
// try to reserve a buffer using the adios_method_buffer_alloc
181
// if it does not give the correct amount, overflow. Make sure
182
// the amount given is big enough for the first part of the file.
184
fd->write_size_bytes += overhead;
186
uint64_t allocated = adios_method_buffer_alloc (fd->write_size_bytes);
187
if (allocated != fd->write_size_bytes)
189
fd->shared_buffer = adios_flag_no;
191
fprintf (stderr, "adios_group_size (%s): Not buffering. "
192
"needs: %llu available: %llu.\n"
193
,fd->group->name, fd->write_size_bytes, allocated
198
fd->shared_buffer = adios_flag_yes;
201
// call each transport method to coordinate the write and handle
202
// if an overflow is detected.
203
// now tell each transport attached that it is being written
206
enum ADIOS_FLAG should_buffer = adios_flag_yes;
207
if ( m->method->m != ADIOS_METHOD_UNKNOWN
208
&& m->method->m != ADIOS_METHOD_NULL
209
&& adios_transports [m->method->m].adios_should_buffer_fn
212
should_buffer = adios_transports [m->method->m].
213
adios_should_buffer_fn (fd
218
if (should_buffer == adios_flag_no) // can't write directly since
219
fd->shared_buffer = adios_flag_no; // some might want to share
224
if (fd->shared_buffer == adios_flag_no)
226
adios_method_buffer_free (allocated);
229
fd->bytes_written = 0;
233
fd->buffer = malloc (fd->write_size_bytes);
234
fd->buffer_size = fd->write_size_bytes;
236
fd->bytes_written = 0;
239
fprintf (stderr, "Cannot allocate %llu bytes for buffered output.\n",
240
fd->write_size_bytes);
246
// write the process group header
247
adios_write_process_group_header_v1 (fd, *total_size);
249
// setup for writing vars
250
adios_write_open_vars_v1 (fd);
254
// each var will be added to the buffer by the adios_write calls
255
// attributes will be added by adios_close
260
///////////////////////////////////////////////////////////////////////////////
261
/* common_adios_write is just a partial implementation. It expects filled out
262
* structures. This is because C and Fortran implementations of adios_write are
263
* different for some part and this is the common part.
265
int common_adios_write (struct adios_file_struct * fd, struct adios_var_struct * v, void * var)
267
struct adios_method_list_struct * m = fd->group->methods;
269
if (fd->shared_buffer == adios_flag_yes)
271
// var payload sent for sizing information
272
adios_write_var_header_v1 (fd, v);
275
adios_write_var_payload_v1 (fd, v);
278
// now tell each transport attached that it is being written
281
if ( m->method->m != ADIOS_METHOD_UNKNOWN
282
&& m->method->m != ADIOS_METHOD_NULL
283
&& adios_transports [m->method->m].adios_write_fn
286
adios_transports [m->method->m].adios_write_fn
287
(fd, v, var, m->method);
301
///////////////////////////////////////////////////////////////////////////////
302
int common_adios_get_write_buffer (int64_t fd_p, const char * name
307
struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
310
fprintf (stderr, "Invalid handle passed to adios_get_write_buffer\n");
314
struct adios_var_struct * v = fd->group->vars;
315
struct adios_method_list_struct * m = fd->group->methods;
317
v = adios_find_var_by_name (v, name, fd->group->all_unique_var_names);
322
,"Bad var name (ignored): '%s' (%c%c%c)\n"
323
,name, name[0], name[1], name[2]
329
if (fd->mode == adios_mode_read)
331
fprintf (stderr, "write attempted on %s in %s. This was opened for"
339
// since we are only getting one buffer, get it from the first
340
// transport method that can provide it.
343
if ( m->method->m != ADIOS_METHOD_UNKNOWN
344
&& m->method->m != ADIOS_METHOD_NULL
345
&& adios_transports [m->method->m].adios_get_write_buffer_fn
348
adios_transports [m->method->m].adios_get_write_buffer_fn
349
(fd, v, size, buffer, m->method);
359
///////////////////////////////////////////////////////////////////////////////
360
int common_adios_read (int64_t fd_p, const char * name, void * buffer
361
,uint64_t buffer_size
364
struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
367
fprintf (stderr, "Invalid handle passed to adios_read\n");
371
struct adios_var_struct * v;
372
struct adios_method_list_struct * m = fd->group->methods;
374
if (m && m->next == NULL && m->method->m == ADIOS_METHOD_NULL)
376
// nothing to do so just return
380
if (!(fd->mode == adios_mode_read))
382
fprintf (stderr, "read attempted on %s which was opened for write\n"
389
v = adios_find_var_by_name (fd->group->vars, name
390
,fd->group->all_unique_var_names
394
// since can only read from one place into the buffer,
395
// read from the first transport method that can
398
if ( m->method->m != ADIOS_METHOD_UNKNOWN
399
&& m->method->m != ADIOS_METHOD_NULL
400
&& adios_transports [m->method->m].adios_read_fn
403
adios_transports [m->method->m].adios_read_fn
404
(fd, v, buffer, buffer_size, m->method);
413
fprintf (stderr, "var %s in file %s not found on read\n"
423
///////////////////////////////////////////////////////////////////////////////
424
int common_adios_set_path (int64_t fd_p, const char * path)
426
struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
429
fprintf (stderr, "Invalid handle passed to adios_set_path\n");
433
struct adios_group_struct * t = fd->group;
434
struct adios_var_struct * v = t->vars;
435
struct adios_attribute_struct * a = t->attributes;
444
v->path = strdup (path);
456
a->path = strdup (path);
464
///////////////////////////////////////////////////////////////////////////////
465
int common_adios_set_path_var (int64_t fd_p, const char * path
469
struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
472
fprintf (stderr, "Invalid handle passed to adios_set_path_var\n");
476
struct adios_group_struct * t = fd->group;
477
struct adios_var_struct * v = t->vars;
479
// check for vars and then attributes
480
v = adios_find_var_by_name (t->vars, name, fd->group->all_unique_var_names);
489
v->path = strdup (path);
493
fprintf (stderr, "adios_set_path_var (path=%s, var=%s): var not found\n"
503
///////////////////////////////////////////////////////////////////////////////
504
// hint that we reached the end of an iteration (for asynchronous pacing)
505
int common_adios_end_iteration ()
507
struct adios_method_list_struct * m;
509
for (m = adios_get_methods (); m; m = m->next)
511
if ( m->method->m != ADIOS_METHOD_UNKNOWN
512
&& m->method->m != ADIOS_METHOD_NULL
513
&& adios_transports [m->method->m].adios_end_iteration_fn
516
adios_transports [m->method->m].adios_end_iteration_fn
524
///////////////////////////////////////////////////////////////////////////////
525
// hint to start communicating
526
int common_adios_start_calculation ()
528
struct adios_method_list_struct * m;
530
for (m = adios_get_methods (); m; m = m->next)
532
if ( m->method->m != ADIOS_METHOD_UNKNOWN
533
&& m->method->m != ADIOS_METHOD_NULL
534
&& adios_transports [m->method->m].adios_start_calculation_fn
537
adios_transports [m->method->m].adios_start_calculation_fn
545
///////////////////////////////////////////////////////////////////////////////
546
// hint to stop communicating
547
int common_adios_stop_calculation ()
549
struct adios_method_list_struct * m;
551
for (m = adios_get_methods (); m; m = m->next)
553
if ( m->method->m != ADIOS_METHOD_UNKNOWN
554
&& m->method->m != ADIOS_METHOD_NULL
555
&& adios_transports [m->method->m].adios_stop_calculation_fn
558
adios_transports [m->method->m].adios_stop_calculation_fn
566
///////////////////////////////////////////////////////////////////////////////
567
int common_adios_close (int64_t fd_p)
569
struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
572
fprintf (stderr, "Invalid handle passed to adios_close\n");
576
struct adios_method_list_struct * m = fd->group->methods;
577
if (m && m->next == NULL && m->method->m == ADIOS_METHOD_NULL)
579
// nothing to do so just return
583
struct adios_attribute_struct * a = fd->group->attributes;
584
struct adios_var_struct * v = fd->group->vars;
586
if (fd->shared_buffer == adios_flag_yes)
588
adios_write_close_vars_v1 (fd);
590
adios_write_open_attributes_v1 (fd);
594
adios_write_attribute_v1 (fd, a);
599
adios_write_close_attributes_v1 (fd);
602
// in order to get the index assembled, we need to do it in the
603
// transport once we have collected all of the pieces
605
// now tell all of the transports to write the buffer during close
606
for (;m; m = m->next)
608
if ( m->method->m != ADIOS_METHOD_UNKNOWN
609
&& m->method->m != ADIOS_METHOD_NULL
610
&& adios_transports [m->method->m].adios_close_fn
613
adios_transports [m->method->m].adios_close_fn
618
if (fd->shared_buffer == adios_flag_yes)
620
adios_method_buffer_free (fd->write_size_bytes);
639
while (fd->group->vars_written)
641
if (fd->group->vars_written->name)
642
free (fd->group->vars_written->name);
643
if (fd->group->vars_written->path)
644
free (fd->group->vars_written->path);
646
while (fd->group->vars_written->dimensions)
648
struct adios_dimension_struct * dimensions
649
= fd->group->vars_written->dimensions->next;
651
free (fd->group->vars_written->dimensions);
652
fd->group->vars_written->dimensions = dimensions;
656
if (fd->group->vars_written->stats)
658
uint8_t j = 0, idx = 0;
659
uint8_t c = 0, count = adios_get_stat_set_count(fd->group->vars_written->type);
661
for (c = 0; c < count; c ++)
663
while (fd->group->vars_written->bitmap >> j)
665
if ((fd->group->vars_written->bitmap >> j) & 1)
667
if (j == adios_statistic_hist)
669
struct adios_hist_struct * hist = (struct adios_hist_struct *) (fd->group->vars_written->stats[c][idx].data);
671
free (hist->frequencies);
675
free (fd->group->vars_written->stats[c][idx].data);
681
free (fd->group->vars_written->stats[c]);
683
free (fd->group->vars_written->stats);
685
if (fd->group->vars_written->data)
686
free (fd->group->vars_written->data);
688
v = fd->group->vars_written->next;
689
free (fd->group->vars_written);
690
fd->group->vars_written = v;
699
free ((void *) fd_p);
704
//////////////////////////////////////////////////////////////////////////////
705
// Methods normally only called by the XML parser
706
//////////////////////////////////////////////////////////////////////////////
708
// adios_common_declare_group is in adios_internals.c
709
// adios_common_define_var is in adios_internals.c
710
// adios_common_define_attribute is in adios_internals.c
711
// adios_common_select_method is in adios_internals.c