v1.15.0 #1624
shi-eric
announced in
Announcements
v1.15.0
#1624
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Warp v1.15.0
Warp v1.15 adds opt-in deterministic execution for supported atomic patterns, broader replay for CPU and saved CUDA graphs, CUDA managed-memory allocation, and mipmapped textures. It also extends Warp functions with in-place references and function arguments, adds struct support to tile operations, and lets sparse matrices reserve BSR row capacity.
New features
Reproducible atomic execution
Simulation, validation, and regression-test workloads can now trade some performance for reproducible ordering of common atomic updates.
wp.DeterministicMode.RUN_TO_RUNproduces bit-exact repeated results on the same GPU architecture, whilewp.DeterministicMode.GPU_TO_GPUuses a more conservative path intended to preserve results across GPU architectures (#1443).Note
Deterministic mode changes the execution algorithm and uses temporary storage, so its performance impact depends on the atomic pattern and contention. Highly contended accumulations may run faster because deterministic reduction replaces a serialized atomic hotspot with parallel sort-and-reduce work. Sparse accumulations usually slow down because normal atomics have little contention, while deterministic mode still pays for recording and sorting. Counter-based slot allocation also requires counting, scanning, and replaying the kernel to assign stable slots, so it usually slows down. The more conservative
GPU_TO_GPUmode can also be slower thanRUN_TO_RUN. Benchmark affected kernels before enabling deterministic mode broadly.The following kernel compacts even thread IDs into an output array. Since each thread uses the return value from
wp.atomic_add()as its slot, deterministic mode assigns the same output ordering across repeated launches.Key capabilities:
wp.config.deterministicbefore defining or importing kernel modules. Usewp.set_module_options()to override an existing module, ormodule="unique"withmodule_optionsfor intentional per-kernel isolation.wp.atomic_add(),wp.atomic_sub(),wp.atomic_min(), andwp.atomic_max()updates, sorts them by destination and thread, and combines the updates for each destination with a deterministic reduction instead of applying them in CUDA's scheduler-dependent atomic order. It handles+=and-=updates the same way, while counter-based allocation uses count, scan, and replay passes to assign stable output slots.wp.config.deterministic_max_recordsbefore defining or importing affected modules. The value is the maximum number of records one thread can emit for one atomic target, such as an output array. The default0uses Warp's code-generated estimate. For example, usewp.config.deterministic_max_records = 8when each thread can execute that atomic at most eight times. A bound that is too small raises an overflow error outside CUDA graph capture. Capture and replay cannot report overflows, so size the bound conservatively. Larger bounds allocate more temporary storage and can increase captured-launch work.wp.atomic_cas(),wp.atomic_exch(), and tile atomics are not rewritten. Deterministic CUDA kernels cannot currently run inside conditional body graphs or APIC serialization. See the deterministic execution guide for the full limits.Replay more operations in CPU and saved CUDA graphs
Important
This is an experimental feature. The API may change without a formal deprecation cycle.
CPU graphs can now replay fills, scans, sorts, run-length encoding, sparse topology updates, adjoint launches, reusable recorded launches, and conditional graph nodes. Saved CUDA
.wrpgraphs can now serialize and rebuild supported helper operations, conditional nodes, adjoint launches, and reusablerecord_cmd=Truelaunches (#1431).The captured scan below reads the current contents of
srceach time the graph launches. Changing the input produces a new prefix sum without recapturing the graph.Notable replay limitations:
int32,float32,int64, andfloat64scalar and vector arrays, but not negative strides. Non-contiguous copies and fills, along with the host-return form ofwp.utils.runlength_encode(), are unsupported.wp.utils.runlength_encode(), and CUDAwp.sparse.bsr_set_from_triplets()are unsupported. Stream events and texture array copies are not recorded, and onlywp.Meshobject handles can be serialized.See the runtime guide sections on CPU Graphs and Saving and Loading Graphs for the complete lists of recorded operations and limitations.
Shared CPU and GPU arrays with managed memory
Applications can now allocate CUDA Unified Memory explicitly. These allocations remain CUDA arrays in Warp, while the CUDA driver manages physical page placement and may migrate pages between host memory and CUDA devices as they are accessed. On supported systems, CPU kernels can access them directly.
wp.CudaManagedAllocator()works with the existing allocator scopes, andarray.memory_kindidentifies the allocation aswp.MemoryKind.CUDA_MANAGED(#1523).Direct CPU access depends on the system's managed-memory capabilities, so portable code should check
wp.can_access(). Allocate managed arrays before CUDA graph capture and reuse them inside the graph; Warp does not currently support allocating managed arrays during capture. Managed arrays cannot be exported through CUDA IPC because CUDA does not provide IPC handles forcudaMallocManaged()allocations.Language and kernel programming
Modify values in place with
wp.refUser-defined Warp functions previously received scalar, vector, matrix, quaternion, transform, and struct arguments by value. A helper that changed one of these values had to return it and rely on its caller to assign it back. Functions can now declare
wp.ref[T]parameters to update caller-owned storage directly. This removes the return-and-reassign step from reusable helpers, especially when they update several values (#1277).When calling a function with a
wp.ref[T]parameter, pass writable storage such as a local variable, array element, or struct field. Literals, arithmetic results, function return values, and compile-time constants are rejected because there is no original storage to update.wp.address_of(expr)exposes a raw pointer to the same kinds of writable expressions for C++/CUDA snippets; usearray.ptrfor the base pointer of an entire array. Warp does not automatically differentiate@wp.funchelpers that usewp.ref[T], so declare the calling kernel withenable_backward=False. For differentiable code, define the helper with@wp.func_nativeusing a C++/CUDA snippet and provide its derivative inadj_snippet.Pass Warp functions as arguments
User-defined Warp functions can now accept another Warp function as an argument, so one helper can apply different operations without defining a separate wrapper for each one. Annotate the parameter with
wp.Functionand pass a user-defined@wp.funcor a simple builtin such aswp.sinorwp.sqrt(#1424).The target is chosen when Warp generates the kernel, not while it runs. Warp compiles a specialized version of the helper for each distinct target, so using many target combinations can increase compilation work. Defaults and keyword arguments are supported. Arbitrary Python callables and builtins such as
wp.printfare not valid targets. A helper with awp.Functionparameter cannot also use@wp.func_grador@wp.func_replay.Lean CUDA kernel launches
Performance-sensitive CUDA kernels can now opt out of Warp's grid-stride loop.
@wp.kernel(grid_stride=False)uses a lean launch path with one thread per work item, reducing loop-control overhead and potentially lowering register pressure for lightweight or bandwidth-bound kernels (#1270).Use the
"default_grid_stride": Falsemodule option or setwp.config.default_grid_stride = Falseto opt in more broadly. Grid-stride launches remain the default. Lean kernels support launches of any practical size, but they cannot usemax_blocksto cap the block count. Passingmax_blocks > 0raises an error.Other CUDA kernel controls
@wp.kernel(cluster_dim=...)andwp.get_cuda_max_cluster_dim()expose CUDA Thread Block Clusters to native functions on cluster-capable GPUs (Support Thread Block Cluster group specification #1401).Array utility updates
wp.utils.array_scan()now accepts 64-bit scalar and vector types.wp.utils.radix_sort_pairs()accepts 32-bit and 64-bit signed, unsigned, and floating-point keys with 4-byte or 8-byte values (Extend scan and radix sort type support #1538).Textures and geometry
Mipmap sampling
Important
The texture API is experimental and subject to change without a formal deprecation cycle. Pass texture constructor options by keyword when possible.
Textures can now store a full level-of-detail chain and sample a chosen resolution from Warp kernels. Set
num_mip_levels=0to generate the full chain, or request a fixed number of levels, then passlodtowp.texture_sample()(#1409).Each output element samples the same normalized coordinate at LOD 0, 1, and 2, so
[0.0, 2.5, 7.5]shows how the sampled value changes across the mip chain.Warp builds lower levels from construction data with a 2x box filter. Mipmapped textures are immutable after construction, cannot wrap an external CUDA array, and cannot use surface access. CUDA mipmapped textures also require normalized coordinates.
Expanded cuBQL construction and queries
Important
This is an experimental feature. The API may change without a formal deprecation cycle.
Warp 1.15 expands the experimental cuBQL BVH backend with direct
wp.Bvhconstruction and broader query support. Select it withconstructor="cubql"forwp.Bvhorbvh_constructor="cubql"forwp.Mesh. The resulting structures support AABB, closest-point, furthest-point, and ray queries through Warp's existing query APIs (#1467).Grouped BVHs and meshes are not supported, and
wp.Meshwinding-number queries remain unavailable. A cuBQL BVH also cannot switch to or from another constructor during an in-place rebuild.Tile and sparse programming
Structs in tile operations
Tiles can now contain Warp struct values, so tile kernels no longer need a separate array for each struct field.
wp.tile_map()can process struct elements and broadcast non-tile struct arguments. Struct tiles support field-wise addition and subtraction, reductions, atomic addition, gradients, and use aswp.tile_sort()value payloads (#573).wp.tile_sort()treats structs as value payloads rather than keys, and sorting is forward-only for struct values. Struct tiles do not define a canonicalwp.tile_ones()value, bitwise in-place operations, or ordering reductions.Reserved BSR row capacity
Sparse assembly can now reserve a bounded number of blocks per row, update topology without reallocating the whole matrix, and compact candidate entries in place.
warp.sparse.bsr_zeros(row_capacity=...)creates padded storage,bsr_compress()sorts and coalesces active entries, and matrix status reports whether an operation exceeded its row capacity (#1537).Output:
The
inplace=Truecompression path supportsfloat32andfloat64scalar matrices and is not differentiable. The default out-of-place path remains differentiable.warp.fem.integrate()andwarp.fem.interpolate()can use in-place compression during matrix assembly to reduce peak memory use.Building and debugging from source
CMake source builds
Warp's source tree now includes ready-to-use CMake configuration for parallel and incremental local builds of the native
warpandwarp-clanglibraries (#1495). This optional developer workflow does not build or replace Warp's Python wheels, which remain the primary way to install Warp. See the CMake build documentation.AddressSanitizer for CPU kernels
Source builds can instrument native libraries and JIT-compiled CPU kernels with AddressSanitizer (#1387):
uv run build_lib.py --sanitize=addressRun the target kernel in release mode so Warp's debug bounds assertion does not fire before AddressSanitizer. Linux processes must preload the AddressSanitizer runtime before importing Warp. Standard
pipinstallations are unchanged.Breaking changes
wp.copy()validates offsets, counts, and element sizesWarp now rejects non-integer or negative offsets, a negative
count, and contiguous copies whose source and destination element sizes differ. Warp v1.14 treated a negative count as a request to copy the whole array, which could hide mistakes (#1584).Output:
Native library version mismatches stop initialization
Warp now stops initialization with
RuntimeErrorwhen the Python package version does not matchwarp.dll,warp-clang.dll, or their platform equivalents. Warp previously warned and continued, which could load an incompatible native ABI. Rebuild or reinstall Warp so the native libraries match the Python package (#1508).Announcements
Tentative CUDA 13 PyPI wheel builds
We are tentatively planning to build Warp's PyPI wheels with a CUDA 13.x Toolkit starting with Warp 1.17, currently targeted for September 2026. CUDA Toolkit 13.0 was released in August 2025, more than a year before that target, and we recommend moving to an R580-series or newer NVIDIA driver in advance. If this plan proceeds, R580 will be the minimum driver branch for using Warp's CUDA backend from those wheels.
pipdoes not check the installed driver and can install the wheels on systems with older drivers, but the CUDA backend will not work on those systems. The driver must support the CUDA 13.x family, but it does not need to match the exact CUDA 13.x Toolkit version used to build Warp. See NVIDIA's CUDA minor-version compatibility table.CUDA 12 support will continue beyond Warp 1.17. After the PyPI wheels move to CUDA 13.x, users who need CUDA 12 can build Warp from source or install a pre-built CUDA 12 wheel from GitHub Releases.
Removals in this release
warp.femarguments have been removed. Pass awarp.fem.Quadratureorwarp.fem.GeometryDomainthroughatinstead of the oldquadratureordomainarguments towarp.fem.interpolate(). Usespace_topologyfor partitions andspace_topologyorspace_partitionfor restrictions.warp.render.UsdRenderer.update_body_transforms()method has been removed. It referenced attributes thatUsdRenderernever defined and could not update USD transforms. Use the supported shape-rendering methods to author time-varying USD transforms instead.Upcoming removals
wp.MarchingCubessizing arguments and compatibility attributes are deprecated and scheduled for removal in Warp 1.19. Themax_vertsandmax_trisvalues are retained only for compatibility and do not limit the dynamically sized output arrays. Likewise,devicedoes not select the extraction device. Extraction always uses the input field's device.idno longer identifies a native resource, whileruntimeis not used during extraction. Neither has a replacement. Stop passingmax_verts,max_tris, ordeviceto the constructor, stop passingmax_vertsormax_tristoresize(), and remove accesses to these compatibility attributes (Deprecate legacy MarchingCubes arguments and state #1594).masked=Trueinwarp.sparsetopology-changing operations is deprecated. Passtopology="masked"instead. The old argument will be removed in a future feature release under the standard deprecation timeline (Add 4-array BSR storage with row capacity #1537).Acknowledgments
We also thank the following contributors from outside the core Warp development team:
_warp_fastcallcrash, which informed the removal of fastcall support (Fix/free threaded python fastcall #1578).For a complete list of changes, see the full changelog.
This discussion was created from the release v1.15.0.
Beta Was this translation helpful? Give feedback.
All reactions