1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2003 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
15 #define MAX_BUF_SIZE (400 * 1024 * 1024) /* 400 MB */
16 #define PUT_SIZE (1024 * 1024) /* 1MB */
19 static char MTEST_Descrip[] = "ADLB mimic test";
24 * This test uses one server process (S), one target process (T)
25 * and a bunch of origin processes (O). 'O' PUTs (LOCK/PUT/UNLOCK)
26 * data to a distinct part of the window, and sends a message to
27 * 'S' once the UNLOCK has completed. The server forwards this
28 * message to 'T'. 'T' GETS the data from this buffer after it
29 * receives the message from 'S', to see if it contains the correct
39 * ------- step 1 -------
45 * ------- SEND -------
49 int main(int argc, char **argv)
51 int comm_size, comm_rank, i, by_rank, errs = 0;
53 char *rma_win_addr, *local_buf;
57 int max_buf_size = 0, put_size = PUT_SIZE;
59 MTest_Init(&argc, &argv);
60 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
61 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
64 fprintf( stderr, "This test requires at least 3 processes\n" );
65 MPI_Abort( MPI_COMM_WORLD, 1 );
68 max_buf_size = comm_size * put_size;
69 if (max_buf_size > MAX_BUF_SIZE) {
70 fprintf( stderr, "Too many processes in COMM_WORLD (max is %d)\n",
71 MAX_BUF_SIZE / put_size );
72 MPI_Abort( MPI_COMM_WORLD, 1 );
75 /* If alloc mem returns an error (because too much memory is requested */
76 MPI_Errhandler_set( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
78 rc = MPI_Alloc_mem(max_buf_size, MPI_INFO_NULL, (void *) &rma_win_addr);
80 MTestPrintErrorMsg( "Unable to MPI_Alloc_mem space (not an error)", rc );
81 MPI_Abort( MPI_COMM_WORLD, 0 );
84 memset(rma_win_addr, 0, max_buf_size);
85 MPI_Win_create((void *) rma_win_addr, max_buf_size, 1, MPI_INFO_NULL,
86 MPI_COMM_WORLD, &win);
88 /* Note that it is not necessary to use MPI_Alloc_mem for the memory that
89 is not part of the MPI_Win. */
90 rc = MPI_Alloc_mem(put_size, MPI_INFO_NULL, (void *) &local_buf);
92 MTestPrintErrorMsg( "Unable to MPI_Alloc_mem space (not an error)", rc );
93 MPI_Abort( MPI_COMM_WORLD, 0 );
96 for (i = 0; i < put_size; i++)
99 MPI_Barrier(MPI_COMM_WORLD);
101 if (comm_rank == 0) { /* target */
102 for (i = 0; i < (NUM_TIMES * (comm_size - 2)); i++) {
103 /* Wait for a message from the server to notify me that
104 * someone put some data in my window */
105 MPI_Recv(&by_rank, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);
107 /* Got a message from the server that 'by_rank' put some
108 * data in my local window. Check the last byte to make
109 * sure we got it correctly. */
110 MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
111 MPI_Get((void *) &check, 1, MPI_CHAR, 0,
112 ((by_rank + 1) * put_size) - 1, 1,
114 MPI_Win_unlock(0, win);
116 /* If this is not the value I expect, count it as an error */
120 /* Reset the buffer to zero for the next round */
121 memset((void *) (rma_win_addr + (by_rank * put_size)), 0, put_size);
123 /* Tell the origin that I am ready for the next round */
124 MPI_Send(NULL, 0, MPI_INT, by_rank, 0, MPI_COMM_WORLD);
128 else if (comm_rank == 1) { /* server */
129 for (i = 0; i < (NUM_TIMES * (comm_size - 2)); i++) {
130 /* Wait for a message from any of the origin processes
131 * informing me that it has put data to the target
133 MPI_Recv(NULL, 0, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD,
135 by_rank = status.MPI_SOURCE;
137 /* Tell the target process that it should be seeing some
138 * data in its local buffer */
139 MPI_Send(&by_rank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
144 for (i = 0; i < NUM_TIMES; i++) {
145 /* Put some data in the target window */
146 MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
147 MPI_Put(local_buf, put_size, MPI_CHAR, 0, comm_rank * put_size,
148 put_size, MPI_CHAR, win);
149 MPI_Win_unlock(0, win);
151 /* Tell the server that the put has completed */
152 MPI_Send(NULL, 0, MPI_INT, 1, 0, MPI_COMM_WORLD);
154 /* Wait for a message from the target that it is ready for
156 MPI_Recv(NULL, 0, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
162 MPI_Free_mem(rma_win_addr);
163 MPI_Free_mem(local_buf);
165 MTest_Finalize(errs);