x>" IPM.Microsoft Mail.Note1 RE: [ublas] Snapshot 20081116 2 T  2 T !8C75B527DAEC7745ADDC70BDA17EA9D3 9&6@9ubL=RE: G5c=US;a= ;p=Synopsys;l=DE02WEMBX1-081122165011Z-62101IRe: [ublas] Snapshot 20081116@N LZublas-bounces@lists.boost.org[Y+nTublas-bounces@lists.boost.orgSMTPublas-bounces@lists.boost.org\#SMTP:UBLAS-BOUNCES@LISTS.BOOST.ORG]Rutger ter Borg^@+nTRutger ter BorgSMTPrutger@terborg.net_SMTP:RUTGER@TERBORG.NETfSMTPgublas-bounces@lists.boost.orghSMTPirutger@terborg.netp[ublas] Snapshot 20081116qL mEhQ>'tublas@lists.boost.org Thomas Klimpel[ublas] Snapshot 20081116 |x LZFu$Z rcpg1252CtexA PV?U%Qch set2%3F0,3 ;05" `cP3 d36P Helutg, T bBg w`:Q> Ipa jtus@w  g,!uldn'@i@beq0.p"Ph"nu[c"p d!qs!libr y a!o L%e "A own!n#s %" "uBLAS?D0y` *!"r ( "c a+%"$ %O&_'b? Qg P*0b`i  +g` ":-)Od*t p.Ck'`.A/ Q1.a`v". p"P./2:!m9"@ $a (8;0Gc( 0(0"3 P""p1#0E. F?bsh.#=! `?` k"B>Qg` "@mp7aLdd,1="bkg"!i.eCP v8Q!0+ -R"= -A(HF  .??S,1F$s9unc4@"Py)HKrGd(mM?K0@k9! supFL64-$P@ Q0ms).AO1K=go@+X.ak90p`p l*&f?_/!.`?!WP:scV -Q008QU(M{?!OO\K(3fi2Iq4!^W1-P0EVPM(!rEH_`"anS+K  M r"P tC5D`8xZb W@> h@p:/V/0@K.B.A/.M pi9s/u` /07/06nP166.p|hpQir= FkkRwtp.clpk!eu9nle/pn _am0p[n/tw/TW5n.lpkm!SJ'Yr$ Mi29pZ?3r(  ]-a`q-?(_Ti6gp( -L$VCP>Ti-PJ(pyip -3.a+V ?1.0p}9R00vpG-3.1p/SRCHy ?|gti6 quyq+oQr-RLrT>QIQ!f "gV,VzA0B-"p[B5daC@ PEC@g'y?1Z(UJ8yVP0H0@(Mg>a)NCPx(8Dpi6EJQQ05v!!H `6"Z.R"i (wp @gmira`M@iB0p $!'D0"  g njaS+vA-arp`+#7(P0YqHA' 'QA`cJRi#)C:aQ!([01Pъf9M5quZq_HSYbE".( (i0'TO0FVYcHEr i@vJB(H0)C!a"PќMi0p2`"QJQ=nqJl2S+R_pq$}5J<202155BFFBADAF47A29C8D3B7668017832A17A@DE02WEMBX1.internal.synopsys.com>9J<200811161506.26995.lists@informa.tiker.net> Gmessage/rfc822 HRE%3A [ublas] Snapshot 20081116.EML @02L@0bL?o? ?Thomas Klimpel?^ܧ@B+//O=SYNOPSYS/OU=DE02 ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=KLIMPEL?System Administrator?ܧ@B+/.?@@@@0@KLIMPEL1@KLIMPEL2@ublas-bounces@lists.boost.org3@rutger@terborg.net8@KLIMPEL9@.v@ ) #¹,eHELLORUTGER,RUTGERTERBORGWROTE:IWASJUSTWONDERING,WOULDNTITBETIMETOPITCHTHENUMERICBINDINGSLIBRARYASABJ<202155BFFBADAF47A29C8D3B7668017832A17A@DE02WEMBX1.internal.synopsys.com> = $; $; lapack~1.py2y># Copyright Thomas Klimpel 2008. # Use, modification and distribution are subject to 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 script is only intended to parse the documentation # from the fortran source files in lapack-3.1.1\SRC and generate # some boilerplate code for c++ bindings against these source files. # Since this folder contains both BLAS and LAPACK, both type of files # should be parsed correctly. import sys class myArgument: def __init__(self, myName, myType, myDims, myConst, myDocs): self.myName = myName self.myType = myType self.myDims = myDims self.myConst = myConst self.myDocs = myDocs def get_bindings_type(self, single_precision, prototype): if single_precision and prototype: bindReal = 'float' bindCplx = 'fcomplex_t' elif prototype: bindReal = 'double' bindCplx = 'dcomplex_t' elif single_precision: bindReal = 'float' bindCplx = 'traits::complex_f' else: bindReal = 'double' bindCplx = 'traits::complex_d' bindtypedict = { 'CHARACTER': 'char', 'INTEGER': 'int', 'LOGICAL': 'logical_t', 'REAL': bindReal, 'COMPLEX': bindCplx } if self.myType in bindtypedict: return bindtypedict[self.myType] else: return 'void' def get_inline_name(self): if not self.myDims: return '&'+self.myName if self.myType == 'COMPLEX': return 'traits::complex_ptr('+self.myName+')' return self.myName def parse_dimension (line): """Separate to dimension arguments into a list""" key = "dimension" i = len(key) while len(line) > i: if line[i-len(key):i] == key: break else: i += 1 dims = [] nestlev = 0 dbegin = i while i < len(line): if line[i] == '(': nestlev += 1 if nestlev == 1: dbegin = i+1 elif line[i] == ')': nestlev -= 1 if nestlev == 0: dims.append(line[dbegin:i]) elif nestlev == 1 and line[i] == ',': dims.append(line[dbegin:i]) dbegin = i+1 i += 1 return dims class rawArgument: def __init__(self, rawName, rawType, rawDocs): self.rawName = rawName self.rawType = rawType self.rawDocs = rawDocs def parse(self): inout = ["(input)", " (input)", "(output)", " (output)", "(input/output)", "(input or output)", "(workspace)", "(workspace/output)", "(external procedure)"] finetype = self.rawDocs[0] reftype = -1 for i in range(len(inout)): if len(finetype) >= len(inout[i]) and finetype[:len(inout[i])] == inout[i]: reftype = i if reftype == -1: raise Exception("could not deduce reftype", self.rawName, finetype) myConst = (reftype == 0 or reftype == 1) #ToDo: parse input/output # parse dimension for array arguments myDims = parse_dimension(finetype) myDocs = [] for i in range(1, len(self.rawDocs)): line = self.rawDocs[i] if len(line) > 11: myDocs.append(line[11:]) elif i+1 < len(self.rawDocs): myDocs.append("\n") return myArgument(self.rawName, self.rawType, myDims, myConst, myDocs) #define function for splitting lapack fortran source files def split_lapack_source (filename): """Scan a lapack fortran source file Return the splitted sections""" fortran_source = open(filename,'r') #put header into one long line subroutine_header = fortran_source.readline().strip() line = fortran_source.readline() while len(line) >= 6 and line[5] != ' ': subroutine_header = " ".join([subroutine_header, line[6:].strip()]) line = fortran_source.readline() #skip forward to Scalar Arguments block next_block="* .. Scalar Arguments .." while len(line) < len(next_block) or line[:len(next_block)] != next_block: line = fortran_source.readline() #assume that the lines until the next comment are the scalar arguments line = fortran_source.readline() scalar_arguments = [line.strip()] line = fortran_source.readline() while len(line) >= 1 and line[0] == ' ': if len(line) >= 6 and line[5] != ' ': scalar_arguments[-1] = " ".join([scalar_arguments[-1], line[6:].strip()]) else: scalar_arguments.append(line.strip()) line = fortran_source.readline() #skip forward to Array Arguments block next_block="* .. Array Arguments .." while len(line) < len(next_block) or line[:len(next_block)] != next_block: line = fortran_source.readline() #assume that the lines until the next comment are the array arguments line = fortran_source.readline() array_arguments = [line.strip()] line = fortran_source.readline() while len(line) >= 1 and line[0] == ' ': if len(line) >= 6 and line[5] != ' ': array_arguments[-1] = " ".join([array_arguments[-1], line[6:].strip()]) else: array_arguments.append(line.strip()) line = fortran_source.readline() #skip forward to Purpose block next_block="* Purpose" while len(line) < len(next_block) or line[:len(next_block)] != next_block: line = fortran_source.readline() #read till documentation delimiter end_block="* =====================================================================" documentation = [] while line and (len(line) < len(end_block) or line[:len(end_block)] != end_block): documentation.append(line) line = fortran_source.readline() documentation.append(line) return subroutine_header, scalar_arguments, array_arguments, documentation #end of function split_lapack_source def determine_subroutine_name(subroutine_header): """parse the subroutine_name from the subroutine header returns the subroutine_name""" subroutine_name = subroutine_header[ subroutine_header.find('SUBROUTINE ')+11:subroutine_header.find('(')] return subroutine_name #end of function determine_subroutine_name def determine_argument_name_list(subroutine_header): """parse the argument_name_list from the subroutine header returns the argument_name_list""" argument_name_list = subroutine_header[ subroutine_header.find('( ')+2:subroutine_header.find(' )')].split(", ") return argument_name_list #end of function determine_argument_name_list def interpret_documentation(documentation): xxx_begin = [0, 0, 0, 0] xxx_end = [0, 0, 0, 0] xxx_name = ["* Purpose\n", "* Description\n", "* Arguments\n"] # "* Further Details\n"] xxx = -1 end_block="* ===" for i in range(len(documentation)): line = documentation[i] if len(line) >= len(end_block) and line[:len(end_block)] == end_block: if xxx >= 0 and xxx_begin[xxx] != i+2: xxx_end[xxx] = i-1 xxx = -1 for j in range(len(xxx_name)): if line == xxx_name[j]: if xxx >= 0: xxx_end[xxx] = i-1 xxx = j xxx_begin[xxx] = i+3 docs_list = [] for line in documentation[xxx_begin[2]:xxx_end[2]]: if len(line) > 3 and line[3] != ' ': if line[2] == ' ': namestart = 3 else: namestart = 2 ii = line[namestart:].find(' ') # docs_list.append((line[namestart:3+ii], [line[namestart+ii:]])) docs_list.append((line[namestart:namestart+ii], [line[11:]])) else: docs_list[-1][1].append(line) return documentation[xxx_begin[0]:xxx_end[0]], docs_list #end of function interpret_documentation def determine_rawArgumet_list(argument_name_list, scalar_arguments, array_arguments, documentation): """determine rawArgumet_list returns the rawArgumet_list""" scalar_list = [] for typeline in scalar_arguments: typename = typeline[:typeline.find(' ')] namelist = typeline[typeline.find(' '):].strip().split(", ") scalar_list.append((typename, set(namelist))) array_list = [] for typeline in array_arguments: typename = typeline[:typeline.find(' ')] namelist = typeline[typeline.find(' '):].strip().split("), ") namelist[-1] = namelist[-1][:-1] namelist1 = [] for name_x in namelist: namelist1.append(name_x.split("(")[0]) array_list.append((typename, set(namelist1))) purpose, docs_list = interpret_documentation (documentation) rawArgument_list = [] #ToDo: split "Arguments" docu into name and docu for name in argument_name_list: rawType = "*" for scalar_type in scalar_list: if name in scalar_type[1]: rawType = scalar_type[0] for array_type in array_list: if name in array_type[1]: rawType = array_type[0]#+"()" rawDocs = ["!"] for docs in docs_list: if name == docs[0]: rawDocs = docs[1] rawArgument_list.append(rawArgument(name,rawType,rawDocs)) return rawArgument_list, purpose #end of function determine_rawArgumet_list #define function for scanning lapack fortran source files def load_fortran_src(filename): """Scan a lapack fortran source file Return the argument list""" subroutine_header, scalar_arguments, array_arguments, \ documentation = split_lapack_source (filename) name = determine_subroutine_name(subroutine_header) argument_name_list = determine_argument_name_list(subroutine_header) rawArgument_list, purpose = determine_rawArgumet_list(argument_name_list, scalar_arguments, array_arguments, documentation) argument_list = [] for rawArg in rawArgument_list: argument_list.append(rawArg.parse()) return name, argument_list, purpose #end of function load_fortran_src def generate_interface_code(subroutine_name, argument_list, single_precision): """try to produce a nice c function prototype""" section = [] result_list = [] tmp = '/* name macro for lapack_names.h */\n' section.append(tmp) tmp = '' tmp += '#define LAPACK_'+subroutine_name+' FORTRAN_ID( '+ subroutine_name.lower()+' )\n' result_list.append(tmp) tmp = '/* function prototype for lapack.h */\n' section.append(tmp) tmp = '' tmp += ' void LAPACK_'+subroutine_name+(' '*(7-len(subroutine_name)))+'(' for i in range(len(argument_list)): argument = argument_list[i] if argument.myConst: cmodif = ' const* ' else: cmodif = '* ' tmp += argument.get_bindings_type(single_precision, True) + cmodif + argument.myName.lower() if i+1 == len(argument_list): tmp += ');\n' elif i % 3 == 2: tmp += ',\n'+(' '*22) else: tmp += ', ' result_list.append(tmp) tmp = '/* inline overload resolve for ' + subroutine_name[1:].lower()+'.hpp */\n' section.append(tmp) tmp = '' tmp += ' inline void '+subroutine_name[1:].lower()+' (\n'+(' '*8) for i in range(len(argument_list)): argument = argument_list[i] if argument.myConst and not argument.myDims: cmodif = ' const ' elif argument.myConst: cmodif = ' const* ' elif not argument.myDims: cmodif = '& ' else: cmodif = '* ' tmp += argument.get_bindings_type(single_precision, False) + cmodif + argument.myName.lower() if i+1 == len(argument_list): tmp += ')\n {\n' elif i % 3 == 2: tmp += ',\n'+(' '*8) else: tmp += ', ' tmp += ' LAPACK_'+subroutine_name+' (\n'+(' '*10) for i in range(len(argument_list)): argument = argument_list[i] tmp += argument.get_inline_name().lower() if i+1 == len(argument_list): tmp += ');\n }\n\n' elif i % 3 == 2: tmp += ',\n'+(' '*10) else: tmp += ', ' result_list.append(tmp) return (section, result_list) def write_prototype(filename,subroutine_name, argument_list): """try to produce a nice c function prototype""" dname = subroutine_name if subroutine_name[0] == 'S': dname = 'D' + subroutine_name[1:] elif subroutine_name[0] == 'C': dname = 'Z' + subroutine_name[1:] else: raise Exception('expected \'S\' or \'C\' as first letter of function name', subroutine_name) (ssection, sresult) = generate_interface_code(subroutine_name, argument_list, True) assert(len(ssection) == len(sresult)) (dsection, dresult) = generate_interface_code(dname, argument_list, False) assert(len(dsection) == len(dresult)) assert(ssection == dsection) tmp = open(filename,'w') for i in range(len(ssection)): tmp.write(ssection[i]) tmp.write(sresult[i]) tmp.write(dresult[i]) #define function for saving resulting jones matrix def save_results(filename,argument_list,documentation): """Save the results in a human readable format to be extended""" tmp = open(filename,'w') for argument in argument_list: if argument.myConst: cmodif = ' const* ' else: cmodif = '* ' tmp.write("name: " + argument.myName + " type: " + argument.myType + " dims: " + repr(argument.myDims) + " const: " + repr(argument.myConst) + "\n") tmp.write("carg: " + argument.get_bindings_type(True, True) + cmodif + argument.myName.lower() + "\n") tmp.write("docs:\n" + "".join(argument.myDocs) + "\n") tmp.write("Documentation:\n") for line in documentation: tmp.write(line) #end of function save_results #define function for processing lapack source files def process_lapack_source(fortran_source_filename): failing = ["hseqr.f", "lacgv.f", "lacn2.f", "lacon.f", "lacrt.f", "ladiv.f", "laed0.f", "laed7.f", "laed8.f", "laesy.f", "laev2.f", "lags2.f", "lahqr.f", "lals0.f", "lalsa.f", "lalsd.f", "langb.f", "lange.f", "langt.f", "lanhb.f", "lanhe.f", "lanhp.f"] for name in failing: if fortran_source_filename[-len(name):] == name: return if fortran_source_filename[-2:] == ".f": print "process source_file: ", fortran_source_filename prototype_source_filename = fortran_source_filename[:-2] + ".hpp" log_filename = fortran_source_filename[:-2] + ".log" name, args,docs = load_fortran_src(fortran_source_filename) write_prototype(prototype_source_filename,name,args) save_results(log_filename,args,docs) #end of function process_lapack_source #start main programm if __name__ == "__main__" and len(sys.argv) > 1: for fortran_source_filename in sys.argv: process_lapack_source(fortran_source_filename) else: process_lapack_source("C:\lapack-3.1.1\SRC\clanhs.f") [  >!xoOt//0lapack_extractor.py@0,$L@0,$L7py77lapack_extractor.py 77 text/plain-