Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51197 - in sandbox/numeric_bindings/libs/numeric/bindings/tools: . templates templates/computational templates/driver templates/test
From: rutger_at_[hidden]
Date: 2009-02-11 09:02:00


Author: rutger
Date: 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
New Revision: 51197
URL: http://svn.boost.org/trac/boost/changeset/51197

Log:
Added the Python generator scripts for the BLAS and LAPACK bindings

Added:
   sandbox/numeric_bindings/libs/numeric/bindings/tools/README.txt (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsdc.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsqr.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gebrd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gelqf.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hetr.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hgeqz.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/larz.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/opmtr.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/org.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/orm.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stedc.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/un.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/cgesv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gees.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geesx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gegv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gels.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelss.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsy.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesdd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gges.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggesx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggglm.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gglse.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevr.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/lalsd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevr.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syev.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevr.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvd.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysv.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysvx.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/lapack.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_lapack.hpp (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/CMakeLists.txt (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/test_case.cpp (contents, props changed)

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/README.txt
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/README.txt 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,25 @@
+
+Using the Python Generator
+----
+To test the python generator, you will need the lapack sources. Make sure the path to your lapack sources is also set in the lapack_parser.py file; look for the variable lapack_src_path.
+
+On a debian-based system, acquiring the sources of BLAS and LAPACK may be achieved by
+
+$ cd tools
+$ apt-get source blas lapack
+
+this will give you a subdirectory called 'blas-X.X' and 'lapack-X.X.X'. Running the generator may be done by
+
+$ ./lapack_generator
+$ ./blas_generator
+
+from within the tools directory.
+
+To use the compile_test, you need cmake. Please do a
+
+$ mkdir build
+$ cd build
+$ cmake ..
+$ make
+
+to try to compile all test files. ]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,121 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import re
+
+#
+# This routine actually does what it's named after :-).
+# Changes:
+# * used regex matching on delimiter instead of .find
+#
+def proper_indent( input_string ):
+ max_chars = 80
+ all_results = []
+ find_delim = re.compile( "([\,\+/]|\|\||>=|std::log\(|work\()[ ]*" )
+ for input_line in input_string.splitlines():
+ result = ''
+ # extra indentation size is 8
+ indentation = len(input_line) - len(input_line.lstrip() ) + 8
+
+ #print "indentation: ", indentation
+
+ indentation_string = ''
+ for i in range(indentation ):
+ indentation_string += ' '
+ #cur_index = input_line.find( ",", 0, -1 ) + 1
+
+ match_delim = find_delim.search( input_line, 0, len(input_line) )
+ if match_delim != None:
+ #print match_delim.end( 0 )- match_delim.start( 0 )
+ cur_index = match_delim.end( 0 )
+ else:
+ cur_index = 0
+
+ prev_index = 0
+ prev_slice = 0
+ prev_indentation = 0
+ while cur_index != 0:
+ if ( (cur_index - prev_slice) > (79-prev_indentation) ):
+ result = result + input_line[ prev_slice : prev_index ].rstrip() + '\n' + indentation_string
+ prev_indentation = indentation
+ prev_slice = prev_index
+ prev_index = cur_index
+ if cur_index != len(input_line):
+ match_delim = find_delim.search( input_line, cur_index+1, len(input_line) )
+ if match_delim != None:
+ #print match_delim.end( 0 )- match_delim.start( 0 )
+ cur_index = match_delim.end( 0 )
+ else:
+ cur_index = 0
+ #cur_index = input_line.find( ",", cur_index+1, -1 ) + 1
+ if cur_index == 0:
+ cur_index = len(input_line)
+ else:
+ cur_index = 0
+ cur_index = len( input_line )
+ result = result + input_line[ prev_slice : cur_index ]
+ all_results += [ result ]
+
+ return "\n".join( all_results ) + "\n"
+
+
+
+#
+# Write the blas.h/lapack_names.h file.
+#
+def write_names_header( global_info_map, group, template_map, dest_file ):
+ parsermode = template_map[ 'PARSERMODE' ].lower()
+ group_keys = group.keys()
+ group_keys.sort()
+ content = ''
+ for g in group_keys:
+ content += '// Variants of ' + g.lower() + '\n'
+ for k in group[ g ]:
+ template = template_map[ parsermode + '_names.h_function' ]
+ template = template.replace( '$SUBROUTINE', k )
+ template = template.replace( '$subroutine', k.lower() )
+ content += template
+ content += '\n'
+
+ result = template_map[ parsermode + '_names.h' ]
+ result = result.replace( "$CONTENT", content )
+ #//result = result.replace( "$PARSERMODE", template_map[ "PARSERMODE" ] )
+
+ open( dest_file, 'wb' ).write( result )
+
+
+#
+# Write the blas.h/lapack.h file
+#
+def write_header( global_info_map, group, template_map, dest_file ):
+ parsermode = template_map[ 'PARSERMODE' ].lower()
+ group_keys = group.keys()
+ group_keys.sort()
+ content = ''
+ for g in group_keys:
+ content += '$INDENT// Variants of ' + g.lower() + '\n'
+ for k in group[ g ]:
+
+ template = template_map[ parsermode + '.h_function' ]
+ arg_list = []
+ for arg in global_info_map[ k ][ 'arguments' ]:
+ arg_list += [ global_info_map[ k ][ 'argument_map' ][ arg ][ 'code' ][ 'lapack_h' ] ]
+
+ template = template.replace( "$SUBROUTINE", k )
+ template = template.replace( "$ARGUMENTS", ", ".join( arg_list ) )
+ content += proper_indent( template )
+
+ content += '\n'
+
+ result = template_map[ parsermode + '.h' ]
+ result = result.replace( "$CONTENT", content )
+ result = result.replace( '$INDENT', ' ' )
+ #result = result.replace( "$PARSERMODE", template_map[ "PARSERMODE" ] )
+
+ open( dest_file, 'wb' ).write( result )

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,823 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import netlib
+import bindings
+
+import re, os.path, copy
+from types import StringType
+
+# for debugging purposes
+import pprint
+
+
+global_type_map = {
+ 'CHARACTER': 'char',
+ 'LOGICAL': 'logical_t',
+ 'INTEGER': 'integer_t',
+ 'REAL': 'float',
+ 'DOUBLE PRECISION': 'double' }
+
+templates = {}
+
+
+
+def c_type( name, properties ):
+ m_type_map = global_type_map
+ m_type_map[ 'COMPLEX' ] = 'fcomplex_t'
+ m_type_map[ 'COMPLEX*16' ] = 'dcomplex_t'
+
+ result = m_type_map[ properties[ 'value_type' ] ];
+ if properties[ 'io' ] == [ 'input' ]:
+ result += ' const'
+ result += '*'
+ result += ' ' + name.lower() # is this really needed?
+
+ return result
+
+
+def cpp_type( name, properties ):
+ m_type_map = global_type_map
+ m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
+ m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+
+ result = m_type_map[ properties[ 'value_type' ] ]
+
+ if properties[ 'type' ] == 'scalar':
+ if properties[ 'io' ] == [ 'input' ]:
+ result += ' const'
+ elif properties[ 'io' ] == [ 'external procedure' ]:
+ result += '*'
+ else:
+ result += '&'
+
+ if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+ result += '*'
+
+ result += ' ' + name.lower()
+
+ return result
+
+def call_c_type( name, properties ):
+ result = ''
+ if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+ if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+ result = 'traits::complex_ptr(' + name.lower() + ')'
+ else:
+ result = name.lower()
+ elif properties[ 'type' ] == 'scalar':
+ if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+ result = 'traits::complex_ptr(&' + name.lower() + ')'
+ else:
+ result = '&' + name.lower()
+
+ return result
+
+
+def call_level0_type( name, properties, arg_map ):
+ result = ''
+ if properties[ 'type' ] == 'matrix':
+ result = "traits::matrix_storage(" + name.lower() + ")"
+ elif properties[ 'type' ] == 'vector':
+ my_name = name.lower()
+ if 'workspace' in properties[ 'io' ]:
+ my_name = 'work.select(' + workspace_type( name, properties ) + '())'
+ result = "traits::vector_storage(" + my_name + ")"
+ elif properties.has_key( 'trait_type' ):
+ if properties[ 'trait_type' ] == 'lda':
+ result = "traits::leading_dimension(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'num_columns':
+ result = "traits::matrix_size2(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'num_rows':
+ result = "traits::matrix_size1(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'size':
+ my_name = properties[ 'trait_of' ].lower()
+ referring_to_properties = arg_map[ properties[ 'trait_of' ] ]
+ if 'workspace' in referring_to_properties[ 'io' ]:
+ my_name = 'work.select(' + workspace_type( properties[ 'trait_of' ].lower(), referring_to_properties ) + \
+ '())'
+ result = "traits::vector_size(" + my_name + ")"
+ if properties[ 'trait_type' ] == 'uplo':
+ result = "traits::matrix_uplo_tag(" + properties[ 'trait_of' ].lower() + ")"
+ else:
+ result = name.lower()
+ return result
+
+
+def level1_type( name, properties ):
+ result = None
+ if not properties.has_key( 'trait_of' ) and 'workspace' not in properties[ 'io' ]:
+ if properties[ 'type' ] == 'matrix':
+ result = "Matrix" + name + "& " + name.lower()
+ elif properties[ 'type' ] == 'vector':
+ result = "Vector" + name + "& " + name.lower()
+ else:
+ result = cpp_type( name, properties )
+ if properties[ 'value_type' ] == 'REAL':
+ result = result.replace( "float", "real_type" )
+ if properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = result.replace( "double", "real_type" )
+ return result
+
+
+def level2_type( name, properties ):
+ result = level1_type( name, properties )
+ if name == 'INFO' and 'output' in properties[ 'io' ]:
+ result = None
+
+ if result != None:
+ if properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = result.replace( "real_type", "typename traits::$TYPEOF_FIRST_TYPENAME" + \
+ "_traits< $FIRST_TYPENAME >::value_type" )
+
+ return result
+
+
+def level1_typename( name, properties ):
+ result = None
+ if 'workspace' not in properties[ 'io' ]:
+ if properties[ 'type' ] == 'matrix':
+ result = "typename Matrix" + name
+ if properties[ 'type' ] == 'vector':
+ result = "typename Vector" + name
+ return result
+
+
+
+def nested_list_args( arg ):
+ print "finding nested list arguments of", arg
+ if type( arg ) == StringType:
+ if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+ return [ None ]
+ else:
+ return [ arg.upper() ]
+
+ # we are dealing with a list-type, e.g.,
+ # [ '*', [ 'A', 'B' ] ]
+ # [ 'A', 'B' ]
+ result = []
+ if re.compile( '^[A-Z]+$' ).match( arg[0] ) == None:
+ for a in arg[1]:
+ sub_result = nested_list_args( a )
+ if sub_result != [ None ]:
+ for r in sub_result:
+ if r not in result:
+ result.append( r )
+
+ else:
+ for a in arg:
+ result.append( a )
+
+ print "returning ",result
+ return result
+
+
+
+
+def expand_nested_list( arg, arg_map, use_arg_map = True ):
+
+ print "Expanding nested list: ", arg, len(arg)
+ if type( arg ) == StringType:
+ print "Type is string"
+ # .....
+ if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+ return arg
+ else:
+ if use_arg_map:
+ if not arg_map.has_key( arg ):
+ return '?' + arg.upper()
+ else:
+ return arg_map[ arg ][ 'code' ][ 'call_level_0' ]
+ else:
+ return arg.lower()
+
+ if arg[0] == '()':
+ result = '(' + expand_nested_list( arg[1], arg_map, use_arg_map ) + ')'
+ return result
+
+ if arg[0] == 'max' or arg[0] == 'min':
+ print "arg1: ", arg[1]
+ result = 'std::' + arg[0] + '('
+ i = 0
+ for a in arg[1]:
+ result += expand_nested_list( a, arg_map, use_arg_map )
+ i += 1
+ if i != len(arg[1]):
+ result += ","
+ result += ')'
+ return result
+
+ if arg[0] == '*' or arg[0] == '/' or arg[0] == '+' or arg[0] == '-':
+ print "arg1: ", arg[1]
+ arg_list = []
+ for a in arg[1]:
+ arg_list += [ expand_nested_list( a, arg_map, use_arg_map ) ]
+ result = arg[0].join( arg_list )
+ return result
+
+ print "ERROR: Don't know what to do!!"
+ return 'ERROR'
+
+def level1_assert( name, properties, arg_map ):
+ result = None
+
+ if properties.has_key( 'assert_char' ):
+ result = "assert( "
+ result_array = []
+ for char in properties[ 'assert_char' ]:
+ result_array += [ call_level0_type( name, properties, arg_map ) + ' == \'' + char + '\'' ]
+ result += " || ".join( result_array )
+ result += " );"
+
+ if properties.has_key( 'assert_ge' ) and not properties.has_key( 'workspace_query_for' ):
+ result = "assert( " + call_level0_type( name, properties, arg_map ) + " >= " + expand_nested_list( properties[ 'assert_ge' ], arg_map ) + ' );'
+
+ if 'workspace' in properties[ 'io' ]:
+ min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+ if min_workspace_call == None:
+ min_workspace_call = '$CALL_MIN_SIZE'
+ result = 'assert( traits::vector_size(work.select(' + workspace_type( name, properties ) + '()) >= ' + \
+ 'min_size_' + name.lower() + '( ' + min_workspace_call + ' )));'
+
+ elif properties.has_key( 'assert_size' ):
+ result = "assert( traits::vector_size(" + call_level0_type( name, properties, arg_map ) + ") >= " + \
+ expand_nested_list( properties[ 'assert_size' ], arg_map ) + ' );'
+
+ return result
+
+
+def call_level1_type( name, properties ):
+ result = None
+ if level1_type( name, properties ) != None:
+ result = name.lower()
+ return result
+
+
+def workspace_type( name, properties ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties[ 'value_type' ] == 'INTEGER':
+ result = 'integer_t'
+ elif properties[ 'value_type' ] == 'LOGICAL':
+ result = 'bool'
+ elif properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = 'real_type'
+ else:
+ result = 'value_type'
+ return result
+
+
+
+
+def opt_workspace_pre_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ result = workspace_type( name, properties ) + ' opt_size_' + name.lower() + ';'
+ else:
+ min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+ if min_workspace_call == None:
+ min_workspace_call = '$CALL_MIN_SIZE'
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( min_size_' + name.lower() + '( ' + min_workspace_call + ' ) );'
+ return result
+
+
+def opt_workspace_post_type( name, properties ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ if properties['value_type'] == 'INTEGER':
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( opt_size_' + name.lower() + ' );'
+ else:
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( traits::detail::to_int( opt_size_' + name.lower() + ' ) );'
+ return result
+
+
+
+def opt_workspace_query_type( name, properties, arg_map ):
+ result = None
+ if properties.has_key( 'workspace_query_for' ):
+ result = '-1'
+ elif 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ result = '&opt_size_' + name.lower();
+ else:
+ result = 'traits::vector_storage(tmp_' + name.lower() + ')'
+ else:
+ result = call_level0_type( name, properties, arg_map )
+ return result
+
+
+def min_workspace_size_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size' ):
+ result = expand_nested_list( properties[ 'assert_size' ], arg_map, False );
+ return result
+
+
+def min_workspace_arg_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+ code_result = []
+ for arg in properties[ 'assert_size_args' ]:
+ if arg_map.has_key( arg ):
+ code_result += [ cpp_type( arg, arg_map[ arg ] ) ]
+ else:
+ code_result += [ '?' + arg.upper() ]
+ result = ", ".join( code_result )
+ return result
+
+
+def min_workspace_call_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+ code_result = []
+ for arg in properties[ 'assert_size_args' ]:
+ if arg_map.has_key( arg ):
+ code_result += [ call_level0_type( arg, arg_map[ arg ], arg_map ) ]
+ else:
+ code_result += [ '?' + arg.upper() ]
+
+ result = ", ".join( code_result )
+ return result
+
+
+def user_defined_type( name, properties, arg_map ):
+ result = None
+ if properties.has_key( 'user_defined' ):
+ result = properties[ 'user_defined' ]
+ return result
+
+
+
+#
+#
+#
+#
+def match_formulae( text_field ):
+ find_start = re.compile( '([A-Z]+)\s?(>=|is\sat\sleast)\s?(.*)the\scode\swill', re.M | re.S ).findall( text_field )
+ for element in find_start:
+ print element
+
+
+
+#
+# Split string using a list of delimiters
+# Delimiters may be substrings of length 1 or 2 (may be increased if necessary)
+#
+def split_delim( s, delim = [','] ):
+ result = []
+ parentheses = 0
+ cur_pos = 0
+ prev_pos = 0
+ for index in range( 0, len(s) ):
+ if s[ index ] == '(':
+ parentheses += 1
+ elif s[ index ] == ')':
+ parentheses -= 1
+ for length in range( 1, 3 ):
+ if index >= (length-1) and parentheses == 0:
+ c = s[ index-(length-1): index+1 ]
+ if c in delim:
+ result += [ s[ prev_pos:(index-(length-1)) ] ]
+ prev_pos = index+1
+
+ result += [ s[ prev_pos:len(s) ] ]
+ return result
+
+
+
+#
+# Look for implicit products, like 5N, and replace with 5*N
+#
+def replace_implicit_products( text_field ):
+ result = re.sub( '([0-9])+([A-Z]+)', '\\1*\\2', text_field )
+ return result
+
+
+
+
+def decompose_formula( text_field ):
+ text_field = text_field.strip()
+ print "Decompose: ", text_field
+
+ if text_field[0] == '(' and text_field[-1] == ')':
+ result = text_field[ 1:-1 ]
+ return [ '()', decompose_formula( result ) ]
+
+ if len( split_delim( text_field, [ ',' ] ) ) > 1:
+ print "ERROR! (in BLAS?)"
+ return [ 'ERROR' ]
+
+ #
+ # Detect leaf: if text_field equals a argument (like N), or a number
+ #
+ if re.compile( '^([a-zA-Z]+|[0-9]+)$' ).match( text_field ):
+ print "decompose: at leaf: '" + text_field + "'"
+ return text_field.upper()
+
+
+ if len( split_delim( text_field, [ '**' ] ) ) > 1:
+ print 'decompose: inserting pow'
+ arguments = split_delim( text_field, [ '**' ] )
+ print arguments
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ return [ 'pow', result ]
+
+ for operator in [ '*', '/', '+', '-' ]:
+ if len( split_delim( text_field, [ operator ] ) ) > 1:
+ print 'decompose: inserting ' + operator
+ arguments = split_delim( text_field, operator )
+ print arguments
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ return [ operator, result ]
+
+
+ if (text_field[ 0:4 ] == 'max(' or text_field[ 0:4 ] == 'MAX(') and \
+ text_field[ -1 ] == ')':
+ print "decompose: inserting max"
+ arguments = split_delim( text_field[ 4:-1 ] )
+ print arguments, len(arguments)
+ # keep max a binary function ... :-)
+ if len( arguments ) > 2:
+ return [ 'max', [ decompose_formula( arguments[0] ), decompose_formula( 'max(' + ",".join( arguments[1:] ) + ')' ) ] ]
+ else:
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+ return [ 'max', result ]
+
+
+ if (text_field[ 0:4 ] == 'min(' or text_field[ 0:4 ] == 'MIN(') and \
+ text_field[ -1 ] == ')':
+ print "decompose: inserting min"
+ arguments = split_delim( text_field[ 4:-1 ] )
+ print arguments, len(arguments)
+ # keep max a binary function ... :-)
+ if len( arguments ) > 2:
+ return [ 'min', [ decompose_formula( arguments[0] ), decompose_formula( 'min(' + ",".join( arguments[1:] ) + ')' ) ] ]
+ else:
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+ return [ 'min', result ]
+
+
+#
+#
+def match_assert_ge( argument_map, text_field ):
+ #print "Match assert GE..."
+ match_it = re.compile( ' +[A-Z]+[ ]{0,3}(>=|must be at least)[ ]{0,3}([0-9]|(min|max|MIN|MAX|[\(\)\,0-9A-Z\+\*\-])+)' ).findall( text_field )
+ if len( match_it ) == 1:
+ print "Match assert GE:", match_it
+ #print match_it
+ #if len( match_it[ 0 ][ 2 ] ) > 0:
+ return decompose_formula( match_it[ 0 ][ 1 ] )
+ else:
+ print "nr of matches: ", len( match_it )
+ return None
+
+
+
+
+
+# try different keys, return the one that exists, if any
+
+def my_has_key( key_name, template_map ):
+ # try, e.g., gelsd.all.
+ m_all_key = key_name.replace( ".complex", ".all" ).replace( ".real", ".all" )
+ if template_map.has_key( key_name ):
+ print "using key ", key_name
+ return key_name
+ if template_map.has_key( m_all_key ):
+ print "using key ", m_all_key
+ return m_all_key
+ print "tried keys ", key_name, "and", m_all_key,", no results"
+ return None
+
+
+
+#
+# Default user-defined arg is of type scalar INTEGER
+#
+def add_user_defined_args( arg, argument_map, template_map, base_name ):
+ print "Trying to add user-defined argument definitions for", arg
+
+ argument_map[ arg ] = {}
+
+ base_key = base_name.lower() + '.' + arg
+ print "base_key",base_key
+
+ if my_has_key( base_key + '.value_type', template_map ) != None:
+ argument_map[ arg ][ 'value_type' ] = template_map[ my_has_key( base_key + '.value_type', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'value_type' ] = 'INTEGER'
+
+ if my_has_key( base_key + '.type', template_map ) != None:
+ argument_map[ arg ][ 'type' ] = template_map[ my_has_key( base_key + '.type', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'type' ] = 'scalar'
+
+ if my_has_key( base_key + '.init', template_map ) != None:
+ argument_map[ arg ][ 'user_defined' ] = template_map[ my_has_key( base_key + '.init', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'user_defined' ] = 'UNDEFINED'
+
+ argument_map[ arg ][ 'io' ] = [ 'input' ]
+
+ return
+
+
+
+#
+# Desired order of routines in C++ code: float, double, single complex, double complex
+#
+def routine_cmp( a, b ):
+ letter_a = a[0]
+ letter_b = b[0]
+ value_map = { 'S': 0, 'D': 1, 'C': 2, 'Z': 3 }
+ result = 0
+ if value_map[ a[0] ] < value_map[ b[ 0] ]:
+ result = -1
+ if value_map[ a[0] ] > value_map[ b[ 0] ]:
+ result = 1
+ return result
+
+
+#
+# Group subroutines on their name, with the first character removed. This will
+# group them in the same .hpp file as well. Sort these subroutines based on
+# routine_cmp above.
+#
+def group_by_value_type( global_info_map ):
+ group_map = {}
+ for i in global_info_map.keys():
+ short_name = i[ 1: ]
+ if not group_map.has_key( short_name ):
+ group_map[ short_name ] = []
+ group_map[ short_name ] += [ i ]
+ for value in group_map.values():
+ value.sort( routine_cmp )
+ return group_map
+
+
+
+
+#
+# Write the (many) driver routine file(s).
+#
+def write_functions( info_map, group, template_map, base_dir ):
+ #
+ # group.keys() is a vector of different grouped function names
+ # like gees, dgesv, etc.
+ #
+ for group_name, subroutines in group.iteritems():
+
+ filename = group_name.lower() + '.hpp'
+ includes = [ '#include <cassert>',
+ '#include <boost/numeric/bindings/traits/traits.hpp>',
+ '#include <boost/numeric/bindings/traits/type_traits.hpp>',
+ '#include <boost/numeric/bindings/blas/blas.h>' ]
+
+ if template_map.has_key( group_name.lower() + '.includes' ):
+ includes += template_map[ group_name.lower() + '.includes' ].splitlines()
+
+ #
+ # LEVEL 0 HANDLING
+ #
+ overloads = ''
+ for subroutine in subroutines:
+ sub_template = template_map[ 'blas_overloads' ]
+ # add the argument list here
+ arg_list = []
+ lapack_arg_list = []
+ for arg in info_map[ subroutine ][ 'arguments' ]:
+ arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_0' ] ]
+ lapack_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_c_header' ] ]
+ sub_template = sub_template.replace( "$LEVEL0", ", ".join( arg_list ) )
+ 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() )
+
+ overloads += bindings.proper_indent( sub_template )
+
+ cases = {}
+ # first, see what kind of functions we have
+ # needed for argument check etc.
+ for subroutine in subroutines:
+ if subroutine[0] == 'S' or subroutine[0] == 'D':
+ if not cases.has_key( 'real' ):
+ cases[ 'real' ] = {}
+ cases[ 'real' ][ 'subroutines' ] = []
+ cases[ 'real' ][ 'subroutines' ] += [ subroutine ]
+ if subroutine[0] == 'C' or subroutine[0] == 'Z':
+ if not cases.has_key( 'complex' ):
+ cases[ 'complex' ] = {}
+ cases[ 'complex' ][ 'subroutines' ] = []
+ cases[ 'complex' ][ 'subroutines' ] += [ subroutine ]
+
+ #
+ # LEVEL 1 and 2 HANDLING
+ #
+ level1_map = {}
+ level2_map = {}
+ for value_type, case_map in cases.iteritems():
+ level1_template = ''
+ level2_template = ''
+ level1_template = template_map[ 'blas_level1' ]
+
+ level0_arg_list = []
+ level1_arg_list = []
+ call_level1_arg_list = []
+ level1_type_arg_list = []
+ level1_assert_list = []
+ for arg in info_map[ subroutine ][ 'arguments' ]:
+ level0_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_0' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] != None:
+ level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] != None:
+ call_level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] != None and \
+ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] not in level1_type_arg_list:
+ 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' ] ]
+
+ # Level 1 replacements
+ level1_template = level1_template.replace( "$CALL_LEVEL0", ", ".join( level0_arg_list ) )
+ level1_template = level1_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+ 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_map[ value_type ] = bindings.proper_indent( level1_template )
+
+ #
+ # LEVEL 1 and 2 FINALIZATION
+ #
+ for mapping in [ level1_map, level2_map ]:
+ if len(mapping) > 1:
+ # compare real and complex cases
+ all_keys = mapping.keys()
+ if mapping[ all_keys[0] ] == mapping[ all_keys[1] ]:
+ print "literally everything is the same!!, falling back to 1 case"
+ del mapping[ all_keys[ 1 ] ]
+
+ level1 = ''
+ for value_type in level1_map.keys():
+ level1 += level1_map[ value_type ]
+
+ #
+ # handle addition of includes
+ #
+ includes_code = ''
+ unique_includes = []
+ for include in includes:
+ if include not in unique_includes:
+ unique_includes += [ include ]
+ sorted_includes = sorted( unique_includes, lambda x, y: cmp( x.lower(), y.lower() ) )
+ if len( sorted_includes ) > 0:
+ includes_code = "\n".join( sorted_includes )
+
+ result = template_map[ 'blas.hpp' ]
+ result = result.replace( '$INCLUDES', includes_code )
+ result = result.replace( '$OVERLOADS', overloads )
+ result = result.replace( '$LEVEL1', level1 )
+ result = result.replace( '$GROUPNAME', group_name )
+ result = result.replace( '$groupname', group_name.lower() )
+
+ # replace the global variables as last (this is convenient)
+ #result = result.replace( '$INDENT', ' ' )
+ #result = result.replace( '$groupname', group_name.lower() )
+ #result = result.replace( '$DESCRIPTION', info_map[ group[g][0] ][ 'description' ] )
+
+ open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+
+#
+# Write the (many) driver routine test cases to cpp files.
+#
+def write_test_case( info_map, group, template_map, base_dir, level_name ):
+
+ for group_name, subroutines in group.iteritems():
+
+ filename = group_name.lower() + '.cpp'
+ result = template_map[ 'test_case.cpp' ]
+ result = result.replace( '$groupname', group_name.lower() )
+ result = result.replace( '$levelname', level_name.lower() )
+
+ open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+def write_cmakefile( level_properties, template_map, base_dir ):
+
+ entries = ''
+ for problem_type, problem_properties in level_properties.iteritems():
+ if problem_properties.has_key( 'routines_by_value_type' ):
+ group = problem_properties[ 'routines_by_value_type' ]
+ for group_name, subroutines in group.iteritems():
+ sub_result = template_map[ 'CMakeLists.entry' ]
+ sub_result = sub_result.replace( '$groupname', group_name.lower() )
+ entries += sub_result
+
+ filename = 'CMakeLists.txt'
+ result = template_map[ 'CMakeLists.txt' ]
+ result = result.replace( '$ENTRIES', entries )
+ open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+
+def read_templates( template_file ):
+ file_contents = open( template_file ).read()
+ split_regex = re.compile( '^\$TEMPLATE\[([^\]]+)\]\s', re.M | re.S )
+ split_templates = split_regex.split( file_contents )[ 1:-1 ]
+ result = {}
+ for index in range(len(split_templates)/2):
+ print "Adding template", split_templates[ index*2 ]
+ result[ split_templates[ index*2 ] ] = split_templates[ index*2 + 1 ]
+ return result
+
+lapack_src_path = './blas-1.2/src'
+template_src_path = './templates'
+bindings_target_path = '../../../../boost/numeric/bindings/blas/'
+test_target_path = '../test/lapack/'
+
+templates = {}
+templates[ 'PARSERMODE' ] = 'BLAS'
+for root, dirs, files in os.walk( template_src_path ):
+ right_file = re.compile( '^.+\.(cpp|h|hpp|txt)$' )
+ for template_file in files:
+ if right_file.match( template_file ) != None:
+ path_to_template_file = os.path.join( root, template_file )
+ print "Reading template file", path_to_template_file
+ templates.update( read_templates( path_to_template_file ) )
+
+function_info_map = {}
+for lapack_file in os.listdir( lapack_src_path ):
+ right_file = re.compile( '^[cdsz].+\.f$' )
+ if right_file.match( lapack_file ) != None:
+ print "Parsing", lapack_file, "..."
+ key, value = netlib.parse_file( os.path.join( lapack_src_path, lapack_file ), templates )
+ if key != None and value != None:
+ print "Adding LAPACK subroutine", key
+ function_info_map[ key ] = value
+
+print "Grouping subroutines..."
+
+value_type_groups = {}
+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[ 'level_2' ] = {}
+routines[ 'level_2' ][ 'endings' ] = [ 'MV', 'SV', 'GER', 'GERU', 'GERC', 'HER', 'HPR', 'HER2', 'HPR2', 'SYR', 'SPR', 'SYR2' ]
+
+routines[ 'level_3' ] = {}
+routines[ 'level_3' ][ 'endings' ] = [ 'MM', 'RK', 'R2K', 'SM' ]
+
+for name in value_type_groups.keys():
+ found = False
+ for level, level_properties in routines.iteritems():
+ if name[ -2: ] in level_properties[ 'endings' ] or \
+ name[ -3: ] in level_properties[ 'endings' ] or \
+ name[ -4: ] in level_properties[ 'endings' ]:
+ print name, "is in " + level
+ if not level_properties.has_key( 'routines_by_value_type' ):
+ level_properties[ 'routines_by_value_type' ] = {}
+ level_properties[ 'routines_by_value_type' ][ name ] = value_type_groups[ name ]
+ found = True
+ if found == False:
+ print name, "is in {??}"
+
+print routines
+
+
+bindings.write_names_header( function_info_map, value_type_groups, templates, bindings_target_path + 'blas_names.h' )
+bindings.write_header( function_info_map, value_type_groups, templates, bindings_target_path + 'blas.h' )
+
+for level, level_properties in routines.iteritems():
+ target_path = bindings_target_path + level
+ if not os.path.exists( target_path ):
+ print "Creating directory " + target_path
+ os.mkdir( target_path )
+
+ print level_properties
+
+ if level_properties.has_key( 'routines_by_value_type' ):
+ print "has key..."
+ write_functions( function_info_map, level_properties[ 'routines_by_value_type' ], templates, target_path )

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,1052 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import netlib
+import bindings
+
+import re, os.path, copy
+from types import StringType
+
+# for debugging purposes
+import pprint
+
+
+global_type_map = {
+ 'CHARACTER': 'char',
+ 'LOGICAL': 'logical_t',
+ 'INTEGER': 'integer_t',
+ 'REAL': 'float',
+ 'DOUBLE PRECISION': 'double' }
+
+templates = {}
+
+
+
+def c_type( name, properties ):
+ m_type_map = global_type_map
+ m_type_map[ 'COMPLEX' ] = 'fcomplex_t'
+ m_type_map[ 'COMPLEX*16' ] = 'dcomplex_t'
+
+ result = m_type_map[ properties[ 'value_type' ] ];
+ if properties[ 'io' ] == [ 'input' ]:
+ result += ' const'
+ result += '*'
+ result += ' ' + name.lower() # is this really needed?
+
+ return result
+
+
+def cpp_type( name, properties ):
+ m_type_map = global_type_map
+ m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
+ m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+
+ result = m_type_map[ properties[ 'value_type' ] ]
+
+ if properties[ 'type' ] == 'scalar':
+ if properties[ 'io' ] == [ 'input' ]:
+ result += ' const'
+ elif properties[ 'io' ] == [ 'external procedure' ]:
+ result += '*'
+ else:
+ result += '&'
+
+ if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+ result += '*'
+
+ result += ' ' + name.lower()
+
+ return result
+
+def call_c_type( name, properties ):
+ result = ''
+ if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+ if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+ result = 'traits::complex_ptr(' + name.lower() + ')'
+ else:
+ result = name.lower()
+ elif properties[ 'type' ] == 'scalar':
+ if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+ result = 'traits::complex_ptr(&' + name.lower() + ')'
+ else:
+ result = '&' + name.lower()
+
+ return result
+
+
+def call_level0_type( name, properties, arg_map ):
+ result = ''
+ if properties[ 'type' ] == 'matrix':
+ result = "traits::matrix_storage(" + name.lower() + ")"
+ elif properties[ 'type' ] == 'vector':
+ my_name = name.lower()
+ if 'workspace' in properties[ 'io' ]:
+ my_name = 'work.select(' + workspace_type( name, properties ) + '())'
+ result = "traits::vector_storage(" + my_name + ")"
+ elif properties.has_key( 'trait_type' ):
+ if properties[ 'trait_type' ] == 'lda':
+ result = "traits::leading_dimension(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'num_columns':
+ result = "traits::matrix_size2(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'num_rows':
+ result = "traits::matrix_size1(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'size':
+ my_name = properties[ 'trait_of' ].lower()
+ referring_to_properties = arg_map[ properties[ 'trait_of' ] ]
+ if 'workspace' in referring_to_properties[ 'io' ]:
+ my_name = 'work.select(' + workspace_type( properties[ 'trait_of' ].lower(), referring_to_properties ) + \
+ '())'
+ result = "traits::vector_size(" + my_name + ")"
+ if properties[ 'trait_type' ] == 'uplo':
+ result = "traits::matrix_uplo_tag(" + properties[ 'trait_of' ].lower() + ")"
+ else:
+ result = name.lower()
+ return result
+
+
+def level1_type( name, properties ):
+ result = None
+ if not properties.has_key( 'trait_of' ) and 'workspace' not in properties[ 'io' ]:
+ if properties[ 'type' ] == 'matrix':
+ result = "Matrix" + name + "& " + name.lower()
+ elif properties[ 'type' ] == 'vector':
+ result = "Vector" + name + "& " + name.lower()
+ else:
+ result = cpp_type( name, properties )
+ if properties[ 'value_type' ] == 'REAL':
+ result = result.replace( "float", "real_type" )
+ if properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = result.replace( "double", "real_type" )
+ return result
+
+
+def level2_type( name, properties ):
+ result = level1_type( name, properties )
+ if name == 'INFO' and 'output' in properties[ 'io' ]:
+ result = None
+
+ if result != None:
+ if properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = result.replace( "real_type", "typename traits::$TYPEOF_FIRST_TYPENAME" + \
+ "_traits< $FIRST_TYPENAME >::value_type" )
+
+ return result
+
+
+def level1_typename( name, properties ):
+ result = None
+ if 'workspace' not in properties[ 'io' ]:
+ if properties[ 'type' ] == 'matrix':
+ result = "typename Matrix" + name
+ if properties[ 'type' ] == 'vector':
+ result = "typename Vector" + name
+ return result
+
+
+
+def nested_list_args( arg ):
+ print "finding nested list arguments of", arg
+ if type( arg ) == StringType:
+ if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+ return [ None ]
+ else:
+ return [ arg.upper() ]
+
+ # we are dealing with a list-type, e.g.,
+ # [ '*', [ 'A', 'B' ] ]
+ # [ 'A', 'B' ]
+ result = []
+ if re.compile( '^[A-Z]+$' ).match( arg[0] ) == None:
+ for a in arg[1]:
+ sub_result = nested_list_args( a )
+ if sub_result != [ None ]:
+ for r in sub_result:
+ if r not in result:
+ result.append( r )
+
+ else:
+ for a in arg:
+ result.append( a )
+
+ print "returning ",result
+ return result
+
+
+
+
+def expand_nested_list( arg, arg_map, use_arg_map = True ):
+
+ print "Expanding nested list: ", arg, len(arg)
+ if type( arg ) == StringType:
+ print "Type is string"
+ # .....
+ if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+ return arg
+ else:
+ if use_arg_map:
+ if not arg_map.has_key( arg ):
+ return '?' + arg.upper()
+ else:
+ return arg_map[ arg ][ 'code' ][ 'call_level_0' ]
+ else:
+ return arg.lower()
+
+ if arg[0] == '()':
+ result = '(' + expand_nested_list( arg[1], arg_map, use_arg_map ) + ')'
+ return result
+
+ if arg[0] == 'max' or arg[0] == 'min':
+ print "arg1: ", arg[1]
+ result = 'std::' + arg[0] + '('
+ i = 0
+ for a in arg[1]:
+ result += expand_nested_list( a, arg_map, use_arg_map )
+ i += 1
+ if i != len(arg[1]):
+ result += ","
+ result += ')'
+ return result
+
+ if arg[0] == '*' or arg[0] == '/' or arg[0] == '+' or arg[0] == '-':
+ print "arg1: ", arg[1]
+ arg_list = []
+ for a in arg[1]:
+ arg_list += [ expand_nested_list( a, arg_map, use_arg_map ) ]
+ result = arg[0].join( arg_list )
+ return result
+
+ print "ERROR: Don't know what to do!!"
+ return 'ERROR'
+
+def level1_assert( name, properties, arg_map ):
+ result = None
+
+ if properties.has_key( 'assert_char' ):
+ result = "assert( "
+ result_array = []
+ for char in properties[ 'assert_char' ]:
+ result_array += [ call_level0_type( name, properties, arg_map ) + ' == \'' + char + '\'' ]
+ result += " || ".join( result_array )
+ result += " );"
+
+ if properties.has_key( 'assert_ge' ) and not properties.has_key( 'workspace_query_for' ):
+ result = "assert( " + call_level0_type( name, properties, arg_map ) + " >= " + expand_nested_list( properties[ 'assert_ge' ], arg_map ) + ' );'
+
+ if 'workspace' in properties[ 'io' ]:
+ min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+ if min_workspace_call == None:
+ min_workspace_call = '$CALL_MIN_SIZE'
+ result = 'assert( traits::vector_size(work.select(' + workspace_type( name, properties ) + '()) >= ' + \
+ 'min_size_' + name.lower() + '( ' + min_workspace_call + ' )));'
+
+ elif properties.has_key( 'assert_size' ):
+ result = "assert( traits::vector_size(" + call_level0_type( name, properties, arg_map ) + ") >= " + \
+ expand_nested_list( properties[ 'assert_size' ], arg_map ) + ' );'
+
+ return result
+
+
+def call_level1_type( name, properties ):
+ result = None
+ if level1_type( name, properties ) != None:
+ result = name.lower()
+ return result
+
+
+def workspace_type( name, properties ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties[ 'value_type' ] == 'INTEGER':
+ result = 'integer_t'
+ elif properties[ 'value_type' ] == 'LOGICAL':
+ result = 'bool'
+ elif properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = 'real_type'
+ else:
+ result = 'value_type'
+ return result
+
+
+
+
+def opt_workspace_pre_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ result = workspace_type( name, properties ) + ' opt_size_' + name.lower() + ';'
+ else:
+ min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+ if min_workspace_call == None:
+ min_workspace_call = '$CALL_MIN_SIZE'
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( min_size_' + name.lower() + '( ' + min_workspace_call + ' ) );'
+ return result
+
+
+def opt_workspace_post_type( name, properties ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ if properties['value_type'] == 'INTEGER':
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( opt_size_' + name.lower() + ' );'
+ else:
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( traits::detail::to_int( opt_size_' + name.lower() + ' ) );'
+ return result
+
+
+
+def opt_workspace_query_type( name, properties, arg_map ):
+ result = None
+ if properties.has_key( 'workspace_query_for' ):
+ result = '-1'
+ elif 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ result = '&opt_size_' + name.lower();
+ else:
+ result = 'traits::vector_storage(tmp_' + name.lower() + ')'
+ else:
+ result = call_level0_type( name, properties, arg_map )
+ return result
+
+
+def min_workspace_size_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size' ):
+ result = expand_nested_list( properties[ 'assert_size' ], arg_map, False );
+ return result
+
+
+def min_workspace_arg_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+ code_result = []
+ for arg in properties[ 'assert_size_args' ]:
+ if arg_map.has_key( arg ):
+ code_result += [ cpp_type( arg, arg_map[ arg ] ) ]
+ else:
+ code_result += [ '?' + arg.upper() ]
+ result = ", ".join( code_result )
+ return result
+
+
+def min_workspace_call_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+ code_result = []
+ for arg in properties[ 'assert_size_args' ]:
+ if arg_map.has_key( arg ):
+ code_result += [ call_level0_type( arg, arg_map[ arg ], arg_map ) ]
+ else:
+ code_result += [ '?' + arg.upper() ]
+
+ result = ", ".join( code_result )
+ return result
+
+
+def user_defined_type( name, properties, arg_map ):
+ result = None
+ if properties.has_key( 'user_defined' ):
+ result = properties[ 'user_defined' ]
+ return result
+
+
+
+#
+#
+#
+#
+def match_formulae( text_field ):
+ find_start = re.compile( '([A-Z]+)\s?(>=|is\sat\sleast)\s?(.*)the\scode\swill', re.M | re.S ).findall( text_field )
+ for element in find_start:
+ print element
+
+
+
+#
+# Split string using a list of delimiters
+# Delimiters may be substrings of length 1 or 2 (may be increased if necessary)
+#
+def split_delim( s, delim = [','] ):
+ result = []
+ parentheses = 0
+ cur_pos = 0
+ prev_pos = 0
+ for index in range( 0, len(s) ):
+ if s[ index ] == '(':
+ parentheses += 1
+ elif s[ index ] == ')':
+ parentheses -= 1
+ for length in range( 1, 3 ):
+ if index >= (length-1) and parentheses == 0:
+ c = s[ index-(length-1): index+1 ]
+ if c in delim:
+ result += [ s[ prev_pos:(index-(length-1)) ] ]
+ prev_pos = index+1
+
+ result += [ s[ prev_pos:len(s) ] ]
+ return result
+
+
+
+#
+# Look for implicit products, like 5N, and replace with 5*N
+#
+def replace_implicit_products( text_field ):
+ result = re.sub( '([0-9])+([A-Z]+)', '\\1*\\2', text_field )
+ return result
+
+
+
+
+def decompose_formula( text_field ):
+ text_field = text_field.strip()
+ print "Decompose: ", text_field
+
+ if text_field[0] == '(' and text_field[-1] == ')':
+ result = text_field[ 1:-1 ]
+ return [ '()', decompose_formula( result ) ]
+
+ if len( split_delim( text_field, [ ',' ] ) ) > 1:
+ print "ERROR! (in LAPACK?)"
+ return [ 'ERROR' ]
+
+ #
+ # Detect leaf: if text_field equals a argument (like N), or a number
+ #
+ if re.compile( '^([a-zA-Z]+|[0-9]+)$' ).match( text_field ):
+ print "decompose: at leaf: '" + text_field + "'"
+ return text_field.upper()
+
+
+ if len( split_delim( text_field, [ '**' ] ) ) > 1:
+ print 'decompose: inserting pow'
+ arguments = split_delim( text_field, [ '**' ] )
+ print arguments
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ return [ 'pow', result ]
+
+ for operator in [ '*', '/', '+', '-' ]:
+ if len( split_delim( text_field, [ operator ] ) ) > 1:
+ print 'decompose: inserting ' + operator
+ arguments = split_delim( text_field, operator )
+ print arguments
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ return [ operator, result ]
+
+
+ if (text_field[ 0:4 ] == 'max(' or text_field[ 0:4 ] == 'MAX(') and \
+ text_field[ -1 ] == ')':
+ print "decompose: inserting max"
+ arguments = split_delim( text_field[ 4:-1 ] )
+ print arguments, len(arguments)
+ # keep max a binary function ... :-)
+ if len( arguments ) > 2:
+ return [ 'max', [ decompose_formula( arguments[0] ), decompose_formula( 'max(' + ",".join( arguments[1:] ) + ')' ) ] ]
+ else:
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+ return [ 'max', result ]
+
+
+ if (text_field[ 0:4 ] == 'min(' or text_field[ 0:4 ] == 'MIN(') and \
+ text_field[ -1 ] == ')':
+ print "decompose: inserting min"
+ arguments = split_delim( text_field[ 4:-1 ] )
+ print arguments, len(arguments)
+ # keep max a binary function ... :-)
+ if len( arguments ) > 2:
+ return [ 'min', [ decompose_formula( arguments[0] ), decompose_formula( 'min(' + ",".join( arguments[1:] ) + ')' ) ] ]
+ else:
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+ return [ 'min', result ]
+
+
+#
+#
+def match_assert_ge( argument_map, text_field ):
+ #print "Match assert GE..."
+ match_it = re.compile( ' +[A-Z]+[ ]{0,3}(>=|must be at least)[ ]{0,3}([0-9]|(min|max|MIN|MAX|[\(\)\,0-9A-Z\+\*\-])+)' ).findall( text_field )
+ if len( match_it ) == 1:
+ print "Match assert GE:", match_it
+ #print match_it
+ #if len( match_it[ 0 ][ 2 ] ) > 0:
+ return decompose_formula( match_it[ 0 ][ 1 ] )
+ else:
+ print "nr of matches: ", len( match_it )
+ return None
+
+
+
+
+
+# try different keys, return the one that exists, if any
+
+def my_has_key( key_name, template_map ):
+ # try, e.g., gelsd.all.
+ m_all_key = key_name.replace( ".complex", ".all" ).replace( ".real", ".all" )
+ if template_map.has_key( key_name ):
+ print "using key ", key_name
+ return key_name
+ if template_map.has_key( m_all_key ):
+ print "using key ", m_all_key
+ return m_all_key
+ print "tried keys ", key_name, "and", m_all_key,", no results"
+ return None
+
+
+
+#
+# Default user-defined arg is of type scalar INTEGER
+#
+def add_user_defined_args( arg, argument_map, template_map, base_name ):
+ print "Trying to add user-defined argument definitions for", arg
+
+ argument_map[ arg ] = {}
+
+ base_key = base_name.lower() + '.' + arg
+ print "base_key",base_key
+
+ if my_has_key( base_key + '.value_type', template_map ) != None:
+ argument_map[ arg ][ 'value_type' ] = template_map[ my_has_key( base_key + '.value_type', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'value_type' ] = 'INTEGER'
+
+ if my_has_key( base_key + '.type', template_map ) != None:
+ argument_map[ arg ][ 'type' ] = template_map[ my_has_key( base_key + '.type', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'type' ] = 'scalar'
+
+ if my_has_key( base_key + '.init', template_map ) != None:
+ argument_map[ arg ][ 'user_defined' ] = template_map[ my_has_key( base_key + '.init', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'user_defined' ] = 'UNDEFINED'
+
+ argument_map[ arg ][ 'io' ] = [ 'input' ]
+
+ return
+
+
+#
+# Desired order of routines in C++ code: float, double, single complex, double complex
+#
+def routine_cmp( a, b ):
+ letter_a = a[0]
+ letter_b = b[0]
+ value_map = { 'S': 0, 'D': 1, 'C': 2, 'Z': 3 }
+ result = 0
+ if value_map[ a[0] ] < value_map[ b[ 0] ]:
+ result = -1
+ if value_map[ a[0] ] > value_map[ b[ 0] ]:
+ result = 1
+ return result
+
+
+#
+# Group subroutines on their name, with the first character removed. This will
+# group them in the same .hpp file as well. Sort these subroutines based on
+# routine_cmp above.
+#
+def group_by_value_type( global_info_map ):
+ group_map = {}
+ for i in global_info_map.keys():
+ short_name = i[ 1: ]
+ if not group_map.has_key( short_name ):
+ group_map[ short_name ] = []
+ group_map[ short_name ] += [ i ]
+ for value in group_map.values():
+ value.sort( routine_cmp )
+ return group_map
+
+
+
+
+def indent_lines( source_text, indent_size = 8 ):
+ indent_string = '\n'
+ for i in range(indent_size):
+ indent_string += ' '
+ return indent_string.join( source_text.splitlines() )
+
+
+
+#
+# Write the (many) driver routine file(s).
+#
+def write_functions( info_map, group, template_map, base_dir ):
+ #
+ # group.keys() is a vector of different grouped function names
+ # like gees, dgesv, etc.
+ #
+ for group_name, subroutines in group.iteritems():
+
+ filename = group_name.lower() + '.hpp'
+ includes = [ '#include <cassert>',
+ '#include <boost/numeric/bindings/traits/traits.hpp>',
+ '#include <boost/numeric/bindings/traits/type_traits.hpp>',
+ '#include <boost/numeric/bindings/lapack/lapack.h>' ]
+
+ if template_map.has_key( group_name.lower() + '.includes' ):
+ includes += template_map[ group_name.lower() + '.includes' ].splitlines()
+
+ #
+ # LEVEL 0 HANDLING
+ #
+ overloads = ''
+ for subroutine in subroutines:
+ sub_template = template_map[ 'lapack_overloads' ]
+ # add the argument list here
+ arg_list = []
+ lapack_arg_list = []
+ for arg in info_map[ subroutine ][ 'arguments' ]:
+ arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_0' ] ]
+ lapack_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_c_header' ] ]
+ sub_template = sub_template.replace( "$LEVEL0", ", ".join( arg_list ) )
+ 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() )
+
+ overloads += bindings.proper_indent( sub_template )
+
+ cases = {}
+ # first, see what kind of functions we have
+ # needed for argument check etc.
+ for subroutine in subroutines:
+ if subroutine[0] == 'S' or subroutine[0] == 'D':
+ if not cases.has_key( 'real' ):
+ cases[ 'real' ] = {}
+ cases[ 'real' ][ 'subroutines' ] = []
+ cases[ 'real' ][ 'subroutines' ] += [ subroutine ]
+ if subroutine[0] == 'C' or subroutine[0] == 'Z':
+ if not cases.has_key( 'complex' ):
+ cases[ 'complex' ] = {}
+ cases[ 'complex' ][ 'subroutines' ] = []
+ cases[ 'complex' ][ 'subroutines' ] += [ subroutine ]
+
+ #
+ # LEVEL 1 and 2 HANDLING
+ #
+ level1_map = {}
+ level2_map = {}
+ for value_type, case_map in cases.iteritems():
+
+ level1_template = ''
+ level2_template = ''
+ if info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ].has_key( 'workspace' ):
+ level1_template = template_map[ 'level1_workspace' ]
+ level2_template = template_map[ 'level2_workspace' ]
+ else:
+ level1_template = template_map[ 'level1_noworkspace' ]
+ level2_template = template_map[ 'level2_noworkspace' ]
+
+ level1_template = level1_template.replace( '$groupname', group_name.lower() )
+ level1_template = level1_template.replace( "$SPECIALIZATION", value_type )
+
+ # take this subroutine for arguments etc.
+ subroutine = case_map[ 'subroutines' ][ 0 ]
+ print "taking",subroutine
+
+ level0_arg_list = []
+ level1_arg_list = []
+ level2_arg_list = []
+ level1_type_arg_list = []
+ level1_assert_list = []
+ call_level1_arg_list = []
+ workspace_query_arg_list = []
+ user_defined_arg_list = []
+ user_defined_opt_arg_list = []
+ for arg in info_map[ subroutine ][ 'arguments' ]:
+ level0_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_0' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] != None:
+ level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_2' ] != None:
+ level2_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_2' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] != None and \
+ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] not in level1_type_arg_list:
+ 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' ][ 'call_level_1' ] != None:
+ call_level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'opt_workspace_query' ] != None:
+ workspace_query_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'opt_workspace_query' ] ]
+
+ if info_map[ subroutine ][ 'user_defined_variables' ] != None:
+ for arg in info_map[ subroutine ][ 'user_defined_variables' ]:
+ print arg
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] != None:
+ user_defined_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] ]
+
+ if info_map[ subroutine ][ 'user_defined_opt_variables' ] != None:
+ for arg in info_map[ subroutine ][ 'user_defined_opt_variables' ]:
+ print arg
+ if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] != None:
+ user_defined_opt_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] ]
+
+ # Level 1 replacements
+ level1_template = level1_template.replace( "$CALL_LEVEL0", ", ".join( level0_arg_list ) )
+ level1_template = level1_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+ 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 ) )
+
+ if len( user_defined_arg_list ) > 0:
+ level1_template = level1_template.replace( "$INIT_USER_DEFINED_VARIABLES", indent_lines( "\n".join(user_defined_arg_list), 8 ) )
+ else:
+ level1_template = level1_template.replace( "\n $INIT_USER_DEFINED_VARIABLES", "" )
+
+ # 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 ) )
+ first_typename = level1_type_arg_list[0].split(" ")[-1]
+ first_typename_datatype = first_typename[0:6].lower() # 'matrix' or 'vector'
+ 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 ) )
+
+ #
+ # Workspace stuff
+ #
+ if info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ].has_key( 'workspace' ):
+ # Add an include for the workspace stuff
+ includes += [ '#include <boost/numeric/bindings/lapack/workspace.hpp>' ]
+ includes += [ '#include <boost/numeric/bindings/traits/detail/array.hpp>' ]
+
+ # Continue
+ workspace_size = len( info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ] )
+ workspace_args = info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]
+ level1_template = level1_template.replace( "$WORKSPACE_SIZE", str(workspace_size) )
+ level1_template = level1_template.replace( "$WORKSPACE_TYPENAMES", "typename " + ", typename ".join( workspace_args ) )
+ level1_template = level1_template.replace( "$WORKSPACE_TYPES", ", ".join( workspace_args ) )
+
+ # $TMP_WORKARRAYS is something like "tmp_work, tmp_rwork"
+ tmp_workspace_args = []
+ for name in info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]:
+ tmp_workspace_args += [ 'tmp_' + name.lower() ]
+ level1_template = level1_template.replace( "$TMP_WORKARRAYS", ", ".join( tmp_workspace_args ) )
+
+ # $SETUP_WORKARRAYS looks like
+ # traits::detail::array< value_type > $TMP_NAME ....
+ setup_min_workarrays = ''
+ setup_opt_workarrays_pre = []
+ setup_opt_workarrays_post = []
+ for name in info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]:
+ # minimal case
+ sub_min_template = template_map[ 'setup_min_workspace' ]
+ sub_min_template = sub_min_template.replace( '$NAME', name.lower() )
+ sub_min_template = sub_min_template.replace( '$WORKSPACE_TYPE', info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'workspace_type' ] )
+ if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_call' ] != None:
+ sub_min_template = sub_min_template.replace( "$CALL_MIN_SIZE", info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_call' ] )
+
+ setup_min_workarrays += sub_min_template
+
+ # optimal case
+ if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_pre' ] != None:
+ setup_opt_workarrays_pre += [ info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_pre' ] ]
+ if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_post' ] != None:
+ setup_opt_workarrays_post += [ info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_post' ] ]
+
+
+ # if the length of setup_opt_workarrays_post equals 0, it's equal to the minimal_case
+ opt_workspace_template = ''
+ if len( setup_opt_workarrays_post ) == 0:
+ print "EQUAL to MINIMAL CASE!"
+ opt_workspace_template = template_map[ 'level1_opt_workspace_is_min' ]
+ else:
+ includes += [ '#include <boost/numeric/bindings/traits/detail/utils.hpp>' ]
+ opt_workspace_template = template_map[ 'level1_opt_workspace' ]
+
+ opt_workspace_template = opt_workspace_template.replace( "$WORKSPACE_QUERY", ", ".join( workspace_query_arg_list ) )
+ opt_workspace_template = opt_workspace_template.replace( "$SETUP_OPT_WORKARRAYS_POST", "\n ".join( setup_opt_workarrays_post ) )
+ opt_workspace_template = opt_workspace_template.replace( "$SETUP_OPT_WORKARRAYS_PRE", "\n ".join( setup_opt_workarrays_pre ) )
+ opt_workspace_template = opt_workspace_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+ opt_workspace_template = opt_workspace_template.replace( "$TMP_WORKARRAYS", ", ".join( tmp_workspace_args ) )
+
+
+ if len( user_defined_opt_arg_list ) > 0:
+ opt_workspace_template = opt_workspace_template.replace( "$INIT_USER_DEFINED_OPT_VARIABLES", indent_lines( "\n".join(user_defined_arg_list), 8 ) )
+ else:
+ print "removing $INIT_USER_DEFINED_OPT_VARIABLES"
+ opt_workspace_template = opt_workspace_template.replace( " $INIT_USER_DEFINED_OPT_VARIABLES\n", "" )
+
+
+ level1_template = level1_template.replace( "$OPT_WORKSPACE_FUNC", opt_workspace_template.rstrip() )
+ level1_template = level1_template.replace( "$SETUP_MIN_WORKARRAYS_POST", setup_min_workarrays.rstrip() )
+
+
+ #
+ # INSERT THE MINIMAL WORKSPACE FUNCTIONS
+ #
+ min_size_funcs = ''
+ for name in info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]:
+ sub_template = template_map[ 'min_size_func' ]
+ sub_template = sub_template.replace( "$NAME", name.lower() )
+
+ # first: user-defined stuff (overrules any auto-detected stuff)
+ my_key = group_name.lower() + '.' + value_type + '.min_size_' + name.lower()
+ my_key_all = group_name.lower() + '.all.min_size_' + name.lower()
+ print my_key
+ if template_map.has_key( my_key ):
+ sub_template = sub_template.replace( "$MIN_SIZE", indent_lines( template_map[ my_key ].rstrip(), 8 ) )
+
+ # if that fails, try the more generic key "all"
+ elif template_map.has_key( my_key_all ):
+ sub_template = sub_template.replace( "$MIN_SIZE", indent_lines( template_map[ my_key_all ].rstrip(), 8 ) )
+
+ elif info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace' ] != None:
+ resulting_code = 'return ' + info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace' ] + ';'
+ sub_template = sub_template.replace( "$MIN_SIZE", resulting_code.rstrip() )
+
+ # Do about the same for the argument stuff.
+ if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_args' ] != None:
+ sub_template = sub_template.replace( "$ARGUMENTS", info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_args' ] )
+
+ #sub_template += 'FOUND'
+ min_size_funcs += sub_template
+
+ min_size_funcs = min_size_funcs.rstrip()
+ level1_template = level1_template.replace( "$MIN_SIZE_FUNCS", min_size_funcs )
+
+ level1_map[ value_type ] = bindings.proper_indent( level1_template )
+ level2_map[ value_type ] = bindings.proper_indent( level2_template )
+
+ #
+ # LEVEL 1 and 2 FINALIZATION
+ #
+ for mapping in [ level1_map, level2_map ]:
+ if len(mapping) > 1:
+ # compare real and complex cases
+ all_keys = mapping.keys()
+ if mapping[ all_keys[0] ] == mapping[ all_keys[1] ]:
+ print "literally everything is the same!!, falling back to 1 case"
+ del mapping[ all_keys[ 1 ] ]
+
+ level1 = ''
+ if len( level1_map ) > 1:
+ level1 = template_map[ 'level1_pre_header' ]
+ includes += [ '#include <boost/utility/enable_if.hpp>' ]
+ includes += [ '#include <boost/numeric/bindings/traits/is_real.hpp>' ]
+ includes += [ '#include <boost/numeric/bindings/traits/is_complex.hpp>' ]
+
+ for value_type in level1_map.keys():
+ if len( level1_map ) == 1:
+ header = template_map[ 'level1_header1' ]
+ else:
+ header = template_map[ 'level1_header2' ]
+
+ level1 += header.replace( "$SPECIALIZATION", value_type )
+ level1 += level1_map[ value_type ]
+
+ level2 = ''
+ for value_type in level2_map.keys():
+ level2 += level2_map[ value_type ]
+
+ #
+ # handle addition of includes
+ #
+ includes_code = ''
+ unique_includes = []
+ for include in includes:
+ if include not in unique_includes:
+ unique_includes += [ include ]
+ sorted_includes = sorted( unique_includes, lambda x, y: cmp( x.lower(), y.lower() ) )
+ if len( sorted_includes ) > 0:
+ includes_code = "\n".join( sorted_includes )
+
+ result = template_map[ 'lapack.hpp' ]
+ 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() )
+
+ # replace the global variables as last (this is convenient)
+ #result = result.replace( '$INDENT', ' ' )
+ #result = result.replace( '$groupname', group_name.lower() )
+ #result = result.replace( '$DESCRIPTION', info_map[ group[g][0] ][ 'description' ] )
+
+ open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+#
+# Write the (many) driver routine test cases to cpp files.
+#
+def write_test_case( info_map, group, template_map, base_dir, level_name ):
+
+ for group_name, subroutines in group.iteritems():
+
+ filename = group_name.lower() + '.cpp'
+ result = template_map[ 'test_case.cpp' ]
+ result = result.replace( '$groupname', group_name.lower() )
+ result = result.replace( '$levelname', level_name.lower() )
+
+ open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+def write_cmakefile( level_properties, template_map, base_dir ):
+
+ entries = ''
+ for problem_type, problem_properties in level_properties.iteritems():
+ if problem_properties.has_key( 'routines_by_value_type' ):
+ group = problem_properties[ 'routines_by_value_type' ]
+ for group_name, subroutines in group.iteritems():
+ sub_result = template_map[ 'CMakeLists.entry' ]
+ sub_result = sub_result.replace( '$groupname', group_name.lower() )
+ entries += sub_result
+
+ filename = 'CMakeLists.txt'
+ result = template_map[ 'CMakeLists.txt' ]
+ result = result.replace( '$ENTRIES', entries )
+ open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+
+def read_templates( template_file ):
+ file_contents = open( template_file ).read()
+ split_regex = re.compile( '^\$TEMPLATE\[([^\]]+)\]\s', re.M | re.S )
+ split_templates = split_regex.split( file_contents )[ 1:-1 ]
+ result = {}
+ for index in range(len(split_templates)/2):
+ print "Adding template", split_templates[ index*2 ]
+ result[ split_templates[ index*2 ] ] = split_templates[ index*2 + 1 ]
+ return result
+
+lapack_src_path = './lapack-3.1.1/SRC'
+template_src_path = './templates'
+bindings_target_path = '../../../../boost/numeric/bindings/lapack/'
+test_target_path = '../test/lapack/'
+
+templates = {}
+templates[ 'PARSERMODE' ] = 'LAPACK'
+for root, dirs, files in os.walk( template_src_path ):
+ right_file = re.compile( '^.+\.(cpp|h|hpp|txt)$' )
+ for template_file in files:
+ if right_file.match( template_file ) != None:
+ path_to_template_file = os.path.join( root, template_file )
+ print "Reading template file", path_to_template_file
+ templates.update( read_templates( path_to_template_file ) )
+
+function_info_map = {}
+for lapack_file in os.listdir( lapack_src_path ):
+ right_file = re.compile( '^[cdsz].+\.f$' )
+ if right_file.match( lapack_file ) != None:
+ print "Parsing", lapack_file, "..."
+ key, value = netlib.parse_file( os.path.join( lapack_src_path, lapack_file ), templates )
+ if key != None and value != None:
+ print "Adding LAPACK subroutine", key
+ function_info_map[ key ] = value
+
+print "Grouping subroutines..."
+
+value_type_groups = {}
+value_type_groups = group_by_value_type( function_info_map )
+
+routines = {}
+routines[ 'driver' ] = {}
+routines[ 'driver' ][ 'linear_equations' ] = {}
+routines[ 'driver' ][ 'linear_equations' ][ 'endings' ] = [ 'SV', 'SVX' ]
+
+routines[ 'driver' ][ 'least_squares' ] = {}
+routines[ 'driver' ][ 'least_squares' ][ 'endings' ] = [ 'LS', 'LSY', 'LSS', 'LSD' ]
+
+routines[ 'driver' ][ 'general_least_squares' ] = {}
+routines[ 'driver' ][ 'general_least_squares' ][ 'endings' ] = [ 'LSE', 'GLM' ]
+
+# based on LAPACK Users' Guide, table 2.5
+routines[ 'driver' ][ 'eigen' ] = {}
+routines[ 'driver' ][ 'eigen' ][ 'endings' ] = [ 'YEV', 'EEV', 'YEVX', 'EEVX', 'YEVD', 'EEVD', 'YEVR', 'EEVR', 'EES', 'PEV', 'PEVD', 'PEVX', 'BEV', 'BEVD', 'BEVX', 'EESX', 'ESVD', 'ESDD', 'TEV', 'TEVD', 'TEVX', 'TEVR' ]
+
+# based on LAPACK Users' Guide, table 2.6
+routines[ 'driver' ][ 'general_eigen' ] = {}
+routines[ 'driver' ][ 'general_eigen' ][ 'endings' ] = [ 'GV', 'GVD', 'GVX', 'GES', 'GESX', 'GEV', 'GEVX', 'GSVD' ]
+
+
+routines[ 'computational' ] = {}
+
+# based on LAPACK Users' Guide, table 2.7
+routines[ 'computational' ][ 'linear_equations' ] = {}
+routines[ 'computational' ][ 'linear_equations' ][ 'endings' ] = [ 'TRF', 'TRS', 'CON', 'RFS', 'TRI', 'EQU' ]
+
+# based on LAPACK Users' Guide, table 2.9
+routines[ 'computational' ][ 'least_squares' ] = {}
+routines[ 'computational' ][ 'least_squares' ][ 'endings' ] = [ 'QP3', 'EQRF', 'GQR', 'MQR', 'LQF', 'GLQ', 'MLQ', 'QLF', 'GQL', 'MQL', 'ERQF', 'GRQ', 'MRQ', 'RZF', 'RZ' ]
+
+routines[ 'computational' ][ 'general_least_squares' ] = {}
+routines[ 'computational' ][ 'general_least_squares' ][ 'endings' ] = [ 'GQRF', 'GRQF' ]
+
+# based on LAPACK Users' Guide, table 2.10
+routines[ 'computational' ][ 'symmetric_eigen' ] = {}
+routines[ 'computational' ][ 'symmetric_eigen' ][ 'endings' ] = [ 'TRD', 'MTR', 'GTR', 'TEQR', 'ERF', 'EDC', 'EGR', 'EBZ', 'TEIN' ]
+
+# based on LAPACK Users' Guide, table 2.11
+routines[ 'computational' ][ 'nonsymmetric_eigen' ] = {}
+routines[ 'computational' ][ 'nonsymmetric_eigen' ][ 'endings' ] = [ 'EHRD', 'EBAL', 'EBAK', 'GHR', 'MHR', 'SEQR', 'SEIN', 'REVC', 'REXC', 'RSYL', 'RSNA', 'RSEN' ]
+
+# based on LAPACK Users' Guide, table 2.12
+routines[ 'computational' ][ 'svd' ] = {}
+routines[ 'computational' ][ 'svd' ][ 'endings' ] = [ 'BRD', 'GBR', 'MBR', 'SQR', 'SDC' ]
+
+# based on LAPACK Users' Guide, table 2.14
+routines[ 'computational' ][ 'general_eigen' ] = {}
+routines[ 'computational' ][ 'general_eigen' ][ 'endings' ] = [ 'GST', 'STF' ]
+
+# based on LAPACK Users' Guide, table 2.15
+routines[ 'computational' ][ 'general_nonsymmetric_eigen' ] = {}
+routines[ 'computational' ][ 'general_nonsymmetric_eigen' ][ 'endings' ] = [ 'GHRD', 'GBAL', 'GBAK', 'EQZ', 'GEVC', 'GEXC', 'GSYL', 'GSNA', 'GSEN' ]
+
+# based on LAPACK Users' Guide, table 2.16
+routines[ 'computational' ][ 'general_nonsymmetric_svd' ] = {}
+routines[ 'computational' ][ 'general_nonsymmetric_svd' ][ 'endings' ] = [ 'SVP', 'SJA' ]
+
+for name in value_type_groups.keys():
+ found = False
+ for level, level_properties in routines.iteritems():
+ for problem_type, problem_properties in level_properties.iteritems():
+ if name[ -2: ] in problem_properties[ 'endings' ] or \
+ name[ -3: ] in problem_properties[ 'endings' ] or \
+ name[ -4: ] in problem_properties[ 'endings' ]:
+ print name, "is in {"+level+", "+ problem_type + "}"
+ if not problem_properties.has_key( 'routines_by_value_type' ):
+ problem_properties[ 'routines_by_value_type' ] = {}
+ problem_properties[ 'routines_by_value_type' ][ name ] = value_type_groups[ name ]
+ found = True
+ if found == False:
+ print name, "is in {??}"
+
+print routines
+
+
+bindings.write_names_header( function_info_map, value_type_groups, templates, bindings_target_path + 'lapack_names.h' )
+bindings.write_header( function_info_map, value_type_groups, templates, bindings_target_path + 'lapack.h' )
+
+for level, level_properties in routines.iteritems():
+ target_path = bindings_target_path + level
+ if not os.path.exists( target_path ):
+ os.mkdir( target_path )
+ if not os.path.exists( test_target_path + level ):
+ os.mkdir( test_target_path + level )
+
+ for problem_type, problem_properties in level_properties.iteritems():
+ if problem_properties.has_key( 'routines_by_value_type' ):
+ write_functions( function_info_map, problem_properties[ 'routines_by_value_type' ], templates, target_path )
+
+ write_test_case( function_info_map, problem_properties[ 'routines_by_value_type' ], templates, test_target_path + level, level )
+
+ write_cmakefile( level_properties, templates, test_target_path + level )
+
+

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,1064 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import re, os.path, copy
+from types import StringType
+
+# for debugging purposes
+import pprint
+
+
+global_type_map = {
+ 'CHARACTER': 'char',
+ 'LOGICAL': 'logical_t',
+ 'INTEGER': 'integer_t',
+ 'REAL': 'float',
+ 'DOUBLE PRECISION': 'double' }
+
+templates = {}
+
+
+
+def c_type( name, properties ):
+ 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'
+
+ result = m_type_map[ properties[ 'value_type' ] ];
+ if properties[ 'io' ] == [ 'input' ]:
+ result += ' const'
+ result += '*'
+ result += ' ' + name.lower() # is this really needed?
+
+ return result
+
+
+def cpp_type( name, properties ):
+ m_type_map = global_type_map
+ m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
+ m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+
+ result = m_type_map[ properties[ 'value_type' ] ]
+
+ if properties[ 'type' ] == 'scalar':
+ if properties[ 'io' ] == [ 'input' ]:
+ result += ' const'
+ elif properties[ 'io' ] == [ 'external procedure' ]:
+ result += '*'
+ else:
+ result += '&'
+
+ if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+ result += '*'
+
+ result += ' ' + name.lower()
+
+ return result
+
+def call_c_type( name, properties ):
+ result = ''
+ if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+ if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+ result = 'traits::complex_ptr(' + name.lower() + ')'
+ else:
+ result = name.lower()
+ elif properties[ 'type' ] == 'scalar':
+ if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+ result = 'traits::complex_ptr(&' + name.lower() + ')'
+ else:
+ result = '&' + name.lower()
+
+ return result
+
+
+def call_level0_type( name, properties, arg_map ):
+ result = ''
+ if properties[ 'type' ] == 'matrix':
+ result = "traits::matrix_storage(" + name.lower() + ")"
+ elif properties[ 'type' ] == 'vector':
+ my_name = name.lower()
+ if 'workspace' in properties[ 'io' ]:
+ my_name = 'work.select(' + workspace_type( name, properties ) + '())'
+ result = "traits::vector_storage(" + my_name + ")"
+ elif properties.has_key( 'trait_type' ):
+ if properties[ 'trait_type' ] == 'lda':
+ result = "traits::leading_dimension(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'num_columns':
+ result = "traits::matrix_size2(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'num_rows':
+ result = "traits::matrix_size1(" + properties[ 'trait_of' ].lower() + ")"
+ if properties[ 'trait_type' ] == 'size':
+ my_name = properties[ 'trait_of' ].lower()
+ referring_to_properties = arg_map[ properties[ 'trait_of' ] ]
+ if 'workspace' in referring_to_properties[ 'io' ]:
+ my_name = 'work.select(' + workspace_type( properties[ 'trait_of' ].lower(), referring_to_properties ) + \
+ '())'
+ result = "traits::vector_size(" + my_name + ")"
+ if properties[ 'trait_type' ] == 'uplo':
+ result = "traits::matrix_uplo_tag(" + properties[ 'trait_of' ].lower() + ")"
+ else:
+ result = name.lower()
+ return result
+
+
+def level1_type( name, properties ):
+ result = None
+ if not properties.has_key( 'trait_of' ) and 'workspace' not in properties[ 'io' ]:
+ if properties[ 'type' ] == 'matrix':
+ result = "Matrix" + name + "& " + name.lower()
+ elif properties[ 'type' ] == 'vector':
+ result = "Vector" + name + "& " + name.lower()
+ else:
+ result = cpp_type( name, properties )
+ if properties[ 'value_type' ] == 'REAL':
+ result = result.replace( "float", "real_type" )
+ if properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = result.replace( "double", "real_type" )
+ return result
+
+
+def level2_type( name, properties ):
+ result = level1_type( name, properties )
+ if name == 'INFO' and 'output' in properties[ 'io' ]:
+ result = None
+
+ if result != None:
+ if properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = result.replace( "real_type", "typename traits::$TYPEOF_FIRST_TYPENAME" + \
+ "_traits< $FIRST_TYPENAME >::value_type" )
+
+ return result
+
+
+def level1_typename( name, properties ):
+ result = None
+ if 'workspace' not in properties[ 'io' ]:
+ if properties[ 'type' ] == 'matrix':
+ result = "typename Matrix" + name
+ if properties[ 'type' ] == 'vector':
+ result = "typename Vector" + name
+ return result
+
+
+
+def nested_list_args( arg ):
+ print "finding nested list arguments of", arg
+ if type( arg ) == StringType:
+ if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+ return [ None ]
+ else:
+ return [ arg.upper() ]
+
+ # we are dealing with a list-type, e.g.,
+ # [ '*', [ 'A', 'B' ] ]
+ # [ 'A', 'B' ]
+ result = []
+ if re.compile( '^[A-Z]+$' ).match( arg[0] ) == None:
+ for a in arg[1]:
+ sub_result = nested_list_args( a )
+ if sub_result != [ None ]:
+ for r in sub_result:
+ if r not in result:
+ result.append( r )
+
+ else:
+ for a in arg:
+ result.append( a )
+
+ print "returning ",result
+ return result
+
+
+
+
+def expand_nested_list( arg, arg_map, use_arg_map = True ):
+
+ print "Expanding nested list: ", arg, len(arg)
+ if type( arg ) == StringType:
+ print "Type is string"
+ # .....
+ if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+ return arg
+ else:
+ if use_arg_map:
+ if not arg_map.has_key( arg ):
+ return '?' + arg.upper()
+ else:
+ return arg_map[ arg ][ 'code' ][ 'call_level_0' ]
+ else:
+ return arg.lower()
+
+ if arg[0] == '()':
+ result = '(' + expand_nested_list( arg[1], arg_map, use_arg_map ) + ')'
+ return result
+
+ if arg[0] == 'max' or arg[0] == 'min':
+ print "arg1: ", arg[1]
+ result = 'std::' + arg[0] + '('
+ i = 0
+ for a in arg[1]:
+ result += expand_nested_list( a, arg_map, use_arg_map )
+ i += 1
+ if i != len(arg[1]):
+ result += ","
+ result += ')'
+ return result
+
+ if arg[0] == '*' or arg[0] == '/' or arg[0] == '+' or arg[0] == '-':
+ print "arg1: ", arg[1]
+ arg_list = []
+ for a in arg[1]:
+ arg_list += [ expand_nested_list( a, arg_map, use_arg_map ) ]
+ result = arg[0].join( arg_list )
+ return result
+
+ print "ERROR: Don't know what to do!!"
+ return 'ERROR'
+
+def level1_assert( name, properties, arg_map ):
+ result = None
+
+ if properties.has_key( 'assert_char' ):
+ result = "assert( "
+ result_array = []
+ for char in properties[ 'assert_char' ]:
+ result_array += [ call_level0_type( name, properties, arg_map ) + ' == \'' + char + '\'' ]
+ result += " || ".join( result_array )
+ result += " );"
+
+ if properties.has_key( 'assert_ge' ) and not properties.has_key( 'workspace_query_for' ):
+ result = "assert( " + call_level0_type( name, properties, arg_map ) + " >= " + expand_nested_list( properties[ 'assert_ge' ], arg_map ) + ' );'
+
+ if 'workspace' in properties[ 'io' ]:
+ min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+ if min_workspace_call == None:
+ min_workspace_call = '$CALL_MIN_SIZE'
+ result = 'assert( traits::vector_size(work.select(' + workspace_type( name, properties ) + '()) >= ' + \
+ 'min_size_' + name.lower() + '( ' + min_workspace_call + ' )));'
+
+ elif properties.has_key( 'assert_size' ):
+ result = "assert( traits::vector_size(" + call_level0_type( name, properties, arg_map ) + ") >= " + \
+ expand_nested_list( properties[ 'assert_size' ], arg_map ) + ' );'
+
+ return result
+
+
+def call_level1_type( name, properties ):
+ result = None
+ if level1_type( name, properties ) != None:
+ result = name.lower()
+ return result
+
+
+def workspace_type( name, properties ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties[ 'value_type' ] == 'INTEGER':
+ result = 'integer_t'
+ elif properties[ 'value_type' ] == 'LOGICAL':
+ result = 'bool'
+ elif properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+ result = 'real_type'
+ else:
+ result = 'value_type'
+ return result
+
+
+
+
+def opt_workspace_pre_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ result = workspace_type( name, properties ) + ' opt_size_' + name.lower() + ';'
+ else:
+ min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+ if min_workspace_call == None:
+ min_workspace_call = '$CALL_MIN_SIZE'
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( min_size_' + name.lower() + '( ' + min_workspace_call + ' ) );'
+ return result
+
+
+def opt_workspace_post_type( name, properties ):
+ result = None
+ if 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ if properties['value_type'] == 'INTEGER':
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( opt_size_' + name.lower() + ' );'
+ else:
+ result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+ ' tmp_' + name.lower() + '( traits::detail::to_int( opt_size_' + name.lower() + ' ) );'
+ return result
+
+
+
+def opt_workspace_query_type( name, properties, arg_map ):
+ result = None
+ if properties.has_key( 'workspace_query_for' ):
+ result = '-1'
+ elif 'workspace' in properties[ 'io' ]:
+ if properties.has_key( 'workspace_query_by' ):
+ result = '&opt_size_' + name.lower();
+ else:
+ result = 'traits::vector_storage(tmp_' + name.lower() + ')'
+ else:
+ result = call_level0_type( name, properties, arg_map )
+ return result
+
+
+def min_workspace_size_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size' ):
+ result = expand_nested_list( properties[ 'assert_size' ], arg_map, False );
+ return result
+
+
+def min_workspace_arg_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+ code_result = []
+ for arg in properties[ 'assert_size_args' ]:
+ if arg_map.has_key( arg ):
+ code_result += [ cpp_type( arg, arg_map[ arg ] ) ]
+ else:
+ code_result += [ '?' + arg.upper() ]
+ result = ", ".join( code_result )
+ return result
+
+
+def min_workspace_call_type( name, properties, arg_map ):
+ result = None
+ if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+ code_result = []
+ for arg in properties[ 'assert_size_args' ]:
+ if arg_map.has_key( arg ):
+ code_result += [ call_level0_type( arg, arg_map[ arg ], arg_map ) ]
+ else:
+ code_result += [ '?' + arg.upper() ]
+
+ result = ", ".join( code_result )
+ return result
+
+
+def user_defined_type( name, properties, arg_map ):
+ result = None
+ if properties.has_key( 'user_defined' ):
+ result = properties[ 'user_defined' ]
+ return result
+
+
+
+#
+#
+#
+#
+def match_formulae( text_field ):
+ find_start = re.compile( '([A-Z]+)\s?(>=|is\sat\sleast)\s?(.*)the\scode\swill', re.M | re.S ).findall( text_field )
+ for element in find_start:
+ print element
+
+
+
+#
+# Split string using a list of delimiters
+# Delimiters may be substrings of length 1 or 2 (may be increased if necessary)
+#
+def split_delim( s, delim = [','] ):
+ result = []
+ parentheses = 0
+ cur_pos = 0
+ prev_pos = 0
+ for index in range( 0, len(s) ):
+ if s[ index ] == '(':
+ parentheses += 1
+ elif s[ index ] == ')':
+ parentheses -= 1
+ for length in range( 1, 3 ):
+ if index >= (length-1) and parentheses == 0:
+ c = s[ index-(length-1): index+1 ]
+ if c in delim:
+ result += [ s[ prev_pos:(index-(length-1)) ] ]
+ prev_pos = index+1
+
+ result += [ s[ prev_pos:len(s) ] ]
+ return result
+
+
+
+#
+# Look for implicit products, like 5N, and replace with 5*N
+#
+def replace_implicit_products( text_field ):
+ result = re.sub( '([0-9])+([A-Z]+)', '\\1*\\2', text_field )
+ return result
+
+
+
+
+def decompose_formula( text_field ):
+ text_field = text_field.strip()
+ print "Decompose: ", text_field
+
+ if text_field[0] == '(' and text_field[-1] == ')':
+ result = text_field[ 1:-1 ]
+ return [ '()', decompose_formula( result ) ]
+
+ if len( split_delim( text_field, [ ',' ] ) ) > 1:
+ print "ERROR! (in LAPACK?)"
+ return [ 'ERROR' ]
+
+ #
+ # Detect leaf: if text_field equals a argument (like N), or a number
+ #
+ if re.compile( '^([a-zA-Z]+|[0-9]+)$' ).match( text_field ):
+ print "decompose: at leaf: '" + text_field + "'"
+ return text_field.upper()
+
+
+ if len( split_delim( text_field, [ '**' ] ) ) > 1:
+ print 'decompose: inserting pow'
+ arguments = split_delim( text_field, [ '**' ] )
+ print arguments
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ return [ 'pow', result ]
+
+ for operator in [ '*', '/', '+', '-' ]:
+ if len( split_delim( text_field, [ operator ] ) ) > 1:
+ print 'decompose: inserting ' + operator
+ arguments = split_delim( text_field, operator )
+ print arguments
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ return [ operator, result ]
+
+
+ if (text_field[ 0:4 ] == 'max(' or text_field[ 0:4 ] == 'MAX(') and \
+ text_field[ -1 ] == ')':
+ print "decompose: inserting max"
+ arguments = split_delim( text_field[ 4:-1 ] )
+ print arguments, len(arguments)
+ # keep max a binary function ... :-)
+ if len( arguments ) > 2:
+ return [ 'max', [ decompose_formula( arguments[0] ), decompose_formula( 'max(' + ",".join( arguments[1:] ) + ')' ) ] ]
+ else:
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+ return [ 'max', result ]
+
+
+ if (text_field[ 0:4 ] == 'min(' or text_field[ 0:4 ] == 'MIN(') and \
+ text_field[ -1 ] == ')':
+ print "decompose: inserting min"
+ arguments = split_delim( text_field[ 4:-1 ] )
+ print arguments, len(arguments)
+ # keep max a binary function ... :-)
+ if len( arguments ) > 2:
+ return [ 'min', [ decompose_formula( arguments[0] ), decompose_formula( 'min(' + ",".join( arguments[1:] ) + ')' ) ] ]
+ else:
+ result = []
+ for arg in arguments:
+ result.append( decompose_formula( arg ) )
+ #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+ return [ 'min', result ]
+
+
+#
+#
+def match_assert_ge( argument_map, text_field ):
+ #print "Match assert GE..."
+ match_it = re.compile( ' +[A-Z]+[ ]{0,3}(>=|must be at least)[ ]{0,3}([0-9]|(min|max|MIN|MAX|[\(\)\,0-9A-Z\+\*\-])+)' ).findall( text_field )
+ if len( match_it ) == 1:
+ print "Match assert GE:", match_it
+ #print match_it
+ #if len( match_it[ 0 ][ 2 ] ) > 0:
+ return decompose_formula( match_it[ 0 ][ 1 ] )
+ else:
+ print "nr of matches: ", len( match_it )
+ return None
+
+
+
+
+
+# try different keys, return the one that exists, if any
+
+def my_has_key( key_name, template_map ):
+ # try, e.g., gelsd.all.
+ m_all_key = key_name.replace( ".complex", ".all" ).replace( ".real", ".all" )
+ if template_map.has_key( key_name ):
+ print "using key ", key_name
+ return key_name
+ if template_map.has_key( m_all_key ):
+ print "using key ", m_all_key
+ return m_all_key
+ print "tried keys ", key_name, "and", m_all_key,", no results"
+ return None
+
+
+
+#
+# Default user-defined arg is of type scalar INTEGER
+#
+def add_user_defined_args( arg, argument_map, template_map, base_name ):
+ print "Trying to add user-defined argument definitions for", arg
+
+ argument_map[ arg ] = {}
+
+ base_key = base_name.lower() + '.' + arg
+ print "base_key",base_key
+
+ if my_has_key( base_key + '.value_type', template_map ) != None:
+ argument_map[ arg ][ 'value_type' ] = template_map[ my_has_key( base_key + '.value_type', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'value_type' ] = 'INTEGER'
+
+ if my_has_key( base_key + '.type', template_map ) != None:
+ argument_map[ arg ][ 'type' ] = template_map[ my_has_key( base_key + '.type', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'type' ] = 'scalar'
+
+ if my_has_key( base_key + '.init', template_map ) != None:
+ argument_map[ arg ][ 'user_defined' ] = template_map[ my_has_key( base_key + '.init', template_map ) ].strip()
+ else:
+ argument_map[ arg ][ 'user_defined' ] = 'UNDEFINED'
+
+ argument_map[ arg ][ 'io' ] = [ 'input' ]
+
+ return
+
+
+
+
+
+
+
+#
+# Parse a LAPACK file
+# input: filename
+# output: a pair of ( function name, map )
+# the map contains:
+# 'arguments': an array of arguments
+# 'argument_map': a map of ( argument_name, property ),
+# in which property can be
+# 'type': Fortran type
+# 'cpptype': C++ type
+# 'io': the (input/output) part from the comment section
+#
+def parse_file( filename, template_map ):
+
+ # for nice printing
+ pp = pprint.PrettyPrinter( indent = 2 )
+
+ # read the entire fortran source file
+ source = open( filename ).read()
+
+ # parse and split the code
+ # * merge multilines to one line (using the $ and + characters)
+ # * split comments-blocks and code blocks
+ # * remove '*' from comments
+ # input: full source code
+ # output: an array of lines of code
+ # an array of lines of comments
+ code = []
+ comments = []
+ for i in source.splitlines():
+
+ # Special case: in e.g. CHEEVR comments are lead by many stars instead of 1
+ # replace those (more than 1) with spaces so that it becomes a regular comment
+ # block.
+ leading_stars = re.compile( '^[ ]*\*(\*+)' ).match( i )
+ if leading_stars != None:
+ spaces = i[ leading_stars.start(1):leading_stars.end(1) ].replace( '*', ' ' )
+ i = i[0:leading_stars.start(1)] + spaces + \
+ i[leading_stars.end(1):len(i)]
+
+ # Continue for the regular case
+ match_comment = re.compile( '^[ ]*\*(.*)' ).search( i )
+ if match_comment == None:
+ match_multi = re.compile( '^[ ]*[\$\+][ ]*(.*)$' ).search( i )
+ if match_multi == None:
+ code += [ i ]
+ else:
+ code[-1 ] += match_multi.expand( "\\1" )
+ else:
+ comments += [ match_comment.expand( "\\1" ) ]
+
+ # Acquire important information
+ # * the subroutine name
+ # * the arguments of the subroutine
+ subroutine_found = False
+ subroutine_name = ''
+ subroutine_arguments = []
+ 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 ] )
+ if match_subroutine_name != None:
+ subroutine_found = True
+ subroutine_name = match_subroutine_name.group( 1 )
+ subroutine_arguments = match_subroutine_name.group( 2 ).replace( ' ', '' ).split( "," )
+ code_line_nr += 1
+
+ # If we could not find a subroutine, we quit at our earliest convenience
+ if code_line_nr == len(code):
+ return None, None
+
+ #
+ # Do some further analysis as to what kind of routine this is
+ #
+ subroutine_group_name = subroutine_name[ 1: ]
+ subroutine_value_type = None
+ if subroutine_name[0] == 'C' or subroutine_name[0] == 'Z':
+ subroutine_value_type = 'complex'
+ if subroutine_name[0] == 'S' or subroutine_name[0] == 'D':
+ subroutine_value_type = 'real'
+
+ print "Subroutine: ", subroutine_name
+ print "Arguments: ", len(subroutine_arguments),":",subroutine_arguments
+ print "Group name: ", subroutine_group_name
+ print "Variant: ", subroutine_value_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
+ # INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
+ # COMPLEX A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
+ # into a map containing
+ # INFO: value_type=INTEGER, type=scalar
+ # WORK: value_type=COMPLEX, type=vector
+ # A: value_type=COMPLEX, type=matrix, leading_dimension=LDA
+ # etc.
+ arguments_found = False
+ argument_map = {}
+ while code_line_nr < len(code) and len( argument_map ) < len( subroutine_arguments ):
+ match_argument_declaration = re.compile( '^[ ]*(EXTERNAL|LOGICAL|CHARACTER|REAL|INTEGER' + \
+ '|DOUBLE PRECISION|DOUBLE COMPLEX|COMPLEX\*16|COMPLEX)[ ]+(.*)$' ).search( code[ code_line_nr] )
+ if match_argument_declaration != None:
+ for argument_match in re.findall( '([A-Z0-9]+(\([^\)]+\))?)[, ]?', match_argument_declaration.group( 2 ) ):
+ argument_description = argument_match[0].strip().split( "(" )
+ argument_name = argument_description[0]
+ argument_map[ argument_name ] = {}
+ argument_map[ argument_name ][ 'value_type' ] = match_argument_declaration.group( 1 )
+ if len(argument_description) == 1:
+ argument_map[ argument_name ][ 'type' ] = 'scalar'
+ else:
+ if argument_description[1].find( "," ) == -1:
+ argument_map[ argument_name ][ 'type' ] = 'vector'
+ else:
+ argument_map[ argument_name ][ 'type' ] = 'matrix'
+ # check if there is a leading dimension
+ argument_map[ argument_name ][ 'leading_dimension' ] = argument_description[1].split( "," )[0].strip()
+ code_line_nr += 1
+
+ # Create convenience lookups by value_type and types of arguments
+ # e.g., grouped_arguments[ 'by_value_type' ][ 'INTEGER' ] will give an array of all integer types
+ # grouped_arguments[ 'by_type' ][ 'matrix' ] will give an array of all matrices
+ grouped_arguments = {}
+ key_array = [ 'type', 'value_type' ]
+ for s in key_array:
+ grouped_arguments[ 'by_' + s ] = {}
+ # make sure the order of argument names is the same as those in the subroutine argument order
+ for argument_name in subroutine_arguments:
+ argument_properties = argument_map[ argument_name ]
+ for s in key_array:
+ if not grouped_arguments[ 'by_' + s ].has_key( argument_properties[ s ] ):
+ grouped_arguments[ 'by_' + s ][ argument_properties[ s ] ] = []
+ grouped_arguments[ 'by_' + s ][ argument_properties[ s ] ] += [ argument_name ]
+
+ # 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.
+ comment_line_nr = 0
+ purpose_line_nr = -1
+ arguments_line_nr = -1
+ while comment_line_nr < len(comments) and purpose_line_nr == -1:
+ if re.compile( '^[ ]+Purpose[ ]*$' ).search( comments[ comment_line_nr ] ) != None:
+ purpose_line_nr = comment_line_nr
+ comment_line_nr += 1
+
+ while comment_line_nr < len(comments) and arguments_line_nr == -1:
+ if re.compile( '^[ ]+Arguments[ ]*$' ).search( comments[ comment_line_nr ] ) != None:
+ arguments_line_nr = comment_line_nr
+ comment_line_nr += 1
+
+ # Gather the actual subroutine purpose. This is always following the Purpose title (obvious :-))
+ # and stopping before the "Arguments" block.
+ subroutine_purpose = ''
+ if purpose_line_nr > 0 and arguments_line_nr > 0:
+ subroutine_purpose = "//" + "\n//".join( comments[ purpose_line_nr+3:arguments_line_nr-1 ] )
+
+ # Break up the comments
+ # Now, for each argument, locate its associated comment field
+ #
+ # In this case, for M, we store the range [45, 48>
+ no_commented_arguments = 0
+ if arguments_line_nr > 0:
+ preceding_argument = ''
+ finished_the_last = False
+ detected_lapack_style = False
+ detected_blas_style = False
+ while comment_line_nr < len(comments) and not finished_the_last:
+
+ # Example for LAPACK-style matching.
+ # 45 M (input) INTEGER
+ # 46 The number of rows of the matrix A. M >= 0.
+ # 47
+ # 48 N (input) INTEGER
+ match_lapack_style = re.compile( '^[\s]*([A-Z]+[2]?)[\s]+\(([a-z/ ]+)\)' ).search( comments[ comment_line_nr ] )
+ if not detected_blas_style and match_lapack_style != None:
+ detected_lapack_style = True
+ argument_name = match_lapack_style.group(1)
+ 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) )
+ if preceding_argument != '':
+ argument_map[ preceding_argument ][ 'comment_lines' ] += [ comment_line_nr ]
+ preceding_argument = argument_name
+ no_commented_arguments += 1
+
+ # Example for BLAS, which doesn't mention input/output on the same line
+ # 37 N - INTEGER.
+ # 38 On entry, N specifies the order of the matrix A.
+ # 39 N must be at least zero.
+ # 40 Unchanged on exit.
+ match_blas_style = re.compile( '^[\s]*([A-Z]+[2]?)[\s]+\- [A-Z]+' ).search( comments[comment_line_nr] )
+ if not detected_lapack_style and match_blas_style != None:
+ detected_blas_style = True
+ argument_name = match_blas_style.group(1)
+ argument_map[ argument_name ][ 'comment_lines' ] = [ comment_line_nr ]
+ # default input/output with blas to output, this will be overwritten if "unchanged on exit" is
+ # found
+ argument_map[ argument_name ][ 'io' ] = [ 'output' ]
+ if preceding_argument != '':
+ argument_map[ preceding_argument ][ 'comment_lines' ] += [ comment_line_nr ]
+ preceding_argument = argument_name
+ no_commented_arguments += 1
+
+ # Detection for BLAS' "input" statement
+ match_unchanged_on_exit = re.compile( '^[\s]*[uU]nchanged on exit' ).search( comments[comment_line_nr] )
+ if detected_blas_style and match_unchanged_on_exit != None:
+ argument_map[ preceding_argument ][ 'io' ] = [ 'input' ]
+
+ # INFO comes last, so detect an empty line for this case
+ if no_commented_arguments == len( subroutine_arguments ) and \
+ len( argument_map[ preceding_argument ][ 'comment_lines' ] ) < 2:
+ match_empty_line = re.compile( '^[ ]*$' ).search( comments[ comment_line_nr ] )
+ if match_empty_line != None:
+ argument_map[ preceding_argument ][ 'comment_lines' ] += [ comment_line_nr + 1 ]
+ finished_the_last = True
+
+ comment_line_nr += 1
+
+ # Inform the debug.log / user which comment style we employed
+ if ( detected_lapack_style ):
+ print "Argument comment style: LAPACK"
+ elif ( detected_blas_style ):
+ print "Argument comment style: BLAS"
+
+ #
+ # TODO
+ # TODO
+ # TODO
+ #
+ if no_commented_arguments != len( subroutine_arguments ):
+ print str(no_commented_arguments) + " out of " + str(len(subroutine_arguments)) + \
+ " arguments are commented, bailing out"
+ return subroutine_name, None
+
+ #
+ # Make a back-reference to those arguments that are defined as leading dimension in the code
+ #
+ for argument_name, argument_properties in argument_map.iteritems():
+ if argument_properties.has_key( 'leading_dimension' ):
+ referring_argument_name = argument_properties[ 'leading_dimension' ]
+ if argument_map.has_key( referring_argument_name ):
+ argument_map[ referring_argument_name ][ 'trait_type' ] = 'lda'
+ argument_map[ referring_argument_name ][ 'trait_of' ] = argument_name
+
+ # Extend convenience lookups by io, recently acquired when processing the comment
+ # fields. We have to be sure arguments are processed in the right order.
+ grouped_arguments[ 'by_io' ] = {}
+ for argument_name in subroutine_arguments:
+ argument_properties = argument_map[ argument_name ]
+ print argument_name, argument_properties
+ for io_type in argument_properties[ 'io' ]:
+ if not grouped_arguments[ 'by_io' ].has_key( io_type ):
+ grouped_arguments[ 'by_io' ][ io_type ] = []
+ grouped_arguments[ 'by_io' ][ io_type ] += [ argument_name ]
+
+ #
+ # Parse the comment fields
+ #
+ user_defined_arg_map = {}
+ for argument_name, argument_properties in argument_map.iteritems():
+
+ print "\n\n**********"
+ print argument_name
+ comment_block = "\n".join( comments[ argument_properties[ 'comment_lines' ][0] : argument_properties[ 'comment_lines' ][1] ] )
+ print comment_block
+ match_formulae( comment_block )
+
+ #
+ # Handle scalar INTEGER comment blocks. Look for type traits stuff.
+ #
+ if argument_properties[ 'type' ] == 'scalar' and \
+ argument_properties[ 'value_type' ] == 'INTEGER':
+ #
+ # Fetch matrix traits such as "the number of columns of A"
+ #
+ match_matrix_traits = re.compile( '(rows|columns|order)(in|of|the|input|\s)+(matrix|matrices|\s)+' + \
+ '([A-Z]+\s+and\s+[A-Z]+|[A-Z]+)', re.M | re.S ).findall( comment_block )
+ if len( match_matrix_traits ) == 1:
+ if match_matrix_traits[0][0] == 'order':
+ # PANIC: return none
+ # e.g., in tridiagonal case, there is no matrix, but a number of
+ # vectors (the diagonals)
+ if not grouped_arguments[ 'by_type' ].has_key( 'matrix' ):
+ # TODO
+ # TODO
+ return subroutine_name, None
+ # TODO
+ # TODO
+ if match_matrix_traits[0][3] in grouped_arguments[ 'by_type' ][ 'matrix' ]:
+ # because it is both #rows and #columns, we have to choose one
+ argument_properties[ 'trait_type' ] = 'num_columns'
+ argument_properties[ 'trait_of' ] = match_matrix_traits[0][3].strip()
+
+ # see if the traits are overruled through the template system
+ traits_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.' + argument_name + '.trait_of'
+ if my_has_key( traits_key, template_map ):
+ argument_properties[ 'trait_type' ] = 'num_columns'
+ argument_properties[ 'trait_of' ] = template_map[ my_has_key( traits_key, template_map ) ].strip()
+
+ else:
+ references = match_matrix_traits[0][3].split( 'and' )
+ for matrix_name in references:
+ if matrix_name.strip() in grouped_arguments[ 'by_type' ][ 'matrix' ]:
+ argument_properties[ 'trait_type' ] = 'num_' + match_matrix_traits[0][0]
+ argument_properties[ 'trait_of' ] = matrix_name.strip()
+
+ #
+ # Fetch array traits, such as "the length of the array WORK"
+ #
+ match_array_traits = re.compile( '(The length|The dimension)(of|the|\s)+(array|\s)+([A-Z]+)', re.M | re.S ).findall( comment_block )
+ if len( match_array_traits ) > 0 and match_array_traits[ 0 ][ 3 ] in grouped_arguments[ 'by_type' ][ 'vector' ]:
+ argument_properties[ 'trait_type' ] = 'size'
+ argument_properties[ 'trait_of' ] = match_array_traits[ 0 ][ 3 ]
+
+ # Fetch greater-than-or-equal-to integer asserts, such as
+ # M >= 0.
+ # N >= max(...)
+ match_greater_equal = match_assert_ge( argument_map, comment_block )
+ if match_greater_equal != None:
+ argument_properties[ 'assert_ge' ] = match_greater_equal
+
+ # Are we dealing with a workspace-length integer?
+ # If so, try to detect the workspace-query text.
+ # And, try to detect for which work arrays the query will run.
+ # Keep the same order of workspace names as used in the grouped arguments map
+ if 'WORK' in argument_name:
+ match_query = re.compile( 'If ' + argument_name + ' \= \-1(\,|then|a|workspace|\s)+query', re.M ).search( comment_block )
+ if match_query != None:
+ work_query_block = comment_block[ match_query.start(0): ]
+ any_workspace = "(" + "|".join( grouped_arguments[ 'by_io' ][ 'workspace' ] ) + ")"
+ match_workspace = re.compile( '[^A-Z]' + any_workspace, re.M | re.S ).findall( work_query_block )
+ if len( match_workspace ) > 0:
+ argument_properties[ 'workspace_query_for' ] = []
+ for name in grouped_arguments[ 'by_io' ][ 'workspace' ]:
+ if name in match_workspace:
+ argument_properties[ 'workspace_query_for' ] += [ name ]
+
+ #
+ # Handle CHARACTER comment blocks.
+ # Try to get which variables are valid, to put this in asserts.
+ #
+ elif argument_properties[ 'value_type' ] == 'CHARACTER':
+ match_statements = re.compile( '=(\s|or|\'[0-9A-Z]\')+[:,]', re.M ).finditer( comment_block )
+ for statement in match_statements:
+ print "Statement:",statement.group(0)
+ match_letters = re.compile( '\'([0-9A-Z])\'' ).findall( statement.group(0) )
+ for letter in match_letters:
+ print "Letter",letter
+ if not argument_properties.has_key( 'assert_char' ):
+ argument_properties[ 'assert_char' ] = []
+ if not letter in argument_properties[ 'assert_char' ]:
+ argument_properties[ 'assert_char' ] += [ letter ]
+
+ if argument_name == 'UPLO':
+ match_uplo = re.compile( '(Upper|Lower)(triangle|triangles|of|input|matrix|\s)+([A-Z]+)' ).findall( comment_block )
+ if len( match_uplo ) == 2 and len( argument_properties[ 'assert_char' ] ) == 2 and \
+ 'U' in argument_properties[ 'assert_char' ] and 'L' in argument_properties[ 'assert_char' ]:
+ print "adding uplo trait"
+ argument_properties[ 'trait_type' ] = 'uplo'
+ argument_properties[ 'trait_of' ] = match_uplo[ 0 ][ 2 ]
+
+ # see if the traits are overruled through the template system
+ traits_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.' + argument_name + '.trait_of'
+ if my_has_key( traits_key, template_map ):
+ argument_properties[ 'trait_of' ] = template_map[ my_has_key( traits_key, template_map ) ].strip()
+
+ #
+ # Minimal workspace dimension recognition
+ #
+ elif argument_properties[ 'type' ] == 'vector':
+ # usually this text is
+ # 1) dimension (...) without spaces in the formula
+ # 2) dimension at least ... (e.g., RWORK IN CLALSA)
+ match_dim = re.compile( 'dimension \((.+)\)' ).findall( comment_block )
+ print "Matches on dimension(): ", len( match_dim )
+ for d in match_dim:
+ d = d.replace( ' ', '' )
+ #
+ # TODO
+ # make some sensible rules here
+ #
+ match_unwanted_text = re.compile( '\s([Ii]f|[Ww]hen)\s' ).findall( comment_block )
+ print match_unwanted_text
+ if len( match_unwanted_text ) == 0:
+ argument_properties[ 'assert_size' ] = decompose_formula( replace_implicit_products( d ) )
+ argument_properties[ 'assert_size_args' ] = nested_list_args( argument_properties[ 'assert_size' ] )
+
+ # assert_size_args determines the arguments of min_size function for this
+ # workspace array. But, this gets overruled by user-defined templates.
+ if 'workspace' in argument_properties[ 'io' ]:
+ args_string = None
+ template_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.min_size_' + argument_name.lower() + '.args'
+ if my_has_key( template_key, template_map ) != None:
+ args_string = template_map[ my_has_key( template_key, template_map ) ]
+ tmp_result = []
+ for arg in args_string.split( "," ):
+ tmp_result.append( arg.strip().upper() )
+ if tmp_result == ['']:
+ tmp_result = []
+
+ 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 )
+
+ argument_properties[ 'assert_size_args' ] = tmp_result
+ print "Using user-defined assert_size_args: ", tmp_result
+
+ #
+ # Try to detect packed strorage stuff. Typically these are vectors in Fortran, but
+ # matrices in our bindings. E.g. as used in spsv.
+ #
+ packed_keywords = re.compile( '(/s|packed|matrix)+', re.M ).findall( comment_block )
+ if 'matrix' in packed_keywords and 'packed' in packed_keywords:
+ #
+ # Overrule my type :-)
+ #
+ argument_properties[ 'type' ] = 'matrix'
+
+ #
+ # Add user-defined arguments to the argument_map
+ #
+ argument_map.update( user_defined_arg_map )
+
+
+ print "Argument map: "
+ pp.pprint( argument_map )
+
+
+ #
+ # Make a back-reference for workspace queries
+ #
+ for argument_name, argument_properties in argument_map.iteritems():
+ if argument_properties.has_key( 'workspace_query_for' ):
+ for referring_argument_name in argument_properties[ 'workspace_query_for' ]:
+ if argument_map.has_key( referring_argument_name ):
+ if not argument_map[ referring_argument_name ].has_key( 'workspace_query_by' ):
+ argument_map[ referring_argument_name ][ 'workspace_query_by' ] = []
+ argument_map[ referring_argument_name ][ 'workspace_query_by' ] += [ argument_name ]
+
+
+ #
+ # Generate the actual C++ code statements, based on information acquired so far.
+ #
+ # pass 1
+ for argument_name, argument_properties in argument_map.iteritems():
+ argument_properties[ 'code' ] = {}
+ argument_properties[ 'code' ][ 'lapack_h' ] = c_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'call_c_header' ] = call_c_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'level_0' ] = cpp_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'call_level_0' ] = call_level0_type( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'level_1' ] = level1_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'level_1_type' ] = level1_typename( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'call_level_1' ] = call_level1_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'level_2' ] = level2_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'workspace_type' ] = workspace_type( argument_name, argument_properties )
+
+ # Pass 2
+ # A second pass is needed, because the asserts may cross-reference other
+ # variables which have been assigned their code in pass 1.
+ for argument_name, argument_properties in argument_map.iteritems():
+ argument_properties[ 'code' ][ 'level_1_assert' ] = level1_assert( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'opt_workspace_query' ] = opt_workspace_query_type( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'opt_workspace_pre' ] = opt_workspace_pre_type( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'opt_workspace_post' ] = opt_workspace_post_type( argument_name, argument_properties )
+ argument_properties[ 'code' ][ 'min_workspace' ] = min_workspace_size_type( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'min_workspace_args' ] = min_workspace_arg_type( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'min_workspace_call' ] = min_workspace_call_type( argument_name, argument_properties, argument_map )
+ argument_properties[ 'code' ][ 'user_defined_init' ] = user_defined_type( argument_name, argument_properties, argument_map )
+
+ print "Argument map: "
+ pp.pprint( argument_map )
+
+ print "Grouped arguments: "
+ pp.pprint( grouped_arguments )
+
+ #
+ # create a dict object
+ #
+ info_map = {}
+ info_map[ 'arguments' ] = subroutine_arguments
+ info_map[ 'purpose' ] = subroutine_purpose
+ info_map[ 'argument_map' ] = argument_map
+ info_map[ 'grouped_arguments' ] = grouped_arguments
+
+ #
+ # Pass / check user-defined stuff right here.
+ #
+ user_def_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.extra_variables'
+ if my_has_key( user_def_key, template_map ) != None:
+ user_vars = template_map[ my_has_key( user_def_key, template_map ) ].split( "," )
+ tmp_result = []
+ for v in user_vars:
+ tmp_result.append( v.strip().upper() )
+ info_map[ 'user_defined_variables' ] = tmp_result
+ else:
+ info_map[ 'user_defined_variables' ] = None
+
+ #
+ # Pass / check user-defined stuff right here.
+ # OPTIMAL CASE (may contain fewer variables)
+ #
+ user_def_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.extra_opt_variables'
+ if my_has_key( user_def_key, template_map ) != None:
+ user_vars = template_map[ my_has_key( user_def_key, template_map ) ].split( "," )
+ tmp_result = []
+ for v in user_vars:
+ tmp_result.append( v.strip().upper() )
+ info_map[ 'user_defined_opt_variables' ] = tmp_result
+ else:
+ info_map[ 'user_defined_opt_variables' ] = None
+
+
+ #subroutine_description.replace( subroutine_name, subroutine_name[ 1: ] )
+ #info_map[ 'description' ] = subroutine_description
+
+ return subroutine_name, info_map
+
+

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,57 @@
+$TEMPLATE[blas.hpp]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_BLAS_$GROUPNAME_HPP
+#define BOOST_NUMERIC_BINDINGS_BLAS_$GROUPNAME_HPP
+
+$INCLUDES
+
+namespace boost {
+namespace numeric {
+namespace bindings {
+namespace blas {
+
+//$DESCRIPTION
+
+// overloaded functions to call blas
+namespace detail {
+$OVERLOADS}
+
+$LEVEL1
+
+}}}} // namespace boost::numeric::bindings::blas
+
+#endif
+$TEMPLATE[blas_overloads]
+ inline void $groupname( $LEVEL0 ) {
+ BLAS_$SUBROUTINE( $CALL_C_HEADER );
+ }
+$TEMPLATE[blas_level1]
+// value-type based template
+template< typename ValueType >
+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 );
+ }
+};
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsdc.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsdc.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[bdsdc.real.min_size_work.args]
+COMPQ, N
+$TEMPLATE[bdsdc.real.min_size_work]
+switch ( compq ) {
+ case 'N': return 4*n;
+ case 'P': return 6*n;
+ case 'I': return 3*n*n + 4*n;
+}
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsqr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsqr.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,15 @@
+$TEMPLATE[bdsqr.all.min_size_work.args]
+N,NCVT,NRU,NCC
+$TEMPLATE[bdsqr.real.min_size_work]
+if ( ncvt == 0 && nru == 0 && ncc == 0 )
+ return 2*n;
+else
+ return std::max(1, 4*n);
+$TEMPLATE[bdsqr.complex.min_size_rwork.args]
+N,NCVT,NRU,NCC
+$TEMPLATE[bdsqr.complex.min_size_rwork]
+if ( ncvt == 0 && nru == 0 && ncc == 0 )
+ return 2*n;
+else
+ return std::max(1, 4*n-4);
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gebrd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gebrd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[gebrd.all.min_size_work.args]
+M,N
+$TEMPLATE[gebrd.all.min_size_work]
+return std::max( 1, std::max( m, n ) );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gelqf.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gelqf.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,13 @@
+$TEMPLATE[gelqf.all.min_size_work.args]
+M
+$TEMPLATE[gelqf.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[geqlf.all.min_size_work.args]
+N
+$TEMPLATE[geqlf.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[getri.all.min_size_work.args]
+N
+$TEMPLATE[getri.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hetr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hetr.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,7 @@
+$TEMPLATE[hetrd.all.min_size_work.args]
+$TEMPLATE[hetrd.all.min_size_work]
+return 1;
+$TEMPLATE[hetrf.all.min_size_work.args]
+$TEMPLATE[hetrf.all.min_size_work]
+return 1;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hgeqz.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hgeqz.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hgeqz.all.min_size_work.args]
+N
+$TEMPLATE[hgeqz.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/larz.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/larz.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[larz.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[larz.all.min_size_work]
+if ( side == 'L' )
+ return n;
+else
+ return m;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/opmtr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/opmtr.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[opmtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[opmtr.all.min_size_work]
+if ( side == 'L' )
+ return n;
+else
+ return m;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/org.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/org.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,25 @@
+$TEMPLATE[orgbr.all.min_size_work.args]
+M,N
+$TEMPLATE[orgbr.all.min_size_work]
+return std::max( 1, std::min( m, n );
+$TEMPLATE[orglq.all.min_size_work.args]
+M
+$TEMPLATE[orglq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[orgrq.all.min_size_work.args]
+M
+$TEMPLATE[orgrq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[orgql.all.min_size_work.args]
+N
+$TEMPLATE[orgql.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[orgqr.all.min_size_work.args]
+N
+$TEMPLATE[orgqr.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[orgtr.all.min_size_work.args]
+N
+$TEMPLATE[orgtr.all.min_size_work]
+return std::max( 1, n-1 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/orm.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/orm.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,50 @@
+$TEMPLATE[ormbr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormbr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[ormlq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormlq.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[ormqr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormqr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[ormrq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormrq.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[ormtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormtr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[ormql.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormql.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[ormhr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormhr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stedc.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stedc.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[stedc.all.min_size_iwork.args]
+COMPZ,N
+$TEMPLATE[stedc.all.min_size_iwork]
+// some formula
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/un.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/un.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,77 @@
+$TEMPLATE[ungbr.all.min_size_work.args]
+M,N
+$TEMPLATE[ungbr.all.min_size_work]
+return std::max( 1, std::min( m, n ) );
+$TEMPLATE[ungql.all.min_size_work.args]
+N
+$TEMPLATE[ungql.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[ungqr.all.min_size_work.args]
+N
+$TEMPLATE[ungqr.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[unglq.all.min_size_work.args]
+M
+$TEMPLATE[unglq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[ungrq.all.min_size_work.args]
+M
+$TEMPLATE[ungrq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[ungtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ungtr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmbr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmbr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmhr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmhr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmlq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmlq.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmqr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmqr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmrq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmrq.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmql.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmql.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[unmtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmtr.all.min_size_work]
+if ( side == 'L' )
+ return std::max( 1, n );
+else
+ return std::max( 1, m );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/cgesv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/cgesv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[cgesv.complex.min_size_work.args]
+N, NRHS
+$TEMPLATE[cgesv.complex.min_size_work]
+return n*nrhs;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[gbsv.all.N.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,13 @@
+$TEMPLATE[gbsvx.real.min_size_iwork.args]
+N
+$TEMPLATE[gbsvx.real.min_size_iwork]
+return n;
+$TEMPLATE[gbsvx.real.min_size_work.args]
+N
+$TEMPLATE[gbsvx.real.min_size_work]
+return 3*n;
+$TEMPLATE[gbsvx.complex.min_size_rwork.args]
+N
+$TEMPLATE[gbsvx.complex.min_size_rwork]
+return n;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gees.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gees.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,16 @@
+$TEMPLATE[gees.real.min_size_work.args]
+N
+$TEMPLATE[gees.real.min_size_work]
+return std::max( 1, 3*n );
+$TEMPLATE[gees.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[gees.all.min_size_bwork]
+if ( sort == 'N' )
+ return 0;
+else
+ return n;
+$TEMPLATE[gees.complex.min_size_work.args]
+N
+$TEMPLATE[gees.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geesx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geesx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,27 @@
+$TEMPLATE[geesx.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[geesx.all.min_size_bwork]
+if ( sort == 'N' )
+ return 0;
+else
+ return n;
+$TEMPLATE[geesx.real.min_size_iwork.args]
+N, SENSE
+$TEMPLATE[geesx.real.min_size_iwork]
+if ( sense == 'N' || sense == 'E' )
+ return 1;
+else
+ return std::max( 1, n*n/4 );
+$TEMPLATE[geesx.all.min_size_work.args]
+N, SENSE
+$TEMPLATE[geesx.real.min_size_work]
+if ( sense == 'N' )
+ return std::max( 1, 3*n );
+else
+ return std::max( 1, n+n*n/2 );
+$TEMPLATE[geesx.complex.min_size_work]
+if ( sense == 'N' )
+ return std::max( 1, 2*n );
+else
+ return std::max( 1, n*n/2 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,12 @@
+$TEMPLATE[geev.real.min_size_work.args]
+JOBVL,JOBVR,N
+$TEMPLATE[geev.real.min_size_work]
+if ( jobvl == 'V' || jobvr == 'V' )
+ return std::max( 1, 4*n );
+else
+ return std::max( 1, 3*n );
+$TEMPLATE[geev.complex.min_size_work.args]
+N
+$TEMPLATE[geev.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,25 @@
+$TEMPLATE[geevx.real.min_size_iwork.args]
+SENSE,N
+$TEMPLATE[geevx.real.min_size_iwork]
+if ( sense == 'N' || sense == 'E' )
+ return 0;
+else
+ return 2*n-2;
+$TEMPLATE[geevx.real.min_size_work.args]
+SENSE,JOBVL,JOBVR,N
+$TEMPLATE[geevx.real.min_size_work]
+if ( sense == 'N' || sense == 'E' ) {
+ if ( jobvl =='V' || jobvr == 'V' )
+ return std::max( 1, 3*n );
+ else
+ return std::max( 1, 2*n );
+} else
+ return std::max( 1, n*(n+6) );
+$TEMPLATE[geevx.complex.min_size_work.args]
+SENSE,N
+$TEMPLATE[geevx.complex.min_size_work]
+if ( sense == 'N' || sense == 'E' )
+ return std::max( 1, 2*n );
+else
+ return std::max( 1, n*n + 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gegv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gegv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[gegv.real.min_size_work.args]
+N
+$TEMPLATE[gegv.real.min_size_work]
+return std::max( 1, 8*n );
+$TEMPLATE[gegv.complex.min_size_work.args]
+N
+$TEMPLATE[gegv.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gels.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gels.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,6 @@
+$TEMPLATE[gels.all.min_size_work.args]
+M,N,NRHS
+$TEMPLATE[gels.all.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, minmn + std::max( minmn, nrhs ) );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,29 @@
+$TEMPLATE[gelsd.includes]
+#include <boost/numeric/bindings/lapack/auxiliary/ilaenv.hpp>
+$TEMPLATE[gelsd.complex.min_size_rwork.args]
+MINMN,SMLSIZ,NLVL,NRHS
+$TEMPLATE[gelsd.all.extra_variables]
+MINMN,SMLSIZ,NLVL
+$TEMPLATE[gelsd.all.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gelsd.all.SMLSIZ.init]
+integer_t smlsiz = ilaenv(9, "GELSD", "");
+$TEMPLATE[gelsd.all.NLVL.init]
+integer_t nlvl = static_cast<integer_t>(((std::log(static_cast<real_type>(minmn)) / std::log(static_cast<real_type>(2.))) / (smlsiz+1)) + 1);
+$TEMPLATE[gelsd.complex.min_size_rwork]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return std::max( 1, 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + smlsiz_plus_one * smlsiz_plus_one );
+$TEMPLATE[gelsd.complex.min_size_work.args]
+MINMN, NRHS
+$TEMPLATE[gelsd.complex.min_size_work]
+return std::max( 1, 2*minmn + minmn*nrhs );
+$TEMPLATE[gelsd.all.min_size_iwork.args]
+MINMN,NLVL
+$TEMPLATE[gelsd.all.min_size_iwork]
+return std::max( 1, 3*minmn*nlvl + 11*minmn );
+$TEMPLATE[gelsd.real.min_size_work.args]
+MINMN,SMLSIZ, NLVL, NRHS
+$TEMPLATE[gelsd.real.min_size_work]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return std::max( 1, 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + smlsiz_plus_one * smlsiz_plus_one );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelss.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelss.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,20 @@
+$TEMPLATE[gelss.real.min_size_work.args]
+M,N,NRHS
+$TEMPLATE[gelss.real.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, 3*minmn + std::max( std::max( 2*minmn, std::max(m,n) ), nrhs ) );
+$TEMPLATE[gelss.complex.extra_variables]
+MINMN
+$TEMPLATE[gelss.complex.extra_opt_variables]
+MINMN
+$TEMPLATE[gelss.complex.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gelss.complex.min_size_work.args]
+M,N,NRHS,MINMN
+$TEMPLATE[gelss.complex.min_size_work]
+return std::max( 1, 2*minmn + std::max( std::max( m,n ), nrhs ) );
+$TEMPLATE[gelss.complex.min_size_rwork.args]
+MINMN
+$TEMPLATE[gelss.complex.min_size_rwork]
+return 5*minmn;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsy.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsy.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[gelsy.all.min_size_work.args]
+M,N,NRHS
+$TEMPLATE[gelsy.real.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, std::max( minmn+3*n+1, 2*minmn+nrhs ));
+$TEMPLATE[gelsy.complex.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, std::max( std::max( 2*minmn, n+1 ), minmn+nrhs ) );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesdd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesdd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,28 @@
+$TEMPLATE[gesdd.all.extra_variables]
+MINMN
+$TEMPLATE[gesdd.all.extra_opt_variables]
+MINMN
+$TEMPLATE[gesdd.all.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gesdd.all.min_size_work.args]
+M, N, JOBZ, MINMN
+$TEMPLATE[gesdd.real.min_size_work]
+if ( n == 0 ) return 1;
+if ( jobz == 'N' ) return 3*minmn + std::max( std::max(m,n), 7*minmn );
+if ( jobz == 'O' ) return 3*minmn*minmn + std::max( std::max( m,n ), 5*minmn*minmn + 4*minmn );
+return 3*minmn*minmn + std::max( std::max( m,n ), 4*minmn*minmn + 4*minmn );
+$TEMPLATE[gesdd.complex.min_size_work]
+if ( n == 0 ) return 1;
+if ( jobz == 'N' ) return 2*minmn + std::max( m,n );
+if ( jobz == 'O' ) return 2*(minmn*minmn + minmn) + std::max( m, n );
+return minmn*minmn + 2*minmn + std::max( m, n );
+$TEMPLATE[gesdd.all.min_size_iwork.args]
+MINMN
+$TEMPLATE[gesdd.all.min_size_iwork]
+ return 8*minmn;
+$TEMPLATE[gesdd.complex.min_size_rwork.args]
+MINMN, JOBZ
+$TEMPLATE[gesdd.complex.min_size_rwork]
+if ( jobz == 'N' ) return 5*minmn;
+return 5*minmn*minmn + 7*minmn;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,20 @@
+$TEMPLATE[gesvd.real.min_size_work.args]
+M,N
+$TEMPLATE[gesvd.real.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, std::max( 3*minmn+std::max(m,n), 5*minmn ) );
+$TEMPLATE[gesvd.complex.extra_variables]
+MINMN
+$TEMPLATE[gesvd.complex.extra_opt_variables]
+MINMN
+$TEMPLATE[gesvd.complex.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gesvd.complex.min_size_work.args]
+M,N,MINMN
+$TEMPLATE[gesvd.complex.min_size_work]
+return std::max( 1, 2*minmn+std::max(m,n) );
+$TEMPLATE[gesvd.complex.min_size_rwork.args]
+MINMN
+$TEMPLATE[gesvd.complex.min_size_rwork]
+return 5*minmn;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[gesvx.real.min_size_work.args]
+N
+$TEMPLATE[gesvx.real.min_size_work]
+return 4*n;
+$TEMPLATE[gesvx.complex.min_size_rwork.args]
+N
+$TEMPLATE[gesvx.complex.min_size_rwork]
+return 2*n;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gges.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gges.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,14 @@
+$TEMPLATE[gges.all.min_size_work.args]
+N
+$TEMPLATE[gges.real.min_size_work]
+return std::max( 1, 8*n + 16 );
+$TEMPLATE[gges.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[gges.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[gges.all.min_size_bwork]
+if ( sort == 'N' )
+ return 0;
+else
+ return n;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggesx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggesx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,34 @@
+$TEMPLATE[ggesx.all.min_size_iwork.args]
+N, SENSE
+$TEMPLATE[ggesx.real.min_size_iwork]
+if ( sense == 'N' )
+ return 1;
+else
+ return std::max( 1, n+6 );
+$TEMPLATE[ggesx.complex.min_size_iwork]
+if ( sense == 'N' )
+ return 1;
+else
+ return std::max( 1, n+2 );
+$TEMPLATE[ggesx.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[ggesx.all.min_size_bwork]
+if ( sort == 'N' )
+ return 0;
+else
+ return n;
+$TEMPLATE[ggesx.all.min_size_work.args]
+N, SENSE
+$TEMPLATE[ggesx.real.min_size_work]
+if ( n == 0 )
+ return 1;
+if ( sense == 'N' )
+ return std::max( 8*n, 6*n+16 );
+else
+ return std::max( 8*n, std::max( 6*n+16, n*n/2 ));
+$TEMPLATE[ggesx.complex.min_size_work]
+if ( sense == 'N' )
+ return std::max( 1, 2*n );
+else
+ return std::max( 1, std::max( 2*n, n*n/2 ) );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[ggev.real.min_size_work.args]
+N
+$TEMPLATE[ggev.real.min_size_work]
+return std::max( 1, 8*n );
+$TEMPLATE[ggev.complex.min_size_work.args]
+N
+$TEMPLATE[ggev.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,50 @@
+$TEMPLATE[ggevx.all.min_size_bwork.args]
+SENSE, N
+$TEMPLATE[ggevx.all.min_size_bwork]
+if ( sense == 'N' )
+ return 0;
+else
+ return n;
+$TEMPLATE[ggevx.real.min_size_iwork.args]
+SENSE, N
+$TEMPLATE[ggevx.real.min_size_iwork]
+if ( sense == 'E' )
+ return 0;
+else
+ return n+6;
+$TEMPLATE[ggevx.complex.min_size_iwork.args]
+SENSE, N
+$TEMPLATE[ggevx.complex.min_size_iwork]
+if ( sense == 'E' )
+ return 0;
+else
+ return n+2;
+$TEMPLATE[ggevx.complex.min_size_rwork.args]
+BALANC, N
+$TEMPLATE[ggevx.complex.min_size_rwork]
+if ( balanc == 'S' || balanc == 'B' )
+ return std::max( 1, 6*n );
+else
+ return std::max( 1, 2*n );
+$TEMPLATE[ggevx.real.min_size_work.args]
+BALANC,JOBVL,JOBVR,SENSE,N
+$TEMPLATE[ggevx.real.min_size_work]
+if ( balanc == 'S' || balanc == 'B' || jobvl == 'V' || jobvr == 'V' )
+ return std::max( 1, 6*n );
+if ( sense == 'E' )
+ return std::max( 1, 10*n );
+if ( sense == 'V' || sense == 'B' )
+ return 2*n*n + 8*n + 16;
+return std::max( 1, 2*n );
+$TEMPLATE[ggevx.complex.min_size_work.args]
+SENSE, N
+$TEMPLATE[ggevx.complex.min_size_work]
+if ( sense == 'N' )
+ return std::max( 1, 2*n );
+else {
+ if ( sense == 'E' )
+ return std::max( 1, 4*n );
+ else
+ return std::max( 1, 2*n*n+2*n );
+}
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggglm.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggglm.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[ggglm.all.min_size_work.args]
+M,N,P
+$TEMPLATE[ggglm.all.min_size_work]
+return std::max( 1, n+m+p );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gglse.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gglse.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[gglse.all.min_size_work.args]
+M,N,P
+$TEMPLATE[gglse.all.min_size_work]
+return std::max( 1, m+n+p );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbev.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hbevd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hbevd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[hbevd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hbevd.complex.min_size_rwork]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hbevd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hbevd.complex.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 2*n*n;
+}
+$TEMPLATE[hbevd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbevx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbgv.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hbgvd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hbgvd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[hbgvd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hbgvd.complex.min_size_rwork]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hbgvd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hbgvd.complex.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 2*n*n;
+}
+$TEMPLATE[hbgvd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbgvx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[heev.complex.min_size_rwork.args]
+N
+$TEMPLATE[heev.complex.min_size_rwork]
+return std::max( 1, 3*n-2 );
+$TEMPLATE[heev.complex.min_size_work.args]
+N
+$TEMPLATE[heev.complex.min_size_work]
+return std::max( 1, 2*n-1 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,30 @@
+$TEMPLATE[heevd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[heevd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[heevd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[heevd.complex.min_size_rwork]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[heevd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[heevd.complex.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n+1;
+ else
+ return 2*n + n*n;
+}
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevr.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,13 @@
+$TEMPLATE[heevr.complex.min_size_work.args]
+N
+$TEMPLATE[heevr.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[heevr.complex.min_size_rwork.args]
+N
+$TEMPLATE[heevr.complex.min_size_rwork]
+return std::max( 1, 24*n );
+$TEMPLATE[heevr.complex.min_size_iwork.args]
+N
+$TEMPLATE[heevr.complex.min_size_iwork]
+return std::max( 1, 10*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[heevx.complex.min_size_work.args]
+N
+$TEMPLATE[heevx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[hegv.complex.min_size_rwork.args]
+N
+$TEMPLATE[hegv.complex.min_size_rwork]
+return std::max( 1, 3*n-2 );
+$TEMPLATE[hegv.complex.min_size_work.args]
+N
+$TEMPLATE[hegv.complex.min_size_work]
+return std::max( 1, 2*n-1 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,30 @@
+$TEMPLATE[hegvd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hegvd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[hegvd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hegvd.complex.min_size_rwork]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hegvd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hegvd.complex.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n+1;
+ else
+ return 2*n + n*n;
+}
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hegvx.complex.min_size_work.args]
+N
+$TEMPLATE[hegvx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,4 @@
+$TEMPLATE[hesv.complex.min_size_work.args]
+$TEMPLATE[hesv.complex.min_size_work]
+return 1;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hesvx.complex.min_size_work.args]
+N
+$TEMPLATE[hesvx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpev.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hpevd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hpevd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[hpevd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hpevd.complex.min_size_rwork]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hpevd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hpevd.complex.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 2*n;
+}
+$TEMPLATE[hpevd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpevx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpgv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hpgvd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hpgvd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[hpgvd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hpgvd.complex.min_size_rwork]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hpgvd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hpgvd.complex.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return n;
+ else
+ return 2*n;
+}
+$TEMPLATE[hpgvd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpgvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hpsv.all.N.trait_of]
+AP
+$TEMPLATE[hpsv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpsvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/lalsd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/lalsd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,26 @@
+$TEMPLATE[lalsd.real.min_size_work.args]
+N,SMLSIZ, NLVL, NRHS
+$TEMPLATE[lalsd.real.min_size_work]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return 9*n + 2*n*smlsiz + 8*n*nlvl + n*nrhs + smlsiz_plus_one * smlsiz_plus_one;
+$TEMPLATE[lalsd.real.min_size_iwork.args]
+N,NLVL
+$TEMPLATE[lalsd.real.min_size_iwork]
+return 3*n*nlvl + 11*n;
+$TEMPLATE[lalsd.complex.min_size_rwork.args]
+N,SMLSIZ, NLVL, NRHS
+$TEMPLATE[lalsd.complex.min_size_rwork]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return 9*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs + smlsiz_plus_one * smlsiz_plus_one;
+$TEMPLATE[lalsd.all.extra_variables]
+NLVL
+$TEMPLATE[lalsd.complex.NLVL.init]
+integer_t nlvl = std::max( 0, static_cast<integer_t>(
+ std::log(static_cast<real_type>(std::min(traits::matrix_size2(b),n))/
+ static_cast<real_type>(smlsiz+1)) /
+ std::log(static_cast<real_type>(2.))) + 1 );
+$TEMPLATE[lalsd.real.NLVL.init]
+integer_t nlvl = std::max( 0, static_cast<integer_t>(
+ std::log(static_cast<real_type>(n)/static_cast<real_type>(smlsiz+1)) /
+ std::log(static_cast<real_type>(2.)) ) + 1 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[pbsv.all.N.trait_of]
+AB
+$TEMPLATE[pbsv.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[pbsvx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[ppsv.all.N.trait_of]
+AP
+$TEMPLATE[ppsv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[ppsvx.all.N.trait_of]
+AP
+$TEMPLATE[ppsvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbev.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[sbevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[sbevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[sbevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[sbevd.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return 2*n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[sbevd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbevx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbgv.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[sbgvd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[sbgvd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[sbgvd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[sbgvd.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return 3*n;
+ else
+ return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[sbgvd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbgvx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spev.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[spevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[spevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[spevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[spevd.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return 2*n;
+ else
+ return 1 + 6*n + n*n;
+}
+$TEMPLATE[spevd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spevx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spgv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[spgvd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[spgvd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[spgvd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[spgvd.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return 2*n;
+ else
+ return 1 + 6*n + n*n;
+}
+$TEMPLATE[spgvd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spgvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[spsv.all.N.trait_of]
+AP
+$TEMPLATE[spsv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[spsvx.all.N.trait_of]
+AP
+$TEMPLATE[spsvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[stev.real.min_size_work.args]
+N
+$TEMPLATE[stev.real.min_size_work]
+return std::max( 1, 2*n-2 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,15 @@
+$TEMPLATE[stevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[stevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[stevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[stevd.real.min_size_work]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 1 + 4*n + n*n;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevr.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[stevr.real.min_size_work.args]
+N
+$TEMPLATE[stevr.real.min_size_work]
+return std::max( 1, 20*n );
+$TEMPLATE[stevr.real.min_size_iwork.args]
+N
+$TEMPLATE[stevr.real.min_size_iwork]
+return std::max( 1, 10*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syev.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[syev.real.min_size_work.args]
+N
+$TEMPLATE[syev.real.min_size_work]
+return std::max( 1, 3*n-1 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,19 @@
+$TEMPLATE[syevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[syevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[syevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[syevd.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return 2*n + 1;
+ else
+ return 1 + 6*n + 2*n*n;
+}
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevr.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[syevr.real.min_size_work.args]
+N
+$TEMPLATE[syevr.real.min_size_work]
+return std::max( 1, 26*n );
+$TEMPLATE[syevr.real.min_size_iwork.args]
+N
+$TEMPLATE[syevr.real.min_size_iwork]
+return std::max( 1, 10*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[syevx.real.min_size_work.args]
+N
+$TEMPLATE[syevx.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else
+ return 8*n;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[sygv.real.min_size_work.args]
+N
+$TEMPLATE[sygv.real.min_size_work]
+return std::max( 1, 3*n-1 );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvd.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,19 @@
+$TEMPLATE[sygvd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[sygvd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+ return 1;
+else
+ return 3 + 5*n;
+$TEMPLATE[sygvd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[sygvd.real.min_size_work]
+if ( n < 2 )
+ return 1;
+else {
+ if ( jobz == 'N' )
+ return 2*n + 1;
+ else
+ return 1 + 6*n + 2*n*n;
+}
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[sygvx.real.min_size_work.args]
+N
+$TEMPLATE[sygvx.real.min_size_work]
+return std::max( 1, 8*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysv.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,4 @@
+$TEMPLATE[sysv.all.min_size_work.args]
+$TEMPLATE[sysv.all.min_size_work]
+return 1;
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysvx.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[sysvx.real.min_size_work.args]
+N
+$TEMPLATE[sysvx.real.min_size_work]
+return std::max( 1, 3*n );
+$TEMPLATE[sysvx.complex.min_size_work.args]
+N
+$TEMPLATE[sysvx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/lapack.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/lapack.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,137 @@
+$TEMPLATE[lapack.hpp]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_$GROUPNAME_HPP
+#define BOOST_NUMERIC_BINDINGS_LAPACK_$GROUPNAME_HPP
+
+$INCLUDES
+
+namespace boost {
+namespace numeric {
+namespace bindings {
+namespace lapack {
+
+//$DESCRIPTION
+
+// overloaded functions to call lapack
+namespace detail {
+$OVERLOADS}
+
+$LEVEL1
+$LEVEL2
+}}}} // namespace boost::numeric::bindings::lapack
+
+#endif
+$TEMPLATE[lapack_overloads]
+ inline void $groupname( $LEVEL0 ) {
+ LAPACK_$SUBROUTINE( $CALL_C_HEADER );
+ }
+$TEMPLATE[level1_pre_header]
+// value-type based template
+template< typename ValueType, typename Enable = void >
+struct $groupname_impl{};
+
+$TEMPLATE[level1_header1]
+// value-type based template
+template< typename ValueType >
+struct $groupname_impl {
+
+$TEMPLATE[level1_header2]
+// $SPECIALIZATION specialization
+template< typename ValueType >
+struct $groupname_impl< ValueType, typename boost::enable_if< traits::is_$SPECIALIZATION<ValueType> >::type > {
+
+$TEMPLATE[level1_workspace]
+ typedef ValueType value_type;
+ typedef typename traits::type_traits<ValueType>::real_type real_type;
+
+ // user-defined workspace specialization
+ template< $TYPES, $WORKSPACE_TYPENAMES >
+ static void compute( $LEVEL1, detail::workspace$WORKSPACE_SIZE< $WORKSPACE_TYPES > work ) {
+#ifndef NDEBUG
+ $INIT_USER_DEFINED_VARIABLES
+ $ASSERTS
+#endif
+ detail::$groupname( $CALL_LEVEL0 );
+ }
+
+ // minimal workspace specialization
+ template< $TYPES >
+ static void compute( $LEVEL1, minimal_workspace work ) {
+ $INIT_USER_DEFINED_VARIABLES
+$SETUP_MIN_WORKARRAYS_POST
+ compute( $CALL_LEVEL1, workspace( $TMP_WORKARRAYS ) );
+ }
+
+ // optimal workspace specialization
+ template< $TYPES >
+ static void compute( $LEVEL1, optimal_workspace work ) {
+$OPT_WORKSPACE_FUNC
+ }
+
+$MIN_SIZE_FUNCS
+};
+
+$TEMPLATE[level1_opt_workspace]
+ $INIT_USER_DEFINED_OPT_VARIABLES
+ $SETUP_OPT_WORKARRAYS_PRE
+ detail::$groupname( $WORKSPACE_QUERY );
+ $SETUP_OPT_WORKARRAYS_POST
+ compute( $CALL_LEVEL1, workspace( $TMP_WORKARRAYS ) );
+$TEMPLATE[level1_opt_workspace_is_min]
+ compute( $CALL_LEVEL1, minimal_workspace() );
+$TEMPLATE[level2_workspace]
+// template function to call $groupname
+template< $TYPES, typename Workspace >
+inline integer_t $groupname( $LEVEL2, Workspace work = optimal_workspace() ) {
+ typedef typename traits::$TYPEOF_FIRST_TYPENAME_traits< $FIRST_TYPENAME >::value_type value_type;
+ integer_t info(0);
+ $groupname_impl< value_type >::compute( $CALL_LEVEL1, work );
+ return info;
+}
+
+$TEMPLATE[setup_min_workspace]
+ traits::detail::array< $WORKSPACE_TYPE > tmp_$NAME( min_size_$NAME( $CALL_MIN_SIZE ) );
+$TEMPLATE[setup_opt_workspace]
+ traits::detail::array< $WORKSPACE_TYPE > tmp_$NAME( $TMP_SIZE );
+$TEMPLATE[min_size_func]
+ static integer_t min_size_$NAME( $ARGUMENTS ) {
+ $MIN_SIZE
+ }
+
+$TEMPLATE[level1_noworkspace]
+ 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 );
+ }
+};
+
+$TEMPLATE[level2_noworkspace]
+// 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/singleton_blas.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,56 @@
+$TEMPLATE[blas.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H
+#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H
+
+#include <boost/numeric/bindings/traits/type.h>
+#include <boost/numeric/bindings/blas/blas_names.h>
+
+extern "C" {
+
+$CONTENT
+
+}
+
+#endif
+
+$TEMPLATE[blas.h_function]
+ void BLAS_$SUBROUTINE( $ARGUMENTS );
+$TEMPLATE[blas_names.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H
+#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H
+
+#include <boost/numeric/bindings/traits/fortran.h>
+
+$CONTENT
+
+#endif
+
+$TEMPLATE[blas_names.h_function]
+#define BLAS_$SUBROUTINE FORTRAN_ID( $subroutine )
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_lapack.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_lapack.hpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,66 @@
+$TEMPLATE[lapack.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_H
+#define BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_H
+
+#include <boost/numeric/bindings/traits/type.h>
+#include <boost/numeric/bindings/lapack/lapack_names.h>
+
+#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
+# define BOOST_NUMERIC_BINDINGS_FORTRAN
+#endif
+
+extern "C" {
+
+$CONTENT
+
+ int LAPACK_ILAENV(int const* ispec, const char* name, const char* opt,
+ int const* n1, int const* n2, int const* n3, int const* n4, int, int);
+}
+
+#endif
+
+$TEMPLATE[lapack.h_function]
+ void LAPACK_$SUBROUTINE( $ARGUMENTS );
+$TEMPLATE[lapack_names.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_NAMES_H
+#define BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_NAMES_H
+
+#ifndef BOOST_NUMERIC_BINDINGS_USE_CLAPACK
+# include <boost/numeric/bindings/traits/fortran.h>
+#else
+# define FORTRAN_ID( id ) id##_
+#endif
+
+$CONTENT
+
+#endif
+
+$TEMPLATE[lapack_names.h_function]
+#define LAPACK_$SUBROUTINE FORTRAN_ID( $subroutine )
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/CMakeLists.txt
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/CMakeLists.txt 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,23 @@
+$TEMPLATE[CMakeLists.txt]
+#
+# Copyright (c) 2009 by Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+# THIS FILE IS AUTOMATICALLY GENERATED
+# PLEASE DO NOT EDIT!
+#
+
+enable_language( Fortran )
+find_package( LAPACK REQUIRED )
+
+#include_directories( . )
+
+$ENTRIES
+
+$TEMPLATE[CMakeLists.entry]
+add_executable( $groupname $groupname.cpp )
+target_link_libraries( $groupname ${LAPACK_LIBRARIES} )
+$TEMPLATE[end]

Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/test_case.cpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/test_case.cpp 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[test_case.cpp]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#include <cstdlib>
+#include <boost/numeric/bindings/lapack/$levelname/$groupname.hpp>
+
+int main(int argc, char *argv[]) {
+
+
+
+
+
+
+
+
+
+
+ return EXIT_SUCCESS;
+}
+
+$TEMPLATE[end]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk