Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix tesh tests.
[simgrid.git] / teshsuite / smpi / macro-partial-shared-communication / macro-partial-shared-communication.c
1 /* Copyright (c) 2009-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <stdio.h>
8 #include <mpi.h>
9 #include <stdint.h>
10 #include <inttypes.h>
11 #include <assert.h>
12
13 // Set the elements between buf[start] and buf[stop-1] to (i+value)%256
14 static void set(uint8_t *buf, size_t start, size_t stop, uint8_t value) {
15   for(size_t i = start; i < stop; i++) {
16     buf[i] = (i+value)%256;
17   }
18 }
19
20 // Return the number of times that an element is equal to (i+value)%256 between buf[start] and buf[stop-1].
21 static  int count_all(uint8_t *buf, size_t start, size_t stop, uint8_t value) {
22   size_t occ = 0;
23   for(size_t i = start ; i < stop ; i++) {
24     if(buf[i] == (i+value)%256) {
25       occ ++;
26     }
27   }
28   return occ;
29 }
30
31 // Return true iff the values from buf[start] to buf[stop-1] are all equal to (i+value)%256.
32 static int check_all(uint8_t *buf, size_t start, size_t stop, uint8_t value) {
33   size_t occ = count_all(buf, start, stop, value);
34   return occ == stop-start;
35 }
36
37 // Return true iff "enough" elements are equal to (i+value)%256 between buf[start] and buf[stop-1].
38 static int check_enough(uint8_t *buf, size_t start, size_t stop, uint8_t value) {
39   int page_size = 0x1000;
40   size_t size = stop-start;
41   if(size <= 2*page_size) // we are not sure to have a whole page that is shared
42     return 1;
43   size_t occ = count_all(buf, start, stop, value);
44   return occ >= size - 2*page_size;
45 }
46
47 int main(int argc, char *argv[])
48 {
49   MPI_Init(&argc, &argv);
50   int rank;
51   int size;
52   size_t mem_size = 0x10000000;
53   size_t shared_blocks[] = {
54     0,         0x1234567,
55     0x1300000, 0x1300010,
56     0x3456789, 0x3457890,
57     0x4444444, 0x5555555,
58     0x5555565, 0x5600000,
59     0x8000000, 0x10000000
60   };
61   int nb_blocks = (sizeof(shared_blocks)/sizeof(size_t))/2;
62   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
63   MPI_Comm_size(MPI_COMM_WORLD, &size);
64   //Let's Allocate a shared memory buffer
65   assert(size%2 == 0);
66   uint8_t *buf;
67   buf = SMPI_PARTIAL_SHARED_MALLOC(mem_size, shared_blocks, nb_blocks);
68   memset(buf, rank, mem_size);
69   MPI_Barrier(MPI_COMM_WORLD);
70
71   // Even processes write their rank in private blocks
72   if(rank%2 == 0) {
73     for(int i = 0; i < nb_blocks-1; i++) {
74       size_t start = shared_blocks[2*i+1];
75       size_t stop = shared_blocks[2*i+2];
76       set(buf, start, stop, rank);
77     }
78   }
79   // Then, even processes send their buffer to their successor
80   if(rank%2 == 0) {
81     MPI_Send(buf, mem_size, MPI_UINT8_T, rank+1, 0, MPI_COMM_WORLD);
82   }
83   else {
84     MPI_Recv(buf, mem_size, MPI_UINT8_T, rank-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
85   }
86
87
88   // Odd processes verify that they successfully received the message
89   if(rank%2 == 1) {
90     for(int i = 0; i < nb_blocks-1; i++) {
91       size_t start = shared_blocks[2*i+1];
92       size_t stop = shared_blocks[2*i+2];
93       int comm = check_all(buf, start, stop, rank-1);
94       printf("[%d] The result of the (normal) communication check for block (0x%lx, 0x%lx) is: %d\n", rank, start, stop, comm);
95     }
96     memset(buf, rank, mem_size);
97   }
98
99   MPI_Barrier(MPI_COMM_WORLD);
100
101   // Then, even processes send a sub-part of their buffer their successor
102   // Note that the last block should not be copied entirely
103   if(rank%2 == 0) {
104     MPI_Send(buf+0x10000, mem_size-0xa000000, MPI_UINT8_T, rank+1, 0, MPI_COMM_WORLD);
105   }
106   else {
107     MPI_Recv(buf+0x10000, mem_size-0xa000000, MPI_UINT8_T, rank-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
108   }
109
110
111   // Odd processes verify that they successfully received the message
112   if(rank%2 == 1) {
113     for(int i = 0; i < nb_blocks-1; i++) {
114       size_t start = shared_blocks[2*i+1];
115       size_t stop = shared_blocks[2*i+2];
116       int comm = check_all(buf, start, stop, rank-1);
117       printf("[%d] The result of the (shifted) communication check for block (0x%lx, 0x%lx) is: %d\n", rank, start, stop, comm);
118     }
119   }
120
121   SMPI_SHARED_FREE(buf);
122
123   MPI_Finalize();
124   return 0;
125 }