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

« back to all changes in this revision

Viewing changes to src/adios_posix.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
 
#include <sys/types.h>
9
 
#include <unistd.h>
10
 
#include <fcntl.h>
11
 
#include <sys/stat.h>
12
 
#include <stdlib.h>
13
 
#include <math.h>
14
 
#include <string.h>
15
 
#include <stdint.h>
16
 
 
17
 
// see if we have MPI or other tools
18
 
#include "config.h"
19
 
 
20
 
 
21
 
// xml parser
22
 
#include <mxml.h>
23
 
 
24
 
#include "adios.h"
25
 
#include "adios_transport_hooks.h"
26
 
#include "adios_bp_v1.h"
27
 
#include "adios_internals.h"
28
 
#include "buffer.h"
29
 
 
30
 
#if defined(__APPLE__) 
31
 
#    define O_LARGEFILE 0
32
 
#endif
33
 
 
34
 
static int adios_posix_initialized = 0;
35
 
 
36
 
struct adios_POSIX_data_struct
37
 
{
38
 
    // our file bits
39
 
    struct adios_bp_buffer_struct_v1 b;
40
 
 
41
 
    // old index structs we read in and have to be merged in
42
 
    struct adios_index_process_group_struct_v1 * old_pg_root;
43
 
    struct adios_index_var_struct_v1 * old_vars_root;
44
 
    struct adios_index_attribute_struct_v1 * old_attrs_root;
45
 
 
46
 
    uint64_t vars_start;
47
 
    uint64_t vars_header_size;
48
 
#ifdef HAVE_MPI
49
 
    // Metadata file handle
50
 
    int mf;
51
 
    MPI_Comm group_comm;
52
 
    int rank;
53
 
    int size;
54
 
#endif
55
 
};
56
 
 
57
 
#ifdef HAVE_MPI
58
 
static void adios_var_to_comm (const char * comm_name
59
 
                              ,enum ADIOS_FLAG host_language_fortran
60
 
                              ,void * data
61
 
                              ,MPI_Comm * comm
62
 
                              )
63
 
{
64
 
    if (data)
65
 
    {
66
 
        int t = *(int *) data;
67
 
 
68
 
        if (!comm_name)
69
 
        {
70
 
            if (!t)
71
 
            {
72
 
                fprintf (stderr, "communicator not provided and none "
73
 
                                 "listed in XML.  Defaulting to "
74
 
                                 "MPI_COMM_SELF\n"
75
 
                        );
76
 
 
77
 
                *comm = MPI_COMM_SELF;
78
 
            }
79
 
            else
80
 
            {
81
 
                if (host_language_fortran == adios_flag_yes)
82
 
                {
83
 
                    *comm = MPI_Comm_f2c (t);
84
 
                }
85
 
                else
86
 
                {
87
 
                    *comm = *(MPI_Comm *) data;
88
 
                }
89
 
            }
90
 
        }
91
 
        else
92
 
        {
93
 
            if (!strcmp (comm_name, ""))
94
 
            {
95
 
                if (!t)
96
 
                {
97
 
                    fprintf (stderr, "communicator not provided and none "
98
 
                                     "listed in XML.  Defaulting to "
99
 
                                     "MPI_COMM_SELF\n"
100
 
                            );
101
 
 
102
 
                    *comm = MPI_COMM_SELF;
103
 
                }
104
 
                else
105
 
                {
106
 
                    if (host_language_fortran == adios_flag_yes)
107
 
                    {
108
 
                        *comm = MPI_Comm_f2c (t);
109
 
                    }
110
 
                    else
111
 
                    {
112
 
                        *comm = *(MPI_Comm *) data;
113
 
                    }
114
 
                }
115
 
            }
116
 
            else
117
 
            {
118
 
                if (!t)
119
 
                {
120
 
                    fprintf (stderr, "communicator not provided but one "
121
 
                                     "listed in XML.  Defaulting to "
122
 
                                     "MPI_COMM_WORLD\n"
123
 
                            );
124
 
 
125
 
                    *comm = MPI_COMM_WORLD;
126
 
                }
127
 
                else
128
 
                {
129
 
                    if (host_language_fortran == adios_flag_yes)
130
 
                    {
131
 
                        *comm = MPI_Comm_f2c (t);
132
 
                    }
133
 
                    else
134
 
                    {
135
 
                        *comm = *(MPI_Comm *) data;
136
 
                    }
137
 
                }
138
 
            }
139
 
        }
140
 
    }
141
 
    else
142
 
    {
143
 
        fprintf (stderr, "coordination-communication not provided. "
144
 
                         "Using MPI_COMM_SELF instead\n"
145
 
                );
146
 
 
147
 
        *comm = MPI_COMM_SELF;
148
 
    }
149
 
}
150
 
#endif
151
 
 
152
 
void adios_posix_init (const char * parameters
153
 
                      ,struct adios_method_struct * method
154
 
                      )
155
 
{
156
 
    struct adios_POSIX_data_struct * p = 0;
157
 
 
158
 
    if (!adios_posix_initialized)
159
 
    {
160
 
        adios_posix_initialized = 1;
161
 
    }
162
 
 
163
 
    method->method_data = malloc (sizeof (struct adios_POSIX_data_struct));
164
 
    p = (struct adios_POSIX_data_struct *) method->method_data;
165
 
    adios_buffer_struct_init (&p->b);
166
 
    p->old_pg_root = 0;
167
 
    p->old_vars_root = 0;
168
 
    p->old_attrs_root = 0;
169
 
    p->vars_start = 0;
170
 
    p->vars_header_size = 0;
171
 
#ifdef HAVE_MPI
172
 
    p->mf = 0;
173
 
    p->group_comm = MPI_COMM_NULL;
174
 
    p->rank = 0;
175
 
    p->size = 0;
176
 
#endif
177
 
}
178
 
 
179
 
int adios_posix_open (struct adios_file_struct * fd
180
 
                     ,struct adios_method_struct * method, void * comm
181
 
                     )
182
 
{
183
 
    char * subfile_name;
184
 
    char * mdfile_name;
185
 
    int rank;
186
 
    char * name_with_rank, rank_string[16];
187
 
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
188
 
                                                          method->method_data;
189
 
#ifdef HAVE_MPI
190
 
    // Need to figure out new the new fd->name, such as restart.bp.0, restart.bp.1....
191
 
    adios_var_to_comm (fd->group->group_comm
192
 
                      ,fd->group->adios_host_language_fortran
193
 
                      ,comm
194
 
                      ,&p->group_comm
195
 
                      );
196
 
 
197
 
    if (p->group_comm == MPI_COMM_NULL)
198
 
    {
199
 
        p->group_comm = MPI_COMM_SELF;
200
 
    }
201
 
 
202
 
    // if communicator is not MPI_COMM_NULL/MPI_COMM_SELF, subfiles will be generated in a dir.
203
 
    if (p->group_comm != MPI_COMM_SELF)
204
 
    {
205
 
        char * n = strrchr (fd->name, '/');
206
 
        if (!n)
207
 
        {
208
 
            n = fd->name;
209
 
        }
210
 
        else
211
 
        {
212
 
            n++;
213
 
        }
214
 
 
215
 
        MPI_Comm_rank (p->group_comm, &p->rank);
216
 
        MPI_Comm_size (p->group_comm, &p->size);
217
 
 
218
 
        sprintf (rank_string, "%d", p->rank);
219
 
        // fd->name + '.' + MPI rank + '\0'
220
 
        name_with_rank = malloc (strlen (n) + strlen (rank_string) + 2);
221
 
        sprintf (name_with_rank, "%s.%s",  n, rank_string);
222
 
 
223
 
        // e.g., subfile_name is restart.bp.dir/restart.bp.0
224
 
        subfile_name = malloc (strlen (fd->name)
225
 
                              + 5
226
 
                              + strlen (method->base_path)
227
 
                              + strlen (name_with_rank)
228
 
                              + 1
229
 
                              );
230
 
        sprintf (subfile_name, "%s%s%s%s"
231
 
                             , fd->name
232
 
                             , ".dir/"
233
 
                             , method->base_path
234
 
                             , name_with_rank
235
 
                             );
236
 
 
237
 
        mdfile_name = malloc (strlen (method->base_path)
238
 
                             + strlen (fd->name)
239
 
                             + 1
240
 
                             );
241
 
        sprintf (mdfile_name, "%s%s"
242
 
                            , method->base_path
243
 
                            , fd->name
244
 
                            );
245
 
 
246
 
        free (name_with_rank);
247
 
    }
248
 
    else
249
 
#endif
250
 
    {
251
 
        // if the communicator is MPI_COMM_SELF, there won't be metadata file generated.
252
 
        // The actually subfile name is the one supplied by the user
253
 
        subfile_name = malloc (strlen (method->base_path) + strlen (fd->name) + 1);
254
 
        sprintf (subfile_name, "%s%s", method->base_path, fd->name);
255
 
        mdfile_name = 0;
256
 
    }
257
 
 
258
 
    fd->subfile_index = p->rank;
259
 
 
260
 
    struct stat s;
261
 
    if (stat (subfile_name, &s) == 0)
262
 
        p->b.file_size = s.st_size;
263
 
 
264
 
    switch (fd->mode)
265
 
    {
266
 
        case adios_mode_read:
267
 
        {
268
 
            p->b.f = open (subfile_name, O_RDONLY | O_LARGEFILE);
269
 
            if (p->b.f == -1)
270
 
            {
271
 
                fprintf (stderr, "ADIOS POSIX: file not found: %s\n", fd->name);
272
 
 
273
 
                free (subfile_name);
274
 
 
275
 
                return 0;
276
 
            }
277
 
            fd->base_offset = 0;
278
 
            fd->pg_start_in_file = 0;
279
 
 
280
 
            break;
281
 
        }
282
 
 
283
 
        case adios_mode_write:
284
 
        {
285
 
#ifdef HAVE_MPI
286
 
            // create dir to keep all the subfiles
287
 
            if (p->group_comm != MPI_COMM_SELF)
288
 
            {
289
 
                if (p->rank == 0)
290
 
                {
291
 
                    char * dir_name = malloc (strlen (fd->name) + 4 + 1);
292
 
                    sprintf (dir_name, "%s%s"
293
 
                                     , fd->name
294
 
                                     , ".dir"
295
 
                                     ) ;
296
 
 
297
 
                    mkdir (dir_name, S_IRWXU | S_IRWXG);
298
 
                    free (dir_name);
299
 
                }
300
 
 
301
 
                MPI_Barrier (p->group_comm);
302
 
            }
303
 
#endif
304
 
            p->b.f = open (subfile_name, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE
305
 
                                       ,  S_IRUSR | S_IWUSR
306
 
                                        | S_IRGRP | S_IWGRP
307
 
                                        | S_IROTH | S_IWOTH
308
 
                            );
309
 
            if (p->b.f == -1)
310
 
            {
311
 
                fprintf (stderr, "adios_posix_open failed for "
312
 
                                 "base_path %s, subfile name %s\n"
313
 
                        ,method->base_path, subfile_name
314
 
                        );
315
 
 
316
 
                free (subfile_name);
317
 
                free (mdfile_name);
318
 
 
319
 
                return 0;
320
 
            }
321
 
 
322
 
#ifdef HAVE_MPI
323
 
            // open metadata file
324
 
            if (p->group_comm != MPI_COMM_SELF)
325
 
            {
326
 
                if (p->rank == 0)
327
 
                {
328
 
                    p->mf = open (mdfile_name, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE
329
 
                                  ,  S_IRUSR | S_IWUSR
330
 
                                   | S_IRGRP | S_IWGRP
331
 
                                   | S_IROTH | S_IWOTH
332
 
                             );
333
 
                    if (p->mf == -1)
334
 
                    {
335
 
                        fprintf (stderr, "adios_posix_open failed for "
336
 
                                         "base_path %s, metadata file name %s\n"
337
 
                                ,method->base_path, mdfile_name
338
 
                                );
339
 
 
340
 
                        free (subfile_name);
341
 
                        free (mdfile_name);
342
 
 
343
 
                        return 0;
344
 
                    }
345
 
                }
346
 
            }
347
 
#endif
348
 
            fd->base_offset = 0;
349
 
            fd->pg_start_in_file = 0;
350
 
 
351
 
            break;
352
 
        }
353
 
 
354
 
        case adios_mode_append:
355
 
        {
356
 
            int old_file = 1;
357
 
#ifdef HAVE_MPI
358
 
            if (p->group_comm != MPI_COMM_SELF)
359
 
            {
360
 
                if (p->rank == 0)
361
 
                {
362
 
                    char * dir_name = malloc (strlen (fd->name) + 4 + 1);
363
 
                    sprintf (dir_name, "%s%s"
364
 
                                     , fd->name
365
 
                                     , ".dir"
366
 
                                     ) ;
367
 
 
368
 
                    mkdir (dir_name, S_IRWXU | S_IRWXG);
369
 
                    free (dir_name);
370
 
                }
371
 
 
372
 
                MPI_Barrier (p->group_comm);
373
 
            }
374
 
#endif
375
 
            p->b.f = open (subfile_name, O_RDWR | O_LARGEFILE);
376
 
            if (p->b.f == -1)
377
 
            {
378
 
                old_file = 0;
379
 
                p->b.f = open (subfile_name,  O_WRONLY | O_CREAT | O_LARGEFILE
380
 
                                ,  S_IRUSR | S_IWUSR
381
 
                                 | S_IRGRP | S_IWGRP
382
 
                                 | S_IROTH | S_IWOTH
383
 
                                );
384
 
                if (p->b.f == -1)
385
 
                {
386
 
                    fprintf (stderr, "adios_posix_open failed for "
387
 
                                     "base_path %s, name %s\n"
388
 
                            ,method->base_path, fd->name
389
 
                            );
390
 
 
391
 
                    free (subfile_name);
392
 
                    free (mdfile_name);
393
 
 
394
 
                    return 0;
395
 
                }
396
 
            }
397
 
#ifdef HAVE_MPI
398
 
            // open metadata file
399
 
            if (p->group_comm != MPI_COMM_SELF)
400
 
            {
401
 
                if (p->rank == 0)
402
 
                {
403
 
                    p->mf = open (mdfile_name, O_WRONLY | O_TRUNC | O_LARGEFILE
404
 
                                              , S_IRUSR | S_IWUSR
405
 
                                              | S_IRGRP | S_IWGRP
406
 
                                              | S_IROTH | S_IWOTH
407
 
                                 );
408
 
                    if (p->mf == -1)
409
 
                    {
410
 
                        p->mf = open (mdfile_name, O_WRONLY| O_CREAT | O_LARGEFILE
411
 
                                                 , S_IRUSR | S_IWUSR
412
 
                                                 | S_IRGRP | S_IWGRP
413
 
                                             | S_IROTH | S_IWOTH
414
 
                                     );
415
 
                        if (p->mf == -1)
416
 
                        {
417
 
                            fprintf (stderr, "adios_posix_open failed for "
418
 
                                             "base_path %s, name %s\n"
419
 
                                    ,method->base_path, fd->name
420
 
                                    );
421
 
 
422
 
                            free (subfile_name);
423
 
                            free (mdfile_name);
424
 
 
425
 
                            return 0;
426
 
                        }
427
 
                    }
428
 
                }
429
 
            }
430
 
#endif
431
 
            if (old_file)
432
 
            {
433
 
                // now we have to read the old stuff so we can merge it
434
 
                // in at the end and set the base_offset for the old index
435
 
                // start
436
 
                uint32_t version;
437
 
                adios_posix_read_version (&p->b);
438
 
                adios_parse_version (&p->b, &version);
439
 
 
440
 
                switch (version & ADIOS_VERSION_NUM_MASK)
441
 
                {
442
 
                    case 1:
443
 
                        // read the old stuff and set the base offset
444
 
                        adios_posix_read_index_offsets (&p->b);
445
 
                        adios_parse_index_offsets_v1 (&p->b);
446
 
 
447
 
                        adios_posix_read_process_group_index (&p->b);
448
 
                        adios_parse_process_group_index_v1 (&p->b
449
 
                                                           ,&p->old_pg_root
450
 
                                                           );
451
 
 
452
 
                        // find the largest time index so we can append properly
453
 
                        struct adios_index_process_group_struct_v1 * pg;
454
 
                        uint32_t max_time_index = 0;
455
 
                        pg = p->old_pg_root;
456
 
                        while (pg)
457
 
                        {
458
 
                            if (pg->time_index > max_time_index)
459
 
                                max_time_index = pg->time_index;
460
 
                            pg = pg->next;
461
 
                        }
462
 
                        fd->group->time_index = ++max_time_index;
463
 
 
464
 
                        adios_posix_read_vars_index (&p->b);
465
 
                        adios_parse_vars_index_v1 (&p->b, &p->old_vars_root);
466
 
 
467
 
                        adios_posix_read_attributes_index (&p->b);
468
 
                        adios_parse_attributes_index_v1 (&p->b
469
 
                                                        ,&p->old_attrs_root
470
 
                                                        );
471
 
 
472
 
                        fd->base_offset = p->b.end_of_pgs;
473
 
                        fd->pg_start_in_file = p->b.end_of_pgs;
474
 
                        break;
475
 
 
476
 
                    default:
477
 
                        fprintf (stderr, "Unknown bp version: %d.  "
478
 
                                         "Cannot append\n"
479
 
                                ,version
480
 
                                );
481
 
 
482
 
                        free (subfile_name);
483
 
                        free (mdfile_name);
484
 
 
485
 
                        return 0;
486
 
                }
487
 
            }
488
 
 
489
 
            break;
490
 
        }
491
 
 
492
 
        default:
493
 
        {
494
 
            fprintf (stderr, "Unknown file mode: %d\n", fd->mode);
495
 
 
496
 
            free (subfile_name);
497
 
            free (mdfile_name);
498
 
 
499
 
            return 0;
500
 
        }
501
 
    }
502
 
 
503
 
    free (subfile_name);
504
 
    free (mdfile_name);
505
 
 
506
 
    return 1;
507
 
}
508
 
 
509
 
enum ADIOS_FLAG adios_posix_should_buffer (struct adios_file_struct * fd
510
 
                                          ,struct adios_method_struct * method
511
 
                                          )
512
 
{
513
 
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
514
 
                                                          method->method_data;
515
 
 
516
 
    if (fd->shared_buffer == adios_flag_no && fd->mode != adios_mode_read)
517
 
    {
518
 
        // write the process group header
519
 
        adios_write_process_group_header_v1 (fd, fd->write_size_bytes);
520
 
 
521
 
        lseek (p->b.f, fd->base_offset, SEEK_SET);
522
 
        ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
523
 
        if (s != fd->bytes_written)
524
 
        {
525
 
            fprintf (stderr, "POSIX method tried to write %llu, "
526
 
                             "only wrote %llu\n"
527
 
                    ,fd->bytes_written
528
 
                    ,s
529
 
                    );
530
 
        }
531
 
        fd->base_offset += s;
532
 
        fd->offset = 0;
533
 
        fd->bytes_written = 0;
534
 
        adios_shared_buffer_free (&p->b);
535
 
 
536
 
        // setup for writing vars
537
 
        adios_write_open_vars_v1 (fd);
538
 
        p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR);  // save loc
539
 
        p->vars_header_size = p->vars_start - fd->base_offset;  // the size
540
 
        p->vars_start -= fd->offset; // adjust to start of header
541
 
        fd->base_offset += fd->offset;  // add the size of the vars header
542
 
        fd->offset = 0;
543
 
        fd->bytes_written = 0;
544
 
        adios_shared_buffer_free (&p->b);
545
 
    }
546
 
 
547
 
    return fd->shared_buffer;   // buffer if there is space
548
 
}
549
 
 
550
 
void adios_posix_write (struct adios_file_struct * fd
551
 
                       ,struct adios_var_struct * v
552
 
                       ,void * data
553
 
                       ,struct adios_method_struct * method
554
 
                       )
555
 
{
556
 
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
557
 
                                                          method->method_data;
558
 
 
559
 
    if (v->got_buffer == adios_flag_yes)
560
 
    {
561
 
        if (data != v->data)  // if the user didn't give back the same thing
562
 
        {
563
 
            if (v->free_data == adios_flag_yes)
564
 
            {
565
 
                free (v->data);
566
 
                adios_method_buffer_free (v->data_size);
567
 
            }
568
 
        }
569
 
        else
570
 
        {
571
 
            // we already saved all of the info, so we're ok.
572
 
            return;
573
 
        }
574
 
    }
575
 
 
576
 
    if (fd->shared_buffer == adios_flag_no)
577
 
    {
578
 
        // var payload sent for sizing information
579
 
        adios_write_var_header_v1 (fd, v);
580
 
        ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
581
 
        if (s != fd->bytes_written)
582
 
        {
583
 
            fprintf (stderr, "POSIX method tried to write %llu, "
584
 
                             "only wrote %llu\n"
585
 
                    ,fd->bytes_written
586
 
                    ,s
587
 
                    );
588
 
        }
589
 
        fd->base_offset += s;
590
 
        fd->offset = 0;
591
 
        fd->bytes_written = 0;
592
 
        adios_shared_buffer_free (&p->b);
593
 
 
594
 
        // write payload
595
 
        // adios_write_var_payload_v1 (fd, v);
596
 
        uint64_t var_size = adios_get_var_size (v, fd->group, v->data);
597
 
        if (fd->base_offset + var_size > fd->pg_start_in_file + fd->write_size_bytes)
598
 
            fprintf (stderr, "adios_posix_write exceeds pg bound. File is corrupted. "
599
 
                             "Need to enlarge group size. \n"); 
600
 
 
601
 
        int32_t to_write;
602
 
        uint64_t bytes_written = 0;
603
 
        if (var_size > INT32_MAX)
604
 
        {
605
 
            to_write = INT32_MAX;
606
 
        }
607
 
        else
608
 
        {
609
 
            to_write = (int32_t) fd->bytes_written;
610
 
        }
611
 
 
612
 
        while (bytes_written < var_size)
613
 
        {
614
 
            bytes_written += write (p->b.f, v->data + bytes_written, to_write);
615
 
            if (var_size > bytes_written)
616
 
            {
617
 
                if (var_size - bytes_written > INT32_MAX)
618
 
                {
619
 
                    to_write = INT32_MAX;
620
 
                }
621
 
                else
622
 
                {
623
 
                    to_write = var_size - bytes_written;
624
 
                }
625
 
            }
626
 
        }
627
 
 
628
 
//        s = write (p->b.f, v->data, var_size);
629
 
        s = bytes_written;
630
 
        if (s != var_size)
631
 
        {
632
 
            fprintf (stderr, "POSIX method tried to write %llu, "
633
 
                             "only wrote %llu\n"
634
 
                    ,var_size
635
 
                    ,s
636
 
                    );
637
 
        }
638
 
        fd->base_offset += s;
639
 
        fd->offset = 0;
640
 
        fd->bytes_written = 0;
641
 
        adios_shared_buffer_free (&p->b);
642
 
    }
643
 
}
644
 
 
645
 
void adios_posix_get_write_buffer (struct adios_file_struct * fd
646
 
                                  ,struct adios_var_struct * v
647
 
                                  ,uint64_t * size
648
 
                                  ,void ** buffer
649
 
                                  ,struct adios_method_struct * method
650
 
                                  )
651
 
{
652
 
    uint64_t mem_allowed;
653
 
 
654
 
    if (*size == 0)
655
 
    {
656
 
        *buffer = 0;
657
 
 
658
 
        return;
659
 
    }
660
 
 
661
 
    if (v->data && v->free_data)
662
 
    {
663
 
        adios_method_buffer_free (v->data_size);
664
 
        free (v->data);
665
 
    }
666
 
 
667
 
    mem_allowed = adios_method_buffer_alloc (*size);
668
 
    if (mem_allowed == *size)
669
 
    {
670
 
        *buffer = malloc (*size);
671
 
        if (!*buffer)
672
 
        {
673
 
            adios_method_buffer_free (mem_allowed);
674
 
            fprintf (stderr, "Out of memory allocating %llu bytes for %s\n"
675
 
                    ,*size, v->name
676
 
                    );
677
 
            v->got_buffer = adios_flag_no;
678
 
            v->free_data = adios_flag_no;
679
 
            v->data_size = 0;
680
 
            v->data = 0;
681
 
            *size = 0;
682
 
            *buffer = 0;
683
 
        }
684
 
        else
685
 
        {
686
 
            v->got_buffer = adios_flag_yes;
687
 
            v->free_data = adios_flag_yes;
688
 
            v->data_size = mem_allowed;
689
 
            v->data = *buffer;
690
 
        }
691
 
    }
692
 
    else
693
 
    {
694
 
        adios_method_buffer_free (mem_allowed);
695
 
        fprintf (stderr, "OVERFLOW: Cannot allocate requested buffer of %llu "
696
 
                         "bytes for %s\n"
697
 
                ,*size
698
 
                ,v->name
699
 
                );
700
 
        *size = 0;
701
 
        *buffer = 0;
702
 
    }
703
 
}
704
 
 
705
 
void adios_posix_read (struct adios_file_struct * fd
706
 
                      ,struct adios_var_struct * v
707
 
                      ,void * buffer
708
 
                      ,uint64_t buffer_size
709
 
                      ,struct adios_method_struct * method
710
 
                      )
711
 
{
712
 
    v->data = buffer;
713
 
    v->data_size = buffer_size;
714
 
}
715
 
 
716
 
static void adios_posix_do_write (struct adios_file_struct * fd
717
 
                                 ,struct adios_method_struct * method
718
 
                                 ,char * buffer
719
 
                                 ,uint64_t buffer_size
720
 
                                 )
721
 
{
722
 
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
723
 
                                                          method->method_data;
724
 
    int32_t to_write;
725
 
    uint64_t bytes_written = 0;
726
 
 
727
 
    if (fd->shared_buffer == adios_flag_yes)
728
 
    {
729
 
        lseek (p->b.f, p->b.end_of_pgs, SEEK_SET);
730
 
        if (p->b.end_of_pgs + fd->bytes_written > fd->pg_start_in_file + fd->write_size_bytes)
731
 
            fprintf (stderr, "adios_posix_write exceeds pg bound. File is corrupted. "
732
 
                             "Need to enlarge group size. \n");
733
 
 
734
 
        if (fd->bytes_written > INT32_MAX)
735
 
        {
736
 
            to_write = INT32_MAX;
737
 
        }
738
 
        else
739
 
        {
740
 
            to_write = (int32_t) fd->bytes_written;
741
 
        }
742
 
 
743
 
        while (bytes_written < fd->bytes_written)
744
 
        {
745
 
            write (p->b.f, fd->buffer, to_write);
746
 
            bytes_written += to_write;
747
 
            if (fd->bytes_written > bytes_written)
748
 
            {
749
 
                if (fd->bytes_written - bytes_written > INT32_MAX)
750
 
                {
751
 
                    to_write = INT32_MAX;
752
 
                }
753
 
                else
754
 
                {
755
 
                    to_write = fd->bytes_written - bytes_written;
756
 
                }
757
 
            }
758
 
        }
759
 
    }
760
 
 
761
 
    // index location calculation:
762
 
    // for buffered, base_offset = 0, fd->offset = write loc
763
 
    // for unbuffered, base_offset = write loc, fd->offset = 0
764
 
    // for append buffered, base_offset = start, fd->offset = size
765
 
    lseek (p->b.f, fd->base_offset + fd->offset, SEEK_SET);
766
 
    write (p->b.f, buffer, buffer_size);
767
 
}
768
 
 
769
 
static void adios_posix_do_read (struct adios_file_struct * fd
770
 
                                ,struct adios_method_struct * method
771
 
                                )
772
 
{
773
 
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
774
 
                                                          method->method_data;
775
 
    struct adios_var_struct * v = fd->group->vars;
776
 
 
777
 
    struct adios_parse_buffer_struct data;
778
 
 
779
 
    data.vars = v;
780
 
    data.buffer = 0;
781
 
    data.buffer_len = 0;
782
 
 
783
 
    uint32_t version = 0;
784
 
 
785
 
    adios_posix_read_version (&p->b);
786
 
    adios_parse_version (&p->b, &version);
787
 
 
788
 
    switch (version & ADIOS_VERSION_NUM_MASK)
789
 
    {
790
 
        case 1:
791
 
        {
792
 
            struct adios_index_process_group_struct_v1 * pg_root = 0;
793
 
            struct adios_index_process_group_struct_v1 * pg_root_temp = 0;
794
 
            struct adios_index_var_struct_v1 * vars_root = 0;
795
 
            struct adios_index_attribute_struct_v1 * attrs_root = 0;
796
 
 
797
 
            adios_posix_read_index_offsets (&p->b);
798
 
            adios_parse_index_offsets_v1 (&p->b);
799
 
 
800
 
            adios_posix_read_process_group_index (&p->b);
801
 
            adios_parse_process_group_index_v1 (&p->b, &pg_root);
802
 
#if 1
803
 
            adios_posix_read_vars_index (&p->b);
804
 
            adios_parse_vars_index_v1 (&p->b, &vars_root);
805
 
 
806
 
            adios_posix_read_attributes_index (&p->b);
807
 
            adios_parse_attributes_index_v1 (&p->b, &attrs_root);
808
 
#endif
809
 
 
810
 
            // the three section headers
811
 
            struct adios_process_group_header_struct_v1 pg_header;
812
 
            struct adios_vars_header_struct_v1 vars_header;
813
 
            struct adios_attributes_header_struct_v1 attrs_header;
814
 
 
815
 
            struct adios_var_header_struct_v1 var_header;
816
 
            struct adios_var_payload_struct_v1 var_payload;
817
 
            struct adios_attribute_struct_v1 attribute;
818
 
 
819
 
            int i;
820
 
 
821
 
            pg_root_temp = pg_root;
822
 
            while (pg_root_temp && pg_root_temp->next)
823
 
                pg_root_temp = pg_root_temp->next;
824
 
 
825
 
            p->b.read_pg_offset = pg_root_temp->offset_in_file;
826
 
            if (pg_root_temp->next)
827
 
            {
828
 
                p->b.read_pg_size =   pg_root_temp->next->offset_in_file
829
 
                                    - pg_root_temp->offset_in_file;
830
 
            }
831
 
            else
832
 
            {
833
 
                p->b.read_pg_size =   p->b.pg_index_offset
834
 
                                    - pg_root_temp->offset_in_file;
835
 
            }
836
 
 
837
 
            adios_posix_read_process_group (&p->b);
838
 
            adios_parse_process_group_header_v1 (&p->b, &pg_header);
839
 
 
840
 
            adios_parse_vars_header_v1 (&p->b, &vars_header);
841
 
 
842
 
            for (i = 0; i < vars_header.count; i++)
843
 
            {
844
 
                memset (&var_payload, 0
845
 
                       ,sizeof (struct adios_var_payload_struct_v1)
846
 
                       );
847
 
                adios_parse_var_data_header_v1 (&p->b, &var_header);
848
 
 
849
 
                struct adios_var_struct * v1 = v;
850
 
                while (v1)
851
 
                {
852
 
                    if (   strcasecmp (var_header.name, v1->name)
853
 
                        || strcasecmp (var_header.path, v1->path)
854
 
                       )
855
 
                    {
856
 
                        v1 = v1->next;
857
 
                    }
858
 
                    else
859
 
                        break;
860
 
                }
861
 
 
862
 
                if (v1)
863
 
                {
864
 
                    var_payload.payload = v1->data;
865
 
                    adios_parse_var_data_payload_v1 (&p->b, &var_header
866
 
                                                    ,&var_payload
867
 
                                                    ,v1->data_size
868
 
                                                    );
869
 
                }
870
 
                else
871
 
                {
872
 
                    adios_parse_var_data_payload_v1 (&p->b, &var_header
873
 
                                                    ,NULL, 0
874
 
                                                    );
875
 
                }
876
 
 
877
 
                adios_clear_var_header_v1 (&var_header);
878
 
            }
879
 
 
880
 
#if 1
881
 
            adios_parse_attributes_header_v1 (&p->b, &attrs_header);
882
 
 
883
 
            for (i = 0; i < attrs_header.count; i++)
884
 
            {
885
 
                adios_parse_attribute_v1 (&p->b, &attribute);
886
 
                adios_clear_attribute_v1 (&attribute);
887
 
            }
888
 
#endif
889
 
            adios_clear_process_group_header_v1 (&pg_header);
890
 
            adios_clear_index_v1 (pg_root, vars_root, attrs_root);
891
 
            break;
892
 
        }
893
 
 
894
 
        default:
895
 
            fprintf (stderr, "POSIX read: file version unknown: %u\n"
896
 
                    ,version
897
 
                    );
898
 
            return;
899
 
    }
900
 
 
901
 
    adios_buffer_struct_clear (&p->b);
902
 
}
903
 
 
904
 
void adios_posix_close (struct adios_file_struct * fd
905
 
                       ,struct adios_method_struct * method
906
 
                       )
907
 
{
908
 
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
909
 
                                                          method->method_data;
910
 
    struct adios_attribute_struct * a = fd->group->attributes;
911
 
 
912
 
    struct adios_index_process_group_struct_v1 * new_pg_root = 0;
913
 
    struct adios_index_var_struct_v1 * new_vars_root = 0;
914
 
    struct adios_index_attribute_struct_v1 * new_attrs_root = 0;
915
 
 
916
 
    switch (fd->mode)
917
 
    {
918
 
        case adios_mode_write:
919
 
        {
920
 
            if (fd->shared_buffer == adios_flag_no)
921
 
            {
922
 
                off_t new_off;
923
 
                // set it up so that it will start at 0, but have correct sizes
924
 
                new_off = lseek (p->b.f, 0, SEEK_CUR);
925
 
                fd->offset = fd->base_offset - p->vars_start;
926
 
                fd->vars_start = 0;
927
 
                fd->buffer_size = 0;
928
 
                adios_write_close_vars_v1 (fd);
929
 
                // fd->vars_start gets updated with the size written
930
 
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
931
 
                ssize_t s = write (p->b.f, fd->buffer, p->vars_header_size);
932
 
                if (s != fd->vars_start)
933
 
                {
934
 
                    fprintf (stderr, "POSIX method tried to write %llu, "
935
 
                                     "only wrote %llu\n"
936
 
                            ,fd->vars_start
937
 
                            ,s
938
 
                            );
939
 
                }
940
 
                fd->offset = 0;
941
 
                fd->bytes_written = 0;
942
 
                adios_shared_buffer_free (&p->b);
943
 
 
944
 
                new_off = lseek (p->b.f, new_off, SEEK_SET);  // go back to end
945
 
                adios_write_open_attributes_v1 (fd);
946
 
                p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR); // save loc
947
 
                p->vars_header_size = p->vars_start - fd->base_offset;
948
 
                p->vars_start -= fd->offset; // adjust to start of header
949
 
                fd->base_offset += fd->offset;  // add size of header
950
 
                fd->offset = 0;
951
 
                fd->bytes_written = 0;
952
 
 
953
 
                while (a)
954
 
                {
955
 
                    adios_write_attribute_v1 (fd, a);
956
 
                    if (fd->base_offset + fd->bytes_written > fd->pg_start_in_file + fd->write_size_bytes)
957
 
                        fprintf (stderr, "adios_posix_write exceeds pg bound. File is corrupted. "
958
 
                                         "Need to enlarge group size. \n");
959
 
                    ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
960
 
                    if (s != fd->bytes_written)
961
 
                    {
962
 
                        fprintf (stderr, "POSIX method tried to write %llu, "
963
 
                                         "only wrote %llu\n"
964
 
                                ,fd->bytes_written
965
 
                                ,s
966
 
                                );
967
 
                    }
968
 
                    fd->base_offset += s;
969
 
                    fd->offset = 0;
970
 
                    fd->bytes_written = 0;
971
 
                    adios_shared_buffer_free (&p->b);
972
 
 
973
 
                    a = a->next;
974
 
                }
975
 
 
976
 
                // set it up so that it will start at 0, but have correct sizes
977
 
                fd->offset = fd->base_offset - p->vars_start;
978
 
                fd->vars_start = 0;
979
 
                fd->buffer_size = 0;
980
 
                adios_write_close_attributes_v1 (fd);
981
 
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
982
 
                // fd->vars_start gets updated with the size written
983
 
                s = write (p->b.f, fd->buffer, p->vars_header_size);
984
 
                if (s != p->vars_header_size)
985
 
                {
986
 
                    fprintf (stderr, "POSIX method tried to write %llu, "
987
 
                                     "only wrote %llu\n"
988
 
                            ,p->vars_header_size
989
 
                            ,s
990
 
                            );
991
 
                }
992
 
                fd->offset = 0;
993
 
                fd->bytes_written = 0;
994
 
            }
995
 
 
996
 
            // buffering or not, write the index
997
 
            char * buffer = 0;
998
 
            uint64_t buffer_size = 0;
999
 
            uint64_t buffer_offset = 0;
1000
 
            uint64_t index_start = fd->base_offset + fd->offset;
1001
 
 
1002
 
            // build index
1003
 
            adios_build_index_v1 (fd, &p->old_pg_root, &p->old_vars_root
1004
 
                                 ,&p->old_attrs_root
1005
 
                                 );
1006
 
            // if collective, gather the indexes from the rest and call
1007
 
            // adios_merge_index_v1 (&new_pg_root, &new_vars_root, pg, vars);
1008
 
            adios_write_index_v1 (&buffer, &buffer_size, &buffer_offset
1009
 
                                 ,index_start, p->old_pg_root, p->old_vars_root
1010
 
                                 ,p->old_attrs_root
1011
 
                                 );
1012
 
            adios_write_version_v1 (&buffer, &buffer_size, &buffer_offset);
1013
 
            adios_posix_do_write (fd, method, buffer, buffer_offset);
1014
 
#ifdef HAVE_MPI
1015
 
            if (p->group_comm != MPI_COMM_SELF)
1016
 
            {
1017
 
                if (p->rank == 0)
1018
 
                {
1019
 
                    int * index_sizes = malloc (4 * p->size);
1020
 
                    int * index_offsets = malloc (4 * p->size);
1021
 
                    char * recv_buffer = 0;
1022
 
                    int i;
1023
 
                    uint32_t size = 0, total_size = 0;
1024
 
 
1025
 
                    MPI_Gather (&size, 1, MPI_INT
1026
 
                               ,index_sizes, 1, MPI_INT
1027
 
                               ,0, p->group_comm
1028
 
                               );
1029
 
 
1030
 
                    for (i = 0; i < p->size; i++)
1031
 
                    {
1032
 
                        index_offsets [i] = total_size;
1033
 
                        total_size += index_sizes [i];
1034
 
                    }
1035
 
 
1036
 
                    recv_buffer = malloc (total_size);
1037
 
                    MPI_Gatherv (&size, 0, MPI_BYTE
1038
 
                                ,recv_buffer, index_sizes, index_offsets
1039
 
                                ,MPI_BYTE, 0, p->group_comm
1040
 
                                );
1041
 
 
1042
 
                    char * buffer_save = p->b.buff;
1043
 
                    uint64_t buffer_size_save = p->b.length;
1044
 
                    uint64_t offset_save = p->b.offset;
1045
 
 
1046
 
                    for (i = 1; i < p->size; i++)
1047
 
                    {
1048
 
                        p->b.buff = recv_buffer + index_offsets [i];
1049
 
                        p->b.length = index_sizes [i];
1050
 
                        p->b.offset = 0;
1051
 
 
1052
 
                        adios_parse_process_group_index_v1 (&p->b
1053
 
                                                           ,&new_pg_root
1054
 
                                                           );
1055
 
                        adios_parse_vars_index_v1 (&p->b, &new_vars_root);
1056
 
                        adios_parse_attributes_index_v1 (&p->b
1057
 
                                                        ,&new_attrs_root
1058
 
                                                        );
1059
 
 
1060
 
                        adios_merge_index_v1 (&p->old_pg_root
1061
 
                                             ,&p->old_vars_root
1062
 
                                             ,&p->old_attrs_root
1063
 
                                             ,new_pg_root, new_vars_root
1064
 
                                             ,new_attrs_root
1065
 
                                             );
1066
 
                        new_pg_root = 0;
1067
 
                        new_vars_root = 0;
1068
 
                        new_attrs_root = 0;
1069
 
                    }
1070
 
 
1071
 
                    p->b.buff = buffer_save;
1072
 
                    p->b.length = buffer_size_save;
1073
 
                    p->b.offset = offset_save;
1074
 
 
1075
 
                    free (recv_buffer);
1076
 
                    free (index_sizes);
1077
 
                    free (index_offsets);
1078
 
 
1079
 
                    char * global_index_buffer = 0;
1080
 
                    uint64_t global_index_buffer_size = 0;
1081
 
                    uint64_t global_index_buffer_offset = 0;
1082
 
                    uint64_t global_index_start = 0;
1083
 
                    uint16_t flag = 0;
1084
 
 
1085
 
                    adios_write_index_v1 (&global_index_buffer, &global_index_buffer_size
1086
 
                                         ,&global_index_buffer_offset, global_index_start
1087
 
                                         ,p->old_pg_root, p->old_vars_root, p->old_attrs_root
1088
 
                                         );
1089
 
 
1090
 
                    flag |= ADIOS_VERSION_HAVE_SUBFILE;
1091
 
 
1092
 
                    adios_write_version_flag_v1 (&global_index_buffer
1093
 
                                                ,&global_index_buffer_size
1094
 
                                                ,&global_index_buffer_offset
1095
 
                                                ,flag
1096
 
                                                );
1097
 
                    ssize_t s = write (p->mf, global_index_buffer, global_index_buffer_offset);
1098
 
                    if (s != global_index_buffer_offset)
1099
 
                    {
1100
 
                        fprintf (stderr, "POSIX method tried to write %llu, "
1101
 
                                         "only wrote %llu\n"
1102
 
                                         ,fd->bytes_written
1103
 
                                         ,s
1104
 
                                );
1105
 
                    }
1106
 
 
1107
 
                    close (p->mf);
1108
 
                }
1109
 
                else
1110
 
                {
1111
 
                                        // Added this explicit cast to avoid truncation of low-order bytes on BGP
1112
 
                                        int i_buffer_size = (int) buffer_size;
1113
 
                    MPI_Gather (&i_buffer_size, 1, MPI_INT
1114
 
                               ,0, 0, MPI_INT
1115
 
                               ,0, p->group_comm
1116
 
                               );
1117
 
 
1118
 
                    MPI_Gatherv (buffer, buffer_size, MPI_BYTE
1119
 
                                ,0, 0, 0, MPI_BYTE
1120
 
                                ,0, p->group_comm
1121
 
                                );
1122
 
                }
1123
 
            }
1124
 
#endif
1125
 
            free (buffer);
1126
 
 
1127
 
            adios_clear_index_v1 (new_pg_root, new_vars_root, new_attrs_root);
1128
 
 
1129
 
            break;
1130
 
        }
1131
 
 
1132
 
        case adios_mode_append:
1133
 
        {
1134
 
            if (fd->shared_buffer == adios_flag_no)
1135
 
            {
1136
 
                off_t new_off;
1137
 
                // set it up so that it will start at 0, but have correct sizes
1138
 
                new_off = lseek (p->b.f, 0, SEEK_CUR);
1139
 
                fd->offset = fd->base_offset - p->vars_start;
1140
 
                fd->vars_start = 0;
1141
 
                fd->buffer_size = 0;
1142
 
                adios_write_close_vars_v1 (fd);
1143
 
                // fd->vars_start gets updated with the size written
1144
 
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
1145
 
                ssize_t s = write (p->b.f, fd->buffer, p->vars_header_size);
1146
 
                if (s != fd->vars_start)
1147
 
                {
1148
 
                    fprintf (stderr, "POSIX method tried to write %llu, "
1149
 
                                     "only wrote %llu\n"
1150
 
                            ,fd->vars_start
1151
 
                            ,s
1152
 
                            );
1153
 
                }
1154
 
                fd->offset = 0;
1155
 
                fd->bytes_written = 0;
1156
 
                adios_shared_buffer_free (&p->b);
1157
 
 
1158
 
                new_off = lseek (p->b.f, new_off, SEEK_SET);  // go back to end
1159
 
                adios_write_open_attributes_v1 (fd);
1160
 
                p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR); // save loc
1161
 
                p->vars_header_size = p->vars_start - fd->base_offset;
1162
 
                p->vars_start -= fd->offset; // adjust to start of header
1163
 
                fd->base_offset += fd->offset;  // add size of header
1164
 
                fd->offset = 0;
1165
 
                fd->bytes_written = 0;
1166
 
 
1167
 
                while (a)
1168
 
                {
1169
 
                    adios_write_attribute_v1 (fd, a);
1170
 
                    ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
1171
 
                    if (s != fd->bytes_written)
1172
 
                    {
1173
 
                        fprintf (stderr, "POSIX method tried to write %llu, "
1174
 
                                         "only wrote %llu\n"
1175
 
                                ,fd->bytes_written
1176
 
                                ,s
1177
 
                                );
1178
 
                    }
1179
 
                    fd->base_offset += s;
1180
 
                    fd->offset = 0;
1181
 
                    fd->bytes_written = 0;
1182
 
                    adios_shared_buffer_free (&p->b);
1183
 
 
1184
 
                    a = a->next;
1185
 
                }
1186
 
 
1187
 
                // set it up so that it will start at 0, but have correct sizes
1188
 
                fd->offset = fd->base_offset - p->vars_start;
1189
 
                fd->vars_start = 0;
1190
 
                fd->buffer_size = 0;
1191
 
                adios_write_close_attributes_v1 (fd);
1192
 
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
1193
 
                // fd->vars_start gets updated with the size written
1194
 
                s = write (p->b.f, fd->buffer, p->vars_header_size);
1195
 
                if (s != p->vars_header_size)
1196
 
                {
1197
 
                    fprintf (stderr, "POSIX method tried to write %llu, "
1198
 
                                     "only wrote %llu\n"
1199
 
                            ,p->vars_header_size
1200
 
                            ,s
1201
 
                            );
1202
 
                }
1203
 
                fd->offset = 0;
1204
 
                fd->bytes_written = 0;
1205
 
            }
1206
 
 
1207
 
            char * buffer = 0;
1208
 
            uint64_t buffer_size = 0;
1209
 
            uint64_t buffer_offset = 0;
1210
 
            uint64_t index_start = fd->base_offset + fd->offset;
1211
 
 
1212
 
            // build index
1213
 
            adios_build_index_v1 (fd, &p->old_pg_root, &p->old_vars_root
1214
 
                                 ,&p->old_attrs_root
1215
 
                                 );
1216
 
            adios_write_index_v1 (&buffer, &buffer_size, &buffer_offset
1217
 
                                 ,index_start, p->old_pg_root, p->old_vars_root
1218
 
                                 ,p->old_attrs_root
1219
 
                                 );
1220
 
#ifdef HAVE_MPI
1221
 
            if (p->group_comm != MPI_COMM_SELF)
1222
 
            {
1223
 
                if (p->rank == 0)
1224
 
                {
1225
 
                    int * index_sizes = malloc (4 * p->size);
1226
 
                    int * index_offsets = malloc (4 * p->size);
1227
 
                    char * recv_buffer = 0;
1228
 
                    int i;
1229
 
                    uint32_t size = 0, total_size = 0;
1230
 
 
1231
 
                    MPI_Gather (&size, 1, MPI_INT
1232
 
                               ,index_sizes, 1, MPI_INT
1233
 
                               ,0, p->group_comm
1234
 
                               );
1235
 
 
1236
 
                    for (i = 0; i < p->size; i++)
1237
 
                    {
1238
 
                        index_offsets [i] = total_size;
1239
 
                        total_size += index_sizes [i];
1240
 
                    }
1241
 
 
1242
 
                    recv_buffer = malloc (total_size);
1243
 
                    MPI_Gatherv (&size, 0, MPI_BYTE
1244
 
                                ,recv_buffer, index_sizes, index_offsets
1245
 
                                ,MPI_BYTE, 0, p->group_comm
1246
 
                                );
1247
 
 
1248
 
                    char * buffer_save = p->b.buff;
1249
 
                    uint64_t buffer_size_save = p->b.length;
1250
 
                    uint64_t offset_save = p->b.offset;
1251
 
 
1252
 
                    for (i = 1; i < p->size; i++)
1253
 
                    {
1254
 
                        p->b.buff = recv_buffer + index_offsets [i];
1255
 
                        p->b.length = index_sizes [i];
1256
 
                        p->b.offset = 0;
1257
 
 
1258
 
                        adios_parse_process_group_index_v1 (&p->b
1259
 
                                                           ,&new_pg_root
1260
 
                                                           );
1261
 
                        adios_parse_vars_index_v1 (&p->b, &new_vars_root);
1262
 
                        adios_parse_attributes_index_v1 (&p->b
1263
 
                                                        ,&new_attrs_root
1264
 
                                                        );
1265
 
 
1266
 
                        adios_merge_index_v1 (&p->old_pg_root
1267
 
                                             ,&p->old_vars_root
1268
 
                                             ,&p->old_attrs_root
1269
 
                                             ,new_pg_root, new_vars_root
1270
 
                                             ,new_attrs_root
1271
 
                                             );
1272
 
                    
1273
 
                        new_pg_root = 0;
1274
 
                        new_vars_root = 0;
1275
 
                        new_attrs_root = 0;
1276
 
                    }
1277
 
 
1278
 
                    adios_sort_index_v1 (&p->old_pg_root
1279
 
                                        ,&p->old_vars_root
1280
 
                                        ,&p->old_attrs_root
1281
 
                                        );
1282
 
 
1283
 
                    p->b.buff = buffer_save;
1284
 
                    p->b.length = buffer_size_save;
1285
 
                    p->b.offset = offset_save;
1286
 
 
1287
 
                    free (recv_buffer);
1288
 
                    free (index_sizes);
1289
 
                    free (index_offsets);
1290
 
 
1291
 
                    char * global_index_buffer = 0;
1292
 
                    uint64_t global_index_buffer_size = 0;
1293
 
                    uint64_t global_index_buffer_offset = 0;
1294
 
                    uint64_t global_index_start = 0;
1295
 
                    uint16_t flag = 0;
1296
 
 
1297
 
                    adios_write_index_v1 (&global_index_buffer, &global_index_buffer_size
1298
 
                                         ,&global_index_buffer_offset, global_index_start
1299
 
                                         ,p->old_pg_root, p->old_vars_root, p->old_attrs_root
1300
 
                                         );
1301
 
 
1302
 
                    flag |= ADIOS_VERSION_HAVE_SUBFILE;
1303
 
 
1304
 
                    adios_write_version_flag_v1 (&global_index_buffer
1305
 
                                                ,&global_index_buffer_size
1306
 
                                                ,&global_index_buffer_offset
1307
 
                                                ,flag
1308
 
                                                );
1309
 
 
1310
 
                    ssize_t s = write (p->mf, global_index_buffer, global_index_buffer_offset);
1311
 
                    if (s != global_index_buffer_offset)
1312
 
                    {
1313
 
                        fprintf (stderr, "POSIX method tried to write %llu, "
1314
 
                                         "only wrote %llu, Mode: a\n"
1315
 
                                         ,global_index_buffer_offset
1316
 
                                         ,s
1317
 
                                );
1318
 
                    }
1319
 
 
1320
 
                    close (p->mf);
1321
 
 
1322
 
                    free (global_index_buffer);
1323
 
                }
1324
 
                else
1325
 
                {
1326
 
                    MPI_Gather (&buffer_size, 1, MPI_INT
1327
 
                               ,0, 0, MPI_INT
1328
 
                               ,0, p->group_comm
1329
 
                               );
1330
 
 
1331
 
                    MPI_Gatherv (buffer, buffer_size, MPI_BYTE
1332
 
                                ,0, 0, 0, MPI_BYTE
1333
 
                                ,0, p->group_comm
1334
 
                                );
1335
 
                }
1336
 
            }
1337
 
#endif
1338
 
            adios_write_version_v1 (&buffer, &buffer_size, &buffer_offset);
1339
 
            adios_posix_do_write (fd, method, buffer, buffer_offset);
1340
 
 
1341
 
            free (buffer);
1342
 
 
1343
 
            break;
1344
 
        }
1345
 
 
1346
 
        case adios_mode_read:
1347
 
        {
1348
 
            // read the index to find the place to start reading
1349
 
            adios_posix_do_read (fd, method);
1350
 
            struct adios_var_struct * v = fd->group->vars;
1351
 
            while (v)
1352
 
            {
1353
 
                v->data = 0;
1354
 
                v = v->next;
1355
 
            }
1356
 
 
1357
 
            break;
1358
 
        }
1359
 
 
1360
 
        default:
1361
 
        {
1362
 
            fprintf (stderr, "Unknown file mode: %d\n", fd->mode);
1363
 
 
1364
 
            return;
1365
 
        }
1366
 
    }
1367
 
 
1368
 
    adios_posix_close_internal (&p->b);
1369
 
    adios_clear_index_v1 (p->old_pg_root, p->old_vars_root, p->old_attrs_root);
1370
 
    p->old_pg_root = 0;
1371
 
    p->old_vars_root = 0;
1372
 
    p->old_attrs_root = 0;
1373
 
}
1374
 
 
1375
 
void adios_posix_finalize (int mype, struct adios_method_struct * method)
1376
 
{
1377
 
// nothing to do here
1378
 
    if (adios_posix_initialized)
1379
 
        adios_posix_initialized = 0;
1380
 
}
1381
 
 
1382
 
void adios_posix_end_iteration (struct adios_method_struct * method)
1383
 
{
1384
 
}
1385
 
 
1386
 
void adios_posix_start_calculation (struct adios_method_struct * method)
1387
 
{
1388
 
}
1389
 
 
1390
 
void adios_posix_stop_calculation (struct adios_method_struct * method)
1391
 
{
1392
 
}