JIT Kernel Compilation#
Mooncake EP JIT currently supports only the NVIDIA (CUDA) backend.
Instead of shipping every kernel specialization in the library, Mooncake EP compiles several of its device kernels at runtime. The first call that needs a given kernel variant runs nvcc, caches the resulting cubin on disk, and reuses it for the rest of the process and for later runs.
As a result, a deployed Mooncake EP needs more than
libmooncake_ep_device.so. It also needs a working nvcc, the kernel headers,
the CUDA headers, a writable cache directory, and, for builds with
USE_NCCL_DEVICE=ON, the NCCL device headers. Each of these is found through an
environment variable, with a fallback compiled into the library. A build used
where it was built, or an installed wheel, usually needs no configuration. The
environment variables cover the other cases: relocated installs, containers,
read-only filesystems, and cross-architecture builds.
Path resolution#
Each path comes from the first rule in its list that gives a value. The compiled-in defaults are set by CMake at build time and point into the build tree.
Kernel headers (the Mooncake EP and transfer engine headers that the JIT compiles against):
The
MOONCAKE_EP_JIT_SOURCE_DIRenvironment variable.$MOONCAKE_EP_HOME/include/mooncake_ep.mooncake_ep_jit/include/mooncake_epnext tolibmooncake_ep_device.so, if that directory exists (the layout of an installed wheel).The compiled-in
MOONCAKE_EP_JIT_SOURCE_DIR.
NCCL device headers (only for builds with USE_NCCL_DEVICE=ON):
The
MOONCAKE_EP_JIT_BUILD_INCLUDE_DIRenvironment variable.$NCCL_HOME/include.The compiled-in
MOONCAKE_EP_JIT_BUILD_INCLUDE_DIR.
CUDA headers:
The
MOONCAKE_EP_JIT_CUDA_INCLUDE_DIRenvironment variable.$CUDA_HOME/include, or$CUDA_PATH/includeifCUDA_HOMEis not set.The compiled-in
MOONCAKE_EP_JIT_CUDA_INCLUDE_DIR.
Compiler:
The
MOONCAKE_EP_JIT_NVCCenvironment variable.The
NVCCenvironment variable.$CUDA_HOME/bin/nvcc, or$CUDA_PATH/bin/nvccifCUDA_HOMEis not set, if that file exists.nvccfromPATH.
Cache#
Compiled cubins are cached in MOONCAKE_EP_JIT_CACHE_DIR, which defaults to
/tmp/mooncake_ep/jit.
The cache key combines two fingerprints:
The kernel variant: kernel family, variant name, entry point, generated source, target SM and architecture, and runtime key.
The compile environment: compiler identity, the contents of the kernel, transfer engine and NCCL header trees, and the full list of compile options.
This has two consequences:
The cache invalidates itself. Editing a kernel header, switching compilers, changing architecture flags, or using different include directories all change the key, so a new entry is compiled. A stale cubin is never loaded, and there is no need to clear the cache after a rebuild.
Old entries are never removed. Superseded cubins stay on disk, so on a machine that rebuilds often the cache keeps growing. Deleting the directory is always safe; the only cost is recompiling.
Cache writes are atomic. Each cubin is first written to a temporary file named with the process ID and thread ID, then renamed into place. Ranks on the same node can therefore fill a shared cache at the same time without corrupting each other’s entries.
Set MOONCAKE_EP_JIT_CACHE_DIR to another location when /tmp is read-only,
too small, or not shared across containers the way you expect. Putting the
cache on a persistent volume also avoids the first-call compile delay each time
a new container starts.
Diagnostics#
Set MOONCAKE_EP_JIT_LOG=1 to print JIT logs to stderr. Each line starts with
[mooncake_ep jit] pid=<pid>. The log shows cache hits and misses, compile
attempts and failures, and cache write errors (mkdir, open, write, and rename).
It is the quickest way to find a cache directory that is not writable or is
full.
Each kernel variant has its own directory in the cache, containing
kernel.cu (the generated source), kernel.cubin, metadata.json, and, after
a compile, compile.log (the nvcc output).
When a variant fails to compile, the failure is recorded in two places:
In the process: the variant is not compiled again, and its warning is printed only once.
On disk: a
compile.failedfile is written to the variant’s cache directory. Later processes that use the same cache skip the compile and report the failure without running nvcc again.
To retry after fixing the cause (for example, a missing header), delete that variant’s directory or the whole cache directory. Changes that alter the cache key, such as editing a header or changing compile options, retry automatically because they use a new directory.
Deployment checklist#
nvcc can be found through
MOONCAKE_EP_JIT_NVCC,NVCC,CUDA_HOME,CUDA_PATH, orPATH.Kernel headers can be found. Installed wheels and builds used where they were built need no setup. If the library was moved after it was built, set
MOONCAKE_EP_HOMEorMOONCAKE_EP_JIT_SOURCE_DIR.CUDA headers can be found through
CUDA_HOME,CUDA_PATH, orMOONCAKE_EP_JIT_CUDA_INCLUDE_DIR.NCCL device headers (only for
USE_NCCL_DEVICE=ONbuilds) can be found throughNCCL_HOMEorMOONCAKE_EP_JIT_BUILD_INCLUDE_DIR.The cache directory is writable. Set
MOONCAKE_EP_JIT_CACHE_DIRif/tmpis not suitable.The first call to each kernel variant includes compile time. Later calls, and later runs that share the cache, do not.