| |
MPI routines: Collective Communication
| MPI_Allgather |
Send data from each process in a group to
all the other processes in the group. Also see
MPI_Gather. |
| MPI_Allreduce |
Perform an operation on an operand and distribute
the result to all processes in the group. Also see
MPI_reduce. |
| MPI_Bcast |
Broadcasts a message from the root process
to all other processes in the group. |
| MPI_Gather |
Send data from processes in a group to the
root process (reverse of MPI_Scatter). |
| MPI_Reduce |
Perform an operation on an operand and store
the result on the root process. Also see
MPI_Allreduce. |
| MPI_Scatter |
Send data from one process to all other processes in the
group (reverse of MPI_Gather). |
Return the rank of the calling process in a communicator.
- Syntax
int MPI_Comm_rank(MPI_Comm comm int *rank)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank,work;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
if (myrank) printf("My process rank ==> %d\n",myrank);
MPI_Finalize();
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
My process rank ==> 1
Return the size of the group associated with a communicator.
- Syntax
int MPI_Comm_Size(MPI_Comm comm int *size)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank,work;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
if (!myrank) printf("Number of processes ==> %d\n",numprocs);
MPI_Finalize();
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
Number of processes ==> 2
Terminate the MPI execution environment.
- Syntax
- Notes
- This routine does not have to be the last line in
your program. It may be placed anywhere so long as
no other MPI library calls follow it.
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
MPI_Init(&argc, &argv );
printf ("The return code from MPI_Finalize is %d\n",MPI_Finalize());
}
mpirun -np 1 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1
The return code from MPI_Finalize is 0
Return the name of the processing node.
- Syntax
int MPI_Get_processor_name(char* name int resultlen)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank, namelen, i;
char processor_name[MPI_MAX_PROCESSOR_NAME];
char greeting[MPI_MAX_PROCESSOR_NAME + 80];
MPI_Status status;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
MPI_Get_processor_name(processor_name,&namelen);
sprintf(greeting, "hello, world from process %d of %d on %s",myrank,numprocs,processor_name);
if (myrank == 0) {
printf("%s\n", greeting);
for (i=1;inumprocs;i++) {
MPI_Recv(greeting,sizeof(greeting),MPI_CHAR,i,1,MPI_COMM_WORLD,&status);
printf("%s\n",greeting);
}
}
else
MPI_Send(greeting,strlen(greeting)+1,MPI_CHAR,0,1,MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
hello, world from process 0 of 2 on argo4-4
hello, world from process 1 of 2 on argo4-3
Start the MPI execution environment.
- Syntax
int MPI_Init(int* argc_ptr,char** argv_ptr[])
- Notes
- This routine does not have to be the first line in
your program. It may be placed anywhere so long as it
is executed before any calls to other MPI routines.
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
printf ("The return code from MPI_Init is %d\n",MPI_Init(&argc, &argv ));
MPI_Finalize();
}
mpirun -np 1 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1
The return code from MPI_Init is 0
See if the MPI environment has been initialized (has MPI_Init been called).
- Syntax
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int* rc1;
MPI_Initialized(rc1) ? printf("MPI_init called\n") : printf("MPI_Init not called\n");
MPI_Init(&argc, &argv);
!(MPI_Initialized(rc1)) ? printf("MPI_init called\n") : printf("MPI_Init not called\n");
MPI_Finalize();
}
mpirun -np 1 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1
MPI_Init not called
MPI_init called
Receive a message.
- Syntax
int MPI_Recv(void* message, int count,
MPI_Datatype datatype, int source, int tag,
MPI_Comm comm, MPI_Status* status)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank, namelen, i, num_chars, src;
char processor_name[MPI_MAX_PROCESSOR_NAME];
char greeting[100], *greeting1;
MPI_Status status;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
MPI_Get_processor_name(processor_name,&namelen);
sprintf(greeting,"Hello world from %s - process %d of %d",processor_name,myrank,numprocs);
if (myrank == 0) {
printf("Hello world from %s - process %d of %d\n",processor_name,myrank,numprocs);
for (i=1;inumprocs;i++) {
MPI_Probe(MPI_ANY_SOURCE,1,MPI_COMM_WORLD,&status);
MPI_Get_count(&status,MPI_CHAR,&num_chars);
src = status.MPI_SOURCE;
MPI_Recv(greeting,num_chars,MPI_CHAR,src,1,MPI_COMM_WORLD,&status);
printf("%s\n",greeting);
}
}
else {
MPI_Send(greeting,strlen(greeting)+1,MPI_CHAR,0,1,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
Hello world from argo4-4 - process 0 of 2
Hello world from argo4-3 - process 1 of 2
Send a message.
- Syntax
int MPI_Send(void* message, int count,
MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank, namelen, i, num_chars, src;
char processor_name[MPI_MAX_PROCESSOR_NAME];
char greeting[100], *greeting1;
MPI_Status status;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
MPI_Get_processor_name(processor_name,&namelen);
sprintf(greeting,"Hello world from %s - process %d of %d",processor_name,myrank,numprocs);
if (myrank == 0) {
printf("Hello world from %s - process %d of %d\n",processor_name,myrank,numprocs);
for (i=1;inumprocs;i++) {
MPI_Probe(MPI_ANY_SOURCE,1,MPI_COMM_WORLD,&status);
MPI_Get_count(&status,MPI_CHAR,&num_chars);
src = status.MPI_SOURCE;
MPI_Recv(greeting,num_chars,MPI_CHAR,src,1,MPI_COMM_WORLD,&status);
printf("%s\n",greeting);
}
}
else {
MPI_Send(greeting,strlen(greeting)+1,MPI_CHAR,0,1,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
Hello world from argo4-4 - process 0 of 2
Hello world from argo4-3 - process 1 of 2
Send data from each processes to all the other processes in
the group associated with communicator comm.
- Syntax
int MPI_Gather(void* send_data, int send_count,
MPI_Datatype sendtype, void* receive_data,
int receive_count, MPI_Datatype receivetype, int
root, MPI_Comm comm)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main (int argc, char *argv[])
{
int numprocs, myrank, loop, loop1;
int send_data[3] = { 3, 4, 5 };
int rec_data[3] = {-1,-1,-1};
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
for (loop=0;loop=2;loop++) {
if (myrank == loop) {
printf ("Process %d of %d: send_data[%d] ==> %d\n",myrank, numprocs, loop, send_data[loop]);
}
}
MPI_Allgather(send_data,3,MPI_INT,rec_data,3,MPI_INT,MPI_COMM_WORLD);
for (loop=0;loop<=numprocs;loop++) {
if (myrank == loop) {
printf("Process %d of %d\n",myrank,numprocs);
for (loop1=0;loop1=2;loop1++) {
printf("rec_data[%d] ==> %d\n",loop1,rec_data[loop1]);
}
printf("\n");
}
}
MPI_Finalize();
return 0;
}
mpirun -np 3 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1 argo4-2 1
Process 1 of 3: send_data[1] ==> 4
Process 2 of 3: send_data[2] ==> 5
Process 0 of 3: send_data[0] ==> 3
Process 1 of 3
rec_data[0] ==> 3
rec_data[1] ==> 4
rec_data[2] ==> 5
Process 0 of 3
rec_data[0] ==> 3
rec_data[1] ==> 4
rec_data[2] ==> 5
Process 2 of 3
rec_data[0] ==> 3
rec_data[1] ==> 4
rec_data[2] ==> 5
Peform the operation operator on each processes'
copy of operand and store the result in result
on all the processes in the communicator comm (unlike
MPI_Reduce which stores the result
just on the root process.
- Syntax
int MPI_Allreduce(void* operand, void* result, int count,
MPI_Datatype datatype, MPI_Op operator, MPI_Comm comm)
- Notes
-
As is also the case for MPI_Reduce aliasing,
referencing the same variable for the
fields operand and result is not
permitted. For example:
MPI_Allreduce(&total,&total,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD)
-
Click here to see a list
reduction operands.
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank;
float a1,a2;
float subtotal,total=0;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
if (!myrank) {
printf("Enter a and b\n");
scanf("%f %f", &a1, &a2);
}
MPI_Bcast(&a1,1,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Bcast(&a2,1,MPI_FLOAT,0,MPI_COMM_WORLD);
subtotal = a1 + a2;
printf("rank ==> %d of %d -- Subtotal ==> %f\n",myrank,numprocs,subtotal);
MPI_Allreduce(&subtotal,&total,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD);
printf("rank ==> %d of %d -- Grand total ==> %f\n",myrank,numprocs,total);
MPI_Finalize();
return 0;
}
mpirun -np 3 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1 argo4-2 1
Enter a and b
1 2
rank ==> 1 of 3 -- Subtotal ==> 3.000000
rank ==> 2 of 3 -- Subtotal ==> 3.000000
rank ==> 0 of 3 -- Subtotal ==> 3.000000
rank ==> 0 of 3 -- Grand total ==> 9.000000
rank ==> 1 of 3 -- Grand total ==> 9.000000
rank ==> 2 of 3 -- Grand total ==> 9.000000
Broadcast a message buffer from the root process
to every process in the communicator comm.
- Syntax
int MPI_Bcast(void* buffer, int count,
MPI_Datatype datatype, int root, MPI_Comm comm)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank;
float a1,a2;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
if (!myrank) {
printf("Enter a and b\n");
scanf("%f %f", &a1, &a2);
}
MPI_Bcast(&a1,1,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Bcast(&a2,1,MPI_FLOAT,0,MPI_COMM_WORLD);
printf("rank ==> %d of %d -- a1 ==> %f a2 ==> %f \n",myrank,numprocs,a1,a2);
MPI_Finalize();
return 0;
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
Enter a and b
1.01 2.02
rank ==> 0 of 2 -- a1 ==> 1.010000 a2 ==> 2.020000
rank ==> 1 of 2 -- a1 ==> 1.010000 a2 ==> 2.020000
MPI_Gather collects data from each process in
a group and returns it to the root
process. Datum is placed in a location
in the receive buffer that matches the sending process
id. Datum from process id zero is placed in the zero location,
datum from process id one is placed in location one, and so on
(see diagram below).
- Syntax
int MPI_Gather(void* send_data, int send_count,
MPI_Datatype sendtype, void* receive_data,
int receive_count, MPI_Datatype receivetype, int
root, MPI_Comm comm)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[])
{
int numprocs, myrank,loop;
int send_data[3]={3,4,5};
int rec_data[3];
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
for (loop=0;loop=2;loop++) {
if (myrank == loop) {
printf ("Process %d of %d: send_data[%d] ==> %d\n",myrank, numprocs, loop, send_data[loop]);
}
}
MPI_Gather(send_data,1,MPI_INT,rec_data,1,MPI_INT,0,MPI_COMM_WORLD);
if (!myrank) {
printf("\n");
for (loop=0;loop=2;loop++) {
printf("Process root: rec_data[%d] ==> %d\n",loop,rec_data[loop]);
}
}
MPI_Finalize();
return 0;
}
mpirun -np 3 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1 argo4-2 1
Process 1 of 3: send_data[1] ==> 4
Process 2 of 3: send_data[2] ==> 5
Process 0 of 3: send_data[0] ==> 3
Process root: rec_data[0] ==> 3
Process root: rec_data[1] ==> 4
Process root: rec_data[2] ==> 5
Peform the operation operator on each processes'
copy of operand and store the result in result
on the root process.
- Syntax
int MPI_Reduce(void* operand, void* result, int count,
MPI_Datatype datatype, MPI_Op operator, int root,
MPI_Comm comm)
- Notes
- Aliasing, referencing the same variable for the
fields operand and result is not
permitted. For example:
MPI_Reduce(&total,&total,1,MPI_FLOAT,MPI_SUM,0,MPI_COMM_WORLD)
-
MPI reduction operands
| MPI_MAX |
Maximum |
| MPI_MIN |
Minimum |
| MPI_SUM |
Sum |
| MPI_PROD |
Product |
| MPI_LAND |
Logical and |
| MPI_BAND |
Bitwise and |
| MPI_LOR |
Logical or |
| MPI_BOR |
Bitwise or |
| MPI_LXOR |
Logical exclusive or |
| MPI_BXOR |
Bitwise exclusive or |
| MPI_MAXLOC |
Maximum and location of maximum |
| MPI_MINLOC |
Minimum and location of minimum |
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank;
float a1,a2;
float subtotal,total=0;
MPI_Init(&argc, &argv );
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
if (!myrank) {
printf("Enter a and b\n");
scanf("%f %f", &a1, &a2);
}
MPI_Bcast(&a1,1,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Bcast(&a2,1,MPI_FLOAT,0,MPI_COMM_WORLD);
subtotal = a1 + a2;
printf("rank ==> %d of %d -- Subtotal ==> %f\n",myrank,numprocs,subtotal);
MPI_Reduce(&subtotal,&total,1,MPI_FLOAT,MPI_SUM,0,MPI_COMM_WORLD);
if (!myrank) printf("Grand total ==> %f\n",total);
MPI_Finalize();
return 0;
}
mpirun -np 3 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1 argo4-2 1
Enter a and b
2 3
rank ==> 1 of 3 -- Subtotal ==> 5.000000
rank ==> 2 of 3 -- Subtotal ==> 5.000000
rank ==> 0 of 3 -- Subtotal ==> 5.000000
Grand total ==> 15.000000
MPI_Scatter makes a subset of the data send_data
on the processs with rank root and sends to each
process in the communicator comm one of the subsets.
- Syntax
int MPI_Scatter(void* send_data, int send_count,
MPI_Datatype sendtype, void* receive_data,
int receive_count, MPI_Datatype receivetype, int
root, MPI_Comm comm)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[])
{
int numprocs, myrank,loop;
int send_data[6]={3,4,5,6,7,8};
int rec_data[2];
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (!myrank) printf("\nExample of scattering 2 data points from array send_data to each of 3 processes in MPI_COMM_WORLD\n\n");
MPI_Scatter(send_data,2,MPI_INT,rec_data,2,MPI_INT,0,MPI_COMM_WORLD);
printf("Process %d of %d: rec_data[%d] ==> %d\n",myrank,numprocs,0,rec_data[0]);
printf("Process %d of %d: rec_data[%d] ==> %d\n\n",myrank,numprocs,1,rec_data[1]);
MPI_Finalize();
return 0;
}
mpirun -np 3 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1 argo4-2 1
Example of scattering 2 data points from array send_data to each of 3 processes in MPI_COMM_WORLD
Process 1 of 3: rec_data[0] ==> 5
Process 1 of 3: rec_data[1] ==> 6
Process 0 of 3: rec_data[0] ==> 3
Process 0 of 3: rec_data[1] ==> 4
Process 2 of 3: rec_data[0] ==> 7
Process 2 of 3: rec_data[1] ==> 8
Return the address of the variable location.
- Syntax
int MPI_Address(void* location MPI_Aint* address)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
/* Derived datatype example program. Sending different types of data to other
processes */
int main( int argc, char *argv[])
{
#define elements 5
int numprocs, myrank,loop;
/* variables to pass to other processes */
float x=10.0, y=20.0, z=30.0;
int a=9;
int b[6]={3,4,5,6,7,8};
int blocks[elements] = {1,1,1,1,1};
MPI_Aint disp[elements];
MPI_Aint addresses[elements];
/* Define the types of variables to transmit */
MPI_Datatype type_of_data[elements] = {MPI_FLOAT,MPI_FLOAT,MPI_FLOAT,MPI_INT,MPI_INT};
MPI_Aint next_address;
MPI_Datatype pointer_to_new_mpi_type;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (!myrank) printf("\nExample of sending multiple variables, of various types, to other processes.\n\n");
/* Element #5 in the list of items to pass is a pointer to a six
element element array. Indicate that there are six elements.
blocks[4] = 6;
/* Get the address of each element to pass */
MPI_Address(&x,addresses+0); MPI_Address(&y,addresses+1);
MPI_Address(&z,addresses+2); MPI_Address(&a,addresses+3);
MPI_Address(&b,addresses+4);
/* Calculate relative address of the variables from the first
variable, x, in the list of items to pass */
for (loop = 0; loop elements; loop++){
disp[loop] = addresses[loop] - addresses[0];
}
/* Build the derived datatype for the items to pass */
MPI_Type_struct(elements,blocks,disp,type_of_data,&pointer_to_new_mpi_type);
MPI_Type_commit(&pointer_to_new_mpi_type);
/* Root contains the elements. Send them to other processes */
if (!myrank) MPI_Send(&x,1,pointer_to_new_mpi_type,1,0,MPI_COMM_WORLD);
else {
/* Non-root processes receive the variables and print them */
MPI_Recv(&x,1,pointer_to_new_mpi_type,0,0,MPI_COMM_WORLD,&status);
printf("In process with rank %d\n",myrank);
printf("\tx ==> %f y ==> %f z ==> %f a ==> %d\n",x,y,z,a);
for(loop=0;loop=elements;loop++){
printf("\tb[%d]==> %d\n",loop,b[loop]);
}
}
/* finish up */
MPI_Type_free(&pointer_to_new_mpi_type);
MPI_Finalize();
return 0;
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
Example of sending multiple variables, of various types, to other processes.
In process with rank 1
x ==> 10.000000 y ==> 20.000000 z ==> 30.000000 a ==> 9
b[0]==> 3
b[1]==> 4
b[2]==> 5
b[3]==> 6
b[4]==> 7
b[5]==> 8
Commit the datatype.
- Syntax
int MPI_Type_commit(MPI_Datatype* datatype)
- Notes
- Example program (C) including output:
The example program is in the section MPI_Address. Click
here to go there.
Mark the datatype for deallocation.
- Syntax
int MPI_Type_free(MPI_Datatype* datatype)
- Notes
- MPI_Type free frees the datatype by marking
the datatype variable to MPI_TYPE_NULL.
- Example program (C) including output:
The example program is in the section MPI_Address. Click
here to go there.
Build a general derived datatype constructor.
- Syntax
int MPI_Type_struct(int count int
block_lengths[],MPI_Aint displacements[],MPI_Datatype[],
MPI_Datatype* new_derived_type)
- Field #1 (count): the number of blocks of elements. In the
example program, there are five blocks. Don't confuse
the number of blocks with the number of elements within
a block. Each block, whether it contains a single variable
or an array, constitutes one block.
- Field #2 (block_lengths[]): the number of elements in each
block. In the example, the first four blocks each contain single
variables; the fifth block is an array containing six elements.
- Field #3 (displacements[]): the relative address of each block from
the first block. Each address is of type MPI_Aint, a special
MPI datatype that allows for addresses larger than what
can be represented by a standard C-type INTEGER.
- Field #4 (typelist[]): the type of data contained in each block. In the
example, the first three blocks each contain a single variable of type
FLOAT. The fourth block contains a single INTEGER variable. The
fifth block contains an array each element of that array is
an INTEGER.
- Field #5 (new_derived_type): a pointer to the
new MPI datatype. Also used by the call
MPI_Type_commit.
Notice the correspondence among the positional elements
in arrays block_lengths, displacements, and
typelist. For example,
the first element in block_lengths, block_lengths[0], contains
the number of entries in the first block. The
displacement of that first block is in displacement[0] and the
type of data elements (FLOAT, INT, etc) in that first block is given in typelist[0].
Information regarding the second element is contained within
position one, [1], of the appropriate arrays.
- Notes
- Example program (C) including output:
The example program is in the section MPI_Address. Click
here to go there.
A more strigent version of MPI_type_struct. Builds a
derived datatype constructor consisting of a subset of
entries in an array.
- Syntax
int MPI_Type_vector(int count int
block_length, int stride,MPI_Datatype,
MPI_Datatype* new_derived_type)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
/* Derived datatype example program. Sending subset of entries in an array */
int main( int argc, char *argv[])
{
#define elements 4
int numprocs, myrank, loop, count, block_length, stride;
MPI_Datatype pointer_to_new_mpi_type;
MPI_Status status;
/* two dimensional array. Pass column 3 to other processes */
int x[elements][6]={
{10,20,30,40,50,60},
{70,80,90,100,110,120},
{130,140,150,160,170,180},
{190,200,210,220,230,240}
};
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (!myrank) printf("\nExample program to print noncontiguous items in a two-dimensional array\n\n");
/* Build the derived datatype to pass column 3
Pass b[0][3] containing 40
b[1][3] " 100
b[2][3] " 160
b[3][3] " 220
count: number of elements (# of array entries) to pass
block_length: number of entries in each element
stride: number of elements between each element to pass
*/
count = elements; block_length = 1; stride = 6;
MPI_Type_vector(count,block_length,stride,MPI_INT,&pointer_to_new_mpi_type);
/* commit the new datatype */
MPI_Type_commit(&pointer_to_new_mpi_type);
/* Root contains the elements. Send them to other processes */
if (!myrank) MPI_Send(&x[0][3],1,pointer_to_new_mpi_type,1,0,MPI_COMM_WORLD);
else {
/* Non-root processes receive the variables and print them */
MPI_Recv(&x[0][3],1,pointer_to_new_mpi_type,0,0,MPI_COMM_WORLD,&status);
printf("In process with rank %d\n",myrank);
for(loop=0;loopelements;loop++){
printf("\tx[%d][3]==> %d\n",loop,x[loop][3]);
}
}
/* finish up */
MPI_Type_free(&pointer_to_new_mpi_type);
MPI_Finalize();
return 0;
}
mpirun -np 2 example
/opt/scali/bin/mpimon -stdin all example -- argo4-4 1 argo4-3 1
Example program to print noncontiguous items in a two-dimensional array
In process with rank 1
x[0][3]==> 40
x[1][3]==> 100
x[2][3]==> 160
x[3][3]==> 220
Get the underlying group associated with a communicator.
- Syntax
int MPI_Comm_group(MPI_Comm comm,MPI_Group* group)
- Notes
- Example program (C) including output:
#include "mpi.h"
#include stdio.h
int main( int argc, char *argv[] )
{
int numprocs, myrank, namelen, i, myrank_in_sub_group, num_chars, src;
char processor_name[MPI_MAX_PROCESSOR_NAME];
char greeting[MPI_MAX_PROCESSOR_NAME + 80];
MPI_Status status;
MPI_Group group_world;
MPI_Group sub_group;
MPI_Comm sub_group_comm;
int process_ranks[3]={0,1,2};
MPI_Init(&argc, &argv );
/* Get rank, number, and processor of processes in group whose tag is MPI_COMM_WORLD */
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
MPI_Get_processor_name(processor_name,&namelen);
sprintf(greeting,"Hello world from %s - process %d of %d in communicator MPI_COMM_WORLD",processor_name,myrank,numprocs);
if (myrank == 0) {
printf("%s\n",greeting);
for (i=1;inumprocs;i++) {
MPI_Probe(MPI_ANY_SOURCE,1,MPI_COMM_WORLD,&status);
MPI_Get_count(&status,MPI_CHAR,&num_chars);
src = status.MPI_SOURCE;
MPI_Recv(greeting,num_chars,MPI_CHAR,src,1,MPI_COMM_WORLD,&status);
printf("%s\n",greeting);
}
}
else {
MPI_Send(greeting,strlen(greeting)+1,MPI_CHAR,0,1,MPI_COMM_WORLD);
}
/* Get the group for communicator MPI_COMM_WORLD */
MPI_Comm_group(MPI_COMM_WORLD,&group_world);
/* Create a new group composed of three members of group underlying MPI_COMM_WORLD */
MPI_Group_incl(group_world,3,process_ranks,&sub_group);
/* Create a communicator for the new group */
MPI_Comm_create(MPI_COMM_WORLD,sub_group,&sub_group_comm);
/* Get my rank in the subgroup (communicator: sub_group_comm) */
MPI_Comm_rank(sub_group_comm,&myrank_in_sub_group);
/* Format a message and send it to root process for printing to STDOUT */
sprintf(greeting,"Hello again from %s - process %d of 3 in communicator sub_group_comm",processor_name,myrank_in_sub_group);
if (myrank == 0) {
printf("\n%s\n",greeting);
for (i=1;i3;i++) {
MPI_Probe(MPI_ANY_SOURCE,1,sub_group_comm,&status);
MPI_Get_count(&status,MPI_CHAR,&num_chars);
src = status.MPI_SOURCE;
MPI_Recv(greeting,num_chars,MPI_CHAR,src,1,sub_group_comm,&status);
printf("%s\n",greeting);
}
}
else {
MPI_Send(greeting,strlen(greeting)+1,MPI_CHAR,0,1,sub_group_comm);
}
MPI_Finalize();
return 0;
}
mpimon hello -- argo4-3 1 argo4-2 1 argo4-1 1
Hello world from argo4-3 - process 0 of 3 in communicator MPI_COMM_WORLD
Hello world from argo4-2 - process 1 of 3 in communicator MPI_COMM_WORLD
Hello world from argo4-1 - process 2 of 3 in communicator MPI_COMM_WORLD
Hello again from argo4-3 - process 0 of 3 in communicator sub_group_comm
Hello again from argo4-2 - process 1 of 3 in communicator sub_group_comm
Hello again from argo4-1 - process 2 of 3 in communicator sub_group_comm
Form a new group.
- Syntax
int MPI_Comm_rank(MPI_Group group,int n,int ranks[],MPI_Group* newgroup)
- Notes
- Example program (C) including output:
|
|