Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c663655

Browse files
committed
Implemented detection of gfortran usage for ATLAS linkage. get_atlas_version returns now a tuple (version_str, info_dict). Nice thing about the patch is that specifying gnu95 compiler is not needed anymore for numpy (neither for scipy) build when using ATLAS containing gfortran compiled blas/lapack.
1 parent 3743430 commit c663655

2 files changed

Lines changed: 65 additions & 28 deletions

File tree

numpy/distutils/command/config.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,15 @@ def get_output(self, body, headers=None, include_dirs=None,
399399
self._check_compiler()
400400
exitcode, output = 255, ''
401401
try:
402-
src, obj, exe = self._link(body, headers, include_dirs,
403-
libraries, library_dirs, lang)
402+
grabber = GrabStdout()
403+
try:
404+
src, obj, exe = self._link(body, headers, include_dirs,
405+
libraries, library_dirs, lang)
406+
grabber.restore()
407+
except:
408+
output = grabber.data
409+
grabber.restore()
410+
raise
404411
exe = os.path.join('.', exe)
405412
exitstatus, output = exec_command(exe, execute_in='.')
406413
if hasattr(os, 'WEXITSTATUS'):
@@ -416,6 +423,22 @@ def get_output(self, body, headers=None, include_dirs=None,
416423
log.info("success!")
417424
except (CompileError, LinkError):
418425
log.info("failure.")
419-
420426
self._clean()
421427
return exitcode, output
428+
429+
class GrabStdout(object):
430+
431+
def __init__(self):
432+
self.sys_stdout = sys.stdout
433+
self.data = ''
434+
sys.stdout = self
435+
436+
def write (self, data):
437+
self.sys_stdout.write(data)
438+
self.data += data
439+
440+
def flush (self):
441+
self.sys_stdout.flush()
442+
443+
def restore(self):
444+
sys.stdout = self.sys_stdout

numpy/distutils/system_info.py

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,9 @@ def calc_info(self):
10111011
else:
10121012
info['language'] = 'f77'
10131013

1014+
atlas_version, atlas_extra_info = get_atlas_version(**atlas)
1015+
dict_append(info, **atlas_extra_info)
1016+
10141017
self.set_info(**info)
10151018

10161019
class atlas_blas_info(atlas_info):
@@ -1035,6 +1038,9 @@ def calc_info(self):
10351038
dict_append(info,include_dirs=[h])
10361039
info['language'] = 'c'
10371040

1041+
atlas_version, atlas_extra_info = get_atlas_version(**atlas)
1042+
dict_append(atlas, **atlas_extra_info)
1043+
10381044
dict_append(info,**atlas)
10391045

10401046
self.set_info(**info)
@@ -1209,22 +1215,44 @@ def get_atlas_version(**config):
12091215
return _cached_atlas_version[key]
12101216
c = cmd_config(Distribution())
12111217
atlas_version = None
1218+
info = {}
12121219
try:
12131220
s, o = c.get_output(atlas_version_c_text,
12141221
libraries=libraries, library_dirs=library_dirs)
1215-
except: # failed to get version from file -- maybe on Windows
1222+
if s and re.search (r'undefined reference to `_gfortran', o, re.M):
1223+
s, o = c.get_output(atlas_version_c_text,
1224+
libraries=libraries + ['gfortran'], library_dirs=library_dirs)
1225+
if not s:
1226+
warnings.warn("""
1227+
*****************************************************
1228+
Linkage with ATLAS requires gfortran. Use
1229+
1230+
python setup.py config_fc --fcompiler=gnu95 ...
1231+
1232+
when building extension libraries that use ATLAS.
1233+
Make sure that -lgfortran is used for C++ extensions.
1234+
*****************************************************
1235+
""")
1236+
dict_append(info, language='f90',
1237+
define_macros = [('ATLAS_REQUIRES_GFORTRAN', None)])
1238+
except Exception, msg: # failed to get version from file -- maybe on Windows
12161239
# look at directory name
12171240
for o in library_dirs:
12181241
m = re.search(r'ATLAS_(?P<version>\d+[.]\d+[.]\d+)_',o)
12191242
if m:
12201243
atlas_version = m.group('version')
12211244
if atlas_version is not None:
1245+
12221246
break
12231247
# final choice --- look at ATLAS_VERSION environment
12241248
# variable
12251249
if atlas_version is None:
12261250
atlas_version = os.environ.get('ATLAS_VERSION',None)
1227-
return atlas_version or '?.?.?'
1251+
if atlas_version:
1252+
dict_append(info, define_macros = [('ATLAS_INFO','"\\"%s\\""' % atlas_version)])
1253+
else:
1254+
dict_append(info, define_macros = [('NO_ATLAS_INFO',-1)])
1255+
return atlas_version or '?.?.?', info
12281256

12291257
if not s:
12301258
m = re.search(r'ATLAS version (?P<version>\d+[.]\d+[.]\d+)',o)
@@ -1236,8 +1264,13 @@ def get_atlas_version(**config):
12361264
else:
12371265
log.info('Status: %d', s)
12381266
log.info('Output: %s', o)
1239-
_cached_atlas_version[key] = atlas_version
1240-
return atlas_version
1267+
1268+
if atlas_version=='3.2.1_pre3.3.6':
1269+
dict_append(info, define_macros = [('NO_ATLAS_INFO',-2)])
1270+
else:
1271+
dict_append(info, define_macros = [('ATLAS_INFO','"\\"%s\\""' % atlas_version)])
1272+
result = _cached_atlas_version[key] = atlas_version, info
1273+
return result
12411274

12421275
from distutils.util import get_platform
12431276

@@ -1286,22 +1319,12 @@ def calc_info(self):
12861319
need_blas = 0
12871320
info = {}
12881321
if atlas_info:
1289-
version_info = atlas_info.copy()
1290-
atlas_version = get_atlas_version(**version_info)
1291-
if 'define_macros' not in atlas_info:
1292-
atlas_info['define_macros'] = []
1293-
if atlas_version is None:
1294-
atlas_info['define_macros'].append(('NO_ATLAS_INFO',2))
1295-
else:
1296-
atlas_info['define_macros'].append(('ATLAS_INFO',
1297-
'"\\"%s\\""' % atlas_version))
1298-
if atlas_version=='3.2.1_pre3.3.6':
1299-
atlas_info['define_macros'].append(('NO_ATLAS_INFO',4))
1300-
l = atlas_info.get('define_macros',[])
1322+
l = atlas_info.get ('define_macros', [])
13011323
if ('ATLAS_WITH_LAPACK_ATLAS',None) in l \
13021324
or ('ATLAS_WITHOUT_LAPACK',None) in l:
13031325
need_lapack = 1
13041326
info = atlas_info
1327+
13051328
else:
13061329
warnings.warn(AtlasNotFoundError.__doc__)
13071330
need_blas = 1
@@ -1385,15 +1408,6 @@ def calc_info(self):
13851408
need_blas = 0
13861409
info = {}
13871410
if atlas_info:
1388-
version_info = atlas_info.copy()
1389-
atlas_version = get_atlas_version(**version_info)
1390-
if 'define_macros' not in atlas_info:
1391-
atlas_info['define_macros'] = []
1392-
if atlas_version is None:
1393-
atlas_info['define_macros'].append(('NO_ATLAS_INFO',2))
1394-
else:
1395-
atlas_info['define_macros'].append(('ATLAS_INFO',
1396-
'"\\"%s\\""' % atlas_version))
13971411
info = atlas_info
13981412
else:
13991413
warnings.warn(AtlasNotFoundError.__doc__)

0 commit comments

Comments
 (0)