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; }
int adios_posix_open (struct adios_file_struct * fd ,struct adios_method_struct * method, MPI_Comm comm ) { char * subfile_name = 0; char * mdfile_name = 0; char * name_with_rank, rank_string[16]; struct adios_POSIX_data_struct * p = (struct adios_POSIX_data_struct *) method->method_data; #if defined ADIOS_TIMERS || defined ADIOS_TIMER_EVENTS int timer_count = 7; char ** timer_names = (char**) malloc (timer_count * sizeof (char*) ); timer_names [0] = "Communication"; timer_names [1] = "I/O"; timer_names [2] = "Metadata"; timer_names [3] = "ad_open"; timer_names [4] = "ad_write"; timer_names [5] = "ad_close"; timer_names [6] = "ad_should_buffer"; // Ensure both timing objects exist // timing_obj should get created at every open // prev_timing_obj should only be created at the first open if (fd->group) { if (!fd->group->timing_obj) fd->group->timing_obj = adios_timing_create (timer_count, timer_names); if (!fd->group->prev_timing_obj) fd->group->prev_timing_obj = adios_timing_create (timer_count, timer_names); } #endif START_TIMER (ADIOS_TIMER_POSIX_AD_OPEN); #ifdef HAVE_MPI // Need to figure out new the new fd->name, such as restart.bp.0, restart.bp.1.... p->group_comm = comm; if (p->group_comm == MPI_COMM_NULL) { p->group_comm = MPI_COMM_SELF; } // if communicator is not MPI_COMM_NULL/MPI_COMM_SELF, subfiles will be generated in a dir. if (p->group_comm != MPI_COMM_SELF) { char * n = strrchr (fd->name, '/'); if (!n) { n = fd->name; } else { n++; } MPI_Comm_rank (p->group_comm, &p->rank); MPI_Comm_size (p->group_comm, &p->size); fd->group->process_id = p->rank; sprintf (rank_string, "%d", p->rank); // fd->name + '.' + MPI rank + '\0' name_with_rank = malloc (strlen (n) + strlen (rank_string) + 2); sprintf (name_with_rank, "%s.%s", n, rank_string); // e.g., subfile_name is restart.bp.dir/restart.bp.0 subfile_name = malloc (strlen (fd->name) + 5 + strlen (method->base_path) + strlen (name_with_rank) + 1 ); sprintf (subfile_name, "%s%s%s%s" , fd->name , ".dir/" , method->base_path , name_with_rank ); mdfile_name = malloc (strlen (method->base_path) + strlen (fd->name) + 1 ); sprintf (mdfile_name, "%s%s" , method->base_path , fd->name ); free (name_with_rank); } else #endif { // if the communicator is MPI_COMM_SELF, there won't be metadata file generated. // The actually subfile name is the one supplied by the user subfile_name = malloc (strlen (method->base_path) + strlen (fd->name) + 1); sprintf (subfile_name, "%s%s", method->base_path, fd->name); mdfile_name = 0; } #ifdef HAVE_MPI fd->subfile_index = p->rank; // Only if HAVE_MPI #endif struct stat s; if (stat (subfile_name, &s) == 0) p->b.file_size = s.st_size; switch (fd->mode) { case adios_mode_read: { p->b.f = open (subfile_name, O_RDONLY | O_LARGEFILE); if (p->b.f == -1) { fprintf (stderr, "ADIOS POSIX: file not found: %s\n", fd->name); free (subfile_name); return 0; } fd->base_offset = 0; fd->pg_start_in_file = 0; break; } case adios_mode_write: { #ifdef HAVE_MPI // create dir to keep all the subfiles if (p->group_comm != MPI_COMM_SELF) { if (p->rank == 0) { char * dir_name = malloc (strlen (fd->name) + 4 + 1); sprintf (dir_name, "%s%s" , fd->name , ".dir" ) ; mkdir (dir_name, S_IRWXU | S_IRWXG); free (dir_name); } MPI_Barrier (p->group_comm); } #endif p->b.f = open (subfile_name, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->b.f == -1) { fprintf (stderr, "adios_posix_open failed for " "base_path %s, subfile name %s\n" ,method->base_path, subfile_name ); free (subfile_name); free (mdfile_name); return 0; } #ifdef HAVE_MPI // open metadata file if (p->group_comm != MPI_COMM_SELF) { if (p->rank == 0) { p->mf = open (mdfile_name, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->mf == -1) { fprintf (stderr, "adios_posix_open failed for " "base_path %s, metadata file name %s\n" ,method->base_path, mdfile_name ); free (subfile_name); free (mdfile_name); return 0; } } } #endif fd->base_offset = 0; fd->pg_start_in_file = 0; break; } case adios_mode_append: case adios_mode_update: { int old_file = 1; #ifdef HAVE_MPI if (p->group_comm != MPI_COMM_SELF) { if (p->rank == 0) { char * dir_name = malloc (strlen (fd->name) + 4 + 1); sprintf (dir_name, "%s%s" , fd->name , ".dir" ) ; mkdir (dir_name, S_IRWXU | S_IRWXG); free (dir_name); } MPI_Barrier (p->group_comm); } #endif p->b.f = open (subfile_name, O_RDWR | O_LARGEFILE); if (p->b.f == -1) { old_file = 0; p->b.f = open (subfile_name, O_WRONLY | O_CREAT | O_LARGEFILE , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->b.f == -1) { fprintf (stderr, "adios_posix_open failed for " "base_path %s, name %s\n" ,method->base_path, fd->name ); free (subfile_name); free (mdfile_name); return 0; } } #ifdef HAVE_MPI // open metadata file if (p->group_comm != MPI_COMM_SELF) { if (p->rank == 0) { p->mf = open (mdfile_name, O_WRONLY | O_TRUNC | O_LARGEFILE , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->mf == -1) { p->mf = open (mdfile_name, O_WRONLY| O_CREAT | O_LARGEFILE , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->mf == -1) { fprintf (stderr, "adios_posix_open failed for " "base_path %s, name %s\n" ,method->base_path, fd->name ); free (subfile_name); free (mdfile_name); return 0; } } } } #endif if (old_file) { // now we have to read the old stuff so we can merge it // in at the end and set the base_offset for the old index // start uint32_t version; adios_posix_read_version (&p->b); adios_parse_version (&p->b, &version); switch (version & ADIOS_VERSION_NUM_MASK) { case 1: case 2: // read the old stuff and set the base offset adios_posix_read_index_offsets (&p->b); adios_parse_index_offsets_v1 (&p->b); adios_posix_read_process_group_index (&p->b); adios_parse_process_group_index_v1 (&p->b, &p->index->pg_root); // find the largest time index so we can append properly struct adios_index_process_group_struct_v1 * pg; uint32_t max_time_index = 0; pg = p->index->pg_root; while (pg) { if (pg->time_index > max_time_index) max_time_index = pg->time_index; pg = pg->next; } fd->group->time_index = ++max_time_index; adios_posix_read_vars_index (&p->b); adios_parse_vars_index_v1 (&p->b, &p->index->vars_root, p->index->hashtbl_vars, &p->index->vars_tail); adios_posix_read_attributes_index (&p->b); adios_parse_attributes_index_v1 (&p->b, &p->index->attrs_root); fd->base_offset = p->b.end_of_pgs; fd->pg_start_in_file = p->b.end_of_pgs; break; default: fprintf (stderr, "Unknown bp version: %d. " "Cannot append\n" ,version ); free (subfile_name); free (mdfile_name); return 0; } } break; } default: { fprintf (stderr, "Unknown file mode: %d\n", fd->mode); free (subfile_name); free (mdfile_name); return 0; } } if (subfile_name) { free (subfile_name); } if (mdfile_name) { free (mdfile_name); } STOP_TIMER (ADIOS_TIMER_POSIX_AD_OPEN); return 1; }
static void adios_posix_do_read (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_var_struct * v = fd->group->vars; uint32_t version = 0; adios_posix_read_version (&p->b); adios_parse_version (&p->b, &version); version &= ADIOS_VERSION_NUM_MASK; switch (version) { case 1: case 2: { struct adios_index_struct_v1 * index = adios_alloc_index_v1(0); // no hashtables struct adios_index_process_group_struct_v1 * pg_root = index->pg_root; struct adios_index_process_group_struct_v1 * pg_root_temp = 0; adios_posix_read_index_offsets (&p->b); adios_parse_index_offsets_v1 (&p->b); adios_posix_read_process_group_index (&p->b); adios_parse_process_group_index_v1 (&p->b, &pg_root); #if 1 adios_posix_read_vars_index (&p->b); adios_parse_vars_index_v1 (&p->b, &index->vars_root, NULL, NULL); adios_posix_read_attributes_index (&p->b); adios_parse_attributes_index_v1 (&p->b, &index->attrs_root); #endif // the three section headers 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; int i; pg_root_temp = pg_root; while (pg_root_temp && pg_root_temp->next) pg_root_temp = pg_root_temp->next; p->b.read_pg_offset = pg_root_temp->offset_in_file; if (pg_root_temp->next) { p->b.read_pg_size = pg_root_temp->next->offset_in_file - pg_root_temp->offset_in_file; } else { p->b.read_pg_size = p->b.pg_index_offset - pg_root_temp->offset_in_file; } adios_posix_read_process_group (&p->b); adios_parse_process_group_header_v1 (&p->b, &pg_header); adios_parse_vars_header_v1 (&p->b, &vars_header); for (i = 0; i < vars_header.count; i++) { memset (&var_payload, 0 ,sizeof (struct adios_var_payload_struct_v1) ); adios_parse_var_data_header_v1 (&p->b, &var_header); struct adios_var_struct * v1 = v; while (v1) { if ( strcasecmp (var_header.name, v1->name) || strcasecmp (var_header.path, v1->path) ) { v1 = v1->next; } else break; } if (v1) { var_payload.payload = v1->data; adios_parse_var_data_payload_v1 (&p->b, &var_header ,&var_payload ,v1->data_size ); } else { adios_parse_var_data_payload_v1 (&p->b, &var_header ,NULL, 0 ); } adios_clear_var_header_v1 (&var_header); } #if 1 adios_parse_attributes_header_v1 (&p->b, &attrs_header); for (i = 0; i < attrs_header.count; i++) { adios_parse_attribute_v1 (&p->b, &attribute); adios_clear_attribute_v1 (&attribute); } #endif adios_clear_process_group_header_v1 (&pg_header); adios_clear_index_v1 (index); break; } default: fprintf (stderr, "POSIX read: file version unknown: %u\n", version); return; } adios_buffer_struct_clear (&p->b); }
int adios_posix1_open (struct adios_file_struct * fd ,struct adios_method_struct * method, MPI_Comm comm ) { char * name; struct adios_POSIX1_data_struct * p = (struct adios_POSIX1_data_struct *) method->method_data; // figure out the actual name of the file. name = malloc (strlen (method->base_path) + strlen (fd->name) + 1); sprintf (name, "%s%s", method->base_path, fd->name); struct stat s; if (stat (name, &s) == 0) p->b.file_size = s.st_size; switch (fd->mode) { case adios_mode_read: { p->b.f = open (name, O_RDONLY #ifndef __APPLE__ | O_LARGEFILE #endif ); if (p->b.f == -1) { fprintf (stderr, "ADIOS POSIX1: file not found: %s\n", fd->name); free (name); return 0; } fd->base_offset = 0; fd->pg_start_in_file = 0; break; } case adios_mode_write: { p->b.f = open (name, O_WRONLY | O_CREAT | O_TRUNC #ifndef __APPLE__ | O_LARGEFILE #endif , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->b.f == -1) { fprintf (stderr, "adios_posix1_open failed for " "base_path %s, name %s\n" ,method->base_path, fd->name ); free (name); return 0; } fd->base_offset = 0; fd->pg_start_in_file = 0; break; } case adios_mode_append: { int old_file = 1; p->b.f = open (name, O_RDWR #ifndef __APPLE__ | O_LARGEFILE #endif ); if (p->b.f == -1) { old_file = 0; p->b.f = open (name, O_WRONLY | O_CREAT #ifndef __APPLE__ | O_LARGEFILE #endif , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if (p->b.f == -1) { fprintf (stderr, "adios_posix1_open failed for " "base_path %s, name %s\n" ,method->base_path, fd->name ); free (name); return 0; } } if (old_file) { // now we have to read the old stuff so we can merge it // in at the end and set the base_offset for the old index // start uint32_t version; adios_posix_read_version (&p->b); adios_parse_version (&p->b, &version); switch (version & ADIOS_VERSION_NUM_MASK) { case 1: case 2: case 3: // read the old stuff and set the base offset adios_posix_read_index_offsets (&p->b); adios_parse_index_offsets_v1 (&p->b); adios_posix_read_process_group_index (&p->b); adios_parse_process_group_index_v1 (&p->b, &p->index->pg_root, &p->index->pg_tail); // find the largest time index so we can append properly struct adios_index_process_group_struct_v1 * pg; uint32_t max_time_index = 0; pg = p->index->pg_root; while (pg) { if (pg->time_index > max_time_index) max_time_index = pg->time_index; pg = pg->next; } if (fd->mode == adios_mode_append) { ++max_time_index; } fd->group->time_index = max_time_index; adios_posix_read_vars_index (&p->b); adios_parse_vars_index_v1 (&p->b, &p->index->vars_root, p->index->hashtbl_vars, &p->index->vars_tail); adios_posix_read_attributes_index (&p->b); adios_parse_attributes_index_v1 (&p->b ,&p->index->attrs_root ); fd->base_offset = p->b.end_of_pgs; fd->pg_start_in_file = p->b.end_of_pgs; break; default: fprintf (stderr, "Unknown bp version: %d. " "Cannot append\n" ,version ); free (name); return 0; } } break; } default: { fprintf (stderr, "Unknown file mode: %d\n", fd->mode); free (name); return 0; } } free (name); return 1; }