1
1

Merge pull request #6953 from rhc54/topic/pmix4

Update to current PMIx 4.0.0 (master)
Этот коммит содержится в:
Ralph Castain 2019-09-03 19:47:58 -07:00 коммит произвёл GitHub
родитель f1a065f4dc 9a2902c047
Коммит 73c5fe8f05
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
61 изменённых файлов: 1733 добавлений и 1126 удалений

Просмотреть файл

@ -30,7 +30,7 @@ greek=
# command, or with the date (if "git describe" fails) in the form of
# "date<date>".
repo_rev=git7e40284d
repo_rev=gitf87459fe
# If tarball_version is not empty, it is used as the version string in
# the tarball filename, regardless of all other versions listed in
@ -44,7 +44,7 @@ tarball_version=
# The date when this release was created
date="Jul 26, 2019"
date="Sep 03, 2019"
# The shared library version of each of PMIx's public libraries.
# These versions are maintained in accordance with the "Library

Просмотреть файл

@ -21,7 +21,7 @@
# $HEADER$
#
helpers = setup.py pmix.pyx
helpers = setup.py pmix.pyx pmix.pxi construct.py
if WANT_PYTHON_BINDINGS

Просмотреть файл

@ -1,33 +0,0 @@
@PMIX_PYTHON_PATH@
from pmix import *
def main():
foo = PMIxClient()
print("Testing PMIx ", foo.get_version())
info = {PMIX_PROGRAMMING_MODEL: ('TEST', PMIX_STRING), PMIX_MODEL_LIBRARY_NAME: ("PMIX", PMIX_STRING)}
my_result = foo.init(info)
print("Init result ", my_result)
if 0 != my_result:
print("FAILED TO INIT")
exit(1)
# try putting something
print("PUT")
rc = foo.put(PMIX_GLOBAL, "mykey", (1, PMIX_INT32))
print("Put result ", rc);
# commit it
print("COMMIT")
rc = foo.commit()
print ("Commit result ", rc)
# execute fence
print("FENCE")
procs = []
info = {}
rc = foo.fence(procs, info)
print("Fence result ", rc)
# finalize
info = {}
foo.finalize(info)
print("Client finalize complete")
if __name__ == '__main__':
main()

Просмотреть файл

@ -1,137 +0,0 @@
@PMIX_PYTHON_PATH@
from pmix import *
import signal, time
import os
import select
import subprocess
global killer
class GracefulKiller:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)
def exit_gracefully(self,signum, frame):
self.kill_now = True
def clientconnected(proc:tuple is not None):
print("CLIENT CONNECTED", proc)
return PMIX_SUCCESS
def clientfinalized(proc:tuple is not None):
print("CLIENT FINALIZED", proc)
return PMIX_SUCCESS
def clientfence(args:dict is not None):
print("SERVER FENCE", args)
return PMIX_SUCCESS
def main():
try:
foo = PMIxServer()
except:
print("FAILED TO CREATE SERVER")
exit(1)
print("Testing server version ", foo.get_version())
args = {PMIX_SERVER_SCHEDULER: ('T', PMIX_BOOL)}
map = {'clientconnected': clientconnected,
'clientfinalized': clientfinalized,
'fencenb': clientfence}
my_result = foo.init(args, map)
print("Testing PMIx_Initialized")
rc = foo.initialized()
print("Initialized: ", rc)
vers = foo.get_version()
print("Version: ", vers)
# Register a fabric
rc = foo.register_fabric(None)
print("Fabric registered: ", rc)
# Get the number of vertices in this fabric
nverts = foo.get_num_vertices()
print("Nverts in fabric: ", nverts)
# setup the application
(rc, regex) = foo.generate_regex("test000,test001,test002")
print("Node regex: ", regex)
(rc, ppn) = foo.generate_ppn("0,1,2;3,4,5;6,7")
print("PPN: ", ppn)
darray = (PMIX_INFO, [{PMIX_ALLOC_NETWORK_ID: ("SIMPSCHED.net", PMIX_STRING)},
{PMIX_ALLOC_NETWORK_SEC_KEY: ('T', PMIX_BOOL)},
{PMIX_SETUP_APP_ENVARS: ('T', PMIX_BOOL)}])
kyvals = {PMIX_NODE_MAP: (regex, PMIX_STRING), PMIX_PROC_MAP: (ppn, PMIX_STRING), PMIX_ALLOC_NETWORK: (darray, PMIX_DATA_ARRAY)}
appinfo = []
rc, appinfo = foo.setup_application("SIMPSCHED", kyvals)
print("SETUPAPP: ", appinfo)
rc = foo.setup_local_support("SIMPSCHED", appinfo)
print("SETUPLOCAL: ", rc)
# get our environment as a base
env = os.environ.copy()
# register an nspace for the client app
kvals = {PMIX_NODE_MAP: (regex, PMIX_STRING), PMIX_PROC_MAP: (ppn, PMIX_STRING), PMIX_UNIV_SIZE: (1, PMIX_UINT32), PMIX_JOB_SIZE: (1, PMIX_UINT32)}
print("REGISTERING NSPACE")
rc = foo.register_nspace("testnspace", 1, kvals)
print("RegNspace ", rc)
# register a client
uid = os.getuid()
gid = os.getgid()
print("REGISTERING CLIENT")
rc = foo.register_client(("testnspace", 0), uid, gid)
print("RegClient ", rc)
# setup the fork
rc = foo.setup_fork(("testnspace", 0), env)
print("SetupFrk", rc)
# setup the client argv
args = ["./client.py"]
# open a subprocess with stdout and stderr
# as distinct pipes so we can capture their
# output as the process runs
p = subprocess.Popen(args, env=env,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# define storage to catch the output
stdout = []
stderr = []
# loop until the pipes close
while True:
reads = [p.stdout.fileno(), p.stderr.fileno()]
ret = select.select(reads, [], [])
stdout_done = True
stderr_done = True
for fd in ret[0]:
# if the data
if fd == p.stdout.fileno():
read = p.stdout.readline()
if read:
read = read.decode('utf-8').rstrip()
print('stdout: ' + read)
stdout_done = False
elif fd == p.stderr.fileno():
read = p.stderr.readline()
if read:
read = read.decode('utf-8').rstrip()
print('stderr: ' + read)
stderr_done = False
if stdout_done and stderr_done:
break
print("FINALIZING")
foo.finalize()
if __name__ == '__main__':
global killer
killer = GracefulKiller()
main()

Просмотреть файл

@ -1,107 +0,0 @@
@PMIX_PYTHON_PATH@
from pmix import *
import signal, time
import os
import select
import subprocess
global killer
class GracefulKiller:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)
def exit_gracefully(self,signum, frame):
self.kill_now = True
def clientconnected(proc:tuple is not None):
print("CLIENT CONNECTED", proc)
return PMIX_SUCCESS
def clientfinalized(proc:tuple is not None):
print("CLIENT FINALIZED", proc)
return PMIX_SUCCESS
def clientfence(args:dict is not None):
print("SERVER FENCE", args)
return PMIX_SUCCESS
def main():
try:
foo = PMIxServer()
except:
print("FAILED TO CREATE SERVER")
exit(1)
print("Testing server version ", foo.get_version())
args = {'FOOBAR': ('VAR', PMIX_STRING), 'BLAST': (7, PMIX_INT32)}
map = {'clientconnected': clientconnected,
'clientfinalized': clientfinalized,
'fencenb': clientfence}
my_result = foo.init(args, map)
print("Testing PMIx_Initialized")
rc = foo.initialized()
print("Initialized: ", rc)
vers = foo.get_version()
print("Version: ", vers)
# get our environment as a base
env = os.environ.copy()
# register an nspace for the client app
darray = (PMIX_SIZE, [1, 2, 3, 4, 5])
kvals = {'testkey': (darray, PMIX_DATA_ARRAY)}
print("REGISTERING NSPACE")
rc = foo.register_nspace("testnspace", 1, kvals)
print("RegNspace ", rc)
# register a client
uid = os.getuid()
gid = os.getgid()
rc = foo.register_client(("testnspace", 0), uid, gid)
print("RegClient ", rc)
# setup the fork
rc = foo.setup_fork(("testnspace", 0), env)
print("SetupFrk", rc)
# setup the client argv
args = ["./client.py"]
# open a subprocess with stdout and stderr
# as distinct pipes so we can capture their
# output as the process runs
p = subprocess.Popen(args, env=env,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# define storage to catch the output
stdout = []
stderr = []
# loop until the pipes close
while True:
reads = [p.stdout.fileno(), p.stderr.fileno()]
ret = select.select(reads, [], [])
stdout_done = True
stderr_done = True
for fd in ret[0]:
# if the data
if fd == p.stdout.fileno():
read = p.stdout.readline()
if read:
read = read.decode('utf-8').rstrip()
print('stdout: ' + read)
stdout_done = False
elif fd == p.stderr.fileno():
read = p.stderr.readline()
if read:
read = read.decode('utf-8').rstrip()
print('stderr: ' + read)
stderr_done = False
if stdout_done and stderr_done:
break
print("FINALIZING")
foo.finalize()
if __name__ == '__main__':
global killer
killer = GracefulKiller()
main()

Просмотреть файл

@ -11,9 +11,9 @@ dnl University of Stuttgart. All rights reserved.
dnl Copyright (c) 2004-2005 The Regents of the University of California.
dnl All rights reserved.
dnl Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
dnl Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
dnl Copyright (c) 2015 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl Copyright (c) 2014-2019 Intel, Inc. All rights reserved.
dnl Copyright (c) 2015-2019 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
@ -44,7 +44,9 @@ AC_DEFUN([PMIX_C_GET_ALIGNMENT],[
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);
diff = ((char *)&p->x) - ((char *)&p->c);
free(p);
fprintf(f, "%d\n", (diff >= 0) ? diff : -diff);
fclose(f);
]])], [AS_TR_SH([pmix_cv_c_align_$1])=`cat conftestval`],
[AC_MSG_WARN([*** Problem running configure test!])
AC_MSG_WARN([*** See config.log for details.])

Просмотреть файл

@ -885,6 +885,10 @@ AC_DEFUN([PMIX_SETUP_CORE],[
AC_CONFIG_FILES(pmix_config_prefix[test/run_tests13.pl], [chmod +x test/run_tests13.pl])
AC_CONFIG_FILES(pmix_config_prefix[test/run_tests14.pl], [chmod +x test/run_tests14.pl])
AC_CONFIG_FILES(pmix_config_prefix[test/run_tests15.pl], [chmod +x test/run_tests15.pl])
if test "$WANT_PYTHON_BINDINGS" = "1"; then
AC_CONFIG_FILES(pmix_config_prefix[test/python/run_server.sh], [chmod +x test/python/run_server.sh])
AC_CONFIG_FILES(pmix_config_prefix[test/python/run_sched.sh], [chmod +x test/python/run_sched.sh])
fi
############################################################################
# final output
@ -910,11 +914,6 @@ AC_DEFUN([PMIX_SETUP_CORE],[
pmix_config_prefix[src/tools/pps/Makefile]
pmix_config_prefix[src/tools/pattrs/Makefile]
)
if test "$WANT_PYTHON_BINDINGS" = "1"; then
AC_CONFIG_FILES(pmix_config_prefix[bindings/python/server.py], [chmod +x bindings/python/server.py])
AC_CONFIG_FILES(pmix_config_prefix[bindings/python/client.py], [chmod +x bindings/python/client.py])
AC_CONFIG_FILES(pmix_config_prefix[bindings/python/sched.py], [chmod +x bindings/python/sched.py])
fi
# publish any embedded flags so external wrappers can use them
AC_SUBST(PMIX_EMBEDDED_LIBS)
@ -1213,9 +1212,8 @@ AM_CONDITIONAL([WANT_PYTHON_BINDINGS], [test $WANT_PYTHON_BINDINGS -eq 1])
if test "$WANT_PYTHON_BINDINGS" = "1"; then
AM_PATH_PYTHON([3.4])
AC_SUBST([PMIX_PYTHON_PATH], [#!"$PYTHON"], "Full Python executable path")
pyvers=`python --version`
python_version=${pyvers#"Python"}
pyvers=`python3 --version`
python_version=${pyvers#"Python "}
major=$(echo $python_version | cut -d. -f1)
minor=$(echo $python_version | cut -d. -f2)
if test "$major" -lt "3"; then
@ -1233,7 +1231,7 @@ if test "$WANT_PYTHON_BINDINGS" = "1"; then
PMIX_SUMMARY_ADD([[Bindings]],[[Python]], [pmix_python], [yes ($python_version)])
AC_MSG_CHECKING([if Cython package installed])
AC_MSG_CHECKING([if Cython package installed as Python package])
have_cython=`$srcdir/config/pmix_check_cython.py 2> /dev/null`
if test "$have_cython" = "0"; then
AC_MSG_RESULT([yes])
@ -1243,11 +1241,25 @@ if test "$WANT_PYTHON_BINDINGS" = "1"; then
PMIX_SUMMARY_ADD([[Bindings]],[[Cython]], [pmix_cython], [yes ($cython_version)])
else
AC_MSG_RESULT([no])
AC_MSG_WARN([Python bindings were enabled, but the Cython])
AC_MSG_WARN([package was not found. PMIx Python bindings])
AC_MSG_WARN([require that the Cython package be installed])
AC_MSG_ERROR([Cannot continue])
# Cython doesn't have any include or lib files - it is just a binary
AC_CHECK_PROG(pmix_cython_rpm, cython, ["found"], ["not found"])
if test "$pmix_cython_rpm" = "found"; then
AC_MSG_CHECKING([Cython version])
cyvers=`cython --version 2>&1`
cython_version=${cyvers#"Cython version "}
AC_MSG_RESULT([$cython_version])
PMIX_SUMMARY_ADD([[Bindings]],[[Cython]], [pmix_cython], [yes ($cython_version)])
else
AC_MSG_RESULT([no])
AC_MSG_WARN([Python bindings were enabled, but the Cython])
AC_MSG_WARN([package was not found. PMIx Python bindings])
AC_MSG_WARN([require that the Cython package be installed])
AC_MSG_ERROR([Cannot continue])
fi
fi
pmix_pythondir=`eval echo $pythondir`
AC_SUBST([PMIX_PYTHON_EGG_PATH], [$pmix_pythondir], [Path to installed Python egg])
fi
# see if they want to disable non-RTLD_GLOBAL dlopen

Просмотреть файл

@ -1,7 +1,9 @@
dnl -*- shell-script -*-
dnl
dnl Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
dnl Copyright (c) 2013-2017 Intel, Inc. All rights reserved.
dnl Copyright (c) 2013-2019 Intel, Inc. All rights reserved.
dnl Copyright (c) 2019 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl
dnl $COPYRIGHT$
dnl
@ -43,6 +45,7 @@ int main (int argc, char * argv[])
f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf (f, "%d", PLATFORM_COMPILER_$1);
fclose(f);
return 0;
}
], [
@ -75,6 +78,7 @@ int main (int argc, char * argv[])
f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf (f, "%s", PLATFORM_COMPILER_$1);
fclose(f);
return 0;
}
], [
@ -110,6 +114,7 @@ int main (int argc, char * argv[])
f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf (f, "%s", _STRINGIFY(PLATFORM_COMPILER_$1));
fclose(f);
return 0;
}
], [

Просмотреть файл

@ -10,9 +10,9 @@ dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved.
dnl Copyright (c) 2004-2005 The Regents of the University of California.
dnl All rights reserved.
dnl Copyright (c) 2014 Intel, Inc. All rights reserved.
dnl Copyright (c) 2016 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl Copyright (c) 2014-2019 Intel, Inc. All rights reserved.
dnl Copyright (c) 2016-2019 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
@ -45,6 +45,7 @@ int main ()
func (4711, "Help %d [%s]\n", 10, "ten");
f=fopen ("conftestval", "w");
if (!f) exit (1);
fclose(f);
return 0;
}

Просмотреть файл

@ -287,7 +287,8 @@ AC_SUBST([libmca_common_dstore_so_version])
AC_CONFIG_FILES(pmix_config_prefix[contrib/Makefile]
pmix_config_prefix[examples/Makefile]
pmix_config_prefix[test/Makefile]
pmix_config_prefix[test/simple/Makefile])
pmix_config_prefix[test/simple/Makefile]
pmix_config_prefix[test/python/Makefile])
pmix_show_title "Configuration complete"

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2018 Intel, Inc. All rights reserved.
* Copyright (c) 2013-2019 Intel, Inc. All rights reserved.
* Copyright (c) 2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
*
@ -411,9 +411,6 @@ PMIX_EXPORT pmix_status_t PMIx_Resolve_nodes(const pmix_nspace_t nspace, char **
* executing on a given node. We assume that the host RM will
* exercise appropriate access control on the information.
*
* NOTE: there is no blocking form of this API as the structures
* passed to query info differ from those for receiving the results
*
* The following return status codes are provided in the callback:
*
* PMIX_SUCCESS - all data has been returned
@ -421,6 +418,9 @@ PMIX_EXPORT pmix_status_t PMIx_Resolve_nodes(const pmix_nspace_t nspace, char **
* PMIX_ERR_PARTIAL_SUCCESS - some of the data has been returned
* PMIX_ERR_NOT_SUPPORTED - the host RM does not support this function
*/
PMIX_EXPORT pmix_status_t PMIx_Query_info(pmix_query_t queries[], size_t nqueries,
pmix_info_t **results, size_t *nresults);
PMIX_EXPORT pmix_status_t PMIx_Query_info_nb(pmix_query_t queries[], size_t nqueries,
pmix_info_cbfunc_t cbfunc, void *cbdata);

Просмотреть файл

@ -157,7 +157,7 @@ typedef uint32_t pmix_rank_t;
#define PMIX_SERVER_GATEWAY "pmix.srv.gway" // (bool) Server is acting as a gateway for PMIx requests
// that cannot be serviced on backend nodes
// (e.g., logging to email)
#define PMIX_SERVER_SCHEDULER "pmix.src.sched" // (bool) Server supports system scheduler
#define PMIX_SERVER_SCHEDULER "pmix.srv.sched" // (bool) Server supports system scheduler
/* tool-related attributes */
#define PMIX_TOOL_NSPACE "pmix.tool.nspace" // (char*) Name of the nspace to use for this tool
@ -281,7 +281,6 @@ typedef uint32_t pmix_rank_t;
// specified network plane in the requested view
#define PMIX_NETWORK_SHAPE_STRING "pmix.net.shapestr" // (char*) network shape expressed as a string (e.g., "10x12x2")
/* size info */
#define PMIX_UNIV_SIZE "pmix.univ.size" // (uint32_t) #procs in this nspace
#define PMIX_JOB_SIZE "pmix.job.size" // (uint32_t) #procs in this job
@ -337,6 +336,7 @@ typedef uint32_t pmix_rank_t;
#define PMIX_EMBED_BARRIER "pmix.embed.barrier" // (bool) execute a blocking fence operation before executing the
// specified operation
#define PMIX_JOB_TERM_STATUS "pmix.job.term.status" // (pmix_status_t) status returned upon job termination
#define PMIX_PROC_TERM_STATUS "pmix.proc.term.status" // (pmix_status_t) status returned upon process termination
#define PMIX_PROC_STATE_STATUS "pmix.proc.state" // (pmix_proc_state_t) process state
#define PMIX_NOTIFY_LAUNCH "pmix.note.lnch" // (bool) notify the requestor upon launch of the child job and return
// its namespace in the event
@ -907,15 +907,17 @@ typedef int pmix_status_t;
#define PMIX_ERR_IOF_COMPLETE -172
#define PMIX_LAUNCH_COMPLETE -173 // include nspace of the launched job with notification
#define PMIX_FABRIC_UPDATED -174
#define PMIX_FABRIC_UPDATE_PENDING -175
/* system failures */
#define PMIX_ERR_SYS_BASE -230
#define PMIX_ERR_NODE_DOWN -231
#define PMIX_ERR_NODE_OFFLINE -232
#define PMIX_ERR_SYS_OTHER -330
/* define a macro for identifying system event values */
#define PMIX_SYSTEM_EVENT(a) \
((a) <= PMIX_ERR_NODE_DOWN && PMIX_ERR_SYS_OTHER <= (a))
((a) <= PMIX_ERR_SYS_BASE && PMIX_ERR_SYS_OTHER <= (a))
/* used by event handlers */
#define PMIX_EVENT_NO_ACTION_TAKEN -331
@ -987,6 +989,7 @@ typedef uint16_t pmix_data_type_t;
#define PMIX_ENVAR 46
#define PMIX_COORD 47
#define PMIX_REGATTR 48
#define PMIX_REGEX 49
/********************/
/* define a boundary for implementers so they can add their own data types */
@ -1144,6 +1147,8 @@ typedef uint8_t pmix_coord_view_t;
/* define a structure for a proc's network coordinate */
typedef struct pmix_coord {
char *fabric;
char *plane;
pmix_coord_view_t view;
int *coord;
size_t dims;
@ -1153,14 +1158,18 @@ typedef struct pmix_coord {
do { \
(m) = (pmix_coord_t*)pmix_calloc((n), sizeof(pmix_coord_t)); \
if (NULL != (m)) { \
(m)->fabric = NULL; \
(m)->plane = NULL; \
(m)->view = PMIX_COORD_VIEW_UNDEF; \
(m)->dims = (d); \
(m)->coord = (int*)pmix_calloc((m)->dims, sizeof(int)); \
} \
} while(0)
#define PMIX_COORD_CONSTRUCT(m, d) \
#define PMIX_COORD_CONSTRUCT(m) \
do { \
(m)->fabric = NULL; \
(m)->plane = NULL; \
(m)->view = PMIX_COORD_VIEW_UNDEF; \
(m)->coord = NULL; \
(m)->dims = 0; \
@ -1170,6 +1179,12 @@ typedef struct pmix_coord {
do { \
(m)->view = PMIX_COORD_VIEW_UNDEF; \
if (NULL != (m)->coord) { \
if (NULL != (m)->fabric) { \
free((m)->fabric); \
} \
if (NULL != (m)->plane) { \
free((m)->plane); \
}; \
pmix_free((m)->coord); \
(m)->coord = NULL; \
(m)->dims = 0; \

Просмотреть файл

@ -64,6 +64,8 @@ extern "C" {
typedef struct pmix_fabric_s {
/* user-supplied name for this fabric */
char *name;
/* a PMIx-supplied index identifying this registration object */
size_t index;
/* communication cost array - the number of vertices
* (nverts) equals the number of interfaces in the
* fabric. This equates to the number of columns & rows

Просмотреть файл

@ -571,34 +571,41 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module,
* memory usage is released */
PMIX_EXPORT pmix_status_t PMIx_server_finalize(void);
/* given a semicolon-separated list of input values, generate
* a regex that can be passed down to the client for parsing.
* The caller is responsible for free'ing the resulting
* string
/* Given a comma-separated list of \refarg{input} values, generate
* a reduced size representation of the input that can be passed
* down to PMIx_server_register_nspace for parsing. The order of
* the individual values in the \refarg{input} string is preserved
* across the operation. The caller is responsible for releasing
* the returned data.
*
* If values have leading zero's, then that is preserved. You
* have to add back any prefix/suffix for node names
* odin[009-015,017-023,076-086]
*
* "pmix:odin[009-015,017-023,076-086]"
*
* Note that the "pmix" at the beginning of each regex indicates
* that the PMIx native parser is to be used by the client for
* parsing the provided regex. Other parsers may be supported - see
* the pmix_client.h header for a list.
* The returned representation may be an arbitrary array of bytes
* as opposed to a valid NULL-terminated string. However, the
* method used to generate the representation shall be identified
* with a colon-delimited string at the beginning of the output.
* For example, an output starting with "pmix:" indicates that
* the representation is a PMIx-defined regular expression.
* In contrast, an output starting with "blob:" is a compressed
* binary array.
*/
PMIX_EXPORT pmix_status_t PMIx_generate_regex(const char *input, char **regex);
/* The input is expected to consist of a comma-separated list
* of ranges. Thus, an input of:
* "1-4;2-5;8,10,11,12;6,7,9"
* would generate a regex of
* "[pmix:2x(3);8,10-12;6-7,9]"
/* The input shall consist of a semicolon-separated list of ranges
* representing the ranks of processes on each node of the job -
* e.g., "1-4;2-5;8,10,11,12;6,7,9". Each field of the input must
* correspond to the node name provided at that position in the
* input to PMIx_generate_regex. Thus, in the example, ranks 1-4
* would be located on the first node of the comma-separated list
* of names provided to PMIx_generate_regex, and ranks 2-5 would
* be on the second name in the list.
*
* Note that the "pmix" at the beginning of each regex indicates
* that the PMIx native parser is to be used by the client for
* parsing the provided regex. Other parsers may be supported - see
* the pmix_client.h header for a list.
* The returned representation may be an arbitrary array of bytes
* as opposed to a valid NULL-terminated string. However, the
* method used to generate the representation shall be identified
* with a colon-delimited string at the beginning of the output.
* For example, an output starting with "pmix:" indicates that
* the representation is a PMIx-defined regular expression.
* In contrast, an output starting with "blob:" is a compressed
* binary array.
*/
PMIX_EXPORT pmix_status_t PMIx_generate_ppn(const char *input, char **ppn);

Просмотреть файл

@ -294,6 +294,7 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
int32_t cnt;
pmix_proc_t proc;
pmix_kval_t *kv;
bool diffnspace;
pmix_output_verbose(2, pmix_client_globals.get_output,
"pmix: get_nb callback recvd");
@ -308,6 +309,9 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
pmix_strncpy(proc.nspace, cb->pname.nspace, PMIX_MAX_NSLEN);
proc.rank = cb->pname.rank;
/* check for a different nspace */
diffnspace = !PMIX_CHECK_NSPACE(pmix_globals.myid.nspace, proc.nspace);
/* a zero-byte buffer indicates that this recv is being
* completed due to a lost connection */
if (PMIX_BUFFER_IS_EMPTY(buf)) {
@ -329,7 +333,7 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
if (PMIX_SUCCESS != ret) {
goto done;
}
if (PMIX_RANK_UNDEF == proc.rank) {
if (PMIX_RANK_UNDEF == proc.rank || diffnspace) {
PMIX_GDS_ACCEPT_KVS_RESP(rc, pmix_globals.mypeer, buf);
} else {
PMIX_GDS_ACCEPT_KVS_RESP(rc, pmix_client_globals.myserver, buf);
@ -352,7 +356,7 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
/* fetch the data from server peer module - since it is passing
* it back to the user, we need a copy of it */
cb->copy = true;
if (PMIX_RANK_UNDEF == proc.rank) {
if (PMIX_RANK_UNDEF == proc.rank || diffnspace) {
PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, cb);
} else {
PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, cb);
@ -636,11 +640,13 @@ static void _getnbfn(int fd, short flags, void *cbdata)
if (PMIX_SUCCESS != rc) {
pmix_output_verbose(5, pmix_client_globals.get_output,
"pmix:client job-level data NOT found");
if (0 != strncmp(cb->pname.nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)) {
if (!PMIX_CHECK_NSPACE(cb->pname.nspace, pmix_globals.myid.nspace)) {
/* we are asking about the job-level info from another
* namespace. It seems that we don't have it - go and
* ask server
* ask server and indicate we only need job-level info
* by setting the rank to WILDCARD
*/
proc.rank = PMIX_RANK_WILDCARD;
goto request;
} else if (NULL != cb->key) {
/* if immediate was given, then we are being directed to
@ -742,8 +748,7 @@ static void _getnbfn(int fd, short flags, void *cbdata)
* this nspace:rank. If we do, then no need to ask again as the
* request will return _all_ data from that proc */
PMIX_LIST_FOREACH(cbret, &pmix_client_globals.pending_requests, pmix_cb_t) {
if (0 == strncmp(cbret->pname.nspace, cb->pname.nspace, PMIX_MAX_NSLEN) &&
cbret->pname.rank == cb->pname.rank) {
if (PMIX_CHECK_PROCID(&cbret->pname, &cb->pname)) {
/* we do have a pending request, but we still need to track this
* outstanding request so we can satisfy it once the data is returned */
pmix_list_append(&pmix_client_globals.pending_requests, &cb->super);
@ -753,7 +758,7 @@ static void _getnbfn(int fd, short flags, void *cbdata)
/* we don't have a pending request, so let's create one - don't worry
* about packing the key as we return everything from that proc */
msg = _pack_get(cb->pname.nspace, cb->pname.rank, cb->info, cb->ninfo, PMIX_GETNB_CMD);
msg = _pack_get(cb->pname.nspace, proc.rank, cb->info, cb->ninfo, PMIX_GETNB_CMD);
if (NULL == msg) {
rc = PMIX_ERROR;
goto respond;

Просмотреть файл

@ -133,6 +133,69 @@ static void _local_cbfunc(int sd, short args, void *cbdata)
PMIX_RELEASE(cd);
}
static void qinfocb(pmix_status_t status, pmix_info_t info[], size_t ninfo,
void *cbdata, pmix_release_cbfunc_t release_fn, void *release_cbdata)
{
pmix_cb_t *cb = (pmix_cb_t*)cbdata;
size_t n;
cb->status = status;
if (NULL != info) {
cb->ninfo = ninfo;
PMIX_INFO_CREATE(cb->info, cb->ninfo);
for (n=0; n < ninfo; n++) {
PMIX_INFO_XFER(&cb->info[n], &info[n]);
}
}
if (NULL != release_fn) {
release_fn(release_cbdata);
}
PMIX_WAKEUP_THREAD(&cb->lock);
}
PMIX_EXPORT pmix_status_t PMIx_Query_info(pmix_query_t queries[], size_t nqueries,
pmix_info_t **results, size_t *nresults)
{
pmix_cb_t cb;
pmix_status_t rc;
PMIX_ACQUIRE_THREAD(&pmix_global_lock);
if (pmix_globals.init_cntr <= 0) {
PMIX_RELEASE_THREAD(&pmix_global_lock);
return PMIX_ERR_INIT;
}
PMIX_RELEASE_THREAD(&pmix_global_lock);
pmix_output_verbose(2, pmix_globals.debug_output,
"%s pmix:query", PMIX_NAME_PRINT(&pmix_globals.myid));
/* create a callback object as we need to pass it to the
* recv routine so we know which callback to use when
* the return message is recvd */
PMIX_CONSTRUCT(&cb, pmix_cb_t);
if (PMIX_SUCCESS != (rc = PMIx_Query_info_nb(queries, nqueries,
qinfocb, &cb))) {
PMIX_DESTRUCT(&cb);
return rc;
}
/* wait for the operation to complete */
PMIX_WAIT_THREAD(&cb.lock);
rc = cb.status;
if (NULL != cb.info) {
*results = cb.info;
*nresults = cb.ninfo;
cb.info = NULL;
cb.ninfo = 0;
}
PMIX_DESTRUCT(&cb);
pmix_output_verbose(2, pmix_globals.debug_output,
"pmix:job_ctrl completed");
return rc;
}
PMIX_EXPORT pmix_status_t PMIx_Query_info_nb(pmix_query_t queries[], size_t nqueries,
pmix_info_cbfunc_t cbfunc, void *cbdata)

Просмотреть файл

@ -475,6 +475,9 @@ PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_coord(pmix_pointer_array_t *regt
PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_regattr(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, const void *src,
int32_t num_vals, pmix_data_type_t type);
PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_regex(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, const void *src,
int32_t num_vals, pmix_data_type_t type);
/*
* "Standard" unpack functions
@ -612,6 +615,9 @@ PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_coord(pmix_pointer_array_t *re
PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_regattr(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, void *dest,
int32_t *num_vals, pmix_data_type_t type);
PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_regex(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, void *dest,
int32_t *num_vals, pmix_data_type_t type);
/**** DEPRECATED ****/
PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_array(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, void *dest,
@ -677,6 +683,9 @@ PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_coord(pmix_coord_t **dest,
PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_regattr(pmix_regattr_t **dest,
pmix_regattr_t *src,
pmix_data_type_t type);
PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_regex(char **dest,
char *src,
pmix_data_type_t type);
/*
* "Standard" print functions
@ -791,6 +800,9 @@ PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_coord(char **output, char *pref
PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_regattr(char **output, char *prefix,
pmix_regattr_t *src,
pmix_data_type_t type);
PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_regex(char **output, char *prefix,
char *src,
pmix_data_type_t type);
/*
* Common helper functions

Просмотреть файл

@ -26,6 +26,7 @@
#include "src/util/error.h"
#include "src/util/output.h"
#include "src/include/pmix_globals.h"
#include "src/mca/preg/preg.h"
#include "src/mca/bfrops/base/base.h"
@ -848,6 +849,13 @@ pmix_status_t pmix_bfrops_base_copy_darray(pmix_data_array_t **dest,
pc = (pmix_coord_t*)p->array;
sc = (pmix_coord_t*)src->array;
for (n=0; n < src->size; n++) {
PMIX_COORD_CONSTRUCT(&pc[n]);
if (NULL != sc[n].fabric) {
pc[n].fabric = strdup(sc[n].fabric);
}
if (NULL != sc[n].plane) {
pc[n].plane = strdup(sc[n].plane);
}
pc[n].view = sc[n].view;
pc[n].dims = sc[n].dims;
if (0 < pc[n].dims) {
@ -948,6 +956,13 @@ pmix_status_t pmix_bfrops_base_copy_coord(pmix_coord_t **dest,
if (NULL == d) {
return PMIX_ERR_NOMEM;
}
PMIX_COORD_CONSTRUCT(d);
if (NULL != src->fabric) {
d->fabric = strdup(src->fabric);
}
if (NULL != src->plane) {
d->plane = strdup(src->plane);
}
d->view = src->view;
d->dims = src->dims;
if (0 < d->dims) {
@ -985,3 +1000,16 @@ pmix_status_t pmix_bfrops_base_copy_regattr(pmix_regattr_t **dest,
(*dest)->description = pmix_argv_copy(src->description);
return PMIX_SUCCESS;
}
pmix_status_t pmix_bfrops_base_copy_regex(char **dest,
char *src,
pmix_data_type_t type)
{
size_t len;
if (PMIX_REGEX != type) {
return PMIX_ERR_BAD_PARAM;
}
return pmix_preg.copy(dest, &len, src);
}

Просмотреть файл

@ -30,6 +30,7 @@
#include "src/util/argv.h"
#include "src/util/error.h"
#include "src/include/pmix_globals.h"
#include "src/mca/preg/preg.h"
#include "src/mca/bfrops/base/base.h"
@ -219,7 +220,13 @@ void pmix_bfrops_base_value_load(pmix_value_t *v, const void *data,
PMIX_ERROR_LOG(rc);
}
break;
case PMIX_REGEX:
/* load it into the byte object */
rc = pmix_preg.copy(&v->data.bo.bytes, &v->data.bo.size, (char*)data);
if (PMIX_SUCCESS != rc) {
PMIX_ERROR_LOG(rc);
}
break;
default:
/* silence warnings */
break;
@ -400,6 +407,15 @@ pmix_status_t pmix_bfrops_base_value_unload(pmix_value_t *kv,
regattr->description = pmix_argv_copy(r->description);
*data = regattr;
break;
case PMIX_REGEX:
if (NULL != kv->data.bo.bytes && 0 < kv->data.bo.size) {
*data = kv->data.bo.bytes;
*sz = kv->data.bo.size;
} else {
*data = NULL;
*sz = 0;
}
break;
default:
/* silence warnings */
rc = PMIX_ERROR;
@ -667,6 +683,7 @@ pmix_status_t pmix_bfrops_base_value_xfer(pmix_value_t *p,
break;
case PMIX_BYTE_OBJECT:
case PMIX_COMPRESSED_STRING:
case PMIX_REGEX:
memset(&p->data.bo, 0, sizeof(pmix_byte_object_t));
if (NULL != src->data.bo.bytes && 0 < src->data.bo.size) {
p->data.bo.bytes = malloc(src->data.bo.size);

Просмотреть файл

@ -32,6 +32,7 @@
#include "src/util/error.h"
#include "src/util/output.h"
#include "src/include/pmix_globals.h"
#include "src/mca/preg/preg.h"
#include "src/mca/bfrops/base/base.h"
@ -1248,6 +1249,16 @@ pmix_status_t pmix_bfrops_base_pack_coord(pmix_pointer_array_t *regtypes,
return PMIX_ERR_BAD_PARAM;
}
for (i=0; i < num_vals; ++i) {
/* pack the fabric name */
PMIX_BFROPS_PACK_TYPE(ret, buffer, &ptr[i].fabric, 1, PMIX_STRING, regtypes);
if (PMIX_SUCCESS != ret) {
return ret;
}
/* pack the plane */
PMIX_BFROPS_PACK_TYPE(ret, buffer, &ptr[i].plane, 1, PMIX_STRING, regtypes);
if (PMIX_SUCCESS != ret) {
return ret;
}
/* pack the view */
PMIX_BFROPS_PACK_TYPE(ret, buffer, &ptr[i].view, 1, PMIX_UINT8, regtypes);
if (PMIX_SUCCESS != ret) {
@ -1329,3 +1340,26 @@ pmix_status_t pmix_bfrops_base_pack_regattr(pmix_pointer_array_t *regtypes,
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_bfrops_base_pack_regex(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, const void *src,
int32_t num_vals, pmix_data_type_t type)
{
char **ptr = (char**)src;
int32_t i;
pmix_status_t ret;
if (NULL == regtypes) {
return PMIX_ERR_BAD_PARAM;
}
if (PMIX_REGEX != type) {
return PMIX_ERR_BAD_PARAM;
}
for (i=0; i < num_vals; ++i) {
ret = pmix_preg.pack(buffer, ptr[i]);
if (PMIX_SUCCESS != ret) {
return ret;
}
}
return PMIX_SUCCESS;
}

Просмотреть файл

@ -1875,8 +1875,9 @@ pmix_status_t pmix_bfrops_base_print_coord(char **output, char *prefix,
} else {
tp = "UNRECOGNIZED";
}
ret = asprintf(output, "%sData type: PMIX_COORD\tView: %s\tDims: %lu",
prefx, tp, (unsigned long)src->dims);
ret = asprintf(output, "%sData type: PMIX_COORD\tFabric: %s\tPlane: %s\tView: %s\tDims: %lu",
prefx, (NULL == src->fabric) ? "NULL" : src->fabric,
(NULL == src->plane) ? "NULL" : src->plane, tp, (unsigned long)src->dims);
if (prefx != prefix) {
free(prefx);
}
@ -1921,3 +1922,35 @@ pmix_status_t pmix_bfrops_base_print_regattr(char **output, char *prefix,
return PMIX_SUCCESS;
}
}
pmix_status_t pmix_bfrops_base_print_regex(char **output, char *prefix,
char *src,
pmix_data_type_t type)
{
char *prefx;
int ret;
if (PMIX_REGEX != type) {
return PMIX_ERR_BAD_PARAM;
}
/* deal with NULL prefix */
if (NULL == prefix) {
if (0 > asprintf(&prefx, " ")) {
return PMIX_ERR_NOMEM;
}
} else {
prefx = prefix;
}
ret = asprintf(output, "%sData type: PMIX_REGEX\tName: %s", prefx, src);
if (prefx != prefix) {
free(prefx);
}
if (0 > ret) {
return PMIX_ERR_OUT_OF_RESOURCE;
} else {
return PMIX_SUCCESS;
}
}

Просмотреть файл

@ -28,6 +28,8 @@
#include "src/util/error.h"
#include "src/util/output.h"
#include "src/include/pmix_globals.h"
#include "src/mca/preg/preg.h"
#include "src/mca/bfrops/bfrops_types.h"
#include "src/mca/bfrops/base/base.h"
@ -1470,6 +1472,19 @@ pmix_status_t pmix_bfrops_base_unpack_coord(pmix_pointer_array_t *regtypes,
n = *num_vals;
for (i = 0; i < n; ++i) {
PMIX_COORD_CONSTRUCT(&ptr[i]);
/* unpack the fabric name */
m=1;
PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].fabric, &m, PMIX_STRING, regtypes);
if (PMIX_SUCCESS != ret) {
return ret;
}
/* unpack the plane */
m=1;
PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].plane, &m, PMIX_STRING, regtypes);
if (PMIX_SUCCESS != ret) {
return ret;
}
/* unpack the view */
m=1;
PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].view, &m, PMIX_UINT8, regtypes);
@ -1581,3 +1596,31 @@ pmix_status_t pmix_bfrops_base_unpack_regattr(pmix_pointer_array_t *regtypes,
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_bfrops_base_unpack_regex(pmix_pointer_array_t *regtypes,
pmix_buffer_t *buffer, void *dest,
int32_t *num_vals, pmix_data_type_t type)
{
char **ptr;
int32_t i, n;
pmix_status_t ret;
pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
"pmix_bfrop_unpack: %d regex", *num_vals);
if (PMIX_REGEX != type) {
return PMIX_ERR_BAD_PARAM;
}
ptr = (char **) dest;
n = *num_vals;
for (i = 0; i < n; ++i) {
ret = pmix_preg.unpack(buffer, &ptr[n]);
if (PMIX_SUCCESS != ret) {
*num_vals = n;
return ret;
}
}
return PMIX_SUCCESS;
}

Просмотреть файл

@ -445,6 +445,13 @@ static pmix_status_t init(void)
pmix_bfrops_base_print_regattr,
&mca_bfrops_v4_component.types);
PMIX_REGISTER_TYPE("PMIX_REGEX",
PMIX_REGEX,
pmix_bfrops_base_pack_regex,
pmix_bfrops_base_unpack_regex,
pmix_bfrops_base_copy_regex,
pmix_bfrops_base_print_regex,
&mca_bfrops_v4_component.types);
return PMIX_SUCCESS;
}

Просмотреть файл

@ -2157,9 +2157,10 @@ static pmix_status_t _dstore_fetch(pmix_common_dstore_ctx_t *ds_ctx,
break;
}
} else if (NULL == key) {
char *kname_ptr = PMIX_DS_KNAME_PTR(ds_ctx, addr);
PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
"%s:%d:%s: for rank %s:%u, found target key %s",
__FILE__, __LINE__, __func__, nspace, cur_rank, PMIX_DS_KNAME_PTR(ds_ctx, addr)));
__FILE__, __LINE__, __func__, nspace, cur_rank, kname_ptr));
uint8_t *data_ptr = PMIX_DS_DATA_PTR(ds_ctx, addr);
size_t data_size = PMIX_DS_DATA_SIZE(ds_ctx, addr, data_ptr);
@ -2173,8 +2174,8 @@ static pmix_status_t _dstore_fetch(pmix_common_dstore_ctx_t *ds_ctx,
PMIX_ERROR_LOG(rc);
goto done;
}
pmix_strncpy(info[kval_cnt - 1].key, PMIX_DS_KNAME_PTR(ds_ctx, addr),
PMIX_DS_KNAME_LEN(ds_ctx, addr));
pmix_strncpy(info[kval_cnt - 1].key, kname_ptr,
PMIX_DS_KNAME_LEN(ds_ctx, kname_ptr));
pmix_value_xfer(&info[kval_cnt - 1].value, &val);
PMIX_VALUE_DESTRUCT(&val);
buffer.base_ptr = NULL;

Просмотреть файл

@ -552,7 +552,7 @@ static pmix_status_t process_job_array(pmix_info_t *info,
return PMIX_ERR_BAD_PARAM;
}
/* parse the regex to get the argv array containing proc ranks on each node */
if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(iptr[j].value.data.string, procs))) {
if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(iptr[j].value.data.bo.bytes, procs))) {
PMIX_ERROR_LOG(rc);
return rc;
}
@ -564,22 +564,8 @@ static pmix_status_t process_job_array(pmix_info_t *info,
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
return PMIX_ERR_BAD_PARAM;
}
/* store the node map itself since that is
* what v3 uses */
kp2 = PMIX_NEW(pmix_kval_t);
kp2->key = strdup(PMIX_NODE_MAP);
kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t));
kp2->value->type = PMIX_STRING;
kp2->value->data.string = strdup(iptr[j].value.data.string);
if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->internal, PMIX_RANK_WILDCARD, kp2))) {
PMIX_ERROR_LOG(rc);
PMIX_RELEASE(kp2);
return rc;
}
PMIX_RELEASE(kp2); // maintain acctg
/* parse the regex to get the argv array of node names */
if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(iptr[j].value.data.string, nodes))) {
if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(iptr[j].value.data.bo.bytes, nodes))) {
PMIX_ERROR_LOG(rc);
return rc;
}
@ -1120,22 +1106,8 @@ pmix_status_t hash_cache_job_info(struct pmix_namespace_t *ns,
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
return PMIX_ERR_BAD_PARAM;
}
/* store the node map itself since that is
* what v3 uses */
kp2 = PMIX_NEW(pmix_kval_t);
kp2->key = strdup(PMIX_NODE_MAP);
kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t));
kp2->value->type = PMIX_STRING;
kp2->value->data.string = strdup(info[n].value.data.string);
if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) {
PMIX_ERROR_LOG(rc);
PMIX_RELEASE(kp2);
return rc;
}
PMIX_RELEASE(kp2); // maintain acctg
/* parse the regex to get the argv array of node names */
if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(info[n].value.data.string, &nodes))) {
if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(info[n].value.data.bo.bytes, &nodes))) {
PMIX_ERROR_LOG(rc);
goto release;
}
@ -1148,13 +1120,13 @@ pmix_status_t hash_cache_job_info(struct pmix_namespace_t *ns,
return PMIX_ERR_BAD_PARAM;
}
/* parse the regex to get the argv array containing proc ranks on each node */
if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(info[n].value.data.string, &procs))) {
if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(info[n].value.data.bo.bytes, &procs))) {
PMIX_ERROR_LOG(rc);
goto release;
}
/* mark that we got the map */
flags |= PMIX_HASH_PROC_MAP;
} else if (0 == strcmp(info[n].key, PMIX_PROC_DATA)) {
} else if (PMIX_CHECK_KEY(&info[n], PMIX_PROC_DATA)) {
flags |= PMIX_HASH_PROC_DATA;
/* an array of data pertaining to a specific proc */
if (PMIX_DATA_ARRAY != info[n].value.type) {
@ -1290,14 +1262,10 @@ pmix_status_t hash_cache_job_info(struct pmix_namespace_t *ns,
}
/* we must have the proc AND node maps */
if (NULL == procs || NULL == nodes) {
rc = PMIX_ERR_NOT_FOUND;
goto release;
}
if (PMIX_SUCCESS != (rc = store_map(ht, nodes, procs, flags))) {
PMIX_ERROR_LOG(rc);
goto release;
if (NULL != procs && NULL != nodes) {
if (PMIX_SUCCESS != (rc = store_map(ht, nodes, procs, flags))) {
PMIX_ERROR_LOG(rc);
}
}
release:
@ -1841,6 +1809,10 @@ static pmix_status_t hash_store(const pmix_proc_t *proc,
pmix_status_t rc;
pmix_kval_t *kp;
pmix_namespace_t *ns, *nptr;
pmix_rank_t rank;
size_t j, size, len;
pmix_info_t *iptr;
uint8_t *tmp;
pmix_output_verbose(2, pmix_gds_base_framework.framework_output,
"%s gds:hash:hash_store for proc %s key %s type %s scope %s",
@ -1887,9 +1859,10 @@ static pmix_status_t hash_store(const pmix_proc_t *proc,
pmix_list_append(&myjobs, &trk->super);
}
/* see if the proc is me */
/* see if the proc is me - cannot use CHECK_PROCID as
* we don't want rank=wildcard to match */
if (proc->rank == pmix_globals.myid.rank &&
0 == strncmp(proc->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)) {
PMIX_CHECK_NSPACE(proc->nspace, pmix_globals.myid.nspace)) {
if (PMIX_INTERNAL != scope) {
/* always maintain a copy of my own info here to simplify
* later retrieval */
@ -1924,6 +1897,67 @@ static pmix_status_t hash_store(const pmix_proc_t *proc,
/* store it in the corresponding hash table */
if (PMIX_INTERNAL == scope) {
/* if this is proc data, then we have to expand it and
* store the values on that rank */
if (PMIX_CHECK_KEY(kv, PMIX_PROC_DATA)) {
/* an array of data pertaining to a specific proc */
if (PMIX_DATA_ARRAY != kv->value->type) {
PMIX_ERROR_LOG(PMIX_ERR_TYPE_MISMATCH);
return PMIX_ERR_TYPE_MISMATCH;
}
size = kv->value->data.darray->size;
iptr = (pmix_info_t*)kv->value->data.darray->array;
/* first element of the array must be the rank */
if (0 != strcmp(iptr[0].key, PMIX_RANK) ||
PMIX_PROC_RANK != iptr[0].value.type) {
rc = PMIX_ERR_TYPE_MISMATCH;
PMIX_ERROR_LOG(rc);
return rc;
}
rank = iptr[0].value.data.rank;
/* cycle thru the values for this rank and store them */
for (j=1; j < size; j++) {
kp = PMIX_NEW(pmix_kval_t);
if (NULL == kp) {
rc = PMIX_ERR_NOMEM;
return rc;
}
kp->key = strdup(iptr[j].key);
PMIX_VALUE_XFER(rc, kp->value, &iptr[j].value);
if (PMIX_SUCCESS != rc) {
PMIX_ERROR_LOG(rc);
PMIX_RELEASE(kp);
return rc;
}
/* if the value contains a string that is longer than the
* limit, then compress it */
if (PMIX_STRING_SIZE_CHECK(kp->value)) {
if (pmix_compress.compress_string(kp->value->data.string, &tmp, &len)) {
if (NULL == tmp) {
PMIX_ERROR_LOG(PMIX_ERR_NOMEM);
rc = PMIX_ERR_NOMEM;
return rc;
}
kp->value->type = PMIX_COMPRESSED_STRING;
free(kp->value->data.string);
kp->value->data.bo.bytes = (char*)tmp;
kp->value->data.bo.size = len;
}
}
pmix_output_verbose(2, pmix_gds_base_framework.framework_output,
"%s gds:hash:STORE data for nspace %s rank %u: key %s",
PMIX_NAME_PRINT(&pmix_globals.myid),
trk->ns, rank, kp->key);
/* store it in the hash_table */
if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->internal, rank, kp))) {
PMIX_ERROR_LOG(rc);
PMIX_RELEASE(kp);
return rc;
}
PMIX_RELEASE(kp); // maintain acctg
}
return PMIX_SUCCESS;
}
if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->internal, proc->rank, kv))) {
PMIX_ERROR_LOG(rc);
return rc;
@ -2080,7 +2114,7 @@ static pmix_status_t _hash_store_modex(pmix_gds_base_ctx_t ctx,
static pmix_status_t dohash(pmix_hash_table_t *ht,
const char *key,
pmix_rank_t rank,
bool skip_genvals,
int skip_genvals,
pmix_list_t *kvs)
{
pmix_status_t rc;
@ -2102,12 +2136,24 @@ static pmix_status_t dohash(pmix_hash_table_t *ht,
PMIX_RELEASE(val);
return PMIX_ERR_NOT_FOUND;
}
/* if they want the value returned in its array form,
* then we are done */
if (2 == skip_genvals) {
kv = PMIX_NEW(pmix_kval_t);
if (NULL == kv) {
PMIX_VALUE_RELEASE(val);
return PMIX_ERR_NOMEM;
}
kv->value = val;
pmix_list_append(kvs, &kv->super);
return PMIX_SUCCESS;
}
info = (pmix_info_t*)val->data.darray->array;
ninfo = val->data.darray->size;
for (n=0; n < ninfo; n++) {
/* if the rank is UNDEF, then we don't want
* anything that starts with "pmix" */
if (skip_genvals &&
if (1 == skip_genvals &&
0 == strncmp(info[n].key, "pmix", 4)) {
continue;
}
@ -2314,14 +2360,14 @@ static pmix_status_t hash_fetch(const pmix_proc_t *proc,
{
pmix_job_t *trk, *t;
pmix_status_t rc;
pmix_value_t *val;
pmix_kval_t *kv, *kvptr;
pmix_info_t *info;
size_t n, ninfo;
pmix_info_t *info, *iptr;
size_t n, ninfo, niptr;
pmix_hash_table_t *ht;
pmix_session_t *sptr;
uint32_t sid;
pmix_rank_t rnk;
pmix_list_t rkvs;
pmix_output_verbose(2, pmix_gds_base_framework.framework_output,
"%s pmix:gds:hash fetch %s for proc %s on scope %s",
@ -2346,48 +2392,56 @@ static pmix_status_t hash_fetch(const pmix_proc_t *proc,
/* let the caller know */
return PMIX_ERR_INVALID_NAMESPACE;
}
/* the job data is stored on the internal hash table */
ht = &trk->internal;
/* fetch all values from the hash table tied to rank=wildcard */
val = NULL;
rc = pmix_hash_fetch(ht, PMIX_RANK_WILDCARD, NULL, &val);
if (PMIX_SUCCESS != rc) {
if (NULL != val) {
PMIX_VALUE_RELEASE(val);
}
return rc;
}
if (NULL == val) {
return PMIX_ERR_NOT_FOUND;
}
/* the data is returned in a pmix_data_array_t of pmix_info_t
* structs. cycle thru and transfer them to the list */
if (PMIX_DATA_ARRAY != val->type ||
NULL == val->data.darray ||
PMIX_INFO != val->data.darray->type) {
PMIX_VALUE_RELEASE(val);
return PMIX_ERR_INVALID_VAL;
}
info = (pmix_info_t*)val->data.darray->array;
ninfo = val->data.darray->size;
for (n=0; n < ninfo; n++) {
dohash(&trk->internal, NULL, PMIX_RANK_WILDCARD, 0, kvs);
/* also need to add any job-level info */
PMIX_LIST_FOREACH(kvptr, &trk->jobinfo, pmix_kval_t) {
kv = PMIX_NEW(pmix_kval_t);
if (NULL == kv) {
rc = PMIX_ERR_NOMEM;
PMIX_VALUE_RELEASE(val);
return rc;
}
kv->key = strdup(info[n].key);
PMIX_VALUE_XFER(rc, kv->value, &info[n].value);
kv->key = strdup(kvptr->key);
kv->value = (pmix_value_t*)malloc(sizeof(pmix_value_t));
PMIX_VALUE_XFER(rc, kv->value, kvptr->value);
if (PMIX_SUCCESS != rc) {
PMIX_ERROR_LOG(rc);
PMIX_RELEASE(kv);
PMIX_VALUE_RELEASE(val);
return rc;
}
pmix_list_append(kvs, &kv->super);
}
PMIX_VALUE_RELEASE(val);
/* finally, we need the job-level info for each rank in the job */
for (rnk=0; rnk < trk->nptr->nprocs; rnk++) {
PMIX_CONSTRUCT(&rkvs, pmix_list_t);
rc = dohash(&trk->internal, NULL, rnk, 2, &rkvs);
if (PMIX_ERR_NOMEM == rc) {
return rc;
}
if (0 == pmix_list_get_size(&rkvs)) {
PMIX_DESTRUCT(&rkvs);
continue;
}
/* should only have one entry on list */
kvptr = (pmix_kval_t*)pmix_list_get_first(&rkvs);
/* we have to assemble the results into a proc blob
* so the remote end will know what to do with it */
info = (pmix_info_t*)kvptr->value->data.darray->array;
ninfo = kvptr->value->data.darray->size;
/* setup to return the result */
kv = PMIX_NEW(pmix_kval_t);
kv->key = strdup(PMIX_PROC_DATA);
kv->value = (pmix_value_t*)malloc(sizeof(pmix_value_t));
kv->value->type = PMIX_DATA_ARRAY;
niptr = ninfo + 1; // need space for the rank
PMIX_DATA_ARRAY_CREATE(kv->value->data.darray, niptr, PMIX_INFO);
iptr = (pmix_info_t*)kv->value->data.darray->array;
/* start with the rank */
PMIX_INFO_LOAD(&iptr[0], PMIX_RANK, &rnk, PMIX_PROC_RANK);
/* now transfer rest of data across */
for (n=0; n < ninfo; n++) {
PMIX_INFO_XFER(&iptr[n+1], &info[n]);
}
/* add to the results */
pmix_list_append(kvs, &kv->super);
/* release the search result */
PMIX_LIST_DESTRUCT(&rkvs);
}
return PMIX_SUCCESS;
}

Просмотреть файл

@ -16,5 +16,4 @@ headers += \
libmca_pcompress_la_SOURCES += \
base/pcompress_base_frame.c \
base/pcompress_base_select.c \
base/pcompress_base_fns.c
base/pcompress_base_select.c

Просмотреть файл

@ -74,11 +74,6 @@ PMIX_EXPORT extern pmix_compress_base_t pmix_compress_base;
PMIX_EXPORT extern pmix_mca_base_framework_t pmix_pcompress_base_framework;
PMIX_EXPORT extern pmix_compress_base_module_t pmix_compress;
/**
*
*/
PMIX_EXPORT int pmix_compress_base_tar_create(char ** target);
PMIX_EXPORT int pmix_compress_base_tar_extract(char ** target);
#if defined(c_plusplus) || defined(__cplusplus)
}

Просмотреть файл

@ -1,138 +0,0 @@
/*
* Copyright (c) 2004-2010 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
*
* Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
* Copyright (c) 2019 Intel, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "pmix_config.h"
#include <string.h>
#include <sys/wait.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include "pmix_common.h"
#include "src/mca/mca.h"
#include "src/mca/base/base.h"
#include "src/util/os_dirpath.h"
#include "src/util/output.h"
#include "src/util/argv.h"
#include "src/util/printf.h"
#include "src/mca/pcompress/pcompress.h"
#include "src/mca/pcompress/base/base.h"
/******************
* Local Function Defs
******************/
/******************
* Object stuff
******************/
int pmix_compress_base_tar_create(char ** target)
{
int exit_status = PMIX_SUCCESS;
char *tar_target = NULL;
char **argv = NULL;
pid_t child_pid = 0;
int status = 0;
pmix_asprintf(&tar_target, "%s.tar", *target);
child_pid = fork();
if( 0 == child_pid ) { /* Child */
char *cmd;
pmix_asprintf(&cmd, "tar -cf %s %s", tar_target, *target);
argv = pmix_argv_split(cmd, ' ');
status = execvp(argv[0], argv);
pmix_output(0, "compress:base: Tar:: Failed to exec child [%s] status = %d\n", cmd, status);
exit(PMIX_ERROR);
}
else if(0 < child_pid) {
waitpid(child_pid, &status, 0);
if( !WIFEXITED(status) ) {
exit_status = PMIX_ERROR;
goto cleanup;
}
free(*target);
*target = strdup(tar_target);
}
else {
exit_status = PMIX_ERROR;
goto cleanup;
}
cleanup:
if( NULL != tar_target ) {
free(tar_target);
}
return exit_status;
}
int pmix_compress_base_tar_extract(char ** target)
{
int exit_status = PMIX_SUCCESS;
char **argv = NULL;
pid_t child_pid = 0;
int status = 0;
child_pid = fork();
if( 0 == child_pid ) { /* Child */
char *cmd;
pmix_asprintf(&cmd, "tar -xf %s", *target);
argv = pmix_argv_split(cmd, ' ');
status = execvp(argv[0], argv);
pmix_output(0, "compress:base: Tar:: Failed to exec child [%s] status = %d\n", cmd, status);
exit(PMIX_ERROR);
}
else if(0 < child_pid) {
waitpid(child_pid, &status, 0);
if( !WIFEXITED(status) ) {
exit_status = PMIX_ERROR;
goto cleanup;
}
/* Strip off the '.tar' */
(*target)[strlen(*target)-4] = '\0';
}
else {
exit_status = PMIX_ERROR;
goto cleanup;
}
cleanup:
return exit_status;
}
/******************
* Local Functions
******************/

Просмотреть файл

@ -82,7 +82,7 @@ bool pmix_compress_zlib_compress_block(char *instring,
rc = deflate (&strm, Z_FINISH);
deflateEnd (&strm);
if (Z_OK != rc) {
if (Z_OK != rc && Z_STREAM_END != rc) {
free(tmp);
return false;
}

Просмотреть файл

@ -28,7 +28,7 @@
#include "src/mca/pnet/base/base.h"
static pmix_status_t process_maps(char *nspace, char *nregex, char *pregex);
static pmix_status_t process_maps(char *nspace, char **nodes, char **procs);
/* NOTE: a tool (e.g., prun) may call this function to
* harvest local envars for inclusion in a call to
@ -42,7 +42,7 @@ pmix_status_t pmix_pnet_base_allocate(char *nspace,
pmix_status_t rc = PMIX_SUCCESS;
pmix_namespace_t *nptr, *ns;
size_t n;
char *nregex, *pregex;
char **nodes, **procs;
char *params[2] = {"PMIX_MCA_", NULL};
if (!pmix_pnet_globals.initialized) {
@ -78,16 +78,22 @@ pmix_status_t pmix_pnet_base_allocate(char *nspace,
if (NULL != info) {
/* check for description of the node and proc maps */
nregex = NULL;
pregex = NULL;
nodes = NULL;
procs = NULL;
for (n=0; n < ninfo; n++) {
if (0 == strncmp(info[n].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN)) {
nregex = info[n].value.data.string;
} else if (0 == strncmp(info[n].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN)) {
pregex = info[n].value.data.string;
if (PMIX_CHECK_KEY(&info[n], PMIX_NODE_MAP)) {
rc = pmix_preg.parse_nodes(info[n].value.data.bo.bytes, &nodes);
if (PMIX_SUCCESS != rc) {
return rc;
}
} else if (PMIX_CHECK_KEY(&info[n], PMIX_PROC_MAP)) {
rc = pmix_preg.parse_procs(info[n].value.data.bo.bytes, &procs);
if (PMIX_SUCCESS != rc) {
return rc;
}
}
}
if (NULL != nregex && NULL != pregex) {
if (NULL != nodes && NULL != procs) {
/* assemble the pnet node and proc descriptions
* NOTE: this will eventually be folded into the
* new shared memory system, but we do it here
@ -95,7 +101,9 @@ pmix_status_t pmix_pnet_base_allocate(char *nspace,
* the host will not have registered the clients
* and nspace prior to calling allocate
*/
rc = process_maps(nspace, nregex, pregex);
rc = process_maps(nspace, nodes, procs);
pmix_argv_free(nodes);
pmix_argv_free(procs);
if (PMIX_SUCCESS != rc) {
return rc;
}
@ -596,9 +604,9 @@ pmix_status_t pmix_pnet_base_harvest_envars(char **incvars, char **excvars,
return PMIX_SUCCESS;
}
static pmix_status_t process_maps(char *nspace, char *nregex, char *pregex)
static pmix_status_t process_maps(char *nspace, char **nodes, char **procs)
{
char **nodes, **procs, **ranks;
char **ranks;
pmix_status_t rc;
size_t m, n;
pmix_pnet_job_t *jptr, *job;
@ -608,27 +616,10 @@ static pmix_status_t process_maps(char *nspace, char *nregex, char *pregex)
PMIX_ACQUIRE_THREAD(&pmix_pnet_globals.lock);
/* parse the regex to get the argv array of node names */
if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(nregex, &nodes))) {
PMIX_ERROR_LOG(rc);
PMIX_RELEASE_THREAD(&pmix_pnet_globals.lock);
return rc;
}
/* parse the regex to get the argv array of proc ranks on each node */
if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(pregex, &procs))) {
PMIX_ERROR_LOG(rc);
pmix_argv_free(nodes);
PMIX_RELEASE_THREAD(&pmix_pnet_globals.lock);
return rc;
}
/* bozo check */
if (pmix_argv_count(nodes) != pmix_argv_count(procs)) {
rc = PMIX_ERR_BAD_PARAM;
PMIX_ERROR_LOG(rc);
pmix_argv_free(nodes);
pmix_argv_free(procs);
PMIX_RELEASE_THREAD(&pmix_pnet_globals.lock);
return rc;
}
@ -705,9 +696,6 @@ static pmix_status_t process_maps(char *nspace, char *nregex, char *pregex)
pmix_argv_free(ranks);
}
pmix_argv_free(nodes);
pmix_argv_free(procs);
PMIX_RELEASE_THREAD(&pmix_pnet_globals.lock);
return PMIX_SUCCESS;
}

Просмотреть файл

@ -98,6 +98,7 @@ typedef struct {
pmix_list_item_t super;
char *name;
int index;
bool onswitch;
void *node; // pointer to node hosting this nic
void *s; // pointer to switch hosting this port, or
// pointer to switch this nic is attached to
@ -108,6 +109,7 @@ static void ncon(pnet_nic_t *p)
{
p->name = NULL;
p->index = -1;
p->onswitch = false;
p->node = NULL;
p->s = NULL;
p->plane = NULL;
@ -155,6 +157,7 @@ typedef struct {
int index;
bool dense;
int nswitches;
int nportsperswitch;
uint64_t nverts;
uint16_t **costmatrix;
pmix_list_t switches;
@ -167,6 +170,7 @@ static void pcon(pnet_plane_t *p)
p->index = -1;
p->dense = false;
p->nswitches = 0;
p->nportsperswitch = 0;
p->nverts = 0;
p->costmatrix = NULL;
PMIX_CONSTRUCT(&p->switches, pmix_list_t);
@ -217,20 +221,12 @@ static pmix_list_t myplanes;
static pmix_list_t mynodes;
static pmix_pointer_array_t myfabrics;
static pmix_pointer_array_t mynics;
static pmix_pointer_array_t mysws;
static char **myenvlist = NULL;
static char **myvalues = NULL;
static pmix_status_t test_init(void)
{
int n, r, ns, nplane, nnodes, nports;
uint64_t n64, m64;
char **system=NULL, **ptr;
pnet_plane_t *p;
pnet_switch_t *s, *s2;
pnet_nic_t *nic, *nic2;
pnet_node_t *node;
pmix_status_t rc;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: test init");
@ -240,221 +236,10 @@ static pmix_status_t test_init(void)
pmix_pointer_array_init(&myfabrics, 1, INT_MAX, 1);
PMIX_CONSTRUCT(&mynics, pmix_pointer_array_t);
pmix_pointer_array_init(&mynics, 8, INT_MAX, 8);
PMIX_CONSTRUCT(&mysws, pmix_pointer_array_t);
pmix_pointer_array_init(&mysws, 8, INT_MAX, 8);
/* if we have a config file, read it now */
if (NULL != mca_pnet_test_component.cfg_file) {
} else if (NULL != mca_pnet_test_component.nverts) {
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: test creating system configuration");
/* the system description is configured as nodes and fabric planes
* delineated by semi-colons */
system = pmix_argv_split(mca_pnet_test_component.nverts, ';');
/* there can be multiple planes defined, but only one set of
* nodes. The nodes description contains the #nodes - we assume
* that each node has a single NIC attached to each fabric plane.
* Thus, the nodes entry has a single field associated with it that
* contains the number of nodes in the system.
*
* Similarly, we assume that each switch in the plane contains
* a port to connect to each node in the system. For simplicity,
* we assume a ring connection topology between the switches and
* reserve one port on each switch to connect to its "left" peer
* and another to connect to its "right" peer.
*
* Thus, the #NICS in a node equals the number of planes in the
* overall system. The #ports in a switch equals the #nodes in
* the system plus two for cross-switch communications.
*/
for (r=0; NULL != system[r]; r++) {
if (0 == strncasecmp(system[r], "nodes", 5)) {
/* the number of nodes must follow the colon after "nodes" */
nnodes = strtoul(&system[r][6], NULL, 10);
for (n=0; n < nnodes; n++) {
node = PMIX_NEW(pnet_node_t);
if (0 > asprintf(&node->name, "test%03d", n)) {
rc = PMIX_ERR_NOMEM;
PMIX_RELEASE(node);
goto cleanup;
}
pmix_list_append(&mynodes, &node->super);
}
} else if (0 == strncasecmp(system[r], "plane", 5)) {
/* create a plane object */
p = PMIX_NEW(pnet_plane_t);
/* the plane contains a flag indicating how the nodes
* are to be distributed across the plane plus the
* number of switches in the plane */
ptr = pmix_argv_split(&system[r][6], ':');
if (1 == pmix_argv_count(ptr)) {
/* default to dense */
p->dense = true;
p->nswitches = strtoul(ptr[0], NULL, 10);
} else {
if ('d' == ptr[0][0] || 'D' == ptr[0][0]) {
p->dense = true;
}
p->nswitches = strtoul(ptr[1], NULL, 10);
}
pmix_argv_free(ptr);
pmix_list_append(&myplanes, &p->super);
} else {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
rc = PMIX_ERR_BAD_PARAM;
goto cleanup;
}
}
/* setup the ports in each switch for each plane */
nplane = 0;
PMIX_LIST_FOREACH(p, &myplanes, pnet_plane_t) {
/* assign a name to the plane */
if (0 > asprintf(&p->name, "plane%03d", nplane)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
p->index = nplane;
for (n=0; n < p->nswitches; n++) {
s = PMIX_NEW(pnet_switch_t);
if (0 > asprintf(&s->name, "%s:switch%03d", p->name, n)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
s->index = n;
s->plane = p;
pmix_list_append(&p->switches, &s->super);
}
/* now cycle across the nodes and setup their connections
* to the switches */
if (p->dense) {
/* setup the ports on the switches */
nports = nnodes / p->nswitches;
/* if it didn't divide evenly, then we have to add
* one to each switch to ensure we have enough ports */
if (0 != nnodes % p->nswitches) {
++nports;
}
/* connect each successive node to the same switch
* until that switch is full - then move to the next */
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
ns = nports;
PMIX_LIST_FOREACH(node, &mynodes, pnet_node_t) {
nic2 = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic2->name, "%s:nic.%s.0", node->name, p->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
--ns;
nic2->node = node;
nic2->s = s;
nic2->plane = p;
nic2->index = pmix_pointer_array_add(&mynics, nic2);
PMIX_RETAIN(nic2);
pmix_list_append(&node->nics, &nic2->super);
/* create a corresponding link on the switch */
nic = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic->name, "%s:nic.0", s->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
pmix_list_append(&s->ports, &nic->super);
nic2->link = nic;
nic->link = nic2;
if (0 == ns) {
/* move to the next switch */
s = (pnet_switch_t*)pmix_list_get_next(&s->super);
if (NULL == s || (pnet_switch_t*)pmix_list_get_end(&p->switches) == s) {
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
}
nic = (pnet_nic_t*)pmix_list_get_first(&s->ports);
ns = nports;
}
}
} else {
/* connect the nodes to the switches in a round-robin manner */
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
PMIX_LIST_FOREACH(node, &mynodes, pnet_node_t) {
nic2 = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic2->name, "%s:nic.%s.0", node->name, p->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
--ns;
nic2->node = node;
nic2->s = s;
nic2->plane = p;
nic2->index = pmix_pointer_array_add(&mynics, nic2);
PMIX_RETAIN(nic2);
pmix_list_append(&node->nics, &nic2->super);
/* create a corresponding link on the switch */
nic = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic->name, "%s:nic.0", s->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
pmix_list_append(&s->ports, &nic->super);
nic2->link = nic;
nic->link = nic2;
/* move to the next switch */
s = (pnet_switch_t*)pmix_list_get_next(&s->super);
/* if we are at the end, rotate around to the first */
if (NULL == s || (pnet_switch_t*)pmix_list_get_end(&p->switches) == s) {
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
}
}
}
/* setup the cost matrix - we assume switch-to-switch hops
* have a cost of 1, as do all node-to-switch hops */
p->nverts = nnodes; // we ignore the switch ports for now
p->costmatrix = (uint16_t**)malloc(p->nverts * sizeof(uint16_t*));
for (n64=0; n64 < p->nverts; n64++) {
p->costmatrix[n64] = malloc(p->nverts * sizeof(uint16_t));
}
/* fill the matrix with the #hops between each NIC, keeping it symmetric */
for (n64=0; n64 < p->nverts; n64++) {
p->costmatrix[n64][n64] = 0;
nic = (pnet_nic_t*)pmix_pointer_array_get_item(&mynics, n64);
if (NULL == nic) {
PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND);
continue;
}
for (m64=n64+1; m64 < p->nverts; m64++) {
nic2 = (pnet_nic_t*)pmix_pointer_array_get_item(&mynics, m64);
if (NULL == nic2) {
PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND);
continue;
}
/* if they are on the same switch, then cost is 2 */
if (nic->s == nic2->s) {
p->costmatrix[n64][m64] = 2;
} else {
/* the cost is increased by the distance
* between switches */
s = (pnet_switch_t*)nic->s;
s2 = (pnet_switch_t*)nic2->s;
if (s->index > s2->index) {
p->costmatrix[n64][m64] = 2 + s->index - s2->index;
} else {
p->costmatrix[n64][m64] = 2 + s2->index - s->index;
}
}
p->costmatrix[m64][n64] = p->costmatrix[n64][m64];
}
}
++nplane;
}
pmix_argv_free(system);
system = NULL;
}
rc = PMIX_SUCCESS;
cleanup:
if (NULL != system) {
pmix_argv_free(system);
}
return rc;
return PMIX_SUCCESS;
}
static void test_finalize(void)
@ -482,6 +267,241 @@ static void test_finalize(void)
PMIX_LIST_DESTRUCT(&myplanes);
}
static pmix_status_t build_topo(char **nodes)
{
int n, r, ns, nplane, nports;
uint64_t n64, m64;
char **system=NULL, **ptr;
pnet_plane_t *p;
pnet_switch_t *s, *s2;
pnet_nic_t *nic, *nic2;
pnet_node_t *node, *nd, *nd2;
pmix_status_t rc=PMIX_SUCCESS;
bool update = false;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: test creating system configuration");
/* setup the list of nodes */
for (n=0; NULL != nodes[n]; n++) {
/* check to see if this node is already on our list */
nd = NULL;
PMIX_LIST_FOREACH(nd2, &mynodes, pnet_node_t) {
if (0 == strcmp(nd2->name, nodes[n])) {
nd = nd2;
break;
}
}
if (NULL == nd) {
/* add it */
nd = PMIX_NEW(pnet_node_t);
nd->name = strdup(nodes[n]);
pmix_list_append(&mynodes, &nd->super);
update = true;
}
}
if (!update) {
return PMIX_SUCCESS;
}
/* the system description is configured as nodes and fabric planes
* delineated by semi-colons */
system = pmix_argv_split(mca_pnet_test_component.planes, ';');
/* there can be multiple planes defined.
* We assume that each switch in the plane contains
* a port to connect to each node in the system. For simplicity,
* we assume a ring connection topology between the switches.
*
* Thus, the #NICS in a node equals the number of planes in the
* overall system.
*/
for (r=0; NULL != system[r]; r++) {
/* create a plane object */
p = PMIX_NEW(pnet_plane_t);
/* the plane contains a flag indicating how the nodes
* are to be distributed across the plane plus the
* number of switches in the plane and the number of
* ports/switch */
ptr = pmix_argv_split(&system[r][6], ':');
if (1 == pmix_argv_count(ptr)) {
/* just gave us #switches - default to dense
* with 3 ports/switch */
p->dense = true;
p->nswitches = strtoul(ptr[0], NULL, 10);
p->nportsperswitch = 3;
} else if (2 == pmix_argv_count(ptr)) {
/* gave us density and #switches */
if ('d' == ptr[0][0] || 'D' == ptr[0][0]) {
p->dense = true;
}
p->nswitches = strtoul(ptr[1], NULL, 10);
p->nportsperswitch = 3;
} else {
if ('d' == ptr[0][0] || 'D' == ptr[0][0]) {
p->dense = true;
}
p->nswitches = strtoul(ptr[1], NULL, 10);
p->nportsperswitch = strtoul(ptr[2], NULL, 10);
}
pmix_argv_free(ptr);
pmix_list_append(&myplanes, &p->super);
}
/* setup the ports in each switch for each plane */
nplane = 0;
PMIX_LIST_FOREACH(p, &myplanes, pnet_plane_t) {
/* assign a name to the plane */
if (0 > asprintf(&p->name, "plane%03d", nplane)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
p->index = nplane;
for (n=0; n < p->nswitches; n++) {
s = PMIX_NEW(pnet_switch_t);
if (0 > asprintf(&s->name, "%s:switch%03d", p->name, n)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
s->index = pmix_pointer_array_add(&mysws, s);
s->plane = p;
PMIX_RETAIN(s);
pmix_list_append(&p->switches, &s->super);
}
/* now cycle across the nodes and setup their connections
* to the switches */
if (p->dense) {
/* setup the ports on the switches */
nports = p->nportsperswitch;
/* connect each successive node to the same switch
* until that switch is full - then move to the next */
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
ns = nports;
PMIX_LIST_FOREACH(node, &mynodes, pnet_node_t) {
nic2 = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic2->name, "%s:nic.%s.0", node->name, p->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
nic2->node = node;
nic2->s = s;
nic2->plane = p;
nic2->index = pmix_pointer_array_add(&mynics, nic2);
PMIX_RETAIN(nic2);
pmix_list_append(&node->nics, &nic2->super);
p->nverts++;
/* create a corresponding link on the switch */
nic = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic->name, "%s:nic.0", s->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
nic->s = s;
nic->onswitch = true;
nic->index = pmix_pointer_array_add(&mynics, nic);
PMIX_RETAIN(nic);
pmix_list_append(&s->ports, &nic->super);
nic2->link = nic;
nic->link = nic2;
--ns;
if (0 == ns) {
/* move to the next switch */
s = (pnet_switch_t*)pmix_list_get_next(&s->super);
if (NULL == s || (pnet_switch_t*)pmix_list_get_end(&p->switches) == s) {
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
/* add one per switch as we have overrun their initial value */
ns = 1;
} else {
ns = nports;
}
nic = (pnet_nic_t*)pmix_list_get_first(&s->ports);
}
}
} else {
/* connect the nodes to the switches in a round-robin manner */
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
PMIX_LIST_FOREACH(node, &mynodes, pnet_node_t) {
nic2 = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic2->name, "%s:nic.%s.0", node->name, p->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
nic2->node = node;
nic2->s = s;
nic2->plane = p;
nic2->index = pmix_pointer_array_add(&mynics, nic2);
PMIX_RETAIN(nic2);
pmix_list_append(&node->nics, &nic2->super);
p->nverts++;
/* create a corresponding link on the switch */
nic = PMIX_NEW(pnet_nic_t);
if (0 > asprintf(&nic->name, "%s:nic.0", s->name)) {
rc = PMIX_ERR_NOMEM;
goto cleanup;
}
nic->s = s;
nic->onswitch = true;
nic->index = pmix_pointer_array_add(&mynics, nic);
PMIX_RETAIN(nic);
pmix_list_append(&s->ports, &nic->super);
nic2->link = nic;
nic->link = nic2;
/* move to the next switch */
s = (pnet_switch_t*)pmix_list_get_next(&s->super);
/* if we are at the end, rotate around to the first */
if (NULL == s || (pnet_switch_t*)pmix_list_get_end(&p->switches) == s) {
s = (pnet_switch_t*)pmix_list_get_first(&p->switches);
}
}
}
/* setup the cost matrix - we assume switch-to-switch hops
* have a cost of 1, as do all node-to-switch hops */
p->costmatrix = (uint16_t**)malloc(p->nverts * sizeof(uint16_t*));
for (n64=0; n64 < p->nverts; n64++) {
p->costmatrix[n64] = malloc(p->nverts * sizeof(uint16_t));
}
/* fill the matrix with the #hops between each NIC, keeping it symmetric */
for (n64=0; n64 < (uint64_t)mynics.size; n64++) {
nic = (pnet_nic_t*)pmix_pointer_array_get_item(&mynics, n64);
if (NULL == nic || p != nic->plane || !nic->onswitch) {
continue;
}
p->costmatrix[n64][n64] = 0;
for (m64=n64+1; m64 < (uint64_t)mynics.size; m64++) {
nic2 = (pnet_nic_t*)pmix_pointer_array_get_item(&mynics, m64);
if (NULL == nic2 || p != nic2->plane || !nic2->onswitch) {
continue;
}
/* if they are on the same switch, then cost is 2 */
if (nic->s == nic2->s) {
p->costmatrix[n64][m64] = 2;
} else {
/* the cost is increased by the distance
* between switches */
s = (pnet_switch_t*)nic->s;
s2 = (pnet_switch_t*)nic2->s;
if (s->index > s2->index) {
p->costmatrix[n64][m64] = 2 + s->index - s2->index;
} else {
p->costmatrix[n64][m64] = 2 + s2->index - s->index;
}
}
p->costmatrix[m64][n64] = p->costmatrix[n64][m64];
}
}
++nplane;
}
pmix_argv_free(system);
system = NULL;
cleanup:
if (NULL != system) {
pmix_argv_free(system);
}
return rc;
}
/* NOTE: if there is any binary data to be transferred, then
* this function MUST pack it for transport as the host will
* not know how to do so */
@ -674,6 +694,13 @@ static pmix_status_t allocate(pmix_namespace_t *nptr,
"pnet:test:allocate assigning endpoints for nspace %s",
nptr->nspace);
/* setup the topology */
rc = build_topo(nodes);
if (PMIX_SUCCESS != rc) {
PMIX_ERROR_LOG(rc);
goto cleanup;
}
/* cycle across the nodes and add the endpoints
* for each proc on the node - we assume the same
* list of static endpoints on each node */
@ -693,14 +720,10 @@ static pmix_status_t allocate(pmix_namespace_t *nptr,
}
}
if (NULL == nd) {
/* we don't have this node in our list - so since this
* is a mockup, take the nth node in the list of nodes
* we know about */
p = n % pmix_list_get_size(&mynodes);
nd = (pnet_node_t*)pmix_list_get_first(&mynodes);
for (m=0; m < p; m++) {
nd = (pnet_node_t*)pmix_list_get_next(&nd->super);
}
/* should be impossible */
rc = PMIX_ERR_NOT_FOUND;
PMIX_ERROR_LOG(rc);
goto cleanup;
}
kv = PMIX_NEW(pmix_kval_t);
if (NULL == kv) {
@ -773,14 +796,16 @@ static pmix_status_t allocate(pmix_namespace_t *nptr,
"pnet:test:allocate assigning %d coordinates for rank %u",
(int)q, rank);
for (p=0; p < q; p++) {
pln = (pnet_plane_t*)nic->plane;
sw = (pnet_switch_t*)nic->s;
coords[p].fabric = strdup("test");
coords[p].plane = strdup(pln->name);
coords[p].view = PMIX_COORD_LOGICAL_VIEW;
coords[p].dims = 3;
coords[p].coord = (int*)malloc(3 * sizeof(int));
pln = (pnet_plane_t*)nic->plane;
coords[p].coord[0] = pln->index;
sw = (pnet_switch_t*)nic->s;
coords[p].coord[2] = pln->index;
coords[p].coord[1] = sw->index;
coords[p].coord[2] = nic->index;
coords[p].coord[0] = ((pnet_nic_t*)nic->link)->index;
nic = (pnet_nic_t*)pmix_list_get_next(&nic->super);
}
}

Просмотреть файл

@ -20,8 +20,7 @@ BEGIN_C_DECLS
typedef struct {
pmix_pnet_base_component_t super;
char *cfg_file;
char *nverts;
char *planes;
uint16_t **costmatrix;
} pmix_pnet_test_component_t;

Просмотреть файл

@ -65,8 +65,7 @@ pmix_pnet_test_component_t mca_pnet_test_component = {
PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT
}
},
.cfg_file = NULL,
.nverts = NULL,
.planes = NULL,
.costmatrix = NULL
};
@ -74,19 +73,14 @@ static pmix_status_t component_register(void)
{
pmix_mca_base_component_t *component = &mca_pnet_test_component.super.base;
(void)pmix_mca_base_component_var_register(component, "cfg_file",
"Comma-delimited list of files containing descriptions of the test fabric, one plane per file",
(void)pmix_mca_base_component_var_register(component, "planes",
"Comma-delimited list describing each fabric plane in format\n"
"plane:<(d)ense or (s)parse>:#switches:#ports(defaults to 3+fit) - examples:\n"
"\tplane:d:3:4,plane:s:2,plane:3",
PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
PMIX_INFO_LVL_2,
PMIX_MCA_BASE_VAR_SCOPE_READONLY,
&mca_pnet_test_component.cfg_file);
(void)pmix_mca_base_component_var_register(component, "nverts",
"Comma-delimited list of number of vertices in each fabric plane (if no cfg file given)",
PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
PMIX_INFO_LVL_2,
PMIX_MCA_BASE_VAR_SCOPE_READONLY,
&mca_pnet_test_component.nverts);
&mca_pnet_test_component.planes);
return PMIX_SUCCESS;
}
@ -95,6 +89,12 @@ static pmix_status_t component_open(void)
int index;
const pmix_mca_base_var_storage_t *value=NULL;
if (NULL == mca_pnet_test_component.planes) {
/* nothing we can do without a description
* of the fabric topology */
return PMIX_ERROR;
}
/* we only allow ourselves to be considered IF the user
* specifically requested so */
if (0 > (index = pmix_mca_base_var_find("pmix", "pnet", NULL, NULL))) {
@ -102,7 +102,7 @@ static pmix_status_t component_open(void)
}
pmix_mca_base_var_get_value(index, &value, NULL, NULL);
if (NULL != value && NULL != value->stringval && '\0' != value->stringval[0]) {
if (NULL != strstr(value->stringval, "test")) {
if (NULL != strcasestr(value->stringval, "test")) {
return PMIX_SUCCESS;
}
}

Просмотреть файл

@ -11,7 +11,7 @@
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
* Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
* Copyright (c) 2014-2019 Intel, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
@ -91,6 +91,18 @@ PMIX_EXPORT pmix_status_t pmix_preg_base_resolve_peers(const char *nodename,
PMIX_EXPORT pmix_status_t pmix_preg_base_resolve_nodes(const char *nspace,
char **nodelist);
PMIX_EXPORT pmix_status_t pmix_preg_base_copy(char **dest, size_t *len, const char *input);
PMIX_EXPORT pmix_status_t pmix_preg_base_pack(pmix_buffer_t *buffer, const char *input);
PMIX_EXPORT pmix_status_t pmix_preg_base_unpack(pmix_buffer_t *buffer, char **regex);
PMIX_EXPORT pmix_status_t pmix_preg_base_std_resolve_peers(const char *nodename,
const char *nspace,
pmix_proc_t **procs, size_t *nprocs);
PMIX_EXPORT pmix_status_t pmix_preg_base_std_resolve_nodes(const char *nspace,
char **nodelist);
END_C_DECLS

Просмотреть файл

@ -11,7 +11,7 @@
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved.
* Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
* Copyright (c) 2014-2019 Intel, Inc. All rights reserved.
* Copyright (c) 2015-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2019 IBM Corporation. All rights reserved.
@ -52,7 +52,10 @@ pmix_preg_module_t pmix_preg = {
.parse_nodes = pmix_preg_base_parse_nodes,
.parse_procs = pmix_preg_base_parse_procs,
.resolve_peers = pmix_preg_base_resolve_peers,
.resolve_nodes = pmix_preg_base_resolve_nodes
.resolve_nodes = pmix_preg_base_resolve_nodes,
.copy = pmix_preg_base_copy,
.pack = pmix_preg_base_pack,
.unpack = pmix_preg_base_unpack
};
static pmix_status_t pmix_preg_close(void)

Просмотреть файл

@ -9,7 +9,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2015-2017 Intel, Inc. All rights reserved.
* Copyright (c) 2015-2019 Intel, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -27,7 +27,7 @@
#include "src/util/argv.h"
#include "src/util/error.h"
#include "src/include/pmix_globals.h"
#include "src/client/pmix_client_ops.h"
#include "src/mca/preg/base/base.h"
pmix_status_t pmix_preg_base_generate_node_regex(const char *input,
@ -126,3 +126,204 @@ pmix_status_t pmix_preg_base_resolve_nodes(const char *nspace,
return PMIX_ERR_NOT_SUPPORTED;
}
pmix_status_t pmix_preg_base_copy(char **dest, size_t *len, const char *input)
{
pmix_preg_base_active_module_t *active;
PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) {
if (NULL != active->module->copy) {
if (PMIX_SUCCESS == active->module->copy(dest, len, input)) {
return PMIX_SUCCESS;
}
}
}
return PMIX_ERR_NOT_SUPPORTED;
}
pmix_status_t pmix_preg_base_pack(pmix_buffer_t *buffer, const char *input)
{
pmix_preg_base_active_module_t *active;
PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) {
if (NULL != active->module->pack) {
if (PMIX_SUCCESS == active->module->pack(buffer, input)) {
return PMIX_SUCCESS;
}
}
}
return PMIX_ERR_NOT_SUPPORTED;
}
pmix_status_t pmix_preg_base_unpack(pmix_buffer_t *buffer, char **regex)
{
pmix_preg_base_active_module_t *active;
PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) {
if (NULL != active->module->unpack) {
if (PMIX_SUCCESS == active->module->unpack(buffer, regex)) {
return PMIX_SUCCESS;
}
}
}
return PMIX_ERR_NOT_SUPPORTED;
}
pmix_status_t pmix_preg_base_std_resolve_peers(const char *nodename,
const char *nspace,
pmix_proc_t **procs, size_t *nprocs)
{
pmix_cb_t cb;
pmix_status_t rc;
pmix_kval_t *kv;
pmix_proc_t proc;
char **ptr;
pmix_info_t *info;
pmix_proc_t *p=NULL;
size_t ninfo, np=0, n, j;
PMIX_CONSTRUCT(&cb, pmix_cb_t);
cb.key = strdup(nodename);
/* this data isn't going anywhere, so we don't require a copy */
cb.copy = false;
/* scope is irrelevant as the info we seek must be local */
cb.scope = PMIX_SCOPE_UNDEF;
/* let the proc point to the nspace */
pmix_strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN);
proc.rank = PMIX_RANK_WILDCARD;
cb.proc = &proc;
PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, &cb);
if (PMIX_SUCCESS != rc) {
if (PMIX_ERR_INVALID_NAMESPACE != rc) {
PMIX_ERROR_LOG(rc);
}
goto complete;
}
/* should just be the one value on the list */
if (1 != pmix_list_get_size(&cb.kvs)) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
rc = PMIX_ERR_BAD_PARAM;
goto complete;
}
kv = (pmix_kval_t*)pmix_list_get_first(&cb.kvs);
/* the hostname used as a key with wildcard rank will return
* a pmix_data_array_t of pmix_info_t structs */
if (NULL == kv->value ||
PMIX_DATA_ARRAY != kv->value->type ||
NULL == kv->value->data.darray ||
PMIX_INFO != kv->value->data.darray->type) {
PMIX_ERROR_LOG(PMIX_ERR_DATA_VALUE_NOT_FOUND);
rc = PMIX_ERR_DATA_VALUE_NOT_FOUND;
goto complete;
}
info = (pmix_info_t*)kv->value->data.darray->array;
ninfo = kv->value->data.darray->size;
/* find the PMIX_LOCAL_PEERS key */
for (n=0; n < ninfo; n++) {
if (0 == strncmp(info[n].key, PMIX_LOCAL_PEERS, PMIX_MAX_KEYLEN)) {
/* split the string */
ptr = pmix_argv_split(info[n].value.data.string, ',');
np = pmix_argv_count(ptr);
PMIX_PROC_CREATE(p, np);
if (NULL == p) {
rc = PMIX_ERR_NOMEM;
pmix_argv_free(ptr);
goto complete;
}
for (j=0; j < np; j++) {
pmix_strncpy(p[j].nspace, nspace, PMIX_MAX_NSLEN);
p[j].rank = strtoul(ptr[j], NULL, 10);
}
rc = PMIX_SUCCESS;
pmix_argv_free(ptr);
break;
}
}
complete:
if (NULL != cb.info) {
PMIX_INFO_FREE(cb.info, cb.ninfo);
}
if (NULL != cb.key) {
free(cb.key);
cb.key = NULL;
}
PMIX_DESTRUCT(&cb);
*procs = p;
*nprocs = np;
return rc;
}
pmix_status_t pmix_preg_base_std_resolve_nodes(const char *nspace,
char **nodelist)
{
pmix_cb_t cb;
pmix_status_t rc;
pmix_kval_t *kv;
pmix_proc_t proc;
PMIX_CONSTRUCT(&cb, pmix_cb_t);
/* setup default answer */
*nodelist = NULL;
/* create a pmix_info_t so we can pass the nspace
* into the fetch as a qualifier */
PMIX_INFO_CREATE(cb.info, 1);
if (NULL == cb.info) {
PMIX_DESTRUCT(&cb);
return PMIX_ERR_NOMEM;
}
cb.ninfo = 1;
PMIX_INFO_LOAD(&cb.info[0], PMIX_NSPACE, nspace, PMIX_STRING);
/* tell the GDS what we want */
cb.key = PMIX_NODE_MAP;
/* this data isn't going anywhere, so we don't require a copy */
cb.copy = false;
/* scope is irrelevant as the info we seek must be local */
cb.scope = PMIX_SCOPE_UNDEF;
/* put the nspace in the proc field */
pmix_strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN);
/* the info will be associated with PMIX_RANK_WILDCARD */
proc.rank = PMIX_RANK_WILDCARD;
cb.proc = &proc;
PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, &cb);
if (PMIX_SUCCESS != rc) {
PMIX_ERROR_LOG(rc);
goto complete;
}
/* should just be the one value on the list */
if (1 != pmix_list_get_size(&cb.kvs)) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
rc = PMIX_ERR_BAD_PARAM;
goto complete;
}
kv = (pmix_kval_t*)pmix_list_get_first(&cb.kvs);
/* the PMIX_NODE_MAP key is supposed to return
* a regex string - check that it did */
if (NULL == kv->value ||
PMIX_STRING != kv->value->type) {
PMIX_ERROR_LOG(PMIX_ERR_DATA_VALUE_NOT_FOUND);
rc = PMIX_ERR_DATA_VALUE_NOT_FOUND;
goto complete;
}
/* return the string */
if (NULL != kv->value->data.string) {
*nodelist = strdup(kv->value->data.string);
}
complete:
if (NULL != cb.info) {
PMIX_INFO_FREE(cb.info, cb.ninfo);
}
return rc;
}

Просмотреть файл

@ -0,0 +1,53 @@
# -*- makefile -*-
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
# Copyright (c) 2013-2019 Intel, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
headers = preg_compress.h
sources = \
preg_compress_component.c \
preg_compress.c
# Make the output library in this directory, and name it either
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
# (for static builds).
if MCA_BUILD_pmix_preg_compress_DSO
lib =
lib_sources =
component = mca_preg_compress.la
component_sources = $(headers) $(sources)
else
lib = libmca_preg_compress.la
lib_sources = $(headers) $(sources)
component =
component_sources =
endif
mcacomponentdir = $(pmixlibdir)
mcacomponent_LTLIBRARIES = $(component)
mca_preg_compress_la_SOURCES = $(component_sources)
mca_preg_compress_la_LDFLAGS = -module -avoid-version
if NEED_LIBPMIX
mca_preg_compress_la_LIBADD = $(top_builddir)/src/libpmix.la
endif
noinst_LTLIBRARIES = $(lib)
libmca_preg_compress_la_SOURCES = $(lib_sources)
libmca_preg_compress_la_LDFLAGS = -module -avoid-version

Просмотреть файл

@ -0,0 +1,281 @@
/*
* Copyright (c) 2015-2019 Intel, Inc. All rights reserved.
* Copyright (c) 2016-2019 IBM Corporation. All rights reserved.
* Copyright (c) 2018 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include <src/include/pmix_config.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <ctype.h>
#include <pmix_common.h>
#include <pmix.h>
#include "src/include/pmix_socket_errno.h"
#include "src/include/pmix_globals.h"
#include "src/util/argv.h"
#include "src/util/error.h"
#include "src/util/output.h"
#include "src/class/pmix_list.h"
#include "src/mca/bfrops/base/base.h"
#include "src/mca/gds/gds.h"
#include "src/client/pmix_client_ops.h"
#include "src/mca/pcompress/pcompress.h"
#include "src/mca/preg/base/base.h"
#include "preg_compress.h"
static pmix_status_t generate_node_regex(const char *input,
char **regex);
static pmix_status_t generate_ppn(const char *input,
char **ppn);
static pmix_status_t parse_nodes(const char *regexp,
char ***names);
static pmix_status_t parse_procs(const char *regexp,
char ***procs);
static pmix_status_t copy(char **dest, size_t *len, const char *input);
static pmix_status_t pack(pmix_buffer_t *buffer, const char *input);
static pmix_status_t unpack(pmix_buffer_t *buffer, char **regex);
pmix_preg_module_t pmix_preg_compress_module = {
.name = "compress",
.generate_node_regex = generate_node_regex,
.generate_ppn = generate_ppn,
.parse_nodes = parse_nodes,
.parse_procs = parse_procs,
.resolve_peers = pmix_preg_base_std_resolve_peers,
.resolve_nodes = pmix_preg_base_std_resolve_nodes,
.copy = copy,
.pack = pack,
.unpack = unpack
};
static pmix_status_t generate_node_regex(const char *input,
char **regexp)
{
char *result, *slen;
size_t len;
uint8_t *tmp;
if (!pmix_compress.compress_string((char*)input, &tmp, &len)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
if (NULL == tmp) {
return PMIX_ERR_NOMEM;
}
/* convert the length to a string */
if (0 > asprintf(&slen, "%lu", (unsigned long)len)) {
free(tmp);
return PMIX_ERR_NOMEM;
}
/* create the result */
result = calloc(len + 6 + strlen(slen) + 1, sizeof(char));
strcpy(result, "blob");
result[5] = ':';
strcpy(&result[6], slen);
memcpy(&result[6 + strlen(slen) + 1], tmp, len);
free(tmp);
free(slen);
*regexp = result;
return PMIX_SUCCESS;
}
static pmix_status_t generate_ppn(const char *input,
char **regexp)
{
char *result, *slen;
size_t len;
uint8_t *tmp;
if (!pmix_compress.compress_string((char*)input, &tmp, &len)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
if (NULL == tmp) {
return PMIX_ERR_NOMEM;
}
/* print the length */
if (0 > asprintf(&slen, "%lu", (unsigned long)len)) {
free(tmp);
return PMIX_ERR_NOT_FOUND;
}
/* create the result */
result = calloc(len + 6 + strlen(slen) + 1, sizeof(char));
strcpy(result, "blob");
/* leave a gap - calloc will have put a NULL in it */
result[5] = ':';
/* add the size */
strcpy(&result[6], slen);
/* leave a NULL gap at the end of the size */
memcpy(&result[6] + strlen(slen) + 1, tmp, len);
free(tmp);
*regexp = result;
return PMIX_SUCCESS;
}
static pmix_status_t parse_nodes(const char *regexp,
char ***names)
{
char *tmp, *ptr, **argv;
size_t len;
if (0 != strncmp(regexp, "blob", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
len = strtoul(&regexp[6], &ptr, 10);
++ptr; // step over NULL
if (NULL == ptr) {
return PMIX_ERR_BAD_PARAM;
}
/* malloc the space */
tmp = malloc(len);
if (NULL == tmp) {
return PMIX_ERR_NOMEM;
}
if (!pmix_compress.decompress_string(&tmp, (uint8_t*)ptr, len)) {
free(tmp);
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* tmp now contains the comma-delimited list of node names */
argv = pmix_argv_split(tmp, ',');
free(tmp);
*names = argv;
return PMIX_SUCCESS;
}
static pmix_status_t parse_procs(const char *regexp,
char ***procs)
{
char *tmp, *ptr, **argv;
size_t len;
if (0 != strncmp(regexp, "blob", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* extract the size */
len = strtoul(&regexp[6], &ptr, 10);
++ptr; // step over NULL
/* malloc the space */
tmp = malloc(len);
if (NULL == tmp) {
return PMIX_ERR_NOMEM;
}
if (!pmix_compress.decompress_string(&tmp, (uint8_t*)ptr, len)) {
free(tmp);
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* tmp now contains the semicolon-delimited list of procs */
argv = pmix_argv_split(tmp, ';');
free(tmp);
*procs = argv;
return PMIX_SUCCESS;
}
static pmix_status_t copy(char **dest, size_t *len, const char *input)
{
size_t slen;
char *tmp;
if (0 != strncmp(input, "blob", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* extract the size */
slen = strtoul(&input[6], NULL, 10) + 6 + strlen(&input[6]);
/* malloc the space */
tmp = malloc(slen);
if (NULL == tmp) {
return PMIX_ERR_NOMEM;
}
/* copy the data */
memcpy(tmp, input, slen);
*dest = tmp;
*len = slen;
return PMIX_SUCCESS;
}
static pmix_status_t pack(pmix_buffer_t *buffer, const char *input)
{
size_t slen;
char *ptr;
if (0 != strncmp(input, "blob", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* extract the size */
slen = strtoul(&input[6], NULL, 10) + 6 + strlen(&input[6]);
/* ensure the buffer has enough space */
ptr = pmix_bfrop_buffer_extend(buffer, slen);
if (NULL == ptr) {
return PMIX_ERR_NOMEM;
}
/* xfer the data */
memcpy(ptr, input, slen);
buffer->bytes_used += slen;
buffer->pack_ptr += slen;
return PMIX_SUCCESS;
}
static pmix_status_t unpack(pmix_buffer_t *buffer, char **regex)
{
size_t slen;
char *ptr, *output;
/* the value starts at the unpack_ptr */
ptr = buffer->unpack_ptr;
if (0 != strncmp(ptr, "blob", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* extract the size */
slen = strtoul(&ptr[6], NULL, 10) + 6 + strlen(&ptr[6]);
/* get the space */
output = (char*)malloc(slen);
if (NULL == output) {
*regex = NULL;
return PMIX_ERR_NOMEM;
}
/* xfer the data */
memcpy(output, ptr, slen);
buffer->unpack_ptr += slen;
*regex = output;
return PMIX_SUCCESS;
}

Просмотреть файл

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015-2019 Intel, Inc. All rights reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef PMIX_PREG_compress_H
#define PMIX_PREG_compress_H
#include <src/include/pmix_config.h>
#include "src/mca/preg/preg.h"
BEGIN_C_DECLS
/* the component must be visible data for the linker to find it */
PMIX_EXPORT extern pmix_mca_base_component_t mca_preg_compress_component;
extern pmix_preg_module_t pmix_preg_compress_module;
END_C_DECLS
#endif

Просмотреть файл

@ -0,0 +1,82 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2016-2019 Intel, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*
* These symbols are in a file by themselves to provide nice linker
* semantics. Since linkers generally pull in symbols by object
* files, keeping these symbols as the only symbols in this file
* prevents utility programs such as "ompi_info" from having to import
* entire components just to query their version and parameters.
*/
#include <src/include/pmix_config.h>
#include "pmix_common.h"
#include "src/mca/pcompress/pcompress.h"
#include "src/mca/preg/preg.h"
#include "preg_compress.h"
static pmix_status_t component_open(void);
static pmix_status_t component_close(void);
static pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority);
/*
* Instantiate the public struct with all of our public information
* and pointers to our public functions in it
*/
pmix_mca_base_component_t mca_preg_compress_component = {
PMIX_PREG_BASE_VERSION_1_0_0,
/* Component name and version */
.pmix_mca_component_name = "compress",
PMIX_MCA_BASE_MAKE_VERSION(component,
PMIX_MAJOR_VERSION,
PMIX_MINOR_VERSION,
PMIX_RELEASE_VERSION),
/* Component open and close functions */
.pmix_mca_open_component = component_open,
.pmix_mca_close_component = component_close,
.pmix_mca_query_component = component_query,
};
static int component_open(void)
{
return PMIX_SUCCESS;
}
static int component_query(pmix_mca_base_module_t **module, int *priority)
{
if (NULL == pmix_compress.compress_string) {
return PMIX_ERROR;
}
/* we should always be first in priority */
*priority = 100;
*module = (pmix_mca_base_module_t *)&pmix_preg_compress_module;
return PMIX_SUCCESS;
}
static int component_close(void)
{
return PMIX_SUCCESS;
}

Просмотреть файл

@ -35,10 +35,11 @@
#include "src/util/error.h"
#include "src/util/output.h"
#include "src/class/pmix_list.h"
#include "src/mca/bfrops/base/base.h"
#include "src/mca/gds/gds.h"
#include "src/client/pmix_client_ops.h"
#include "src/mca/preg/preg.h"
#include "src/mca/preg/base/base.h"
#include "preg_native.h"
static pmix_status_t generate_node_regex(const char *input,
@ -49,11 +50,9 @@ static pmix_status_t parse_nodes(const char *regexp,
char ***names);
static pmix_status_t parse_procs(const char *regexp,
char ***procs);
static pmix_status_t resolve_peers(const char *nodename,
const char *nspace,
pmix_proc_t **procs, size_t *nprocs);
static pmix_status_t resolve_nodes(const char *nspace,
char **nodelist);
static pmix_status_t copy(char **dest, size_t *len, const char *input);
static pmix_status_t pack(pmix_buffer_t *buffer, const char *input);
static pmix_status_t unpack(pmix_buffer_t *buffer, char **regex);
pmix_preg_module_t pmix_preg_native_module = {
.name = "pmix",
@ -61,8 +60,11 @@ pmix_preg_module_t pmix_preg_native_module = {
.generate_ppn = generate_ppn,
.parse_nodes = parse_nodes,
.parse_procs = parse_procs,
.resolve_peers = resolve_peers,
.resolve_nodes = resolve_nodes
.resolve_peers = pmix_preg_base_std_resolve_peers,
.resolve_nodes = pmix_preg_base_std_resolve_nodes,
.copy = copy,
.pack = pack,
.unpack = unpack
};
static pmix_status_t regex_parse_value_ranges(char *base, char *ranges,
@ -455,7 +457,6 @@ static pmix_status_t parse_nodes(const char *regexp,
/* the regex generator used to create this regex
* is tagged at the beginning of the string */
if (NULL == (ptr = strchr(tmp, '['))) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
free(tmp);
return PMIX_ERR_BAD_PARAM;
}
@ -497,7 +498,6 @@ static pmix_status_t parse_procs(const char *regexp,
/* the regex generator used to create this regex
* is tagged at the beginning of the string */
if (NULL == (ptr = strchr(tmp, '['))) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
free(tmp);
return PMIX_ERR_BAD_PARAM;
}
@ -517,159 +517,60 @@ static pmix_status_t parse_procs(const char *regexp,
return rc;
}
static pmix_status_t resolve_peers(const char *nodename,
const char *nspace,
pmix_proc_t **procs, size_t *nprocs)
static pmix_status_t copy(char **dest, size_t *len, const char *input)
{
pmix_cb_t cb;
pmix_status_t rc;
pmix_kval_t *kv;
pmix_proc_t proc;
char **ptr;
pmix_info_t *info;
pmix_proc_t *p=NULL;
size_t ninfo, np=0, n, j;
PMIX_CONSTRUCT(&cb, pmix_cb_t);
cb.key = strdup(nodename);
/* this data isn't going anywhere, so we don't require a copy */
cb.copy = false;
/* scope is irrelevant as the info we seek must be local */
cb.scope = PMIX_SCOPE_UNDEF;
/* let the proc point to the nspace */
pmix_strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN);
proc.rank = PMIX_RANK_WILDCARD;
cb.proc = &proc;
PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, &cb);
if (PMIX_SUCCESS != rc) {
if (PMIX_ERR_INVALID_NAMESPACE != rc) {
PMIX_ERROR_LOG(rc);
}
goto complete;
}
/* should just be the one value on the list */
if (1 != pmix_list_get_size(&cb.kvs)) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
rc = PMIX_ERR_BAD_PARAM;
goto complete;
}
kv = (pmix_kval_t*)pmix_list_get_first(&cb.kvs);
/* the hostname used as a key with wildcard rank will return
* a pmix_data_array_t of pmix_info_t structs */
if (NULL == kv->value ||
PMIX_DATA_ARRAY != kv->value->type ||
NULL == kv->value->data.darray ||
PMIX_INFO != kv->value->data.darray->type) {
PMIX_ERROR_LOG(PMIX_ERR_DATA_VALUE_NOT_FOUND);
rc = PMIX_ERR_DATA_VALUE_NOT_FOUND;
goto complete;
}
info = (pmix_info_t*)kv->value->data.darray->array;
ninfo = kv->value->data.darray->size;
/* find the PMIX_LOCAL_PEERS key */
for (n=0; n < ninfo; n++) {
if (0 == strncmp(info[n].key, PMIX_LOCAL_PEERS, PMIX_MAX_KEYLEN)) {
/* split the string */
ptr = pmix_argv_split(info[n].value.data.string, ',');
np = pmix_argv_count(ptr);
PMIX_PROC_CREATE(p, np);
if (NULL == p) {
rc = PMIX_ERR_NOMEM;
pmix_argv_free(ptr);
goto complete;
}
for (j=0; j < np; j++) {
pmix_strncpy(p[j].nspace, nspace, PMIX_MAX_NSLEN);
p[j].rank = strtoul(ptr[j], NULL, 10);
}
rc = PMIX_SUCCESS;
pmix_argv_free(ptr);
break;
}
if (0 != strncmp(input, "pmix", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
complete:
if (NULL != cb.info) {
PMIX_INFO_FREE(cb.info, cb.ninfo);
}
if (NULL != cb.key) {
free(cb.key);
cb.key = NULL;
}
PMIX_DESTRUCT(&cb);
*procs = p;
*nprocs = np;
return rc;
*dest = strdup(input);
*len = strlen(input);
return PMIX_SUCCESS;
}
static pmix_status_t resolve_nodes(const char *nspace,
char **nodelist)
static pmix_status_t pack(pmix_buffer_t *buffer, const char *input)
{
pmix_cb_t cb;
pmix_status_t rc;
pmix_kval_t *kv;
pmix_proc_t proc;
size_t slen;
char *ptr;
PMIX_CONSTRUCT(&cb, pmix_cb_t);
if (0 != strncmp(input, "pmix", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
/* setup default answer */
*nodelist = NULL;
/* extract the size */
slen = strlen(input) + 1; // retain the NULL terminator
/* create a pmix_info_t so we can pass the nspace
* into the fetch as a qualifier */
PMIX_INFO_CREATE(cb.info, 1);
if (NULL == cb.info) {
PMIX_DESTRUCT(&cb);
/* ensure the buffer has enough space */
ptr = pmix_bfrop_buffer_extend(buffer, slen);
if (NULL == ptr) {
return PMIX_ERR_NOMEM;
}
cb.ninfo = 1;
PMIX_INFO_LOAD(&cb.info[0], PMIX_NSPACE, nspace, PMIX_STRING);
/* tell the GDS what we want */
cb.key = PMIX_NODE_MAP;
/* this data isn't going anywhere, so we don't require a copy */
cb.copy = false;
/* scope is irrelevant as the info we seek must be local */
cb.scope = PMIX_SCOPE_UNDEF;
/* put the nspace in the proc field */
pmix_strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN);
/* the info will be associated with PMIX_RANK_WILDCARD */
proc.rank = PMIX_RANK_WILDCARD;
cb.proc = &proc;
/* xfer the data */
memcpy(ptr, input, slen);
buffer->bytes_used += slen;
buffer->pack_ptr += slen;
PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, &cb);
if (PMIX_SUCCESS != rc) {
PMIX_ERROR_LOG(rc);
goto complete;
}
/* should just be the one value on the list */
if (1 != pmix_list_get_size(&cb.kvs)) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
rc = PMIX_ERR_BAD_PARAM;
goto complete;
}
kv = (pmix_kval_t*)pmix_list_get_first(&cb.kvs);
/* the PMIX_NODE_MAP key is supposed to return
* a regex string - check that it did */
if (NULL == kv->value ||
PMIX_STRING != kv->value->type) {
PMIX_ERROR_LOG(PMIX_ERR_DATA_VALUE_NOT_FOUND);
rc = PMIX_ERR_DATA_VALUE_NOT_FOUND;
goto complete;
}
/* return the string */
if (NULL != kv->value->data.string) {
*nodelist = strdup(kv->value->data.string);
return PMIX_SUCCESS;
}
static pmix_status_t unpack(pmix_buffer_t *buffer, char **regex)
{
char *ptr;
ptr = buffer->unpack_ptr;
if (0 != strncmp(ptr, "pmix", 4)) {
return PMIX_ERR_TAKE_NEXT_OPTION;
}
complete:
if (NULL != cb.info) {
PMIX_INFO_FREE(cb.info, cb.ninfo);
*regex = strdup(ptr);
buffer->unpack_ptr += strlen(ptr) + 1;
if (NULL == *regex) {
return PMIX_ERR_NOMEM;
}
return rc;
return PMIX_SUCCESS;
}
static pmix_status_t pmix_regex_extract_nodes(char *regexp, char ***names)

Просмотреть файл

@ -12,7 +12,7 @@
* All rights reserved.
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2016-2017 Intel, Inc. All rights reserved.
* Copyright (c) 2016-2019 Intel, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -66,8 +66,7 @@ static int component_open(void)
static int component_query(pmix_mca_base_module_t **module, int *priority)
{
/* we should always be first in priority */
*priority = 100;
*priority = 50;
*module = (pmix_mca_base_module_t *)&pmix_preg_native_module;
return PMIX_SUCCESS;
}

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015-2017 Intel, Inc. All rights reserved.
* Copyright (c) 2015-2019 Intel, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
@ -28,6 +28,7 @@
#include "src/mca/mca.h"
#include "src/mca/base/pmix_mca_base_var.h"
#include "src/mca/base/pmix_mca_base_framework.h"
#include "src/mca/bfrops/bfrops_types.h"
#include "src/mca/preg/preg_types.h"
@ -85,6 +86,12 @@ typedef pmix_status_t (*pmix_preg_base_module_resolve_peers_fn_t)(const char *no
typedef pmix_status_t (*pmix_preg_base_module_resolve_nodes_fn_t)(const char *nspace,
char **nodelist);
typedef pmix_status_t (*pmix_preg_base_module_copy_fn_t)(char **dest, size_t *len, const char *input);
typedef pmix_status_t (*pmix_preg_base_module_pack_fn_t)(pmix_buffer_t *buffer, const char *regex);
typedef pmix_status_t (*pmix_preg_base_module_unpack_fn_t)(pmix_buffer_t *buffer, char **regex);
/**
* Base structure for a PREG module
*/
@ -96,6 +103,9 @@ typedef struct {
pmix_preg_base_module_parse_procs_fn_t parse_procs;
pmix_preg_base_module_resolve_peers_fn_t resolve_peers;
pmix_preg_base_module_resolve_nodes_fn_t resolve_nodes;
pmix_preg_base_module_copy_fn_t copy;
pmix_preg_base_module_pack_fn_t pack;
pmix_preg_base_module_unpack_fn_t unpack;
} pmix_preg_module_t;
/* we just use the standard component definition */

Просмотреть файл

@ -3,7 +3,7 @@
* All rights reserved.
* Copyright (c) 2017 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2017-2018 Intel, Inc. All rights reserved.
* Copyright (c) 2017-2019 Intel, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -82,9 +82,9 @@ static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name
if (ENOSPC == rc) {
rc = PMIX_ERR_OUT_OF_RESOURCE;
goto out;
} else if ((ENOTSUP != rc)
} else if (EINVAL != rc && ENOTSUP != rc
#ifdef EOPNOTSUPP
&& (EOPNOTSUPP != rc)
&& EOPNOTSUPP != rc
#endif
){
rc = PMIX_ERROR;

Просмотреть файл

@ -357,7 +357,7 @@ int pmix_rte_init(pmix_proc_type_t type,
return ret;
}
/* open the preg and select the active plugins */
/* open the preg and select the active plugins - must come after pcompress! */
if (PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_preg_base_framework, 0)) ) {
error = "pmix_preg_base_open";
goto return_error;

Просмотреть файл

@ -201,16 +201,13 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
/* check if the nspace of the requestor is different from
* the nspace of the target process */
if (!PMIX_CHECK_NSPACE(nspace, cd->peer->info->pname.nspace)) {
diffnspace = true;
}
diffnspace = !PMIX_CHECK_NSPACE(nspace, cd->peer->info->pname.nspace);
pmix_output_verbose(2, pmix_server_globals.get_output,
"%s:%d EXECUTE GET FOR %s:%d ON BEHALF OF %s:%d",
pmix_globals.myid.nspace,
pmix_globals.myid.rank, nspace, rank,
cd->peer->info->pname.nspace,
cd->peer->info->pname.rank);
"%s EXECUTE GET FOR %s:%d ON BEHALF OF %s",
PMIX_NAME_PRINT(&pmix_globals.myid),
nspace, rank,
PMIX_PNAME_PRINT(&cd->peer->info->pname));
/* This call flows upward from a local client If we don't
* know about this nspace, then it cannot refer to the
@ -237,6 +234,9 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
if (localonly) {
/* the user doesn't want us to look for the info,
* so we simply return at this point */
pmix_output_verbose(5, pmix_server_globals.get_output,
"%s UNKNOWN NSPACE: LOCAL ONLY - NOT FOUND",
PMIX_NAME_PRINT(&pmix_globals.myid));
return PMIX_ERR_NOT_FOUND;
}
/* this is for an nspace we don't know about yet, so
@ -254,6 +254,9 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
return rc;
}
if (PMIX_SUCCESS == rc) {
pmix_output_verbose(5, pmix_server_globals.get_output,
"%s UNKNOWN NSPACE: DUPLICATE REQUEST - WAITING",
PMIX_NAME_PRINT(&pmix_globals.myid));
/* if they specified a timeout for this specific
* request, set it up now */
if (0 < tv.tv_sec) {
@ -275,6 +278,9 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
* up on its own, but at worst the direct modex
* will simply overwrite the info later */
if (NULL != pmix_host_server.direct_modex) {
pmix_output_verbose(5, pmix_server_globals.get_output,
"%s UNKNOWN NSPACE: REQUEST PASSED TO HOST",
PMIX_NAME_PRINT(&pmix_globals.myid));
rc = pmix_host_server.direct_modex(&lcd->proc, info, ninfo, dmdx_cbfunc, lcd);
if (PMIX_SUCCESS != rc) {
PMIX_INFO_FREE(info, ninfo);
@ -291,7 +297,10 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
req->event_active = true;
}
} else {
/* if we don't have direct modex feature, just respond with "not found" */
/* if we don't have direct modex feature, just respond with "not found" */
pmix_output_verbose(5, pmix_server_globals.get_output,
"%s UNKNOWN NSPACE: NO DMODEX AVAILABLE - NOT FOUND",
PMIX_NAME_PRINT(&pmix_globals.myid));
PMIX_INFO_FREE(info, ninfo);
pmix_list_remove_item(&pmix_server_globals.local_reqs, &lcd->super);
PMIX_RELEASE(lcd);
@ -305,6 +314,10 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
* if the rank is wildcard, or the nspace is different, then
* they are asking for the job-level info for this nspace - provide it */
if (PMIX_RANK_WILDCARD == rank || diffnspace) {
pmix_output_verbose(5, pmix_server_globals.get_output,
"%s LOOKING FOR %s",
PMIX_NAME_PRINT(&pmix_globals.myid),
diffnspace ? "WILDCARD RANK" : "DIFF NSPACE");
/* see if we have the job-level info - we won't have it
* if we have no local procs and haven't already asked
* for it, so there is no guarantee we have it */
@ -333,6 +346,10 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf,
* simply be added to the cb.kvs list */
if (PMIX_RANK_WILDCARD != rank) {
proc.rank = rank;
pmix_output_verbose(5, pmix_server_globals.get_output,
"%s GETTING JOB-DATA FOR %s",
PMIX_NAME_PRINT(&pmix_globals.myid),
PMIX_NAME_PRINT(&proc));
PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb);
if (PMIX_SUCCESS != rc) {
PMIX_DESTRUCT(&cb);

Просмотреть файл

@ -498,7 +498,7 @@ static pmix_server_trkr_t* new_tracker(char *id, pmix_proc_t *procs,
}
trk->nlocal += ns_local;
if (!ns_local) {
if (0 == ns_local) {
trk->local = false;
} else if (PMIX_RANK_WILDCARD == procs[i].rank) {
/* If proc is a wildcard we need to additionally check
@ -1001,7 +1001,7 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd,
if (trk->def_complete &&
pmix_list_get_size(&trk->local_cbs) == trk->nlocal) {
pmix_output_verbose(2, pmix_server_globals.fence_output,
"fence complete");
"fence LOCALLY complete");
/* if this is a purely local fence (i.e., all participants are local),
* then it is done and we notify accordingly */
if (trk->local) {

Просмотреть файл

@ -27,6 +27,7 @@
#include "pmix_common.h"
#include "src/threads/tsd.h"
#include "src/include/pmix_globals.h"
#include "src/util/error.h"
#include "src/util/name_fns.h"
#include "src/util/printf.h"
@ -94,7 +95,7 @@ get_print_name_buffer(void)
return (pmix_print_args_buffers_t*) ptr;
}
char* pmix_util_print_name_args(const pmix_proc_t *name)
static char* print_args(char *ns, pmix_rank_t rnk)
{
pmix_print_args_buffers_t *ptr;
char *rank;
@ -107,8 +108,8 @@ char* pmix_util_print_name_args(const pmix_proc_t *name)
return pmix_print_args_null;
}
/* protect against NULL names */
if (NULL == name) {
/* protect against NULL nspace */
if (NULL == ns) {
index = ptr->cntr;
snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "[NO-NAME]");
ptr->cntr++;
@ -118,12 +119,12 @@ char* pmix_util_print_name_args(const pmix_proc_t *name)
return ptr->buffers[index];
}
rank = pmix_util_print_rank(name->rank);
rank = pmix_util_print_rank(rnk);
index = ptr->cntr;
snprintf(ptr->buffers[index],
PMIX_PRINT_NAME_ARGS_MAX_SIZE,
"[%s:%s]", name->nspace, rank);
"[%s:%s]", ns, rank);
ptr->cntr++;
if (PMIX_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
@ -132,6 +133,24 @@ char* pmix_util_print_name_args(const pmix_proc_t *name)
return ptr->buffers[index];
}
char* pmix_util_print_name_args(const pmix_proc_t *name)
{
if (NULL == name) {
return print_args(NULL, PMIX_RANK_UNDEF);
}
return print_args((char*)name->nspace, name->rank);
}
char *pmix_util_print_pname_args(const pmix_name_t *name)
{
if (NULL == name) {
return print_args(NULL, PMIX_RANK_UNDEF);
}
return print_args((char*)name->nspace, name->rank);
}
char* pmix_util_print_rank(const pmix_rank_t vpid)
{
pmix_print_args_buffers_t *ptr;

Просмотреть файл

@ -12,7 +12,7 @@
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2018 Intel, Inc. All rights reserved.
* Copyright (c) 2018-2019 Intel, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -30,6 +30,7 @@
#endif
#include "pmix_common.h"
#include "src/include/pmix_globals.h"
BEGIN_C_DECLS
@ -38,6 +39,10 @@ PMIX_EXPORT char* pmix_util_print_name_args(const pmix_proc_t *name);
#define PMIX_NAME_PRINT(n) \
pmix_util_print_name_args(n)
PMIX_EXPORT char *pmix_util_print_pname_args(const pmix_name_t *name);
#define PMIX_PNAME_PRINT(n) \
pmix_util_print_pname_args(n)
PMIX_EXPORT char* pmix_util_print_rank(const pmix_rank_t vpid);
#define PMIX_RANK_PRINT(n) \
pmix_util_print_rank(n)

Просмотреть файл

@ -25,6 +25,11 @@ if !WANT_HIDDEN
# these tests use internal symbols
# use --disable-visibility
SUBDIRS = simple
if WANT_PYTHON_BINDINGS
SUBDIRS += python
endif
endif
headers = test_common.h cli_stages.h server_callbacks.h utils.h test_fence.h \

Просмотреть файл

@ -0,0 +1,26 @@
#
# Copyright (c) 2019 Intel, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
noinst_SCRIPTS = \
run_server.sh.in \
run_sched.sh.in \
server.py \
sched.py \
client.py
#########################
# Support for "make check"
if WANT_PYTHON_BINDINGS
TESTS = \
run_server.sh \
run_sched.sh
endif

5
opal/mca/pmix/pmix4x/pmix/test/python/run_sched.sh.in Исполняемый файл
Просмотреть файл

@ -0,0 +1,5 @@
#!/bin/bash
export PYTHONPATH=@PMIX_PYTHON_EGG_PATH@
./sched.py

5
opal/mca/pmix/pmix4x/pmix/test/python/run_server.sh.in Исполняемый файл
Просмотреть файл

@ -0,0 +1,5 @@
#!/bin/bash
export PYTHONPATH=@PMIX_PYTHON_EGG_PATH@
./server.py

Просмотреть файл

@ -26,7 +26,7 @@ headers = simptest.h
noinst_PROGRAMS = simptest simpclient simppub simpdyn simpft simpdmodex \
test_pmix simptool simpdie simplegacy simptimeout \
gwtest gwclient stability quietclient simpjctrl simpio simpsched \
simpcoord
simpcoord
simptest_SOURCES = \
simptest.c

Просмотреть файл

@ -580,14 +580,10 @@ static void set_namespace(int nprocs, char *ranks, char *nspace,
x->info[3].value.data.string = strdup(ranks);
PMIx_generate_regex(hostname, &regex);
(void)strncpy(x->info[4].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN);
x->info[4].value.type = PMIX_STRING;
x->info[4].value.data.string = regex;
PMIX_INFO_LOAD(&x->info[4], PMIX_NODE_MAP, regex, PMIX_REGEX);
PMIx_generate_ppn(ranks, &ppn);
(void)strncpy(x->info[5].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN);
x->info[5].value.type = PMIX_STRING;
x->info[5].value.data.string = ppn;
PMIX_INFO_LOAD(&x->info[5], PMIX_PROC_MAP, ppn, PMIX_REGEX);
(void)strncpy(x->info[6].key, PMIX_JOB_SIZE, PMIX_MAX_KEYLEN);
x->info[6].value.type = PMIX_UINT32;

Просмотреть файл

@ -49,6 +49,7 @@ int main(int argc, char **argv)
uint32_t nprocs, n, *u32;
size_t ninfo, m;
pmix_coord_t *coords;
char *hostname;
if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) {
pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %s",
@ -79,6 +80,15 @@ int main(int argc, char **argv)
PMIX_VALUE_RELEASE(val);
pmix_output(0, "Client %s:%d job size %d", myproc.nspace, myproc.rank, nprocs);
/* get our assumed hostname */
if (PMIX_SUCCESS != (rc = PMIx_Get(&myproc, PMIX_HOSTNAME, NULL, 0, &val))) {
pmix_output(0, "Client ns %s rank %d: PMIx_Get hostname failed: %s",
myproc.nspace, myproc.rank, PMIx_Error_string(rc));
goto done;
}
hostname = strdup(val->data.string);
PMIX_VALUE_RELEASE(val);
/* get our assigned network endpts */
if (PMIX_SUCCESS != (rc = PMIx_Get(&myproc, PMIX_NETWORK_ENDPT, NULL, 0, &val))) {
pmix_output(0, "Client ns %s rank %d: PMIx_Get network endpt failed: %s",
@ -100,7 +110,7 @@ int main(int argc, char **argv)
}
tmp = pmix_argv_join(foo, ',');
pmix_argv_free(foo);
pmix_output(0, "ASSIGNED ENDPTS: %s", tmp);
pmix_output(0, "Rank %u[%s]: ASSIGNED ENDPTS: %s", myproc.rank, hostname, tmp);
free(tmp);
}
@ -110,9 +120,6 @@ int main(int argc, char **argv)
myproc.nspace, myproc.rank, PMIx_Error_string(rc));
goto done;
}
pmix_output(0, "Client %s:%d was assigned %lu coordinates",
myproc.nspace, myproc.rank,
(unsigned long)val->data.darray->size);
coords = (pmix_coord_t*)val->data.darray->array;
ninfo = val->data.darray->size;
for (m=0; m < ninfo; m++) {
@ -130,7 +137,7 @@ int main(int argc, char **argv)
} else {
view = "PHYSICAL";
}
pmix_output(0, "COORD[%d] VIEW %s: %s", (int)m, view, tmp);
pmix_output(0, "Rank %u[%s]: COORD[%d] VIEW %s: %s", myproc.rank, hostname, (int)m, view, tmp);
free(tmp);
}

Просмотреть файл

@ -133,60 +133,57 @@ int main(int argc, char **argv)
/* register a fabric */
rc = PMIx_server_register_fabric(&myfabric, NULL, 0);
if (PMIX_SUCCESS != rc) {
fprintf(stderr, "Fabric registration failed with error: %s\n", PMIx_Error_string(rc));
goto cleanup;
}
if (PMIX_SUCCESS == rc) {
fprintf(stderr, "Number of fabric vertices: %u\n", myfabric.nverts);
fprintf(stderr, "Number of fabric vertices: %u\n", myfabric.nverts);
for (n32=0; n32 < myfabric.nverts; n32++) {
fprintf(stderr, "%u:", n32);
for (m32=0; m32 < myfabric.nverts; m32++) {
fprintf(stderr, " %u", myfabric.commcost[n32][m32]);
for (n32=0; n32 < myfabric.nverts; n32++) {
fprintf(stderr, "%u:", n32);
for (m32=0; m32 < myfabric.nverts; m32++) {
fprintf(stderr, " %u", myfabric.commcost[n32][m32]);
}
fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}
rc = PMIx_server_get_vertex_info(&myfabric, myfabric.nverts/2, &val, &nodename);
if (PMIX_SUCCESS != rc) {
fprintf(stderr, "Fabric get vertex info failed with error: %s\n", PMIx_Error_string(rc));
goto cleanup;
}
if (PMIX_DATA_ARRAY != val.type) {
fprintf(stderr, "Fabric get vertex info returned wrong type: %s\n", PMIx_Data_type_string(val.type));
goto cleanup;
}
fprintf(stderr, "Vertex info for index %u on node %s:\n", myfabric.nverts/2, nodename);
info = (pmix_info_t*)val.data.darray->array;
for (n=0; n < val.data.darray->size; n++) {
fprintf(stderr, "\t%s:\t%s\n", info[n].key, info[n].value.data.string);
}
PMIX_VALUE_DESTRUCT(&val);
free(nodename);
rc = PMIx_server_get_vertex_info(&myfabric, myfabric.nverts/2, &val, &nodename);
if (PMIX_SUCCESS != rc) {
fprintf(stderr, "Fabric get vertex info failed with error: %s\n", PMIx_Error_string(rc));
goto cleanup;
}
if (PMIX_DATA_ARRAY != val.type) {
fprintf(stderr, "Fabric get vertex info returned wrong type: %s\n", PMIx_Data_type_string(val.type));
goto cleanup;
}
fprintf(stderr, "Vertex info for index %u on node %s:\n", myfabric.nverts/2, nodename);
info = (pmix_info_t*)val.data.darray->array;
for (n=0; n < val.data.darray->size; n++) {
fprintf(stderr, "\t%s:\t%s\n", info[n].key, info[n].value.data.string);
}
PMIX_VALUE_DESTRUCT(&val);
free(nodename);
PMIX_INFO_CREATE(info, 1);
PMIX_INFO_LOAD(&info[0], PMIX_NETWORK_NIC, "test002:nic002", PMIX_STRING);
val.type = PMIX_DATA_ARRAY;
PMIX_DATA_ARRAY_CREATE(val.data.darray, 1, PMIX_INFO);
val.data.darray->array = info;
rc = PMIx_server_get_index(&myfabric, &val, &n32);
if (PMIX_SUCCESS != rc) {
fprintf(stderr, "Fabric get index failed with error: %s\n", PMIx_Error_string(rc));
goto cleanup;
PMIX_INFO_CREATE(info, 1);
PMIX_INFO_LOAD(&info[0], PMIX_NETWORK_NIC, "test002:nic002", PMIX_STRING);
val.type = PMIX_DATA_ARRAY;
PMIX_DATA_ARRAY_CREATE(val.data.darray, 1, PMIX_INFO);
val.data.darray->array = info;
rc = PMIx_server_get_index(&myfabric, &val, &n32);
if (PMIX_SUCCESS != rc) {
fprintf(stderr, "Fabric get index failed with error: %s\n", PMIx_Error_string(rc));
goto cleanup;
}
fprintf(stderr, "Index %u for NIC %s\n", n32, "test002:nic002");
}
fprintf(stderr, "Index %u for NIC %s\n", n32, "test002:nic002");
/* setup an application */
PMIX_INFO_CREATE(iptr, 4);
hosts = "test000,test001,test002";
PMIx_generate_regex(hosts, &regex);
PMIX_INFO_LOAD(&iptr[0], PMIX_NODE_MAP, regex, PMIX_STRING);
PMIX_INFO_LOAD(&iptr[0], PMIX_NODE_MAP, regex, PMIX_REGEX);
free(regex);
procs = "0,1,2;3,4,5;6,7";
PMIx_generate_ppn(procs, &ppn);
PMIX_INFO_LOAD(&iptr[1], PMIX_PROC_MAP, ppn, PMIX_STRING);
PMIX_INFO_LOAD(&iptr[1], PMIX_PROC_MAP, ppn, PMIX_REGEX);
free(ppn);
PMIX_LOAD_KEY(iptr[2].key, PMIX_ALLOC_NETWORK);

Просмотреть файл

@ -518,7 +518,7 @@ int main(int argc, char **argv)
#endif
if (nettest) {
/* set a known network configuration for the pnet/test component */
putenv("PMIX_MCA_pnet_test_nverts=nodes:5;plane:d:3;plane:s:2;plane:d:5");
putenv("PMIX_MCA_pnet_test_planes=plane:d:3;plane:s:2;plane:d:5:2");
putenv("PMIX_MCA_pnet=test");
}
if (PMIX_SUCCESS != (rc = PMIx_server_init(&mymodule, info, ninfo))) {
@ -528,7 +528,7 @@ int main(int argc, char **argv)
PMIX_INFO_FREE(info, ninfo);
if (nettest) {
unsetenv("PMIX_MCA_pnet");
unsetenv("PMIX_MCA_pnet_test_nverts");
unsetenv("PMIX_MCA_pnet_test_planes");
}
/* register the default errhandler */
@ -759,6 +759,14 @@ static void set_namespace(int nprocs, char *ranks, char *nspace,
pmix_info_t *info, *iptr, *ip;
myxfer_t cd, lock;
pmix_status_t rc;
char *hostnames[] = {
"test000",
"test001",
"test002",
NULL
};
char **map[3] = {NULL, NULL, NULL};
char tmp[50] , **agg = NULL;
if (arrays) {
x->ninfo = 15 + nprocs;
@ -767,33 +775,53 @@ static void set_namespace(int nprocs, char *ranks, char *nspace,
}
PMIX_INFO_CREATE(x->info, x->ninfo);
if (nprocs < 3) {
/* take only the number of hostnames equal to
* the number of procs */
for (m=0; m < nprocs; m++) {
pmix_argv_append_nosize(&agg, hostnames[m]);
}
ppn = pmix_argv_join(agg, ',');
pmix_argv_free(agg);
agg = NULL;
} else {
ppn = pmix_argv_join(hostnames, ',');
}
PMIx_generate_regex(ppn, &regex);
free(ppn);
/* compute the placement of the procs */
for (m=0; m < nprocs; m++) {
snprintf(tmp, 50, "%d", m);
pmix_argv_append_nosize(&map[m%3], tmp);
memset(tmp, 0, 50);
}
for (m=0; m < 3; m++) {
if (NULL != map[m]) {
rks = pmix_argv_join(map[m], ',');
pmix_argv_append_nosize(&agg, rks);
free(rks);
pmix_argv_free(map[m]);
}
}
rks = pmix_argv_join(agg, ';');
pmix_argv_free(agg);
PMIx_generate_ppn(rks, &ppn);
free(rks);
n = 0;
PMIx_generate_regex("test000,test001,test002", &regex);
PMIx_generate_ppn("0;1;2", &ppn);
if (arrays) {
(void)strncpy(x->info[n].key, PMIX_JOB_INFO_ARRAY, PMIX_MAX_KEYLEN);
x->info[n].value.type = PMIX_DATA_ARRAY;
PMIX_DATA_ARRAY_CREATE(x->info[n].value.data.darray, 2, PMIX_INFO);
iptr = (pmix_info_t*)x->info[n].value.data.darray->array;
(void)strncpy(iptr[0].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN);
iptr[0].value.type = PMIX_STRING;
iptr[0].value.data.string = regex;
(void)strncpy(iptr[1].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN);
iptr[1].value.type = PMIX_STRING;
iptr[1].value.data.string = ppn;
PMIX_INFO_LOAD(&iptr[0], PMIX_NODE_MAP, regex, PMIX_REGEX);
PMIX_INFO_LOAD(&iptr[1], PMIX_PROC_MAP, ppn, PMIX_REGEX);
++n;
} else {
(void)strncpy(x->info[n].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN);
x->info[n].value.type = PMIX_STRING;
x->info[n].value.data.string = regex;
PMIX_INFO_LOAD(&x->info[n], PMIX_NODE_MAP, regex, PMIX_REGEX);
++n;
/* if we have some empty nodes, then fill their spots */
(void)strncpy(x->info[n].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN);
x->info[n].value.type = PMIX_STRING;
x->info[n].value.data.string = ppn;
PMIX_INFO_LOAD(&x->info[n], PMIX_PROC_MAP, ppn, PMIX_REGEX);
++n;
}
@ -904,7 +932,7 @@ static void set_namespace(int nprocs, char *ranks, char *nspace,
for (m=0; m < nprocs; m++) {
(void)strncpy(x->info[n].key, PMIX_PROC_DATA, PMIX_MAX_KEYLEN);
x->info[n].value.type = PMIX_DATA_ARRAY;
PMIX_DATA_ARRAY_CREATE(array, 5, PMIX_INFO);
PMIX_DATA_ARRAY_CREATE(array, 6, PMIX_INFO);
x->info[n].value.data.darray = array;
info = (pmix_info_t*)array->array;
k = 0;
@ -928,7 +956,12 @@ static void set_namespace(int nprocs, char *ranks, char *nspace,
(void)strncpy(info[k].key, PMIX_NODEID, PMIX_MAX_KEYLEN);
info[k].value.type = PMIX_UINT32;
info[k].value.data.uint32 = 0;
info[k].value.data.uint32 = m % 3;
++k;
(void)strncpy(info[k].key, PMIX_HOSTNAME, PMIX_MAX_KEYLEN);
info[k].value.type = PMIX_STRING;
info[k].value.data.string = strdup(hostnames[m % 3]);
++k;
/* move to next proc */
++n;

Просмотреть файл

@ -587,22 +587,13 @@ static void set_namespace(int nprocs, char *ranks, char *nspace,
PMIX_DATA_ARRAY_CREATE(x->info[n].value.data.darray, 2, PMIX_INFO);
iptr = (pmix_info_t*)x->info[n].value.data.darray->array;
(void)strncpy(iptr[0].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN);
iptr[0].value.type = PMIX_STRING;
iptr[0].value.data.string = regex;
(void)strncpy(iptr[1].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN);
iptr[1].value.type = PMIX_STRING;
iptr[1].value.data.string = ppn;
PMIX_INFO_LOAD(&iptr[0], PMIX_NODE_MAP, regex, PMIX_REGEX);
PMIX_INFO_LOAD(&iptr[1], PMIX_PROC_MAP, ppn, PMIX_REGEX);
++n;
} else {
(void)strncpy(x->info[n].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN);
x->info[n].value.type = PMIX_STRING;
x->info[n].value.data.string = regex;
PMIX_INFO_LOAD(&x->info[n], PMIX_NODE_MAP, regex, PMIX_REGEX);
++n;
/* if we have some empty nodes, then fill their spots */
(void)strncpy(x->info[n].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN);
x->info[n].value.type = PMIX_STRING;
x->info[n].value.data.string = ppn;
PMIX_INFO_LOAD(&x->info[n], PMIX_PROC_MAP, ppn, PMIX_REGEX);
++n;
}

Просмотреть файл

@ -148,9 +148,7 @@ static void set_namespace(int local_size, int univ_size,
free(ranks);
PMIx_generate_regex(NODE_NAME, &regex);
pmix_strncpy(info[4].key, PMIX_NODE_MAP, PMIX_MAX_KEYLEN);
info[4].value.type = PMIX_STRING;
info[4].value.data.string = strdup(regex);
PMIX_INFO_LOAD(&info[4], PMIX_NODE_MAP, regex, PMIX_REGEX);
/* generate the global proc map */
fill_seq_ranks_array(univ_size, 0, &ranks);
@ -159,9 +157,7 @@ static void set_namespace(int local_size, int univ_size,
}
PMIx_generate_ppn(ranks, &ppn);
free(ranks);
pmix_strncpy(info[5].key, PMIX_PROC_MAP, PMIX_MAX_KEYLEN);
info[5].value.type = PMIX_STRING;
info[5].value.data.string = strdup(ppn);
PMIX_INFO_LOAD(&info[5], PMIX_PROC_MAP, ppn, PMIX_REGEX);
pmix_strncpy(info[6].key, PMIX_JOB_SIZE, PMIX_MAX_KEYLEN);
info[6].value.type = PMIX_UINT32;

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2018 Intel, Inc. All rights reserved.
* Copyright (c) 2014-2019 Intel, Inc. All rights reserved.
* Copyright (c) 2014-2018 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016-2018 Cisco Systems, Inc. All rights reserved
@ -20,6 +20,7 @@
#include "opal/constants.h"
#include "opal/class/opal_list.h"
#include "opal/util/opal_environ.h"
#include "opal/util/proc.h"
#include "opal/util/show_help.h"
#include "opal/mca/pmix/pmix.h"
@ -126,6 +127,8 @@ static int external_open(void)
"incorrect-pmix", true, version, "v4.x");
return OPAL_ERROR;
}
/* we are going to be used, so set an envar */
opal_setenv("PMIX_MCA_preg", "native", true, &environ);
return OPAL_SUCCESS;
}