Conversation
Add derivative rules for the complex dot products in their cblas `_sub` form (e.g. cblas_zdotc_sub64_), whose result is written through a pointer passed as the last argument instead of being returned. dotc: res = sum(conj(x_i) * y_i) REV: dx += conj(dres)*y, dy += dres*x dotu: res = sum(x_i * y_i) REV: dx += dres*y, dy += dres*x FWD (both): dres = dot(dx, y) + dot(x, dy) To express this in the BLAS tblgen: * new `fpret` argument type for a scalar result returned through a pointer; its shadow provides DiffeRet in reverse mode (and is reset, since the primal overwrote the result) and receives the dual in forward mode. BlasCalls to `*_sub` functions get a result alloca appended and their result loaded back, like the cublas v2 path. * new `BConj` op for the complex conjugate of an fp scalar. * per-pattern `supportsComplex` bit, so the blanket "complex inputs not supported in reverse mode" error only applies to patterns that have not been checked for complex inputs. * complex scalars under the cblas ABI are passed by pointer, so byRefFloat now accounts for that (shared helper for all generators). The result pointer is attributed nocapture but not writeonly: with writeonly, the unused-value analysis drops a local result buffer (e.g. a julia Ref) while keeping the primal call writing to it. nocapture is also no longer applied to non-pointer (integer) vector arguments, which is invalid IR. Assisted-by: Claude Code (Fable 5.1)
vchuravy
marked this pull request as draft
September 15, 2026 14:03
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.
Adds derivative rules for the complex dot products in their cblas
_subform (e.g.cblas_zdotc_sub64_as used by Julia'sBLAS.dotc), whose result is written through a pointer passed as the last argument instead of being returned.dotc_subres = Σ conj(x_i)·y_idx += conj(dres)·y,dy += dres·xdres = dotc(dx,y) + dotc(x,dy)dotu_subres = Σ x_i·y_idx += dres·y,dy += dres·xdres = dotu(dx,y) + dotu(x,dy)All
c/zvariants and suffixes ("",_,64_,_64_) are recognized; the adjoints are emitted ascblas_?axpycalls, and overwritten inputs are cached viacblas_?copy.tblgen changes
fpretargument type for a scalar result returned through a pointer. In reverse mode its shadow providesDiffeRetand is reset afterwards (the primal overwrote the result); in forward mode it receives the dual.BlasCalls to*_subfunctions get a result alloca appended and their result loaded back, mirroring the existing cublas v2 path.BConjop (complex conjugate of an fp scalar, identity for real types).supportsComplexbit: the blanket "complex inputs not yet supported in reverse mode" error now only applies to patterns that have not opted in.byRefFloataccounts for that; the ABI flags are now emitted by one shared helper for all four generators.Utils.cppfor conjugation and for element-aligned load/store of a blas scalar through a pointer that may be passed as an integer (Julia).Notes
nocapturebut deliberately notwriteonly: withwriteonly, the unused-value analysis considers a local result buffer (e.g. a JuliaRef/alloca) unneeded and replaces it with a fictitious phi, while the primal call writing to it is kept. That looks like a general gap incalculateUnusedValuesInFunctionfor calls whose only writes go to unneeded memory; left as is here.nocaptureis no longer applied to integer-typed vector arguments (invalid IR, hit with Julia-stylei64pointers).Testing
New lit tests for both functions in forward and reverse mode (
test/Enzyme/{ForwardMode,ReverseMode}/blas/cblas_zdot{c,u}_sub64_.ll), including the caching path. Verified locally against LLVM 22; the CHECK lines use regexes tolerant of the typed-pointer /nocapturespelling on older LLVM. Also checked by hand thatcblas_cdotc_sub(single precision, 32-bit ints) and the Julia-style form with pointers passed asi64produce the expected code, and that the existingddotderivatives are unchanged.🤖 Generated with Claude Code
https://claude.ai/code/session_01XgNCvikUqowFPsvLWUJqVB