Example #1
0
def main():
    fname_wrapper = 'cWrapper.f95'
    fname_signature = 'shtools.h'

    print('now cracking Fortran file ' + fname_wrapper +
          ' using f2py function...')
    crackfortran.verbose = False
    crackfortran.dolowercase = False
    cracked_shtools = crackfortran.crackfortran(fname_wrapper)

    with open(fname_signature, 'w') as outfile:

        outfile.write('#pragma once\n')
        outfile.write('namespace shtools{\n')
        outfile.write('extern "C"\n{\n')
        for subroutine in cracked_shtools:
            return_type = 'void'
            if subroutine['block'] == 'function':

                return_type = TYPEMAP[subroutine['vars'][subroutine['name']]
                                      ['typespec']]

            newline = return_type + ' ' + subroutine['name'] \
                + '( ' + create_signature(subroutine) + ')' + ';'
            outfile.write(newline + '\n')
        outfile.write('}\n}\n')

    os.system('clang-format -i -style=Mozilla ' + fname_signature)
 def test_defaultPrivate(self, tmp_path):
     f_path = tmp_path / "mod.f90"
     with f_path.open('w') as ff:
         ff.write(
             textwrap.dedent("""\
         module foo
           private
           integer :: a
           public :: setA
           integer :: b
         contains
           subroutine setA(v)
             integer, intent(in) :: v
             a = v
           end subroutine setA
         end module foo
         """))
     mod = crackfortran.crackfortran([str(f_path)])
     assert len(mod) == 1
     mod = mod[0]
     assert 'private' in mod['vars']['a']['attrspec']
     assert 'public' not in mod['vars']['a']['attrspec']
     assert 'private' in mod['vars']['b']['attrspec']
     assert 'public' not in mod['vars']['b']['attrspec']
     assert 'private' not in mod['vars']['seta']['attrspec']
     assert 'public' in mod['vars']['seta']['attrspec']
 def test_defaultPublic(self, tmp_path):
     f_path = tmp_path / "mod.f90"
     with f_path.open("w") as ff:
         ff.write(
             textwrap.dedent(
                 """\
         module foo
           public
           integer, private :: a
           public :: setA
         contains
           subroutine setA(v)
             integer, intent(in) :: v
             a = v
           end subroutine setA
         end module foo
         """
             )
         )
     mod = crackfortran.crackfortran([str(f_path)])
     assert len(mod) == 1
     mod = mod[0]
     assert "private" in mod["vars"]["a"]["attrspec"]
     assert "public" not in mod["vars"]["a"]["attrspec"]
     assert "private" not in mod["vars"]["seta"]["attrspec"]
     assert "public" in mod["vars"]["seta"]["attrspec"]
Example #4
0
def main():
    fname_wrapper = 'PythonWrapper.f95'
    fname_signature = 'pyshtools.pyf'

    print('now cracking Fortran file SHTOOLS.f95 using f2py function...')
    crackfortran.verbose = False
    crackfortran.dolowercase = False
    cracked_shtools = crackfortran.crackfortran(fname_wrapper)
    for subroutine in cracked_shtools:
        subroutine['f2pyenhancements'] = \
            {'fortranname': subroutine['name'].lower()}
    for subroutine in cracked_shtools:
        subroutine['name'] = subroutine['name'][2:]
    interface = {
        'block': 'interface',
        'name': 'unknown_interface',
        'from': '',
        'body': cracked_shtools,
        'externals': [],
        'interfaced': [],
        'vars': {}
    }
    module = {
        'block': 'python module',
        'name': '_SHTOOLS',
        'from': '',
        'body': interface,
        'externals': [],
        'interfaced': [],
        'vars': {}
    }
    out = crackfortran.crack2fortran(module)
    with open(fname_signature, 'w') as outfile:
        outfile.write(out)
 def test_parse_abstract_interface(self):
     # Test gh18403
     fpath = util.getpath("tests", "src", "abstract_interface",
                          "gh18403_mod.f90")
     mod = crackfortran.crackfortran([str(fpath)])
     assert len(mod) == 1
     assert len(mod[0]["body"]) == 1
     assert mod[0]["body"][0]["block"] == "abstract interface"
Example #6
0
 def test_access_type(self, tmp_path):
     fpath = util.getpath("tests", "src", "crackfortran", "accesstype.f90")
     mod = crackfortran.crackfortran([str(fpath)])
     assert len(mod) == 1
     tt = mod[0]['vars']
     assert set(tt['a']['attrspec']) == {'private', 'bind(c)'}
     assert set(tt['b_']['attrspec']) == {'public', 'bind(c)'}
     assert set(tt['c']['attrspec']) == {'public'}
Example #7
0
 def test_defaultPublic(self, tmp_path):
     fpath = util.getpath("tests", "src", "crackfortran", "publicmod.f90")
     mod = crackfortran.crackfortran([str(fpath)])
     assert len(mod) == 1
     mod = mod[0]
     assert "private" in mod["vars"]["a"]["attrspec"]
     assert "public" not in mod["vars"]["a"]["attrspec"]
     assert "private" not in mod["vars"]["seta"]["attrspec"]
     assert "public" in mod["vars"]["seta"]["attrspec"]
Example #8
0
def make_signature(filename):
    info = crackfortran.crackfortran(filename)[0]
    name = info['name']
    if info['block'] == 'subroutine':
        return_type = 'void'
    else:
        return_type = get_type(info, name)
    arglist = [' *'.join([get_type(info, arg), arg]) for arg in info['args']]
    args = ', '.join(arglist)
    # Eliminate strange variable naming that replaces rank with rank_bn.
    args = args.replace('rank_bn', 'rank')
    return '{0} {1}({2})\n'.format(return_type, name, args)
def make_signature(filename):
    info = crackfortran.crackfortran(filename)[0]
    name = info['name']
    if info['block'] == 'subroutine':
        return_type = 'void'
    else:
        return_type = get_type(info, name)
    arglist = [' *'.join([get_type(info, arg), arg]) for arg in info['args']]
    args = ', '.join(arglist)
    # Eliminate strange variable naming that replaces rank with rank_bn.
    args = args.replace('rank_bn', 'rank')
    return '{0} {1}({2})\n'.format(return_type, name, args)
Example #10
0
 def test_input_encoding(self, tmp_path, encoding):
     # gh-635
     f_path = tmp_path / f"input_with_{encoding}_encoding.f90"
     # explicit BOM is required for UTF8
     bom = {'utf-8': codecs.BOM_UTF8}.get(encoding, b'')
     with f_path.open('w', encoding=encoding) as ff:
         ff.write(
             bom.decode(encoding) + """
                  subroutine foo()
                  end subroutine foo
                  """)
     mod = crackfortran.crackfortran([str(f_path)])
     assert mod[0]['name'] == 'foo'
Example #11
0
 def test_notPublicPrivate(self, tmp_path):
     fpath = util.getpath("tests", "src", "crackfortran", "pubprivmod.f90")
     mod = crackfortran.crackfortran([str(fpath)])
     assert len(mod) == 1
     mod = mod[0]
     assert mod['vars']['a']['attrspec'] == [
         'private',
     ]
     assert mod['vars']['b']['attrspec'] == [
         'public',
     ]
     assert mod['vars']['seta']['attrspec'] == [
         'public',
     ]
Example #12
0
 def test_dependencies(self, tmp_path):
     f_path = tmp_path / "mod.f90"
     with f_path.open('w') as ff:
         ff.write(
             textwrap.dedent("""\
         module foo
           type bar
             character(len = 4) :: text
           end type bar
           type(bar), parameter :: abar = bar('abar')
         end module foo
         """))
     mod = crackfortran.crackfortran([str(f_path)])
     assert len(mod) == 1
     assert mod[0]['vars']['abar']['='] == "bar('abar')"
Example #13
0
 def test_parse_abstract_interface(self, tmp_path):
     # Test gh18403
     f_path = tmp_path / "gh18403_mod.f90"
     with f_path.open('w') as ff:
         ff.write(textwrap.dedent("""\
             module test
               abstract interface
                 subroutine foo()
                 end subroutine
               end interface
             end module test
             """))
     mod = crackfortran.crackfortran([str(f_path)])
     assert len(mod) == 1
     assert len(mod[0]['body']) == 1
     assert mod[0]['body'][0]['block'] == 'abstract interface'
Example #14
0
 def test_moduleOperators(self, tmp_path):
     fpath = util.getpath("tests", "src", "crackfortran", "operators.f90")
     mod = crackfortran.crackfortran([str(fpath)])
     assert len(mod) == 1
     mod = mod[0]
     assert "body" in mod and len(mod["body"]) == 9
     assert mod["body"][1]["name"] == "operator(.item.)"
     assert "implementedby" in mod["body"][1]
     assert mod["body"][1]["implementedby"] == \
         ["item_int", "item_real"]
     assert mod["body"][2]["name"] == "operator(==)"
     assert "implementedby" in mod["body"][2]
     assert mod["body"][2]["implementedby"] == ["items_are_equal"]
     assert mod["body"][3]["name"] == "assignment(=)"
     assert "implementedby" in mod["body"][3]
     assert mod["body"][3]["implementedby"] == \
         ["get_int", "get_real"]
Example #15
0
def main():
    fname_wrapper = 'PythonWrapper.f95'
    fname_signature = 'pyshtools.pyf'

    print('now cracking Fortran file SHTOOLS.f95 using f2py function...')
    crackfortran.verbose = False
    crackfortran.dolowercase = False
    cracked_shtools = crackfortran.crackfortran(fname_wrapper)
    for subroutine in cracked_shtools:
        subroutine['f2pyenhancements'] = {'fortranname': subroutine['name'].lower()}
    for subroutine in cracked_shtools:
        subroutine['name'] = subroutine['name'][2:]
    interface = {'block': 'interface', 'name': 'unknown_interface', 'from': '',
                 'body': cracked_shtools, 'externals': [], 'interfaced': [],
                 'vars': {}}
    module = {'block': 'python module', 'name': '_SHTOOLS', 'from': '',
              'body': interface, 'externals': [], 'interfaced': [],
              'vars': {}}
    out = crackfortran.crack2fortran(module)
    with open(fname_signature, 'w') as outfile:
        outfile.write(out)
Example #16
0
# - final setup
if len(site_libs): libs = site_libs
if len(site_libdirs): libdirs.extend(site_libdirs)


# Special setups
extra_link_args=[]
if sys.platform=='darwin':
    extra_link_args += ['-bundle','-bundle_loader '+sys.prefix+'/bin/python']
kwext = dict(libraries=libs, library_dirs=libdirs, extra_link_args=extra_link_args)

if __name__=='__main__':

    # Generate pyf files
    crackfortran.f77modulename = '_core'
    pyfcode = crackfortran.crack2fortran(crackfortran.crackfortran(['lib/spanlib/spanlib_pywrap.f90']))
    f = open('lib/spanlib/spanlib.pyf', 'w')
    f.write(pyfcode)
    f.close()
    crackfortran.f77modulename = 'anaxv'
    pyfcode = crackfortran.crack2fortran(crackfortran.crackfortran(['lib/spanlib/anaxv.f90']))
    f = open('lib/spanlib/anaxv.pyf', 'w')
    f.write(pyfcode)
    f.close()

    # Setup the python module
    s = setup(name="spanlib",
        version=version,
        description=description,
        author=author,
        author_email=author_email,
Example #17
0
def create(file_name):
    """
    Function to create ERSEM module index everytime the docs are built

    :param file_name: file name of the api
    :type file_name: str
    """
    main_header = "ERSEM module index"
    heading_boarder = "#" * len(main_header)
    index_str = ".. _api:\n\n{}\n{}\n{}\n\n".format(heading_boarder,
                                                    main_header,
                                                    heading_boarder)

    structure = ["include", "!", "module", "extends"]
    f = io.StringIO()
    # removing standard output from console
    with redirect_stdout(f):
        for fname in glob.glob("../../src/*.F90"):
            if fname != "../../src/shared.F90":
                with open(fname, "r") as f:
                    file_contence = f.readlines()
                module_dict = {"include": [], "!": [], "module": [], "extends": []}
                for line in file_contence:
                    check = [s in line for s in structure]
                    index = where(check)[0]
                    if len(index) > 0:
                        key = structure[index[0]]
                        value = line.split(key)[1][1:].strip("\n")
                        if key == "extends":
                            value = value.split(")")[0]
                        module_dict[key].append(value)
                    if "extends" in line:
                        break
                module_dict["class inheritance"] = module_dict.pop("extends")
                module_dict["description"] = module_dict.pop("!")
                module_str = "Module name: {}\n{}\n\n".format(
                        module_dict["module"][0],
                        (len(module_dict["module"][0]) + 13) * "~")
                module_dict.pop('module', None)
                indent = " " * 4
                for key, item in module_dict.items():
                    if key == "description":
                        list_str = \
                                "\n".join(item).replace("\n", "\n" + indent * 2)
                    else:
                        list_str = f"\n{2*indent}.. code-block:: bash \n\n{indent*4}" + \
                                "\n".join(item).replace("\n", "\n" + indent * 4)
                    module_str += f"{indent}**{key.capitalize()}**:\n{indent*2}{list_str}\n\n"

                # Find additional functions within module
                interface = [sub["saved_interface"].split("\n")[1:-1]
                             for sub in crackfortran(fname)[0]["body"]
                             if sub["block"] in ["function"]]
                if interface != []:
                    subroutines = []
                    for i in interface:
                        joined_str = "\n".join(i)
                        subroutines.append(".. code-block:: bash \n\n" + joined_str)
                        func_str = "{}**Functions**:\n\n{}".format(indent,
                                                           "\n".join(subroutines))
                        module_str += func_str.replace("\n", "\n" + indent * 2) +"\n"
            index_str += module_str

        with open(file_name, "w") as index_file:
            index_file.write(index_str)
Example #18
0
#it uses the crackfortran module


import os
import numpy.f2py.crackfortran as cf
srcpath = '../src'
filelist = os.listdir(srcpath)
print filelist
filelist2=[]
for fname in filelist:
    filelist2.append(srcpath + '/' + fname)

for fname in filelist2:
    print fname

postlist = cf.crackfortran(filelist2[:-1])

def dimlst2str(dimlst):
    s = '('
    for dm in dimlst:
        s += dm + ','
    s = s[:-1] + ')'
    if 'njas' in s: print dimlst
    return s
    
for b in postlist:
    print 'Blockname: ', b['name']
    if b.has_key('vars'):
        for varname in b['vars'].keys():
            d = b['vars'][varname]
            s = ''
def main():
    fname_fortran = 'SHTOOLS.f95'
    fname_wrapper = 'cWrapper.f95'

    explicite_dims_file = "explicite_dimensions.yml"
    with open(explicite_dims_file, 'r') as exp_dim_fid:
        explicite_dims = yaml.safe_load(exp_dim_fid.read())

    print('now cracking Fortran file SHTOOLS.f95 using f2py function...')
    crackfortran.verbose = False
    crackfortran.dolowercase = False
    cracked_shtools = crackfortran.crackfortran(fname_fortran)

    print('decending through shtools module tree...')
    module = cracked_shtools[0]
    interface_old = module['body'][0]
    interface_new = deepcopy(interface_old)
    for subroutine in interface_new['body']:
        if subroutine['name'] in explicite_dims:
            modify_subroutine(subroutine, explicite_dims[subroutine['name']])
        else:
            modify_subroutine(subroutine)

    print('create interface string...')
    wrapper = crackfortran.crack2fortran(interface_new)
    wrapperlines = wrapper.split('\n')

    # search for the indices of 'use shtools,' to insert 'implicit none' after
    iusestatement = [
        iline for iline, line in enumerate(wrapperlines)
        if 'use shtools,' in line
    ]
    assert len(iusestatement) == len(interface_new['body']), \
        'number of subroutines don\'t match'

    # search for the indices of 'end subroutine'
    iendsubroutine = [
        iline for iline, line in enumerate(wrapperlines)
        if 'end subroutine' in line or 'end function' in line
    ]
    assert len(iendsubroutine) == len(interface_new['body']), \
        'number of subroutines don\'t match'

    print('sort variables...')
    for i in range(len(iusestatement)):
        declaration = wrapperlines[iusestatement[i] + 1:iendsubroutine[i]]
        current_order = [(line.split('::')[1]).strip() for line in declaration]
        order = interface_new['body'][i]['sortvars']

        idx = []
        for j in range(len(order)):
            idx.append(current_order.index(order[j]))

        declaration[:] = [declaration[k] for k in idx]
        wrapperlines[iusestatement[i] + 1:iendsubroutine[i]] = declaration[:]

    print('add implicit none statements')
    for iline in iusestatement[::-1]:
        wrapperlines.insert(iline + 1,
                            2 * crackfortran.tabchar + 'implicit none')

    print('add shtools subroutine calls...')

    # search for the indices of 'end subroutine'
    iendsubroutine = [
        iline for iline, line in enumerate(wrapperlines)
        if 'end subroutine' in line or 'end function' in line
    ]
    assert len(iendsubroutine) == len(interface_new['body']), \
        'number of subroutines don\'t match'

    # insert call statements before 'end subroutine' line starting from the
    # end such that we don't change the preceding indices
    for sroutine_new, sroutine_old, iline in list(
            zip(interface_new['body'], interface_old['body'],
                iendsubroutine))[::-1]:
        args = create_arg_list(sroutine_old)
        if sroutine_new['block'] == 'function':
            newline = 2 * crackfortran.tabchar +\
                '%s=%s(' % (sroutine_new['name'], sroutine_old['name']) +\
                args+ ')'
        elif sroutine_new['block'] == 'subroutine':
            newline = 2 * crackfortran.tabchar +\
                'call %s(' % sroutine_old['name'] +\
                args+ ')'
        wrapperlines.insert(iline + 1, '')
        wrapperlines.insert(iline, newline)

    print('add bind statment...')
    p = re.compile('\s*(subroutine|function)')
    # search for the indices of 'subroutine'
    isubroutine = [
        iline for iline, line in enumerate(wrapperlines)
        if p.match(line) is not None
    ]
    assert len(isubroutine) == len(interface_new['body']), \
        'number of subroutines don\'t match'

    for sroutine_new, sroutine_old, iline in list(
            zip(interface_new['body'], interface_old['body'],
                isubroutine))[::-1]:
        wrapperlines[iline] = wrapperlines[iline] + ' bind(c, name=\"' \
          + sroutine_old['name'] + '\")'
        newline = 2 * crackfortran.tabchar + 'use, intrinsic :: iso_c_binding'
        wrapperlines.insert(iline + 1, newline)

    print('writing wrapper to file %s' % fname_wrapper)
    for iline, line in enumerate(wrapperlines):
        try:
            firstword = line.split()[0]
            secondword = line.split()[1]
            words = [
                'real(kind=c_double)', 'complex(kind=c_double_complex)',
                'integer(kind=c_int)', 'character(kind=c_char)',
                'real(kind=8)', 'real*8', 'integer', 'integer(kind=4)',
                'character*(*)', 'complex*16'
            ]
            for word in words:
                if (firstword == word and not secondword[0] == ':'
                        or secondword[0] == ','):
                    line = line.replace(word, word + ',')
            wrapperlines[iline] = line
        except IndexError:
            pass

    with open(fname_wrapper, 'w') as outfile:
        for line in wrapperlines[4:-5]:
            line = line.replace('! in SHTOOLS.f95:SHTOOLS:unknown_interface',
                                '')
            if len(line) <= 80:
                outfile.write(line + '\n')
            else:
                elems = line.split(',')
                newline = elems[0]
                for elem in elems[1:]:
                    if len(newline) > 80:
                        outfile.write(newline + '&\n')
                        newline = ' ' * len(elems[0])
                    newline += ',' + elem
                outfile.write(newline + '\n')

    print('\n==== ALL DONE ====\n')
Example #20
0
 def test_dependencies(self, tmp_path):
     fpath = util.getpath("tests", "src", "crackfortran", "foo_deps.f90")
     mod = crackfortran.crackfortran([str(fpath)])
     assert len(mod) == 1
     assert mod[0]["vars"]["abar"]["="] == "bar('abar')"
def main():
    fname_fortran = 'SHTOOLS.f95'
    fname_wrapper = 'PythonWrapper.f95'
    outfile = open(fname_wrapper, 'w')

    print 'now cracking Fortran file SHTOOLS.f95 using f2py function...'
    crackfortran.verbose = False
    crackfortran.dolowercase = False
    cracked_shtools = crackfortran.crackfortran(fname_fortran)

    print 'decending through shtools module tree...'
    module = cracked_shtools[0]
    interface_old = module['body'][0]
    interface_new = deepcopy(interface_old)
    for subroutine in interface_new['body']:
        modify_subroutine(subroutine)

    print 'create interface string...'
    wrapper = crackfortran.crack2fortran(interface_new)
    wrapperlines = wrapper.split('\n')

    print 'add implicit none statements'
    # search for the indices of 'use shtools,' to insert 'implicit none' after
    iusestatement = [iline for iline, line in enumerate(wrapperlines) if 'use shtools,' in line]
    assert len(iusestatement) == len(interface_new['body']), 'number of subroutines don\'t match'
    for iline in iusestatement[::-1]:
        wrapperlines.insert(iline + 1, 2 * crackfortran.tabchar + 'implicit none')

    print 'add shtools subroutine calls...'
    # search for the indices of 'end subroutine'
    iendsubroutine = [iline for iline, line in enumerate(wrapperlines)
                      if 'end subroutine' in line or 'end function' in line]
    assert len(iendsubroutine) == len(interface_new['body']), 'number of subroutines don\'t match'

    # insert call statements before 'end subroutine' line starting from the end such that we
    # don't change the preceding indices
    for sroutine_new, sroutine_old, iline in zip(interface_new['body'],
                                                 interface_old['body'],
                                                 iendsubroutine)[::-1]:
        if sroutine_new['block'] == 'function':
            newline = 2 * crackfortran.tabchar +\
                '%s=%s(' % (sroutine_new['name'], sroutine_old['name']) +\
                ','.join(sroutine_old['args']) + ')'
        elif sroutine_new['block'] == 'subroutine':
            newline = 2 * crackfortran.tabchar +\
                'call %s(' % sroutine_old['name'] +\
                ','.join(sroutine_old['args']) + ')'
        wrapperlines.insert(iline + 1, '')
        wrapperlines.insert(iline, newline)

    print 'writing wrapper to file %s' % fname_wrapper
    for iline, line in enumerate(wrapperlines):
        try:
            firstword = line.split()[0]
            secondword = line.split()[1]
            words = ['real*8', 'integer', 'integer(kind=4)', 'character*(*)', 'complex*16']
            for word in words:
                if firstword == word and not secondword[0] == ':' or secondword[0] == ',':
                    line = line.replace(word, word + ',')
            wrapperlines[iline] = line
        except IndexError:
            pass

    for line in wrapperlines[4:-5]:
        line = line.replace('! in SHTOOLS.f95:SHTOOLS:unknown_interface', '')
        if len(line) <= 100:
            outfile.write(line + '\n')
        else:
            elems = line.split(',')
            newline = elems[0]
            for elem in elems[1:]:
                if len(newline) > 100:
                    outfile.write(newline + '&\n')
                    newline = ' ' * len(elems[0])
                newline += ',' + elem
            outfile.write(newline + '\n')

    outfile.close()
    print '\n==== ALL DONE ====\n'
Example #22
0
def to_magma(fin, module, magma_src, ignore_func=[]):
    if magma_src:
        magma_impl = [
            f[:-4] for f in os.listdir(magma_src) if f.endswith('.cpp')
        ]
    else:
        magma_impl = []

    ignores = []
    blocks = crackfortran([fin])
    cfile = []
    cfile.append('#include <cuda.h>')
    cfile.append('#include "magma_v2.h"')
    cfile.append('#include <stdio.h>')
    cfile.append('#include <stdlib.h>')
    cfile.append('typedef struct {float r,i;} complex_float;')
    cfile.append('typedef struct {double r,i;} complex_double;')
    for func in blocks[0]['body'][0]['body']:
        name = func['name']
        ignore = False
        for func_name in ignore_func:
            startswith = False
            endswith = False
            if func_name[0] == '*':
                endsswith = True
                func_name = func_name[1:]
            if func_name[-1] == '*':
                startswith = True
                func_name = func_name[:-1]
            if startswith:
                if name.startswith(func_name):
                    ignore = True
                    print(f'{name} ignored because starts with {func_name}')
            if endswith:
                if name.endswith(func_name):
                    ignore = True
                    print(f'{name} ignored because ends with {func_name}')
            if name == func_name:
                ignore = True
                print(f'{name} ignored because equals {func_name}')
        if name not in magma_impl:
            ignore = True
            print(f'{name} ignored because not found in MAGMA')
        if not ignore:
            if 'f2pyenhancements' in func:
                types = func['f2pyenhancements']['callprotoargument'].split(
                    ',')
            else:
                types = get_types(func['saved_interface'])
            magma_types, params, convs = get_magma_types(magma_src, name)
            if len(types) != len(magma_types):
                # not the same number of parameters, ignore this function
                ignore = True
                print(
                    f'{name} ignored because parameters between LAPACK and MAGMA mismatch'
                )
        if ignore:
            ignores.append(name)
        else:
            cwrap = []
            proto = []
            proto.append(f'void _magma_{name}(')
            proto.append(', '.join([f'{t} {p}'
                                    for t, p in zip(types, params)]))
            proto.append(') {')
            cwrap.append(''.join(proto))
            cwrap.append('#ifdef SCIPY_GPU_DEBUG')
            cwrap.append(f'    fprintf(stderr, "GPU {name}\\n");')
            for p, t in zip(params, types):
                pt = {'char*': 'c', 'int*': 'd'}.get(t, None)
                if pt:
                    cwrap.append(f'    fprintf(stderr, "{p}=%{pt}\\n", *{p});')
            cwrap.append('#endif')
            # MAGMA function call
            margs = []
            for p, t, mt, c in zip(params, types, magma_types, convs):
                if c:
                    ma = f'_magma_{p}_'
                    cwrap.append(f'    {c}')
                elif t == mt:
                    ma = p
                else:
                    ma = f'*{p}'
                margs.append(ma)
            margs = ', '.join(margs)
            cwrap.append(f'    magma_{name}({margs});')
            cwrap.append('}')
            cwrap = '\n'.join(cwrap)
            cfile.append(cwrap)

    with open(f'to_magma.c', 'wt') as f:
        f.write('\n'.join(cfile))

    with open(module) as f:
        clines = f.readlines()

    new_clines = []
    first_extern = True
    s0 = 'extern void F_FUNC('
    s1 = 'F_FUNC('
    for l in clines:
        line_done = False
        if not line_done:
            if (s0 in l) and not l.startswith('/*'):
                if first_extern:
                    first_extern = False
                    new_clines.append('extern void magma_init();\n')
                    new_clines.append('extern void magma_finalize();\n')
                i0 = l.find(s0) + len(s0)
                i1 = l.find(',')
                name = l[i0:i1]
                i2 = l.find(')')
                if name not in ignores:
                    line_done = True
                    new_l = f'extern void _magma_{name}' + l[i2 + 1:]
                    new_clines.append(new_l)
        if not line_done:
            if (s1 in l) and ('f2py_init_func') in l:
                i0 = l.find(s1)
                i1 = i0 + len(s1)
                i2 = l[i1:].find(',') + i1
                name = l[i1:i2]
                i3 = l[i1:].find(')') + i1
                if name not in ignores:
                    line_done = True
                    new_l = l[:i0] + f'_magma_{name}' + l[i3 + 1:]
                    new_clines.append(new_l)
        if not line_done:
            new_clines.append(l)

    i = len(new_clines)
    done = False
    while not done:
        i -= 1
        if 'return RETVAL;' in new_clines[i]:
            new_clines.insert(i, '  magma_init();\n')
            new_clines.insert(
                i, '  on_exit(magma_finalize,(void*)"_flapack");\n')
            done = True

    with open(module, 'wt') as f:
        f.write(''.join(new_clines))
Example #23
0
# Special setups
extra_link_args = []
if sys.platform == 'darwin':
    extra_link_args += [
        '-bundle', '-bundle_loader ' + sys.prefix + '/bin/python'
    ]
kwext = dict(libraries=libs,
             library_dirs=libdirs,
             extra_link_args=extra_link_args)

if __name__ == '__main__':

    # Generate pyf files
    crackfortran.f77modulename = '_core'
    pyfcode = crackfortran.crack2fortran(
        crackfortran.crackfortran(['lib/spanlib/spanlib_pywrap.f90']))
    f = open('lib/spanlib/spanlib.pyf', 'w')
    f.write(pyfcode)
    f.close()
    crackfortran.f77modulename = 'anaxv'
    pyfcode = crackfortran.crack2fortran(
        crackfortran.crackfortran(['lib/spanlib/anaxv.f90']))
    f = open('lib/spanlib/anaxv.pyf', 'w')
    f.write(pyfcode)
    f.close()

    # Setup the python module
    s = setup(
        name="spanlib",
        version=version,
        description=description,
Example #24
0
def main():
    fname_fortran = 'SHTOOLS.f95'
    fname_wrapper = 'PythonWrapper.f95'
    outfile = open(fname_wrapper, 'w')

    print 'now cracking Fortran file SHTOOLS.f95 using f2py function...'
    crackfortran.verbose = False
    crackfortran.dolowercase = False
    cracked_shtools = crackfortran.crackfortran(fname_fortran)

    print 'decending through shtools module tree...'
    module = cracked_shtools[0]
    interface_old = module['body'][0]
    interface_new = deepcopy(interface_old)
    for subroutine in interface_new['body']:
        modify_subroutine(subroutine)

    print 'create interface string...'
    wrapper = crackfortran.crack2fortran(interface_new)
    wrapperlines = wrapper.split('\n')

    print 'add implicit none statements'
    # search for the indices of 'use shtools,' to insert 'implicit none' after
    iusestatement = [
        iline for iline, line in enumerate(wrapperlines)
        if 'use shtools,' in line
    ]
    assert len(iusestatement) == len(
        interface_new['body']), 'number of subroutines don\'t match'
    for iline in iusestatement[::-1]:
        wrapperlines.insert(iline + 1,
                            2 * crackfortran.tabchar + 'implicit none')

    print 'add shtools subroutine calls...'
    # search for the indices of 'end subroutine'
    iendsubroutine = [
        iline for iline, line in enumerate(wrapperlines)
        if 'end subroutine' in line or 'end function' in line
    ]
    assert len(iendsubroutine) == len(
        interface_new['body']), 'number of subroutines don\'t match'

    # insert call statements before 'end subroutine' line starting from the end such that we
    # don't change the preceding indices
    for sroutine_new, sroutine_old, iline in zip(interface_new['body'],
                                                 interface_old['body'],
                                                 iendsubroutine)[::-1]:
        if sroutine_new['block'] == 'function':
            newline = 2 * crackfortran.tabchar +\
                '%s=%s(' % (sroutine_new['name'], sroutine_old['name']) +\
                ','.join(sroutine_old['args']) + ')'
        elif sroutine_new['block'] == 'subroutine':
            newline = 2 * crackfortran.tabchar +\
                'call %s(' % sroutine_old['name'] +\
                ','.join(sroutine_old['args']) + ')'
        wrapperlines.insert(iline + 1, '')
        wrapperlines.insert(iline, newline)

    print 'writing wrapper to file %s' % fname_wrapper
    for iline, line in enumerate(wrapperlines):
        try:
            firstword = line.split()[0]
            secondword = line.split()[1]
            words = [
                'real*8', 'integer', 'integer(kind=4)', 'character*(*)',
                'complex*16'
            ]
            for word in words:
                if firstword == word and not secondword[
                        0] == ':' or secondword[0] == ',':
                    line = line.replace(word, word + ',')
            wrapperlines[iline] = line
        except IndexError:
            pass

    for line in wrapperlines[4:-5]:
        line = line.replace('! in SHTOOLS.f95:SHTOOLS:unknown_interface', '')
        if len(line) <= 100:
            outfile.write(line + '\n')
        else:
            elems = line.split(',')
            newline = elems[0]
            for elem in elems[1:]:
                if len(newline) > 100:
                    outfile.write(newline + '&\n')
                    newline = ' ' * len(elems[0])
                newline += ',' + elem
            outfile.write(newline + '\n')

    outfile.close()
    print '\n==== ALL DONE ====\n'
Example #25
0
def process_fortran(filename):
    infos = []

    # read comments to obtain dimension information
    dimension_info = {}
    intent_info = {}
    with open(filename, "r") as f:
        text = f.read()
        for line in text.splitlines():
            m = re.match(
                r"^\*>\s+([A-Z]+) is INTEGER array, dimension \(([A-Z]+)\)\.?\s*$",
                line,
                flags=re.I,
            )
            if m:
                dimension_info[m.group(1).lower()] = ("var",
                                                      m.group(2).lower())

            m = re.match(
                r"^\*>\s+([A-Z]+) is INTEGER array, dimension \(min\(([A-Z]+),([A-Z]+)\)\)\.?\s*$",
                line,
                flags=re.I,
            )
            if m:
                dimension_info[m.group(1).lower()] = (
                    "min",
                    m.group(2).lower(),
                    m.group(3).lower(),
                )

            m = re.match(
                r"^\*>\s+([A-Z]+) is INTEGER array, dimension \(([0-9]+)\*min\(([A-Z]+),([A-Z]+)\)\)\.?\s*$",
                line,
                flags=re.I,
            )
            if m:
                dimension_info[m.group(1).lower()] = (
                    "mulmin",
                    int(m.group(2).lower()),
                    m.group(3).lower(),
                    m.group(4).lower(),
                )

            m = re.match(
                r"^\*>\s+([A-Z]+) is INTEGER array, dimension \(max\(1,([A-Z]+)\)\)\.?\s*$",
                line,
                flags=re.I,
            )
            if m:
                dimension_info[m.group(1).lower()] = ("var",
                                                      m.group(2).lower())

            m = re.match(
                r"^\*>\s+\\param\[(in|out|in,out)\]\s+([A-Z]+)\s*$",
                line,
                flags=re.I,
            )
            if m:
                intent_info[m.group(2).lower()] = m.group(1).split(",")

    # parse with f2py
    for info in crackfortran(filename):
        # Drop unnecessary info
        for kw in [
                "body", "entry", "externals", "from", "interfaced", "sortvars"
        ]:
            info.pop(kw, None)
        for varname, varinfo in info["vars"].items():
            for kw in ["check", "depend", "=", "attrspec"]:
                varinfo.pop(kw, None)

        # Determine integer array dimensions, if possible
        for varname, varinfo in info["vars"].items():
            if varinfo["typespec"] != "integer":
                continue

            dims = varinfo.get("dimension", [])

            if dims == ["*"]:
                dt, *di = dimension_info.get(varname, (None, None))

                if dt == "var" and di[0] in info["vars"]:
                    varinfo["dimension"] = di

                if dt == "min" and di[0] in info["vars"] and di[1] in info[
                        "vars"]:
                    varinfo["dimension"] = [{"min": di}]

                if dt == "mulmin" and di[1] in info["vars"] and di[2] in info[
                        "vars"]:
                    varinfo["dimension"] = [{"mulmin": di}]

            if varname in intent_info:
                varinfo["intent"] = intent_info[varname]

        infos.append(info)

    return filename, infos