📄 mpid_init.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#include "mpidimpl.h"#if defined(HAVE_LIMITS_H)#include <limits.h>#endif#if defined(HAVE_UNISTD_H)#include <unistd.h>#endif/* FIXME: This does not belong here */#ifdef USE_MPIU_DBG_PRINT_VCchar *MPIU_DBG_parent_str = "?";#endif/* FIXME: the PMI init function should ONLY do the PMI operations, not the process group or bc operations. These should be in a separate routine */#include "pmi.h"static int InitPG( int *argc_p, char ***argv_p, int *has_args, int *has_env, int *has_parent, int *pg_rank_p, MPIDI_PG_t **pg_p );static int MPIDI_CH3I_PG_Compare_ids(void * id1, void * id2);static int MPIDI_CH3I_PG_Destroy(MPIDI_PG_t * pg );MPIDI_Process_t MPIDI_Process = { NULL };MPIDI_CH3U_SRBuf_element_t * MPIDI_CH3U_SRBuf_pool = NULL;#undef FUNCNAME#define FUNCNAME MPID_Init#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_Init(int *argc, char ***argv, int requested, int *provided, int *has_args, int *has_env){ int mpi_errno = MPI_SUCCESS; int has_parent; MPIDI_PG_t * pg=NULL; int pg_rank=-1; int pg_size; MPID_Comm * comm; int p; MPIDI_STATE_DECL(MPID_STATE_MPID_INIT); MPIDI_FUNC_ENTER(MPID_STATE_MPID_INIT); /* FIXME: This is a good place to check for environment variables and command line options that may control the device */#if 1 /* This is a sanity check because we define a generic packet size */ if (sizeof(MPIDI_CH3_PktGeneric_t) < sizeof(MPIDI_CH3_Pkt_t)) { fprintf( stderr, "Internal error - packet definition is too small\n" ); exit(1); }#endif /* * Set global process attributes. These can be overridden by the channel * if necessary. */ MPIR_Process.attrs.tag_ub = MPIDI_TAG_UB; /* If the channel requires any setup before making any other channel calls (including CH3_PG_Init), the channel will define this routine (the dynamically loaded channel uses this) */#ifdef HAVE_CH3_PRELOAD mpi_errno = MPIDI_CH3_PreLoad(); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }#endif /* * Perform channel-independent PMI initialization */ mpi_errno = InitPG( argc, argv, has_args, has_env, &has_parent, &pg_rank, &pg ); if (mpi_errno) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|ch3_init"); } /* * Let the channel perform any necessary initialization * The channel init should assume that PMI_Init has been called and that * the basic information about the job has been extracted from PMI (e.g., * the size and rank of this process, and the process group id) */ mpi_errno = MPIU_CALL(MPIDI_CH3,Init(has_parent, pg, pg_rank)); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|ch3_init"); } /* FIXME: Why are pg_size and pg_rank handled differently? */ pg_size = MPIDI_PG_Get_size(pg); MPIDI_Process.my_pg = pg; /* brad : this is rework for shared memories * because they need this set earlier * for getting the business card */ MPIDI_Process.my_pg_rank = pg_rank; /* FIXME: Why do we add a ref to pg here? */ MPIDI_PG_add_ref(pg); /* * Initialize the MPI_COMM_WORLD object */ comm = MPIR_Process.comm_world; comm->rank = pg_rank; comm->remote_size = pg_size; comm->local_size = pg_size; mpi_errno = MPID_VCRT_Create(comm->remote_size, &comm->vcrt); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**dev|vcrt_create", "**dev|vcrt_create %s", "MPI_COMM_WORLD"); } mpi_errno = MPID_VCRT_Get_ptr(comm->vcrt, &comm->vcr); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**dev|vcrt_get_ptr", "dev|vcrt_get_ptr %s", "MPI_COMM_WORLD"); } /* Initialize the connection table on COMM_WORLD from the process group's connection table */ for (p = 0; p < pg_size; p++) { MPID_VCR_Dup(&pg->vct[p], &comm->vcr[p]); } MPID_Dev_comm_create_hook (comm); /* * Initialize the MPI_COMM_SELF object */ comm = MPIR_Process.comm_self; comm->rank = 0; comm->remote_size = 1; comm->local_size = 1; mpi_errno = MPID_VCRT_Create(comm->remote_size, &comm->vcrt); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**dev|vcrt_create", "**dev|vcrt_create %s", "MPI_COMM_SELF"); } mpi_errno = MPID_VCRT_Get_ptr(comm->vcrt, &comm->vcr); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**dev|vcrt_get_ptr", "dev|vcrt_get_ptr %s", "MPI_COMM_WORLD"); } MPID_VCR_Dup(&pg->vct[pg_rank], &comm->vcr[0]); /* Currently, mpidpre.h always defines MPID_NEEDS_ICOMM_WORLD. */#ifdef MPID_NEEDS_ICOMM_WORLD /* * Initialize the MPIR_ICOMM_WORLD object (an internal, private version * of MPI_COMM_WORLD) */ comm = MPIR_Process.icomm_world; comm->rank = pg_rank; comm->remote_size = pg_size; comm->local_size = pg_size;#if 0 mpi_errno = MPID_VCRT_Create(comm->remote_size, &comm->vcrt); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**dev|vcrt_create", "**dev|vcrt_create %s", "MPI_COMM_WORLD"); } mpi_errno = MPID_VCRT_Get_ptr(comm->vcrt, &comm->vcr); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**dev|vcrt_get_ptr", "dev|vcrt_get_ptr %s", "MPI_COMM_WORLD"); } /* Initialize the connection table on COMM_WORLD from the process group's connection table */ for (p = 0; p < pg_size; p++) { MPID_VCR_Dup(&pg->vct[p], &comm->vcr[p]); }#endif MPID_VCRT_Add_ref( MPIR_Process.comm_world->vcrt ); comm->vcrt = MPIR_Process.comm_world->vcrt; comm->vcr = MPIR_Process.comm_world->vcr; MPID_Dev_comm_create_hook (comm);#endif /* * If this process group was spawned by a MPI application, then * form the MPI_COMM_PARENT inter-communicator. */ /* * FIXME: The code to handle the parent case should be in a separate * routine and should not rely on #ifdefs */#ifndef MPIDI_CH3_HAS_NO_DYNAMIC_PROCESS if (has_parent) { char * parent_port; /* FIXME: To allow just the "root" process to request the port and then use MPIR_Bcast to distribute it to the rest of the processes, we need to perform the Bcast after MPI is otherwise initialized. We could do this by adding another MPID call that the MPI_Init(_thread) routine would make after the rest of MPI is initialized, but before MPI_Init returns. In fact, such a routine could be used to perform various checks, including parameter consistency value (e.g., all processes have the same environment variable values). Alternately, we could allow a few routines to operate with predefined parameter choices (e.g., bcast, allreduce) for the purposes of initialization. */ mpi_errno = MPIDI_CH3_GetParentPort(&parent_port); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|get_parent_port"); } MPIU_DBG_MSG_S(CH3_CONNECT,VERBOSE,"Parent port is %s\n", parent_port); mpi_errno = MPID_Comm_connect(parent_port, NULL, 0, MPIR_Process.comm_world, &comm); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**ch3|conn_parent", "**ch3|conn_parent %s", parent_port); } MPIR_Process.comm_parent = comm; MPIU_Assert(MPIR_Process.comm_parent != NULL); MPIU_Strncpy(comm->name, "MPI_COMM_PARENT", MPI_MAX_OBJECT_NAME); /* FIXME: Check that this intercommunicator gets freed in MPI_Finalize if not already freed. */ }#endif /* * Set provided thread level */ if (provided != NULL) { /* This must be min(requested,MPICH_THREAD_LEVEL) if runtime control of thread level is available */ *provided = (MPICH_THREAD_LEVEL < requested) ? MPICH_THREAD_LEVEL : requested; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -