[Numpy-svn] r4362 - in branches/numpy.scons/numpy: distutils/scons/checkers scons_fake/checkers

numpy-svn@scip... numpy-svn@scip...
Wed Oct 31 02:20:53 CDT 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