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

numpy-svn@scip... numpy-svn@scip...
Fri Nov 16 03:08:49 CST 2007


Author: cdavid
Date: 2007-11-16 03:08:18 -0600 (Fri, 16 Nov 2007)
New Revision: 4462

Modified:
   branches/numpy.scons/numpy/distutils/scons/__init__.py
   branches/numpy.scons/numpy/distutils/scons/checkers/__init__.py
   branches/numpy.scons/numpy/distutils/scons/checkers/custom_checkers.py
   branches/numpy.scons/numpy/distutils/scons/checkers/support.py
   branches/numpy.scons/numpy/distutils/scons/testcode_snippets.py
   branches/numpy.scons/numpy/linalg/SConstruct
   branches/numpy.scons/numpy/scons_fake/checkers/SConstruct
Log:
Improve lapack and blas checkers, make the difference between  C and F77 blas/lapack

Modified: branches/numpy.scons/numpy/distutils/scons/__init__.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/__init__.py	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/distutils/scons/__init__.py	2007-11-16 09:08:18 UTC (rev 4462)
@@ -4,7 +4,7 @@
 from core.extension import get_python_inc, get_pythonlib_dir
 from core.utils import isstring, rsplit
 
-from checkers import CheckCBLAS, CheckLAPACK
+from checkers import CheckCBLAS, CheckCLAPACK, CheckF77BLAS, CheckF77LAPACK
 from fortran_scons import CheckF77Verbose, CheckF77Clib, CheckF77Mangling
 
 # XXX: this is ugly, better find the mathlibs with a checker 

Modified: branches/numpy.scons/numpy/distutils/scons/checkers/__init__.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/checkers/__init__.py	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/distutils/scons/checkers/__init__.py	2007-11-16 09:08:18 UTC (rev 4462)
@@ -1 +1 @@
-from custom_checkers import CheckLAPACK, CheckCBLAS
+from custom_checkers import CheckCLAPACK, CheckCBLAS, CheckF77BLAS, CheckF77LAPACK

Modified: branches/numpy.scons/numpy/distutils/scons/checkers/custom_checkers.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/checkers/custom_checkers.py	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/distutils/scons/checkers/custom_checkers.py	2007-11-16 09:08:18 UTC (rev 4462)
@@ -1,5 +1,5 @@
 #! /usr/bin/env python
-# Last Change: Mon Nov 12 07:00 PM 2007 J
+# Last Change: Fri Nov 16 05:00 PM 2007 J
 
 # Module for custom, common checkers for numpy (and scipy)
 import sys
@@ -9,7 +9,7 @@
 
 from numpy.distutils.scons.core.libinfo import get_config_from_section, get_config
 from numpy.distutils.scons.testcode_snippets import cblas_sgemm as cblas_src, \
-        c_sgemm as sunperf_src, lapack_sgesv
+        c_sgemm as sunperf_src, lapack_sgesv, blas_sgemm, c_sgemm2
 from numpy.distutils.scons.fortran_scons import CheckF77Mangling, CheckF77Clib
 from numpy.distutils.scons.configuration import add_info
 from numpy.distutils.scons.core.utils import rsplit
@@ -34,6 +34,17 @@
     # XXX: rpath vs LD_LIBRARY_PATH ?
     env = context.env
 
+    def check(func, name, suplibs):
+        st, res = func(context, autoadd)
+        if st:
+            for lib in suplibs:
+                res.cfgopts['libs'].insert(0, lib)
+            st = check_include_and_run(context, 'CBLAS (%s)' % name, 
+                                       res.cfgopts, [], cblas_src, autoadd)
+            if st:
+                add_info(env, 'cblas', res)
+            return st
+
     # If section cblas is in site.cfg, use those options. Otherwise, use default
     section = "cblas"
     siteconfig, cfgfiles = get_config()
@@ -48,20 +59,13 @@
         return st
     else:
         if sys.platform == 'darwin':
-            st, res = CheckAccelerate(context, autoadd)
+            # Check Accelerate
+            st = check(CheckAccelerate, 'Accelerate Framework', [])
             if st:
-                st = check_include_and_run(context, 'CBLAS (Accelerate Framework)', 
-                                           res.cfgopts, [], cblas_src, autoadd)
-                if st:
-                    add_info(env, 'cblas', res)
                 return st
 
-            st, res = CheckVeclib(context, autoadd)
+            st = check(CheckVeclib, 'vecLib Framework', [])
             if st:
-                st = check_include_and_run(context, 'CBLAS (vecLib Framework)', 
-                                           res.cfgopts, [], cblas_src, autoadd)
-                if st:
-                    add_info(env, 'cblas', res)
                 return st
 
             add_info(env, 'cblas', 'Def numpy implementation used')
@@ -69,38 +73,178 @@
             
         else:
             # XXX: think about how to share headers info between checkers ?
+
             # Check MKL
-            st, res = CheckMKL(context, autoadd)
+            st = check(CheckMKL, 'MKL', [])
             if st:
-                st = check_include_and_run(context, 'CBLAS (MKL)', res.cfgopts,
-                                           [], cblas_src, autoadd)
-                if st:
-                    add_info(env, 'cblas', res)
                 return st
 
             # Check ATLAS
-            st, res = CheckATLAS(context, autoadd)
+            st = check(CheckATLAS, 'ATLAS', ['blas'])
             if st:
-                res.cfgopts['libs'].insert(0, 'blas')
-                st = check_include_and_run(context, 'CBLAS (ATLAS)', res.cfgopts,
-                                           [], cblas_src, autoadd)
-                if st:
-                    add_info(env, 'cblas', res)
                 return st
 
             # Check Sunperf
-            st, res = CheckSunperf(context, autoadd)
+            st = check(CheckSunperf, 'Sunperf', [])
             if st:
-                st = check_include_and_run(context, 'CBLAS (Sunperf)', res.cfgopts,
-                                           [], cblas_src, autoadd)
-                if st:
-                    add_info(env, 'cblas', res)
                 return st
 
             add_info(env, 'cblas', 'Def numpy implementation used')
             return 0
 
-def CheckLAPACK(context, autoadd = 1):
+def CheckF77BLAS(context, autoadd = 1):
+    """This checker tries to find optimized library for blas (fortran F77).
+
+    This test is pretty strong: it first detects an optimized library, and then
+    tests that a simple blas program (in C) can be run using this (F77) lib.
+    
+    It looks for the following libs:
+        - Mac OS X: Accelerate, and then vecLib.
+        - Others: MKL, then ATLAS, then Sunperf."""
+    # XXX: rpath vs LD_LIBRARY_PATH ?
+    env = context.env
+
+
+    # Get Fortran things we need
+    if not env.has_key('F77_NAME_MANGLER'):
+        if not CheckF77Mangling(context):
+            return 0
+    func_name = env['F77_NAME_MANGLER']('sgemm')
+    test_src = c_sgemm2 % {'func' : func_name}
+
+    #if not env.has_key('F77_LDFLAGS'):
+    #    if not CheckF77Clib(context):
+    #        return 0
+
+
+    def check(func, name, suplibs):
+        st, res = func(context, autoadd)
+        if st:
+            for lib in suplibs:
+                res.cfgopts['libs'].insert(0, lib)
+            st = check_include_and_run(context, 'BLAS (%s)' % name, res.cfgopts,
+                    [], test_src, autoadd)
+            if st:
+                add_info(env, 'blas', res)
+            return st
+
+    # If section blas is in site.cfg, use those options. Otherwise, use default
+    section = "blas"
+    siteconfig, cfgfiles = get_config()
+    (cpppath, libs, libpath), found = get_config_from_section(siteconfig, section)
+    if found:
+        cfg = ConfigOpts(cpppath = cpppath, libs = libs, libpath = libpath,
+                         rpath = libpath)
+        st = check_include_and_run(context, 'BLAS (from site.cfg) ', cfg,
+                                  [], test_src, autoadd)
+        if st:
+            add_info(env, 'blas', ConfigRes('blas', cfg, found))
+        return st
+    else:
+        if sys.platform == 'darwin':
+            return 0
+        else:
+            # Check MKL
+            st = check(CheckMKL, 'MKL', [])
+            if st:
+                return st
+
+            # Check ATLAS
+            st = check(CheckATLAS, 'ATLAS', ['f77blas'])
+            if st:
+                return st
+
+            # Check Sunperf
+            st = check(CheckSunperf, 'Sunperf', [])
+            if st:
+                return st
+
+            return 0
+
+def CheckF77LAPACK(context, autoadd = 1):
+    """This checker tries to find optimized library for F77 lapack.
+
+    This test is pretty strong: it first detects an optimized library, and then
+    tests that a simple (C) program can be run using this (F77) lib.
+    
+    It looks for the following libs:
+        - Mac OS X: Accelerate, and then vecLib.
+        - Others: MKL, then ATLAS."""
+    env = context.env
+
+    if not env.has_key('F77_NAME_MANGLER'):
+        if not CheckF77Mangling(context):
+            add_info(env, 'lapack', 'Def numpy implementation used')
+            return 0
+    
+    # Get the mangled name of our test function
+    sgesv_string = env['F77_NAME_MANGLER']('sgesv')
+    test_src = lapack_sgesv % sgesv_string
+
+    def check(func, name, suplibs):
+        st, res = func(context, autoadd)
+        if st:
+            for lib in suplibs:
+                res.cfgopts['libs'].insert(0, lib)
+            st = check_include_and_run(context, 'LAPACK (%s)' % name, res.cfgopts,
+                                       [], test_src, autoadd)
+            if st:
+                add_info(env, 'lapack', res)
+            return st
+
+    # If section lapack is in site.cfg, use those options. Otherwise, use default
+    section = "lapack"
+    siteconfig, cfgfiles = get_config()
+    (cpppath, libs, libpath), found = get_config_from_section(siteconfig, section)
+    if found:
+        # XXX: handle def library names correctly
+        if len(libs) == 1 and len(libs[0]) == 0:
+            libs = ['lapack', 'blas']
+        cfg = ConfigOpts(cpppath = cpppath, libs = libs, libpath = libpath,
+                         rpath = deepcopy(libpath))
+
+        # fortrancfg is used to merge info from fortran checks and site.cfg
+        fortrancfg = deepcopy(cfg)
+        fortrancfg['linkflags'].extend(env['F77_LDFLAGS'])
+
+        st = check_include_and_run(context, 'LAPACK (from site.cfg) ', fortrancfg,
+                                  [], test_src, autoadd)
+        if st:
+            add_info(env, 'lapack', ConfigRes('lapack', cfg, found))
+        return st
+    else:
+        if sys.platform == 'darwin':
+            st = check(CheckAccelerate, 'Accelerate Framework', [])
+            if st:
+                return st
+
+            st = check(CheckVeclib, 'vecLib Framework', [])
+            if st:
+                return st
+
+            add_info(env, 'lapack: def numpy implementation', opts)
+            return 0
+        else:
+            # Check MKL
+            # XXX: handle different versions of mkl (with different names)
+            st = check(CheckMKL, 'MKL', ['lapack'])
+            if st:
+                return st
+
+            # Check ATLAS
+            st = check(CheckMKL, 'ATLAS', ['lapack'])
+            if st:
+                return st
+
+            # Check Sunperf
+            st = check(CheckMKL, 'Sunperf', ['lapack'])
+            if st:
+                return st
+
+    add_info(env, 'lapack', 'Def numpy implementation used')
+    return 0
+
+def CheckCLAPACK(context, autoadd = 1):
     """This checker tries to find optimized library for lapack.
 
     This test is pretty strong: it first detects an optimized library, and then
@@ -109,6 +253,9 @@
     It looks for the following libs:
         - Mac OS X: Accelerate, and then vecLib.
         - Others: MKL, then ATLAS."""
+    context.Message('Checking CLAPACK ...')
+    context.Result('FIXME: not implemented yet')
+    return 0
     env = context.env
 
     # If section lapack is in site.cfg, use those options. Otherwise, use default
@@ -122,8 +269,8 @@
         cfg = ConfigOpts(cpppath = cpppath, libs = libs, libpath = libpath,
                          rpath = deepcopy(libpath))
 
-	# XXX: How to know whether we need fortran or not
-	# ?
+        # XXX: How to know whether we need fortran or not
+        # ?
         if not env.has_key('F77_NAME_MANGLER'):
             if not CheckF77Mangling(context):
                 return 0

Modified: branches/numpy.scons/numpy/distutils/scons/checkers/support.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/checkers/support.py	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/distutils/scons/checkers/support.py	2007-11-16 09:08:18 UTC (rev 4462)
@@ -1,5 +1,5 @@
 #! /usr/bin/env python
-# Last Change: Tue Nov 06 01:00 PM 2007 J
+# Last Change: Fri Nov 16 04:00 PM 2007 J
 
 # This module defines some helper functions, to be used by high level checkers
 
@@ -216,3 +216,37 @@
 
     context.Result(ret)
     return ret
+
+def check_run_f77(context, name, opts, run_src, autoadd = 1):
+    """This is a basic implementation for generic "run" testers.
+    
+    For example, for library foo, which implements function do_foo
+        - test that the given source code can be compiled. The source code
+          should contain a simple program with the function.
+          
+    Arguments:
+        - name: name of the library."""
+
+    context.Message('Checking for %s ... ' % name)
+    env = context.env
+
+    #------------------------------
+    # Check a simple example works
+    #------------------------------
+    saved = save_and_set(env, opts)
+    try:
+        # 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([run_src] + [r'* %s' % s for s in str(opts).split('\n')])
+        ret, out = context.TryRun(src, '.f')
+    finally:
+        if (not ret or not autoadd):
+            # If test failed or autoadd is disabled, restore everything
+            restore(env, saved)
+
+    if not ret:
+        context.Result('Failed: %s test could not be linked and run' % name)
+        return 0
+
+    context.Result(ret)
+    return ret

Modified: branches/numpy.scons/numpy/distutils/scons/testcode_snippets.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/testcode_snippets.py	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/distutils/scons/testcode_snippets.py	2007-11-16 09:08:18 UTC (rev 4462)
@@ -1,5 +1,5 @@
 #! /usr/bin/env python
-# Last Change: Tue Nov 06 04:00 PM 2007 J
+# Last Change: Fri Nov 16 04:00 PM 2007 J
 
 # This module should contains useful test code (as strings). They are mainly
 # useful for checkers who need to run the tests (to check the mere presence of
@@ -110,3 +110,66 @@
     return compare(B, X, 4);
 }
 """
+
+# Simple test of blas (pure F77 program)
+blas_sgemm = """
+      program dot_main
+          real x(2, 2), y(2, 2), z(2, 2)
+          real sgemm, res, alpha
+          integer n, m, k, incx, incy, i
+          external sgemm
+          n = 2
+          m = 2
+          k = 2
+          alpha = 1
+          
+          x(1, 1) = 1
+          x(2, 1) = 2
+          x(1, 2) = 3
+          x(2, 2) = 4
+          
+          y(1, 1) = 1
+          y(2, 1) = -2
+          y(1, 2) = -1
+          y(2, 2) = 2
+          res = sgemm('n', 'n', n, m, k, alpha, x, n, y, n, 0, z, n)
+c          z should be ((-5, 5), (-6, 6))
+c          print*, 'sgemm = ', z(1, 1), z(1, 2)
+c          print*, '        ', z(2, 1), z(2, 2)
+      end
+"""
+
+# Check whether calling sgemm from C works (FOLLOW FORTRAN CONVENTION !). 
+c_sgemm2 = r"""
+#include <stdio.h>
+
+int
+main (void)
+{
+    char transa = 'N', transb = 'N';
+    int lda = 2;
+    int ldb = 3;
+    int n = 2, m = 2, k = 3;
+    float alpha = 1.0, beta = 0.0;
+
+    float A[] = {1, 4,
+		 2, 5,
+		 3, 6};
+
+    float B[] = {1, 3, 5,
+	         2, 4, 6}; 
+    int ldc = 2;
+    float C[] = { 0.00, 0.00,
+                 0.00, 0.00 };
+
+    /* Compute C = A B */
+    %(func)s(&transa, &transb, &n, &m, &k,
+          &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
+
+    printf("C = {%%f, %%f; %%f, %%f}\n", C[0], C[2], C[1], C[3]);
+    return 0;  
+}
+"""
+
+if __name__ == '__main__':
+    pass

Modified: branches/numpy.scons/numpy/linalg/SConstruct
===================================================================
--- branches/numpy.scons/numpy/linalg/SConstruct	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/linalg/SConstruct	2007-11-16 09:08:18 UTC (rev 4462)
@@ -1,18 +1,18 @@
-# Last Change: Tue Nov 13 11:00 PM 2007 J
+# Last Change: Fri Nov 16 05:00 PM 2007 J
 # vim:syntax=python
 import os.path
 
 from numpy.distutils.misc_util import get_numpy_include_dirs, get_mathlibs
 from numpy.distutils.scons import GetNumpyEnvironment, scons_get_paths, \
                                   scons_get_mathlib
-from numpy.distutils.scons import CheckLAPACK
+from numpy.distutils.scons import CheckF77LAPACK
 from numpy.distutils.scons.configuration import write_info
 
 env = GetNumpyEnvironment(ARGUMENTS)
 env.Append(CPPPATH = scons_get_paths(env['include_bootstrap']))
 
 config = env.NumpyConfigure(custom_tests = 
-    {'CheckLAPACK' : CheckLAPACK})
+    {'CheckLAPACK' : CheckF77LAPACK})
 
 use_lapack = config.CheckLAPACK()
 

Modified: branches/numpy.scons/numpy/scons_fake/checkers/SConstruct
===================================================================
--- branches/numpy.scons/numpy/scons_fake/checkers/SConstruct	2007-11-16 04:35:30 UTC (rev 4461)
+++ branches/numpy.scons/numpy/scons_fake/checkers/SConstruct	2007-11-16 09:08:18 UTC (rev 4462)
@@ -2,7 +2,8 @@
 from numpy.distutils.scons import GetNumpyEnvironment
 from numpy.distutils.scons.checkers.perflib import \
         CheckATLAS, CheckAccelerate, CheckMKL, CheckSunperf
-from numpy.distutils.scons.checkers.custom_checkers import CheckCBLAS, CheckLAPACK
+from numpy.distutils.scons.checkers.custom_checkers import CheckCBLAS, \
+        CheckCLAPACK, CheckF77BLAS, CheckF77LAPACK
 from numpy.distutils.scons import CheckF77Mangling
 
 env = GetNumpyEnvironment(ARGUMENTS)
@@ -20,8 +21,10 @@
     'CheckMKL' : CheckMKL,
     'CheckAccelerate' : CheckAccelerate,
     'CheckCBLAS' : CheckCBLAS,
-    'CheckLAPACK' : CheckLAPACK,
     'CheckF77Mangling' : CheckF77Mangling,
+    'CheckF77BLAS' : CheckF77BLAS,
+    'CheckF77LAPACK' : CheckF77LAPACK,
+    'CheckCLAPACK' : CheckCLAPACK,
     'CheckSunperf' : CheckSunperf})
 
 if do_check == 1:
@@ -29,8 +32,10 @@
     st, opts = config.CheckMKL(autoadd = 0)
     st, opts = config.CheckAccelerate(autoadd = 0)
     st, opts = config.CheckSunperf(autoadd = 0)
+    st = config.CheckF77BLAS(autoadd = 0)
     st = config.CheckCBLAS(autoadd = 0)
-    st = config.CheckLAPACK(autoadd = 0)
+    st = config.CheckF77LAPACK(autoadd = 0)
+    st = config.CheckCLAPACK(autoadd = 0)
     st = config.CheckF77Mangling()
 
     if env.has_key('LIBS'):



More information about the Numpy-svn mailing list