Prebuilt kernel definitions =========================== Xsuite distributes prebuilt kernels for common tracking configurations. These kernels let users run many standard cases without compiling C code on first use. When a new beam element, helper structure, or package-level C source is added, the prebuilt-kernel definitions may need to be updated so that the generated kernel shared objects contain the required code. The definitions live in two places: * package-local ``prebuilt_kernel_definitions`` modules, which expose element classes and optional constructor defaults; * ``xsuite/kernel_definitions.py``, which combines those package-local lists into the actual prebuilt kernel configurations built by ``xsuite-prebuild``. Package-local definitions ------------------------- Each package that contributes elements to the default Xsuite kernels keeps its own lists under ``/prebuilt_kernel_definitions``. For example, Xtrack exports: .. code-block:: python # xtrack/prebuilt_kernel_definitions/__init__.py from .element_types import ( ONLY_XTRACK_ELEMENTS, NO_SYNRAD_ELEMENTS, NON_TRACKING_ELEMENTS, ) from .element_inits import XTRACK_ELEMENTS_INIT_DEFAULTS The element-type module contains the classes to make available in prebuilt kernels. Tracking elements go in the lists used as ``classes`` in ``xsuite/kernel_definitions.py``. Helper structures and elements that are not part of the line, but whose APIs or extra kernels need to be present, go in ``extra_classes`` through a package-local list such as ``NON_TRACKING_ELEMENTS``. Some classes cannot be instantiated with an empty constructor. For those, provide minimal build-time arguments in the package-local ``*_ELEMENTS_INIT_DEFAULTS`` dictionary: .. code-block:: python XTRACK_ELEMENTS_INIT_DEFAULTS = { 'LimitPolygon': { 'x_vertices': np.array([0, 1, 1, 0]), 'y_vertices': np.array([0, 0, 1, 1]), }, } These objects are only used to build representative trackers for kernel generation. Keep the defaults as small and inert as possible. Adding a class to Xsuite kernels -------------------------------- After adding the class to the package-local definitions, make sure it is available in the appropriate configuration in ``xsuite/kernel_definitions.py``. For an existing Xsuite package this usually means adding the class to one of the lists already imported by ``xsuite/kernel_definitions.py``. For a new package, ``xsuite/kernel_definitions.py`` must import that package's prebuilt-kernel lists and include them in the selected configurations. Each entry has this shape: .. code-block:: python ('default_base_config', { 'config': BASE_CONFIG, 'classes': XTRACK_ELEMENTS + DEFAULT_XFIELDS_ELEMENTS, 'extra_classes': [xt.Particles], }), ``classes`` Beam elements that are placed in the temporary ``xt.Line`` used to build the tracker kernel. ``extra_classes`` Xobjects classes that are not line elements for this configuration, but whose C API or ``_kernels`` need to be compiled into the module. ``xt.Particles`` is normally included here. ``config`` Tracker configuration values used when building the prebuilt kernel. At run time, prebuilt kernels are selected only when the requested config matches the metadata exactly. The order of ``kernel_definitions`` matters. Runtime selection tries the entries in order and uses the first compatible prebuilt kernel, so more-specific or higher-priority definitions should stay above broader ones. Making C headers discoverable ----------------------------- If a package provides C headers that are included by kernel sources, Xobjects needs to know where that package's sources are installed. Register an ``xobjects`` entry point named ``include`` in the package's ``pyproject.toml``. .. code-block:: toml [project.entry-points.xobjects] include = "my_package" Xobjects loads entry points from the ``xobjects`` group with the name ``include`` and adds the parent directory of the imported package to the C include path. This makes includes such as the following work from kernel sources: .. code-block:: c #include "my_package/path/to/header.h" The hook only provides include paths. The headers still need to be part of the installed package or source distribution. Regenerating and checking ------------------------- After changing definitions, regenerate the prebuilt kernels locally: .. code-block:: bash xsuite-prebuild regenerate # or, alternatively: xsuite-prebuild regenerate --kind serial # default xsuite-prebuild regenerate --kind openmp # (re)build only OpenMP kernels xsuite-prebuild regenerate --kind serial,openmp # (re)build both CPU serial and OpenMP kernels The ``--kind`` option limits kernel regeneration to the requested context kind. If omitted, ``xsuite-prebuild regenerate`` builds only ``serial`` kernels. Set ``XSUITE_VERBOSE`` when checking runtime selection. With this environment variable set, Xsuite prints which prebuilt kernels it considers and why each candidate is accepted or rejected.