plMapcalc Python edition is a single script — plmapcalc.py — with no build step. Installation means: get Python, install three packages, download the script.

Requirements

Step-by-step: Linux / macOS

1

Check Python version

shell
python3 --version

Must print Python 3.9 or newer. If not, install Python from python.org or via your system package manager.

2

Create a virtual environment (recommended)

shell
python3 -m venv ~/.venv/mapcalc
source ~/.venv/mapcalc/bin/activate
3

Install dependencies

shell
pip install numpy rasterio numba

Or using the requirements file:

shell
pip install -r requirements.txt
4

Download plmapcalc.py

shell
wget https://plmapcalc.netzel.pl/plmapcalc.py
5

Verify

shell
python3 plmapcalc.py --help

You should see the full usage message with all options listed.

Step-by-step: Windows

1

Install Python

Download the installer from python.org. During setup, check Add Python to PATH.

2

Install dependencies in Command Prompt

cmd
pip install numpy rasterio numba
3

Download plmapcalc.py and run

cmd
python plmapcalc.py --help

On Windows use double quotes instead of single quotes for -e expressions and use backslash \ as the path separator inside -i / -o / -r / -s.

Without numba

If numba cannot be installed, plMapcalc still works but uses a pure-Python fallback loop. Expect processing times 50–200× slower than the JIT path. The tool prints a warning at startup:

stderr
[WARN] numba not installed – processing will be slower.
💡

On HPC clusters, load the numba conda package or use pip install numba in a user-local environment. Numba ships its own LLVM — no system LLVM needed.

GPU acceleration (optional)

Passing --gpu routes the pixel kernel to a CUDA-capable GPU via numba-cuda. Each GPU thread processes one pixel; thousands of pixels run simultaneously. This is most effective for large rasters with compute-intensive expressions.

Hardware requirements

RequirementMinimumNotes
GPUNVIDIA, Compute Capability ≥ 3.5RTX 20/30/40/50 series, Tesla, Quadro — check with nvidia-smi
NVIDIA driver≥ 520 (CUDA 11.8+)Blackwell (RTX 50xx) requires driver ≥ 570 (CUDA 12.8)
CUDA runtime12.xProvided by nvidia-cuda-runtime-cu12 pip package — no system CUDA Toolkit required

Python packages

GPU mode requires a dedicated virtual environment with the following pip packages. These must not be mixed with torch (which pins cuda-bindings<13 — incompatible with numba-cuda≥0.25).

PackageVersionPurpose
numba≥ 0.61JIT compiler (CPU + GPU base)
numba-cuda≥ 0.29CUDA target for numba; provides numba.cuda namespace and pathfinder for CUDA libs
cuda-bindings≥ 13 (auto)Installed automatically as a dependency of numba-cuda ≥ 0.25
nvidia-cuda-runtime-cu12≥ 12.8Provides libcudart.so
nvidia-cuda-nvcc-cu12≥ 12.8Provides libnvvm.so (PTX compiler)
nvidia-cuda-nvrtc-cu12≥ 12.8Provides libnvrtc.so (runtime compilation)
nvidia-nvjitlink-cu12≥ 12.8Provides libnvJitLink.so (link-time optimisation; optional but eliminates a warning)

Dedicated venv required. numba-cuda ≥ 0.25 installs cuda-bindings ≥ 13, which conflicts with torch (requires cuda-bindings < 13). Keep plmapcalc GPU mode in a separate virtual environment from any PyTorch installation.

Install — step by step

  1. Create a dedicated venv and activate it
    shell
    python3 -m venv ~/.venv/plmc_gpu
    source ~/.venv/plmc_gpu/bin/activate
  2. Install plmapcalc core dependencies
    shell
    pip install numpy rasterio numba
  3. Install numba-cuda and CUDA libraries
    shell
    pip install numba-cuda
    pip install nvidia-cuda-runtime-cu12 \
                nvidia-cuda-nvcc-cu12 \
                nvidia-cuda-nvrtc-cu12 \
                nvidia-nvjitlink-cu12

    For Blackwell GPUs (RTX 50xx) ensure the CUDA 12.8 versions are installed:

    shell
    pip install "nvidia-cuda-runtime-cu12>=12.8" \
                "nvidia-cuda-nvcc-cu12>=12.8" \
                "nvidia-cuda-nvrtc-cu12>=12.8" \
                "nvidia-nvjitlink-cu12>=12.8"
  4. Create missing .so symlinks

    pip installs versioned libraries (e.g. libnvvm.so.4.0.0) but not the unversioned symlink (libnvvm.so) that the pathfinder requires. Run once after installation:

    shell
    find $VIRTUAL_ENV -path "*/nvidia/*" -name "lib*.so.*" | while read f; do
        link="${f%.so.*}.so"
        [ ! -e "$link" ] && ln -sf "$f" "$link" && echo "linked: $link"
    done

    Or use the provided patch_activate_cuda.sh helper which performs this step automatically alongside patching LD_LIBRARY_PATH.

  5. Patch the venv activate script (LD_LIBRARY_PATH)

    CUDA shared libraries installed via pip are not on the default library path. The helper script patches the venv activate to add them automatically:

    shell
    bash patch_activate_cuda.sh   # run with venv active
    source $VIRTUAL_ENV/bin/activate
  6. Verify
    shell
    python -c "from numba import cuda; cuda.detect()"

    Expected output lists your GPU(s) with compute capability and marks them as [SUPPORTED].

Usage

shell
python plmapcalc.py --gpu -i band4.tif -i band3.tif \
    -o ndvi.tif:float32:-9999 \
    -e 'x = IN[0]+IN[1]; OUT[0] = -9999 if x==0 else (IN[0]-IN[1])/x'

Blackwell (RTX 50xx) note

Blackwell GPUs (Compute Capability 12.0, sm_120) are supported via PTX JIT compilation. The first run compiles PTX to native sm_120 code, which takes approximately 30 seconds. Subsequent runs use the cached binary and are fast. Native Blackwell kernels require CUDA 12.8 or newer and driver ≥ 570.

Automatic fallback: if CUDA is unavailable (no GPU, missing driver, or numba-cuda not installed), --gpu falls back to CPU automatically with a warning. Expressions that write to MEM[] (e.g. MEM[0] += IN[0]) always use the serial CPU kernel — parallel GPU threads cannot safely write to shared memory cells without race conditions. Expressions that only read from MEM[] run on GPU normally.