Skip to content

Commit

Permalink
implement MPI_Info_create_env
Browse files Browse the repository at this point in the history
related to open-mpi#7993

Signed-off-by: Howard Pritchard <[email protected]>
  • Loading branch information
hppritcha committed Sep 8, 2022
1 parent 01ebde1 commit 04207e5
Show file tree
Hide file tree
Showing 22 changed files with 363 additions and 38 deletions.
80 changes: 80 additions & 0 deletions docs/man-openmpi/man3/MPI_Info_create_env.3.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.. _mpi_info_create_env:


MPI_Info_create_env
===================

.. include_body
:ref:`MPI_Info_create_env` - Creates a new info object with the same construction as MPI_INFO_ENV as created during :ref:`MPI_Init` or :ref:`MPI_Init_thread` when the same arguments
are used.


SYNTAX
------


C Syntax
^^^^^^^^

.. code-block:: c
#include <mpi.h>
int MPI_Info_create_env(int argc, char *argv[], MPI_Info *info)
Fortran Syntax
^^^^^^^^^^^^^^

.. code-block:: fortran
USE MPI
! or the older form: INCLUDE 'mpif.h'
MPI_INFO_CREATE_ENV(INFO, IERROR)
INTEGER INFO, IERROR
Fortran 2008 Syntax
^^^^^^^^^^^^^^^^^^^

.. code-block:: fortran
USE mpi_f08
MPI_Info_create_env(info, ierror)
TYPE(MPI_Info), INTENT(OUT) :: info
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
OUTPUT PARAMETERS
-----------------
* ``info``: Info object created (handle).
* ``IERROR``: Fortran only: Error status (integer).

DESCRIPTION
-----------

:ref:`MPI_Info_create_env` creates a new info object and populates it with the same key/value pairs as are present in MPI_INFO_ENV.

Note
----

:ref:`MPI_Info_create_env` is one of the few functions that can be called
before :ref:`MPI_Init` and after :ref:`MPI_Finalize`.

ERRORS
------

Almost all MPI routines return an error value; C routines as the value
of the function and Fortran routines in the last argument.

Before the error value is returned, the current MPI error handler is
called. By default, this error handler aborts the MPI job, except for
I/O function errors. The error handler may be changed with
:ref:`MPI_Comm_set_errhandler`; the predefined error handler MPI_ERRORS_RETURN
may be used to cause error values to be returned. Note that MPI does not
guarantee that an MPI program can continue past an error.


.. seealso::
:ref:`MPI_Info_delete` :ref:`MPI_Info_dup` :ref:`MPI_Info_free` :ref:`MPI_Info_get` :ref:`MPI_Info_set`
1 change: 1 addition & 0 deletions docs/man-openmpi/man3/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ MPI API manual pages (section 3)
MPI_Ineighbor_alltoallw.3.rst
MPI_Info_c2f.3.rst
MPI_Info_create.3.rst
MPI_Info_create_env.3.rst
MPI_Info_delete.3.rst
MPI_Info_dup.3.rst
MPI_Info_env.3.rst
Expand Down
2 changes: 2 additions & 0 deletions ompi/include/mpi.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,7 @@ OMPI_DECLSPEC int MPI_Imrecv(void *buf, int count, MPI_Datatype type,
MPI_Message *message, MPI_Request *request);
OMPI_DECLSPEC MPI_Fint MPI_Info_c2f(MPI_Info info);
OMPI_DECLSPEC int MPI_Info_create(MPI_Info *info);
OMPI_DECLSPEC int MPI_Info_create_env(int argc, char *argv[], MPI_Info *info);
OMPI_DECLSPEC int MPI_Info_delete(MPI_Info info, const char *key);
OMPI_DECLSPEC int MPI_Info_dup(MPI_Info info, MPI_Info *newinfo);
OMPI_DECLSPEC MPI_Info MPI_Info_f2c(MPI_Fint info);
Expand Down Expand Up @@ -2507,6 +2508,7 @@ OMPI_DECLSPEC int PMPI_Imrecv(void *buf, int count, MPI_Datatype type,
MPI_Message *message, MPI_Request *request);
OMPI_DECLSPEC MPI_Fint PMPI_Info_c2f(MPI_Info info);
OMPI_DECLSPEC int PMPI_Info_create(MPI_Info *info);
OMPI_DECLSPEC int PMPI_Info_create_env(int argc, char **argv, MPI_Info *info);
OMPI_DECLSPEC int PMPI_Info_delete(MPI_Info info, const char *key);
OMPI_DECLSPEC int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo);
OMPI_DECLSPEC MPI_Info PMPI_Info_f2c(MPI_Fint info);
Expand Down
63 changes: 39 additions & 24 deletions ompi/info/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,76 +116,91 @@ int ompi_mpiinfo_init(void)
return OMPI_SUCCESS;
}

/*
* Fill in the MPI_INFO_ENV if using MPI3 initialization
/**
* Fill in an info object with ENV info. Used for setting
* MPI_INFO_ENV and by invocation of MPI_Info_create_env.
*/
int ompi_mpiinfo_init_mpi3(void)

int ompi_mpiinfo_init_env(int argc, char **argv, ompi_info_t *info)
{
char *cptr, **tmp;
char *cptr = NULL, **tmp = NULL;

/* fill the env info object */

/* command for this app_context */
if (NULL != ompi_process_info.command) {
if (NULL != argv) {
tmp = argv;
} else if (NULL != ompi_process_info.command) {
tmp = opal_argv_split(ompi_process_info.command, ' ');
opal_info_set(&ompi_mpi_info_env.info.super, "command", tmp[0]);
}

if (NULL != tmp) {
if (NULL != tmp[0]) {
opal_info_set(&info->super, "command", tmp[0]);
}

/* space-separated list of argv for this command */
if (1 < opal_argv_count(tmp)) {
cptr = opal_argv_join(&tmp[1], ' ');
} else {
cptr = strdup(tmp[0]);
if (NULL != tmp[0]) {
cptr = strdup(tmp[0]);
}
}
if (NULL == argv) {
opal_argv_free(tmp);
}
opal_info_set(&info->super, "argv", cptr);
if (NULL != cptr) {
free(cptr);
}
opal_argv_free(tmp);
opal_info_set(&ompi_mpi_info_env.info.super, "argv", cptr);
free(cptr);
}

/* max procs for the entire job */
opal_asprintf(&cptr, "%u", ompi_process_info.num_procs);
opal_info_set(&ompi_mpi_info_env.info.super, "maxprocs", cptr);
opal_info_set(&info->super, "maxprocs", cptr);
/* Open MPI does not support the "soft" option, so set it to maxprocs */
opal_info_set(&ompi_mpi_info_env.info.super, "soft", cptr);
opal_info_set(&info->super, "soft", cptr);
free(cptr);

/* the initial error handler, set it as requested (nothing if not
* requested) */
if (NULL != ompi_process_info.initial_errhandler) {
opal_info_set(&ompi_mpi_info_env.info.super, "mpi_initial_errhandler", ompi_process_info.initial_errhandler);
opal_info_set(&info->super, "mpi_initial_errhandler", ompi_process_info.initial_errhandler);
}

/* local host name */
opal_info_set(&ompi_mpi_info_env.info.super, "host", ompi_process_info.nodename);
opal_info_set(&info->super, "host", ompi_process_info.nodename);

#ifdef HAVE_SYS_UTSNAME_H
{
struct utsname sysname;
uname(&sysname);
cptr = sysname.machine;
opal_info_set(&ompi_mpi_info_env.info.super, "arch", cptr);
opal_info_set(&info->super, "arch", cptr);
}
#endif

/* initial working dir of this process, if provided */
if (NULL != ompi_process_info.initial_wdir) {
opal_info_set(&ompi_mpi_info_env.info.super, "wdir", ompi_process_info.initial_wdir);
opal_info_set(&info->super, "wdir", ompi_process_info.initial_wdir);
}

/* provide the REQUESTED thread level - may be different
* than the ACTUAL thread level you get.
* ugly, but have to do a switch to find the string representation */
switch (ompi_mpi_thread_requested) {
case MPI_THREAD_SINGLE:
opal_info_set(&ompi_mpi_info_env.info.super, "thread_level", "MPI_THREAD_SINGLE");
opal_info_set(&info->super, "thread_level", "MPI_THREAD_SINGLE");
break;
case MPI_THREAD_FUNNELED:
opal_info_set(&ompi_mpi_info_env.info.super, "thread_level", "MPI_THREAD_FUNNELED");
opal_info_set(&info->super, "thread_level", "MPI_THREAD_FUNNELED");
break;
case MPI_THREAD_SERIALIZED:
opal_info_set(&ompi_mpi_info_env.info.super, "thread_level", "MPI_THREAD_SERIALIZED");
opal_info_set(&info->super, "thread_level", "MPI_THREAD_SERIALIZED");
break;
case MPI_THREAD_MULTIPLE:
opal_info_set(&ompi_mpi_info_env.info.super, "thread_level", "MPI_THREAD_MULTIPLE");
opal_info_set(&info->super, "thread_level", "MPI_THREAD_MULTIPLE");
break;
default:
/* do nothing - don't know the value */
Expand All @@ -196,24 +211,24 @@ int ompi_mpiinfo_init_mpi3(void)

/* the number of app_contexts in this job */
opal_asprintf(&cptr, "%u", ompi_process_info.num_apps);
opal_info_set(&ompi_mpi_info_env.info.super, "ompi_num_apps", cptr);
opal_info_set(&info->super, "ompi_num_apps", cptr);
free(cptr);

/* space-separated list of first MPI rank of each app_context */
if (NULL != ompi_process_info.app_ldrs) {
opal_info_set(&ompi_mpi_info_env.info.super, "ompi_first_rank", ompi_process_info.app_ldrs);
opal_info_set(&info->super, "ompi_first_rank", ompi_process_info.app_ldrs);
}

/* space-separated list of num procs for each app_context */
if (NULL != ompi_process_info.app_sizes) {
opal_info_set(&ompi_mpi_info_env.info.super, "ompi_np", ompi_process_info.app_sizes);
opal_info_set(&info->super, "ompi_np", ompi_process_info.app_sizes);
}

/* location of the directory containing any prepositioned files
* the user may have requested
*/
if (NULL != ompi_process_info.proc_session_dir) {
opal_info_set(&ompi_mpi_info_env.info.super, "ompi_positioned_file_dir", ompi_process_info.proc_session_dir);
opal_info_set(&info->super, "ompi_positioned_file_dir", ompi_process_info.proc_session_dir);
}

/* All done */
Expand Down
6 changes: 3 additions & 3 deletions ompi/info/info.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_info_t);
int ompi_mpiinfo_init(void);

/**
* This function is invoked during ompi_mpi_init() and sets up
* the MPI_INFO_ENV object
* Fill in an info object with ENV info. Used for setting
* MPI_INFO_ENV and by invocation of MPI_Info_create_env.
*/
int ompi_mpiinfo_init_mpi3(void);
int ompi_mpiinfo_init_env(int argc, char *argv[], ompi_info_t *info);

/**
* This function is used to free a ompi level info
Expand Down
6 changes: 3 additions & 3 deletions ompi/instance/instance.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,9 @@ static int ompi_mpi_instance_init_common (int argc, char **argv)
return ret;
}

/* initialize info */
if (OMPI_SUCCESS != (ret = ompi_mpiinfo_init_mpi3())) {
return ompi_instance_print_error ("ompi_info_init_mpi3() failed", ret);
/* initialize MPI_INFO_ENV */
if (OMPI_SUCCESS != (ret = ompi_mpiinfo_init_env(0, NULL, &ompi_mpi_info_env.info))) {
return ompi_instance_print_error ("ompi_info_init_env() failed", ret);
}

/* declare our presence for interlib coordination, and
Expand Down
1 change: 1 addition & 0 deletions ompi/mpi/c/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ interface_profile_sources = \
imrecv.c \
info_c2f.c \
info_create.c \
info_create_env.c \
info_delete.c \
info_dup.c \
info_f2c.c \
Expand Down
79 changes: 79 additions & 0 deletions ompi/mpi/c/info_create_env.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2020 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2018-2021 Triad National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/

#include "ompi_config.h"

#include "ompi/mpi/c/bindings.h"
#include "ompi/runtime/params.h"
#include "ompi/communicator/communicator.h"
#include "ompi/errhandler/errhandler.h"
#include "ompi/info/info.h"

#if OMPI_BUILD_MPI_PROFILING
#if OPAL_HAVE_WEAK_SYMBOLS
#pragma weak MPI_Info_create_env = PMPI_Info_create_env
#endif
#define MPI_Info_create_env PMPI_Info_create_env
#endif

static const char FUNC_NAME[] = "MPI_Info_create_env";

/**
* Returns an info object with the same construction as MPI_INFO_ENV as created
* during MPI_INIT or MPI_INIT_THREAD when the same arguments are used.
*
* @param argc number or arguments (Integer)
* @param argv Pointer to array of arguments
* @param info Pointer to the MPI_Info handle
*
* @retval MPI_SUCCESS
* @retval MPI_ERR_INFO
* @retval MPI_ERR_NO_MEM
*
* When an MPI_Info object is not being used, it should be freed using
* MPI_Info_free
*/
int MPI_Info_create_env(int argc, char *argv[], MPI_Info *info)
{
int rc;
ompi_info_t *the_info;

if (MPI_PARAM_CHECK) {
if (NULL == info) {
return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_INFO,
FUNC_NAME);
}
}

the_info = ompi_info_allocate ();
if (NULL == the_info) {
return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_NO_MEM,
FUNC_NAME);
}

*info = the_info;

rc = ompi_mpiinfo_init_env(argc, argv, the_info);
OMPI_ERRHANDLER_NOHANDLE_CHECK(rc, rc, FUNC_NAME);
return MPI_SUCCESS;
}
3 changes: 2 additions & 1 deletion ompi/mpi/fortran/mpif-h/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# and Technology (RIST). All rights reserved.
# Copyright (c) 2016 IBM Corporation. All rights reserved.
# Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
# Copyright (c) 2021 Triad National Security, LLC. All rights
# Copyright (c) 2021-2022 Triad National Security, LLC. All rights
# reserved.
#
# $COPYRIGHT$
Expand Down Expand Up @@ -334,6 +334,7 @@ lib@OMPI_LIBMPI_NAME@_mpifh_la_SOURCES += \
ineighbor_alltoallv_f.c \
ineighbor_alltoallw_f.c \
info_create_f.c \
info_create_env_f.c \
info_delete_f.c \
info_dup_f.c \
info_free_f.c \
Expand Down
Loading

0 comments on commit 04207e5

Please sign in to comment.