|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (C) 2013 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
This program performs a short test of MPI_BSEND in a
|
|
Packit Service |
c5cf8c |
multithreaded environment.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
It starts a single receiver thread that expects
|
|
Packit Service |
c5cf8c |
NUMSENDS messages and NUMSENDS sender threads, that
|
|
Packit Service |
c5cf8c |
use MPI_Bsend to send a message of size MSGSIZE
|
|
Packit Service |
c5cf8c |
to its right neigbour or rank 0 if (my_rank==comm_size-1), i.e.
|
|
Packit Service |
c5cf8c |
target_rank = (my_rank+1)%size .
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
After all messages have been received, the
|
|
Packit Service |
c5cf8c |
receiver thread prints a message, the threads
|
|
Packit Service |
c5cf8c |
are joined into the main thread and the application
|
|
Packit Service |
c5cf8c |
terminates.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include <mpi.h>
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#include "mpitest.h"
|
|
Packit Service |
c5cf8c |
#include "mpithreadtest.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define NUMSENDS 32
|
|
Packit Service |
c5cf8c |
#define BUFSIZE 10000000
|
|
Packit Service |
c5cf8c |
#define MSGSIZE 1024
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int rank, size;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void *receiver(void *ptr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int k;
|
|
Packit Service |
c5cf8c |
char buf[MSGSIZE];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
MPI_Recv(buf, MSGSIZE, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG,
|
|
Packit Service |
c5cf8c |
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void *sender_bsend(void *ptr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buffer[MSGSIZE];
|
|
Packit Service |
c5cf8c |
MTEST_VG_MEM_INIT(buffer, MSGSIZE * sizeof(char));
|
|
Packit Service |
c5cf8c |
MPI_Bsend(buffer, MSGSIZE, MPI_CHAR, (rank + 1) % size, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void *sender_ibsend(void *ptr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buffer[MSGSIZE];
|
|
Packit Service |
c5cf8c |
MPI_Request req;
|
|
Packit Service |
c5cf8c |
MTEST_VG_MEM_INIT(buffer, MSGSIZE * sizeof(char));
|
|
Packit Service |
c5cf8c |
MPI_Ibsend(buffer, MSGSIZE, MPI_CHAR, (rank + 1) % size, 0, MPI_COMM_WORLD, &req;;
|
|
Packit Service |
c5cf8c |
MPI_Wait(&req, MPI_STATUS_IGNORE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void *sender_isend(void *ptr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buffer[MSGSIZE];
|
|
Packit Service |
c5cf8c |
MPI_Request req;
|
|
Packit Service |
c5cf8c |
MTEST_VG_MEM_INIT(buffer, MSGSIZE * sizeof(char));
|
|
Packit Service |
c5cf8c |
MPI_Isend(buffer, MSGSIZE, MPI_CHAR, (rank + 1) % size, 0, MPI_COMM_WORLD, &req;;
|
|
Packit Service |
c5cf8c |
MPI_Wait(&req, MPI_STATUS_IGNORE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void *sender_send(void *ptr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buffer[MSGSIZE];
|
|
Packit Service |
c5cf8c |
MTEST_VG_MEM_INIT(buffer, MSGSIZE * sizeof(char));
|
|
Packit Service |
c5cf8c |
MPI_Send(buffer, MSGSIZE, MPI_CHAR, (rank + 1) % size, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char *argv[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int provided, i[2], k;
|
|
Packit Service |
c5cf8c |
char *buffer, *ptr_dt;
|
|
Packit Service |
c5cf8c |
buffer = (char *) malloc(BUFSIZE * sizeof(char));
|
|
Packit Service |
c5cf8c |
MTEST_VG_MEM_INIT(buffer, BUFSIZE * sizeof(char));
|
|
Packit Service |
c5cf8c |
MPI_Status status;
|
|
Packit Service |
c5cf8c |
pthread_t receiver_thread, sender_thread[NUMSENDS];
|
|
Packit Service |
c5cf8c |
pthread_attr_t attr;
|
|
Packit Service |
c5cf8c |
MPI_Comm communicator;
|
|
Packit Service |
c5cf8c |
int bs;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MTest_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (provided != MPI_THREAD_MULTIPLE) {
|
|
Packit Service |
c5cf8c |
printf("Error\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(911, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Buffer_attach(buffer, BUFSIZE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &size);
|
|
Packit Service |
c5cf8c |
MPI_Comm_dup(MPI_COMM_WORLD, &communicator); /* We do not use this communicator in this program, but
|
|
Packit Service |
c5cf8c |
* with this call, the problem appears more reliably.
|
|
Packit Service |
c5cf8c |
* If the MPI_Comm_dup() call is commented out, it is still
|
|
Packit Service |
c5cf8c |
* evident but does not appear that often (don't know why) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Initialize and set thread detached attribute */
|
|
Packit Service |
c5cf8c |
pthread_attr_init(&attr);
|
|
Packit Service |
c5cf8c |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
pthread_create(&receiver_thread, &attr, &receiver, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_create(&sender_thread[k], &attr, &sender_bsend, NULL);
|
|
Packit Service |
c5cf8c |
pthread_join(receiver_thread, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_join(sender_thread[k], NULL);
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
pthread_create(&receiver_thread, &attr, &receiver, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_create(&sender_thread[k], &attr, &sender_ibsend, NULL);
|
|
Packit Service |
c5cf8c |
pthread_join(receiver_thread, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_join(sender_thread[k], NULL);
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
pthread_create(&receiver_thread, &attr, &receiver, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_create(&sender_thread[k], &attr, &sender_isend, NULL);
|
|
Packit Service |
c5cf8c |
pthread_join(receiver_thread, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_join(sender_thread[k], NULL);
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
pthread_create(&receiver_thread, &attr, &receiver, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_create(&sender_thread[k], &attr, &sender_send, NULL);
|
|
Packit Service |
c5cf8c |
pthread_join(receiver_thread, NULL);
|
|
Packit Service |
c5cf8c |
for (k = 0; k < NUMSENDS; k++)
|
|
Packit Service |
c5cf8c |
pthread_join(sender_thread[k], NULL);
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
pthread_attr_destroy(&attr);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&communicator);
|
|
Packit Service |
c5cf8c |
MPI_Buffer_detach(&ptr_dt, &bs);
|
|
Packit Service |
c5cf8c |
free(buffer);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MTest_Finalize(0);
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|