-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #164 from eve-le-guillou/mpiExample
[MPI] Add example of use for MPI
- Loading branch information
Showing
4 changed files
with
14,304 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# MPI Example | ||
|
||
![MPI example Image](https://topology-tool-kit.github.io/img/gallery/mpiExample.jpg) | ||
|
||
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. | ||
|
||
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). | ||
|
||
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`). | ||
|
||
## Pipeline description | ||
|
||
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. | ||
|
||
First, the magnitude of the scalar field is computed and the data set is resampled to $256^3$. This dimension can be changed | ||
(see the corresponding [Python script below](#python-code)). | ||
|
||
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). | ||
|
||
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). | ||
|
||
Next, the geometry of the integral lines is smoothed using the [GeometrySmoother](https://topology-tool-kit.github.io/doc/html/classttkGeometrySmoother.html). | ||
|
||
Finally, the critical points of the magnitude are computed on the smoothed geometry of the integral lines. | ||
|
||
## ParaView | ||
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: | ||
|
||
``` bash | ||
OMP_NUM_THREADS=2 mpirun -n 4 pvserver | ||
``` | ||
In another command line enter the following command: | ||
``` bash | ||
paraview | ||
``` | ||
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`. | ||
|
||
|
||
## Python code | ||
|
||
``` python linenums="1" | ||
--8<-- "python/mpiExample.py" | ||
``` | ||
|
||
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: | ||
``` bash | ||
OMP_NUM_THREADS=2 mpirun -n 4 pvbatch python/mpiExample.py | ||
``` | ||
|
||
By default, the dataset is resampled to $256^3$. To resample to a higher dimension, for example $2048^3$, enter the following command: | ||
|
||
```bash | ||
OMP_NUM_THREADS=2 mpirun -n 4 pvbatch python/mpiExample.py 2048 | ||
``` | ||
Be aware that this will require a lot of memory to execute and will most likely not be possible on a regular laptop. | ||
|
||
|
||
|
||
## Inputs | ||
- [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. | ||
|
||
## Outputs | ||
- `integralLines.pvtu`: the geometry of the smoothed integral lines capturing the covalent and hydrogen bonds of the molecule, as extracted by the analysis pipeline. | ||
- `criticalPoints.pvtp`: the critical points computed on the geometry of the integral lines, showing the rapid changes in the bonds. | ||
|
||
## C++/Python API | ||
|
||
[ArrayPreconditioning](https://topology-tool-kit.github.io/doc/html/classttkArrayPreconditioning.html) | ||
|
||
[GeometrySmoother](https://topology-tool-kit.github.io/doc/html/classttkGeometrySmoother.html) | ||
|
||
[IntegralLines](https://topology-tool-kit.github.io/doc/html/classttkIntegralLines.html) | ||
|
||
[PointDataSelector](https://topology-tool-kit.github.io/doc/html/classttkPointDataSelector.html) | ||
|
||
[ScalarFieldCriticalPoints](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldCriticalPoints.html) | ||
|
||
[ScalarFieldNormalizer](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldNormalizer.html) | ||
|
||
[ScalarFieldSmoother](https://topology-tool-kit.github.io/doc/html/classttkScalarFieldSmoother.html) | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#### import the simple module from the paraview | ||
from paraview.simple import * | ||
|
||
# ---------------------------------------------------------------- | ||
# Choose the resampling dimension for the example | ||
# ---------------------------------------------------------------- | ||
|
||
if len(sys.argv) == 2: | ||
dim = int(sys.argv[1]) | ||
else: | ||
dim = 256 | ||
|
||
# create a new 'XML Image Data Reader' | ||
atvti = XMLImageDataReader(FileName=["at.vti"]) | ||
atvti.PointArrayStatus = ["density"] | ||
|
||
calculator1 = Calculator(Input=atvti) | ||
calculator1.ResultArrayType = "Float" | ||
calculator1.ResultArrayName = "density" | ||
calculator1.Function = "density" | ||
|
||
# create a new 'Compute Derivatives' | ||
computeDerivatives1 = ComputeDerivatives(Input=calculator1) | ||
computeDerivatives1.Scalars = ["POINTS", "density"] | ||
computeDerivatives1.Vectors = ["POINTS", "1"] | ||
|
||
# create a new 'Calculator' | ||
calculator2 = Calculator(Input=computeDerivatives1) | ||
calculator2.AttributeType = "Cell Data" | ||
calculator2.ResultArrayName = "gradientMagnitude" | ||
calculator2.Function = "mag(ScalarGradient)" | ||
calculator2.ResultArrayType = "Float" | ||
|
||
|
||
# create a new 'Cell Data to Point Data' | ||
cellDatatoPointData1 = CellDatatoPointData(Input=calculator2) | ||
cellDatatoPointData1.CellDataArraytoprocess = ["gradientMagnitude"] | ||
|
||
# create a new 'TTK PointDataSelector' | ||
tTKPointDataSelector1 = TTKPointDataSelector(Input=cellDatatoPointData1) | ||
tTKPointDataSelector1.ScalarFields = ["density", "gradientMagnitude"] | ||
tTKPointDataSelector1.RangeId = [0, 2] | ||
|
||
# create a new 'Cell Data to Point Data' | ||
cellDatatoPointData2 = CellDatatoPointData(Input=tTKPointDataSelector1) | ||
cellDatatoPointData2.CellDataArraytoprocess = ["ScalarGradient", "gradientMagnitude"] | ||
|
||
# create a new 'Resample To Image' | ||
resampleToImage1 = ResampleToImage(Input=cellDatatoPointData2) | ||
resampleToImage1.SamplingDimensions = [dim, dim, dim] | ||
resampleToImage1.SamplingBounds = [0.0, 176.0, 0.0, 94.0, 0.0, 47.0] | ||
|
||
# create a new 'TTK ScalarFieldSmoother' | ||
tTKScalarFieldSmoother1 = TTKScalarFieldSmoother(Input=resampleToImage1) | ||
tTKScalarFieldSmoother1.ScalarField = ["POINTS", "density"] | ||
tTKScalarFieldSmoother1.IterationNumber = 1 | ||
|
||
# create a new 'TTK ScalarFieldSmoother' | ||
tTKScalarFieldSmoother2 = TTKScalarFieldSmoother(Input=tTKScalarFieldSmoother1) | ||
tTKScalarFieldSmoother2.ScalarField = ["POINTS", "gradientMagnitude"] | ||
tTKScalarFieldSmoother2.IterationNumber = 10 | ||
|
||
# create a new 'TTK ScalarFieldNormalizer' | ||
tTKScalarFieldNormalizer2 = TTKScalarFieldNormalizer(Input=tTKScalarFieldSmoother2) | ||
tTKScalarFieldNormalizer2.ScalarField = ["POINTS", "density"] | ||
|
||
# create a new 'TTK ArrayPreconditioning' | ||
tTKArrayPreconditioning1 = TTKArrayPreconditioning(Input=tTKScalarFieldNormalizer2) | ||
tTKArrayPreconditioning1.PointDataArrays = ["density"] | ||
|
||
# create a new 'TTK ScalarFieldCriticalPoints' | ||
tTKScalarFieldCriticalPoints2 = TTKScalarFieldCriticalPoints( | ||
Input=tTKArrayPreconditioning1 | ||
) | ||
tTKScalarFieldCriticalPoints2.ScalarField = ["POINTS", "density"] | ||
tTKScalarFieldCriticalPoints2.Backend = "Default generic backend" | ||
|
||
# create a new 'Mask Points' | ||
maskPoints2 = MaskPoints(Input=tTKScalarFieldCriticalPoints2) | ||
maskPoints2.OnRatio = 1 | ||
maskPoints2.MaximumNumberofPoints = 99999999 | ||
maskPoints2.ProportionallyDistributeMaximumNumberOfPoints = 1 | ||
maskPoints2.RandomSampling = 1 | ||
maskPoints2.RandomSamplingMode = "Random Sampling" | ||
maskPoints2.GenerateVertices = 1 | ||
maskPoints2.SingleVertexPerCell = 1 | ||
|
||
# create a new 'Threshold' | ||
threshold1 = Threshold(Input=maskPoints2) | ||
threshold1.Scalars = ["POINTS", "CriticalType"] | ||
threshold1.LowerThreshold = 1.0 | ||
threshold1.UpperThreshold = 1.0 | ||
|
||
# create a new 'Threshold' | ||
threshold4 = Threshold(Input=threshold1) | ||
threshold4.Scalars = ["POINTS", "IsOnBoundary"] | ||
|
||
# create a new 'TTK IntegralLines' | ||
tTKIntegralLines1 = TTKIntegralLines(Domain=tTKArrayPreconditioning1, Seeds=threshold4) | ||
tTKIntegralLines1.ScalarField = ["POINTS", "density"] | ||
tTKIntegralLines1.Direction = "Backward" | ||
tTKIntegralLines1.Vertexidentifierfield = ["POINTS", "CriticalType"] | ||
tTKIntegralLines1.EnableForking = 1 | ||
|
||
# create a new 'Clean to Grid' | ||
cleantoGrid1 = CleantoGrid(Input=tTKIntegralLines1) | ||
|
||
# create a new 'TTK GeometrySmoother' | ||
tTKGeometrySmoother2 = TTKGeometrySmoother(Input=cleantoGrid1) | ||
tTKGeometrySmoother2.IterationNumber = 200 | ||
|
||
# create a new 'Resample With Dataset' | ||
resampleWithDataset1 = ResampleWithDataset( | ||
SourceDataArrays=cellDatatoPointData1, DestinationMesh=tTKGeometrySmoother2 | ||
) | ||
resampleWithDataset1.CellLocator = "Static Cell Locator" | ||
resampleWithDataset1.PassCellArrays = 1 | ||
resampleWithDataset1.PassPointArrays = 1 | ||
|
||
# create a new 'TTK ScalarFieldCriticalPoints' | ||
tTKScalarFieldCriticalPoints1 = TTKScalarFieldCriticalPoints(Input=resampleWithDataset1) | ||
tTKScalarFieldCriticalPoints1.ScalarField = ["POINTS", "gradientMagnitude"] | ||
tTKScalarFieldCriticalPoints1.Backend = "Default generic backend" | ||
|
||
SaveData("integralLines.pvtu", tTKGeometrySmoother2) | ||
SaveData("criticalPoints.pvtp", tTKScalarFieldCriticalPoints1) |
Oops, something went wrong.