Prerequisites¶
pylcm requires Python 3.14+. We recommend pixi or uv for environment management.
Install with pixi¶
pixi add pylcmInstall with uv¶
uv add pylcmInstall from GitHub¶
If you require features not yet in a released version, install from GitHub:
# pixi
pixi add pylcm --pypi --git https://github.com/OpenSourceEconomics/pylcm.git --rev main
# uv
uv add pylcm --git https://github.com/OpenSourceEconomics/pylcm.git --rev mainThe compiled kernel, and installing without a C++ compiler¶
Installing pylcm compiles a small C++ library, the exact-affine kernel. It backs the
"exact" upper envelope, which is the default for DC-EGM — so this is not an
optional extra: without it, DC-EGM cannot run on its defaults. Brute-force backward
induction never touches it and is unaffected.
The build needs a C++ compiler: c++ or g++ on the path on Linux and macOS, cl.exe
from an activated MSVC developer environment on Windows, or CXX set to one (on Windows
that must be cl or clang-cl, since the compile uses MSVC flags). It also builds a
CUDA variant when nvcc is present; where it is not, the certified envelope runs on CPU
only, and the build says so as it runs. Windows builds the CPU kernel and, finding no
compiler, fails the install exactly as the other platforms do.
If no compiler is found, the install fails with a message naming what is missing. That is deliberate: an install that quietly dropped the kernel would look fine and then fail hours later inside a solve.
To install without a compiler on purpose, say so:
LCM_SKIP_EXACT_AFFINE=1 pip install pylcmThe build then compiles nothing and prints which capability the install will not have.
Any other value, including 0, builds the kernel as usual. You can check afterwards
whether an install has one:
from _lcm.egm.upper_envelope._exact_affine.ffi import kernel_built
print(kernel_built()) # False in a skipped installA skipped install still imports. Constructing a Model whose DCEGM regime selects
ExactEnvelope — directly, or as the inner solver of a NEGM regime — then raises
immediately, before compilation or solve(), rather than returning a silently different
answer. Grid-search models and endogenous-grid models selecting a different typed
envelope remain usable. To get the certified capability back, unset the variable and
reinstall.
GPU Acceleration (optional, but then this is the whole point of it)¶
pylcm uses JAX for numerical computation. By default, JAX runs on CPU. For GPU acceleration, install the appropriate JAX variant.
Linux (CUDA)¶
If you use pixi, add a CUDA feature to your pyproject.toml:
[tool.pixi.feature.cuda13]
platforms = ["linux-64"]
system-requirements = {cuda = "13"}
[tool.pixi.feature.cuda13.target.linux-64.dependencies]
cuda-nvcc = "~=13.0"
[tool.pixi.feature.cuda13.target.linux-64.pypi-dependencies]
jax = {version = ">=0.8", extras = ["cuda13"]}For CUDA 12, replace cuda13 with cuda12 throughout.
If you use uv:
uv add "jax[cuda13]"See the JAX installation guide for details on CUDA toolkit requirements.
macOS (Metal)¶
# pixi
pixi add jax-metal --pypi
# uv
uv add jax-metalThis requires Apple Silicon (M1 or later).
Verify Installation¶
import lcm
import jax
print(jax.devices()) # Should show GPU if configuredIf GPU acceleration is set up correctly, you will see a GpuDevice or MetalDevice in
the output. Otherwise, you will see CpuDevice, which is fine for development and
smaller models.
JAX Settings¶
pylcm sets three JAX configuration defaults on import:
XLA_PYTHON_CLIENT_PREALLOCATE=false— disables JAX’s default of reserving 75% of GPU memory upfront. This letsnvidia-smireflect actual usage and plays nicely with other GPU processes.JAX_COMPILATION_CACHE_DIR=~/.cache/jax— enables persistent JIT compilation caching. Large models (many regimes and states) can take minutes to compile on first run; the cache makes subsequent runs near-instant.JAX_PERSISTENT_CACHE_MIN_COMPILE_TIME_SECS=0— writes every compiled program to the persistent cache. JAX’s default only caches programs that take longer than a second to compile, which excludes most of the many small programs a pylcm model compiles — leaving the cache empty and every fresh process recompiling everything.
All three only apply if you have not already set the variable yourself.
Import order does not matter¶
JAX reads its environment variables once, while it defines its configuration — so a
value exported after import jax never reaches it. pylcm therefore applies both
compilation-cache settings through jax.config as well, and they hold whether lcm is
imported before or after jax. This matters in practice: test suites, notebooks, and
other libraries routinely import jax first, and a cache that is switched off reports
nothing at all — it simply recompiles, which on a large model costs minutes per process.
XLA_PYTHON_CLIENT_PREALLOCATE is read by XLA when the backend is first initialised
rather than at import, so it is enough to import lcm before running any computation.
To confirm caching is live in a given process:
import jax
import lcm
print(jax.config.jax_compilation_cache_dir) # a path
print(jax.config.jax_persistent_cache_min_compile_time_secs) # 0.0A directory of None means the cache is off and every fresh process is recompiling the
whole model.
On HPC systems where the home directory is on a slow network filesystem, you may want to point the compilation cache at a fast local disk. Set the environment variable before importing pylcm:
import os
os.environ["JAX_COMPILATION_CACHE_DIR"] = os.path.expandvars(
"/scratch/$USER/.cache/jax"
)
import lcmTroubleshooting¶
Python version too old: pylcm requires Python 3.14+. Check with
python --version.No C++ compiler foundduring install (No MSVC C++ compiler foundon Windows): install one — on Windows, activate an MSVC developer environment socl.exeis on the path — or install without the certified upper envelope usingLCM_SKIP_EXACT_AFFINE=1(see above), accepting that DC-EGM will not run on its defaults.An
ExactEnvelopeavailability error duringModel(...): the install skipped the kernel, or carries one built by a different toolchain. Rebuild in the current environment withpixi run build-exact-affine, or explicitly select another typed envelope under its approximation contract.JAX GPU not detected: Ensure the CUDA toolkit (Linux) or jax-metal (macOS) is properly installed. See the JAX installation guide.