Skip to content

Commit 4b9f47e

Browse files
Build pymomentum on Windows (#238)
Summary: Now that the [PyTorch conda package is available on Windows](conda-forge/pytorch-cpu-feedstock#231), we can enable building PyMomentum on this platform. - [x] Adheres to the [style guidelines](https://facebookincubator.github.io/momentum/docs/developer_guide/style_guide) - [x] Codebase formatted by running `pixi run lint` Test Plan: CI on Windows Differential Revision: D71858372 Pulled By: jeongseok-meta
1 parent 84cd3a4 commit 4b9f47e

15 files changed

+4980
-1178
lines changed

.github/workflows/ci_macos.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
fail-fast: false
2121
matrix:
2222
os: [macos-latest, macos-latest-large]
23-
mode: ["", "_dev"]
23+
mode: [""]
2424
steps:
2525
- name: Checkout
2626
uses: actions/checkout@v4

.github/workflows/ci_ubuntu.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ jobs:
100100
environments: ${{ matrix.pixi_env }}
101101
cache: true
102102

103-
- name: Build PyMomentum
103+
- name: Build and test PyMomentum
104104
run: |
105105
pixi run -e ${{ matrix.pixi_env }} test_py
106106

.github/workflows/ci_windows.yml

+46-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ on:
1313
- "**/website/**"
1414

1515
jobs:
16-
build:
16+
momentum:
1717
name: cpp-${{ matrix.mode == '' && 'opt' || 'dev' }}-win
1818
runs-on: windows-latest
1919
strategy:
@@ -43,3 +43,48 @@ jobs:
4343
--build momentum/examples/hello_world/build `
4444
--config Release `
4545
--parallel
46+
47+
pymomentum:
48+
name: py-${{ matrix.pixi_env }}-win
49+
runs-on: windows-latest
50+
strategy:
51+
fail-fast: false
52+
matrix:
53+
include:
54+
- pixi_env: "cpu"
55+
- pixi_env: "gpu"
56+
cuda_version: "12.8.0"
57+
env:
58+
FULL_CUDA_VERSION: ${{ matrix.cuda_version }}
59+
steps:
60+
- name: Checkout
61+
uses: actions/checkout@v4
62+
63+
- name: Install CUDA Toolkit
64+
if: ${{ contains(matrix.pixi_env, 'cuda') || contains(matrix.pixi_env, 'gpu') }}
65+
uses: Jimver/[email protected]
66+
id: cuda-toolkit
67+
with:
68+
# Available versions: https://github.com/Jimver/cuda-toolkit/blob/v0.2.21/src/links/linux-links.ts
69+
cuda: ${{ matrix.cuda_version }}
70+
71+
- name: Check CUDA Version
72+
if: ${{ contains(matrix.pixi_env, 'cuda') || contains(matrix.pixi_env, 'gpu') }}
73+
run: |
74+
nvcc --version
75+
76+
- name: Set Conda environment variables
77+
if: ${{ contains(matrix.pixi_env, 'cuda') || contains(matrix.pixi_env, 'gpu') }}
78+
shell: pwsh
79+
run: |
80+
$majorVersion = $Env:FULL_CUDA_VERSION.Split('.')[0]
81+
"CONDA_OVERRIDE_CUDA=$majorVersion" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
82+
83+
- name: Set up pixi
84+
uses: prefix-dev/[email protected]
85+
with:
86+
cache: true
87+
88+
- name: Build and test PyMomentum
89+
run: |
90+
pixi run -e ${{ matrix.pixi_env }} test_py

CMakeLists.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ if(MOMENTUM_USE_SYSTEM_RERUN_CPP_SDK)
111111
else()
112112
include(FetchContent)
113113
FetchContent_Declare(rerun_sdk
114-
URL https://github.com/rerun-io/rerun/releases/download/0.19.1/rerun_cpp_sdk.zip
114+
URL https://github.com/rerun-io/rerun/releases/download/0.21.0/rerun_cpp_sdk.zip
115115
)
116116
FetchContent_MakeAvailable(rerun_sdk)
117117
endif()
@@ -496,7 +496,6 @@ mt_library(
496496
PUBLIC_LINK_LIBRARIES
497497
Eigen3::Eigen
498498
rerun_sdk
499-
NO_INSTALL
500499
)
501500

502501
mt_library(
@@ -511,7 +510,6 @@ mt_library(
511510
PRIVATE_LINK_LIBRARIES
512511
rerun_eigen_adapters
513512
axel
514-
NO_INSTALL
515513
)
516514

517515
#===============================================================================

cmake/mt_defs.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ function(mt_setup_gtest)
351351
)
352352

353353
if(NOT _ARG_GIT_TAG)
354-
set(_ARG_GIT_TAG v1.15.2)
354+
set(_ARG_GIT_TAG v1.16.0)
355355
endif()
356356

357357
if(MOMENTUM_USE_SYSTEM_GOOGLETEST)

momentum/io/urdf/urdf_io.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ bool loadUrdfSkeletonRecursive(
8282
joint.name = urdfLink->name; // Use link name or joint name?
8383
joint.parent = parentJointId;
8484

85-
const size_t jointId = data.skeleton.joints.size();
86-
const size_t jointParamsBaseIndex = jointId * kParametersPerJoint;
87-
const size_t modelParamsBaseIndex = data.totalDoFs;
85+
const Eigen::Index jointId = data.skeleton.joints.size();
86+
const Eigen::Index jointParamsBaseIndex = jointId * kParametersPerJoint;
87+
const Eigen::Index modelParamsBaseIndex = data.totalDoFs;
8888

8989
//---------------------------
9090
// Parse Parameter transform

pixi.lock

+4,834-1,109
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pixi.toml

+54-33
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,39 @@ homepage = "https://facebookincubator.github.io/momentum/"
1010
repository = "https://github.com/facebookincubator/momentum"
1111

1212
[build-dependencies]
13-
boost = ">=1.85.0,<2"
14-
c-compiler = ">=1.8.0,<2"
15-
clang-format = ">=18.1.8,<19"
16-
cmake = ">=3.31.2,<4"
17-
cxx-compiler = ">=1.8.0,<2"
18-
gtest = ">=1.15.2,<2"
13+
boost = ">=1.84.0,<2"
14+
c-compiler = ">=1.9.0,<2"
15+
clang-format = ">=20.1.1,<21"
16+
cmake = ">=3.31.6,<4"
17+
cxx-compiler = ">=1.9.0,<2"
18+
gtest = ">=1.16.0,<2"
1919
ninja = ">=1.12.1,<2"
2020
rerun-sdk = ">=0.21.0,<0.22"
21-
pip = ">=24.3.1,<25"
21+
pip = ">=25.0.1,<26"
2222
pybind11 = ">=2.13.6,<3"
23-
pytest = ">=8.3.4,<9"
24-
scipy = ">=1.15.0,<2"
25-
setuptools = ">=75.6.0,<76"
23+
pytest = ">=8.3.5,<9"
24+
scipy = ">=1.15.2,<2"
25+
setuptools = ">=75.8.2,<76"
2626
sphinx = ">=8.1.3,<9"
2727
sphinx-rtd-theme = ">=3.0.1,<4"
2828
tracy-profiler-gui = ">=0.11.1,<0.12"
2929

3030
[dependencies]
31-
blas = ">=2.129,<3"
31+
blas = ">=2.131,<3"
3232
ceres-solver = ">=2.2.0,<3"
33-
cli11 = ">=2.4.2,<3"
33+
cli11 = ">=2.5.0,<3"
3434
dispenso = ">=1.4.0,<2"
3535
eigen = ">=3.4.0,<4"
36-
ezc3d = ">=1.5.17,<2"
36+
ezc3d = ">=1.5.18,<2"
3737
drjit-cpp = ">=1.0.5,<2"
38-
fmt = ">=11.0.2,<12"
38+
fmt = ">=11.1.4,<12"
3939
fx-gltf = ">=2.0.0,<3"
4040
librerun-sdk = ">=0.21.0,<0.22"
41-
ms-gsl = ">=4.1.0,<5"
41+
ms-gsl = ">=4.2.0,<5"
4242
nlohmann_json = ">=3.11.3,<4"
4343
openfbx = ">=0.9,<0.10"
4444
openssl = ">=3.4.1,<4"
45+
pytorch = ">=2.6.0,<3"
4546
re2 = ">=2024.7.2,<2025"
4647
spdlog = ">=1.15.1,<2"
4748
tracy-profiler-client = ">=0.11.1,<0.12"
@@ -132,6 +133,15 @@ install = { cmd = "cmake --build build/$PIXI_ENVIRONMENT_NAME/cpp/release -j --t
132133
"build",
133134
] }
134135
tracy = { cmd = "tracy-profiler" }
136+
test_py = { cmd = "pytest pymomentum/test/*.py", env = { MOMENTUM_MODELS_PATH = "momentum/" }, depends-on = [
137+
"build_py",
138+
] }
139+
doc_py = { cmd = "sphinx-build -a -E -b html pymomentum/doc build/python_api_doc", depends-on = [
140+
"build_py",
141+
] }
142+
open_doc_py = { cmd = "open build/python_api_doc/index.html", depends-on = [
143+
"doc_py",
144+
] }
135145

136146
#===========
137147
# linux-64
@@ -141,7 +151,6 @@ tracy = { cmd = "tracy-profiler" }
141151
nvtx-c = ">=3.1.0" # TODO: Add to pytorch as run dep
142152

143153
[target.linux-64.dependencies]
144-
pytorch = ">=2.6.0,<3"
145154
sysroot_linux-64 = ">=2.28"
146155

147156
[target.linux-64.tasks]
@@ -204,16 +213,18 @@ config_dev = { cmd = """
204213
] }
205214
build_py = { cmd = "pip install . -vv", env = { FBXSDK_PATH = ".deps/fbxsdk", CMAKE_ARGS = """
206215
-DMOMENTUM_BUILD_IO_FBX=ON \
207-
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD
216+
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD \
217+
-DMOMENTUM_USE_SYSTEM_GOOGLETEST=ON \
218+
-DMOMENTUM_USE_SYSTEM_PYBIND11=OFF \
219+
-DMOMENTUM_USE_SYSTEM_RERUN_CPP_SDK=ON
208220
""", MOMENTUM_ENABLE_SIMD = "ON" }, depends-on = [
209221
"install_deps",
210222
] }
211223
test_py = { cmd = "pytest pymomentum/test/*.py", env = { MOMENTUM_MODELS_PATH = "momentum/" }, depends-on = [
212224
"build_py",
213225
] }
214-
install_py = { cmd = "pip install -e ." }
215226
doc_py = { cmd = "sphinx-build -a -E -b html pymomentum/doc build/python_api_doc", depends-on = [
216-
"install_py",
227+
"build_py",
217228
] }
218229
open_doc_py = { cmd = "open build/python_api_doc/index.html", depends-on = [
219230
"doc_py",
@@ -226,20 +237,21 @@ open_doc_py = { cmd = "open build/python_api_doc/index.html", depends-on = [
226237
[target.osx.build-dependencies]
227238

228239
[target.osx.dependencies]
229-
pytorch = ">=2.6.0,<3"
230240

231241
[target.osx.tasks]
232242
build_py = { cmd = "pip install . -vv", env = { CMAKE_ARGS = """
233243
-DMOMENTUM_BUILD_IO_FBX=$MOMENTUM_BUILD_IO_FBX \
234-
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD
244+
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD \
245+
-DMOMENTUM_USE_SYSTEM_GOOGLETEST=ON \
246+
-DMOMENTUM_USE_SYSTEM_PYBIND11=ON \
247+
-DMOMENTUM_USE_SYSTEM_RERUN_CPP_SDK=ON
235248
""", MOMENTUM_BUILD_IO_FBX = "OFF", MOMENTUM_ENABLE_SIMD = "ON" } }
236249
# TODO: Remove -k option, once this tests are disabled programmatically if momentum is not built with FBX support
237250
test_py = { cmd = "pytest pymomentum/test/*.py -k 'not (TestFBXIO and (test_save_motions_with_joint_params or test_save_motions_with_model_params))'", env = { MOMENTUM_MODELS_PATH = "momentum/" }, depends-on = [
238251
"build_py",
239252
] }
240-
install_py = { cmd = "pip install -e ." }
241253
doc_py = { cmd = "sphinx-build -a -E -b html pymomentum/doc build/python_api_doc", depends-on = [
242-
"install_py",
254+
"build_py",
243255
] }
244256
open_doc_py = { cmd = "open build/python_api_doc/index.html", depends-on = [
245257
"doc_py",
@@ -252,20 +264,21 @@ open_doc_py = { cmd = "open build/python_api_doc/index.html", depends-on = [
252264
[target.osx-arm64.build-dependencies]
253265

254266
[target.osx-arm64.dependencies]
255-
pytorch = ">=2.6.0,<3"
256267

257268
[target.osx-arm64.tasks]
258269
build_py = { cmd = "pip install . -vv", env = { CMAKE_ARGS = """
259270
-DMOMENTUM_BUILD_IO_FBX=$MOMENTUM_BUILD_IO_FBX \
260-
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD
271+
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD \
272+
-DMOMENTUM_USE_SYSTEM_GOOGLETEST=ON \
273+
-DMOMENTUM_USE_SYSTEM_PYBIND11=ON \
274+
-DMOMENTUM_USE_SYSTEM_RERUN_CPP_SDK=ON
261275
""", MOMENTUM_BUILD_IO_FBX = "OFF", MOMENTUM_ENABLE_SIMD = "ON" } }
262276
# TODO: Remove -k option, once this tests are disabled programmatically if momentum is not built with FBX support
263277
test_py = { cmd = "pytest pymomentum/test/*.py -k 'not (TestFBXIO and (test_save_motions_with_joint_params or test_save_motions_with_model_params))'", env = { MOMENTUM_MODELS_PATH = "momentum/" }, depends-on = [
264278
"build_py",
265279
] }
266-
install_py = { cmd = "pip install -e ." }
267280
doc_py = { cmd = "sphinx-build -a -E -b html pymomentum/doc build/python_api_doc", depends-on = [
268-
"install_py",
281+
"build_py",
269282
] }
270283
open_doc_py = { cmd = "open build/python_api_doc/index.html", depends-on = [
271284
"doc_py",
@@ -340,6 +353,14 @@ install = { cmd = "cmake --build build/$PIXI_ENVIRONMENT_NAME/cpp -j --target in
340353
"build",
341354
] }
342355
tracy = { cmd = "tracy-profiler.exe" }
356+
build_py = { cmd = "pip install . -vv", env = { CMAKE_ARGS = """
357+
-DMOMENTUM_BUILD_IO_FBX=$MOMENTUM_BUILD_IO_FBX \
358+
-DMOMENTUM_ENABLE_SIMD=$MOMENTUM_ENABLE_SIMD
359+
""", MOMENTUM_BUILD_IO_FBX = "OFF", MOMENTUM_ENABLE_SIMD = "ON" } }
360+
# TODO: Remove -k option, once this tests are disabled programmatically if momentum is not built with FBX support
361+
test_py = { cmd = "pytest pymomentum/test/*.py -k 'not (TestFBXIO and (test_save_motions_with_joint_params or test_save_motions_with_model_params))'", env = { MOMENTUM_MODELS_PATH = "momentum/" }, depends-on = [
362+
"build_py",
363+
] }
343364

344365
#==============
345366
# Feature: CPU
@@ -352,21 +373,21 @@ tracy = { cmd = "tracy-profiler.exe" }
352373
#==============
353374

354375
[feature.py312-cuda126]
355-
platforms = ["linux-64"]
376+
platforms = ["linux-64", "win-64"]
356377
system-requirements = { cuda = "12" }
357-
build-dependencies = { cuda-toolkit = ">=12.6.3,<13", cuda-nvtx-dev = ">=12.6.3,<13" }
378+
build-dependencies = { cuda-toolkit = ">=12.6.3,<13", nvtx-c = ">=3.1.1" }
358379
dependencies = { python = "3.12.*", pytorch-gpu = ">=2.6.0,<3" }
359380

360381
[feature.py311-cuda126]
361-
platforms = ["linux-64"]
382+
platforms = ["linux-64", "win-64"]
362383
system-requirements = { cuda = "12" }
363-
build-dependencies = { cuda-toolkit = ">=12.6.3,<13", cuda-nvtx-dev = ">=12.6.3,<13" }
384+
build-dependencies = { cuda-toolkit = ">=12.6.3,<13", nvtx-c = ">=3.1.1" }
364385
dependencies = { python = "3.11.*", pytorch-gpu = ">=2.6.0,<3" }
365386

366387
[feature.py310-cuda126]
367-
platforms = ["linux-64"]
388+
platforms = ["linux-64", "win-64"]
368389
system-requirements = { cuda = "12" }
369-
build-dependencies = { cuda-toolkit = ">=12.6.3,<13", cuda-nvtx-dev = ">=12.6.3,<13" }
390+
build-dependencies = { cuda-toolkit = ">=12.6.3,<13", nvtx-c = ">=3.1.1" }
370391
dependencies = { python = "3.10.*", pytorch-gpu = ">=2.6.0,<3" }
371392

372393
#==============

pymomentum/CMakeLists.txt

+24-10
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,33 @@
77
# Find dependencies
88
#===============================================================================
99

10+
if(NOT DEFINED ENV{CONDA_PREFIX})
11+
message(FATAL_ERROR
12+
"CONDA_PREFIX is not set. pymomentum currently only supports building"
13+
"with Conda/Pixi. Please ensure you are using a Conda or Pixi environment."
14+
)
15+
endif()
16+
1017
set(ENV{NVTOOLSEXT_PATH} "$ENV{CONDA_PREFIX}/include")
1118

12-
find_package(ATen CONFIG REQUIRED
13-
HINTS
14-
$ENV{CONDA_PREFIX}/lib/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/torch/
15-
)
19+
if(WIN32)
20+
set(libtorch_base_path $ENV{CONDA_PREFIX}/Lib/site-packages/torch)
21+
else()
22+
set(libtorch_base_path $ENV{CONDA_PREFIX})
23+
endif()
1624

17-
find_package(Torch CONFIG REQUIRED
18-
HINTS
19-
$ENV{CONDA_PREFIX}/lib/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/torch/
20-
)
25+
if(NOT EXISTS "${libtorch_base_path}")
26+
message(FATAL_ERROR
27+
"PyTorch not found in the expected location: ${libtorch_base_path}"
28+
"Please ensure PyTorch is installed in your Conda/Pixi environment."
29+
)
30+
endif()
2131

32+
find_package(ATen CONFIG REQUIRED HINTS ${libtorch_base_path})
33+
find_package(Torch CONFIG REQUIRED HINTS ${libtorch_base_path})
2234
find_library(torch_python
2335
NAMES torch_python
24-
HINTS
25-
$ENV{CONDA_PREFIX}/lib/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/torch/lib/
36+
HINTS ${libtorch_base_path}/lib/
2637
REQUIRED
2738
)
2839

@@ -56,6 +67,8 @@ mt_library(
5667
${TORCH_INCLUDE_DIRS}
5768
PUBLIC_LINK_LIBRARIES
5869
Eigen3::Eigen
70+
pybind11::pybind11
71+
${Python3_LIBRARIES}
5972
${TORCH_LIBRARIES}
6073
PRIVATE_LINK_LIBRARIES
6174
momentum
@@ -218,6 +231,7 @@ if(MOMENTUM_BUILD_TESTING)
218231
character_test_helpers
219232
tensor_ik
220233
tensor_utility
234+
${Python3_LIBRARIES}
221235
)
222236
endif()
223237

0 commit comments

Comments
 (0)