コード例 #1
0
ファイル: main.cpp プロジェクト: 6366295/mgsim
int main(int argc, char** argv)
{
    std::set_new_handler(MemoryExhausted);

    ProgramConfig flags;
    UNIQUE_PTR<Config> config;
    UNIQUE_PTR<MGSystem> sys;
    UNIQUE_PTR<Monitor> mo;
    UNIQUE_PTR<Communicator> comm;

    ////
    // Early initialization.
    // Argument parsing, no simulation yet.
    try
    {
        // Parse command line arguments
        argp_parse(&argp, argc, argv, 0, 0, &flags);
    }
    catch (const exception& e)
    {
        PrintException(NULL, cerr, e);
        return 1;
    }

    if (flags.m_interactive)
    {
        // Interactive mode: print name & version first
        clog << argp_program_version << endl
             << endl;

        // Then print also command name & arguments
        clog  << "Command line:";
        for (int i = 0; i < argc; ++i)
            clog << ' ' << argv[i];
        char buf[MAXPATHLEN];
        getcwd(buf, MAXPATHLEN);
        clog << endl << "Current working directory: " << buf << endl;
    }

    // Convert the remaining m_regs to an override
    if (!flags.m_regs.empty())
    {
        ostringstream s;
        for (size_t i = 0; i < flags.m_regs.size(); ++i)
        {
            if (i)
                s << ',';
            s << flags.m_regs[i];
        }
        flags.m_overrides.append("CmdLineRegs", s.str());
    }

    // Convert the extra devices created with -L to an override
    if (!flags.m_extradevs.empty())
    {
        string n;
        for (size_t i = 0; i < flags.m_extradevs.size(); ++i)
        {
            if (i > 0)
                n += ',';
            n += flags.m_extradevs[i];
        }
        flags.m_overrides.append("CmdLineFileDevs", n);
    }

    if (flags.m_quiet)
    {
        // Silence the ROM loads.
        flags.m_overrides.append("*.ROMVerboseLoad", "false");
    }

    ////
    // Load the simulation configuration.
    // Process -c, group with overrides and argv.
    try
    {
        // Read configuration from file
        ConfigMap base_config;
        ConfigParser parser(base_config);
        try {
            parser(read_file(flags.m_configFile));
        } catch (runtime_error& e) {
            throw runtime_error("Error reading configuration file: " + flags.m_configFile + "\n" + e.what());
        }

        config.reset(new Config(base_config, flags.m_overrides, flags.m_argv));
    }
    catch (const exception& e)
    {
        PrintException(NULL, cerr, e);
        return 1;
    }

    ////
    // Initialize the random seed.
    // We place it in the configuration, so that dumpConfiguration below
    // can print it too (for reproducability).
    try
    {
        (void)config->getValue<string>("RandomSeed");
    }
    catch (const exception& e)
    {
        // Not in configuration(yet)
        char s[20];
        snprintf(s, 20, "%u", (unsigned)time(NULL));
        flags.m_overrides.append("RandomSeed", s);
    }
    {
        unsigned seed = config->getValue<unsigned>("RandomSeed");
        clog << "### random seed: " << seed << endl;
        srand(seed);
    }

    if (flags.m_dumpconf)
    {
        // Printing the configuration if requested. We need to
        // do/check this early, in case constructing the system
        // (below) fails.
        clog << "### simulator version: " PACKAGE_VERSION << endl;
        config->dumpConfiguration(clog, flags.m_configFile);
    }


    ////
    // Construct the simulator.
    // This instantiates all the components, in the initial (stopped) state.
    // It also populates the "config" object with a cache of all
    // values effectively looked up by the instantiated components.
    try
    {
        // Create the system
        sys.reset(new MGSystem(*config, !flags.m_interactive));
    }
    catch (const exception& e)
    {
        PrintException(NULL, cerr, e);
        return 1;
    }

    if (flags.m_dumpcache)
    {
        // Dump the configuration cache if requested.
        config->dumpConfigurationCache(clog);
    }

    if (flags.m_dumpvars)
    {
        // Dump the list of monitoring variables if requested.
        clog << "### begin monitor variables" << endl;
        ListSampleVariables(clog);
        clog << "### end monitor variables" << endl;
    }

    if (flags.m_areaTech > 0)
    {
        // Dump the area estimation information if requested.
        clog << "### begin area information" << endl;
#ifdef ENABLE_CACTI
        sys->DumpArea(cout, flags.m_areaTech);
#else
        clog << "# Warning: CACTI not enabled; reconfigure with --enable-cacti" << endl;
#endif
        clog << "### end area information" << endl;
    }

    if (flags.m_dumptopo)
    {
        // Dump the component topology diagram if requested.
        ofstream of(flags.m_topofile.c_str(), ios::out);
        config->dumpComponentGraph(of, flags.m_dumpnodeprops, flags.m_dumpedgeprops);
        of.close();
    }

    if (flags.m_earlyquit)
        // At this point the simulation is ready and we have dumped
        // everything requested. If the user requested to not do anything,
        // we can just stop here.
        return 0;

    // Otherwise, the simulation should start.

    CommandLineReader clr;
    comm.reset(new Communicator(*sys, &clr, flags.m_visual, flags.m_quiet));

    ////
    // Start the simulation.

    // First construct the monitor thread, if enabled.
    string mo_mdfile = config->getValueOrDefault<string>("MonitorMetadataFile", "mgtrace.md");
    string mo_tfile = config->getValueOrDefault<string>("MonitorTraceFile", "mgtrace.out");
    mo.reset(new Monitor(*sys, flags.m_enableMonitor,
                         mo_mdfile, flags.m_earlyquit ? "" : mo_tfile, !flags.m_interactive));

    // Simulation proper.
    // Rules:
    // - if interactive, then do not automatically start the simulation.
    // - if interactive at start, always remain interactive.
    // - if not interactive at start and the simulation stops abnormally, then become interactive unless -t is specified.
    // - upon becoming interative because of an exception, print the exception.
    // - always print statistics at termination if not quiet.
    // - always print final variables at termination.

    bool interactive = flags.m_interactive;
    try
    {
        if (!interactive)
        {
            // Non-interactive: automatically start and run until simulation terminates.
            try
            {
                mo->start();
                StepSystem(*sys, INFINITE_CYCLES);
                mo->stop();

            }
            catch (const exception& e)
            {
                mo->stop();
                if (flags.m_terminate)
                {
                    // Re-throw to terminate.
                    throw;
                }

                // else
                // Print the exception and become interactive.
                PrintException(sys.get(), cerr, e);
                interactive = true;
            }
        }

        if (interactive)
        {
            // Command loop
            cout << endl;
            cli_context ctx = { clr, *sys, *mo };

            while (HandleCommandLine(ctx) == false)
                /* just loop */;
        }
    }
    catch (const exception& e)
    {
        const ProgramTerminationException *ex = dynamic_cast<const ProgramTerminationException*>(&e);

        if (!flags.m_quiet || ex == NULL)
            // Print exception.
            PrintException(sys.get(), cerr, e);

        // Print statistics & final variables.
        AtEnd(*sys, flags);

        if (ex != NULL)
        {
            // The program is telling us how to terminate. Do it.
            if (ex->TerminateWithAbort())
                abort();
            else
                return ex->GetExitCode();
        }
        else
            // No more information, simply terminate with error.
            return 1;
    }

    // Print statistics & final variables.
    AtEnd(*sys, flags);

    return 0;
}
コード例 #2
0
ファイル: main.cpp プロジェクト: qyang/mgsim
int main(int argc, char** argv)
{
    struct timeval tv1, tv2, tv3;
    struct rusage ru1, ru2, ru3;
    
    gettimeofday(&tv1, 0);
    getrusage(RUSAGE_SELF, &ru1);
    
    srand(time(NULL));

    ProgramConfig flags;
    UNIQUE_PTR<Config> config;
    UNIQUE_PTR<MGSystem> sys;
#ifdef ENABLE_MONITOR
    UNIQUE_PTR<Monitor> mo;
#endif

    ////
    // Early initialization.
    // Argument parsing, no simulation yet.
    try
    {
        // Parse command line arguments
        argp_parse(&argp, argc, argv, 0, 0, &flags);
    }
    catch (const exception& e)
    {
        PrintException(NULL, cerr, e);
        return 1;
    }

    if (flags.m_interactive)
    {
        // Interactive mode: print name & version first
        clog << argp_program_version << endl;
    }

    // Convert the remaining m_regs to an override
    if (!flags.m_regs.empty())
    {
        ostringstream s;
        for (size_t i = 0; i < flags.m_regs.size(); ++i)
        {
            if (i)
                s << ',';
            s << flags.m_regs[i];
        }
        flags.m_overrides.append("CmdLineRegs", s.str());
    }

    // Convert the extra devices created with -L to an override
    if (!flags.m_extradevs.empty())
    {
        string n;
        for (size_t i = 0; i < flags.m_extradevs.size(); ++i)
        {
            if (i > 0)
                n += ',';
            n += flags.m_extradevs[i];
        }
        flags.m_overrides.append("CmdLineFileDevs", n);
    }

    if (flags.m_quiet)
    {
        // Silence the ROM loads.
        flags.m_overrides.append("*.ROMVerboseLoad", "false");
    }

    ////
    // Load the simulation configuration.
    // Process -c, group with overrides and argv.
    try
    {
        // Read configuration from file
        config.reset(new Config(flags.m_configFile, flags.m_overrides, flags.m_argv));
    }
    catch (const exception& e)
    {
        PrintException(NULL, cerr, e);
        return 1;
    }

    if (flags.m_dumpconf)
    {
        // Printing the configuration if requested. We need to
        // do/check this early, in case constructing the system
        // (below) fails.
        clog << "### simulator version: " PACKAGE_VERSION << endl;
        config->dumpConfiguration(clog, flags.m_configFile);
    }

    ////
    // Construct the simulator.
    // This instantiates all the components, in the initial (stopped) state.
    // It also populates the "config" object with a cache of all
    // values effectively looked up by the instantiated components.
    try
    {
        // Create the system
        sys.reset(new MGSystem(*config, !flags.m_interactive));
    }
    catch (const exception& e)
    {
        PrintException(NULL, cerr, e);
        return 1;
    }

    if (flags.m_dumpcache)
    {
        // Dump the configuration cache if requested.
        config->dumpConfigurationCache(clog);
    }

    if (flags.m_dumpvars)
    {
        // Dump the list of monitoring variables if requested.
        clog << "### begin monitor variables" << endl;
        ListSampleVariables(clog);
        clog << "### end monitor variables" << endl;
    }

    if (flags.m_areaTech > 0)
    {
        // Dump the area estimation information if requested.
        clog << "### begin area information" << endl;
#ifdef ENABLE_CACTI
        sys->DumpArea(cout, flags.m_areaTech);
#else
        clog << "# Warning: CACTI not enabled; reconfigure with --enable-cacti" << endl;
#endif
        clog << "### end area information" << endl;
    }

    if (flags.m_dumptopo)
    {
        // Dump the component topology diagram if requested.
        ofstream of(flags.m_topofile.c_str(), ios::out);
        config->dumpComponentGraph(of, flags.m_dumpnodeprops, flags.m_dumpedgeprops);
        of.close();
    }

    if (flags.m_earlyquit)
        // At this point the simulation is ready and we have dumped
        // everything requested. If the user requested to not do anything,
        // we can just stop here.
        return 0;

    // Otherwise, the simulation should start.

    ////
    // Start the simulation.

    // First construct the monitor thread, if enabled.
#ifdef ENABLE_MONITOR
    string mo_mdfile = config->getValueOrDefault<string>("MonitorMetadataFile", "mgtrace.md");
    string mo_tfile = config->getValueOrDefault<string>("MonitorTraceFile", "mgtrace.out");
    mo.reset(new Monitor(*sys, flags.m_enableMonitor,
                         mo_mdfile, flags.m_earlyquit ? "" : mo_tfile, !flags.m_interactive));
#endif

    // Simulation proper.
    // Rules:
    // - if interactive, then do not automatically start the simulation.
    // - if interactive at start, always remain interactive.
    // - if not interactive at start and the simulation stops abnormally, then become interactive unless -t is specified.
    // - upon becoming interative because of an exception, print the exception.
    // - always print statistics at termination if not quiet.
    // - always print final variables at termination.

    gettimeofday(&tv2, 0);
    getrusage(RUSAGE_SELF, &ru2);
    
    bool interactive = flags.m_interactive;
    try
    {
        if (!interactive)
        {
            // Non-interactive: automatically start and run until simulation terminates.
            try
            {
#ifdef ENABLE_MONITOR
                mo->start();
#endif
                StepSystem(*sys, INFINITE_CYCLES);
#ifdef ENABLE_MONITOR
                mo->stop();
#endif

            }
            catch (const exception& e)
            {
#ifdef ENABLE_MONITOR
                mo->stop();
#endif
                if (flags.m_terminate)
                {
                    // Re-throw to terminate.
                    throw;
                }

                // else
                // Print the exception and become interactive.
                PrintException(sys.get(), cerr, e);
                interactive = true;
            }
        }

        if (interactive)
        {
            // Command loop
            cout << endl;
            CommandLineReader clr;
            cli_context ctx = { clr, *sys
#ifdef ENABLE_MONITOR
                                , *mo
#endif
            };

            while (HandleCommandLine(ctx) == false)
                /* just loop */;
        }
    }
    catch (const exception& e)
    {
        const ProgramTerminationException *ex = dynamic_cast<const ProgramTerminationException*>(&e);

        if (!flags.m_quiet || ex == NULL)
            // Print exception.
            PrintException(sys.get(), cerr, e);

        gettimeofday(&tv3, 0);
        getrusage(RUSAGE_SELF, &ru3);
        
        std::cerr 
                << "Init time wallclock: " << tv2.tv_sec - tv1.tv_sec + tv2.tv_usec*0.000001 - tv1.tv_usec*0.000001 << std::endl
                << "Init time self: " << ru2.ru_utime.tv_sec - ru1.ru_utime.tv_sec + ru2.ru_utime.tv_usec*0.000001 - ru1.ru_utime.tv_usec*0.000001 << std::endl
                << "Sim time wallclock: " << tv3.tv_sec - tv2.tv_sec + tv3.tv_usec*0.000001 - tv2.tv_usec*0.000001 << std::endl
                << "Sim time self: " << ru3.ru_utime.tv_sec - ru2.ru_utime.tv_sec + ru3.ru_utime.tv_usec*0.000001 - ru2.ru_utime.tv_usec*0.000001 << std::endl
                ;   
        // Print statistics & final variables.
        AtEnd(*sys, flags);

        if (ex != NULL)
        {
            // The program is telling us how to terminate. Do it.
            if (ex->TerminateWithAbort())
                abort();
            else
                return ex->GetExitCode();
        }
        else
            // No more information, simply terminate with error.
            return 1;
    }

    gettimeofday(&tv3, 0);
    getrusage(RUSAGE_SELF, &ru3);
      
    std::cerr 
            << "Init time wallclock: " << tv2.tv_sec - tv1.tv_sec + tv2.tv_usec*0.000001 - tv1.tv_usec*0.000001 << std::endl
            << "Init time self: " << ru2.ru_utime.tv_sec - ru1.ru_utime.tv_sec + ru2.ru_utime.tv_usec*0.000001 - ru1.ru_utime.tv_usec*0.000001 << std::endl
            << "Sim time wallclock: " << tv3.tv_sec - tv2.tv_sec + tv3.tv_usec*0.000001 - tv2.tv_usec*0.000001 << std::endl
            << "Sim time self: " << ru3.ru_utime.tv_sec - ru2.ru_utime.tv_sec + ru3.ru_utime.tv_usec*0.000001 - ru2.ru_utime.tv_usec*0.000001 << std::endl
 ;   
    // Print statistics & final variables.
    AtEnd(*sys, flags);

    return 0;
}