Skip to content

nvcc with MSVC as host compiler (Windows) can't compile stdexec: compiler detection takes the nvcc branch and skips the MSVC settings #2402

Open

Description

@hkaiser

With nvcc on Windows (MSVC as host compiler), even a minimal program fails to compile at current main (1d58877). We ran into this while building HPX with CUDA on Windows.

Versions: CUDA 13.0 (nvcc V13.0.88), MSVC 19.44.35229 (VS 2022 17.14, x64), Windows 11. CUDA 13.0 doesn't accept MSVC 19.52 (VS 18) as host compiler.

// nvcc_msvc.cu
#include <stdexec/execution.hpp>

int main()
{
    auto s = stdexec::just(41) | stdexec::then([](int i) { return i + 1; });
    auto [v] = stdexec::sync_wait(std::move(s)).value();
    return v == 42 ? 0 : 1;
}
nvcc -std=c++20 -Xcompiler=-Zc:__cplusplus -Xcompiler=-Zc:preprocessor -Xcompiler=/EHsc --extended-lambda --expt-relaxed-constexpr -arch=sm_89 -I stdexec/include nvcc_msvc.cu

(-Zc:__cplusplus and -Zc:preprocessor are needed to get past the C++20 check and the preprocessor check in __config.hpp.)

Output (paths shortened, repeated lines removed):

include/stdexec/__detail/__meta.hpp(168): error: declaration is incompatible with variable template "stdexec::__pack::__mk_indices" (declared at line 163)
include/stdexec/__detail/__connect.hpp(83): error: declaration is incompatible with variable template "stdexec::__connect::__connect_declfn_v" (declared at line 77)
include/stdexec/__detail/__connect.hpp(90): error: declaration is incompatible with variable template "stdexec::__connect::__connect_declfn_v" (declared at line 77)
include/stdexec/__detail/__connect.hpp(103): error: declaration is incompatible with variable template "stdexec::__connect::__connect_declfn_v" (declared at line 97)
include/stdexec/__detail/__connect.hpp(110): error: declaration is incompatible with variable template "stdexec::__connect::__connect_declfn_v" (declared at line 97)
include/stdexec/__detail/__spin_loop_pause.hpp(48): error: identifier "__builtin_ia32_pause" is undefined
include/stdexec/__detail/__transform_completion_signatures.hpp(360): error: type name is not allowed
include/stdexec/__detail/__transform_completion_signatures.hpp(360): error: too many initializer values
include/stdexec/__detail/__transform_completion_signatures.hpp(400): error: type name is not allowed
include/stdexec/__detail/__transform_completion_signatures.hpp(400): error: too many initializer values
include/stdexec/__detail/__sync_wait.hpp(353): error: no instance of function template "stdexec::connect_t::operator()" matches the argument list
include/stdexec/__detail/__sync_wait.hpp(355): error: static assertion failed with "..."
nvcc_msvc.cu(6): error: expression must have class type but it has type "void"
15 errors detected in the compilation of "nvcc_msvc.cu".

The cause seems to be the compiler detection in __config.hpp: the __NVCC__ branch comes first, so with an MSVC host neither STDEXEC_MSVC() nor STDEXEC_MSVC_HEADERS() is ever set, although _MSC_VER is defined and the MSVC standard library is used. As a result:

  • __spin_loop_pause() takes the GCC branch (__builtin_ia32_pause()) instead of _mm_pause() from <intrin.h>.
  • __make_indices falls back to the extern variable template partial specializations (__mk_indices), and __connect.hpp uses the __connect_declfn_v specializations instead of the function-based version it already has for MSVC. nvcc's front end in MSVC mode rejects both ("declaration is incompatible with variable template").
  • After the front end, cl compiles nvcc's preprocessed output (.cudafe1.cpp). The macros were already expanded with __NVCC__ defined, so the MSVC workarounds keyed on STDEXEC_MSVC() are missing there too.

What we tried in a local copy of 04de75d (the revision HPX uses today, which fails with the same __mk_indices and __builtin_ia32_pause errors): setting STDEXEC_MSVC_HEADERS() to 1 in the nvcc branch when _MSC_VER is defined fixes the __builtin_ia32_pause error, and using std::make_index_sequence for __make_indices fixes the __mk_indices error. With HPX's CUDA test files, and with the MSVC __msplice_helper variant enabled for nvcc as well, the front end then gets through, but cl fails on the .cudafe1.cpp file: first an internal compiler error (C1001) at __typeinfo.hpp(289), then errors such as C7571 (enable_sender: variable template has already been initialized) at __execution_fwd.hpp(287) and C7608 (atomic constraint should be a constant expression) at __sender_concepts.hpp(131) and __sender_introspection.hpp(259). So it takes more than a few local fixes, and the MSVC code paths would have to apply to both nvcc's front end and the host compilation.

Is nvcc with an MSVC host meant to be supported? If yes, would a separate STDEXEC_NVCC_MSVC_HOST() (or setting STDEXEC_MSVC_HEADERS() and the MSVC workarounds whenever _MSC_VER is defined) be the direction you'd want? If not, it would help to say so in the README and to fail early with an #error, so users don't get errors from deep inside the library.

Activity

  1. hkaiser commented on Nov 2, 2026

    @hkaiser
    Author

    A correction after testing on Linux: only part of this is specific to an MSVC host. With nvcc 13.0 (V13.0.48) and GCC 13.3 or GCC 12.4 as host compiler (nvidia/cuda:13.0.0-devel-ubuntu24.04), the same minimal program fails at 1d58877 with the same errors in __connect.hpp (__connect_declfn_v), __transform_completion_signatures.hpp, __sync_wait.hpp, and additionally in __receiver_adaptor.hpp(125) and __typeinfo.hpp(101). So those come from nvcc's front end in general, and I opened #2403 for them.

    What stays specific to Windows is the compiler detection described above: __builtin_ia32_pause (because STDEXEC_MSVC_HEADERS() is not set for nvcc with an MSVC host), the __mk_indices error (not seen on Linux), and the MSVC workarounds missing from the host compilation of nvcc's output.

  2. ericniebler commented on Nov 2, 2026

    @ericniebler
    Collaborator

    Hi Hartmut, as stated by the README, nvcc is not supported. For CUDA support, you need to use NVIDIA's HPC compiler or clang.

  3. hkaiser commented on Nov 2, 2026

    @hkaiser
    Author

    Hi Hartmut, as stated by the README, nvcc is not supported. For CUDA support, you need to use NVIDIA's HPC compiler or clang.

    Eric, I thought I could convince you otherwise ;-) In any case, thanks!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions