void hsf_global_config_from_parameter_table(){ global_config_from_strs(&global_config,parameter_table,parameter_size); }
/* * main function - reads instantaneous power values (in W) from a trace * file (e.g. "gcc.ptrace") and outputs instantaneous temperature values (in C) to * a trace file("gcc.ttrace"). also outputs steady state temperature values * (including those of the internal nodes of the model) onto stdout. the * trace files are 2-d matrices with each column representing a functional * functional block and each row representing a time unit(sampling_intvl). * columns are tab-separated and each row is a separate line. the first * line contains the names of the functional blocks. the order in which * the columns are specified doesn't have to match that of the floorplan * file. */ int main(int argc, char **argv) { int i, j, idx, base = 0, count = 0, n = 0; int num, size, lines = 0, do_transient = TRUE; char **names; double *vals; /* trace file pointers */ FILE *pin, *tout = NULL; /* floorplan */ flp_t *flp; /* hotspot temperature model */ RC_model_t *model; /* instantaneous temperature and power values */ double *temp = NULL, *power; double total_power = 0.0; /* steady state temperature and power values */ double *overall_power, *steady_temp; /* thermal model configuration parameters */ thermal_config_t thermal_config; /* global configuration parameters */ global_config_t global_config; /* table to hold options and configuration */ str_pair table[MAX_ENTRIES]; /* variables for natural convection iterations */ int natural = 0; double avg_sink_temp = 0; int natural_convergence = 0; double r_convec_old; if (!(argc >= 5 && argc % 2)) { usage(argc, argv); return 1; } size = parse_cmdline(table, MAX_ENTRIES, argc, argv); global_config_from_strs(&global_config, table, size); /* no transient simulation, only steady state */ if(!strcmp(global_config.t_outfile, NULLFILE)) do_transient = FALSE; /* read configuration file */ if (strcmp(global_config.config, NULLFILE)) size += read_str_pairs(&table[size], MAX_ENTRIES, global_config.config); /* * earlier entries override later ones. so, command line options * have priority over config file */ size = str_pairs_remove_duplicates(table, size); /* get defaults */ thermal_config = default_thermal_config(); /* modify according to command line / config file */ thermal_config_add_from_strs(&thermal_config, table, size); /* if package model is used, run package model */ if (((idx = get_str_index(table, size, "package_model_used")) >= 0) && !(table[idx].value==0)) { if (thermal_config.package_model_used) { avg_sink_temp = thermal_config.ambient + SMALL_FOR_CONVEC; natural = package_model(&thermal_config, table, size, avg_sink_temp); if (thermal_config.r_convec<R_CONVEC_LOW || thermal_config.r_convec>R_CONVEC_HIGH) printf("Warning: Heatsink convection resistance is not realistic, double-check your package settings...\n"); } } /* dump configuration if specified */ if (strcmp(global_config.dump_config, NULLFILE)) { size = global_config_to_strs(&global_config, table, MAX_ENTRIES); size += thermal_config_to_strs(&thermal_config, &table[size], MAX_ENTRIES-size); /* prefix the name of the variable with a '-' */ dump_str_pairs(table, size, global_config.dump_config, "-"); } /* initialization: the flp_file global configuration * parameter is overridden by the layer configuration * file in the grid model when the latter is specified. */ flp = read_flp(global_config.flp_file, FALSE); /* allocate and initialize the RC model */ model = alloc_RC_model(&thermal_config, flp); populate_R_model(model, flp); if (do_transient) populate_C_model(model, flp); #if VERBOSE > 2 debug_print_model(model); #endif /* allocate the temp and power arrays */ /* using hotspot_vector to internally allocate any extra nodes needed */ if (do_transient) temp = hotspot_vector(model); power = hotspot_vector(model); steady_temp = hotspot_vector(model); overall_power = hotspot_vector(model); /* set up initial instantaneous temperatures */ if (do_transient && strcmp(model->config->init_file, NULLFILE)) { if (!model->config->dtm_used) /* initial T = steady T for no DTM */ read_temp(model, temp, model->config->init_file, FALSE); else /* initial T = clipped steady T with DTM */ read_temp(model, temp, model->config->init_file, TRUE); } else if (do_transient) /* no input file - use init_temp as the common temperature */ set_temp(model, temp, model->config->init_temp); /* n is the number of functional blocks in the block model * while it is the sum total of the number of functional blocks * of all the floorplans in the power dissipating layers of the * grid model. */ if (model->type == BLOCK_MODEL) n = model->block->flp->n_units; else if (model->type == GRID_MODEL) { for(i=0; i < model->grid->n_layers; i++) if (model->grid->layers[i].has_power) n += model->grid->layers[i].flp->n_units; } else fatal("unknown model type\n"); if(!(pin = fopen(global_config.p_infile, "r"))) fatal("unable to open power trace input file\n"); if(do_transient && !(tout = fopen(global_config.t_outfile, "w"))) fatal("unable to open temperature trace file for output\n"); /* names of functional units */ names = alloc_names(MAX_UNITS, STR_SIZE); if(read_names(pin, names) != n) fatal("no. of units in floorplan and trace file differ\n"); /* header line of temperature trace */ if (do_transient) write_names(tout, names, n); /* read the instantaneous power trace */ vals = dvector(MAX_UNITS); while ((num=read_vals(pin, vals)) != 0) { if(num != n) fatal("invalid trace file format\n"); /* permute the power numbers according to the floorplan order */ if (model->type == BLOCK_MODEL) for(i=0; i < n; i++) power[get_blk_index(flp, names[i])] = vals[i]; else for(i=0, base=0, count=0; i < model->grid->n_layers; i++) { if(model->grid->layers[i].has_power) { for(j=0; j < model->grid->layers[i].flp->n_units; j++) { idx = get_blk_index(model->grid->layers[i].flp, names[count+j]); power[base+idx] = vals[count+j]; } count += model->grid->layers[i].flp->n_units; } base += model->grid->layers[i].flp->n_units; } /* compute temperature */ if (do_transient) { /* if natural convection is considered, update transient convection resistance first */ if (natural) { avg_sink_temp = calc_sink_temp(model, temp); natural = package_model(model->config, table, size, avg_sink_temp); populate_R_model(model, flp); } /* for the grid model, only the first call to compute_temp * passes a non-null 'temp' array. if 'temp' is NULL, * compute_temp remembers it from the last non-null call. * this is used to maintain the internal grid temperatures * across multiple calls of compute_temp */ if (model->type == BLOCK_MODEL || lines == 0) compute_temp(model, power, temp, model->config->sampling_intvl); else compute_temp(model, power, NULL, model->config->sampling_intvl); /* permute back to the trace file order */ if (model->type == BLOCK_MODEL) for(i=0; i < n; i++) vals[i] = temp[get_blk_index(flp, names[i])]; else for(i=0, base=0, count=0; i < model->grid->n_layers; i++) { if(model->grid->layers[i].has_power) { for(j=0; j < model->grid->layers[i].flp->n_units; j++) { idx = get_blk_index(model->grid->layers[i].flp, names[count+j]); vals[count+j] = temp[base+idx]; } count += model->grid->layers[i].flp->n_units; } base += model->grid->layers[i].flp->n_units; } /* output instantaneous temperature trace */ write_vals(tout, vals, n); } /* for computing average */ if (model->type == BLOCK_MODEL) for(i=0; i < n; i++) overall_power[i] += power[i]; else for(i=0, base=0; i < model->grid->n_layers; i++) { if(model->grid->layers[i].has_power) for(j=0; j < model->grid->layers[i].flp->n_units; j++) overall_power[base+j] += power[base+j]; base += model->grid->layers[i].flp->n_units; } lines++; } if(!lines) fatal("no power numbers in trace file\n"); /* for computing average */ if (model->type == BLOCK_MODEL) for(i=0; i < n; i++) { overall_power[i] /= lines; //overall_power[i] /=150; //reduce input power for natural convection total_power += overall_power[i]; } else for(i=0, base=0; i < model->grid->n_layers; i++) { if(model->grid->layers[i].has_power) for(j=0; j < model->grid->layers[i].flp->n_units; j++) { overall_power[base+j] /= lines; total_power += overall_power[base+j]; } base += model->grid->layers[i].flp->n_units; } /* natural convection r_convec iteration, for steady-state only */ natural_convergence = 0; if (natural) { /* natural convection is used */ while (!natural_convergence) { r_convec_old = model->config->r_convec; /* steady state temperature */ steady_state_temp(model, overall_power, steady_temp); avg_sink_temp = calc_sink_temp(model, steady_temp) + SMALL_FOR_CONVEC; natural = package_model(model->config, table, size, avg_sink_temp); populate_R_model(model, flp); if (avg_sink_temp > MAX_SINK_TEMP) fatal("too high power for a natural convection package -- possible thermal runaway\n"); if (fabs(model->config->r_convec-r_convec_old)<NATURAL_CONVEC_TOL) natural_convergence = 1; } } else /* natural convection is not used, no need for iterations */ /* steady state temperature */ steady_state_temp(model, overall_power, steady_temp); /* print steady state results */ fprintf(stdout, "Unit\tSteady(Kelvin)\n"); dump_temp(model, steady_temp, "stdout"); /* dump steady state temperatures on to file if needed */ if (strcmp(model->config->steady_file, NULLFILE)) dump_temp(model, steady_temp, model->config->steady_file); /* for the grid model, optionally dump the most recent * steady state temperatures of the grid cells */ if (model->type == GRID_MODEL && strcmp(model->config->grid_steady_file, NULLFILE)) dump_steady_temp_grid(model->grid, model->config->grid_steady_file); #if VERBOSE > 2 if (model->type == BLOCK_MODEL) { if (do_transient) { fprintf(stdout, "printing temp...\n"); dump_dvector(temp, model->block->n_nodes); } fprintf(stdout, "printing steady_temp...\n"); dump_dvector(steady_temp, model->block->n_nodes); } else { if (do_transient) { fprintf(stdout, "printing temp...\n"); dump_dvector(temp, model->grid->total_n_blocks + EXTRA); } fprintf(stdout, "printing steady_temp...\n"); dump_dvector(steady_temp, model->grid->total_n_blocks + EXTRA); } #endif /* cleanup */ fclose(pin); if (do_transient) fclose(tout); delete_RC_model(model); free_flp(flp, FALSE); if (do_transient) free_dvector(temp); free_dvector(power); free_dvector(steady_temp); free_dvector(overall_power); free_names(names); free_dvector(vals); return 0; }
/* main function for the floorplanner */ int main(int argc, char **argv) { flp_desc_t *flp_desc; flp_t *flp; RC_model_t *model; double *power; thermal_config_t thermal_config; flp_config_t flp_config; global_config_t global_config; str_pair table[MAX_ENTRIES]; int size, compacted; if (!(argc >= 7 && argc % 2)) { usage(argc, argv); return 1; } size = parse_cmdline(table, MAX_ENTRIES, argc, argv); global_config_from_strs(&global_config, table, size); /* read configuration file */ if (strcmp(global_config.config, NULLFILE)) size += read_str_pairs(&table[size], MAX_ENTRIES, global_config.config); /* * in the str_pair 'table', earlier entries override later ones. * so, command line options have priority over config file */ size = str_pairs_remove_duplicates(table, size); /* get defaults */ thermal_config = default_thermal_config(); flp_config = default_flp_config(); /* modify according to command line / config file */ thermal_config_add_from_strs(&thermal_config, table, size); flp_config_add_from_strs(&flp_config, table, size); /* dump configuration if specified */ if (strcmp(global_config.dump_config, NULLFILE)) { size = global_config_to_strs(&global_config, table, MAX_ENTRIES); size += thermal_config_to_strs(&thermal_config, &table[size], MAX_ENTRIES-size); size += flp_config_to_strs(&flp_config, &table[size], MAX_ENTRIES-size); /* prefix the name of the variable with a '-' */ dump_str_pairs(table, size, global_config.dump_config, "-"); } /* HotFloorplan currently uses the block model and does not * support the grid model. */ if (!strcasecmp(thermal_config.model_type, GRID_MODEL_STR)) fatal("HotFloorplan doesn't support the grid model\n"); /* description of the functional blocks to be floorplanned */ flp_desc = read_flp_desc(global_config.flp_desc, &flp_config); /* * just an empty frame with blocks' names. * block positions not known yet. */ flp = flp_placeholder(flp_desc); /* temperature model */ model = alloc_RC_model(&thermal_config, flp); /* input power vector */ power = hotspot_vector(model); read_power(model, power, global_config.power_in); /* main floorplanning routine */ compacted = floorplan(flp, flp_desc, model, power); /* * print the finally selected floorplan in a format that can * be understood by tofig.pl (which converts it to a FIG file) */ print_flp_fig(flp); /* print the floorplan statistics */ if (flp_config.wrap_l2 && !strcasecmp(flp_desc->units[flp_desc->n_units-1].name, flp_config.l2_label)) print_flp_stats(flp, model, flp_config.l2_label, global_config.power_in, global_config.flp_desc); /* print the wire delays between blocks */ print_wire_delays(flp, thermal_config.base_proc_freq); /* also output the floorplan to a file readable by hotspot */ dump_flp(flp, global_config.flp_out, FALSE); free_flp_desc(flp_desc); delete_RC_model(model); free_dvector(power); /* while deallocating, free the compacted blocks too */ free_flp(flp, compacted); return 0; }