|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* (C) 2003 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
#include <stdlib.h>
|
|
Packit |
0848f5 |
#include <string.h>
|
|
Packit |
0848f5 |
#include "mpi.h"
|
|
Packit |
0848f5 |
#include "mpitest.h"
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define NUM_TIMES 500
|
|
Packit |
0848f5 |
#define MAX_BUF_SIZE (400 * 1024 * 1024) /* 400 MB */
|
|
Packit |
0848f5 |
#define PUT_SIZE (1024 * 1024) /* 1MB */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
static char MTEST_Descrip[] = "ADLB mimic test";
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
* ALGORITHM:
|
|
Packit |
0848f5 |
* This test uses one server process (S), one target process (T)
|
|
Packit |
0848f5 |
* and a bunch of origin processes (O). 'O' PUTs (LOCK/PUT/UNLOCK)
|
|
Packit |
0848f5 |
* data to a distinct part of the window, and sends a message to
|
|
Packit |
0848f5 |
* 'S' once the UNLOCK has completed. The server forwards this
|
|
Packit |
0848f5 |
* message to 'T'. 'T' GETS the data from this buffer after it
|
|
Packit |
0848f5 |
* receives the message from 'S', to see if it contains the correct
|
|
Packit |
0848f5 |
* contents.
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* -------
|
|
Packit |
0848f5 |
* | S |
|
|
Packit |
0848f5 |
* -------
|
|
Packit |
0848f5 |
* ^ \
|
|
Packit |
0848f5 |
* step 2 / \ step 3
|
|
Packit |
0848f5 |
* SEND / \ SEND
|
|
Packit |
0848f5 |
* / v
|
|
Packit |
0848f5 |
* ------- step 1 -------
|
|
Packit |
0848f5 |
* | | --------> | |
|
|
Packit |
0848f5 |
* | | PUT | |
|
|
Packit |
0848f5 |
* | O | | T |
|
|
Packit |
0848f5 |
* | | step 4 | |
|
|
Packit |
0848f5 |
* | | <-------- | |
|
|
Packit |
0848f5 |
* ------- SEND -------
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char **argv)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int comm_size, comm_rank, i, by_rank, errs = 0;
|
|
Packit |
0848f5 |
int rc;
|
|
Packit |
0848f5 |
char *rma_win_addr, *local_buf;
|
|
Packit |
0848f5 |
char check;
|
|
Packit |
0848f5 |
MPI_Win win;
|
|
Packit |
0848f5 |
MPI_Status status;
|
|
Packit |
0848f5 |
int max_buf_size = 0, put_size = PUT_SIZE;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTest_Init(&argc, &argv);
|
|
Packit |
0848f5 |
MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (comm_size <= 2) {
|
|
Packit |
0848f5 |
fprintf(stderr, "This test requires at least 3 processes\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
max_buf_size = comm_size * put_size;
|
|
Packit |
0848f5 |
if (max_buf_size > MAX_BUF_SIZE) {
|
|
Packit |
0848f5 |
fprintf(stderr, "Too many processes in COMM_WORLD (max is %d)\n", MAX_BUF_SIZE / put_size);
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* If alloc mem returns an error (because too much memory is requested */
|
|
Packit |
0848f5 |
MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
rc = MPI_Alloc_mem(max_buf_size, MPI_INFO_NULL, (void *) &rma_win_addr);
|
|
Packit |
0848f5 |
if (rc) {
|
|
Packit |
0848f5 |
MTestPrintErrorMsg("Unable to MPI_Alloc_mem space (not an error)", rc);
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 0);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
memset(rma_win_addr, 0, max_buf_size);
|
|
Packit |
0848f5 |
MPI_Win_create((void *) rma_win_addr, max_buf_size, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Note that it is not necessary to use MPI_Alloc_mem for the memory that
|
|
Packit |
0848f5 |
* is not part of the MPI_Win. */
|
|
Packit |
0848f5 |
rc = MPI_Alloc_mem(put_size, MPI_INFO_NULL, (void *) &local_buf);
|
|
Packit |
0848f5 |
if (rc) {
|
|
Packit |
0848f5 |
MTestPrintErrorMsg("Unable to MPI_Alloc_mem space (not an error)", rc);
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 0);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < put_size; i++)
|
|
Packit |
0848f5 |
local_buf[i] = 1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (comm_rank == 0) { /* target */
|
|
Packit |
0848f5 |
for (i = 0; i < (NUM_TIMES * (comm_size - 2)); i++) {
|
|
Packit |
0848f5 |
/* Wait for a message from the server to notify me that
|
|
Packit |
0848f5 |
* someone put some data in my window */
|
|
Packit |
0848f5 |
MPI_Recv(&by_rank, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Got a message from the server that 'by_rank' put some
|
|
Packit |
0848f5 |
* data in my local window. Check the last byte to make
|
|
Packit |
0848f5 |
* sure we got it correctly. */
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
|
|
Packit |
0848f5 |
MPI_Get((void *) &check, 1, MPI_CHAR, 0,
|
|
Packit |
0848f5 |
((by_rank + 1) * put_size) - 1, 1, MPI_CHAR, win);
|
|
Packit |
0848f5 |
MPI_Win_unlock(0, win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* If this is not the value I expect, count it as an error */
|
|
Packit |
0848f5 |
if (check != 1)
|
|
Packit |
0848f5 |
errs++;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Reset the buffer to zero for the next round */
|
|
Packit |
0848f5 |
memset((void *) (rma_win_addr + (by_rank * put_size)), 0, put_size);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Tell the origin that I am ready for the next round */
|
|
Packit |
0848f5 |
MPI_Send(NULL, 0, MPI_INT, by_rank, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
else if (comm_rank == 1) { /* server */
|
|
Packit |
0848f5 |
for (i = 0; i < (NUM_TIMES * (comm_size - 2)); i++) {
|
|
Packit |
0848f5 |
/* Wait for a message from any of the origin processes
|
|
Packit |
0848f5 |
* informing me that it has put data to the target
|
|
Packit |
0848f5 |
* process */
|
|
Packit |
0848f5 |
MPI_Recv(NULL, 0, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
by_rank = status.MPI_SOURCE;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Tell the target process that it should be seeing some
|
|
Packit |
0848f5 |
* data in its local buffer */
|
|
Packit |
0848f5 |
MPI_Send(&by_rank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
else { /* origin */
|
|
Packit |
0848f5 |
for (i = 0; i < NUM_TIMES; i++) {
|
|
Packit |
0848f5 |
/* Put some data in the target window */
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
|
|
Packit |
0848f5 |
MPI_Put(local_buf, put_size, MPI_CHAR, 0, comm_rank * put_size,
|
|
Packit |
0848f5 |
put_size, MPI_CHAR, win);
|
|
Packit |
0848f5 |
MPI_Win_unlock(0, win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Tell the server that the put has completed */
|
|
Packit |
0848f5 |
MPI_Send(NULL, 0, MPI_INT, 1, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Wait for a message from the target that it is ready for
|
|
Packit |
0848f5 |
* the next round */
|
|
Packit |
0848f5 |
MPI_Recv(NULL, 0, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Win_free(&win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Free_mem(rma_win_addr);
|
|
Packit |
0848f5 |
MPI_Free_mem(local_buf);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTest_Finalize(errs);
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|