@@ -57,6 +57,10 @@ static int map_colocate(prte_job_t *jdata,
5757 uint16_t procs_per_target ,
5858 prte_rmaps_options_t * options );
5959
60+ static void inherit_env_directives (prte_job_t * jdata ,
61+ prte_job_t * parent ,
62+ pmix_proc_t * proxy );
63+
6064void prte_rmaps_base_map_job (int fd , short args , void * cbdata )
6165{
6266 prte_state_caddy_t * caddy = (prte_state_caddy_t * ) cbdata ;
@@ -70,7 +74,7 @@ void prte_rmaps_base_map_job(int fd, short args, void *cbdata)
7074 prte_job_t * parent = NULL ;
7175 prte_app_context_t * app ;
7276 bool inherit = false;
73- pmix_proc_t * nptr , * target_proc ;
77+ pmix_proc_t * nptr = NULL , * target_proc ;
7478 char * tmp , * * ck , * * env ;
7579 uint16_t u16 = 0 , procs_per_target = 0 ;
7680 uint16_t * u16ptr = & u16 ;
@@ -229,6 +233,11 @@ void prte_rmaps_base_map_job(int fd, short args, void *cbdata)
229233 /* if this is a dynamic job launch and they didn't explicitly
230234 * request inheritance, then don't inherit the launch directives */
231235 if (prte_get_attribute (& jdata -> attributes , PRTE_JOB_LAUNCH_PROXY , (void * * ) & nptr , PMIX_PROC )) {
236+ if (NULL == nptr ) {
237+ PRTE_ERROR_LOG (PRTE_ERR_NOT_FOUND );
238+ PRTE_ACTIVATE_JOB_STATE (jdata , PRTE_JOB_STATE_MAP_FAILED );
239+ goto cleanup ;
240+ }
232241 /* if the launch proxy is me, then this is the initial launch from
233242 * a proxy scenario, so we don't really have a parent */
234243 if (PMIX_CHECK_NSPACE (PRTE_PROC_MY_NAME -> nspace , nptr -> nspace )) {
@@ -263,7 +272,6 @@ void prte_rmaps_base_map_job(int fd, short args, void *cbdata)
263272 } else {
264273 inherit = true;
265274 }
266- PMIX_PROC_RELEASE (nptr );
267275 } else {
268276 /* initial launch always takes on default MCA params for non-specified policies */
269277 inherit = true;
@@ -309,6 +317,8 @@ void prte_rmaps_base_map_job(int fd, short args, void *cbdata)
309317 prte_set_attribute (& jdata -> attributes , PRTE_JOB_GPU_SUPPORT , PRTE_ATTR_GLOBAL , fptr , PMIX_BOOL );
310318 }
311319 }
320+ // copy over any env directives, but do not overwrite anything already specified
321+ inherit_env_directives (jdata , parent , nptr );
312322 } else {
313323 if (!prte_get_attribute (& jdata -> attributes , PRTE_JOB_HWT_CPUS , NULL , PMIX_BOOL ) &&
314324 !prte_get_attribute (& jdata -> attributes , PRTE_JOB_CORE_CPUS , NULL , PMIX_BOOL )) {
@@ -321,6 +331,9 @@ void prte_rmaps_base_map_job(int fd, short args, void *cbdata)
321331 }
322332 }
323333 }
334+ if (NULL != nptr ) {
335+ PMIX_PROC_RELEASE (nptr );
336+ }
324337
325338 /* we always inherit a parent's oversubscribe flag unless the job assigned it */
326339 if (NULL != parent &&
@@ -1250,3 +1263,108 @@ static int map_colocate(prte_job_t *jdata,
12501263 PMIX_LIST_DESTRUCT (& targets );
12511264 return ret ;
12521265}
1266+
1267+ static void inherit_env_directives (prte_job_t * jdata ,
1268+ prte_job_t * parent ,
1269+ pmix_proc_t * proxy )
1270+ {
1271+ prte_app_context_t * app , * app2 ;
1272+ prte_proc_t * p ;
1273+ prte_attribute_t * attr , * attr2 ;
1274+ pmix_value_t * val , * val2 ;
1275+ pmix_envar_t * envar , * envar2 ;
1276+ int n ;
1277+ bool exists ;
1278+
1279+ // deal with job-level attributes first
1280+ PMIX_LIST_FOREACH (attr , & parent -> attributes , prte_attribute_t ) {
1281+ if (PMIX_ENVAR != attr -> data .type ) {
1282+ continue ;
1283+ }
1284+ val = & attr -> data ;
1285+ envar = & val -> data .envar ;
1286+
1287+ // do we have a matching attribute in the new job?
1288+ exists = false;
1289+ PMIX_LIST_FOREACH (attr2 , & jdata -> attributes , prte_attribute_t ) {
1290+ if (PMIX_ENVAR != attr -> data .type ) {
1291+ continue ;
1292+ }
1293+ val2 = & attr2 -> data ;
1294+ envar2 = & val2 -> data .envar ;
1295+
1296+ if (attr -> key == attr2 -> key ) {
1297+ // operation is same - check if the target envars match
1298+ if (0 == strcmp (envar -> envar , envar2 -> envar )) {
1299+ // these match, so don't overwrite it
1300+ exists = true;
1301+ break ;
1302+ }
1303+ }
1304+ }
1305+
1306+ if (exists ) {
1307+ // leave this alone
1308+ continue ;
1309+ }
1310+
1311+ // if it doesn't exist, then inherit it
1312+ prte_prepend_attribute (& jdata -> attributes , attr -> key , PRTE_ATTR_GLOBAL ,
1313+ envar , PMIX_ENVAR );
1314+ }
1315+
1316+ /* There is no one-to-one correlation between the apps, but we can
1317+ * inherit the directives from the proc that called spawn, so do that
1318+ * much here */
1319+ p = prte_get_proc_object (proxy );
1320+ if (NULL == p ) {
1321+ PRTE_ERROR_LOG (PRTE_ERR_NOT_FOUND );
1322+ return ;
1323+ }
1324+ app = (prte_app_context_t * )pmix_pointer_array_get_item (parent -> apps , p -> app_idx );
1325+ if (NULL == app ) {
1326+ PRTE_ERROR_LOG (PRTE_ERR_NOT_FOUND );
1327+ return ;
1328+ }
1329+ for (n = 0 ; n < jdata -> apps -> size ; n ++ ) {
1330+ app2 = (prte_app_context_t * )pmix_pointer_array_get_item (jdata -> apps , n );
1331+ if (NULL == app2 ) {
1332+ continue ;
1333+ }
1334+ PMIX_LIST_FOREACH (attr , & app -> attributes , prte_attribute_t ) {
1335+ if (PMIX_ENVAR != attr -> data .type ) {
1336+ continue ;
1337+ }
1338+ val = & attr -> data ;
1339+ envar = & val -> data .envar ;
1340+
1341+ exists = false;
1342+ PMIX_LIST_FOREACH (attr2 , & app2 -> attributes , prte_attribute_t ) {
1343+ if (PMIX_ENVAR != attr -> data .type ) {
1344+ continue ;
1345+ }
1346+ val2 = & attr2 -> data ;
1347+ envar2 = & val2 -> data .envar ;
1348+
1349+ if (attr -> key == attr2 -> key ) {
1350+ // operation is same - check if the target envars match
1351+ if (0 == strcmp (envar -> envar , envar2 -> envar )) {
1352+ // these match, so don't overwrite it
1353+ exists = true;
1354+ break ;
1355+ }
1356+ }
1357+ }
1358+
1359+ if (exists ) {
1360+ // leave this alone
1361+ continue ;
1362+ }
1363+
1364+ // if it doesn't exist, then inherit it
1365+ prte_prepend_attribute (& app2 -> attributes , attr -> key , PRTE_ATTR_GLOBAL ,
1366+ envar , PMIX_ENVAR );
1367+ }
1368+ }
1369+
1370+ }
0 commit comments