Skip to content

ryan-racer/LSMC_CUDA

Repository files navigation

GPU-Accelerated LSMC American Option Pricing

This repository implements and benchmarks Least Squares Monte Carlo (LSMC) pricing for American-style options on CPU and NVIDIA GPUs.

The first target is a clean reproduction of Fatica and Phillips, "Pricing American Options with Least Squares Monte Carlo on GPUs" (WHPCF 2013), using American put options under geometric Brownian motion. The code is organized as a public Python package with a traditional NumPy CPU backend and a CuPy CUDA GPU backend.

The ACM paper PDF is not redistributed here. Reference values used by the reproduction scripts are encoded as small CSV tables in data/reference/.


Paper Overview

This work is based on:

Pricing American Options with Least Squares Monte Carlo on GPUs

  • Authors: Massimiliano Fatica and Everett Phillips, NVIDIA
  • Venue: WHPCF 2013
  • DOI: 10.1145/2535557.2535564
  • Focus: Longstaff-Schwartz LSMC for American option pricing on CUDA GPUs
  • Reported result: an American put with 200,000 paths and 50 time steps priced in under 10 ms on a Tesla K20X

The paper emphasizes that most of the interesting acceleration comes from keeping simulation data on the GPU and mapping the backward regression phase to GPU-friendly reductions and small normal-equation solves.


What This Repo Adds

This repo provides a public Python reproduction scaffold for the Fatica and Phillips LSMC setup.

Key additions:

  • Standard src/ package layout for public GitHub use
  • Plain pip installation with a single requirements file
  • CPU baseline LSMC using NumPy
  • GPU LSMC using CuPy CUDA arrays and normal equations
  • Paper reference tables as CSV data
  • CLI for pricing, reproduction, benchmarking, and environment diagnostics
  • Unit tests and optional GPU parity tests
  • Clear benchmark reporting for reproducible American put workloads

Features

  • American put LSMC: Longstaff-Schwartz backward induction for early exercise
  • CPU backend: NumPy path generation and QR/lstsq or normal-equation regression
  • GPU backend: CuPy path generation, GPU-resident backward induction, and normal-equation regression
  • Basis functions: Monomial and weighted Laguerre bases
  • Variance reduction: Antithetic variates and moment matching
  • Reproduction scripts: Regenerate paper-style comparison tables
  • Benchmark outputs: CSV, environment metadata, and optional runtime plots
  • CUDA diagnostics: Detects GPU, driver, CuPy, CUDA runtime, and package versions

Deferred v2 ideas include Sobol/quasi-Monte Carlo, European control variates, native CUDA C++ kernels, and multi-right exercise benchmarks.


Benchmark Results

GPU speedups are workload-dependent. The current implementation prioritizes a clear, reproducible Python version of the paper-style American put setup.

Local Test Environment

Component Value
GPU NVIDIA RTX 2000 Ada Generation Laptop GPU
GPU memory 8 GB
Driver CUDA 13.2
Python 3.12
GPU package CuPy 14.1.1

Paper Reference Values

Parameters: American put, K=40, r=0.06, 100,000 paths, 50 time steps per year, four monomial basis terms.

S0 Sigma T Finite difference Longstaff-Schwartz paper Paper GPU
36 0.20 1 4.478 4.472 4.473
36 0.20 2 4.840 4.821 4.854
36 0.40 1 7.101 7.091 7.098
36 0.40 2 8.508 8.488 8.501
38 0.20 1 3.250 3.244 3.248
38 0.20 2 3.745 3.735 3.746
38 0.40 1 6.148 6.139 6.138
38 0.40 2 7.670 7.669 7.663
40 0.20 1 2.314 2.313 2.309
40 0.20 2 2.885 2.879 2.877
40 0.40 1 5.312 5.308 5.305
40 0.40 2 6.920 6.921 6.909
42 0.20 1 1.617 1.617 1.616
42 0.20 2 2.212 2.206 2.204
42 0.40 1 4.582 4.588 4.578
42 0.40 2 6.248 6.243 6.233
44 0.20 1 1.110 1.118 1.112
44 0.20 2 1.690 1.675 1.684
44 0.40 1 3.948 3.957 3.944
44 0.40 2 5.647 5.622 5.627

Local CPU vs GPU Runtime

Parameters: S0=36, K=40, r=0.06, sigma=0.20, T=1, 524,288 paths, 50 time steps, float64.

Backend Solver Price RNG (s) Path gen (s) Regression (s) Total (s) Speedup
CPU NumPy QR / lstsq 4.4720 0.175 0.306 1.654 2.151 1.0x
GPU CuPy Normal equations 4.4712 0.142 0.099 0.849 1.090 2.0x

This is a high-level Python/CuPy implementation, so it validates the GPU workflow but does not claim the full Tesla K20X-style optimized CUDA C performance from the paper.


Installation

To run locally on an NVIDIA machine, clone the repository and install the Python dependencies:

git clone https://github.com/ryan-racer/LSMC_CUDA.git
cd lsmc-cuda
pip install -r requirements.txt

Requires an NVIDIA driver with CUDA support. A system CUDA Toolkit or nvcc is not required for the default CuPy wheel path.


How to Run

Check the environment:

python lsmc.py doctor

Price one American put on CPU:

python lsmc.py price --backend cpu --spot 36 --strike 40 --sigma 0.2 --rate 0.06 --maturity 1

Price one American put on GPU:

python lsmc.py price --backend gpu --spot 36 --strike 40 --sigma 0.2 --rate 0.06 --maturity 1

Reproduce Paper Tables

Run the CPU reproduction:

python lsmc.py reproduce-paper --backend cpu --output-dir outputs/reproduction

Run the GPU reproduction:

python lsmc.py reproduce-paper --backend gpu --output-dir outputs/reproduction-gpu

The default reproduction grid follows the paper's American put setup:

  • Strike K=40
  • Risk-free rate r=0.06
  • Spot prices 36, 38, 40, 42, 44
  • Volatilities 0.20, 0.40
  • Maturities 1, 2
  • 100,000 paths
  • 50 time steps per year
  • Four monomial basis terms

For quick smoke tests, reduce path count and steps:

python lsmc.py reproduce-paper --backend cpu --paths 200 --steps-per-year 5 --output-dir outputs/smoke-reproduction

Benchmark CPU vs GPU

Run an end-to-end benchmark:

python lsmc.py benchmark --backends cpu,gpu --paths 10000,50000,100000 --output-dir outputs/benchmarks

Run a shared-normal benchmark, where CPU and GPU use the same random shocks:

python lsmc.py benchmark --backends cpu,gpu --paths 10000,50000,100000 --shared-normals --output-dir outputs/benchmarks-shared

Benchmark outputs include:

  • runtime_benchmark.csv
  • environment.json
  • runtime_benchmark.png unless --no-plot is passed

Repository Structure

src/lsmc_cuda/
  analytics.py        Black-Scholes diagnostic formula
  basis.py            Monomial and weighted Laguerre bases
  benchmarking.py     CPU/GPU benchmark workflow
  cli.py              lsmc command line interface
  config.py           Dataclasses for params, config, results
  cpu.py              NumPy LSMC backend
  gpu.py              CuPy CUDA LSMC backend
  paths.py            GBM path and random shock generation
  reproduce.py        Paper reproduction workflows

benchmarks/           Script wrappers for benchmark runs
data/reference/       Paper reference tables as CSV
docs/                 Reproduction notes
examples/             Minimal library usage examples
tests/                Unit and CPU/GPU smoke tests

Requirements

CPU:

  • Python 3.12
  • NumPy
  • SciPy
  • pandas
  • matplotlib
  • Typer
  • Rich

GPU:

  • NVIDIA GPU and recent driver
  • CuPy CUDA wheel installed from requirements.txt
  • No system nvcc is required for the default CuPy wheel path

Citations

Fatica, M., and Phillips, E. (2013). "Pricing American Options with Least Squares Monte Carlo on GPUs." Proceedings of the 6th Workshop on High Performance Computational Finance. DOI: 10.1145/2535557.2535564.

Longstaff, F. A., and Schwartz, E. S. (2001). "Valuing American Options by Simulation: A Simple Least-Squares Approach." Review of Financial Studies.


License

MIT License. See LICENSE.

About

GPU-Accelerated LSMC American Option Pricing

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages