Beispiel #1
0
def ifcondcheck(condexpr, threshold):
    def get_nodes(node, bag, depth):
        if node and not hasattr(node, 'items'):
            bag['nodes'].append(node)

    bag = {'nodes': []}
    traverse(condexpr, get_nodes, bag)
    nodes = bag['nodes']

    if len(nodes) > threshold:
        return True
    else:
        return False
Beispiel #2
0
def ifcondcheck(condexpr, threshold):
    def get_nodes(node, bag, depth):
        if node and not hasattr(node, 'items'):
            bag['nodes'].append(node)

    bag = {'nodes': []}
    traverse(condexpr, get_nodes, bag)
    nodes = bag['nodes']

    if len(nodes) > threshold:
        return True
    else:
        return False
Beispiel #3
0
    def tokgen(self):
        from kgen_utils import traverse

        def get_edecl(node, bag, depth):
            from Fortran2003 import Entity_Decl

            if isinstance(node, Entity_Decl) and node.items[0].string == bag["name"]:
                bag["edecl"] = node.tostr()
                return True

        decls = self.entity_decls
        if hasattr(self, "new_entity_decls"):
            decls = []
            for decl in self.new_entity_decls:
                edecl = {"name": decl, "edecl": decl}
                if hasattr(self, "full_decl") and self.full_decl:
                    traverse(self.f2003, get_edecl, edecl)
                decls.append(edecl["edecl"])
            del new_entity_decls

        attrs = self.attrspec if hasattr(self, "attrspec") else None
        if hasattr(self, "new_attrspec"):
            attrs = []
            for attr in self.new_attr_specs:
                attrs.append(attr)
            del self.new_attr_specs

        if hasattr(self, "remove_attr"):
            newattrs = []
            for attr in attrs:
                if any(attr.startswith(rattr) for rattr in self.remove_attr):
                    pass
                else:
                    newattrs.append(attr)
            attrs = newattrs
            del self.remove_attr

        s = self.tostr()
        if attrs:
            s += ", " + ", ".join(attrs)
        if decls:
            s += " :: " + ", ".join(decls)
        return s
Beispiel #4
0
    def tokgen(self):
        from kgen_utils import traverse

        def get_edecl(node, bag, depth):
            from Fortran2003 import Entity_Decl
            if isinstance(node,
                          Entity_Decl) and node.items[0].string == bag['name']:
                bag['edecl'] = node.tostr()
                return True

        decls = self.entity_decls
        if hasattr(self, 'new_entity_decls'):
            decls = []
            for decl in self.new_entity_decls:
                edecl = {'name': decl, 'edecl': decl}
                if hasattr(self, 'full_decl') and self.full_decl:
                    traverse(self.f2003, get_edecl, edecl)
                decls.append(edecl['edecl'])
            del new_entity_decls

        attrs = self.attrspec if hasattr(self, 'attrspec') else None
        if hasattr(self, 'new_attrspec'):
            attrs = []
            for attr in self.new_attr_specs:
                attrs.append(attr)
            del self.new_attr_specs

        if hasattr(self, 'remove_attr'):
            newattrs = []
            for attr in attrs:
                if any(attr.startswith(rattr) for rattr in self.remove_attr):
                    pass
                else:
                    newattrs.append(attr)
            attrs = newattrs
            del self.remove_attr

        s = self.tostr()
        if attrs:
            s += ', ' + ', '.join(attrs)
        if decls:
            s += ' :: ' + ', '.join(decls)
        return s
Beispiel #5
0
def preprocess():
    from kgen_state import SrcFile

    if Config.check_mode:
        check_mode()
        sys.exit(0)
    else:
        if Config.mpi['enabled']:
            # get path of mpif.h
            mpifpath = ''
            if os.path.isabs(Config.mpi['header']):
                if os.path.exists(Config.mpi['header']):
                    mpifpath = Config.mpi['header']
                else:
                    raise UserException('Can not find %s' %
                                        Config.mpi['header'])
            else:
                for p in Config.include['path']:  # KGEN addition
                    fp = os.path.join(p, Config.mpi['header'])
                    if os.path.exists(fp):
                        mpifpath = fp
                        break

            # collect required information
            if mpifpath:
                try:
                    reader = FortranFileReader(
                        mpifpath, include_dirs=Config.include['path'])
                    spec = Specification_Part(reader)

                    bag = {}
                    if Config.mpi['comm'] is None:
                        bag['key'] = 'MPI_COMM_WORLD'
                        bag[bag['key']] = []
                        traverse(spec, get_MPI_PARAM, bag, subnode='content')
                        if bag.has_key(bag['key']):
                            Config.mpi['comm'] = bag[bag['key']][-1]
                        else:
                            raise UserException(
                                'Can not find MPI_COMM_WORLD in mpif.h')

                    if Config.mpi['logical'] is None:
                        bag['key'] = 'MPI_LOGICAL'
                        bag[bag['key']] = []
                        traverse(spec, get_MPI_PARAM, bag, subnode='content')
                        if bag.has_key(bag['key']):
                            Config.mpi['logical'] = bag[bag['key']][-1]
                        else:
                            raise UserException(
                                'Can not find MPI_LOGICAL in mpif.h')

                    if Config.mpi['status_size'] is None:
                        bag['key'] = 'MPI_STATUS_SIZE'
                        bag[bag['key']] = []
                        traverse(spec, get_MPI_PARAM, bag, subnode='content')
                        if bag.has_key(bag['key']):
                            Config.mpi['status_size'] = bag[bag['key']][-1]
                        else:
                            raise UserException(
                                'Can not find MPI_STATUS_SIZE in mpif.h')

                    if Config.mpi['any_source'] is None:
                        bag['key'] = 'MPI_ANY_SOURCE'
                        bag[bag['key']] = []
                        traverse(spec, get_MPI_PARAM, bag, subnode='content')
                        if bag.has_key(bag['key']):
                            Config.mpi['any_source'] = bag[bag['key']][-1]
                        else:
                            raise UserException(
                                'Can not find MPI_ANY_SOURCE in mpif.h')

                    if Config.mpi['source'] is None:
                        bag['key'] = 'MPI_SOURCE'
                        bag[bag['key']] = []
                        traverse(spec, get_MPI_PARAM, bag, subnode='content')
                        if bag.has_key(bag['key']):
                            Config.mpi['source'] = bag[bag['key']][-1]
                        else:
                            raise UserException(
                                'Can not find MPI_SOURCE in mpif.h')

                except Exception as e:
                    raise UserException('Error occurred during reading %s.' %
                                        mpifpath)
            else:
                raise UserException(
                    'Can not find mpif.h. Please provide a path to the file')

        # parse imported source files through include.ini
        for path, import_type in Config.include['import'].iteritems():
            if 'source' == import_type:
                State.imported['source'].append(SrcFile(path))
Beispiel #6
0
def locate_callsite(cs_tree):
    from statements import Comment
    from block_statements import executable_construct
    import re

    def get_next_non_comment(stmt):
        if not stmt: return
        if not hasattr(stmt, 'parent'): return

        started = False
        for s in stmt.parent.content:
            if s == stmt:
                if not isinstance(s, Comment): return s
                started = True
            elif started:
                if not isinstance(s, Comment): return s

    def get_names(node, bag, depth):
        from Fortran2003 import Name
        if isinstance(node, Name) and not node.string in bag:
            bag.append(node.string)

    # collect directives
    directs = []
    for stmt, depth in walk(cs_tree):
        if isinstance(stmt, Comment):
            line = stmt.item.comment.strip()
            match = re.match(r'^[c!*]\$kgen\s+(.+)$', line, re.IGNORECASE)
            if match:
                dsplit = match.group(1).split(' ', 1)
                dname = dsplit[0].strip()
                if len(dsplit) > 1: clause = dsplit[1].strip()
                else: clause = None

                if dname.startswith('begin_'):
                    sname = dname[6:]
                    directs.append(sname)
                    State.kernel['name'] = clause
                elif dname.startswith('end_'):
                    ename = dname[4:]
                    if directs[-1] == ename:
                        directs.pop()
                        if ename == 'callsite':
                            pass
                        else:
                            raise UserException(
                                'WARNING: Not supported KGEN directive: %s' %
                                ename)
                    else:
                        raise UserException('Directive name mismatch: %s, %s' %
                                            (dname_stack[-1], ename))
                elif dname == 'callsite':
                    next_fort_stmt = get_next_non_comment(stmt)
                    if next_fort_stmt:
                        State.kernel['name'] = clause
                        State.callsite['stmts'].append(next_fort_stmt)
                    else:
                        raise UserException('WARNING: callsite is not found')
        else:
            if Config.callsite[
                    'namepath'] and stmt.__class__ in executable_construct:
                names = []
                traverse(stmt.f2003, get_names, names)
                for name in names:
                    if match_namepath(Config.callsite['namepath'],
                                      pack_exnamepath(stmt, name),
                                      internal=False):
                        State.kernel['name'] = name
                        for _s, _d in walk(stmt):
                            State.callsite['stmts'].append(_s)
                        return
            elif len(directs) > 0 and directs[-1] == 'callsite':
                State.callsite['stmts'].append(stmt)

    if len(State.callsite['stmts']) == 0:
        raise UserException('Can not find callsite')
Beispiel #7
0
def update_state_info(parent):
    def get_nodes(node, bag, depth):
        from Fortran2003 import Name
        if isinstance(
                node, Name
        ) and node.string == bag['name'] and not node.parent in bag:
            anc = [node]
            while hasattr(node, 'parent'):
                anc.insert(0, node.parent)
                node = node.parent
            bag['lineage'].append(anc)

    if hasattr(parent, 'content'):
        for stmt in parent.content:
            if isinstance(stmt, TypeDeclarationStatement) and \
                "parameter" not in stmt.attrspec and hasattr(stmt, 'geninfo') and \
                any(len(v)>0 for v in stmt.geninfo.values()):
                for uname, req in KGGenType.get_state_in(stmt.geninfo):
                    if KGGenType.has_uname_out(uname, stmt.geninfo): continue

                    org = req.originator
                    if org in State.callsite['stmts']:
                        bag = {'name': uname.firstpartname(), 'lineage': []}
                        traverse(org.f2003, get_nodes, bag)
                        for lineage in bag['lineage']:
                            copied = False
                            for lidx, anc in enumerate(lineage):
                                # get callname
                                callname = None
                                if anc.__class__ in [
                                        Call_Stmt, Function_Reference
                                ]:
                                    callname = anc.items[0].string
                                elif anc.__class__ == Part_Ref:
                                    callname = anc.items[0].string
                                elif anc.__class__ == Interface_Stmt:
                                    callname = anc.items[0].string

                                # get caller and callee objects
                                callobj = None
                                subpobj = None
                                if callname:
                                    for org_uname, org_req in org.unknowns.iteritems(
                                    ):
                                        if org_uname.firstpartname(
                                        ) == callname:
                                            if isinstance(
                                                    org_req.res_stmts[0],
                                                    SubProgramStatement):
                                                callobj = anc
                                                subpobj = org_req.res_stmts[0]
                                            break

                                # get argument index
                                argidx = -1
                                is_keyword = False
                                if callobj and subpobj:
                                    if callobj.__class__ in [
                                            Call_Stmt, Function_Reference
                                    ]:
                                        arglist = callobj.items[1]
                                        if arglist is None: pass
                                        elif isinstance(
                                                arglist, Actual_Arg_Spec):
                                            argobj = lineage[lidx + 1]
                                            kword = argobj.items[0].string
                                            argidx = subpobj.args.index(kword)
                                        elif isinstance(
                                                arglist, Actual_Arg_Spec_List):
                                            #if len(lineage)<(lidx+3): import pdb; pdb.set_trace()
                                            argobj = lineage[lidx + 2]
                                            argidx = arglist.items.index(
                                                argobj)
                                            if isinstance(
                                                    argobj, Actual_Arg_Spec):
                                                kword = argobj.items[0].string
                                                argidx = subpobj.args.index(
                                                    kword)
                                        else:
                                            argidx = 0
                                    elif anc.__class__ == Part_Ref:
                                        arglist = callobj.items[1]
                                        if arglist is None: pass
                                        elif isinstance(
                                                arglist,
                                                Structure_Constructor_2):
                                            argobj = lineage[lidx + 1]
                                            kword = argobj.items[0].string
                                            argidx = subpobj.args.index(kword)
                                        elif isinstance(
                                                arglist,
                                                Section_Subscript_List):
                                            #if len(lineage)<(lidx+3): import pdb; pdb.set_trace()
                                            argobj = lineage[lidx + 2]
                                            argidx = arglist.items.index(
                                                argobj)
                                            if isinstance(
                                                    argobj,
                                                    Structure_Constructor_2):
                                                kword = argobj.items[0].string
                                                argidx = subpobj.args.index(
                                                    kword)
                                        else:
                                            argidx = 0
                                    elif anc.__class__ == Interface_Stmt:
                                        import pdb
                                        pdb.set_trace()

                                # get intent
                                if argidx >= 0:
                                    argname = subpobj.args[argidx]
                                    var = subpobj.a.variables[
                                        subpobj.args[argidx]]
                                    if var.is_intent_out(
                                    ) or var.is_intent_inout():
                                        req.gentype = KGGenType.STATE_OUT
                                        stmt.add_geninfo(uname, req)
                                        copied = True
                                        break
                            if copied: break

    if hasattr(parent, 'parent'):
        update_state_info(parent.parent)
Beispiel #8
0
def locate_callsite(cs_tree):
    from statements import Comment
    from block_statements import executable_construct
    import re

    def get_next_non_comment(stmt):
        if not stmt: return
        if not hasattr(stmt, 'parent'): return

        started = False
        for s in stmt.parent.content:
            if s==stmt:
                if not isinstance(s, Comment): return s
                started = True
            elif started:
                if not isinstance(s, Comment): return s

    def get_names(node, bag, depth):
        from Fortran2003 import Name
        if isinstance(node, Name) and not node.string in bag:
            bag.append(node.string)
       
    # collect directives
    directs = []
    for stmt, depth in walk(cs_tree):
        if isinstance(stmt, Comment):
            line = stmt.item.comment.strip()
            match = re.match(r'^[c!*]\$kgen\s+(.+)$', line, re.IGNORECASE)
            if match:
                dsplit = match.group(1).split(' ', 1)
                dname = dsplit[0].strip()
                if len(dsplit)>1: clause = dsplit[1].strip()
                else: clause = None

                if dname.startswith('begin_'):
                    sname = dname[6:]
                    directs.append(sname)
                    State.kernel['name'] = clause
                elif dname.startswith('end_'):
                    ename = dname[4:]
                    if directs[-1]==ename:
                        directs.pop()
                        if ename=='callsite':
                            pass
                        else:
                            raise UserException('WARNING: Not supported KGEN directive: %s'%ename)
                    else:
                        raise UserException('Directive name mismatch: %s, %s'%(dname_stack[-1], ename))
                elif dname=='callsite':
                    next_fort_stmt = get_next_non_comment(stmt)
                    if next_fort_stmt:
                        State.kernel['name'] = clause
                        State.callsite['stmts'].append(next_fort_stmt)
                    else:
                        raise UserException('WARNING: callsite is not found')
            elif 'callsite' in directs:
                State.callsite['stmts'].append(stmt)
        elif 'callsite' in directs:
            State.callsite['stmts'].append(stmt)
        else:
            if Config.callsite['namepath'] and stmt.__class__ in executable_construct:
                names = []
                traverse(stmt.f2003, get_names, names)
                for name in names:
                    if match_namepath(Config.callsite['namepath'], pack_exnamepath(stmt, name), internal=False):
                        State.kernel['name'] = name
                        for _s, _d in walk(stmt):
                            State.callsite['stmts'].append(_s)
                        return
            elif len(directs)>0 and directs[-1]=='callsite':
                State.callsite['stmts'].append(stmt)

    if len(State.callsite['stmts'])==0:
        raise UserException('Can not find callsite')
Beispiel #9
0
def update_state_info(parent):

    def get_nodes(node, bag, depth):
        from Fortran2003 import Name
        if isinstance(node, Name) and node.string==bag['name'] and not node.parent in bag:
            anc = [node]
            while hasattr(node, 'parent'):
                anc.insert(0, node.parent)
                node = node.parent
            bag['lineage'].append(anc)

    if hasattr(parent, 'content'):
        for stmt in parent.content:
            if isinstance(stmt, TypeDeclarationStatement) and \
                "parameter" not in stmt.attrspec and hasattr(stmt, 'geninfo') and \
                any(len(v)>0 for v in stmt.geninfo.values()):
                for uname, req in KGGenType.get_state_in(stmt.geninfo):
                    if KGGenType.has_uname_out(uname, stmt.geninfo): continue

                    org = req.originator
                    if org in State.callsite['stmts']:
                        bag = {'name': uname.firstpartname(), 'lineage': [] }
                        traverse(org.f2003, get_nodes, bag)
                        for lineage in bag['lineage']:
                            copied = False
                            for lidx, anc in enumerate(lineage):
                                # get callname
                                callname = None
                                if anc.__class__ in [ Call_Stmt, Function_Reference ]:
                                    callname = anc.items[0].string
                                elif anc.__class__ == Part_Ref:
                                    callname = anc.items[0].string
                                elif anc.__class__ == Interface_Stmt:
                                    callname = anc.items[0].string

                                # get caller and callee objects
                                callobj = None
                                subpobj = None
                                if callname:
                                    for org_uname, org_req in org.unknowns.iteritems():
                                        if org_uname.firstpartname()==callname:
                                            if isinstance(org_req.res_stmts[0], SubProgramStatement):
                                                callobj = anc
                                                subpobj = org_req.res_stmts[0]
                                            break
                                    
                                # get argument index
                                argidx = -1
                                is_keyword = False
                                if callobj and subpobj:
                                    if callobj.__class__ in [ Call_Stmt, Function_Reference ]:
                                        arglist = callobj.items[1]
                                        if arglist is None: pass
                                        elif isinstance(arglist, Actual_Arg_Spec):
                                            argobj = lineage[lidx+1]
                                            kword = argobj.items[0].string
                                            argidx = subpobj.args.index(kword)
                                        elif isinstance(arglist, Actual_Arg_Spec_List):
                                            #if len(lineage)<(lidx+3): import pdb; pdb.set_trace()
                                            argobj = lineage[lidx+2]
                                            argidx = arglist.items.index(argobj)
                                            if isinstance(argobj, Actual_Arg_Spec):
                                                kword = argobj.items[0].string
                                                argidx = subpobj.args.index(kword)
                                        else:
                                            argidx = 0
                                    elif anc.__class__ == Part_Ref:
                                        arglist = callobj.items[1]
                                        if arglist is None: pass
                                        elif isinstance(arglist, Structure_Constructor_2):
                                            argobj = lineage[lidx+1]
                                            kword = argobj.items[0].string
                                            argidx = subpobj.args.index(kword)
                                        elif isinstance(arglist, Section_Subscript_List):
                                            #if len(lineage)<(lidx+3): import pdb; pdb.set_trace()
                                            argobj = lineage[lidx+2]
                                            argidx = arglist.items.index(argobj)
                                            if isinstance(argobj, Structure_Constructor_2):
                                                kword = argobj.items[0].string
                                                argidx = subpobj.args.index(kword)
                                        else:
                                            argidx = 0
                                    elif anc.__class__ == Interface_Stmt:
                                        import pdb; pdb.set_trace()

                                # get intent
                                if argidx>=0:
                                    argname = subpobj.args[argidx]
                                    var = subpobj.a.variables[subpobj.args[argidx]]
                                    if var.is_intent_out() or var.is_intent_inout():
                                        req.gentype = KGGenType.STATE_OUT
                                        stmt.add_geninfo(uname, req)
                                        copied = True
                                        break
                            if copied: break

    if hasattr(parent, 'parent'):
        update_state_info(parent.parent)
Beispiel #10
0
def preprocess():
    from kgen_state import SrcFile

    if Config.check_mode:
        check_mode()
        sys.exit(0)
    else:
        if Config.mpi['enabled']:
            # get path of mpif.h
            mpifpath = ''
            if os.path.isabs(Config.mpi['header']):
                if os.path.exists(Config.mpi['header']):
                    mpifpath = Config.mpi['header']
                else:
                    raise UserException('Can not find %s'%Config.mpi['header'])
            else:
                for p in Config.include['path']:
                    fp = os.path.join(p, Config.mpi['header'])
                    if os.path.exists(fp):
                        mpifpath = fp
                        break
                if not mpifpath:
                    for incpath, incdict in Config.include['file'].items():
                        for p in incdict['path']:
                            fp = os.path.join(p, Config.mpi['header'])
                            if os.path.exists(fp):
                                mpifpath = fp
                                break
                        if mpifpath: break

            # collect required information
            # TODO: FortranFileReader should be replaced with FortranStringReader after preprocessing
            # TODO: include keyword should be handdled properly too.
            if mpifpath:
                try:
                    reader = FortranFileReader(mpifpath, include_dirs = Config.include['path'])
                    spec = Specification_Part(reader)

                    bag = {}
                    config_name_mapping = [
                        ('comm', 'MPI_COMM_WORLD'),
                        ('logical', 'MPI_LOGICAL'),
                        ('status_size', 'MPI_STATUS_SIZE'),
                        ('any_source', 'MPI_ANY_SOURCE'),
                        ('source', 'MPI_SOURCE'),
                        ]
                    for config_key, name in config_name_mapping:
                        if not Config.mpi.has_key(config_key) or Config.mpi[config_key] is None:
                            bag['key'] = name
                            bag[name] = []
                            traverse(spec, get_MPI_PARAM, bag, subnode='content')
                            if len(bag[name]) > 0:
                                Config.mpi[config_key] = bag[name][-1]
                            else:
                                raise UserException('Can not find {name} in mpif.h'.format(name=name))

                except UserException:
                    raise  # Reraise this exception rather than catching it below
                except Exception as e:
                    raise UserException('Error occurred during reading %s.'%mpifpath)
            else:
                raise UserException('Can not find mpif.h. Please provide a path to the file')

        # parse imported source files through include.ini
        for path, import_type in Config.include['import'].iteritems(): 
            if 'source'==import_type:
                State.imported['source'].append(SrcFile(path))