project != p) continue;
if (rp->resource_type() != rsc_type) continue;
if (rp->state() > RESULT_FILES_DOWNLOADED) continue;
n++;
}
return n;
}
void show_resource(int rsc_type) {
unsigned int i;
fprintf(html_out, "", WIDTH2);
bool found = false;
for (i=0; iresult;
if (rsc_type!=RSC_TYPE_CPU && rp->resource_type() != rsc_type) continue;
if (atp->task_state() != PROCESS_EXECUTING) continue;
PROJECT* p = rp->project;
double ninst;
if (rsc_type == RSC_TYPE_CUDA) {
ninst = rp->avp->ncudas;
} else if (rsc_type == RSC_TYPE_ATI) {
ninst = rp->avp->natis;
} else {
ninst = rp->avp->avg_ncpus;
}
fprintf(html_out, "%.2f: %s%s: %.2fG ",
ninst,
colors[p->index%NCOLORS],
atp->result->rr_sim_misses_deadline?"*":"",
atp->result->name,
atp->flops_left/1e9
);
found = true;
}
if (!found) fprintf(html_out, "IDLE");
fprintf(html_out, " Jobs in progress\n");
for (i=0; i%s: %d\n", p->project_name, n);
}
}
fprintf(html_out, " | ");
}
int nproc_types = 1;
void html_start() {
char buf[256];
sprintf(buf, "%s%s", outfile_prefix, TIMELINE_FNAME);
html_out = fopen(buf, "w");
if (!html_out) {
fprintf(stderr, "can't open %s for writing\n", buf);
exit(1);
}
setbuf(html_out, 0);
fprintf(index_file, "
Timeline\n", buf);
fprintf(html_out, "BOINC client simulator
\n");
fprintf(html_out,
"Time | \n", WIDTH1
);
fprintf(html_out,
"CPU Job name and estimated time left color denotes project * means EDF mode | ", WIDTH2
);
if (gstate.host_info.have_cuda()) {
fprintf(html_out, "NVIDIA GPU | ", WIDTH2);
nproc_types++;
}
if (gstate.host_info.have_ati()) {
fprintf(html_out, "ATI GPU | ", WIDTH2);
nproc_types++;
}
fprintf(html_out, "
---|
\n");
}
void html_rec() {
if (html_msg.size()) {
fprintf(html_out,
"%.0f | ",
WIDTH1, gstate.now
);
fprintf(html_out,
"%s |
\n",
nproc_types*WIDTH2,
html_msg.c_str()
);
html_msg = "";
}
fprintf(html_out, "%.0f | ", WIDTH1, gstate.now);
if (active) {
show_resource(RSC_TYPE_CPU);
if (gpu_active) {
if (gstate.host_info.have_cuda()) {
show_resource(RSC_TYPE_CUDA);
}
if (gstate.host_info.have_ati()) {
show_resource(RSC_TYPE_ATI);
}
} else {
if (gstate.host_info.have_cuda()) {
fprintf(html_out, "OFF | ", WIDTH2);
}
if (gstate.host_info.have_ati()) {
fprintf(html_out, "OFF | ", WIDTH2);
}
}
} else {
fprintf(html_out, "OFF | ", WIDTH2);
if (gstate.host_info.have_cuda()) {
fprintf(html_out, "OFF | ", WIDTH2);
}
if (gstate.host_info.have_ati()) {
fprintf(html_out, "OFF | ", WIDTH2);
}
}
fprintf(html_out, "
\n");
}
void html_end() {
fprintf(html_out, "\n");
sim_results.compute();
sim_results.print(html_out);
print_project_results(html_out);
fprintf(html_out, "
\n");
fclose(html_out);
}
#ifdef USE_REC
void set_initial_rec() {
unsigned int i;
double sum=0;
double x = total_peak_flops();
for (i=0; iresource_share;
}
for (i=0; ipwf.rec = 86400*x*(p->resource_share/sum)/1e9;
}
}
void write_recs() {
fprintf(debt_file, "%f ", gstate.now);
for (unsigned int i=0; ipwf.rec);
}
fprintf(debt_file, "\n");
}
void make_graph(const char* title, const char* fname, int field) {
char gp_fname[256], cmd[256], png_fname[256];
sprintf(gp_fname, "%s%s.gp", outfile_prefix, fname);
FILE* f = fopen(gp_fname, "w");
fprintf(f,
"set terminal png small size 1024, 768\n"
"set title \"%s\"\n"
"set yrange[0:]\n"
"plot ",
title
);
for (unsigned int i=0; iproject_name,
(i==gstate.projects.size()-1)?"\n":", \\\n"
);
}
fclose(f);
sprintf(png_fname, "%s%s.png", outfile_prefix, fname);
sprintf(cmd, "gnuplot < %s > %s", gp_fname, png_fname);
fprintf(index_file, "
Graph of %s\n", png_fname, title);
system(cmd);
}
#else
// lines in the debt file have these fields:
// time
// per project:
// overall LTD
// CPU LTD
// CPU STD
// [NVIDIA LTD]
// [NVIDIA STD]
// [ATI LTD]
// [ATI STD]
//
void write_debts() {
fprintf(debt_file, "%f ", gstate.now);
for (unsigned int i=0; ipwf.overall_debt,
p->cpu_pwf.long_term_debt,
p->cpu_pwf.short_term_debt
);
if (gstate.host_info.have_cuda()) {
fprintf(debt_file, "%f %f ",
p->cuda_pwf.long_term_debt,
p->cuda_pwf.short_term_debt
);
}
if (gstate.host_info.have_ati()) {
fprintf(debt_file, "%f %f",
p->ati_pwf.long_term_debt,
p->ati_pwf.short_term_debt
);
}
}
fprintf(debt_file, "\n");
}
// generate a bunch of debt graphs
//
void make_graph(const char* title, const char* fname, int field, int nfields) {
char gp_fname[256], cmd[256], png_fname[256];
sprintf(gp_fname, "%s%s.gp", outfile_prefix, fname);
FILE* f = fopen(gp_fname, "w");
fprintf(f,
"set terminal png small size 1024, 768\n"
"set title \"%s\"\n"
"plot ",
title
);
for (unsigned int i=0; iproject_name,
(i==gstate.projects.size()-1)?"\n":", \\\n"
);
}
fclose(f);
sprintf(png_fname, "%s%s.png", outfile_prefix, fname);
sprintf(cmd, "gnuplot < %s > %s", gp_fname, png_fname);
fprintf(index_file, "
Graph of %s\n", png_fname, title);
system(cmd);
}
void debt_graphs() {
int nfields = 3 + (gstate.host_info.have_cuda()?2:0) + (gstate.host_info.have_ati()?2:0);
make_graph("Overall debt", "debt_overall", 0, nfields);
make_graph("CPU LTD", "debt_cpu_ltd", 1, nfields);
make_graph("CPU STD", "debt_cpu_std", 2, nfields);
if (gstate.host_info.have_cuda()) {
make_graph("NVIDIA LTD", "debt_nvidia_ltd", 3, nfields);
make_graph("NVIDIA STD", "debt_nvidia_std", 4, nfields);
}
if (gstate.host_info.have_ati()) {
int off = gstate.host_info.have_cuda()?2:0;
make_graph("ATI LTD", "debt_ati_ltd", 3+off, nfields);
make_graph("ATI STD", "debt_ati_std", 4+off, nfields);
}
}
#endif
void simulate() {
bool action;
double start = START_TIME;
gstate.now = start;
html_start();
msg_printf(0, MSG_INFO,
"starting simulation. delta %f duration %f", delta, duration
);
while (1) {
on = on_proc.sample(delta);
if (on) {
active = active_proc.sample(delta);
if (active) {
gpu_active = gpu_active_proc.sample(delta);
} else {
gpu_active = false;
}
connected = connected_proc.sample(delta);
} else {
active = gpu_active = connected = false;
}
if (on) {
while (1) {
action = gstate.active_tasks.poll();
action |= gstate.handle_finished_apps();
gpu_suspend_reason = gpu_active?0:1;
action |= gstate.possibly_schedule_cpus();
if (connected) {
action |= gstate.scheduler_rpc_poll();
}
msg_printf(0, MSG_INFO, action?"did action":"did no action");
if (!action) break;
}
}
msg_printf(0, MSG_INFO, "took time step");
for (unsigned int i=0; itask_state() == PROCESS_EXECUTING) {
atp->elapsed_time += delta;
}
}
html_rec();
#ifdef USE_REC
write_recs();
#else
write_debts();
#endif
gstate.now += delta;
if (gstate.now > start + duration) break;
}
html_end();
}
void show_app(APP* app) {
msg_printf(app->project, MSG_INFO,
"app %s fpops_est %.0fG fpops mean %.0fG std_dev %.0fG latency %.2f weight %.2f",
app->name, app->fpops_est/1e9,
app->fpops.mean/1e9, app->fpops.std_dev/1e9,
app->latency_bound,
app->weight
);
for (unsigned int i=0; iapp != app) continue;
msg_printf(avp->project, MSG_INFO,
" app version %s %d (%s): ncpus %.2f ncuda %.2f nati %.2f flops %.0fG",
avp->app_name, avp->version_num, avp->plan_class,
avp->avg_ncpus, avp->ncudas, avp->natis,
avp->flops/1e9
);
}
}
// get application params,
// and set "ignore" for apps that have no versions or no params.
//
// App params can be specified in 2 ways:
// - the presence of a WU and result for that app
// - app.latency_bound and app.fpops_est are populated
//
void get_app_params() {
APP* app;
unsigned int i, j;
for (i=0; iapp;
if (!app->latency_bound) {
app->latency_bound = rp->report_deadline - rp->received_time;
}
}
for (i=0; iapp;
if (!app->fpops_est) {
app->fpops_est = wup->rsc_fpops_est;
}
}
for (i=0; iignore = true;
}
for (i=0; iapp->ignore = false;
}
for (i=0; ifpops_est || !app->latency_bound) {
app->ignore = true;
msg_printf(app->project, MSG_INFO,
"ignoring app %s - no fpops_est or latency bound",
app->name
);
} else if (app->ignore) {
msg_printf(app->project, MSG_INFO,
"ignoring app %s - no app versions",
app->name
);
} else {
if (!app->fpops.mean) {
app->fpops.mean = app->fpops_est;
}
if (!app->weight) {
app->weight = 1;
}
show_app(app);
}
}
}
// zero backoffs and debts.
//
void clear_backoff() {
unsigned int i;
for (i=0; icpu_pwf.reset();
p->cuda_pwf.reset();
p->ati_pwf.reset();
p->min_rpc_time = 0;
}
}
// remove apps with no app versions,
// then projects with no apps
//
void cull_projects() {
unsigned int i;
PROJECT* p;
for (i=0; idont_request_more_work = true;
p->no_cpu_apps = true;
p->no_cuda_apps = true;
p->no_ati_apps = true;
}
for (i=0; incudas) {
avp->project->no_cuda_apps = false;
} else if (avp->natis) {
avp->project->no_ati_apps = false;
} else {
avp->project->no_cpu_apps = false;
}
}
for (i=0; iignore) {
app->project->dont_request_more_work = false;
}
}
vector::iterator iter;
iter = gstate.projects.begin();
while (iter != gstate.projects.end()) {
p = *iter;
if (p->dont_request_more_work) {
msg_printf(p, MSG_INFO,
"Removing from simulation - no jobs in client_state.xml"
);
iter = gstate.projects.erase(iter);
} else {
iter++;
}
}
}
void do_client_simulation() {
char buf[256], buf2[256];
msg_printf(0, MSG_INFO, "SIMULATION START");
sprintf(buf, "%s%s", infile_prefix, CONFIG_FILE);
read_config_file(true, buf);
fprintf(index_file,
"
Configuration file (cc_config.xml)\n",
buf
);
config.show();
gstate.add_platform("client simulator");
sprintf(buf, "%s%s", infile_prefix, STATE_FILE_NAME);
gstate.parse_state_file_aux(buf);
fprintf(index_file,
"
State file (client_state.xml)\n",
buf
);
sprintf(buf, "%s%s", infile_prefix, GLOBAL_PREFS_FILE_NAME);
sprintf(buf2, "%s%s", infile_prefix, GLOBAL_PREFS_OVERRIDE_FILE);
gstate.read_global_prefs(buf, buf2);
fprintf(index_file,
"
Preferences file (global_prefs.xml)\n"
"
Preferences override file (global_prefs_override.xml)\n"
"Output files
\n"
"Log file\n",
buf, buf2, log_filename
);
get_app_params();
cull_projects();
int j=0;
for (unsigned int i=0; iindex = j++;
}
clear_backoff();
gstate.workunits.clear();
gstate.results.clear();
gstate.set_ncpus();
work_fetch.init();
#ifdef USE_REC
set_initial_rec();
#endif
gstate.request_work_fetch("init");
simulate();
sim_results.compute();
sprintf(buf, "%s%s", outfile_prefix, SUMMARY_FNAME);
FILE* f = fopen(buf, "w");
sim_results.print(f);
fclose(f);
printf("Peak FLOPS: CPU %.2fG GPU %.2fG\n",
cpu_peak_flops()/1e9,
gpu_peak_flops()/1e9
);
sim_results.print(stdout);
// then other
print_project_results(stdout);
#ifdef USE_REC
make_graph("REC", "rec", 0);
#else
debt_graphs();
#endif
}
char* next_arg(int argc, char** argv, int& i) {
if (i >= argc) {
fprintf(stderr, "Missing command-line argument\n");
usage(argv[0]);
}
return argv[i++];
}
int main(int argc, char** argv) {
int i, retval;
char buf[256];
sim_results.clear();
for (i=1; iInput files\n"
);
sprintf(log_filename, "%s%s", outfile_prefix, LOG_FNAME);
logfile = fopen(log_filename, "w");
if (!logfile) {
fprintf(stderr, "Can't open %s\n", buf);
exit(1);
}
setbuf(logfile, 0);
sprintf(buf, "%s%s", outfile_prefix, DEBT_FNAME);
debt_file = fopen(buf, "w");
do_client_simulation();
}