Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pip install p4p fails on linux-aarch64 #156

Open
ffeldbauer opened this issue Sep 10, 2024 · 22 comments
Open

pip install p4p fails on linux-aarch64 #156

ffeldbauer opened this issue Sep 10, 2024 · 22 comments

Comments

@ffeldbauer
Copy link

Hey,

I currently try to set up a Docker image for linux/amd64, linux/arm64 and linux/arm/v7 containing p4p and some basic configurations for our setups.

Creating the image for linux/amd64 works fine, but I ran into issues with the two arm architectures.
pip tries to compile epicscorelibs, pvxslibs and p4p and fails with

[...]
  File "/tmp/pip-build-env-aolqqkng/overlay/lib/python3.11/site-packages/numpy/distutils/misc_util.py", line 91, in get_num_build_jobs
    from numpy.distutils.core import get_distribution
  File "/tmp/pip-build-env-aolqqkng/overlay/lib/python3.11/site-packages/numpy/distutils/core.py", line 24, in <module>
    from numpy.distutils.command import config, config_compiler, \
  File "/tmp/pip-build-env-aolqqkng/overlay/lib/python3.11/site-packages/numpy/distutils/command/config.py", line 19, in <module>
    from numpy.distutils.mingw32ccompiler import generate_manifest
  File "/tmp/pip-build-env-aolqqkng/overlay/lib/python3.11/site-packages/numpy/distutils/mingw32ccompiler.py", line 27, in <module>
    from distutils.msvccompiler import get_build_version as get_build_msvc_version
ModuleNotFoundError: No module named 'distutils.msvccompiler'

But when I execute python -c "from distutils.msvccompiler import get_build_version as get_build_msvc_version" it works without an error.

Any idea what goes wrong here?
Maybe I'm missing some build dependencies in my Dockerfile?

@ffeldbauer
Copy link
Author

ffeldbauer commented Sep 13, 2024

In case anyone is interessted:
I grabbed a Raspberry Pi 4 and set up a fresh Raspbian OS 64-bit image and tried to install p4p with the same result.
After some searching on the internet, I found that setuptools 60+ made some breaking changes to their own distutils.

So I cloned this repo (tag 4.1.12) and changed pyproject.toml:

-"setuptools",
+"setuptools<60",

Installing p4p still does not work, but it failed much later:

  src/pvxs_value.cpp:540:75: error: cannot convert ‘PyObject*’ {aka ‘_object*’} to ‘const PyArrayObject*’ {aka ‘const tagPyArrayObject_fields*’}
    540 |             memcpy(dest.data(), PyArray_DATA(arr.obj), PyArray_NBYTES(arr.obj));
        |                                                                       ~~~~^~~
        |                                                                           |
        |                                                                           PyObject* {aka _object*}

EDIT: Also changing the version of numpy and Cython solved the issue:

-"numpy",
-"Cython>=0.20",
+"numpy<2.0",
+"Cython>=0.20,<3.0",

With these two changes to pyproject.toml I was able to compile p4p 4.1.12 on linux-aarch64.

@ffeldbauer ffeldbauer changed the title pip install p4p fails on linux-aarch64 (Docker) pip install p4p fails on linux-aarch64 Sep 13, 2024
@OCopping
Copy link
Contributor

OCopping commented Sep 16, 2024

  src/pvxs_value.cpp:540:75: error: cannot convert ‘PyObject*’ {aka ‘_object*’} to ‘const PyArrayObject*’ {aka ‘const tagPyArrayObject_fields*’}
    540 |             memcpy(dest.data(), PyArray_DATA(arr.obj), PyArray_NBYTES(arr.obj));
        |                                                                       ~~~~^~~
        |                                                                           |
        |                                                                           PyObject* {aka _object*}

This was a breaking change with Numpy 2.0, so that makes sense why pinning to Numpy<2.0 worked. I patched this in commit 1db6252, which corresponds to p4p 4.2.0a1.

What version of Python have you been building p4p against?

I am also surprised you get an error regarding MSVCCompiler as that is normally only used when compiling on Windows systems...

EDIT: I just noticed in your stacktrace is says "python3.11", which is currently broken with p4p 4.2.0a1. We are waiting for the next Numpy release, and once that is done I can merge #152 which should fix this.

@ffeldbauer
Copy link
Author

ffeldbauer commented Sep 16, 2024

For the docker container I used FROM python:3.11-slim (so it is python 3.11.x).
On my raspberry pi, it is 3.11.2

I tried building p4p 4.1.12 (f5c96ba) to have the same version as I have on my amd64 machines where I'm using the prebuild binaries from pypi.org

@ffeldbauer
Copy link
Author

btw: I just noticed that the pvagw does not work on amd64 after installing it via pip install p4p:

epics@6b6bf6a3e8b2:/config$ pvagw -h
Traceback (most recent call last):
  File "/usr/local/bin/pvagw", line 5, in <module>
    from p4p.gw import main
  File "/usr/local/lib/python3.11/site-packages/p4p/__init__.py", line 14, in <module>
    from .wrapper import Value, Type
  File "/usr/local/lib/python3.11/site-packages/p4p/wrapper.py", line 5, in <module>
    from . import _p4p
  File "src/p4p/_p4p.pyx", line 1, in init p4p._p4p
ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject

You have to manually downgrade numpy with

pip install -U "numpy<2.0"

Maybe it would be a good idea to add limitations to pyproject.toml, not only to use a certain minimum version but also limit the version upwards, as numpy 2.1.1 does not seem to be ABI compatible with numpy 1.26.4

At least in the current HEAD I still see, that numpy and setuptools have no restrictions at all

@juanfem
Copy link
Contributor

juanfem commented Sep 16, 2024

Same issue here. I managed to install p4p on linux-aarch64 following @ffeldbauer instructions. Thanks!

@mdavidsaver
Copy link
Member

#152 is merged, and p4p==4.2.0a2 is available for testing.

@mdavidsaver
Copy link
Member

I found that setuptools 60+ made some breaking changes to their own distutils.

@ffeldbauer Can you provide a reference link? Was this change intentional?

@ffeldbauer
Copy link
Author

ffeldbauer commented Sep 16, 2024

@mdavidsaver Yes, here are the two links that I found on my original issue:

Where I first found an answer to the original issue:
spacepy/spacepy#633 (comment)

And the Pull request where this change was acutally done:
pypa/setuptools#3505

EDIT: In the discussion of the pull request is even mentioned that this change broke numpy and implicit amongst others

@ffeldbauer
Copy link
Author

  The conflict is caused by:
      The user requested epicscorelibs==7.0.7.99.0.2
      pvxslibs 1.3.1 depends on epicscorelibs<7.0.7.99.2 and >=7.0.7.99.1.1a2

Seems to me, there is a 0 to much in the requested version of epicscorelibs for 4.2.0a2

@mdavidsaver
Copy link
Member

mdavidsaver commented Sep 16, 2024

I am able to install into a fresh virtualenv

$ virtualenv p4pdev
...
$ ./p4pdev/bin/pip install p4p==4.2.0a2
...
$ ./p4pdev/bin/nose2 p4p
...
Ran 151 tests in 39.173s

OK (skipped=2)
$ ./p4pdev/bin/pip freeze
epicscorelibs==7.0.7.99.1.1a3
nose2==0.15.1
numpy==2.1.1
p4p==4.2.0a2
ply==3.11
pvxslibs==1.3.2a2
setuptools-dso==2.11

...

$ uname -r
6.10.6+bpo-amd64
$ python --version
Python 3.11.2

@ffeldbauer
Copy link
Author

ffeldbauer commented Sep 17, 2024

@mdavidsaver strange that it works for you.

Looking at the pyproject files:

"epicscorelibs==7.0.7.99.0.2; python_version<='3.11'",

For python 3.11 you require epicscorelibs to be exactly of version 7.0.7.99.0.2 and pvxs to be version 1.3.1.
In pvxs 1.3.1 the version of epicscorelibs should be higher then 7.0.3.99.2.0a1:

https://github.com/epics-base/pvxs/blob/93ab81c1532b7078aa261d8608db713898b545b6/pyproject.toml#L2

$ uname -r
6.6.47+rpt-rpi-v8
$ python3 --version
Python 3.11.2

@ffeldbauer
Copy link
Author

Ok...it seems to be (again) an issue with linux-aarch64:

On my desktop PC:

$ python3 -m venv p4ptest
$ ./p4ptest/bin/pip install p4p==4.2.0a2
Collecting p4p==4.2.0a2
  Downloading p4p-4.2.0a2-cp311-cp311-manylinux2014_x86_64.whl (427 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 427.5/427.5 kB 5.2 MB/s eta 0:00:00
Collecting epicscorelibs<7.0.7.99.2,>=7.0.7.99.1.1a3
  Downloading epicscorelibs-7.0.7.99.1.1a3-cp311-cp311-manylinux2014_x86_64.whl (5.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.4/5.4 MB 20.5 MB/s eta 0:00:00
Collecting pvxslibs<1.4.0a1,>=1.3.2a2
  Downloading pvxslibs-1.3.2a2-cp311-cp311-manylinux2014_x86_64.whl (2.6 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.6/2.6 MB 8.8 MB/s eta 0:00:00
Collecting nose2>=0.8.0
  Downloading nose2-0.15.1-py3-none-any.whl (211 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.3/211.3 kB 3.4 MB/s eta 0:00:00
Collecting ply
  Downloading ply-3.11-py2.py3-none-any.whl (49 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.6/49.6 kB 1.0 MB/s eta 0:00:00
Collecting numpy>=1.7
  Downloading numpy-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.3/16.3 MB 23.9 MB/s eta 0:00:00
Requirement already satisfied: setuptools in ./p4ptest/lib/python3.11/site-packages (from epicscorelibs<7.0.7.99.2,>=7.0.7.99.1.1a3->p4p==4.2.0a2) (66.1.1)
Collecting setuptools-dso>=2.11a2
  Downloading setuptools_dso-2.11-py2.py3-none-any.whl (23 kB)
Installing collected packages: ply, setuptools-dso, numpy, nose2, epicscorelibs, pvxslibs, p4p
Successfully installed epicscorelibs-7.0.7.99.1.1a3 nose2-0.15.1 numpy-2.1.1 p4p-4.2.0a2 ply-3.11 pvxslibs-1.3.2a2 setuptools-dso-2.11

$ ./p4ptest/bin/pip freeze
epicscorelibs==7.0.7.99.1.1a3
nose2==0.15.1
numpy==2.1.1
p4p==4.2.0a2
ply==3.11
pvxslibs==1.3.2a2
setuptools-dso==2.11

$ python3 --version
Python 3.11.2
$ uname -r -m
6.1.0-25-amd64 x86_64

@juanfem
Copy link
Contributor

juanfem commented Sep 17, 2024

I can install p4p-4.2.0a2 in aarch64, both on linux (Docker) and darwin, although tests fail when running on Docker (maybe that is expected):

Ran 151 tests in 44.167s

FAILED (failures=125, errors=11, skipped=2)

Errors are TimeoutError and failures are AssertionError: Leftovers from previous test: ClientContextImpl = 1

On macOS, all tests pass

Ran 151 tests in 46.063s

OK (skipped=2)

but I get funny error messages printed on the screen:

.pthread_attr_destroy  ERROR Invalid argument
free_threadInfoThread non-EPICS_13372059648 (0x600003e3a400) can't proceed, suspending.
Dumping a stack trace of thread 'non-EPICS_13372059648':
[       0x10633ac68]: /Users/juanfestebanmuller/temp/p4pdev/lib/python3.11/site-packages/epicscorelibs/lib/libCom.7.0.7.99.1.dylib(epicsStackTrace+0x74)
[       0x106351ed0]: /Users/juanfestebanmuller/temp/p4pdev/lib/python3.11/site-packages/epicscorelibs/lib/libCom.7.0.7.99.1.dylib(cantProceed+0x44)
[       0x10633e3b8]: /Users/juanfestebanmuller/temp/p4pdev/lib/python3.11/site-packages/epicscorelibs/lib/libCom.7.0.7.99.1.dylib(free_threadInfo+0x14c)
[       0x196a23870]: /usr/lib/system/libsystem_pthread.dylib(_pthread_tsd_cleanup+0x1e8)
[       0x196a26684]: /usr/lib/system/libsystem_pthread.dylib(_pthread_exit+0x54)
[       0x196a25fa0]: /usr/lib/system/libsystem_pthread.dylib(_pthread_start+0x94)
[       0x196a20d34]: /usr/lib/system/libsystem_pthread.dylib(thread_start+0x8)

-------------- config --------------

Docker:

# ./p4ptest/bin/pip freeze
epicscorelibs==7.0.7.99.1.1a3
nose2==0.15.1
numpy==2.1.1
p4p==4.2.0a2
ply==3.11
pvxslibs==1.3.2a2
setuptools-dso==2.11

# python --version
Python 3.11.9

# uname -r -m
6.6.41-0-virt x86_64

macOS

% ./p4pdev/bin/pip freeze
epicscorelibs==7.0.7.99.1.1a3
nose2==0.15.1
numpy==2.1.1
p4p==4.2.0a2
ply==3.11
pvxslibs==1.3.2a2
setuptools-dso==2.11

% python --version
Python 3.11.9

% uname -r -m
23.6.0 arm64

@ffeldbauer
Copy link
Author

6.6.41-0-virt x86_64

Your docker container is x86_64. For this architecture I was also able to install p4p 4.2.0a2 too.
But I need to operate p4p on a raspberry pi, so I need it for aarch64.

I tried to look at the various libs more closely:

$ python3 -m venv pvxslibs_test
$ ./pvxslibs_test/bin/pip install pvxslibs==1.3.1
[...]
$ ./pvxslibs_test/bin/python3 -c "import epicscorelibs.version; print( epicscorelibs.version.abi_requires() )"
epicscorelibs >=7.0.7.99.1.1a3, <7.0.7.99.2

So I'm able to install pvxslibs 1.3.1 standalone. But the required epicscorelibs versions are not compatible with the specified build requirements of p4p (epicscorelibs==7.0.7.99.0.2)

@ffeldbauer
Copy link
Author

ffeldbauer commented Sep 17, 2024

$ python3 --version ; uname -r -m
Python 3.11.2
6.6.47+rpt-rpi-v8 aarch64
$ python3 -m venv p4ptest
$ ./p4ptest/bin/pip install --log p4p_install_$(uname -m).log p4p==4.2.0a2

I tried it again and stored the output of the install process in a (verbose) logfile:

p4p_install_aarch64.log

EDIT: After reading the log file, I found the issue and it is similar to the above for p4p==4.1.12:

pvxslibs depends on epicscorelibs>=7.0.3.99.2.0a1, so pip uses the newest version it can find (7.0.7.99.1.1a3) to build and compile pvxslibs.
But this version is too new for building and compiling p4p==4.2.0a2 && python==3.11.

In order to fix this, one has to somehow force pip to use epicscorelibs==7.0.7.99.0.2 when building pvxslibs....

@juanfem
Copy link
Contributor

juanfem commented Sep 17, 2024

Your docker container is x86_64. For this architecture I was also able to install p4p 4.2.0a2 too.

right, sorry I took the wrong container. With another one that is linux-aarch64 I get the same issue:

      The conflict is caused by:
          The user requested epicscorelibs==7.0.7.99.0.2
          pvxslibs 1.3.1 depends on epicscorelibs<7.0.7.99.2 and >=7.0.7.99.1.1a3

@ffeldbauer
Copy link
Author

ffeldbauer commented Sep 17, 2024

On the positive side, I tried to install p4p with python3.12

$ docker run -it --platform linux/arm64 python:3.12-slim bash

and inside the container:

$ uname -m
aarch64
$ pip install -U pip
$ apt-get update && apt-get install -qqy --no-install-recommends gcc g++
[...]
$ pip install p4p==4.2.0a2
[...]
$ pip freeze
epicscorelibs==7.0.7.99.1.1a3
nose2==0.15.1
numpy==2.1.1
p4p==4.2.0a2
ply==3.11
pvxslibs==1.3.2a2
setuptools==75.1.0
setuptools-dso==2.11

Guess I will just use a docker container to run p4p on my Raspi instead of installing it in the host system

@mdavidsaver
Copy link
Member

mdavidsaver commented Sep 17, 2024

Looking at the pyproject files:

"epicscorelibs==7.0.7.99.0.2; python_version<='3.11'",

I think you are correct that this is too strict.

pyproject.toml should have loose ranges based on build time requirements. Strict versioning for binaries should either be prepared by CI jobs, or injected into wheel builds by setup.py.

... see #157

@mdavidsaver
Copy link
Member

Ok...it seems to be (again) an issue with linux-aarch64:

Not entirely. A more representative test needs to avoid using wheels.

$ ./p4pdev/bin/pip install --no-binary epicscorelibs,pvxslibs,p4p p4p==4.2.0a2
...
      ERROR: Cannot install epicscorelibs==7.0.7.99.0.2 and pvxslibs==1.3.1 because these package versions have conflicting dependencies.

@mdavidsaver
Copy link
Member

mdavidsaver commented Sep 18, 2024

Please re-test with 4.2.0a3.

$ ./p4pdev/bin/pip install --no-binary epicscorelibs,pvxslibs,p4p p4p==4.2.0a3
...
Successfully installed epicscorelibs-7.0.7.99.1.1a3 nose2-0.15.1 numpy-2.1.1 p4p-4.2.0a3 ply-3.11 pvxslibs-1.3.1 setuptools-dso-2.11

@ffeldbauer
Copy link
Author

I tested it on my raspi (the --no-binary has no effect here, as epicscorelibs, pvxslibs, and p4p have no prebuild wheels for aarch64)

pandadcs@raspberrypi:~ $ ./p4ptest/bin/pip install p4p==4.2.0a3
[...]
Successfully built p4p
Installing collected packages: ply, nose2, epicscorelibs, pvxslibs, p4p
Successfully installed epicscorelibs-7.0.7.99.1.1a3 nose2-0.15.1 p4p-4.2.0a3 ply-3.11 pvxslibs-1.3.1

@juanfem
Copy link
Contributor

juanfem commented Sep 20, 2024

p4p-4.2.0a3 installs fine and passes all tests on linux-aarch64 for me as well. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants