PyNvVideoCodec 2.2.1__cp313-cp313-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. PyNvVideoCodec/PyNvVideoCodec_121.cp313-win_arm64.pyd +0 -0
  2. PyNvVideoCodec/PyNvVideoCodec_130.cp313-win_arm64.pyd +0 -0
  3. PyNvVideoCodec/VersionCheck.cp313-win_arm64.pyd +0 -0
  4. PyNvVideoCodec/__init__.py +251 -0
  5. PyNvVideoCodec/avformat-62.dll +0 -0
  6. PyNvVideoCodec/avutil-60.dll +0 -0
  7. PyNvVideoCodec/decoders/SimpleDecoder.py +273 -0
  8. PyNvVideoCodec/decoders/ThreadedDecoder.py +129 -0
  9. PyNvVideoCodec/decoders/__init__.py +22 -0
  10. PyNvVideoCodec/transcoder/Transcoder.py +55 -0
  11. PyNvVideoCodec/transcoder/__init__.py +22 -0
  12. benchmarks/cached_decoder_benchmark.py +813 -0
  13. benchmarks/frame_sampling_benchmark.py +765 -0
  14. benchmarks/requirements.txt +52 -0
  15. benchmarks/segmented_transcode_benchmark.py +1546 -0
  16. benchmarks/setup_pycuda_win_arm64.bat +531 -0
  17. pynvvideocodec-2.2.1.data/data/external/ffmpeg/readme.txt +39 -0
  18. pynvvideocodec-2.2.1.data/data/external/ffmpeg/src/ffmpeg-8.1.2.tar.xz +0 -0
  19. pynvvideocodec-2.2.1.dist-info/METADATA +97 -0
  20. pynvvideocodec-2.2.1.dist-info/RECORD +63 -0
  21. pynvvideocodec-2.2.1.dist-info/WHEEL +5 -0
  22. pynvvideocodec-2.2.1.dist-info/licenses/LICENSE.txt +22 -0
  23. pynvvideocodec-2.2.1.dist-info/licenses/NOTICES.txt +167 -0
  24. pynvvideocodec-2.2.1.dist-info/top_level.txt +3 -0
  25. samples/advanced/decode.py +173 -0
  26. samples/advanced/decode_from_memory_buffer.py +204 -0
  27. samples/advanced/decode_perf.py +299 -0
  28. samples/advanced/decode_reconfigure.py +184 -0
  29. samples/advanced/decode_sei_msg.py +193 -0
  30. samples/advanced/decode_with_cuda_control.py +214 -0
  31. samples/advanced/decode_with_low_latency.py +183 -0
  32. samples/advanced/encode_config.json +12 -0
  33. samples/advanced/encode_config_lowlatency.json +13 -0
  34. samples/advanced/encode_perf.py +338 -0
  35. samples/advanced/encode_reconfigure.py +211 -0
  36. samples/advanced/encode_sei_msg.py +188 -0
  37. samples/advanced/simple_decode_from_memory.py +151 -0
  38. samples/advanced/simple_decode_stats.py +179 -0
  39. samples/advanced/transcode.py +288 -0
  40. samples/basic/create_video_segments.py +187 -0
  41. samples/basic/encode.py +574 -0
  42. samples/basic/segments.txt +3 -0
  43. samples/basic/simple_decode_sampling.py +182 -0
  44. samples/basic/transcode_config.json +6 -0
  45. samples/jupyter/ReconfigureDecoder.png +0 -0
  46. samples/jupyter/SimpleDecoderAPIs.png +0 -0
  47. samples/jupyter/ThreadedDecoder.png +0 -0
  48. samples/jupyter/coco_classes.pickle +0 -0
  49. samples/jupyter/face_protect_tutorial.ipynb +881 -0
  50. samples/jupyter/object_detection_tutorial.ipynb +781 -0
  51. samples/jupyter/simple_decode_tutorial.ipynb +674 -0
  52. samples/requirements.txt +84 -0
  53. samples/setup_pycuda_win_arm64.bat +531 -0
  54. samples/utils/Utils.py +405 -0
  55. samples/utils/__init__.py +36 -0
  56. samples/utils/decode_parser.py +642 -0
  57. samples/utils/decode_stats_writer.py +177 -0
  58. samples/utils/encode_parallel_utils.py +174 -0
  59. samples/utils/encode_parser.py +379 -0
  60. samples/utils/frame_utils.py +89 -0
  61. samples/utils/sei_message_parser.py +223 -0
  62. samples/utils/sei_parser.py +223 -0
  63. samples/utils/transcode_parser.py +218 -0
@@ -0,0 +1,84 @@
1
+ # This copyright notice applies to this file only
2
+ #
3
+ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4
+ # SPDX-License-Identifier: MIT
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a
7
+ # copy of this software and associated documentation files (the "Software"),
8
+ # to deal in the Software without restriction, including without limitation
9
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ # and/or sell copies of the Software, and to permit persons to whom the
11
+ # Software is furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ # DEALINGS IN THE SOFTWARE.
23
+
24
+ # Requirements for PyNvVideoCodec Sample Applications
25
+ # This file covers dependencies for:
26
+ # - samples/basic/
27
+ # - samples/advanced/
28
+ # - samples/jupyter/
29
+
30
+ # IMPORTANT: PyTorch must be installed with CUDA support.
31
+ # Windows ARM64 uses NVIDIA's ARM CUDA Torch/TorchVision wheels.
32
+
33
+ # Core dependencies (required for most samples)
34
+ numpy>=1.21.0
35
+ # Native Windows ARM64 users should run setup_pycuda_win_arm64.bat separately.
36
+ pycuda>=2021.1; sys_platform != "win32" or platform_machine != "ARM64"
37
+
38
+ # PyNvVideoCodec (assuming it's installed separately or available locally)
39
+ # PyNvVideoCodec
40
+
41
+ # For visualization in jupyter notebooks
42
+ matplotlib>=3.3.0
43
+
44
+ # For downloading sample videos in jupyter notebooks
45
+ requests>=2.25.0
46
+
47
+ # For running Jupyter notebooks
48
+ jupyter>=1.0.0
49
+ jupyterlab>=3.0.0
50
+ ipython>=7.20.0
51
+
52
+ # PyTorch with CUDA 13.0 support
53
+ # See: https://download.pytorch.org/whl/cu130/torch/
54
+ --extra-index-url https://download.pytorch.org/whl/cu130
55
+ # Windows ARM64 Torch/TorchVision CUDA wheels are available for CPython 3.11-3.14.
56
+ # See: https://pypi.nvidia.com/nvtorch_oot_nightly/
57
+ --extra-index-url https://pypi.nvidia.com/nvtorch_oot_nightly
58
+ torch==2.9.1; sys_platform != "win32" or platform_machine != "ARM64"
59
+ torch==2.15.0.dev20260820+cu134; sys_platform == "win32" and platform_machine == "ARM64" and python_version >= "3.11" and python_version < "3.15"
60
+ torchvision==0.30.0.dev20260820+cu134; sys_platform == "win32" and platform_machine == "ARM64" and python_version >= "3.11" and python_version < "3.15"
61
+
62
+
63
+ # Note: Standard library modules used (no installation needed):
64
+ # - json, os, sys, pathlib, argparse, time, threading, multiprocessing
65
+ # - queue, ctypes, pickle, datetime, gc, atexit
66
+
67
+
68
+ # Running Jupyter Notebooks:
69
+ #
70
+ # Option 1 - Using Jupyter Notebook (Classic):
71
+ # jupyter notebook
72
+ # # Then navigate to samples/jupyter/ and open the desired .ipynb file
73
+ #
74
+ # Option 2 - Using JupyterLab (Recommended):
75
+ # jupyter lab
76
+ # # Then navigate to samples/jupyter/ and open the desired .ipynb file
77
+ #
78
+ # Option 3 - Using specific notebook:
79
+ # jupyter notebook samples/jupyter/object_detection_tutorial.ipynb
80
+ # jupyter notebook samples/jupyter/simple_decode_tutorial.ipynb
81
+ # jupyter notebook samples/jupyter/face_protect_tutorial.ipynb
82
+ #
83
+ # Note: Ensure PyNvVideoCodec is installed before running the notebooks
84
+
@@ -0,0 +1,531 @@
1
+ @echo off
2
+ rem This copyright notice applies to this file only
3
+
4
+ rem SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5
+ rem SPDX-License-Identifier: MIT
6
+
7
+ rem Permission is hereby granted, free of charge, to any person obtaining a
8
+ rem copy of this software and associated documentation files (the "Software"),
9
+ rem to deal in the Software without restriction, including without limitation
10
+ rem the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ rem and/or sell copies of the Software, and to permit persons to whom the
12
+ rem Software is furnished to do so, subject to the following conditions:
13
+
14
+ rem The above copyright notice and this permission notice shall be included in
15
+ rem all copies or substantial portions of the Software.
16
+
17
+ rem THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ rem IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ rem FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ rem THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ rem LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ rem FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ rem DEALINGS IN THE SOFTWARE.
24
+
25
+ setlocal EnableExtensions EnableDelayedExpansion
26
+
27
+ rem Wheels or source checkouts can preserve this file with LF-only line endings.
28
+ rem cmd.exe may then fail to resolve later "call :label" subroutines. Relaunch
29
+ rem once from a CRLF-normalized temp copy before using any subroutine calls.
30
+ if not defined PYNVC_PYCUDA_CRLF_NORMALIZED (
31
+ set "PYNVC_PYCUDA_CRLF_NORMALIZED=1"
32
+ set "PYNVC_PYCUDA_ORIGINAL_BAT=%~f0"
33
+ set "PYNVC_PYCUDA_CRLF_BAT=%TEMP%\%~n0_%RANDOM%_%RANDOM%.bat"
34
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$src=$env:PYNVC_PYCUDA_ORIGINAL_BAT; $dst=$env:PYNVC_PYCUDA_CRLF_BAT; $text=[System.IO.File]::ReadAllText($src); $text=[System.Text.RegularExpressions.Regex]::Replace($text, '\r?\n', [Environment]::NewLine); [System.IO.File]::WriteAllText($dst, $text, [System.Text.Encoding]::ASCII)"
35
+ if errorlevel 1 (
36
+ echo ERROR: Failed to create a CRLF-normalized copy of "%~f0".
37
+ exit /b 1
38
+ )
39
+ call "!PYNVC_PYCUDA_CRLF_BAT!" %*
40
+ set "PYNVC_PYCUDA_CRLF_STATUS=!ERRORLEVEL!"
41
+ del /q "!PYNVC_PYCUDA_CRLF_BAT!" >nul 2>nul
42
+ exit /b !PYNVC_PYCUDA_CRLF_STATUS!
43
+ )
44
+ set "PYCUDA_VERSION=2026.1"
45
+ set "PYCUDA_TAG=v2026.1"
46
+ set "PYCUDA_COMMIT=7610751702a013053fab8b604bdf1c236dd1f3c0"
47
+ set "PYCUDA_REPO=https://github.com/inducer/pycuda.git"
48
+ set "BPL_SUBSET_COMMIT=021f0d90d2730cc138b4dd476cb3184b27c2a33e"
49
+ set "COMPYTE_COMMIT=f1010ef64b5d4559ca4bb7690d4b3394091477b6"
50
+ set "PYTOOLS_VERSION=2024.1.14"
51
+
52
+ if not defined PYTHON_EXE set "PYTHON_EXE=python"
53
+ if not defined PYCUDA_BUILD_ROOT set "PYCUDA_BUILD_ROOT=%LOCALAPPDATA%\PyNvVideoCodec\pycuda-win-arm64\%PYCUDA_VERSION%"
54
+ if not defined PYCUDA_SOURCE_DIR set "PYCUDA_SOURCE_DIR=%PYCUDA_BUILD_ROOT%\src"
55
+
56
+ echo.
57
+ echo PyNvVideoCodec PyCUDA setup for native Windows ARM64
58
+ echo =====================================================
59
+ echo.
60
+
61
+ call :check_python
62
+ if errorlevel 1 goto :fail
63
+
64
+ call :activate_msvc
65
+ if errorlevel 1 goto :fail
66
+
67
+ call :find_cuda
68
+ if errorlevel 1 goto :fail
69
+
70
+ call :install_python_build_deps
71
+ if errorlevel 1 goto :fail
72
+
73
+ call :sync_pycuda_source
74
+ if errorlevel 1 goto :fail
75
+
76
+ call :write_siteconf
77
+ if errorlevel 1 goto :fail
78
+
79
+ call :install_pycuda
80
+ if errorlevel 1 goto :fail
81
+
82
+ call :install_cuda_dll_path_hook
83
+ if errorlevel 1 goto :fail
84
+
85
+ call :verify_pycuda
86
+ if errorlevel 1 goto :fail
87
+
88
+ echo.
89
+ echo PyCUDA setup completed successfully.
90
+ exit /b 0
91
+
92
+ :check_python
93
+ echo Checking Python...
94
+ "%PYTHON_EXE%" -c "import platform, sys; print(' executable:', sys.executable); print(' version :', sys.version.split()[0]); print(' machine :', platform.machine()); raise SystemExit(0 if sys.implementation.name == 'cpython' and sys.maxsize > 2**32 and platform.machine().lower() in ('arm64', 'aarch64') else 1)"
95
+ if errorlevel 1 (
96
+ echo ERROR: PYTHON_EXE must point to a native 64-bit CPython ARM64 interpreter.
97
+ echo Set PYTHON_EXE to the ARM64 python.exe in your target environment and rerun this script.
98
+ exit /b 1
99
+ )
100
+ exit /b 0
101
+
102
+ :activate_msvc
103
+ if /I "%VSCMD_ARG_TGT_ARCH%"=="arm64" (
104
+ where cl.exe >nul 2>nul
105
+ if not errorlevel 1 (
106
+ where link.exe >nul 2>nul
107
+ if not errorlevel 1 (
108
+ echo Using active MSVC environment for target ARM64.
109
+ goto :msvc_verify
110
+ )
111
+ )
112
+ echo Existing MSVC target is ARM64, but cl.exe/link.exe are not on PATH.
113
+ echo Re-activating MSVC from vcvarsall.bat...
114
+ )
115
+
116
+ call :find_vcvarsall
117
+ if errorlevel 1 exit /b 1
118
+
119
+ echo Activating MSVC ARM64 build environment...
120
+ call "%VCVARSALL%" arm64
121
+ if errorlevel 1 (
122
+ echo ERROR: vcvarsall.bat failed for target arm64.
123
+ exit /b 1
124
+ )
125
+
126
+ :msvc_verify
127
+ if /I not "%VSCMD_ARG_TGT_ARCH%"=="arm64" (
128
+ echo ERROR: MSVC target architecture is "%VSCMD_ARG_TGT_ARCH%", expected "arm64".
129
+ exit /b 1
130
+ )
131
+
132
+ where cl.exe >nul 2>nul
133
+ if errorlevel 1 (
134
+ echo ERROR: cl.exe was not found after activating Visual Studio.
135
+ echo Make sure this Visual Studio installation has the MSVC ARM64 C++ build tools installed.
136
+ exit /b 1
137
+ )
138
+
139
+ where link.exe >nul 2>nul
140
+ if errorlevel 1 (
141
+ echo ERROR: link.exe was not found after activating Visual Studio.
142
+ echo Make sure this Visual Studio installation has the MSVC ARM64 C++ build tools installed.
143
+ exit /b 1
144
+ )
145
+
146
+ echo MSVC target: %VSCMD_ARG_TGT_ARCH%
147
+ exit /b 0
148
+
149
+ :find_vcvarsall
150
+ if defined VCVARSALL (
151
+ if exist "%VCVARSALL%" exit /b 0
152
+
153
+ echo ERROR: VCVARSALL is set but does not exist:
154
+ echo "%VCVARSALL%"
155
+ echo Update VCVARSALL or unset it so this script can auto-detect Visual Studio.
156
+ exit /b 1
157
+ )
158
+
159
+ if defined VSINSTALLDIR (
160
+ if exist "%VSINSTALLDIR%\VC\Auxiliary\Build\vcvarsall.bat" (
161
+ set "VCVARSALL=%VSINSTALLDIR%\VC\Auxiliary\Build\vcvarsall.bat"
162
+ exit /b 0
163
+ )
164
+ )
165
+
166
+ set "VSWHERE="
167
+ if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
168
+ set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
169
+ ) else if exist "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" (
170
+ set "VSWHERE=%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe"
171
+ ) else (
172
+ for %%I in (vswhere.exe) do set "VSWHERE=%%~$PATH:I"
173
+ )
174
+
175
+ if defined VSWHERE (
176
+ for /f "usebackq delims=" %%I in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.ARM64 -property installationPath`) do (
177
+ if exist "%%I\VC\Auxiliary\Build\vcvarsall.bat" (
178
+ set "VCVARSALL=%%I\VC\Auxiliary\Build\vcvarsall.bat"
179
+ exit /b 0
180
+ )
181
+ )
182
+ )
183
+
184
+ echo ERROR: Could not find Visual Studio vcvarsall.bat with ARM64 C++ tools.
185
+ echo Install the C++ ARM64 build tools, or set VCVARSALL before running this script.
186
+ echo Example:
187
+ echo set "VCVARSALL=^<Visual Studio root^>\VC\Auxiliary\Build\vcvarsall.bat"
188
+ exit /b 1
189
+
190
+
191
+ :find_cuda
192
+ echo Checking CUDA Toolkit...
193
+ if not defined CUDA_PATH (
194
+ for /f "delims=" %%I in ('where nvcc.exe 2^>nul') do (
195
+ for %%J in ("%%~dpI..") do set "CUDA_PATH=%%~fJ"
196
+ goto :cuda_path_found
197
+ )
198
+ )
199
+
200
+ :cuda_path_found
201
+ if not defined CUDA_PATH (
202
+ echo ERROR: CUDA_PATH is not set and nvcc.exe was not found on PATH.
203
+ echo Install the native Windows ARM64 CUDA Toolkit, or set CUDA_PATH before running this script.
204
+ exit /b 1
205
+ )
206
+
207
+ if not exist "%CUDA_PATH%\include\cuda.h" (
208
+ echo ERROR: "%CUDA_PATH%\include\cuda.h" was not found.
209
+ echo CUDA_PATH must point to the CUDA Toolkit root.
210
+ exit /b 1
211
+ )
212
+
213
+ if not exist "%CUDA_PATH%\lib\arm64\cuda.lib" (
214
+ echo ERROR: "%CUDA_PATH%\lib\arm64\cuda.lib" was not found.
215
+ echo This script only builds native ARM64 PyCUDA and will not link against x64 CUDA libraries.
216
+ exit /b 1
217
+ )
218
+
219
+ set "CUDA_LIB_DIR=%CUDA_PATH%\lib\arm64"
220
+ set "CUDA_ENABLE_CURAND=False"
221
+ if exist "%CUDA_LIB_DIR%\curand.lib" set "CUDA_ENABLE_CURAND=True"
222
+
223
+ rem CUDA 13+ Windows ARM64 toolkits keep runtime DLLs under bin\arm64 (and
224
+ rem x64 under bin\x64). Prefer the native arm64 runtime dir so Python does not
225
+ rem pick up an x64 curand/cudart DLL ("not a valid Win32 application").
226
+ set "CUDA_BIN_DIR="
227
+ if exist "%CUDA_PATH%\bin\arm64\curand64_10.dll" (
228
+ set "CUDA_BIN_DIR=%CUDA_PATH%\bin\arm64"
229
+ ) else if exist "%CUDA_PATH%\bin\arm64\cudart64_13.dll" (
230
+ set "CUDA_BIN_DIR=%CUDA_PATH%\bin\arm64"
231
+ ) else if exist "%CUDA_PATH%\bin\curand64_10.dll" (
232
+ set "CUDA_BIN_DIR=%CUDA_PATH%\bin"
233
+ ) else if exist "%CUDA_PATH%\bin\cudart64_13.dll" (
234
+ set "CUDA_BIN_DIR=%CUDA_PATH%\bin"
235
+ ) else if exist "%CUDA_PATH%\bin" (
236
+ set "CUDA_BIN_DIR=%CUDA_PATH%\bin"
237
+ )
238
+
239
+ if not defined CUDA_BIN_DIR (
240
+ echo ERROR: Could not locate a CUDA runtime bin directory under "%CUDA_PATH%\bin".
241
+ exit /b 1
242
+ )
243
+
244
+ set "PATH=%CUDA_BIN_DIR%;%CUDA_PATH%\bin;%PATH%"
245
+
246
+ if not exist "%CUDA_PATH%\bin\nvcc.exe" (
247
+ echo WARNING: nvcc.exe was not found under CUDA_PATH\bin. PyCUDA driver APIs can still build, but pycuda.compiler will need nvcc later.
248
+ )
249
+
250
+ echo CUDA root : %CUDA_PATH%
251
+ echo CUDA libs : %CUDA_LIB_DIR%
252
+ echo CUDA bins : %CUDA_BIN_DIR%
253
+ echo CURAND : %CUDA_ENABLE_CURAND%
254
+ exit /b 0
255
+
256
+ :install_python_build_deps
257
+ echo Installing Python build dependencies...
258
+ "%PYTHON_EXE%" -m pip install --upgrade --prefer-binary setuptools wheel "numpy>=1.24" mako "platformdirs>=2.2.0" "pytools==%PYTOOLS_VERSION%"
259
+ if errorlevel 1 (
260
+ echo ERROR: Failed to install Python build dependencies.
261
+ exit /b 1
262
+ )
263
+ exit /b 0
264
+
265
+ :sync_pycuda_source
266
+ echo Preparing PyCUDA source in "%PYCUDA_SOURCE_DIR%"...
267
+ if not exist "%PYCUDA_BUILD_ROOT%" mkdir "%PYCUDA_BUILD_ROOT%"
268
+ if errorlevel 1 (
269
+ echo ERROR: Could not create "%PYCUDA_BUILD_ROOT%".
270
+ exit /b 1
271
+ )
272
+
273
+ where git.exe >nul 2>nul
274
+ if errorlevel 1 (
275
+ echo git.exe was not found on PATH. Using GitHub ZIP download fallback.
276
+ call :download_pycuda_source_without_git
277
+ exit /b !ERRORLEVEL!
278
+ )
279
+
280
+ if exist "%PYCUDA_SOURCE_DIR%\.git" (
281
+ git -C "%PYCUDA_SOURCE_DIR%" fetch --tags --depth 1 origin "%PYCUDA_TAG%"
282
+ if errorlevel 1 (
283
+ echo WARNING: Git fetch failed. Trying GitHub ZIP download fallback.
284
+ call :download_pycuda_source_without_git
285
+ exit /b !ERRORLEVEL!
286
+ )
287
+ git -C "%PYCUDA_SOURCE_DIR%" checkout --detach "%PYCUDA_TAG%"
288
+ if errorlevel 1 (
289
+ echo WARNING: Git checkout failed. Trying GitHub ZIP download fallback.
290
+ call :download_pycuda_source_without_git
291
+ exit /b !ERRORLEVEL!
292
+ )
293
+ ) else (
294
+ git clone --branch "%PYCUDA_TAG%" --depth 1 --recurse-submodules "%PYCUDA_REPO%" "%PYCUDA_SOURCE_DIR%"
295
+ if errorlevel 1 (
296
+ echo WARNING: Git clone failed. Trying GitHub ZIP download fallback.
297
+ call :download_pycuda_source_without_git
298
+ exit /b !ERRORLEVEL!
299
+ )
300
+ )
301
+
302
+ git -C "%PYCUDA_SOURCE_DIR%" submodule update --init --recursive
303
+ if errorlevel 1 (
304
+ echo WARNING: Git submodule update failed. Trying GitHub ZIP download fallback.
305
+ call :download_pycuda_source_without_git
306
+ exit /b !ERRORLEVEL!
307
+ )
308
+ exit /b 0
309
+
310
+ :download_pycuda_source_without_git
311
+ where curl.exe >nul 2>nul
312
+ if errorlevel 1 (
313
+ echo ERROR: git.exe is unavailable and curl.exe was not found.
314
+ echo Install Git for Windows, or make curl.exe available on PATH.
315
+ exit /b 1
316
+ )
317
+
318
+ where tar.exe >nul 2>nul
319
+ if errorlevel 1 (
320
+ echo ERROR: git.exe is unavailable and tar.exe was not found.
321
+ echo Install Git for Windows, or make tar.exe available on PATH.
322
+ exit /b 1
323
+ )
324
+
325
+ call :download_and_extract_zip "https://github.com/inducer/pycuda/archive/%PYCUDA_COMMIT%.zip" "%PYCUDA_SOURCE_DIR%" "pycuda-"
326
+ if errorlevel 1 exit /b 1
327
+
328
+ call :download_and_extract_zip "https://github.com/inducer/bpl-subset/archive/%BPL_SUBSET_COMMIT%.zip" "%PYCUDA_SOURCE_DIR%\bpl-subset" "bpl-subset-"
329
+ if errorlevel 1 exit /b 1
330
+
331
+ call :download_and_extract_zip "https://github.com/inducer/compyte/archive/%COMPYTE_COMMIT%.zip" "%PYCUDA_SOURCE_DIR%\pycuda\compyte" "compyte-"
332
+ if errorlevel 1 exit /b 1
333
+
334
+ if not exist "%PYCUDA_SOURCE_DIR%\setup.py" (
335
+ echo ERROR: PyCUDA setup.py was not found after ZIP download.
336
+ exit /b 1
337
+ )
338
+
339
+ if not exist "%PYCUDA_SOURCE_DIR%\bpl-subset\bpl_subset\boost\python.hpp" (
340
+ echo ERROR: bpl-subset was not expanded correctly.
341
+ exit /b 1
342
+ )
343
+
344
+ if not exist "%PYCUDA_SOURCE_DIR%\pycuda\compyte\array.py" (
345
+ echo ERROR: compyte was not expanded correctly.
346
+ exit /b 1
347
+ )
348
+
349
+ exit /b 0
350
+
351
+ :download_and_extract_zip
352
+ set "ZIP_URL=%~1"
353
+ set "ZIP_DEST=%~2"
354
+ set "ZIP_PREFIX=%~3"
355
+ set "ZIP_TEMP=%PYCUDA_BUILD_ROOT%\_zip_%RANDOM%_%RANDOM%"
356
+ set "ZIP_FILE=%ZIP_TEMP%\source.zip"
357
+ set "ZIP_EXTRACT_DIR=%ZIP_TEMP%\extract"
358
+ set "ZIP_EXTRACTED="
359
+
360
+ echo Downloading %ZIP_URL%
361
+ if not exist "%ZIP_TEMP%" mkdir "%ZIP_TEMP%"
362
+ if errorlevel 1 exit /b 1
363
+ mkdir "%ZIP_EXTRACT_DIR%"
364
+ if errorlevel 1 exit /b 1
365
+
366
+ curl.exe -L --fail --retry 3 -o "%ZIP_FILE%" "%ZIP_URL%"
367
+ if errorlevel 1 (
368
+ echo ERROR: Failed to download %ZIP_URL%
369
+ exit /b 1
370
+ )
371
+
372
+ tar.exe -xf "%ZIP_FILE%" -C "%ZIP_EXTRACT_DIR%"
373
+ if errorlevel 1 (
374
+ echo ERROR: Failed to extract "%ZIP_FILE%".
375
+ exit /b 1
376
+ )
377
+
378
+ for /d %%D in ("%ZIP_EXTRACT_DIR%\%ZIP_PREFIX%*") do set "ZIP_EXTRACTED=%%~fD"
379
+ if not defined ZIP_EXTRACTED (
380
+ echo ERROR: Could not find extracted folder matching "%ZIP_PREFIX%*" from %ZIP_URL%
381
+ exit /b 1
382
+ )
383
+
384
+ if not exist "%ZIP_DEST%" mkdir "%ZIP_DEST%"
385
+ if errorlevel 1 exit /b 1
386
+
387
+ robocopy "%ZIP_EXTRACTED%" "%ZIP_DEST%" /E >nul
388
+ set "ROBOCOPY_STATUS=!ERRORLEVEL!"
389
+
390
+ rmdir /s /q "%ZIP_TEMP%" >nul 2>nul
391
+
392
+ if !ROBOCOPY_STATUS! GEQ 8 (
393
+ echo ERROR: Failed to copy extracted files into "%ZIP_DEST%".
394
+ exit /b !ROBOCOPY_STATUS!
395
+ )
396
+
397
+ exit /b 0
398
+
399
+ :write_siteconf
400
+ echo Writing PyCUDA siteconf.py...
401
+ (
402
+ echo # Generated by setup_pycuda_win_arm64.bat.
403
+ echo BOOST_INC_DIR = []
404
+ echo BOOST_LIB_DIR = []
405
+ echo BOOST_COMPILER = "msvc"
406
+ echo USE_SHIPPED_BOOST = True
407
+ echo BOOST_PYTHON_LIBNAME = []
408
+ echo BOOST_THREAD_LIBNAME = []
409
+ echo CUDA_TRACE = False
410
+ echo CUDA_ROOT = r"%CUDA_PATH%"
411
+ echo CUDA_PRETEND_VERSION = None
412
+ echo CUDA_INC_DIR = [r"%CUDA_PATH%\include"]
413
+ echo CUDA_ENABLE_GL = False
414
+ echo CUDA_ENABLE_CURAND = %CUDA_ENABLE_CURAND%
415
+ echo CUDADRV_LIB_DIR = [r"%CUDA_LIB_DIR%"]
416
+ echo CUDADRV_LIBNAME = ["cuda"]
417
+ echo CUDART_LIB_DIR = [r"%CUDA_LIB_DIR%"]
418
+ echo CUDART_LIBNAME = ["cudart"]
419
+ echo CURAND_LIB_DIR = [r"%CUDA_LIB_DIR%"]
420
+ echo CURAND_LIBNAME = ["curand"]
421
+ echo CXXFLAGS = ["/EHsc", "/D_LITTLE_ENDIAN=1"]
422
+ echo LDFLAGS = ["/FORCE", "/MANIFEST:NO"]
423
+ ) > "%PYCUDA_SOURCE_DIR%\siteconf.py"
424
+ if errorlevel 1 (
425
+ echo ERROR: Failed to write PyCUDA siteconf.py.
426
+ exit /b 1
427
+ )
428
+ exit /b 0
429
+
430
+ :install_pycuda
431
+ echo Building and installing PyCUDA %PYCUDA_VERSION%...
432
+ pushd "%PYCUDA_SOURCE_DIR%"
433
+ if errorlevel 1 exit /b 1
434
+
435
+ set "DISTUTILS_USE_SDK=1"
436
+ set "MSSdk=1"
437
+ set "CL=/D_LITTLE_ENDIAN=1 %CL%"
438
+
439
+ "%PYTHON_EXE%" -m pip install --no-build-isolation --no-deps --no-cache-dir --force-reinstall -v .
440
+ set "PIP_STATUS=%ERRORLEVEL%"
441
+ popd
442
+
443
+ if not "%PIP_STATUS%"=="0" (
444
+ echo ERROR: PyCUDA build/install failed.
445
+ exit /b %PIP_STATUS%
446
+ )
447
+ exit /b 0
448
+
449
+ :install_cuda_dll_path_hook
450
+ rem Python 3.8+ on Windows does not search PATH for extension-module DLL
451
+ rem dependencies. Register the native CUDA runtime dir via a site hook so
452
+ rem "import pycuda" finds curand/cudart without manual add_dll_directory.
453
+ echo Installing CUDA DLL search path hook for "%CUDA_BIN_DIR%"...
454
+
455
+ if not defined CUDA_BIN_DIR (
456
+ echo ERROR: CUDA_BIN_DIR is not set.
457
+ exit /b 1
458
+ )
459
+
460
+ if not exist "%CUDA_BIN_DIR%" (
461
+ echo ERROR: CUDA_BIN_DIR does not exist: "%CUDA_BIN_DIR%"
462
+ exit /b 1
463
+ )
464
+
465
+ set "PYCUDA_SITE_DIR="
466
+ set "PYCUDA_SITE_FILE=%PYCUDA_BUILD_ROOT%\pycuda_site_dir.txt"
467
+ "%PYTHON_EXE%" -c "import sysconfig; print(sysconfig.get_path('purelib'))" > "%PYCUDA_SITE_FILE%"
468
+ if errorlevel 1 (
469
+ echo ERROR: Could not query Python site-packages directory.
470
+ exit /b 1
471
+ )
472
+ set /p PYCUDA_SITE_DIR=<"%PYCUDA_SITE_FILE%"
473
+ del /q "%PYCUDA_SITE_FILE%" >nul 2>nul
474
+ if not defined PYCUDA_SITE_DIR (
475
+ echo ERROR: Could not determine Python site-packages directory.
476
+ exit /b 1
477
+ )
478
+
479
+ if not exist "%PYCUDA_SITE_DIR%" (
480
+ echo ERROR: Python site-packages directory does not exist: "%PYCUDA_SITE_DIR%"
481
+ exit /b 1
482
+ )
483
+
484
+ set "PYCUDA_DLL_HOOK=%PYCUDA_SITE_DIR%\_pycuda_cuda_dll_path.py"
485
+ set "PYCUDA_DLL_PTH=%PYCUDA_SITE_DIR%\_pycuda_cuda_dll_path.pth"
486
+
487
+ > "%PYCUDA_DLL_HOOK%" echo import os
488
+ >> "%PYCUDA_DLL_HOOK%" echo from pathlib import Path
489
+ >> "%PYCUDA_DLL_HOOK%" echo(
490
+ >> "%PYCUDA_DLL_HOOK%" echo _CUDA_BIN = Path(r'''%CUDA_BIN_DIR%''')
491
+ >> "%PYCUDA_DLL_HOOK%" echo _DLL_DIR_HANDLES = []
492
+ >> "%PYCUDA_DLL_HOOK%" echo(
493
+ >> "%PYCUDA_DLL_HOOK%" echo def _add():
494
+ >> "%PYCUDA_DLL_HOOK%" echo if not _CUDA_BIN.is_dir():
495
+ >> "%PYCUDA_DLL_HOOK%" echo return
496
+ >> "%PYCUDA_DLL_HOOK%" echo if hasattr(os, "add_dll_directory"):
497
+ >> "%PYCUDA_DLL_HOOK%" echo _DLL_DIR_HANDLES.append(os.add_dll_directory(str(_CUDA_BIN)))
498
+ >> "%PYCUDA_DLL_HOOK%" echo path = os.environ.get("PATH", "")
499
+ >> "%PYCUDA_DLL_HOOK%" echo prefix = str(_CUDA_BIN)
500
+ >> "%PYCUDA_DLL_HOOK%" echo parts = [p.lower() for p in path.split(os.pathsep)]
501
+ >> "%PYCUDA_DLL_HOOK%" echo if prefix.lower() not in parts:
502
+ >> "%PYCUDA_DLL_HOOK%" echo os.environ["PATH"] = prefix + os.pathsep + path
503
+ >> "%PYCUDA_DLL_HOOK%" echo(
504
+ >> "%PYCUDA_DLL_HOOK%" echo _add()
505
+
506
+ > "%PYCUDA_DLL_PTH%" echo import _pycuda_cuda_dll_path
507
+
508
+ if errorlevel 1 (
509
+ echo ERROR: Failed to install CUDA DLL search path hook.
510
+ exit /b 1
511
+ )
512
+
513
+ echo site: %PYCUDA_SITE_DIR%
514
+ echo cuda bin: %CUDA_BIN_DIR%
515
+ echo wrote: _pycuda_cuda_dll_path.py, _pycuda_cuda_dll_path.pth
516
+ exit /b 0
517
+
518
+ :verify_pycuda
519
+ echo Verifying PyCUDA import and CUDA driver initialization...
520
+ "%PYTHON_EXE%" -u -X faulthandler -c "import platform, pycuda, pycuda.driver as cuda; print(' pycuda:', pycuda.VERSION_TEXT); print(' machine:', platform.machine()); cuda.init(); print(' cuda.init: ok'); print(' devices:', cuda.Device.count())"
521
+ if errorlevel 1 (
522
+ echo ERROR: PyCUDA verification failed.
523
+ echo If import still fails, ensure CUDA runtime DLLs are under "%CUDA_BIN_DIR%".
524
+ exit /b 1
525
+ )
526
+ exit /b 0
527
+
528
+ :fail
529
+ echo.
530
+ echo PyCUDA setup failed.
531
+ exit /b 1