[Numpy-svn] r4362 - in branches/numpy.scons/numpy: distutils/scons/checkers scons_fake/checkers
numpy-svn at scipy.org
numpy-svn at scipy.org
Wed Oct 31 03:20:53 EDT 2007
Author: cdavid
Date: 2007-10-31 02:20:40 -0500 (Wed, 31 Oct 2007)
New Revision: 4362
Modified:
branches/numpy.scons/numpy/distutils/scons/checkers/perflib.py
branches/numpy.scons/numpy/distutils/scons/checkers/support.py
branches/numpy.scons/numpy/scons_fake/checkers/SConstruct
Log:
More refactoring of custom checkers:
- implements a scheme for save-and-set / restore env variables used for tests
- MKL and ATLAS checkers implemented using the above scheme
Modified: branches/numpy.scons/numpy/distutils/scons/checkers/perflib.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/checkers/perflib.py 2007-10-30 16:21:04 UTC (rev 4361)
+++ branches/numpy.scons/numpy/distutils/scons/checkers/perflib.py 2007-10-31 07:20:40 UTC (rev 4362)
@@ -37,6 +37,10 @@
# printf("Major version: %d\n",ver.MajorVersion);
# printf("Minor version: %d\n",ver.MinorVersion);
# printf("Build number: %d\n",ver.BuildNumber);
+# printf("Full version: %d.%d.%d\n",
+# ver.MajorVersion,
+# ver.MinorVersion,
+# ver.BuildNumber);
# printf("Product status: %s\n",ver.ProductStatus);
# printf("Build: %s\n",ver.Build);
# printf("Processor optimization: %s\n",ver.Processor);
@@ -45,49 +49,207 @@
# }
# """
-def CheckMKL(context, autoadd = 1):
- """Check MKL is usable using a simple cblas example."""
+# def CheckMKL(context, autoadd = 1):
+# """Check MKL is usable using a simple cblas example."""
+# section = "mkl"
+# siteconfig, cfgfiles = get_config()
+# (cpppath, libs, libpath), found = get_config_from_section(siteconfig, section)
+# if not found:
+# # XXX: find exact options to use for the MKL
+# libs.extend(['mkl', 'guide', 'm'])
+#
+# headers = ['mkl.h']
+#
+# return check_include_and_run(context, 'MKL', cpppath, headers,
+# cblas_src, libs, libpath, [], [], autoadd)
+
+def _CheckATLASVersion(context):
+ pass
+
+from support import save_set, restore
+import re
+
+def CheckMKL(context, check_version = 1, autoadd = 1):
+ """Check whether mkl is usable in C."""
+ context.Message("Checking MKL ... ")
+
+ # XXX: take into account siteconfig
section = "mkl"
siteconfig, cfgfiles = get_config()
(cpppath, libs, libpath), found = get_config_from_section(siteconfig, section)
if not found:
# XXX: find exact options to use for the MKL
libs.extend(['mkl', 'guide', 'm'])
+ opts = {'cpppath' : cpppath, 'libpath' : libpath, 'libs' : libs}
+ env = context.env
+ test_funcs = ['MKLGetVersion']
headers = ['mkl.h']
- return check_include_and_run(context, 'MKL', cpppath, headers,
- cblas_src, libs, libpath, [], [], autoadd)
+ # Check whether the header is available (CheckHeader-like checker)
+ saved = save_set(env, opts)
+ try:
+ # XXX: add dep vars in code
+ src = '\n'.join([r'#include <%s>\n' % h for h in headers])
+ st = context.TryCompile(src, '.c')
+ finally:
+ restore(env, saved)
-def _CheckATLASVersion(context):
- pass
+ if not st:
+ context.Result('Failed (could not check header(s))')
+ return st
+ # Check whether the library is available (CheckLib-like checker)
+ saved = save_set(env, opts)
+ try:
+ for sym in test_funcs:
+ # XXX: add dep vars in code
+ st = check_symbol(context, headers, sym)
+ if not st:
+ break
+ finally:
+ if st == 0 or autoadd == 0:
+ restore(env, saved)
+
+ if not st:
+ context.Result('Failed (could not check symbol %s)' % sym)
+ return st
+
+ context.Result(st)
+
+ # Check version if requested
+ if check_version:
+ saved = save_set(env, opts)
+ version_code = """
+#include <stdio.h>
+#include <mkl.h>
+
+int main(void)
+{
+ MKLVersion ver;
+ MKLGetVersion(&ver);
+
+ printf("Full version: %d.%d.%d\n", ver.MajorVersion,
+ ver.MinorVersion,
+ ver.BuildNumber);
+
+ return 0;
+}
+"""
+
+ try:
+ vst, out = context.TryRun(version_code, '.c')
+ finally:
+ restore(env, saved)
+
+ if not vst:
+ version = r'?.?.? (could not get version)'
+ else:
+ m = re.search(
+ r'Full version: (\d+[.]\d+[.]\d+)',
+ out)
+ if m:
+ version = m.group('version')
+ else:
+ version = r'?.?.? (could not get version)'
+ opts['version'] = version
+
+ return st, opts
+
+def check_symbol(context, headers, sym, extra = r''):
+ # XXX: add dep vars in code
+ code = [r'#include <%s>' %h for h in headers]
+ code.append(r'''
+#undef %(func)s
+#ifdef __cplusplus
+extern "C"
+#endif
+char %(func)s();
+
+int main()
+{
+return %(func)s();
+return 0;
+}
+''' % {'func' : sym})
+ code.append(extra)
+ return context.TryLink('\n'.join(code), '.c')
+
def CheckATLAS2(context, check_version = 1, autoadd = 1):
"""Check whether ATLAS is usable in C."""
- opts = CheckOptions(libs = ['atlas'])
-
context.Message("Checking ATLAS ... ")
+ section = "atlas"
+ siteconfig, cfgfiles = get_config()
+ (cpppath, libs, libpath), found = get_config_from_section(siteconfig, section)
+ if not found:
+ libs.extend(['atlas'])
+ opts = {'cpppath' : cpppath, 'libpath' : libpath, 'libs' : libs}
+
env = context.env
- env.AppendUnique(LIBS = 'atlas')
+ test_funcs = ['ATL_sgemm']
+ headers = ['atlas_enum.h']
+ # Check whether the header is available (CheckHeader-like checker)
+ saved = save_set(env, opts)
+ try:
+ # XXX: add dep vars in code
+ src = '\n'.join([r'#include <%s>\n' % h for h in headers])
+ st = context.TryCompile(src, '.c')
+ finally:
+ restore(env, saved)
+
+ if not st:
+ context.Result('Failed (could not check header(s))')
+ return st
+
# Check whether the library is available (CheckLib-like checker)
+ saved = save_set(env, opts)
+ try:
+ for sym in test_funcs:
+ # XXX: add dep vars in code
+ st = check_symbol(context, headers, sym)
+ if not st:
+ break
+ finally:
+ if st == 0 or autoadd == 0:
+ restore(env, saved)
+
+ if not st:
+ context.Result('Failed (could not check symbol %s)' % sym)
+ return st
+
+ context.Result(st)
# Check version if requested
- version_code = """
+ if check_version:
+ saved = save_set(env, opts)
+ version_code = """
void ATL_buildinfo(void);
int main(void) {
ATL_buildinfo();
return 0;
}
"""
- if not context.TryLink(version_code, '.c'):
- return "blas blas"
+ try:
+ vst, out = context.TryRun(version_code, '.c')
+ finally:
+ restore(env, saved)
- st, out = context.TryRun(version_code, '.c')
- context.Result(st)
- return st
+ if not vst:
+ version = r'?.?.? (could not get version)'
+ else:
+ m = re.search(
+ r'ATLAS version (?P<version>\d+[.]\d+[.]\d+)',
+ out)
+ if m:
+ version = m.group('version')
+ else:
+ version = r'?.?.? (could not get version)'
+ opts['version'] = version
+ return st, opts
+
def CheckATLAS(context, autoadd = 1):
"""Check whether ATLAS is usable in C."""
Modified: branches/numpy.scons/numpy/distutils/scons/checkers/support.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/checkers/support.py 2007-10-30 16:21:04 UTC (rev 4361)
+++ branches/numpy.scons/numpy/distutils/scons/checkers/support.py 2007-10-31 07:20:40 UTC (rev 4362)
@@ -5,94 +5,32 @@
from copy import deepcopy
-class CheckOptions:
- def __init__(self, cpppath = None, headers = None, cflags = None,
- libpath = None, libs = None, linkflags = None):
- if cpppath:
- self.cpppath = cpppath
- else:
- self.cpppath = []
+_arg2env = {'cpppath' : 'CPPPATH',
+ 'cflags' : 'CFLAGS',
+ 'libpath' : 'LIBPATH',
+ 'libs' : 'LIBS',
+ 'linkflags' : 'LINKFLAGS'}
- if headers:
- self.headers = headers
- else:
- self.headers = []
+def save_set(env, opts):
+ """keys given as config opts args."""
+ saved_keys = {}
+ keys = opts.keys()
+ for k in keys:
+ saved_keys[k] = (env.has_key(_arg2env[k]) and\
+ deepcopy(env[_arg2env[k]])) or\
+ []
+ kw = zip([_arg2env[k] for k in keys], [opts[k] for k in keys])
+ kw = dict(kw)
+ env.AppendUnique(**kw)
+ return saved_keys
- if cflags:
- self.cflags = cflags
- else:
- self.cflags = []
+def restore(env, saved_keys):
+ keys = saved_keys.keys()
+ kw = zip([_arg2env[k] for k in keys],
+ [saved_keys[k] for k in keys])
+ kw = dict(kw)
+ env.Replace(**kw)
- if libpath:
- self.libpath = libpath
- else:
- self.libpath = []
-
- if libs:
- self.libs = libs
- else:
- self.libs = []
-
- if linkflags:
- self.linkflags = linkflags
- else:
- self.linkflags = []
-
-def _check_headers(context, cpppath, cflags, headers, autoadd):
- """Try to compile code including the given headers."""
- env = context.env
-
- #----------------------------
- # Check headers are available
- #----------------------------
- oldCPPPATH = (env.has_key('CPPPATH') and deepcopy(env['CPPPATH'])) or []
- oldCFLAGS = (env.has_key('CFLAGS') and deepcopy(env['CFLAGS'])) or []
- env.AppendUnique(CPPPATH = cpppath)
- env.AppendUnique(CFLAGS = cflags)
- # XXX: handle context
- hcode = ['#include <%s>' % h for h in headers]
-
- # HACK: we add cpppath in the command of the source, to add dependency of
- # the check on the cpppath.
- hcode.extend(['#if 0', '%s' % cpppath, '#endif\n'])
- src = '\n'.join(hcode)
-
- ret = context.TryCompile(src, '.c')
- if ret == 0 or autoadd == 0:
- env.Replace(CPPPATH = oldCPPPATH)
- env.Replace(CFLAGS = oldCFLAGS)
- return 0
-
- return ret
-
-def _check_libs(context, cpppath, headers, cflags, libpath, libs, linkflags, autoadd):
- raise NotImplementedError("FIXME")
- #------------------------------
- # Check a simple example works
- #------------------------------
- oldLIBPATH = (env.has_key('LIBPATH') and deepcopy(env['LIBPATH'])) or []
- oldLIBS = (env.has_key('LIBS') and deepcopy(env['LIBS'])) or []
- oldLINKFLAGS = (env.has_key('LINKFLAGS') and deepcopy(env['LINKFLAGS'])) or []
- # # XXX: RPATH, drawbacks using it ?
- # oldRPATH = (env.has_key('RPATH') and deepcopy(env['RPATH'])) or []
- env.AppendUnique(LIBPATH = libpath)
- env.AppendUnique(LIBS = libs)
- #env.AppendUnique(RPATH = libpath)
- env.AppendUnique(LINKFLAGS = linkflags)
-
- # HACK: we add libpath and libs at the end of the source as a comment, to
- # add dependency of the check on those.
- src = '\n'.join(['#include <%s>' % h for h in headers] +\
- [run_src, '#if 0', '%s' % libpath,
- '%s' % headers, '%s' % libs, '#endif'])
- ret = context.TryLink(src, '.c')
- if (not ret or not autoadd):
- # If test failed or autoadd = 0, restore everything
- env.Replace(LIBS = oldLIBS)
- env.Replace(LIBPATH = oldLIBPATH)
- env.Replace(RPATH = oldRPATH)
- env.Replace(LINKFLAGS = oldLINKFLAGS)
-
def check_include_and_run(context, name, cpppath, headers, run_src, libs,
libpath, linkflags, cflags, autoadd = 1):
"""This is a basic implementation for generic "test include and run"
@@ -152,7 +90,3 @@
context.Result(ret)
return ret
-
-def check_lib(context, library = None, symbols = None, headers = None, language = 'C'):
- if language is not 'C':
- raise NotImplementedError('FIXME: support non-C languages')
Modified: branches/numpy.scons/numpy/scons_fake/checkers/SConstruct
===================================================================
--- branches/numpy.scons/numpy/scons_fake/checkers/SConstruct 2007-10-30 16:21:04 UTC (rev 4361)
+++ branches/numpy.scons/numpy/scons_fake/checkers/SConstruct 2007-10-31 07:20:40 UTC (rev 4362)
@@ -21,8 +21,12 @@
if do_check:
#config.CheckATLAS(autoadd = 0)
- config.CheckATLAS2(autoadd = 0)
- config.CheckMKL(autoadd = 0)
+ st, opts = config.CheckATLAS2(autoadd = 0)
+ if st:
+ print opts
+ st, opts = config.CheckMKL(autoadd = 0)
+ if st:
+ print opts
config.CheckAccelerate(autoadd = 0)
config.CheckSunperf(autoadd = 0)
More information about the Numpy-svn
mailing list