. // web interface to client simulator // // to use this, symlink to it from the html/user dir of a BOINC project, // create an apache-writable dir called "scenarios" there, // and symlink from html/inc to sim_util.inc require_once("../inc/util.inc"); require_once("../inc/sim_util.inc"); ini_set ("memory_limit", "1G"); set_time_limit(0); function get_comments($dir) { $d = "$dir/comments"; if (!is_dir($d)) return null; $dd = opendir($d); $x = ""; while (false !== ($f = readdir($dd))) { if ($f == ".") continue; if ($f == "..") continue; if (strlen($x)) $x .= "
\n"; $userid = (int)file_get_contents("$d/$f/userid"); $user = BoincUser::lookup_id($userid); $comment = file_get_contents("$d/$f/comment"); $date = date_str(filemtime("$d/$f/comment")); $x .= "By $user->name ($date):
$comment\n"; } return $x; } function nsims($scen) { $d = opendir("scenarios/$scen/simulations"); $n = 0; while (false !== ($f = readdir($d))) { if ($f == ".") continue; if ($f == "..") continue; $n++; } return $n; } function show_scenario_summary($f) { $desc = file_get_contents("scenarios/$f/description"); $userid = (int)file_get_contents("scenarios/$f/userid"); $user = BoincUser::lookup_id($userid); $date = date_str(filemtime("scenarios/$f")); $nsims = nsims($f); echo " $f $user->name $date $nsims $desc "; } // show existing scenarios, "create scenario" button // function show_scenarios() { page_head("The BOINC Client Emulator"); echo " The BOINC Client Emulator (BCE) emulates a BOINC client attached to one or more projects. It predicts, in a few seconds, what the latest BOINC client will do over a period of day or months. By reporting problem situations to BOINC developers, you can help us fix bugs and improve performance.

Scenarios

The inputs to BCE, called scenarios, describe a particular computer and the project to which it's attached. A scenario consists of: You create a scenario by uploading these files using the Create a scenario button below. You can use the files from a running BOINC client to emulate that client.

You can modify these files, or create new ones, to study hypothetical scenarios (e.g. hosts with a large number of CPUs, hosts attached to a large number of projects, projects with very short or long jobs, and so on). See The BCE documentation for details.

Simulations

You can run simulations based on existing scenarios (including scenarios created by other people). The parameters of a simulation include The outputs of a simulation include

Comments and reports

When you examine the results of a simulation, you may find places where the BOINC client made bad scheduling or work-fetch decisions. Or you find may places where the simulator doesn't seem to be working correctly. In such cases, please add a comment to the simulation, indicating the nature of the problem and the simulation time when it occurred.

Please post to the boinc_dev email list if


"; show_button( "sim_web.php?action=create_scenario_form", "Create a scenario", "Create a new scenario" ); echo "

Existing scenarios

"; start_table(); echo " ID
Click to see simulations Who When # Simulations Description "; $d = opendir("scenarios"); $dirs = array(); while (false !== ($f = readdir($d))) { if ($f === ".") continue; if ($f === "..") continue; $dirs[] = $f; } rsort($dirs); foreach ($dirs as $f) { show_scenario_summary($f); } echo "\n"; page_tail(); } // show form for creating a scenario // function create_scenario_form() { get_logged_in_user(); page_head("Create a scenario"); echo " To create a scenario: choose the input files, enter a short description, and click OK (items with * are required).
"; row2("* client_state.xml", ""); row2("global_prefs.xml", ""); row2("global_prefs_override.xml", ""); row2("cc_config.xml", ""); row2("* Description", ""); row2("", ""); echo "
"; page_tail(); } // create a subdir $dir/N for the first available N // function create_dir_seqno($dir) { $i = -1; $d = opendir($dir); while (false !== ($f = readdir($d))) { $j = -1; $n = sscanf($f, "%d", $j); if ($n == 1 && $j >= 0) { if ($j > $i) { $i = $j; } } } $i++; $p = "$dir/$i"; mkdir($p); return "$i"; } // choose scenario name // create dir, put files there // create meta-data file // redirect to show scenario // function create_scenario() { $user = get_logged_in_user(); $csname = $_FILES['client_state']['tmp_name']; if (!is_uploaded_file($csname)) { error_page("You must specify a client_state.xml file."); } $desc = post_str("description", true); if (!strlen($desc)) { error_page("You must supply a description."); } $desc = strip_tags($desc); $sname = create_dir_seqno("scenarios"); $d = "scenarios/$sname"; move_uploaded_file($csname, "$d/client_state.xml"); $gp = $_FILES['global_prefs']['tmp_name']; if (is_uploaded_file($gp)) { move_uploaded_file($gp, "$d/global_prefs.xml"); } $gpo = $_FILES['global_prefs_override']['tmp_name']; if (is_uploaded_file($gpo)) { move_uploaded_file($gpo, "$d/global_prefs_override.xml"); } $ccc = $_FILES['cc_config']['tmp_name']; if (is_uploaded_file($ccc)) { move_uploaded_file($ccc, "$d/cc_config.xml"); } file_put_contents("$d/userid", "$user->id"); file_put_contents("$d/description", $desc); mkdir("$d/simulations"); header("Location: sim_web.php?action=show_scenario&name=$sname"); } function show_simulation_summary($scen, $sim) { $dir = "scenarios/$scen/simulations/$sim"; $userid = (int)file_get_contents("$dir/userid"); $user = BoincUser::lookup_id($userid); $date = date_str(filemtime($dir)); echo " $sim $user->name $date
".file_get_contents("$dir/inputs.txt")."
        
".file_get_contents("$dir/results.txt")."
        ".get_comments($dir)."
        
    ";
}

// show:
// links to files
// list of existing simulations
// link for new simulation
//
function show_scenario() {
    $name = get_str("name");
    $d = "scenarios/$name";
    if (!is_dir($d)) {
        error_page("No such scenario");
    }
    page_head("Scenario $name");
    $desc = file_get_contents("scenarios/$name/description");
    $userid = (int)file_get_contents("scenarios/$name/userid");
    $user = BoincUser::lookup_id($userid);
    $date = date_str(filemtime("scenarios/$name"));
    start_table();
    row2("Creator", $user->name);
    row2("When", $date);
    row2("Description", $desc);
    $x = "client_state.xml";
    if (file_exists("$d/global_prefs.xml")) {
        $x .= "
global_prefs.xml\n"; } if (file_exists("$d/global_prefs_override.xml")) { $x .= "
global_prefs_override.xml\n"; } if (file_exists("$d/cc_config.xml")) { $x .= "
cc_config.xml\n"; } row2("Input files", $x); end_table(); show_button("sim_web.php?action=simulation_form&scen=$name", "Do new simulation", "Do new simulation" ); echo "

Simulations

"; start_table(); echo " ID
Click for details Who When Parameters Results Comments "; $dirs = array(); $s = opendir("$d/simulations"); while (false !== ($f = readdir($s))) { if (!is_numeric($f)) continue; $dirs[] = $f; } rsort($dirs); foreach ($dirs as $f) { show_simulation_summary($name, $f); } end_table(); page_tail(); } function log_flag_boxes() { return " CPU scheduling debug
Round-robin simulation info
Round-robin simulation details
Work fetch debug "; } function simulation_form() { $scen = get_str("scen"); $detail = get_str("detail", true); page_head("Do simulation"); start_table(); echo "
"; row2("Duration", " seconds"); row2("Time step", " seconds"); if ($detail) { row2("Half life of average-credit decay", " days" ); row2("Existing jobs only?
If checked, simulate only the jobs in the client state file. Otherwise, simulate an infinite stream of jobs modeled after those in the state file.", "" ); row2("Scheduler does detailed deadline check?
If checked, the scheduler's deadline decisions will use a detailed EDF simulation rather than an approximation.", "" ); row2("Client uses pure Round-robin?
If checked, job scheduling will use a simple round-robin policy.", "" ); row2("Include projects without apps", "" ); } else { row2("", "More options"); } row2("Log flags", log_flag_boxes()); row2("", ""); echo "\n"; end_table(); page_tail(); } // create directory for simulation, // run simulation, // redirect to simulation page // function simulation_action() { $user = get_logged_in_user(); $scen = post_str("scen"); if (!is_dir("scenarios/$scen")) { error_page("no such scenario"); } $sim_dir = "scenarios/$scen/simulations"; $sim_name = create_dir_seqno($sim_dir); $sim_path = "$sim_dir/$sim_name"; $policy = new POLICY(""); $policy->duration = (double)post_str("duration"); $policy->delta = (double)post_str("delta"); $policy->rec_half_life = (double)post_str("rec_half_life_days")*86400; $policy->existing_jobs_only = post_str("existing_jobs_only", true); $policy->cpu_sched_rr_only = post_str("cpu_sched_rr_only", true); $policy->include_empty_projects = post_str("include_empty_projects", true); $policy->server_uses_workload = post_str("server_uses_workload", true); file_put_contents("$sim_path/userid", "$user->id"); $x = "\n"; if (post_str("cpu_sched_debug", true)) { $x .= "\n"; } if (post_str("rr_simulation", true)) { $x .= "\n"; } if (post_str("rrsim_detail", true)) { $x .= "\n"; } if (post_str("work_fetch_debug", true)) { $x .= "\n"; } $x .= "\n"; file_put_contents("$sim_path/log_flags.xml", $x); do_sim("scenarios/$scen", $sim_path, $policy); header("Location: sim_web.php?action=show_simulation&scen=$scen&sim=$sim_name"); } // show links to files in simulation directory // function show_simulation() { $scen = get_str("scen"); $sim = get_str("sim"); $dir = "scenarios/$scen/simulations/$sim"; if (!is_dir($dir)) { error_page("No such simulation"); } page_head("Simulation $sim"); start_table(); $userid = (int)file_get_contents("$dir/userid"); $user = BoincUser::lookup_id($userid); $date = date_str(filemtime($dir)); row2("Scenario", "$scen"); row2("Who", $user->name); row2("When", $date); row2("Parameters", "
".file_get_contents("$dir/inputs.txt")."
"); row2("Results", "
".file_get_contents("$dir/results.txt")."
"); $x = file_get_contents("$dir/index.html"); $x = str_replace("

Output files

", "", $x); $x = str_replace("href=", "href=scenarios/$scen/simulations/$sim/", $x); row2("Output files", $x); $x = get_comments($dir); if ($x) { row2("Comments", $x); } echo "
"; row2("", "" ); echo "
"; end_table(); page_tail(); } function add_comment() { $user = get_logged_in_user(); $scen = get_str("scen"); $sim = get_str("sim"); $dir = "scenarios/$scen/simulations/$sim"; if (!is_dir($dir)) { error_page("No such simulation"); } $cdir = "$dir/comments"; @mkdir($cdir); $c = create_dir_seqno($cdir); $p = "$cdir/$c"; file_put_contents("$p/userid", "$user->id"); file_put_contents("$p/comment", get_str("comment")); header("Location: sim_web.php?action=show_simulation&scen=$scen&sim=$sim"); } $action = get_str("action", true); if (!$action) $action = post_str("action", true); switch ($action) { case "create_scenario_form": create_scenario_form(); break; case "create_scenario": create_scenario(); break; case "show_scenario": show_scenario(); break; case "simulation_form": simulation_form(); break; case "simulation_action": simulation_action(); break; case "show_simulation": show_simulation(); break; case "add_comment": add_comment(); break; case null: show_scenarios(); break; default: die("unknown action $action"); } ?>