tuwien-cms / xprec

Full quadruple precision (double-double) data type for numpy
MIT License
12 stars 4 forks source link

Building in Anaconda3 environment #1

Closed shinaoka closed 2 years ago

shinaoka commented 2 years ago

I am struggling to build xprec in a Docker container of anaconda3, which is running on Apple M1 (essentially Ubuntu ARM64).

Dockerfile:

FROM continuumio/anaconda3

ENV PYTHONUNBUFFERED=1

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y \
    build-essential \
    curl \
    ca-certificates \
    git \
    zip \
    vim \
    gosu \
    libopenblas-base libopenblas-dev libhdf5-103 libhdf5-dev \
    cmake pkg-config gfortran \
    openmpi-bin libopenmpi-dev \
    && \
    apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* # clean up

Output of pip install . for the latest commit:

(base) root@0cea7b2e9d26:/workspaces/anaconda3/xprec# pip3 install .
Processing /workspaces/anaconda3/xprec
  DEPRECATION: A future pip version will change local packages to be built in-place without first copying to a temporary directory. We recommend you use --use-feature=in-tree-build to test your packages with this new behavior before it becomes the default.
   pip 21.3 will remove support for this functionality. You can find discussion regarding this at https://github.com/pypa/pip/issues/7555.
Requirement already satisfied: numpy>=1.16 in /opt/conda/lib/python3.9/site-packages (from xprec==1.1.1) (1.20.3)
Building wheels for collected packages: xprec
  Building wheel for xprec (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /opt/conda/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-a13pqm_0/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-a13pqm_0/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-_w_bxa33
       cwd: /tmp/pip-req-build-a13pqm_0/
  Complete output (18 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-aarch64-3.9
  creating build/lib.linux-aarch64-3.9/xprec
  copying pysrc/xprec/__init__.py -> build/lib.linux-aarch64-3.9/xprec
  copying pysrc/xprec/linalg.py -> build/lib.linux-aarch64-3.9/xprec
  running build_ext
  building 'xprec._dd_ufunc' extension
  creating build/temp.linux-aarch64-3.9
  creating build/temp.linux-aarch64-3.9/csrc
  gcc -pthread -B /opt/conda/compiler_compat -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -Wall -fPIC -O2 -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include -fPIC -O2 -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -fPIC -Icsrc -I/opt/conda/lib/python3.9/site-packages/numpy/core/include -I/opt/conda/include/python3.9 -c csrc/_dd_ufunc.c -o build/temp.linux-aarch64-3.9/csrc/_dd_ufunc.o -fopenmp
  gcc: error: .2-a+fp16+rcpc+dotprod+crypto: No such file or directory
  gcc: error: .2-a+fp16+rcpc+dotprod+crypto: No such file or directory
  gcc: error: unrecognized command-line option ‘-n1’; did you mean ‘-n’?
  gcc: error: unrecognized command-line option ‘-n1’; did you mean ‘-n’?
  error: command '/usr/bin/gcc' failed with exit code 1
  ----------------------------------------
  ERROR: Failed building wheel for xprec
  Running setup.py clean for xprec
Failed to build xprec
Installing collected packages: xprec
    Running setup.py install for xprec ... error
    ERROR: Command errored out with exit status 1:
     command: /opt/conda/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-a13pqm_0/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-a13pqm_0/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-uuzx0xtx/install-record.txt --single-version-externally-managed --compile --install-headers /opt/conda/include/python3.9/xprec
         cwd: /tmp/pip-req-build-a13pqm_0/
    Complete output (18 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-aarch64-3.9
    creating build/lib.linux-aarch64-3.9/xprec
    copying pysrc/xprec/__init__.py -> build/lib.linux-aarch64-3.9/xprec
    copying pysrc/xprec/linalg.py -> build/lib.linux-aarch64-3.9/xprec
    running build_ext
    building 'xprec._dd_ufunc' extension
    creating build/temp.linux-aarch64-3.9
    creating build/temp.linux-aarch64-3.9/csrc
    gcc -pthread -B /opt/conda/compiler_compat -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -Wall -fPIC -O2 -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include -fPIC -O2 -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -fPIC -Icsrc -I/opt/conda/lib/python3.9/site-packages/numpy/core/include -I/opt/conda/include/python3.9 -c csrc/_dd_ufunc.c -o build/temp.linux-aarch64-3.9/csrc/_dd_ufunc.o -fopenmp
    gcc: error: .2-a+fp16+rcpc+dotprod+crypto: No such file or directory
    gcc: error: .2-a+fp16+rcpc+dotprod+crypto: No such file or directory
    gcc: error: unrecognized command-line option ‘-n1’; did you mean ‘-n’?
    gcc: error: unrecognized command-line option ‘-n1’; did you mean ‘-n’?
    error: command '/usr/bin/gcc' failed with exit code 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /opt/conda/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-a13pqm_0/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-a13pqm_0/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-uuzx0xtx/install-record.txt --single-version-externally-managed --compile --install-headers /opt/conda/include/python3.9/xprec Check the logs for full command output.

GCC seems to complain abou compilation flags.

shinaoka commented 2 years ago

Debug code for setup.py

        print(self.compiler.compiler_so)

        if platform.system() == 'unix':
            new_flags = {"-march": "native", "-mtune": "native",
                         "-Wextra": None, "-std": "c11"}

Contents of compiler_so:

    ['gcc', '-pthread', '-B', '/opt/conda/compiler_compat', '-Wno-unused-result', '-Wsign-compare', '-DNDEBUG', '-O2', '-Wall', '-fPIC', '-O2', '-n1', '.2-a+fp16+rcpc+dotprod+crypto', '-isystem', '/opt/conda/include', '-I/opt/conda/include', '-fPIC', '-O2', '-n1', '.2-a+fp16+rcpc+dotprod+crypto', '-isystem', '/opt/conda/include', '-fPIC']
mwallerb commented 2 years ago

Something seems to go horribly wrong here with self.compiler.compiler_so before we even touch that variable: The option string does not make any sense at all ... why would we pass -n to gcc, and then the linker, thereby disabling linking to shared libraries, when we are building a shared library? But even if it did, -n does not take any argument, so what is that 1 doing there? Plus what is that: .2-a+fp16+rcpc+dotprod+crypto? We do not even load anything crypto-related ...

So this compiler invocation reads completely nonsensical to me ... can you build anything else with this?

mwallerb commented 2 years ago

I have a hunch: Can you check if anaconda passing -march=neoverse-n1.2-a+fp16+rcpc+dotprod+crypto or similar stuff into setuptools? You can check build flags etc. in python -m sysconfig ...

shinaoka commented 2 years ago

Yes, after removing -n1 .2-a+fp16+rcpc+dotprod+crypto, gcc stops complaining. These flags may come from the compilation flags used to build python.

> python3 -m sysconfig|grep crypto
CFLAGS = "-Wno-unused-result -Wsign-compare -DNDEBUG  -O2 -Wall  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include "        CONFIGURE_CFLAGS = " -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include"
CONFIG_ARGS = "'--prefix=/opt/conda' '--build=aarch64-conda_cos7-linux-gnu' '--host=aarch64-conda_cos7-linux-gnu''--enable-ipv6' '--with-ensurepip=no' '--with-tzpath=/opt/conda/share/zoneinfo:/opt/conda/share/tzinfo' '--with-computed-gotos''--with-system-ffi' '--enable-loadable-sqlite-extensions' '--with-tcltk-includes=-I/opt/conda/include' '--with-tcltk-libs=-L/opt/conda/lib -ltcl8.6 -ltk8.6''--with-platlibdir=lib' '--with-openssl=/opt/conda' 'PKG_CONFIG_LIBDIR=/opt/conda/lib' 'PKG_CONFIG_PATH=/opt/conda/lib' 'CPPFLAGS=-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include -I/opt/conda/include' 'CXXFLAGS=-fvisibility-inlines-hidden -std=c++17 -fmessage-length=0  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include' 'CFLAGS= -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include' 'LDFLAGS=   -Wl,-rpath,/opt/conda/lib -Wl,-rpath-link,/opt/conda/lib -L/opt/conda/lib -L/opt/conda/lib' 'CC= gcc' 'CXX=g++''--with-lto' '--enable-optimizations' '-oldincludedir=/usr/include' '--disable-shared''PROFILE_TASK=-m test --pgo' 'build_alias=aarch64-conda_cos7-linux-gnu' 'host_alias=aarch64-conda_cos7-linux-gnu''MACHDEP=linux' 'CPP=/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/_build_env/bin/cpp'"
OPENSSL_LIBS = "-lssl -lcrypto"
PY_BUILTIN_MODULE_CFLAGS = "-Wno-unused-result -Wsign-compare -DNDEBUG  -O2 -Wall  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include  -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden  -I/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/work/Include/internal -IObjects -IInclude -IPython -I. -I/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/work/Include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include -I/opt/conda/include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include -DPy_BUILD_CORE_BUILTIN"
PY_CFLAGS = "-Wno-unused-result -Wsign-compare -DNDEBUG  -O2 -Wall  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include "
PY_CORE_CFLAGS = "-Wno-unused-result -Wsign-compare -DNDEBUG  -O2 -Wall  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include  -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/work/Include/internal -IObjects -IInclude -IPython -I. -I/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/work/Include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include -I/opt/conda/include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include -DPy_BUILD_CORE"
PY_STDMODULE_CFLAGS = "-Wno-unused-result -Wsign-compare -DNDEBUG  -O2 -Wall  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include -I/opt/conda/include  -fPIC   -O2  -n1 .2-a+fp16+rcpc+dotprod+crypto -isystem /opt/conda/include   -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden  -I/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/work/Include/internal -IObjects -IInclude -IPython -I. -I/home/ec2-user/miniconda3/envs/prefect/conda-bld/python-split_1631809412910/work/Include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include -I/opt/conda/include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /opt/conda/include -I/opt/conda/include"

Full output: sysconfig.txt

mwallerb commented 2 years ago

Not much we can do here ... if python reports to having been built with flags that it could not have been built since the compiler does not understand it, the config is simply broken. Possible workaround is to remove such flags, but I don't know how general this is...

shinaoka commented 2 years ago

A general way may be to distribute precompiled binary packages....

mwallerb commented 2 years ago

We can try, though it does have one downside: performance in double-double arithmetic relies heavily on a fast FMA instruction, which is not universally available. If we build binary packages, can we fine-tune it or do we have to take a performance hit?

shinaoka commented 2 years ago

Do you mean FMA3? Reasonably new x86 processors support FMA3, I think. https://en.wikipedia.org/wiki/FMA_instruction_set I do not know ARM64.

FYI: https://github.com/marketplace/actions/build-and-publish-conda-packages-to-anaconda-org

mwallerb commented 2 years ago

Please have a go at this if you want ...

I have to say I hate setuptools so much that I don't want to touch it unless absolutely necessary :-D

shinaoka commented 2 years ago

I completely agree.

Anaconda has its own compilers bundled. https://docs.conda.io/projects/conda-build/en/latest/resources/compiler-tools.html

shinaoka commented 2 years ago

Do you know any other libraries that have numpy C extensions and are available on conda?

shinaoka commented 2 years ago

The flags may be related to Graviton2, arm CPUs from Amazon.

mwallerb commented 2 years ago

Closed via #4