Committing several things under one commit, but they're all at least
somewhat tied together and I'd rather have a consistent commit rather than several smaller commits that individually break the tree: - first cut of src/file/file.c: MPI_File handling. More to come here. - tweaked MPI_Info handling a bit: cause MPI_Info_f2c to invoke error handler if provided index is out of range (vs. returing MPI_INFO_NULL without invoking an error handler) - moved general MPI MCA params off into their own .h and .c file (so that ompi_info can call it and therefore display MPI MCA params) - first [abbreviated] cut of src/mca/io/base/* -- much more to come here; stripped down to basics for this commit - filled in a small number of MPI_File* functions for testing purposes - updated a bunch of doxygen docs --> Unresolved questions about MPI_ERRORS_RETURN, MPI_ERRORS_ABORT, and MPI::ERRORS_THROW_EXCEPTIONS because of vagueness in MPI standard -- Edgar and I are discussing what to do here --> Unresolved questions about what to do in a case like this: MPI_File_open(..., &file); MPI_File_close(&file); MPI_File_read(..., &file); because MPI-2:9.7 says that the default error handler on MPI_File handles is MPI_ERRORS_RETURN -- we can't even print a warning here! This certainly violates the Law of Least Astonishment for MPI users (who certainly expect MPI functions that fail to complain loudly and to abort by default). This commit was SVN r2136.
Этот коммит содержится в:
родитель
c6d6ea8482
Коммит
cfd5524ad5
@ -278,7 +278,7 @@ enum {
|
||||
#define MPI_ERRHANDLER_NULL (&ompi_mpi_errhandler_null)
|
||||
#define MPI_INFO_NULL (&ompi_mpi_info_null)
|
||||
#define MPI_WIN_NULL ((MPI_Win) 0)
|
||||
#define MPI_FILE_NULL ((MPI_File) 0)
|
||||
#define MPI_FILE_NULL (&ompi_mpi_file_null)
|
||||
|
||||
#define MPI_STATUS_IGNORE ((MPI_Status *) 0)
|
||||
#define MPI_STATUSES_IGNORE ((MPI_Status *) 0)
|
||||
@ -399,6 +399,8 @@ extern struct ompi_errhandler_t ompi_mpi_errhandler_null;
|
||||
extern struct ompi_errhandler_t ompi_mpi_errors_are_fatal;
|
||||
extern struct ompi_errhandler_t ompi_mpi_errors_return;
|
||||
|
||||
extern struct ompi_file_t ompi_file_null;
|
||||
|
||||
extern struct ompi_info_t ompi_mpi_info_null;
|
||||
|
||||
extern MPI_Fint *MPI_F_STATUS_IGNORE;
|
||||
|
@ -89,12 +89,14 @@ libmpi_la_LIBADD = \
|
||||
datatype/libdatatype.la \
|
||||
errhandler/liberrhandler.la \
|
||||
event/libevent.la \
|
||||
file/libfile.la \
|
||||
group/libgroup.la \
|
||||
info/libinfo.la \
|
||||
mca/base/libmca_base.la \
|
||||
mca/allocator/base/libmca_allocator_base.la $(MCA_allocator_STATIC_LTLIBS) \
|
||||
mca/coll/base/libmca_coll_base.la $(MCA_coll_STATIC_LTLIBS) \
|
||||
$(MCA_common_STATIC_LTLIBS) \
|
||||
mca/io/base/libmca_io_base.la $(MCA_coll_STATIC_LTLIBS) \
|
||||
mca/llm/base/libmca_llm_base.la $(MCA_llm_STATIC_LTLIBS) \
|
||||
mca/mpool/base/libmca_mpool_base.la $(MCA_mpool_STATIC_LTLIBS) \
|
||||
mca/ns/base/libmca_ns_base.la $(MCA_ns_STATIC_LTLIBS) \
|
||||
@ -114,8 +116,3 @@ libmpi_la_LIBADD = \
|
||||
threads/libthreads.la \
|
||||
util/libutil.la
|
||||
libmpi_la_DEPENDENCIES = $(libmpi_la_LIBADD)
|
||||
|
||||
not_implemented_yet =\
|
||||
ctnetwork/libctnetwork.la \
|
||||
file/libfile.la \
|
||||
win/libwin.la
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mca/topo/topo.h"
|
||||
#include "mca/topo/base/base.h"
|
||||
#include "mca/ns/base/base.h"
|
||||
#include "mpi/runtime/params.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1,19 +1,20 @@
|
||||
# -*- makefile -*-
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
include $(top_srcdir)/config/Makefile.options
|
||||
|
||||
# JMS Remove this when we actually start building a library in here
|
||||
# and $(headers) gets included in a SOURCES somewhere
|
||||
EXTRA_DIST = $(headers)
|
||||
noinst_LTLIBRARIES = libfile.la
|
||||
|
||||
# Source code files
|
||||
|
||||
headers = \
|
||||
file.h
|
||||
|
||||
libfile_la_SOURCES = \
|
||||
$(headers) \
|
||||
file.c
|
||||
|
||||
# Conditionally install the header files
|
||||
|
||||
if WANT_INSTALL_HEADERS
|
||||
|
267
src/file/file.c
Обычный файл
267
src/file/file.c
Обычный файл
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "file/file.h"
|
||||
#include "class/ompi_list.h"
|
||||
#include "mpi/runtime/params.h"
|
||||
|
||||
|
||||
/*
|
||||
* Table for Fortran <-> C file handle conversion
|
||||
*/
|
||||
ompi_pointer_array_t ompi_file_f_to_c_table;
|
||||
|
||||
/*
|
||||
* MPI_FILE_NULL
|
||||
*/
|
||||
ompi_file_t ompi_mpi_file_null;
|
||||
|
||||
|
||||
/*
|
||||
* Local functions
|
||||
*/
|
||||
static void file_constructor(ompi_file_t *obj);
|
||||
static void file_destructor(ompi_file_t *obj);
|
||||
|
||||
|
||||
/*
|
||||
* Class instance for ompi_file_t
|
||||
*/
|
||||
OBJ_CLASS_INSTANCE(ompi_file_t,
|
||||
ompi_object_t,
|
||||
file_constructor,
|
||||
file_destructor);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize file handling bookeeping
|
||||
*/
|
||||
int ompi_file_init(void)
|
||||
{
|
||||
/* Setup file array */
|
||||
|
||||
OBJ_CONSTRUCT(&ompi_file_f_to_c_table, ompi_pointer_array_t);
|
||||
|
||||
/* Setup MPI_FILE_NULL. Note that it will have the default error
|
||||
handler of MPI_ERRORS_RETURN, per MPI-2:9.7 (p265). */
|
||||
|
||||
OBJ_CONSTRUCT(&ompi_mpi_file_null, ompi_file_t);
|
||||
ompi_mpi_file_null.f_comm = &ompi_mpi_comm_null;
|
||||
OBJ_RETAIN(ompi_mpi_file_null.f_comm);
|
||||
ompi_mpi_file_null.f_f_to_c_index = 0;
|
||||
ompi_pointer_array_set_item(&ompi_file_f_to_c_table, 0,
|
||||
&ompi_mpi_file_null);
|
||||
|
||||
/* All done */
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a file handle
|
||||
*/
|
||||
int ompi_file_open(ompi_communicator_t *comm, char *filename,
|
||||
int amode, ompi_info_t *info, ompi_file_t **fh)
|
||||
{
|
||||
ompi_file_t *file;
|
||||
|
||||
file = OBJ_NEW(ompi_file_t);
|
||||
if (NULL == file) {
|
||||
return OMPI_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
/* Save the params */
|
||||
|
||||
file->f_comm = comm;
|
||||
OBJ_RETAIN(comm);
|
||||
file->f_filename = strdup(filename);
|
||||
file->f_amode = amode;
|
||||
|
||||
/* Select a module and actually open the file */
|
||||
|
||||
/* JMS fill in here */
|
||||
|
||||
/* All done */
|
||||
|
||||
*fh = file;
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close a file handle
|
||||
*/
|
||||
int ompi_file_close(ompi_file_t **file)
|
||||
{
|
||||
(*file)->f_flags |= OMPI_FILE_ISCLOSED;
|
||||
OBJ_RELEASE(*file);
|
||||
*file = MPI_FILE_NULL;
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Shut down the MPI_File bookkeeping
|
||||
*/
|
||||
int ompi_file_finalize(void)
|
||||
{
|
||||
size_t i, max;
|
||||
size_t num_unnamed;
|
||||
ompi_file_t *file;
|
||||
|
||||
/* Release MPI_FILE_NULL. Do this so that we don't get a bogus leak
|
||||
report on it. Plus, it's statically allocated, so we don't want
|
||||
to call OBJ_RELEASE on it. */
|
||||
|
||||
OBJ_DESTRUCT(&ompi_mpi_file_null);
|
||||
ompi_pointer_array_set_item(&ompi_file_f_to_c_table, 0, NULL);
|
||||
|
||||
/* Iterate through all the file handles and destroy them. Note
|
||||
that this also takes care of destroying MPI_FILE_NULL. */
|
||||
|
||||
max = ompi_pointer_array_get_size(&ompi_file_f_to_c_table);
|
||||
for (num_unnamed = i = 0; i < max; ++i) {
|
||||
file = ompi_pointer_array_get_item(&ompi_file_f_to_c_table, i);
|
||||
|
||||
/* If the file was closed but still exists because the user
|
||||
told us to never free handles, then do an OBJ_RELEASE it
|
||||
and all is well. Then get the value again and see if it's
|
||||
actually been freed. */
|
||||
|
||||
if (NULL != file && ompi_debug_no_free_handles &&
|
||||
0 == (file->f_flags & OMPI_FILE_ISCLOSED)) {
|
||||
OBJ_RELEASE(file);
|
||||
file = ompi_pointer_array_get_item(&ompi_file_f_to_c_table, i);
|
||||
}
|
||||
|
||||
if (NULL != file) {
|
||||
|
||||
/* If the user wanted warnings about MPI object leaks,
|
||||
print out a message */
|
||||
|
||||
if (ompi_debug_show_handle_leaks) {
|
||||
++num_unnamed;
|
||||
}
|
||||
|
||||
OBJ_RELEASE(file);
|
||||
}
|
||||
/* Don't bother setting each element back down to NULL; it
|
||||
would just take a lot of thread locks / unlocks and since
|
||||
we're destroying everything, it isn't worth it */
|
||||
}
|
||||
if (num_unnamed > 0) {
|
||||
ompi_output(0, "WANRING: %d unnamed MPI_File handles still allocated at MPI_FINALIZE", num_unnamed);
|
||||
}
|
||||
OBJ_DESTRUCT(&ompi_file_f_to_c_table);
|
||||
|
||||
/* All done */
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
static void file_constructor(ompi_file_t *file)
|
||||
{
|
||||
/* Initialize the MPI_FILE_OPEN params */
|
||||
|
||||
file->f_comm = NULL;
|
||||
file->f_filename = NULL;
|
||||
file->f_amode = 0;
|
||||
|
||||
/* Initialize flags */
|
||||
|
||||
file->f_flags = 0;
|
||||
|
||||
/* Initialize the fortran <--> C translation index */
|
||||
|
||||
file->f_f_to_c_index = ompi_pointer_array_add(&ompi_file_f_to_c_table,
|
||||
file);
|
||||
|
||||
/* Initialize the error handler. Per MPI-2:9.7 (p265), the
|
||||
default error handler on file handles is the error handler on
|
||||
MPI_FILE_NULL, which starts out as MPI_ERRORS_RETURN (but can
|
||||
be changed by invoking MPI_FILE_SET_ERRHANDLER on
|
||||
MPI_FILE_NULL). */
|
||||
|
||||
file->error_handler = ompi_mpi_file_null.error_handler;
|
||||
OBJ_RETAIN(file->error_handler);
|
||||
|
||||
/* Initialize the module */
|
||||
|
||||
file->f_io_version = OMPI_IO_VERSION_NONE;
|
||||
memset(&(file->f_io_selected_module), 0,
|
||||
sizeof(file->f_io_selected_module));
|
||||
file->f_selected_data = NULL;
|
||||
|
||||
/* If the user doesn't want us to ever free it, then add an extra
|
||||
RETAIN here */
|
||||
|
||||
if (ompi_debug_no_free_handles) {
|
||||
OBJ_RETAIN(&(file->super));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destructor
|
||||
*/
|
||||
static void file_destructor(ompi_file_t *file)
|
||||
{
|
||||
/* Finalize the module */
|
||||
|
||||
switch (file->f_io_version) {
|
||||
case OMPI_IO_VERSION_1_0_0:
|
||||
#if 0
|
||||
/* JMS need to implement */
|
||||
file->f_io_selected_module.v1_0_0.iom_finalize(file);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OMPI_IO_VERSION_2_0_0:
|
||||
/* JMS fill in here */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* All other cases are uninitialized or MPI_FILE_NULL */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finalize the data members */
|
||||
|
||||
if (NULL != file->f_comm) {
|
||||
OBJ_RELEASE(file->f_comm);
|
||||
#if OMPI_ENABLE_DEBUG
|
||||
file->f_comm = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (NULL != file->f_filename) {
|
||||
free(file->f_filename);
|
||||
#if OMPI_ENABLE_DEBUG
|
||||
file->f_filename = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (NULL != file->error_handler) {
|
||||
OBJ_RELEASE(file->error_handler);
|
||||
#if OMPI_ENABLE_DEBUG
|
||||
file->error_handler = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Reset the f_to_c table entry */
|
||||
|
||||
if (MPI_UNDEFINED != file->f_f_to_c_index &&
|
||||
NULL != ompi_pointer_array_get_item(&ompi_file_f_to_c_table,
|
||||
file->f_f_to_c_index)) {
|
||||
ompi_pointer_array_set_item(&ompi_file_f_to_c_table,
|
||||
file->f_f_to_c_index, NULL);
|
||||
}
|
||||
}
|
185
src/file/file.h
185
src/file/file.h
@ -7,34 +7,189 @@
|
||||
|
||||
#include "mpi.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "communicator/communicator.h"
|
||||
#include "threads/mutex.h"
|
||||
#include "info/info.h"
|
||||
#include "mca/io/io.h"
|
||||
|
||||
typedef enum {
|
||||
OMPI_IO_1_0_0,
|
||||
OMPI_IO_2_0_0
|
||||
} ompi_io_version_t;
|
||||
/**
|
||||
* Version of IO component interface that we're using.
|
||||
*
|
||||
* The IO component is being designed to ensure that it can
|
||||
* simultaneously support multiple component versions in a single
|
||||
* executable. This is because ROMIO will always be v1.x that
|
||||
* supports pretty much a 1-to-1 MPI-API-to-module-function mapping,
|
||||
* but we plan to have a v2.x series that will be "something
|
||||
* different" (as yet undefined).
|
||||
*/
|
||||
enum ompi_io_version_t {
|
||||
OMPI_IO_VERSION_NONE,
|
||||
OMPI_IO_VERSION_1_0_0,
|
||||
OMPI_IO_VERSION_2_0_0,
|
||||
|
||||
OMPI_IO_VERSION_MAX
|
||||
};
|
||||
/**
|
||||
* Convenience typedef
|
||||
*/
|
||||
typedef enum ompi_io_version_t ompi_io_version_t;
|
||||
|
||||
|
||||
/*
|
||||
* Flags
|
||||
*/
|
||||
#define OMPI_FILE_ISCLOSED 0x00000001
|
||||
#define OMPI_FILE_HIDDEN 0x00000002
|
||||
|
||||
|
||||
/**
|
||||
* Back-end structure for MPI_File
|
||||
*/
|
||||
struct ompi_file_t {
|
||||
char f_name[MPI_MAX_OBJECT_NAME];
|
||||
ompi_io_version_t ompi_io_version;
|
||||
ompi_object_t super;
|
||||
/**< Base of OBJ_* interface */
|
||||
|
||||
/* Hooks for io modules to hang things */
|
||||
ompi_communicator_t *f_comm;
|
||||
/**< Communicator that this file was created with */
|
||||
|
||||
union {
|
||||
mca_io_base_module_1_0_0_t f_io;
|
||||
} mca_io_functions;
|
||||
char *f_filename;
|
||||
/**< Filename that this file was created with */
|
||||
|
||||
/* index in Fortran <-> C translation array */
|
||||
int f_amode;
|
||||
/**< Amode that this file was created with */
|
||||
|
||||
int32_t f_flags;
|
||||
/**< Bit flags */
|
||||
|
||||
int f_f_to_c_index;
|
||||
|
||||
/* Error handling. This field does not have the "f_" prefix so that
|
||||
the OMPI_ERRHDL_* macros can find it, regardless of whether it's a
|
||||
comm, window, or file. */
|
||||
/**< Index in Fortran <-> C translation array */
|
||||
|
||||
ompi_errhandler_t *error_handler;
|
||||
/**< Error handler. This field does not have the "f_" prefix so
|
||||
that the OMPI_ERRHDL_* macros can find it, regardless of
|
||||
whether it's a comm, window, or file. */
|
||||
|
||||
ompi_io_version_t f_io_version;
|
||||
/**< Indicate what version of the IO component we're using (this
|
||||
indicates what member to look at in the union, below) */
|
||||
|
||||
union {
|
||||
mca_io_base_module_1_0_0_t v1_0_0;
|
||||
/**< IO v1.0.0 module */
|
||||
} f_io_selected_module;
|
||||
/**< The selected module */
|
||||
|
||||
struct mca_io_base_file_t *f_selected_data;
|
||||
/**< Allow the selected module to cache data on the file */
|
||||
};
|
||||
/**
|
||||
* Convenience typedef
|
||||
*/
|
||||
typedef struct ompi_file_t ompi_file_t;
|
||||
|
||||
|
||||
/**
|
||||
* Back-end instances for MPI_FILE_NULL
|
||||
*/
|
||||
extern ompi_file_t ompi_mpi_file_null;
|
||||
|
||||
|
||||
/**
|
||||
* Fortran to C conversion table
|
||||
*/
|
||||
extern ompi_pointer_array_t ompi_file_f_to_c_table;
|
||||
|
||||
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* Initialize MPI_File handling.
|
||||
*
|
||||
* @retval OMPI_SUCCESS Always.
|
||||
*
|
||||
* Invoked during ompi_mpi_init().
|
||||
*/
|
||||
int ompi_file_init(void);
|
||||
|
||||
/**
|
||||
* Open a file handle.
|
||||
*
|
||||
* @param comm Communicator
|
||||
* @param filename String filename
|
||||
* @param amode Mode flags
|
||||
* @param info Info
|
||||
* @param fh Output file handle
|
||||
*
|
||||
* @retval OMPI_SUCCESS Upon success
|
||||
* @retval OMPI_ERR* Upon error
|
||||
*
|
||||
* Create a file handle and select an io module to be paired with
|
||||
* it.
|
||||
*/
|
||||
int ompi_file_open(ompi_communicator_t *comm, char *filename,
|
||||
int amode, ompi_info_t *info,
|
||||
ompi_file_t **fh);
|
||||
|
||||
/**
|
||||
* Atomicly set a name on a file handle.
|
||||
*
|
||||
* @param file MPI_File handle to set the name on
|
||||
* @param name NULL-terminated string to use
|
||||
*
|
||||
* @returns OMPI_SUCCESS Always.
|
||||
*
|
||||
* At most (MPI_MAX_OBJECT_NAME-1) characters will be copied over to
|
||||
* the file name's name. This function is performed atomically -- a
|
||||
* lock is used to ensure that there are not multiple writers to the
|
||||
* name to ensure that we don't end up with an erroneous name (e.g.,
|
||||
* a name without a \0 at the end). After invoking this function,
|
||||
* ompi_file_is_name_set() will return true.
|
||||
*/
|
||||
int ompi_file_set_name(ompi_file_t *file, char *name);
|
||||
|
||||
/**
|
||||
* Close a file handle
|
||||
*
|
||||
* @param file MPI_File handle to set the name on
|
||||
*
|
||||
* @returns OMPI_SUCCESS Always.
|
||||
*
|
||||
* Close a file handle and free all resources associated with it.
|
||||
*/
|
||||
int ompi_file_close(ompi_file_t **file);
|
||||
|
||||
/**
|
||||
* Tear down MPI_File handling.
|
||||
*
|
||||
* @retval OMPI_SUCCESS Always.
|
||||
*
|
||||
* Invoked during ompi_mpi_finalize().
|
||||
*/
|
||||
int ompi_file_finalize(void);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if an MPI_File handle is valid.
|
||||
*
|
||||
* @param file The MPI file handle
|
||||
*
|
||||
* @retval true If the file handle is not valid
|
||||
* @retval false If the file handle is valid
|
||||
*
|
||||
* This is a convenience function, mainly for error checking in
|
||||
* top-level MPI API functions.
|
||||
*/
|
||||
static inline bool ompi_file_invalid(ompi_file_t *file)
|
||||
{
|
||||
return (NULL == file ||
|
||||
&ompi_mpi_file_null == file ||
|
||||
0 != (file->f_flags & OMPI_FILE_ISCLOSED));
|
||||
}
|
||||
|
||||
#endif /* OMPI_FILE_H */
|
||||
|
219
src/info/info.c
219
src/info/info.c
@ -4,7 +4,7 @@
|
||||
|
||||
#include "info/info.h"
|
||||
#include "include/constants.h"
|
||||
#include "mpi/runtime/mpiruntime.h"
|
||||
#include "mpi/runtime/params.h"
|
||||
#include "util/output.h"
|
||||
|
||||
|
||||
@ -17,11 +17,11 @@ ompi_info_t ompi_mpi_info_null;
|
||||
/*
|
||||
* Local functions
|
||||
*/
|
||||
static void ompi_info_construct(ompi_info_t *info);
|
||||
static void ompi_info_destruct(ompi_info_t *info);
|
||||
static void ompi_info_entry_construct(ompi_info_entry_t *entry);
|
||||
static void ompi_info_entry_destruct(ompi_info_entry_t *entry);
|
||||
static ompi_info_entry_t *ompi_info_find_key (ompi_info_t *info, char *key);
|
||||
static void info_constructor(ompi_info_t *info);
|
||||
static void info_destructor(ompi_info_t *info);
|
||||
static void info_entry_constructor(ompi_info_entry_t *entry);
|
||||
static void info_entry_destructor(ompi_info_entry_t *entry);
|
||||
static ompi_info_entry_t *info_find_key (ompi_info_t *info, char *key);
|
||||
|
||||
|
||||
/*
|
||||
@ -29,21 +29,21 @@ static ompi_info_entry_t *ompi_info_find_key (ompi_info_t *info, char *key);
|
||||
*/
|
||||
OBJ_CLASS_INSTANCE(ompi_info_t,
|
||||
ompi_list_t,
|
||||
ompi_info_construct,
|
||||
ompi_info_destruct);
|
||||
info_constructor,
|
||||
info_destructor);
|
||||
|
||||
/*
|
||||
* ompi_info_entry_t classes
|
||||
*/
|
||||
OBJ_CLASS_INSTANCE(ompi_info_entry_t,
|
||||
ompi_list_item_t,
|
||||
ompi_info_entry_construct,
|
||||
ompi_info_entry_destruct);
|
||||
info_entry_constructor,
|
||||
info_entry_destructor);
|
||||
|
||||
/*
|
||||
* The global fortran <-> C translation table
|
||||
*/
|
||||
ompi_pointer_array_t *ompi_info_f_to_c_table;
|
||||
ompi_pointer_array_t ompi_info_f_to_c_table;
|
||||
|
||||
|
||||
/*
|
||||
@ -54,15 +54,12 @@ int ompi_info_init(void)
|
||||
{
|
||||
/* initialize table */
|
||||
|
||||
ompi_info_f_to_c_table = OBJ_NEW(ompi_pointer_array_t);
|
||||
if (NULL == ompi_info_f_to_c_table) {
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
OBJ_CONSTRUCT(&ompi_info_f_to_c_table, ompi_pointer_array_t);
|
||||
|
||||
/* Create MPI_INFO_NULL */
|
||||
|
||||
OBJ_CONSTRUCT(&ompi_mpi_info_null, ompi_info_t);
|
||||
ompi_mpi_info_null.i_fhandle = 0;
|
||||
ompi_mpi_info_null.i_f_to_c_index = 0;
|
||||
|
||||
/* All done */
|
||||
|
||||
@ -70,79 +67,6 @@ int ompi_info_init(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Shut down MPI_Info handling
|
||||
*/
|
||||
int ompi_info_finalize(void)
|
||||
{
|
||||
size_t i, max;
|
||||
ompi_info_t *info;
|
||||
ompi_list_item_t *item;
|
||||
ompi_info_entry_t *entry;
|
||||
bool found = false;
|
||||
|
||||
/* Destroy MPI_INFO_NULL */
|
||||
|
||||
OBJ_DESTRUCT(&ompi_mpi_info_null);
|
||||
|
||||
/* Go through the f2c table and see if anything is left. Free them
|
||||
all. */
|
||||
|
||||
max = ompi_pointer_array_get_size(ompi_info_f_to_c_table);
|
||||
for (i = 0; i < max; ++i) {
|
||||
info = ompi_pointer_array_get_item(ompi_info_f_to_c_table, i);
|
||||
|
||||
/* If the info was freed but still exists because the user told us
|
||||
to never free handles, then do an OBJ_RELEASE it and all is
|
||||
well. Then get the value again and see if it's actually been
|
||||
freed. */
|
||||
|
||||
if (NULL != info && ompi_debug_handle_never_free && info->i_freed) {
|
||||
OBJ_RELEASE(info);
|
||||
info = ompi_pointer_array_get_item(ompi_info_f_to_c_table, i);
|
||||
}
|
||||
|
||||
/* If it still exists here and was never freed, then it's an
|
||||
orphan */
|
||||
|
||||
if (NULL != info) {
|
||||
|
||||
/* If the user wanted warnings about MPI object leaks, print out
|
||||
a message */
|
||||
|
||||
if (!info->i_freed && ompi_debug_show_handle_leaks) {
|
||||
if (ompi_debug_show_handle_leaks) {
|
||||
ompi_output(0, "WARNING: MPI_Info still allocated at MPI_FINALIZE");
|
||||
for (item = ompi_list_get_first(&(info->super));
|
||||
ompi_list_get_end(&(info->super)) != item;
|
||||
item = ompi_list_get_next(item)) {
|
||||
entry = (ompi_info_entry_t *) item;
|
||||
ompi_output(0, "WARNING: key=\"%s\", value=\"%s\"",
|
||||
entry->ie_key,
|
||||
NULL != entry->ie_value ? entry->ie_value : "(null)");
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
OBJ_RELEASE(info);
|
||||
}
|
||||
|
||||
/* Don't bother setting each element back down to NULL; it would
|
||||
just take a lot of thread locks / unlocks and since we're
|
||||
destroying everything, it isn't worth it */
|
||||
|
||||
if (!found && ompi_debug_show_handle_leaks) {
|
||||
ompi_output(0, "WARNING: (no keys)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All done -- release the table */
|
||||
|
||||
OBJ_RELEASE(ompi_info_f_to_c_table);
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Duplicate an info
|
||||
*/
|
||||
@ -183,7 +107,7 @@ int ompi_info_set (ompi_info_t *info, char *key, char *value)
|
||||
}
|
||||
|
||||
OMPI_THREAD_LOCK(info->i_lock);
|
||||
old_info = ompi_info_find_key (info, key);
|
||||
old_info = info_find_key (info, key);
|
||||
if (NULL != old_info) {
|
||||
/*
|
||||
* key already exists. remove the value associated with it
|
||||
@ -227,7 +151,7 @@ int ompi_info_get (ompi_info_t *info, char *key, int valuelen,
|
||||
int value_length;
|
||||
|
||||
OMPI_THREAD_LOCK(info->i_lock);
|
||||
search = ompi_info_find_key (info, key);
|
||||
search = info_find_key (info, key);
|
||||
if (NULL == search){
|
||||
*flag = 0;
|
||||
} else {
|
||||
@ -263,7 +187,7 @@ int ompi_info_delete (ompi_info_t *info, char *key)
|
||||
ompi_info_entry_t *found;
|
||||
|
||||
OMPI_THREAD_LOCK(info->i_lock);
|
||||
search = ompi_info_find_key (info, key);
|
||||
search = info_find_key (info, key);
|
||||
if (NULL == search){
|
||||
OMPI_THREAD_UNLOCK(info->i_lock);
|
||||
return MPI_ERR_INFO_NOKEY;
|
||||
@ -291,7 +215,7 @@ int ompi_info_get_valuelen (ompi_info_t *info, char *key, int *valuelen,
|
||||
ompi_info_entry_t *search;
|
||||
|
||||
OMPI_THREAD_LOCK(info->i_lock);
|
||||
search = ompi_info_find_key (info, key);
|
||||
search = info_find_key (info, key);
|
||||
if (NULL == search){
|
||||
*flag = 0;
|
||||
} else {
|
||||
@ -339,20 +263,97 @@ int ompi_info_get_nthkey (ompi_info_t *info, int n, char *key)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Shut down MPI_Info handling
|
||||
*/
|
||||
int ompi_info_finalize(void)
|
||||
{
|
||||
size_t i, max;
|
||||
ompi_info_t *info;
|
||||
ompi_list_item_t *item;
|
||||
ompi_info_entry_t *entry;
|
||||
bool found = false;
|
||||
|
||||
/* Release MPI_INFO_NULL. Do this so that we don't get a bogus
|
||||
leak report on it. Plus, it's statically allocated, so we
|
||||
don't want to call OBJ_RELEASE on it. */
|
||||
|
||||
OBJ_DESTRUCT(&ompi_mpi_info_null);
|
||||
ompi_pointer_array_set_item(&ompi_info_f_to_c_table, 0, NULL);
|
||||
|
||||
/* Go through the f2c table and see if anything is left. Free them
|
||||
all. */
|
||||
|
||||
max = ompi_pointer_array_get_size(&ompi_info_f_to_c_table);
|
||||
for (i = 0; i < max; ++i) {
|
||||
info = ompi_pointer_array_get_item(&ompi_info_f_to_c_table, i);
|
||||
|
||||
/* If the info was freed but still exists because the user
|
||||
told us to never free handles, then do an OBJ_RELEASE it
|
||||
and all is well. Then get the value again and see if it's
|
||||
actually been freed. */
|
||||
|
||||
if (NULL != info && ompi_debug_no_free_handles && info->i_freed) {
|
||||
OBJ_RELEASE(info);
|
||||
info = ompi_pointer_array_get_item(&ompi_info_f_to_c_table, i);
|
||||
}
|
||||
|
||||
/* If it still exists here and was never freed, then it's an
|
||||
orphan */
|
||||
|
||||
if (NULL != info) {
|
||||
|
||||
/* If the user wanted warnings about MPI object leaks, print out
|
||||
a message */
|
||||
|
||||
if (!info->i_freed && ompi_debug_show_handle_leaks) {
|
||||
if (ompi_debug_show_handle_leaks) {
|
||||
ompi_output(0, "WARNING: MPI_Info still allocated at MPI_FINALIZE");
|
||||
for (item = ompi_list_get_first(&(info->super));
|
||||
ompi_list_get_end(&(info->super)) != item;
|
||||
item = ompi_list_get_next(item)) {
|
||||
entry = (ompi_info_entry_t *) item;
|
||||
ompi_output(0, "WARNING: key=\"%s\", value=\"%s\"",
|
||||
entry->ie_key,
|
||||
NULL != entry->ie_value ? entry->ie_value : "(null)");
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
OBJ_RELEASE(info);
|
||||
}
|
||||
|
||||
/* Don't bother setting each element back down to NULL; it
|
||||
would just take a lot of thread locks / unlocks and
|
||||
since we're destroying everything, it isn't worth it */
|
||||
|
||||
if (!found && ompi_debug_show_handle_leaks) {
|
||||
ompi_output(0, "WARNING: (no keys)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All done -- destroy the table */
|
||||
|
||||
OBJ_DESTRUCT(&ompi_info_f_to_c_table);
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is invoked when OBJ_NEW() is called. Here, we add this
|
||||
* info pointer to the table and then store its index as the handle
|
||||
*/
|
||||
static void ompi_info_construct(ompi_info_t *info)
|
||||
static void info_constructor(ompi_info_t *info)
|
||||
{
|
||||
info->i_fhandle = ompi_pointer_array_add(ompi_info_f_to_c_table, info);
|
||||
info->i_f_to_c_index = ompi_pointer_array_add(&ompi_info_f_to_c_table,
|
||||
info);
|
||||
info->i_lock = OBJ_NEW(ompi_mutex_t);
|
||||
info->i_freed = false;
|
||||
|
||||
/* If the user doesn't want us to ever free it, then add an extra
|
||||
RETAIN here */
|
||||
|
||||
if (ompi_debug_handle_never_free) {
|
||||
if (ompi_debug_no_free_handles) {
|
||||
OBJ_RETAIN(&(info->super));
|
||||
}
|
||||
}
|
||||
@ -363,7 +364,7 @@ static void ompi_info_construct(ompi_info_t *info)
|
||||
* done, we need to remove the entry from the ompi fortran to C
|
||||
* translation table
|
||||
*/
|
||||
static void ompi_info_destruct(ompi_info_t *info)
|
||||
static void info_destructor(ompi_info_t *info)
|
||||
{
|
||||
ompi_list_item_t *item;
|
||||
ompi_info_entry_t *iterator;
|
||||
@ -377,28 +378,33 @@ static void ompi_info_destruct(ompi_info_t *info)
|
||||
OBJ_RELEASE(iterator);
|
||||
}
|
||||
|
||||
/* reset the ompi_info_f_to_c_table entry - make sure that the
|
||||
/* reset the &ompi_info_f_to_c_table entry - make sure that the
|
||||
entry is in the table */
|
||||
|
||||
if (NULL != ompi_pointer_array_get_item(ompi_info_f_to_c_table,
|
||||
info->i_fhandle)){
|
||||
ompi_pointer_array_set_item(ompi_info_f_to_c_table,
|
||||
info->i_fhandle, NULL);
|
||||
if (MPI_UNDEFINED != info->i_f_to_c_index &&
|
||||
NULL != ompi_pointer_array_get_item(&ompi_info_f_to_c_table,
|
||||
info->i_f_to_c_index)){
|
||||
ompi_pointer_array_set_item(&ompi_info_f_to_c_table,
|
||||
info->i_f_to_c_index, NULL);
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
|
||||
OBJ_RELEASE(info->i_lock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ompi_info_entry_t interface functions
|
||||
*/
|
||||
static void ompi_info_entry_construct(ompi_info_entry_t *entry)
|
||||
static void info_entry_constructor(ompi_info_entry_t *entry)
|
||||
{
|
||||
memset(entry->ie_key, 0, sizeof(entry->ie_key));
|
||||
entry->ie_key[MPI_MAX_INFO_KEY] = 0;
|
||||
}
|
||||
|
||||
|
||||
static void ompi_info_entry_destruct(ompi_info_entry_t *entry)
|
||||
static void info_entry_destructor(ompi_info_entry_t *entry)
|
||||
{
|
||||
if (NULL != entry->ie_value) {
|
||||
free(entry->ie_value);
|
||||
@ -412,7 +418,7 @@ static void ompi_info_entry_destruct(ompi_info_entry_t *entry)
|
||||
* Do NOT thread lock in here -- the calling function is responsible
|
||||
* for that.
|
||||
*/
|
||||
static ompi_info_entry_t *ompi_info_find_key (ompi_info_t *info, char *key)
|
||||
static ompi_info_entry_t *info_find_key (ompi_info_t *info, char *key)
|
||||
{
|
||||
ompi_info_entry_t *iterator;
|
||||
|
||||
@ -431,6 +437,3 @@ static ompi_info_entry_t *ompi_info_find_key (ompi_info_t *info, char *key)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ struct ompi_info_t {
|
||||
ompi_list_t super;
|
||||
/**< generic list pointer which is the container for (key,value)
|
||||
pairs */
|
||||
int i_fhandle;
|
||||
int i_f_to_c_index;
|
||||
/**< fortran handle for info. This is needed for translation from
|
||||
fortran to C and vice versa */
|
||||
ompi_mutex_t *i_lock;
|
||||
@ -59,7 +59,7 @@ typedef struct ompi_info_entry_t ompi_info_entry_t;
|
||||
/**
|
||||
* Table for Fortran <-> C translation table
|
||||
*/
|
||||
extern ompi_pointer_array_t *ompi_info_f_to_c_table;
|
||||
extern ompi_pointer_array_t ompi_info_f_to_c_table;
|
||||
|
||||
/**
|
||||
* Global instance for MPI_INFO_NULL
|
||||
|
@ -4,7 +4,21 @@
|
||||
|
||||
include $(top_srcdir)/config/Makefile.options
|
||||
|
||||
# For VPATH builds, have to specify where static-modules.h will be found
|
||||
noinst_LTLIBRARIES = libmca_io_base.la
|
||||
|
||||
AM_CPPFLAGS = -I$(top_builddir)/src
|
||||
headers = \
|
||||
base.h
|
||||
|
||||
libmca_io_base_la_SOURCES = \
|
||||
$(headers) \
|
||||
io_base_close.c \
|
||||
io_base_open.c
|
||||
|
||||
# Conditionally install the header files
|
||||
|
||||
if WANT_INSTALL_HEADERS
|
||||
ompidir = $(includedir)/openmpi/mca/io/base
|
||||
ompi_HEADERS = $(headers)
|
||||
else
|
||||
ompidir = $(includedir)
|
||||
endif
|
||||
|
25
src/mca/io/base/base.h
Обычный файл
25
src/mca/io/base/base.h
Обычный файл
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef OMPI_MCA_IO_BASE_H
|
||||
#define OMPI_MCA_IO_BASE_H
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* To be filled in soon
|
||||
*/
|
||||
int mca_io_base_open(void);
|
||||
|
||||
/**
|
||||
* To be filled in soon
|
||||
*/
|
||||
int mca_io_base_close(void);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OMPI_MCA_IO_BASE_H */
|
15
src/mca/io/base/io_base_close.c
Обычный файл
15
src/mca/io/base/io_base_close.c
Обычный файл
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "include/constants.h"
|
||||
#include "mca/io/base/base.h"
|
||||
|
||||
|
||||
int mca_io_base_close(void)
|
||||
{
|
||||
/* JMS More coming here soon */
|
||||
return OMPI_SUCCESS;
|
||||
}
|
15
src/mca/io/base/io_base_open.c
Обычный файл
15
src/mca/io/base/io_base_open.c
Обычный файл
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "include/constants.h"
|
||||
#include "mca/io/base/base.h"
|
||||
|
||||
|
||||
int mca_io_base_open(void)
|
||||
{
|
||||
/* JMS More coming here soon */
|
||||
return OMPI_SUCCESS;
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "mpi/c/bindings.h"
|
||||
#include "communicator/communicator.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
|
||||
#pragma weak MPI_File_c2f = PMPI_File_c2f
|
||||
@ -24,9 +25,12 @@ MPI_Fint MPI_File_c2f(MPI_File file)
|
||||
{
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
if (ompi_file_invalid(file)) {
|
||||
return (MPI_Fint) OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL,
|
||||
MPI_ERR_FILE,
|
||||
FUNC_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is not yet implemented */
|
||||
|
||||
return (MPI_Fint) OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INTERN, FUNC_NAME);
|
||||
return (MPI_Fint) file->f_f_to_c_index;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "mpi/c/bindings.h"
|
||||
#include "communicator/communicator.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
|
||||
#pragma weak MPI_File_close = PMPI_File_close
|
||||
@ -22,11 +23,21 @@ static const char FUNC_NAME[] = "MPI_File_close";
|
||||
|
||||
int MPI_File_close(MPI_File *fh)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
|
||||
/* Note that MPI-2:9.7 (p265) says that errors in
|
||||
MPI_FILE_CLOSE should invoke the default error handler on
|
||||
MPI_FILE_NULL */
|
||||
|
||||
if (NULL == fh || ompi_file_invalid(*fh)) {
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, MPI_ERR_FILE,
|
||||
FUNC_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is not yet implemented */
|
||||
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INTERN, FUNC_NAME);
|
||||
rc = ompi_file_close(fh);
|
||||
OMPI_ERRHANDLER_RETURN(rc, *fh, rc, FUNC_NAME);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "communicator/communicator.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "info/info.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
|
||||
#pragma weak MPI_File_delete = PMPI_File_delete
|
||||
@ -31,7 +32,10 @@ int MPI_File_delete(char *filename, MPI_Info info)
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that MPI-2:9.7 (p265) says that errors in MPI_FILE_DELETE
|
||||
should invoke the default error handler on MPI_FILE_NULL */
|
||||
|
||||
/* This function is not yet implemented */
|
||||
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INTERN, FUNC_NAME);
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, MPI_ERR_INTERN, FUNC_NAME);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "mpi/c/bindings.h"
|
||||
#include "communicator/communicator.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
|
||||
#pragma weak MPI_File_f2c = PMPI_File_f2c
|
||||
@ -20,13 +21,19 @@
|
||||
static const char FUNC_NAME[] = "MPI_File_f2c";
|
||||
|
||||
|
||||
MPI_File MPI_File_f2c(MPI_Fint file)
|
||||
MPI_File MPI_File_f2c(MPI_Fint file_f)
|
||||
{
|
||||
size_t file_index = (size_t) file_f;
|
||||
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
if (file_index < 0 ||
|
||||
file_index >= ompi_pointer_array_get_size(&ompi_file_f_to_c_table)) {
|
||||
(void) OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, MPI_ERR_FILE,
|
||||
FUNC_NAME);
|
||||
return MPI_FILE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is not yet implemented */
|
||||
|
||||
return (MPI_File) OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INTERN, FUNC_NAME);
|
||||
return ompi_file_f_to_c_table.addr[file_index];
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "communicator/communicator.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "info/info.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
|
||||
#pragma weak MPI_File_open = PMPI_File_open
|
||||
@ -24,15 +25,26 @@ static const char FUNC_NAME[] = "MPI_File_open";
|
||||
int MPI_File_open(MPI_Comm comm, char *filename, int amode,
|
||||
MPI_Info info, MPI_File *fh)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
if (NULL == info || ompi_info_is_freed(info)) {
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INFO,
|
||||
FUNC_NAME);
|
||||
} else if (ompi_comm_invalid(comm)) {
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
|
||||
FUNC_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is not yet implemented */
|
||||
/* Note that MPI-2:9.7 (p265) says that errors in MPI_FILE_OPEN
|
||||
(before the file handle is created) should invoke the default
|
||||
error handler on MPI_FILE_NULL. Hence, if we get a file handle
|
||||
out of ompi_file_open(), invoke the error handler on that. If
|
||||
not, invoke the error handler on MPI_FILE_NULL. */
|
||||
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INTERN, FUNC_NAME);
|
||||
*fh = MPI_FILE_NULL;
|
||||
rc = ompi_file_open(comm, filename, amode, info, fh);
|
||||
OMPI_ERRHANDLER_RETURN(rc, *fh, rc, FUNC_NAME);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "mpi/c/bindings.h"
|
||||
#include "communicator/communicator.h"
|
||||
#include "errhandler/errhandler.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
|
||||
#pragma weak MPI_File_read = PMPI_File_read
|
||||
@ -25,6 +26,10 @@ int MPI_File_read(MPI_File fh, void *buf, int count, MPI_Datatype
|
||||
{
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
if (ompi_file_invalid(fh)) {
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, MPI_ERR_FILE,
|
||||
FUNC_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is not yet implemented */
|
||||
|
@ -27,9 +27,12 @@ int MPI_File_set_errhandler( MPI_File file, MPI_Errhandler errhandler)
|
||||
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
if (NULL == file ||
|
||||
MPI_FILE_NULL == file) {
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_FILE,
|
||||
|
||||
/* Note that MPI-2:9.7 (p265) explicitly says that you are
|
||||
allowed to set the error handler on MPI_FILE_NULL */
|
||||
|
||||
if (NULL == file) {
|
||||
return OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, MPI_ERR_FILE,
|
||||
FUNC_NAME);
|
||||
} else if (NULL == errhandler ||
|
||||
MPI_ERRHANDLER_NULL == errhandler ||
|
||||
|
@ -45,5 +45,5 @@ MPI_Fint MPI_Info_c2f(MPI_Info info)
|
||||
}
|
||||
|
||||
/* return the index */
|
||||
return (MPI_Fint)(info->i_fhandle);
|
||||
return (MPI_Fint)(info->i_f_to_c_index);
|
||||
}
|
||||
|
@ -30,15 +30,20 @@ static const char FUNC_NAME[] = "MPI_Info_f2c";
|
||||
*/
|
||||
MPI_Info MPI_Info_f2c(MPI_Fint info)
|
||||
{
|
||||
size_t info_index = (size_t) info;
|
||||
|
||||
/* check the arguments */
|
||||
|
||||
if (MPI_PARAM_CHECK) {
|
||||
OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
|
||||
if (0 > info ||
|
||||
info >= ompi_pointer_array_get_size(ompi_info_f_to_c_table)) {
|
||||
if (info_index < 0 ||
|
||||
info_index >= ompi_pointer_array_get_size(&ompi_info_f_to_c_table)) {
|
||||
(void) OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INFO,
|
||||
FUNC_NAME);
|
||||
return MPI_INFO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the index */
|
||||
return ompi_info_f_to_c_table->addr[info];
|
||||
return ompi_info_f_to_c_table.addr[info_index];
|
||||
}
|
||||
|
@ -12,12 +12,14 @@ noinst_LTLIBRARIES = libmpiruntime.la
|
||||
# Source code files
|
||||
|
||||
headers = \
|
||||
mpiruntime.h
|
||||
mpiruntime.h \
|
||||
params.h
|
||||
|
||||
libmpiruntime_la_SOURCES = \
|
||||
$(headers) \
|
||||
ompi_mpi_init.c \
|
||||
ompi_mpi_finalize.c
|
||||
ompi_mpi_finalize.c \
|
||||
ompi_mpi_params.c
|
||||
|
||||
# Conditionally install the header files
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
* Interface into the MPI portion of the Open MPI Run Time Environment
|
||||
*/
|
||||
|
||||
#ifndef OMPI_MPIRUNTIME_H
|
||||
#define OMPI_MPIRUNTIME_H
|
||||
#ifndef OMPI_MPI_MPIRUNTIME_H
|
||||
#define OMPI_MPI_MPIRUNTIME_H
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
@ -20,10 +20,6 @@
|
||||
extern bool ompi_mpi_initialized;
|
||||
extern bool ompi_mpi_finalized;
|
||||
|
||||
extern bool ompi_mpi_param_check;
|
||||
extern bool ompi_debug_show_handle_leaks;
|
||||
extern bool ompi_debug_handle_never_free;
|
||||
|
||||
extern bool ompi_mpi_thread_multiple;
|
||||
extern int ompi_mpi_thread_requested;
|
||||
extern int ompi_mpi_thread_provided;
|
||||
@ -36,16 +32,29 @@ extern "C" {
|
||||
/**
|
||||
* Initialize the Open MPI MPI environment
|
||||
*
|
||||
* @param argc argc, typically from main() (IN)
|
||||
* @param argv argv, typically from main() (IN)
|
||||
* @param requested Thread support that is requested (IN)
|
||||
* @param provided Thread support that is provided (OUT)
|
||||
*
|
||||
* @returns MPI_SUCCESS if successful
|
||||
* @returns Error code if unsuccessful
|
||||
*
|
||||
* Intialize all support code needed for MPI applications. This
|
||||
* function should only be called by MPI applications (including
|
||||
* singletons). If this function is called, ompi_init and
|
||||
* ompi_rte_init should *not* be called.
|
||||
* singletons). If this function is called, ompi_init() and
|
||||
* ompi_rte_init() should *not* be called.
|
||||
*
|
||||
* It is permissable to pass in (0, NULL) for (argc, argv).
|
||||
*/
|
||||
int ompi_mpi_init(int argc, char **argv, int requested, int *provided);
|
||||
|
||||
/**
|
||||
* Finalize the Open MPI MPI environment
|
||||
*
|
||||
* @returns MPI_SUCCESS if successful
|
||||
* @returns Error code if unsuccessful
|
||||
*
|
||||
* Should be called after all MPI functionality is complete (usually
|
||||
* during MPI_FINALIZE).
|
||||
*/
|
||||
@ -55,4 +64,4 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OMPI_MPIRUNTIME_H */
|
||||
#endif /* OMPI_MPI_MPIRUNTIME_H */
|
||||
|
@ -12,8 +12,10 @@
|
||||
#include "communicator/communicator.h"
|
||||
#include "datatype/datatype.h"
|
||||
#include "op/op.h"
|
||||
#include "file/file.h"
|
||||
#include "info/info.h"
|
||||
#include "runtime/runtime.h"
|
||||
|
||||
#include "mca/base/base.h"
|
||||
#include "mca/ptl/ptl.h"
|
||||
#include "mca/ptl/base/base.h"
|
||||
@ -21,6 +23,10 @@
|
||||
#include "mca/pml/base/base.h"
|
||||
#include "mca/coll/coll.h"
|
||||
#include "mca/coll/base/base.h"
|
||||
#include "mca/topo/topo.h"
|
||||
#include "mca/topo/base/base.h"
|
||||
#include "mca/io/io.h"
|
||||
#include "mca/io/base/base.h"
|
||||
|
||||
|
||||
int ompi_mpi_finalize(void)
|
||||
@ -34,15 +40,18 @@ int ompi_mpi_finalize(void)
|
||||
|
||||
/* Free communication objects */
|
||||
|
||||
/* free window resources */
|
||||
|
||||
/* free file resources */
|
||||
if (OMPI_SUCCESS != (ret = ompi_file_finalize())) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* free communicator resources */
|
||||
if (OMPI_SUCCESS != (ret = ompi_comm_finalize())) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* free window resources */
|
||||
|
||||
/* free file resources */
|
||||
|
||||
/* Free secondary resources */
|
||||
|
||||
/* free group resources */
|
||||
@ -76,6 +85,12 @@ int ompi_mpi_finalize(void)
|
||||
|
||||
/* Close down MCA modules */
|
||||
|
||||
if (OMPI_SUCCESS != (ret = mca_io_base_close())) {
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_topo_base_close())) {
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_coll_base_close())) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -5,11 +5,12 @@
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "include/constants.h"
|
||||
#include "mpi/runtime/mpiruntime.h"
|
||||
#include "mpi/runtime/params.h"
|
||||
#include "runtime/runtime.h"
|
||||
#include "util/sys_info.h"
|
||||
#include "util/proc_info.h"
|
||||
#include "mpi.h"
|
||||
#include "runtime/runtime.h"
|
||||
#include "communicator/communicator.h"
|
||||
#include "group/group.h"
|
||||
#include "info/info.h"
|
||||
@ -19,6 +20,8 @@
|
||||
#include "errhandler/errclass.h"
|
||||
#include "errhandler/errcode-internal.h"
|
||||
#include "op/op.h"
|
||||
#include "file/file.h"
|
||||
|
||||
#include "mca/base/base.h"
|
||||
#include "mca/base/base.h"
|
||||
#include "mca/allocator/base/base.h"
|
||||
@ -33,6 +36,8 @@
|
||||
#include "mca/coll/base/base.h"
|
||||
#include "mca/topo/topo.h"
|
||||
#include "mca/topo/base/base.h"
|
||||
#include "mca/io/io.h"
|
||||
#include "mca/io/base/base.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -42,13 +47,6 @@
|
||||
bool ompi_mpi_initialized = false;
|
||||
bool ompi_mpi_finalized = false;
|
||||
|
||||
/* As a deviation from the norm, ompi_mpi_param_check is extern'ed in
|
||||
src/mpi/interface/c/bindings.h because it is already included in
|
||||
all MPI function imlementation files */
|
||||
bool ompi_mpi_param_check = true;
|
||||
bool ompi_debug_show_handle_leaks = false;
|
||||
bool ompi_debug_handle_never_free = false;
|
||||
|
||||
bool ompi_mpi_thread_multiple = false;
|
||||
int ompi_mpi_thread_requested = MPI_THREAD_SINGLE;
|
||||
int ompi_mpi_thread_provided = MPI_THREAD_SINGLE;
|
||||
@ -56,7 +54,7 @@ int ompi_mpi_thread_provided = MPI_THREAD_SINGLE;
|
||||
|
||||
int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
{
|
||||
int ret, param, value;
|
||||
int ret, param;
|
||||
bool allow_multi_user_threads;
|
||||
bool have_hidden_threads;
|
||||
ompi_proc_t** procs;
|
||||
@ -94,6 +92,15 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Once we've joined the RTE, see if any MCA parameters were
|
||||
passed to the MPI level */
|
||||
|
||||
if (OMPI_SUCCESS != (ret = ompi_mpi_register_params())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_mpi_register_params\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* initialize ompi procs */
|
||||
if (OMPI_SUCCESS != (ret = ompi_proc_init())) {
|
||||
/* JMS show_help */
|
||||
@ -101,36 +108,41 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Open up relevant MCA modules. Do not open io, topo, or one
|
||||
module types here -- they are loaded upon demand (i.e., upon
|
||||
relevant constructors). */
|
||||
/* Open up relevant MCA modules. */
|
||||
|
||||
if (OMPI_SUCCESS != (ret = mca_allocator_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_allocator_base_init\n");
|
||||
printf("show_help: ompi_mpi_init failed in mca_allocator_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_mpool_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_mpool_base_init\n");
|
||||
printf("show_help: ompi_mpi_init failed in mca_mpool_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_pml_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_pml_base_init\n");
|
||||
printf("show_help: ompi_mpi_init failed in mca_pml_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_ptl_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_ptl_base_init\n");
|
||||
printf("show_help: ompi_mpi_init failed in mca_ptl_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_coll_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_coll_base_init\n");
|
||||
printf("show_help: ompi_mpi_init failed in mca_coll_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_topo_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_topo_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
if (OMPI_SUCCESS != (ret = mca_io_base_open())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in mca_io_base_open\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -216,12 +228,12 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If we have run-time MPI parameter checking possible, register
|
||||
an MCA paramter to find out if the user wants it on or off by
|
||||
default */
|
||||
param = mca_base_param_register_int("mpi", NULL, "error_check", NULL, 1);
|
||||
mca_base_param_lookup_int(param, &value);
|
||||
ompi_mpi_param_check = (bool) value;
|
||||
/* initialize file handles */
|
||||
if (OMPI_SUCCESS != (ret = ompi_file_init())) {
|
||||
/* JMS show_help */
|
||||
printf("show_help: ompi_mpi_init failed in ompi_file_init\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do module exchange */
|
||||
if (OMPI_SUCCESS != (ret = mca_base_modex_exchange())) {
|
||||
|
63
src/mpi/runtime/ompi_mpi_params.c
Обычный файл
63
src/mpi/runtime/ompi_mpi_params.c
Обычный файл
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "include/constants.h"
|
||||
#include "mpi/runtime/mpiruntime.h"
|
||||
#include "mpi/runtime/params.h"
|
||||
#include "mca/base/mca_base_param.h"
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*
|
||||
* As a deviation from the norm, ompi_mpi_param_check is also
|
||||
* extern'ed in src/mpi/interface/c/bindings.h because it is already
|
||||
* included in all MPI function imlementation files
|
||||
*
|
||||
* The values below are the default values.
|
||||
*/
|
||||
bool ompi_mpi_param_check = true;
|
||||
bool ompi_debug_show_handle_leaks = false;
|
||||
bool ompi_debug_no_free_handles = false;
|
||||
|
||||
|
||||
int ompi_mpi_register_params(void)
|
||||
{
|
||||
int param_check_param;
|
||||
int show_leaks_param;
|
||||
int no_free_param;
|
||||
int value;
|
||||
|
||||
param_check_param =
|
||||
mca_base_param_register_int("base", "mpi", "param_check",
|
||||
"mpi_param_check",
|
||||
(int) ompi_mpi_param_check);
|
||||
mca_base_param_lookup_int(param_check_param, &value);
|
||||
ompi_mpi_param_check = (bool) value;
|
||||
|
||||
/* Whether or not to show MPI handle leaks */
|
||||
|
||||
show_leaks_param =
|
||||
mca_base_param_register_int("base", "mpi", "show_handle_leaks",
|
||||
"mpi_show_handle_leaks",
|
||||
(int) ompi_debug_show_handle_leaks);
|
||||
mca_base_param_lookup_int(show_leaks_param, &value);
|
||||
ompi_debug_show_handle_leaks = (bool) value;
|
||||
|
||||
/* Whether or not to free MPI handles */
|
||||
|
||||
no_free_param =
|
||||
mca_base_param_register_int("base", "mpi", "no_free_handles",
|
||||
"mpi_no_free_handles",
|
||||
(int) ompi_debug_no_free_handles);
|
||||
mca_base_param_lookup_int(no_free_param, &value);
|
||||
ompi_debug_no_free_handles = (bool) value;
|
||||
|
||||
/* All done */
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
68
src/mpi/runtime/params.h
Обычный файл
68
src/mpi/runtime/params.h
Обычный файл
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef OMPI_RUNTIME_PARAMS_H
|
||||
#define OMPI_RUNTIME_PARAMS_H
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether or not to check the parameters of top-level MPI API
|
||||
* functions or not.
|
||||
*
|
||||
* This variable should never be checked directly; the macro
|
||||
* MPI_PARAM_CHECK should be used instead. This allows multiple
|
||||
* levels of MPI function parameter checking:
|
||||
*
|
||||
* #- Disable all parameter checking at configure/compile time
|
||||
* #- Enable all parameter checking at configure/compile time
|
||||
* #- Disable all parameter checking at run time
|
||||
* #- Enable all parameter checking at run time
|
||||
*
|
||||
* Hence, the MPI_PARAM_CHECK macro will either be "0", "1", or
|
||||
* "ompi_mpi_param_check".
|
||||
*/
|
||||
extern bool ompi_mpi_param_check;
|
||||
|
||||
/**
|
||||
* Whether or not to check for MPI handle leaks during MPI_FINALIZE.
|
||||
* If enabled, each MPI handle type will display a summary of the
|
||||
* handles that are still allocated during MPI_FINALIZE.
|
||||
*
|
||||
* This is good debugging for user applications to find out if they
|
||||
* are inadvertantly orphaning MPI handles.
|
||||
*/
|
||||
extern bool ompi_debug_show_handle_leaks;
|
||||
|
||||
/**
|
||||
* Whether or not to actually free MPI handles when their
|
||||
* corresponding destructor is invoked. If enabled, Open MPI will not
|
||||
* free handles, but will rather simply mark them as "freed". Any
|
||||
* attempt to use them will result in an MPI exception.
|
||||
*
|
||||
* This is good debugging for user applications to find out if they
|
||||
* are inadvertantly using MPI handles after they have been freed.
|
||||
*/
|
||||
extern bool ompi_debug_no_free_handles;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* Register MCA parameters used by the MPI layer.
|
||||
*
|
||||
* @returns OMPI_SUCCESS
|
||||
*
|
||||
* Registers several MCA parameters and initializes corresponding
|
||||
* global variables to the values obtained from the MCA system.
|
||||
*/
|
||||
int ompi_mpi_register_params(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OMPI_RUNTIME_PARAMS_H */
|
@ -10,6 +10,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpi/runtime/params.h"
|
||||
#include "mca/base/base.h"
|
||||
#include "mca/allocator/allocator.h"
|
||||
#include "mca/allocator/base/base.h"
|
||||
@ -80,6 +81,10 @@ void ompi_info::open_components()
|
||||
}
|
||||
}
|
||||
|
||||
// Register the MPI layer's MCA parameters
|
||||
|
||||
ompi_mpi_register_params();
|
||||
|
||||
// Find / open all components
|
||||
|
||||
mca_base_open();
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user