コード例 #1
0
    def RunSimulator(self, dirname, sim_replay_cmd, phase_length, options):
        """
        Run a simulator on all the pinballs in a directory given by 'dirname'.

        @param dirname Directory containing pinball to process
        @param sim_replay_cmd Script used to replay pinball
        @param phase_length Number of instructions executed before CMPSim will print next set of output
        @param options Options given on cmd line

        @return Error code from running the simulator
        """

        # Check to make sure the directory at least exists.
        #
        # import pdb;  pdb.set_trace()
        if not os.path.exists(dirname):
            if options.mode == config.MPI_MT_MODE:
                msg.PrintMsg('WARNING: Directory containing pinballs to run with simulator does not exist:\n   ' + \
                    dirname)
                msg.PrintMsg('Since tracing mode is \'mpi_mt\', this may be OK.')
                return 0
            else:
                msg.PrintMsg('ERROR: Directory containing pinballs to run with simulator does not exist:\n   ' + \
                    dirname)
                return -1

        # Don't do anything if running in debug mode.
        #
        if options.debug:
            return 0

        gv = config.GlobalVar()

        # Get the number of threads in the pinball and round it up
        # to the next power of 2.  This is a requirement of CMPSim.
        #
        # import pdb;  pdb.set_trace()
        threads = util.GetNumThreadsWP(options)
        threads = util.RoundupPow2(threads)

        # Need to let script 'sim_replay_cmd' know type of kit is calling it.
        #
        config.sim_kit_type = self.kit_type

        # Run on all the pinballs in 'dirname'.
        #
        cmd = sim_replay_cmd + ' --replay_dir ' + dirname
        cmd += ' --replay_options'
        cmd += ' "' + options.replay_options + '"'
        cmd += ' --log_options'
        cmd += ' "'
        cmd += '-threads ' + str(threads)

        # If the directory contains the WP directory name for this tracing
        # instance, then get the icount for each process/thread in the WP
        # pinballs.  Use the longest icount as the phase_length for CMPSim.
        #
        # This is done to reduce the CMPSim output to the very minimum for WP
        # pinballs.  For very large WP pinballs, using the 'default' value for
        # phase_length generates CMPSim output which can be multiple GBs in size.
        #
        # import pdb;  pdb.set_trace()
        if util.GetWPDir() in dirname:
            max_icount = 0
            pinballs = glob.glob(os.path.join(dirname, '*.address'))
            for pb in pinballs:
                fname = os.path.basename(pb)
                icount = util.GetMaxIcount(dirname, fname)
                if icount > max_icount:
                    max_icount = icount
            # Check for errors
            #
            # import pdb;  pdb.set_trace()
            if max_icount != 0:
                phase_length = max_icount / 1000000
                if phase_length == 0:
                    # Must have a length of at least 1
                    #
                    phase_length = 1

        cmd += ' ' + self.print_data_knob + ' ' + str(phase_length)
        cmd += '" '
        cmd += ' --sim_add_filename'  # This causes CMPSim output file name to be added to cmd
        cmd += util.AddCfgFile(options)
        cmd += util.AddGlobalFile(gv.DumpGlobalVars(), options)

        # import pdb;  pdb.set_trace()
        end_str = ''  # Don't want to print anything when this cmd finishes.
        result = util.RunCmd(cmd, options, end_str, concurrent=False)

        return result
コード例 #2
0
def RunSniper(pp_dir, sim_replay_cmd, phase_length, options):
    def round(x, roundby=1000000):
        return int(int((x / float(roundby))) * float(roundby))

    # List of pinballs used to print Sniper output when all runs are complete.
    #
    pb_list = []

    ret = 0
    if not os.path.isdir(pp_dir):

        # If running in MPI_MT_MODE, then it's possible for one process to not
        # have a thread corresponding to the the current focus thread.
        # However, another process might have this thread.  Thus, only return
        # an error if not tracing a MPI_MT application.
        #
        if options.mode == config.MPI_MT_MODE:
            msg.PrintMsg('WARNING: Directory containing pinballs to run with simulator does not exist:\n   ' + \
                pp_dir)
            msg.PrintMsg('Since tracing mode is \'mpi_mt\', this may be OK.')
            return 0
        else:
            msg.PrintMsg('ERROR: Directory containing pinballs to run with simulator does not exist:\n   ' + \
                pp_dir)
            return -1

    # List of output sniper directories.
    #
    output_dir_list = []

    for fn in os.listdir(pp_dir):
        if fn.endswith('.address'):
            pinball_path = os.path.join(pp_dir, os.path.splitext(fn)[0])
            fn = os.path.splitext(fn)[0]
            sniper_outputdir = os.path.join(config.sniper_result_dir,
                                            pinball_path)
            output_dir_list += [sniper_outputdir]
            sniper_outputfile = pinball_path + config.sniper_out_ext
            if options.debug:
                # If debugging, check to see if the Sniper result files already exist for the pinball.  If so,
                # then print it out but don't run Sniper again.
                #
                if os.path.isdir(sniper_outputdir):
                    msg.PrintMsgPlus(
                        'WARNING: Skipping Sniper execution because output file already exists.\n'
                        '   %s' % sniper_outputdir)
                    pb_list.append(pinball_path)
                    continue

            # Select the proper config/options to run the desired version of
            # Sniper/SniperLite.
            #
            # import pdb;  pdb.set_trace()
            if options.sniper_options:
                common_sniper_opts = options.sniper_options
            else:
                if options.no_sniperlite:
                    common_sniper_opts = ''
                else:
                    # use_orig = True        # Use older SniperLite options
                    use_orig = False  # New SniperLite options
                    if use_orig:
                        common_sniper_opts = ' -c dunnington -c cacheonly -c nehalem_cmpsim.cfg ' \
                      '-g --general/enable_icache_modeling=false ' \
                      '-g --perf_model/dram/direct_access=true ' \
                      '-g --perf_model/dram/queue_model/type=contention ' \
                      '-g --perf_model/dtlb/size=0'
                    else:
                        # Older patched Sniper 5.3
                        #
                        # common_sniper_opts = ' -c dunnington -c nehalem_cmpsim.cfg -c ccpp1c --pinball-non-sift \
                        # -g -replay:addr_trans -g --general/enable_icache_modeling=false'

                        # Newer patched Sniper 5.3
                        #
                        # common_sniper_opts = ' -c dunnington -c nehalem_cmpsim.cfg -c cc-fast --pinball-non-sift \
                        # -g -replay:addr_trans -g --general/enable_icache_modeling=false'

                        # Production SniperLite 6.0 options
                        #
                        common_sniper_opts = ' -c nehalem-lite --pinball-non-sift '
            partial_run_cmd = (common_sniper_opts + ' --no-cache-warming')

            try:
                # If re.search() fails, code falls though to the exception.
                #
                warmup_region = re.search('warmup(\d+)_prolog(\d+)_region(\d+)_epilog(\d+)_(\d+)_(\d-\d+)', \
                                          pinball_path)

                # Get info on the length of regions in the pinball.
                #
                warmup = int(warmup_region.group(1))
                prolog = int(warmup_region.group(2))
                file_region = int(warmup_region.group(3))
                epilog = int(warmup_region.group(4))
                region_num = int(warmup_region.group(5))
                weight = warmup_region.group(6).replace('-', '.')

                icount = util.GetMaxIcount('', pinball_path)
                sim_region_len = icount - warmup
                calc_region = sim_region_len - prolog - epilog

                if warmup != 0:
                    # If there are warmups, then need to use options to first do cache warmups in Sniper,
                    # then simulate the region.
                    #
                    partial_run_cmd = (common_sniper_opts + ' -s stop-by-icount:%d:%d ' \
              % (sim_region_len, round(warmup)) + ' --roi-script ')

                if not options.list:
                    # Print details about the various sections in the pinball.
                    #
                    msg.PrintMsgPlus('Running Sniper on: ' + fn)
                    msg.PrintMsg('           Warmup count:        ' +
                                 locale.format('%14d', warmup, True))
                    msg.PrintMsg('           Prolog count:        ' +
                                 locale.format('%14d', prolog, True))
                    msg.PrintMsg('           Actual region count: ' + locale.format('%14d', calc_region, True) + \
                        '   (from file name: ' + locale.format('%d', file_region, True) + ')')
                    msg.PrintMsg('           Epilog count:        ' +
                                 locale.format('%14d', epilog, True))
                    msg.PrintMsg('           Total Instr count:   ' +
                                 locale.format('%14d', icount, True))

            except AttributeError:
                if 'whole_program' not in pinball_path:

                    # Whole program pinballs cannot be processed using the options
                    # given above (using -s stop-by-icount:) because they don't have
                    # warmup instructions to be skipped.
                    #
                    # Let the user know the results may be suspect because the dir
                    # appears to contain whole program pinballs, but the name doesn't
                    # contain the string 'whole_program'.  However, don't flag this as
                    # an erorr.  It's possible for the user to give the name of a WP
                    # pinball directory which does not contain this string.
                    #
                    msg.PrintMsgPlus(
                        'WARNING: This pinball may not really be a whole program pinball.\n'
                        '     If this is true, the results may not be valid.\n'
                        '         ' + pinball_path)
                msg.PrintMsgPlus('Running Sniper on whole program pinball: ' +
                                 pinball_path)

            # Format the command and execute it asynchronously.
            #
            cmd = os.path.join(options.sniper_root, sim_replay_cmd) + partial_run_cmd + \
                      (' -d "%s" ' % sniper_outputdir) + ' --pinballs ' + pinball_path + \
                       ' > ' + sniper_outputfile + ' 2>&1 '
            pb_list.append(pinball_path)
            end_str = fn
            # import pdb;  pdb.set_trace()
            result = util.RunCmd(cmd, options, end_str, concurrent=True)
            ret = result or ret
    result = util.WaitJobs(options)
    ret = result or ret

    # Make sure some of the important Sniper output files exist for each pinball.
    #
    file_list = ['sim.stats.sqlite3', 'sim.info', 'sim.cfg', 'sim.out']
    for sim_dir in output_dir_list:
        for f in file_list:
            if not os.path.isfile(os.path.join(sim_dir, f)):
                msg.PrintMsg('\nERROR: Sniper output file does not exist:\n' \
                             '    ' + os.path.join(sim_dir, f))
                ret = -1

    # Define a set of strings which can be ignored as errors if they occur in
    # the output. These are special cases which must be added by hand when a
    # new application is found that contains a string which might be detected
    # as an erorr, but is a normal component of the output from running the
    # application.

    # Errors generated by Sniper itself which are acceptable.
    #
    ign_str = [
        'void Sift::Writer::Sync(): Assertion',
        'Sift::Reader::decodeInstruction'
    ]
    pin_app_term = 'Pin app terminated abnormally'
    ign_str += [pin_app_term]

    # Strings generated by SPEC CPU2006 benchmarks: dealII-ref-1
    #
    ign_str += ['Estimated error=']

    # Strings generated by MILC
    #
    ign_str += ['error_per_site', 'No O(a^2) errors', 'error_for_propagator']

    # Print the output from running Sniper and look for errors in the output.
    #
    error = False
    for pinball_path in pb_list:
        # Get just the pinball name & print it
        #
        fn = os.path.split(pinball_path)[1]

        sniper_outputfile = pinball_path + config.sniper_out_ext
        if os.path.isfile(sniper_outputfile):
            try:
                f_stdout = open(sniper_outputfile, 'r')
            except IOError:
                msg.PrintMsg(
                    'ERROR: Can\'t open Sniper output file to look for errors.\n'
                    '   ' + sniper_outputfile)
                ret = -1

            # Print the output file and look for errors.
            #
            if not options.list:
                if 'whole_program' in pinball_path:
                    msg.PrintMsg('\nSniper output for: ' + pinball_path)
                else:
                    msg.PrintMsg('\nSniper output for: ' + fn)
                for line in f_stdout.readlines():
                    msg.PrintMsgNoCR(line)
                    if not options.ignore_sniper_error and \
                        ('ERROR' in line or \
                         'error' in line or \
                         'Traceback' in line):

                        # Check to see if we can accept this line because
                        # it contains one of the strings we can ignore.
                        #
                        ok_ignore = False
                        for st in ign_str:
                            if st in line:
                                ok_ignore = True
                                break
                        if not ok_ignore:
                            # It's truly an error
                            #
                            error = True

                        # Need to print a msg indicating this error is OK to ignore.
                        #
                        if pin_app_term in line:
                            msg.PrintMsg(
                                'The \'Pin app terminated\' msg can be ignored. '
                                'It is not an error, just a warning.')
                if error:
                    msg.PrintMsg('\nERROR: Sniper failed with an error.')
                    ret = -1
                    error = False  # Reset in order to look for error in next pb
    return ret