Skip to content

Commit

Permalink
[misc] Upgrade C++ and python dependencies.
Browse files Browse the repository at this point in the history
  • Loading branch information
duburcqa committed Mar 19, 2024
1 parent 7521aa3 commit 96bc5c1
Show file tree
Hide file tree
Showing 12 changed files with 394 additions and 30 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,19 @@ jobs:
sudo apt install -y gdb gnupg curl wget build-essential cmake doxygen graphviz texlive-latex-base
"${PYTHON_EXECUTABLE}" -m pip install setuptools wheel "pip>=20.3"
"${PYTHON_EXECUTABLE}" -m pip install "numpy>=1.23,<2.0"
git config --global advice.detachedHead false
- name: Build jiminy dependencies
run: |
BUILD_TYPE="${{ matrix.BUILD_TYPE }}" ./build_tools/build_install_deps_unix.sh
- name: Install pre-compiled binaries for additional gym-jiminy dependencies
if: matrix.PYTHON_VERSION != '3.13'
run: |
"${PYTHON_EXECUTABLE}" -m pip install "torch" -f https://download.pytorch.org/whl/torch
"${PYTHON_EXECUTABLE}" -m pip install "gymnasium>=0.28,<1.0" "stable_baselines3>=2.0"
- name: Install latest numpy version at build-time for run-time binary compatibility
run: |
"${PYTHON_EXECUTABLE}" -m pip install --pre --upgrade "numpy>=1.23,<2.1"
- name: Build jiminy dependencies
run: |
BUILD_TYPE="${{ matrix.BUILD_TYPE }}" ./build_tools/build_install_deps_unix.sh
#####################################################################################

Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,19 @@ jobs:
echo "InstallDir=${GITHUB_WORKSPACE}/install" >> $GITHUB_ENV
"${PYTHON_EXECUTABLE}" -m pip install setuptools wheel "pip>=20.3"
"${PYTHON_EXECUTABLE}" -m pip install "numpy>=1.23,<2.0"
"${PYTHON_EXECUTABLE}" -m pip install delocate twine
- name: Build jiminy dependencies
run: |
OSX_DEPLOYMENT_TARGET=${OSX_DEPLOYMENT_TARGET} OSX_ARCHITECTURES=${OSX_ARCHITECTURES} \
BUILD_TYPE="${{ matrix.BUILD_TYPE }}" ./build_tools/build_install_deps_unix.sh
- name: Install pre-compiled binaries for additional gym-jiminy dependencies
if: matrix.PYTHON_VERSION != '3.13'
run: |
"${PYTHON_EXECUTABLE}" -m pip install "torch" -f https://download.pytorch.org/whl/torch
"${PYTHON_EXECUTABLE}" -m pip install "gymnasium>=0.28,<1.0" "stable_baselines3>=2.0"
- name: Install latest numpy version at build-time for run-time binary compatibility
run: |
"${PYTHON_EXECUTABLE}" -m pip install --pre --upgrade "numpy>=1.23,<2.1"
- name: Build jiminy dependencies
run: |
OSX_DEPLOYMENT_TARGET=${OSX_DEPLOYMENT_TARGET} OSX_ARCHITECTURES=${OSX_ARCHITECTURES} \
BUILD_TYPE="${{ matrix.BUILD_TYPE }}" ./build_tools/build_install_deps_unix.sh
#####################################################################################

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/manylinux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ jobs:
echo "InstallDir=${GITHUB_WORKSPACE}/install" >> $GITHUB_ENV
"${PYTHON_EXECUTABLE}" -m pip install setuptools wheel "pip>=20.3"
"${PYTHON_EXECUTABLE}" -m pip install "numpy>=1.23,<2.0"
"${PYTHON_EXECUTABLE}" -m pip install twine cmake
- name: Install latest numpy version at build-time for run-time binary compatibility
run: |
"${PYTHON_EXECUTABLE}" -m pip install --pre --upgrade "numpy>=1.23,<2.1"
- name: Build project dependencies
run: |
./build_tools/build_install_deps_unix.sh
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,19 @@ jobs:
run: |
git config --global advice.detachedHead false
python -m pip install setuptools wheel "pip>=20.3"
python -m pip install "numpy>=1.23,<2.0"
python -m pip install pefile machomachomangler
- name: Build jiminy dependencies
run: |
${env:BUILD_TYPE} = "${{ matrix.BUILD_TYPE }}"
& "./workspace/build_tools/build_install_deps_windows.ps1"
- name: Install pre-compiled binaries for additional gym-jiminy dependencies
if: matrix.PYTHON_VERSION != '3.13'
run: |
python -m pip install "torch" -f https://download.pytorch.org/whl/torch
python -m pip install "gymnasium>=0.28,<1.0" "stable_baselines3>=2.0"
- name: Install latest numpy version at build-time for run-time binary compatibility
run: |
python -m pip install --pre --upgrade "numpy>=1.23,<2.1"
- name: Build jiminy dependencies
run: |
${env:BUILD_TYPE} = "${{ matrix.BUILD_TYPE }}"
& "./workspace/build_tools/build_install_deps_windows.ps1"
#####################################################################################

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ install
build
build_tools/cmake/*cppad*
**/log
**/*.trace
6 changes: 3 additions & 3 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ python -m pip install --prefer-binary gym-jiminy[all]

## Excluding dependencies on Ubuntu 18+

First, one must install the pre-compiled libraries of the dependencies. Most of them are available on `robotpkg` APT repository. Just run the bash script to install them automatically for Ubuntu 18 and upward. It should be straightforward to adapt it to any other distribution for which `robotpkg` is available. Note that if you plan to use a virtual environment (`venv`, `pyenv`, ...), you must install the Python dependencies manually using `pip`, i.e. `"wheel", "numpy>=1.23,<2.0"`.
First, one must install the pre-compiled libraries of the dependencies. Most of them are available on `robotpkg` APT repository. Just run the bash script to install them automatically for Ubuntu 18 and upward. It should be straightforward to adapt it to any other distribution for which `robotpkg` is available. Note that if you plan to use a virtual environment (`venv`, `pyenv`, ...), you must install the Python dependencies manually using `pip`, i.e. `"wheel", "numpy>=1.23,<2.1"`.

```bash
sudo env "PATH=$PATH" ./build_tools/easy_install_deps_ubuntu.sh
Expand Down Expand Up @@ -79,7 +79,7 @@ make install -j2

```bash
sudo apt install -y gnupg curl wget build-essential cmake doxygen graphviz
python -m pip install "wheel", "numpy>=1.23,<2.0"
python -m pip install "wheel", "numpy>=1.23,<2.1"
```

### Jiminy dependencies build and install
Expand Down Expand Up @@ -121,7 +121,7 @@ You have to preinstall by yourself the (free) MSVC 2019 toolchain.
Then, install `setuptools`, `wheel` and `numpy`.

```powershell
python -m pip install setuptools wheel "numpy>=1.23,<2.0"
python -m pip install setuptools wheel "numpy>=1.23,<2.1"
```

### Jiminy dependencies build and install
Expand Down
6 changes: 2 additions & 4 deletions build_tools/build_install_deps_unix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ rm -rf "${RootDir}/eigenpy/build"
mkdir -p "${RootDir}/eigenpy/build"
cd "${RootDir}/eigenpy"
git reset --hard
git fetch origin "v3.3.0" && git checkout --force FETCH_HEAD || true
git fetch origin "v3.4.0" && git checkout --force FETCH_HEAD || true
git submodule --quiet foreach --recursive git reset --quiet --hard
git submodule --quiet update --init --recursive --depth 1 --jobs 8
git apply --reject --whitespace=fix "${RootDir}/build_tools/patch_deps_unix/eigenpy.patch"
Expand Down Expand Up @@ -207,13 +207,12 @@ git fetch origin "v5.2.5" && git checkout --force FETCH_HEAD || true
### Checkout hpp-fcl
if [ ! -d "${RootDir}/hpp-fcl" ]; then
git clone --depth 1 https://github.com/humanoid-path-planner/hpp-fcl.git "${RootDir}/hpp-fcl"
git config --global url."https://".insteadOf git://
fi
rm -rf "${RootDir}/hpp-fcl/build"
mkdir -p "${RootDir}/hpp-fcl/build"
cd "${RootDir}/hpp-fcl"
git reset --hard
git fetch origin "v2.4.1" && git checkout --force FETCH_HEAD || true
git fetch origin "v2.4.4" && git checkout --force FETCH_HEAD || true

Check notice on line 215 in build_tools/build_install_deps_unix.sh

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

build_tools/build_install_deps_unix.sh#L215

Note that A && B || C is not if-then-else. C may run when A is true.
git submodule --quiet foreach --recursive git reset --quiet --hard
git submodule --quiet update --init --recursive --depth 1 --jobs 8
git apply --reject --whitespace=fix "${RootDir}/build_tools/patch_deps_unix/hppfcl.patch"
Expand All @@ -224,7 +223,6 @@ git fetch origin "v8.0.2" && git checkout --force FETCH_HEAD || true
### Checkout pinocchio and its submodules
if [ ! -d "${RootDir}/pinocchio" ]; then
git clone --depth 1 https://github.com/stack-of-tasks/pinocchio.git "${RootDir}/pinocchio"
git config --global url."https://".insteadOf git://
fi
rm -rf "${RootDir}/pinocchio/build"
mkdir -p "${RootDir}/pinocchio/build"
Expand Down
6 changes: 2 additions & 4 deletions build_tools/build_install_deps_windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ if (-not (Test-Path -PathType Container "$RootDir/eigenpy")) {
}
Push-Location -Path "$RootDir/eigenpy"
git reset --hard
git fetch origin "v3.3.0"
git fetch origin "v3.4.0"
git checkout --force FETCH_HEAD
git submodule --quiet foreach --recursive git reset --quiet --hard
git submodule --quiet update --init --recursive --depth 1 --jobs 8
Expand Down Expand Up @@ -191,11 +191,10 @@ Pop-Location
### Checkout hpp-fcl, then apply some patches
if (-not (Test-Path -PathType Container "$RootDir/hpp-fcl")) {
git clone --depth=1 https://github.com/humanoid-path-planner/hpp-fcl.git "$RootDir/hpp-fcl"
git config --global url."https://".insteadOf git://
}
Push-Location -Path "$RootDir/hpp-fcl"
git reset --hard
git fetch origin "v2.4.1"
git fetch origin "v2.4.4"
git checkout --force FETCH_HEAD
git submodule --quiet foreach --recursive git reset --quiet --hard
git submodule --quiet update --init --recursive --depth 1 --jobs 8
Expand All @@ -210,7 +209,6 @@ Pop-Location
### Checkout pinocchio and its submodules, then apply some patches
if (-not (Test-Path -PathType Container "$RootDir/pinocchio")) {
git clone --depth=1 https://github.com/stack-of-tasks/pinocchio.git "$RootDir/pinocchio"
git config --global url."https://".insteadOf git://
}
Push-Location -Path "$RootDir/pinocchio"
git reset --hard
Expand Down
6 changes: 3 additions & 3 deletions build_tools/easy_install_deps_ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ echo "-- Python writable site-packages: ${PYTHON_SITELIB}"
apt update && \
apt install -y python3-pip && \
${SUDO_CMD} python3 -m pip install setuptools wheel "pip>=20.3" && \
${SUDO_CMD} python3 -m pip install "numpy>=1.23,<2.0" "numba>=0.54.0"
${SUDO_CMD} python3 -m pip install "numpy>=1.23,<2.1" "numba>=0.54.0"

# Install standard linux utilities
apt install -y gnupg curl wget build-essential cmake doxygen graphviz pandoc
Expand All @@ -81,8 +81,8 @@ fi
# Note that `apt-get` is used instead of `apt` because it supports wildcard in package names
apt-mark unhold "robotpkg-py3*-eigenpy" "robotpkg-py3*-hpp-fcl" "robotpkg-py3*-pinocchio"
apt-get install -y --allow-downgrades --allow-unauthenticated \
robotpkg-urdfdom-headers=1.0.4 robotpkg-hpp-fcl=2.4.1 robotpkg-pinocchio=2.7.0 \
robotpkg-py3*-eigenpy=3.3.0 robotpkg-py3*-hpp-fcl=2.4.1 robotpkg-py3*-pinocchio=2.7.0
robotpkg-urdfdom-headers=1.0.4 robotpkg-hpp-fcl=2.4.4 robotpkg-pinocchio=2.7.0 \
robotpkg-py3*-eigenpy=3.4.0 robotpkg-py3*-hpp-fcl=2.4.4 robotpkg-py3*-pinocchio=2.7.0
apt-mark hold "robotpkg-py3*-eigenpy" "robotpkg-py3*-hpp-fcl" "robotpkg-py3*-pinocchio"

# Add openrobots libraries to python packages search path
Expand Down
168 changes: 168 additions & 0 deletions build_tools/patch_deps_unix/eigenpy.patch
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,171 @@ diff --git a/cmake/python.cmake b/cmake/python.cmake
else()
# No hint was provided. We can then check for first Python 2, then Python
# 3
diff --git a/include/eigenpy/numpy-allocator.hpp b/include/eigenpy/numpy-allocator.hpp
index 6165394..4dd5f7e 100644
--- a/include/eigenpy/numpy-allocator.hpp
+++ b/include/eigenpy/numpy-allocator.hpp
@@ -138,7 +138,12 @@ struct numpy_allocator_impl_matrix<Eigen::Ref<MatType, Options, Stride> > {
outer_stride = reverse_strides ? mat.innerStride()
: mat.outerStride();

+#if NPY_ABI_VERSION < 0x02000000
const int elsize = call_PyArray_DescrFromType(Scalar_type_code)->elsize;
+#else
+ const int elsize =
+ PyDataType_ELSIZE(call_PyArray_DescrFromType(Scalar_type_code));
+#endif
npy_intp strides[2] = {elsize * inner_stride, elsize * outer_stride};

PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
@@ -204,7 +209,12 @@ struct numpy_allocator_impl_matrix<
outer_stride = reverse_strides ? mat.innerStride()
: mat.outerStride();

+#if NPY_ABI_VERSION < 0x02000000
const int elsize = call_PyArray_DescrFromType(Scalar_type_code)->elsize;
+#else
+ const int elsize =
+ PyDataType_ELSIZE(call_PyArray_DescrFromType(Scalar_type_code));
+#endif
npy_intp strides[2] = {elsize * inner_stride, elsize * outer_stride};

PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
diff --git a/include/eigenpy/numpy.hpp b/include/eigenpy/numpy.hpp
index 6ab627d..cdcfcf4 100644
--- a/include/eigenpy/numpy.hpp
+++ b/include/eigenpy/numpy.hpp
@@ -19,6 +19,37 @@
#include <numpy/ndarrayobject.h>
#include <numpy/ufuncobject.h>

+/* Allow compiling against NumPy 1.x and 2.x. See:
+ https://github.com/numpy/numpy/blob/afea8fd66f6bdbde855f5aff0b4e73eb0213c646/doc/source/reference/c-api/array.rst#L1224
+*/
+#if NPY_ABI_VERSION < 0x02000000
+ /* Define 2.0 feature version as it is needed below to decide whether we
+ compile for both 1.x and 2.x (defining it gaurantees 1.x only).
+ */
+ #define NPY_2_0_API_VERSION 0x00000012
+ /* If we are compiling with NumPy 1.x, PyArray_RUNTIME_VERSION so we
+ pretend the `PyArray_RUNTIME_VERSION` is `NPY_FEATURE_VERSION`.
+ This allows downstream to use `PyArray_RUNTIME_VERSION` if they need to.
+ */
+ #define PyArray_RUNTIME_VERSION NPY_FEATURE_VERSION
+ // Compiling on NumPy 1.x these are the same
+ #define PyArray_DescrProto PyArray_Descr
+
+static inline PyArray_ArrFuncs* PyDataType_GetArrFuncs(PyArray_Descr* descr) {
+ return descr->f;
+}
+#endif
+
+/* PEP 674 disallow using macros as l-values
+ see : https://peps.python.org/pep-0674/
+*/
+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
+static inline void _Py_SET_TYPE(PyObject* o, PyTypeObject* type) {
+ Py_TYPE(o) = type;
+}
+#define Py_SET_TYPE(o, type) _Py_SET_TYPE((PyObject*)(o), type)
+#endif
+
#if defined _WIN32 || defined __CYGWIN__
#define EIGENPY_GET_PY_ARRAY_TYPE(array) \
call_PyArray_MinScalarType(array)->type_num
@@ -122,7 +153,7 @@ EIGENPY_DLLAPI PyArray_Descr* call_PyArray_DescrFromType(int typenum);

EIGENPY_DLLAPI void call_PyArray_InitArrFuncs(PyArray_ArrFuncs* funcs);

-EIGENPY_DLLAPI int call_PyArray_RegisterDataType(PyArray_Descr* dtype);
+EIGENPY_DLLAPI int call_PyArray_RegisterDataType(PyArray_DescrProto* dtype);

EIGENPY_DLLAPI int call_PyArray_RegisterCanCast(PyArray_Descr* descr,
int totype,
@@ -170,7 +201,7 @@ inline void call_PyArray_InitArrFuncs(PyArray_ArrFuncs* funcs) {
PyArray_InitArrFuncs(funcs);
}

-inline int call_PyArray_RegisterDataType(PyArray_Descr* dtype) {
+inline int call_PyArray_RegisterDataType(PyArray_DescrProto* dtype) {
return PyArray_RegisterDataType(dtype);
}

diff --git a/include/eigenpy/user-type.hpp b/include/eigenpy/user-type.hpp
index e66b2d9..bcca555 100644
--- a/include/eigenpy/user-type.hpp
+++ b/include/eigenpy/user-type.hpp
@@ -171,7 +171,8 @@ struct SpecialMethods<T, NPY_USERDEF> {
char* srcptr = static_cast<char*>(src);

PyArrayObject* py_array = static_cast<PyArrayObject*>(array);
- PyArray_CopySwapFunc* copyswap = PyArray_DESCR(py_array)->f->copyswap;
+ PyArray_CopySwapFunc* copyswap =
+ PyDataType_GetArrFuncs(PyArray_DESCR(py_array))->copyswap;

for (npy_intp i = 0; i < n; i++) {
copyswap(dstptr, srcptr, swap, array);
@@ -189,8 +190,8 @@ struct SpecialMethods<T, NPY_USERDEF> {
return (npy_bool)(value != ZeroValue);
} else {
T tmp_value;
- PyArray_DESCR(py_array)->f->copyswap(
- &tmp_value, ip, PyArray_ISBYTESWAPPED(py_array), array);
+ PyDataType_GetArrFuncs(PyArray_DESCR(py_array))
+ ->copyswap(&tmp_value, ip, PyArray_ISBYTESWAPPED(py_array), array);
return (npy_bool)(tmp_value != ZeroValue);
}
}
diff --git a/src/numpy.cpp b/src/numpy.cpp
index 01018ba..0621edc 100644
--- a/src/numpy.cpp
+++ b/src/numpy.cpp
@@ -14,7 +14,12 @@ void import_numpy() {
}

int PyArray_TypeNum(PyTypeObject* type) {
- return PyArray_TypeNumFromName(const_cast<char*>(type->tp_name));
+ PyArray_Descr* descr =
+ PyArray_DescrFromTypeObject(reinterpret_cast<PyObject*>(type));
+ if (descr == NULL) {
+ return NPY_NOTYPE;
+ }
+ return descr->type_num;
}

#if defined _WIN32 || defined __CYGWIN__
@@ -52,7 +57,7 @@ void call_PyArray_InitArrFuncs(PyArray_ArrFuncs* funcs) {
PyArray_InitArrFuncs(funcs);
}

-int call_PyArray_RegisterDataType(PyArray_Descr* dtype) {
+int call_PyArray_RegisterDataType(PyArray_DescrProto* dtype) {
return PyArray_RegisterDataType(dtype);
}

diff --git a/src/register.cpp b/src/register.cpp
index 84e84f6..1a8ce77 100644
--- a/src/register.cpp
+++ b/src/register.cpp
@@ -63,9 +63,9 @@ int Register::registerNewType(
throw std::invalid_argument("PyType_Ready fails to initialize input type.");
}

- PyArray_Descr* descr_ptr =
- new PyArray_Descr(*call_PyArray_DescrFromType(NPY_OBJECT));
- PyArray_Descr& descr = *descr_ptr;
+ PyArray_DescrProto* descr_ptr = new PyArray_DescrProto();
+ Py_SET_TYPE(descr_ptr, &PyArrayDescr_Type);
+ PyArray_DescrProto& descr = *descr_ptr;
descr.typeobj = py_type_ptr;
descr.kind = 'V';
descr.byteorder = '=';
@@ -98,7 +98,7 @@ int Register::registerNewType(
PyArray_Descr* new_descr = call_PyArray_DescrFromType(code);

if (PyDict_SetItemString(py_type_ptr->tp_dict, "dtype",
- (PyObject*)descr_ptr) < 0) {
+ (PyObject*)new_descr) < 0) {
throw std::invalid_argument("PyDict_SetItemString fails.");
}

Loading

0 comments on commit 96bc5c1

Please sign in to comment.