Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ------------------------------------------------------------------------------
# CMake version requirement
# ------------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.24)
cmake_minimum_required(VERSION 3.26)

# ------------------------------------------------------------------------------
# Policies - use the latest of everything
Expand Down Expand Up @@ -59,6 +59,10 @@ option(IPPL_MARK_FAILING_TESTS
OFF)
option(IPPL_ENABLE_SCRIPTS "Generate job script templates for some benchmarks/tests" OFF)


option(IPPL_ENABLE_CATALYST "Enable ParaView Catalyst" OFF)
set(Catalyst_DIR "" CACHE PATH "Catalyst cmake package directory or install prefix (catalyst_DIR and CATALYST_DIR also accepted)")
set(Catalyst_VERSION "" CACHE STRING "Catalyst version or git.<tag/branch/sha> (default 2.1.0)")
# "Build IPPL as a shared library (ON) or static library (OFF)" OFF) if(IPPL_DYL)
# set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) message(WARNING "IPPL_DYL is deprecated; use
# -DBUILD_SHARED_LIBS=ON instead.") endif()
Expand Down
130 changes: 110 additions & 20 deletions cmake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
# Dependencies.cmake
# ~~~
#
# Resolves third-party libraries: Kokkos and Heffte.
# Resolves third-party libraries: Kokkos, Heffte, and Catalyst.
#
# Responsibilities:
# - Fetch or find Kokkos, using version and backends from Platforms.cmake
# - Fetch Heffte if IPPL_ENABLE_FFT is ON, using CUDA or AVX2 based on platform
# - Fetch or find Catalyst when in-situ support or the FEL demo is enabled
#
# Not responsible for:
# - Selecting platform backends → Platforms.cmake
Expand Down Expand Up @@ -489,6 +490,114 @@ if(IPPL_ENABLE_FINUFFT)
add_compile_definitions(ENABLE_FINUFFT)
endif()

# ------------------------------------------------------------------------------
# Catalyst (libcatalyst SDK and bundled Conduit parser)
# ------------------------------------------------------------------------------
if(IPPL_ENABLE_CATALYST OR IPPL_ENABLE_FEL)
enable_language(C)

if(NOT Catalyst_VERSION)
set(Catalyst_VERSION 2.1.0)
endif()

extract_git_label(Catalyst_VERSION CATALYST_VERSION_GIT)

# Support Catalyst_DIR, catalyst_DIR, CATALYST_DIR (package dir or install prefix)
foreach(_cat_dir_var IN ITEMS Catalyst_DIR catalyst_DIR CATALYST_DIR)
if(DEFINED ${_cat_dir_var} AND ${_cat_dir_var})
if(EXISTS "${${_cat_dir_var}}/catalyst-config.cmake")
set(catalyst_DIR "${${_cat_dir_var}}")
else()
list(APPEND CMAKE_PREFIX_PATH "${${_cat_dir_var}}")
endif()
endif()
endforeach()
unset(_cat_dir_var)

# Do not mistake the package generated by an earlier FetchContent configure
# for a user-provided Catalyst installation on a subsequent configure.
set(_ippl_reuse_fetched_catalyst OFF)
set(_ippl_catalyst_dir_is_in_build_tree OFF)
if(catalyst_DIR)
cmake_path(IS_PREFIX CMAKE_BINARY_DIR "${catalyst_DIR}" NORMALIZE
_ippl_catalyst_dir_is_in_build_tree)
endif()
if(NOT Catalyst_DIR AND NOT CATALYST_DIR
AND (_ippl_catalyst_dir_is_in_build_tree
OR (IPPL_CATALYST_FETCHED AND NOT catalyst_DIR)))
set(_ippl_reuse_fetched_catalyst ON)
unset(catalyst_DIR CACHE)
unset(catalyst_FOUND)
endif()

if(NOT CATALYST_VERSION_GIT AND NOT _ippl_reuse_fetched_catalyst)
find_package(catalyst ${Catalyst_VERSION} CONFIG QUIET)
set(CATALYST_VERSION_GIT "v${Catalyst_VERSION}")
endif()

if(NOT CATALYST_VERSION_GIT)
set(CATALYST_VERSION_GIT "v${Catalyst_VERSION}")
endif()

if(catalyst_FOUND AND NOT _ippl_reuse_fetched_catalyst)
set(IPPL_CATALYST_FETCHED OFF CACHE INTERNAL "Catalyst was fetched by IPPL" FORCE)
set(IPPL_CATALYST_VERSION "${catalyst_VERSION}")
colour_message(STATUS ${Green} "✅ Catalyst ${catalyst_VERSION} found externally")
else()
set(IPPL_CATALYST_FETCHED ON CACHE INTERNAL "Catalyst was fetched by IPPL" FORCE)
colour_message(STATUS ${Green} "✅ Catalyst ${CATALYST_VERSION_GIT} building from source")

set(CATALYST_BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE)
set(CATALYST_BUILD_STUB_IMPLEMENTATION ON CACHE BOOL "" FORCE)
set(CATALYST_BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(CATALYST_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
set(CATALYST_WRAP_PYTHON OFF CACHE BOOL "" FORCE)
set(CATALYST_WRAP_FORTRAN OFF CACHE BOOL "" FORCE)
set(CATALYST_WITH_EXTERNAL_CONDUIT OFF CACHE BOOL "" FORCE)
set(CATALYST_USE_MPI ON CACHE BOOL "" FORCE)

FetchContent_Declare(
catalyst
GIT_REPOSITORY "https://gitlab.kitware.com/paraview/catalyst.git"
GIT_TAG "${CATALYST_VERSION_GIT}"
DOWNLOAD_EXTRACT_TIMESTAMP ON)
FetchContent_MakeAvailable(catalyst)

if(NOT TARGET catalyst::catalyst)
message(FATAL_ERROR "Catalyst FetchContent did not provide catalyst::catalyst")
endif()

file(
STRINGS "${catalyst_SOURCE_DIR}/CMakeLists.txt" _catalyst_project_line
REGEX "^[ \t]*project\\(CATALYST VERSION [0-9]+\\.[0-9]+")
string(REGEX MATCH "VERSION[ \t]+([0-9]+\\.[0-9]+(\\.[0-9]+)?)"
_catalyst_version_match "${_catalyst_project_line}")
if(NOT CMAKE_MATCH_1)
message(FATAL_ERROR "Could not determine the fetched Catalyst project version")
endif()
set(IPPL_CATALYST_VERSION "${CMAKE_MATCH_1}")

unset(_catalyst_project_line)
unset(_catalyst_version_match)
endif()

string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" _catalyst_major_minor
"${IPPL_CATALYST_VERSION}")
if(NOT _catalyst_major_minor)
message(FATAL_ERROR "Could not determine Catalyst's major/minor version")
endif()
set(IPPL_CATALYST_PACKAGE_DIRNAME "catalyst-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}")
if(IPPL_CATALYST_FETCHED)
set(IPPL_CATALYST_BUILD_PACKAGE_DIR
"${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${IPPL_CATALYST_PACKAGE_DIRNAME}")
endif()

set(IPPL_CATALYST_USE_MPI "${CATALYST_USE_MPI}")
unset(_catalyst_major_minor)
unset(_ippl_catalyst_dir_is_in_build_tree)
unset(_ippl_reuse_fetched_catalyst)
endif()

# ------------------------------------------------------------------------------
# GoogleTest
# ------------------------------------------------------------------------------
Expand All @@ -510,22 +619,3 @@ if(IPPL_ENABLE_UNIT_TESTS)
message(STATUS "✅ GoogleTest built from source (${GTest_VERSION})")
endif()
endif()

# ------------------------------------------------------------------------------
# FEL module header-only dependencies (nlohmann/json for config parsing, stb_image_write for the
# Poynting-flux visualization).
# ------------------------------------------------------------------------------
if(IPPL_ENABLE_FEL)
# Fetch the CMake package instead of downloading the release header directly. CMake's
# file(DOWNLOAD) does not fail by default and can leave a zero-byte json.hpp behind when a
# release-asset host is unavailable, which only surfaces later as a confusing compile error.
set(JSON_BuildTests OFF CACHE BOOL "Disable nlohmann/json tests" FORCE)
FetchContent_Declare(
nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.3
GIT_SHALLOW ON)
FetchContent_MakeAvailable(nlohmann_json)

message(STATUS "✅ nlohmann/json loaded for the FEL module.")
endif()
39 changes: 39 additions & 0 deletions cmake/IPPLConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,45 @@ if(@IPPL_ENABLE_FFT@ AND "@Heffte_FOUND@" AND NOT TARGET Heffte::Heffte)
find_dependency(Heffte CONFIG HINTS "${_ipplPrefix}" "@Heffte_DIR@")
endif()

if(@IPPL_ENABLE_CATALYST@)
if("@IPPL_CATALYST_USE_MPI@" AND NOT CMAKE_C_COMPILER_LOADED)
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
"IPPL was built with MPI-enabled Catalyst, which requires the C language. Enable it in the consuming project with project(... LANGUAGES C CXX).")
return()
endif()

if(NOT TARGET catalyst::catalyst)
message(STATUS "Finding IPPL dependency: Catalyst")

if(_ipplBuildTree)
if("@IPPL_CATALYST_FETCHED@")
find_dependency(catalyst @IPPL_CATALYST_VERSION@ CONFIG
HINTS "@IPPL_CATALYST_BUILD_PACKAGE_DIR@")
else()
find_dependency(catalyst @IPPL_CATALYST_VERSION@ CONFIG HINTS "@catalyst_DIR@")
endif()
elseif("@IPPL_CATALYST_FETCHED@")
find_dependency(
catalyst @IPPL_CATALYST_VERSION@ CONFIG
HINTS
"${_ipplPrefix}/@CMAKE_INSTALL_LIBDIR@/cmake/@IPPL_CATALYST_PACKAGE_DIRNAME@")
else()
find_dependency(catalyst @IPPL_CATALYST_VERSION@ CONFIG
HINTS "${_ipplPrefix}" "@catalyst_DIR@")
endif()

message(STATUS "Catalyst version ${catalyst_VERSION}")
endif()
endif()

include("${CMAKE_CURRENT_LIST_DIR}/IPPLTargets.cmake")

if("@IPPL_ENABLE_CATALYST@" AND NOT _ipplBuildTree)
set_property(
TARGET IPPL::ippl APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS
"IPPL_CATALYST_SCRIPTS_DIR=\"${_ipplPrefix}/@CMAKE_INSTALL_DATADIR@/ippl/catalyst_scripts\"")
endif()

unset(_ipplPrefix)
unset(_ipplBuildTree)
1 change: 1 addition & 0 deletions cmake/InstallIppl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(_ippl_install_excludes
PATTERN "*.cc" EXCLUDE
PATTERN "*.cpp" EXCLUDE
PATTERN "*.cu" EXCLUDE
PATTERN "catalyst_scripts" EXCLUDE
# match your filenames if needed
)

Expand Down
43 changes: 43 additions & 0 deletions cmake/SetupCatalyst.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -----------------------------------------------------------------------------
# SetupCatalyst.cmake
#
# Links Catalyst into the ippl target. Resolution (find vs FetchContent) happens
# in Dependencies.cmake.
# -----------------------------------------------------------------------------

if(NOT TARGET ippl)
message(FATAL_ERROR "SetupCatalyst.cmake must be included after the ippl target is created.")
endif()

if(NOT TARGET catalyst::catalyst)
message(
FATAL_ERROR
"Catalyst enabled but catalyst::catalyst target is missing. "
"Set -DCatalyst_DIR=/path/to/catalyst/cmake or allow FetchContent.")
endif()

message(STATUS "Catalyst enabled")

target_compile_definitions(
ippl
PUBLIC IPPL_ENABLE_CATALYST
$<BUILD_INTERFACE:IPPL_CATALYST_SCRIPTS_DIR="${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/ippl/catalyst_scripts">)

target_link_libraries(ippl PUBLIC catalyst::catalyst)

message(STATUS "Catalyst Summary:")
message(STATUS " External install: ${catalyst_FOUND}")
if(catalyst_VERSION)
message(STATUS " Version: ${catalyst_VERSION}")
elseif(Catalyst_VERSION)
message(STATUS " Version: ${Catalyst_VERSION}")
endif()
if(catalyst_DIR)
message(STATUS " CMake config dir: ${catalyst_DIR}")
elseif(Catalyst_PACKAGE_DIR)
message(STATUS " CMake config dir: ${Catalyst_PACKAGE_DIR}")
endif()

get_target_property(_cat_type catalyst::catalyst TYPE)
message(STATUS " Target: catalyst::catalyst (${_cat_type})")
unset(_cat_type)
5 changes: 4 additions & 1 deletion demos/alpine/ExamplesWithoutPicManager/ChargedParticles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,13 @@ class ChargedParticles : public ippl::ParticleBase<PLayout> {
}

void registerAttributes() {
P.set_name("velocity");
E.set_name("electric_field");
q.set_name("charge");
// register the particle attributes
this->addAttribute(q);
this->addAttribute(P);
this->addAttribute(E);
this->addAttribute(q);
}

~ChargedParticles() {}
Expand Down
2 changes: 1 addition & 1 deletion demos/alpine/ParticleContainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ class ParticleContainer : public ippl::ParticleBase<
q.set_name("charge");
E.set_name("electric_field");
// register the particle attributes
this->addAttribute(q);
this->addAttribute(P);
this->addAttribute(E);
this->addAttribute(q);
}
void setupBCs() { setBCAllPeriodic(); }

Expand Down
4 changes: 4 additions & 0 deletions demos/alpine/PenningTrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ int main(int argc, char* argv[]) {

manager.run(manager.getNt());

#ifdef IPPL_ENABLE_CATALYST
manager.cat_viz.Finalize();
#endif

msg << "End." << endl;

IpplTimings::stopTimer(mainTimer);
Expand Down
48 changes: 48 additions & 0 deletions demos/alpine/PenningTrapManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "Random/NormalDistribution.h"
#include "Random/Randn.h"

#ifdef IPPL_ENABLE_CATALYST
#include "Stream/InSitu/CatalystAdaptor.h"
#endif

using view_type = typename ippl::detail::ViewType<ippl::Vector<double, Dim>, 1>::view_type;

template <typename T, unsigned Dim>
Expand Down Expand Up @@ -45,6 +49,13 @@ class PenningTrapManager : public AlpineManager<T, Dim> {
double alpha_m;
double DrInv_m;



#ifdef IPPL_ENABLE_CATALYST
public:
ippl::CatalystAdaptor cat_viz{std::string{TestName}};
#endif

public:
void pre_run() override {
Inform m("Pre Run");
Expand Down Expand Up @@ -124,6 +135,24 @@ class PenningTrapManager : public AlpineManager<T, Dim> {

this->grid2par();

#ifdef IPPL_ENABLE_CATALYST
m << "Catalyst is enabled" << endl;

std::shared_ptr<ippl::VisRegistryRuntime> runtime_steer_registry = ippl::MakeVisRegistryRuntimePtr();
std::shared_ptr<ippl::VisRegistryRuntime> runtime_vis_registry = ippl::MakeVisRegistryRuntimePtr(
"density", this->fcontainer_m->getRho(),
"ions", this->pcontainer_m
);
// runtime_vis_registry->add("potential", this->fcontainer_m->getRho() );
runtime_vis_registry->add("electrostatic", this->fcontainer_m->getE() );

static IpplTimings::TimerRef CAinit = IpplTimings::getTimer("CAinit");
IpplTimings::startTimer(CAinit);
cat_viz.Initialize(runtime_vis_registry, runtime_steer_registry);
IpplTimings::stopTimer(CAinit);

#endif

this->dump();

m << "Done";
Expand Down Expand Up @@ -239,6 +268,11 @@ class PenningTrapManager : public AlpineManager<T, Dim> {
static IpplTimings::TimerRef domainDecomposition = IpplTimings::getTimer("loadBalance");
static IpplTimings::TimerRef SolveTimer = IpplTimings::getTimer("solve");

#ifdef IPPL_ENABLE_CATALYST
static IpplTimings::TimerRef TMR_CAremember = IpplTimings::getTimer("CAremember");
static IpplTimings::TimerRef TMR_CAexecute = IpplTimings::getTimer("CAexecute");
#endif

double alpha = this->alpha_m;
double Bext = this->Bext_m;
double DrInv = this->DrInv_m;
Expand Down Expand Up @@ -298,6 +332,13 @@ class PenningTrapManager : public AlpineManager<T, Dim> {
// scatter the charge onto the underlying grid
this->par2grid();

// Save deep copy of the density field (for later).
#ifdef IPPL_ENABLE_CATALYST
IpplTimings::startTimer(TMR_CAremember);
cat_viz.rememberNow("density");
IpplTimings::stopTimer(TMR_CAremember);
#endif

// Field solve
IpplTimings::startTimer(SolveTimer);
this->fsolver_m->runSolver();
Expand All @@ -306,6 +347,13 @@ class PenningTrapManager : public AlpineManager<T, Dim> {
// gather E field
this->grid2par();

//trigger In Situ pipeline
#ifdef IPPL_ENABLE_CATALYST
IpplTimings::startTimer(TMR_CAexecute);
cat_viz.Execute(it, this->time_m);
IpplTimings::stopTimer(TMR_CAexecute);
#endif

IpplTimings::startTimer(PTimer);
auto R2view = pc->R.getView();
auto P2view = pc->P.getView();
Expand Down
Loading
Loading