Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
e249a3dc4f7712f974fb31ebaeb1b978953e78a2
[simgrid.git] / teshsuite / smpi / MBI / generator_utils.py
1 # Copyright 2021-2022. The MBI project. All rights reserved.
2 # This program is free software; you can redistribute it and/or modify it under the terms of the license (GNU GPL).
3
4 # This is a simple templating system, dedicated to the systematic generation of MPI source code
5
6 import os
7 import re
8
9 # Collectives
10 coll = ['MPI_Barrier', 'MPI_Bcast', 'MPI_Reduce', 'MPI_Gather', 'MPI_Scatter', 'MPI_Scan', 'MPI_Exscan', 'MPI_Allgather', 'MPI_Allreduce', 'MPI_Allgatherv', 'MPI_Alltoall', 'MPI_Alltoallv']
11 icoll = ['MPI_Ibcast', 'MPI_Ireduce', 'MPI_Igather', 'MPI_Iscatter', 'MPI_Iscan', 'MPI_Iexscan', 'MPI_Iallgather', 'MPI_Iallreduce', 'MPI_Iallgatherv', 'MPI_Ialltoall', 'MPI_Ialltoallv']
12 ibarrier = ['MPI_Ibarrier']
13 coll4op = ['MPI_Reduce', 'MPI_Allreduce']
14 icoll4op = ['MPI_Ireduce', 'MPI_Iallreduce']
15 coll4root = ['MPI_Reduce', 'MPI_Bcast', 'MPI_Gather', 'MPI_Scatter']
16 icoll4root = ['MPI_Ireduce', 'MPI_Ibcast', 'MPI_Igather', 'MPI_Iscatter']
17 pcoll = []
18 tcoll = ['MPI_Comm_split', 'MPI_Op_create', 'MPI_Comm_dup', 'MPI_Type_contiguous', 'MPI_Comm_create', 'MPI_Group_excl'] # MPI_Comm_dup removed
19 tcoll4color = ['MPI_Comm_split']
20 tcoll4topo = ['MPI_Cart_get']
21
22 # P2P
23 allsend = ['MPI_Send', 'MPI_Isend', 'MPI_Ssend', 'MPI_Bsend', 'MPI_Send_init']
24 allrecv = ['MPI_Recv', 'MPI_Irecv', 'MPI_Recv_init']
25 send = ['MPI_Send']
26 ssend = ['MPI_Ssend']
27 bsend = ['MPI_Bsend']
28 isend = ['MPI_Isend']
29 psend = ['MPI_Send_init']
30 recv = ['MPI_Recv']
31 irecv = ['MPI_Irecv']
32 precv = ['MPI_Recv_init']
33 probe = ['MPI_Probe']
34
35 # RMA
36 rma = ['MPI_Get', 'MPI_Put']
37 get = ['MPI_Get']
38 put = ['MPI_Put']
39 store = ['store']
40 load = ['load']
41 rstore = ['rstore']
42 rload = ['rload']
43 loadstore = ['loadstore']
44
45
46 # setup
47 init = {}
48 start = {}
49 operation = {}
50 fini = {}
51 free = {}
52 write = {}
53 error = {}
54 epoch = {}
55 finEpoch = {}
56
57
58 ### COLL:basic
59
60 init['MPI_Bcast'] = lambda n: f'int buf{n}[buff_size];'
61 start['MPI_Bcast'] = lambda n: ""
62 operation['MPI_Bcast'] = lambda n: f'MPI_Bcast(buf{n}, buff_size, type, root, newcom);'
63 fini['MPI_Bcast'] = lambda n: ""
64 free['MPI_Bcast'] = lambda n: ""
65 write['MPI_Bcast'] = lambda n: ""
66
67 init['MPI_Barrier'] = lambda n: ""
68 start['MPI_Barrier'] = lambda n: ""
69 operation['MPI_Barrier'] = lambda n: 'MPI_Barrier(newcom);'
70 fini['MPI_Barrier'] = lambda n: ""
71 free['MPI_Barrier'] = lambda n: ""
72 write['MPI_Barrier'] = lambda n: ""
73
74 init['MPI_Reduce'] = lambda n: f"int sum{n}, val{n} = 1;"
75 start['MPI_Reduce'] = lambda n: ""
76 operation['MPI_Reduce'] = lambda n: f"MPI_Reduce(&val{n}, &sum{n}, 1, type, op, root, newcom);"
77 fini['MPI_Reduce'] = lambda n: ""
78 free['MPI_Reduce'] = lambda n: ""
79 write['MPI_Reduce'] = lambda n: ""
80
81 init['MPI_Gather'] = lambda n: f"int val{n}=1, buf{n}[buff_size];"
82 start['MPI_Gather'] = lambda n: ""
83 operation['MPI_Gather'] = lambda n: f"MPI_Gather(&val{n}, 1, type, buf{n},1, type, root, newcom);"
84 fini['MPI_Gather'] = lambda n: ""
85 free['MPI_Gather'] = lambda n: ""
86 write['MPI_Gather'] = lambda n: ""
87
88 init['MPI_Scatter'] = lambda n: f"int val{n}, buf{n}[buff_size];\n  memset(buf{n}, 0, sizeof(int)*buff_size);"
89 start['MPI_Scatter'] = lambda n: ""
90 operation['MPI_Scatter'] = lambda n: f"MPI_Scatter(&buf{n}, 1, type, &val{n}, 1, type, root, newcom);"
91 fini['MPI_Scatter'] = lambda n: ""
92 free['MPI_Scatter'] = lambda n: ""
93 write['MPI_Scatter'] = lambda n: ""
94
95 init['MPI_Allreduce'] = lambda n: f"int sum{n}, val{n} = 1;"
96 start['MPI_Allreduce'] = lambda n: ""
97 operation['MPI_Allreduce'] = lambda n: f"MPI_Allreduce(&val{n}, &sum{n}, 1, type, op, newcom);"
98 fini['MPI_Allreduce'] = lambda n: ""
99 free['MPI_Allreduce'] = lambda n: ""
100 write['MPI_Allreduce'] = lambda n: ""
101
102 init['MPI_Scan'] = lambda n: f"int outbuf{n}[buff_size];\n  memset(outbuf{n}, 0, buff_size*sizeof(int));\n  int inbuf{n}[buff_size];"
103 start['MPI_Scan'] = lambda n: ""
104 operation['MPI_Scan'] = lambda n: f"MPI_Scan(&outbuf{n}, inbuf{n}, buff_size, type, op, newcom);"
105 fini['MPI_Scan'] = lambda n: ""
106 free['MPI_Scan'] = lambda n: ""
107 write['MPI_Scan'] = lambda n: ""
108
109 init['MPI_Exscan'] = lambda n: f"int outbuf{n}[buff_size];\n  memset(outbuf{n}, 0, buff_size*sizeof(int));\n  int inbuf{n}[buff_size];"
110 start['MPI_Exscan'] = lambda n: ""
111 operation['MPI_Exscan'] = lambda n: f"MPI_Exscan(&outbuf{n}, inbuf{n}, buff_size, type, op, newcom);"
112 fini['MPI_Exscan'] = lambda n: ""
113 free['MPI_Exscan'] = lambda n: ""
114 write['MPI_Exscan'] = lambda n: ""
115
116 init['MPI_Allgather'] = lambda n: f"int val{n}=1, *rbuf{n} = (int*)malloc(dbs);"
117 start['MPI_Allgather'] = lambda n: ""
118 operation['MPI_Allgather'] = lambda n: f"MPI_Allgather(&val{n}, 1, type, rbuf{n}, 1, type, newcom);"
119 fini['MPI_Allgather'] = lambda n: ""
120 free['MPI_Allgather'] = lambda n: f"free(rbuf{n});"
121 write['MPI_Allgather'] = lambda n: ""
122
123 init['MPI_Alltoallv'] = lambda n: (f"int *sbuf{n}=(int*)malloc(dbs*2), *rbuf{n}=(int*)malloc(dbs*2), *scounts{n}=(int*)malloc(dbs), *rcounts{n}=(int*)malloc(dbs), *sdispls{n}=(int*)malloc(dbs), *rdispls{n}=(int*)malloc(dbs);\n"
124   +  "  for (int i = 0; i < nprocs; i++) {\n"
125   + f"    scounts{n}[i] = 2;\n"
126   + f"    rcounts{n}[i] = 2;\n"
127   + f"    sdispls{n}[i] = (nprocs - (i + 1)) * 2;\n"
128   + f"    rdispls{n}[i] = i * 2;\n"
129   +  "  }")
130 start['MPI_Alltoallv'] = lambda n: ""
131 operation['MPI_Alltoallv'] = lambda n: f"MPI_Alltoallv(sbuf{n}, scounts{n}, sdispls{n}, type, rbuf{n}, rcounts{n}, rdispls{n}, type, newcom);"
132 fini['MPI_Alltoallv'] = lambda n: ""
133 free['MPI_Alltoallv'] = lambda n: f"free(sbuf{n});free(rbuf{n});free(scounts{n});free(rcounts{n});free(sdispls{n});free(rdispls{n});"
134 write['MPI_Alltoallv'] = lambda n: ""
135
136 init['MPI_Alltoall'] = lambda n: f"int *sbuf{n} = (int*)malloc(dbs), *rbuf{n} = (int*)malloc(dbs);"
137 start['MPI_Alltoall'] = lambda n: ""
138 operation['MPI_Alltoall'] = lambda n: f"MPI_Alltoall(sbuf{n}, 1, type, rbuf{n}, 1, type, newcom);"
139 fini['MPI_Alltoall'] = lambda n: ""
140 free['MPI_Alltoall'] = lambda n: f"free(sbuf{n});free(rbuf{n});"
141 write['MPI_Alltoall'] = lambda n: ""
142
143 init['MPI_Allgatherv'] = lambda n: (f"int *rbuf{n} = (int*)malloc(dbs*2), *rcounts{n}=(int*)malloc(dbs),  *displs{n}=(int*)malloc(dbs);\n"
144   +  "  for (int i = 0; i < nprocs; i++) {\n"
145   + f"    rcounts{n}[i] = 1;\n"
146   + f"    displs{n}[i] = 2 * (nprocs - (i + 1));\n"
147   +  "  }")
148 start['MPI_Allgatherv'] = lambda n: ""
149 operation['MPI_Allgatherv'] = lambda n: f"MPI_Allgatherv(&rank, 1, type, rbuf{n}, rcounts{n}, displs{n}, type, newcom);"
150 fini['MPI_Allgatherv'] = lambda n: ""
151 free['MPI_Allgatherv'] = lambda n: f"free(rbuf{n});free(rcounts{n});free(displs{n});"
152 write['MPI_Allgatherv'] = lambda n: ""
153
154
155 ### COLL:nonblocking
156
157 init['MPI_Ibarrier'] = lambda n: f"MPI_Request req{n}=MPI_REQUEST_NULL; MPI_Status stat{n};"
158 start['MPI_Ibarrier'] = lambda n: ""
159 operation['MPI_Ibarrier'] = lambda n: f'MPI_Ibarrier(newcom, &req{n});'
160 fini['MPI_Ibarrier'] = lambda n: f"MPI_Wait(&req{n}, &stat{n});"
161 free['MPI_Ibarrier'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
162 write['MPI_Ibarrier'] = lambda n: ""
163
164 init['MPI_Ireduce'] = lambda n: f"MPI_Request req{n}=MPI_REQUEST_NULL; MPI_Status stat{n}; int sum{n}, val{n} = 1;"
165 start['MPI_Ireduce'] = lambda n: ""
166 operation['MPI_Ireduce'] = lambda n: f"MPI_Ireduce(&val{n}, &sum{n}, 1, type, op, root, newcom, &req{n});"
167 fini['MPI_Ireduce'] = lambda n: f"MPI_Wait(&req{n}, &stat{n});"
168 free['MPI_Ireduce'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
169 write['MPI_Ireduce'] = lambda n: f"sum{n}++;"
170
171 init['MPI_Iallreduce'] = lambda n: f'MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status stat{n}; int sum{n}, val{n} = 1;'
172 start['MPI_Iallreduce'] = lambda n: ""
173 operation['MPI_Iallreduce'] = lambda n: f'MPI_Iallreduce(&val{n}, &sum{n}, 1, type, op, newcom, &req{n});'
174 fini['MPI_Iallreduce'] = lambda n: f'MPI_Wait(&req{n}, &stat{n});'
175 free['MPI_Iallreduce'] = lambda n: f"if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});"
176 write['MPI_Iallreduce'] = lambda n: f"sum{n}++;"
177
178 init['MPI_Ibcast'] = lambda n: f'MPI_Request req{n}=MPI_REQUEST_NULL; MPI_Status sta{n};int buf{n}[buff_size];'
179 start['MPI_Ibcast'] = lambda n: ""
180 operation['MPI_Ibcast'] = lambda n: f'MPI_Ibcast(buf{n}, buff_size, type, root, newcom, &req{n});'
181 fini['MPI_Ibcast'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
182 free['MPI_Ibcast'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
183 write['MPI_Ibcast'] = lambda n: f'buf{n}[0]++;'
184
185 init['MPI_Igather'] = lambda n: f"int val{n}=1, buf{n}[buff_size];MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status sta{n};"
186 start['MPI_Igather'] = lambda n: ""
187 operation['MPI_Igather'] = lambda n: f'MPI_Igather(&val{n}, 1, type, &buf{n},1, type, root, newcom, &req{n});'
188 write['MPI_Igather'] = lambda n: f'val{n}=3;'
189 fini['MPI_Igather'] = lambda n: f'MPI_Wait(&req{n},&sta{n});'
190 free['MPI_Igather'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
191
192 init['MPI_Iscatter'] = lambda n: f"MPI_Request req{n} = MPI_REQUEST_NULL;\n  MPI_Status sta{n};\n  int val{n};\n  int buf{n}[buff_size];\n  memset(buf{n}, 0, buff_size*sizeof(int));"
193 start['MPI_Iscatter'] = lambda n: ""
194 operation['MPI_Iscatter'] = lambda n: f"MPI_Iscatter(&buf{n}, 1, type, &val{n}, 1, type, root, newcom,&req{n});"
195 fini['MPI_Iscatter'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
196 free['MPI_Iscatter'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
197 write['MPI_Iscatter'] = lambda n: f'buf{n}[0]++;'
198
199 init['MPI_Iscan'] = lambda n: f"MPI_Request req{n} = MPI_REQUEST_NULL;\n  MPI_Status sta{n};\n  int outbuf{n}[buff_size];\n  memset(outbuf{n}, 0, buff_size*sizeof(int));\n  int inbuf{n}[buff_size];"
200 start['MPI_Iscan'] = lambda n: ""
201 operation['MPI_Iscan'] = lambda n: f"MPI_Iscan(&outbuf{n}, inbuf{n}, buff_size, type, op, newcom,&req{n});"
202 fini['MPI_Iscan'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
203 free['MPI_Iscan'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
204 write['MPI_Iscan'] = lambda n: f'outbuf{n}[0]++;'
205
206 init['MPI_Iexscan'] = lambda n: f"MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status sta{n};\n  int outbuf{n}[buff_size];\n  memset(outbuf{n}, 0, buff_size*sizeof(int));\n  int inbuf{n}[buff_size];"
207 start['MPI_Iexscan'] = lambda n: ""
208 operation['MPI_Iexscan'] = lambda n: f"MPI_Iexscan(&outbuf{n}, inbuf{n}, buff_size, type, op, newcom,&req{n});"
209 fini['MPI_Iexscan'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
210 free['MPI_Iexscan'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
211 write['MPI_Iexscan'] = lambda n: f'outbuf{n}[0]++;'
212
213 init['MPI_Iallgather'] = lambda n: f"MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status sta{n};int val{n}=1, *rbuf{n} = (int*)malloc(dbs);"
214 start['MPI_Iallgather'] = lambda n: ""
215 operation['MPI_Iallgather'] = lambda n: f"MPI_Iallgather(&val{n}, 1, type, rbuf{n}, 1, type, newcom,&req{n});"
216 fini['MPI_Iallgather'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
217 free['MPI_Iallgather'] = lambda n: f"free(rbuf{n});"
218 write['MPI_Iallgather'] = lambda n: f'val{n}++;'
219
220 init['MPI_Iallgatherv'] = lambda n: (f"MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status sta{n};int *rbuf{n} = (int*)malloc(dbs*2), *rcounts{n}=(int*)malloc(dbs),  *displs{n}=(int*)malloc(dbs);\n"
221   +  "  for (int i = 0; i < nprocs; i++) {\n"
222   + f"    rcounts{n}[i] = 1;\n"
223   + f"    displs{n}[i] = 2 * (nprocs - (i + 1));\n"
224   +  "  }")
225 start['MPI_Iallgatherv'] = lambda n: ""
226 operation['MPI_Iallgatherv'] = lambda n: f"MPI_Iallgatherv(&rank, 1, type, rbuf{n}, rcounts{n}, displs{n}, type, newcom,&req{n});"
227 fini['MPI_Iallgatherv'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
228 free['MPI_Iallgatherv'] = lambda n: f"free(rbuf{n});free(rcounts{n});free(displs{n});"
229 write['MPI_Iallgatherv'] = lambda n: f"rbuf{n}[0]++;"
230
231 init['MPI_Ialltoall'] = lambda n: f"MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status sta{n};int *sbuf{n} = (int*)malloc(dbs), *rbuf{n} = (int*)malloc(dbs);"
232 start['MPI_Ialltoall'] = lambda n: ""
233 operation['MPI_Ialltoall'] = lambda n: f"MPI_Ialltoall(sbuf{n}, 1, type, rbuf{n}, 1, type, newcom, &req{n});"
234 fini['MPI_Ialltoall'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
235 free['MPI_Ialltoall'] = lambda n: f"free(sbuf{n});free(rbuf{n});"
236 write['MPI_Ialltoall'] = lambda n: f"rbuf{n}[0]++;"
237
238 init['MPI_Ialltoallv'] = lambda n: (f"MPI_Request req{n}=MPI_REQUEST_NULL;MPI_Status sta{n};int *sbuf{n}=(int*)malloc(dbs*2), *rbuf{n}=(int*)malloc(dbs*2), *scounts{n}=(int*)malloc(dbs), *rcounts{n}=(int*)malloc(dbs), *sdispls{n}=(int*)malloc(dbs), *rdispls{n}=(int*)malloc(dbs);\n"
239   +  "  for (int i = 0; i < nprocs; i++) {\n"
240   + f"    scounts{n}[i] = 2;\n"
241   + f"    rcounts{n}[i] = 2;\n"
242   + f"    sdispls{n}[i] = (nprocs - (i + 1)) * 2;\n"
243   + f"    rdispls{n}[i] = i * 2;\n"
244   +  "  }")
245 start['MPI_Ialltoallv'] = lambda n: ""
246 operation['MPI_Ialltoallv'] = lambda n: f"MPI_Ialltoallv(sbuf{n}, scounts{n}, sdispls{n}, type, rbuf{n}, rcounts{n}, rdispls{n}, type, newcom,&req{n});"
247 fini['MPI_Ialltoallv'] = lambda n: f"MPI_Wait(&req{n},&sta{n});"
248 free['MPI_Ialltoallv'] = lambda n: f"free(sbuf{n});free(rbuf{n});free(scounts{n});free(rcounts{n});free(sdispls{n});free(rdispls{n});"
249 write['MPI_Ialltoallv'] = lambda n: f"rbuf{n}[0]++;"
250
251 ### COLL:persistent
252
253
254
255 ### COLL:tools
256
257 init['MPI_Comm_split'] = lambda n: 'MPI_Comm com[size]; int color = rank % 2; int key = 1;'
258 start['MPI_Comm_split'] = lambda n: ""
259 operation['MPI_Comm_split'] = lambda n: 'MPI_Comm_split(MPI_COMM_WORLD,color,key, &com[j]);'
260 error['MPI_Comm_split'] = 'CommunicatorLeak'
261 fini['MPI_Comm_split'] = lambda n: "if(com[j] != MPI_COMM_NULL) MPI_Comm_free(&com[j]);"
262 free['MPI_Comm_split'] = lambda n: ""
263
264
265 init['MPI_Cart_get'] = lambda n: ""
266 start['MPI_Cart_get'] = lambda n: ""
267 operation['MPI_Cart_get'] = lambda n: 'MPI_Cart_get(newcom, 2, dims, periods, coords);'
268 write['MPI_Cart_get'] = lambda n: ""
269 fini['MPI_Cart_get'] = lambda n: ""
270 free['MPI_Cart_get'] = lambda n: ""
271
272
273 init['MPI_Op_create'] = lambda n: 'MPI_Op op[size];'
274 operation['MPI_Op_create'] = lambda n: 'MPI_Op_create((MPI_User_function *)myOp, 0, &op[j]);'
275 error['MPI_Op_create'] = 'OperatorLeak'
276 fini['MPI_Op_create'] = lambda n: "MPI_Op_free(&op[j]);"
277 free['MPI_Op_create'] = lambda n: ""
278
279 init['MPI_Comm_group'] = lambda n: 'MPI_Group grp[size];'
280 operation['MPI_Comm_group'] = lambda n: 'MPI_Comm_group(MPI_COMM_WORLD, &grp[j]);'
281 error['MPI_Comm_group'] = 'GroupLeak'
282 fini['MPI_Comm_group'] = lambda n: "MPI_Group_free(&grp[j]);"
283 free['MPI_Comm_group'] = lambda n: ""
284
285 init['MPI_Group_excl'] = lambda n: 'MPI_Group worldgroup, grp[size];\n MPI_Comm_group(MPI_COMM_WORLD, &worldgroup);'
286 operation['MPI_Group_excl'] = lambda n: 'MPI_Group_excl(worldgroup, 1, &rank, &grp[j]);'
287 error['MPI_Group_excl'] = 'GroupLeak'
288 fini['MPI_Group_excl'] = lambda n: "MPI_Group_free(&grp[j]);"
289 free['MPI_Group_excl'] = lambda n: "MPI_Group_free(&worldgroup);"
290
291 init['MPI_Comm_create'] = lambda n: 'MPI_Comm com[size]; MPI_Group grp[size];'
292 operation['MPI_Comm_create'] = lambda n: 'MPI_Comm_group(MPI_COMM_WORLD, &grp[j]);\n MPI_Comm_create(MPI_COMM_WORLD, grp[j], &com[j]);\n MPI_Group_free(&grp[j]);'
293 error['MPI_Comm_create'] = 'CommunicatorLeak'
294 fini['MPI_Comm_create'] = lambda n: "MPI_Comm_free(&com[j]);"
295 free['MPI_Comm_create'] = lambda n: ""
296
297 init['MPI_Comm_dup'] = lambda n: 'MPI_Comm com[size];'
298 operation['MPI_Comm_dup'] = lambda n: 'MPI_Comm_dup(MPI_COMM_WORLD, &com[j]);'
299 error['MPI_Comm_dup'] = 'CommunicatorLeak'
300 fini['MPI_Comm_dup'] = lambda n: "MPI_Comm_free(&com[j]);"
301 free['MPI_Comm_dup'] = lambda n: ""
302
303 init['MPI_Type_contiguous'] = lambda n: 'MPI_Datatype type[size];'
304 operation['MPI_Type_contiguous'] = lambda n: 'MPI_Type_contiguous(2, MPI_DOUBLE, &type[j]);'
305 error['MPI_Type_contiguous'] = 'TypeLeak'
306 fini['MPI_Type_contiguous'] = lambda n: "MPI_Type_free(&type[j]);"
307 free['MPI_Type_contiguous'] = lambda n: ""
308
309
310
311
312 ### P2P:basic
313
314 init['MPI_Send'] = lambda n: f'int buf{n}=rank;'
315 start['MPI_Send'] = lambda n: ""
316 operation['MPI_Send'] = lambda n: f'MPI_Send(&buf{n}, buff_size, type, dest, stag, newcom);'
317 fini['MPI_Send'] = lambda n: ""
318 free['MPI_Send'] = lambda n: ""
319 write['MPI_Send'] = lambda n: ""
320
321 init['MPI_Ssend'] = lambda n: f'int buf{n}=rank;'
322 start['MPI_Ssend'] = lambda n: ""
323 operation['MPI_Ssend'] = lambda n: f'MPI_Ssend(&buf{n}, buff_size, type, dest, stag, newcom);'
324 fini['MPI_Ssend'] = lambda n: ""
325 free['MPI_Ssend'] = lambda n: ""
326 write['MPI_Ssend'] = lambda n: ""
327
328 init['MPI_Bsend'] = lambda n: (f'int buf{n}=rank;\n'
329             + f'int buffer_attached_size{n} = MPI_BSEND_OVERHEAD + sizeof(int);\n'
330             + f'char* buffer_attached{n} = (char*)malloc(buffer_attached_size{n});\n'
331             + f'MPI_Buffer_attach(buffer_attached{n}, buffer_attached_size{n});')
332 start['MPI_Bsend'] = lambda n: ""
333 operation['MPI_Bsend'] = lambda n: f'MPI_Bsend(&buf{n}, buff_size, type, dest, stag, newcom);'
334 fini['MPI_Bsend'] = lambda n: ""
335 free['MPI_Bsend'] = (lambda n: f'MPI_Buffer_detach(&buffer_attached{n}, &buffer_attached_size{n});\n'
336             + f'free(buffer_attached{n});')
337 write['MPI_Bsend'] = lambda n: ""
338
339 init['MPI_Recv'] = lambda n: f'int buf{n}=-1; MPI_Status sta{n};'
340 start['MPI_Recv'] = lambda n: ""
341 operation['MPI_Recv'] = lambda n: f'MPI_Recv(&buf{n}, buff_size, type, src, rtag, newcom, &sta{n});'
342 fini['MPI_Recv'] = lambda n: ""
343 free['MPI_Recv'] = lambda n: ""
344 write['MPI_Recv'] = lambda n: ""
345
346 init['MPI_Probe'] = lambda n: ""
347 start['MPI_Probe'] = lambda n: ""
348 operation['MPI_Probe'] = lambda n: 'MPI_Probe(src, 0, newcom, &sta);'
349 fini['MPI_Probe'] = lambda n: ""
350 free['MPI_Probe'] = lambda n: ""
351 write['MPI_Probe'] = lambda n: ""
352
353
354
355 ### P2P:nonblocking
356
357 init['MPI_Isend'] = lambda n: f'int buf{n}=rank; MPI_Request req{n}=MPI_REQUEST_NULL;'
358 start['MPI_Isend'] = lambda n: ""
359 operation['MPI_Isend'] = lambda n: f'MPI_Isend(&buf{n}, buff_size, type, dest, stag, newcom, &req{n});'
360 fini['MPI_Isend'] = lambda n: f'MPI_Wait(&req{n}, MPI_STATUS_IGNORE);'
361 free['MPI_Isend'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
362 write['MPI_Isend'] = lambda n: f'buf{n}=4;'
363
364 init['MPI_Irecv'] = lambda n: f'int buf{n}=-1; MPI_Request req{n}=MPI_REQUEST_NULL;'
365 start['MPI_Irecv'] = lambda n: ""
366 operation['MPI_Irecv'] = lambda n: f'MPI_Irecv(&buf{n}, buff_size, type, src, rtag, newcom, &req{n});'
367 fini['MPI_Irecv'] = lambda n: f' MPI_Wait(&req{n}, MPI_STATUS_IGNORE);'
368 free['MPI_Irecv'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
369 write['MPI_Irecv'] = lambda n: f'buf{n}++;'
370
371 ### P2P:persistent
372
373 init['MPI_Send_init'] = lambda n: f'int buf{n}=rank; MPI_Request req{n}=MPI_REQUEST_NULL;'
374 operation['MPI_Send_init'] = lambda n: f'MPI_Send_init(&buf{n}, buff_size, type, dest, stag, newcom, &req{n});'
375 start['MPI_Send_init'] = lambda n: f'MPI_Start(&req{n});'
376 fini['MPI_Send_init'] = lambda n: f'MPI_Wait(&req{n}, MPI_STATUS_IGNORE);'
377 free['MPI_Send_init'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
378 write['MPI_Send_init'] = lambda n: f'buf{n}=4;'
379
380 init['MPI_Recv_init'] = lambda n: f'int buf{n}=-1; MPI_Request req{n}=MPI_REQUEST_NULL;'
381 start['MPI_Recv_init'] = lambda n: f'MPI_Start(&req{n});'
382 operation['MPI_Recv_init'] = lambda n: f'MPI_Recv_init(&buf{n}, buff_size, type, src, rtag, newcom, &req{n});'
383 fini['MPI_Recv_init'] = lambda n: f'MPI_Wait(&req{n}, MPI_STATUS_IGNORE);'
384 free['MPI_Recv_init'] = lambda n: f'if(req{n} != MPI_REQUEST_NULL) MPI_Request_free(&req{n});'
385 write['MPI_Recv_init'] = lambda n: f'buf{n}++;'
386
387 ### RMA
388
389 epoch['MPI_Win_fence'] = lambda n: 'MPI_Win_fence(0, win);'
390 finEpoch['MPI_Win_fence'] = lambda n: 'MPI_Win_fence(0, win);'
391 epoch['MPI_Win_lock'] = lambda n: 'MPI_Win_lock(MPI_LOCK_SHARED, target, 0, win);'
392 finEpoch['MPI_Win_lock'] = lambda n: 'MPI_Win_unlock(target, win);'
393 epoch['MPI_Win_lock_all'] = lambda n: 'MPI_Win_lock_all(0,win);'
394 finEpoch['MPI_Win_lock_all'] = lambda n: 'MPI_Win_unlock_all(win);'
395
396 init['MPI_Put'] = lambda n: f'int localbuf{n}[N] = {{12345}};'
397 operation['MPI_Put'] = lambda n: f'MPI_Put(&localbuf{n}, N, MPI_INT, target, 0, N, type, win);'
398
399 init['MPI_Get'] = lambda n: f'int localbuf{n}[N] = {{54321}};'
400 operation['MPI_Get'] = lambda n: f'MPI_Get(&localbuf{n}, N, MPI_INT, target, 0, N, type, win);'
401
402 init['store'] = lambda n: f'int localbuf{n}[N] = {{0}};'
403 operation['store'] = lambda n: f'localbuf{n}[0] = 8;'
404
405 init['rstore'] = lambda n: ""
406 operation['rstore'] = lambda n: 'winbuf[20] = 12346;'
407
408 init['load'] = lambda n: f'int localbuf{n}[N] = {{0}};'
409 operation['load'] = lambda n: f'int load = localbuf{n}[0];'
410
411 init['rload'] = lambda n: ""
412 operation['rload'] = lambda n: "int load = winbuf[20];"
413
414 init['loadstore'] = lambda n: f'int localbuf{n}[N] = {{0}};'
415 operation['loadstore'] = lambda n: f'if (localbuf{n}[0] % 2 == 0)  localbuf{n}[0]++; '
416
417
418
419
420 def find_line(content, target, filename):
421     res = 1
422     for line in content.split('\n'):
423         if re.search(f'[^:]{target}', line):
424             #print(f'Found {target} at {line}')
425             return res
426         res += 1
427     raise ValueError(f"Line target {target} not found in {filename}.")
428
429
430 def make_file(template, filename, replace):
431     output = template
432     filename = filename.replace("_MPI_", "_")
433     replace['filename'] = filename
434     # Replace all variables that don't have a ':' in their name
435     while re.search(r'@\{[^@:]*\}@', output):
436         m = re.search(r'@\{([^@:]*)\}@', output)
437         target = m.group(1)
438         #print(f"Replace @{{{target}}}@")
439         if target in replace.keys():
440             output = re.sub(fr'@\{{{target}\}}@', replace[target], output)
441             #print(f"Replace {target} -> {replace[target]}")
442         else:
443             raise ValueError(f"Variable {target} used in template, but not defined.")
444     # Now replace all variables with a ':' in their name: line targets are like that, and we don't want to resolve them before the others change the lines
445     while re.search(r'@\{([^:@]*):([^@]*)\}@', output):
446         m = re.search(r'@\{([^:@]*):([^@]*)\}@', output)
447         (kind, target) = (m.group(1), m.group(2))
448         if kind == 'line':
449             replace = f'{find_line(output, target, filename)}'
450             #print(f"Replace @{{line:{target}}}@ with '{replace}'")
451             output = re.sub(fr'@\{{line:{target}\}}@', replace, output)
452         else:
453             raise ValueError(f"Unknown variable kind: {kind}:{target}")
454
455     if os.path.exists(filename):
456         with open(filename, 'r') as file:
457             prev = file.read().split('\n')[0]
458             prev = re.sub('^.*?scripts/', 'scripts/', prev)
459             prev = re.sub('. DO NOT EDIT.', '', prev)
460         now = output.split('\n')[0]
461         now = re.sub('^.*?scripts/', 'scripts/', now)
462         now = re.sub('. DO NOT EDIT.', '', now)
463
464         print(f'WARNING: overwriting {filename}. Previously generated by: {prev}; regenerated by {now}')
465
466     # Ready to output it
467     with open(filename, 'w') as outfile:
468         outfile.write(output)