Wednesday, December 19, 2012

MinGW64, openblas, suitesparse, and numpy under windows 64 bit

First of all, I failed.Numpy works only partially. IO crashed it for sure.I did not test it further. But, at least, compiling was fine.

Numpy depends on openblas and suitesparse(umfpack) for performance, suitesparse depends on intel-tbb and metis. I just use pre-built metis for mingw64 on the sourceforge.

Here is my openblas script
make -j4 BINARY=64 CC=x86_64-w64-mingw32-gcc FC=x86_64-w64-mingw32-gfortran NUM_THREADS=2
I used 2 threads due to my i5 cpu.

Here is the intel-tbb script
mingw32-make.exe compiler=gcc arch=intel64 runtime=mingw
install -d ./pkg/usr/local/lib
install -m755 build/windows_*/*.dll* ./pkg/usr/local/lib
install -d ./pkg/usr/local/include
cp -a include/tbb ./pkg/usr/local/include
cd ./pkg
tar cvf tbb_4.1_msys64.tgz ./usr
tar -tf tbb_4.1_msys64.tgz > tbb_4.1_msys64.list

And my suitesparse script
export CFLAGS=" ${CFLAGS} -DNPARTITION"
mingw32-make CFLAGS="${CFLAGS} -fPIC -I/usr/local/include -L/usr/local/lib" METIS="-lmetis" SPQR_CONFIG="-DTIMING -DHAVE_TBB" TBB="-ltbb" BLAS="-lopenblas" LAPACK="-lopenblas" -C SuiteSparse_config/xerbla
mingw32-make CFLAGS="${CFLAGS} -fPIC -I/usr/local/include -L/usr/local/lib" METIS="-lmetis" SPQR_CONFIG="-DTIMING -DHAVE_TBB" TBB="-ltbb" BLAS="-lopenblas" LAPACK="-lopenblas" -C SuiteSparse_config
for _lib in AMD CAMD COLAMD BTF KLU CCOLAMD UMFPACK CHOLMOD CXSparse SPQR; do
mingw32-make CFLAGS="${CFLAGS} -fPIC -I/usr/local/include -L/usr/local/lib" METIS="-lmetis" SPQR_CONFIG="-DTIMING -DHAVE_TBB" TBB="-ltbb" BLAS="-lopenblas" LAPACK="-lopenblas" -C ${_lib} library
done
mkdir -p shared
gcc -shared -o shared/libsuitesparseconfig.dll -Wl,--out-implib,SuiteSparse_config/libsuitesparseconfig.a
gcc -shared -o shared/libamd.dll -Wl,--out-implib,AMD/Lib/libamd.a -L./shared -lsuitesparseconfig
gcc -shared -o shared/libcamd.dll -Wl,--out-implib,CAMD/Lib/libcamd.a -L./shared -lsuitesparseconfig
gcc -shared -o shared/libcolamd.dll -Wl,--out-implib,COLAMD/Lib/libcolamd.a -L./shared -lsuitesparseconfig
gcc -shared -o shared/libccolamd.dll -Wl,--out-implib,CCOLAMD/Lib/libccolamd.a -L./shared -lsuitesparseconfig
gcc -shared -o shared/libbtf.dll -Wl,--out-implib,BTF/Lib/libbtf.a -L./shared -lsuitesparseconfig
gcc -shared -o shared/libcholmod.dll -Wl,--out-implib,CHOLMOD/Lib/libcholmod.a -L/usr/local/lib -lopenblas -lmetis -L./shared -lamd -lcamd -lcolamd -lccolamd
gcc -shared -o shared/libspqr.dll -Wl,--out-implib,SPQR/Lib/libspqr.a -L/usr/local/lib -lopenblas -ltbb -L./shared -lcholmod
gcc -shared -o shared/libcxsparse.dll -Wl,--out-implib,CXSparse/Lib/libcxsparse.a -L./shared -lsuitesparseconfig
gcc -shared -o shared/libklu.dll -Wl,--out-implib,KLU/Lib/libklu.a -L./shared -lamd -lcolamd -lbtf
gcc -shared -o shared/libumfpack.dll -Wl,--out-implib,UMFPACK/Lib/libumfpack.a -L/usr/local/lib -lopenblas -L./shared -lamd
install -dm755 ${PWD}/pkg/usr/local/{lib,include}
#cp -d shared/*.so* $pkgdir/usr/lib
#install -m755 shared/*.so* $pkgdir/usr/lib

for _lib in SuiteSparse_config AMD CAMD COLAMD BTF KLU LDL CCOLAMD UMFPACK CHOLMOD CXSparse SPQR; do
mingw32-make CFLAGS="${CFLAGS} -fPIC -I/usr/local/include -L/usr/local/lib" METIS="-lmetis" SPQR_CONFIG="-DTIMING -DHAVE_TBB" TBB="-ltbb" BLAS="-lopenblas" LAPACK="-lopenblas" -C ${_lib} INSTALL_LIB=${PWD}/pkg/usr/local/lib INSTALL_INCLUDE=${PWD}/pkg/usr/local/include install
done

chmod 644 ${PWD}/pkg/usr/local/include/*.{h,hpp}
cp -d shared/*.dll* ${PWD}/pkg/usr/local/lib

cd ${PWD}/pkg
tar cvf suitesparse_4.0.2_mingw64.tgz ./usr
tar -tf suitesparse_4.0.2_mingw64.tgz > suitesparse_4.0.2_mingw64.list

Finally, numpy script
p:\\python27_64\\python.exe setup.py config_fc --fcompiler=gnu95 config --compiler="mingw32" config_fc --fcompiler=gnu95 build --compiler=p:\\MinGW\\bin\\g++.exe --compiler="mingw32" bdist_wininst

with this patch
diff -rup numpy-1.7.0b2/numpy/distutils/fcompiler/gnu.py numpy-1.7.0b2_patched/numpy/distutils/fcompiler/gnu.py
--- numpy-1.7.0b2/numpy/distutils/fcompiler/gnu.py 2012-09-19 21:16:52 -0400
+++ numpy-1.7.0b2_patched/numpy/distutils/fcompiler/gnu.py 2012-12-17 01:12:58 -0500
@@ -181,9 +181,9 @@ class GnuFCompiler(FCompiler):
# the following code is not needed (read: breaks) when using MinGW
# in case want to link F77 compiled code with MSVC
opt.append('gcc')
- runtime_lib = msvc_runtime_library()
- if runtime_lib:
- opt.append(runtime_lib)
+ #runtime_lib = msvc_runtime_library()
+ #if runtime_lib:
+ # opt.append(runtime_lib)
if sys.platform == 'darwin':
opt.append('cc_dynamic')
return opt
@@ -323,12 +323,12 @@ class Gnu95FCompiler(GnuFCompiler):
opt.insert(i+1, "mingwex")
opt.insert(i+1, "mingw32")
# XXX: fix this mess, does not work for mingw
- if is_win64():
- c_compiler = self.c_compiler
- if c_compiler and c_compiler.compiler_type == "msvc":
- return []
- else:
- raise NotImplementedError("Only MS compiler supported with gfortran on win64")
+ #if is_win64():
+ # c_compiler = self.c_compiler
+ # if c_compiler and c_compiler.compiler_type == "msvc":
+ # return []
+ # else:
+ # raise NotImplementedError("Only MS compiler supported with gfortran on win64")
return opt

def get_target(self):
diff -rup numpy-1.7.0b2/numpy/distutils/mingw32ccompiler.py numpy-1.7.0b2_patched/numpy/distutils/mingw32ccompiler.py
--- numpy-1.7.0b2/numpy/distutils/mingw32ccompiler.py 2012-09-04 17:31:31 -0400
+++ numpy-1.7.0b2_patched/numpy/distutils/mingw32ccompiler.py 2012-12-17 01:13:10 -0500
@@ -176,7 +176,8 @@ class Mingw32CCompiler(distutils.cygwinc
target_lang=None):
# Include the appropiate MSVC runtime library if Python was built
# with MSVC >= 7.0 (MinGW standard is msvcrt)
- runtime_library = msvc_runtime_library()
+ #runtime_library = msvc_runtime_library()
+ runtime_library = None
if runtime_library:
if not libraries:
libraries = []
diff -rup numpy-1.7.0b2/numpy/distutils/system_info.py numpy-1.7.0b2_patched/numpy/distutils/system_info.py
--- numpy-1.7.0b2/numpy/distutils/system_info.py 2012-09-04 17:31:31 -0400
+++ numpy-1.7.0b2_patched/numpy/distutils/system_info.py 2012-12-17 01:14:12 -0500
@@ -1340,10 +1340,16 @@ Make sure that -lgfortran is used for C+

class lapack_opt_info(system_info):

+ section = 'lapack_opt'
notfounderror = LapackNotFoundError

def calc_info(self):

+ info = self.calc_libraries_info()
+ if info:
+ self.set_info(**info)
+ return
+
if sys.platform == 'darwin' and not os.environ.get('ATLAS', None):
args = []
link_args = []
@@ -1429,10 +1435,16 @@ class lapack_opt_info(system_info):

class blas_opt_info(system_info):

+ section = 'blas_opt'
notfounderror = BlasNotFoundError

def calc_info(self):

+ info = self.calc_libraries_info()
+ if info:
+ self.set_info(**info)
+ return
+
if sys.platform == 'darwin' and not os.environ.get('ATLAS', None):
args = []
link_args = []

And site.cfg
[DEFAULT]
library_dirs = P:\\MinGW64\\msys64\\local\\lib
include_dirs = P:\\MinGW64\\msys64\\local\\include


[blas_opt]
#library_dirs = P:\\MinGW64\\msys64\\local\\lib
libraries = openblas_nehalemp-r0.2.5, gfortran
#libraries = openblas

[lapack_opt]
#library_dirs = P:\\MinGW64\\msys64\\local\\lib
libraries = openblas_nehalemp-r0.2.5, gfortran
#libraries = openblas

#[blas_opt]
#libraries = libopenblas_nehalemp-r0.2.5

#[lapack_opt]
#libraries = libopenblas_nehalemp-r0.2.5

#[blas_opt]
#libraries = f77blas, cblas, atlas
#
#[lapack_opt]
#libraries = lapack, f77blas, cblas, atlas
#
# If your ATLAS was compiled with pthreads, the names of the libraries might be
# different:
#
#[blas_opt]
#libraries = ptf77blas, ptcblas, atlas
#
#[lapack_opt]
#libraries = lapack, ptf77blas, ptcblas, atlas


[amd]
#library_dirs = P:\\MinGW64\\msys64\\local\\lib
amd_libs = amd

[umfpack]
#library_dirs = P:\\MinGW64\\msys64\\local\\lib
umfpack_libs = umfpack


No comments:

Post a Comment