/* * Copyright (C) by Argonne National Laboratory * See COPYRIGHT in top-level directory */ #include "mpioimpl.h" #include "mpiu_external32.h" #ifdef HAVE_WEAK_SYMBOLS /* Include mapping from MPI->PMPI */ #define MPIO_BUILD_PROFILING #include "mpioprof.h" #endif int MPIU_write_external32_conversion_fn(const void *userbuf, MPI_Datatype datatype, int count, void *filebuf) { int position_i = 0; MPI_Aint position = 0; MPI_Aint bytes = 0; int mpi_errno = MPI_SUCCESS; int is_contig = 0; ADIOI_Datatype_iscontig(datatype, &is_contig); mpi_errno = MPI_Pack_external_size("external32", count, datatype, &bytes); if (mpi_errno != MPI_SUCCESS) goto fn_exit; if (is_contig) { #if MPI_VERSION >= 3 mpi_errno = MPI_Pack_external("external32", userbuf, count, datatype, filebuf, bytes, &position); #else mpi_errno = MPI_Pack_external("external32", (void *) userbuf, count, datatype, filebuf, bytes, &position); #endif if (mpi_errno != MPI_SUCCESS) goto fn_exit; } else { void *tmp_buf = NULL; tmp_buf = ADIOI_Malloc(bytes); if (!tmp_buf) { mpi_errno = MPI_ERR_NO_MEM; goto fn_exit; } #if MPI_VERSION >= 3 mpi_errno = MPI_Pack_external("external32", userbuf, count, datatype, tmp_buf, bytes, &position); #else mpi_errno = MPI_Pack_external("external32", (void *) userbuf, count, datatype, tmp_buf, bytes, &position); #endif if (mpi_errno != MPI_SUCCESS) { ADIOI_Free(tmp_buf); goto fn_exit; } mpi_errno = MPI_Unpack(tmp_buf, bytes, &position_i, filebuf, count, datatype, MPI_COMM_WORLD); if (mpi_errno != MPI_SUCCESS) { ADIOI_Free(tmp_buf); goto fn_exit; } ADIOI_Free(tmp_buf); } fn_exit: return mpi_errno; } int MPIU_read_external32_conversion_fn(void *userbuf, MPI_Datatype datatype, int count, void *filebuf) { int position_i = 0; MPI_Aint position = 0; MPI_Aint bytes = 0; int mpi_errno = MPI_SUCCESS; int is_contig = 0; ADIOI_Datatype_iscontig(datatype, &is_contig); mpi_errno = MPI_Pack_external_size("external32", count, datatype, &bytes); if (mpi_errno != MPI_SUCCESS) goto fn_exit; if (is_contig) { mpi_errno = MPI_Unpack_external("external32", filebuf, bytes, &position, userbuf, count, datatype); if (mpi_errno != MPI_SUCCESS) goto fn_exit; } else { void *tmp_buf = NULL; tmp_buf = ADIOI_Malloc(bytes); if (!tmp_buf) { mpi_errno = MPI_ERR_NO_MEM; goto fn_exit; } mpi_errno = MPI_Pack(filebuf, count, datatype, tmp_buf, bytes, &position_i, MPI_COMM_WORLD); if (mpi_errno != MPI_SUCCESS) { ADIOI_Free(tmp_buf); goto fn_exit; } mpi_errno = MPI_Unpack_external("external32", tmp_buf, bytes, &position, userbuf, count, datatype); if (mpi_errno != MPI_SUCCESS) { ADIOI_Free(tmp_buf); goto fn_exit; } ADIOI_Free(tmp_buf); } fn_exit: return mpi_errno; } int MPIU_datatype_full_size(MPI_Datatype datatype, MPI_Aint * size) { int error_code = MPI_SUCCESS; MPI_Aint true_extent = 0; MPI_Aint true_lb = 0; error_code = MPI_Type_get_true_extent(datatype, &true_lb, &true_extent); if (error_code != MPI_SUCCESS) goto fn_exit; *size = true_extent; fn_exit: return error_code; } /* given a buffer, count, and datatype, return an apropriately allocated, sized * and external32-formatted buffer, suitable for handing off to a subsequent * write routine. Caller is responsible for freeing 'newbuf' */ int MPIU_external32_buffer_setup(const void *buf, int count, MPI_Datatype type, void **newbuf) { MPI_Aint datatype_size = 0, bytes = 0; int error_code; error_code = MPIU_datatype_full_size(type, &datatype_size); if (error_code != MPI_SUCCESS) return error_code; bytes = datatype_size * count; *newbuf = ADIOI_Malloc(bytes); error_code = MPIU_write_external32_conversion_fn(buf, type, count, *newbuf); if (error_code != MPI_SUCCESS) { ADIOI_Free(*newbuf); return error_code; } return MPI_SUCCESS; }