/*@ MPI_File_delete - Deletes a file Input Parameters: . filename - name of file to delete (string) . info - info object (handle) .N fortran @*/ int MPI_File_delete(char *filename, MPI_Info info) { int flag, error_code; char *tmp; #ifdef MPI_hpux int fl_xmpi; HPMP_IO_START(fl_xmpi, BLKMPIFILEDELETE, TRDTBLOCK, MPI_FILE_NULL, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ /* first check if ADIO has been initialized. If not, initialize it */ if (ADIO_Init_keyval == MPI_KEYVAL_INVALID) { /* check if MPI itself has been initialized. If not, flag an error. Can't initialize it here, because don't know argc, argv */ MPI_Initialized(&flag); if (!flag) { FPRINTF(stderr, "Error: MPI_Init() must be called before using MPI-IO\n"); MPI_Abort(MPI_COMM_WORLD, 1); } MPI_Keyval_create(MPI_NULL_COPY_FN, ADIOI_End_call, &ADIO_Init_keyval, (void *) 0); /* put a dummy attribute on MPI_COMM_WORLD, because we want the delete function to be called when MPI_COMM_WORLD is freed. Hopefully the MPI library frees MPI_COMM_WORLD when MPI_Finalize is called, though the standard does not mandate this. */ MPI_Attr_put(MPI_COMM_WORLD, ADIO_Init_keyval, (void *) 0); /* initialize ADIO */ ADIO_Init( (int *)0, (char ***)0, &error_code); } tmp = strchr(filename, ':'); #ifdef WIN32 // Unfortunately Windows uses ':' behind the drive letter. // So we check if there is only one letter before the ':' // Please do not use a single letter filesystem name! if(tmp && ((tmp-filename) == 1)) tmp = 0; #endif if (tmp) filename = tmp + 1; ADIO_Delete(filename, &error_code); #ifdef MPI_hpux HPMP_IO_END(fl_xmpi, MPI_FILE_NULL, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ return error_code; }
void ADIO_Close(ADIO_File fd, int *error_code) { int i, j, k, combiner, myrank, err, is_contig; static char myname[] = "ADIO_CLOSE"; if (fd->async_count) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); return; } /* because of deferred open, this warants a bit of explaining. First, if * we've done aggregation (fd->agg_comm has a non-nulll communicator ), * then close the file. Then, if any process left has done independent * i/o, close the file. Otherwise, we'll skip the fs-specific close and * just say everything is a-ok. * * XXX: is it ok for those processes with a "real" communicator and those * with "MPI_COMM_SELF" to both call ADIOI_xxx_Close at the same time ? * everyone who ever opened the file will close it. Is order important? Is * timing important? */ if (fd->agg_comm != MPI_COMM_NULL) { (*(fd->fns->ADIOI_xxx_Close))(fd, error_code); } else { if(fd->is_open) { (*(fd->fns->ADIOI_xxx_Close))(fd, error_code); } else { *error_code = MPI_SUCCESS; } } if (fd->access_mode & ADIO_DELETE_ON_CLOSE) { /* if we are doing aggregation and deferred open, then it's possible * that rank 0 does not have access to the file. make sure only an * aggregator deletes the file.*/ MPI_Comm_rank(fd->comm, &myrank); if (myrank == fd->hints->ranklist[0]) { ADIO_Delete(fd->filename, &err); } MPI_Barrier(fd->comm); } if (fd->fortran_handle != -1) { ADIOI_Ftable[fd->fortran_handle] = MPI_FILE_NULL; } ADIOI_Free(fd->hints->ranklist); ADIOI_Free(fd->hints->cb_config_list); ADIOI_Free(fd->hints); MPI_Comm_free(&(fd->comm)); /* deferred open: if we created an aggregator communicator, free it */ if (fd->agg_comm != MPI_COMM_NULL) { MPI_Comm_free(&(fd->agg_comm)); } ADIOI_Free(fd->filename); MPI_Type_get_envelope(fd->etype, &i, &j, &k, &combiner); if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->etype)); ADIOI_Datatype_iscontig(fd->filetype, &is_contig); if (!is_contig) ADIOI_Delete_flattened(fd->filetype); MPI_Type_get_envelope(fd->filetype, &i, &j, &k, &combiner); if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->filetype)); MPI_Info_free(&(fd->info)); /* memory for fd is freed in MPI_File_close */ }
void ADIO_Close(ADIO_File fd, int *error_code) { int i, j, k, combiner, myrank, err, is_contig; static char myname[] = "ADIO_CLOSE"; if (fd->async_count) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); return; } /* because of deferred open, this warants a bit of explaining. First, if * we've done aggregation, * then close the file. Then, if any process left has done independent * i/o, close the file. Otherwise, we'll skip the fs-specific close and * just say everything is a-ok. * * XXX: is it ok for those processes with a "real" communicator and those * with "MPI_COMM_SELF" to both call ADIOI_xxx_Close at the same time ? * everyone who ever opened the file will close it. Is order important? Is * timing important? */ if (fd->hints->deferred_open && fd->is_agg) { (*(fd->fns->ADIOI_xxx_Close))(fd, error_code); } else { if(fd->is_open) { (*(fd->fns->ADIOI_xxx_Close))(fd, error_code); } else { *error_code = MPI_SUCCESS; } } if (fd->access_mode & ADIO_DELETE_ON_CLOSE) { /* if we are doing aggregation and deferred open, then it's possible * that rank 0 does not have access to the file. make sure only an * aggregator deletes the file.*/ MPI_Comm_rank(fd->comm, &myrank); if (myrank == fd->hints->ranklist[0]) { ADIO_Delete(fd->filename, &err); } MPI_Barrier(fd->comm); } if (fd->fortran_handle != -1) { ADIOI_Ftable[fd->fortran_handle] = MPI_FILE_NULL; } if (fd->hints && fd->hints->ranklist) ADIOI_Free(fd->hints->ranklist); if (fd->hints && fd->hints->cb_config_list) ADIOI_Free(fd->hints->cb_config_list); /* This BlueGene platform-specific free must be done in the common code * because the malloc's for these hint data structures are done at the * scope of ADIO_Open within the SetInfo call (ADIOI_GPFS_SetInfo which * calls ADIOI_BG_gen_agg_ranklist). They cannot be done in the * ADIOI_GPFS_Close because of the file creation case where the * ADIOI_GPFS_Close and re-open via ADIOI_GPFS_Open are done which results * in a double-free - ADIOI_GPFS_Open does not redo the SetInfo... */ #ifdef BGQPLATFORM if (fd->hints && fd->hints->fs_hints.bg.bridgelist) ADIOI_Free(fd->hints->fs_hints.bg.bridgelist); if (fd->hints && fd->hints->fs_hints.bg.bridgelistnum) ADIOI_Free(fd->hints->fs_hints.bg.bridgelistnum); #endif /* Persistent File Realms */ if (fd->hints->cb_pfr == ADIOI_HINT_ENABLE) { /* AAR, FSIZE, and User provided uniform File realms */ if (1) { ADIOI_Delete_flattened (fd->file_realm_types[0]); MPI_Type_free (&fd->file_realm_types[0]); } else { for (i=0; i<fd->hints->cb_nodes; i++) { ADIOI_Datatype_iscontig(fd->file_realm_types[i], &is_contig); if (!is_contig) ADIOI_Delete_flattened(fd->file_realm_types[i]); MPI_Type_free (&fd->file_realm_types[i]); } } ADIOI_Free(fd->file_realm_st_offs); ADIOI_Free(fd->file_realm_types); } if (fd->hints) ADIOI_Free(fd->hints); MPI_Comm_free(&(fd->comm)); ADIOI_Free(fd->filename); MPI_Type_get_envelope(fd->etype, &i, &j, &k, &combiner); if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->etype)); ADIOI_Datatype_iscontig(fd->filetype, &is_contig); if (!is_contig) ADIOI_Delete_flattened(fd->filetype); MPI_Type_get_envelope(fd->filetype, &i, &j, &k, &combiner); if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->filetype)); MPI_Info_free(&(fd->info)); if (fd->io_buf != NULL) ADIOI_Free(fd->io_buf); /* memory for fd is freed in MPI_File_close */ }