void FORTRAN_API mpi_file_get_position_(MPI_Fint *fh, MPI_Offset *offset, int *ierr ) { MPI_File fh_c; fh_c = MPI_File_f2c(*fh); *ierr = MPI_File_get_position(fh_c, offset); }
stream_offset seek(stream_offset off, std::ios_base::seekdir way) { // Advances the read/write head by off characters, // returning the new position, where the offset is // calculated from: // - the start of the sequence if way == ios_base::beg // - the current position if way == ios_base::cur // - the end of the sequence if way == ios_base::end switch (way) { case std::ios::beg: MPI_File_seek(mpifile, (MPI_Offset)(off), MPI_SEEK_SET); break; case std::ios::end: MPI_File_seek(mpifile, (MPI_Offset)(off), MPI_SEEK_END); break; case std::ios::cur: MPI_File_seek(mpifile, (MPI_Offset)(off), MPI_SEEK_CUR); break; default: abort(); break; // Should never happen } MPI_Offset pos; MPI_File_get_position(mpifile, &pos); ++seeks; return pos; }
JNIEXPORT jlong JNICALL Java_mpi_File_getPosition( JNIEnv *env, jobject jthis, jlong fh) { MPI_Offset offset; int rc = MPI_File_get_position((MPI_File)fh, &offset); ompi_java_exceptionCheck(env, rc); return (jlong)offset; }
void mpi_file_get_position_f(MPI_Fint *fh, MPI_Offset *offset, MPI_Fint *ierr) { MPI_File c_fh = MPI_File_f2c(*fh); MPI_Offset c_offset; *ierr = OMPI_INT_2_FINT(MPI_File_get_position(c_fh, &c_offset)); if (MPI_SUCCESS == OMPI_FINT_2_INT(*ierr)) { *offset = (MPI_Fint) c_offset; } }
/* parallel_get_position() * Wrapper for get position/ftell * NOTE: Careful about long conversions. MPI_Offset is long long I think */ int parallel_get_position(coordinateInfo *C, long int *offset) { # ifdef MPI int err; MPI_Offset moffset; err=MPI_File_get_position(*(C->mfp), &moffset); if (err!=MPI_SUCCESS) { printMPIerr(err,"trajFile_get_position"); *offset=-1; return -1; } *offset=(long int) moffset; return 0; #endif return 1; }
void step4(inst i, int r, int s) { inst instance = i; int rank = r; int size = s; // Creation of the 2D torus we will then use MPI_Comm comm; int dim[2] = {instance.p, instance.q}; int period[2] = {1, 1}; int reorder = 0; int coord[2]; MPI_Cart_create(MPI_COMM_WORLD, 2, dim, period, reorder, &comm); MPI_Cart_coords(comm, rank, 2, coord); grid global_grid; char type = 0; MPI_File input_file; // We start by reading the header of the file MPI_File_open(comm, instance.input_path, MPI_MODE_RDONLY, MPI_INFO_NULL, &input_file); MPI_File_read_all(input_file, &type, 1, MPI_CHAR, MPI_STATUS_IGNORE); if(type == 1) { if (rank == 0) fprintf(stderr, "Error: type 1 files are not supported in step 4\n"); MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); exit(EXIT_FAILURE); } // we needed to swap the next 2 lines MPI_File_read_all(input_file, &(global_grid.n), 1, MPI_UINT64_T, MPI_STATUS_IGNORE); MPI_File_read_all(input_file, &(global_grid.m), 1, MPI_UINT64_T, MPI_STATUS_IGNORE); #ifdef DEBUG if(rank == 0) printf("n, m = %zu %zu\n", global_grid.n, global_grid.m); #endif if(!(global_grid.n % instance.p == 0 && global_grid.m % instance.q == 0)) { if(rank == 0) fprintf(stderr, "Error: please choose the grid parameters so they divide the grid of the cellular automaton. For example %zu %zu, but you need to move from %d procs to %zu\n", instance.p + (global_grid.n % instance.p), instance.q + (global_grid.m % instance.q), size, (instance.p + (global_grid.n % instance.p))*(instance.q + (global_grid.m % instance.q))); MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); exit(EXIT_FAILURE); } size_t local_nrows = global_grid.n/instance.p; size_t local_ncols = global_grid.m/instance.q; // Now we create the data structures. int blocks[2] = {1, 2}; MPI_Datatype types[2] = {MPI_BYTE, MPI_DOUBLE}; MPI_Aint a_size = sizeof(cell2); MPI_Aint a_disp[3] = {offsetof(cell2, type), offsetof(cell2, u), offsetof(cell2, s)}; MPI_Aint p_size = 17; MPI_Aint p_disp[3] = {0, 1, 9}; MPI_Datatype p_tmp, a_tmp, p_cell, a_cell; // Aligned struct, memory representation MPI_Type_create_struct(2, blocks, a_disp, types, &a_tmp); MPI_Type_create_resized(a_tmp, 0, a_size, &a_cell); MPI_Type_commit(&a_cell); // Packed struct, file-based representation MPI_Type_create_struct(2, blocks, p_disp, types, &p_tmp); MPI_Type_create_resized(p_tmp, 0, p_size, &p_cell); MPI_Type_commit(&p_cell); // Now, we create our matrix MPI_Datatype matrix; int sizes[2] = {global_grid.n, global_grid.m}; int subsizes[2] = {local_nrows, local_ncols}; int starts[2] = {0, 0}; MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, p_cell, &matrix); MPI_Type_commit(&matrix); // We extend this matrix MPI_Datatype ematrix; int e_subsizes[2] = {2 + subsizes[0], 2 + subsizes[1]}; int e_start[2] = {1, 1}; MPI_Type_create_subarray(2, e_subsizes, subsizes, e_start, MPI_ORDER_C, a_cell, &ematrix); MPI_Type_commit(&ematrix); // The next 3 types are for the export of the grid MPI_Datatype d_type; MPI_Type_create_resized(MPI_DOUBLE, 0, sizeof(cell2), &d_type); MPI_Type_commit(&d_type); MPI_Datatype d_matrix; MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_DOUBLE, &d_matrix); MPI_Type_commit(&d_matrix); MPI_Datatype d_rmatrix; // to go from the extended matrix with ghost zones to the other one MPI_Type_create_subarray(2, e_subsizes, subsizes, e_start, MPI_ORDER_C, d_type, &d_rmatrix); MPI_Type_commit(&d_rmatrix); // Set file view for each element MPI_Offset grid_start; MPI_File_get_position(input_file, &grid_start); MPI_File_set_view(input_file, grid_start + global_grid.m*local_nrows*p_size*coord[0] + local_ncols*p_size*coord[1], p_cell, matrix, "native", MPI_INFO_NULL); // allocate the cell array we will use cell2 **cells; cells = malloc(2*sizeof(cell2 *)); double *sensors; cells[1] = calloc((2+local_nrows)*(2+local_ncols),sizeof(cell2)); cells[0] = calloc((2+local_nrows)*(2+local_ncols),sizeof(cell2)); sensors = calloc(local_nrows*local_ncols, sizeof(double)); MPI_File_read_all(input_file, cells[0], 1, ematrix, MPI_STATUS_IGNORE); MPI_File_close(&input_file); #ifdef DEBUG for(size_t i = 1; i < 1+local_nrows; i++) for(size_t j = 1; j < 1+local_ncols; j++) fprintf(stderr, "%d - %d %f\n", rank, cells[0][i*(2+local_ncols)+j].type, cells[0][i*(2+local_ncols)+j].u); #endif MPI_Datatype l_row; // local row MPI_Type_contiguous(local_ncols, d_type, &l_row); MPI_Type_commit(&l_row); MPI_Datatype l_col; // local column. A bit trickier, we need a type_vector. MPI_Type_vector(local_nrows, 1, local_ncols+2, d_type, &l_col); MPI_Type_commit(&l_col); int top, bot, left, right; double sqspeed = 0; int curr = 0, next = 0; char *alldump = malloc(256); for(int s = 0; s < instance.iteration; s++) { // We will update cell[next], and use the data of cell[curr] curr = s % 2; next = (s+1) % 2; // We copy the edges of the grid. // We first need the ranks of the neighbours MPI_Cart_shift(comm, 0, 1, &top, &bot); MPI_Cart_shift(comm, 1, 1, &left, &right); // Then we need to update the edges of our local grid // Update top and bottom rows MPI_Sendrecv(&(cells[curr][1*(local_ncols+2)+1].u), 1, l_row, top, 0, &(cells[curr][(local_ncols+2)*(local_nrows+1)+1].u), 1, l_row, bot, 0, comm, MPI_STATUS_IGNORE); MPI_Sendrecv(&(cells[curr][(local_ncols+2)*(local_nrows)+1].u), 1, l_row, bot, 0, &(cells[curr][1].u), 1, l_row, top, 0, comm, MPI_STATUS_IGNORE); // Update left and right MPI_Sendrecv(&(cells[curr][1*(local_ncols+2)+1].u), 1, l_col, left, 0, &(cells[curr][1*(local_ncols+2)+local_ncols+1].u), 1, l_col, right, 0, comm, MPI_STATUS_IGNORE); MPI_Sendrecv(&(cells[curr][1*(local_ncols+2)+local_ncols].u), 1, l_col, right, 0, &(cells[curr][1*(local_ncols+2)].u), 1, l_col, left, 0, comm, MPI_STATUS_IGNORE); // We compute the update of the grid for(size_t i = 1; i < 1+local_nrows; i++) { for(size_t j = 1; j < 1+local_ncols; j++) { if(instance.step < 2 || cells[next][j+i*(2+local_ncols)].type != 1) { // If walls we do not do anything sqspeed = cells[0][j+i*(2+local_ncols)].s * cells[0][j+i*(2+local_ncols)].s; cells[next][j+i*(2+local_ncols)].u = cells[curr][j+i*(2+local_ncols)].u + (cells[curr][j+i*(2+local_ncols)].v * instance.dt); cells[next][j+i*(2+local_ncols)].v = cells[curr][j+i*(2+local_ncols)].v + sqspeed * (cells[curr][j+(i+1)*(2+local_ncols)].u + cells[curr][j+(i-1)*(2+local_ncols)].u + cells[curr][(j+1) + i*(2+local_ncols)].u + cells[curr][(j-1) + i*(2+local_ncols)].u - (4 * cells[curr][j+i*(2+local_ncols)].u)) * instance.dt; if(instance.step == 3 && cells[next][j+i*(2+local_ncols)].type == 2) { // Case of sensors sensors[(j-1)+(i-1)*local_ncols] += cells[next][j+i*(2+local_ncols)].u * cells[next][j+i*(2+local_ncols)].u; } } } } if(instance.alldump != NULL && s % instance.frequency == 0) { MPI_File dump_file; sprintf(alldump, instance.alldump, (s / instance.frequency)); MPI_File_open(comm, alldump, MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &dump_file); MPI_File_set_view(dump_file, global_grid.m*local_nrows*sizeof(double)*coord[0] + local_ncols*sizeof(double)*coord[1], MPI_DOUBLE, d_matrix, "native", MPI_INFO_NULL); MPI_File_write_all(dump_file, &(cells[curr][0].u), 1, d_rmatrix, MPI_STATUS_IGNORE); MPI_File_close(&dump_file); } } if(instance.lastdump != NULL) { // bon, comment on fait ça ? peut être qu'en faisant un resize ça marche ? MPI_File last_file; MPI_File_open(comm, instance.lastdump, MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &last_file); MPI_File_set_view(last_file, global_grid.m*local_nrows*sizeof(double)*coord[0] + local_ncols*sizeof(double)*coord[1], MPI_DOUBLE, d_matrix, "native", MPI_INFO_NULL); // déjà, il y a un grid_strat en trop, d_type ou MPI_DOUBLE ? MPI_File_write_all(last_file, &(cells[next][0].u), 1, d_rmatrix, MPI_STATUS_IGNORE); MPI_File_close(&last_file); } if(instance.step == 3 && instance.sensors != NULL) { MPI_File sensor_file; MPI_File_open(comm, instance.sensors, MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &sensor_file); MPI_Datatype string; MPI_Type_contiguous(1024, MPI_CHAR, &string); MPI_Type_commit(&string); char text[1024]; for(size_t i = 1; i < 1+local_nrows; i++) { for(size_t j = 1; j < 1+local_ncols; j++) { if(instance.step == 3 && cells[next][j+i*(2+local_ncols)].type == 2) { memset(text,0,sizeof(text)); sprintf(text, "%zu %zu %f\r\n", (i-1)+coord[0]*local_nrows, (j-1)+coord[1]*local_ncols, sensors[(j-1)+(i-1)*local_ncols]); MPI_File_write(sensor_file, text, 1, string, MPI_STATUS_IGNORE); } } } MPI_Type_free(&string); MPI_File_close(&sensor_file); } // Some cleaning free(cells); free(alldump); MPI_Type_free(&a_cell); MPI_Type_free(&p_cell); MPI_Type_free(&matrix); MPI_Type_free(&ematrix); MPI_Type_free(&d_type); MPI_Type_free(&d_matrix); MPI_Type_free(&d_rmatrix); MPI_Type_free(&l_row); MPI_Type_free(&l_col); }
int main(int argc, char *argv[]) { int i; int is_mpi = 1; int debug = 0; bool verbose = false; bool force = false; // fixed header changes int set_version_major = -1; int set_version_minor = -1; int set_point_data_format = -1; int set_point_data_record_length = -1; int set_gps_time_endcoding = -1; // variable header changes bool remove_extra_header = false; bool remove_all_variable_length_records = false; int remove_variable_length_record = -1; int remove_variable_length_record_from = -1; int remove_variable_length_record_to = -1; bool remove_tiling_vlr = false; bool remove_original_vlr = false; // extract a subsequence //unsigned int subsequence_start = 0; //unsigned int subsequence_stop = U32_MAX; I64 subsequence_start = 0; I64 subsequence_stop = I64_MAX; // fix files with corrupt points bool clip_to_bounding_box = false; double start_time = 0; time_t wall_start_time; time_t wall_end_time; LASreadOpener lasreadopener; //if(is_mpi)lasreadopener.setIsMpi(TRUE); GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if(is_mpi)laswriteopener.setIsMpi(TRUE); int process_count = 1; int rank = 0; start_time = taketime(); time(&wall_start_time); if (is_mpi){ MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&process_count); MPI_Comm_rank(MPI_COMM_WORLD,&rank); if(debug) printf ("MPI task %d has started...\n", rank); } if (argc == 1) { fprintf(stderr,"las2las.exe is better run in the command line or via the lastool.exe GUI\n"); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); } else { for (i = 1; i < argc; i++) { //if (argv[i][0] == '�') argv[i][0] = '-'; if (strcmp(argv[i],"-week_to_adjusted") == 0) { set_gps_time_endcoding = 1; } else if (strcmp(argv[i],"-adjusted_to_week") == 0) { set_gps_time_endcoding = 0; } } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); } else if (strcmp(argv[i],"-cores") == 0) { fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); i++; } else if (strcmp(argv[i],"-force") == 0) { force = true; } else if (strcmp(argv[i],"-subseq") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: start stop\n", argv[i]); byebye(true); } subsequence_start = (unsigned int)atoi(argv[i+1]); subsequence_stop = (unsigned int)atoi(argv[i+2]); i+=2; } else if (strcmp(argv[i],"-start_at_point") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: start\n", argv[i]); byebye(true); } subsequence_start = (unsigned int)atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-stop_at_point") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: stop\n", argv[i]); byebye(true); } subsequence_stop = (unsigned int)atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-set_version") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major.minor\n", argv[i]); byebye(true); } if (sscanf(argv[i+1],"%d.%d",&set_version_major,&set_version_minor) != 2) { fprintf(stderr, "ERROR: cannot understand argument '%s' for '%s'\n", argv[i+1], argv[i]); usage(true); } i+=1; } else if (strcmp(argv[i],"-set_version_major") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major\n", argv[i]); byebye(true); } set_version_major = atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-set_version_minor") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: minor\n", argv[i]); byebye(true); } set_version_minor = atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-remove_extra") == 0) { remove_extra_header = true; } else if (strcmp(argv[i],"-remove_all_vlrs") == 0) { remove_all_variable_length_records = true; } else if (strcmp(argv[i],"-remove_vlr") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); byebye(true); } remove_variable_length_record = atoi(argv[i+1]); remove_variable_length_record_from = -1; remove_variable_length_record_to = -1; i++; } else if (strcmp(argv[i],"-remove_vlrs_from_to") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: start end\n", argv[i]); byebye(true); } remove_variable_length_record = -1; remove_variable_length_record_from = atoi(argv[i+1]); remove_variable_length_record_to = atoi(argv[i+2]); i+=2; } else if (strcmp(argv[i],"-remove_tiling_vlr") == 0) { remove_tiling_vlr = true; i++; } else if (strcmp(argv[i],"-remove_original_vlr") == 0) { remove_original_vlr = true; i++; } else if (strcmp(argv[i],"-set_point_type") == 0 || strcmp(argv[i],"-set_point_data_format") == 0 || strcmp(argv[i],"-point_type") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: type\n", argv[i]); byebye(true); } set_point_data_format = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-set_point_data_record_length") == 0 || strcmp(argv[i],"-set_point_size") == 0 || strcmp(argv[i],"-point_size") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); byebye(true); } set_point_data_record_length = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-clip_to_bounding_box") == 0 || strcmp(argv[i],"-clip_to_bb") == 0) { clip_to_bounding_box = true; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(true); } } // check input if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); usage(true, argc==1); } BOOL extra_pass = laswriteopener.is_piped(); // for piped output we need an extra pass if (extra_pass) { if (lasreadopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); usage(true); } } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // possibly loop over multiple input files while (lasreadopener.active()) { // if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); usage(true, argc==1); } // store the inventory for the header LASinventory lasinventory; // the point we write sometimes needs to be copied LASpoint* point = 0; // prepare the header for output if (set_gps_time_endcoding != -1) { if (set_gps_time_endcoding == 0) { if ((lasreader->header.global_encoding & 1) == 0) { fprintf(stderr, "WARNING: global encoding indicates file already in GPS week time\n"); if (force) { fprintf(stderr, " forced conversion.\n"); } else { fprintf(stderr, " use '-force' to force conversion.\n"); byebye(true); } } else { lasreader->header.global_encoding &= ~1; } } else if (set_gps_time_endcoding == 1) { if ((lasreader->header.global_encoding & 1) == 1) { fprintf(stderr, "WARNING: global encoding indicates file already in Adjusted Standard GPS time\n"); if (force) { fprintf(stderr, " forced conversion.\n"); } else { fprintf(stderr, " use '-force' to force conversion.\n"); byebye(true); } } else { lasreader->header.global_encoding |= 1; } } } if (set_version_major != -1) { if (set_version_major != 1) { fprintf(stderr, "ERROR: unknown version_major %d\n", set_version_major); byebye(true); } lasreader->header.version_major = (U8)set_version_major; } if (set_version_minor >= 0) { if (set_version_minor > 4) { fprintf(stderr, "ERROR: unknown version_minor %d\n", set_version_minor); byebye(true); } if (set_version_minor < 3) { if (lasreader->header.version_minor == 3) { lasreader->header.header_size -= 8; lasreader->header.offset_to_point_data -= 8; } else if (lasreader->header.version_minor >= 4) { lasreader->header.header_size -= (8 + 140); lasreader->header.offset_to_point_data -= (8 + 140); } } else if (set_version_minor == 3) { if (lasreader->header.version_minor < 3) { lasreader->header.header_size += 8; lasreader->header.offset_to_point_data += 8; lasreader->header.start_of_waveform_data_packet_record = 0; } else if (lasreader->header.version_minor >= 4) { lasreader->header.header_size -= 140; lasreader->header.offset_to_point_data -= 140; } } else if (set_version_minor == 4) { if (lasreader->header.version_minor < 3) { lasreader->header.header_size += (8 + 140); lasreader->header.offset_to_point_data += (8 + 140); lasreader->header.start_of_waveform_data_packet_record = 0; } else if (lasreader->header.version_minor == 3) { lasreader->header.header_size += 140; lasreader->header.offset_to_point_data += 140; } } if ((set_version_minor <= 3) && (lasreader->header.version_minor >= 4)) { if (lasreader->header.point_data_format > 5) { switch (lasreader->header.point_data_format) { case 6: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 1\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 1; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 2); lasreader->header.point_data_record_length -= 2; break; case 7: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 3\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 3; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 2); lasreader->header.point_data_record_length -= 2; break; case 8: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 3\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 3; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 4); lasreader->header.point_data_record_length -= 4; break; case 9: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 4\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 4; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 2); lasreader->header.point_data_record_length -= 2; break; case 10: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 5\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 5; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 4); lasreader->header.point_data_record_length -= 4; break; default: fprintf(stderr, "ERROR: unknown point_data_format %d\n", lasreader->header.point_data_format); byebye(true); } } point = new LASpoint; point->init(&lasreader->header, lasreader->header.point_data_format, lasreader->header.point_data_record_length); } lasreader->header.version_minor = (U8)set_version_minor; } // are we supposed to change the point data format if (set_point_data_format != -1) { if (set_point_data_format < 0 || set_point_data_format > 10) { fprintf(stderr, "ERROR: unknown point_data_format %d\n", set_point_data_format); byebye(true); } // depending on the conversion we may need to copy the point if (convert_point_type_from_to[lasreader->header.point_data_format][set_point_data_format]) { if (point == 0) point = new LASpoint; } lasreader->header.point_data_format = (U8)set_point_data_format; lasreader->header.clean_laszip(); switch (lasreader->header.point_data_format) { case 0: lasreader->header.point_data_record_length = 20; break; case 1: lasreader->header.point_data_record_length = 28; break; case 2: lasreader->header.point_data_record_length = 26; break; case 3: lasreader->header.point_data_record_length = 34; break; case 4: lasreader->header.point_data_record_length = 57; break; case 5: lasreader->header.point_data_record_length = 63; break; case 6: lasreader->header.point_data_record_length = 30; break; case 7: lasreader->header.point_data_record_length = 36; break; case 8: lasreader->header.point_data_record_length = 38; break; case 9: lasreader->header.point_data_record_length = 59; break; case 10: lasreader->header.point_data_record_length = 67; break; } } // are we supposed to change the point data record length if (set_point_data_record_length != -1) { I32 num_extra_bytes = 0; switch (lasreader->header.point_data_format) { case 0: num_extra_bytes = set_point_data_record_length - 20; break; case 1: num_extra_bytes = set_point_data_record_length - 28; break; case 2: num_extra_bytes = set_point_data_record_length - 26; break; case 3: num_extra_bytes = set_point_data_record_length - 34; break; case 4: num_extra_bytes = set_point_data_record_length - 57; break; case 5: num_extra_bytes = set_point_data_record_length - 63; break; case 6: num_extra_bytes = set_point_data_record_length - 30; break; case 7: num_extra_bytes = set_point_data_record_length - 36; break; case 8: num_extra_bytes = set_point_data_record_length - 38; break; case 9: num_extra_bytes = set_point_data_record_length - 59; break; case 10: num_extra_bytes = set_point_data_record_length - 67; break; } if (num_extra_bytes < 0) { fprintf(stderr, "ERROR: point_data_format %d needs record length of at least %d\n", lasreader->header.point_data_format, set_point_data_record_length - num_extra_bytes); byebye(true); } if (lasreader->header.point_data_record_length < set_point_data_record_length) { if (!point) point = new LASpoint; } lasreader->header.point_data_record_length = (U16)set_point_data_record_length; lasreader->header.clean_laszip(); } // if the point needs to be copied set up the data fields if (point) { point->init(&lasreader->header, lasreader->header.point_data_format, lasreader->header.point_data_record_length); } // maybe we should remove some stuff if (remove_extra_header) { lasreader->header.clean_user_data_in_header(); lasreader->header.clean_user_data_after_header(); } if (remove_all_variable_length_records) { lasreader->header.clean_vlrs(); } else { if (remove_variable_length_record != -1) { lasreader->header.remove_vlr(remove_variable_length_record); } if (remove_variable_length_record_from != -1) { for (i = remove_variable_length_record_to; i >= remove_variable_length_record_from; i--) { lasreader->header.remove_vlr(i); } } } if (remove_tiling_vlr) { lasreader->header.clean_lastiling(); } if (remove_original_vlr) { lasreader->header.clean_lasoriginal(); } // maybe we should add / change the projection information LASquantizer* reproject_quantizer = 0; LASquantizer* saved_quantizer = 0; if (geoprojectionconverter.has_projection(true) || geoprojectionconverter.has_projection(false)) { if (!geoprojectionconverter.has_projection(true) && lasreader->header.vlr_geo_keys) { geoprojectionconverter.set_projection_from_geo_keys(lasreader->header.vlr_geo_keys[0].number_of_keys, (GeoProjectionGeoKeys*)lasreader->header.vlr_geo_key_entries, lasreader->header.vlr_geo_ascii_params, lasreader->header.vlr_geo_double_params); } if (geoprojectionconverter.has_projection(true) && geoprojectionconverter.has_projection(false)) { reproject_quantizer = new LASquantizer(); double point[3]; point[0] = (lasreader->header.min_x+lasreader->header.max_x)/2; point[1] = (lasreader->header.min_y+lasreader->header.max_y)/2; point[2] = (lasreader->header.min_z+lasreader->header.max_z)/2; geoprojectionconverter.to_target(point); reproject_quantizer->x_scale_factor = geoprojectionconverter.get_target_precision(); reproject_quantizer->y_scale_factor = geoprojectionconverter.get_target_precision(); reproject_quantizer->z_scale_factor = lasreader->header.z_scale_factor; reproject_quantizer->x_offset = ((I64)((point[0]/reproject_quantizer->x_scale_factor)/10000000))*10000000*reproject_quantizer->x_scale_factor; reproject_quantizer->y_offset = ((I64)((point[1]/reproject_quantizer->y_scale_factor)/10000000))*10000000*reproject_quantizer->y_scale_factor; reproject_quantizer->z_offset = ((I64)((point[2]/reproject_quantizer->z_scale_factor)/10000000))*10000000*reproject_quantizer->z_scale_factor; } int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params, !geoprojectionconverter.has_projection(false))) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); free(geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); free(geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } } // do we need an extra pass BOOL extra_pass = laswriteopener.is_piped(); // for piped output we need an extra pass if (extra_pass) { if (lasreadopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); usage(true); } if (verbose) fprintf(stderr, "extra pass for piped output: reading %lld points ...\n", lasreader->npoints); // maybe seek to start position if (subsequence_start) lasreader->seek(subsequence_start); while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_XYZ(reproject_quantizer); } lasinventory.add(&lasreader->point); } lasreader->close(); lasreader->header.number_of_point_records = lasinventory.number_of_point_records; for (i = 0; i < 5; i++) lasreader->header.number_of_points_by_return[i] = lasinventory.number_of_points_by_return[i+1]; if (reproject_quantizer) lasreader->header = *reproject_quantizer; lasreader->header.max_x = lasreader->header.get_x(lasinventory.max_X); lasreader->header.min_x = lasreader->header.get_x(lasinventory.min_X); lasreader->header.max_y = lasreader->header.get_y(lasinventory.max_Y); lasreader->header.min_y = lasreader->header.get_y(lasinventory.min_Y); lasreader->header.max_z = lasreader->header.get_z(lasinventory.max_Z); lasreader->header.min_z = lasreader->header.get_z(lasinventory.min_Z); // if (verbose) { fprintf(stderr,"extra pass took %g sec.\n", taketime()-start_time); start_time = taketime(); } if (verbose) fprintf(stderr, "piped output: reading %lld and writing %d points ...\n", lasreader->npoints, lasinventory.number_of_point_records); } else { if (reproject_quantizer) { saved_quantizer = new LASquantizer(); *saved_quantizer = lasreader->header; lasreader->header = *reproject_quantizer; } //if (verbose) fprintf(stderr, "reading %lld and writing all surviving points ...\n", lasreader->npoints); } // check output if (!laswriteopener.active()) { // create name from input name laswriteopener.make_file_name(lasreadopener.get_file_name()); } // prepare the header for the surviving points strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32); lasreader->header.system_identifier[31] = '\0'; char temp[64]; sprintf(temp, "las2las (version %d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; LASwriter* laswriter = 0; // open laswriter if(is_mpi){ // remove any existing out file, before opening with MPI_File_open if(rank==0){ remove(laswriteopener.get_file_name()); } MPI_Barrier(MPI_COMM_WORLD); } laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); byebye(true, argc==1); } // ************************************************************************************************** if(is_mpi == 1){ // jdw, we do this because only rank 0 now writes the header in laswriter_las.cpp MPI_File fh = laswriter->get_MPI_File(); MPI_Offset offset; //MPI_File_get_position(fh, &offset); //printf ("offset %lld, rank %i fh %lld\n", offset, rank, fh); if(rank==0){ MPI_File_get_position(fh, &offset); } MPI_Bcast(&offset, 1, MPI_OFFSET, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); MPI_File_seek(fh, offset, MPI_SEEK_SET); } // **************************************************************************************************** // for piped output we need to re-open the input file if (extra_pass) { if (!lasreadopener.reopen(lasreader)) { fprintf(stderr, "ERROR: could not re-open lasreader\n"); byebye(true); } } else { if (reproject_quantizer) { lasreader->header = *saved_quantizer; delete saved_quantizer; } } // maybe seek to start position if (subsequence_start) lasreader->seek(subsequence_start); // loop over points if (point) { while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_XYZ(reproject_quantizer); } *point = lasreader->point; laswriter->write_point(point); // without extra pass we need inventory of surviving points if (!extra_pass) laswriter->update_inventory(point); } delete point; point = 0; } else // ***************************** MPI ******************************************************** { // ***** Determine the start and stop points for this process ***** I64 left_over_count = lasreader->npoints % process_count; I64 process_points = lasreader->npoints / process_count; subsequence_start = rank*process_points; subsequence_stop = subsequence_start + process_points; if(rank == process_count-1) subsequence_stop += left_over_count; // ***** Set the input stream file offset for this process ***** // subsequence_start parameter gets cast to U32 in the implementation of seek and overflows for large files // manually set the file offset instead for now //((LASreaderLAS*)lasreader)->stream->seek(subsequence_start); I64 header_end_read_position = lasreader->get_Stream()->tell(); //printf("header end %lld subseqence_start * 28 %lld rank %i\n", header_end_read_position, subsequence_start*28, rank); lasreader->p_count = subsequence_start; lasreader->get_Stream()->seek(header_end_read_position + subsequence_start*28); //printf("seek pos first loop %lld rank %i\n", lasreader->get_Stream()->tell(), rank); if (verbose) fprintf(stderr, "reading %lli points, rank %i\n", subsequence_stop - subsequence_start, rank); // *****Read the file for the first time ***** // this first read and filter of the file is to gather a count of points that pass the filter so that // write offsets can be set. I64 filtered_count = 0; //while (lasreader->read_point()){ lasreader->MPI_END_POINT = subsequence_stop; while (lasreader->read_point()) { filtered_count++; } // ***** Gather and set the write offset for this process ***** I64* filtered_counts = (I64*)malloc(process_count * sizeof(I64)); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); filtered_counts[rank] = filtered_count; if(is_mpi)MPI_Allgather(&filtered_count, 1, MPI_LONG_LONG, filtered_counts, 1, MPI_LONG_LONG, MPI_COMM_WORLD); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); if(debug) printf("filtered count %lli rank %i\n", filtered_counts[rank], rank); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); I64 write_point_offset = 0; for (int k=0; k < rank; k++){ write_point_offset += filtered_counts[k]; } if(is_mpi){ MPI_File fh = laswriter->get_MPI_File(); MPI_Offset cur = 0; // jdw, todo, remove the hardcoding by adding methods to read point size from reader MPI_File_seek(fh, write_point_offset*28, MPI_SEEK_CUR); if(debug){ MPI_File_get_position(fh, &cur); printf ("rank %i, write offset %lld\n", rank, write_point_offset*28); } } if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); // ***** Read and filter the input file again, this time write the filtered point since output file offset in now known amd set ***** //lasreader->seek(subsequence_start); // subsequence_start parameter gets cast to U32 in the implementation and overflows for large files // manually set the file offset instead for now //printf("header end %lld subseqence_start * 28 %lld rank %i\n", header_end_read_position, subsequence_start*28, rank); lasreader->p_count = subsequence_start; lasreader->get_Stream()->seek(header_end_read_position + subsequence_start*28); //printf("seek pos second loop %lld rank %i\n", lasreader->get_Stream()->tell(), rank); lasreader->MPI_END_POINT = subsequence_stop; while (lasreader->read_point()) { //if (lasreader->p_count > subsequence_stop) break; //if (clip_to_bounding_box) //{ // if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) // { // continue; // } // } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_XYZ(reproject_quantizer); } laswriter->write_point(&lasreader->point); // without extra pass we need inventory of surviving points if (!extra_pass){ laswriter->update_inventory(&lasreader->point); } } //***** this is part of an mpi write optimization ***** laswriter->get_Stream()->flushBytes(); } // without the extra pass we need to fix the header now // ***** do the inventory reconciliation ***** // ***** Reduce inventory information in rank 0 ***** if (is_mpi){ U32 number_of_point_records = 0; U32 number_of_points_by_return[8]; for(int i = 0; i<8; i++)number_of_points_by_return[i] = 0; I32 max_X = 0; I32 min_X = 0; I32 max_Y = 0; I32 min_Y = 0; I32 max_Z = 0; I32 min_Z = 0; MPI_Reduce(&laswriter->inventory.number_of_point_records, &number_of_point_records, 1, MPI_UNSIGNED, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(laswriter->inventory.number_of_points_by_return, number_of_points_by_return, 8, MPI_UNSIGNED, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.max_X, &max_X, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.min_X, &min_X, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.max_Y, &max_Y, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.min_Y, &min_Y, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.max_Z, &max_Z, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.min_Z, &min_Z, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); if (rank ==0){ laswriter->inventory.number_of_point_records = number_of_point_records; for(int i=0; i<8; i++)laswriter->inventory.number_of_points_by_return[i] = number_of_points_by_return[i]; laswriter->inventory.max_X = max_X; laswriter->inventory.min_X = min_X; laswriter->inventory.max_Y = max_Y; laswriter->inventory.min_Y = min_Y; laswriter->inventory.max_Z = max_Z; laswriter->inventory.min_Z = min_Z; } } if(rank == 0){ if (!extra_pass) { if (reproject_quantizer) lasreader->header = *reproject_quantizer; laswriter->update_header(&lasreader->header, TRUE); } } if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); if (verbose) { fprintf(stderr,"%lli surviving points written by rank: %i\n", laswriter->p_count, rank); } laswriter->close(FALSE); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); delete laswriter; lasreader->close(); delete lasreader; if (reproject_quantizer) delete reproject_quantizer; } if(is_mpi)MPI_Finalize(); time(&wall_end_time); if (verbose) { fprintf(stderr,"total time %.f sec, cpu time: %g sec. rank: %i\n", difftime(wall_end_time, wall_start_time), taketime()-start_time, rank); } return 0; }
int main(int argc, char **argv) { int buf[1024], amode, flag, mynod, len, i; MPI_File fh; MPI_Status status; MPI_Datatype newtype; MPI_Offset disp, offset; MPI_Group group; MPI_Datatype etype, filetype; char datarep[25], *filename; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &mynod); /* process 0 takes the file name as a command-line argument and broadcasts it to other processes */ if (!mynod) { i = 1; while ((i < argc) && strcmp("-fname", *argv)) { i++; argv++; } if (i >= argc) { printf("\n*# Usage: misc <mpiparameter> -- -fname filename\n\n"); MPI_Abort(MPI_COMM_WORLD, 1); } argv++; len = strlen(*argv); filename = (char *) malloc(len+1); strcpy(filename, *argv); MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD); } else { MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); filename = (char *) malloc(len+1); MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD); } MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); MPI_File_write(fh, buf, 1024, MPI_INT, &status); MPI_File_sync(fh); MPI_File_get_amode(fh, &amode); if (!mynod) printf("testing MPI_File_get_amode\n"); if (amode != (MPI_MODE_CREATE | MPI_MODE_RDWR)) printf("amode is %d, should be %d\n\n", amode, MPI_MODE_CREATE | MPI_MODE_RDWR); MPI_File_get_atomicity(fh, &flag); if (flag) printf("atomicity is %d, should be 0\n", flag); if (!mynod) printf("setting atomic mode\n"); MPI_File_set_atomicity(fh, 1); MPI_File_get_atomicity(fh, &flag); if (!flag) printf("atomicity is %d, should be 1\n", flag); MPI_File_set_atomicity(fh, 0); if (!mynod) printf("reverting back to nonatomic mode\n"); MPI_Type_vector(10, 10, 20, MPI_INT, &newtype); MPI_Type_commit(&newtype); MPI_File_set_view(fh, 1000, MPI_INT, newtype, "native", MPI_INFO_NULL); if (!mynod) printf("testing MPI_File_get_view\n"); MPI_File_get_view(fh, &disp, &etype, &filetype, datarep); if ((disp != 1000) || strcmp(datarep, "native")) printf("disp = %I64, datarep = %s, should be 1000, native\n\n", disp, datarep); if (!mynod) printf("testing MPI_File_get_byte_offset\n"); MPI_File_get_byte_offset(fh, 10, &disp); if (disp != (1000+20*sizeof(int))) printf("byte offset = %I64, should be %d\n\n", disp, (int) (1000+20*sizeof(int))); MPI_File_get_group(fh, &group); if (!mynod) printf("testing MPI_File_set_size\n"); MPI_File_set_size(fh, 1000+15*sizeof(int)); MPI_Barrier(MPI_COMM_WORLD); MPI_File_sync(fh); MPI_File_get_size(fh, &disp); if (disp != 1000+15*sizeof(int)) printf("file size = %I64, should be %d\n\n", disp, (int) (1000+15*sizeof(int))); if (!mynod) printf("seeking to eof and testing MPI_File_get_position\n"); MPI_File_seek(fh, 0, MPI_SEEK_END); MPI_File_get_position(fh, &disp); if (disp != 10) printf("file pointer posn = %I64, should be 10\n\n", disp); if (!mynod) printf("testing MPI_File_get_byte_offset\n"); MPI_File_get_byte_offset(fh, disp, &offset); if (offset != (1000+20*sizeof(int))) printf("byte offset = %I64, should be %d\n\n", offset, (int) (1000+20*sizeof(int))); MPI_Barrier(MPI_COMM_WORLD); if (!mynod) printf("testing MPI_File_seek with MPI_SEEK_CUR\n"); MPI_File_seek(fh, -10, MPI_SEEK_CUR); MPI_File_get_position(fh, &disp); MPI_File_get_byte_offset(fh, disp, &offset); if (offset != 1000) printf("file pointer posn in bytes = %I64, should be 1000\n\n", offset); if (!mynod) printf("preallocating disk space up to 8192 bytes\n"); MPI_File_preallocate(fh, 8192); if (!mynod) printf("closing the file and deleting it\n"); MPI_File_close(&fh); MPI_Barrier(MPI_COMM_WORLD); if (!mynod) MPI_File_delete(filename, MPI_INFO_NULL); MPI_Type_free(&newtype); MPI_Type_free(&filetype); MPI_Group_free(&group); free(filename); MPI_Finalize(); return 0; }
void parallel_readwrite(char *file_name, void *dump_buffer, int type_of_file, int is_write, long long offset) { #if MPI && DO_PARALLEL_WRITE MPI_File fh; MPI_Status status; MPI_Datatype mpi_elementary_type, mpi_file_type; int file_open_error, file_write_error ; int error_string_length; char error_string[BUFSIZ]; MPI_Offset file_size; int count; void *mpi_buffer; size_t mpi_buffer_size; int mode; MPI_Offset mpi_offset; MPI_Barrier(MPI_COMM_WORLD); if (is_write) { mode = MPI_MODE_CREATE | MPI_MODE_WRONLY | MPI_MODE_APPEND; } else { mode = MPI_MODE_RDONLY; } file_open_error = MPI_File_open(MPI_COMM_WORLD, file_name, mode, MPI_INFO_NULL, &fh); if (file_open_error != MPI_SUCCESS) { MPI_Error_string(file_open_error, error_string, &error_string_length); fprintf(stderr, "parallel_readwrite(): error opening file: %3d: %s\n", mpi_rank, error_string); MPI_Abort(MPI_COMM_WORLD, file_open_error); /* It is still OK to abort, because we have failed to open the file. */ } else { // if (i_am_the_master) // chmod(file_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (offset < 0L) { if(is_write) { MPI_File_get_position(fh, &mpi_offset); offset = mpi_offset; } else { offset = 0L; } } MPI_Barrier(MPI_COMM_WORLD); //differentiate data type and buffers involved based on file type if( DUMP_FILE == type_of_file ) { mpi_elementary_type = MPI_DUMP_TYPE; mpi_file_type = dump_file_type; mpi_buffer = (void*)dump_buffer; mpi_buffer_size = dump_buffer_size; } else if( GDUMP_FILE == type_of_file){ mpi_elementary_type = MPI_GDUMP_TYPE; mpi_file_type = gdump_file_type; mpi_buffer = (void*)gdump_buffer; mpi_buffer_size = gdump_buffer_size; } else if( GDUMP2_FILE == type_of_file){ mpi_elementary_type = MPI_GDUMP2_TYPE; mpi_file_type = gdump2_file_type; mpi_buffer = (void*)gdump2_buffer; mpi_buffer_size = gdump2_buffer_size; } else if( RDUMP_FILE == type_of_file){ mpi_elementary_type = MPI_RDUMP_TYPE; mpi_file_type = rdump_file_type; mpi_buffer = (void*)rdump_buffer; mpi_buffer_size = rdump_buffer_size; } else if( FDUMP_FILE == type_of_file){ mpi_elementary_type = MPI_FDUMP_TYPE; mpi_file_type = fdump_file_type; mpi_buffer = (void*)fdump_buffer; mpi_buffer_size = fdump_buffer_size; } else { if(i_am_the_master) fprintf(stderr, "Unknown file type %d\n", type_of_file); MPI_File_close(&fh); MPI_Finalize(); exit(2); } MPI_File_set_view(fh, offset, mpi_elementary_type, mpi_file_type, "native", MPI_INFO_NULL); if (is_write) { file_write_error = MPI_File_write_all(fh, mpi_buffer, mpi_buffer_size, mpi_elementary_type, &status); } else { file_write_error = MPI_File_read_all(fh, mpi_buffer, mpi_buffer_size, mpi_elementary_type, &status); } if (file_write_error != MPI_SUCCESS) { MPI_Error_string(file_write_error, error_string, &error_string_length); fprintf(stderr, "parallel_readwrite(): error %s file: %3d: %s\n", (is_write)?("writing"):("reading"), mpi_rank, error_string); MPI_File_close(&fh); //if (i_am_the_master) MPI_File_delete(file_name, MPI_INFO_NULL); MPI_Finalize(); exit(1); } // MPI_Get_count(&status, MPI_FLOAT, &count); // MPI_File_get_size(fh, &file_size); // if(1) { // printf("%3d: wrote %d floats, expected to write %lld floats\n", mpi_rank, count, (long long int)dump_buffer_size); // printf("%3d: file size is %lld bytes, header-related offset is %lld\n", mpi_rank, file_size, offset); // } MPI_File_close(&fh); } #endif }