Skip to content

Commit b03bb77

Browse files
Merge pull request #164 from eve-le-guillou/mpiExample
[MPI] Add example of use for MPI
2 parents aa4f967 + 71b01b2 commit b03bb77

File tree

4 files changed

+14304
-0
lines changed

4 files changed

+14304
-0
lines changed

docs/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,5 @@ If you have any questions regarding these examples, please let us know by sendin
115115
| [Manifold checks](manifoldCheck/) | ![ExampleImage](https://topology-tool-kit.github.io/img/gallery/manifoldCheck.jpg) |
116116
| [Cinema IO](cinemaIO/) | <iframe width="100%" height="420" src="https://www.youtube.com/embed/yKyiRzPbs0U" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
117117
| [Compact Triangulation](compactTriangulation/) | <iframe width="100%" height="420" src="https://www.youtube.com/embed/vDQRh_tuUSA" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
118+
| [MPI Example](mpiExample) | ![ExampleImage](https://topology-tool-kit.github.io/img/gallery/mpiExample.jpg) |
119+

docs/mpiExample.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# MPI Example
2+
3+
![MPI example Image](https://topology-tool-kit.github.io/img/gallery/mpiExample.jpg)
4+
5+
This toy example illustrates the usage of TTK in a distributed-memory context with MPI. For this example, the original data set is small. Thus, the pipeline first resamples it to $256^3$ but this dimension can be changed to fit the capabilities of your distributed system.
6+
7+
For more information about how to run a pipeline in parallel in ParaView with MPI, please refer to the [ParaView documentation](https://docs.paraview.org/en/latest/ReferenceManual/parallelDataVisualization.html).
8+
9+
Please note both ParaView and TTK need to be compiled with MPI to allow for parallel execution in a distributed context. For that we refer the reader to the ParaView and TTK installation instructions, but, in short, this can be done by setting the following CMake flags `PARAVIEW_USE_MPI=ON` and `TTK_ENABLE_MPI=ON` for ParaView and TTK respectively. Also, for processing large-scale datasets (typically beyond $1024^3$), we recommend to build TTK with 64 bit identifiers (by setting the CMake flag `TTK_ENABLE_64BIT_IDS=ON`).
10+
11+
## Pipeline description
12+
13+
The produced visualization captures the covalent and hydrogen bonds within the Adenine-Thymine molecular complex. It also shows where the electronic density experiences rapid changes, indicating transition points occurring within the bond.
14+
15+
First, the magnitude of the scalar field is computed and the data set is resampled to $256^3$. This dimension can be changed
16+
(see the corresponding [Python script below](#python-code)).
17+
18+
Then, both the scalar field and its magnitude are smoothed via [ScalarFieldSmoother](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldSmoother.html) and normalized via [ScalarFieldNormalizer](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldNormalizer.html).
19+
20+
Next, the critical points of the scalar field are computed via [ScalarFieldCriticalPoints](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldCriticalPoints.html) and used as seeds of the [IntegralLines](https://topology-tool-kit.github.io/doc/html/classttkIntegralLines.html).
21+
22+
Next, the geometry of the integral lines is smoothed using the [GeometrySmoother](https://topology-tool-kit.github.io/doc/html/classttkGeometrySmoother.html).
23+
24+
Finally, the critical points of the magnitude are computed on the smoothed geometry of the integral lines.
25+
26+
## ParaView
27+
To reproduce the above screenshot on 4 processes and 2 threads, go to your [ttk-data](https://github.com/topology-tool-kit/ttk-data) directory and enter the following command:
28+
29+
``` bash
30+
OMP_NUM_THREADS=2 mpirun -n 4 pvserver
31+
```
32+
In another command line enter the following command:
33+
``` bash
34+
paraview
35+
```
36+
Now, follow the procedure described in paragraph $7.2.2$ of the following [ParaView documentation](https://docs.paraview.org/en/latest/ReferenceManual/parallelDataVisualization.html#configuring-a-server-connection) to connect your ParaView server to your client. Once that is done, you can open the state file `states/mpiExample.pvsm` in the ParaView GUI through `File` > `Load State`.
37+
38+
39+
## Python code
40+
41+
``` python linenums="1"
42+
--8<-- "python/mpiExample.py"
43+
```
44+
45+
To run the above Python script using 2 threads and 4 processes, go to your [ttk-data](https://github.com/topology-tool-kit/ttk-data) directory and enter the following command:
46+
``` bash
47+
OMP_NUM_THREADS=2 mpirun -n 4 pvbatch python/mpiExample.py
48+
```
49+
50+
By default, the dataset is resampled to $256^3$. To resample to a higher dimension, for example $2048^3$, enter the following command:
51+
52+
```bash
53+
OMP_NUM_THREADS=2 mpirun -n 4 pvbatch python/mpiExample.py 2048
54+
```
55+
Be aware that this will require a lot of memory to execute and will most likely not be possible on a regular laptop.
56+
57+
58+
59+
## Inputs
60+
- [at.vti](https://github.com/topology-tool-kit/ttk-data/raw/dev/at.vti): A molecular dataset: a three-dimensional regular grid with one scalar field, the electronic density for the Adenine Thymine complex.
61+
62+
## Outputs
63+
- `integralLines.pvtu`: the geometry of the smoothed integral lines capturing the covalent and hydrogen bonds of the molecule, as extracted by the analysis pipeline.
64+
- `criticalPoints.pvtp`: the critical points computed on the geometry of the integral lines, showing the rapid changes in the bonds.
65+
66+
## C++/Python API
67+
68+
[ArrayPreconditioning](https://topology-tool-kit.github.io/doc/html/classttkArrayPreconditioning.html)
69+
70+
[GeometrySmoother](https://topology-tool-kit.github.io/doc/html/classttkGeometrySmoother.html)
71+
72+
[IntegralLines](https://topology-tool-kit.github.io/doc/html/classttkIntegralLines.html)
73+
74+
[PointDataSelector](https://topology-tool-kit.github.io/doc/html/classttkPointDataSelector.html)
75+
76+
[ScalarFieldCriticalPoints](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldCriticalPoints.html)
77+
78+
[ScalarFieldNormalizer](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldNormalizer.html)
79+
80+
[ScalarFieldSmoother](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldSmoother.html)
81+
82+
83+
84+
85+

python/mpiExample.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#### import the simple module from the paraview
2+
from paraview.simple import *
3+
4+
# ----------------------------------------------------------------
5+
# Choose the resampling dimension for the example
6+
# ----------------------------------------------------------------
7+
8+
if len(sys.argv) == 2:
9+
dim = int(sys.argv[1])
10+
else:
11+
dim = 256
12+
13+
# create a new 'XML Image Data Reader'
14+
atvti = XMLImageDataReader(FileName=["at.vti"])
15+
atvti.PointArrayStatus = ["density"]
16+
17+
calculator1 = Calculator(Input=atvti)
18+
calculator1.ResultArrayType = "Float"
19+
calculator1.ResultArrayName = "density"
20+
calculator1.Function = "density"
21+
22+
# create a new 'Compute Derivatives'
23+
computeDerivatives1 = ComputeDerivatives(Input=calculator1)
24+
computeDerivatives1.Scalars = ["POINTS", "density"]
25+
computeDerivatives1.Vectors = ["POINTS", "1"]
26+
27+
# create a new 'Calculator'
28+
calculator2 = Calculator(Input=computeDerivatives1)
29+
calculator2.AttributeType = "Cell Data"
30+
calculator2.ResultArrayName = "gradientMagnitude"
31+
calculator2.Function = "mag(ScalarGradient)"
32+
calculator2.ResultArrayType = "Float"
33+
34+
35+
# create a new 'Cell Data to Point Data'
36+
cellDatatoPointData1 = CellDatatoPointData(Input=calculator2)
37+
cellDatatoPointData1.CellDataArraytoprocess = ["gradientMagnitude"]
38+
39+
# create a new 'TTK PointDataSelector'
40+
tTKPointDataSelector1 = TTKPointDataSelector(Input=cellDatatoPointData1)
41+
tTKPointDataSelector1.ScalarFields = ["density", "gradientMagnitude"]
42+
tTKPointDataSelector1.RangeId = [0, 2]
43+
44+
# create a new 'Cell Data to Point Data'
45+
cellDatatoPointData2 = CellDatatoPointData(Input=tTKPointDataSelector1)
46+
cellDatatoPointData2.CellDataArraytoprocess = ["ScalarGradient", "gradientMagnitude"]
47+
48+
# create a new 'Resample To Image'
49+
resampleToImage1 = ResampleToImage(Input=cellDatatoPointData2)
50+
resampleToImage1.SamplingDimensions = [dim, dim, dim]
51+
resampleToImage1.SamplingBounds = [0.0, 176.0, 0.0, 94.0, 0.0, 47.0]
52+
53+
# create a new 'TTK ScalarFieldSmoother'
54+
tTKScalarFieldSmoother1 = TTKScalarFieldSmoother(Input=resampleToImage1)
55+
tTKScalarFieldSmoother1.ScalarField = ["POINTS", "density"]
56+
tTKScalarFieldSmoother1.IterationNumber = 1
57+
58+
# create a new 'TTK ScalarFieldSmoother'
59+
tTKScalarFieldSmoother2 = TTKScalarFieldSmoother(Input=tTKScalarFieldSmoother1)
60+
tTKScalarFieldSmoother2.ScalarField = ["POINTS", "gradientMagnitude"]
61+
tTKScalarFieldSmoother2.IterationNumber = 10
62+
63+
# create a new 'TTK ScalarFieldNormalizer'
64+
tTKScalarFieldNormalizer2 = TTKScalarFieldNormalizer(Input=tTKScalarFieldSmoother2)
65+
tTKScalarFieldNormalizer2.ScalarField = ["POINTS", "density"]
66+
67+
# create a new 'TTK ArrayPreconditioning'
68+
tTKArrayPreconditioning1 = TTKArrayPreconditioning(Input=tTKScalarFieldNormalizer2)
69+
tTKArrayPreconditioning1.PointDataArrays = ["density"]
70+
71+
# create a new 'TTK ScalarFieldCriticalPoints'
72+
tTKScalarFieldCriticalPoints2 = TTKScalarFieldCriticalPoints(
73+
Input=tTKArrayPreconditioning1
74+
)
75+
tTKScalarFieldCriticalPoints2.ScalarField = ["POINTS", "density"]
76+
tTKScalarFieldCriticalPoints2.Backend = "Default generic backend"
77+
78+
# create a new 'Mask Points'
79+
maskPoints2 = MaskPoints(Input=tTKScalarFieldCriticalPoints2)
80+
maskPoints2.OnRatio = 1
81+
maskPoints2.MaximumNumberofPoints = 99999999
82+
maskPoints2.ProportionallyDistributeMaximumNumberOfPoints = 1
83+
maskPoints2.RandomSampling = 1
84+
maskPoints2.RandomSamplingMode = "Random Sampling"
85+
maskPoints2.GenerateVertices = 1
86+
maskPoints2.SingleVertexPerCell = 1
87+
88+
# create a new 'Threshold'
89+
threshold1 = Threshold(Input=maskPoints2)
90+
threshold1.Scalars = ["POINTS", "CriticalType"]
91+
threshold1.LowerThreshold = 1.0
92+
threshold1.UpperThreshold = 1.0
93+
94+
# create a new 'Threshold'
95+
threshold4 = Threshold(Input=threshold1)
96+
threshold4.Scalars = ["POINTS", "IsOnBoundary"]
97+
98+
# create a new 'TTK IntegralLines'
99+
tTKIntegralLines1 = TTKIntegralLines(Domain=tTKArrayPreconditioning1, Seeds=threshold4)
100+
tTKIntegralLines1.ScalarField = ["POINTS", "density"]
101+
tTKIntegralLines1.Direction = "Backward"
102+
tTKIntegralLines1.Vertexidentifierfield = ["POINTS", "CriticalType"]
103+
tTKIntegralLines1.EnableForking = 1
104+
105+
# create a new 'Clean to Grid'
106+
cleantoGrid1 = CleantoGrid(Input=tTKIntegralLines1)
107+
108+
# create a new 'TTK GeometrySmoother'
109+
tTKGeometrySmoother2 = TTKGeometrySmoother(Input=cleantoGrid1)
110+
tTKGeometrySmoother2.IterationNumber = 200
111+
112+
# create a new 'Resample With Dataset'
113+
resampleWithDataset1 = ResampleWithDataset(
114+
SourceDataArrays=cellDatatoPointData1, DestinationMesh=tTKGeometrySmoother2
115+
)
116+
resampleWithDataset1.CellLocator = "Static Cell Locator"
117+
resampleWithDataset1.PassCellArrays = 1
118+
resampleWithDataset1.PassPointArrays = 1
119+
120+
# create a new 'TTK ScalarFieldCriticalPoints'
121+
tTKScalarFieldCriticalPoints1 = TTKScalarFieldCriticalPoints(Input=resampleWithDataset1)
122+
tTKScalarFieldCriticalPoints1.ScalarField = ["POINTS", "gradientMagnitude"]
123+
tTKScalarFieldCriticalPoints1.Backend = "Default generic backend"
124+
125+
SaveData("integralLines.pvtu", tTKGeometrySmoother2)
126+
SaveData("criticalPoints.pvtp", tTKScalarFieldCriticalPoints1)

0 commit comments

Comments
 (0)