Skip to content

Commit

Permalink
update ex1 and ex2, fix #12
Browse files Browse the repository at this point in the history
  • Loading branch information
jmorice91 committed Nov 18, 2024
1 parent 7334107 commit f5bab60
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 82 deletions.
33 changes: 24 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pdirun mpirun -n 4 ./ex?
Where `?` is the number of the exercise and 4 represents the number of MPI
processes to use.

#### Execution with storage of the log

To store the logs for later comparison, you can use the following command (for
example for ex2.):
```bash
Expand Down Expand Up @@ -109,25 +111,36 @@ read this file.
* Set values in `ex1.yml` to be able to run the code with 4 MPI processes.

```bash
srun -n 4 ./ex1
mpirun -np 4 ./ex1
```


## PDI core & trace plugin

### Ex2. Now with some PDI

Ex2. is the same code as that of ex1. with %PDI calls added in `main` function.
In our YAML file (`ex2.yml`), a new sub-tree has been added under the `pdi` key.
This sub-tree is the %PDI specification tree passed to %PDI at initialization.
Here, the %PDI \ref trace_plugin "Trace plugin" is used to trace %PDI calls.
Ex2. is a similar code as that of ex1. with %PDI calls added in `main` function. This exercise will be run in sequential.

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

* Add the required `::PDI_share` and `::PDI_reclaim` calls to match the output
of `ex2.log` file (only the lines matching `[Trace-plugin]` have been kept).
You only need to change the `ex2.c` file. You can easily check if the files
are the same by running the command:
In our YAML file (`ex2.yml`), the `pdi` key is added. The sub-tree, defined after this key, is the %PDI specification tree passed to %PDI at initialization.

* To observe %PDI calls on the standard output, add \ref trace_plugin "Trace plugin" (`trace`) plugin of %PDI in our YAML file (`ex2.yml`).

* In the C file (`ex2.c`), add `::PDI_share` and `::PDI_reclaim` call to share some data with %PDI.
The shared data are defined in the line that starts with "//***" in `ex2.c`.

Here, the objective is to match the output of `ex2.log` file. In this file, only the line corresponding to `[Trace-plugin]` have been kept.
Moreover, the time are given for each %PDI calls. To compare, we need to remove this information from the log. It is done by adding this line in the sub-tree of the trace plugin.

```yaml
logging: { pattern: '[PDI][%n-plugin] *** %l: %v' }
```
Additionnaly, we run in sequential to facilitate the comparison between logs (In parallel each rank send a `trace` message and the order of writting can be different).

* Add the previous line, in the sub-tree of \ref trace_plugin "Trace plugin" (don't forget to indent this line correctly).
Using the previous section [Execution with storage of the log](#execution-with-storage-of-the-log), run this exercise in saving the output log in the file `ex2.result.log`. After that you can easily check if the files are the same by running the command:

```bash
diff ex2.log <(grep Trace-plugin ex2.result.log)
```
Expand All @@ -138,6 +151,8 @@ interlaced.
Is one better than the other?
If you do not know the answer to this question, just wait until Ex5. :)

\attention
In this exercise, the shared variable and the reclaimed variable are not defined in the YAML file.

## Decl'HDF5 plugin

Expand Down
44 changes: 30 additions & 14 deletions ex1.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <time.h>

#include <paraconf.h>
#include <pdi.h>

/// size of the local data as [HEIGHT, WIDTH] including ghosts & boundary constants
int dsize[2];
Expand All @@ -42,13 +43,32 @@ int pcoord[2];
/// the alpha coefficient used in the computation
double alpha;

double L=1.0;
double source1[4]={0.4, 0.4, 0.2, 100};
double source2[4]={0.7, 0.8, 0.1, 200};

/** Initialize the data all to 0 except for the left border (XX==0) initialized to 1 million
* \param[out] dat the local data to initialize
*/
void init(double dat[dsize[0]][dsize[1]])
{
for (int yy=0; yy<dsize[0]; ++yy) for (int xx=0; xx<dsize[1]; ++xx) dat[yy][xx] = 0;
if ( pcoord[1] == 0 ) for (int yy=0; yy<dsize[0]; ++yy) dat[yy][0] = 1000000;
double dy = L / ((dsize[0]-2) *psize[0]) ;
double dx = L / ((dsize[1]-2) *psize[1]) ;

double cpos_x,cpos_y;
for(int yy=0; yy<dsize[0];++yy) {
cpos_y=(yy+pcoord[0]*(dsize[0]-2))*dy-0.5*dy;
for(int xx=0; xx<dsize[1];++xx) {
cpos_x=(xx+pcoord[1]*(dsize[1]-2))*dx-0.5*dx;
if((cpos_y-source1[0])*(cpos_y-source1[0]) + (cpos_x-source1[1])*(cpos_x-source1[1]) <= source1[2]*source1[2]) {
dat[yy][xx] = source1[3];
}
if((cpos_y-source2[0])*(cpos_y-source2[0]) + (cpos_x-source2[1])*(cpos_x-source2[1]) <= source2[2]*source2[2]) {
dat[yy][xx] = source2[3];
}
}
}
}

/** Compute the values at the next time-step based on the values at the current time-step
Expand All @@ -58,21 +78,15 @@ void init(double dat[dsize[0]][dsize[1]])
void iter(double cur[dsize[0]][dsize[1]], double next[dsize[0]][dsize[1]])
{
int xx, yy;
for (xx=0; xx<dsize[1]; ++xx) next[0][xx] = cur[0][xx];
for (yy=1; yy<dsize[0]-1; ++yy) {
next[yy][0] = cur[yy][0];
for (xx=1; xx<dsize[1]-1; ++xx) {
next[yy][xx] =
(1.-4.*alpha) * cur[yy][xx]
+ alpha * ( cur[yy][xx-1]
+ cur[yy][xx+1]
+ cur[yy-1][xx]
+ cur[yy+1][xx]
);
next[yy][xx] = (1.-4.*alpha) * cur[yy][xx]
+alpha * ( cur[yy][xx-1]
+ cur[yy][xx+1]
+ cur[yy-1][xx]
+ cur[yy+1][xx]);
}
next[yy][dsize[1]-1] = cur[yy][dsize[1]-1];
}
for (xx=0; xx<dsize[1]; ++xx) next[dsize[0]-1][xx] = cur[dsize[0]-1][xx];
}

/** Exchanges ghost values with neighbours
Expand Down Expand Up @@ -138,8 +152,9 @@ int main( int argc, char* argv[] )
// load the alpha parameter
PC_double(PC_get(conf, ".alpha"), &alpha);

int global_size[2]={12,12};
// load the global data-size
int global_size[2];
// you can use paraconf to read some parameters from the yml config file
PC_int(PC_get(conf, ".global_size.height"), &longval); global_size[0] = longval;
PC_int(PC_get(conf, ".global_size.width"), &longval); global_size[1] = longval;

Expand All @@ -157,7 +172,7 @@ int main( int argc, char* argv[] )
dsize[1] = global_size[1]/psize[1] + 2;

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

Expand All @@ -173,6 +188,7 @@ int main( int argc, char* argv[] )

// the main loop
for (; ii<10; ++ii) {

// compute the values for the next iteration
iter(cur, next);

Expand Down
2 changes: 1 addition & 1 deletion ex1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ alpha: 0.125
# global data-size (excluding spacer for boundary conditions or ghosts)
global_size: { height: 60, width: 12 }
# degree of parallelism (number of blocks in each dimension)
parallelism: { height: 1, width: 1 }
parallelism: { height: 1, width: 1 }
61 changes: 37 additions & 24 deletions ex2.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include <time.h>

#include <paraconf.h>
// load the PDI header
#include <pdi.h>

/// size of the local data as [HEIGHT, WIDTH] including ghosts & boundary constants
Expand All @@ -44,13 +43,32 @@ int pcoord[2];
/// the alpha coefficient used in the computation
double alpha;

double L=1.0;
double source1[4]={0.4, 0.4, 0.2, 100};
double source2[4]={0.7, 0.8, 0.1, 200};

/** Initialize the data all to 0 except for the left border (XX==0) initialized to 1 million
* \param[out] dat the local data to initialize
*/
void init(double dat[dsize[0]][dsize[1]])
{
for (int yy=0; yy<dsize[0]; ++yy) for (int xx=0; xx<dsize[1]; ++xx) dat[yy][xx] = 0;
if ( pcoord[1] == 0 ) for (int yy=0; yy<dsize[0]; ++yy) dat[yy][0] = 1000000;
double dy = L / ((dsize[0]-2) *psize[0]) ;
double dx = L / ((dsize[1]-2) *psize[1]) ;

double cpos_x,cpos_y;
for(int yy=0; yy<dsize[0];++yy) {
cpos_y=(yy+pcoord[0]*(dsize[0]-2))*dy-0.5*dy;
for(int xx=0; xx<dsize[1];++xx) {
cpos_x=(xx+pcoord[1]*(dsize[1]-2))*dx-0.5*dx;
if((cpos_y-source1[0])*(cpos_y-source1[0]) + (cpos_x-source1[1])*(cpos_x-source1[1]) <= source1[2]*source1[2]) {
dat[yy][xx] = source1[3];
}
if((cpos_y-source2[0])*(cpos_y-source2[0]) + (cpos_x-source2[1])*(cpos_x-source2[1]) <= source2[2]*source2[2]) {
dat[yy][xx] = source2[3];
}
}
}
}

/** Compute the values at the next time-step based on the values at the current time-step
Expand All @@ -60,21 +78,15 @@ void init(double dat[dsize[0]][dsize[1]])
void iter(double cur[dsize[0]][dsize[1]], double next[dsize[0]][dsize[1]])
{
int xx, yy;
for (xx=0; xx<dsize[1]; ++xx) next[0][xx] = cur[0][xx];
for (yy=1; yy<dsize[0]-1; ++yy) {
next[yy][0] = cur[yy][0];
for (xx=1; xx<dsize[1]-1; ++xx) {
next[yy][xx] =
(1.-4.*alpha) * cur[yy][xx]
+ alpha * ( cur[yy][xx-1]
+ cur[yy][xx+1]
+ cur[yy-1][xx]
+ cur[yy+1][xx]
);
next[yy][xx] = (1.-4.*alpha) * cur[yy][xx]
+alpha * ( cur[yy][xx-1]
+ cur[yy][xx+1]
+ cur[yy-1][xx]
+ cur[yy+1][xx]);
}
next[yy][dsize[1]-1] = cur[yy][dsize[1]-1];
}
for (xx=0; xx<dsize[1]; ++xx) next[dsize[0]-1][xx] = cur[dsize[0]-1][xx];
}

/** Exchanges ghost values with neighbours
Expand Down Expand Up @@ -162,7 +174,7 @@ int main( int argc, char* argv[] )
dsize[1] = global_size[1]/psize[1] + 2;

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

Expand All @@ -176,15 +188,17 @@ int main( int argc, char* argv[] )
// our loop counter so as to be able to use it outside the loop
int ii=0;

// share useful configuration bits with PDI
PDI_share("ii", &ii, PDI_OUT);
PDI_reclaim("ii");
//*** share useful configuration bits with PDI
//*** pcoord, psize, dsize
//...

// the main loop
for (; ii<10; ++ii) {
// share the loop counter at each iteration
PDI_share("ii", &ii, PDI_OUT);
PDI_reclaim("ii");
//*** share the loop counter at each iteration
//...

//*** share the main field: cur
//...

// compute the values for the next iteration
iter(cur, next);
Expand All @@ -195,9 +209,8 @@ int main( int argc, char* argv[] )
// swap the current and next values
double (*tmp)[dsize[1]] = cur; cur = next; next = tmp;
}
// finally share the main field after the main loop body
PDI_share("main_field", cur, PDI_OUT);
PDI_reclaim("main_field");
//*** finally share the main field after the main loop body
//...

// finalize PDI
PDI_finalize();
Expand Down
28 changes: 26 additions & 2 deletions ex2.log
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
[PDI][Trace-plugin] *** info: Welcome!
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: pcoord
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: pcoord
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: dsize
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: dsize
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: psize
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: psize
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: ii
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: ii
[PDI][Trace-plugin] *** info: =>> data becoming available in the store: main_field
[PDI][Trace-plugin] *** info: <<= data stop being available in the store: main_field
[PDI][Trace-plugin] *** info: Goodbye!
7 changes: 3 additions & 4 deletions ex2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ alpha: 0.125
global_size: { height: 60, width: 12 }
# degree of parallelism (number of blocks in each dimension)
parallelism: { height: 1, width: 1 }
# PDI configuration

pdi:
plugins:
trace:
logging: { pattern: '[PDI][%n-plugin] *** %l: %v' }
#*** PDI configuration: use the trace plugin to print all the PDI activities
#...
2 changes: 1 addition & 1 deletion solutions/ex1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ alpha: 0.125
# global data-size (excluding spacer for boundary conditions or ghosts)
global_size: { height: 60, width: 12 }
# degree of parallelism (number of blocks in each dimension)
parallelism: { height: 2, width: 2 }
parallelism: { height: 2, width: 2 }
Loading

0 comments on commit f5bab60

Please sign in to comment.