Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Installation

Prerequisites

pylcm requires Python 3.14+. We recommend pixi or uv for environment management.

Install with pixi

pixi add pylcm

Install with uv

uv add pylcm

Install 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 main

The 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 pylcm

The 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 install

A 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-metal

This requires Apple Silicon (M1 or later).

Verify Installation

import lcm
import jax

print(jax.devices())  # Should show GPU if configured

If 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:

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.0

A 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 lcm

Troubleshooting