Skip to content

Commit 16e6871

Browse files
FgoDtalihassanijr
andauthored
Add MSVC support (#118)
Adds support for Windows builds with MSVC! --------- Co-authored-by: Ali Hassani <alih@gatech.edu>
1 parent 85374b0 commit 16e6871

7 files changed

+158
-16
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,6 @@ dmypy.json
133133

134134
# Output files
135135
*.out
136+
137+
# MSVC
138+
.vs/

WindowsBuilder.bat

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
@ECHO off
2+
3+
if [%1] == [test] shift & goto :test
4+
if [%1] == [install] shift & goto :install
5+
if [%1] == [clean] shift & goto :clean
6+
7+
:parseArgs
8+
if [%1] == [WORKERS] set NATTEN_N_WORKERS=%2 & shift & shift & goto :parseargs
9+
if [%1] == [CUDA_ARCH] set NATTEN_CUDA_ARCH=%2 & shift & shift & goto :parseargs
10+
if [%1] == [VERBOSE] set NATTEN_VERBOSE=%2 & shift & shift & goto :parseargs
11+
goto :installContinue
12+
:end
13+
14+
:test
15+
echo "Testing NATTEN"
16+
pip install -r requirements-dev.txt
17+
pytest -v -x ./tests
18+
goto :eof
19+
:end
20+
21+
:install
22+
goto :installStart
23+
:end
24+
25+
:installStart
26+
goto :parseargs
27+
:end
28+
29+
:installFinalize
30+
set NATTEN_N_WORKERS=
31+
set NATTEN_CUDA_ARCH=
32+
set NATTEN_VERBOSE=
33+
goto :eof
34+
:end
35+
36+
:installContinue
37+
echo NATTEN_N_WORKERS: %NATTEN_N_WORKERS%
38+
echo NATTEN_CUDA_ARCH: %NATTEN_CUDA_ARCH%
39+
echo NATTEN_VERBOSE: %NATTEN_VERBOSE%
40+
pip install -r requirements.txt
41+
python setup.py install
42+
goto :installFinalize
43+
:end
44+
45+
:clean
46+
echo Cleaning up
47+
echo "Removing %CD%\build"
48+
del %CD%\build
49+
goto :eof
50+
:end

csrc/CMakeLists.txt

+18-2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,17 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
9797
set(CMAKE_CUDA_FLAGS_RELEASE "${CMAKE_CUDA_FLAGS_RELEASE} -Xcompiler -O3")
9898
set(CMAKE_CUDA_FLAGS_RELEASE "${CMAKE_CUDA_FLAGS_RELEASE} --use_fast_math")
9999

100+
101+
if(${NATTEN_IS_WINDOWS})
102+
# Copied from xformers
103+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Zc:lambda /Zc:preprocessor")
104+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler /Zc:lambda -Xcompiler /Zc:preprocessor")
105+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP /Zc:lambda /Zc:preprocessor")
106+
set(CMAKE_CUDA_FLAGS_DEBUG "-Xcompiler /Zc:lambda -Xcompiler /Zc:preprocessor")
107+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MP /Zc:lambda /Zc:preprocessor")
108+
set(CMAKE_CUDA_FLAGS_RELEASE "${CMAKE_CUDA_FLAGS_RELEASE} -Xcompiler /Zc:lambda -Xcompiler /Zc:preprocessor")
109+
endif()
110+
100111
message("CMAKE_CUDA_FLAGS_RELEASE: ${CMAKE_CUDA_FLAGS_RELEASE}")
101112
if(${NATTEN_WITH_CUDA})
102113
message("CUDA compiler: " ${CMAKE_CUDA_COMPILER})
@@ -179,6 +190,11 @@ include_directories(${COMMON_HEADER_DIRS})
179190
# Find torch lib dir so we can link with libtorch
180191
link_directories("${TORCH_DIR}/lib/")
181192

193+
# Windows builds require linking with python*.lib
194+
if(NATTEN_IS_WINDOWS)
195+
link_directories("${PY_LIB_DIR}")
196+
endif()
197+
182198
add_library(natten SHARED ${ALL_SOURCES})
183199

184200
set_target_properties(natten PROPERTIES PREFIX "" OUTPUT_NAME ${OUTPUT_FILE_NAME})
@@ -193,7 +209,7 @@ if(${NATTEN_IS_MAC})
193209
endif()
194210

195211
if(${NATTEN_WITH_CUDA})
196-
target_link_libraries(natten PUBLIC "-lc10 -ltorch -ltorch_cpu -ltorch_python -lcudart -lc10_cuda -ltorch_cuda")
212+
target_link_libraries(natten PUBLIC c10 torch torch_cpu torch_python cudart c10_cuda torch_cuda)
197213
else()
198-
target_link_libraries(natten PUBLIC "-lc10 -ltorch -ltorch_cpu -ltorch_python")
214+
target_link_libraries(natten PUBLIC c10 torch torch_cpu torch_python)
199215
endif()

docs/install.md

+56-6
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,10 @@ We plan to port our naive kernels to metal soon, but we certainly welcome contri
2222

2323
### Windows
2424

25-
NATTEN does not support Windows builds yet.
26-
This leaves Windows users with only one option: WSL.
25+
NATTEN does not come with Windows releases yet, but you can build it from source.
26+
If you're using WSL, please follow the same steps as building for Linux below.
2727

28-
Since [switching to cmake](https://github.com/SHI-Labs/NATTEN/tree/3036259bdc5c30b7b49fe8ba17d60a0ab0d780dd) for building
29-
libnatten, we have not been able to support MSVC builds.
30-
While we welcome contributions, we are not going to be able to fix MSVC builds any time in the near future,
31-
so we recommend building and running NATTEN with either WSL or MinGW.
28+
If you're building with MSVC, please refer to [Build with MSVC](#Build-with-MSVC).
3229

3330
### Building from source
3431
In order to build from source, please make sure that you have your preferred PyTorch build installed,
@@ -62,6 +59,59 @@ You can do so by passing in the following arguments:
6259
make WORKERS=64
6360
```
6461

62+
It is highly recommended to run all unit tests when you build from source:
63+
```bash
64+
make test
65+
```
66+
67+
#### Build with MSVC
68+
**NOTE: Windows builds are experimental and not regularly tested.**
69+
70+
71+
To build with MSVC, please open the "Native Tools Command Prompt for Visual Studio".
72+
The exact name may depend on your version of Windows, Visual Studio, and cpu architecture (in our case it was x64 Native Tools
73+
Command Prompt for VS".)
74+
75+
Once in the command prompt, make sure your correct Python environment is in the system path. If you're using anaconda, you
76+
should be able to do `conda activate $YOUR_ENV_NAME`.
77+
78+
Then simply confirm you have PyTorch installed, and use our Windows batch script to build:
79+
80+
```
81+
WindowsBuilder.bat install
82+
83+
# Build with 8 parallel workers
84+
WindowsBuilder.bat install WORKERS=8
85+
86+
# Build targeting SM89 (Ada Lovelace)
87+
WindowsBuilder.bat install CUDA_ARCH=8.9
88+
```
89+
90+
Note that depending on how many workers you end up using, build time may vary, and the MSVC compiler tends to throw plenty of
91+
warnings at you, but as long as it does not fail and give you back the command prompt, just let it keep building.
92+
93+
Once it's done building, it is highly recommended to run the unit tests to make sure everything went as expected:
94+
```
95+
WindowsBuilder.bat test
96+
```
97+
98+
##### PyTorch issue: nvToolsExt not found
99+
Windows users may come across this issue when building NATTEN from source with CUDA 12.0 and newer.
100+
The build process fails with an error indicating "nvtoolsext" cannot be found on your system.
101+
This is because nvtoolsext binaries are no longer part of the CUDA toolkit for Windows starting CUDA 12.0, but the PyTorch
102+
cmake still looks for it (as of torch==2.2.1).
103+
104+
The only workaround is to modify the following files:
105+
```
106+
$PATH_TO_YOUR_PYTHON_ENV\Lib\site-packages\torch\share\cmake\Torch\TorchConfig.cmake
107+
$PATH_TO_YOUR_PYTHON_ENV\Lib\site-packages\torch\share\cmake\Torch\Caffe2Targets.cmake
108+
$PATH_TO_YOUR_PYTHON_ENV\Lib\site-packages\torch\share\cmake\Caffe2\public\cuda.cmake
109+
```
110+
111+
find all mentions of nvtoolsext (or nvToolsExt), and comment them out, to get past it.
112+
113+
More information on the issue: [pytorch/pytorch#116926](https://github.com/pytorch/pytorch/pull/116926)
114+
65115
### NGC docker images
66116
NATTEN supports PyTorch builds that are built from source, an example of which is the builds that ship with
67117
NVIDIA's [NGC container images](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch).

requirements-dev.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
packaging
12
torch>=2.0.0
2-
cmake==3.20.3
3+
# cmake==3.20.3
34
ufmt==2.3.0
45
flake8==7.0.0
56
mypy==1.8.0

requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
packaging
12
torch>=2.0.0
2-
cmake==3.20.3
3+
# cmake==3.20.3

setup.py

+27-6
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,18 @@
7272
CUDA_VERSION = [int(x) for x in TORCH_CUDA_VERSION]
7373

7474
assert CUDA_VERSION >= [11, 0], "NATTEN only supports CUDA 11.0 and above."
75+
if CUDA_VERSION >= [12, 0] and IS_WINDOWS:
76+
print(
77+
"WARNING: Torch cmake will likely fail on Windows with CUDA 12.X. "
78+
"Please refer to NATTEN documentation to read more about the issue "
79+
"and how to get around it until the issue is fixed in torch."
80+
)
7581

7682

77-
n_workers = os.environ.get("NATTEN_N_WORKERS", DEFAULT_N_WORKERS)
83+
n_workers = str(os.environ.get("NATTEN_N_WORKERS", DEFAULT_N_WORKERS)).strip()
7884
# In case the env variable is set, but to an empty string
7985
if n_workers == "":
80-
n_workers = DEFAULT_N_WORKERS
86+
n_workers = str(DEFAULT_N_WORKERS)
8187

8288
if HAS_CUDA:
8389
print(f"Building NATTEN with CUDA {CUDA_TAG}")
@@ -182,6 +188,16 @@ def build_extension(self, ext):
182188
if max_sm >= 50:
183189
cmake_args.append("-DNATTEN_WITH_CUTLASS=1")
184190

191+
if IS_WINDOWS:
192+
python_path = sys.executable
193+
assert (
194+
"python.exe" in python_path
195+
), f"Expected the python executable path to end with python.exe, got {python_path}"
196+
python_lib_dir = python_path.replace("python.exe", "libs").strip()
197+
cmake_args.append(f"-DPY_LIB_DIR={python_lib_dir}")
198+
cmake_args.append("-G Ninja")
199+
cmake_args.append("-DCMAKE_BUILD_TYPE=Release")
200+
185201
if not os.path.exists(self.build_lib):
186202
os.makedirs(self.build_lib)
187203

@@ -193,9 +209,15 @@ def build_extension(self, ext):
193209
subprocess.check_call(
194210
["cmake", cmake_lists_dir] + cmake_args, cwd=self.build_lib
195211
)
196-
subprocess.check_call(
197-
["make", f"-j{n_workers}", f"VERBOSE={verbose}"], cwd=self.build_lib
198-
)
212+
cmake_build_args = [
213+
"--build",
214+
self.build_lib,
215+
"-j",
216+
n_workers,
217+
]
218+
if verbose:
219+
cmake_build_args.append("--verbose")
220+
subprocess.check_call(["cmake", *cmake_build_args])
199221

200222
# Clean up cmake files when building dist package;
201223
# otherwise they will get packed into the wheel.
@@ -224,7 +246,6 @@ def build_extension(self, ext):
224246
python_requires=">=3.8",
225247
install_requires=[
226248
"packaging",
227-
"cmake==3.20.3",
228249
"torch>=2.0.0",
229250
],
230251
extras_require={

0 commit comments

Comments
 (0)