Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix the communication optimization.
[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 void set(uint8_t *buf, int start, int stop, uint8_t value) {
15   for(int 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 int count_all(uint8_t *buf, int start, int stop, uint8_t value) {
22   int occ = 0;
23   for(int 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 int check_all(uint8_t *buf, int start, int stop, uint8_t value) {
33   int 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 int check_enough(uint8_t *buf, int start, int stop, uint8_t value) {
39   int page_size = 0x1000;
40   int 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   int 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   int mem_size = 0x10000000;
53   int 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(int))/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       int start = shared_blocks[2*i+1];
75       int 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       int start = shared_blocks[2*i+1];
92       int 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%x, 0x%x) 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 part (0, 0x10000) which is not sent is a shared part, so we do not care
103   if(rank%2 == 0) {
104     MPI_Send(buf+0x10000, mem_size-0x10000, MPI_UINT8_T, rank+1, 0, MPI_COMM_WORLD);
105   }
106   else {
107     MPI_Recv(buf+0x10000, mem_size-0x10000, 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       int start = shared_blocks[2*i+1];
115       int 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%x, 0x%x) is: %d\n", rank, start, stop, comm);
118     }
119   }
120
121   SMPI_SHARED_FREE(buf);
122
123   MPI_Finalize();
124   return 0;
125 }