Skip to content

Commit c7bc5b1

Browse files
authored
fix #25, update ex6 (#29)
* fix #25, update ex6 * Update README.md Co-authored-by: [email protected] * small fix * change the filename output * fix typo + indent * homogenization --------- Co-authored-by: [email protected] and [email protected]
1 parent 15b0f4a commit c7bc5b1

File tree

5 files changed

+124
-55
lines changed

5 files changed

+124
-55
lines changed

README.md

+17-3
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ in two distinct groups `iter1` and `iter2`.
336336
```bash
337337
diff ex5.h5dump <(h5dump ex5-data-*.h5)
338338
```
339+
339340
To see your `h5` file in readable file format, you can check the section
340341
[Comparison with the `h5dump` command](#h5comparison).
341342

@@ -346,10 +347,13 @@ As you can notice, the %PDI code is quite redundant.
346347
In this exercise, you will use `::PDI_expose` and `::PDI_multi_expose` to
347348
simplify the code while keeping the exact same behaviour.
348349
For once, there is no need to modify the YAML file here, you only need to modify
349-
the C file in this exercise.
350+
the C file. Moreover, this exercise will be launched sequentially to facilitate
351+
the comparison between logs.
350352

351353
* Examine the source code, compile it and run it.
352354

355+
\remark At the end of the iteration loop, a new event `finalization` is added.
356+
353357
There are lots of matched `::PDI_share`/`::PDI_reclaim` in the code.
354358

355359
* Replace these by `::PDI_expose` that is the exact equivalent of a
@@ -362,12 +366,22 @@ then triggers an event and finally does all the reclaim in reverse order.
362366

363367
* Replace the remaining `::PDI_share`/`::PDI_reclaim` by `::PDI_expose`s and
364368
`::PDI_multi_expose`s and ensure that your code keeps the exact same behaviour
365-
by comparing its trace to `ex6.log` (only the lines matching `[Trace-plugin]`
366-
have been kept). You can easily check if the files are the same by running:
369+
as in previous exercise by comparing its trace to `ex6.log` (only the lines matching
370+
`[Trace-plugin]` have been kept). Using the previous section
371+
[Execution with storage of the log](#execution-with-storage-of-the-log),
372+
run this exercise in saving the output log in the `ex6.result.log`.
373+
After that you can easily check if the files are the same by running:
367374
```bash
368375
diff ex6.log <(grep Trace-plugin ex6.result.log)
369376
```
370377

378+
In summary:
379+
380+
1. `::PDI_expose` is equivalent to `::PDI_share` + `::PDI_reclaim`.
381+
382+
2. `::PDI_multi_expose` is equivalent to `::PDI_share` + `::PDI_event` + `::PDI_reclaim`.
383+
384+
371385
### Ex7. Writing a selection
372386

373387
In this exercise, you will only write a selection of the 2D array in memory

ex6.c

+59-30
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,57 @@
3232
// load the PDI header
3333
#include <pdi.h>
3434

35-
/// size of the local data as [HEIGHT, WIDTH] including ghosts & boundary constants
35+
// size of the local data as [HEIGHT, WIDTH] including the number of ghost layers
36+
// for communications or boundary conditions
3637
int dsize[2];
3738

38-
/// 2D size of the process grid as [HEIGHT, WIDTH]
39+
// 2D size of the process grid as [HEIGHT, WIDTH]
3940
int psize[2];
4041

41-
/// 2D rank of the local process in the process grid as [YY, XX]
42+
// 2D rank of the local process in the process grid as [YY, XX]
4243
int pcoord[2];
4344

44-
/// the alpha coefficient used in the computation
45+
// the alpha coefficient used in the computation
4546
double alpha;
4647

47-
/** Initialize the data all to 0 except for the left border (XX==0) initialized to 1 million
48+
double L=1.0;
49+
// definition of the source
50+
// the source corresponds to a disk of an uniform value
51+
// source1: center=(0.4,0.4), radius=0.2 and value=100
52+
double source1[4]={0.4, 0.4, 0.2, 100};
53+
// source2: center=(0.8,0.7), radius=0.1 and value=200
54+
double source2[4]={0.7, 0.8, 0.1, 200};
55+
// the order of the coordinates of the center (XX,YY) is inverted in the vector
56+
57+
/** Initialize all the data to 0, with the exception of a given cell
58+
* whose center (cpos_x,cpos_y) is inside of the disks
59+
* defined by source1 or source2
4860
* \param[out] dat the local data to initialize
4961
*/
5062
void init(double dat[dsize[0]][dsize[1]])
5163
{
5264
for (int yy=0; yy<dsize[0]; ++yy) for (int xx=0; xx<dsize[1]; ++xx) dat[yy][xx] = 0;
53-
if ( pcoord[1] == 0 ) for (int yy=0; yy<dsize[0]; ++yy) dat[yy][0] = 1000000;
65+
double dy = L / ((dsize[0]-2) *psize[0]) ;
66+
double dx = L / ((dsize[1]-2) *psize[1]) ;
67+
68+
double cpos_x,cpos_y;
69+
double square_dist1, square_dist2;
70+
for(int yy=0; yy<dsize[0];++yy) {
71+
cpos_y=(yy+pcoord[0]*(dsize[0]-2))*dy-0.5*dy;
72+
for(int xx=0; xx<dsize[1];++xx) {
73+
cpos_x=(xx+pcoord[1]*(dsize[1]-2))*dx-0.5*dx;
74+
square_dist1 = ( cpos_y-source1[0] ) * ( cpos_y-source1[0] )
75+
+ ( cpos_x-source1[1] ) * ( cpos_x-source1[1] );
76+
if (square_dist1 <= source1[2] * source1[2]) {
77+
dat[yy][xx] = source1[3];
78+
}
79+
square_dist2 = ( cpos_y-source2[0] ) * ( cpos_y-source2[0] )
80+
+ ( cpos_x-source2[1] ) * ( cpos_x-source2[1] );
81+
if (square_dist2 <= source2[2] * source2[2]) {
82+
dat[yy][xx] = source2[3];
83+
}
84+
}
85+
}
5486
}
5587

5688
/** Compute the values at the next time-step based on the values at the current time-step
@@ -60,24 +92,18 @@ void init(double dat[dsize[0]][dsize[1]])
6092
void iter(double cur[dsize[0]][dsize[1]], double next[dsize[0]][dsize[1]])
6193
{
6294
int xx, yy;
63-
for (xx=0; xx<dsize[1]; ++xx) next[0][xx] = cur[0][xx];
6495
for (yy=1; yy<dsize[0]-1; ++yy) {
65-
next[yy][0] = cur[yy][0];
6696
for (xx=1; xx<dsize[1]-1; ++xx) {
67-
next[yy][xx] =
68-
(1.-4.*alpha) * cur[yy][xx]
69-
+ alpha * ( cur[yy][xx-1]
70-
+ cur[yy][xx+1]
71-
+ cur[yy-1][xx]
72-
+ cur[yy+1][xx]
73-
);
97+
next[yy][xx] = (1.-4.*alpha) * cur[yy][xx]
98+
+alpha * ( cur[yy][xx-1]
99+
+ cur[yy][xx+1]
100+
+ cur[yy-1][xx]
101+
+ cur[yy+1][xx]);
74102
}
75-
next[yy][dsize[1]-1] = cur[yy][dsize[1]-1];
76103
}
77-
for (xx=0; xx<dsize[1]; ++xx) next[dsize[0]-1][xx] = cur[dsize[0]-1][xx];
78104
}
79105

80-
/** Exchanges ghost values with neighbours
106+
/** Exchange ghost values with neighbours
81107
* \param[in] cart_comm the MPI communicator with all processes organized in a 2D Cartesian grid
82108
* \param[in] cur the local data at the current time-step whose ghosts need exchanging
83109
*/
@@ -104,8 +130,8 @@ void exchange(MPI_Comm cart_comm, double cur[dsize[0]][dsize[1]])
104130

105131
// send up
106132
MPI_Cart_shift(cart_comm, 0, -1, &rank_source, &rank_dest);
107-
MPI_Sendrecv(&cur[1][1], 1, row, rank_dest, 100, // send column after ghost
108-
&cur[dsize[0]-1][1], 1, row, rank_source, 100, // receive last column (ghost)
133+
MPI_Sendrecv(&cur[1][1], 1, row, rank_dest, 100, // send row after ghost
134+
&cur[dsize[0]-1][1], 1, row, rank_source, 100, // receive last row (ghost)
109135
cart_comm, &status);
110136

111137
// send to the right
@@ -116,7 +142,7 @@ void exchange(MPI_Comm cart_comm, double cur[dsize[0]][dsize[1]])
116142

117143
// send to the left
118144
MPI_Cart_shift(cart_comm, 1, -1, &rank_source, &rank_dest);
119-
MPI_Sendrecv(&cur[1][1], 1, column, rank_dest, 100, // send column after ghost
145+
MPI_Sendrecv(&cur[1][1], 1, column, rank_dest, 100, // send column after ghost
120146
&cur[1][dsize[1]-1], 1, column, rank_source, 100, // receive last column (ghost)
121147
cart_comm, &status);
122148
}
@@ -157,12 +183,12 @@ int main( int argc, char* argv[] )
157183
assert(global_size[1]%psize[1]==0);
158184
assert(psize[1]*psize[0] == psize_1d);
159185

160-
// compute the local data-size with space for ghosts and boundary constants
186+
// compute the local data-size (the number of ghost layers is 2 for each coordinate)
161187
dsize[0] = global_size[0]/psize[0] + 2;
162188
dsize[1] = global_size[1]/psize[1] + 2;
163189

164190
// create a 2D Cartesian MPI communicator & get our coordinate (rank) in it
165-
int cart_period[2] = { 0, 0 };
191+
int cart_period[2] = { 1, 1 };
166192
MPI_Comm cart_comm; MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_comm);
167193
MPI_Cart_coords(cart_comm, pcoord_1d, 2, pcoord);
168194

@@ -178,20 +204,20 @@ int main( int argc, char* argv[] )
178204
int ii=0;
179205

180206
// share useful configuration bits with PDI
181-
PDI_share("ii", &ii, PDI_OUT);
182-
PDI_reclaim("ii");
207+
//*** use PDI_expose to replace PDI_share + reclaim
208+
//...
183209
PDI_share("pcoord", pcoord, PDI_OUT);
184210
PDI_reclaim("pcoord");
185211
PDI_share("dsize", dsize, PDI_OUT);
186212
PDI_reclaim("dsize");
187213
PDI_share("psize", psize, PDI_OUT);
188214
PDI_reclaim("psize");
189-
PDI_share("main_field", cur, PDI_OUT);
190-
PDI_reclaim("main_field");
191215

192216
// the main loop
193-
for (; ii<10; ++ii) {
217+
for (; ii<4; ++ii) {
194218
// share the loop counter & main field at each iteration
219+
//*** use PDI_multi_expose to replace PDI_share + event + reclaim
220+
//...
195221
PDI_share("ii", &ii, PDI_OUT);
196222
PDI_share("main_field", cur, PDI_OUT);
197223
PDI_event("loop");
@@ -208,11 +234,13 @@ int main( int argc, char* argv[] )
208234
double (*tmp)[dsize[1]] = cur; cur = next; next = tmp;
209235
}
210236
// finally share the main field as well as the loop counter after the loop
211-
PDI_share("main_field", cur, PDI_OUT);
237+
//*** use PDI_multi_expose to replace PDI_share + event + reclaim
238+
//...
212239
PDI_share("ii", &ii, PDI_OUT);
240+
PDI_share("main_field", cur, PDI_OUT);
213241
PDI_event("finalization");
214-
PDI_reclaim("ii");
215242
PDI_reclaim("main_field");
243+
PDI_reclaim("ii");
216244

217245
// finalize PDI
218246
PDI_finalize();
@@ -230,3 +258,4 @@ int main( int argc, char* argv[] )
230258
fprintf(stderr, "[%d] SUCCESS\n", pcoord_1d);
231259
return EXIT_SUCCESS;
232260
}
261+

ex6.log

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
[PDI][Trace-plugin] *** info: Welcome!
22
[PDI][Trace-plugin] *** info: !!! named event: initialization
3-
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
4-
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
53
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: pcoord
64
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: pcoord
75
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: dsize
86
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: dsize
97
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: psize
108
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: psize
9+
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
1110
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
11+
[PDI][Trace-plugin] *** info: !!! named event: loop
1212
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
13+
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
1314
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
1415
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
1516
[PDI][Trace-plugin] *** info: !!! named event: loop

ex6.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# the alpha parameter
22
alpha: 0.125
3-
# global data-size (excluding spacer for boundary conditions or ghosts)
3+
# global data-size (excluding the number of ghost layers for boundary conditions)
44
global_size: { height: 60, width: 12 }
55
# degree of parallelism (number of blocks in each dimension)
66
parallelism: { height: 1, width: 1 }
@@ -16,3 +16,14 @@ pdi:
1616
plugins:
1717
trace:
1818
logging: { pattern: '[PDI][%n-plugin] *** %l: %v' }
19+
decl_hdf5:
20+
- file: ex6-meta-${pcoord[0]}x${pcoord[1]}.h5
21+
write: [ dsize, psize ]
22+
- file: ex6-data-${pcoord[0]}x${pcoord[1]}.h5
23+
on_event: loop
24+
when: '$ii>0 & $ii<3'
25+
write:
26+
ii:
27+
dataset: 'iter${ii}/ii'
28+
main_field:
29+
dataset: 'iter${ii}/main_field'

solutions/ex6.c

+33-19
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,32 @@ int pcoord[2];
4444
/// the alpha coefficient used in the computation
4545
double alpha;
4646

47+
double L=1.0;
48+
double source1[4]={0.4, 0.4, 0.2, 100};
49+
double source2[4]={0.7, 0.8, 0.1, 200};
50+
4751
/** Initialize the data all to 0 except for the left border (XX==0) initialized to 1 million
4852
* \param[out] dat the local data to initialize
4953
*/
5054
void init(double dat[dsize[0]][dsize[1]])
5155
{
5256
for (int yy=0; yy<dsize[0]; ++yy) for (int xx=0; xx<dsize[1]; ++xx) dat[yy][xx] = 0;
53-
if ( pcoord[1] == 0 ) for (int yy=0; yy<dsize[0]; ++yy) dat[yy][0] = 1000000;
57+
double dy = L / ((dsize[0]-2) *psize[0]) ;
58+
double dx = L / ((dsize[1]-2) *psize[1]) ;
59+
60+
double cpos_x,cpos_y;
61+
for(int yy=0; yy<dsize[0];++yy) {
62+
cpos_y=(yy+pcoord[0]*(dsize[0]-2))*dy-0.5*dy;
63+
for(int xx=0; xx<dsize[1];++xx) {
64+
cpos_x=(xx+pcoord[1]*(dsize[1]-2))*dx-0.5*dx;
65+
if((cpos_y-source1[0])*(cpos_y-source1[0]) + (cpos_x-source1[1])*(cpos_x-source1[1]) <= source1[2]*source1[2]) {
66+
dat[yy][xx] = source1[3];
67+
}
68+
if((cpos_y-source2[0])*(cpos_y-source2[0]) + (cpos_x-source2[1])*(cpos_x-source2[1]) <= source2[2]*source2[2]) {
69+
dat[yy][xx] = source2[3];
70+
}
71+
}
72+
}
5473
}
5574

5675
/** Compute the values at the next time-step based on the values at the current time-step
@@ -60,21 +79,15 @@ void init(double dat[dsize[0]][dsize[1]])
6079
void iter(double cur[dsize[0]][dsize[1]], double next[dsize[0]][dsize[1]])
6180
{
6281
int xx, yy;
63-
for (xx=0; xx<dsize[1]; ++xx) next[0][xx] = cur[0][xx];
6482
for (yy=1; yy<dsize[0]-1; ++yy) {
65-
next[yy][0] = cur[yy][0];
6683
for (xx=1; xx<dsize[1]-1; ++xx) {
67-
next[yy][xx] =
68-
(1.-4.*alpha) * cur[yy][xx]
69-
+ alpha * ( cur[yy][xx-1]
70-
+ cur[yy][xx+1]
71-
+ cur[yy-1][xx]
72-
+ cur[yy+1][xx]
73-
);
84+
next[yy][xx] = (1.-4.*alpha) * cur[yy][xx]
85+
+alpha * ( cur[yy][xx-1]
86+
+ cur[yy][xx+1]
87+
+ cur[yy-1][xx]
88+
+ cur[yy+1][xx]);
7489
}
75-
next[yy][dsize[1]-1] = cur[yy][dsize[1]-1];
7690
}
77-
for (xx=0; xx<dsize[1]; ++xx) next[dsize[0]-1][xx] = cur[dsize[0]-1][xx];
7891
}
7992

8093
/** Exchanges ghost values with neighbours
@@ -104,8 +117,8 @@ void exchange(MPI_Comm cart_comm, double cur[dsize[0]][dsize[1]])
104117

105118
// send up
106119
MPI_Cart_shift(cart_comm, 0, -1, &rank_source, &rank_dest);
107-
MPI_Sendrecv(&cur[1][1], 1, row, rank_dest, 100, // send column after ghost
108-
&cur[dsize[0]-1][1], 1, row, rank_source, 100, // receive last column (ghost)
120+
MPI_Sendrecv(&cur[1][1], 1, row, rank_dest, 100, // send row after ghost
121+
&cur[dsize[0]-1][1], 1, row, rank_source, 100, // receive last row (ghost)
109122
cart_comm, &status);
110123

111124
// send to the right
@@ -116,7 +129,7 @@ void exchange(MPI_Comm cart_comm, double cur[dsize[0]][dsize[1]])
116129

117130
// send to the left
118131
MPI_Cart_shift(cart_comm, 1, -1, &rank_source, &rank_dest);
119-
MPI_Sendrecv(&cur[1][1], 1, column, rank_dest, 100, // send column after ghost
132+
MPI_Sendrecv(&cur[1][1], 1, column, rank_dest, 100, // send column after ghost
120133
&cur[1][dsize[1]-1], 1, column, rank_source, 100, // receive last column (ghost)
121134
cart_comm, &status);
122135
}
@@ -162,7 +175,7 @@ int main( int argc, char* argv[] )
162175
dsize[1] = global_size[1]/psize[1] + 2;
163176

164177
// create a 2D Cartesian MPI communicator & get our coordinate (rank) in it
165-
int cart_period[2] = { 0, 0 };
178+
int cart_period[2] = { 1, 1 };
166179
MPI_Comm cart_comm; MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_comm);
167180
MPI_Cart_coords(cart_comm, pcoord_1d, 2, pcoord);
168181

@@ -178,15 +191,15 @@ int main( int argc, char* argv[] )
178191
int ii=0;
179192

180193
// share useful configuration bits with PDI
181-
PDI_expose("ii", &ii, PDI_OUT);
194+
//*** use PDI_expose to replace PDI_share + reclaim
182195
PDI_expose("pcoord", pcoord, PDI_OUT);
183196
PDI_expose("dsize", dsize, PDI_OUT);
184197
PDI_expose("psize", psize, PDI_OUT);
185-
PDI_expose("main_field", cur, PDI_OUT);
186198

187199
// the main loop
188-
for (; ii<3; ++ii) {
200+
for (; ii<4; ++ii) {
189201
// share the loop counter & main field at each iteration
202+
//*** use PDI_multi_expose to replace PDI_share + event + reclaim
190203
PDI_multi_expose("loop",
191204
"ii", &ii, PDI_OUT,
192205
"main_field", cur, PDI_OUT,
@@ -202,6 +215,7 @@ int main( int argc, char* argv[] )
202215
double (*tmp)[dsize[1]] = cur; cur = next; next = tmp;
203216
}
204217
// finally share the main field as well as the loop counter after the loop
218+
//*** use PDI_multi_expose to replace PDI_share + event + reclaim
205219
PDI_multi_expose("finalization",
206220
"main_field", cur, PDI_OUT,
207221
"ii", &ii, PDI_OUT,

0 commit comments

Comments
 (0)