You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
4.5 KiB
187 lines
4.5 KiB
4 years ago
|
#include "mpi.h"
|
||
|
#include <stdio.h>
|
||
|
/* stdlib is needed for declaring malloc */
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#define MAX2(a,b) (((a)>(b)) ? (a) : (b))
|
||
|
|
||
|
int GlobalReadInteger( void );
|
||
|
void Hello( void );
|
||
|
void Ring( void );
|
||
|
/*
|
||
|
* void Stress( void );
|
||
|
* void Globals( void );
|
||
|
* */
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
|
||
|
int me, option, namelen, size;
|
||
|
char processor_name[MPI_MAX_PROCESSOR_NAME];
|
||
|
|
||
|
MPI_Init(&argc, &argv);
|
||
|
MPI_Comm_rank(MPI_COMM_WORLD,&me);
|
||
|
MPI_Comm_size(MPI_COMM_WORLD,&size);
|
||
|
|
||
|
if (size < 2) {
|
||
|
fprintf(stderr, "systest requires at least 2 processes" );
|
||
|
MPI_Abort(MPI_COMM_WORLD,1);
|
||
|
}
|
||
|
|
||
|
MPI_Get_processor_name(processor_name,&namelen);
|
||
|
|
||
|
fprintf(stderr,"Process %d is alive on %s\n",
|
||
|
me, processor_name);
|
||
|
|
||
|
while (1) {
|
||
|
|
||
|
MPI_Barrier(MPI_COMM_WORLD);
|
||
|
|
||
|
again:
|
||
|
if (me == 0) {
|
||
|
/* Read user input for action */
|
||
|
/* (void) printf("\nOptions: 0=quit, 1=Hello, 2=Ring, 3=Stress, ");
|
||
|
* (void) printf("4=Globals : "); */
|
||
|
(void) printf("\nOptions: 0=quit, 1=Hello, 2=Ring : ");
|
||
|
(void) fflush(stdout);
|
||
|
}
|
||
|
option = GlobalReadInteger();
|
||
|
if ( (option < 0) || (option > 4) )
|
||
|
goto again;
|
||
|
|
||
|
switch (option) {
|
||
|
case 0:
|
||
|
MPI_Finalize();
|
||
|
return(0);
|
||
|
case 1:
|
||
|
Hello(); break;
|
||
|
case 2:
|
||
|
Ring(); break;
|
||
|
/*
|
||
|
* case 3:
|
||
|
* Stress(); break;
|
||
|
* case 4:
|
||
|
* Globals(); break;
|
||
|
* */
|
||
|
default:
|
||
|
fprintf(stderr,"systest: invalid option %d\n", option); break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int GlobalReadInteger( void )
|
||
|
/*
|
||
|
* Process zero reads an integer from stdin and broadcasts
|
||
|
* to everyone else
|
||
|
* */
|
||
|
{
|
||
|
int me, value;
|
||
|
|
||
|
MPI_Comm_rank(MPI_COMM_WORLD, &me);
|
||
|
if (me == 0) {
|
||
|
if (scanf("%d", &value) != 1)
|
||
|
fprintf(stderr,"failed reading integer value from stdin\n");
|
||
|
}
|
||
|
MPI_Bcast(&value, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
void Hello( void )
|
||
|
/*
|
||
|
* Everyone exchanges a hello message with everyone else.
|
||
|
* The hello message just comprises the sending and target nodes.
|
||
|
* */
|
||
|
{
|
||
|
int nproc, me;
|
||
|
int type = 1;
|
||
|
int buffer[2], node;
|
||
|
MPI_Status status;
|
||
|
|
||
|
MPI_Comm_rank(MPI_COMM_WORLD, &me);
|
||
|
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
|
||
|
|
||
|
if (me == 0) {
|
||
|
printf("\nHello test ... show network integrity\n----------\n\n");
|
||
|
fflush(stdout);
|
||
|
}
|
||
|
|
||
|
for (node = 0; node<nproc; node++) {
|
||
|
if (node != me) {
|
||
|
buffer[0] = me;
|
||
|
buffer[1] = node;
|
||
|
MPI_Send(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD);
|
||
|
MPI_Recv(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD, &status);
|
||
|
|
||
|
if ( (buffer[0] != node) || (buffer[1] != me) ) {
|
||
|
(void) fprintf(stderr, "Hello: %d!=%d or %d!=%d\n",
|
||
|
buffer[0], node, buffer[1], me);
|
||
|
printf("Mismatch on hello process ids; node = %d\n", node);
|
||
|
}
|
||
|
|
||
|
printf("Hello from %d to %d\n", me, node);
|
||
|
fflush(stdout);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Ring( void ) /* Time passing a message round a ring */
|
||
|
{
|
||
|
int nproc, me;
|
||
|
MPI_Status status;
|
||
|
int type = 4;
|
||
|
int left, right;
|
||
|
char *buffer;
|
||
|
int lenbuf, max_len;
|
||
|
double us_rate;
|
||
|
double start_ustime, used_ustime;
|
||
|
|
||
|
MPI_Comm_rank(MPI_COMM_WORLD, &me);
|
||
|
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
|
||
|
left = (me + nproc - 1) % nproc;
|
||
|
right = (me + 1) % nproc;
|
||
|
|
||
|
/* Find out how big a message to use */
|
||
|
|
||
|
if (me == 0) {
|
||
|
(void) printf("\nRing test...time network performance\n---------\n\n");
|
||
|
(void) printf("Input maximum message size: ");
|
||
|
(void) fflush(stdout);
|
||
|
}
|
||
|
max_len = GlobalReadInteger();
|
||
|
if ( (max_len <= 0) || (max_len >= 4*1024*1024) )
|
||
|
max_len = 512*1024;
|
||
|
if ( (buffer = (char *) malloc((unsigned) max_len)) == (char *) NULL) {
|
||
|
printf("process %d could not allocate buffer of size %d\n",me,max_len);
|
||
|
MPI_Abort(MPI_COMM_WORLD,7777);
|
||
|
}
|
||
|
|
||
|
lenbuf = 1;
|
||
|
while (lenbuf <= max_len) {
|
||
|
start_ustime = MPI_Wtime();
|
||
|
if (me == 0) {
|
||
|
MPI_Send(buffer,lenbuf,MPI_CHAR,left, type,MPI_COMM_WORLD);
|
||
|
MPI_Recv(buffer,lenbuf,MPI_CHAR,right,type,MPI_COMM_WORLD,&status);
|
||
|
}
|
||
|
else {
|
||
|
MPI_Recv(buffer,lenbuf,MPI_CHAR,right,type,MPI_COMM_WORLD,&status);
|
||
|
MPI_Send(buffer,lenbuf,MPI_CHAR,left, type,MPI_COMM_WORLD);
|
||
|
}
|
||
|
used_ustime = MPI_Wtime() - start_ustime;
|
||
|
|
||
|
if (used_ustime > 0) /* rate is megabytes per second */
|
||
|
us_rate = (double)(nproc*lenbuf / (used_ustime*(double)1000000));
|
||
|
else
|
||
|
us_rate = 0.0;
|
||
|
if (me == 0) {
|
||
|
printf("len=%d bytes, used= %f sec., rate=%f Mbytes/sec\n",
|
||
|
lenbuf, used_ustime, us_rate);
|
||
|
}
|
||
|
lenbuf *= 2;
|
||
|
}
|
||
|
if (me == 0)
|
||
|
printf("clock resolution in seconds: %10.8f\n", MPI_Wtick());
|
||
|
free(buffer);
|
||
|
}
|
||
|
|
||
|
|