$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r51212 - in sandbox/numeric_bindings/libs/numeric/bindings/tools: . templates templates/level1
From: rutger_at_[hidden]
Date: 2009-02-12 05:24:34
Author: rutger
Date: 2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
New Revision: 51212
URL: http://svn.boost.org/trac/boost/changeset/51212
Log:
Added support for value type declarations through templating system, 
return types for BLAS, argument substitution for BLAS, and more.
Added:
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/axpy.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/dot.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/iamax.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotg.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotm.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotmg.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/swap.hpp   (contents, props changed)
Text files modified: 
   sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py                  |     2                                         
   sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py            |    43 ++++++++++++++++--                      
   sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py                    |    91 ++++++++++++++++++++++++++++++++++++--- 
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp           |    24 ++++++---                               
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp |     2                                         
   5 files changed, 139 insertions(+), 23 deletions(-)
Modified: sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py
==============================================================================
--- sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py	(original)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -109,6 +109,8 @@
 
       template = template.replace( "$SUBROUTINE", k )
       template = template.replace( "$ARGUMENTS", ", ".join( arg_list ) )
+      template = template.replace( '$RETURN_TYPE', global_info_map[ k ][ 'return_value_type' ] )
+      template = template.replace( '$RETURN_STATEMENT', global_info_map[ k ][ 'return_statement' ] )
       content += proper_indent( template )
 
     content += '\n'
Modified: sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py
==============================================================================
--- sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py	(original)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -613,6 +613,8 @@
       sub_template = sub_template.replace( "$CALL_C_HEADER", ", ".join( lapack_arg_list ) )
       sub_template = sub_template.replace( "$SUBROUTINE", subroutine )
       sub_template = sub_template.replace( '$groupname', group_name.lower() )
+      sub_template = sub_template.replace( '$RETURN_TYPE', info_map[ subroutine ][ 'return_value_type' ] )
+      sub_template = sub_template.replace( '$RETURN_STATEMENT', info_map[ subroutine ][ 'return_statement' ] )
       
       overloads += bindings.proper_indent( sub_template )
   
@@ -640,9 +642,11 @@
       level1_template = ''
       level2_template = ''
       level1_template = template_map[ 'blas_level1' ]
+      level2_template = template_map[ 'blas_level2' ]
 
       level0_arg_list = []
       level1_arg_list = []
+      level2_arg_list = []
       call_level1_arg_list = []
       level1_type_arg_list = []
       level1_assert_list = []
@@ -657,6 +661,8 @@
           level1_type_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] ]
         if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_assert' ] != None:
           level1_assert_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_assert' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_2' ] != None:
+          level2_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_2' ] ]
 
       # Level 1 replacements
       level1_template = level1_template.replace( "$CALL_LEVEL0", ", ".join( level0_arg_list ) )
@@ -664,8 +670,28 @@
       level1_template = level1_template.replace( "$LEVEL1", ", ".join( level1_arg_list ) )
       level1_template = level1_template.replace( "$TYPES", ", ".join( level1_type_arg_list ) )
       level1_template = level1_template.replace( "$ASSERTS", "\n        ".join( level1_assert_list ) )
+      level1_template = level1_template.replace( '$RETURN_TYPE', info_map[ subroutine ][ 'level1_return_type' ] )
+      level1_template = level1_template.replace( '$RETURN_STATEMENT', info_map[ subroutine ][ 'return_statement' ] )
+
+      # Level 2 replacements
+      # some special stuff is done here, such as replacing real_type with a 
+      # type-traits deduction, etc..
+      level2_template = level2_template.replace( "$LEVEL2", ", ".join( level2_arg_list ) )
+      
+      if len(level1_type_arg_list)>0:
+        first_typename = level1_type_arg_list[0].split(" ")[-1]
+        first_typename_datatype = first_typename[0:6].lower() # 'matrix' or 'vector'
+      else:
+        first_typename = 'TODO'
+        first_typename_datatype = 'TODO'
+      level2_template = level2_template.replace( "$FIRST_TYPENAME", first_typename )
+      level2_template = level2_template.replace( "$TYPEOF_FIRST_TYPENAME", first_typename_datatype )
+      level2_template = level2_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+      level2_template = level2_template.replace( "$TYPES", ", ".join( level1_type_arg_list ) )
 
       level1_map[ value_type ] = bindings.proper_indent( level1_template )
+      level2_map[ value_type ] = bindings.proper_indent( level2_template )
+
 
     #
     # LEVEL 1 and 2 FINALIZATION
@@ -682,6 +708,10 @@
     for value_type in level1_map.keys():
       level1 += level1_map[ value_type ]
 
+    level2 = ''
+    for value_type in level2_map.keys():
+      level2 += level2_map[ value_type ]
+
     #
     # handle addition of includes
     #
@@ -698,6 +728,7 @@
     result = result.replace( '$INCLUDES', includes_code )
     result = result.replace( '$OVERLOADS', overloads )
     result = result.replace( '$LEVEL1', level1 )
+    result = result.replace( '$LEVEL2', level2 )
     result = result.replace( '$GROUPNAME', group_name )
     result = result.replace( '$groupname', group_name.lower() )
 
@@ -781,14 +812,14 @@
 value_type_groups = group_by_value_type( function_info_map )
 
 routines = {}
-routines[ 'level_1' ] = {}
-routines[ 'level_1' ][ 'endings' ] = [ 'ROTG', 'OTMG', 'ROT', 'ROTM', 'SWAP', 'SCAL', 'COPY', 'AXPY', 'DOT', 'DOTU', 'DOTC', 'NRM2', 'ASUM', 'AMAX' ]
+routines[ 'level1' ] = {}
+routines[ 'level1' ][ 'endings' ] = [ 'ROTG', 'OTMG', 'ROT', 'ROTM', 'SWAP', 'SCAL', 'COPY', 'AXPY', 'DOT', 'DOTU', 'DOTC', 'NRM2', 'ASUM', 'AMAX' ]
 
-routines[ 'level_2' ] = {}
-routines[ 'level_2' ][ 'endings' ] = [ 'MV', 'SV', 'GER', 'GERU', 'GERC', 'HER', 'HPR', 'HER2', 'HPR2', 'SYR', 'SPR', 'SYR2' ]
+routines[ 'level2' ] = {}
+routines[ 'level2' ][ 'endings' ] = [ 'MV', 'SV', 'GER', 'GERU', 'GERC', 'HER', 'HPR', 'HER2', 'HPR2', 'SYR', 'SPR', 'SYR2' ]
 
-routines[ 'level_3' ] = {}
-routines[ 'level_3' ][ 'endings' ] = [ 'MM', 'RK', 'R2K', 'SM' ]
+routines[ 'level3' ] = {}
+routines[ 'level3' ][ 'endings' ] = [ 'MM', 'RK', 'R2K', 'SM' ]
 
 for name in value_type_groups.keys():
   found = False
Modified: sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py
==============================================================================
--- sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py	(original)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -24,6 +24,14 @@
 templates = {}
 
 
+
+
+def value_type( fortran_type ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'fcomplex_t'
+  m_type_map[ 'COMPLEX*16' ] = 'dcomplex_t'
+  m_type_map[ 'DOUBLE COMPLEX' ] = 'dcomplex_t'
+  return m_type_map[ fortran_type ]
   
 def c_type( name, properties ):
   m_type_map = global_type_map
@@ -44,6 +52,7 @@
   m_type_map = global_type_map
   m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
   m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+  m_type_map[ 'DOUBLE COMPLEX' ] = 'traits::complex_d'
   
   result = m_type_map[ properties[ 'value_type' ] ]
   
@@ -65,12 +74,14 @@
 def call_c_type( name, properties ):
   result = ''
   if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
-    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX' or \
+       properties[ 'value_type' ] == 'DOUBLE COMPLEX':
       result = 'traits::complex_ptr(' + name.lower() + ')'
     else:
       result = name.lower()
   elif properties[ 'type' ] == 'scalar':
-    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX' or \
+       properties[ 'value_type' ] == 'DOUBLE COMPLEX':
       result = 'traits::complex_ptr(&' + name.lower() + ')'
     else:
       result = '&' + name.lower()
@@ -603,13 +614,18 @@
   subroutine_found = False
   subroutine_name = ''
   subroutine_arguments = []
+  subroutine_return_type = None
+
   code_line_nr = 0
   while code_line_nr < len(code) and not subroutine_found:
-    match_subroutine_name = re.compile( 'SUBROUTINE[ ]+([A-Z]+)\(([^\)]+)' ).search( code[ code_line_nr ] )
+    match_subroutine_name = re.compile( '(DOUBLE PRECISION FUNCTION|REAL FUNCTION|SUBROUTINE)[ ]+([A-Z]+)\(([^\)]+)' ).search( code[ code_line_nr ] )
     if match_subroutine_name != None:
       subroutine_found = True
-      subroutine_name = match_subroutine_name.group( 1 )
-      subroutine_arguments = match_subroutine_name.group( 2 ).replace( ' ', '' ).split( "," )
+      subroutine_name = match_subroutine_name.group( 2 )
+      subroutine_arguments = match_subroutine_name.group( 3 ).replace( ' ', '' ).split( "," )
+      if match_subroutine_name.group(1) != 'SUBROUTINE':
+        subroutine_return_type = " ".join( match_subroutine_name.group(1).split(" ")[0:-1] )
+
     code_line_nr += 1
 
   # If we could not find a subroutine, we quit at our earliest convenience
@@ -630,6 +646,7 @@
   print "Arguments:  ", len(subroutine_arguments),":",subroutine_arguments
   print "Group name: ", subroutine_group_name
   print "Variant:    ", subroutine_value_type
+  print "Return:     ", subroutine_return_type
 
   # Now we have the names of the arguments. The code following the subroutine statement are
   # the argument declarations. Parse those right now, splitting these examples
@@ -677,6 +694,39 @@
         grouped_arguments[ 'by_' + s ][ argument_properties[ s ] ] = []
       grouped_arguments[ 'by_' + s ][ argument_properties[ s ] ] += [ argument_name ]
 
+  # See if we are hard-forcing argument renaming aliases
+  # This is needed for BLAS. It has argument names that are tied to the 
+  # value_type variant of the routine. E.g., daxpy has dx and dy, caxpy has
+  # cx and cy. This is confusing for the generator, so we replace it with 
+  # x and y, if the command for that is issued in its template.
+  argument_replace_map = {}
+  argument_value_type_prepend_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.remove_argument_value_type_prepend'
+  if my_has_key( argument_value_type_prepend_key, template_map ):
+    arguments_to_do = template_map[ my_has_key( argument_value_type_prepend_key, template_map ) ].strip().split(",")
+    for argument_new_name in arguments_to_do:
+      argument_new_name = argument_new_name.strip()
+      # try to find the original argument with value type
+      # it's either from a complex or double variant, 
+      # not as cleanly applied as we might say
+      if subroutine_value_type == 'complex':
+        prefixes = [ 'C', 'Z' ]
+      else:
+        prefixes = [ 'S', 'D' ]
+      # determine the original name
+      argument_with_value_type = ''
+      for prefix in prefixes:
+        try_name = prefix + argument_new_name
+        if try_name in subroutine_arguments:
+          argument_with_value_type = try_name
+      loc = subroutine_arguments.index( argument_with_value_type )
+      # replace in the overall subroutine arguments list
+      subroutine_arguments[ loc ] = argument_new_name
+      # rename the key in the argument map
+      # create a copy, delete the old
+      argument_replace_map[ argument_with_value_type ] = argument_new_name
+      argument_map[ argument_new_name ] = argument_map[ argument_with_value_type ]
+      del argument_map[ argument_with_value_type ]
+
   # The next bulk load of information can be acquired from the comment fields, 
   # this is between "Purpose" and "Arguments". Locate those headers, and init with
   # -1 so that we can check if they where found.
@@ -699,6 +749,19 @@
   if purpose_line_nr > 0 and arguments_line_nr > 0:
     subroutine_purpose = "//" + "\n//".join( comments[ purpose_line_nr+3:arguments_line_nr-1 ] )
 
+  # try to see if we are overriding the arguments piece
+  arguments_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.arguments'
+  if my_has_key( arguments_key, template_map ):
+    print arguments_line_nr, comment_line_nr
+    arguments_line_nr = len(comments)
+    comments += template_map[ my_has_key( arguments_key, template_map ) ].splitlines()
+    comments += [ '' ]
+    
+    pp.pprint( comments )
+    
+  pp.pprint( argument_map )
+
+
   # Break up the comments
   # Now, for each argument, locate its associated comment field
   #
@@ -711,6 +774,8 @@
     detected_blas_style = False
     while comment_line_nr < len(comments) and not finished_the_last:
 
+      print comments[ comment_line_nr ]
+
       # Example for LAPACK-style matching. 
       # 45 M       (input) INTEGER
       # 46         The number of rows of the matrix A. M >= 0.
@@ -720,6 +785,9 @@
       if not detected_blas_style and match_lapack_style != None:
         detected_lapack_style = True
         argument_name = match_lapack_style.group(1)
+        # If we're replacing arguments, we should do se here as well.
+        if argument_replace_map.has_key( argument_name ):
+          argument_name = argument_replace_map[ argument_name ]
         argument_map[ argument_name ][ 'comment_lines' ] = [ comment_line_nr ]
         split_regex = re.compile( '\/| or ' )
         argument_map[ argument_name ][ 'io' ] = split_regex.split( match_lapack_style.group(2) )
@@ -946,7 +1014,7 @@
           for arg in tmp_result:
             if arg not in argument_map.keys():
               # variable not found, try user-defined variable definitions
-              add_user_defined_args( arg, user_defined_arg_map, template_map, subroutine_group_name + '.' + subroutine_value_type )
+              args( arg, user_defined_arg_map, template_map, subroutine_group_name + '.' + subroutine_value_type )
 
           argument_properties[ 'assert_size_args' ] = tmp_result
           print "Using user-defined assert_size_args: ", tmp_result
@@ -1025,9 +1093,18 @@
   info_map = {}
   info_map[ 'arguments' ] = subroutine_arguments
   info_map[ 'purpose' ] = subroutine_purpose
+  info_map[ 'return_type' ] = subroutine_return_type
   info_map[ 'argument_map' ] = argument_map
   info_map[ 'grouped_arguments' ] = grouped_arguments
-  
+  if subroutine_return_type != None:
+    info_map[ 'return_value_type' ] = value_type( subroutine_return_type )
+    info_map[ 'level1_return_type' ] = 'value_type'
+    info_map[ 'return_statement' ] = 'return '
+  else:
+    info_map[ 'return_value_type' ] = 'void'
+    info_map[ 'level1_return_type' ] = 'void'
+    info_map[ 'return_statement' ] = ''
+
   #
   # Pass / check user-defined stuff right here.
   #
Modified: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp
==============================================================================
--- sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp	(original)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -29,13 +29,13 @@
 $OVERLOADS}
 
 $LEVEL1
-
+$LEVEL2
 }}}} // namespace boost::numeric::bindings::blas
 
 #endif
 $TEMPLATE[blas_overloads]
-    inline void $groupname( $LEVEL0 ) {
-        BLAS_$SUBROUTINE( $CALL_C_HEADER );
+    inline $RETURN_TYPE $groupname( $LEVEL0 ) {
+        $RETURN_STATEMENTBLAS_$SUBROUTINE( $CALL_C_HEADER );
     }
 $TEMPLATE[blas_level1]
 // value-type based template
@@ -43,15 +43,21 @@
 struct $groupname_impl {
 
     typedef ValueType value_type;
-    typedef typename traits::type_traits<ValueType>::real_type real_type;
 
     // templated specialization
     template< $TYPES >
-    static void compute( $LEVEL1 ) {
-#ifndef NDEBUG
-        $ASSERTS
-#endif
-        detail::$groupname( $CALL_LEVEL0 );
+    static $RETURN_TYPE compute( $LEVEL1 ) {
+        $RETURN_STATEMENTdetail::$groupname( $CALL_LEVEL0 );
     }
 };
+$TEMPLATE[blas_level2]
+// template function to call $groupname
+template< $TYPES >
+inline integer_t $groupname( $LEVEL2 ) {
+    typedef typename traits::$TYPEOF_FIRST_TYPENAME_traits< $FIRST_TYPENAME >::value_type value_type;
+    integer_t info(0);
+    $groupname_impl< value_type >::compute( $CALL_LEVEL1 );
+    return info;
+}
+
 $TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/axpy.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/axpy.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1,11 @@
+$TEMPLATE[axpy.all.remove_argument_value_type_prepend]
+A,X,Y
+$TEMPLATE[axpy.all.arguments]
+ N         (input) INTEGER
+           Dimension of array A
+ INCX      (input) INTEGER
+ INCY      (input) INTEGER
+ A        (input) DATATYPE variable alpha
+ X        (input) DATATYPE array of length (N)
+ Y        (output) DATATYPE array of length (N)
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/dot.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/dot.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1,10 @@
+$TEMPLATE[dot.all.remove_argument_value_type_prepend]
+X,Y
+$TEMPLATE[dot.all.arguments]
+ N         (input) INTEGER
+           Dimension of array A
+ INCX      (input) INTEGER
+ INCY      (input) INTEGER
+ X         (input) DATATYPE array of length (N)
+ Y         (input) DATATYPE array of length (N)
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/iamax.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/iamax.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1,7 @@
+$TEMPLATE[iamax.all.remove_argument_value_type_prepend]
+X
+$TEMPLATE[iamax.all.arguments]
+ N         (input) INTEGER
+ INCX      (input) INTEGER
+ X         (input) DATATYPE
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotg.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotg.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[rotg.all.remove_argument_value_type_prepend]
+A,B
+$TEMPLATE[rotg.all.arguments]
+ A         (input/output) DATATYPE
+ B         (input/output) DATATYPE
+ C         (input/output) DATATYPE
+ S         (input/output) DATATYPE
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotm.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotm.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[rotm.all.remove_argument_value_type_prepend]
+X,Y,PARAM
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotmg.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/rotmg.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1 @@
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/swap.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/level1/swap.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[swap.all.remove_argument_value_type_prepend]
+X,Y
+$TEMPLATE[swap.all.arguments]
+ N         (input) INTEGER
+ INCX      (input) INTEGER increment in X
+ INCY      (input) INTEGER increment in Y
+ X        (output) DATATYPE
+ Y        (output) DATATYPE
+$TEMPLATE[end]
Modified: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp
==============================================================================
--- sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp	(original)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp	2009-02-12 05:24:32 EST (Thu, 12 Feb 2009)
@@ -27,7 +27,7 @@
 #endif
 
 $TEMPLATE[blas.h_function]
-    void BLAS_$SUBROUTINE( $ARGUMENTS );
+    $RETURN_TYPE BLAS_$SUBROUTINE( $ARGUMENTS );
 $TEMPLATE[blas_names.h]
 //
 // Copyright (c) 2003--2009