|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* (C) 2015 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This test is going to test the atomicity for "read-modify-write" in CAS
|
|
Packit |
0848f5 |
* operations */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* There are three processes involved in this test: P0 (origin_shm), P1 (origin_am),
|
|
Packit |
0848f5 |
* and P2 (dest). P0 and P1 issues one CAS to P2 via SHM and AM respectively.
|
|
Packit |
0848f5 |
* For P0, origin value is 1 and compare value is 0; for P1, origin value is 0 and
|
|
Packit |
0848f5 |
* compare value is 1; for P2, initial target value is 0. The correct results can
|
|
Packit |
0848f5 |
* only be one of the following cases:
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* (1) result value on P0: 0, result value on P1: 0, target value on P2: 1.
|
|
Packit |
0848f5 |
* (2) result value on P0: 0, result value on P1: 1, target value on P2: 0.
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* All other results are not correct. */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include "mpi.h"
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define LOOP_SIZE 10000
|
|
Packit |
0848f5 |
#define CHECK_TAG 123
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char *argv[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int rank, size, k;
|
|
Packit |
0848f5 |
int errors = 0;
|
|
Packit |
0848f5 |
int origin_shm, origin_am, dest;
|
|
Packit |
0848f5 |
int *orig_buf = NULL, *result_buf = NULL, *compare_buf = NULL,
|
|
Packit |
0848f5 |
*target_buf = NULL, *check_buf = NULL;
|
|
Packit |
0848f5 |
int target_value = 0;
|
|
Packit |
0848f5 |
MPI_Win win;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Init(&argc, &argv);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit |
0848f5 |
MPI_Comm_size(MPI_COMM_WORLD, &size);
|
|
Packit |
0848f5 |
if (size != 3) {
|
|
Packit |
0848f5 |
/* run this test with three processes */
|
|
Packit |
0848f5 |
goto exit_test;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* this works when MPIR_PARAM_CH3_ODD_EVEN_CLIQUES is set */
|
|
Packit |
0848f5 |
dest = 2;
|
|
Packit |
0848f5 |
origin_shm = 0;
|
|
Packit |
0848f5 |
origin_am = 1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (rank != dest) {
|
|
Packit |
0848f5 |
MPI_Alloc_mem(sizeof(int), MPI_INFO_NULL, &orig_buf);
|
|
Packit |
0848f5 |
MPI_Alloc_mem(sizeof(int), MPI_INFO_NULL, &result_buf);
|
|
Packit |
0848f5 |
MPI_Alloc_mem(sizeof(int), MPI_INFO_NULL, &compare_buf);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Win_allocate(sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &target_buf, &win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (k = 0; k < LOOP_SIZE; k++) {
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* init buffers */
|
|
Packit |
0848f5 |
if (rank == origin_shm) {
|
|
Packit |
0848f5 |
orig_buf[0] = 1;
|
|
Packit |
0848f5 |
compare_buf[0] = 0;
|
|
Packit |
0848f5 |
result_buf[0] = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (rank == origin_am) {
|
|
Packit |
0848f5 |
orig_buf[0] = 0;
|
|
Packit |
0848f5 |
compare_buf[0] = 1;
|
|
Packit |
0848f5 |
result_buf[0] = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit |
0848f5 |
target_buf[0] = 0;
|
|
Packit |
0848f5 |
MPI_Win_unlock(rank, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* perform FOP */
|
|
Packit |
0848f5 |
MPI_Win_lock_all(0, win);
|
|
Packit |
0848f5 |
if (rank != dest) {
|
|
Packit |
0848f5 |
MPI_Compare_and_swap(orig_buf, compare_buf, result_buf, MPI_INT, dest, 0, win);
|
|
Packit |
0848f5 |
MPI_Win_flush(dest, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Win_unlock_all(win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* check results */
|
|
Packit |
0848f5 |
if (rank != dest) {
|
|
Packit |
0848f5 |
MPI_Gather(result_buf, 1, MPI_INT, check_buf, 1, MPI_INT, dest, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit |
0848f5 |
target_value = target_buf[0];
|
|
Packit |
0848f5 |
MPI_Win_unlock(rank, win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Alloc_mem(sizeof(int) * 3, MPI_INFO_NULL, &check_buf);
|
|
Packit |
0848f5 |
MPI_Gather(&target_value, 1, MPI_INT, check_buf, 1, MPI_INT, dest, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (!(check_buf[dest] == 0 && check_buf[origin_shm] == 0 && check_buf[origin_am] == 1)
|
|
Packit |
0848f5 |
&& !(check_buf[dest] == 1 && check_buf[origin_shm] == 0 &&
|
|
Packit |
0848f5 |
check_buf[origin_am] == 0)) {
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
printf
|
|
Packit |
0848f5 |
("Wrong results: target result = %d, origin_shm result = %d, origin_am result = %d\n",
|
|
Packit |
0848f5 |
check_buf[dest], check_buf[origin_shm], check_buf[origin_am]);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
printf
|
|
Packit |
0848f5 |
("Expected results (1): target result = 1, origin_shm result = 0, origin_am result = 0\n");
|
|
Packit |
0848f5 |
printf
|
|
Packit |
0848f5 |
("Expected results (2): target result = 0, origin_shm result = 0, origin_am result = 1\n");
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
errors++;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Free_mem(check_buf);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Win_free(&win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (rank == origin_am || rank == origin_shm) {
|
|
Packit |
0848f5 |
MPI_Free_mem(orig_buf);
|
|
Packit |
0848f5 |
MPI_Free_mem(result_buf);
|
|
Packit |
0848f5 |
MPI_Free_mem(compare_buf);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
exit_test:
|
|
Packit |
0848f5 |
if (rank == dest && errors == 0)
|
|
Packit |
0848f5 |
printf(" No Errors\n");
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|