From fcc7eb82cf83dcea20545da07e944292524758cf Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr> Date: Thu, 29 Oct 2020 00:50:50 +0100 Subject: [PATCH] add python3 docker image, fix build for python3 --- CMakeLists.txt | 4 +- ci/docker_images/ubuntu/groovy/Dockerfile | 246 ++++++++++++++++++++++ cmake/FindPythonFull.cmake | 6 +- cmake/PythonInstallSetup.cmake | 8 +- cmake/explore_python_config.py | 8 +- 5 files changed, 258 insertions(+), 14 deletions(-) create mode 100644 ci/docker_images/ubuntu/groovy/Dockerfile diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f4a57e28..792af8bc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,8 +154,6 @@ find_python_module(argparse_color_formatter REQUIRED) find_python_module(primefac REQUIRED) find_python_module(networkx REQUIRED) find_python_module(pyfftw REQUIRED) -find_python_module(backports.weakref REQUIRED) # python-backports.weakref -#find_python_module(backports.functools-lru-cache REQUIRED) # python-backports.functools-lru-cache find_python_module(matplotlib OPTIONAL) find_python_module(pyvis OPTIONAL) @@ -187,7 +185,7 @@ endif() # Find python build dir name --> needed for tests and doc if(USE_CXX OR USE_FORTRAN) execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.util as ut ; import distutils.sysconfig as sy; print 'lib.'+ut.get_platform()+'-'+sy.get_python_version()" + COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.util as ut ; import distutils.sysconfig as sy; print('lib.'+ut.get_platform()+'-'+sy.get_python_version())" OUTPUT_VARIABLE ${PROJECT_NAME}_PYTHON_BUILD_DIR) string(STRIP ${${PROJECT_NAME}_PYTHON_BUILD_DIR} ${PROJECT_NAME}_PYTHON_BUILD_DIR) set(HYSOP_BUILD_PYTHONPATH ${CMAKE_BINARY_DIR}/build/${${PROJECT_NAME}_PYTHON_BUILD_DIR} CACHE INTERNAL "Python package build path") diff --git a/ci/docker_images/ubuntu/groovy/Dockerfile b/ci/docker_images/ubuntu/groovy/Dockerfile new file mode 100644 index 000000000..8d23b561a --- /dev/null +++ b/ci/docker_images/ubuntu/groovy/Dockerfile @@ -0,0 +1,246 @@ +# Test docker for gitlab-ci +FROM ubuntu:groovy +MAINTAINER Jean-Baptiste.Keck@imag.fr + +# parallel builds +ARG NTHREADS +ENV MAKEFLAGS "-j${NTHREADS}" + +# upgrade initial image +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update +RUN apt-get full-upgrade -y + +# get build tools and required libraries +RUN apt-get install -y --no-install-recommends expat unzip xz-utils automake libtool pkg-config cmake rsync git vim ssh curl wget ca-certificates gcc g++ gfortran lsb-core cpio libnuma1 libpciaccess0 libreadline-dev libblas-dev liblapack-dev libgcc-9-dev libgfortran-9-dev libgmp-dev libmpfr-dev libmpc-dev python3.8-dev opencl-headers swig libgmp-dev libmpfr-dev libmpc-dev libcairo-dev libcairomm-1.0-dev python3.8-tk + +# python packages using pip3.8 +RUN cd /tmp && \ + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ + python3.8 get-pip.py && \ + pip3.8 install --upgrade pip && \ + rm -f /tmp/get-pip.py +RUN pip3.8 install --upgrade numpy setuptools cffi wheel pytest pybind11 cython + +# OpenMPI 4 + mpi4py (enable mpi1 compatibility for mpi4py) +ENV MPI_ROOT "/usr/local" +RUN cd /tmp && \ + wget https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.5.tar.gz && \ + tar -xvzf openmpi-*.tar.gz && \ + rm -f openmpi-*.tar.gz && \ + cd openmpi-* && \ + ./configure --enable-shared --disable-static --with-threads=posix --enable-ipv6 --prefix="${MPI_ROOT}" --with-hwloc=internal --with-libevent=internal --enable-mpi1-compatibility && \ + make -j$(nproc) && \ + make install && \ + rm -rf /tmp/openmpi-* + +ENV MPICC "${MPI_ROOT}/bin/mpicc" +RUN ldconfig && pip3.8 install --upgrade mpi4py + +# HDF5 + h5py (v1.10.6 is currently the last supported by h5py) +RUN cd /tmp && \ + wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.6/src/hdf5-1.10.6.tar.gz && \ + tar -xvzf hdf5-*.tar.gz && \ + rm -rf hdf5-*.tar.gz && \ + cd hdf5-* && \ + CC="${MPICC}" ./configure --prefix="${MPI_ROOT}" --enable-parallel --enable-shared=yes --enable-static=no && \ + make -j$(nproc) && \ + make install && \ + rm -rf /tmp/hdf5-* +RUN CC="${MPICC}" HDF5_MPI="ON" HDF5_VERSION="1.10.6" HDF5_DIR="${MPI_ROOT}" pip3.8 install --upgrade --no-binary=h5py h5py + +# llvm + numba + llvmlite (llvmlite 0.32 has a bug with llvm8) +RUN apt-get install -y llvm-8-dev libclang-8-dev clang-8 +ENV LLVM_CONFIG=llvm-config-8 +RUN pip3.8 install --upgrade numba llvmlite==0.31.0 + +# other python packages +RUN pip3.8 install --upgrade scipy sympy matplotlib gmpy2 psutil py-cpuinfo Mako subprocess32 editdistance portalocker colors.py tee primefac pycairo argparse_color_formatter networkx pyvis zarr numcodecs jsonpickle memory-tempfile + +# patchelf +RUN cd /tmp && \ + git clone https://github.com/NixOS/patchelf && \ + cd patchelf && \ + ./bootstrap.sh && \ + ./configure && \ + make && \ + make install && \ + cd - && \ + rm -Rf /tmp/patchelf + +# Intel experimental OpenCL platform with SYCL support (2020-09) +ENV LD_LIBRARY_PATH "/opt/intel/oclcpuexp/x64:${LD_LIBRARY_PATH}" +RUN cd /tmp && \ + mkdir -p /opt/intel/oclcpuexp && \ + wget https://github.com/intel/llvm/releases/download/2020-09/oclcpuexp-2020.11.8.0.27_rel.tar.gz && \ + tar -xvzf oclcpuexp-*.tar.gz && \ + mv x64/ /opt/intel/oclcpuexp/ && \ + mv clbltfnshared.rtl /opt/intel/oclcpuexp/ && \ + rm -rf *.rtl oclcpuexp-* && \ + wget https://github.com/oneapi-src/oneTBB/releases/download/v2020.3/tbb-2020.3-lin.tgz && \ + tar -xvzf tbb-*.tgz && \ + rm -f tbb-*.tgz && \ + mv tbb/lib/intel64/gcc4.8/* /opt/intel/oclcpuexp/x64/ && \ + rm -f /usr/local/lib/libOpenCL.so && \ + rm -f /usr/local/lib/libOpenCL.so && \ + rm -f /usr/local/lib/libOpenCL.so.1 && \ + rm -f /usr/local/lib/libOpenCL.so.2.0 && \ + ln -s /opt/intel/oclcpuexp/x64/libOpenCL.so /usr/local/lib/libOpenCL.so && \ + ln -s /opt/intel/oclcpuexp/x64/libOpenCL.so.1 /usr/local/lib/libOpenCL.so.1 && \ + ln -s /opt/intel/oclcpuexp/x64/libOpenCL.so.2.0 /usr/local/lib/libOpenCL.so.2.0 && \ + mkdir -p /etc/OpenCL/vendors && \ + echo /opt/intel/oclcpuexp/x64/libintelocl.so > /etc/OpenCL/vendors/intel_expcpu.icd && \ + rm -rf /tmp/tbb* + +# clinfo 2.2.18 (2018) +RUN cd /tmp && \ + wget https://github.com/Oblomov/clinfo/archive/2.2.18.04.06.tar.gz && \ + tar -xvzf *.tar.gz && \ + rm -f *.tar.gz && \ + cd clinfo-* && \ + make && \ + mv clinfo /usr/local/bin && \ + rm -rf /tmp/clinfo-* + +# clpeak 1.1.0 RC2 (2019) +RUN cd /tmp && \ + wget https://github.com/krrishnarraj/clpeak/archive/1.1.0.tar.gz && \ + tar -xvzf *.tar.gz && \ + rm -f *.tar.gz && \ + cd clpeak-* && \ + mkdir build && \ + cd build/ && \ + cmake .. && \ + make && \ + mv clpeak /usr/local/bin && \ + rm -rf /tmp/clpeak-* + +# pyopencl +RUN cd /tmp && \ + git clone https://github.com/inducer/pyopencl && \ + cd pyopencl && \ + git submodule update --init && \ + git checkout v2020.1 && \ + python3.8 configure.py && \ + make && \ + pip3.8 install --upgrade . && \ + cd - && \ + rm -Rf /tmp/pyopencl + +# oclgrind +RUN cd /tmp && \ + git clone https://github.com/jrprice/Oclgrind && \ + cd Oclgrind && \ + mkdir build && \ + cd build && \ + cmake -DCMAKE_BUILD_TYPE=Release .. && \ + make && \ + make install && \ + cd - && \ + rm -Rf /tmp/Oclgrind + +# clFFT +RUN cd /tmp && \ + ln -s /usr/local/lib /usr/local/lib64 && \ + git clone https://github.com/clMathLibraries/clFFT && \ + cd clFFT && \ + cd src && \ + mkdir build && \ + cd build && \ + cmake -DCMAKE_BUILD_TYPE=Release .. && \ + make && \ + make install && \ + cd - && \ + rm -Rf /tmp/clFFT + +# gpyFFT +RUN cd /tmp && \ + git clone https://github.com/geggo/gpyfft && \ + cd gpyfft && \ + pip3.8 install . && \ + cd - && \ + rm -Rf /tmp/gpyfft + +# HPTT (CPU tensor permutation library) +RUN cd /tmp && \ + git clone https://gitlab.com/keckj/hptt && \ + cd hptt && \ + mkdir build && \ + cd build && \ + cmake -DCMAKE_BUILD_TYPE=Release .. && \ + make && \ + make install && \ + cd ../pythonAPI && \ + pip3.8 install --upgrade . && \ + cd /tmp && \ + rm -Rf /tmp/hptt + +# python flint (FLINT2 + ARB + python-flint) +RUN cd /tmp \ + && wget https://github.com/wbhart/flint2/archive/v2.6.1.tar.gz \ + && tar -xvzf v2.6.1.tar.gz \ + && cd flint2-2.6.1 \ + && ./configure \ + && make -j$(nproc) \ + && make install \ + && cd - \ + && rm -rf flint2-2.6.1 +RUN cd /tmp \ + && wget https://github.com/fredrik-johansson/arb/archive/2.18.1.tar.gz \ + && tar -xvzf 2.18.1.tar.gz \ + && cd arb-2.18.1 \ + && ./configure \ + && make -j$(nproc) \ + && make install \ + && cd - \ + && rm -rf arb-2.18.1 +RUN pip3.8 install --upgrade python-flint + +# static fftw + pyfftw (with R2R transforms) +# Weird pyfftw bug : not passing -O2 explicitely during build causes a segfault on import... +# See https://bugs.gentoo.org/548776 +ENV FFTW_ROOT="/usr/local" +ADD ci/patch/pyfftw.patch /tmp/pyfftw.patch +RUN cd /tmp && \ + wget http://www.fftw.org/fftw-3.3.8.tar.gz && \ + tar -xvzf fftw-*.tar.gz && \ + rm -f fftw-*.tar.gz && \ + cd fftw-* && \ + ./configure --enable-openmp --enable-threads --enable-mpi --enable-static --with-pic --prefix="${FFTW_ROOT}" --enable-single && \ + make -j$(nproc) && \ + make install && \ + make clean && \ + ./configure --enable-openmp --enable-threads --enable-mpi --enable-static --with-pic --prefix="${FFTW_ROOT}" && \ + make -j8 && \ + make install && \ + make clean && \ + ./configure --enable-openmp --enable-threads --enable-mpi --enable-static --with-pic --prefix="${FFTW_ROOT}" --enable-long-double && \ + make -j8 && \ + make install && \ + rm -rf /tmp/fftw-* + +RUN cd /tmp && \ + git config --global user.email "you@example.com" && \ + git config --global user.name "Your Name" && \ + git clone https://github.com/grlee77/pyFFTW && \ + cd pyFFTW && \ + git checkout r2r-try-three && \ + git remote add fork https://github.com/pyFFTW/pyFFTW && \ + git fetch fork && \ + git merge v0.12.0 && \ + STATIC_FFTW_DIR="${FFTW_ROOT}/lib" CFLAGS="-Wl,-Bsymbolic -fopenmp -I${FFTW_ROOT}/include -O2" python3.8 setup.py build_ext --inplace && \ + pip3.8 install --upgrade . && \ + rm -rf /tmp/pyFFTW + +RUN pip3.8 uninstall --yes primefac && \ + pip3.8 install git+git://github.com/elliptic-shiho/primefac-fork@master + +# ensure all libraries are known by the runtime linker +RUN ldconfig + +# clean cached packages +RUN rm -rf /var/lib/apt/lists/* +RUN rm -rf $HOME/.cache/pip/* +RUN rm -rf /tmp/* + +CMD ["/bin/bash"] diff --git a/cmake/FindPythonFull.cmake b/cmake/FindPythonFull.cmake index 857bde5c9..aabb1a719 100644 --- a/cmake/FindPythonFull.cmake +++ b/cmake/FindPythonFull.cmake @@ -49,6 +49,7 @@ else() string(REGEX REPLACE ".*exec_prefix:([^\n]+).*$" "\\1" PYTHON_PREFIX ${python_config}) string(REGEX REPLACE ".*\nversion:([^\n]+).*$" "\\1" PYTHON_VERSION ${python_config}) string(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" PYTHON_INCLUDE_DIRS ${python_config}) + string(REGEX REPLACE ".*\npy_lib_dir:([^\n]+).*$" "\\1" PYTHON_LIBRARY_DIRS ${python_config}) string(REGEX REPLACE ".*\nsite_packages_dir:([^\n]+).*$" "\\1" PYTHON_SITE_PACKAGES_DIR ${python_config}) string(REGEX REPLACE "([0-9]+).([0-9]+)" "\\1\\2" PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) if(WIN32) @@ -61,9 +62,8 @@ else() NAMES python${PYTHON_VERSION_NO_DOTS} python${PYTHON_VERSION} NO_DEFAULT_PATH - HINTS ${PYTHON_PREFIX} ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config-${CMAKE_LIBRARY_ARCHITECTURE} - PATH_SUFFIXES lib libs - ) + HINTS ${PYTHON_LIBRARY_DIRS} ${PYTHON_PREFIX} ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config + PATH_SUFFIXES lib libs lib/${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}) set(PYTHON_LIBRARIES ${PYTHON_LIBRARY} CACHE FILEPATH "Python libraries" FORCE) diff --git a/cmake/PythonInstallSetup.cmake b/cmake/PythonInstallSetup.cmake index c7b1ec86c..e6b1c8577 100755 --- a/cmake/PythonInstallSetup.cmake +++ b/cmake/PythonInstallSetup.cmake @@ -37,19 +37,19 @@ function(set_python_install_path) # and on which python is used (virtualenv or not) # First, we need to check if '--user' option works in the current environment. execute_process(COMMAND ${PYTHON_EXECUTABLE} -c - "import site; print site.ENABLE_USER_SITE" OUTPUT_VARIABLE ENABLE_USER) + "import site; print(site.ENABLE_USER_SITE)" OUTPUT_VARIABLE ENABLE_USER) string(STRIP ${ENABLE_USER} ENABLE_USER) if(ENABLE_USER) # --user works ... # Find install path for --user (site.USER_SITE) execute_process(COMMAND ${PYTHON_EXECUTABLE} -c - "import site; print site.USER_BASE" OUTPUT_VARIABLE USER_BASE) + "import site; print(site.USER_BASE)" OUTPUT_VARIABLE USER_BASE) string(STRIP ${USER_BASE} USER_BASE) list(APPEND python_install_options --user)#prefix=${USER_BASE}) # Get python user site and install path = USER_SITE + project_name set(PYTHON_COMMAND_GET_INSTALL_DIR - "import site, os, sys ; print os.path.join(site.USER_BASE, os.path.join(\"lib\", os.path.join(\"python\" + str(sys.version_info.major) + '.' + str(sys.version_info.minor), - \"site-packages\")))") + "import site, os, sys ; print(os.path.join(site.USER_BASE, os.path.join(\"lib\", os.path.join(\"python\" + str(sys.version_info.major) + '.' + str(sys.version_info.minor), + \"site-packages\"))))") execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${PYTHON_COMMAND_GET_INSTALL_DIR}" OUTPUT_VARIABLE PY_INSTALL_DIR) diff --git a/cmake/explore_python_config.py b/cmake/explore_python_config.py index 4d0c7b4ac..2a0d8d19b 100644 --- a/cmake/explore_python_config.py +++ b/cmake/explore_python_config.py @@ -31,10 +31,10 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. import sys -import distutils.sysconfig +import distutils.sysconfig as cfg print("exec_prefix:%s" % sys.exec_prefix) print("version:%s" % sys.version[:3]) -print("py_inc_dir:%s" % distutils.sysconfig.get_python_inc()) -print("site_packages_dir:%s" % distutils.sysconfig.get_python_lib(plat_specific=1)) - +print("py_inc_dir:%s" % cfg.get_python_inc()) +print("py_lib_dir:%s" % cfg.get_config_var('LIBDIR')) +print("site_packages_dir:%s" % cfg.get_python_lib(plat_specific=1)) -- GitLab