Warp
Warp is a Python framework by NVIDIA for writing high-performance simulation and graphics code. It JIT compiles Python functions into efficient CPU or GPU kernels, enabling GPU-accelerated workloads for physics simulation, robotics, and machine learning. Currently at version 1.12.1, it receives frequent updates including both bug fixes and new features.
Warnings
- breaking Starting from Warp v1.12.0, built-in functions and vector/matrix indexing for non-native scalar types (e.g., `wp.float16`, `wp.float64`) now return Warp scalar types instead of Python native types. Native types like `wp.int32` still return Python `int`. This change optimizes performance by avoiding implicit Python object creation.
- deprecated Python 3.9 support will be removed in Warp 1.13.0, making Python 3.10 the minimum supported version. A `DeprecationWarning` is currently emitted when using Python 3.9. Also, implicit conversion of scalar values to composite types (vectors, matrices) in kernel launches or struct field assignments is deprecated; explicit constructors (e.g., `wp.vec3(...)`) should be used.
- gotcha GPU acceleration requires an NVIDIA GPU and a CUDA driver. If the installed driver is too old (e.g., < 525 for CUDA 12.x wheels), Warp will issue a `UserWarning` and fall back to CPU-only execution, significantly impacting performance. macOS platforms only support CPU execution; GPU acceleration is not available.
- gotcha Warp kernels (`@wp.kernel`) operate on a restricted subset of Python. All function arguments for kernels and `wp.func` functions must be explicitly typed, and kernels cannot return values. Control flow is limited, and arbitrary Python functions cannot be called inside kernels.
- gotcha All Warp arrays used in a kernel launch must reside on the same device as specified for the kernel launch. Attempting to launch a kernel on a 'cpu' device with arrays allocated on 'cuda:0' (or vice-versa) will result in an error.
Install
-
pip install warp-lang -
pip install warp-lang[examples]
Imports
- wp
import warp as wp
Quickstart
import warp as wp
import numpy as np
# Initialize Warp (optional, but good practice)
wp.init()
num_particles = 1_000_000
dt = 0.01
@wp.kernel
def gravity_step(pos: wp.array[wp.vec3], vel: wp.array[wp.vec3]):
i = wp.tid()
position = pos[i]
dist_sq = wp.length_sq(position) + 0.01 # softened distance
acc = -1000.0 / dist_sq * wp.normalize(position) # gravitational pull toward origin
vel[i] = vel[i] + acc * dt
pos[i] = pos[i] + vel[i] * dt
rng = np.random.default_rng(42)
positions = wp.array(rng.normal(size=(num_particles, 3)), dtype=wp.vec3, device='cuda')
velocities = wp.array(rng.normal(size=(num_particles, 3)), dtype=wp.vec3, device='cuda')
for _ in range(100):
wp.launch(kernel=gravity_step, dim=num_particles, inputs=[positions, velocities], device='cuda')
print(f"Final position of first particle: {positions.numpy()[0]}")