Skip to content

Commit 100621e

Browse files
DUPRAT, JULIENEmmanuelBRELLE
authored andcommitted
Properly del_proc spawned procs upon instance finalize
Signed-off-by: Brelle Emmanuel <[email protected]>
1 parent 0ca8526 commit 100621e

File tree

6 files changed

+139
-13
lines changed

6 files changed

+139
-13
lines changed

ompi/communicator/comm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,11 @@ int ompi_comm_get_rprocs (ompi_communicator_t *local_comm, ompi_communicator_t *
24172417
goto err_exit;
24182418
}
24192419

2420+
/* When a process gets spawned, every local_comm process needs to create
2421+
* an intercomm with the spawnees to communicate. These spawned procs needs
2422+
* to be remembered for cleaning later on */
2423+
ompi_proc_retain_spawned_jobids(rprocs, rsize);
2424+
24202425
err_exit:
24212426
/* rprocs isn't freed unless we have an error,
24222427
since it is used in the communicator */

ompi/dpm/dpm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* reserved.
2626
* Copyright (c) 2022 IBM Corporation. All rights reserved.
2727
* Copyright (c) 2023 Jeffrey M. Squyres. All rights reserved.
28+
* Copyright (c) 2025 BULL S.A.S. All rights reserved.
2829
* $COPYRIGHT$
2930
*
3031
* Additional copyrights may follow
@@ -473,7 +474,10 @@ int ompi_dpm_connect_accept(ompi_communicator_t *comm, int root,
473474
} while (!opal_list_is_empty(&ilist));
474475

475476
/* call add_procs on the new ones */
476-
rc = MCA_PML_CALL(add_procs(new_proc_list, opal_list_get_size(&ilist)));
477+
rc = MCA_PML_CALL(add_procs(new_proc_list, i));
478+
/* Register spawned procs names to clean them up after */
479+
ompi_proc_retain_spawned_jobids(new_proc_list, i);
480+
477481
free(new_proc_list);
478482
new_proc_list = NULL;
479483
if (OMPI_SUCCESS != rc) {

ompi/instance/instance.c

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* reserved.
99
* Copyright (c) 2023 Jeffrey M. Squyres. All rights reserved.
1010
* Copyright (c) 2024 NVIDIA Corporation. All rights reserved.
11+
* Copyright (c) 2025 Bull SAS. All rights reserved.
1112
* $COPYRIGHT$
1213
*
1314
* Additional copyrights may follow
@@ -19,6 +20,7 @@
1920
#include "instance.h"
2021

2122
#include "opal/util/arch.h"
23+
#include "opal/util/proc.h"
2224

2325
#include "opal/util/show_help.h"
2426
#include "opal/util/argv.h"
@@ -39,6 +41,7 @@
3941
#include "ompi/dpm/dpm.h"
4042
#include "ompi/file/file.h"
4143
#include "ompi/mpiext/mpiext.h"
44+
#include "ompi/runtime/ompi_rte.h"
4245

4346
#include "ompi/mca/hook/base/base.h"
4447
#include "ompi/mca/op/base/base.h"
@@ -110,13 +113,17 @@ static void ompi_instance_construct (ompi_instance_t *instance)
110113
instance->i_name[0] = '\0';
111114
instance->i_flags = 0;
112115
instance->i_keyhash = NULL;
116+
OBJ_CONSTRUCT(&instance->i_spawned_proc_namelists, opal_list_t);
117+
OBJ_CONSTRUCT(&instance->i_spawned_proc_lock, opal_mutex_t);
113118
OBJ_CONSTRUCT(&instance->s_lock, opal_mutex_t);
114119
instance->errhandler_type = OMPI_ERRHANDLER_TYPE_INSTANCE;
115120
instance->bsend_buffer = NULL;
116121
}
117122

118123
static void ompi_instance_destruct(ompi_instance_t *instance)
119124
{
125+
OBJ_DESTRUCT(&instance->i_spawned_proc_namelists);
126+
OBJ_DESTRUCT(&instance->i_spawned_proc_lock);
120127
OBJ_DESTRUCT(&instance->s_lock);
121128
}
122129

@@ -177,18 +184,90 @@ static int ompi_instance_print_error (const char *error, int ret)
177184
return ret;
178185
}
179186

187+
/* This function is only needed for the world paradigm because it's the only one
188+
* we can spawn processes in it for now */
189+
void ompi_proc_retain_spawned_jobids(ompi_proc_t **spawned_procs, size_t list_size) {
190+
const ompi_proc_t *spawned_proc;
191+
opal_namelist_t *registered_proc;
192+
ompi_process_name_t name;
193+
ompi_rte_cmp_bitmask_t mask;
194+
195+
/* NULL if session paradigm, not NULL if world paradigm */
196+
if (ompi_mpi_instance_default == NULL) {
197+
return;
198+
}
199+
200+
/* return the proc-struct which matches this jobid */
201+
mask = OMPI_RTE_CMP_JOBID;
202+
203+
for (size_t i = 0; i < list_size; i++) {
204+
/* The idea is to filter the procs that have the same jobid,
205+
* aka the jobs in the same instance.
206+
* After that we lookup if the jobid is already present, meaning this
207+
* instance is already registered via the jobid of its procs.
208+
* If the jobid is not present we add it */
209+
210+
int found = 0;
211+
spawned_proc = spawned_procs[i];
212+
if (OMPI_PROC_MY_NAME->jobid == spawned_proc->super.proc_name.jobid) {
213+
continue;
214+
}
215+
216+
name.jobid = spawned_proc->super.proc_name.jobid;
217+
name.vpid = spawned_proc->super.proc_name.vpid;
218+
219+
opal_mutex_lock(&ompi_mpi_instance_default->i_spawned_proc_lock);
220+
OPAL_LIST_FOREACH(registered_proc,
221+
&ompi_mpi_instance_default->i_spawned_proc_namelists,
222+
opal_namelist_t) {
223+
if (OPAL_EQUAL == ompi_rte_compare_name_fields(mask,
224+
&registered_proc->name, &name)) {
225+
found = 1;
226+
break;
227+
}
228+
}
229+
230+
if (0 == found) {
231+
opal_namelist_t *namelist = OBJ_NEW(opal_namelist_t);
232+
namelist->name.jobid = name.jobid;
233+
namelist->name.vpid = 0; /* not needed for lookup */
234+
opal_list_append(&ompi_mpi_instance_default->i_spawned_proc_namelists,
235+
&namelist->super);
236+
}
237+
opal_mutex_unlock(&ompi_mpi_instance_default->i_spawned_proc_lock);
238+
}
239+
return;
240+
}
241+
180242
static int ompi_mpi_instance_cleanup_pml (void)
181243
{
182244
/* call del_procs on all allocated procs even though some may not be known
183245
* to the pml layer. the pml layer is expected to be resilient and ignore
184246
* any unknown procs. */
185247
size_t nprocs = 0;
186248
ompi_proc_t **procs;
249+
opal_namelist_t *registered_name;
250+
opal_namelist_t *next;
187251

188252
procs = ompi_proc_get_allocated (&nprocs);
189253
MCA_PML_CALL(del_procs(procs, nprocs));
190254
free(procs);
191255

256+
/* If we are in a world paradigm and spawned processes we need to clean */
257+
if (ompi_mpi_instance_default != NULL) {
258+
259+
/* Let's loop on all spawned jobids and del_proc the concerned procs */
260+
OPAL_LIST_FOREACH_SAFE(registered_name, next,
261+
&ompi_mpi_instance_default->i_spawned_proc_namelists,
262+
opal_namelist_t) {
263+
264+
procs = ompi_proc_get_by_name(&registered_name->name, &nprocs);
265+
MCA_PML_CALL(del_procs(procs, nprocs));
266+
opal_list_remove_item(&ompi_mpi_instance_default->i_spawned_proc_namelists,
267+
&registered_name->super);
268+
}
269+
}
270+
192271
return OMPI_SUCCESS;
193272
}
194273

@@ -989,14 +1068,14 @@ int ompi_mpi_instance_finalize (ompi_instance_t **instance)
9891068
{
9901069
int ret = OMPI_SUCCESS;
9911070

992-
OBJ_RELEASE(*instance);
993-
9941071
opal_mutex_lock (&instance_lock);
9951072
if (0 == opal_atomic_add_fetch_32 (&ompi_instance_count, -1)) {
9961073
ret = ompi_mpi_instance_finalize_common ();
9971074
}
9981075
opal_mutex_unlock (&instance_lock);
9991076

1077+
OBJ_RELEASE(*instance);
1078+
10001079
*instance = &ompi_mpi_instance_null.instance;
10011080

10021081
return ret;

ompi/instance/instance.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
22
/*
33
* Copyright (c) 2018-2025 Triad National Security, LLC. All rights reserved.
4+
* Copyright (c) 2025 BULL S.A.S. All rights reserved.
45
* $COPYRIGHT$
56
*
67
* Additional copyrights may follow
@@ -34,6 +35,8 @@ struct ompi_instance_t {
3435

3536
/* Attributes */
3637
opal_hash_table_t *i_keyhash;
38+
opal_mutex_t i_spawned_proc_lock;
39+
opal_list_t i_spawned_proc_namelists;
3740

3841
/* index in Fortran <-> C translation array (for when I get around
3942
* to implementing fortran support-- UGH) */
@@ -88,7 +91,7 @@ OBJ_CLASS_DECLARATION(ompi_instance_t);
8891
* the PREDEFINED_COMMUNICATOR_PAD macro?
8992
* A: Most likely not, but it would be good to check.
9093
*/
91-
#define PREDEFINED_INSTANCE_PAD 512
94+
#define PREDEFINED_INSTANCE_PAD 1024
9295

9396
struct ompi_predefined_instance_t {
9497
ompi_instance_t instance;
@@ -120,6 +123,14 @@ int ompi_mpi_instance_retain (void);
120123
*/
121124
void ompi_mpi_instance_release (void);
122125

126+
/**
127+
* @brief Saves jobid of spawned procs to cleanup upon finalize
128+
*
129+
* @param[in] spawned_proc_list list of procs that were spawned
130+
* @param[in] list_size size of the list of procs that were spawned
131+
*/
132+
void ompi_proc_retain_spawned_jobids(ompi_proc_t **spawned_proc_list, size_t list_size);
133+
123134
/**
124135
* @brief Create a new MPI instance
125136
*

ompi/proc/proc.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved.
2121
*
2222
* Copyright (c) 2021 Nanook Consulting. All rights reserved.
23+
* Copyright (c) 2025 Bull SAS. All rights reserved.
2324
* $COPYRIGHT$
2425
*
2526
* Additional copyrights may follow
@@ -417,25 +418,19 @@ int ompi_proc_world_size (void)
417418
return ompi_process_info.num_procs;
418419
}
419420

420-
ompi_proc_t **ompi_proc_get_allocated (size_t *size)
421+
ompi_proc_t **ompi_proc_get_by_name(const ompi_process_name_t *name, size_t *size)
421422
{
422423
ompi_proc_t **procs;
423424
ompi_proc_t *proc;
424425
size_t count = 0;
425426
ompi_rte_cmp_bitmask_t mask;
426-
ompi_process_name_t my_name;
427427

428-
/* check bozo case */
429-
if (NULL == ompi_proc_local_proc) {
430-
return NULL;
431-
}
432428
mask = OMPI_RTE_CMP_JOBID;
433-
my_name = *OMPI_CAST_RTE_NAME(&ompi_proc_local_proc->super.proc_name);
434429

435430
/* First count how many match this jobid */
436431
opal_mutex_lock (&ompi_proc_lock);
437432
OPAL_LIST_FOREACH(proc, &ompi_proc_list, ompi_proc_t) {
438-
if (OPAL_EQUAL == ompi_rte_compare_name_fields(mask, OMPI_CAST_RTE_NAME(&proc->super.proc_name), &my_name)) {
433+
if (OPAL_EQUAL == ompi_rte_compare_name_fields(mask, OMPI_CAST_RTE_NAME(&proc->super.proc_name), name)) {
439434
++count;
440435
}
441436
}
@@ -450,7 +445,7 @@ ompi_proc_t **ompi_proc_get_allocated (size_t *size)
450445
/* now save only the procs that match this jobid */
451446
count = 0;
452447
OPAL_LIST_FOREACH(proc, &ompi_proc_list, ompi_proc_t) {
453-
if (OPAL_EQUAL == ompi_rte_compare_name_fields(mask, &proc->super.proc_name, &my_name)) {
448+
if (OPAL_EQUAL == ompi_rte_compare_name_fields(mask, &proc->super.proc_name, name)) {
454449
/* DO NOT RETAIN THIS OBJECT - the reference count on this
455450
* object will be adjusted by external callers. The intent
456451
* here is to allow the reference count to drop to zero if
@@ -474,6 +469,19 @@ ompi_proc_t **ompi_proc_get_allocated (size_t *size)
474469
return procs;
475470
}
476471

472+
ompi_proc_t **ompi_proc_get_allocated (size_t *size)
473+
{
474+
ompi_process_name_t my_name;
475+
476+
/* check bozo case */
477+
if (NULL == ompi_proc_local_proc) {
478+
return NULL;
479+
}
480+
my_name = *OMPI_CAST_RTE_NAME(&ompi_proc_local_proc->super.proc_name);
481+
482+
return ompi_proc_get_by_name(&my_name, size);
483+
}
484+
477485
ompi_proc_t **ompi_proc_world (size_t *size)
478486
{
479487
ompi_proc_t **procs;

ompi/proc/proc.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* Copyright (c) 2015-2016 Research Organization for Information Science
1818
* and Technology (RIST). All rights reserved.
1919
* Copyright (c) 2021 Nanook Consulting. All rights reserved.
20+
* Copyright (c) 2025 BULL S.A.S. All rights reserved.
2021
* $COPYRIGHT$
2122
*
2223
* Additional copyrights may follow
@@ -192,6 +193,24 @@ OMPI_DECLSPEC ompi_proc_t** ompi_proc_world(size_t* size);
192193

193194
OMPI_DECLSPEC int ompi_proc_world_size (void);
194195

196+
/**
197+
* Returns the list of proc with the given name
198+
* Returns the list of proc associated with the jobid of the given
199+
* name. If at least one proc with the jobid, then the name is known and we
200+
* return the procs.
201+
*
202+
* @note The reference count of each process in the array is
203+
* NOT incremented.
204+
*
205+
* @param[in] name Name containing the jobid of wanted processes
206+
* @param[in] size Number of processes in the ompi_proc_t array
207+
*
208+
* @return Array of pointers to proc instances under the same name in the current
209+
* MPI_COMM_WORLD, or NULL if there is an internal failure.
210+
*/
211+
OMPI_DECLSPEC ompi_proc_t **ompi_proc_get_by_name(const ompi_process_name_t *name,
212+
size_t *size);
213+
195214
/**
196215
* Returns the list of proc instances associated with this job.
197216
*

0 commit comments

Comments
 (0)