File: atomic_rmw_fop.c

package info (click to toggle)
mpich 4.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 423,384 kB
  • sloc: ansic: 1,088,434; cpp: 71,364; javascript: 40,763; f90: 22,829; sh: 17,463; perl: 14,773; xml: 14,418; python: 10,265; makefile: 9,246; fortran: 8,008; java: 4,355; asm: 324; ruby: 176; lisp: 19; php: 8; sed: 4
file content (135 lines) | stat: -rw-r--r-- 4,316 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/* This test is going to test the atomicity for "read-modify-write" in FOP
 * operations */

/* There are three processes involved in this test: P0 (origin_shm), P1 (origin_am),
 * and P2 (dest). P0 and P1 issues multiple FOP with MPI_SUM and integer (value 1)
 * to P2 via SHM and AM respectively. The correct results should be that the
 * results on P0 and P1 never be the same. */

#include "mpi.h"
#include <stdio.h>
#include "mpitest.h"

#define AM_BUF_SIZE  10
#define SHM_BUF_SIZE 1000
#define WIN_BUF_SIZE 1

#define LOOP_SIZE 15
#define CHECK_TAG 123

int main(int argc, char *argv[])
{
    int rank, size, i, j, k;
    int errors = 0;
    int origin_shm, origin_am, dest;
    int my_buf_size = 0;        /* to avoid warnings */
    int *orig_buf = NULL, *result_buf = NULL, *target_buf = NULL, *check_buf = NULL;
    MPI_Win win;
    MPI_Status status;

    MTest_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    if (size != 3) {
        /* run this test with three processes */
        goto exit_test;
    }

    /* this works when MPIR_PARAM_CH3_ODD_EVEN_CLIQUES is set */
    dest = 2;
    origin_shm = 0;
    origin_am = 1;

    if (rank == origin_am)
        my_buf_size = AM_BUF_SIZE;
    else if (rank == origin_shm)
        my_buf_size = SHM_BUF_SIZE;

    if (rank != dest) {
        MPI_Alloc_mem(sizeof(int) * my_buf_size, MPI_INFO_NULL, &orig_buf);
        MPI_Alloc_mem(sizeof(int) * my_buf_size, MPI_INFO_NULL, &result_buf);
    }

    MPI_Win_allocate(sizeof(int) * WIN_BUF_SIZE, sizeof(int), MPI_INFO_NULL,
                     MPI_COMM_WORLD, &target_buf, &win);

    for (k = 0; k < LOOP_SIZE; k++) {

        /* init buffers */
        if (rank != dest) {
            for (i = 0; i < my_buf_size; i++) {
                orig_buf[i] = 1;
                result_buf[i] = 0;
            }
        } else {
            MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
            for (i = 0; i < WIN_BUF_SIZE; i++) {
                target_buf[i] = 0;
            }
            MPI_Win_unlock(rank, win);
        }

        MPI_Barrier(MPI_COMM_WORLD);

        /* perform FOP */
        MPI_Win_lock_all(0, win);
        if (rank != dest) {
            for (i = 0; i < my_buf_size; i++) {
                MPI_Fetch_and_op(&(orig_buf[i]), &(result_buf[i]), MPI_INT, dest, 0, MPI_SUM, win);
                MPI_Win_flush(dest, win);
            }
        }
        MPI_Win_unlock_all(win);

        MPI_Barrier(MPI_COMM_WORLD);

        if (rank != dest) {
            /* check results on P0 and P2 (origin) */
            if (rank == origin_am) {
                MPI_Send(result_buf, AM_BUF_SIZE, MPI_INT, origin_shm, CHECK_TAG, MPI_COMM_WORLD);
            } else if (rank == origin_shm) {
                MPI_Alloc_mem(sizeof(int) * AM_BUF_SIZE, MPI_INFO_NULL, &check_buf);
                MPI_Recv(check_buf, AM_BUF_SIZE, MPI_INT, origin_am, CHECK_TAG, MPI_COMM_WORLD,
                         &status);
                for (i = 0; i < AM_BUF_SIZE; i++) {
                    for (j = 0; j < SHM_BUF_SIZE; j++) {
                        if (check_buf[i] == result_buf[j]) {
                            printf
                                ("LOOP=%d, rank=%d, FOP, both check_buf[%d] and result_buf[%d] equal to %d, expected to be different. \n",
                                 k, rank, i, j, check_buf[i]);
                            errors++;
                        }
                    }
                }
                MPI_Free_mem(check_buf);
            }
        } else {
            MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
            /* check results on P1 */
            if (target_buf[0] != AM_BUF_SIZE + SHM_BUF_SIZE) {
                printf("LOOP=%d, rank=%d, FOP, target_buf[0] = %d, expected %d. \n",
                       k, rank, target_buf[0], AM_BUF_SIZE + SHM_BUF_SIZE);
                errors++;
            }
            MPI_Win_unlock(rank, win);
        }
    }

    MPI_Win_free(&win);

    if (rank == origin_am || rank == origin_shm) {
        MPI_Free_mem(orig_buf);
        MPI_Free_mem(result_buf);
    }

  exit_test:

    MTest_Finalize(errors);
    return MTestReturnValue(errors);
}