示例#1
0
    def readMeasuredValueFromFile(location):
        """Reads the measured value of a path from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            Measured value of a path, represented as a number
            (either an integer or a floating-point number).
        """
        try:
            measuredValueFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading the measured value of a path from "
                      "the file located at %s: %s" % (location, e))
            raise GameTimeError(errMsg)
        else:
            with measuredValueFileHandler:
                line = measuredValueFileHandler.readline().strip()
                try:
                    result = int(line)
                except ValueError:
                    try:
                        result = float(line)
                    except ValueError:
                        errMsg = ("The following line, in the file located "
                                  "at %s, does not represent a valid "
                                  "measured value of a path: %s" %
                                  (location, line))
                        raise GameTimeError(errMsg)
                return result
示例#2
0
    def setSmtSolverAndModelParser(self, smtSolverName):
        """
        Sets the SMT solver and model parser objects associated with this
        :class:`~gametime.projectConfiguration.ProjectConfiguration`
        object to ones that can interface with the SMT solver
        whose name is provided.

        Arguments:
            smtSolverName:
                Name of an SMT solver.
        """
        smtSolverName = smtSolverName.lower()
        if smtSolverName.startswith("boolector"):
            if config.SOLVER_BOOLECTOR == "":
                errMsg = ("The Boolector executable was not found "
                          "during the configuration of GameTime. "
                          "This GameTime project cannot use Boolector "
                          "as its backend SMT solver.")
                raise GameTimeError(errMsg)
            else:
                from smt.solvers.boolectorSolver import BoolectorSolver
                from smt.solvers.boolectorSolver import SatSolver
                satSolverName = smtSolverName[len("boolector"):]
                satSolverName = satSolverName.split("-")[-1]
                boolectorSatSolver = \
                SatSolver.getSatSolver(satSolverName)
                self.smtSolver = BoolectorSolver(boolectorSatSolver)

                from smt.parsers.boolectorModelParser \
                import BoolectorModelParser
                self.smtModelParser = BoolectorModelParser()
        elif smtSolverName == "z3":
            if config.SOLVER_Z3 == "":
                errMsg = ("The Z3 Python frontend was not found "
                          "during the configuration of GameTime. "
                          "This GameTime project cannot use Z3 "
                          "as its backend SMT solver.")
                raise GameTimeError(errMsg)
            else:
                from smt.solvers.z3Solver import Z3Solver
                self.smtSolver = Z3Solver()
                from smt.parsers.z3ModelParser import Z3ModelParser
                self.smtModelParser = Z3ModelParser()
        elif smtSolverName == "":
            errMsg = "SMT solver not specified."
            raise GameTimeError(errMsg)
        else:
            errMsg = ("Incorrect option specified for "
                      "the SMT solver: %s") % smtSolverName
            raise GameTimeError(errMsg)
示例#3
0
def numPaths(dag, source, sink):
    """
    Arguments:
        dag:
            DAG represented by a :class:`~gametime.nxHelper.Dag` object.
        source:
            Source node.
        sink:
            Sink node.

    Returns:
        Number of paths in the DAG provided.
    """
    # Dictionary that maps each node to the number of paths in the
    # DAG provided from the input source node to that node.
    nodesToNumPaths = {}
    nodesToNumPaths[source] = 1

    # Topologically sort the nodes in the graph.
    nodesToVisit = nx.topological_sort(dag)
    if nodesToVisit.pop(0) != source:
        errMsg = ("The source node should be the first node in "
                  "a topological sort of the control-flow graph.")
        raise GameTimeError(errMsg)

    while len(nodesToVisit) > 0:
        currNode = nodesToVisit.pop(0)
        numPathsToNode = 0
        for inEdge in dag.in_edges(currNode):
            inNeighbor = inEdge[0]
            numPathsToNode += nodesToNumPaths[inNeighbor]
        nodesToNumPaths[currNode] = numPathsToNode

    return nodesToNumPaths[sink]
示例#4
0
def _generateOtherSourcesFile(projectConfig):
    """Creates a file that contains the paths of other files to be
    merged with the source file.

    Arguments:
        projectConfig:
            :class:`~gametime.projectConfiguration.ProjectConfiguration`
            object that represents the configuration of a GameTime project.

    Returns:
        Path to the file that contains the paths of other files
        to be merged with the source file.
    """
    otherSourcesFilePath = os.path.join(projectConfig.locationTempDir,
                                        config.TEMP_MERGED)

    # Create the file.
    try:
        otherSourcesFileHandler = open(otherSourcesFilePath, "w")
    except EnvironmentError as e:
        errMsg = ("Error creating a temporary file located at %s, "
                  "which stores the paths of the other files to be "
                  "merged with the source file: %s" %
                  (otherSourcesFilePath, e))
        raise GameTimeError(errMsg)
    else:
        with otherSourcesFileHandler:
            for filePath in projectConfig.merged:
                otherSourcesFileHandler.write("%s\n" % filePath)

    return otherSourcesFilePath
示例#5
0
    def readAssignmentsFromFile(location):
        """
        Reads, from a file, the assignments to variables that would
        drive an execution of the code under analysis along a path.

        Arguments:
            location:
                Location of the file.

        Returns:
            Dictionary of assignments to variables that would
            drive an execution of the code under analysis along a path.
        """
        try:
            assignmentFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading the assignments to variables "
                      "that would drive an execution of the code "
                      "along a path: %s") % e
            raise GameTimeError(errMsg)
        else:
            assignments = {}
            with assignmentFileHandler:
                assignmentFileLines = assignmentFileHandler.readlines()
                for line in assignmentFileLines:
                    (variable, assignment) = \
                    line.strip().replace(";", "").split(" = ")
                    assignments[variable] = assignment
                return assignments
示例#6
0
    def readArrayAccessesFromFile(location):
        """
        Reads information about the array accesses made in conditions
        along a path from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            Dictionary that maps an array name to a list of tuples, each of
            which contains the numbers of the temporary index variables
            in an array access.
        """
        try:
            arrayAccessesFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading information about the array accesses "
                      "made in conditions along a path: %s") % e
            raise GameTimeError(errMsg)
        else:
            arrayAccesses = {}
            with arrayAccessesFileHandler:
                arrayAccessLines = arrayAccessesFileHandler.readlines()
                for arrayAccessLine in arrayAccessLines:
                    # Process the array access information.
                    arrayAccessLine = arrayAccessLine.strip().split(": ")
                    arrayName = arrayAccessLine[0]

                    tempIndicesTuples = literal_eval(arrayAccessLine[1])
                    if arrayName in arrayAccesses:
                        arrayAccesses[arrayName].extend(tempIndicesTuples)
                    else:
                        arrayAccesses[arrayName] = tempIndicesTuples
                return arrayAccesses
示例#7
0
    def readConditionTruthsFromFile(location):
        """
        Reads the line numbers of the conditional points in the code
        being analyzed, along with their truth values along a path,
        from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            Dictionary that associates the line numbers of
            the conditional points in the code being analyzed with
            their truth values.
        """
        try:
            conditionTruthsFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading line numbers of the conditional "
                      "points in the code being analyzed, along with "
                      "their truth values along a path: %s") % e
            raise GameTimeError(errMsg)
        else:
            conditionTruths = {}
            with conditionTruthsFileHandler:
                conditionTruthsFileLines = \
                conditionTruthsFileHandler.readlines()
                for line in conditionTruthsFileLines:
                    (lineNumber, conditionTruth) = line.strip().split(": ")
                    conditionTruths[lineNumber] = conditionTruth == "True"
                return conditionTruths
示例#8
0
    def readConditionEdgesFromFile(location):
        """
        Reads the numbers of the conditions along a path, and
        the edges that are associated with the conditions, from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            Dictionary that associates the number of a condition with
            the edge in the directed acyclic graph that is associated with
            the condition. The edge is represented as a tuple.
        """
        try:
            conditionEdgesFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading the numbers of the conditions along "
                      "a path, and the edges that are associated with "
                      "the conditions: %s") % e
            raise GameTimeError(errMsg)
        else:
            conditionEdges = {}
            with conditionEdgesFileHandler:
                conditionEdgesFileLines = conditionEdgesFileHandler.readlines()
                for line in conditionEdgesFileLines:
                    (conditionNum, edge) = line.strip().split(": ")
                    edge = tuple(edge.strip().split(" "))
                    conditionEdges[int(conditionNum.strip())] = edge
                return conditionEdges
示例#9
0
def writeDagToDotFile(dag,
                      location,
                      dagName="",
                      edgesToLabels=None,
                      highlightedEdges=None,
                      highlightColor="red"):
    """Writes the directed acyclic graph provided to a file in DOT format.

    Arguments:
        location:
            Location of the file.
        dagName:
            Name of the directed acyclic graph, as will be written to
            the file. If this argument is not provided, the directed
            acyclic graph will not have a name.
        edgesToLabels:
            Dictionary that maps an edge to the label that will annotate
            the edge when the DOT file is processed by a visualization tool.
            If this argument is not provided, these annotations will not
            be made.
        highlightedEdges:
            List of edges that will be highlighted when the DOT file is
            processed by a visualization tool. If this argument
            is not provided, no edges will be highlighted.
        highlightColor:
            Color of the highlighted edges. This argument can be any value
            that is legal in the DOT format. If the `highlightedEdges` argument
            is not provided, this argument is ignored.
    """
    _, extension = os.path.splitext(location)
    if extension.lower() != ".dot":
        location = "%s.dot" % location

    dagName = " %s" % dagName.strip()
    contents = []
    contents.append("digraph%s {" % dagName)
    for edge in dag.edges():
        line = "  %s -> %s" % edge
        attributes = []
        if edgesToLabels:
            attributes.append("label = \"%s\"" % edgesToLabels[edge])
        if highlightedEdges and edge in highlightedEdges:
            attributes.append("color = \"%s\"" % highlightColor)
        if len(attributes) > 0:
            line += " [%s]" % ", ".join(attributes)
        contents.append("%s;" % line)
    contents.append("}")

    try:
        dagDotFileHandler = open(location, "w")
    except EnvironmentError as e:
        errMsg = ("Error writing the DAG to a file located at %s: %s" %
                  (location, e))
        raise GameTimeError(errMsg)
    else:
        with dagDotFileHandler:
            dagDotFileHandler.write("\n".join(contents))
示例#10
0
    def setIlpSolver(self, ilpSolverName):
        """
        Sets the PuLP solver object associated with this
        :class:`~gametime.projectConfiguration.ProjectConfiguration`
        object to one that can interface with the integer
        linear programming solver whose name is provided.

        Arguments:
            ilpSolverName:
                Name of an integer linear programming solver.
        """
        def _ilpSolverErrMsg(ilpSolverName):
            """
            Arguments:
                ilpSolverName:
                    Name of an integer linear programming solver.

            Returns:
                Error message that informs the user that the integer
                linear programming solver, whose name is provided, cannot
                be used for this GameTime project.
            """
            if ilpSolverName == "":
                return ("The default integer linear programming solver "
                        "of the PuLP package was not found. "
                        "This GameTime project cannot use it as its "
                        "backend integer linear programming solver.")
            ilpSolverName = pulpHelper.getProperName(ilpSolverName)
            return ("The integer linear programming solver %s "
                    "was not found. This GameTime project cannot use %s "
                    "as its backend integer linear programming solver." %
                    (ilpSolverName, ilpSolverName))

        ilpSolverName = ilpSolverName.lower()
        if not pulpHelper.isIlpSolverName(ilpSolverName):
            errMsg = ("Incorrect option specified for the integer "
                      "linear programming solver: %s") % ilpSolverName
            raise GameTimeError(errMsg)
        else:
            ilpSolver = pulpHelper.getIlpSolver(ilpSolverName, self)
            if ilpSolver is not None:
                self.ilpSolver = ilpSolver
            else:
                raise GameTimeError(_ilpSolverErrMsg(ilpSolverName))
示例#11
0
    def writeIlpProblemToLpFile(self, location):
        """
        Writes, to an LP file, the integer linear programming problem that,
        when solved, produced this path.

        Arguments:
            location:
                Location of the file.
        """
        if self.ilpProblem is not None:
            _, extension = os.path.splitext(location)
            if extension.lower() != ".lp":
                location = location + ".lp"
            try:
                self.ilpProblem.writeLP(location)
            except (PulpError, EnvironmentError) as e:
                errMsg = ("Error writing the integer linear programming "
                          "problem to an LP file: %s") % e
                raise GameTimeError(errMsg)
        else:
            errMsg = ("This path is not associated with an integer linear "
                      "programming problem.")
            raise GameTimeError(errMsg)
示例#12
0
def removeFile(location):
    """Removes the file at the provided location. This is a wrapper around
    the :func:`~os.remove` function of the :mod:`os` module, but does not
    raise an exception if the file is not present.

    Arguments:
        location:
            Location of the file to be removed.
    """
    try:
        if os.path.exists(location):
            os.remove(location)
    except EnvironmentError as e:
        raise GameTimeError("Cannot remove file located at %s: %s" %
                            (location, e))
示例#13
0
    def writeMeasuredValueToFile(self, location):
        """Writes the measured value of this path to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            measuredValueFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing the measured value of the path "
                      "to the file located at %s: %s" % (location, e))
            raise GameTimeError(errMsg)
        else:
            with measuredValueFileHandler:
                measuredValueFileHandler.write(self.getMeasuredValue())
示例#14
0
    def writeConditionsToFile(self, location):
        """
        Writes the conditions along this path to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            conditionsFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = "Error writing conditions along the path: %s" % e
            raise GameTimeError(errMsg)
        else:
            with conditionsFileHandler:
                conditionsFileHandler.write(self.getConditions())
示例#15
0
    def writeArrayAccessesToFile(self, location):
        """
        Writes information about the array accesses made in conditions
        along this path to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            arrayAccessesFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing information about the array accesses "
                      "made in conditions along the path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with arrayAccessesFileHandler:
                arrayAccessesFileHandler.write(self.getArrayAccesses())
示例#16
0
    def writeLineNumbersToFile(self, location):
        """
        Writes the line numbers of the source-level statements that
        lie along this path to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            lineNumbersFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing line numbers of the source-level "
                      "statements along the path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with lineNumbersFileHandler:
                lineNumbersFileHandler.write(self.getLineNumbers())
示例#17
0
    def writeNodesToFile(self, location):
        """
        Writes the IDs of the nodes in a directed acyclic graph
        along this path to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            nodesFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing the IDs of the nodes in "
                      "a directed acyclic graph along the path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with nodesFileHandler:
                nodesFileHandler.write(self.getNodes())
示例#18
0
def createDir(location):
    """Creates the leaf directory in the path specified, along with any
    intermediate-level directories needed to contain the directory.
    This is a wrapper around the :func:`~os.makedirs` function of
    the :mod:`os` module, but does not raise an exception if
    the directory is already present,

    Arguments:
        location:
            Location of the directory to be created.
    """
    try:
        if not os.path.isdir(location):
            os.makedirs(location)
    except EnvironmentError as e:
        if e.errno != errno.EEXIST:
            raise GameTimeError("Cannot create directory located at %s: %s" %
                                (location, e))
示例#19
0
    def writeConditionTruthsToFile(self, location):
        """
        Writes the line numbers of the conditional points in the code
        being analyzed, along with their truth values, to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            conditionTruthsFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing line numbers of the conditional "
                      "points in the code being analyzed, along with "
                      "their truth values: %s") % e
            raise GameTimeError(errMsg)
        else:
            with conditionTruthsFileHandler:
                conditionTruthsFileHandler.write(self.getConditionTruths())
示例#20
0
    def writeConditionEdgesToFile(self, location):
        """
        Writes the numbers of the conditions along this path, and
        the edges that are associated with the conditions, to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            conditionEdgesFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing the numbers of the conditions along "
                      "the path, and the edges that are associated with "
                      "the conditions: %s") % e
            raise GameTimeError(errMsg)
        else:
            with conditionEdgesFileHandler:
                conditionEdgesFileHandler.write(self.getConditionEdges())
示例#21
0
    def writeAssignmentsToFile(self, location):
        """
        Writes the assignments to variables that would drive an execution
        of the code under analysis along this path to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            assignmentFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing the assignments to variables "
                      "that would drive an execution of the code "
                      "along the path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with assignmentFileHandler:
                assignmentFileHandler.write(self.getAssignments())
示例#22
0
def constructDag(location):
    """Constructs a :class:`~gametime.nxHelper.Dag` object to represent
    the directed acyclic graph described in DOT format in the file provided.

    Arguments:
        location:
            Path to the file describing a directed acyclic graph
            in DOT format.

    Returns:
        :class:`~gametime.nxHelper.Dag` object that represents
        the directed acyclic graph.
    """
    try:
        dagDotFileHandler = open(location, "r")
    except EnvironmentError as e:
        errMsg = ("Error opening the DOT file, located at %s, that contains "
                  "the directed acyclic graph to analyze: %s") % (location, e)
        raise GameTimeError(errMsg)
    else:
        with dagDotFileHandler:
            dagDotFileLines = dagDotFileHandler.readlines()

    # This is a hacky way of parsing the file, but for this
    # small and constant a use case, we should be fine: we should not
    # have to generate a parser from a grammar. If, however, for some
    # reason, the format with which the Phoenix and Python code communicate
    # changes, this should be modified or made more robust.
    dagDotFileLines = dagDotFileLines[1:-1]
    dagDotFileLines = [line.replace(lsep, "") for line in dagDotFileLines]
    dagDotFileLines = [line.replace(";", "") for line in dagDotFileLines]
    dagDotFileLines = [line.replace("->", "") for line in dagDotFileLines]
    dagDotFileLines = [line.strip() for line in dagDotFileLines]

    # Construct the graph.
    dag = Dag()
    for line in dagDotFileLines:
        edge = line.split(" ")
        edge = [node for node in edge if node != ""]
        dag.add_edge(edge[0], edge[1])
    dag.loadVariables()
    return dag
示例#23
0
    def writeAggIndexExprsToFile(self, location):
        """
        Writes information about the expressions associated with the
        temporary index variables of aggregate accesses along this path
        to a file.

        Arguments:
            location:
                Location of the file.
        """
        try:
            aggIndexExprsFileHandler = open(location, "w")
        except EnvironmentError as e:
            errMsg = ("Error writing information about the expressions "
                      "associated with the temporary index variables of "
                      "aggregate accesses along this path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with aggIndexExprsFileHandler:
                aggIndexExprsFileHandler.write(self.getAggIndexExprs())
示例#24
0
    def readAggIndexExprsFromFile(location):
        """
        Reads, from a file, information about the expressions associated with
        the temporary index variables of aggregate accesses along a path.

        Arguments:
            location:
                Location of the file.

        Returns:
            Dictionary that maps the number of a temporary index
            variable to an ``IndexExpression`` object.
        """
        try:
            aggIndexExprsFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading information about the expressions "
                      "associated with the temporary index variables of "
                      "aggregate accesses along a path: %s") % e
            raise GameTimeError(errMsg)
        else:
            aggIndexExprs = {}
            with aggIndexExprsFileHandler:
                aggIndexExprsLines = aggIndexExprsFileHandler.readlines()
                for aggIndexExprsLine in aggIndexExprsLines:
                    lineTokens = aggIndexExprsLine.strip().split(": ")

                    tempIndexNumber = int(lineTokens[0])
                    lineTokens = lineTokens[1].split()
                    if len(lineTokens) == 1:
                        varName = lineTokens[0]
                        aggIndexExprs[tempIndexNumber] = \
                        VariableIndexExpression(varName)
                    else:
                        arrayVarName = lineTokens[0]
                        indices = tuple(int(index) for index in lineTokens[1:])
                        aggIndexExprs[tempIndexNumber] = \
                        ArrayIndexExpression(arrayVarName, indices)
                return aggIndexExprs
示例#25
0
def writeHistogramToFile(location, paths, bins=10, range=None, measured=False):
    """Computes a histogram from the values of a list of
    feasible paths generated by GameTime, and writes the histogram
    to a file. Each line of the file has the left edge of each bin
    and the number of samples in each bin, with both of the values
    separated by whitespace.

    Arguments:
        location:
            Location of the file.
        paths:
            List of feasible paths generated by GameTime, each
            represented by a :class:`~gametime.path.Path` object.
        bins:
            Same purpose as the same-named argument of the function
            :func:`numpy.histogram`.
        range:
            Same purpose as the same-named argument of the function
            :func:`numpy.histogram`.
        measured:
            `True` if, and only if, the values that will be used for
            the histogram are the measured values of the feasible paths.
    """
    logger.info("Creating histogram...")

    hist, binEdges = computeHistogram(paths, bins, range, measured)
    try:
        histogramFileHandler = open(location, "w")
    except EnvironmentError as e:
        errMsg = ("Error writing the histogram to the file located "
                  "at %s: %s" % (location, e))
        raise GameTimeError(errMsg)
    else:
        with histogramFileHandler:
            for binEdge, sample in zip(binEdges, hist):
                histogramFileHandler.write("%s\t%s\n" % (binEdge, sample))

    logger.info("Histogram created.")
示例#26
0
    def readNodesFromFile(location):
        """
        Reads the IDs of the nodes in a directed acyclic graph
        along a path from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            IDs of the nodes in a directed acyclic graph along a path,
            represented as a list of strings.
        """
        try:
            nodesFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading the IDs of the nodes in "
                      "a directed acyclic graph along a path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with nodesFileHandler:
                nodes = nodesFileHandler.readline().strip().split()
                return nodes
示例#27
0
    def readConditionsFromFile(location):
        """
        Reads the conditions along a path from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            Conditions along a path, represented as a list of strings.
        """
        try:
            conditionsFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = "Error reading conditions along a path: %s" % e
            raise GameTimeError(errMsg)
        else:
            with conditionsFileHandler:
                conditions = conditionsFileHandler.readlines()
                conditions = [condition.strip() for condition in conditions]
                conditions = [condition for condition in conditions
                              if condition is not ""]
                return conditions
示例#28
0
    def readLineNumbersFromFile(location):
        """
        Reads the line numbers of the source-level statements that
        lie along a path from a file.

        Arguments:
            location:
                Location of the file.

        Returns:
            Line numbers of the source-level statements along this path,
            represented as a list of positive integers.
        """
        try:
            lineNumbersFileHandler = open(location, "r")
        except EnvironmentError as e:
            errMsg = ("Error reading line numbers of the source-level "
                      "statements along a path: %s") % e
            raise GameTimeError(errMsg)
        else:
            with lineNumbersFileHandler:
                lineNumbers = lineNumbersFileHandler.readline().strip().split()
                lineNumbers = [int(lineNumber) for lineNumber in lineNumbers]
                return lineNumbers
示例#29
0
def readProjectConfigFile(location):
    """
    Reads project configuration information from the XML file provided.

    Arguments:
        location:
            Location of the XML file that contains project
            configuration information.

    Returns:
        :class:`~gametime.projectConfiguration.ProjectConfiguration` object
        that contains information from the XML file whose location is provided.
    """
    logger.info("Reading project configuration in %s..." % location)

    if not os.path.exists(location):
        errMsg = "Cannot find project configuration file: %s" % location
        raise GameTimeError(errMsg)

    try:
        projectConfigDom = minidom.parse(location)
    except EnvironmentError as e:
        errMsg = "Error reading from project configuration file: %s" % e
        raise GameTimeError(errMsg)

    # Check that the root element is properly named.
    rootNode = projectConfigDom.documentElement
    if rootNode.tagName != 'gametime-project':
        raise GameTimeError("The root element in the XML file should be "
                            "named `gametime-project'.")

    # Check that no child element of the root element has an illegal tag.
    rootChildNodes = [
        node for node in rootNode.childNodes
        if node.nodeType == node.ELEMENT_NODE
    ]
    for childNode in rootChildNodes:
        childNodeTag = childNode.tagName
        if childNodeTag not in ["file", "preprocess", "analysis", "debug"]:
            raise GameTimeError("Unrecognized tag: %s" % childNodeTag)

    # Find the directory that contains the project configuration XML file.
    projectConfigDir = os.path.dirname(os.path.abspath(location))

    # Initialize the instantiation variables for
    # the ProjectConfiguration object.
    locationFile, func = "", ""
    startLabel, endLabel = "", ""
    included, merged, inlined, unrollLoops = [], [], [], False
    randomizeInitialBasis = False
    maximumErrorScaleFactor = 10
    determinantThreshold, maxInfeasiblePaths = 0.001, 100
    modelAsNestedArrays, preventBasisRefinement = False, False
    ilpSolverName, smtSolverName = "", ""

    # Process information about the file to be analyzed.
    fileNode = (projectConfigDom.getElementsByTagName("file"))[0]

    for node in fileNode.childNodes:
        if node.nodeType == node.ELEMENT_NODE:
            nodeText = _getText(node)
            nodeTag = node.tagName

            if nodeTag == "location":
                locationFile = \
                os.path.normpath(os.path.join(projectConfigDir, nodeText))
            elif nodeTag == "analysis-function":
                func = nodeText
            elif nodeTag == "start-label":
                startLabel = nodeText
            elif nodeTag == "end-label":
                endLabel = nodeText
            else:
                raise GameTimeError("Unrecognized tag: %s" % nodeTag)

    # Process the preprocessing variables and flags.
    preprocessingNode = \
    (projectConfigDom.getElementsByTagName("preprocess"))[0]

    for node in preprocessingNode.childNodes:
        if node.nodeType == node.ELEMENT_NODE:
            nodeText = _getText(node)
            nodeTag = node.tagName

            if nodeTag == "unroll-loops":
                unrollLoops = True
            elif nodeTag == "include":
                if nodeText != "":
                    included = getDirPaths(nodeText, projectConfigDir)
            elif nodeTag == "merge":
                if nodeText != "":
                    merged = getFilePaths(nodeText, projectConfigDir)
            elif nodeTag == "inline":
                if nodeText != "":
                    inlined = getFuncNames(nodeText)
            else:
                raise GameTimeError("Unrecognized tag: %s" % nodeTag)

    # Process the analysis variables and flags.
    analysisNode = (projectConfigDom.getElementsByTagName("analysis"))[0]

    for node in analysisNode.childNodes:
        if node.nodeType == node.ELEMENT_NODE:
            nodeText = _getText(node)
            nodeTag = node.tagName
            if nodeTag == "randomize-initial-basis":
                randomizeInitialBasis = True
            elif nodeTag == "maximum-error-scale-factor":
                maximumErrorScaleFactor = float(nodeText)
            elif nodeTag == "determinant-threshold":
                determinantThreshold = float(nodeText)
            elif nodeTag == "max-infeasible-paths":
                maxInfeasiblePaths = int(nodeText)
            elif nodeTag == "model-as-nested-arrays":
                modelAsNestedArrays = True
            elif nodeTag == "prevent-basis-refinement":
                preventBasisRefinement = True
            elif nodeTag == "ilp-solver":
                ilpSolverName = nodeText
            elif nodeTag == "smt-solver":
                smtSolverName = nodeText
            else:
                raise GameTimeError("Unrecognized tag: %s" % nodeTag)

    # Initialize the instantiation variables for the
    # DebugConfiguration object.
    keepCilTemps, dumpIr, keepIlpSolverOutput = False, False, False
    dumpInstructionTrace, dumpPath, dumpAllPaths = False, False, False
    dumpSmtTrace, dumpAllQueries = False, False
    keepParserOutput, keepSimulatorOutput = False, False

    # Process the debug flags.
    debugNode = (projectConfigDom.getElementsByTagName("debug"))[0]

    for node in debugNode.childNodes:
        if node.nodeType == node.ELEMENT_NODE:
            nodeText = _getText(node)
            nodeTag = node.tagName

            if nodeTag == "keep-cil-temps":
                keepCilTemps = True
            elif nodeTag == "dump-ir":
                dumpIr = True
            elif nodeTag == "keep-ilp-solver-output":
                keepIlpSolverOutput = True
            elif nodeTag == "dump-instruction-trace":
                dumpInstructionTrace = True
            elif nodeTag == "dump-path":
                dumpPath = True
            elif nodeTag == "dump-all-paths":
                dumpAllPaths = True
            elif nodeTag == "dump-smt-trace":
                dumpSmtTrace = True
            elif nodeTag == "dump-all-queries":
                dumpAllQueries = True
            elif nodeTag == "keep-parser-output":
                keepParserOutput = True
            elif nodeTag == "keep-simulator-output":
                keepSimulatorOutput = True
            else:
                raise GameTimeError("Unrecognized tag: %s" % nodeTag)

    # Instantiate a DebugConfiguration object.
    debugConfig = DebugConfiguration(keepCilTemps, dumpIr, keepIlpSolverOutput,
                                     dumpInstructionTrace, dumpPath,
                                     dumpAllPaths, dumpSmtTrace,
                                     dumpAllQueries, keepParserOutput,
                                     keepSimulatorOutput)

    # We have obtained all the information we need from the XML
    # file provided. Instantiate a ProjectConfiguration object.
    projectConfig = ProjectConfiguration(
        locationFile, func, smtSolverName, startLabel, endLabel, included,
        merged, inlined, unrollLoops, randomizeInitialBasis,
        maximumErrorScaleFactor, determinantThreshold, maxInfeasiblePaths,
        modelAsNestedArrays, preventBasisRefinement, ilpSolverName,
        debugConfig)
    logger.info("Successfully loaded project.")
    logger.info("")
    return projectConfig
示例#30
0
    def writeToXmlFile(self, locationXmlFile=None):
        """
        Writes the project configuration information to an XML file.

        Arguments:
            locationXmlFile:
                Location of the XML file. If this is not provided,
                the XML file will be located in the temporary
                directory where GameTime stores its temporary files.
        """
        locationXmlFile = locationXmlFile or self.locationXmlFile

        xmlDoc = minidom.Document()

        # Begin the construction of the XML node tree with the root node.
        projectRoot = xmlDoc.createElement("gametime-project")
        xmlDoc.appendChild(projectRoot)

        # Create the XML node that stores information about
        # the file to be analyzed.
        fileNode = xmlDoc.createElement("file")
        projectRoot.appendChild(fileNode)

        locationNode = xmlDoc.createElement("location")
        locationNode.appendChild(xmlDoc.createTextNode(self.locationOrigFile))
        fileNode.appendChild(locationNode)

        funcNode = xmlDoc.createElement("analysis-function")
        funcNode.appendChild(xmlDoc.createTextNode(self.func))
        fileNode.appendChild(funcNode)

        startLabelNode = xmlDoc.createElement("start-label")
        startLabelNode.appendChild(xmlDoc.createTextNode(self.startLabel))
        fileNode.appendChild(startLabelNode)

        endLabelNode = xmlDoc.createElement("end-label")
        endLabelNode.appendChild(xmlDoc.createTextNode(self.endLabel))
        fileNode.appendChild(endLabelNode)

        # Create the XML node that stores the preprocessing
        # variables and flags.
        preprocessingNode = xmlDoc.createElement("preprocess")
        projectRoot.appendChild(preprocessingNode)

        includeNode = xmlDoc.createElement("include")
        includeNode.appendChild(xmlDoc.createTextNode(" ".join(self.included)))
        preprocessingNode.appendChild(includeNode)

        mergeNode = xmlDoc.createElement("merge")
        mergeNode.appendChild(xmlDoc.createTextNode(" ".join(self.merged)))
        preprocessingNode.appendChild(mergeNode)

        inlineNode = xmlDoc.createElement("inline")
        inlineNode.appendChild(xmlDoc.createTextNode(" ".join(self.inlined)))
        preprocessingNode.appendChild(inlineNode)

        if self.UNROLL_LOOPS:
            unrollLoopsNode = xmlDoc.createElement("unroll-loops")
            preprocessingNode.appendChild(unrollLoopsNode)

        # Create the XML node that stores the analysis variables and flags.
        analysisNode = xmlDoc.createElement("analysis")
        projectRoot.appendChild(analysisNode)

        if self.RANDOMIZE_INITIAL_BASIS:
            randomizeInitialBasisNode = \
            xmlDoc.createElement("randomize-initial-basis")
            analysisNode.appendChild(randomizeInitialBasisNode)

        maximumErrorScaleFactorNode = \
        xmlDoc.createElement("maximum-error-scale-factor")
        basisErrorNode = xmlDoc.createTextNode("%g" %
                                               self.MAXIMUM_ERROR_SCALE_FACTOR)
        maximumErrorScaleFactorNode.appendChild(basisErrorNode)

        determinantThresholdNode = \
        xmlDoc.createElement("determinant-threshold")
        thresholdAmountNode = xmlDoc.createTextNode("%g" %
                                                    self.DETERMINANT_THRESHOLD)
        determinantThresholdNode.appendChild(thresholdAmountNode)
        analysisNode.appendChild(determinantThresholdNode)

        maxInfeasiblePathsNode = xmlDoc.createElement("max-infeasible-paths")
        numInfeasiblePathsNode = \
        xmlDoc.createTextNode("%g" % self.MAX_INFEASIBLE_PATHS)
        maxInfeasiblePathsNode.appendChild(numInfeasiblePathsNode)
        analysisNode.appendChild(maxInfeasiblePathsNode)

        if self.MODEL_AS_NESTED_ARRAYS:
            modelAsNestedArraysNode = \
            xmlDoc.createElement("model-as-nested-arrays")
            analysisNode.appendChild(modelAsNestedArraysNode)

        if self.PREVENT_BASIS_REFINEMENT:
            preventBasisRefinementNode = \
            xmlDoc.createElement("prevent-basis-refinement")
            analysisNode.appendChild(preventBasisRefinementNode)

        ilpSolverNode = xmlDoc.createElement("ilp-solver")
        ilpSolverName = pulpHelper.getIlpSolverName(self.ilpSolver)
        ilpSolverNode.appendChild(xmlDoc.createTextNode(ilpSolverName))
        analysisNode.appendChild(ilpSolverNode)

        smtSolverNode = xmlDoc.createElement("smt-solver")
        smtSolverNode.appendChild(xmlDoc.createTextNode(str(self.smtSolver)))
        analysisNode.appendChild(smtSolverNode)

        # Create the XML node that stores the debug flags.
        debugNode = xmlDoc.createElement("debug")
        projectRoot.appendChild(debugNode)

        if self.debugConfig.KEEP_CIL_TEMPS:
            keepCilTempsNode = xmlDoc.createElement("keep-cil-temps")
            debugNode.appendChild(keepCilTempsNode)

        if self.debugConfig.DUMP_IR:
            dumpIrNode = xmlDoc.createElement("dump-ir")
            debugNode.appendChild(dumpIrNode)

        if self.debugConfig.KEEP_ILP_SOLVER_OUTPUT:
            keepIlpSolverOutputNode = \
            xmlDoc.createElement("keep-ilp-solver-output")
            debugNode.appendChild(keepIlpSolverOutputNode)

        if self.debugConfig.DUMP_PATH:
            dumpPathNode = xmlDoc.createElement("dump-path")
            debugNode.appendChild(dumpPathNode)

        if self.debugConfig.DUMP_ALL_PATHS:
            dumpAllPathsNode = xmlDoc.createElement("dump-all-paths")
            debugNode.appendChild(dumpAllPathsNode)

        if self.debugConfig.DUMP_INSTRUCTION_TRACE:
            dumpInstrTraceNode = xmlDoc.createElement("dump-instruction-trace")
            debugNode.appendChild(dumpInstrTraceNode)

        if self.debugConfig.DUMP_SMT_TRACE:
            dumpSmtTraceNode = xmlDoc.createElement("dump-smt-trace")
            debugNode.appendChild(dumpSmtTraceNode)

        if self.debugConfig.DUMP_ALL_QUERIES:
            dumpAllQueriesNode = xmlDoc.createElement("dump-all-queries")
            debugNode.appendChild(dumpAllQueriesNode)

        if self.debugConfig.KEEP_PARSER_OUTPUT:
            keepParserOutputNode = xmlDoc.createElement("keep-parser-output")
            debugNode.appendChild(keepParserOutputNode)

        if self.debugConfig.KEEP_SIMULATOR_OUTPUT:
            keepSimulatorOutputNode = \
            xmlDoc.createElement("keep-simulator-output")
            debugNode.appendChild(keepSimulatorOutputNode)

        try:
            locationHandler = open(locationXmlFile, "w")
        except EnvironmentError as e:
            errMsg = ("Error creating the project configuration "
                      "XML file: %s") % e
            raise GameTimeError(errMsg)
        else:
            with locationHandler:
                # Create the pretty-printed text version of the XML node tree.
                prettyPrinted = xmlDoc.toprettyxml(indent="    ")
                locationHandler.write(prettyPrinted)