Skip to content

Fix Windows CUDA build: don't pass /openmp:experimental to nvcc - #93

Merged
0xShug0 merged 1 commit into
0xShug0:mainfrom
CaptainArni:fix/cuda-openmp-flag-msvc
Jul 23, 2026
Merged

Fix Windows CUDA build: don't pass /openmp:experimental to nvcc#93
0xShug0 merged 1 commit into
0xShug0:mainfrom
CaptainArni:fix/cuda-openmp-flag-msvc

Conversation

@CaptainArni

Copy link
Copy Markdown
Contributor

Problem

A CUDA release build on Windows/MSVC (scripts/build_windows.ps1 -Preset windows-cuda-release) fails to compile the two CUDA sources in engine_runtime:

FAILED: CMakeFiles/engine_runtime.dir/src/framework/sampling/torch_random_cuda_runtime.cu.obj
nvcc fatal   : A single input file is required for a non-link phase when an outputfile is specified
FAILED: CMakeFiles/engine_runtime.dir/src/framework/audio/istft_cuda_runtime.cu.obj
nvcc fatal   : A single input file is required for a non-link phase when an outputfile is specified

Reproduced on latest main (365b4f6) with CUDA 13.3 + MSVC (VS 2022/18).

Cause

CMakeLists.txt adds the MSVC OpenMP flag to engine_runtime unconditionally:

target_compile_options(engine_runtime PRIVATE /openmp:experimental)

engine_runtime also compiles CUDA sources (istft_cuda_runtime.cu, torch_random_cuda_runtime.cu), so this flag is applied to their nvcc invocations too. The generated compile line for a .cu object ends with a bare /openmp:experimental:

FLAGS = -Xcompiler=/utf-8 -Xcompiler="-O2 -Ob2" -DNDEBUG -std=c++17 \
        "--generate-code=arch=compute_120a,code=[sm_120a]" -Xcompiler=-MD /openmp:experimental

nvcc does not recognize /openmp:experimental and does not forward it to the host compiler (-forward-unknown-to-host-compiler only forwards --prefixed unknowns, not /-prefixed ones). It therefore parses the token as a second input file, and aborts because an output file is already specified — hence the nvcc fatal above.

Note: passing -DOpenMP_CUDA_FLAGS=/openmp:experimental in build_windows.ps1 does not help, because the offending flag does not come from an OpenMP::OpenMP_CUDA target — it is the hard-coded target_compile_options line, which lands on every language in the target.

Fix

Guard the flag on the C++ language so it never reaches nvcc:

target_compile_options(engine_runtime PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/openmp:experimental>)

The OpenMP 4.0 SIMD pragmas in the C++ sources (e.g. longformer_attention.cpp) still receive the flag; the .cu files no longer do.

Verification

  • Before: engine_runtime build fails at the two .cu objects with nvcc fatal (above).
  • After: reconfigured and rebuilt engine_runtime on the windows-cuda-release preset — both CUDA objects compile and the target builds to completion (CUDA 13.3, MSVC, RTX 5090 / sm_120a).

engine_runtime compiles both C++ and CUDA sources, but the MSVC
OpenMP flag was added to the whole target unconditionally:

    target_compile_options(engine_runtime PRIVATE /openmp:experimental)

nvcc does not recognize /openmp:experimental and does not forward a
/-prefixed unknown to the host compiler, so it treats the token as a
second input file and aborts:

    nvcc fatal : A single input file is required for a non-link phase
    when an outputfile is specified

Guard the flag on COMPILE_LANGUAGE:CXX so only the C++ sources (which
need it for their OpenMP 4.0 SIMD pragmas) receive it, and the .cu
files no longer do.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@0xShug0
0xShug0 merged commit 9202d30 into 0xShug0:main Jul 23, 2026
4 checks passed
@0xShug0

0xShug0 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

@CaptainArni Merged. Thank you!

0xShug0 added a commit that referenced this pull request Jul 23, 2026
engine_runtime compiles both C++ and CUDA sources, but the MSVC
OpenMP flag was added to the whole target unconditionally:

    target_compile_options(engine_runtime PRIVATE /openmp:experimental)

nvcc does not recognize /openmp:experimental and does not forward a
/-prefixed unknown to the host compiler, so it treats the token as a
second input file and aborts:

    nvcc fatal : A single input file is required for a non-link phase
    when an outputfile is specified

Guard the flag on COMPILE_LANGUAGE:CXX so only the C++ sources (which
need it for their OpenMP 4.0 SIMD pragmas) receive it, and the .cu
files no longer do.
dleiferives pushed a commit to dleiferives/audio.cpp that referenced this pull request Jul 25, 2026
…ug0#93)

engine_runtime compiles both C++ and CUDA sources, but the MSVC
OpenMP flag was added to the whole target unconditionally:

    target_compile_options(engine_runtime PRIVATE /openmp:experimental)

nvcc does not recognize /openmp:experimental and does not forward a
/-prefixed unknown to the host compiler, so it treats the token as a
second input file and aborts:

    nvcc fatal : A single input file is required for a non-link phase
    when an outputfile is specified

Guard the flag on COMPILE_LANGUAGE:CXX so only the C++ sources (which
need it for their OpenMP 4.0 SIMD pragmas) receive it, and the .cu
files no longer do.
Anc813 pushed a commit to Anc813/audio.cpp that referenced this pull request Jul 25, 2026
…ug0#93)

engine_runtime compiles both C++ and CUDA sources, but the MSVC
OpenMP flag was added to the whole target unconditionally:

    target_compile_options(engine_runtime PRIVATE /openmp:experimental)

nvcc does not recognize /openmp:experimental and does not forward a
/-prefixed unknown to the host compiler, so it treats the token as a
second input file and aborts:

    nvcc fatal : A single input file is required for a non-link phase
    when an outputfile is specified

Guard the flag on COMPILE_LANGUAGE:CXX so only the C++ sources (which
need it for their OpenMP 4.0 SIMD pragmas) receive it, and the .cu
files no longer do.
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.

2 participants