Repository navigation
Conversation
The `UniqueTreeTransformer` is now a single struct-of-arrays used by both the CPU and GPU code paths: `coeffs`, `structs_dst`, `structs_src`, `work_offsets` and `nwork`, with the entries in canonical destination order. The type of the locators is determined by the `SubblockLayout` of either tensor, which is now part of the transformer cache key: `StridedLayout` for `TensorMap`s, where the source strides are permuted by `p` in advance and the destination structure is shared with the space, and `PositionalLayout` for other tensor types, which index `subblocks` by position. The CPU kernel now works on the flat data vector, and the GPU extension moves the host transformer to the device through `Adapt`, replacing `DeviceUniqueTreeTransformer`. The one-tree blocks of the `DeviceGenericTreeTransformer` reuse the same struct. Part of #578. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Store `n + 1` work offsets instead of a separate `nwork`, computed with `cumsum`; the GPU kernel reads the total on the device and launches over the destination length instead. The subblock accessors are now plain `@inline` functions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `GenericTreeTransformer` now reuses the `UniqueTreeTransformer` for its single-tree blocks and stores the multi-tree blocks as concatenated recoupling matrices and locators, together with `tree_offsets`, `coeff_offsets` and `work_offsets` describing each block. The same structure is used on the CPU and, through `Adapt`, on the GPU, replacing `DeviceGenericTreeTransformer`. The CPU kernels now operate on the flat data of a `TensorMap` instead of `StridedSubblocks`, where the permutation is applied when packing the source blocks. Part of #578. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`StridedSubblocks` is no longer used by the index manipulation kernels, which now operate on the flat data of a `TensorMap` with the subblock locations stored in the transformers. Also fix the dense strides of the GPU kernels for subblocks without indices. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #578.
This unifies the CPU and GPU tree transformers into a single data structure per fusion style, while keeping the kernel implementations themselves separate.
Design
Both transformers are structs of arrays of
isbitselements, such that the host version is moved to the GPU withAdapt.adapt. This replacesDeviceUniqueTreeTransformerandDeviceGenericTreeTransformer.UniqueTreeTransformer:coeffs,structs_dst,structs_srcandn + 1work_offsets. The transformation is a bijection between the fusion trees, so the entries are stored in the canonical order of the destination.GenericTreeTransformer: reuses aUniqueTreeTransformerfor the single-tree blocks, and stores the multi-tree blocks as concatenated (square) recoupling matrices and locators, described bytree_offsets,coeff_offsetsandwork_offsets.The type of the locators depends on the
SubblockLayoutof either tensor, which is now part of the transformer cache key:StridedLayout(TensorMap):(sizes, strides, offset)for the destination and(strides, offset)for the source, with the source strides permuted bypin advance. For unique transformers, the destination structure is shared with the space.PositionalLayout(any otherAbstractTensorMap, e.g.DiagonalTensorMap): subblock positions intosubblocks(t), andpis applied in the kernel.The CPU kernels now operate on the flat data vector of a
TensorMapinstead ofStridedSubblocks, which is removed. For the generic transformer, the permutation is now applied when packing the source blocks, such that the unpacking is a trivial strided addition.Benchmarks
Single-threaded
permute!,mainvs this branch, on an exclusive AMD EPYC 7742 (rome) node:Float64andComplexF64across nodes, and are entirely inside the kernel, which performs identical per-block work on both revisions. This is attributed to code layout rather than to the changes here.The multi-threaded behaviour (32 threads) is still under investigation: there, the results vary between 0.66× and 1.65× for tensors with many small subblocks, where
mainalso slows down with more threads.Testing
--fast) CPU test files for index manipulations, diagonal tensors, braiding tensors, planar operations, contractions and construction, pluscuda/tensorsandcuda/planaron an RTX A6000.conjsrc.🤖 Generated with Claude Code