2018년 11월 21일 수요일

Redhat ppc64le 환경에서의 boost와 pyarrow build 및 설치

Redhat 7.5의 기본 gcc 버전은 4.8.5입니다.   OS의 주요 library들도 모두 gcc 4.8.5로 build되어 있습니다.   그런데 Anaconda의 v5.2부터는 python이 gcc 7.2.0으로 build되어 있습니다.

[bsyu@redhat74 cudf]$ python
Python 3.7.0 (default, Jun 28 2018, 13:02:24)
[GCC 7.2.0] :: Anaconda, Inc. on linux

이로 인해 벌어지는 문제 중 하나가, OS의 기본 gcc/g++을 사용해 build한 python package의 경우 아래처럼 undefined symbol error를 내는 경우가 많다는 것입니다.

ImportError: /home/bsyu/anaconda3/lib/python3.7/site-packages/pyarrow/libparquet.so.12: undefined symbol: _ZN5boost13match_resultsIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaINS_9sub_matchISB_EEEE12maybe_assignERKSF_

이는 gcc 5.1부터 CXXABI가 달라졌기 때문입니다.  그에 대한 자세한 내용은 아래에 나와 있습니다. 

https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

이 문제를 해결하려면 gcc 버전을 7.2로 올리는 것이 좋습니다.  그에 대해서는 아래 link를 따라 하시면 됩니다.

http://hwengineer.blogspot.com/2018/05/ppc64le-gcc7-cmake3-source-build.html

이제 gcc 7.2.0을 갖게 되었습니다.

[bsyu@redhat74 files]$ which gcc
/usr/local/bin/gcc

[bsyu@redhat74 files]$ gcc --version
gcc (GCC) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

OS 기본 gcc가 아닌, 새로 만든 gcc 7.2.0을 쓰기 위해서는 PATH와 LD_LIBRARY_PATH를 환경변수에서 /usr/local을 먼저 참조하도록 설정하십시요.

[bsyu@redhat74 files]$ cat ~/.bashrc
...
export PATH=/usr/local/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib:/lib64:/lib:$LD_LIBRARY_PATH
export MAKEFLAGS=-j16
export ARROW_BUILD_TYPE=release

이제 anaconda3를 설치하시고...

[bsyu@redhat74 files]$ ./Anaconda3-5.3.0-Linux-ppc64le.sh

[bsyu@redhat74 files]$ which python
~/anaconda3/bin/python

[bsyu@redhat74 files]$ python
Python 3.7.0 (default, Jun 28 2018, 13:02:24)
[GCC 7.2.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.

pyarrow를 설치하기 위해서는 먼저 boost library들도 gcc 7.2로 build 해야 합니다.  OS에서 기본 제공되는 것들은 맨 위의 예와 같이 undefined symbol error를 내기 때문입니다.

[bsyu@redhat74 files]$ wget https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.tar.gz

[bsyu@redhat74 files]$ tar -zxf boost_1_68_0.tar.gz

여기서 나중에 "pyconfig.h Not Found" error를 피하기 위해서 아래와 같이 pyconfig.h를 살짝 link를 걸어 줘야 합니다.

[bsyu@redhat74 include]$ ln -s python3.7m/pyconfig.h pyconfig.h

[bsyu@redhat74 files]$ cd boost_1_68_0

[bsyu@redhat74 boost_1_68_0]$ ./bootstrap.sh --with-python=/home/bsyu/anaconda3/bin/python --with-python-root=/home/bsyu/anaconda3

[bsyu@redhat74 boost_1_68_0]$ ./b2 -j16

[bsyu@redhat74 boost_1_68_0]$ sudo ./b2 install

이제 boost library들이 설치되었습니다.   이제 pyarrow를 build 합니다.

[bsyu@redhat74 files]$ conda install numpy six setuptools cython pandas pytest cmake flatbuffers rapidjson boost-cpp thrift snappy zlib gflags brotli lz4-c zstd -c conda-forge

(base) [bsyu@redhat74 files]$ which cmake
~/anaconda3/bin/cmake
(base) [bsyu@redhat74 files]$ cmake --version
cmake version 3.12.2

(base) [bsyu@redhat74 files]$ git clone https://github.com/apache/arrow.git

(base) [bsyu@redhat74 files]$ cd arrow

(base) [bsyu@redhat74 arrow]$ export CC=/usr/local/bin/gcc
(base) [bsyu@redhat74 arrow]$ export CXX=/usr/local/bin/g++

(base) [bsyu@redhat74 arrow]$ mkdir cpp/build && cd cpp/build

(base) [bsyu@redhat74 build]$ cmake -DCMAKE_BUILD_TYPE=release -DARROW_PYTHON=on -DARROW_PLASMA=on -DARROW_BUILD_TESTS=OFF  -DARROW_PARQUET=ON  ..

(base) [bsyu@redhat74 build]$ make -j16

(base) [bsyu@redhat74 build]$ sudo make install

(base) [bsyu@redhat74 build]$ cd ../../python

(base) [bsyu@redhat74 python]$ export ARROW_HOME=/usr/local

(base) [bsyu@redhat74 python]$ MAKEFLAGS=-j16 python setup.py build_ext --build-type=$ARROW_BUILD_TYPE --with-parquet --inplace

(base) [bsyu@redhat74 python]$ python setup.py build_ext --build-type=release --with-parquet --bundle-arrow-cpp bdist_wheel

위까지 마치면 dist directory 밑에 wheel file이 생성되어 있습니다.

(base) [bsyu@redhat74 python]$ ls -ltr dist
-rw-rw-r-- 1 bsyu bsyu 9645047 Nov 21 10:42 pyarrow-0.11.1.dev264+g7e6bf41.d20181121-cp37-cp37m-linux_ppc64le.whl

이제 이것을 pip로 설치합니다.

(base) [bsyu@redhat74 python]$ pip install ./dist/pyarrow-0.11.1.dev264+g7e6bf41.d20181121-cp37-cp37m-linux_ppc64le.whl

이제 import pyarrow를 해보면 맨 위의 예에서 보이던 undefined symbol error가 없어진 것을 확인하실 수 있습니다.

(base) [bsyu@redhat74 python]$ python
Python 3.7.0 (default, Jun 28 2018, 13:02:24)
[GCC 7.2.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyarrow
>>>

여기서 만든 pyarrow*.whl은 아래 google drive에 올려놓았습니다.   python 3.7용입니다.

https://drive.google.com/open?id=16cF8F9A2a8ZtpnpV0PdckJMyotkVYEns


참고로 ldd로 보면, 이제 lib.cpython-37m-powerpc64le-linux-gnu.so가 OS에서 기본 제공하는 library (/usr/lib64/libstdc++.so.6, /usr/lib/libboost_regex.so 등 )가 아닌 /usr/local/lib64/libstdc++.so.6, /usr/local/lib/libboost_regex.so 등을 참조하는 것을 보실 수 있습니다.

(base) [bsyu@redhat74 ~]$ ldd /home/bsyu/anaconda3/lib/python3.7/site-packages/pyarrow/lib.cpython-37m-powerpc64le-linux-gnu.so
        linux-vdso64.so.1 =>  (0x00003fff9f750000)
        libarrow.so.12 => /usr/local/lib64/libarrow.so.12 (0x00003fff9efc0000)
        libarrow_python.so.12 => /usr/local/lib64/libarrow_python.so.12 (0x00003fff9ee70000)
        libparquet.so.12 => /usr/local/lib64/libparquet.so.12 (0x00003fff9ebf0000)
        libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00003fff9e9c0000)
        libm.so.6 => /usr/lib64/libm.so.6 (0x00003fff9e8d0000)
        libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00003fff9e890000)
        libc.so.6 => /usr/lib64/libc.so.6 (0x00003fff9e6a0000)
        libdl.so.2 => /usr/lib64/libdl.so.2 (0x00003fff9e670000)
        libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00003fff9e630000)
        libz.so.1 => /usr/lib64/libz.so.1 (0x00003fff9e5f0000)
        libboost_system.so.1.68.0 => /usr/local/lib/libboost_system.so.1.68.0 (0x00003fff9e5c0000)
        libboost_filesystem.so.1.68.0 => /usr/local/lib/libboost_filesystem.so.1.68.0 (0x00003fff9e580000)
        libboost_regex.so.1.68.0 => /usr/local/lib/libboost_regex.so.1.68.0 (0x00003fff9e440000)
        librt.so.1 => /usr/lib64/librt.so.1 (0x00003fff9e410000)
        /lib64/ld64.so.2 (0x000000007f930000)
        libutil.so.1 => /usr/lib64/libutil.so.1 (0x00003fff9e3e0000)



댓글 없음:

댓글 쓰기