-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/mpidi_pg.c
-: 0:Graph:mpidi_pg.gcno
-: 0:Data:mpidi_pg.gcda
-: 0:Runs:4382
-: 0:Programs:1376
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: * (C) 2001 by Argonne National Laboratory.
-: 4: * See COPYRIGHT in top-level directory.
-: 5: */
-: 6:
-: 7:#include "mpidimpl.h"
-: 8:#ifdef USE_PMI2_API
-: 9:#include "pmi2.h"
-: 10:#else
-: 11:#include "pmi.h"
-: 12:#endif
-: 13:
-: 14:#define MAX_JOBID_LEN 1024
-: 15:
-: 16:/* FIXME: These routines need a description. What is their purpose? Who
-: 17: calls them and why? What does each one do?
-: 18:*/
-: 19:static MPIDI_PG_t * MPIDI_PG_list = NULL;
-: 20:static MPIDI_PG_t * MPIDI_PG_iterator_next = NULL;
-: 21:static MPIDI_PG_Compare_ids_fn_t MPIDI_PG_Compare_ids_fn;
-: 22:static MPIDI_PG_Destroy_fn_t MPIDI_PG_Destroy_fn;
-: 23:
-: 24:/* Set verbose to 1 to record changes to the process group structure. */
-: 25:static int verbose = 0;
-: 26:
-: 27:/* Key track of the process group corresponding to the MPI_COMM_WORLD
-: 28: of this process */
-: 29:static MPIDI_PG_t *pg_world = NULL;
-: 30:
-: 31:#define MPIDI_MAX_KVS_KEY_LEN 256
-: 32:
-: 33:#undef FUNCNAME
-: 34:#define FUNCNAME MPIDI_PG_Init
-: 35:#undef FCNAME
-: 36:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 37:int MPIDI_PG_Init(int *argc_p, char ***argv_p,
-: 38: MPIDI_PG_Compare_ids_fn_t compare_ids_fn,
-: 39: MPIDI_PG_Destroy_fn_t destroy_fn)
4382: 40:{
4382: 41: int mpi_errno = MPI_SUCCESS;
-: 42: char *p;
-: 43:
4382: 44: MPIDI_PG_Compare_ids_fn = compare_ids_fn;
4382: 45: MPIDI_PG_Destroy_fn = destroy_fn;
-: 46:
-: 47: /* Check for debugging options. We use MPICHD_DBG and -mpichd-dbg
-: 48: to avoid confusion with the code in src/util/dbg/dbg_printf.c */
4382: 49: p = getenv( "MPICHD_DBG_PG" );
4382: 50: if (p && ( strcmp( p, "YES" ) == 0 || strcmp( p, "yes" ) == 0) )
|
#####: 51: verbose = 1;
|
4382: 52: if (argc_p && argv_p) {
3710: 53: int argc = *argc_p, i;
3710: 54: char **argv = *argv_p;
-: 55: /* applied patch from Juha Jeronen, req #3920 */
4984: 56: for (i=1; i<argc && argv[i]; i++) {
1274: 57: if (strcmp( "-mpichd-dbg-pg", argv[i] ) == 0) {
-: 58: int j;
|
#####: 59: verbose = 1;
#####: 60: for (j=i; j<argc-1; j++) {
#####: 61: argv[j] = argv[j+1];
-: 62: }
#####: 63: argv[argc-1] = NULL;
#####: 64: *argc_p = argc - 1;
#####: 65: break;
-: 66: }
-: 67: }
-: 68: }
-: 69:
|
4382: 70: return mpi_errno;
-: 71:}
-: 72:
-: 73:#undef FUNCNAME
-: 74:#define FUNCNAME MPIDI_PG_Finalize
-: 75:#undef FCNAME
-: 76:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 77:/*@
-: 78: MPIDI_PG_Finalize - Finalize the process groups, including freeing all
-: 79: process group structures
-: 80: @*/
-: 81:int MPIDI_PG_Finalize(void)
4374: 82:{
4374: 83: int mpi_errno = MPI_SUCCESS;
-: 84: MPIDI_PG_t *pg, *pgNext;
-: 85: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_FINALIZE);
-: 86:
-: 87: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_FINALIZE);
-: 88:
-: 89: /* Print the state of the process groups */
4374: 90: if (verbose) {
|
#####: 91: MPIU_PG_Printall( stdout );
-: 92: }
-: 93:
-: 94: /* FIXME - straighten out the use of PMI_Finalize - no use after
-: 95: PG_Finalize */
|
4374: 96: if (pg_world->connData) {
-: 97:#ifdef USE_PMI2_API
-: 98: mpi_errno = PMI2_Finalize();
|
-: 99: if (mpi_errno) MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**ch3|pmi_finalize");
-: 100:#else
-: 101: int rc;
|
4374: 102: rc = PMI_Finalize();
4374: 103: if (rc) {
|
#####: 104: MPIU_ERR_SET1(mpi_errno,MPI_ERR_OTHER,
-: 105: "**ch3|pmi_finalize",
-: 106: "**ch3|pmi_finalize %d", rc);
-: 107: }
-: 108:#endif
-: 109: }
-: 110:
-: 111: /* Free the storage associated with the process groups */
|
4374: 112: pg = MPIDI_PG_list;
13281: 113: while (pg) {
4533: 114: pgNext = pg->next;
-: 115:
-: 116: /* In finalize, we free all process group information, even if
-: 117: the ref count is not zero. This can happen if the user
-: 118: fails to use MPI_Comm_disconnect on communicators that
-: 119: were created with the dynamic process routines.*/
-: 120: /* XXX DJG FIXME-MT should we be checking this? */
-: 121: if (MPIU_Object_get_ref(pg) == 0 || 1) {
4533: 122: if (pg == MPIDI_Process.my_pg)
4374: 123: MPIDI_Process.my_pg = NULL;
-: 124:
4533: 125: MPIU_Object_set_ref(pg, 0); /* satisfy assertions in PG_Destroy */
4533: 126: MPIDI_PG_Destroy( pg );
-: 127: }
4533: 128: pg = pgNext;
-: 129: }
-: 130:
-: 131: /* If COMM_WORLD is still around (it normally should be),
-: 132: try to free it here. The reason that we need to free it at this
-: 133: point is that comm_world (and comm_self) still exist, and
-: 134: hence the usual process to free the related VC structures will
-: 135: not be invoked. */
4374: 136: if (MPIDI_Process.my_pg) {
|
#####: 137: MPIDI_PG_Destroy(MPIDI_Process.my_pg);
-: 138: }
|
4374: 139: MPIDI_Process.my_pg = NULL;
-: 140:
-: 141: /* ifdefing out this check because the list will not be NULL in
-: 142: Ch3_finalize because
-: 143: one additional reference is retained in MPIDI_Process.my_pg.
-: 144: That reference is released
-: 145: only after ch3_finalize returns. If I release it before ch3_finalize,
-: 146: the ssm channel crashes. */
-: 147:
-: 148:#if 0
-: 149:
-: 150: if (MPIDI_PG_list != NULL)
-: 151: {
-: 152:
|
-: 153: /* --BEGIN ERROR HANDLING-- */
-: 154: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_INTERN,
-: 155: "**dev|pg_finalize|list_not_empty", NULL);
-: 156: /* --END ERROR HANDLING-- */
-: 157: }
-: 158:#endif
-: 159:
-: 160: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_FINALIZE);
|
4374: 161: return mpi_errno;
-: 162:}
-: 163:
-: 164:/* FIXME: This routine needs to make it clear that the pg_id, for example
-: 165: is saved; thus, if the pg_id is a string, then that string is not
-: 166: copied and must be freed by a PG_Destroy routine */
-: 167:
-: 168:/* This routine creates a new process group description and appends it to
-: 169: the list of the known process groups. The pg_id is saved, not copied.
-: 170: The PG_Destroy routine that was set with MPIDI_PG_Init is responsible for
-: 171: freeing any storage associated with the pg_id.
-: 172:
-: 173: The new process group is returned in pg_ptr
-: 174:*/
-: 175:#undef FUNCNAME
-: 176:#define FUNCNAME MPIDI_PG_Create
-: 177:#undef FCNAME
-: 178:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 179:int MPIDI_PG_Create(int vct_sz, void * pg_id, MPIDI_PG_t ** pg_ptr)
6368: 180:{
6368: 181: MPIDI_PG_t * pg = NULL, *pgnext;
-: 182: int p;
6368: 183: int mpi_errno = MPI_SUCCESS;
6368: 184: MPIU_CHKPMEM_DECL(2);
-: 185: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_CREATE);
-: 186:
-: 187: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_CREATE);
-: 188:
6368: 189: MPIU_CHKPMEM_MALLOC(pg,MPIDI_PG_t*,sizeof(MPIDI_PG_t),mpi_errno,"pg");
12736: 190: MPIU_CHKPMEM_MALLOC(pg->vct,MPIDI_VC_t *,sizeof(MPIDI_VC_t)*vct_sz,
-: 191: mpi_errno,"pg->vct");
-: 192:
6368: 193: if (verbose) {
|
#####: 194: fprintf( stdout, "Creating a process group of size %d\n", vct_sz );
#####: 195: fflush(stdout);
-: 196: }
-: 197:
|
6368: 198: pg->handle = 0;
-: 199: /* The reference count indicates the number of vc's that are or
-: 200: have been in use and not disconnected. It starts at zero,
-: 201: except for MPI_COMM_WORLD. */
6368: 202: MPIU_Object_set_ref(pg, 0);
6368: 203: pg->size = vct_sz;
6368: 204: pg->id = pg_id;
-: 205: /* Initialize the connection information to null. Use
-: 206: the appropriate MPIDI_PG_InitConnXXX routine to set up these
-: 207: fields */
6368: 208: pg->connData = 0;
6368: 209: pg->getConnInfo = 0;
6368: 210: pg->connInfoToString = 0;
6368: 211: pg->connInfoFromString = 0;
6368: 212: pg->freeConnInfo = 0;
-: 213:
30185: 214: for (p = 0; p < vct_sz; p++)
-: 215: {
-: 216: /* Initialize device fields in the VC object */
23817: 217: MPIDI_VC_Init(&pg->vct[p], pg, p);
-: 218: }
-: 219:
-: 220: /* We may first need to initialize the channel before calling the channel
-: 221: VC init functions. This routine may be a no-op; look in the
-: 222: ch3_init.c file in each channel */
6368: 223: MPIU_CALL(MPIDI_CH3,PG_Init( pg ));
-: 224:
-: 225: /* These are now done in MPIDI_VC_Init */
-: 226:#if 0
-: 227: for (p = 0; p < vct_sz; p++)
-: 228: {
-: 229: /* Initialize the channel fields in the VC object */
-: 230: MPIDI_CH3_VC_Init( &pg->vct[p] );
-: 231: }
-: 232:#endif
-: 233:
-: 234: /* The first process group is always the world group */
6368: 235: if (!pg_world) { pg_world = pg; }
-: 236:
-: 237: /* Add pg's at the tail so that comm world is always the first pg */
6368: 238: pg->next = 0;
6368: 239: if (!MPIDI_PG_list)
-: 240: {
4382: 241: MPIDI_PG_list = pg;
-: 242: }
-: 243: else
-: 244: {
1986: 245: pgnext = MPIDI_PG_list;
4760: 246: while (pgnext->next)
-: 247: {
788: 248: pgnext = pgnext->next;
-: 249: }
1986: 250: pgnext->next = pg;
-: 251: }
6368: 252: *pg_ptr = pg;
-: 253:
6368: 254: fn_exit:
|
-: 255: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_CREATE);
|
6368: 256: return mpi_errno;
-: 257:
|
-: 258: fn_fail:
|
#####: 259: MPIU_CHKPMEM_REAP();
-: 260: goto fn_exit;
-: 261:}
-: 262:
-: 263:#undef FUNCNAME
-: 264:#define FUNCNAME MPIDI_PG_Destroy
-: 265:#undef FCNAME
-: 266:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 267:int MPIDI_PG_Destroy(MPIDI_PG_t * pg)
|
6360: 268:{
-: 269: MPIDI_PG_t * pg_prev;
-: 270: MPIDI_PG_t * pg_cur;
-: 271: int i;
6360: 272: int mpi_errno = MPI_SUCCESS;
-: 273: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_DESTROY);
-: 274:
-: 275: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_DESTROY);
-: 276:
6360: 277: MPIU_Assert(MPIU_Object_get_ref(pg) == 0);
-: 278:
6360: 279: pg_prev = NULL;
6360: 280: pg_cur = MPIDI_PG_list;
15215: 281: while(pg_cur != NULL)
-: 282: {
8855: 283: if (pg_cur == pg)
-: 284: {
6360: 285: if (MPIDI_PG_iterator_next == pg)
-: 286: {
|
#####: 287: MPIDI_PG_iterator_next = MPIDI_PG_iterator_next->next;
-: 288: }
-: 289:
|
6360: 290: if (pg_prev == NULL)
4533: 291: MPIDI_PG_list = pg->next;
-: 292: else
1827: 293: pg_prev->next = pg->next;
-: 294:
-: 295: MPIU_DBG_MSG_FMT(CH3_DISCONNECT, VERBOSE, (MPIU_DBG_FDEST, "destroying pg=%p pg->id=%s", pg, (char *)pg->id));
-: 296:
30162: 297: for (i = 0; i < pg->size; ++i) {
-: 298: /* FIXME it would be good if we could make this assertion.
-: 299: Unfortunately, either:
-: 300: 1) We're not being disciplined and some caller of this
-: 301: function doesn't bother to manage all the refcounts
-: 302: because he thinks he knows better. Annoying, but not
-: 303: strictly a bug.
-: 304: (wdg - actually, that is a bug - managing the ref
-: 305: counts IS required and missing one is a bug.)
-: 306: 2) There is a real bug lurking out there somewhere and we
-: 307: just haven't hit it in the tests yet. */
-: 308: /*MPIU_Assert(MPIU_Object_get_ref(pg->vct[i]) == 0);*/
-: 309:
-: 310: MPIU_DBG_MSG_FMT(CH3_DISCONNECT, VERBOSE, (MPIU_DBG_FDEST, "about to free pg->vct=%p which contains vc=%p", pg->vct, &pg->vct[i]));
-: 311:
-: 312: /* This used to be handled in MPID_VCRT_Release, but that was
-: 313: not the right place to do this. The VC should only be freed
-: 314: when the PG that it belongs to is freed, not just when the
-: 315: VC's refcount drops to zero. [goodell@ 2008-06-13] */
-: 316: /* In that case, the fact that the VC is in the PG should
-: 317: increment the ref count - reflecting the fact that the
-: 318: use in the PG constitutes a reference-count-incrementing
-: 319: use. Alternately, if the PG is able to recreate a VC,
-: 320: and can thus free unused (or idle) VCs, it should be allowed
-: 321: to do so. [wdg 2008-08-31] */
23802: 322: mpi_errno = MPIU_CALL(MPIDI_CH3,VC_Destroy(&(pg->vct[i])));
|
23802: 323: if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
-: 324: }
-: 325:
|
6360: 326: MPIDI_PG_Destroy_fn(pg);
6360: 327: MPIU_Free(pg->vct);
6360: 328: if (pg->connData) {
6360: 329: if (pg->freeConnInfo) {
6360: 330: (*pg->freeConnInfo)( pg );
-: 331: }
-: 332: else {
|
#####: 333: MPIU_Free(pg->connData);
-: 334: }
-: 335: }
|
6360: 336: mpi_errno = MPIU_CALL(MPIDI_CH3,PG_Destroy(pg));
6360: 337: MPIU_Free(pg);
-: 338:
6360: 339: goto fn_exit;
-: 340: }
-: 341:
2495: 342: pg_prev = pg_cur;
2495: 343: pg_cur = pg_cur->next;
-: 344: }
-: 345:
-: 346: /* PG not found if we got here */
|
#####: 347: MPIU_ERR_SET1(mpi_errno,MPI_ERR_OTHER,
-: 348: "**dev|pg_not_found", "**dev|pg_not_found %p", pg);
-: 349:
|
6360: 350: fn_exit:
|
-: 351: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_DESTROY);
|
6360: 352: return mpi_errno;
|
-: 353: fn_fail:
-: 354: goto fn_exit;
-: 355:}
-: 356:
-: 357:#undef FUNCNAME
-: 358:#define FUNCNAME MPIDI_PG_Find
-: 359:#undef FCNAME
-: 360:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 361:int MPIDI_PG_Find(void * id, MPIDI_PG_t ** pg_ptr)
|
10776: 362:{
-: 363: MPIDI_PG_t * pg;
10776: 364: int mpi_errno = MPI_SUCCESS;
-: 365: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_FIND);
-: 366:
-: 367: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_FIND);
-: 368:
10776: 369: pg = MPIDI_PG_list;
26193: 370: while (pg != NULL)
-: 371: {
13431: 372: if (MPIDI_PG_Compare_ids_fn(id, pg->id) != FALSE)
-: 373: {
8790: 374: *pg_ptr = pg;
8790: 375: goto fn_exit;
-: 376: }
-: 377:
4641: 378: pg = pg->next;
-: 379: }
-: 380:
1986: 381: *pg_ptr = NULL;
-: 382:
10776: 383: fn_exit:
|
-: 384: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_FIND);
|
10776: 385: return mpi_errno;
-: 386:}
-: 387:
-: 388:
-: 389:#undef FUNCNAME
-: 390:#define FUNCNAME MPIDI_PG_Id_compare
-: 391:#undef FCNAME
-: 392:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 393:int MPIDI_PG_Id_compare(void * id1, void *id2)
1567: 394:{
1567: 395: return MPIDI_PG_Compare_ids_fn(id1, id2);
-: 396:}
-: 397:
-: 398:/* iter always points at the next element */
-: 399:#undef FUNCNAME
-: 400:#define FUNCNAME MPIDI_PG_Get_next
-: 401:#undef FCNAME
-: 402:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 403:int MPIDI_PG_Get_next(MPIDI_PG_iterator *iter, MPIDI_PG_t ** pg_ptr)
9263: 404:{
9263: 405: *pg_ptr = (*iter);
9263: 406: if ((*iter) != NULL) {
9262: 407: (*iter) = (*iter)->next;
-: 408: }
-: 409:
9263: 410: return MPI_SUCCESS;
-: 411:}
-: 412:
-: 413:#undef FUNCNAME
-: 414:#define FUNCNAME MPIDI_PG_Has_next
-: 415:#undef FCNAME
-: 416:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 417:int MPIDI_PG_Has_next(MPIDI_PG_iterator *iter)
|
#####: 418:{
#####: 419: return (*iter != NULL);
-: 420:}
-: 421:
-: 422:#undef FUNCNAME
-: 423:#define FUNCNAME MPIDI_PG_Get_iterator
-: 424:#undef FCNAME
-: 425:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 426:int MPIDI_PG_Get_iterator(MPIDI_PG_iterator *iter)
|
9240: 427:{
9240: 428: *iter = MPIDI_PG_list;
9240: 429: return MPI_SUCCESS;
-: 430:}
-: 431:
-: 432:/* FIXME: What does DEV_IMPLEMENTS_KVS mean? Why is it used? Who uses
-: 433: PG_To_string and why? */
-: 434:
-: 435:#ifdef MPIDI_DEV_IMPLEMENTS_KVS
-: 436:
-: 437:/* PG_To_string is used in the implementation of connect/accept (and
-: 438: hence in spawn) in ch3u_port.c */
-: 439:/* Note: Allocated memory that is returned in str_ptr. The user of
-: 440: this routine must free that data */
-: 441:#undef FUNCNAME
-: 442:#define FUNCNAME MPIDI_PG_To_string
-: 443:#undef FCNAME
-: 444:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 445:int MPIDI_PG_To_string(MPIDI_PG_t *pg_ptr, char **str_ptr, int *lenStr)
1537: 446:{
1537: 447: int mpi_errno = MPI_SUCCESS;
-: 448: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_TO_STRING);
-: 449:
-: 450: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_TO_STRING);
-: 451:
-: 452: /* Replace this with the new string */
1537: 453: if (pg_ptr->connInfoToString) {
1537: 454: (*pg_ptr->connInfoToString)( str_ptr, lenStr, pg_ptr );
-: 455: }
-: 456: else {
|
#####: 457: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,"**noConnInfoToString");
-: 458: }
-: 459:
-: 460: /*printf( "PgToString: Pg string is %s\n", *str_ptr ); fflush(stdout);*/
|
1537: 461:fn_exit:
|
-: 462: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_TO_STRING);
|
1537: 463: return mpi_errno;
|
-: 464:fn_fail:
-: 465: goto fn_exit;
-: 466:}
-: 467:
-: 468:/* This routine takes a string description of a process group (created with
-: 469: MPIDI_PG_To_string, usually on a different process) and returns a pointer to
-: 470: the matching process group. If the group already exists, flag is set to
-: 471: false. If the group does not exist, it is created with MPIDI_PG_Create (and
-: 472: hence is added to the list of active process groups) and flag is set to
-: 473: true. In addition, the connection information is set up using the
-: 474: information in the input string.
-: 475:*/
-: 476:#undef FUNCNAME
-: 477:#define FUNCNAME MPIDI_PG_Create_from_string
-: 478:#undef FCNAME
-: 479:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 480:int MPIDI_PG_Create_from_string(const char * str, MPIDI_PG_t ** pg_pptr,
-: 481: int *flag)
|
3404: 482:{
3404: 483: int mpi_errno = MPI_SUCCESS;
-: 484: const char *p;
-: 485: int vct_sz;
3404: 486: MPIDI_PG_t *existing_pg, *pg_ptr=0;
-: 487: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_CREATE_FROM_STRING);
-: 488:
-: 489: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_CREATE_FROM_STRING);
-: 490:
-: 491: /*printf( "PgCreateFromString: Creating pg from %s\n", str );
-: 492: fflush(stdout); */
-: 493: /* The pg_id is at the beginning of the string, so we can just pass
-: 494: it to the find routine */
-: 495: /* printf( "Looking for pg with id %s\n", str );fflush(stdout); */
3404: 496: mpi_errno = MPIDI_PG_Find((void *)str, &existing_pg);
|
3404: 497: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
-: 498:
|
3404: 499: if (existing_pg != NULL) {
-: 500: /* return the existing PG */
1418: 501: *pg_pptr = existing_pg;
1418: 502: *flag = 0;
-: 503: /* Note that the memory for the pg_id is freed in the exit */
1418: 504: goto fn_exit;
-: 505: }
1986: 506: *flag = 1;
-: 507:
-: 508: /* Get the size from the string */
1986: 509: p = str;
1986: 510: while (*p) p++; p++;
1986: 511: vct_sz = atoi(p);
-: 512:
1986: 513: mpi_errno = MPIDI_PG_Create(vct_sz, (void *)str, pg_pptr);
1986: 514: if (mpi_errno != MPI_SUCCESS) {
|
#####: 515: MPIU_ERR_POP(mpi_errno);
-: 516: }
-: 517:
|
1986: 518: pg_ptr = *pg_pptr;
1986: 519: pg_ptr->id = MPIU_Strdup( str );
-: 520:
-: 521: /* Set up the functions to use strings to manage connection information */
1986: 522: MPIDI_PG_InitConnString( pg_ptr );
1986: 523: (*pg_ptr->connInfoFromString)( str, pg_ptr );
-: 524:
3404: 525:fn_exit:
|
-: 526: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_CREATE_FROM_STRING);
|
3404: 527: return mpi_errno;
|
-: 528:fn_fail:
-: 529: goto fn_exit;
-: 530:}
-: 531:
-: 532:#ifdef HAVE_CTYPE_H
-: 533:/* Needed for isdigit */
-: 534:#include <ctype.h>
-: 535:#endif
-: 536:
-: 537:/* Convert a process group id into a number. This is a hash-based approach,
-: 538: * which has the potential for some collisions. This is an alternative to the
-: 539: * previous approach that caused req#3930, which was to sum up the values of the
-: 540: * characters. The summing approach worked OK when the id's were all similar
-: 541: * but with an incrementing prefix or suffix, but terrible for a 32 hex-character
-: 542: * UUID type of id.
-: 543: *
-: 544: * FIXME It would really be best if the PM could give us this value.
-: 545: */
-: 546:void MPIDI_PG_IdToNum( MPIDI_PG_t *pg, int *id )
|
12667: 547:{
12667: 548: const char *p = (const char *)pg->id;
12667: 549: int pgid = 0;
-: 550:
464117: 551: while (*p) {
438783: 552: pgid += *p++;
438783: 553: pgid += (pgid << 10);
438783: 554: pgid ^= (pgid >> 6);
-: 555: }
12667: 556: pgid += (pgid << 3);
12667: 557: pgid ^= (pgid >> 11);
12667: 558: pgid += (pgid << 15);
-: 559:
-: 560: /* restrict to 31 bits */
12667: 561: *id = (pgid & 0x7fffffff);
12667: 562:}
-: 563:#else
-: 564:/* FIXME: This is a temporary hack for devices that do not define
-: 565: MPIDI_DEV_IMPLEMENTS_KVS
-: 566: FIXME: MPIDI_DEV_IMPLEMENTS_KVS should be removed
-: 567: */
-: 568:void MPIDI_PG_IdToNum( MPIDI_PG_t *pg, int *id )
-: 569:{
-: 570: *id = 0;
-: 571:}
-: 572:#endif
-: 573:
-: 574:/*
-: 575: * Managing connection information for process groups
-: 576: *
-: 577: *
-: 578: */
-: 579:
-: 580:/* Setting a process's connection information
-: 581:
-: 582: This is a collective call (for scalability) over all of the processes in
-: 583: the same MPI_COMM_WORLD.
-: 584:*/
-: 585:#undef FUNCNAME
-: 586:#define FUNCNAME MPIDI_PG_SetConnInfo
-: 587:#undef FCNAME
-: 588:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 589:int MPIDI_PG_SetConnInfo( int rank, const char *connString )
4382: 590:{
-: 591:#ifdef USE_PMI2_API
-: 592: int mpi_errno = MPI_SUCCESS;
-: 593: int len;
-: 594: char key[PMI2_MAX_KEYLEN];
-: 595: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_SetConnInfo);
-: 596:
-: 597: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_SetConnInfo);
-: 598:
-: 599: len = MPIU_Snprintf(key, sizeof(key), "P%d-businesscard", rank);
-: 600: MPIU_ERR_CHKANDJUMP1(len < 0 || len > sizeof(key), mpi_errno, MPI_ERR_OTHER, "**snprintf", "**snprintf %d", len);
-: 601:
-: 602: mpi_errno = PMI2_KVS_Put(key, connString);
|
-: 603: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
-: 604:
-: 605: mpi_errno = PMI2_KVS_Fence();
-: 606: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
-: 607:
-: 608: fn_exit:
-: 609: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_SetConnInfo);
-: 610: return mpi_errno;
-: 611: fn_fail:
-: 612: goto fn_exit;
-: 613:#else
|
4382: 614: int mpi_errno = MPI_SUCCESS;
-: 615: int pmi_errno;
-: 616: int len;
-: 617: char key[128];
-: 618: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_SetConnInfo);
-: 619:
-: 620: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_SetConnInfo);
-: 621:
4382: 622: MPIU_Assert(pg_world->connData);
-: 623:
4382: 624: len = MPIU_Snprintf(key, sizeof(key), "P%d-businesscard", rank);
4382: 625: if (len < 0 || len > sizeof(key)) {
|
#####: 626: MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**snprintf",
-: 627: "**snprintf %d", len);
-: 628: }
|
4382: 629: pmi_errno = PMI_KVS_Put(pg_world->connData, key, connString );
4382: 630: if (pmi_errno != PMI_SUCCESS) {
|
#####: 631: MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**pmi_kvs_put",
-: 632: "**pmi_kvs_put %d", pmi_errno);
-: 633: }
|
4382: 634: pmi_errno = PMI_KVS_Commit(pg_world->connData);
4382: 635: if (pmi_errno != PMI_SUCCESS) {
|
#####: 636: MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**pmi_kvs_commit",
-: 637: "**pmi_kvs_commit %d", pmi_errno);
-: 638: }
-: 639:
|
4382: 640: pmi_errno = PMI_Barrier();
4382: 641: if (pmi_errno != PMI_SUCCESS) {
|
#####: 642: MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**pmi_barrier",
-: 643: "**pmi_barrier %d", pmi_errno);
-: 644: }
|
4382: 645: fn_exit:
|
-: 646: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_SetConnInfo);
|
4382: 647: return mpi_errno;
|
-: 648: fn_fail:
-: 649: goto fn_exit;
-: 650:#endif
-: 651:}
-: 652:
-: 653:/* For all of these routines, the format of the process group description
-: 654: that is created and used by the connTo/FromString routines is this:
-: 655: (All items are strings, terminated by null)
-: 656:
-: 657: process group id string
-: 658: sizeof process group (as string)
-: 659: conninfo for rank 0
-: 660: conninfo for rank 1
-: 661: ...
-: 662:
-: 663: The "conninfo for rank 0" etc. for the original (MPI_COMM_WORLD)
-: 664: process group are stored in the PMI_KVS space with the keys
-: 665: p<rank>-businesscard .
-: 666:
-: 667: Fixme: Add a routine to publish the connection info to this file so that
-: 668: the key for the businesscard is defined in just this one file.
-: 669:*/
-: 670:
-: 671:
-: 672:/* The "KVS" versions are for the process group to which the calling
-: 673: process belongs. These use the PMI_KVS routines to access the
-: 674: process information */
-: 675:#undef FUNCNAME
-: 676:#define FUNCNAME getConnInfoKVS
-: 677:#undef FCNAME
-: 678:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 679:static int getConnInfoKVS( int rank, char *buf, int bufsize, MPIDI_PG_t *pg )
|
9012: 680:{
-: 681:#ifdef USE_PMI2_API
-: 682: char key[MPIDI_MAX_KVS_KEY_LEN];
-: 683: int mpi_errno = MPI_SUCCESS, rc;
-: 684: int vallen;
-: 685:
-: 686: rc = MPIU_Snprintf(key, MPIDI_MAX_KVS_KEY_LEN, "P%d-businesscard", rank );
-: 687: if (rc < 0 || rc > MPIDI_MAX_KVS_KEY_LEN) {
|
-: 688: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
-: 689: }
-: 690:
-: 691: mpi_errno = PMI2_KVS_Get(pg->connData, PMI2_ID_NULL, key, buf, bufsize, &vallen);
-: 692: if (mpi_errno) {
-: 693: MPIDI_PG_CheckForSingleton();
-: 694: mpi_errno = PMI2_KVS_Get(pg->connData, PMI2_ID_NULL, key, buf, bufsize, &vallen);
-: 695: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
-: 696: }
-: 697: fn_exit:
-: 698: return mpi_errno;
-: 699: fn_fail:
-: 700: goto fn_exit;
-: 701:#else
-: 702: char key[MPIDI_MAX_KVS_KEY_LEN];
|
9012: 703: int mpi_errno = MPI_SUCCESS, rc, pmi_errno;
-: 704:
9012: 705: rc = MPIU_Snprintf(key, MPIDI_MAX_KVS_KEY_LEN, "P%d-businesscard", rank );
9012: 706: if (rc < 0 || rc > MPIDI_MAX_KVS_KEY_LEN) {
|
#####: 707: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
-: 708: }
|
9012: 709: pmi_errno = PMI_KVS_Get(pg->connData, key, buf, bufsize );
9012: 710: if (pmi_errno) {
|
#####: 711: MPIDI_PG_CheckForSingleton();
#####: 712: pmi_errno = PMI_KVS_Get(pg->connData, key, buf, bufsize );
-: 713: }
|
9012: 714: if (pmi_errno) {
|
#####: 715: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**pmi_kvs_get");
-: 716: }
-: 717:
|
9012: 718: fn_exit:
9012: 719: return mpi_errno;
|
-: 720: fn_fail:
-: 721: goto fn_exit;
-: 722:#endif
-: 723:}
-: 724:
-: 725:/* *slen is the length of the string, including the null terminator. So if the
-: 726: resulting string is |foo\0bar\0|, then *slen == 8. */
-: 727:static int connToStringKVS( char **buf_p, int *slen, MPIDI_PG_t *pg )
|
1336: 728:{
1336: 729: char *string = 0;
1336: 730: char *pg_idStr = (char *)pg->id; /* In the PMI/KVS space,
-: 731: the pg id is a string */
-: 732: char buf[MPIDI_MAX_KVS_VALUE_LEN];
1336: 733: int i, j, vallen, rc, mpi_errno = MPI_SUCCESS, len;
-: 734: int curSlen;
-: 735:
-: 736: /* Make an initial allocation of a string with an estimate of the
-: 737: needed space */
1336: 738: len = 0;
1336: 739: curSlen = 10 + pg->size * 128;
1336: 740: string = (char *)MPIU_Malloc( curSlen );
-: 741:
-: 742: /* Start with the id of the pg */
49432: 743: while (*pg_idStr && len < curSlen)
46760: 744: string[len++] = *pg_idStr++;
1336: 745: string[len++] = 0;
-: 746:
-: 747: /* Add the size of the pg */
1336: 748: MPIU_Snprintf( &string[len], curSlen - len, "%d", pg->size );
1336: 749: while (string[len]) len++;
1336: 750: len++;
-: 751:
3974: 752: for (i=0; i<pg->size; i++) {
2638: 753: rc = getConnInfoKVS( i, buf, MPIDI_MAX_KVS_VALUE_LEN, pg );
2638: 754: if (rc) {
|
#####: 755: MPIU_Internal_error_printf(
-: 756: "Panic: getConnInfoKVS failed for %s (rc=%d)\n",
-: 757: (char *)pg->id, rc );
-: 758: }
-: 759:#ifndef USE_PERSISTENT_SHARED_MEMORY
-: 760: /* FIXME: This is a hack to avoid including shared-memory
-: 761: queue names in the business card that may be used
-: 762: by processes that were not part of the same COMM_WORLD.
-: 763: To fix this, the shared memory channels should look at the
-: 764: returned connection info and decide whether to use
-: 765: sockets or shared memory by determining whether the
-: 766: process is in the same MPI_COMM_WORLD. */
-: 767: /* FIXME: The more general problem is that the connection information
-: 768: needs to include some information on the range of validity (e.g.,
-: 769: all processes, same comm world, particular ranks), and that
-: 770: representation needs to be scalable */
-: 771:/* printf( "Adding key %s value %s\n", key, val ); */
-: 772: {
|
2638: 773: char *p = strstr( buf, "$shm_host" );
2638: 774: if (p) p[1] = 0;
-: 775: /* printf( "(fixed) Adding key %s value %s\n", key, val ); */
-: 776: }
-: 777:#endif
-: 778: /* Add the information to the output buffer */
2638: 779: vallen = strlen(buf);
-: 780: /* Check that this will fix in the remaining space */
2638: 781: if (len + vallen + 1 >= curSlen) {
|
#####: 782: char *nstring = 0;
#####: 783: curSlen += (pg->size - i) * (vallen + 1 );
#####: 784: nstring = MPIU_Realloc( string, curSlen);
#####: 785: if (!nstring) {
|
#####: 786: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
-: 787: }
|
#####: 788: string = nstring;
-: 789: }
-: 790: /* Append to string */
|
153004: 791: for (j=0; j<vallen+1; j++) {
150366: 792: string[len++] = buf[j];
-: 793: }
-: 794: }
-: 795:
1336: 796: MPIU_Assert(len <= curSlen);
-: 797:
1336: 798: *buf_p = string;
1336: 799: *slen = len;
1336: 800: fn_exit:
1336: 801: return mpi_errno;
|
#####: 802: fn_fail:
|
#####: 803: if (string) MPIU_Free(string);
-: 804: goto fn_exit;
-: 805:}
-: 806:static int connFromStringKVS( const char *buf ATTRIBUTE((unused)),
-: 807: MPIDI_PG_t *pg ATTRIBUTE((unused)) )
#####: 808:{
-: 809: /* Fixme: this should be a failure to call this routine */
#####: 810: return MPI_SUCCESS;
-: 811:}
-: 812:static int connFreeKVS( MPIDI_PG_t *pg )
|
4374: 813:{
4374: 814: if (pg->connData) {
4374: 815: MPIU_Free( pg->connData );
-: 816: }
4374: 817: return MPI_SUCCESS;
-: 818:}
-: 819:
-: 820:
-: 821:#undef FUNCNAME
-: 822:#define FUNCNAME MPIDI_PG_InitConnKVS
-: 823:#undef FCNAME
-: 824:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 825:int MPIDI_PG_InitConnKVS( MPIDI_PG_t *pg )
4382: 826:{
-: 827:#ifdef USE_PMI2_API
-: 828: int mpi_errno = MPI_SUCCESS;
-: 829:
-: 830: pg->connData = (char *)MPIU_Malloc(MAX_JOBID_LEN);
-: 831: if (pg->connData == NULL) {
|
-: 832: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**nomem");
-: 833: }
-: 834:
-: 835: mpi_errno = PMI2_Job_GetId(pg->connData, MAX_JOBID_LEN);
-: 836: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
-: 837:#else
-: 838: int pmi_errno, kvs_name_sz;
|
4382: 839: int mpi_errno = MPI_SUCCESS;
-: 840:
4382: 841: pmi_errno = PMI_KVS_Get_name_length_max( &kvs_name_sz );
4382: 842: if (pmi_errno != PMI_SUCCESS) {
|
#####: 843: MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,
-: 844: "**pmi_kvs_get_name_length_max",
-: 845: "**pmi_kvs_get_name_length_max %d", pmi_errno);
-: 846: }
-: 847:
|
4382: 848: pg->connData = (char *)MPIU_Malloc(kvs_name_sz + 1);
4382: 849: if (pg->connData == NULL) {
|
#####: 850: MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**nomem");
-: 851: }
-: 852:
|
4382: 853: pmi_errno = PMI_KVS_Get_my_name(pg->connData, kvs_name_sz);
4382: 854: if (pmi_errno != PMI_SUCCESS) {
|
#####: 855: MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,
-: 856: "**pmi_kvs_get_my_name",
-: 857: "**pmi_kvs_get_my_name %d", pmi_errno);
-: 858: }
-: 859:#endif
|
4382: 860: pg->getConnInfo = getConnInfoKVS;
4382: 861: pg->connInfoToString = connToStringKVS;
4382: 862: pg->connInfoFromString = connFromStringKVS;
4382: 863: pg->freeConnInfo = connFreeKVS;
-: 864:
4382: 865: fn_exit:
4382: 866: return mpi_errno;
|
#####: 867: fn_fail:
|
#####: 868: if (pg->connData) { MPIU_Free(pg->connData); }
-: 869: goto fn_exit;
-: 870:}
-: 871:
-: 872:/* Return the kvsname associated with the MPI_COMM_WORLD of this process. */
-: 873:int MPIDI_PG_GetConnKVSname( char ** kvsname )
|
4346: 874:{
4346: 875: *kvsname = pg_world->connData;
4346: 876: return MPI_SUCCESS;
-: 877:}
-: 878:
-: 879:/* For process groups that are not our MPI_COMM_WORLD, store the connection
-: 880: information in an array of strings. These routines and structure
-: 881: implement the access to this information. */
-: 882:typedef struct {
-: 883: int toStringLen; /* Length needed to encode this connection info */
-: 884: char ** connStrings; /* pointer to an array, indexed by rank, containing
-: 885: connection information */
-: 886:} MPIDI_ConnInfo;
-: 887:
-: 888:static int getConnInfo( int rank, char *buf, int bufsize, MPIDI_PG_t *pg )
997: 889:{
997: 890: MPIDI_ConnInfo *connInfo = (MPIDI_ConnInfo *)pg->connData;
-: 891:
-: 892: /* printf( "Entering getConnInfo\n" ); fflush(stdout); */
997: 893: if (!connInfo || !connInfo->connStrings || !connInfo->connStrings[rank]) {
-: 894: /* FIXME: Turn this into a valid error code create/return */
|
#####: 895: printf( "Fatal error in getConnInfo (rank = %d)\n", rank );
#####: 896: printf( "connInfo = %p\n", connInfo );fflush(stdout);
#####: 897: if (connInfo) {
#####: 898: printf( "connInfo->connStrings = %p\n", connInfo->connStrings );
-: 899: }
-: 900: /* Fatal error. Connection information missing */
#####: 901: fflush(stdout);
-: 902: }
-: 903:
-: 904: /* printf( "Copying %s to buf\n", connInfo->connStrings[rank] ); fflush(stdout); */
-: 905:
|
997: 906: MPIU_Strncpy( buf, connInfo->connStrings[rank], bufsize );
997: 907: return MPI_SUCCESS;
-: 908:}
-: 909:
-: 910:#undef FUNCNAME
-: 911:#define FUNCNAME connToString
-: 912:#undef FCNAME
-: 913:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 914:static int connToString( char **buf_p, int *slen, MPIDI_PG_t *pg )
201: 915:{
201: 916: int mpi_errno = MPI_SUCCESS;
201: 917: char *str = NULL, *pg_id;
201: 918: int i, len=0;
201: 919: MPIU_CHKPMEM_DECL(1);
201: 920: MPIDI_ConnInfo *connInfo = (MPIDI_ConnInfo *)pg->connData;
-: 921:
-: 922: /* Create this from the string array */
201: 923: MPIU_CHKPMEM_MALLOC(str, char *, connInfo->toStringLen, mpi_errno, "str");
-: 924:
-: 925:#if defined(MPICH_DEBUG_MEMINIT)
-: 926: memset(str, 0, connInfo->toStringLen);
-: 927:#endif
-: 928:
201: 929: pg_id = pg->id;
-: 930: /* FIXME: This is a hack, and it doesn't even work */
-: 931: /* MPIDI_PrintConnStrToFile( stdout, __FILE__, __LINE__,
-: 932: "connToString: pg id is", (char *)pg_id );*/
-: 933: /* This is intended to cause a process to transition from a singleton
-: 934: to a non-singleton. */
-: 935: /* XXX DJG TODO figure out what this little bit is all about. */
201: 936: if (strstr( pg_id, "singinit_kvs" ) == pg_id) {
-: 937:#ifdef USE_PMI2_API
-: 938: MPIU_Assertp(0); /* don't know what to do here for pmi2 yet. DARIUS */
-: 939:#else
|
#####: 940: PMI_Get_id( pg->id, 256 );
-: 941:#endif
-: 942: }
-: 943:
|
7035: 944: while (*pg_id) str[len++] = *pg_id++;
201: 945: str[len++] = 0;
-: 946:
201: 947: MPIU_Snprintf( &str[len], 20, "%d", pg->size);
-: 948: /* Skip over the length */
402: 949: while (str[len++]);
-: 950:
-: 951: /* Copy each connection string */
1003: 952: for (i=0; i<pg->size; i++) {
802: 953: char *p = connInfo->connStrings[i];
802: 954: while (*p) { str[len++] = *p++; }
802: 955: str[len++] = 0;
-: 956: }
-: 957:
201: 958: if (len > connInfo->toStringLen) {
|
#####: 959: *buf_p = 0;
#####: 960: *slen = 0;
#####: 961: MPIU_ERR_INTERNALANDJUMP(mpi_errno, "len > connInfo->toStringLen");
-: 962: }
-: 963:
|
201: 964: *buf_p = str;
201: 965: *slen = len;
-: 966:
201: 967:fn_exit:
201: 968: MPIU_CHKPMEM_COMMIT();
201: 969: return mpi_errno;
|
-: 970:fn_fail:
|
#####: 971: MPIU_CHKPMEM_REAP();
-: 972: goto fn_exit;
-: 973:
-: 974:}
-: 975:static int connFromString( const char *buf, MPIDI_PG_t *pg )
|
1986: 976:{
1986: 977: MPIDI_ConnInfo *conninfo = 0;
1986: 978: int i, mpi_errno = MPI_SUCCESS;
1986: 979: const char *buf0 = buf; /* save the start of buf */
-: 980:
-: 981: /* printf( "Starting with buf = %s\n", buf );fflush(stdout); */
-: 982:
-: 983: /* Skip the pg id */
1986: 984: while (*buf) buf++; buf++;
-: 985:
-: 986: /* Determine the size of the pg */
1986: 987: pg->size = atoi( buf );
1986: 988: while (*buf) buf++; buf++;
-: 989:
1986: 990: conninfo = (MPIDI_ConnInfo *)MPIU_Malloc( sizeof(MPIDI_ConnInfo) );
1986: 991: conninfo->connStrings = (char **)MPIU_Malloc( pg->size * sizeof(char *));
-: 992:
-: 993: /* For now, make a copy of each item */
6510: 994: for (i=0; i<pg->size; i++) {
-: 995: /* printf( "Adding conn[%d] = %s\n", i, buf );fflush(stdout); */
4524: 996: conninfo->connStrings[i] = MPIU_Strdup( buf );
4524: 997: while (*buf) buf++;
4524: 998: buf++;
-: 999: }
1986: 1000: pg->connData = conninfo;
-: 1001:
-: 1002: /* Save the length of the string needed to encode the connection
-: 1003: information */
1986: 1004: conninfo->toStringLen = (int)(buf - buf0) + 1;
-: 1005:
1986: 1006: return mpi_errno;
-: 1007:}
-: 1008:static int connFree( MPIDI_PG_t *pg )
1986: 1009:{
1986: 1010: MPIDI_ConnInfo *conninfo = (MPIDI_ConnInfo *)pg->connData;
-: 1011: int i;
-: 1012:
6510: 1013: for (i=0; i<pg->size; i++) {
4524: 1014: MPIU_Free( conninfo->connStrings[i] );
-: 1015: }
1986: 1016: MPIU_Free( conninfo->connStrings );
1986: 1017: MPIU_Free( conninfo );
-: 1018:
1986: 1019: return MPI_SUCCESS;
-: 1020:}
-: 1021:
-: 1022:#ifdef USE_DBG_LOGGING
-: 1023:/* This is a temporary routine that is used to print out the pg string.
-: 1024: A better approach may be to convert it into a single (long) string
-: 1025: with no nulls. */
-: 1026:int MPIDI_PrintConnStr( const char *file, int line,
-: 1027: const char *label, const char *str )
-: 1028:{
-: 1029: int pg_size, i;
-: 1030:
-: 1031: MPIU_DBG_Outevent( file, line, MPIU_DBG_CH3_CONNECT, 0, "%s", label );
-: 1032: MPIU_DBG_Outevent( file, line, MPIU_DBG_CH3_CONNECT, 0, "%s", str );
-: 1033:
-: 1034: /* Skip the pg id */
-: 1035: while (*str) str++; str++;
-: 1036:
-: 1037: /* Determine the size of the pg */
-: 1038: pg_size = atoi( str );
-: 1039: while (*str) str++; str++;
-: 1040:
-: 1041: for (i=0; i<pg_size; i++) {
-: 1042: MPIU_DBG_Outevent( file, line, MPIU_DBG_CH3_CONNECT, 0, "%s", str );
-: 1043: while (*str) str++;
-: 1044: str++;
-: 1045: }
-: 1046: return 0;
-: 1047:}
-: 1048:int MPIDI_PrintConnStrToFile( FILE *fd, const char *file, int line,
-: 1049: const char *label, const char *str )
-: 1050:{
-: 1051: int pg_size, i;
-: 1052:
-: 1053: fprintf( fd, "ConnStr from %s(%d); %s\n\t%s\n", file, line, label, str );
-: 1054:
-: 1055: /* Skip the pg id */
-: 1056: while (*str) str++; str++;
-: 1057:
-: 1058: fprintf( fd, "\t%s\n", str );
-: 1059: /* Determine the size of the pg */
-: 1060: pg_size = atoi( str );
-: 1061: while (*str) str++; str++;
-: 1062:
-: 1063: for (i=0; i<pg_size; i++) {
-: 1064: fprintf( fd, "\t%s\n", str );
-: 1065: while (*str) str++;
-: 1066: str++;
-: 1067: }
-: 1068: fflush(stdout);
-: 1069: return 0;
-: 1070:}
-: 1071:#endif
-: 1072:
-: 1073:int MPIDI_PG_InitConnString( MPIDI_PG_t *pg )
1986: 1074:{
1986: 1075: int mpi_errno = MPI_SUCCESS;
-: 1076:
1986: 1077: pg->connData = 0;
1986: 1078: pg->getConnInfo = getConnInfo;
1986: 1079: pg->connInfoToString = connToString;
1986: 1080: pg->connInfoFromString = connFromString;
1986: 1081: pg->freeConnInfo = connFree;
-: 1082:
1986: 1083: return mpi_errno;
-: 1084:}
-: 1085:
-: 1086:/* Temp to get connection value for rank r */
-: 1087:#undef FUNCNAME
-: 1088:#define FUNCNAME MPIDI_PG_GetConnString
-: 1089:#undef FCNAME
-: 1090:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 1091:int MPIDI_PG_GetConnString( MPIDI_PG_t *pg, int rank, char *val, int vallen )
7371: 1092:{
7371: 1093: int mpi_errno = MPI_SUCCESS;
-: 1094:
7371: 1095: if (pg->getConnInfo) {
7371: 1096: mpi_errno = (*pg->getConnInfo)( rank, val, vallen, pg );
-: 1097: }
-: 1098: else {
|
#####: 1099: MPIU_Internal_error_printf( "Panic: no getConnInfo defined!\n" );
-: 1100: }
-: 1101:
|
7371: 1102: return mpi_errno;
-: 1103:}
-: 1104:
-: 1105:
-: 1106:#undef FUNCNAME
-: 1107:#define FUNCNAME MPIDI_PG_Dup_vcr
-: 1108:#undef FCNAME
-: 1109:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 1110:/*@
-: 1111: MPIDI_PG_Dup_vcr - Duplicate a virtual connection from a process group
-: 1112:
-: 1113: Notes:
-: 1114: This routine provides a dup of a virtual connection given a process group
-: 1115: and a rank in that group. This routine is used only in initializing
-: 1116: the MPI-1 communicators 'MPI_COMM_WORLD' and 'MPI_COMM_SELF', and in creating
-: 1117: the initial intercommunicator after an 'MPI_Comm_spawn',
-: 1118: 'MPI_Comm_spawn_multiple', or 'MPI_Comm_connect/MPI_Comm_accept'.
-: 1119:
-: 1120: In addition to returning a dup of the virtual connection, it manages the
-: 1121: reference count of the process group, which is always the number of inuse
-: 1122: virtual connections.
-: 1123: @*/
-: 1124:int MPIDI_PG_Dup_vcr( MPIDI_PG_t *pg, int rank, MPIDI_VC_t **vc_p )
6938: 1125:{
-: 1126: MPIDI_VC_t *vc;
-: 1127: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_DUP_VCR);
-: 1128:
-: 1129: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_DUP_VCR);
-: 1130:
6938: 1131: vc = &pg->vct[rank];
-: 1132: /* Increase the reference count of the vc. If the reference count
-: 1133: increases from 0 to 1, increase the reference count of the
-: 1134: process group *and* the reference count of the vc (this
-: 1135: allows us to distinquish between Comm_free and Comm_disconnect) */
-: 1136: /* FIXME-MT: This should be a fetch and increment for thread-safety */
6938: 1137: if (MPIU_Object_get_ref(vc) == 0) {
5720: 1138: MPIDI_PG_add_ref(pg);
5720: 1139: MPIDI_VC_add_ref(vc);
-: 1140: }
6938: 1141: MPIDI_VC_add_ref(vc);
6938: 1142: *vc_p = vc;
-: 1143:
|
-: 1144: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_DUP_VCR);
|
6938: 1145: return MPI_SUCCESS;
-: 1146:}
-: 1147:
-: 1148:/* FIXME: This routine should invoke a close method on the connection,
-: 1149: rather than have all of the code here */
-: 1150:#undef FUNCNAME
-: 1151:#define FUNCNAME MPIDI_PG_Close_VCs
-: 1152:#undef FCNAME
-: 1153:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 1154:/*@
-: 1155: MPIDI_PG_Close_VCs - Close all virtual connections on all process groups.
-: 1156:
-: 1157: Note:
-: 1158: This routine is used in MPID_Finalize. It is here to keep the process-group
-: 1159: related functions together.
-: 1160: @*/
-: 1161:int MPIDI_PG_Close_VCs( void )
4374: 1162:{
4374: 1163: MPIDI_PG_t * pg = MPIDI_PG_list;
4374: 1164: int mpi_errno = MPI_SUCCESS;
-: 1165: MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_CLOSE_VCS);
-: 1166:
-: 1167: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_CLOSE_VCS);
-: 1168:
13281: 1169: while (pg) {
-: 1170: int i, inuse;
-: 1171:
-: 1172: MPIU_DBG_MSG_S(CH3_DISCONNECT,VERBOSE,"Closing vcs for pg %s",
-: 1173: (char *)pg->id );
-: 1174:
-: 1175:
24047: 1176: for (i = 0; i < pg->size; i++)
-: 1177: {
19514: 1178: MPIDI_VC_t * vc = &pg->vct[i];
-: 1179: /* If the VC is myself then skip the close message */
19514: 1180: if (pg == MPIDI_Process.my_pg && i == MPIDI_Process.my_pg_rank) {
-: 1181: /* XXX DJG FIXME-MT should we be checking this? */
4374: 1182: if (MPIU_Object_get_ref(vc) != 0) {
4374: 1183: MPIDI_PG_release_ref(pg, &inuse);
-: 1184: }
-: 1185: continue;
-: 1186: }
-: 1187:
15140: 1188: if (vc->state == MPIDI_VC_STATE_ACTIVE ||
-: 1189: vc->state == MPIDI_VC_STATE_REMOTE_CLOSE
-: 1190:#if defined(MPIDI_CH3_USES_SSHM) && 0
-: 1191: /* FIXME: Remove this IFDEF */
-: 1192: /* sshm queues are uni-directional. A VC that is connected
-: 1193: * in the read direction is marked MPIDI_VC_STATE_INACTIVE
-: 1194: * so that a connection will be formed on the first write.
-: 1195: * Since the other side is marked MPIDI_VC_STATE_ACTIVE for
-: 1196: * writing
-: 1197: * we need to initiate the close protocol on the read side
-: 1198: * even if the write state is MPIDI_VC_STATE_INACTIVE. */
-: 1199: || ((vc->state == MPIDI_VC_STATE_INACTIVE) &&
-: 1200: ((MPIDI_CH3I_VC *)(vc->channel_private))->shm_read_connected)
-: 1201:#endif
-: 1202: )
-: 1203: {
11292: 1204: MPIDI_CH3U_VC_SendClose( vc, i );
-: 1205: }
-: 1206: else
-: 1207: {
-: 1208: /* XXX DJG FIXME-MT should we be checking this? */
3848: 1209: if (vc->state == MPIDI_VC_STATE_INACTIVE && MPIU_Object_get_ref(vc) != 0) {
-: 1210: /* FIXME: If the reference count for the vc is not 0,
-: 1211: something is wrong */
3836: 1212: MPIDI_PG_release_ref(pg, &inuse);
-: 1213: }
-: 1214:
-: 1215: MPIU_DBG_MSG_FMT(CH3_DISCONNECT,VERBOSE,(MPIU_DBG_FDEST,
-: 1216: "vc=%p: not sending a close to %d, vc in state %s", vc,i,
-: 1217: MPIDI_VC_GetStateString(vc->state)));
-: 1218: }
-: 1219: }
4533: 1220: pg = pg->next;
-: 1221: }
-: 1222: /* Note that we do not free the process groups within this routine, even
-: 1223: if the reference counts have gone to zero. That is done once the
-: 1224: connections are in fact closed (by the final progress loop that
-: 1225: handles any close requests that this code generates) */
-: 1226:
|
-: 1227: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_CLOSE_VCS);
|
4374: 1228: return mpi_errno;
-: 1229:}
-: 1230:
-: 1231:/*
-: 1232: * This routine may be called to print the contents (including states and
-: 1233: * reference counts) for process groups.
-: 1234: */
-: 1235:int MPIU_PG_Printall( FILE *fp )
|
#####: 1236:{
-: 1237: MPIDI_PG_t *pg;
-: 1238: int i;
-: 1239:
#####: 1240: pg = MPIDI_PG_list;
-: 1241:
#####: 1242: fprintf( fp, "Process groups:\n" );
#####: 1243: while (pg) {
-: 1244: /* XXX DJG FIXME-MT should we be checking this? */
#####: 1245: fprintf( fp, "size = %d, refcount = %d, id = %s\n",
-: 1246: pg->size, MPIU_Object_get_ref(pg), (char *)pg->id );
#####: 1247: for (i=0; i<pg->size; i++) {
#####: 1248: fprintf( fp, "\tVCT rank = %d, refcount = %d, lpid = %d, state = %d \n",
-: 1249: pg->vct[i].pg_rank, MPIU_Object_get_ref(&pg->vct[i]),
-: 1250: pg->vct[i].lpid, (int)pg->vct[i].state );
-: 1251: }
#####: 1252: fflush(fp);
#####: 1253: pg = pg->next;
-: 1254: }
-: 1255:
#####: 1256: return 0;
-: 1257:}
-: 1258:
-: 1259:int MPIDI_PG_CheckForSingleton( void )
|
1337: 1260:{
-: 1261:
-: 1262:#ifdef USE_PMI2_API
-: 1263: MPIU_Assertp(0); /* figure this out for pmi2 DARIUS */
-: 1264:#else
1337: 1265: if (strstr((char*)pg_world->id,"singinit_kvs") == (char *)pg_world->id) {
-: 1266: char buf[256];
-: 1267: /* Force an enroll */
|
#####: 1268: PMI_KVS_Get( "foobar", "foobar", buf, sizeof(buf) );
#####: 1269: PMI_Get_id( pg_world->id, 256 );
#####: 1270: PMI_KVS_Get_my_name( pg_world->connData, 256 );
-: 1271: }
-: 1272:#endif
|
1337: 1273: return MPI_SUCCESS;
-: 1274:}
|