Skip to content

Commit 8d36da1

Browse files
authored
fix #19, tutorial update pycall (ex10) (#21)
* Update ex10
1 parent 91bfa24 commit 8d36da1

5 files changed

Lines changed: 357 additions & 233 deletions

File tree

README.md

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -466,42 +466,65 @@ otherwise the data will not be changed correctly.
466466

467467
### Ex10. Post-processing the data in python
468468

469+
\attention
470+
You need to have a version %PDI with the \ref pycall_plugin "Pycall plugin"
471+
to do this exercise.
472+
469473
In this exercise, you will once again modify the YAML file only and use python
470474
to post-process the data in situ before writing it to HDF5.
471475
Here, you will write the square root of the raw data to HDF5 instead of the
472476
data itself.
473477

474478
* Examine the YAML file and compile the code.
475479

480+
* Load the \ref pycall_plugin "Pycall plugin" and enable this plugin
481+
when the `loop` event is triggered.
482+
483+
Some variables of the python script inside `ex10.yml` are not defined.
484+
The `with` directive of this plugin allows to specify input variables (parameters)
485+
to pass to Python as a set of "$-expressions".
486+
These parameters can be given as multiple blocks.
487+
488+
* Add a `with` block with the missing parameter to let the Python code process
489+
the data exposed in `main_field` for event `loop`.
490+
491+
* Use the keyword `exec` of \ref pycall_plugin "Pycall plugin".
492+
After the colon (":"), add a space and a vertical bar (" |").
493+
Uncomment the python script.
494+
476495
Notice that the Decl'HDF5 configuration was simplified, no memory selection is
477-
applied, the when condition disappeared.
496+
applied, the `when` condition disappeared because it is done in the python script:
497+
```python
498+
if 0 < iter_id < 4:
499+
transformed_field = np.sqrt(source_field[1:-1,1:-1])
500+
pdi.expose('transformed_field', transformed_field, pdi.OUT)
501+
```
502+
The last line of the python script allows to expose the transformed field to %PDI.
503+
Moreover, this data is known to %PDI in this call.
504+
505+
* Modify the Decl'HDF5 configuration to write the new data `transformed_field`
506+
exposed from Python.
507+
508+
\attention
478509
The dataset name is however explicitly specified now because it does not match
479510
the %PDI variable name anymore, you will instead write a new variable exposed
480511
from python.
481512

482-
The `pycall` section has been added to load the
483-
\ref pycall_plugin "Pycall plugin".
484-
It executes the provided code when the "loop" event is triggered.
485-
The `with` section specifies the variables (parameters) to pass to Python as a
486-
set of "$-expressions".
487-
The provided code again exposes its result to %PDI and multiple blocks can be
488-
chained this way.
489-
490-
* Add the missing parameter to the `with` block to let the Python code process
491-
the data exposed in `main_field`.
492-
493-
* Modify the Decl'HDF5 configuration to write the new data exposed from Python.
494-
495-
* Match the output from `ex10.h5dump`. You can easily check if the files are the
496-
same by running:
513+
You should be able to match the expected output described in `ex10.h5dump`.
514+
You can easily check if the files are the same by running:
497515
```bash
498516
diff ex10.h5dump <(h5dump ex10*.h5)
499517
```
518+
To see your `h5` file in readable file format,
519+
you can check the section [Comparison with the `h5dump` command](#h5comparison).
520+
521+
\warning
522+
If you relaunch the executable, remember to delete your old `ex10.h5` file before,
523+
otherwise the data will not be changed.
500524

501525
\attention
502526
In a more realistic setup, one would typically not write much code in the YAML
503-
file directly, but would instead call functions specified in a `.py` file on
504-
the side.
527+
file directly, but would instead call functions specified in a `.py` file on the side.
505528

506529
## set value of data and metadata
507530

ex10.c

Lines changed: 32 additions & 21 deletions
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
@@ -87,7 +100,7 @@ void exchange(MPI_Comm cart_comm, double cur[dsize[0]][dsize[1]])
87100
int rank_source, rank_dest;
88101
static MPI_Datatype column, row;
89102
static int initialized = 0;
90-
103+
91104
if ( !initialized ) {
92105
MPI_Type_vector(dsize[0]-2, 1, dsize[1], MPI_DOUBLE, &column);
93106
MPI_Type_commit(&column);
@@ -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,11 +191,9 @@ 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);
182194
PDI_expose("pcoord", pcoord, PDI_OUT);
183195
PDI_expose("dsize", dsize, PDI_OUT);
184196
PDI_expose("psize", psize, PDI_OUT);
185-
PDI_expose("main_field", cur, PDI_OUT);
186197

187198
// the main loop
188199
for (; ii<10; ++ii) {
@@ -197,14 +208,14 @@ int main( int argc, char* argv[] )
197208

198209
// exchange data with the neighbours
199210
exchange(cart_comm, next);
200-
211+
201212
// swap the current and next values
202213
double (*tmp)[dsize[1]] = cur; cur = next; next = tmp;
203214
}
204215
// finally share the main field as well as the loop counter after the loop
205216
PDI_multi_expose("finalization",
206-
"main_field", cur, PDI_OUT,
207217
"ii", &ii, PDI_OUT,
218+
"main_field", cur, PDI_OUT,
208219
NULL);
209220

210221
// finalize PDI

0 commit comments

Comments
 (0)