📄 initthread.c
字号:
MPIR_Process.icomm_world->handle = MPIR_ICOMM_WORLD; MPIU_Object_set_ref( MPIR_Process.icomm_world, 1 ); MPIR_Process.icomm_world->context_id = 8; /* XXX */ MPIR_Process.icomm_world->recvcontext_id= 8; MPIR_Process.icomm_world->attributes = NULL; MPIR_Process.icomm_world->local_group = NULL; MPIR_Process.icomm_world->remote_group = NULL; MPIR_Process.icomm_world->comm_kind = MPID_INTRACOMM; /* This initialization of the comm name could be done only when comm_get_name is called */ MPIU_Strncpy(MPIR_Process.icomm_world->name, "MPI_ICOMM_WORLD", MPI_MAX_OBJECT_NAME); MPIR_Process.icomm_world->errhandler = NULL; /* XXX */ MPIR_Process.icomm_world->coll_fns = NULL; /* XXX */ MPIR_Process.icomm_world->topo_fns = NULL; /* XXX */ /* Note that these communicators are not ready for use - MPID_Init will setup self and world, and icomm_world if it desires it. */#endif MPIR_Process.comm_parent = NULL; /* Setup the initial communicator list in case we have enabled the debugger message-queue interface */ MPIR_COMML_REMEMBER( MPIR_Process.comm_world ); MPIR_COMML_REMEMBER( MPIR_Process.comm_self ); /* Call any and all MPID_Init type functions */ /* FIXME: The call to err init should be within an ifdef HAVE_ ERROR_CHECKING block (as must all uses of Err_create_code) */ MPID_Wtime_init();#ifdef USE_DBG_LOGGING MPIU_DBG_PreInit( argc, argv );#endif MPIR_Err_init(); MPIR_Datatype_init(); MPIU_THREADPRIV_GET; MPIR_Nest_init(); /* MPIU_Timer_pre_init(); */ /* define MPI as initialized so that we can use MPI functions within MPID_Init if necessary */ MPIR_Process.initialized = MPICH_WITHIN_MPI; /* For any code in the device that wants to check for runtime decisions on the value of isThreaded, set a provisional value here. We could let the MPID_Init routine override this */#ifdef HAVE_RUNTIME_THREADCHECK MPIR_ThreadInfo.isThreaded = required == MPI_THREAD_MULTIPLE;#endif mpi_errno = MPID_Init(argc, argv, required, &thread_provided, &has_args, &has_env); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, "MPIR_Init_thread", __LINE__, MPI_ERR_OTHER, "**init", 0); /* FIXME: the default behavior for all MPI routines is to abort. This isn't always convenient, because there's no other way to get this routine to simply return. But we should provide some sort of control for that and follow the default defined by the standard */ return mpi_errno; } /* --END ERROR HANDLING-- */ /* Capture the level of thread support provided */ MPIR_ThreadInfo.thread_provided = thread_provided; if (provided) *provided = thread_provided; /* FIXME: Rationalize this with the above */#ifdef HAVE_RUNTIME_THREADCHECK MPIR_ThreadInfo.isThreaded = required == MPI_THREAD_MULTIPLE; if (provided) *provided = required;#endif /* FIXME: Define these in the interface. Does Timer init belong here? */ MPIU_dbg_init(MPIR_Process.comm_world->rank); MPIU_Timer_init(MPIR_Process.comm_world->rank, MPIR_Process.comm_world->local_size);#ifdef USE_MEMORY_TRACING MPIU_trinit( MPIR_Process.comm_world->rank ); /* Indicate that we are near the end of the init step; memory allocated already will have an id of zero; this helps separate memory leaks in the initialization code from leaks in the "active" code */ /* Uncomment this code to leave out any of the MPID_Init/etc memory allocations from the memory leak testing */ /* MPIU_trid( 1 ); */#endif#ifdef USE_DBG_LOGGING MPIU_DBG_Init( argc, argv, has_args, has_env, MPIR_Process.comm_world->rank );#endif /* FIXME: There is no code for this comment */ /* We now initialize the Fortran symbols from within the Fortran interface in the routine that first needs the symbols. This fixes a problem with symbols added by a Fortran compiler that are not part of the C runtime environment (the Portland group compilers would do this) */ /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) MPIR_Process.initialized = MPICH_PRE_INIT; /* --END ERROR HANDLING-- */#ifdef HAVE_DEBUGGER_SUPPORT MPIR_WaitForDebugger();#endif /* Let the device know that the rest of the init process is completed */ if (mpi_errno == MPI_SUCCESS) mpi_errno = MPID_InitCompleted(); return mpi_errno;}#endif#undef FUNCNAME#define FUNCNAME MPI_Init_thread/*@ MPI_Init_thread - Initialize the MPI execution environment Input Parameters:+ argc - Pointer to the number of arguments . argv - Pointer to the argument vector- required - Level of desired thread support Output Parameter:. provided - Level of provided thread support Command line arguments: MPI specifies no command-line arguments but does allow an MPI implementation to make use of them. See 'MPI_INIT' for a description of the command line arguments supported by 'MPI_INIT' and 'MPI_INIT_THREAD'. Notes: The valid values for the level of thread support are\:+ MPI_THREAD_SINGLE - Only one thread will execute. . MPI_THREAD_FUNNELED - The process may be multi-threaded, but only the main thread will make MPI calls (all MPI calls are funneled to the main thread). . MPI_THREAD_SERIALIZED - The process may be multi-threaded, and multiple threads may make MPI calls, but only one at a time: MPI calls are not made concurrently from two distinct threads (all MPI calls are serialized). - MPI_THREAD_MULTIPLE - Multiple threads may call MPI, with no restrictions. Notes for Fortran: Note that the Fortran binding for this routine does not have the 'argc' and 'argv' arguments. ('MPI_INIT_THREAD(required, provided, ierror)').N Errors.N MPI_SUCCESS.N MPI_ERR_OTHER.seealso: MPI_Init, MPI_Finalize@*/int MPI_Init_thread( int *argc, char ***argv, int required, int *provided ){ static const char FCNAME[] = "MPI_Init_thread"; int mpi_errno = MPI_SUCCESS; MPID_MPI_INIT_STATE_DECL(MPID_STATE_MPI_INIT_THREAD); MPID_CS_INITIALIZE(); /* FIXME: Can we get away without locking every time. Now, we need a MPID_CS_ENTER/EXIT around MPI_Init and MPI_Init_thread. Progress may be called within MPI_Init, e.g., by a spawned child process. Within progress, the lock is released and reacquired when blocking. If the lock isn't acquired before then, the release in progress is incorrect. Furthermore, if we don't release the lock after progress, we'll deadlock the next time this process tries to acquire the lock. MPID_CS_ENTER/EXIT functions are used here instead of MPIU_THREAD_SINGLE_CS_ENTER/EXIT because MPIR_ThreadInfo.isThreaded hasn't been initialized yet. */ MPID_CS_ENTER();#if 0 /* Create the thread-private region if necessary and go ahead and initialize it */ MPIU_THREADPRIV_INITKEY; MPIU_THREADPRIV_INIT;#endif MPID_MPI_INIT_FUNC_ENTER(MPID_STATE_MPI_INIT_THREAD); # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { if (MPIR_Process.initialized != MPICH_PRE_INIT) { mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPI_Init_thread", __LINE__, MPI_ERR_OTHER, "**inittwice", 0 ); } if (mpi_errno != MPI_SUCCESS) goto fn_fail; } MPID_END_ERROR_CHECKS; }# endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPIR_Init_thread( argc, argv, required, provided ); if (mpi_errno != MPI_SUCCESS) goto fn_fail; /* ... end of body of routine ... */ MPID_MPI_INIT_FUNC_EXIT(MPID_STATE_MPI_INIT_THREAD); MPID_CS_EXIT(); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */# ifdef HAVE_ERROR_REPORTING { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_init_thread", "**mpi_init_thread %p %p %d %p", argc, argv, required, provided); }# endif mpi_errno = MPIR_Err_return_comm( 0, FCNAME, mpi_errno ); MPID_MPI_INIT_FUNC_EXIT(MPID_STATE_MPI_INIT_THREAD); MPID_CS_EXIT(); MPID_CS_FINALIZE(); return mpi_errno; /* --END ERROR HANDLING-- */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -