Modify the RMGR components to allow job setup with a given jobid, and add another attribute so that we can setup triggers without launching.
Add some debugging output to the ODLS default module, and the orted. Remove the nodename data from the ODLS info report - that info is already stored in the registry by the RMAPS framework upon completing the mapping procedure. Add another test program that does an ORTE-only dynamic spawn (gasp!). Looks just like comm_spawn - just no MPI involved. Modify the ODLS to release the processor when we "kill" local procs in a more scalable fashion. It previously had a sleep in it that Jeff's prior commit removed. However, he introduced some Windows code into the non-Windows component (protected by "if"s, but unnecessary). This is a more general solution he proposed - included here so I could get things to compile properly. This commit was SVN r12579.
Этот коммит содержится в:
родитель
bfdf801487
Коммит
4636125e2d
@ -86,19 +86,6 @@ int orte_odls_base_report_spawn(opal_list_t *children)
|
||||
return rc;
|
||||
}
|
||||
dval.data = NULL;
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.set(&dval, (void*)orte_system_info.nodename, ORTE_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
opal_argv_free(tokens);
|
||||
free(segment);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.put_1(mode, segment, tokens, ORTE_NODE_NAME_KEY, &dval))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
opal_argv_free(tokens);
|
||||
free(segment);
|
||||
return rc;
|
||||
}
|
||||
dval.data = NULL;
|
||||
opal_argv_free(tokens);
|
||||
free(segment);
|
||||
|
||||
|
@ -30,7 +30,9 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
@ -38,7 +40,9 @@
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
@ -49,6 +53,18 @@
|
||||
#include <sys/stat.h>
|
||||
#endif /* HAVE_SYS_STAT_H */
|
||||
|
||||
#if defined(HAVE_SCHED_YIELD)
|
||||
/* Only if we have sched_yield() */
|
||||
#ifdef HAVE_SCHED_H
|
||||
#include <sched.h>
|
||||
#endif
|
||||
#else
|
||||
/* Only do these if we don't have <sched.h> */
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#endif /* HAVE_SCHED_YIELD */
|
||||
|
||||
#include "opal/event/event.h"
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/util/output.h"
|
||||
@ -206,7 +222,11 @@ static bool odls_default_child_died(pid_t pid, unsigned int timeout, int *exit_s
|
||||
{
|
||||
time_t end;
|
||||
pid_t ret;
|
||||
|
||||
#if !defined(HAVE_SCHED_YIELD)
|
||||
struct timeval t;
|
||||
fd_set bogus;
|
||||
#endif
|
||||
|
||||
end = time(NULL) + timeout;
|
||||
do {
|
||||
ret = waitpid(pid, exit_status, WNOHANG);
|
||||
@ -219,11 +239,17 @@ static bool odls_default_child_died(pid_t pid, unsigned int timeout, int *exit_s
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
SwitchToThread();
|
||||
#elif defined(HAVE_SCHED_YIELD)
|
||||
#if defined(HAVE_SCHED_YIELD)
|
||||
sched_yield();
|
||||
#else
|
||||
/* Bogus delay for 1 usec */
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 1;
|
||||
FD_ZERO(&bogus);
|
||||
FD_SET(0, &bogus);
|
||||
select(1, &bogus, NULL, NULL, &t);
|
||||
#endif
|
||||
|
||||
} while (time(NULL) < end);
|
||||
|
||||
/* The child didn't die, so return false */
|
||||
@ -541,7 +567,7 @@ static int odls_default_fork_local_proc(
|
||||
} else {
|
||||
environ_copy = opal_argv_copy(base_environ);
|
||||
}
|
||||
|
||||
|
||||
/* special case handling for --prefix: this is somewhat icky,
|
||||
but at least some users do this. :-\ It is possible that
|
||||
when using --prefix, the user will also "-x PATH" and/or
|
||||
@ -618,7 +644,7 @@ static int odls_default_fork_local_proc(
|
||||
opal_setenv(param, uri, true, &environ_copy);
|
||||
free(param);
|
||||
free(uri);
|
||||
|
||||
|
||||
/* use same nodename as the starting daemon (us) */
|
||||
param = mca_base_param_environ_variable("orte", "base", "nodename");
|
||||
opal_setenv(param, orte_system_info.nodename, true, &environ_copy);
|
||||
@ -628,6 +654,7 @@ static int odls_default_fork_local_proc(
|
||||
orte_ns_nds_env_put(child->name, vpid_start, vpid_range,
|
||||
&environ_copy);
|
||||
|
||||
|
||||
/* close all file descriptors w/ exception of stdin/stdout/stderr */
|
||||
for(fd=3; fd<fdmax; fd++)
|
||||
close(fd);
|
||||
@ -745,6 +772,9 @@ int orte_odls_default_launch_local_procs(orte_gpr_notify_data_t *data, char **ba
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
opal_output(orte_odls_globals.output, "odls: setting up launch for job %ld", (long)job);
|
||||
|
||||
/* We need to create a list of the app_contexts
|
||||
* so we can know what to launch - the process info only gives
|
||||
* us an index into the app_context array, not the app_context
|
||||
@ -892,6 +922,9 @@ int orte_odls_default_launch_local_procs(orte_gpr_notify_data_t *data, char **ba
|
||||
continue;
|
||||
}
|
||||
|
||||
opal_output(orte_odls_globals.output, "odls: preparing to launch child [%ld, %ld, %ld]",
|
||||
ORTE_NAME_ARGS(child->name));
|
||||
|
||||
/* find the indicated app_context in the list */
|
||||
for (item2 = opal_list_get_first(&app_context_list);
|
||||
item2 != opal_list_get_end(&app_context_list);
|
||||
|
@ -143,17 +143,27 @@ void orte_rmgr_base_recv(int status, orte_process_name_t* sender,
|
||||
return;
|
||||
}
|
||||
|
||||
/* process the request */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr.setup_job(context, num_context, &job))) {
|
||||
/* unpack the attributes */
|
||||
OBJ_CONSTRUCT(&attrs, opal_list_t);
|
||||
count = 1;
|
||||
if(ORTE_SUCCESS != (rc = orte_dss.unpack(buffer, &attrs, &count, ORTE_ATTR_LIST))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto SEND_ANSWER;
|
||||
goto CLEANUP_SPAWN;
|
||||
}
|
||||
|
||||
/* process the request */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr.setup_job(context, num_context, &job, &attrs))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto CLEANUP_SPAWN;
|
||||
}
|
||||
|
||||
/* return the new jobid */
|
||||
if(ORTE_SUCCESS != (rc = orte_dss.pack(&answer, &job, 1, ORTE_JOBID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto SEND_ANSWER;
|
||||
goto CLEANUP_SPAWN;
|
||||
}
|
||||
|
||||
goto CLEANUP_SPAWN; /* clean up the attrs and contexts */
|
||||
break;
|
||||
|
||||
case ORTE_RMGR_SPAWN_JOB_CMD:
|
||||
|
@ -39,10 +39,10 @@
|
||||
#include "rmgr_cnos.h"
|
||||
|
||||
|
||||
static int orte_rmgr_cnos_setup_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid);
|
||||
static int orte_rmgr_cnos_setup_job(orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid,
|
||||
opal_list_t *attrs);
|
||||
|
||||
static int orte_rmgr_cnos_spawn_job(
|
||||
orte_app_context_t** app_context,
|
||||
@ -119,7 +119,7 @@ orte_rmgr_base_module_t orte_rmgr_cnos_module = {
|
||||
static int orte_rmgr_cnos_setup_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid)
|
||||
orte_jobid_t* jobid, opal_list_t *attrs)
|
||||
{
|
||||
return ORTE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -41,10 +41,10 @@
|
||||
#include "orte/mca/rmgr/proxy/rmgr_proxy.h"
|
||||
|
||||
|
||||
static int orte_rmgr_proxy_setup_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid);
|
||||
static int orte_rmgr_proxy_setup_job(orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid,
|
||||
opal_list_t *attributes);
|
||||
|
||||
static int orte_rmgr_proxy_setup_stage_gates(orte_jobid_t jobid);
|
||||
|
||||
@ -85,10 +85,10 @@ orte_rmgr_base_module_t orte_rmgr_proxy_module = {
|
||||
* and name service actions to the HNP for efficiency.
|
||||
*/
|
||||
|
||||
static int orte_rmgr_proxy_setup_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid)
|
||||
static int orte_rmgr_proxy_setup_job(orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid,
|
||||
opal_list_t *attrs)
|
||||
{
|
||||
orte_buffer_t cmd;
|
||||
orte_buffer_t rsp;
|
||||
@ -122,6 +122,13 @@ static int orte_rmgr_proxy_setup_job(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* pack any attributes */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(&cmd, attrs, 1, ORTE_ATTR_LIST))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&cmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send the command */
|
||||
if(0 > (rc = orte_rml.send_buffer(ORTE_RML_NAME_SEED, &cmd, ORTE_RML_TAG_RMGR, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
@ -391,7 +398,7 @@ static int orte_rmgr_proxy_spawn_job(
|
||||
*/
|
||||
if (flags & ORTE_RMGR_SETUP) {
|
||||
if (ORTE_SUCCESS !=
|
||||
(rc = orte_rmgr_proxy_setup_job(app_context,num_context,jobid))) {
|
||||
(rc = orte_rmgr_proxy_setup_job(app_context,num_context,jobid, attributes))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
@ -415,73 +422,74 @@ static int orte_rmgr_proxy_spawn_job(
|
||||
}
|
||||
}
|
||||
|
||||
/* if we don't want to launch, then just return here - don't setup the io forwarding
|
||||
* or do any of the remaining pre-launch things
|
||||
*/
|
||||
if (!(flags & ORTE_RMGR_LAUNCH)) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup I/O forwarding
|
||||
*/
|
||||
|
||||
name.jobid = *jobid;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(&name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDOUT, 1))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(&name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDERR, 2))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (flags & ORTE_RMGR_SETUP_TRIGS) {
|
||||
/*
|
||||
* setup I/O forwarding
|
||||
*/
|
||||
|
||||
name.jobid = *jobid;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(&name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDOUT, 1))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(&name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDERR, 2))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* setup the launch system's stage gate counters and subscriptions */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_proxy_setup_stage_gates(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** setup the subscription so we can complete the wireup when all processes reach LAUNCHED */
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_proxy_wireup_callback, NULL, ORTE_PROC_STATE_LAUNCHED);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the ERRMGR's callbacks as required
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_errmgr.register_job(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup callback
|
||||
*/
|
||||
|
||||
if(NULL != cbfunc) {
|
||||
union {
|
||||
orte_rmgr_cb_fn_t func;
|
||||
void * ptr;
|
||||
} cbfunc_union;
|
||||
void *cbdata;
|
||||
|
||||
/* ISO C forbids conversion of object pointer to function
|
||||
pointer. So we do this, which is the same thing, but without
|
||||
the warning from GCC */
|
||||
cbfunc_union.func = cbfunc;
|
||||
cbdata = cbfunc_union.ptr;
|
||||
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_proxy_callback, cbdata, cb_conditions);
|
||||
/* setup the launch system's stage gate counters and subscriptions */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_proxy_setup_stage_gates(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** setup the subscription so we can complete the wireup when all processes reach LAUNCHED */
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_proxy_wireup_callback, NULL, ORTE_PROC_STATE_LAUNCHED);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the ERRMGR's callbacks as required
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_errmgr.register_job(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup callback
|
||||
*/
|
||||
|
||||
if(NULL != cbfunc) {
|
||||
union {
|
||||
orte_rmgr_cb_fn_t func;
|
||||
void * ptr;
|
||||
} cbfunc_union;
|
||||
void *cbdata;
|
||||
|
||||
/* ISO C forbids conversion of object pointer to function
|
||||
pointer. So we do this, which is the same thing, but without
|
||||
the warning from GCC */
|
||||
cbfunc_union.func = cbfunc;
|
||||
cbdata = cbfunc_union.ptr;
|
||||
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_proxy_callback, cbdata, cb_conditions);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* if we don't want to launch, then just return here */
|
||||
if (!(flags & ORTE_RMGR_LAUNCH)) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* launch the job
|
||||
*/
|
||||
|
@ -65,7 +65,8 @@ extern "C" {
|
||||
typedef int (*orte_rmgr_base_module_setup_job_fn_t)(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t *jobid);
|
||||
orte_jobid_t *jobid,
|
||||
opal_list_t *attributes);
|
||||
|
||||
/*
|
||||
* Callback function for resource manager
|
||||
|
@ -55,10 +55,16 @@ ORTE_DECLSPEC OBJ_CLASS_DECLARATION(orte_attribute_t);
|
||||
* to create any desired "flow" through the RMGR's spawn
|
||||
* procedure.
|
||||
*/
|
||||
#define ORTE_RMGR_SETUP 0x01
|
||||
#define ORTE_RMGR_ALLOC 0x02
|
||||
#define ORTE_RMGR_MAP 0x04
|
||||
#define ORTE_RMGR_LAUNCH 0x08
|
||||
#define ORTE_RMGR_SETUP 0x01
|
||||
#define ORTE_RMGR_ALLOC 0x02
|
||||
#define ORTE_RMGR_MAP 0x04
|
||||
#define ORTE_RMGR_SETUP_TRIGS 0x08
|
||||
#define ORTE_RMGR_LAUNCH 0x10
|
||||
|
||||
/* direct the RMGR spawn procedure to use the provided jobid
|
||||
* instead of getting a new one
|
||||
*/
|
||||
#define ORTE_RMGR_USE_GIVEN_JOBID "orte-rmgr-use-jobid"
|
||||
|
||||
|
||||
/* RESOURCE MANAGER DATA TYPES */
|
||||
|
@ -46,13 +46,15 @@
|
||||
#include "orte/mca/smr/smr.h"
|
||||
|
||||
#include "orte/mca/rmgr/base/rmgr_private.h"
|
||||
#include "orte/mca/rmgr/base/base.h"
|
||||
#include "orte/mca/rmgr/urm/rmgr_urm.h"
|
||||
|
||||
|
||||
static int orte_rmgr_urm_setup_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid);
|
||||
orte_jobid_t* jobid,
|
||||
opal_list_t *attrs);
|
||||
|
||||
static int orte_rmgr_urm_spawn_job(
|
||||
orte_app_context_t** app_context,
|
||||
@ -110,20 +112,31 @@ static int orte_rmgr_urm_module_init(void)
|
||||
* Setup the job
|
||||
*/
|
||||
|
||||
static int orte_rmgr_urm_setup_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid)
|
||||
static int orte_rmgr_urm_setup_job(orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
orte_jobid_t* jobid,
|
||||
opal_list_t *attrs)
|
||||
{
|
||||
int rc;
|
||||
orte_std_cntr_t i;
|
||||
orte_attribute_t *attr;
|
||||
orte_jobid_t *jptr;
|
||||
|
||||
OPAL_TRACE(1);
|
||||
|
||||
/* allocate a jobid */
|
||||
if (ORTE_SUCCESS != (rc = orte_ns.create_jobid(jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
/* check for given jobid */
|
||||
if (NULL != (attr = orte_rmgr.find_attribute(attrs, ORTE_RMGR_USE_GIVEN_JOBID))) {
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.get((void**)&jptr, attr->value, ORTE_JOBID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
*jobid = *jptr;
|
||||
} else {
|
||||
/* allocate a jobid */
|
||||
if (ORTE_SUCCESS != (rc = orte_ns.create_jobid(jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* for each app_context, we need to purge their environment of HNP
|
||||
@ -273,6 +286,9 @@ static void orte_rmgr_urm_wireup_callback(orte_gpr_notify_data_t *data, void *cb
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return;
|
||||
}
|
||||
|
||||
opal_output(orte_rmgr_base.rmgr_output, "rmgr_urm:wireup_callback called for job %ld", (long)jobid);
|
||||
|
||||
orte_rmgr_urm_wireup_stdin(jobid);
|
||||
}
|
||||
|
||||
@ -340,13 +356,11 @@ static int orte_rmgr_urm_spawn_job(
|
||||
* with a valid jobid, so no need to get one
|
||||
*/
|
||||
if (flags & ORTE_RMGR_SETUP) {
|
||||
if (ORTE_JOBID_INVALID == *jobid) { /* setup the job */
|
||||
if (ORTE_SUCCESS !=
|
||||
(rc = orte_rmgr_urm_setup_job(app_context,num_context,jobid))) {
|
||||
(rc = orte_rmgr_urm_setup_job(app_context,num_context,jobid,attributes))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & ORTE_RMGR_ALLOC) {
|
||||
@ -367,85 +381,85 @@ static int orte_rmgr_urm_spawn_job(
|
||||
}
|
||||
}
|
||||
|
||||
/* if we don't want to launch, then just return here - don't setup the io forwarding
|
||||
* or do any of the remaining pre-launch things
|
||||
*/
|
||||
if (!(flags & ORTE_RMGR_LAUNCH)) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup I/O forwarding
|
||||
*/
|
||||
if (flags & ORTE_RMGR_SETUP_TRIGS) {
|
||||
/*
|
||||
* setup I/O forwarding
|
||||
*/
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_ns.create_process_name(&name, 0, *jobid, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDOUT, 1))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDERR, 2))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
free(name); /* done with this */
|
||||
if (ORTE_SUCCESS != (rc = orte_ns.create_process_name(&name, 0, *jobid, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDOUT, 1))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDERR, 2))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
free(name); /* done with this */
|
||||
|
||||
/* setup the launch system's stage gate counters and subscriptions */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_base_proc_stage_gate_init(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** setup the subscription so we can complete the wireup when all processes reach LAUNCHED */
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_urm_wireup_callback, NULL, ORTE_PROC_STATE_LAUNCHED);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the ERRMGR's callbacks as required
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_errmgr.register_job(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup caller's callback
|
||||
*/
|
||||
|
||||
if(NULL != cbfunc) {
|
||||
union {
|
||||
orte_rmgr_cb_fn_t func;
|
||||
void * ptr;
|
||||
} cbfunc_union;
|
||||
void *cbdata;
|
||||
|
||||
/* ISO C forbids conversion of object pointer to function
|
||||
pointer. So we do this, which is the same thing, but without
|
||||
the warning from GCC */
|
||||
cbfunc_union.func = cbfunc;
|
||||
cbdata = cbfunc_union.ptr;
|
||||
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_urm_callback, cbdata, cb_conditions);
|
||||
/* setup the launch system's stage gate counters and subscriptions */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_base_proc_stage_gate_init(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** setup the subscription so we can complete the wireup when all processes reach LAUNCHED */
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_urm_wireup_callback, NULL, ORTE_PROC_STATE_LAUNCHED);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for timing request - get stop time and report elapsed time if so */
|
||||
if (mca_rmgr_urm_component.timing) {
|
||||
if (0 != gettimeofday(&urmstop, NULL)) {
|
||||
opal_output(0, "rmgr_urm: could not obtain stop time");
|
||||
} else {
|
||||
opal_output(0, "rmgr_urm: job setup time is %ld usec",
|
||||
(long int)((urmstop.tv_sec - urmstart.tv_sec)*1000000 +
|
||||
(urmstop.tv_usec - urmstart.tv_usec)));
|
||||
/*
|
||||
* Define the ERRMGR's callbacks as required
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_errmgr.register_job(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup caller's callback
|
||||
*/
|
||||
|
||||
if(NULL != cbfunc) {
|
||||
union {
|
||||
orte_rmgr_cb_fn_t func;
|
||||
void * ptr;
|
||||
} cbfunc_union;
|
||||
void *cbdata;
|
||||
|
||||
/* ISO C forbids conversion of object pointer to function
|
||||
pointer. So we do this, which is the same thing, but without
|
||||
the warning from GCC */
|
||||
cbfunc_union.func = cbfunc;
|
||||
cbdata = cbfunc_union.ptr;
|
||||
|
||||
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_urm_callback, cbdata, cb_conditions);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for timing request - get stop time and report elapsed time if so */
|
||||
if (mca_rmgr_urm_component.timing) {
|
||||
if (0 != gettimeofday(&urmstop, NULL)) {
|
||||
opal_output(0, "rmgr_urm: could not obtain stop time");
|
||||
} else {
|
||||
opal_output(0, "rmgr_urm: job setup time is %ld usec",
|
||||
(long int)((urmstop.tv_sec - urmstart.tv_sec)*1000000 +
|
||||
(urmstop.tv_usec - urmstart.tv_usec)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if we don't want to launch, then just return here */
|
||||
if (!(flags & ORTE_RMGR_LAUNCH)) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
271
orte/test/system/orte_proc_subscribe.c
Обычный файл
271
orte/test/system/orte_proc_subscribe.c
Обычный файл
@ -0,0 +1,271 @@
|
||||
/* -*- C -*-
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
* The most basic of MPI applications
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "opal/threads/condition.h"
|
||||
|
||||
#include "orte/util/proc_info.h"
|
||||
#include "orte/dss/dss.h"
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
#include "orte/mca/rmgr/rmgr.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
#include "orte/mca/rmaps/rmaps_types.h"
|
||||
|
||||
bool waitexit;
|
||||
opal_mutex_t lock;
|
||||
opal_condition_t cond;
|
||||
|
||||
static int orte_subscribe_proc(orte_jobid_t job);
|
||||
static void job_state_callback(orte_jobid_t jobid, orte_proc_state_t state);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int rc;
|
||||
orte_proc_state_t cb_states;
|
||||
orte_app_context_t *app;
|
||||
orte_jobid_t job;
|
||||
opal_list_t attributes;
|
||||
opal_list_item_t *item;
|
||||
uint8_t flow;
|
||||
|
||||
OBJ_CONSTRUCT(&lock, opal_mutex_t);
|
||||
OBJ_CONSTRUCT(&cond, opal_condition_t);
|
||||
waitexit = false;
|
||||
|
||||
if (0 > (rc = orte_init())) {
|
||||
fprintf(stderr, "couldn't init orte - error code %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* create an app_context */
|
||||
app = OBJ_NEW(orte_app_context_t);
|
||||
app->app = strdup("hostname");
|
||||
opal_argv_append_nosize(&app->argv, "hostname");
|
||||
app->num_procs = 3;
|
||||
app->cwd = strdup("/private/tmp");
|
||||
|
||||
/* setup the job through the setup trigs stage, but don't launch. We need to
|
||||
* do this so we can
|
||||
* setup the subscription that will return pids and other info to us
|
||||
* when all procs achieve LAUNCHED state. We have to go through the MAP
|
||||
* stage so that we can handle orterun's that don't specify the number
|
||||
* of procs. For that case, the num_procs in the registry isn't set until the
|
||||
* MAP stage is completed.
|
||||
*/
|
||||
OBJ_CONSTRUCT(&attributes, opal_list_t);
|
||||
flow = ORTE_RMGR_SETUP | ORTE_RMGR_ALLOC | ORTE_RMGR_MAP | ORTE_RMGR_SETUP_TRIGS;
|
||||
orte_rmgr.add_attribute(&attributes, ORTE_RMGR_SPAWN_FLOW, ORTE_UINT8, (void*)&flow, ORTE_RMGR_ATTR_OVERRIDE);
|
||||
orte_rmgr.add_attribute(&attributes, ORTE_RMAPS_DISPLAY_AFTER_MAP, ORTE_UNDEF, NULL, ORTE_RMGR_ATTR_OVERRIDE);
|
||||
|
||||
cb_states = ORTE_PROC_STATE_TERMINATED;
|
||||
rc = orte_rmgr.spawn_job(&app, 1, &job, 0, NULL, job_state_callback, cb_states, &attributes);
|
||||
|
||||
while (NULL != (item = opal_list_remove_first(&attributes))) OBJ_RELEASE(item);
|
||||
|
||||
/* now that all the info is on the registry, we can setup our subscription */
|
||||
orte_subscribe_proc(job);
|
||||
|
||||
orte_gpr.dump_local_triggers();
|
||||
|
||||
/* and now we can go ahead and actually launch! */
|
||||
flow = ORTE_RMGR_LAUNCH;
|
||||
orte_rmgr.add_attribute(&attributes, ORTE_RMGR_SPAWN_FLOW, ORTE_UINT8, (void*)&flow, ORTE_RMGR_ATTR_OVERRIDE);
|
||||
|
||||
rc = orte_rmgr.spawn_job(&app, 1, &job, 0, NULL, NULL, 0, &attributes);
|
||||
|
||||
/* Wait for the app to complete */
|
||||
|
||||
OPAL_THREAD_LOCK(&lock);
|
||||
while (!waitexit) {
|
||||
opal_condition_wait(&cond, &lock);
|
||||
}
|
||||
|
||||
/* All done */
|
||||
OBJ_RELEASE(app);
|
||||
while (NULL != (item = opal_list_remove_first(&attributes))) OBJ_RELEASE(item);
|
||||
OBJ_DESTRUCT(&attributes);
|
||||
|
||||
orte_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void job_state_callback(orte_jobid_t jobid, orte_proc_state_t state)
|
||||
{
|
||||
OPAL_THREAD_LOCK(&lock);
|
||||
|
||||
waitexit = true;
|
||||
opal_condition_signal(&cond);
|
||||
|
||||
OPAL_THREAD_UNLOCK(&lock);
|
||||
}
|
||||
|
||||
static void eclipse_launch_cb(orte_gpr_notify_data_t *notify_data, void *user_tag)
|
||||
{
|
||||
int len;
|
||||
orte_std_cntr_t i;
|
||||
orte_std_cntr_t j;
|
||||
orte_std_cntr_t k;
|
||||
orte_gpr_value_t ** values;
|
||||
orte_gpr_value_t * value;
|
||||
orte_gpr_keyval_t ** keyvals;
|
||||
char * str1;
|
||||
char * str2;
|
||||
char * res;
|
||||
char * kv = NULL;
|
||||
char * vpid = NULL;
|
||||
|
||||
fprintf(stderr, "launch cb entered\n");
|
||||
orte_dss.dump(0, notify_data, ORTE_GPR_NOTIFY_DATA);
|
||||
|
||||
#if 0
|
||||
values = (orte_gpr_value_t**)(data->values)->addr;
|
||||
|
||||
for(i=0, k=0; k<data->cnt && i < (data->values)->size; i++) {
|
||||
if(values[i] == NULL) continue;
|
||||
|
||||
k++;
|
||||
value = values[i];
|
||||
keyvals = value->keyvals;
|
||||
|
||||
len = strlen(ORTE_VPID_KEY);
|
||||
|
||||
if (strlen(value->tokens[1]) <= len
|
||||
|| strncmp(value->tokens[1], ORTE_VPID_KEY, len) != 0)
|
||||
continue;
|
||||
|
||||
asprintf(&vpid, "%s", value->tokens[1]+len+1);
|
||||
|
||||
for(j=0; j<value->cnt; j++) {
|
||||
orte_gpr_keyval_t *keyval = keyvals[j];
|
||||
char *external_key = NULL;
|
||||
char * tmp_str = NULL;
|
||||
|
||||
if (!strcmp(keyval->key, ORTE_NODE_NAME_KEY))
|
||||
asprintf(&external_key, "%s", ATTRIB_PROCESS_NODE_NAME);
|
||||
else if (!strcmp(keyval->key, ORTE_PROC_LOCAL_PID_KEY))
|
||||
asprintf(&external_key, "%s", ATTRIB_PROCESS_PID);
|
||||
else
|
||||
external_key = strdup(keyval->key);
|
||||
|
||||
if (external_key != NULL) {
|
||||
switch(ORTE_KEYVALUE_TYPE(keyval)) {
|
||||
case ORTE_STRING:
|
||||
if ((tmp_str = ORTE_GET_STRING_VALUE(keyval)) != NULL);
|
||||
asprintf(&kv, "%s=%s", external_key, tmp_str);
|
||||
break;
|
||||
case ORTE_UINT32:
|
||||
asprintf(&kv, "%s=%d", external_key, ORTE_GET_UINT32_VALUE
|
||||
(keyval));
|
||||
break;
|
||||
case ORTE_PID:
|
||||
asprintf(&kv, "%s=%d", external_key, ORTE_GET_PID_VALUE(keyval));
|
||||
break;
|
||||
default:
|
||||
asprintf(&kv, "%s=<unknown type>%d", external_key,
|
||||
ORTE_KEYVALUE_TYPE(keyval));
|
||||
break;
|
||||
}
|
||||
|
||||
if (kv != NULL) {
|
||||
if (job != NULL) {
|
||||
proxy_cstring_to_str("", &str1);
|
||||
proxy_cstring_to_str(kv, &str2);
|
||||
asprintf(&res, "%d %d 0:0 %s 1 %s %s", RTEV_PATTR, job-
|
||||
>ptp_jobid, str1, vpid, str2);
|
||||
AddToList(eventList, (void *)res);
|
||||
free(str1);
|
||||
free(str2);
|
||||
}
|
||||
free(kv);
|
||||
kv = NULL;
|
||||
}
|
||||
|
||||
free(external_key);
|
||||
}
|
||||
}
|
||||
|
||||
free(vpid);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Subscribe to attribute changes for 'procid' in 'job'.
|
||||
*/
|
||||
static int
|
||||
orte_subscribe_proc(orte_jobid_t job)
|
||||
{
|
||||
int rc;
|
||||
char *segment;
|
||||
orte_gpr_subscription_t *subs, sub = ORTE_GPR_SUBSCRIPTION_EMPTY;
|
||||
orte_gpr_trigger_t *trigs, trig = ORTE_GPR_TRIGGER_EMPTY;
|
||||
orte_gpr_value_t *values[1];
|
||||
|
||||
subs = ⊂
|
||||
if (ORTE_SUCCESS !=
|
||||
(rc = orte_schema.get_std_subscription_name(&sub.name, "eclipse-launch-sub", job))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
sub.action = ORTE_GPR_NOTIFY_DELETE_AFTER_TRIG;
|
||||
sub.values = values;
|
||||
sub.cnt = 1;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_schema.get_job_segment_name(&segment, job))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
free(sub.name);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.create_value(&(values[0]), ORTE_GPR_TOKENS_OR | ORTE_GPR_KEYS_OR,
|
||||
segment, 3, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
free(sub.name);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.create_keyval(&(values[0]->keyvals[0]), ORTE_NODE_NAME_KEY, ORTE_UNDEF, NULL))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(values[0]);
|
||||
free(sub.name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.create_keyval(&(values[0]->keyvals[1]), ORTE_PROC_LOCAL_PID_KEY, ORTE_UNDEF, NULL))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(values[0]);
|
||||
free(sub.name);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.create_keyval(&(values[0]->keyvals[2]), ORTE_PROC_NAME_KEY, ORTE_UNDEF, NULL))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(values[0]);
|
||||
free(sub.name);
|
||||
return rc;
|
||||
}
|
||||
sub.cbfunc = eclipse_launch_cb;
|
||||
|
||||
/* attach ourselves to the standard launched trigger */
|
||||
trigs = &trig;
|
||||
if (ORTE_SUCCESS !=
|
||||
(rc = orte_schema.get_std_trigger_name(&trig.name, ORTE_ALL_LAUNCHED_TRIGGER, job))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(values[0]);
|
||||
free(sub.name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.subscribe(1, &subs, 1, &trigs))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_RELEASE(values[0]);
|
||||
free(sub.name);
|
||||
free(trig.name);
|
||||
|
||||
return 0;
|
||||
}
|
@ -520,7 +520,7 @@ int main(int argc, char *argv[])
|
||||
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
opal_output(0, "[%lu,%lu,%lu] ompid: mutex cleared - finalizing", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: mutex cleared - finalizing", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
@ -532,7 +532,7 @@ int main(int argc, char *argv[])
|
||||
orte_finalize();
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
opal_output(0, "[%lu,%lu,%lu] ompid: done - exiting", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: done - exiting", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@ -547,6 +547,10 @@ static void orted_local_cb_launcher(orte_gpr_notify_data_t *data, void *user_tag
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: received launch callback", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
/* pass the data to the orted_local_launcher and get a report on
|
||||
* success or failure of the launch
|
||||
*/
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user