diff --git a/recipe/aarch_site.cfg b/recipe/aarch_site.cfg deleted file mode 100644 index fcb89f4e..00000000 --- a/recipe/aarch_site.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[openblas] -libraries = armpl_lp64 -library_dirs = $PREFIX/lib -include_dirs = $PREFIX/include -runtime_library_dirs = $PREFIX/lib - diff --git a/recipe/install_base.sh b/recipe/install_base.sh index bb44cf8c..ead8624e 100644 --- a/recipe/install_base.sh +++ b/recipe/install_base.sh @@ -8,10 +8,11 @@ if [[ ! -f $BUILD_PREFIX/bin/ranlib ]]; then ln -s $AR $BUILD_PREFIX/bin/ar fi -# site.cfg is provided by blas devel packages (either mkl-devel or openblas-devel) -case $( uname -m ) in -aarch64) cp $RECIPE_DIR/aarch_site.cfg site.cfg;; -*) cp $PREFIX/site.cfg site.cfg;; -esac +# To build the different BLAS variants, the site.cfg file is provided +# by the BLAS packages (mkl-devel, openblas-devel, or armpl). See: +# intel_repack-feedstock/recipe/install-devel.sh +# openblas-feedstock/recipe/build.sh +# armpl-feedstock/recipe/repack_armpl.sh +cp $PREFIX/site.cfg site.cfg ${PYTHON} -m pip install --no-deps --ignore-installed -v . diff --git a/recipe/meta.yaml b/recipe/meta.yaml index e050d303..771a0a5b 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -14,6 +14,7 @@ source: - patches/0004-disable-autorun-for-cmd-test.patch # [win] - patches/0005-array_coercion_fix.patch # [blas_impl == "mkl" and win] - patches/0006-popcnt_fix.patch # [blas_impl == "mkl" and win] + - patches/0007-armpl-build.patch # [blas_impl == "armpl"] build: number: 0 @@ -41,15 +42,16 @@ outputs: - {{ compiler("c") }} # libllvm10 10.0.0 build 1 has an issue building numpy, use build 0 - libllvm10 10.0.0 h21ff451_0 # [osx] - - armpl #[aarch64] host: - python - pip - cython >=0.29.21 - - mkl-devel {{ mkl }} # [blas_impl == "mkl"] + - mkl-devel {{ mkl }} # [blas_impl == "mkl"] - openblas-devel {{ openblas }} # [blas_impl == "openblas"] + - armpl {{ armpl }} # [blas_impl == "armpl"] run: - python + - armpl {{ armpl }} # [blas_impl == "armpl"] # When building out the initial package set for a new Python version / MKL version the # recommendation is to build numpy-base but not numpy, then build # mkl_fft and mkl_random, and then numpy. @@ -67,19 +69,20 @@ outputs: build: # for runtime alignment - {{ compiler('c') }} - - armpl # [aarch64] host: - python # these import blas metapackages to ensure consistency with downstream libs that also use blas - - mkl-devel {{ mkl }} # [blas_impl == 'mkl'] + - mkl-devel {{ mkl }} # [blas_impl == 'mkl'] - openblas-devel {{ openblas }} # [blas_impl == 'openblas'] + - armpl {{ armpl }} # [blas_impl == "armpl"] run: - python - {{ pin_subpackage('numpy-base', exact=True) }} # openblas or mkl runtime included with run_exports - - mkl_fft # [blas_impl == 'mkl'] - - mkl_random # [blas_impl == 'mkl' and (not win or vc>=14)] - # - mkl_umath # [blas_impl == 'mkl'] + - mkl_fft # [blas_impl == 'mkl'] + - mkl_random # [blas_impl == 'mkl' and (not win or vc>=14)] + # - mkl_umath # [blas_impl == 'mkl'] + - armpl # [blas_impl == "armpl"] {% endif %} {% set tests_to_skip = "_not_a_real_test" %} # Seems to fail with current version of blas for large numbers @@ -91,6 +94,8 @@ outputs: # Only the complex256 system is failing, but I don't know how to skip it on its own # https://github.com/numpy/numpy/issues/15243 {% set tests_to_skip = tests_to_skip + " or test_loss_of_precision" %} # [ppc64le or aarch64 or s390x] + # ArmPL BLAS implementation requires us to add additional Arm modules. + {% set tests_to_skip = tests_to_skip + " or test_all_modules_are_expected" %} # [blas_impl == "armpl"] test: requires: - pip # force installation or `test_api_importable` will fail diff --git a/recipe/patches/0007-armpl-build.patch b/recipe/patches/0007-armpl-build.patch new file mode 100644 index 00000000..a4fee38f --- /dev/null +++ b/recipe/patches/0007-armpl-build.patch @@ -0,0 +1,257 @@ +From 9b68ebe83d9f4ffbd0e70a3aed7e477e10568007 Mon Sep 17 00:00:00 2001 +From: Paul Yim +Date: Thu, 14 Oct 2021 17:05:58 -0400 +Subject: [PATCH] patch changes v1.21.2 + +--- + numpy/distutils/armccompiler.py | 23 +++++++++ + numpy/distutils/ccompiler.py | 2 + + numpy/distutils/fcompiler/__init__.py | 2 +- + numpy/distutils/fcompiler/arm.py | 72 +++++++++++++++++++++++++++ + numpy/distutils/system_info.py | 60 ++++++++++++++++++++-- + 5 files changed, 155 insertions(+), 4 deletions(-) + create mode 100644 numpy/distutils/armccompiler.py + create mode 100644 numpy/distutils/fcompiler/arm.py + +diff --git a/numpy/distutils/armccompiler.py b/numpy/distutils/armccompiler.py +new file mode 100644 +index 000000000..4b58e6033 +--- /dev/null ++++ b/numpy/distutils/armccompiler.py +@@ -0,0 +1,23 @@ ++from __future__ import division, absolute_import, print_function ++ ++from distutils.unixccompiler import UnixCCompiler ++ ++class ArmCCompiler(UnixCCompiler): ++ ++ """ ++ Arm compiler. ++ """ ++ ++ compiler_type = 'arm' ++ cc_exe = 'armclang' ++ cxx_exe = 'armclang++' ++ ++ def __init__ (self, verbose=0, dry_run=0, force=0): ++ UnixCCompiler.__init__ (self, verbose, dry_run, force) ++ cc_compiler = self.cc_exe ++ cxx_compiler = self.cxx_exe ++ self.set_executables(compiler=cc_compiler + ' -mcpu=native -O3', ++ compiler_so=cc_compiler + ' -mcpu=native -O3', ++ compiler_cxx=cxx_compiler + ' -mcpu=native -O3', ++ linker_exe=cc_compiler + ' -lamath', ++ linker_so=cc_compiler + ' -lamath -shared') +diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py +index 061f4862d..f2df44884 100644 +--- a/numpy/distutils/ccompiler.py ++++ b/numpy/distutils/ccompiler.py +@@ -699,6 +699,8 @@ def CCompiler_cxx_compiler(self): + "Intel C Compiler for 64-bit applications on Windows") + compiler_class['pathcc'] = ('pathccompiler', 'PathScaleCCompiler', + "PathScale Compiler for SiCortex-based applications") ++compiler_class['arm'] = ('armccompiler', 'ArmCCompiler', ++ "Arm C Compiler") + ccompiler._default_compilers += (('linux.*', 'intel'), + ('linux.*', 'intele'), + ('linux.*', 'intelem'), +diff --git a/numpy/distutils/fcompiler/__init__.py b/numpy/distutils/fcompiler/__init__.py +index d7579e976..6744f28b2 100644 +--- a/numpy/distutils/fcompiler/__init__.py ++++ b/numpy/distutils/fcompiler/__init__.py +@@ -743,7 +743,7 @@ def wrap_unlinkable_objects(self, objects, output_dir, extra_dll_dir): + ('win32', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95', + 'intelvem', 'intelem', 'flang')), + ('cygwin.*', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95')), +- ('linux.*', ('gnu95', 'intel', 'lahey', 'pg', 'nv', 'absoft', 'nag', 'vast', 'compaq', ++ ('linux.*', ('arm', 'gnu95', 'intel', 'lahey', 'pg', 'nv', 'absoft', 'nag', 'vast', 'compaq', + 'intele', 'intelem', 'gnu', 'g95', 'pathf95', 'nagfor', 'fujitsu')), + ('darwin.*', ('gnu95', 'nag', 'absoft', 'ibm', 'intel', 'gnu', 'g95', 'pg')), + ('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')), +diff --git a/numpy/distutils/fcompiler/arm.py b/numpy/distutils/fcompiler/arm.py +new file mode 100644 +index 000000000..fd51d2627 +--- /dev/null ++++ b/numpy/distutils/fcompiler/arm.py +@@ -0,0 +1,72 @@ ++from __future__ import division, absolute_import, print_function ++ ++import sys ++ ++from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file ++from sys import platform ++from os.path import join, dirname, normpath ++ ++compilers = ['ArmFlangCompiler'] ++ ++import functools ++ ++class ArmFlangCompiler(FCompiler): ++ compiler_type = 'arm' ++ description = 'Arm Compiler' ++ version_pattern = r'\s*Arm.*version (?P[\d.-]+).*' ++ ++ ar_exe = 'lib.exe' ++ possible_executables = ['armflang'] ++ ++ executables = { ++ 'version_cmd': ["", "--version"], ++ 'compiler_f77': ["armflang"], ++ 'compiler_fix': ["armflang", "-ffixed-form"], ++ 'compiler_f90': ["armflang"], ++ 'linker_so': ["armflang", "-fPIC", "-shared"], ++ 'archiver': ["ar", "-cr"], ++ 'ranlib': None ++ } ++ ++ pic_flags = ["-fPIC", "-DPIC"] ++ c_compiler = 'arm' ++ module_dir_switch = '-module ' # Don't remove ending space! ++ ++ def get_libraries(self): ++ opt = FCompiler.get_libraries(self) ++ opt.extend(['flang', 'flangrti', 'ompstub']) ++ return opt ++ ++ @functools.lru_cache(maxsize=128) ++ def get_library_dirs(self): ++ """List of compiler library directories.""" ++ opt = FCompiler.get_library_dirs(self) ++ flang_dir = dirname(self.executables['compiler_f77'][0]) ++ opt.append(normpath(join(flang_dir, '..', 'lib'))) ++ ++ return opt ++ ++ def get_flags(self): ++ return [] ++ ++ def get_flags_free(self): ++ return [] ++ ++ def get_flags_debug(self): ++ return ['-g'] ++ ++ def get_flags_opt(self): ++ return ['-O3'] ++ ++ def get_flags_arch(self): ++ return [] ++ ++ def runtime_library_dir_option(self, dir): ++ return '-Wl,-rpath=%s' % dir ++ ++ ++if __name__ == '__main__': ++ from distutils import log ++ log.set_verbosity(2) ++ from numpy.distutils import customized_fcompiler ++ print(customized_fcompiler(compiler='armflang').get_version()) +diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py +index 59de69d77..bc0eefb5c 100644 +--- a/numpy/distutils/system_info.py ++++ b/numpy/distutils/system_info.py +@@ -501,7 +501,11 @@ def get_info(name, notfound_action=0): + 1 - display warning message + 2 - raise error + """ +- cl = {'atlas': atlas_info, # use lapack_opt or blas_opt instead ++ cl = {'armpl': armpl_info, ++ 'blas_armpl': blas_armpl_info, ++ 'lapack_armpl': lapack_armpl_info, ++ 'fftw3_armpl' : fftw3_armpl_info, ++ 'atlas': atlas_info, # use lapack_opt or blas_opt instead + 'atlas_threads': atlas_threads_info, # ditto + 'atlas_blas': atlas_blas_info, + 'atlas_blas_threads': atlas_blas_threads_info, +@@ -1153,6 +1157,17 @@ class fftw3_info(fftw_info): + ] + + ++class fftw3_armpl_info(fftw_info): ++ section = 'fftw3' ++ dir_env_var = 'PREFIX' ++ notfounderror = FFTWNotFoundError ++ ver_info = [{'name':'fftw3', ++ 'libs':['armpl_lp64_mp'], ++ 'includes':['fftw3.h'], ++ 'macros':[('SCIPY_FFTW3_H', None)]}, ++ ] ++ ++ + class dfftw_info(fftw_info): + section = 'fftw' + dir_env_var = 'FFTW' +@@ -1303,6 +1318,31 @@ def calc_info(self): + self.set_info(**info) + + ++class armpl_info(system_info): ++ section = 'armpl' ++ dir_env_var = 'ARMPL_DIR' ++ _lib_armpl = ['armpl_lp64_mp'] ++ ++ def calc_info(self): ++ lib_dirs = self.get_lib_dirs() ++ incl_dirs = self.get_include_dirs() ++ armpl_libs = self.get_libs('armpl_libs', self._lib_armpl) ++ info = self.check_libs2(lib_dirs, armpl_libs) ++ if info is None: ++ return ++ dict_append(info, ++ define_macros=[('SCIPY_MKL_H', None), ++ ('HAVE_CBLAS', None)], ++ include_dirs=incl_dirs) ++ self.set_info(**info) ++ ++class lapack_armpl_info(armpl_info): ++ pass ++ ++class blas_armpl_info(armpl_info): ++ pass ++ ++ + class lapack_mkl_info(mkl_info): + pass + +@@ -1750,10 +1790,17 @@ class lapack_opt_info(system_info): + notfounderror = LapackNotFoundError + + # List of all known LAPACK libraries, in the default order +- lapack_order = ['mkl', 'openblas', 'flame', ++ lapack_order = ['armpl', 'mkl', 'openblas', 'flame', + 'accelerate', 'atlas', 'lapack'] + order_env_var_name = 'NPY_LAPACK_ORDER' + ++ def _calc_info_armpl(self): ++ info = get_info('lapack_armpl') ++ if info: ++ self.set_info(**info) ++ return True ++ return False ++ + def _calc_info_mkl(self): + info = get_info('lapack_mkl') + if info: +@@ -1927,10 +1974,17 @@ class blas_opt_info(system_info): + notfounderror = BlasNotFoundError + # List of all known BLAS libraries, in the default order + +- blas_order = ['mkl', 'blis', 'openblas', ++ blas_order = ['armpl', 'mkl', 'blis', 'openblas', + 'accelerate', 'atlas', 'blas'] + order_env_var_name = 'NPY_BLAS_ORDER' + ++ def _calc_info_armpl(self): ++ info = get_info('blas_armpl') ++ if info: ++ self.set_info(**info) ++ return True ++ return False ++ + def _calc_info_mkl(self): + info = get_info('blas_mkl') + if info: +-- +2.24.3 (Apple Git-128) + +