Architecture

This section describes the internal architecture of Catalyst, including the runtime dispatch mechanism, implementation loading, and the optional asynchronous execution mode.

Overview

Catalyst is designed as a thin dispatch layer between simulation codes and in situ processing implementations. Its architecture enforces a strict separation between the API consumed by simulations and the implementations that perform actual data analysis and visualization.

┌────────────────────────────────────────────────────────┐
│              Simulation Code                          │
│         (NekRS, FUN3D, MINT, etc.)                    │
└──────────────────────┬─────────────────────────────────┘
                       │  conduit_node*
                       ▼
┌────────────────────────────────────────────────────────┐
│                   Adaptor                             │
│    Builds Conduit Blueprint mesh, calls Catalyst API  │
└──────────────────────┬─────────────────────────────────┘
                       │  catalyst_execute()
                       ▼
┌────────────────────────────────────────────────────────┐
│              libcatalyst (catalyst_api.c)              │
│                                                       │
│  ┌─────────────────────────────────────────────────┐  │
│  │  Runtime Dispatch                               │  │
│  │  • dlopen / LoadLibrary                         │  │
│  │  • Function pointer table (catalyst_impl)       │  │
│  └─────────────────────────────────────────────────┘  │
│  ┌─────────────────────────────────────────────────┐  │
│  │  Async Layer (optional)                         │  │
│  │  • Worker thread, bounded queue                 │  │
│  │  • Deep copy via compact_to()                   │  │
│  │  • MPI-synchronized skip decisions              │  │
│  └─────────────────────────────────────────────────┘  │
└──────────────────────┬─────────────────────────────────┘
                       │  impl->execute()
                       ▼
┌────────────────────────────────────────────────────────┐
│           Implementation Library                      │
│  (libcatalyst-paraview.so, libcatalyst-stub.so, etc.) │
└────────────────────────────────────────────────────────┘

Runtime Dispatch

The core of Catalyst is catalyst_api.c, which maintains a static pointer to a catalyst_impl structure:

struct catalyst_impl
{
  int version;
  enum catalyst_status (*initialize)(const conduit_node*);
  enum catalyst_status (*execute)(const conduit_node*);
  enum catalyst_status (*finalize)(const conduit_node*);
  enum catalyst_status (*about)(conduit_node*);
  enum catalyst_status (*results)(conduit_node*);
  conduit_uint64 conduit_is_external;
};

When catalyst_initialize() is called, Catalyst locates and loads an implementation library using the following search order:

  1. The name specified in params["catalyst_load/implementation"]

  2. The CATALYST_IMPLEMENTATION_NAME environment variable

  3. If neither is set, the built-in stub implementation is used

The implementation library is found by searching:

  1. Paths in params["catalyst_load/search_paths"]

  2. Paths in CATALYST_IMPLEMENTATION_PATHS environment variable

  3. The catalyst/ directory adjacent to libcatalyst

Once loaded, the library’s exported catalyst_api_impl symbol provides the function pointer table. Catalyst validates the version and Conduit ABI compatibility before accepting the implementation.

This design means a simulation compiled against the stub can switch to ParaView Catalyst (or any other implementation) at runtime by simply setting environment variables, without recompiling.

Key Source Files

src/catalyst/catalyst_api.c

The dispatch layer. Loads implementations via dlopen/LoadLibrary, maintains the global impl pointer, and routes all API calls through the function pointer table.

src/catalyst/catalyst_impl.h

Defines the catalyst_impl structure that implementations must export.

src/catalyst/catalyst_stub.cpp

The default (stub) implementation. Optionally dumps Conduit nodes for debugging.

src/catalyst/catalyst_api_default.cpp

Wires the stub functions into a catalyst_impl structure as the compile-time default.

src/catalyst/catalyst_async.cpp

The async execution layer. See Asynchronous Execution for details.