|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
* (C) 2011 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This test attempts to execute multiple simultaneous nonblocking collective
|
|
Packit |
0848f5 |
* (NBC) MPI routines at the same time, and manages their completion with a
|
|
Packit |
0848f5 |
* variety of routines (MPI_{Wait,Test}{,_all,_any,_some}). It also throws a
|
|
Packit |
0848f5 |
* few point-to-point operations into the mix.
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* Possible improvements:
|
|
Packit |
0848f5 |
* - post operations on multiple comms from multiple threads
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include "mpi.h"
|
|
Packit |
0848f5 |
#include <stdlib.h>
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
#include <string.h>
|
|
Packit |
0848f5 |
#include <assert.h>
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
0848f5 |
#include <unistd.h>
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
static int errs = 0;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Constants that control the high level test harness behavior. */
|
|
Packit |
0848f5 |
/* MAIN_ITERATIONS is how many NBC ops the test will attempt to issue. */
|
|
Packit |
0848f5 |
#define MAIN_ITERATIONS (100000)
|
|
Packit |
0848f5 |
/* WINDOW is the maximum number of outstanding NBC requests at any given time */
|
|
Packit |
0848f5 |
#define WINDOW (20)
|
|
Packit |
0848f5 |
/* we sleep with probability 1/CHANCE_OF_SLEEP */
|
|
Packit |
0848f5 |
#define CHANCE_OF_SLEEP (1000)
|
|
Packit |
0848f5 |
/* JITTER_DELAY is denominated in microseconds (us) */
|
|
Packit |
0848f5 |
#define JITTER_DELAY (50000) /* 0.05 seconds */
|
|
Packit |
0848f5 |
/* NUM_COMMS is the number of communicators on which ops will be posted */
|
|
Packit |
0848f5 |
#define NUM_COMMS (4)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Constants that control behavior of the individual testing operations.
|
|
Packit |
0848f5 |
* Altering these can help to explore the testing space, but increasing them too
|
|
Packit |
0848f5 |
* much can consume too much memory (often O(n^2) usage). */
|
|
Packit |
0848f5 |
/* FIXME is COUNT==10 too limiting? should we try a larger count too (~500)? */
|
|
Packit |
0848f5 |
#define COUNT (10)
|
|
Packit |
0848f5 |
#define PRIME (17)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define my_assert(cond_) \
|
|
Packit |
0848f5 |
do { \
|
|
Packit |
0848f5 |
if (!(cond_)) { \
|
|
Packit |
0848f5 |
++errs; \
|
|
Packit |
0848f5 |
if (errs < 10) { \
|
|
Packit |
0848f5 |
fprintf(stderr, "assertion (%s) failed on line %d\n", #cond_, __LINE__); \
|
|
Packit |
0848f5 |
} \
|
|
Packit |
0848f5 |
} \
|
|
Packit |
0848f5 |
} while (0)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Intended to act like "rand_r", but we can be sure that it will exist and be
|
|
Packit |
0848f5 |
* consistent across all of comm world. Returns a number in the range
|
|
Packit |
0848f5 |
* [0,GEN_PRN_MAX] */
|
|
Packit |
0848f5 |
#define GEN_PRN_MAX (4294967291-1)
|
|
Packit |
0848f5 |
static unsigned int gen_prn(unsigned int x)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* a simple "multiplicative congruential method" PRNG, with parameters:
|
|
Packit |
0848f5 |
* m=4294967291, largest 32-bit prime
|
|
Packit |
0848f5 |
* a=279470273, good primitive root of m from "TABLES OF LINEAR
|
|
Packit |
0848f5 |
* CONGRUENTIAL GENERATORS OF DIFFERENT SIZES AND GOOD
|
|
Packit |
0848f5 |
* LATTICE STRUCTURE", by Pierre L’Ecuyer */
|
|
Packit |
0848f5 |
return (279470273UL * (unsigned long) x) % 4294967291UL;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* given a random unsigned int value "rndval_" from gen_prn, this evaluates to a
|
|
Packit |
0848f5 |
* value in the range [min_,max_) */
|
|
Packit |
0848f5 |
#define rand_range(rndval_,min_,max_) \
|
|
Packit |
0848f5 |
((unsigned int)((min_) + ((rndval_) * (1.0 / (GEN_PRN_MAX+1.0)) * ((max_) - (min_)))))
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
static void sum_fn(void *invec, void *inoutvec, int *len, MPI_Datatype * datatype)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i;
|
|
Packit |
0848f5 |
int *in = invec;
|
|
Packit |
0848f5 |
int *inout = inoutvec;
|
|
Packit |
0848f5 |
for (i = 0; i < *len; ++i) {
|
|
Packit |
0848f5 |
inout[i] = in[i] + inout[i];
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* used to keep track of buffers that should be freed after the corresponding
|
|
Packit |
0848f5 |
* operation has completed */
|
|
Packit |
0848f5 |
struct laundry {
|
|
Packit |
0848f5 |
int case_num; /* which test case initiated this req/laundry */
|
|
Packit |
0848f5 |
MPI_Comm comm;
|
|
Packit |
0848f5 |
int *buf;
|
|
Packit |
0848f5 |
int *recvbuf;
|
|
Packit |
0848f5 |
int *sendcounts;
|
|
Packit |
0848f5 |
int *recvcounts;
|
|
Packit |
0848f5 |
int *sdispls;
|
|
Packit |
0848f5 |
int *rdispls;
|
|
Packit |
0848f5 |
int *sendtypes;
|
|
Packit |
0848f5 |
int *recvtypes;
|
|
Packit |
0848f5 |
};
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
static void cleanup_laundry(struct laundry *l)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
l->case_num = -1;
|
|
Packit |
0848f5 |
l->comm = MPI_COMM_NULL;
|
|
Packit |
0848f5 |
if (l->buf)
|
|
Packit |
0848f5 |
free(l->buf);
|
|
Packit |
0848f5 |
if (l->recvbuf)
|
|
Packit |
0848f5 |
free(l->recvbuf);
|
|
Packit |
0848f5 |
if (l->sendcounts)
|
|
Packit |
0848f5 |
free(l->sendcounts);
|
|
Packit |
0848f5 |
if (l->recvcounts)
|
|
Packit |
0848f5 |
free(l->recvcounts);
|
|
Packit |
0848f5 |
if (l->sdispls)
|
|
Packit |
0848f5 |
free(l->sdispls);
|
|
Packit |
0848f5 |
if (l->rdispls)
|
|
Packit |
0848f5 |
free(l->rdispls);
|
|
Packit |
0848f5 |
if (l->sendtypes)
|
|
Packit |
0848f5 |
free(l->sendtypes);
|
|
Packit |
0848f5 |
if (l->recvtypes)
|
|
Packit |
0848f5 |
free(l->recvtypes);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Starts a "random" operation on "comm" corresponding to "rndnum" and returns
|
|
Packit |
0848f5 |
* in (*req) a request handle corresonding to that operation. This call should
|
|
Packit |
0848f5 |
* be considered collective over comm (with a consistent value for "rndnum"),
|
|
Packit |
0848f5 |
* even though the operation may only be a point-to-point request. */
|
|
Packit |
0848f5 |
static void start_random_nonblocking(MPI_Comm comm, unsigned int rndnum, MPI_Request * req,
|
|
Packit |
0848f5 |
struct laundry *l)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, j;
|
|
Packit |
0848f5 |
int rank, size;
|
|
Packit |
0848f5 |
int *buf = NULL;
|
|
Packit |
0848f5 |
int *recvbuf = NULL;
|
|
Packit |
0848f5 |
int *sendcounts = NULL;
|
|
Packit |
0848f5 |
int *recvcounts = NULL;
|
|
Packit |
0848f5 |
int *sdispls = NULL;
|
|
Packit |
0848f5 |
int *rdispls = NULL;
|
|
Packit |
0848f5 |
int *sendtypes = NULL;
|
|
Packit |
0848f5 |
int *recvtypes = NULL;
|
|
Packit |
0848f5 |
signed char *buf_alias = NULL;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_rank(comm, &rank;;
|
|
Packit |
0848f5 |
MPI_Comm_size(comm, &size);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
*req = MPI_REQUEST_NULL;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
l->case_num = -1;
|
|
Packit |
0848f5 |
l->comm = comm;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
l->buf = buf = malloc(COUNT * size * sizeof(int));
|
|
Packit |
0848f5 |
l->recvbuf = recvbuf = malloc(COUNT * size * sizeof(int));
|
|
Packit |
0848f5 |
l->sendcounts = sendcounts = malloc(size * sizeof(int));
|
|
Packit |
0848f5 |
l->recvcounts = recvcounts = malloc(size * sizeof(int));
|
|
Packit |
0848f5 |
l->sdispls = sdispls = malloc(size * sizeof(int));
|
|
Packit |
0848f5 |
l->rdispls = rdispls = malloc(size * sizeof(int));
|
|
Packit |
0848f5 |
l->sendtypes = sendtypes = malloc(size * sizeof(MPI_Datatype));
|
|
Packit |
0848f5 |
l->recvtypes = recvtypes = malloc(size * sizeof(MPI_Datatype));
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define NUM_CASES (21)
|
|
Packit |
0848f5 |
l->case_num = rand_range(rndnum, 0, NUM_CASES);
|
|
Packit |
0848f5 |
switch (l->case_num) {
|
|
Packit |
0848f5 |
case 0: /* MPI_Ibcast */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
buf[i] = i;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
buf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ibcast(buf, COUNT, MPI_INT, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 1: /* MPI_Ibcast (again, but designed to stress scatter/allgather impls) */
|
|
Packit |
0848f5 |
/* FIXME fiddle with PRIME and buffer allocation s.t. PRIME is much larger (1021?) */
|
|
Packit |
0848f5 |
buf_alias = (signed char *) buf;
|
|
Packit |
0848f5 |
my_assert(COUNT * size * sizeof(int) > PRIME); /* sanity */
|
|
Packit |
0848f5 |
for (i = 0; i < PRIME; ++i) {
|
|
Packit |
0848f5 |
if (rank == 0)
|
|
Packit |
0848f5 |
buf_alias[i] = i;
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
buf_alias[i] = 0xdb;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = PRIME; i < COUNT * size * sizeof(int); ++i) {
|
|
Packit |
0848f5 |
buf_alias[i] = 0xbf;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ibcast(buf_alias, PRIME, MPI_SIGNED_CHAR, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 2: /* MPI_Ibarrier */
|
|
Packit |
0848f5 |
MPI_Ibarrier(comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 3: /* MPI_Ireduce */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ireduce(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 4: /* same again, use a user op and free it before the wait */
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Op op = MPI_OP_NULL;
|
|
Packit |
0848f5 |
MPI_Op_create(sum_fn, /*commute= */ 1, &op);
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ireduce(buf, recvbuf, COUNT, MPI_INT, op, 0, comm, req);
|
|
Packit |
0848f5 |
MPI_Op_free(&op);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 5: /* MPI_Iallreduce */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Iallreduce(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 6: /* MPI_Ialltoallv (a weak test, neither irregular nor sparse) */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
sendcounts[i] = COUNT;
|
|
Packit |
0848f5 |
recvcounts[i] = COUNT;
|
|
Packit |
0848f5 |
sdispls[i] = COUNT * i;
|
|
Packit |
0848f5 |
rdispls[i] = COUNT * i;
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = rank + (i * j);
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ialltoallv(buf, sendcounts, sdispls, MPI_INT, recvbuf, recvcounts, rdispls, MPI_INT,
|
|
Packit |
0848f5 |
comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 7: /* MPI_Igather */
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Igather(buf, COUNT, MPI_INT, recvbuf, COUNT, MPI_INT, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 8: /* same test again, just use a dup'ed datatype and free it before the wait */
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Datatype type = MPI_DATATYPE_NULL;
|
|
Packit |
0848f5 |
MPI_Type_dup(MPI_INT, &type);
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Igather(buf, COUNT, MPI_INT, recvbuf, COUNT, type, 0, comm, req);
|
|
Packit |
0848f5 |
MPI_Type_free(&type); /* should cause implementations that don't refcount
|
|
Packit |
0848f5 |
* correctly to blow up or hang in the wait */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 9: /* MPI_Iscatter */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
if (rank == 0)
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = i + j;
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Iscatter(buf, COUNT, MPI_INT, recvbuf, COUNT, MPI_INT, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 10: /* MPI_Iscatterv */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
/* weak test, just test the regular case where all counts are equal */
|
|
Packit |
0848f5 |
sendcounts[i] = COUNT;
|
|
Packit |
0848f5 |
sdispls[i] = i * COUNT;
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
if (rank == 0)
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = i + j;
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Iscatterv(buf, sendcounts, sdispls, MPI_INT, recvbuf, COUNT, MPI_INT, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 11: /* MPI_Ireduce_scatter */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
recvcounts[i] = COUNT;
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ireduce_scatter(buf, recvbuf, recvcounts, MPI_INT, MPI_SUM, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 12: /* MPI_Ireduce_scatter_block */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ireduce_scatter_block(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 13: /* MPI_Igatherv */
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
recvcounts[i] = COUNT;
|
|
Packit |
0848f5 |
rdispls[i] = i * COUNT;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Igatherv(buf, COUNT, MPI_INT, recvbuf, recvcounts, rdispls, MPI_INT, 0, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 14: /* MPI_Ialltoall */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = rank + (i * j);
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ialltoall(buf, COUNT, MPI_INT, recvbuf, COUNT, MPI_INT, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 15: /* MPI_Iallgather */
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Iallgather(buf, COUNT, MPI_INT, recvbuf, COUNT, MPI_INT, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 16: /* MPI_Iallgatherv */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
recvcounts[i] = COUNT;
|
|
Packit |
0848f5 |
rdispls[i] = i * COUNT;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i)
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
MPI_Iallgatherv(buf, COUNT, MPI_INT, recvbuf, recvcounts, rdispls, MPI_INT, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 17: /* MPI_Iscan */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Iscan(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 18: /* MPI_Iexscan */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
buf[i] = rank + i;
|
|
Packit |
0848f5 |
recvbuf[i] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Iexscan(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 19: /* MPI_Ialltoallw (a weak test, neither irregular nor sparse) */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
sendcounts[i] = COUNT;
|
|
Packit |
0848f5 |
recvcounts[i] = COUNT;
|
|
Packit |
0848f5 |
sdispls[i] = COUNT * i * sizeof(int);
|
|
Packit |
0848f5 |
rdispls[i] = COUNT * i * sizeof(int);
|
|
Packit |
0848f5 |
sendtypes[i] = MPI_INT;
|
|
Packit |
0848f5 |
recvtypes[i] = MPI_INT;
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
buf[i * COUNT + j] = rank + (i * j);
|
|
Packit |
0848f5 |
recvbuf[i * COUNT + j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Ialltoallw(buf, sendcounts, sdispls, sendtypes, recvbuf, recvcounts, rdispls, recvtypes,
|
|
Packit |
0848f5 |
comm, req);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 20: /* basic pt2pt MPI_Isend/MPI_Irecv pairing */
|
|
Packit |
0848f5 |
/* even ranks send to odd ranks, but only if we have a full pair */
|
|
Packit |
0848f5 |
if ((rank % 2 != 0) || (rank != size - 1)) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
buf[j] = j;
|
|
Packit |
0848f5 |
recvbuf[j] = 0xdeadbeef;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (rank % 2 == 0)
|
|
Packit |
0848f5 |
MPI_Isend(buf, COUNT, MPI_INT, rank + 1, 5, comm, req);
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
MPI_Irecv(recvbuf, COUNT, MPI_INT, rank - 1, 5, comm, req);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
default:
|
|
Packit |
0848f5 |
fprintf(stderr, "unexpected value for l->case_num=%d)\n", (l->case_num));
|
|
Packit |
0848f5 |
MPI_Abort(comm, 1);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
static void check_after_completion(struct laundry *l)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, j;
|
|
Packit |
0848f5 |
int rank, size;
|
|
Packit |
0848f5 |
MPI_Comm comm = l->comm;
|
|
Packit |
0848f5 |
int *buf = l->buf;
|
|
Packit |
0848f5 |
int *recvbuf = l->recvbuf;
|
|
Packit |
0848f5 |
int *sendcounts = l->sendcounts;
|
|
Packit |
0848f5 |
int *recvcounts = l->recvcounts;
|
|
Packit |
0848f5 |
int *sdispls = l->sdispls;
|
|
Packit |
0848f5 |
int *rdispls = l->rdispls;
|
|
Packit |
0848f5 |
int *sendtypes = l->sendtypes;
|
|
Packit |
0848f5 |
int *recvtypes = l->recvtypes;
|
|
Packit |
0848f5 |
char *buf_alias = (char *) buf;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_rank(comm, &rank;;
|
|
Packit |
0848f5 |
MPI_Comm_size(comm, &size);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* these cases all correspond to cases in start_random_nonblocking */
|
|
Packit |
0848f5 |
switch (l->case_num) {
|
|
Packit |
0848f5 |
case 0: /* MPI_Ibcast */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
if (buf[i] != i)
|
|
Packit |
0848f5 |
printf("buf[%d]=%d i=%d\n", i, buf[i], i);
|
|
Packit |
0848f5 |
my_assert(buf[i] == i);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 1: /* MPI_Ibcast (again, but designed to stress scatter/allgather impls) */
|
|
Packit |
0848f5 |
for (i = 0; i < PRIME; ++i) {
|
|
Packit |
0848f5 |
if (buf_alias[i] != i)
|
|
Packit |
0848f5 |
printf("buf_alias[%d]=%d i=%d\n", i, buf_alias[i], i);
|
|
Packit |
0848f5 |
my_assert(buf_alias[i] == i);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 2: /* MPI_Ibarrier */
|
|
Packit |
0848f5 |
/* nothing to check */
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 3: /* MPI_Ireduce */
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
if (recvbuf[i] != ((size * (size - 1) / 2) + (i * size)))
|
|
Packit |
0848f5 |
printf("got recvbuf[%d]=%d, expected %d\n", i, recvbuf[i],
|
|
Packit |
0848f5 |
((size * (size - 1) / 2) + (i * size)));
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == ((size * (size - 1) / 2) + (i * size)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 4: /* same again, use a user op and free it before the wait */
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
if (recvbuf[i] != ((size * (size - 1) / 2) + (i * size)))
|
|
Packit |
0848f5 |
printf("got recvbuf[%d]=%d, expected %d\n", i, recvbuf[i],
|
|
Packit |
0848f5 |
((size * (size - 1) / 2) + (i * size)));
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == ((size * (size - 1) / 2) + (i * size)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 5: /* MPI_Iallreduce */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
if (recvbuf[i] != ((size * (size - 1) / 2) + (i * size)))
|
|
Packit |
0848f5 |
printf("got recvbuf[%d]=%d, expected %d\n", i, recvbuf[i],
|
|
Packit |
0848f5 |
((size * (size - 1) / 2) + (i * size)));
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == ((size * (size - 1) / 2) + (i * size)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 6: /* MPI_Ialltoallv (a weak test, neither irregular nor sparse) */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/*printf("recvbuf[%d*COUNT+%d]=%d, expecting %d\n", i, j, recvbuf[i*COUNT+j], (i + (rank * j))); */
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == (i + (rank * j)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 7: /* MPI_Igather */
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == i + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 8: /* same test again, just use a dup'ed datatype and free it before the wait */
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == i + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 9: /* MPI_Iscatter */
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[j] == rank + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (rank != 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
/* check we didn't corrupt the sendbuf somehow */
|
|
Packit |
0848f5 |
my_assert(buf[i] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 10: /* MPI_Iscatterv */
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[j] == rank + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (rank != 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
/* check we didn't corrupt the sendbuf somehow */
|
|
Packit |
0848f5 |
my_assert(buf[i] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 1; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/* check we didn't corrupt the rest of the recvbuf */
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 11: /* MPI_Ireduce_scatter */
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[j] == (size * rank + ((size - 1) * size) / 2));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 1; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/* check we didn't corrupt the rest of the recvbuf */
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 12: /* MPI_Ireduce_scatter_block */
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[j] == (size * rank + ((size - 1) * size) / 2));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 1; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/* check we didn't corrupt the rest of the recvbuf */
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 13: /* MPI_Igatherv */
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == i + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
for (i = 0; i < size * COUNT; ++i) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 14: /* MPI_Ialltoall */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/*printf("recvbuf[%d*COUNT+%d]=%d, expecting %d\n", i, j, recvbuf[i*COUNT+j], (i + (i * j))); */
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == (i + (rank * j)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 15: /* MPI_Iallgather */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == i + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 16: /* MPI_Iallgatherv */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == i + j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 17: /* MPI_Iscan */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == ((rank * (rank + 1) / 2) + (i * (rank + 1))));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 18: /* MPI_Iexscan */
|
|
Packit |
0848f5 |
for (i = 0; i < COUNT; ++i) {
|
|
Packit |
0848f5 |
if (rank == 0)
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == 0xdeadbeef);
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
my_assert(recvbuf[i] == ((rank * (rank + 1) / 2) + (i * (rank + 1)) - (rank + i)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 19: /* MPI_Ialltoallw (a weak test, neither irregular nor sparse) */
|
|
Packit |
0848f5 |
for (i = 0; i < size; ++i) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/*printf("recvbuf[%d*COUNT+%d]=%d, expecting %d\n", i, j, recvbuf[i*COUNT+j], (i + (rank * j))); */
|
|
Packit |
0848f5 |
my_assert(recvbuf[i * COUNT + j] == (i + (rank * j)));
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 20: /* basic pt2pt MPI_Isend/MPI_Irecv pairing */
|
|
Packit |
0848f5 |
/* even ranks send to odd ranks, but only if we have a full pair */
|
|
Packit |
0848f5 |
if ((rank % 2 != 0) || (rank != size - 1)) {
|
|
Packit |
0848f5 |
for (j = 0; j < COUNT; ++j) {
|
|
Packit |
0848f5 |
/* only odd procs did a recv */
|
|
Packit |
0848f5 |
if (rank % 2 == 0) {
|
|
Packit |
0848f5 |
my_assert(recvbuf[j] == 0xdeadbeef);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
if (recvbuf[j] != j)
|
|
Packit |
0848f5 |
printf("recvbuf[%d]=%d j=%d\n", j, recvbuf[j], j);
|
|
Packit |
0848f5 |
my_assert(recvbuf[j] == j);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
default:
|
|
Packit |
0848f5 |
printf("invalid case_num (%d) detected\n", l->case_num);
|
|
Packit |
0848f5 |
assert(0);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#undef NUM_CASES
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
static void complete_something_somehow(unsigned int rndnum, int numreqs, MPI_Request reqs[],
|
|
Packit |
0848f5 |
int *outcount, int indices[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, idx, flag;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define COMPLETION_CASES (8)
|
|
Packit |
0848f5 |
switch (rand_range(rndnum, 0, COMPLETION_CASES)) {
|
|
Packit |
0848f5 |
case 0:
|
|
Packit |
0848f5 |
MPI_Waitall(numreqs, reqs, MPI_STATUSES_IGNORE);
|
|
Packit |
0848f5 |
*outcount = numreqs;
|
|
Packit |
0848f5 |
for (i = 0; i < numreqs; ++i) {
|
|
Packit |
0848f5 |
indices[i] = i;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 1:
|
|
Packit |
0848f5 |
MPI_Testsome(numreqs, reqs, outcount, indices, MPI_STATUS_IGNORE);
|
|
Packit |
0848f5 |
if (*outcount == MPI_UNDEFINED) {
|
|
Packit |
0848f5 |
*outcount = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 2:
|
|
Packit |
0848f5 |
MPI_Waitsome(numreqs, reqs, outcount, indices, MPI_STATUS_IGNORE);
|
|
Packit |
0848f5 |
if (*outcount == MPI_UNDEFINED) {
|
|
Packit |
0848f5 |
*outcount = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 3:
|
|
Packit |
0848f5 |
MPI_Waitany(numreqs, reqs, &idx, MPI_STATUS_IGNORE);
|
|
Packit |
0848f5 |
if (idx == MPI_UNDEFINED) {
|
|
Packit |
0848f5 |
*outcount = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
*outcount = 1;
|
|
Packit |
0848f5 |
indices[0] = idx;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 4:
|
|
Packit |
0848f5 |
MPI_Testany(numreqs, reqs, &idx, &flag, MPI_STATUS_IGNORE);
|
|
Packit |
0848f5 |
if (idx == MPI_UNDEFINED) {
|
|
Packit |
0848f5 |
*outcount = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
*outcount = 1;
|
|
Packit |
0848f5 |
indices[0] = idx;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 5:
|
|
Packit |
0848f5 |
MPI_Testall(numreqs, reqs, &flag, MPI_STATUSES_IGNORE);
|
|
Packit |
0848f5 |
if (flag) {
|
|
Packit |
0848f5 |
*outcount = numreqs;
|
|
Packit |
0848f5 |
for (i = 0; i < numreqs; ++i) {
|
|
Packit |
0848f5 |
indices[i] = i;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
*outcount = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 6:
|
|
Packit |
0848f5 |
/* select a new random index and wait on it */
|
|
Packit |
0848f5 |
rndnum = gen_prn(rndnum);
|
|
Packit |
0848f5 |
idx = rand_range(rndnum, 0, numreqs);
|
|
Packit |
0848f5 |
MPI_Wait(&reqs[idx], MPI_STATUS_IGNORE);
|
|
Packit |
0848f5 |
*outcount = 1;
|
|
Packit |
0848f5 |
indices[0] = idx;
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
case 7:
|
|
Packit |
0848f5 |
/* select a new random index and wait on it */
|
|
Packit |
0848f5 |
rndnum = gen_prn(rndnum);
|
|
Packit |
0848f5 |
idx = rand_range(rndnum, 0, numreqs);
|
|
Packit |
0848f5 |
MPI_Test(&reqs[idx], &flag, MPI_STATUS_IGNORE);
|
|
Packit |
0848f5 |
*outcount = (flag ? 1 : 0);
|
|
Packit |
0848f5 |
indices[0] = idx;
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
default:
|
|
Packit |
0848f5 |
assert(0);
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#undef COMPLETION_CASES
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char **argv)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, num_posted, num_completed;
|
|
Packit |
0848f5 |
int wrank, wsize;
|
|
Packit |
0848f5 |
unsigned int seed = 0x10bc;
|
|
Packit |
0848f5 |
unsigned int post_seq, complete_seq;
|
|
Packit |
0848f5 |
struct laundry larr[WINDOW];
|
|
Packit |
0848f5 |
MPI_Request reqs[WINDOW];
|
|
Packit |
0848f5 |
int outcount;
|
|
Packit |
0848f5 |
int indices[WINDOW];
|
|
Packit |
0848f5 |
MPI_Comm comms[NUM_COMMS];
|
|
Packit |
0848f5 |
MPI_Comm comm;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Init(&argc, &argv);
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
|
|
Packit |
0848f5 |
MPI_Comm_size(MPI_COMM_WORLD, &wsize);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* it is critical that all processes in the communicator start with a
|
|
Packit |
0848f5 |
* consistent value for "post_seq" */
|
|
Packit |
0848f5 |
post_seq = complete_seq = gen_prn(seed);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
num_completed = 0;
|
|
Packit |
0848f5 |
num_posted = 0;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* construct all of the communicators, just dups of comm world for now */
|
|
Packit |
0848f5 |
for (i = 0; i < NUM_COMMS; ++i) {
|
|
Packit |
0848f5 |
MPI_Comm_dup(MPI_COMM_WORLD, &comms[i]);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* fill the entire window of ops */
|
|
Packit |
0848f5 |
for (i = 0; i < WINDOW; ++i) {
|
|
Packit |
0848f5 |
reqs[i] = MPI_REQUEST_NULL;
|
|
Packit |
0848f5 |
memset(&larr[i], 0, sizeof(struct laundry));
|
|
Packit |
0848f5 |
larr[i].case_num = -1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* randomly select a comm, using a new seed to avoid correlating
|
|
Packit |
0848f5 |
* particular kinds of NBC ops with particular communicators */
|
|
Packit |
0848f5 |
comm = comms[rand_range(gen_prn(post_seq), 0, NUM_COMMS)];
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
start_random_nonblocking(comm, post_seq, &reqs[i], &larr[i]);
|
|
Packit |
0848f5 |
++num_posted;
|
|
Packit |
0848f5 |
post_seq = gen_prn(post_seq);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* now loop repeatedly, completing ops with "random" completion functions,
|
|
Packit |
0848f5 |
* until we've posted and completed MAIN_ITERATIONS ops */
|
|
Packit |
0848f5 |
while (num_completed < MAIN_ITERATIONS) {
|
|
Packit |
0848f5 |
complete_something_somehow(complete_seq, WINDOW, reqs, &outcount, indices);
|
|
Packit |
0848f5 |
complete_seq = gen_prn(complete_seq);
|
|
Packit |
0848f5 |
for (i = 0; i < outcount; ++i) {
|
|
Packit |
0848f5 |
int idx = indices[i];
|
|
Packit |
0848f5 |
assert(reqs[idx] == MPI_REQUEST_NULL);
|
|
Packit |
0848f5 |
if (larr[idx].case_num != -1) {
|
|
Packit |
0848f5 |
check_after_completion(&larr[idx]);
|
|
Packit |
0848f5 |
cleanup_laundry(&larr[idx]);
|
|
Packit |
0848f5 |
++num_completed;
|
|
Packit |
0848f5 |
if (num_posted < MAIN_ITERATIONS) {
|
|
Packit |
0848f5 |
comm = comms[rand_range(gen_prn(post_seq), 0, NUM_COMMS)];
|
|
Packit |
0848f5 |
start_random_nonblocking(comm, post_seq, &reqs[idx], &larr[idx]);
|
|
Packit |
0848f5 |
++num_posted;
|
|
Packit |
0848f5 |
post_seq = gen_prn(post_seq);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* "randomly" and infrequently introduce some jitter into the system */
|
|
Packit |
0848f5 |
if (0 == rand_range(gen_prn(complete_seq + wrank), 0, CHANCE_OF_SLEEP)) {
|
|
Packit |
0848f5 |
usleep(JITTER_DELAY); /* take a short nap */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < NUM_COMMS; ++i) {
|
|
Packit |
0848f5 |
MPI_Comm_free(&comms[i]);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (wrank == 0) {
|
|
Packit |
0848f5 |
if (errs)
|
|
Packit |
0848f5 |
printf("found %d errors\n", errs);
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
printf(" No errors\n");
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|