Merge pull request #6953 from rhc54/topic/pmix4
Update to current PMIx 4.0.0 (master)
Этот коммит содержится в:
Коммит
73c5fe8f05
@ -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;
|
||||
}
|
||||
|
||||
|
53
opal/mca/pmix/pmix4x/pmix/src/mca/preg/compress/Makefile.am
Обычный файл
53
opal/mca/pmix/pmix4x/pmix/src/mca/preg/compress/Makefile.am
Обычный файл
@ -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
|
281
opal/mca/pmix/pmix4x/pmix/src/mca/preg/compress/preg_compress.c
Обычный файл
281
opal/mca/pmix/pmix4x/pmix/src/mca/preg/compress/preg_compress.c
Обычный файл
@ -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(®exp[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(®exp[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;
|
||||
}
|
27
opal/mca/pmix/pmix4x/pmix/src/mca/preg/compress/preg_compress.h
Обычный файл
27
opal/mca/pmix/pmix4x/pmix/src/mca/preg/compress/preg_compress.h
Обычный файл
@ -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 \
|
||||
|
26
opal/mca/pmix/pmix4x/pmix/test/python/Makefile.am
Обычный файл
26
opal/mca/pmix/pmix4x/pmix/test/python/Makefile.am
Обычный файл
@ -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
Исполняемый файл
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
Исполняемый файл
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, ®ex);
|
||||
(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, ®ex);
|
||||
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, ®ex);
|
||||
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", ®ex);
|
||||
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, ®ex);
|
||||
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;
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user