// -*- c++ -*- // // Copyright (c) 2006 Los Alamos National Security, LLC. All rights // reserved. // Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. // $COPYRIGHT$ // // Additional copyrights may follow // // $HEADER$ // // Do not include ompi_config.h before mpi.h because it causes // malloc/free problems due to setting OMPI_BUILDING to 1 #include "mpi.h" #include "ompi/constants.h" #include "ompi/mpi/cxx/mpicxx.h" #include "opal/threads/mutex.h" #include "opal/class/opal_list.h" #include "ompi/file/file.h" #include "ompi/errhandler/errhandler.h" #include "ompi/runtime/mpiruntime.h" void MPI::File::Close() { MPI_File save = mpi_file; (void) MPI_File_close(&mpi_file); } MPI::Errhandler MPI::File::Create_errhandler(MPI::File::Errhandler_fn* function) { MPI_Errhandler c_errhandler = ompi_errhandler_create(OMPI_ERRHANDLER_TYPE_FILE, (ompi_errhandler_generic_handler_fn_t*) function, OMPI_ERRHANDLER_LANG_CXX); c_errhandler->eh_cxx_dispatch_fn = (ompi_errhandler_cxx_dispatch_fn_t*) ompi_mpi_cxx_file_errhandler_invoke; return c_errhandler; } // // Infrastructure for MPI_REGISTER_DATAREP // // Similar to what we have to do in the F77 bindings: call the C // MPI_Register_datarep function with "intercept" callback functions // that conform to the C bindings. In these intercepts, convert the // arguments to C++ calling convertions, and then invoke the actual // C++ callbacks. // Data structure passed to the intercepts (see below). It is an OPAL // list_item_t so that we can clean this memory up during // MPI_FINALIZE. typedef struct intercept_extra_state { opal_list_item_t base; MPI::Datarep_conversion_function *read_fn_cxx; MPI::Datarep_conversion_function *write_fn_cxx; MPI::Datarep_extent_function *extent_fn_cxx; void *extra_state_cxx; } intercept_extra_state_t; static void intercept_extra_state_constructor(intercept_extra_state_t *obj) { obj->read_fn_cxx = NULL; obj->write_fn_cxx = NULL; obj->extent_fn_cxx = NULL; obj->extra_state_cxx = NULL; } OBJ_CLASS_DECLARATION(intercept_extra_state_t); OBJ_CLASS_INSTANCE(intercept_extra_state_t, opal_list_item_t, intercept_extra_state_constructor, NULL); // Intercept function for read conversions static int read_intercept_fn(void *userbuf, MPI_Datatype type_c, int count_c, void *filebuf, MPI_Offset position_c, void *extra_state) { MPI::Datatype type_cxx(type_c); MPI::Offset position_cxx(position_c); intercept_extra_state_t *intercept_data = (intercept_extra_state_t*) extra_state; intercept_data->read_fn_cxx(userbuf, type_cxx, count_c, filebuf, position_cxx, intercept_data->extra_state_cxx); return MPI_SUCCESS; } // Intercept function for write conversions static int write_intercept_fn(void *userbuf, MPI_Datatype type_c, int count_c, void *filebuf, MPI_Offset position_c, void *extra_state) { MPI::Datatype type_cxx(type_c); MPI::Offset position_cxx(position_c); intercept_extra_state_t *intercept_data = (intercept_extra_state_t*) extra_state; intercept_data->write_fn_cxx(userbuf, type_cxx, count_c, filebuf, position_cxx, intercept_data->extra_state_cxx); return MPI_SUCCESS; } // Intercept function for extent calculations static int extent_intercept_fn(MPI_Datatype type_c, MPI_Aint *file_extent_c, void *extra_state) { MPI::Datatype type_cxx(type_c); MPI::Aint file_extent_cxx(*file_extent_c); intercept_extra_state_t *intercept_data = (intercept_extra_state_t*) extra_state; intercept_data->extent_fn_cxx(type_cxx, file_extent_cxx, intercept_data->extra_state_cxx); *file_extent_c = file_extent_cxx; return MPI_SUCCESS; } // C++ bindings for MPI::Register_datarep void MPI::Register_datarep(const char* datarep, Datarep_conversion_function* read_fn_cxx, Datarep_conversion_function* write_fn_cxx, Datarep_extent_function* extent_fn_cxx, void* extra_state_cxx) { intercept_extra_state_t *intercept; intercept = OBJ_NEW(intercept_extra_state_t); if (NULL == intercept) { OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE, "MPI::Register_datarep"); return; } opal_list_append(&ompi_registered_datareps, &(intercept->base)); intercept->read_fn_cxx = read_fn_cxx; intercept->write_fn_cxx = write_fn_cxx; intercept->extent_fn_cxx = extent_fn_cxx; intercept->extra_state_cxx = extra_state_cxx; (void)MPI_Register_datarep(const_cast(datarep), read_intercept_fn, write_intercept_fn, extent_intercept_fn, intercept); } void MPI::Register_datarep(const char* datarep, MPI_Datarep_conversion_function* read_fn_c, Datarep_conversion_function* write_fn_cxx, Datarep_extent_function* extent_fn_cxx, void* extra_state_cxx) { intercept_extra_state_t *intercept; intercept = OBJ_NEW(intercept_extra_state_t); if (NULL == intercept) { OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE, "MPI::Register_datarep"); return; } opal_list_append(&ompi_registered_datareps, &(intercept->base)); intercept->write_fn_cxx = write_fn_cxx; intercept->extent_fn_cxx = extent_fn_cxx; intercept->extra_state_cxx = extra_state_cxx; (void)MPI_Register_datarep(const_cast(datarep), read_fn_c, write_intercept_fn, extent_intercept_fn, intercept); } void MPI::Register_datarep(const char* datarep, Datarep_conversion_function* read_fn_cxx, MPI_Datarep_conversion_function* write_fn_c, Datarep_extent_function* extent_fn_cxx, void* extra_state_cxx) { intercept_extra_state_t *intercept; intercept = OBJ_NEW(intercept_extra_state_t); if (NULL == intercept) { OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE, "MPI::Register_datarep"); return; } opal_list_append(&ompi_registered_datareps, &(intercept->base)); intercept->read_fn_cxx = read_fn_cxx; intercept->extent_fn_cxx = extent_fn_cxx; intercept->extra_state_cxx = extra_state_cxx; (void)MPI_Register_datarep(const_cast(datarep), read_intercept_fn, write_fn_c, extent_intercept_fn, intercept); } void MPI::Register_datarep(const char* datarep, MPI_Datarep_conversion_function* read_fn_c, MPI_Datarep_conversion_function* write_fn_c, Datarep_extent_function* extent_fn_cxx, void* extra_state_cxx) { intercept_extra_state_t *intercept; intercept = OBJ_NEW(intercept_extra_state_t); if (NULL == intercept) { OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE, "MPI::Register_datarep"); return; } opal_list_append(&ompi_registered_datareps, &(intercept->base)); intercept->extent_fn_cxx = extent_fn_cxx; intercept->extra_state_cxx = extra_state_cxx; (void)MPI_Register_datarep(const_cast(datarep), read_fn_c, write_fn_c, extent_intercept_fn, intercept); }