📄 mpe_seq.c
字号:
#include "mpi.h"
#include "mpptest.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern void *malloc();
#endif
static int MPE_Seq_keyval = MPI_KEYVAL_INVALID;
/*
MPE_Seq_begin - Begins a sequential section of code.
Input Parameters:
+ comm - Communicator to sequentialize.
- ng - Number in group. This many processes are allowed to execute
at the same time. Usually one.
Notes:
MPE_Seq_begin and MPE_Seq_end provide a way to force a section of code to
be executed by the processes in rank order. Typically, this is done
with
$ MPE_Seq_begin( comm, 1 );
$ <code to be executed sequentially>
$ MPE_Seq_end( comm, 1 );
$
Often, the sequential code contains output statements (e.g., printf) to
be executed. Note that you may need to flush the I/O buffers before
calling MPE_Seq_end; also note that some systems do not propagate I/O in any
order to the controling terminal (in other words, even if you flush the
output, you may not get the data in the order that you want).
*/
void MPE_Seq_begin( MPI_Comm comm, int ng )
{
int lidx, np;
int flag;
MPI_Comm local_comm;
MPI_Status status;
/* Get the private communicator for the sequential operations */
if (MPE_Seq_keyval == MPI_KEYVAL_INVALID) {
MPI_Keyval_create( MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
&MPE_Seq_keyval, NULL );
}
MPI_Attr_get( comm, MPE_Seq_keyval, (void *)&local_comm, &flag );
if (!flag) {
/* This expects a communicator to be a pointer */
MPI_Comm_dup( comm, &local_comm );
MPI_Attr_put( comm, MPE_Seq_keyval, (void *)local_comm );
}
MPI_Comm_rank( comm, &lidx );
MPI_Comm_size( comm, &np );
if (lidx != 0) {
MPI_Recv( NULL, 0, MPI_INT, lidx-1, 0, local_comm, &status );
}
/* Send to the next process in the group unless we are the last process
in the processor set */
if ( (lidx % ng) < ng - 1 && lidx != np - 1) {
MPI_Send( NULL, 0, MPI_INT, lidx + 1, 0, local_comm );
}
}
/*@
MPE_Seq_end - Ends a sequential section of code.
Input Parameters:
+ comm - Communicator to sequentialize.
- ng - Number in group. This many processes are allowed to execute
at the same time. Usually one.
Notes:
See MPE_Seq_begin for more details.
@*/
void MPE_Seq_end( MPI_Comm comm, int ng )
{
int lidx, np, flag;
MPI_Status status;
MPI_Comm local_comm;
MPI_Comm_rank( comm, &lidx );
MPI_Comm_size( comm, &np );
MPI_Attr_get( comm, MPE_Seq_keyval, (void *)&local_comm, &flag );
if (!flag)
MPI_Abort( comm, MPI_ERR_UNKNOWN );
/* Send to the first process in the next group OR to the first process
in the processor set */
if ( (lidx % ng) == ng - 1 || lidx == np - 1) {
MPI_Send( NULL, 0, MPI_INT, (lidx + 1) % np, 0, local_comm );
}
if (lidx == 0) {
MPI_Recv( NULL, 0, MPI_INT, np-1, 0, local_comm, &status );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -