2004-07-08 18:48:34 +04:00
|
|
|
/*
|
2006-03-05 14:18:19 +03:00
|
|
|
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
|
2005-11-05 22:57:48 +03:00
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
2011-06-24 00:38:02 +04:00
|
|
|
* Copyright (c) 2004-2011 The University of Tennessee and The University
|
2005-11-05 22:57:48 +03:00
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2006-03-05 14:18:19 +03:00
|
|
|
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
|
2004-11-28 23:09:25 +03:00
|
|
|
* University of Stuttgart. All rights reserved.
|
2006-03-05 14:18:19 +03:00
|
|
|
* Copyright (c) 2004-2006 The Regents of the University of California.
|
2005-03-24 15:43:37 +03:00
|
|
|
* All rights reserved.
|
2007-01-27 16:44:03 +03:00
|
|
|
* Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
2012-04-06 18:23:13 +04:00
|
|
|
* Copyright (c) 2012 Los Alamos National Security, LLC. All rights
|
|
|
|
* reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
2005-09-01 05:07:30 +04:00
|
|
|
*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Additional copyrights may follow
|
2005-09-01 05:07:30 +04:00
|
|
|
*
|
2004-11-22 03:37:56 +03:00
|
|
|
* $HEADER$
|
2004-07-08 18:48:34 +04:00
|
|
|
*/
|
|
|
|
|
2004-08-19 03:24:27 +04:00
|
|
|
#include "ompi_config.h"
|
|
|
|
|
2004-02-13 16:56:55 +03:00
|
|
|
#include <string.h>
|
2004-07-08 18:48:34 +04:00
|
|
|
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
#include "ompi/constants.h"
|
|
|
|
#include "opal/datatype/opal_convertor.h"
|
2005-07-04 02:45:48 +04:00
|
|
|
#include "opal/threads/mutex.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "opal/dss/dss.h"
|
2009-07-14 00:03:41 +04:00
|
|
|
#include "opal/util/arch.h"
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
|
2012-06-27 18:53:55 +04:00
|
|
|
#include "orte/mca/db/db_types.h"
|
2012-06-27 05:28:28 +04:00
|
|
|
#include "orte/mca/errmgr/errmgr.h"
|
|
|
|
#include "orte/util/proc_info.h"
|
|
|
|
#include "orte/util/name_fns.h"
|
|
|
|
#include "orte/util/show_help.h"
|
|
|
|
#include "orte/runtime/orte_globals.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
|
2005-07-15 02:43:01 +04:00
|
|
|
#include "ompi/proc/proc.h"
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
#include "ompi/datatype/ompi_datatype.h"
|
2007-01-02 11:04:34 +03:00
|
|
|
#include "ompi/runtime/mpiruntime.h"
|
2009-07-14 00:03:41 +04:00
|
|
|
#include "ompi/runtime/ompi_module_exchange.h"
|
2004-01-29 18:34:47 +03:00
|
|
|
|
2005-07-03 20:22:16 +04:00
|
|
|
static opal_list_t ompi_proc_list;
|
2005-07-04 02:45:48 +04:00
|
|
|
static opal_mutex_t ompi_proc_lock;
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t* ompi_proc_local_proc = NULL;
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
static void ompi_proc_construct(ompi_proc_t* proc);
|
|
|
|
static void ompi_proc_destruct(ompi_proc_t* proc);
|
2004-01-16 03:31:58 +03:00
|
|
|
|
2004-10-26 15:39:16 +04:00
|
|
|
OBJ_CLASS_INSTANCE(
|
2005-09-01 05:07:30 +04:00
|
|
|
ompi_proc_t,
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t,
|
2005-09-01 05:07:30 +04:00
|
|
|
ompi_proc_construct,
|
2004-10-26 15:39:16 +04:00
|
|
|
ompi_proc_destruct
|
|
|
|
);
|
|
|
|
|
2004-01-16 03:31:58 +03:00
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
void ompi_proc_construct(ompi_proc_t* proc)
|
2004-01-16 03:31:58 +03:00
|
|
|
{
|
2006-07-04 05:20:20 +04:00
|
|
|
proc->proc_bml = NULL;
|
2004-02-14 01:16:39 +03:00
|
|
|
proc->proc_pml = NULL;
|
2004-03-26 17:15:20 +03:00
|
|
|
|
2008-04-30 23:49:53 +04:00
|
|
|
/* By default all processors are supposedly having the same architecture as me. Thus,
|
|
|
|
* by default we run in a homogeneous environment. Later, when the RTE can tell us
|
|
|
|
* the arch of the remote nodes, we will have to set the convertors to the correct
|
|
|
|
* architecture.
|
2005-08-05 22:03:30 +04:00
|
|
|
*/
|
2009-07-14 00:03:41 +04:00
|
|
|
proc->proc_arch = opal_local_arch;
|
2005-08-05 22:03:30 +04:00
|
|
|
proc->proc_convertor = ompi_mpi_local_convertor;
|
|
|
|
OBJ_RETAIN( ompi_mpi_local_convertor );
|
2004-01-29 18:34:47 +03:00
|
|
|
|
2005-07-15 02:43:01 +04:00
|
|
|
proc->proc_flags = 0;
|
|
|
|
|
2008-04-30 23:49:53 +04:00
|
|
|
/* initialize this pointer to NULL */
|
2006-05-11 23:46:21 +04:00
|
|
|
proc->proc_hostname = NULL;
|
2004-01-16 03:31:58 +03:00
|
|
|
}
|
|
|
|
|
2004-01-29 18:34:47 +03:00
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
void ompi_proc_destruct(ompi_proc_t* proc)
|
2004-01-16 03:31:58 +03:00
|
|
|
{
|
2005-08-05 22:03:30 +04:00
|
|
|
/* As all the convertors are created with OBJ_NEW we can just call OBJ_RELEASE. All, except
|
|
|
|
* the local convertor, will get destroyed at some point here. If the reference count is correct
|
|
|
|
* the local convertor (who has the reference count increased in the datatype) will not get
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
* destroyed here. It will be destroyed later when the ompi_datatype_finalize is called.
|
2005-08-05 22:03:30 +04:00
|
|
|
*/
|
2005-07-13 00:25:47 +04:00
|
|
|
OBJ_RELEASE( proc->proc_convertor );
|
2008-04-30 23:49:53 +04:00
|
|
|
/* DO NOT FREE THE HOSTNAME FIELD AS THIS POINTS
|
|
|
|
* TO AN AREA ALLOCATED/FREE'D ELSEWHERE
|
|
|
|
*/
|
2008-07-08 07:56:51 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
|
|
|
opal_list_remove_item(&ompi_proc_list, (opal_list_item_t*)proc);
|
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2004-01-16 03:31:58 +03:00
|
|
|
}
|
|
|
|
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
int ompi_proc_init(void)
|
2004-02-13 16:56:55 +03:00
|
|
|
{
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_vpid_t i;
|
2009-07-14 00:03:41 +04:00
|
|
|
int ret;
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2005-07-03 20:22:16 +04:00
|
|
|
OBJ_CONSTRUCT(&ompi_proc_list, opal_list_t);
|
2005-07-04 02:45:48 +04:00
|
|
|
OBJ_CONSTRUCT(&ompi_proc_lock, opal_mutex_t);
|
2004-10-15 01:04:45 +04:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
/* create proc structures and find self */
|
2012-06-27 05:28:28 +04:00
|
|
|
for( i = 0; i < orte_process_info.num_procs; i++ ) {
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t *proc = OBJ_NEW(ompi_proc_t);
|
2008-07-07 21:39:49 +04:00
|
|
|
opal_list_append(&ompi_proc_list, (opal_list_item_t*)proc);
|
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
proc->proc_name.jobid = ORTE_PROC_MY_NAME->jobid;
|
2008-02-28 04:57:57 +03:00
|
|
|
proc->proc_name.vpid = i;
|
2011-08-27 02:16:14 +04:00
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
if (i == ORTE_PROC_MY_NAME->vpid) {
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_local_proc = proc;
|
Per the RFC, extend the current use of the ompi_proc_t flags field (without changing the field itself).
The prior ompi_proc_t structure had a uint8_t flag field in it, where only one
bit was used to flag that a proc was "local". In that context, "local" was
constrained to mean "local to this node".
This commit provides a greater degree of granularity on the term "local", to include tests
to see if the proc is on the same socket, PC board, node, switch, CU (computing
unit), and cluster.
Add #define's to designate which bits stand for which local condition. This
was added to the OPAL layer to avoid conflicting with the proposed movement of
the BTLs. To make it easier to use, a set of macros have been defined - e.g.,
OPAL_PROC_ON_LOCAL_SOCKET - that test the specific bit. These can be used in
the code base to clearly indicate which sense of locality is being considered.
All locations in the code base that looked at the current proc_t field have
been changed to use the new macros.
Also modify the orte_ess modules so that each returns a uint8_t (to match the
ompi_proc_t field) that contains a complete description of the locality of this
proc. Obviously, not all environments will be capable of providing such detailed
info. Thus, getting a "false" from a test for "on_local_socket" may simply
indicate a lack of knowledge.
This commit was SVN r20496.
2009-02-10 05:20:16 +03:00
|
|
|
proc->proc_flags = OPAL_PROC_ALL_LOCAL;
|
2012-06-27 05:28:28 +04:00
|
|
|
proc->proc_hostname = orte_process_info.nodename;
|
2009-07-14 00:03:41 +04:00
|
|
|
proc->proc_arch = opal_local_arch;
|
|
|
|
/* add our arch to the modex */
|
2009-07-15 08:54:53 +04:00
|
|
|
if (OMPI_SUCCESS != (ret = ompi_modex_send_key_value("OMPI_ARCH", &proc->proc_arch, OPAL_UINT32))) {
|
2009-07-14 00:03:41 +04:00
|
|
|
return ret;
|
|
|
|
}
|
2008-06-19 02:17:53 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-18 06:54:38 +04:00
|
|
|
/**
|
|
|
|
* The process creation is split into two steps. The second step
|
|
|
|
* is the important one, it sets the properties of the remote
|
|
|
|
* process, such as architecture, node name and locality flags.
|
|
|
|
*
|
|
|
|
* This function is to be called __only__ after the modex exchange
|
|
|
|
* has been performed, in order to allow the modex to carry the data
|
|
|
|
* instead of requiring the runtime to provide it.
|
2008-07-08 07:56:51 +04:00
|
|
|
*/
|
2011-10-18 06:54:38 +04:00
|
|
|
int ompi_proc_complete_init(void)
|
2008-06-19 02:17:53 +04:00
|
|
|
{
|
|
|
|
ompi_proc_t *proc = NULL;
|
|
|
|
opal_list_item_t *item = NULL;
|
2011-10-18 06:54:38 +04:00
|
|
|
int ret, errcode = OMPI_SUCCESS;
|
2012-06-27 18:53:55 +04:00
|
|
|
opal_hwloc_locality_t *hwlocale;
|
|
|
|
uint32_t *ui32ptr;
|
|
|
|
|
2008-06-19 02:17:53 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
2012-06-27 18:53:55 +04:00
|
|
|
|
2008-06-19 02:17:53 +04:00
|
|
|
for( item = opal_list_get_first(&ompi_proc_list);
|
2011-10-18 00:51:22 +04:00
|
|
|
item != opal_list_get_end(&ompi_proc_list);
|
|
|
|
item = opal_list_get_next(item)) {
|
2008-06-19 02:17:53 +04:00
|
|
|
proc = (ompi_proc_t*)item;
|
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
if (proc->proc_name.vpid != ORTE_PROC_MY_NAME->vpid) {
|
2011-10-18 06:54:38 +04:00
|
|
|
/* get the locality information */
|
2012-06-27 18:53:55 +04:00
|
|
|
hwlocale = &(proc->proc_flags);
|
|
|
|
ret = ompi_modex_recv_key_value(ORTE_DB_LOCALITY, proc, (void**)&hwlocale, OPAL_HWLOC_LOCALITY_T);
|
|
|
|
if (OMPI_SUCCESS != ret) {
|
|
|
|
errcode = ret;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* get a pointer to the name of the node it is on */
|
|
|
|
ret = ompi_modex_recv_string_pointer(ORTE_DB_HOSTNAME, proc, (void**)&(proc->proc_hostname), OPAL_STRING);
|
|
|
|
if (OMPI_SUCCESS != ret) {
|
|
|
|
errcode = ret;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* get the remote architecture */
|
|
|
|
ui32ptr = &(proc->proc_arch);
|
|
|
|
ret = ompi_modex_recv_key_value("OMPI_ARCH", proc, (void**)&ui32ptr, OPAL_UINT32);
|
2010-02-03 08:07:40 +03:00
|
|
|
if (OMPI_SUCCESS == ret) {
|
|
|
|
/* if arch is different than mine, create a new convertor for this proc */
|
|
|
|
if (proc->proc_arch != opal_local_arch) {
|
2009-05-07 00:11:28 +04:00
|
|
|
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
|
2010-02-03 08:07:40 +03:00
|
|
|
OBJ_RELEASE(proc->proc_convertor);
|
|
|
|
proc->proc_convertor = opal_convertor_create(proc->proc_arch, 0);
|
2007-08-09 22:53:28 +04:00
|
|
|
#else
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_show_help("help-mpi-runtime",
|
2010-02-03 08:07:40 +03:00
|
|
|
"heterogeneous-support-unavailable",
|
2012-06-27 05:28:28 +04:00
|
|
|
true, orte_process_info.nodename,
|
2011-10-18 06:54:38 +04:00
|
|
|
proc->proc_hostname == NULL ? "<hostname unavailable>" : proc->proc_hostname);
|
|
|
|
errcode = OMPI_ERR_NOT_SUPPORTED;
|
|
|
|
break;
|
2007-08-09 22:53:28 +04:00
|
|
|
#endif
|
2010-02-03 08:07:40 +03:00
|
|
|
}
|
2012-04-06 18:23:13 +04:00
|
|
|
} else if (OMPI_ERR_NOT_IMPLEMENTED == ret) {
|
2010-02-03 08:07:40 +03:00
|
|
|
proc->proc_arch = opal_local_arch;
|
|
|
|
} else {
|
2011-10-18 06:54:38 +04:00
|
|
|
errcode = ret;
|
|
|
|
break;
|
2008-06-19 02:17:53 +04:00
|
|
|
}
|
2007-08-09 22:53:28 +04:00
|
|
|
}
|
2005-09-01 19:05:03 +04:00
|
|
|
}
|
2008-06-19 02:17:53 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2011-10-18 06:54:38 +04:00
|
|
|
return errcode;
|
2004-02-13 16:56:55 +03:00
|
|
|
}
|
|
|
|
|
2008-06-19 02:17:53 +04:00
|
|
|
|
2004-12-02 16:28:10 +03:00
|
|
|
int ompi_proc_finalize (void)
|
|
|
|
{
|
2008-07-08 07:56:51 +04:00
|
|
|
opal_list_item_t *item;
|
|
|
|
|
|
|
|
/* remove all items from list and destroy them. Since we cannot know
|
|
|
|
* the reference count of the procs for certain, it is possible that
|
|
|
|
* a single OBJ_RELEASE won't drive the count to zero, and hence will
|
|
|
|
* not release the memory. Accordingly, we cycle through the list here,
|
|
|
|
* calling release on each item.
|
|
|
|
*
|
|
|
|
* This will cycle until it forces the reference count of each item
|
|
|
|
* to zero, thus causing the destructor to run - which will remove
|
|
|
|
* the item from the list!
|
|
|
|
*
|
|
|
|
* We cannot do this under the thread lock as the destructor will
|
|
|
|
* call it when removing the item from the list. However, this function
|
|
|
|
* is ONLY called from MPI_Finalize, and all threads are prohibited from
|
|
|
|
* calling an MPI function once ANY thread has called MPI_Finalize. Of
|
|
|
|
* course, multiple threads are allowed to call MPI_Finalize, so this
|
|
|
|
* function may get called multiple times by various threads. We believe
|
|
|
|
* it is thread safe to do so...though it may not -appear- to be so
|
|
|
|
* without walking through the entire list/destructor sequence.
|
|
|
|
*/
|
|
|
|
while (opal_list_get_end(&ompi_proc_list) != (item = opal_list_get_first(&ompi_proc_list))) {
|
|
|
|
OBJ_RELEASE(item);
|
2004-12-02 16:28:10 +03:00
|
|
|
}
|
2008-07-08 07:56:51 +04:00
|
|
|
/* now destruct the list and thread lock */
|
2004-12-02 16:28:10 +03:00
|
|
|
OBJ_DESTRUCT(&ompi_proc_list);
|
2008-07-07 21:39:49 +04:00
|
|
|
OBJ_DESTRUCT(&ompi_proc_lock);
|
2004-12-02 16:28:10 +03:00
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t** ompi_proc_world(size_t *size)
|
2004-02-13 16:56:55 +03:00
|
|
|
{
|
2005-07-15 02:43:01 +04:00
|
|
|
ompi_proc_t **procs;
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t *proc;
|
2004-02-13 16:56:55 +03:00
|
|
|
size_t count = 0;
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_ns_cmp_bitmask_t mask;
|
|
|
|
orte_process_name_t my_name;
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2005-07-15 02:43:01 +04:00
|
|
|
/* check bozo case */
|
|
|
|
if (NULL == ompi_proc_local_proc) {
|
2004-02-13 16:56:55 +03:00
|
|
|
return NULL;
|
2005-07-15 02:43:01 +04:00
|
|
|
}
|
2012-06-27 05:28:28 +04:00
|
|
|
mask = ORTE_NS_CMP_JOBID;
|
2005-07-15 02:43:01 +04:00
|
|
|
my_name = ompi_proc_local_proc->proc_name;
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2005-07-15 02:43:01 +04:00
|
|
|
/* First count how many match this jobid */
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
2005-09-01 05:07:30 +04:00
|
|
|
for (proc = (ompi_proc_t*)opal_list_get_first(&ompi_proc_list);
|
2005-07-15 02:43:01 +04:00
|
|
|
proc != (ompi_proc_t*)opal_list_get_end(&ompi_proc_list);
|
|
|
|
proc = (ompi_proc_t*)opal_list_get_next(proc)) {
|
2012-06-27 05:28:28 +04:00
|
|
|
if (OPAL_EQUAL == orte_util_compare_name_fields(mask, &proc->proc_name, &my_name)) {
|
2005-07-15 02:43:01 +04:00
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate an array */
|
|
|
|
procs = (ompi_proc_t**) malloc(count * sizeof(ompi_proc_t*));
|
|
|
|
if (NULL == procs) {
|
2008-07-07 21:39:49 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2005-07-15 02:43:01 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now save only the procs that match this jobid */
|
|
|
|
count = 0;
|
2005-09-01 05:07:30 +04:00
|
|
|
for (proc = (ompi_proc_t*)opal_list_get_first(&ompi_proc_list);
|
2005-07-15 02:43:01 +04:00
|
|
|
proc != (ompi_proc_t*)opal_list_get_end(&ompi_proc_list);
|
|
|
|
proc = (ompi_proc_t*)opal_list_get_next(proc)) {
|
2012-06-27 05:28:28 +04:00
|
|
|
if (OPAL_EQUAL == orte_util_compare_name_fields(mask, &proc->proc_name, &my_name)) {
|
2008-07-08 07:56:51 +04:00
|
|
|
/* DO NOT RETAIN THIS OBJECT - the reference count on this
|
|
|
|
* object will be adjusted by external callers. The intent
|
|
|
|
* here is to allow the reference count to drop to zero if
|
|
|
|
* the app no longer desires to communicate with this proc.
|
|
|
|
* For example, the proc may call comm_disconnect on all
|
|
|
|
* communicators involving this proc. In such cases, we want
|
|
|
|
* the proc object to be removed from the list. By not incrementing
|
|
|
|
* the reference count here, we allow this to occur.
|
|
|
|
*
|
|
|
|
* We don't implement that yet, but we are still safe for now as
|
|
|
|
* the OBJ_NEW in ompi_proc_init owns the initial reference
|
|
|
|
* count which cannot be released until ompi_proc_finalize is
|
|
|
|
* called.
|
|
|
|
*/
|
2005-07-15 02:43:01 +04:00
|
|
|
procs[count++] = proc;
|
|
|
|
}
|
2004-02-13 16:56:55 +03:00
|
|
|
}
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2005-07-15 02:43:01 +04:00
|
|
|
|
2004-02-13 16:56:55 +03:00
|
|
|
*size = count;
|
|
|
|
return procs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t** ompi_proc_all(size_t* size)
|
2004-02-13 16:56:55 +03:00
|
|
|
{
|
2005-09-01 05:07:30 +04:00
|
|
|
ompi_proc_t **procs =
|
2005-07-03 20:22:16 +04:00
|
|
|
(ompi_proc_t**) malloc(opal_list_get_size(&ompi_proc_list) * sizeof(ompi_proc_t*));
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t *proc;
|
2004-02-13 16:56:55 +03:00
|
|
|
size_t count = 0;
|
|
|
|
|
2005-07-15 02:43:01 +04:00
|
|
|
if (NULL == procs) {
|
2004-02-13 16:56:55 +03:00
|
|
|
return NULL;
|
2005-07-15 02:43:01 +04:00
|
|
|
}
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
2005-09-01 05:07:30 +04:00
|
|
|
for(proc = (ompi_proc_t*)opal_list_get_first(&ompi_proc_list);
|
2005-07-03 20:22:16 +04:00
|
|
|
proc != (ompi_proc_t*)opal_list_get_end(&ompi_proc_list);
|
|
|
|
proc = (ompi_proc_t*)opal_list_get_next(proc)) {
|
2008-07-08 07:56:51 +04:00
|
|
|
/* We know this isn't consistent with the behavior in ompi_proc_world,
|
|
|
|
* but we are leaving the RETAIN for now because the code using this function
|
|
|
|
* assumes that the results need to be released when done. It will
|
|
|
|
* be cleaned up later as the "fix" will impact other places in
|
|
|
|
* the code
|
|
|
|
*/
|
2004-02-13 16:56:55 +03:00
|
|
|
OBJ_RETAIN(proc);
|
|
|
|
procs[count++] = proc;
|
|
|
|
}
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2004-02-13 16:56:55 +03:00
|
|
|
*size = count;
|
|
|
|
return procs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_proc_t** ompi_proc_self(size_t* size)
|
2004-02-13 16:56:55 +03:00
|
|
|
{
|
2004-10-18 20:11:14 +04:00
|
|
|
ompi_proc_t **procs = (ompi_proc_t**) malloc(sizeof(ompi_proc_t*));
|
2005-07-15 02:43:01 +04:00
|
|
|
if (NULL == procs) {
|
2004-02-13 16:56:55 +03:00
|
|
|
return NULL;
|
2005-07-15 02:43:01 +04:00
|
|
|
}
|
2008-07-08 07:56:51 +04:00
|
|
|
/* We know this isn't consistent with the behavior in ompi_proc_world,
|
|
|
|
* but we are leaving the RETAIN for now because the code using this function
|
|
|
|
* assumes that the results need to be released when done. It will
|
|
|
|
* be cleaned up later as the "fix" will impact other places in
|
|
|
|
* the code
|
|
|
|
*/
|
2004-06-07 19:33:53 +04:00
|
|
|
OBJ_RETAIN(ompi_proc_local_proc);
|
|
|
|
*procs = ompi_proc_local_proc;
|
2004-02-13 16:56:55 +03:00
|
|
|
*size = 1;
|
|
|
|
return procs;
|
|
|
|
}
|
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
ompi_proc_t * ompi_proc_find ( const orte_process_name_t * name )
|
2004-05-18 01:28:32 +04:00
|
|
|
{
|
2004-09-17 14:10:24 +04:00
|
|
|
ompi_proc_t *proc, *rproc=NULL;
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_ns_cmp_bitmask_t mask;
|
2004-05-18 01:28:32 +04:00
|
|
|
|
|
|
|
/* return the proc-struct which matches this jobid+process id */
|
2012-06-27 05:28:28 +04:00
|
|
|
mask = ORTE_NS_CMP_JOBID | ORTE_NS_CMP_VPID;
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
2005-09-01 05:07:30 +04:00
|
|
|
for(proc = (ompi_proc_t*)opal_list_get_first(&ompi_proc_list);
|
2005-07-03 20:22:16 +04:00
|
|
|
proc != (ompi_proc_t*)opal_list_get_end(&ompi_proc_list);
|
|
|
|
proc = (ompi_proc_t*)opal_list_get_next(proc)) {
|
2012-06-27 05:28:28 +04:00
|
|
|
if (OPAL_EQUAL == orte_util_compare_name_fields(mask, &proc->proc_name, name)) {
|
2005-03-14 23:57:21 +03:00
|
|
|
rproc = proc;
|
|
|
|
break;
|
|
|
|
}
|
2004-05-18 01:28:32 +04:00
|
|
|
}
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
|
2004-09-17 14:10:24 +04:00
|
|
|
return rproc;
|
2004-05-18 01:28:32 +04:00
|
|
|
}
|
2004-07-01 18:49:54 +04:00
|
|
|
|
2004-08-04 21:05:22 +04:00
|
|
|
|
2008-04-30 23:49:53 +04:00
|
|
|
int ompi_proc_refresh(void) {
|
|
|
|
ompi_proc_t *proc = NULL;
|
|
|
|
opal_list_item_t *item = NULL;
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_vpid_t i = 0;
|
2012-06-27 18:53:55 +04:00
|
|
|
int ret=OMPI_SUCCESS;
|
|
|
|
opal_hwloc_locality_t *hwlocale;
|
|
|
|
uint32_t *uiptr;
|
2004-09-17 14:10:24 +04:00
|
|
|
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
2004-09-17 14:10:24 +04:00
|
|
|
|
2008-04-30 23:49:53 +04:00
|
|
|
for( item = opal_list_get_first(&ompi_proc_list), i = 0;
|
|
|
|
item != opal_list_get_end(&ompi_proc_list);
|
|
|
|
item = opal_list_get_next(item), ++i ) {
|
|
|
|
proc = (ompi_proc_t*)item;
|
|
|
|
|
2008-05-01 21:48:13 +04:00
|
|
|
/* Does not change: proc->proc_name.vpid */
|
2012-06-27 05:28:28 +04:00
|
|
|
proc->proc_name.jobid = ORTE_PROC_MY_NAME->jobid;
|
2008-05-01 21:48:13 +04:00
|
|
|
|
2008-05-08 22:47:47 +04:00
|
|
|
/* Make sure to clear the local flag before we set it below */
|
|
|
|
proc->proc_flags = 0;
|
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
if (i == ORTE_PROC_MY_NAME->vpid) {
|
2008-04-30 23:49:53 +04:00
|
|
|
ompi_proc_local_proc = proc;
|
Per the RFC, extend the current use of the ompi_proc_t flags field (without changing the field itself).
The prior ompi_proc_t structure had a uint8_t flag field in it, where only one
bit was used to flag that a proc was "local". In that context, "local" was
constrained to mean "local to this node".
This commit provides a greater degree of granularity on the term "local", to include tests
to see if the proc is on the same socket, PC board, node, switch, CU (computing
unit), and cluster.
Add #define's to designate which bits stand for which local condition. This
was added to the OPAL layer to avoid conflicting with the proposed movement of
the BTLs. To make it easier to use, a set of macros have been defined - e.g.,
OPAL_PROC_ON_LOCAL_SOCKET - that test the specific bit. These can be used in
the code base to clearly indicate which sense of locality is being considered.
All locations in the code base that looked at the current proc_t field have
been changed to use the new macros.
Also modify the orte_ess modules so that each returns a uint8_t (to match the
ompi_proc_t field) that contains a complete description of the locality of this
proc. Obviously, not all environments will be capable of providing such detailed
info. Thus, getting a "false" from a test for "on_local_socket" may simply
indicate a lack of knowledge.
This commit was SVN r20496.
2009-02-10 05:20:16 +03:00
|
|
|
proc->proc_flags = OPAL_PROC_ALL_LOCAL;
|
2012-06-27 05:28:28 +04:00
|
|
|
proc->proc_hostname = orte_process_info.nodename;
|
2009-07-14 00:03:41 +04:00
|
|
|
proc->proc_arch = opal_local_arch;
|
2008-04-30 23:49:53 +04:00
|
|
|
} else {
|
2012-06-27 18:53:55 +04:00
|
|
|
hwlocale = &(proc->proc_flags);
|
|
|
|
ret = ompi_modex_recv_key_value(ORTE_DB_LOCALITY, proc, (void**)&hwlocale, OPAL_HWLOC_LOCALITY_T);
|
|
|
|
if (OMPI_SUCCESS != ret) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* get the name of the node it is on */
|
2012-07-20 16:11:47 +04:00
|
|
|
ret = ompi_modex_recv_string_pointer(ORTE_DB_HOSTNAME, proc, (void**)&(proc->proc_hostname), OPAL_STRING);
|
2012-06-27 18:53:55 +04:00
|
|
|
if (OMPI_SUCCESS != ret) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* get the remote architecture */
|
|
|
|
uiptr = &(proc->proc_arch);
|
|
|
|
ret = ompi_modex_recv_key_value("OMPI_ARCH", proc, (void**)&uiptr, OPAL_UINT32);
|
2008-04-30 23:49:53 +04:00
|
|
|
/* if arch is different than mine, create a new convertor for this proc */
|
2009-07-14 00:03:41 +04:00
|
|
|
if (proc->proc_arch != opal_local_arch) {
|
2009-05-07 00:11:28 +04:00
|
|
|
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
|
2008-04-30 23:49:53 +04:00
|
|
|
OBJ_RELEASE(proc->proc_convertor);
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
proc->proc_convertor = opal_convertor_create(proc->proc_arch, 0);
|
2008-04-30 23:49:53 +04:00
|
|
|
#else
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_show_help("help-mpi-runtime",
|
2008-04-30 23:49:53 +04:00
|
|
|
"heterogeneous-support-unavailable",
|
2012-06-27 05:28:28 +04:00
|
|
|
true, orte_process_info.nodename,
|
2008-04-30 23:49:53 +04:00
|
|
|
proc->proc_hostname == NULL ? "<hostname unavailable>" :
|
|
|
|
proc->proc_hostname);
|
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
|
|
|
return OMPI_ERR_NOT_SUPPORTED;
|
|
|
|
#endif
|
|
|
|
}
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
}
|
2004-09-17 14:10:24 +04:00
|
|
|
}
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
|
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
|
|
|
|
2012-06-27 18:53:55 +04:00
|
|
|
return ret;
|
2004-09-17 14:10:24 +04:00
|
|
|
}
|
|
|
|
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
int
|
2008-02-28 04:57:57 +03:00
|
|
|
ompi_proc_pack(ompi_proc_t **proclist, int proclistsize, opal_buffer_t* buf)
|
2004-08-04 21:05:22 +04:00
|
|
|
{
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
int i, rc;
|
2008-04-30 23:49:53 +04:00
|
|
|
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
2008-07-08 07:56:51 +04:00
|
|
|
|
|
|
|
/* cycle through the provided array, packing the OMPI level
|
|
|
|
* data for each proc. This data may or may not be included
|
|
|
|
* in any subsequent modex operation, so we include it here
|
|
|
|
* to ensure completion of a connect/accept handshake. See
|
|
|
|
* the ompi/mca/dpm framework for an example of where and how
|
|
|
|
* this info is used.
|
|
|
|
*
|
|
|
|
* Eventually, we will review the procedures that call this
|
|
|
|
* function to see if duplication of communication can be
|
|
|
|
* reduced. For now, just go ahead and pack the info so it
|
|
|
|
* can be sent.
|
|
|
|
*/
|
2004-08-04 21:05:22 +04:00
|
|
|
for (i=0; i<proclistsize; i++) {
|
2012-06-27 05:28:28 +04:00
|
|
|
rc = opal_dss.pack(buf, &(proclist[i]->proc_name), 1, ORTE_NAME);
|
2011-10-04 18:50:31 +04:00
|
|
|
if(rc != OPAL_SUCCESS) {
|
2012-06-27 05:28:28 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
These changes were mostly captured in a prior RFC (except for #2 below) and are aimed specifically at improving startup performance and setting up the remaining modifications described in that RFC.
The commit has been tested for C/R and Cray operations, and on Odin (SLURM, rsh) and RoadRunner (TM). I tried to update all environments, but obviously could not test them. I know that Windows needs some work, and have highlighted what is know to be needed in the odls process component.
This represents a lot of work by Brian, Tim P, Josh, and myself, with much advice from Jeff and others. For posterity, I have appended a copy of the email describing the work that was done:
As we have repeatedly noted, the modex operation in MPI_Init is the single greatest consumer of time during startup. To-date, we have executed that operation as an ORTE stage gate that held the process until a startup message containing all required modex (and OOB contact info - see #3 below) info could be sent to it. Each process would send its data to the HNP's registry, which assembled and sent the message when all processes had reported in.
In addition, ORTE had taken responsibility for monitoring process status as it progressed through a series of "stage gates". The process reported its status at each gate, and ORTE would then send a "release" message once all procs had reported in.
The incoming changes revamp these procedures in three ways:
1. eliminating the ORTE stage gate system and cleanly delineating responsibility between the OMPI and ORTE layers for MPI init/finalize. The modex stage gate (STG1) has been replaced by a collective operation in the modex itself that performs an allgather on the required modex info. The allgather is implemented using the orte_grpcomm framework since the BTL's are not active at that point. At the moment, the grpcomm framework only has a "basic" component analogous to OMPI's "basic" coll framework - I would recommend that the MPI team create additional, more advanced components to improve performance of this step.
The other stage gates have been replaced by orte_grpcomm barrier functions. We tried to use MPI barriers instead (since the BTL's are active at that point), but - as we discussed on the telecon - these are not currently true barriers so the job would hang when we fell through while messages were still in process. Note that the grpcomm barrier doesn't actually resolve that problem, but Brian has pointed out that we are unlikely to ever see it violated. Again, you might want to spend a little time on an advanced barrier algorithm as the one in "basic" is very simplistic.
Summarizing this change: ORTE no longer tracks process state nor has direct responsibility for synchronizing jobs. This is now done via collective operations within the MPI layer, albeit using ORTE collective communication services. I -strongly- urge the MPI team to implement advanced collective algorithms to improve the performance of this critical procedure.
2. reducing the volume of data exchanged during modex. Data in the modex consisted of the process name, the name of the node where that process is located (expressed as a string), plus a string representation of all contact info. The nodename was required in order for the modex to determine if the process was local or not - in addition, some people like to have it to print pretty error messages when a connection failed.
The size of this data has been reduced in three ways:
(a) reducing the size of the process name itself. The process name consisted of two 32-bit fields for the jobid and vpid. This is far larger than any current system, or system likely to exist in the near future, can support. Accordingly, the default size of these fields has been reduced to 16-bits, which means you can have 32k procs in each of 32k jobs. Since the daemons must have a vpid, and we require one daemon/node, this also restricts the default configuration to 32k nodes.
To support any future "mega-clusters", a configuration option --enable-jumbo-apps has been added. This option increases the jobid and vpid field sizes to 32-bits. Someday, if necessary, someone can add yet another option to increase them to 64-bits, I suppose.
(b) replacing the string nodename with an integer nodeid. Since we have one daemon/node, the nodeid corresponds to the local daemon's vpid. This replaces an often lengthy string with only 2 (or at most 4) bytes, a substantial reduction.
(c) when the mca param requesting that nodenames be sent to support pretty error messages, a second mca param is now used to request FQDN - otherwise, the domain name is stripped (by default) from the message to save space. If someone wants to combine those into a single param somehow (perhaps with an argument?), they are welcome to do so - I didn't want to alter what people are already using.
While these may seem like small savings, they actually amount to a significant impact when aggregated across the entire modex operation. Since every proc must receive the modex data regardless of the collective used to send it, just reducing the size of the process name removes nearly 400MBytes of communication from a 32k proc job (admittedly, much of this comm may occur in parallel). So it does add up pretty quickly.
3. routing RML messages to reduce connections. The default messaging system remains point-to-point - i.e., each proc opens a socket to every proc it communicates with and sends its messages directly. A new option uses the orteds as routers - i.e., each proc only opens a single socket to its local orted. All messages are sent from the proc to the orted, which forwards the message to the orted on the node where the intended recipient proc is located - that orted then forwards the message to its local proc (the recipient). This greatly reduces the connection storm we have encountered during startup.
It also has the benefit of removing the sharing of every proc's OOB contact with every other proc. The orted routing tables are populated during launch since every orted gets a map of where every proc is being placed. Each proc, therefore, only needs to know the contact info for its local daemon, which is passed in via the environment when the proc is fork/exec'd by the daemon. This alone removes ~50 bytes/process of communication that was in the current STG1 startup message - so for our 32k proc job, this saves us roughly 32k*50 = 1.6MBytes sent to 32k procs = 51GBytes of messaging.
Note that you can use the new routing method by specifying -mca routed tree - if you so desire. This mode will become the default at some point in the future.
There are a few minor additional changes in the commit that I'll just note in passing:
* propagation of command line mca params to the orteds - fixes ticket #1073. See note there for details.
* requiring of "finalize" prior to "exit" for MPI procs - fixes ticket #1144. See note there for details.
* cleanup of some stale header files
This commit was SVN r16364.
2007-10-05 23:48:23 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
|
|
|
return rc;
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = opal_dss.pack(buf, &(proclist[i]->proc_arch), 1, OPAL_UINT32);
|
2011-10-04 18:50:31 +04:00
|
|
|
if(rc != OPAL_SUCCESS) {
|
2012-06-27 05:28:28 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
|
|
|
return rc;
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = opal_dss.pack(buf, &(proclist[i]->proc_hostname), 1, OPAL_STRING);
|
2011-10-04 18:50:31 +04:00
|
|
|
if(rc != OPAL_SUCCESS) {
|
2012-06-27 05:28:28 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2005-03-14 23:57:21 +03:00
|
|
|
return rc;
|
|
|
|
}
|
2004-08-04 21:05:22 +04:00
|
|
|
}
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
2004-08-04 21:05:22 +04:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2008-04-30 23:49:53 +04:00
|
|
|
static ompi_proc_t *
|
2012-06-27 05:28:28 +04:00
|
|
|
ompi_proc_find_and_add(const orte_process_name_t * name, bool* isnew)
|
2008-04-30 23:49:53 +04:00
|
|
|
{
|
|
|
|
ompi_proc_t *proc, *rproc = NULL;
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_ns_cmp_bitmask_t mask;
|
2008-04-30 23:49:53 +04:00
|
|
|
|
|
|
|
/* return the proc-struct which matches this jobid+process id */
|
2012-06-27 05:28:28 +04:00
|
|
|
mask = ORTE_NS_CMP_JOBID | ORTE_NS_CMP_VPID;
|
2008-04-30 23:49:53 +04:00
|
|
|
OPAL_THREAD_LOCK(&ompi_proc_lock);
|
|
|
|
for(proc = (ompi_proc_t*)opal_list_get_first(&ompi_proc_list);
|
|
|
|
proc != (ompi_proc_t*)opal_list_get_end(&ompi_proc_list);
|
|
|
|
proc = (ompi_proc_t*)opal_list_get_next(proc)) {
|
2012-06-27 05:28:28 +04:00
|
|
|
if (OPAL_EQUAL == orte_util_compare_name_fields(mask, &proc->proc_name, name)) {
|
2008-04-30 23:49:53 +04:00
|
|
|
rproc = proc;
|
|
|
|
*isnew = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-08 07:56:51 +04:00
|
|
|
/* if we didn't find this proc in the list, create a new
|
|
|
|
* proc_t and append it to the list
|
|
|
|
*/
|
2008-04-30 23:49:53 +04:00
|
|
|
if (NULL == rproc) {
|
|
|
|
*isnew = true;
|
|
|
|
rproc = OBJ_NEW(ompi_proc_t);
|
|
|
|
if (NULL != rproc) {
|
2008-07-10 00:45:24 +04:00
|
|
|
opal_list_append(&ompi_proc_list, (opal_list_item_t*)rproc);
|
2008-04-30 23:49:53 +04:00
|
|
|
rproc->proc_name = *name;
|
|
|
|
}
|
|
|
|
/* caller had better fill in the rest of the proc, or there's
|
|
|
|
going to be pain later... */
|
|
|
|
}
|
|
|
|
|
|
|
|
OPAL_THREAD_UNLOCK(&ompi_proc_lock);
|
|
|
|
|
|
|
|
return rproc;
|
|
|
|
}
|
|
|
|
|
2004-08-04 21:05:22 +04:00
|
|
|
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
int
|
2008-02-28 04:57:57 +03:00
|
|
|
ompi_proc_unpack(opal_buffer_t* buf,
|
These changes were mostly captured in a prior RFC (except for #2 below) and are aimed specifically at improving startup performance and setting up the remaining modifications described in that RFC.
The commit has been tested for C/R and Cray operations, and on Odin (SLURM, rsh) and RoadRunner (TM). I tried to update all environments, but obviously could not test them. I know that Windows needs some work, and have highlighted what is know to be needed in the odls process component.
This represents a lot of work by Brian, Tim P, Josh, and myself, with much advice from Jeff and others. For posterity, I have appended a copy of the email describing the work that was done:
As we have repeatedly noted, the modex operation in MPI_Init is the single greatest consumer of time during startup. To-date, we have executed that operation as an ORTE stage gate that held the process until a startup message containing all required modex (and OOB contact info - see #3 below) info could be sent to it. Each process would send its data to the HNP's registry, which assembled and sent the message when all processes had reported in.
In addition, ORTE had taken responsibility for monitoring process status as it progressed through a series of "stage gates". The process reported its status at each gate, and ORTE would then send a "release" message once all procs had reported in.
The incoming changes revamp these procedures in three ways:
1. eliminating the ORTE stage gate system and cleanly delineating responsibility between the OMPI and ORTE layers for MPI init/finalize. The modex stage gate (STG1) has been replaced by a collective operation in the modex itself that performs an allgather on the required modex info. The allgather is implemented using the orte_grpcomm framework since the BTL's are not active at that point. At the moment, the grpcomm framework only has a "basic" component analogous to OMPI's "basic" coll framework - I would recommend that the MPI team create additional, more advanced components to improve performance of this step.
The other stage gates have been replaced by orte_grpcomm barrier functions. We tried to use MPI barriers instead (since the BTL's are active at that point), but - as we discussed on the telecon - these are not currently true barriers so the job would hang when we fell through while messages were still in process. Note that the grpcomm barrier doesn't actually resolve that problem, but Brian has pointed out that we are unlikely to ever see it violated. Again, you might want to spend a little time on an advanced barrier algorithm as the one in "basic" is very simplistic.
Summarizing this change: ORTE no longer tracks process state nor has direct responsibility for synchronizing jobs. This is now done via collective operations within the MPI layer, albeit using ORTE collective communication services. I -strongly- urge the MPI team to implement advanced collective algorithms to improve the performance of this critical procedure.
2. reducing the volume of data exchanged during modex. Data in the modex consisted of the process name, the name of the node where that process is located (expressed as a string), plus a string representation of all contact info. The nodename was required in order for the modex to determine if the process was local or not - in addition, some people like to have it to print pretty error messages when a connection failed.
The size of this data has been reduced in three ways:
(a) reducing the size of the process name itself. The process name consisted of two 32-bit fields for the jobid and vpid. This is far larger than any current system, or system likely to exist in the near future, can support. Accordingly, the default size of these fields has been reduced to 16-bits, which means you can have 32k procs in each of 32k jobs. Since the daemons must have a vpid, and we require one daemon/node, this also restricts the default configuration to 32k nodes.
To support any future "mega-clusters", a configuration option --enable-jumbo-apps has been added. This option increases the jobid and vpid field sizes to 32-bits. Someday, if necessary, someone can add yet another option to increase them to 64-bits, I suppose.
(b) replacing the string nodename with an integer nodeid. Since we have one daemon/node, the nodeid corresponds to the local daemon's vpid. This replaces an often lengthy string with only 2 (or at most 4) bytes, a substantial reduction.
(c) when the mca param requesting that nodenames be sent to support pretty error messages, a second mca param is now used to request FQDN - otherwise, the domain name is stripped (by default) from the message to save space. If someone wants to combine those into a single param somehow (perhaps with an argument?), they are welcome to do so - I didn't want to alter what people are already using.
While these may seem like small savings, they actually amount to a significant impact when aggregated across the entire modex operation. Since every proc must receive the modex data regardless of the collective used to send it, just reducing the size of the process name removes nearly 400MBytes of communication from a 32k proc job (admittedly, much of this comm may occur in parallel). So it does add up pretty quickly.
3. routing RML messages to reduce connections. The default messaging system remains point-to-point - i.e., each proc opens a socket to every proc it communicates with and sends its messages directly. A new option uses the orteds as routers - i.e., each proc only opens a single socket to its local orted. All messages are sent from the proc to the orted, which forwards the message to the orted on the node where the intended recipient proc is located - that orted then forwards the message to its local proc (the recipient). This greatly reduces the connection storm we have encountered during startup.
It also has the benefit of removing the sharing of every proc's OOB contact with every other proc. The orted routing tables are populated during launch since every orted gets a map of where every proc is being placed. Each proc, therefore, only needs to know the contact info for its local daemon, which is passed in via the environment when the proc is fork/exec'd by the daemon. This alone removes ~50 bytes/process of communication that was in the current STG1 startup message - so for our 32k proc job, this saves us roughly 32k*50 = 1.6MBytes sent to 32k procs = 51GBytes of messaging.
Note that you can use the new routing method by specifying -mca routed tree - if you so desire. This mode will become the default at some point in the future.
There are a few minor additional changes in the commit that I'll just note in passing:
* propagation of command line mca params to the orteds - fixes ticket #1073. See note there for details.
* requiring of "finalize" prior to "exit" for MPI procs - fixes ticket #1144. See note there for details.
* cleanup of some stale header files
This commit was SVN r16364.
2007-10-05 23:48:23 +04:00
|
|
|
int proclistsize, ompi_proc_t ***proclist,
|
|
|
|
int *newproclistsize, ompi_proc_t ***newproclist)
|
2004-08-04 21:05:22 +04:00
|
|
|
{
|
|
|
|
int i;
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
size_t newprocs_len = 0;
|
|
|
|
ompi_proc_t **plist=NULL, **newprocs = NULL;
|
2008-04-30 23:49:53 +04:00
|
|
|
|
2005-07-15 02:43:01 +04:00
|
|
|
/* do not free plist *ever*, since it is used in the remote group
|
2008-04-30 23:49:53 +04:00
|
|
|
structure of a communicator */
|
2004-09-16 14:07:14 +04:00
|
|
|
plist = (ompi_proc_t **) calloc (proclistsize, sizeof (ompi_proc_t *));
|
2004-08-04 21:05:22 +04:00
|
|
|
if ( NULL == plist ) {
|
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
/* free this on the way out */
|
|
|
|
newprocs = (ompi_proc_t **) calloc (proclistsize, sizeof (ompi_proc_t *));
|
|
|
|
if (NULL == newprocs) {
|
2008-08-12 00:46:27 +04:00
|
|
|
free(plist);
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
2008-04-30 23:49:53 +04:00
|
|
|
|
2008-07-08 07:56:51 +04:00
|
|
|
/* cycle through the array of provided procs and unpack
|
|
|
|
* their info - as packed by ompi_proc_pack
|
|
|
|
*/
|
2004-08-04 21:05:22 +04:00
|
|
|
for ( i=0; i<proclistsize; i++ ){
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_std_cntr_t count=1;
|
|
|
|
orte_process_name_t new_name;
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
uint32_t new_arch;
|
|
|
|
char *new_hostname;
|
|
|
|
bool isnew = false;
|
|
|
|
int rc;
|
2008-04-30 23:49:53 +04:00
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
rc = opal_dss.unpack(buf, &new_name, &count, ORTE_NAME);
|
2011-10-04 18:50:31 +04:00
|
|
|
if (rc != OPAL_SUCCESS) {
|
2012-06-27 05:28:28 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
2008-08-12 00:46:27 +04:00
|
|
|
free(plist);
|
|
|
|
free(newprocs);
|
These changes were mostly captured in a prior RFC (except for #2 below) and are aimed specifically at improving startup performance and setting up the remaining modifications described in that RFC.
The commit has been tested for C/R and Cray operations, and on Odin (SLURM, rsh) and RoadRunner (TM). I tried to update all environments, but obviously could not test them. I know that Windows needs some work, and have highlighted what is know to be needed in the odls process component.
This represents a lot of work by Brian, Tim P, Josh, and myself, with much advice from Jeff and others. For posterity, I have appended a copy of the email describing the work that was done:
As we have repeatedly noted, the modex operation in MPI_Init is the single greatest consumer of time during startup. To-date, we have executed that operation as an ORTE stage gate that held the process until a startup message containing all required modex (and OOB contact info - see #3 below) info could be sent to it. Each process would send its data to the HNP's registry, which assembled and sent the message when all processes had reported in.
In addition, ORTE had taken responsibility for monitoring process status as it progressed through a series of "stage gates". The process reported its status at each gate, and ORTE would then send a "release" message once all procs had reported in.
The incoming changes revamp these procedures in three ways:
1. eliminating the ORTE stage gate system and cleanly delineating responsibility between the OMPI and ORTE layers for MPI init/finalize. The modex stage gate (STG1) has been replaced by a collective operation in the modex itself that performs an allgather on the required modex info. The allgather is implemented using the orte_grpcomm framework since the BTL's are not active at that point. At the moment, the grpcomm framework only has a "basic" component analogous to OMPI's "basic" coll framework - I would recommend that the MPI team create additional, more advanced components to improve performance of this step.
The other stage gates have been replaced by orte_grpcomm barrier functions. We tried to use MPI barriers instead (since the BTL's are active at that point), but - as we discussed on the telecon - these are not currently true barriers so the job would hang when we fell through while messages were still in process. Note that the grpcomm barrier doesn't actually resolve that problem, but Brian has pointed out that we are unlikely to ever see it violated. Again, you might want to spend a little time on an advanced barrier algorithm as the one in "basic" is very simplistic.
Summarizing this change: ORTE no longer tracks process state nor has direct responsibility for synchronizing jobs. This is now done via collective operations within the MPI layer, albeit using ORTE collective communication services. I -strongly- urge the MPI team to implement advanced collective algorithms to improve the performance of this critical procedure.
2. reducing the volume of data exchanged during modex. Data in the modex consisted of the process name, the name of the node where that process is located (expressed as a string), plus a string representation of all contact info. The nodename was required in order for the modex to determine if the process was local or not - in addition, some people like to have it to print pretty error messages when a connection failed.
The size of this data has been reduced in three ways:
(a) reducing the size of the process name itself. The process name consisted of two 32-bit fields for the jobid and vpid. This is far larger than any current system, or system likely to exist in the near future, can support. Accordingly, the default size of these fields has been reduced to 16-bits, which means you can have 32k procs in each of 32k jobs. Since the daemons must have a vpid, and we require one daemon/node, this also restricts the default configuration to 32k nodes.
To support any future "mega-clusters", a configuration option --enable-jumbo-apps has been added. This option increases the jobid and vpid field sizes to 32-bits. Someday, if necessary, someone can add yet another option to increase them to 64-bits, I suppose.
(b) replacing the string nodename with an integer nodeid. Since we have one daemon/node, the nodeid corresponds to the local daemon's vpid. This replaces an often lengthy string with only 2 (or at most 4) bytes, a substantial reduction.
(c) when the mca param requesting that nodenames be sent to support pretty error messages, a second mca param is now used to request FQDN - otherwise, the domain name is stripped (by default) from the message to save space. If someone wants to combine those into a single param somehow (perhaps with an argument?), they are welcome to do so - I didn't want to alter what people are already using.
While these may seem like small savings, they actually amount to a significant impact when aggregated across the entire modex operation. Since every proc must receive the modex data regardless of the collective used to send it, just reducing the size of the process name removes nearly 400MBytes of communication from a 32k proc job (admittedly, much of this comm may occur in parallel). So it does add up pretty quickly.
3. routing RML messages to reduce connections. The default messaging system remains point-to-point - i.e., each proc opens a socket to every proc it communicates with and sends its messages directly. A new option uses the orteds as routers - i.e., each proc only opens a single socket to its local orted. All messages are sent from the proc to the orted, which forwards the message to the orted on the node where the intended recipient proc is located - that orted then forwards the message to its local proc (the recipient). This greatly reduces the connection storm we have encountered during startup.
It also has the benefit of removing the sharing of every proc's OOB contact with every other proc. The orted routing tables are populated during launch since every orted gets a map of where every proc is being placed. Each proc, therefore, only needs to know the contact info for its local daemon, which is passed in via the environment when the proc is fork/exec'd by the daemon. This alone removes ~50 bytes/process of communication that was in the current STG1 startup message - so for our 32k proc job, this saves us roughly 32k*50 = 1.6MBytes sent to 32k procs = 51GBytes of messaging.
Note that you can use the new routing method by specifying -mca routed tree - if you so desire. This mode will become the default at some point in the future.
There are a few minor additional changes in the commit that I'll just note in passing:
* propagation of command line mca params to the orteds - fixes ticket #1073. See note there for details.
* requiring of "finalize" prior to "exit" for MPI procs - fixes ticket #1144. See note there for details.
* cleanup of some stale header files
This commit was SVN r16364.
2007-10-05 23:48:23 +04:00
|
|
|
return rc;
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = opal_dss.unpack(buf, &new_arch, &count, OPAL_UINT32);
|
2011-10-04 18:50:31 +04:00
|
|
|
if (rc != OPAL_SUCCESS) {
|
2012-06-27 05:28:28 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
2008-08-12 00:46:27 +04:00
|
|
|
free(plist);
|
|
|
|
free(newprocs);
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
return rc;
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = opal_dss.unpack(buf, &new_hostname, &count, OPAL_STRING);
|
2011-10-04 18:50:31 +04:00
|
|
|
if (rc != OPAL_SUCCESS) {
|
2012-06-27 05:28:28 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
2008-08-12 00:46:27 +04:00
|
|
|
free(plist);
|
|
|
|
free(newprocs);
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
return rc;
|
|
|
|
}
|
2008-04-30 23:49:53 +04:00
|
|
|
|
2008-07-08 07:56:51 +04:00
|
|
|
/* see if this proc is already on our ompi_proc_list */
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
plist[i] = ompi_proc_find_and_add(&new_name, &isnew);
|
|
|
|
if (isnew) {
|
2008-07-08 07:56:51 +04:00
|
|
|
/* if not, then it was added, so update the values
|
|
|
|
* in the proc_t struct with the info that was passed
|
|
|
|
* to us
|
|
|
|
*/
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
newprocs[newprocs_len++] = plist[i];
|
2008-04-30 23:49:53 +04:00
|
|
|
|
Repair the MPI-2 dynamic operations. This includes:
1. repair of the linear and direct routed modules
2. repair of the ompi/pubsub/orte module to correctly init routes to the ompi-server, and correctly handle failure to correctly parse the provided ompi-server URI
3. modification of orterun to accept both "file" and "FILE" for designating where the ompi-server URI is to be found - purely a convenience feature
4. resolution of a message ordering problem during the connect/accept handshake that allowed the "send-first" proc to attempt to send to the "recv-first" proc before the HNP had actually updated its routes.
Let this be a further reminder to all - message ordering is NOT guaranteed in the OOB
5. Repair the ompi/dpm/orte module to correctly init routes during connect/accept.
Reminder to all: messages sent to procs in another job family (i.e., started by a different mpirun) are ALWAYS routed through the respective HNPs. As per the comments in orte/routed, this is REQUIRED to maintain connect/accept (where only the root proc on each side is capable of init'ing the routes), allow communication between mpirun's using different routing modules, and to minimize connections on tools such as ompi-server. It is all taken care of "under the covers" by the OOB to ensure that a route back to the sender is maintained, even when the different mpirun's are using different routed modules.
6. corrections in the orte/odls to ensure proper identification of daemons participating in a dynamic launch
7. corrections in build/nidmap to support update of an existing nidmap during dynamic launch
8. corrected implementation of the update_arch function in the ESS, along with consolidation of a number of ESS operations into base functions for easier maintenance. The ability to support info from multiple jobs was added, although we don't currently do so - this will come later to support further fault recovery strategies
9. minor updates to several functions to remove unnecessary and/or no longer used variables and envar's, add some debugging output, etc.
10. addition of a new macro ORTE_PROC_IS_DAEMON that resolves to true if the provided proc is a daemon
There is still more cleanup to be done for efficiency, but this at least works.
Tested on single-node Mac, multi-node SLURM via odin. Tests included connect/accept, publish/lookup/unpublish, comm_spawn, comm_spawn_multiple, and singleton comm_spawn.
Fixes ticket #1256
This commit was SVN r18804.
2008-07-03 21:53:37 +04:00
|
|
|
/* update all the values */
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
plist[i]->proc_arch = new_arch;
|
|
|
|
/* if arch is different than mine, create a new convertor for this proc */
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
if (plist[i]->proc_arch != opal_local_arch) {
|
2009-05-07 00:11:28 +04:00
|
|
|
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
OBJ_RELEASE(plist[i]->proc_convertor);
|
- Split the datatype engine into two parts: an MPI specific part in
OMPI
and a language agnostic part in OPAL. The convertor is completely
moved into OPAL. This offers several benefits as described in RFC
http://www.open-mpi.org/community/lists/devel/2009/07/6387.php
namely:
- Fewer basic types (int* and float* types, boolean and wchar
- Fixing naming scheme to ompi-nomenclature.
- Usability outside of the ompi-layer.
- Due to the fixed nature of simple opal types, their information is
completely
known at compile time and therefore constified
- With fewer datatypes (22), the actual sizes of bit-field types may be
reduced
from 64 to 32 bits, allowing reorganizing the opal_datatype
structure, eliminating holes and keeping data required in convertor
(upon send/recv) in one cacheline...
This has implications to the convertor-datastructure and other parts
of the code.
- Several performance tests have been run, the netpipe latency does not
change with
this patch on Linux/x86-64 on the smoky cluster.
- Extensive tests have been done to verify correctness (no new
regressions) using:
1. mpi_test_suite on linux/x86-64 using clean ompi-trunk and
ompi-ddt:
a. running both trunk and ompi-ddt resulted in no differences
(except for MPI_SHORT_INT and MPI_TYPE_MIX_LB_UB do now run
correctly).
b. with --enable-memchecker and running under valgrind (one buglet
when run with static found in test-suite, commited)
2. ibm testsuite on linux/x86-64 using clean ompi-trunk and ompi-ddt:
all passed (except for the dynamic/ tests failed!! as trunk/MTT)
3. compilation and usage of HDF5 tests on Jaguar using PGI and
PathScale compilers.
4. compilation and usage on Scicortex.
- Please note, that for the heterogeneous case, (-m32 compiled
binaries/ompi), neither
ompi-trunk, nor ompi-ddt branch would successfully launch.
This commit was SVN r21641.
2009-07-13 08:56:31 +04:00
|
|
|
plist[i]->proc_convertor = opal_convertor_create(plist[i]->proc_arch, 0);
|
2006-12-30 20:13:18 +03:00
|
|
|
#else
|
2012-06-27 05:28:28 +04:00
|
|
|
orte_show_help("help-mpi-runtime",
|
2006-12-30 20:13:18 +03:00
|
|
|
"heterogeneous-support-unavailable",
|
2012-06-27 05:28:28 +04:00
|
|
|
true, orte_process_info.nodename,
|
2006-12-30 20:13:18 +03:00
|
|
|
new_hostname == NULL ? "<hostname unavailable>" :
|
2008-04-30 23:49:53 +04:00
|
|
|
new_hostname);
|
2008-08-12 00:46:27 +04:00
|
|
|
free(plist);
|
|
|
|
free(newprocs);
|
2006-12-30 20:13:18 +03:00
|
|
|
return OMPI_ERR_NOT_SUPPORTED;
|
|
|
|
#endif
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
}
|
2008-04-30 23:49:53 +04:00
|
|
|
if (0 == strcmp(ompi_proc_local_proc->proc_hostname,new_hostname)) {
|
Per the RFC, extend the current use of the ompi_proc_t flags field (without changing the field itself).
The prior ompi_proc_t structure had a uint8_t flag field in it, where only one
bit was used to flag that a proc was "local". In that context, "local" was
constrained to mean "local to this node".
This commit provides a greater degree of granularity on the term "local", to include tests
to see if the proc is on the same socket, PC board, node, switch, CU (computing
unit), and cluster.
Add #define's to designate which bits stand for which local condition. This
was added to the OPAL layer to avoid conflicting with the proposed movement of
the BTLs. To make it easier to use, a set of macros have been defined - e.g.,
OPAL_PROC_ON_LOCAL_SOCKET - that test the specific bit. These can be used in
the code base to clearly indicate which sense of locality is being considered.
All locations in the code base that looked at the current proc_t field have
been changed to use the new macros.
Also modify the orte_ess modules so that each returns a uint8_t (to match the
ompi_proc_t field) that contains a complete description of the locality of this
proc. Obviously, not all environments will be capable of providing such detailed
info. Thus, getting a "false" from a test for "on_local_socket" may simply
indicate a lack of knowledge.
This commit was SVN r20496.
2009-02-10 05:20:16 +03:00
|
|
|
plist[i]->proc_flags |= (OPAL_PROC_ON_NODE | OPAL_PROC_ON_CU | OPAL_PROC_ON_CLUSTER);
|
These changes were mostly captured in a prior RFC (except for #2 below) and are aimed specifically at improving startup performance and setting up the remaining modifications described in that RFC.
The commit has been tested for C/R and Cray operations, and on Odin (SLURM, rsh) and RoadRunner (TM). I tried to update all environments, but obviously could not test them. I know that Windows needs some work, and have highlighted what is know to be needed in the odls process component.
This represents a lot of work by Brian, Tim P, Josh, and myself, with much advice from Jeff and others. For posterity, I have appended a copy of the email describing the work that was done:
As we have repeatedly noted, the modex operation in MPI_Init is the single greatest consumer of time during startup. To-date, we have executed that operation as an ORTE stage gate that held the process until a startup message containing all required modex (and OOB contact info - see #3 below) info could be sent to it. Each process would send its data to the HNP's registry, which assembled and sent the message when all processes had reported in.
In addition, ORTE had taken responsibility for monitoring process status as it progressed through a series of "stage gates". The process reported its status at each gate, and ORTE would then send a "release" message once all procs had reported in.
The incoming changes revamp these procedures in three ways:
1. eliminating the ORTE stage gate system and cleanly delineating responsibility between the OMPI and ORTE layers for MPI init/finalize. The modex stage gate (STG1) has been replaced by a collective operation in the modex itself that performs an allgather on the required modex info. The allgather is implemented using the orte_grpcomm framework since the BTL's are not active at that point. At the moment, the grpcomm framework only has a "basic" component analogous to OMPI's "basic" coll framework - I would recommend that the MPI team create additional, more advanced components to improve performance of this step.
The other stage gates have been replaced by orte_grpcomm barrier functions. We tried to use MPI barriers instead (since the BTL's are active at that point), but - as we discussed on the telecon - these are not currently true barriers so the job would hang when we fell through while messages were still in process. Note that the grpcomm barrier doesn't actually resolve that problem, but Brian has pointed out that we are unlikely to ever see it violated. Again, you might want to spend a little time on an advanced barrier algorithm as the one in "basic" is very simplistic.
Summarizing this change: ORTE no longer tracks process state nor has direct responsibility for synchronizing jobs. This is now done via collective operations within the MPI layer, albeit using ORTE collective communication services. I -strongly- urge the MPI team to implement advanced collective algorithms to improve the performance of this critical procedure.
2. reducing the volume of data exchanged during modex. Data in the modex consisted of the process name, the name of the node where that process is located (expressed as a string), plus a string representation of all contact info. The nodename was required in order for the modex to determine if the process was local or not - in addition, some people like to have it to print pretty error messages when a connection failed.
The size of this data has been reduced in three ways:
(a) reducing the size of the process name itself. The process name consisted of two 32-bit fields for the jobid and vpid. This is far larger than any current system, or system likely to exist in the near future, can support. Accordingly, the default size of these fields has been reduced to 16-bits, which means you can have 32k procs in each of 32k jobs. Since the daemons must have a vpid, and we require one daemon/node, this also restricts the default configuration to 32k nodes.
To support any future "mega-clusters", a configuration option --enable-jumbo-apps has been added. This option increases the jobid and vpid field sizes to 32-bits. Someday, if necessary, someone can add yet another option to increase them to 64-bits, I suppose.
(b) replacing the string nodename with an integer nodeid. Since we have one daemon/node, the nodeid corresponds to the local daemon's vpid. This replaces an often lengthy string with only 2 (or at most 4) bytes, a substantial reduction.
(c) when the mca param requesting that nodenames be sent to support pretty error messages, a second mca param is now used to request FQDN - otherwise, the domain name is stripped (by default) from the message to save space. If someone wants to combine those into a single param somehow (perhaps with an argument?), they are welcome to do so - I didn't want to alter what people are already using.
While these may seem like small savings, they actually amount to a significant impact when aggregated across the entire modex operation. Since every proc must receive the modex data regardless of the collective used to send it, just reducing the size of the process name removes nearly 400MBytes of communication from a 32k proc job (admittedly, much of this comm may occur in parallel). So it does add up pretty quickly.
3. routing RML messages to reduce connections. The default messaging system remains point-to-point - i.e., each proc opens a socket to every proc it communicates with and sends its messages directly. A new option uses the orteds as routers - i.e., each proc only opens a single socket to its local orted. All messages are sent from the proc to the orted, which forwards the message to the orted on the node where the intended recipient proc is located - that orted then forwards the message to its local proc (the recipient). This greatly reduces the connection storm we have encountered during startup.
It also has the benefit of removing the sharing of every proc's OOB contact with every other proc. The orted routing tables are populated during launch since every orted gets a map of where every proc is being placed. Each proc, therefore, only needs to know the contact info for its local daemon, which is passed in via the environment when the proc is fork/exec'd by the daemon. This alone removes ~50 bytes/process of communication that was in the current STG1 startup message - so for our 32k proc job, this saves us roughly 32k*50 = 1.6MBytes sent to 32k procs = 51GBytes of messaging.
Note that you can use the new routing method by specifying -mca routed tree - if you so desire. This mode will become the default at some point in the future.
There are a few minor additional changes in the commit that I'll just note in passing:
* propagation of command line mca params to the orteds - fixes ticket #1073. See note there for details.
* requiring of "finalize" prior to "exit" for MPI procs - fixes ticket #1144. See note there for details.
* cleanup of some stale header files
This commit was SVN r16364.
2007-10-05 23:48:23 +04:00
|
|
|
}
|
2008-04-30 23:49:53 +04:00
|
|
|
|
Clean up the way procs are added to the global process list after MPI_INIT:
* Do not add new procs to the global list during modex callback or
when sharing orte names during accept/connect. For modex, we
cache the modex info for later, in case that proc ever does get
added to the global proc list. For accept/connect orte name
exchange between the roots, we only need the orte name, so no
need to add a proc structure anyway. The procs will be added
to the global process list during the proc exchange later in
the wireup process
* Rename proc_get_namebuf and proc_get_proclist to proc_pack
and proc_unpack and extend them to include all information
needed to build that proc struct on a remote node (which
includes ORTE name, architecture, and hostname). Change
unpack to call pml_add_procs for the entire list of new
procs at once, rather than one at a time.
* Remove ompi_proc_find_and_add from the public proc
interface and make it a private function. This function
would add a half-created proc to the global proc list, so
making it harder to call is a good thing.
This means that there's only two ways to add new procs into the global proc list at this time: During MPI_INIT via the call to ompi_proc_init, where my job is added to the list and via ompi_proc_unpack using a buffer from a packed proc list sent to us by someone else. Currently, this is enough to implement MPI semantics. We can extend the interface more if we like, but that may require HNP communication to get the remote proc information and I wanted to avoid that if at all possible.
Refs trac:564
This commit was SVN r12798.
The following Trac tickets were found above:
Ticket 564 --> https://svn.open-mpi.org/trac/ompi/ticket/564
2006-12-07 22:56:54 +03:00
|
|
|
/* Save the hostname */
|
These changes were mostly captured in a prior RFC (except for #2 below) and are aimed specifically at improving startup performance and setting up the remaining modifications described in that RFC.
The commit has been tested for C/R and Cray operations, and on Odin (SLURM, rsh) and RoadRunner (TM). I tried to update all environments, but obviously could not test them. I know that Windows needs some work, and have highlighted what is know to be needed in the odls process component.
This represents a lot of work by Brian, Tim P, Josh, and myself, with much advice from Jeff and others. For posterity, I have appended a copy of the email describing the work that was done:
As we have repeatedly noted, the modex operation in MPI_Init is the single greatest consumer of time during startup. To-date, we have executed that operation as an ORTE stage gate that held the process until a startup message containing all required modex (and OOB contact info - see #3 below) info could be sent to it. Each process would send its data to the HNP's registry, which assembled and sent the message when all processes had reported in.
In addition, ORTE had taken responsibility for monitoring process status as it progressed through a series of "stage gates". The process reported its status at each gate, and ORTE would then send a "release" message once all procs had reported in.
The incoming changes revamp these procedures in three ways:
1. eliminating the ORTE stage gate system and cleanly delineating responsibility between the OMPI and ORTE layers for MPI init/finalize. The modex stage gate (STG1) has been replaced by a collective operation in the modex itself that performs an allgather on the required modex info. The allgather is implemented using the orte_grpcomm framework since the BTL's are not active at that point. At the moment, the grpcomm framework only has a "basic" component analogous to OMPI's "basic" coll framework - I would recommend that the MPI team create additional, more advanced components to improve performance of this step.
The other stage gates have been replaced by orte_grpcomm barrier functions. We tried to use MPI barriers instead (since the BTL's are active at that point), but - as we discussed on the telecon - these are not currently true barriers so the job would hang when we fell through while messages were still in process. Note that the grpcomm barrier doesn't actually resolve that problem, but Brian has pointed out that we are unlikely to ever see it violated. Again, you might want to spend a little time on an advanced barrier algorithm as the one in "basic" is very simplistic.
Summarizing this change: ORTE no longer tracks process state nor has direct responsibility for synchronizing jobs. This is now done via collective operations within the MPI layer, albeit using ORTE collective communication services. I -strongly- urge the MPI team to implement advanced collective algorithms to improve the performance of this critical procedure.
2. reducing the volume of data exchanged during modex. Data in the modex consisted of the process name, the name of the node where that process is located (expressed as a string), plus a string representation of all contact info. The nodename was required in order for the modex to determine if the process was local or not - in addition, some people like to have it to print pretty error messages when a connection failed.
The size of this data has been reduced in three ways:
(a) reducing the size of the process name itself. The process name consisted of two 32-bit fields for the jobid and vpid. This is far larger than any current system, or system likely to exist in the near future, can support. Accordingly, the default size of these fields has been reduced to 16-bits, which means you can have 32k procs in each of 32k jobs. Since the daemons must have a vpid, and we require one daemon/node, this also restricts the default configuration to 32k nodes.
To support any future "mega-clusters", a configuration option --enable-jumbo-apps has been added. This option increases the jobid and vpid field sizes to 32-bits. Someday, if necessary, someone can add yet another option to increase them to 64-bits, I suppose.
(b) replacing the string nodename with an integer nodeid. Since we have one daemon/node, the nodeid corresponds to the local daemon's vpid. This replaces an often lengthy string with only 2 (or at most 4) bytes, a substantial reduction.
(c) when the mca param requesting that nodenames be sent to support pretty error messages, a second mca param is now used to request FQDN - otherwise, the domain name is stripped (by default) from the message to save space. If someone wants to combine those into a single param somehow (perhaps with an argument?), they are welcome to do so - I didn't want to alter what people are already using.
While these may seem like small savings, they actually amount to a significant impact when aggregated across the entire modex operation. Since every proc must receive the modex data regardless of the collective used to send it, just reducing the size of the process name removes nearly 400MBytes of communication from a 32k proc job (admittedly, much of this comm may occur in parallel). So it does add up pretty quickly.
3. routing RML messages to reduce connections. The default messaging system remains point-to-point - i.e., each proc opens a socket to every proc it communicates with and sends its messages directly. A new option uses the orteds as routers - i.e., each proc only opens a single socket to its local orted. All messages are sent from the proc to the orted, which forwards the message to the orted on the node where the intended recipient proc is located - that orted then forwards the message to its local proc (the recipient). This greatly reduces the connection storm we have encountered during startup.
It also has the benefit of removing the sharing of every proc's OOB contact with every other proc. The orted routing tables are populated during launch since every orted gets a map of where every proc is being placed. Each proc, therefore, only needs to know the contact info for its local daemon, which is passed in via the environment when the proc is fork/exec'd by the daemon. This alone removes ~50 bytes/process of communication that was in the current STG1 startup message - so for our 32k proc job, this saves us roughly 32k*50 = 1.6MBytes sent to 32k procs = 51GBytes of messaging.
Note that you can use the new routing method by specifying -mca routed tree - if you so desire. This mode will become the default at some point in the future.
There are a few minor additional changes in the commit that I'll just note in passing:
* propagation of command line mca params to the orteds - fixes ticket #1073. See note there for details.
* requiring of "finalize" prior to "exit" for MPI procs - fixes ticket #1144. See note there for details.
* cleanup of some stale header files
This commit was SVN r16364.
2007-10-05 23:48:23 +04:00
|
|
|
plist[i]->proc_hostname = new_hostname;
|
2008-07-08 07:56:51 +04:00
|
|
|
|
2012-06-27 05:28:28 +04:00
|
|
|
/* eventually, we will update the orte/mca/ess framework's data
|
2008-07-08 07:56:51 +04:00
|
|
|
* to contain the info for the new proc. For now, we ignore
|
|
|
|
* this step since the MPI layer already has all the info
|
|
|
|
* it requires
|
|
|
|
*/
|
2004-10-25 23:52:37 +04:00
|
|
|
}
|
2004-08-04 21:05:22 +04:00
|
|
|
}
|
2008-04-30 23:49:53 +04:00
|
|
|
|
These changes were mostly captured in a prior RFC (except for #2 below) and are aimed specifically at improving startup performance and setting up the remaining modifications described in that RFC.
The commit has been tested for C/R and Cray operations, and on Odin (SLURM, rsh) and RoadRunner (TM). I tried to update all environments, but obviously could not test them. I know that Windows needs some work, and have highlighted what is know to be needed in the odls process component.
This represents a lot of work by Brian, Tim P, Josh, and myself, with much advice from Jeff and others. For posterity, I have appended a copy of the email describing the work that was done:
As we have repeatedly noted, the modex operation in MPI_Init is the single greatest consumer of time during startup. To-date, we have executed that operation as an ORTE stage gate that held the process until a startup message containing all required modex (and OOB contact info - see #3 below) info could be sent to it. Each process would send its data to the HNP's registry, which assembled and sent the message when all processes had reported in.
In addition, ORTE had taken responsibility for monitoring process status as it progressed through a series of "stage gates". The process reported its status at each gate, and ORTE would then send a "release" message once all procs had reported in.
The incoming changes revamp these procedures in three ways:
1. eliminating the ORTE stage gate system and cleanly delineating responsibility between the OMPI and ORTE layers for MPI init/finalize. The modex stage gate (STG1) has been replaced by a collective operation in the modex itself that performs an allgather on the required modex info. The allgather is implemented using the orte_grpcomm framework since the BTL's are not active at that point. At the moment, the grpcomm framework only has a "basic" component analogous to OMPI's "basic" coll framework - I would recommend that the MPI team create additional, more advanced components to improve performance of this step.
The other stage gates have been replaced by orte_grpcomm barrier functions. We tried to use MPI barriers instead (since the BTL's are active at that point), but - as we discussed on the telecon - these are not currently true barriers so the job would hang when we fell through while messages were still in process. Note that the grpcomm barrier doesn't actually resolve that problem, but Brian has pointed out that we are unlikely to ever see it violated. Again, you might want to spend a little time on an advanced barrier algorithm as the one in "basic" is very simplistic.
Summarizing this change: ORTE no longer tracks process state nor has direct responsibility for synchronizing jobs. This is now done via collective operations within the MPI layer, albeit using ORTE collective communication services. I -strongly- urge the MPI team to implement advanced collective algorithms to improve the performance of this critical procedure.
2. reducing the volume of data exchanged during modex. Data in the modex consisted of the process name, the name of the node where that process is located (expressed as a string), plus a string representation of all contact info. The nodename was required in order for the modex to determine if the process was local or not - in addition, some people like to have it to print pretty error messages when a connection failed.
The size of this data has been reduced in three ways:
(a) reducing the size of the process name itself. The process name consisted of two 32-bit fields for the jobid and vpid. This is far larger than any current system, or system likely to exist in the near future, can support. Accordingly, the default size of these fields has been reduced to 16-bits, which means you can have 32k procs in each of 32k jobs. Since the daemons must have a vpid, and we require one daemon/node, this also restricts the default configuration to 32k nodes.
To support any future "mega-clusters", a configuration option --enable-jumbo-apps has been added. This option increases the jobid and vpid field sizes to 32-bits. Someday, if necessary, someone can add yet another option to increase them to 64-bits, I suppose.
(b) replacing the string nodename with an integer nodeid. Since we have one daemon/node, the nodeid corresponds to the local daemon's vpid. This replaces an often lengthy string with only 2 (or at most 4) bytes, a substantial reduction.
(c) when the mca param requesting that nodenames be sent to support pretty error messages, a second mca param is now used to request FQDN - otherwise, the domain name is stripped (by default) from the message to save space. If someone wants to combine those into a single param somehow (perhaps with an argument?), they are welcome to do so - I didn't want to alter what people are already using.
While these may seem like small savings, they actually amount to a significant impact when aggregated across the entire modex operation. Since every proc must receive the modex data regardless of the collective used to send it, just reducing the size of the process name removes nearly 400MBytes of communication from a 32k proc job (admittedly, much of this comm may occur in parallel). So it does add up pretty quickly.
3. routing RML messages to reduce connections. The default messaging system remains point-to-point - i.e., each proc opens a socket to every proc it communicates with and sends its messages directly. A new option uses the orteds as routers - i.e., each proc only opens a single socket to its local orted. All messages are sent from the proc to the orted, which forwards the message to the orted on the node where the intended recipient proc is located - that orted then forwards the message to its local proc (the recipient). This greatly reduces the connection storm we have encountered during startup.
It also has the benefit of removing the sharing of every proc's OOB contact with every other proc. The orted routing tables are populated during launch since every orted gets a map of where every proc is being placed. Each proc, therefore, only needs to know the contact info for its local daemon, which is passed in via the environment when the proc is fork/exec'd by the daemon. This alone removes ~50 bytes/process of communication that was in the current STG1 startup message - so for our 32k proc job, this saves us roughly 32k*50 = 1.6MBytes sent to 32k procs = 51GBytes of messaging.
Note that you can use the new routing method by specifying -mca routed tree - if you so desire. This mode will become the default at some point in the future.
There are a few minor additional changes in the commit that I'll just note in passing:
* propagation of command line mca params to the orteds - fixes ticket #1073. See note there for details.
* requiring of "finalize" prior to "exit" for MPI procs - fixes ticket #1144. See note there for details.
* cleanup of some stale header files
This commit was SVN r16364.
2007-10-05 23:48:23 +04:00
|
|
|
if (NULL != newproclistsize) *newproclistsize = newprocs_len;
|
|
|
|
if (NULL != newproclist) {
|
|
|
|
*newproclist = newprocs;
|
|
|
|
} else if (newprocs != NULL) {
|
|
|
|
free(newprocs);
|
|
|
|
}
|
2008-04-30 23:49:53 +04:00
|
|
|
|
2004-08-04 21:05:22 +04:00
|
|
|
*proclist = plist;
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|