Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add ARM Compiler with ARM Performance Library support #20682

Merged
merged 12 commits into from Dec 30, 2021
28 changes: 28 additions & 0 deletions numpy/distutils/armccompiler.py
@@ -0,0 +1,28 @@
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 +
' -O3 -fPIC',
compiler_so=cc_compiler +
' -O3 -fPIC',
compiler_cxx=cxx_compiler +
' -O3 -fPIC',
linker_exe=cc_compiler +
' -lamath',
linker_so=cc_compiler +
' -lamath -shared')
3 changes: 3 additions & 0 deletions numpy/distutils/ccompiler.py
Expand Up @@ -708,6 +708,9 @@ 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'),
Expand Down
5 changes: 3 additions & 2 deletions numpy/distutils/fcompiler/__init__.py
Expand Up @@ -743,8 +743,9 @@ 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',
'intele', 'intelem', 'gnu', 'g95', 'pathf95', 'nagfor', 'fujitsu')),
('linux.*', ('arm', 'gnu95', 'intel', 'lahey', 'pg', 'nv', 'absoft', 'nag',
'vast', 'compaq', 'intele', 'intelem', 'gnu', 'g95',
'pathf95', 'nagfor', 'fujitsu')),
('darwin.*', ('gnu95', 'nag', 'nagfor', 'absoft', 'ibm', 'intel', 'gnu',
'g95', 'pg')),
('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')),
Expand Down
73 changes: 73 additions & 0 deletions numpy/distutils/fcompiler/arm.py
@@ -0,0 +1,73 @@
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<version>[\d.-]+).*'

ar_exe = 'lib.exe'
possible_executables = ['armflang']

executables = {
'version_cmd': ["", "--version"],
'compiler_f77': ["armflang", "-fPIC"],
'compiler_fix': ["armflang", "-fPIC", "-ffixed-form"],
'compiler_f90': ["armflang", "-fPIC"],
'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())

59 changes: 56 additions & 3 deletions numpy/distutils/system_info.py
Expand Up @@ -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,
Expand Down Expand Up @@ -1152,6 +1156,16 @@ class fftw3_info(fftw_info):
'macros':[('SCIPY_FFTW3_H', None)]},
]


class fftw3_armpl_info(fftw_info):
section = 'fftw3'
dir_env_var = 'ARMPL_DIR'
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'
Expand Down Expand Up @@ -1311,6 +1325,31 @@ class blas_mkl_info(mkl_info):
pass


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 atlas_info(system_info):
section = 'atlas'
dir_env_var = 'ATLAS'
Expand Down Expand Up @@ -1748,9 +1787,16 @@ 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')
Expand Down Expand Up @@ -1925,9 +1971,16 @@ 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')
Expand Down
2 changes: 2 additions & 0 deletions numpy/tests/test_public_api.py
Expand Up @@ -189,6 +189,7 @@ def test_NPY_NO_EXPORT():
"core.shape_base",
"core.umath",
"core.umath_tests",
"distutils.armccompiler",
"distutils.ccompiler",
'distutils.ccompiler_opt',
"distutils.command",
Expand All @@ -214,6 +215,7 @@ def test_NPY_NO_EXPORT():
"distutils.extension",
"distutils.fcompiler",
"distutils.fcompiler.absoft",
"distutils.fcompiler.arm",
"distutils.fcompiler.compaq",
"distutils.fcompiler.environment",
"distutils.fcompiler.g95",
Expand Down