Skip to content

Raise __nv_sinpi/__nv_sinpif in libdevice pass for kernel lowering#2542

Draft
wsmoses with Copilot wants to merge 18 commits into
mainfrom
copilot/add-support-for-sinpi
Draft

Raise __nv_sinpi/__nv_sinpif in libdevice pass for kernel lowering#2542
wsmoses with Copilot wants to merge 18 commits into
mainfrom
copilot/add-support-for-sinpi

Conversation

Copilot AI commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Kernel compilation failed when CUDA emitted llvm.call @__nv_sinpi because libdeviceraise had no rewrite for this symbol. This PR adds explicit raising so sinpi in GPU kernels can be converted into supported math ops during lowering.

  • Raising support in LibDeviceFuncsRaisingPass

    • Added a dedicated SinPiRaising pattern for:
      • __nv_sinpi (f64)
      • __nv_sinpif (f32)
    • Rewrites each call to sin(x * π) using MLIR ops:
      • arith.constant (typed π)
      • arith.mulf
      • math.sin
    • Registered the new pattern in populateLibDeviceFuncsToOpsPatterns.
  • Targeted lit coverage

    • Extended test/lit_tests/raising/libdevice_raise.mlir with a test_module_sinpi case validating both float and double variants raise to mul-by-π + math.sin.
%pi = arith.constant ... : f64
%scaled = arith.mulf %arg, %pi : f64
%out = math.sin %scaled : f64

Copilot AI linked an issue Jun 10, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add support for sinpi in kernels Raise __nv_sinpi/__nv_sinpif in libdevice pass for kernel lowering Jun 10, 2026
Copilot AI requested a review from wsmoses June 10, 2026 04:43
@wsmoses

wsmoses commented Jun 10, 2026

Copy link
Copy Markdown
Member

@copilot

ot/.bazel
INFO: Options provided by the client:
Inherited 'common' options: --isatty=0 --terminal_columns=80
INFO: Reading rc options for 'build' from /__w/Enzyme-JAX/Enzyme-JAX/.bazelrc:
Inherited 'common' options: --noenable_bzlmod --noincompatible_enable_cc_toolchain_resolution --announce_rc --repo_env=USE_PYWRAP_RULES=True --copt=-DGRPC_BAZEL_BUILD --host_copt=-DGRPC_BAZEL_BUILD --action_env=GRPC_BAZEL_RUNTIME=1 --repo_env=PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=upb --action_env=PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=upb --experimental_repo_remote_exec --cxxopt=-Wno-deprecated-declarations --host_cxxopt=-Wno-deprecated-declarations --cxxopt=-Wno-sign-compare --host_cxxopt=-Wno-sign-compare --cxxopt=-Wno-array-bounds --host_cxxopt=-Wno-array-bounds --cxxopt=-Wno-comment --host_cxxopt=-Wno-comment --cxxopt=-Wno-invalid-constexpr --host_cxxopt=-Wno-invalid-constexpr --cxxopt=-Wno-mismatched-new-delete --host_cxxopt=-Wno-mismatched-new-delete --cxxopt=-Wno-unused-but-set-parameter --host_cxxopt=-Wno-unused-but-set-parameter --cxxopt=-Wno-unused-but-set-variable --host_cxxopt=-Wno-unused-but-set-variable --cxxopt=-Wno-misleading-indentation --host_cxxopt=-Wno-misleading-indentation --cxxopt=-Wno-return-type --host_cxxopt=-Wno-return-type --cxxopt=-Wno-unused-function --host_cxxopt=-Wno-unused-function --cxxopt=-Wno-parentheses --host_cxxopt=-Wno-parentheses --cxxopt=-Wno-unused-local-typedefs --host_cxxopt=-Wno-unused-local-typedefs --cxxopt=-Wno-reorder --host_cxxopt=-Wno-reorder --cxxopt=-Wno-missing-braces --host_cxxopt=-Wno-missing-braces --cxxopt=-Wno-range-loop-construct --host_cxxopt=-Wno-range-loop-construct --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 --color=yes --define=grpc_no_ares=true --define=tsl_link_protobuf=true --define open_source_build=true --define framework_shared_object=true --define tsl_protobuf_header_only=true --define=allow_oversize_protos=true
INFO: Reading rc options for 'build' from /__w/Enzyme-JAX/Enzyme-JAX/.bazelrc:
'build' options: --@rules_python//python/config_settings:precompile=force_disabled -c opt
INFO: Found applicable config definition common:public_cache_push in file /__w/Enzyme-JAX/Enzyme-JAX/.bazelrc: --config=public_cache --remote_upload_local_results=true --google_default_credentials
INFO: Found applicable config definition common:public_cache in file /__w/Enzyme-JAX/Enzyme-JAX/.bazelrc: --remote_cache=https://storage.googleapis.com/enzyme-presubmit-bazel-cache/ --remote_upload_local_results=false
Computing main repo mapping:
WARNING: option '--remote_upload_local_results' was expanded to from both option '--config=public_cache_push' (source command line options) and option '--config=public_cache_push' (source command line options)
Loading:
Loading: 0 packages loaded
Analyzing: target //:enzymexlamlir-opt (1 packages loaded, 0 targets configured)
Analyzing: target //:enzymexlamlir-opt (1 packages loaded, 0 targets configured)

DEBUG: Rule 'cuda_tile' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-YBqJhzobmsmk4EAMPss513cnk2+qgud2uJz2qf6BeFk="
DEBUG: Repository cuda_tile instantiated at:
/__w/Enzyme-JAX/Enzyme-JAX/WORKSPACE:346:20: in
/__w/Enzyme-JAX/Enzyme-JAX/third_party/cuda_tile/workspace.bzl:16:17: in repo
Repository rule http_archive defined at:
/root/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:400:31: in
DEBUG: Rule 'enzyme' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-cMEBORhThaDLipZcFoHqMeEhbDLqCL2HcXL7poI2fSY="
DEBUG: Repository enzyme instantiated at:
/__w/Enzyme-JAX/Enzyme-JAX/WORKSPACE:344:17: in
/__w/Enzyme-JAX/Enzyme-JAX/third_party/enzyme/workspace.bzl:13:21: in repo
Repository rule http_archive defined at:
/root/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:400:31: in
Analyzing: target //:enzymexlamlir-opt (118 packages loaded, 9242 targets configured)

INFO: Analyzed target //:enzymexlamlir-opt (158 packages loaded, 15955 targets configured).
[2,251 / 8,817] Compiling absl/hash/internal/city.cc; 0s remote-cache ... (32 actions, 0 running)
INFO: From Compiling hwloc/memattrs.c:
external/hwloc/hwloc/memattrs.c:770:9: warning: unused variable 'err' [-Wunused-variable]
770 | int err = from_internal_location(&imi->initiator, &initiators[i]);
| ^~~
| ^
external/shardy/shardy/dialect/sdy/transforms/propagation/basic_propagation.h:55:34: note: default constructor of 'BasicPropagationPassImpl' is implicitly deleted because base class 'OperationPass' has no default constructor
55 | class BasicPropagationPassImpl : public OperationPass {
| ^
external/shardy/shardy/dialect/sdy/transforms/propagation/basic_propagation.h:59:32: note: replace 'default' with 'delete'
59 | BasicPropagationPassImpl() = default;
| ^~~~~~~
| delete
1 warning generated.
INFO: From Compiling third_party/nvidia/lib/TritonNVIDIAGPUToLLVM/TensorMemoryToLLVM.cpp:
external/triton/third_party/nvidia/lib/TritonNVIDIAGPUToLLVM/TensorMemoryToLLVM.cpp:361:21: warning: lambda capture 'kRow' is not used [-Wunused-lambda-capture]
361 | auto getRowCol = [kRow, kCol](const auto &rowCol) {
| ^~~~~
external/triton/third_party/nvidia/lib/TritonNVIDIAGPUToLLVM/TensorMemoryToLLVM.cpp:361:27: warning: lambda capture 'kCol' is not used [-Wunused-lambda-capture]
361 | auto getRowCol = [kRow, kCol](const auto &rowCol) {
| ~~^~~~
2 warnings generated.
INFO: From Compiling src/enzyme_ad/jax/Passes/ConvertPolygeistToLLVM.cpp:
src/enzyme_ad/jax/Passes/ConvertPolygeistToLLVM.cpp:2651:8: warning: private field 'kernelBarePtrCallConv' is not used [-Wunused-private-field]
2651 | bool kernelBarePtrCallConv;
| ^
1 warning generated.
INFO: From Compiling third_party/amd/lib/TritonAMDGPUToLLVM/SchedInstructions.cpp:
external/triton/third_party/amd/lib/TritonAMDGPUToLLVM/SchedInstructions.cpp:99:11: warning: private field 'numStages' is not used [-Wunused-private-field]
99 | int32_t numStages;
| ^
1 warning generated.
[8,852 / 8,884] Compiling src/enzyme_ad/jax/Passes/LLVMToMemrefAccess.cpp; 0s remote-cache ... (31 actions, 0 running)
[8,882 / 8,884] [Sched] Compiling src/enzyme_ad/jax/Passes/LibDeviceFuncsRaisingPass.cpp; Downloading external/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUGenRegisterInfoTargetDesc.inc, 56.8 MiB / 107.4 MiB
[8,882 / 8,884] Compiling src/enzyme_ad/jax/Passes/LibDeviceFuncsRaisingPass.cpp; 0s remote-cache, processwrapper-sandbox
[8,882 / 8,884] Compiling src/enzyme_ad/jax/Passes/LibDeviceFuncsRaisingPass.cpp; 11s remote-cache, processwrapper-sandbox
ERROR: /__w/Enzyme-JAX/Enzyme-JAX/src/enzyme_ad/jax/BUILD:1164:11: Compiling src/enzyme_ad/jax/Passes/LibDeviceFuncsRaisingPass.cpp failed: (Exit 1): clang failed: error executing CppCompile command (from target //src/enzyme_ad/jax:XLADerivatives) /usr/lib/llvm-18/bin/clang -U_FORTIFY_SOURCE -fstack-protector -Wall -Wthread-safety -Wself-assign -Wunused-but-set-parameter -Wno-free-nonheap-object -fcolor-diagnostics -fno-omit-frame-pointer -g0 ... (remaining 631 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
src/enzyme_ad/jax/Passes/LibDeviceFuncsRaisingPass.cpp:462:35: error: no member named 'getPi' in 'llvm::APFloat'
462 | floatType, llvm::APFloat::getPi(floatType.getFloatSemantics()));
| ~~~~~~~~~~~~~~~^
1 error generated.
Target //:enzymexlamlir-opt failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 48.643s, Critical Path: 18.83s
INFO: 8883 processes: 6228 remote cache hit, 2655 internal.
ERROR: Build did NOT complete successfully

Copilot AI commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot

ot/.bazel
...

Fixed in 64d1953. I traced the CI failure to APFloat::getPi not being available in the LLVM version used by CI and updated SinPiRaising to use LLVM18-compatible, semantics-aware APFloat construction for the f32/f64 π constants.

Copilot AI requested a review from wsmoses June 10, 2026 20:15
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 25.46%. Comparing base (970aad9) to head (64d1953).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2542      +/-   ##
==========================================
- Coverage   25.66%   25.46%   -0.21%     
==========================================
  Files         223      223              
  Lines       44823    44669     -154     
==========================================
- Hits        11506    11375     -131     
+ Misses      33317    33294      -23     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wsmoses

wsmoses commented Jun 22, 2026

Copy link
Copy Markdown
Member

@copilot

[17,595 / 17,734] 911 / 1050 tests, 2 failed; Testing //test/lit_tests:raising_affine_to_stablehlo_gu.mlir.test; 6s remote-cache, processwrapper-sandbox ... (32 actions, 31 running)
FAIL: //test/lit_tests:raising_libdevice_raise.mlir.test (see /root/.bazel/execroot/__main__/bazel-out/k8-dbg/testlogs/test/lit_tests/raising_libdevice_raise.mlir.test/test.log)
INFO: From Testing //test/lit_tests:raising_libdevice_raise.mlir.test:
==================== Test output for //test/lit_tests:raising_libdevice_raise.mlir.test:
-- Testing: 1 tests, 1 workers --
FAIL: Enzyme-JaX :: lit_tests/raising/libdevice_raise.mlir (1 of 1)
******************** TEST 'Enzyme-JaX :: lit_tests/raising/libdevice_raise.mlir' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
enzymexlamlir-opt --libdevice-funcs-raise /root/.bazel/sandbox/processwrapper-sandbox/15960/execroot/__main__/bazel-out/k8-dbg/bin/test/lit_tests/raising_libdevice_raise.mlir.test.runfiles/__main__/test/lit_tests/raising/libdevice_raise.mlir | FileCheck /root/.bazel/sandbox/processwrapper-sandbox/15960/execroot/__main__/bazel-out/k8-dbg/bin/test/lit_tests/raising_libdevice_raise.mlir.test.runfiles/__main__/test/lit_tests/raising/libdevice_raise.mlir # RUN: at line 1
+ enzymexlamlir-opt --libdevice-funcs-raise /root/.bazel/sandbox/processwrapper-sandbox/15960/execroot/__main__/bazel-out/k8-dbg/bin/test/lit_tests/raising_libdevice_raise.mlir.test.runfiles/__main__/test/lit_tests/raising/libdevice_raise.mlir
+ FileCheck /root/.bazel/sandbox/processwrapper-sandbox/15960/execroot/__main__/bazel-out/k8-dbg/bin/test/lit_tests/raising_libdevice_raise.mlir.test.runfiles/__main__/test/lit_tests/raising/libdevice_raise.mlir
/root/.bazel/sandbox/processwrapper-sandbox/15960/execroot/__main__/bazel-out/k8-dbg/bin/test/lit_tests/raising_libdevice_raise.mlir.test.runfiles/__main__/test/lit_tests/raising/libdevice_raise.mlir:247:12: error: CHECK: expected string not found in input
 // CHECK: %[[PI_F64:.*]] = arith.constant {{.*}} : f64
           ^
<stdin>:232:24: note: scanning from here
 %2 = math.sin %1 : f32
                       ^
<stdin>:234:2: note: possible intended match here
 %4 = math.sin %3 : f64
 ^

Input file: <stdin>
Check file: /root/.bazel/sandbox/processwrapper-sandbox/15960/execroot/__main__/bazel-out/k8-dbg/bin/test/lit_tests/raising_libdevice_raise.mlir.test.runfiles/__main__/test/lit_tests/raising/libdevice_raise.mlir

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             .
             .
             .
           227:  llvm.func @gpu_sinpi(%arg0: f32, %arg1: f64) -> !llvm.struct<(f32, f64)> attributes {llvm.emit_c_interface} { 
           228:  %cst = arith.constant 3.1415926535897931 : f64 
           229:  %0 = llvm.mlir.undef : !llvm.struct<(f32, f64)> 
           230:  %cst_0 = arith.constant 3.14159274 : f32 
           231:  %1 = arith.mulf %arg0, %cst_0 : f32 
           232:  %2 = math.sin %1 : f32 
check:247'0                            X error: no match found
           233:  %3 = arith.mulf %arg1, %cst : f64 
check:247'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           234:  %4 = math.sin %3 : f64 
check:247'0     ~~~~~~~~~~~~~~~~~~~~~~~~
check:247'1      ?                       possible intended match
           235:  %5 = llvm.insertvalue %2, %0[0] : !llvm.struct<(f32, f64)>  
check:247'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           236:  %6 = llvm.insertvalue %4, %5[1] : !llvm.struct<(f32, f64)>  
check:247'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           237:  llvm.return %6 : !llvm.struct<(f32, f64)> 
check:247'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           238:  } 
check:247'0     ~~~
           239:  } 
check:247'0     ~~~
             .
             .
             .
>>>>>>

Copilot AI commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot

[17,595 / 17,734] 911 / 1050 tests, 2 failed; Testing //test/lit_tests:raising_affine_to_stablehlo_gu.mlir.test; 6s remote-cache, processwrapper-sandbox ... (32 actions, 31 running)

...

Fixed in 6177477. I updated the gpu_sinpi lit checks to be order-robust for independent f32/f64 pi constants (CHECK-DAG) while keeping ordered CHECK assertions for each dependent mul→sin chain, which matches the observed lowering output and avoids the CI mismatch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for sinpi in kernels

2 participants