Skip to content

Commit 815f99a

Browse files
ChristosTandrewcombsax3l
authored
Catalyst2 support (#5155)
* Added Catalyst support - Created a parent FlushFormat for Catalyst and Ascent - Added Catalyst documentation - Fixed documentation mistake - Added mesh (electrostatic sphere) and particle (ioniaztion) examples - Fixed Catalyst particle striding error * FlushFormatCatalyst merge fixes * FlushFormatCatalyst: Support compiling without conduit * FlushFormatInSitu fix warnings * cmake: Add WarpX_CATALYST option Created based on the logic of WarpX_ASCENT * ci: Add catalyst job to test WarpX integration * ci: fix style job - Update wrongFileNameInExamples script to support catalyst scripts to satisfy "Proper file names in Examples" task - move catalyst-specific options to insitu.yaml instead of separate input file to satisfy "Examples are tested" task * ci: constrain OMP threads in insitu Avoids oversubscription in GH runners see #5155 (comment) * docs: Fix spacing in documentation * catalyst: update compatibility version * ci: disable ruff F403 warning for catalyst scripts Using paraview.simple as such in a catalyst script is a common practice * docs: use anonymous links * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Docs: Catalyst in TOC Include in TOC to ensure docs get rendered. --------- Co-authored-by: Andrew Combs <andrew.combs@kitware.com> Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
1 parent cd02d4b commit 815f99a

22 files changed

+1301
-66
lines changed

.github/workflows/insitu.yml

+55
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ jobs:
1717
CXXFLAGS: "-Werror -Wshadow -Woverloaded-virtual -Wunreachable-code -Wno-error=pass-failed"
1818
CMAKE_GENERATOR: Ninja
1919
CMAKE_PREFIX_PATH: /root/install/sensei/v4.0.0/lib64/cmake
20+
OMP_NUM_THREADS: 1
2021
container:
2122
image: senseiinsitu/ci:fedora35-amrex-20220613
2223
steps:
@@ -38,6 +39,7 @@ jobs:
3839
CXX: g++
3940
CC: gcc
4041
CMAKE_PREFIX_PATH: /ascent/install/lib/cmake/
42+
OMP_NUM_THREADS: 1
4143
container:
4244
image: alpinedav/ascent:0.9.2
4345
steps:
@@ -68,3 +70,56 @@ jobs:
6870
*.png
6971
conduit_*
7072
if-no-files-found: error
73+
74+
catalyst:
75+
name: Catalyst
76+
runs-on: ubuntu-20.04
77+
if: github.event.pull_request.draft == false
78+
env:
79+
CXX: g++
80+
CC: gcc
81+
CMAKE_PREFIX_PATH: "/opt/conduit:/opt/catalyst"
82+
CATALYST_DEBUG: 1
83+
CATALYST_IMPLEMENTATION_PATHS: /opt/paraview/lib/catalyst
84+
OMP_NUM_THREADS: 1
85+
86+
container:
87+
image: kitware/paraview:ci-catalyst-amrex-warpx-20240701
88+
steps:
89+
- uses: actions/checkout@v4
90+
- name: Configure
91+
run: |
92+
cmake -S . -B build \
93+
-DWarpX_DIMS="2;3" \
94+
-DWarpX_CATALYST=ON
95+
- name: Build
96+
run: |
97+
cmake --build build -j 10
98+
- name: 2D Test
99+
run: |
100+
cp Examples/Tests/ionization/inputs_2d_rt .
101+
cp Examples/Tests/ionization/catalyst_pipeline.py .
102+
mpiexec -n 2 ./build/bin/warpx.2d \
103+
inputs_2d_rt \
104+
catalyst.script_paths = catalyst_pipeline.py\
105+
catalyst.implementation = paraview\
106+
diag1.intervals = 16\
107+
diag1.species = "electrons ions"\
108+
diag1.format = catalyst
109+
- name: 3D Test
110+
run: |
111+
cp Examples/Tests/electrostatic_sphere/inputs_3d .
112+
cp Examples/Tests/electrostatic_sphere/catalyst_pipeline.py .
113+
mpiexec -n 2 ./build/bin/warpx.3d \
114+
inputs_3d \
115+
catalyst.script_paths = catalyst_pipeline.py \
116+
catalyst.implementation = paraview \
117+
diagnostics.diags_names = diag1 \
118+
diag1.format = catalyst\
119+
diag1.intervals = 3
120+
- uses: actions/upload-artifact@v4
121+
with:
122+
name: catalyst-test-artifacts
123+
path: |
124+
datasets/*.png
125+
if-no-files-found: error

.github/workflows/source/wrongFileNameInExamples

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ do
1717
if [[ ${file:0:6 } != inputs ]] &&
1818
[[ ${file:0:12} != PICMI_inputs ]] &&
1919
[[ ${file:0:8 } != analysis ]] &&
20+
[[ ${file:0:8 } != catalyst ]] &&
2021
[[ ${file: -4} != yaml ]] &&
2122
[[ ${file:0:4 } != plot ]] &&
2223
[[ ${file:0:6 } != README ]]

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ set_default_install_dirs()
7474
include(CMakeDependentOption)
7575
option(WarpX_APP "Build the WarpX executable application" ON)
7676
option(WarpX_ASCENT "Ascent in situ diagnostics" OFF)
77+
option(WarpX_CATALYST "Catalyst in situ diagnostics" OFF)
7778
option(WarpX_EB "Embedded boundary support" OFF)
7879
option(WarpX_LIB "Build WarpX as a library" OFF)
7980
option(WarpX_MPI "Multi-node support (message-passing)" ON)

Docs/source/dataanalysis/catalyst.rst

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
.. _visualization-catalyst:
2+
3+
In situ Visualization with Catalyst 2
4+
=====================================
5+
Catalyst 2 (further referred to as just Catalyst) is a lightweight in-situ visualization and analysis framework API developed for simulations and other scientific data producers. It has a lightweight implementation
6+
(or **stub**) and an SDK to develop custom implementations of Catalyst. ParaView comes with its own implementation (known as **ParaView Catalyst**) for leveraging ParaView's
7+
visualization and analysis capabilities, which is what this document will focus on.
8+
9+
10+
Enabling Catalyst
11+
-----------------
12+
In order to use Catalyst with WarpX, you must `build Catalyst 2 <https://catalyst-in-situ.readthedocs.io/en/latest/build_and_install.html>`_ and `build <https://github.com/Kitware/ParaView/blob/master/Documentation/dev/build.md>`__ or `install <https://www.paraview.org/download/>`__ ParaView 5.9+. Afterward, AMReX must be built with ``AMReX_CONDUIT=TRUE``,
13+
``AMReX_CATALYST=TRUE``, ``Conduit_DIR=/path/to/conduit``, and ``Catalyst_DIR=/path/to/catalyst`` (``/path/to/catalyst`` should be the directory containing ``catalyst-config.cmake``, not the path to the implementation).
14+
15+
Once AMReX is appropriately built, WarpX can be built with the following options:
16+
17+
.. code-block:: cmake
18+
19+
WarpX_amrex_internal=FALSE
20+
AMReX_DIR="/path/to/amrex/build"
21+
22+
If they cannot be found, ``Conduit_DIR`` and ``Catalyst_DIR`` will have to be set again. Ensure that AMReX is built with all required options, some common ones being:
23+
24+
.. code-block:: cmake
25+
26+
AMReX_MPI=TRUE
27+
AMReX_MPI_THREAD_MULTIPLE=TRUE
28+
AMReX_LINEAR_SOLVERS=TRUE
29+
AMReX_PARTICLES=TRUE
30+
AMReX_PARTICLES_PRECISION=DOUBLE
31+
AMReX_PIC=TRUE
32+
AMReX_TINY_PROFILE=TRUE
33+
34+
35+
Inputs File Configuration
36+
-------------------------
37+
Once WarpX has been compiled with Catalyst support, it will need to be enabled and configured at runtime.
38+
This is done using our usual inputs file (read with ``amrex::ParmParse``).
39+
The supported parameters are part of the :ref:`FullDiagnostics <running-cpp-parameters-diagnostics>` with ``<diag_name>.format`` parameter set to ``catalyst``.
40+
41+
In addition to configuring the diagnostics, the following parameters must be included:
42+
* ``catalyst.script_paths``: The locations of the pipeline scripts, separated by either a colon or semicolon (e.g. ``/path/to/script1.py;/path/to/script2.py``).
43+
* ``catalyst.implementation`` (default ``paraview``): The name of the implementation being used (case sensitive).
44+
* ``catalyst.implementation_search_paths``: The locations to search for the given implementation. The specific file being searched for will be ``catalyst_{implementation}.so``.
45+
46+
Because the scripts and implementations are global, Catalyst does not benefit from nor differentiate between multiple diagnostics.
47+
48+
49+
Visualization/Analysis Pipeline Configuration
50+
---------------------------------------------
51+
Catalyst uses the files specified in ``catalyst.script_paths`` to run all analysis.
52+
53+
The following script, :code:`simple_catalyst_pipeline.py`, automatically detects the type of data for both the mesh and particles, then creates an extractor for them. In most
54+
cases, these will be saved as ``.VTPC`` files which can be read with the ``XML Partitioned Dataset Collection Reader``.
55+
56+
.. code-block:: python
57+
58+
from paraview.simple import *
59+
from paraview import catalyst
60+
61+
# Helper function
62+
def create_extractor(data_node, filename="Dataset"):
63+
VTK_TYPES = ["vtkImageData", "vtkRectilinearGrid", "vtkStructuredGrid", "vtkPolyData", "vtkUnstructuredGrid", "vtkUniformGridAMR", "vtkMultiBlockDataSet", "vtkPartitionedDataSet", "vtkPartitionedDataSetCollection", "vtkHyperTreeGrid"]
64+
FILE_ASSOCIATIONS = ["VTI", "VTR", "VTS", "VTP", "VTU", "VTH", "VTM", "VTPD", "VTPC", "HTG"]
65+
clientside_data = data_node.GetClientSideObject().GetOutputDataObject(0) # Gets the dataobject from the default output port
66+
67+
# Loop is required because .IsA() detects valid classes that inherit from the VTK_TYPES
68+
for i, vtk_type in enumerate(VTK_TYPES):
69+
if (clientside_data.IsA(vtk_type)):
70+
filetype = FILE_ASSOCIATIONS[i]
71+
extractor = CreateExtractor(filetype, data_node, registrationName=f"_{filetype}")
72+
extractor.Writer.FileName = filename + "_{timestep:}" + f".{filetype}"
73+
return extractor
74+
75+
raise RuntimeError(f"Unsupported data type: {clientside_data.GetClassName()}")
76+
77+
# Camera settings
78+
paraview.simple._DisableFirstRenderCameraReset() # Prevents the camera from being shown
79+
80+
# Options
81+
options = catalyst.Options()
82+
83+
options.CatalystLiveTrigger = "TimeStep" # "Python", "TimeStep", "TimeValue"
84+
options.EnableCatalystLive = 0 # 0 (disabled), 1 (enabled)
85+
if (options.EnableCatalystLive == 1):
86+
options.CatalystLiveURL = "localhost:22222" # localhost:22222 is default
87+
88+
options.ExtractsOutputDirectory = "datasets" # Base for where all files are saved
89+
options.GenerateCinemaSpecification = 0 # 0 (disabled), 1 (enabled), generates additional descriptor files for cinema exports
90+
options.GlobalTrigger = "TimeStep" # "Python", "TimeStep", "TimeValue"
91+
92+
meshSource = PVTrivialProducer(registrationName="mesh") # "mesh" is the node where the mesh data is stored
93+
create_extractor(meshSource, filename="meshdata")
94+
particleSource = PVTrivialProducer(registrationName="particles") # "particles" is the node where particle data is stored
95+
create_extractor(particleSource, filename="particledata")
96+
97+
# Called on catalyst initialize (after Cxx side initialize)
98+
def catalyst_initialize():
99+
return
100+
101+
# Called on catalyst execute (after Cxx side update)
102+
def catalyst_execute(info):
103+
print(f"Time: {info.time}, Timestep: {info.timestep}, Cycle: {info.cycle}")
104+
return
105+
106+
# Callback if global trigger is set to "Python"
107+
def is_activated(controller):
108+
return True
109+
110+
# Called on catalyst finalize (after Cxx side finalize)
111+
def catalyst_finalize():
112+
return
113+
114+
if __name__ == '__main__':
115+
paraview.simple.SaveExtractsUsingCatalystOptions(options)
116+
117+
118+
For the case of ParaView Catalyst, pipelines are run with ParaView's included ``pvbatch`` executable and use the ``paraview`` library to modify the data. While pipeline scripts
119+
could be written manually, this is not advised for anything beyond the script above. It is much more practical to use ParaView's built in ``Save Catalyst State`` button.
120+
121+
The process for creating a pipeline is as follows:
122+
1. Run at least one step of simulation and save the data in a ParaView compatible format, then open it in ParaView.
123+
2. Set up the desired scene, including filters, camera and views, and extractors.
124+
3. Press ``Save Catalyst State``, or the multicolored flask icon in the top left corner, and save it to a desired location.
125+
4. Open the script and replace the used producer with ``PVTrivialProducer``, setting the ``registrationName`` to either ``mesh`` or ``particles`` based on what data is used.
126+
127+
As an example for step four, here are a few lines from a script directly exported from ParaView:
128+
129+
.. code-block:: python
130+
131+
# create a new 'XML Image Data Reader'
132+
meshdatavti = XMLImageDataReader(registrationName='meshdata.vti', FileName=['/path/to/meshdata.vti'])
133+
meshdatavti.CellArrayStatus = ['Bx', 'By', 'Bz', 'Ex', 'Ey', 'Ez']
134+
meshdatavti.TimeArray = 'None'
135+
136+
# Calculator sample filter
137+
calculator1 = Calculator(registrationName='Calculator1', Input=meshdatavti)
138+
calculator1.AttributeType = 'Cell Data'
139+
calculator1.ResultArrayName = 'BField'
140+
calculator1.Function = 'sqrt(Bx^2 + By^2 + Bz^2)'
141+
142+
In order to use it with the mesh data coming from the simulation, the above code would be changed to:
143+
144+
.. code-block:: python
145+
146+
# create the producer
147+
meshdata = PVTrivialProducer(registrationName='mesh')
148+
meshdata.CellArrayStatus = ['Bx', 'By', 'Bz', 'Ex', 'Ey', 'Ez']
149+
meshdata.TimeArray = 'None'
150+
151+
# Calculator sample filter
152+
calculator1 = Calculator(registrationName='Calculator1', Input=meshdata)
153+
calculator1.AttributeType = 'Cell Data'
154+
calculator1.ResultArrayName = 'BField'
155+
calculator1.Function = 'sqrt(Bx^2 + By^2 + Bz^2)'
156+
157+
Steps one is advised so that proper scaling and framing can be done, however in certain cases it may not be possible. If this is the case, a dummy object can be used instead
158+
(such as a wavelet or geometric shape scaled appropriately) and the rest of the steps can be followed as usual.
159+
160+
Replay
161+
------
162+
163+
Catalyst 2 supports replay capabilities, which can be read about `here <https://catalyst-in-situ.readthedocs.io/en/latest/catalyst_replay.html>`_.
164+
165+
.. note::
166+
167+
* TODO: Add more extensive documentation on replay

Docs/source/dataanalysis/formats.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ files to disk).
4141
.. toctree::
4242
:maxdepth: 1
4343

44-
sensei
4544
ascent
45+
catalyst
46+
sensei
4647

4748
If you like the 3D rendering of laser wakefield acceleration
4849
on the WarpX documentation front page (which is

Docs/source/dataanalysis/paraview.rst

+6
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,9 @@ Plotfiles (AMReX)
5454

5555
ParaView also supports visualizing AMReX plotfiles.
5656
Please see `the AMReX documentation <https://amrex-codes.github.io/amrex/docs_html/Visualization.html#paraview>`__ for more details.
57+
58+
59+
In Situ Analysis with Catalyst 2
60+
--------------------------------
61+
62+
Continue reading :ref:`here <visualization-catalyst>`.

Docs/source/install/cmake.rst

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ CMake Option Default & Values Descr
8585
``CMAKE_VERBOSE_MAKEFILE`` ON/**OFF** `Print all compiler commands to the terminal during build <https://cmake.org/cmake/help/latest/variable/CMAKE_VERBOSE_MAKEFILE.html>`__
8686
``WarpX_APP`` **ON**/OFF Build the WarpX executable application
8787
``WarpX_ASCENT`` ON/**OFF** Ascent in situ visualization
88+
``WarpX_CATALYST`` ON/**OFF** Catalyst in situ visualization
8889
``WarpX_COMPUTE`` NOACC/**OMP**/CUDA/SYCL/HIP On-node, accelerated computing backend
8990
``WarpX_DIMS`` **3**/2/1/RZ Simulation dimensionality. Use ``"1;2;RZ;3"`` for all.
9091
``WarpX_EB`` ON/**OFF** Embedded boundary support (not supported in RZ yet)

0 commit comments

Comments
 (0)