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; }
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; }
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); }
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 }
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; }