def measure(self, path):
        """
        Arguments:
            path:
                :class:`~gametime.path.Path` object that represents the path
                whose cycle count needs to be measured.

        Returns:
            Cycle count of the path, as measured on the PTARM simulator.
        """
        # Create the temporary directory where the temporary files generated
        # during measurement will be stored.
        createDir(self._measurementDir)

        try:
            # This sequence of function calls closely mimics the steps
            # described at
            # http://chess.eecs.berkeley.edu/pret/src/ptarm-1.0/\
            # ptarm_simulator.html#%5B%5BCompiling%20Programs%5D%5D.
            testCaseFileLocation = self._createTestCaseFile(path)
            outFileLocation = self._compileFile(testCaseFileLocation)
            asmFileLocation = self._dumpAsmFile(outFileLocation)
            self._convertToSrec(outFileLocation)
            self._copyEvecSrec()
            cycleCount = self._runSimulatorAndParseOutput(asmFileLocation)
        except EnvironmentError as e:
            errMsg = ("Error in measuring the cycle count of a path "
                      "when simulated on the PTARM simulator: %s" % e)
            raise GameTimeError(errMsg)

        if not self.projectConfig.debugConfig.KEEP_SIMULATOR_OUTPUT:
            self._removeTemps()
        return cycleCount
def generateBasisPaths(projectConfig, analyzerLocation):
    """Demonstrates how to generate the :class:`~gametime.path.Path` objects
    that represent the basis paths of the code specified in a GameTime project
    configuration, represented by a
    :class:`~gametime.projectConfiguration.ProjectConfiguration` object.

    The function saves the information from the :class:`~gametime.path.Path`
    objects to different files in a temporary directory called `analysis`,
    created in the directory that contains the code being analyzed.
    The :class:`~gametime.analyzer.Analyzer` object that is used for analysis
    is saved to the location provided.

    Arguments:
        projectConfig:
            :class:`~gametime.projectConfiguration.ProjectConfiguration`
            object that represents the configuration of a GameTime project.
        analyzerLocation:
            Location where the :class:`~gametime.analyzer.Analyzer` object
            will be saved.
    """
    # Create a new :class:`~gametime.analyzer.Analyzer` object
    # for this analysis.
    analyzer = GameTime.analyze(projectConfig)

    # Generate a list of the :class:`~gametime.path.Path` objects that
    # represent the basis paths of the code specified in the XML file.
    basisPaths = analyzer.generateBasisPaths()

    # To keep the filesystem clean, create a directory for the basis paths
    # within the temporary directory called `analysis`. Write
    # the information contained in the :class:`~gametime.path.Path` objects
    # to this directory.
    analysisDir = os.path.join(projectConfig.locationOrigDir, "analysis")
    basisDir = os.path.join(analysisDir, "basis")
    createDir(basisDir)
    analyzer.writePathsToFiles(paths=basisPaths,
                               writePerPath=False,
                               rootDir=basisDir)

    # Save the analyzer for later use.
    analyzer.saveToFile(analyzerLocation)
    def measure(self, path):
        """
        Arguments:
            path:
                :class:`~gametime.path.Path` object that represents the path
                whose cycle count needs to be measured.

        Returns:
            Cycle count of the path, as measured on the SimIt-ARM simulator.
        """
        # Create the temporary directory where the temporary files generated
        # during measurement will be stored.
        createDir(self._measurementDir)

        try:
            if run("mkdir -p %s" % self._remoteMeasurementDir):
                errMsg = ("Error in creating the temporary directory "
                          "for measurements on the remote computer.")
                raise GameTimeError(errMsg)

            testCaseFileLocation = self._createTestCaseFile(path)
            self._transferFile(testCaseFileLocation)
            zeroTestCaseFileLocation = self._createZeroTestCaseFile(path)
            self._transferFile(zeroTestCaseFileLocation)

            if run("rm -rf %s" % self._remoteMeasurementDir):
                errMsg = ("Error in removing the temporary directory "
                          "for measurements on the remote computer.")
                raise GameTimeError(errMsg)
        except EnvironmentError as e:
            errMsg = ("Error in measuring the cycle count of a path "
                      "when simulated on the SimIt-ARM simulator: %s" % e)
            raise GameTimeError(errMsg)

        # TODO (jokotker): Not completely integrated.
        return 0
def generatePaths(projectConfig, analyzerLocation, basisValuesLocation,
                  numPaths, pathType, interval, useObExtraction):
    """Demonstrates how to load an :class:`~gametime.analyzer.Analyzer`
    object, saved from a previous analysis, from a file, and how to load
    the values to be associated with the basis :class:`~gametime.path.Path`
    objects from a file.

    Once these values are loaded, the function generates as many feasible
    paths as possible, upper-bounded by the `numPaths` argument. This
    argument is ignored if the function is called to generate all of
    the feasible paths of the code being analyzed.

    The type of paths that will be generated is determined by
    the `pathType` argument, which is a class variable of
    the :class:`~gametime.pathGenerator.PathType` class. For
    a description of the types, refer to the documentation of
    the :class:`~gametime.pathGenerator.PathType` class.

    The function saves the information from the :class:`~gametime.path.Path`
    objects to different files in a temporary directory called `analysis`,
    created in the directory that contains the code being analyzed.
    The :class:`~gametime.analyzer.Analyzer` object that is used for analysis
    is saved back to the location provided. The predicted values of
    the feasible paths, stored as the values of the corresponding
    :class:`~gametime.path.Path` objects, are also saved to a file whose name
    has the prefix `predicted-`.

    Arguments:
        projectConfig:
            :class:`~gametime.projectConfiguration.ProjectConfiguration`
            object that represents the configuration of a GameTime project.
        analyzerLocation:
            Location of the saved :class:`~gametime.analyzer.Analyzer` object.
        basisValuesLocation:
            Location of the file that contains the values to be associated
            with the basis :class:`~gametime.path.Path` objects.
        pathType:
            Type of paths to generate, represented by a class variable of
            the :class:`~gametime.pathGenerator.PathType` class.
            The different types of paths are described in the documentation of
            the :class:`~gametime.pathGenerator.PathType` class.
        numPaths:
            Upper bound on the number of paths to generate.
        interval:
            Two-element tuple that represents the closed interval
            of values that the generated paths can have.
        useObExtraction:
            Boolean value specifiying whether to use overcomplete basis
            extraction algorithm

    Returns:
        List of :class:`~gametime.path.Path` objects that represent
        the feasible paths generated.
    """
    # Load an :class:`~gametime.analyzer.Analyzer` object from
    # a file saved from a previous analysis.
    analyzer = Analyzer.loadFromFile(analyzerLocation)

    # Load the values to be associated with the basis
    # :class:`~gametime.path.Path` objects from the file specified.
    analyzer.loadBasisValuesFromFile(basisValuesLocation)

    # Generate the list of the :class:`~gametime.path.Path` objects
    # that represent the feasible paths requested.
    paths = analyzer.generatePaths(numPaths, pathType, interval,
                                   useObExtraction)

    # To keep the filesystem clean, create a directory for these feasible
    # paths in the temporary directory called `analysis`. Write
    # the information contained in the :class:`~gametime.path.Path`
    # objects to this directory.
    projectConfig = analyzer.projectConfig
    analysisDir = os.path.join(projectConfig.locationOrigDir, "analysis")

    pathsDirName = PathType.getDescription(pathType)
    pathsDir = os.path.join(analysisDir, pathsDirName)
    createDir(pathsDir)
    analyzer.writePathsToFiles(paths, writePerPath=False, rootDir=pathsDir)

    # Get a one-word description of the path type.
    pathTypeDesc = PathType.getDescription(pathType)

    # Construct the location of the file that will store
    # the predictions of the values of the feasible paths.
    # Write the predicted values to this file.
    predictedValuesFileName = "predicted-%s" % pathTypeDesc
    predictedValuesLocation = os.path.join(analysisDir,
                                           predictedValuesFileName)
    Analyzer.writePathValuesToFile(paths, predictedValuesLocation)

    # Write the computed delta and the deltaMultiple into respective files
    if useObExtraction:
        Analyzer.writeValueToFile(analyzer.inferredMuMax,
                                  os.path.join(analysisDir, "mu-max"))
        Analyzer.writeValueToFile(
            analyzer.errorScaleFactor,
            os.path.join(analysisDir, "error-scale-factor"))

    # Save the analyzer for later use.
    analyzer.saveToFile(analyzerLocation)

    return paths
def main():
    """Main function invoked when this script is run."""
    argParser = _createArgParser()
    args = argParser.parse_args()

    argsAndPathTypes = [(args.worst_case, PathType.WORST_CASE),
                        (args.best_case, PathType.BEST_CASE),
                        (args.random, PathType.RANDOM),
                        (args.all_decreasing, PathType.ALL_DECREASING),
                        (args.all_increasing, PathType.ALL_INCREASING)]
    pathTypeArgs = [pathTypeArg for pathTypeArg, _ in argsAndPathTypes]
    pathTypes = [pathType for _, pathType in argsAndPathTypes]

    # Require the use of new_extraction algorithm when used with overcomplete
    # basis
    if ((args.overcomplete_basis and any(pathTypeArgs))
            and not (args.ob_extraction)):
        raise GameTimeError("New extraction algorithm must be used when over "
                            "complete basis is requested")

    # Proceed only if either the generation of feasible paths, or
    # the measurement of the values of feasible paths, or the creation
    # of a histogram of path values has been requested.
    if (not args.basis and not any(pathTypeArgs) and not args.measure_tests
            and not args.histogram):
        return

    # Find the XML file that will be used to initialize the GameTime project.
    workingDir = os.getcwd()
    location = os.path.normpath(os.path.join(workingDir, args.analyze))
    projectConfigXmlFile = _findXmlFile(location)
    if not projectConfigXmlFile:
        raise GameTimeError("No XML file for the configuration of "
                            "a GameTime project was found at %s." % location)

    # Initialize a :class:`~gametime.projectConfiguration.ProjectConfiguration`
    # object, which represents the configuration of a GameTime project, with
    # the contents of the XML file.
    projectConfig = readProjectConfigFile(projectConfigXmlFile)
    if args.unroll_loops:
        projectConfig.UNROLL_LOOPS = args.unroll_loops

    if args.overcomplete_basis:
        projectConfig.OVER_COMPLETE_BASIS = True

    # Create a temporary directory called `analysis` in
    # the directory that contains the code being analyzed.
    analysisDir = os.path.join(projectConfig.locationOrigDir, "analysis")
    createDir(analysisDir)

    # Determine the location where
    # the :class:`~gametime.analyzer.Analyzer` object used for
    # analysis will be saved and loaded from.
    analyzerLocation = (args.analyzer_location
                        or os.path.join(analysisDir, "analyzer"))

    # Generate the feasible basis paths, if requested.
    if args.basis:
        generateBasisPaths(projectConfig, analyzerLocation)

    # If measurement of feasible paths is requested but no type has been
    # provided, or the generation of feasible basis paths is also requested,
    # measure the values of the feasible basis paths.
    if (args.measure_tests and (args.basis or not any(pathTypeArgs))):
        simulator = _getSimulator(args.simulator, projectConfig)
        measureBasisPaths(analyzerLocation, simulator)

    # If the creation of a histogram is requested but no type has been
    # provided, or the generation of feasible basis paths is also requested,
    # create a histogram from the values of the feasible basis paths.
    if (args.histogram and (args.basis or not any(pathTypeArgs))):
        createHistogramForBasisPaths(analyzerLocation, args.hist_bins,
                                     args.hist_lower, args.hist_upper)

    # Generate other types of feasible paths, if requested.
    basisValuesLocation = (os.path.join(workingDir, args.values) if args.values
                           else os.path.join(analysisDir, "measured-basis"))
    numPaths = args.num_paths
    interval = Interval(args.lower, args.upper)
    useObExtraction = True if args.ob_extraction else False

    for pathTypeArg, pathType in argsAndPathTypes:
        if pathTypeArg:
            paths = generatePaths(projectConfig, analyzerLocation,
                                  basisValuesLocation, numPaths, pathType,
                                  interval, useObExtraction)

            # Create a histogram of the predicted values of
            # the feasible paths generated, if requested.
            if args.histogram:
                createHistogramForPaths(projectConfig, paths, pathType,
                                        args.hist_bins, args.hist_lower,
                                        args.hist_upper)

            # Measure the feasible paths generated, if requested.
            if args.measure_tests:
                simulator = _getSimulator(args.simulator, projectConfig)
                measurePaths(projectConfig, simulator, paths, pathType)

            # Create a histogram of the measured values of
            # the feasible paths generated, if requested.
            if args.measure_tests and args.histogram:
                createHistogramForPaths(projectConfig,
                                        paths,
                                        pathType,
                                        args.hist_bins,
                                        args.hist_lower,
                                        args.hist_upper,
                                        measured=True)