Installation

Get Access

Moreau is available by request

Request access here to receive install credentials and a license key.

Moreau is distributed via Gemfury. After requesting access you’ll receive a token.

Install directly:

pip install moreau[cuda] --extra-index-url https://<your-token>:@pypi.fury.io/optimalintellect/

Or, to avoid passing the URL every time, add to ~/.pip/pip.conf:

[global]
index-url = https://<your-token>:@pypi.fury.io/optimalintellect/
extra-index-url = https://pypi.org/simple/

License Key

Moreau requires a license key to call solve(). Everything else (import, solver construction, setup()) works without one.

After requesting access, you’ll receive a license key. Provide it via any of the following methods (checked in priority order):

Place your key in ~/.moreau/key:

mkdir -p ~/.moreau
echo "moreau_v1_..." > ~/.moreau/key

Alternatively, place it at ~/.moreau_key.

Place a .moreau_key file in your working directory:

echo "moreau_v1_..." > .moreau_key

This is useful for per-project keys. Be sure to add .moreau_key to your .gitignore.

Set the MOREAU_LICENSE_KEY environment variable:

export MOREAU_LICENSE_KEY="moreau_v1_..."

For persistent use, add this to your shell profile (~/.bashrc, ~/.zshrc, etc.) or your CI/CD environment secrets.

Lookup Order

When multiple key sources exist, Moreau checks them in this order:

  1. MOREAU_LICENSE_KEY environment variable

  2. .moreau_key in the current directory

  3. ~/.moreau/key

  4. ~/.moreau_key

The first non-empty key found is used.

If your key is missing or expired, solve() will raise a RuntimeError with instructions. Contact info@optimalintellect.com to obtain or renew a license.


Quick Install

CPU Only
pip install moreau

Pure Python interface with Rust-based CPU solver.

GPU Support
pip install moreau[cuda]

CUDA 12 by default, or moreau[cuda13] for CUDA 13. Requires Python 3.12+.


Choose Your Framework

If PyTorch (>= 2.0) is installed, moreau.torch works automatically — no extra install step needed.

Provides moreau.torch.Solver for neural network integration with full autograd support.

If JAX (>= 0.4.0) is installed, moreau.jax works automatically — no extra install step needed.

Provides moreau.jax.Solver compatible with jax.grad, jax.vmap, and jax.jit.


Available Extras

Extra

Installs

Notes

moreau[cuda]

moreau-cuda12

CUDA 12 GPU backend (default)

moreau[cuda12]

moreau-cuda12

CUDA 12 GPU backend (explicit)

moreau[cuda13]

moreau-cuda13

CUDA 13 GPU backend

moreau[test]

pytest, cvxpy

Test dependencies


Verify Installation

import moreau
import numpy as np
from scipy import sparse

# Simple QP
P = sparse.diags([1.0, 1.0], format='csr')
q = np.array([1.0, 1.0])
A = sparse.csr_array([[1.0, 0.0], [0.0, 1.0]])
b = np.array([0.5, 0.5])

cones = moreau.Cones(num_nonneg_cones=2)
solver = moreau.Solver(P, q, A, b, cones=cones)
solution = solver.solve()

print(f"Solution: {solution.x}")
print(f"Status: {solver.info.status}")
print("Installation successful!")
import torch
from moreau.torch import Solver
import moreau

cones = moreau.Cones(num_nonneg_cones=2)
solver = Solver(
    n=2, m=2,
    P_row_offsets=torch.tensor([0, 1, 2]),
    P_col_indices=torch.tensor([0, 1]),
    A_row_offsets=torch.tensor([0, 1, 2]),
    A_col_indices=torch.tensor([0, 1]),
    cones=cones,
)

P_values = torch.tensor([1.0, 1.0], dtype=torch.float64)
A_values = torch.tensor([1.0, 1.0], dtype=torch.float64)
solver.setup(P_values, A_values)

q = torch.tensor([1.0, 1.0], dtype=torch.float64, requires_grad=True)
b = torch.tensor([0.5, 0.5], dtype=torch.float64)
solution = solver.solve(q, b)

print(f"Solution: {solution.x}")
print(f"Device: {solver.device}")
print("PyTorch installation successful!")
import jax.numpy as jnp
from moreau.jax import Solver
import moreau

cones = moreau.Cones(num_nonneg_cones=2)
solver = Solver(
    n=2, m=2,
    P_row_offsets=jnp.array([0, 1, 2]),
    P_col_indices=jnp.array([0, 1]),
    A_row_offsets=jnp.array([0, 1, 2]),
    A_col_indices=jnp.array([0, 1]),
    cones=cones,
)

P_data = jnp.array([1.0, 1.0])
A_data = jnp.array([1.0, 1.0])
q = jnp.array([1.0, 1.0])
b = jnp.array([0.5, 0.5])

solution = solver.solve(P_data, A_data, q, b)

print(f"Solution: {solution.x}")
print(f"Device: {solver.device}")
print("JAX installation successful!")

GPU Acceleration

CUDA Support

For NVIDIA GPUs, the CUDA backend provides significant speedups, especially for batched problems.

Check GPU availability:

import moreau

print(f"Available devices: {moreau.available_devices()}")
print(f"Default device: {moreau.default_device()}")
print(f"CUDA available: {moreau.device_available('cuda')}")

Force GPU usage:

settings = moreau.Settings(device='cuda')
solver = moreau.Solver(P, q, A, b, cones=cones, settings=settings)

Dependencies

Core Dependencies

Package

Version

Purpose

Python

>= 3.9

Runtime

NumPy

>= 1.19.0

Array operations

Pydantic

>= 2.0.0

Data validation

moreau-cpu

>= 0.2.0

CPU solver backend

Optional Dependencies

Package

Version

Purpose

moreau-cuda12

>= 0.2.0

GPU solver backend (CUDA 12, Python >= 3.12)

moreau-cuda13

>= 0.2.0

GPU solver backend (CUDA 13, Python >= 3.12)

PyTorch

>= 2.0

PyTorch integration

JAX

>= 0.4.0

JAX integration

SciPy

>= 1.6.0

Sparse matrix construction (used in examples)


Troubleshooting

ImportError: moreau-cpu not found

The core CPU backend is required. Install it with:

pip install moreau-cpu

Or reinstall moreau:

pip install --force-reinstall moreau
CUDA not detected

Ensure you have:

  1. An NVIDIA GPU with CUDA support

  2. CUDA drivers installed

  3. The CUDA backend: pip install moreau[cuda]

Check CUDA availability:

import moreau
print(moreau.device_available('cuda'))

# Diagnose the error
error = moreau.device_error('cuda')
if error:
    print(f"CUDA error: {error}")
PyTorch/JAX import errors

Install the frameworks separately:

Once installed, moreau.torch and moreau.jax are available automatically.