danielamadori opened a new issue, #822:
URL: https://github.com/apache/tvm-ffi/issues/822

   ### Summary
   
   On Windows, `_generate_ninja_build` emits a CUDA build line that `nvcc` 
refuses, and a link line that cannot resolve the CUDA runtime. Four separate 
problems in the same `if IS_WINDOWS:` branch of 
`python/tvm_ffi/cpp/extension.py`; each one is only reachable after the 
previous is fixed, which is why they are reported together.
   
   The Linux branch of the same function is correct in every one of these 
places.
   
   Measured with **apache-tvm-ffi 0.1.13.post3**, CUDA 12.6, MSVC, Windows 11. 
**0.1.14.post1 carries the identical code** in all four places, so upgrading 
does not help.
   
   ### 1. `-Xcompiler` takes a single argument, so `/O2` becomes an input file
   
   ```python
   default_cuda_cflags = ["-Xcompiler", "/std:c++17", "/O2"]
   ```
   
   `-Xcompiler` forwards **one** argument to the host compiler. `nvcc` hands 
`/std:c++17` to `cl.exe` and is left holding `/O2`, which it reads as a second 
input file:
   
   ```
   nvcc fatal : A single input file is required for a non-link phase when an 
outputfile is specified
   ```
   
   Minimal reproduction, with a `.cu` containing only `__global__ void k(){}`:
   
   ```
   > nvcc -Xcompiler /std:c++17 /O2 -c k.cu -o k.obj
   nvcc fatal : A single input file is required for a non-link phase when an 
outputfile is specified
   
   > nvcc -Xcompiler /std:c++17,/O2 -c k.cu -o k.obj
   (passes argument analysis)
   ```
   
   Suggested fix: `["-Xcompiler", "/std:c++17,/O2"]`, or two separate 
`-Xcompiler` groups.
   
   ### 2. that `/std:c++17` then overrides a caller asking for C++20
   
   Not a defect on its own, but worth knowing because it bites immediately 
after fixing (1). `nvcc` places its own `-std=` on the host line **first** and 
every `-Xcompiler` group **after**, so tvm-ffi's `/std:c++17` ends up the last 
`/std:` on `cl`'s command line and wins over `extra_cuda_cflags` passed by the 
caller. Headers that need C++20 (`<concepts>`, `<source_location>`) then fail 
with `C2039`.
   
   A caller can work around it by appending `-Xcompiler 
/std:c++20,/Zc:__cplusplus` (the `/Zc:__cplusplus` is needed because MSVC 
otherwise reports `__cplusplus` as `199711L` even when compiling C++20, and 
`<source_location>` is guarded on that), but a default that silently downgrades 
the caller's language standard is surprising.
   
   ### 3. the CUDA runtime library is never linked on Windows
   
   `cudart` appears exactly once in `extension.py`, inside the non-Windows 
branch:
   
   ```python
   if with_cuda:
       default_ldflags += [
           "-L{}".format(str(Path(_find_cuda_home()) / "lib64")),
           "-lcudart",
       ]
   ```
   
   The Windows branch sets `default_ldflags` and never adds a CUDA library path 
or the runtime, so the link fails on the symbols that live in it:
   
   ```
   cuda_0.o : error LNK2019: unresolved external symbol __cudaRegisterFatBinary
   cuda_0.o : error LNK2019: unresolved external symbol 
__cudaRegisterFatBinaryEnd
   cuda_0.o : error LNK2019: unresolved external symbol 
__cudaUnregisterFatBinary
   cuda_0.o : error LNK2019: unresolved external symbol __cudaRegisterFunction
   <module>.dll : fatal error LNK1120: 8 unresolved externals
   ```
   
   Suggested fix, in the Windows branch:
   
   ```python
   if with_cuda:
       default_ldflags += [
           '/LIBPATH:"{}"'.format(Path(_find_cuda_home()) / "lib" / "x64"),
           "cudart.lib",
       ]
   ```
   
   Note `lib/x64`, not `lib64`: on a Windows CUDA install 
`v12.6/lib/x64/cudart.lib` exists and `v12.6/lib64` does not.
   
   ### 4. `/LIBPATH:` is not quoted, and the default CUDA path contains a space
   
   With (3) applied but unquoted, the linker splits the standard CUDA location 
`C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6` on its space:
   
   ```
   LINK : fatal error LNK1181: cannot open input file 'Files\NVIDIA.obj'
   ```
   
   The same applies to the existing `f"/LIBPATH:{tvm_ffi_lib_path}"` one line 
above. That one has never been observed failing, because the path lives inside 
the virtualenv — but it would fail the same way on a machine whose user name 
contains a space. Quoting a path that has no spaces is harmless, so both are 
worth quoting.
   
   ### What works after all four
   
   With the four fixed, a CUDA kernel built through `load_inline` compiles, 
links and loads on Windows, and the engine using it serves generations normally.
   
   ### Environment
   
   ```
   apache-tvm-ffi  0.1.13.post3   (0.1.14.post1 identical in these four places)
   CUDA            12.6
   OS              Windows 11
   compiler        MSVC (cl.exe), nvcc 12.6
   GPU             NVIDIA RTX 3050 Laptop (sm_86)
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to