예제 #1
0
파일: bpdump.c 프로젝트: wjlei1990/ADIOS
int main (int argc, char ** argv)
{
    char * filename;
    int rc = 0;
    struct dump_struct dump;

    if (argc < 2 || argc > 4)
    {
        fprintf (stderr, "usage: %s [-d [var]|--dump [var]] <filename>\n"
                ,argv [0]
                );

        return -1;
    }

    if (argv [1][0] && argv [1][0] == '-')
    {
        if (   !strcmp (argv [1], "-d")
            || !strcmp (argv [1], "--dump")
           )
        {
            dump.do_dump = 1;
            if (argc > 3)
            {
                dump.dump_var = argv [2];
                filename = argv [3];
                printf("%s %s\n",dump.dump_var,filename);
            }
            else
            {
                dump.dump_var = 0;
                filename = argv [2];
                printf("ALLVARS %s\n",filename);
            }
        }
        else
        {
            fprintf (stderr, "usage: %s [-d [var]|--dump [var]] <filename>\n"
                    ,argv [0]
                    );

            return -1;
        }
    }
    else
    {
        filename = argv [1];
        dump.do_dump = 0;
        dump.dump_var = 0;
    }

    have_subfiles = 0;
    struct adios_bp_buffer_struct_v1 * b = 0;
    uint32_t version = 0;

    b = malloc (sizeof (struct adios_bp_buffer_struct_v1));
    adios_buffer_struct_init (b);

    rc = adios_posix_open_read_internal (filename, "", b);
    if (!rc)
    {
        fprintf (stderr, "bpdump: file not found: %s\n", filename);

        return -1;
    }

    adios_posix_read_version (b);
    adios_parse_version (b, &version);
    version = version & ADIOS_VERSION_NUM_MASK;
    printf ("BP format version: %d\n", version);
    if (version < 2)
    {
        fprintf (stderr, "bpdump: This version of bpdump can only dump BP format version 2. "
                 "Use an older bpdump from adios 1.6 to dump this file.\n");
        adios_posix_close_internal (b);
        return -1;
    }

    struct adios_index_process_group_struct_v1 * pg_root = 0;
    struct adios_index_process_group_struct_v1 * pg = 0;
    struct adios_index_var_struct_v1 * vars_root = 0;
    struct adios_index_attribute_struct_v1 * attrs_root = 0;

    printf (DIVIDER);
    printf ("Process Groups Index:\n");
    adios_posix_read_index_offsets (b);
    adios_parse_index_offsets_v1 (b);

    /*
    printf ("End of process groups       = %" PRIu64 "\n", b->end_of_pgs);
    printf ("Process Groups Index Offset = %" PRIu64 "\n", b->pg_index_offset);
    printf ("Process Groups Index Size   = %" PRIu64 "\n", b->pg_size);
    printf ("Variable Index Offset       = %" PRIu64 "\n", b->vars_index_offset);
    printf ("Variable Index Size         = %" PRIu64 "\n", b->vars_size);
    printf ("Attribute Index Offset      = %" PRIu64 "\n", b->attrs_index_offset);
    printf ("Attribute Index Size        = %" PRIu64 "\n", b->attrs_size);
    */

    adios_posix_read_process_group_index (b);
    adios_parse_process_group_index_v1 (b, &pg_root, NULL);
    print_process_group_index (pg_root);

    printf (DIVIDER);
    printf ("Vars Index:\n");
    adios_posix_read_vars_index (b);
    adios_parse_vars_index_v1 (b, &vars_root, NULL, NULL);
    print_vars_index (vars_root);

    printf (DIVIDER);
    printf ("Attributes Index:\n");
    adios_posix_read_attributes_index (b);
    adios_parse_attributes_index_v1 (b, &attrs_root);
    print_attributes_index (attrs_root);

    if (version & ADIOS_VERSION_HAVE_SUBFILE)
    {
        printf (DIVIDER);
        return 0;
    }


    uint64_t pg_num = 0;
    pg = pg_root;
    while (pg)
    {

        pg_num++;
        /* Avoid processing PG's whose offset is beyond the start of index (they are actually in subfiles) */
        /* Note: only variables have subfile index, PG's don't so we need to be this indirect in the test */
        if (pg->offset_in_file >= b->pg_index_offset) 
        {
            printf ("Process Group %" PRIu64 " offset is beyond the footer.", pg_num);
            if (have_subfiles) {
                printf (" It is probably in a subfile but bpdump does not process subfiles.\n");
            } else {
                printf (" Since there are no subfiles, this probably means the BP file is corrupt.\n"
                        "offset=%" PRIu64 "  footer starts at %" PRIu64 "\n", pg->offset_in_file, b->pg_index_offset);
            }
            pg = pg->next;
            continue;
        }

        int var_dims_count = 0;
        struct var_dim * var_dims = 0;

        printf (DIVIDER);

        struct adios_process_group_header_struct_v1 pg_header;
        struct adios_vars_header_struct_v1 vars_header;
        struct adios_attributes_header_struct_v1 attrs_header;

        struct adios_var_header_struct_v1 var_header;
        struct adios_var_payload_struct_v1 var_payload;
        struct adios_attribute_struct_v1 attribute;

        // setup where to read the process group from (and size)
        b->read_pg_offset = pg->offset_in_file;
        if (pg->next)
        {
            b->read_pg_size =   pg->next->offset_in_file
                              - pg->offset_in_file;
        }
        else
        {
            b->read_pg_size =   b->pg_index_offset
                              - pg->offset_in_file;
        }

        adios_posix_read_process_group (b);
        adios_parse_process_group_header_v1 (b, &pg_header);
        print_process_group_header (pg_num, &pg_header);
        //printf ("\tSize of group in fil: %" PRIu64 " bytes\n",  b->read_pg_size);

        adios_parse_vars_header_v1 (b, &vars_header);
        print_vars_header (&vars_header);

        dump.host_language_fortran = pg_header.host_language_fortran;
        int i;
        for (i = 0; i < vars_header.count; i++)
        {
            var_payload.payload = 0;

            adios_parse_var_data_header_v1 (b, &var_header);
            print_var_header (&var_header);

            if ( var_header.dims == 0 || 
                 ( dump.do_dump &&
                   dump.dump_var &&
                   !strcasecmp (dump.dump_var, var_header.name)
                 )
               )
            {
                // add one for string null terminators
                var_payload.payload = malloc (var_header.payload_size + 1);
                adios_parse_var_data_payload_v1 (b, &var_header, &var_payload
                                                ,var_header.payload_size
                                                );
            }
            else
            {
                adios_parse_var_data_payload_v1 (b, &var_header, NULL, 0);
            }

            if (var_header.is_dim == adios_flag_yes)
            {
                var_dims = realloc (var_dims,   (var_dims_count + 1)
                                              * sizeof (struct var_dim)
                                   );

                var_dims [var_dims_count].id = var_header.id;
                var_dims [var_dims_count].rank = *(unsigned int *)
                                                        var_payload.payload;
                var_dims_count++;
            }

            if (dump.do_dump)
            {
                // make sure the buffer is big enough or send in null
                print_var_payload (&var_header, &var_payload, &dump
                                  ,var_dims_count, var_dims
                                  );
            }
            if (var_payload.payload)
            {
                free (var_payload.payload);
                var_payload.payload = 0;
            }
            printf ("\n");
        }

        adios_parse_attributes_header_v1 (b, &attrs_header);
        print_attrs_header (&attrs_header);

        for (i = 0; i < attrs_header.count; i++)
        {
            adios_parse_attribute_v1 (b, &attribute);
            print_attribute (&attribute);
            printf ("\n");
        }

        var_dims_count = 0;
        if (var_dims)
            free (var_dims);
        pg = pg->next;
    }
    printf (DIVIDER);
    printf ("End of %s\n", filename);

    adios_posix_close_internal (b);

    return 0;
}
예제 #2
0
파일: bpmeta.c 프로젝트: Dumbear/ADIOS
int process_subfiles (int tid, int startidx, int endidx)
{
    char fn[256];
    uint32_t version = 0;
    int idx;
    int rc = 0;

    subindex[tid] = adios_alloc_index_v1(1);

    for (idx=startidx; idx<=endidx; idx++) 
    {
        b[idx] = malloc (sizeof (struct adios_bp_buffer_struct_v1));
        adios_buffer_struct_init (b[idx]);

        snprintf (fn, 256, "%s.dir/%s.%d", filename, filename, idx);
        rc = adios_posix_open_read_internal (fn, "", b[idx]);
        if (!rc)
        {
            fprintf (stderr, "bpmeta: file not found: %s\n", fn);
            return -1;
        }

        adios_posix_read_version (b[idx]);
        adios_parse_version (b[idx], &version);
        version = version & ADIOS_VERSION_NUM_MASK;
        if (verbose) {
            //printf (DIVIDER);
            printf ("Thread %d: Metadata of %s:\n", tid, fn);
            printf ("Thread %d: BP format version: %d\n", tid, version);
        }
        if (version < 2)
        {
            fprintf (stderr, "bpmeta: This version of bpmeta can only work with BP format version 2 and up. "
                    "Use an older bpmeta from adios 1.6 to work with this file.\n");
            adios_posix_close_internal (b[idx]);
            return -1;
        }

        struct adios_index_process_group_struct_v1 * new_pg_root = 0;
        struct adios_index_var_struct_v1 * new_vars_root = 0;
        struct adios_index_attribute_struct_v1 * new_attrs_root = 0;

        adios_posix_read_index_offsets (b[idx]);
        adios_parse_index_offsets_v1 (b[idx]);

        /*
           printf ("End of process groups       = %llu\n", b->end_of_pgs);
           printf ("Process Groups Index Offset = %llu\n", b->pg_index_offset);
           printf ("Process Groups Index Size   = %llu\n", b->pg_size);
           printf ("Variable Index Offset       = %llu\n", b->vars_index_offset);
           printf ("Variable Index Size         = %llu\n", b->vars_size);
           printf ("Attribute Index Offset      = %llu\n", b->attrs_index_offset);
           printf ("Attribute Index Size        = %llu\n", b->attrs_size);
         */

        adios_posix_read_process_group_index (b[idx]);
        adios_parse_process_group_index_v1 (b[idx], &new_pg_root);
        print_pg_index (tid, new_pg_root);

        adios_posix_read_vars_index (b[idx]);
        adios_parse_vars_index_v1 (b[idx], &new_vars_root, NULL, NULL);
        print_variable_index (tid, new_vars_root);

        adios_posix_read_attributes_index (b[idx]);
        adios_parse_attributes_index_v1 (b[idx], &new_attrs_root);
        print_attribute_index (tid, new_attrs_root);

        adios_merge_index_v1 (subindex[tid], new_pg_root, new_vars_root, new_attrs_root); 

        adios_posix_close_internal (b[idx]);
        adios_shared_buffer_free (b[idx]);

    }

    if (verbose>1) {
        //printf (DIVIDER);
        printf ("Thread %d: End of reading all subfiles\n", tid);
    }


    return 0;
}
예제 #3
0
파일: adios_posix1.c 프로젝트: npe9/ADIOS
void adios_posix1_close (struct adios_file_struct * fd
                       ,struct adios_method_struct * method
                       )
{
    struct adios_POSIX1_data_struct * p = (struct adios_POSIX1_data_struct *)
                                                          method->method_data;
    struct adios_attribute_struct * a = fd->group->attributes;

    switch (fd->mode)
    {
        case adios_mode_write:
        {
            if (fd->shared_buffer == adios_flag_no)
            {
                off_t new_off;
                // set it up so that it will start at 0, but have correct sizes
                new_off = lseek (p->b.f, 0, SEEK_CUR);
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_vars_v1 (fd);
                // fd->vars_start gets updated with the size written
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                ssize_t s = write (p->b.f, fd->buffer, p->vars_header_size);
                if (s != fd->vars_start)
                {
                    fprintf (stderr, "POSIX1 method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,fd->vars_start
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
                adios_shared_buffer_free (&p->b);

                new_off = lseek (p->b.f, new_off, SEEK_SET);  // go back to end
                adios_write_open_attributes_v1 (fd);
                p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR); // save loc
                p->vars_header_size = p->vars_start - fd->base_offset;
                p->vars_start -= fd->offset; // adjust to start of header
                fd->base_offset += fd->offset;  // add size of header
                fd->offset = 0;
                fd->bytes_written = 0;

                while (a)
                {
                    adios_write_attribute_v1 (fd, a);
                    if (fd->base_offset + fd->bytes_written > fd->pg_start_in_file + fd->write_size_bytes)
                        fprintf (stderr, "adios_posix1_write exceeds pg bound. File is corrupted. "
                                         "Need to enlarge group size. \n");
                    ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
                    if (s != fd->bytes_written)
                    {
                        fprintf (stderr, "POSIX1 method tried to write %llu, "
                                         "only wrote %lld\n"
                                ,fd->bytes_written
                                ,(int64_t)s
                                );
                    }
                    fd->base_offset += s;
                    fd->offset = 0;
                    fd->bytes_written = 0;
                    adios_shared_buffer_free (&p->b);

                    a = a->next;
                }

                // set it up so that it will start at 0, but have correct sizes
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_attributes_v1 (fd);
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                // fd->vars_start gets updated with the size written
                s = write (p->b.f, fd->buffer, p->vars_header_size);
                if (s != p->vars_header_size)
                {
                    fprintf (stderr, "POSIX1 method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,p->vars_header_size
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
            }

            // buffering or not, write the index
            char * buffer = 0;
            uint64_t buffer_size = 0;
            uint64_t buffer_offset = 0;
            uint64_t index_start = fd->base_offset + fd->offset;

            // build index
            adios_build_index_v1 (fd, p->index);
            adios_write_index_v1 (&buffer, &buffer_size, &buffer_offset
                                 ,index_start, p->index);
            adios_write_version_v1 (&buffer, &buffer_size, &buffer_offset);
            adios_posix1_do_write (fd, method, buffer, buffer_offset);

            free (buffer);

            break;
        }

        case adios_mode_append:
        {
            if (fd->shared_buffer == adios_flag_no)
            {
                off_t new_off;
                // set it up so that it will start at 0, but have correct sizes
                new_off = lseek (p->b.f, 0, SEEK_CUR);
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_vars_v1 (fd);
                // fd->vars_start gets updated with the size written
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                ssize_t s = write (p->b.f, fd->buffer, p->vars_header_size);
                if (s != fd->vars_start)
                {
                    fprintf (stderr, "POSIX1 method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,fd->vars_start
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
                adios_shared_buffer_free (&p->b);

                new_off = lseek (p->b.f, new_off, SEEK_SET);  // go back to end
                adios_write_open_attributes_v1 (fd);
                p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR); // save loc
                p->vars_header_size = p->vars_start - fd->base_offset;
                p->vars_start -= fd->offset; // adjust to start of header
                fd->base_offset += fd->offset;  // add size of header
                fd->offset = 0;
                fd->bytes_written = 0;

                while (a)
                {
                    adios_write_attribute_v1 (fd, a);
                    ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
                    if (s != fd->bytes_written)
                    {
                        fprintf (stderr, "POSIX1 method tried to write %llu, "
                                         "only wrote %lld\n"
                                ,fd->bytes_written
                                ,(int64_t)s
                                );
                    }
                    fd->base_offset += s;
                    fd->offset = 0;
                    fd->bytes_written = 0;
                    adios_shared_buffer_free (&p->b);

                    a = a->next;
                }

                // set it up so that it will start at 0, but have correct sizes
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_attributes_v1 (fd);
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                // fd->vars_start gets updated with the size written
                s = write (p->b.f, fd->buffer, p->vars_header_size);
                if (s != p->vars_header_size)
                {
                    fprintf (stderr, "POSIX1 method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,p->vars_header_size
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
            }

            char * buffer = 0;
            uint64_t buffer_size = 0;
            uint64_t buffer_offset = 0;
            uint64_t index_start = fd->base_offset + fd->offset;

            // build index. Note: It merges with old indices already stored 
            //                    in p->index in adios_posix_open's append case
            adios_build_index_v1 (fd, p->index);
            // merge in old indicies
            //adios_merge_index_v1 (p->index, new_pg_root, 
            //                      new_vars_root, new_attrs_root
            //                     );
            adios_write_index_v1 (&buffer, &buffer_size, &buffer_offset
                                 ,index_start, p->index);
            adios_write_version_v1 (&buffer, &buffer_size, &buffer_offset);
            adios_posix1_do_write (fd, method, buffer, buffer_offset);

            free (buffer);

            break;
        }

        case adios_mode_read:
        {
            // read the index to find the place to start reading
            adios_posix1_do_read (fd, method);
            struct adios_var_struct * v = fd->group->vars;
            while (v)
            {
                v->data = 0;
                v = v->next;
            }

            break;
        }

        default:
        {
            fprintf (stderr, "Unknown file mode: %d\n", fd->mode);

            return;
        }
    }

    adios_posix_close_internal (&p->b);
    adios_clear_index_v1 (p->index);
}
예제 #4
0
파일: adios_posix.c 프로젝트: acbauer/ADIOS
void adios_posix_close (struct adios_file_struct * fd
                       ,struct adios_method_struct * method
                       )
{
    struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *)
                                                          method->method_data;
    struct adios_attribute_struct * a = fd->group->attributes;

    struct adios_index_process_group_struct_v1 * new_pg_root = 0;
    struct adios_index_var_struct_v1 * new_vars_root = 0;
    struct adios_index_attribute_struct_v1 * new_attrs_root = 0;

    START_TIMER (ADIOS_TIMER_POSIX_AD_CLOSE);

    switch (fd->mode)
    {
        case adios_mode_write:
        {
            if (fd->shared_buffer == adios_flag_no)
            {
                off_t new_off;
                // set it up so that it will start at 0, but have correct sizes
                new_off = lseek (p->b.f, 0, SEEK_CUR);
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_vars_v1 (fd);
                // fd->vars_start gets updated with the size written
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                START_TIMER (ADIOS_TIMER_POSIX_IO);
                ssize_t s = write (p->b.f, fd->buffer, p->vars_header_size);
                STOP_TIMER (ADIOS_TIMER_POSIX_IO);
                if (s != fd->vars_start)
                {
                    fprintf (stderr, "POSIX method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,fd->vars_start
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
                adios_shared_buffer_free (&p->b);

                new_off = lseek (p->b.f, new_off, SEEK_SET);  // go back to end
                adios_write_open_attributes_v1 (fd);
                p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR); // save loc
                p->vars_header_size = p->vars_start - fd->base_offset;
                p->vars_start -= fd->offset; // adjust to start of header
                fd->base_offset += fd->offset;  // add size of header
                fd->offset = 0;
                fd->bytes_written = 0;

                if (!fd->group->process_id) { // from ADIOS 1.4, only rank 0 writes attributes
                    while (a)
                    {
                        adios_write_attribute_v1 (fd, a);
                        if (fd->base_offset + fd->bytes_written > fd->pg_start_in_file + fd->write_size_bytes)
                            fprintf (stderr, "adios_posix_write exceeds pg bound. File is corrupted. "
                                    "Need to enlarge group size. \n");
                        START_TIMER (ADIOS_TIMER_POSIX_MD);
                        ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
                        STOP_TIMER (ADIOS_TIMER_POSIX_MD);
                        if (s != fd->bytes_written)
                        {
                            fprintf (stderr, "POSIX method tried to write %llu, "
                                    "only wrote %lld\n"
                                    ,fd->bytes_written
                                    ,(int64_t)s
                                    );
                        }
                        fd->base_offset += s;
                        fd->offset = 0;
                        fd->bytes_written = 0;
                        adios_shared_buffer_free (&p->b);

                        a = a->next;
                    }
                }

                // set it up so that it will start at 0, but have correct sizes
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_attributes_v1 (fd);
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                // fd->vars_start gets updated with the size written
                START_TIMER (ADIOS_TIMER_POSIX_MD);
                s = write (p->b.f, fd->buffer, p->vars_header_size);
                STOP_TIMER (ADIOS_TIMER_POSIX_MD);
                if (s != p->vars_header_size)
                {
                    fprintf (stderr, "POSIX method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,p->vars_header_size
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
            }

            // buffering or not, write the index
            char * buffer = 0;
            uint64_t buffer_size = 0;
            uint64_t buffer_offset = 0;
            uint64_t index_start = fd->base_offset + fd->offset;

            // build index
            adios_build_index_v1 (fd, p->index);
            // if collective, gather the indexes from the rest and call
            // adios_merge_index_v1 (&new_pg_root, &new_vars_root, pg, vars);
            adios_write_index_v1 (&buffer, &buffer_size, &buffer_offset
                                 ,index_start, p->index);
            adios_write_version_v1 (&buffer, &buffer_size, &buffer_offset);
            START_TIMER (ADIOS_TIMER_POSIX_IO);
            adios_posix_do_write (fd, method, buffer, buffer_offset); // Buffered vars written here
            STOP_TIMER (ADIOS_TIMER_POSIX_IO);
#ifdef HAVE_MPI
            if (p->group_comm != MPI_COMM_SELF)
            {
                if (p->rank == 0)
                {
                    int * index_sizes = malloc (4 * p->size);
                    int * index_offsets = malloc (4 * p->size);
                    char * recv_buffer = 0;
                    int i;
                    uint32_t size = 0, total_size = 0;

                    START_TIMER (ADIOS_TIMER_POSIX_COMM);
                    MPI_Gather (&size, 1, MPI_INT
                               ,index_sizes, 1, MPI_INT
                               ,0, p->group_comm
                               );
                    STOP_TIMER (ADIOS_TIMER_POSIX_COMM);

                    for (i = 0; i < p->size; i++)
                    {
                        index_offsets [i] = total_size;
                        total_size += index_sizes [i];
                    }

                    recv_buffer = malloc (total_size);
                    START_TIMER (ADIOS_TIMER_POSIX_COMM);
                    MPI_Gatherv (&size, 0, MPI_BYTE
                                ,recv_buffer, index_sizes, index_offsets
                                ,MPI_BYTE, 0, p->group_comm
                                );
                    STOP_TIMER (ADIOS_TIMER_POSIX_COMM);

                    char * buffer_save = p->b.buff;
                    uint64_t buffer_size_save = p->b.length;
                    uint64_t offset_save = p->b.offset;

                    for (i = 1; i < p->size; i++)
                    {
                        p->b.buff = recv_buffer + index_offsets [i];
                        p->b.length = index_sizes [i];
                        p->b.offset = 0;

                        adios_parse_process_group_index_v1 (&p->b
                                                           ,&new_pg_root
                                                           );
                        adios_parse_vars_index_v1 (&p->b, &new_vars_root, NULL, NULL);
                        // do not merge attributes from other processes from 1.4
                        /*
                        adios_parse_attributes_index_v1 (&p->b
                                                        ,&new_attrs_root
                                                        );
                        */

                        adios_merge_index_v1 (p->index, new_pg_root, 
                                              new_vars_root, new_attrs_root);
                        new_pg_root = 0;
                        new_vars_root = 0;
                        new_attrs_root = 0;
                    }

                    p->b.buff = buffer_save;
                    p->b.length = buffer_size_save;
                    p->b.offset = offset_save;

                    free (recv_buffer);
                    free (index_sizes);
                    free (index_offsets);

                    char * global_index_buffer = 0;
                    uint64_t global_index_buffer_size = 0;
                    uint64_t global_index_buffer_offset = 0;
                    uint64_t global_index_start = 0;
                    uint16_t flag = 0;

                    adios_write_index_v1 (&global_index_buffer, &global_index_buffer_size
                                         ,&global_index_buffer_offset, global_index_start
                                         ,p->index);

                    flag |= ADIOS_VERSION_HAVE_SUBFILE;

                    adios_write_version_flag_v1 (&global_index_buffer
                                                ,&global_index_buffer_size
                                                ,&global_index_buffer_offset
                                                ,flag
                                                );
                    START_TIMER (ADIOS_TIMER_POSIX_MD);
                    ssize_t s = write (p->mf, global_index_buffer, global_index_buffer_offset);
                    STOP_TIMER (ADIOS_TIMER_POSIX_MD);
                    if (s != global_index_buffer_offset)
                    {
                        fprintf (stderr, "POSIX method tried to write %llu, "
                                         "only wrote %lld\n"
                                         ,fd->bytes_written
                                         ,(int64_t)s
                                );
                    }

                    close (p->mf);
                }
                else
                {
                    START_TIMER (ADIOS_TIMER_POSIX_COMM);
                    // Added this explicit cast to avoid truncation of low-order bytes on BGP
                    int i_buffer_size = (int) buffer_size;
                    MPI_Gather (&i_buffer_size, 1, MPI_INT
                               ,0, 0, MPI_INT
                               ,0, p->group_comm
                               );

                    MPI_Gatherv (buffer, buffer_size, MPI_BYTE
                                ,0, 0, 0, MPI_BYTE
                                ,0, p->group_comm
                                );
                    STOP_TIMER (ADIOS_TIMER_POSIX_COMM);
                }
            }
#endif
            free (buffer);

            break;
        }

        case adios_mode_append:
        case adios_mode_update:
        {
            if (fd->shared_buffer == adios_flag_no)
            {
                off_t new_off;
                // set it up so that it will start at 0, but have correct sizes
                new_off = lseek (p->b.f, 0, SEEK_CUR);
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_vars_v1 (fd);
                // fd->vars_start gets updated with the size written
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                START_TIMER (ADIOS_TIMER_POSIX_IO);
                ssize_t s = write (p->b.f, fd->buffer, p->vars_header_size);
                STOP_TIMER (ADIOS_TIMER_POSIX_IO);
                if (s != fd->vars_start)
                {
                    fprintf (stderr, "POSIX method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,fd->vars_start
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
                adios_shared_buffer_free (&p->b);

                new_off = lseek (p->b.f, new_off, SEEK_SET);  // go back to end
                adios_write_open_attributes_v1 (fd);
                p->vars_start = lseek (p->b.f, fd->offset, SEEK_CUR); // save loc
                p->vars_header_size = p->vars_start - fd->base_offset;
                p->vars_start -= fd->offset; // adjust to start of header
                fd->base_offset += fd->offset;  // add size of header
                fd->offset = 0;
                fd->bytes_written = 0;

                if (!fd->group->process_id) { // from ADIOS 1.4, only rank 0 writes attributes
                    while (a)
                    {
                        adios_write_attribute_v1 (fd, a);
                        START_TIMER (ADIOS_TIMER_POSIX_MD);
                        ssize_t s = write (p->b.f, fd->buffer, fd->bytes_written);
                        STOP_TIMER (ADIOS_TIMER_POSIX_MD);
                        if (s != fd->bytes_written)
                        {
                            fprintf (stderr, "POSIX method tried to write %llu, "
                                    "only wrote %lld\n"
                                    ,fd->bytes_written
                                    ,(int64_t)s
                                    );
                        }
                        fd->base_offset += s;
                        fd->offset = 0;
                        fd->bytes_written = 0;
                        adios_shared_buffer_free (&p->b);

                        a = a->next;
                    }
                }

                // set it up so that it will start at 0, but have correct sizes
                fd->offset = fd->base_offset - p->vars_start;
                fd->vars_start = 0;
                fd->buffer_size = 0;
                adios_write_close_attributes_v1 (fd);
                fd->offset = lseek (p->b.f, p->vars_start, SEEK_SET);
                // fd->vars_start gets updated with the size written
                START_TIMER (ADIOS_TIMER_POSIX_MD);
                s = write (p->b.f, fd->buffer, p->vars_header_size);
                STOP_TIMER (ADIOS_TIMER_POSIX_MD);
                if (s != p->vars_header_size)
                {
                    fprintf (stderr, "POSIX method tried to write %llu, "
                                     "only wrote %lld\n"
                            ,p->vars_header_size
                            ,(int64_t)s
                            );
                }
                fd->offset = 0;
                fd->bytes_written = 0;
            }

            char * buffer = 0;
            uint64_t buffer_size = 0;
            uint64_t buffer_offset = 0;
            uint64_t index_start = fd->base_offset + fd->offset;

            // build index
            adios_build_index_v1 (fd, p->index);
            adios_write_index_v1 (&buffer, &buffer_size, &buffer_offset
                                 ,index_start, p->index);
#ifdef HAVE_MPI
            if (p->group_comm != MPI_COMM_SELF)
            {
                if (p->rank == 0)
                {
                    int * index_sizes = malloc (4 * p->size);
                    int * index_offsets = malloc (4 * p->size);
                    char * recv_buffer = 0;
                    int i;
                    uint32_t size = 0, total_size = 0;

                    START_TIMER (ADIOS_TIMER_POSIX_COMM);
                    MPI_Gather (&size, 1, MPI_INT
                               ,index_sizes, 1, MPI_INT
                               ,0, p->group_comm
                               );
                    STOP_TIMER (ADIOS_TIMER_POSIX_COMM);

                    for (i = 0; i < p->size; i++)
                    {
                        index_offsets [i] = total_size;
                        total_size += index_sizes [i];
                    }

                    recv_buffer = malloc (total_size);

                    START_TIMER (ADIOS_TIMER_POSIX_COMM);
                    MPI_Gatherv (&size, 0, MPI_BYTE
                                ,recv_buffer, index_sizes, index_offsets
                                ,MPI_BYTE, 0, p->group_comm
                                );
                    STOP_TIMER (ADIOS_TIMER_POSIX_COMM);

                    char * buffer_save = p->b.buff;
                    uint64_t buffer_size_save = p->b.length;
                    uint64_t offset_save = p->b.offset;

                    for (i = 1; i < p->size; i++)
                    {
                        p->b.buff = recv_buffer + index_offsets [i];
                        p->b.length = index_sizes [i];
                        p->b.offset = 0;

                        adios_parse_process_group_index_v1 (&p->b
                                                           ,&new_pg_root
                                                           );
                        adios_parse_vars_index_v1 (&p->b, &new_vars_root, NULL, NULL);
                        // do not merge attributes from other processes from 1.4
                        /*
                        adios_parse_attributes_index_v1 (&p->b
                                                        ,&new_attrs_root
                                                        );
                         */

                        adios_merge_index_v1 (p->index,new_pg_root, 
                                              new_vars_root, new_attrs_root);
                    
                        new_pg_root = 0;
                        new_vars_root = 0;
                        new_attrs_root = 0;
                    }

                    adios_sort_index_v1 (&p->index->pg_root
                                        ,&p->index->vars_root
                                        ,&p->index->attrs_root
                                        );

                    p->b.buff = buffer_save;
                    p->b.length = buffer_size_save;
                    p->b.offset = offset_save;

                    free (recv_buffer);
                    free (index_sizes);
                    free (index_offsets);

                    char * global_index_buffer = 0;
                    uint64_t global_index_buffer_size = 0;
                    uint64_t global_index_buffer_offset = 0;
                    uint64_t global_index_start = 0;
                    uint16_t flag = 0;

                    adios_write_index_v1 (&global_index_buffer, &global_index_buffer_size
                                         ,&global_index_buffer_offset, global_index_start
                                         ,p->index);

                    flag |= ADIOS_VERSION_HAVE_SUBFILE;

                    adios_write_version_flag_v1 (&global_index_buffer
                                                ,&global_index_buffer_size
                                                ,&global_index_buffer_offset
                                                ,flag
                                                );

                    START_TIMER (ADIOS_TIMER_POSIX_MD);
                    ssize_t s = write (p->mf, global_index_buffer, global_index_buffer_offset);
                    STOP_TIMER (ADIOS_TIMER_POSIX_MD);
                    if (s != global_index_buffer_offset)
                    {
                        fprintf (stderr, "POSIX method tried to write %llu, "
                                         "only wrote %lld, Mode: a\n"
                                         ,global_index_buffer_offset
                                         ,(int64_t)s
                                );
                    }

                    close (p->mf);

                    free (global_index_buffer);
                }
                else
                {
                    START_TIMER (ADIOS_TIMER_POSIX_COMM);
                    MPI_Gather (&buffer_size, 1, MPI_INT
                               ,0, 0, MPI_INT
                               ,0, p->group_comm
                               );

                    MPI_Gatherv (buffer, buffer_size, MPI_BYTE
                                ,0, 0, 0, MPI_BYTE
                                ,0, p->group_comm
                                );
                    STOP_TIMER (ADIOS_TIMER_POSIX_COMM);
                }
            }
#endif
            adios_write_version_v1 (&buffer, &buffer_size, &buffer_offset);
            START_TIMER (ADIOS_TIMER_POSIX_MD);
            adios_posix_do_write (fd, method, buffer, buffer_offset);
            STOP_TIMER (ADIOS_TIMER_POSIX_MD);

            free (buffer);

            break;
        }

        case adios_mode_read:
        {
            // read the index to find the place to start reading
            adios_posix_do_read (fd, method);
            struct adios_var_struct * v = fd->group->vars;
            while (v)
            {
                v->data = 0;
                v = v->next;
            }

            break;
        }

        default:
        {
            fprintf (stderr, "Unknown file mode: %d\n", fd->mode);

            return;
        }
    }

    adios_posix_close_internal (&p->b);
    adios_clear_index_v1 (p->index);

    STOP_TIMER (ADIOS_TIMER_POSIX_AD_CLOSE);

#if defined ADIOS_TIMERS || defined ADIOS_TIMER_EVENTS

    //Finished timing this cycle, swap the timing buffers
    adios_timing_destroy(fd->group->prev_timing_obj);
    fd->group->prev_timing_obj = fd->group->timing_obj;
    fd->group->timing_obj = 0;

    // prev_timing_obj points to unwritten timing info, timing_obj is
    // ready to allocate at the next open

#endif

}
예제 #5
0
int main (int argc, char ** argv)
{
    char * filename;
    int rc = 0;

    if (argc < 2 || argc > 3)
    {
        print_usage (argc, argv);
        return -1;
    }

    if (argv [1][0] && argv [1][0] == '-')
    {
        if (   !strcmp (argv [1], "-f")
            || !strcmp (argv [1], "--force")
           )
        {
            do_write_index = 1;
            filename = argv [2];
        }
        else
        {
            print_usage (argc, argv);
            return -1;
        }
    }
    else
    {
        filename = argv [1];
        do_write_index = 0;
    }

    have_subfiles = 0;
    struct adios_bp_buffer_struct_v1 * b = 0;
    uint32_t version = 0;

    b = malloc (sizeof (struct adios_bp_buffer_struct_v1));
    adios_buffer_struct_init (b);

    int flags = O_RDONLY;
    if (do_write_index)
        flags = O_RDWR;

    int fd = open (filename, flags);
    if (fd < 0) {
        fprintf (stderr, "recover: cannot open file %s\n", filename);
        if (errno)
            fprintf (stderr, "%s\n", strerror(errno));
        return -1;
    }

    struct stat statbuf; 
    fstat (fd, &statbuf);
    uint64_t file_size = statbuf.st_size;

    b->f = fd; 

    printf ("File size in bytes: %llu\n", file_size);

    /* Variables to build new index */
    struct adios_index_struct_v1 * index = adios_alloc_index_v1(1);
    //struct adios_index_process_group_struct_v1 * pg_root = 0;
    struct adios_index_process_group_struct_v1 * pg = 0;
    //struct adios_index_var_struct_v1 * vars_root = 0;
    //struct adios_index_attribute_struct_v1 * attrs_root = 0;


    uint64_t pg_num = 0L;
    uint64_t curr_offset = 0L;
    uint64_t new_offset = 0L;
    uint64_t pgsize_reported; // size of current pg (as indicated in PG header (wrongly))
    uint64_t pgsize_actual; // size of current pg based on processing (accurate)
    int found_pg = 0;

    printf (DIVIDER);
    found_pg = find_pg (fd, new_offset, file_size, &pgsize_reported);

    // pass over the PGs from beginning of file
    while (found_pg)
    {
        curr_offset = new_offset;
        pg_num++;
        printf ("PG %llu found at offset %llu\n", pg_num, curr_offset);


        /* Let's process the group */
        /* Allocate PG index struct here to allow to be used below */
        pg = (struct adios_index_process_group_struct_v1 *)
                malloc (sizeof(struct adios_index_process_group_struct_v1));

        // setup where to read the process group from (and size)
        pg->offset_in_file = curr_offset;
        //b->read_pg_offset = pg->offset_in_file;
        b->read_pg_offset = curr_offset;
        b->read_pg_size = pgsize_reported;

        /* Temporary variables for parsing one PG */
        struct adios_process_group_header_struct_v1 pg_header;
        struct adios_vars_header_struct_v1 vars_header;
        struct adios_attributes_header_struct_v1 attrs_header;

        struct adios_var_header_struct_v1 var_header;
        struct adios_var_payload_struct_v1 var_payload;
        struct adios_attribute_struct_v1 attribute;

        init_dimensions ();  // store scalar values from this PG temporarily

        /* Read the whole PG into a buffer and start parsing */
        adios_posix_read_process_group (b);
        adios_parse_process_group_header_v1 (b, &pg_header);
        print_process_group_header (pg_num, &pg_header);

        add_pg_to_index (index, &pg_header, curr_offset);

        adios_parse_vars_header_v1 (b, &vars_header);
        print_vars_header (&vars_header);

        int i;
        for (i = 0; i < vars_header.count; i++)
        {
            var_payload.payload = 0;

            adios_parse_var_data_header_v1 (b, &var_header);
            print_var_header (&var_header);

            if ( var_header.dims == 0)
            {
                // Load scalars to save them for handling as dimension values
                var_payload.payload = malloc (var_header.payload_size + 1);
                adios_parse_var_data_payload_v1 (b, &var_header, &var_payload
                                                ,var_header.payload_size
                                                );
            }
            else
            {
                // Just parse to move the offset in buffer, don't read data
                adios_parse_var_data_payload_v1 (b, &var_header, NULL, 0);
            }

            store_scalar_dimensions (&var_header, &var_payload);
            add_var_to_index (index, &pg_header, &var_header, &var_payload);

            if (var_payload.payload)
            {
                free (var_payload.payload);
                var_payload.payload = 0;
            }
            //printf ("\n");

        }

        adios_parse_attributes_header_v1 (b, &attrs_header);
        print_attrs_header (&attrs_header);

        for (i = 0; i < attrs_header.count; i++)
        {
            adios_parse_attribute_v1 (b, &attribute);
            //print_attribute (&attribute);
            //printf ("\n");
        }

        pgsize_actual = b->offset;
        printf ("Actual size of group by processing: %llu bytes\n", pgsize_actual);

        pg = pg->next;
        

        printf (DIVIDER);
        found_pg = 0;
        if (curr_offset + pgsize_actual < file_size) 
        {
            new_offset =  curr_offset + pgsize_actual;
            found_pg = find_pg (fd, curr_offset+pgsize_actual, file_size, &pgsize_reported);
        }
        if (!found_pg && 
            pgsize_actual != pgsize_reported &&
            curr_offset + pgsize_reported < file_size) 
        {
            new_offset =  curr_offset + pgsize_reported;
            found_pg = find_pg (fd, curr_offset+pgsize_reported, file_size, &pgsize_reported);
        }
    }

    // The end of the last successfully processed PG
    // This will be the start of the index data
    curr_offset += pgsize_actual;

    printf (DIVIDER);
    printf ("Found %llu PGs to be processable\n", pg_num);

    write_index (fd, curr_offset, index);
    adios_posix_close_internal (b); // will close fd

    return 0;
}