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 136 137
|
/*
* Copyright (C) 2010. See COPYRIGHT in top-level directory.
*/
/* One-Sided MPI 2-D Strided Get Test
*
* Author: James Dinan <dinan@mcs.anl.gov>
* Date : December, 2010
*
* This code performs N strided get operations from a 2d patch of a shared
* array. The array has dimensions [X, Y] and the subarray has dimensions
* [SUB_X, SUB_Y] and begins at index [0, 0]. The input and output buffers are
* specified using an MPI indexed type.
*/
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define XDIM 8
#define YDIM 1024
#define SUB_XDIM 8
#define SUB_YDIM 256
int main(int argc, char **argv) {
int i, j, rank, nranks, peer, bufsize, errors;
double *win_buf, *loc_buf;
MPI_Win buf_win;
MPI_Aint idx_loc[SUB_YDIM];
int idx_rem[SUB_YDIM];
int blk_len[SUB_YDIM];
MPI_Datatype loc_type, rem_type;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nranks);
bufsize = XDIM * YDIM * sizeof(double);
MPI_Alloc_mem(bufsize, MPI_INFO_NULL, &win_buf);
MPI_Alloc_mem(bufsize, MPI_INFO_NULL, &loc_buf);
if (rank == 0)
printf("MPI RMA Strided Get Test:\n");
for (i = 0; i < XDIM*YDIM; i++)
*(win_buf + i) = 1.0 + rank;
MPI_Win_create(win_buf, bufsize, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &buf_win);
peer = (rank+1) % nranks;
// Build the datatype
for (i = 0; i < SUB_YDIM; i++) {
MPI_Get_address(&loc_buf[i*XDIM], &idx_loc[i]);
idx_rem[i] = i*XDIM;
blk_len[i] = SUB_XDIM;
}
MPI_Type_indexed(SUB_YDIM, blk_len, idx_rem, MPI_DOUBLE, &loc_type);
MPI_Type_indexed(SUB_YDIM, blk_len, idx_rem, MPI_DOUBLE, &rem_type);
MPI_Type_commit(&loc_type);
MPI_Type_commit(&rem_type);
// Perform get operation
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, peer, 0, buf_win);
MPI_Get(loc_buf, 1, loc_type, peer, 0, 1, rem_type, buf_win);
// Use the datatype only on the remote side (must have SUB_XDIM == XDIM)
// MPI_Get(loc_buf, SUB_XDIM*SUB_YDIM, MPI_DOUBLE, peer, 0, 1, rem_type, buf_win);
MPI_Win_unlock(peer, buf_win);
MPI_Type_free(&loc_type);
MPI_Type_free(&rem_type);
MPI_Barrier(MPI_COMM_WORLD);
// Verify that the results are correct
errors = 0;
for (i = 0; i < SUB_XDIM; i++) {
for (j = 0; j < SUB_YDIM; j++) {
const double actual = *(loc_buf + i + j*XDIM);
const double expected = (1.0 + peer);
if (actual - expected > 1e-10) {
printf("%d: Data validation failed at [%d, %d] expected=%f actual=%f\n",
rank, j, i, expected, actual);
errors++;
fflush(stdout);
}
}
}
for (i = SUB_XDIM; i < XDIM; i++) {
for (j = 0; j < SUB_YDIM; j++) {
const double actual = *(loc_buf + i + j*XDIM);
const double expected = 1.0 + rank;
if (actual - expected > 1e-10) {
printf("%d: Data validation failed at [%d, %d] expected=%f actual=%f\n",
rank, j, i, expected, actual);
errors++;
fflush(stdout);
}
}
}
for (i = 0; i < XDIM; i++) {
for (j = SUB_YDIM; j < YDIM; j++) {
const double actual = *(loc_buf + i + j*XDIM);
const double expected = 1.0 + rank;
if (actual - expected > 1e-10) {
printf("%d: Data validation failed at [%d, %d] expected=%f actual=%f\n",
rank, j, i, expected, actual);
errors++;
fflush(stdout);
}
}
}
MPI_Win_free(&buf_win);
MPI_Free_mem(win_buf);
MPI_Free_mem(loc_buf);
MPI_Finalize();
if (errors == 0) {
printf("%d: Success\n", rank);
return 0;
} else {
printf("%d: Fail\n", rank);
return 1;
}
}
|