2006-12-31 02:41:42 +03:00
|
|
|
// -*- c++ -*-
|
|
|
|
//
|
|
|
|
// Copyright (c) 2006 Los Alamos National Security, LLC. All rights
|
|
|
|
// reserved.
|
2007-12-07 16:09:07 +03:00
|
|
|
// Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
2006-12-31 02:41:42 +03:00
|
|
|
// $COPYRIGHT$
|
|
|
|
//
|
|
|
|
// Additional copyrights may follow
|
|
|
|
//
|
|
|
|
// $HEADER$
|
|
|
|
//
|
|
|
|
|
2007-12-07 16:09:07 +03:00
|
|
|
// Do not include ompi_config.h before mpi.h because it causes
|
|
|
|
// malloc/free problems due to setting OMPI_BUILDING to 1
|
2006-12-31 02:41:42 +03:00
|
|
|
#include "mpi.h"
|
2007-12-07 16:09:07 +03:00
|
|
|
|
|
|
|
#include "ompi/constants.h"
|
2006-12-31 02:41:42 +03:00
|
|
|
#include "ompi/mpi/cxx/mpicxx.h"
|
|
|
|
#include "opal/threads/mutex.h"
|
2007-12-07 16:09:07 +03:00
|
|
|
#include "opal/class/opal_list.h"
|
|
|
|
#include "ompi/file/file.h"
|
|
|
|
#include "ompi/errhandler/errhandler.h"
|
|
|
|
#include "ompi/runtime/mpiruntime.h"
|
2006-12-31 02:41:42 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
MPI::File::Close()
|
|
|
|
{
|
|
|
|
MPI_File save = mpi_file;
|
|
|
|
(void) MPI_File_close(&mpi_file);
|
|
|
|
|
|
|
|
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
|
|
|
|
MPI::File::mpi_file_map.erase(save);
|
|
|
|
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
MPI::File::Set_errhandler(const MPI::Errhandler& errhandler)
|
|
|
|
{
|
|
|
|
my_errhandler = (MPI::Errhandler *)&errhandler;
|
|
|
|
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
|
|
|
|
MPI::File::mpi_file_map[mpi_file] = this;
|
|
|
|
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
|
|
|
|
(void)MPI_File_set_errhandler(mpi_file, errhandler);
|
|
|
|
}
|
2007-12-07 16:09:07 +03:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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<char*>(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<char*>(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<char*>(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<char*>(datarep), read_fn_c,
|
|
|
|
write_fn_c,
|
|
|
|
extent_intercept_fn, intercept);
|
|
|
|
}
|
|
|
|
|
|
|
|
|