Ejemplo n.º 1
0
 def generate_spec(self):
     assert self.fspec.targetlang == "python", "Wrong target language for this" " call"
     assert self.fspec.varspecs != {}, "varspecs attribute must be defined"
     specnames_unsorted = list(self.fspec.varspecs.keys())
     _vbfs_inv = invertMap(self.fspec._varsbyforspec)
     # Process state variable specifications
     if len(_vbfs_inv) > 0:
         specname_vars = []
         specname_auxvars = []
         for varname in self.fspec.vars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_vars:
                 specname_vars.append(varname)
         for varname in self.fspec.auxvars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_auxvars:
                 specname_auxvars.append(varname)
     else:
         specname_vars = intersect(self.fspec.vars, specnames_unsorted)
         specname_auxvars = intersect(self.fspec.auxvars, specnames_unsorted)
     specname_vars.sort()
     for vn, vs in list(self.fspec.varspecs.items()):
         if any([pt in vs for pt in ("^", "**")]):
             self.fspec.varspecs[vn] = convertPowers(vs, "pow")
     self.fspec.vars.sort()
     reusestr, specupdated = self._processReusedPy(specname_vars, self.fspec.varspecs)
     self.fspec.varspecs.update(specupdated)
     temp = self._specStrParse(specname_vars, self.fspec.varspecs, "xnew")
     specstr_py = self._generate_fun("_specfn", reusestr + temp, "xnew", specname_vars, docodeinserts=True)
     # Process auxiliary variable specifications
     specname_auxvars.sort()
     assert self.fspec.auxvars == specname_auxvars, (
         "Mismatch between declared auxiliary" " variable names and varspecs keys"
     )
     reusestraux, specupdated = self._processReusedPy(specname_auxvars, self.fspec.varspecs)
     self.fspec.varspecs.update(specupdated)
     tempaux = self._specStrParse(specname_auxvars, self.fspec.varspecs, "auxvals")
     auxspecstr_py = self._generate_fun(
         "_auxspecfn", reusestraux + tempaux, "auxvals", specname_auxvars, docodeinserts=True
     )
     try:
         spec_info = makeUniqueFn(specstr_py)
     except SyntaxError:
         print("Syntax error in specification:\n" + specstr_py)
         raise
     try:
         auxspec_info = makeUniqueFn(auxspecstr_py)
     except SyntaxError:
         print("Syntax error in auxiliary spec:\n" + auxspecstr_py)
         raise
     self.fspec.spec = spec_info
     self.fspec.auxspec = auxspec_info
Ejemplo n.º 2
0
 def generate_spec(self):
     assert self.fspec.targetlang == 'python', (
         'Wrong target language for this'
         ' call')
     assert self.fspec.varspecs != {}, 'varspecs attribute must be defined'
     specnames_unsorted = list(self.fspec.varspecs.keys())
     _vbfs_inv = invertMap(self.fspec._varsbyforspec)
     # Process state variable specifications
     if len(_vbfs_inv) > 0:
         specname_vars = []
         specname_auxvars = []
         for varname in self.fspec.vars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_vars:
                 specname_vars.append(varname)
         for varname in self.fspec.auxvars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_auxvars:
                 specname_auxvars.append(varname)
     else:
         specname_vars = intersect(self.fspec.vars, specnames_unsorted)
         specname_auxvars = intersect(self.fspec.auxvars,
                                      specnames_unsorted)
     specname_vars.sort()
     for vn, vs in list(self.fspec.varspecs.items()):
         if any([pt in vs for pt in ('^', '**')]):
             self.fspec.varspecs[vn] = convertPowers(vs, 'pow')
     self.fspec.vars.sort()
     reusestr, specupdated = self._processReusedPy(specname_vars,
                                                   self.fspec.varspecs)
     self.fspec.varspecs.update(specupdated)
     temp = self._specStrParse(specname_vars, self.fspec.varspecs, 'xnew')
     specstr_py = self._generate_fun('_specfn',
                                     reusestr + temp,
                                     'xnew',
                                     specname_vars,
                                     docodeinserts=True)
     # Process auxiliary variable specifications
     specname_auxvars.sort()
     assert self.fspec.auxvars == specname_auxvars, \
         ('Mismatch between declared auxiliary'
          ' variable names and varspecs keys')
     reusestraux, specupdated = self._processReusedPy(
         specname_auxvars, self.fspec.varspecs)
     self.fspec.varspecs.update(specupdated)
     tempaux = self._specStrParse(specname_auxvars, self.fspec.varspecs,
                                  'auxvals')
     auxspecstr_py = self._generate_fun('_auxspecfn',
                                        reusestraux + tempaux,
                                        'auxvals',
                                        specname_auxvars,
                                        docodeinserts=True)
     try:
         spec_info = makeUniqueFn(specstr_py)
     except SyntaxError:
         print("Syntax error in specification:\n" + specstr_py)
         raise
     try:
         auxspec_info = makeUniqueFn(auxspecstr_py)
     except SyntaxError:
         print("Syntax error in auxiliary spec:\n" + auxspecstr_py)
         raise
     self.fspec.spec = spec_info
     self.fspec.auxspec = auxspec_info
Ejemplo n.º 3
0
 def generate_spec(self):
     assert self.fspec.targetlang == "c", "Wrong target language for this" " call"
     assert self.fspec.varspecs != {}, "varspecs attribute must be defined"
     specnames_unsorted = list(self.fspec.varspecs.keys())
     _vbfs_inv = invertMap(self.fspec._varsbyforspec)
     # Process state variable specifications
     if len(_vbfs_inv) > 0:
         specname_vars = []
         specname_auxvars = []
         for varname in self.fspec.vars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_vars:
                 specname_vars.append(varname)
         for varname in self.fspec.auxvars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_auxvars:
                 specname_auxvars.append(varname)
     else:
         specname_vars = intersect(self.fspec.vars, specnames_unsorted)
         specname_auxvars = intersect(self.fspec.auxvars, specnames_unsorted)
     specname_vars.sort()
     # sorted version of var and par names
     pnames = self.fspec.pars
     inames = self.fspec.inputs
     pnames.sort()
     inames.sort()
     pardefines = ""
     vardefines = ""
     inpdefines = ""
     parundefines = ""
     varundefines = ""
     inpundefines = ""
     # produce vector field specification
     assert self.fspec.vars == specname_vars, (
         "Mismatch between declared " " variable names and varspecs keys"
     )
     valid_depTargNames = self.fspec.inputs + self.fspec.vars + self.fspec.auxvars
     for specname, specstr in self.fspec.varspecs.items():
         assert type(specstr) == str, (
             "Specification for %s was not a string" % specname
         )
         if any([pt in specstr for pt in ("^", "**")]):
             self.fspec.varspecs[specname] = convertPowers(specstr, "pow")
     # pre-process reused sub-expression dictionary to adapt for
     # known calling sequence in C
     reusestr, specupdated = self._processReusedC(specname_vars, self.fspec.varspecs)
     self.fspec.varspecs.update(specupdated)
     specstr_C = self._generate_fun(
         "vfieldfunc",
         reusestr,
         specname_vars,
         pardefines,
         vardefines,
         inpdefines,
         parundefines,
         varundefines,
         inpundefines,
         True,
     )
     self.fspec.spec = specstr_C
     # produce auxiliary variables specification
     specname_auxvars.sort()
     assert self.fspec.auxvars == specname_auxvars, (
         "Mismatch between declared auxiliary" " variable names and varspecs keys"
     )
     if self.fspec.auxvars != []:
         reusestraux, specupdated = self._processReusedC(
             specname_auxvars, self.fspec.varspecs
         )
         self.fspec.varspecs.update(specupdated)
     if self.fspec.auxvars == []:
         auxspecstr_C = self._generate_fun(
             "auxvars", "", specname_auxvars, "", "", "", "", "", "", False
         )
     else:
         auxspecstr_C = self._generate_fun(
             "auxvars",
             reusestraux,
             specname_auxvars,
             pardefines,
             vardefines,
             inpdefines,
             parundefines,
             varundefines,
             inpundefines,
             False,
         )
     self.fspec.auxspec = auxspecstr_C
Ejemplo n.º 4
0
def test_invertMap_for_dict():
    assert {'x': 'x', 'y': 'y'} == invertMap({'x': ['x'], 'y': ['y']})
Ejemplo n.º 5
0
def _processReused(specnames,
                   specdict,
                   reuseterms,
                   indentstr='',
                   typestr='',
                   endstatementchar='',
                   parseFunc=idfn):
    """Process substitutions of reused terms."""

    seenrepterms = []  # for new protected names (global to all spec names)
    reused = {}.fromkeys(specnames)
    reuseterms_inv = invertMap(reuseterms)
    # establish order for reusable terms, in case of inter-dependencies
    are_dependent = []
    deps = {}
    for origterm, rterm in reuseterms.items():
        for _, rt in reuseterms.items():
            if proper_match(origterm, rt):
                if rterm not in are_dependent:
                    are_dependent.append(rterm)
                try:
                    deps[rterm].append(rt)
                except KeyError:
                    # new list
                    deps[rterm] = [rt]
    order = remain(sorted(reuseterms.values()), are_dependent) + are_dependent
    for specname in specnames:
        reused[specname] = []
        specstr = specdict[specname]
        repeatkeys = []
        for origterm, repterm in reuseterms.items():
            # only add definitions if string found
            if proper_match(specstr, origterm):
                specstr = specstr.replace(origterm, repterm)
                if repterm not in seenrepterms:
                    reused[specname].append([
                        indentstr, typestr + ' ' * (len(typestr) > 0), repterm,
                        " = ",
                        parseFunc(origterm), endstatementchar, "\n"
                    ])
                    seenrepterms.append(repterm)
            else:
                # look for this term on second pass
                repeatkeys.append(origterm)
        if len(seenrepterms) > 0:
            # don't bother with a second pass if specstr has not changed
            for origterm in repeatkeys:
                # second pass
                repterm = reuseterms[origterm]
                if proper_match(specstr, origterm):
                    specstr = specstr.replace(origterm, repterm)
                    if repterm not in seenrepterms:
                        seenrepterms.append(repterm)
                        reused[specname].append([
                            indentstr, typestr + ' ' * (len(typestr) > 0),
                            repterm, " = ",
                            parseFunc(origterm), endstatementchar, "\n"
                        ])
        # if replacement terms have already been used in the specifications
        # and there are no occurrences of the terms meant to be replaced then
        # just log the definitions that will be needed without replacing
        # any strings.
        if reused[specname] == [] and len(reuseterms) > 0:
            for origterm, repterm in reuseterms.items():
                # add definition if *replacement* string found in specs
                if proper_match(specstr,
                                repterm) and repterm not in seenrepterms:
                    reused[specname].append([
                        indentstr, typestr + ' ' * (len(typestr) > 0), repterm,
                        " = ",
                        parseFunc(origterm), endstatementchar, "\n"
                    ])
                    seenrepterms.append(repterm)
        specdict[specname] = specstr
        # add any dependencies for repeated terms to those that will get
        # defined when functions are instantiated
        for r in seenrepterms:
            if r in are_dependent:
                for repterm in deps[r]:
                    if repterm not in seenrepterms:
                        reused[specname].append([
                            indentstr, typestr + ' ' * (len(typestr) > 0),
                            repterm, " = ",
                            parseFunc(reuseterms_inv[repterm]),
                            endstatementchar, "\n"
                        ])
                        seenrepterms.append(repterm)
    # reuseterms may be automatically provided for a range of definitions
    # that may or may not contain instances, and it's too inefficient to
    # check in advance, so we'll not cause an error here if none show up.
    # if len(seenrepterms) == 0 and len(reuseterms) > 0:
    #     print("Reuse terms expected:%r" % reuseterms)
    #     info(specdict)
    #     raise RuntimeError("Declared reusable term definitions did not match"
    #                        " any occurrences in the specifications")
    return (reused, specdict, seenrepterms, order)
Ejemplo n.º 6
0
 def generate_spec(self):
     assert self.fspec.targetlang == 'c', ('Wrong target language for this'
                                      ' call')
     assert self.fspec.varspecs != {}, 'varspecs attribute must be defined'
     specnames_unsorted = list(self.fspec.varspecs.keys())
     _vbfs_inv = invertMap(self.fspec._varsbyforspec)
     # Process state variable specifications
     if len(_vbfs_inv) > 0:
         specname_vars = []
         specname_auxvars = []
         for varname in self.fspec.vars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_vars:
                 specname_vars.append(varname)
         for varname in self.fspec.auxvars:
             # check if varname belongs to a for macro grouping in
             # self.fspec.varspecs
             if varname not in specname_auxvars:
                 specname_auxvars.append(varname)
     else:
         specname_vars = intersect(self.fspec.vars, specnames_unsorted)
         specname_auxvars = intersect(self.fspec.auxvars, specnames_unsorted)
     specname_vars.sort()
     # sorted version of var and par names
     pnames = self.fspec.pars
     inames = self.fspec.inputs
     pnames.sort()
     inames.sort()
     pardefines = ""
     vardefines = ""
     inpdefines = ""
     parundefines = ""
     varundefines = ""
     inpundefines = ""
     # produce vector field specification
     assert self.fspec.vars == specname_vars, ('Mismatch between declared '
                                          ' variable names and varspecs keys')
     valid_depTargNames = self.fspec.inputs + self.fspec.vars + self.fspec.auxvars
     for specname, specstr in self.fspec.varspecs.items():
         assert type(
             specstr) == str, "Specification for %s was not a string" % specname
         if any([pt in specstr for pt in ('^', '**')]):
             self.fspec.varspecs[specname] = convertPowers(specstr, 'pow')
     # pre-process reused sub-expression dictionary to adapt for
     # known calling sequence in C
     reusestr, specupdated = self._processReusedC(specname_vars,
                                                  self.fspec.varspecs)
     self.fspec.varspecs.update(specupdated)
     specstr_C = self._generate_fun(
         'vfieldfunc', reusestr, specname_vars,
         pardefines, vardefines, inpdefines,
         parundefines, varundefines, inpundefines,
         True)
     self.fspec.spec = specstr_C
     # produce auxiliary variables specification
     specname_auxvars.sort()
     assert self.fspec.auxvars == specname_auxvars, \
         ('Mismatch between declared auxiliary'
          ' variable names and varspecs keys')
     if self.fspec.auxvars != []:
         reusestraux, specupdated = self._processReusedC(
             specname_auxvars,
             self.fspec.varspecs)
         self.fspec.varspecs.update(specupdated)
     if self.fspec.auxvars == []:
         auxspecstr_C = self._generate_fun('auxvars', '',
                                           specname_auxvars,
                                           '', '', '',
                                           '', '', '', False)
     else:
         auxspecstr_C = self._generate_fun('auxvars', reusestraux,
                                           specname_auxvars, pardefines,
                                           vardefines, inpdefines, parundefines,
                                           varundefines, inpundefines,
                                           False)
     self.fspec.auxspec = auxspecstr_C
Ejemplo n.º 7
0
def _processReused(specnames, specdict, reuseterms, indentstr='',
                   typestr='', endstatementchar='', parseFunc=idfn):
    """Process substitutions of reused terms."""

    seenrepterms = []  # for new protected names (global to all spec names)
    reused = {}.fromkeys(specnames)
    reuseterms_inv = invertMap(reuseterms)
    # establish order for reusable terms, in case of inter-dependencies
    are_dependent = []
    deps = {}
    for origterm, rterm in reuseterms.iteritems():
        for _, rt in reuseterms.iteritems():
            if proper_match(origterm, rt):
                if rterm not in are_dependent:
                    are_dependent.append(rterm)
                try:
                    deps[rterm].append(rt)
                except KeyError:
                    # new list
                    deps[rterm] = [rt]
    order = remain(reuseterms.values(), are_dependent) + are_dependent
    for specname in specnames:
        reused[specname] = []
        specstr = specdict[specname]
        repeatkeys = []
        for origterm, repterm in reuseterms.iteritems():
            # only add definitions if string found
            if proper_match(specstr, origterm):
                specstr = specstr.replace(origterm, repterm)
                if repterm not in seenrepterms:
                    reused[specname].append([indentstr,
                                             typestr + ' ' *
                                             (len(typestr) > 0),
                                             repterm, " = ",
                                             parseFunc(origterm),
                                             endstatementchar, "\n"])
                    seenrepterms.append(repterm)
            else:
                # look for this term on second pass
                repeatkeys.append(origterm)
        if len(seenrepterms) > 0:
            # don't bother with a second pass if specstr has not changed
            for origterm in repeatkeys:
                # second pass
                repterm = reuseterms[origterm]
                if proper_match(specstr, origterm):
                    specstr = specstr.replace(origterm, repterm)
                    if repterm not in seenrepterms:
                        seenrepterms.append(repterm)
                        reused[specname].append([indentstr,
                                                 typestr + ' ' *
                                                 (len(typestr) > 0),
                                                 repterm, " = ",
                                                 parseFunc(origterm),
                                                 endstatementchar, "\n"])
        # if replacement terms have already been used in the specifications
        # and there are no occurrences of the terms meant to be replaced then
        # just log the definitions that will be needed without replacing
        # any strings.
        if reused[specname] == [] and len(reuseterms) > 0:
            for origterm, repterm in reuseterms.iteritems():
                # add definition if *replacement* string found in specs
                if proper_match(specstr, repterm) and repterm not in seenrepterms:
                    reused[specname].append([indentstr,
                                             typestr + ' ' *
                                             (len(typestr) > 0),
                                             repterm, " = ",
                                             parseFunc(origterm),
                                             endstatementchar, "\n"])
                    seenrepterms.append(repterm)
        specdict[specname] = specstr
        # add any dependencies for repeated terms to those that will get
        # defined when functions are instantiated
        for r in seenrepterms:
            if r in are_dependent:
                for repterm in deps[r]:
                    if repterm not in seenrepterms:
                        reused[specname].append([indentstr,
                                                 typestr + ' ' *
                                                 (len(typestr) > 0),
                                                 repterm, " = ",
                                                 parseFunc(
                                                     reuseterms_inv[repterm]),
                                                 endstatementchar, "\n"])
                        seenrepterms.append(repterm)
    # reuseterms may be automatically provided for a range of definitions
    # that may or may not contain instances, and it's too inefficient to
    # check in advance, so we'll not cause an error here if none show up.
    # if len(seenrepterms) == 0 and len(reuseterms) > 0:
    #     print "Reuse terms expected:", reuseterms
    #     info(specdict)
    #     raise RuntimeError("Declared reusable term definitions did not match"
    #                        " any occurrences in the specifications")
    return (reused, specdict, seenrepterms, order)