gem5/splash2/codes/apps/radiosity/rad_tools.C
Sanchayan Maity 0f4b39775c Fix splash2 benchmark
During the last commit of splash2 benchmark it seems before committing
when we ran "make clean", it effectively undid what the patch at below
link did
http://www.capsl.udel.edu/splash/Download.html

Fix this since without this it is not possible to build the arcane
splash2 benchmark.
2017-04-26 21:33:02 +05:30

537 lines
18 KiB
C

/*************************************************************************/
/* */
/* Copyright (c) 1994 Stanford University */
/* */
/* All rights reserved. */
/* */
/* Permission is given to use, copy, and modify this software for any */
/* non-commercial purpose as long as this copyright notice is not */
/* removed. All other uses, including redistribution in whole or in */
/* part, are forbidden without prior written permission. */
/* */
/* This software is provided with absolutely no warranty and no */
/* support. */
/* */
/*************************************************************************/
/**************************************************************
*
* Utility package
*
***************************************************************/
#include <stdio.h>
EXTERN_ENV;
include(radiosity.h)
static void clear_element_radiosity(Element *elem, long dummy, long process_id);
/***************************************
*
* Global variables
*
****************************************/
#define MAX_INTERACTION_PER_ELEMENT (100)
long total_patches ;
long total_elements ;
long total_equiv_elements ;
long total_interactions ;
long total_comp_visible_interactions ;
long total_invisible_interactions ;
long total_match3, total_match2, total_match1, total_match0 ;
typedef struct
{
long count ;
float area ;
} Elem_Interaction ;
Elem_Interaction elem_interaction[MAX_INTERACTION_PER_ELEMENT+1] ;
Elem_Interaction many_interaction ;
/***************************************
*
* Prinit statistics
*
****************************************/
void print_statistics(FILE *fd, long process_id)
{
long i ;
/* Initialize information */
total_patches = 0 ;
total_elements = 0 ;
total_equiv_elements = 0 ;
total_interactions = 0 ;
total_comp_visible_interactions = 0 ;
total_invisible_interactions = 0 ;
total_match3 = 0 ;
total_match2 = 0 ;
total_match1 = 0 ;
total_match0 = 0 ;
for( i = 0 ; i < MAX_INTERACTION_PER_ELEMENT ; i++ )
{
elem_interaction[i].count = 0 ;
elem_interaction[i].area = 0 ;
}
many_interaction.count = 0 ;
many_interaction.area = 0 ;
foreach_patch_in_bsp( get_patch_stat, 0, 0 ) ;
fprintf( fd, "Rasiosity Statistics\n\n" ) ;
fprintf( fd, " Histogram of interactions/elem\n" ) ;
fprintf( fd, "\t Interactions Occurrence\n" ) ;
fprintf( fd, "\t -------------------------------\n" ) ;
if( many_interaction.count > 0 )
{
fprintf( fd, "\t (Over %d) %ld (%f)\n",
MAX_INTERACTION_PER_ELEMENT,
many_interaction.count,
many_interaction.area / many_interaction.count ) ;
}
for( i = MAX_INTERACTION_PER_ELEMENT ;
elem_interaction[i].count == 0 ; i-- ) ;
for( ; i >= 0 ; i-- )
{
if( elem_interaction[i].count == 0 )
continue ;
if( elem_interaction[i].count == 0 )
fprintf( fd, "\t %ld %ld (---)\n",
i, elem_interaction[i].count ) ;
else
fprintf( fd, "\t %ld %ld (%f)\n",
i, elem_interaction[i].count,
elem_interaction[i].area / elem_interaction[i].count);
}
fprintf( fd, " Configurations\n" ) ;
#if PATCH_ASSIGNMENT == PATCH_ASSIGNMENT_COSTBASED
fprintf( fd, "\tPatch assignment: Costbased\n" ) ;
fprintf( fd, "\tUsing non-greedy cost-based algorithm\n") ;
#endif
#if PATCH_ASSIGNMENT == PATCH_ASSIGNMENT_STATIC
fprintf( fd, "\tPatch assignment: Static equal number\n" ) ;
#endif
fprintf( fd, "\tAlways inserting at top of list for visibility testing (not sorted)\n" ) ;
fprintf( fd, "\tRecursive pruning enabled for BSP tree traversal\n" ) ;
fprintf( fd, "\tPatch cache: Enabled\n" ) ;
fprintf( fd, "\tAlways check all other queues when task stealing (not neighbor scheme)\n" ) ;
fprintf( fd, " Parameters\n" ) ;
fprintf( fd, "\tNumber of processors: %ld\n", n_processors ) ;
fprintf( fd, "\tNumber of task queues: %ld\n", n_taskqueues ) ;
fprintf( fd, "\tNumber of tasks / queue: %ld\n", n_tasks_per_queue ) ;
fprintf( fd, "\tArea epsilon: %f\n", Area_epsilon ) ;
fprintf( fd, "\t#inter parallel refine: %ld\n",
N_inter_parallel_bf_refine);
fprintf( fd, "\t#visibility comp / task: %ld\n", N_visibility_per_task ) ;
fprintf( fd, "\tBF epsilon: %f\n", BFepsilon ) ;
fprintf( fd, "\tEnergy convergence: %f\n", Energy_epsilon ) ;
fprintf( fd, " Iterations to converge: %ld times\n",
global->iteration_count ) ;
fprintf( fd, " Resource Usage\n" ) ;
fprintf( fd, "\tNumber of patches: %ld\n", total_patches ) ;
fprintf( fd, "\tTotal number of elements: %ld\n", total_elements ) ;
fprintf( fd, "\tTotal number of interactions: %ld\n", total_interactions);
fprintf( fd, "\t completely visible: %ld\n",
total_comp_visible_interactions ) ;
fprintf( fd, "\t completely invisible: %ld\n",
total_invisible_interactions ) ;
fprintf( fd, "\t partially visible: %ld\n",
total_interactions - total_comp_visible_interactions
- total_invisible_interactions ) ;
fprintf( fd, "\tInteraction coherence (root interaction not counted)\n");
fprintf( fd, "\t Common for 4 siblings: %ld\n", total_match3 ) ;
fprintf( fd, "\t Common for 3 siblings: %ld\n", total_match2 ) ;
fprintf( fd, "\t Common for 2 siblings: %ld\n", total_match1 ) ;
fprintf( fd, "\t Common for no sibling: %ld\n", total_match0 ) ;
fprintf( fd, "\tAvg. elements per patch: %.1f\n",
(float)total_elements / (float)total_patches ) ;
fprintf( fd, "\tAvg. interactions per patch: %.1f\n",
(float)total_interactions / (float)total_patches ) ;
fprintf( fd, "\tAvg. interactions per element:%.1f\n",
(float)total_interactions / (float)total_elements ) ;
fprintf( fd, "\tNumber of elements in equivalent uniform mesh: %ld\n",
total_equiv_elements ) ;
fprintf( fd, "\tElem(hierarchical)/Elem(uniform): %.2f%%\n",
(float)total_elements / (float)total_equiv_elements * 100.0 ) ;
}
/**********************************************************
*
* print_per_process_info()
*
***********************************************************/
void print_per_process_info(FILE *fd, long process)
{
long cache_line ;
long iteration ;
StatisticalInfo *ps ;
Element *e ;
ps = &global->stat_info[process] ;
fprintf( fd, "\t\tModeling tasks: %ld\n",
ps->total_modeling_tasks ) ;
fprintf( fd, "\t\tDefine patch tasks: %ld\n",
ps->total_def_patch_tasks ) ;
fprintf( fd, "\t\tFF refinement tasks: %ld\n",
ps->total_ff_ref_tasks ) ;
fprintf( fd, "\t\tRay processing tasks: %ld\n",
ps->total_ray_tasks ) ;
fprintf( fd, "\t\tRadiosity Avg/Norm tasks: %ld\n",
ps->total_radavg_tasks ) ;
fprintf( fd, "\t\tInteraction computations: %ld\n",
ps->total_interaction_comp ) ;
fprintf( fd, "\t\tVisibility computations: %ld\n",
ps->total_visibility_comp ) ;
fprintf( fd, "\t\t (%ld of %ld were partially visible)\n",
ps->partially_visible,
ps->total_visibility_comp ) ;
fprintf( fd, "\t\tRay intersection tests: %ld\n",
ps->total_ray_intersect_test ) ;
fprintf( fd, "\t\tPatch cache hit ratio: %.2f%%\n",
ps->total_patch_cache_hit * 100 /
(ps->total_patch_cache_check + 0.01) ) ;
for( cache_line = 0 ; cache_line < PATCH_CACHE_SIZE ; cache_line++ )
fprintf( fd, "\t\t (level %ld): %.2f%%\n",
cache_line,
ps->patch_cache_hit[cache_line] * 100 /
(ps->total_patch_cache_check + 0.01));
/* Per iteration info */
fprintf( fd, "\t\tPer iteration info.\n" ) ;
for( iteration = 0 ; iteration < global->iteration_count ; iteration++ )
{
fprintf( fd, "\t\t [%ld] Interaction comp: %ld\n",
iteration, ps->per_iteration[iteration].visibility_comp ) ;
fprintf( fd, "\t\t Ray Intersection: %ld\n",
ps->per_iteration[iteration].ray_intersect_test ) ;
fprintf( fd, "\t\t Tasks from my Q: %ld\n",
ps->per_iteration[iteration].tasks_from_myq ) ;
fprintf( fd, "\t\t Tasks from other Q: %ld\n",
ps->per_iteration[iteration].tasks_from_otherq ) ;
fprintf( fd, "\t\t Process_task wait count: %ld\n",
ps->per_iteration[iteration].process_tasks_wait ) ;
e = ps->per_iteration[iteration].last_pr_task ;
if( e == 0 )
continue ;
if( e->parent == 0 )
{
fprintf( fd, "\t\t Last task: Patch level\n" ) ;
fprintf( fd, "\t\t (%ld root inter)\n",
e->n_interactions ) ;
}
else
{
fprintf( fd, "\t\t Last task: Elem level\n" ) ;
fprintf( fd, "\t\t (%ld inter, %.3f Elem/Patch)\n",
e->n_interactions, e->area / e->patch->area ) ;
}
}
}
/**********************************************************
*
* get_patch_stat()
*
***********************************************************/
long n_elements_in_patch ;
long n_equiv_elem_in_patch ;
float min_elem_area ;
long n_interactions_in_patch ;
long n_comp_visible_interactions ;
long n_invisible_interactions ;
void get_patch_stat(Patch *patch, long dummy, long process_id)
{
/* Initialize stat info for element */
n_elements_in_patch = 0 ;
n_equiv_elem_in_patch = 1 ;
min_elem_area = patch->area ;
n_interactions_in_patch = 0 ;
n_comp_visible_interactions = 0 ;
n_invisible_interactions = 0 ;
/* Traverse the quad tree */
foreach_element_in_patch( patch, get_elem_stat, 0, process_id ) ;
/* Update global stat variables */
total_patches++ ;
total_elements += n_elements_in_patch ;
total_equiv_elements += n_equiv_elem_in_patch ;
total_interactions += n_interactions_in_patch ;
total_comp_visible_interactions += n_comp_visible_interactions ;
total_invisible_interactions += n_invisible_interactions ;
#if PATCH_ASSIGNMENT == PATCH_ASSIGNMENT_COSTBASED
if( n_interactions_in_patch
!= global->patch_cost[patch->seq_no].n_total_inter )
{
printf( "Error: patch(%d) Inter counted: %d (n_total_inter %d)\n",
patch->seq_no,
n_interactions_in_patch,
global->patch_cost[patch->seq_no].n_total_inter ) ;
}
#endif
}
void get_elem_stat(Element *elem, long dummy, long process_id)
{
Interaction *pi ;
long p_visible = 0 ;
long c_visible = 0 ;
long i_visible = 0 ;
long match0, match1, match2, match3 ;
n_elements_in_patch++ ;
while( elem->area < min_elem_area )
{
min_elem_area *= 0.25 ;
n_equiv_elem_in_patch *= 4 ;
}
/* Classify visibility */
n_interactions_in_patch += elem->n_interactions ;
for( pi = elem->interactions ; pi ; pi = pi->next )
{
if( pi->visibility == 0.0 )
i_visible++ ;
else if( pi->visibility == 1.0 )
c_visible++ ;
else
p_visible++ ;
}
if( i_visible + c_visible + p_visible != elem->n_interactions )
printf( "Fatal: Interactions count miss match\n" ) ;
if( elem->n_vis_undef_inter != 0 )
printf( "Fatal: Visibility undef list count non zero(%ld)\n",
elem->n_vis_undef_inter ) ;
if( elem->vis_undef_inter != 0 )
printf( "Fatal: Visibility undef list not empty\n" ) ;
n_comp_visible_interactions += c_visible ;
n_invisible_interactions += i_visible ;
/* Count interactions / element */
if( elem->n_interactions > MAX_INTERACTION_PER_ELEMENT )
{
many_interaction.count++ ;
many_interaction.area += elem->area ;
}
else
{
elem_interaction[ elem->n_interactions ].count++ ;
elem_interaction[ elem->n_interactions ].area += elem->area ;
}
/* Analyze object coherence */
if( ! LEAF_ELEMENT( elem ) )
{
match0 = match1 = match2 = match3 = 0 ;
count_interaction(elem->center, elem->top, elem->right, elem->left,
&match3, &match2, &match1, &match0, process_id ) ;
count_interaction(elem->top, elem->right, elem->left, elem->center,
&match3, &match2, &match1, &match0, process_id ) ;
count_interaction(elem->right, elem->left, elem->center, elem->top,
&match3, &match2, &match1, &match0, process_id ) ;
count_interaction(elem->left, elem->center, elem->top, elem->right,
&match3, &match2, &match1, &match0, process_id ) ;
total_match3 += match3 ;
total_match2 += match2 ;
total_match1 += match1 ;
total_match0 += match0 ;
}
}
void count_interaction(Element *es, Element *e1, Element *e2, Element *e3, long *c3, long *c2, long *c1, long *c0, long process_id)
{
Interaction *pi ;
long occurrence ;
for( pi = es->interactions ; pi ; pi = pi->next )
{
occurrence = search_intearction( e1->interactions, pi, process_id ) ;
occurrence += search_intearction( e2->interactions, pi, process_id ) ;
occurrence += search_intearction( e3->interactions, pi, process_id ) ;
switch( occurrence )
{
case 0: (*c0)++ ; break ;
case 1: (*c1)++ ; break ;
case 2: (*c2)++ ; break ;
case 3: (*c3)++ ; break ;
}
}
}
long search_intearction(Interaction *int_list, Interaction *inter, long process_id)
{
while( int_list )
{
if( int_list->destination == inter->destination )
return( 1 ) ;
int_list = int_list->next ;
}
return( 0 ) ;
}
/***************************************
*
* Prinit running time
*
****************************************/
void print_running_time(long process_id)
{
long time_diff, time_diff1 ;
time_diff = time_rad_end - time_rad_start ;
time_diff1 = time_rad_end - timing[0]->rad_start;
if( time_diff < 0 )
time_diff += CLOCK_MAX_VAL ;
if( time_diff1 < 0 )
time_diff1 += CLOCK_MAX_VAL ;
printf( "\tOverall start time\t%20lu\n", time_rad_start);
printf( "\tOverall end time\t%20lu\n", time_rad_end);
printf( "\tTotal time with initialization\t%20lu\n", time_diff);
printf( "\tTotal time without initialization\t%20lu\n", time_diff1);
}
/***************************************
*
* Print process creation overhead
*
****************************************/
void print_fork_time(long process_id)
{
long pid ;
if( n_processors <= 1 )
return ;
printf( "\tProcess fork overhead\n" ) ;
for( pid = 0 ; pid < n_processors-1 ; pid++ )
{
printf( "\t Process %ld %.2f mS\n",
pid,
(timing[pid]->rad_start - time_rad_start) / 1000.0 ) ;
}
printf( "\t (total) %.2f mS\n",
(time_process_start[n_processors-2] - time_rad_start) / 1000.0 ) ;
}
/***************************************
*
* Initialize statistical info
*
****************************************/
void init_stat_info(long process_id)
{
long pid ;
long i ;
StatisticalInfo *ps ;
for( pid = 0 ; pid < MAX_PROCESSORS ; pid++ )
{
ps = &global->stat_info[ pid ] ;
ps->total_modeling_tasks = 0 ;
ps->total_def_patch_tasks = 0 ;
ps->total_ff_ref_tasks = 0 ;
ps->total_ray_tasks = 0 ;
ps->total_radavg_tasks = 0 ;
ps->total_interaction_comp = 0 ;
ps->total_visibility_comp = 0 ;
ps->partially_visible = 0 ;
ps->total_ray_intersect_test= 0 ;
ps->total_patch_cache_check = 0 ;
ps->total_patch_cache_hit = 0 ;
for( i = 0 ; i < PATCH_CACHE_SIZE ; i++ )
ps->patch_cache_hit[i] = 0 ;
for( i = 0 ; i < MAX_ITERATION_INFO ; i++ )
{
ps->per_iteration[ i ].visibility_comp = 0 ;
ps->per_iteration[ i ].ray_intersect_test = 0 ;
ps->per_iteration[ i ].tasks_from_myq = 0 ;
ps->per_iteration[ i ].tasks_from_otherq = 0 ;
ps->per_iteration[ i ].process_tasks_wait = 0 ;
ps->per_iteration[ i ].last_pr_task = 0 ;
}
}
}
/**********************************************************
*
* clear_radiosity()
*
***********************************************************/
void clear_radiosity(long process_id)
{
foreach_patch_in_bsp( clear_patch_radiosity, 0, 0 ) ;
}
void clear_patch_radiosity(Patch *patch, long dummy, long process_id)
{
foreach_element_in_patch( patch, clear_element_radiosity, 0, process_id ) ;
}
static void clear_element_radiosity(Element *elem, long dummy, long process_id)
{
elem->rad.r = 0 ;
elem->rad.g = 0 ;
elem->rad.b = 0 ;
elem->rad_subtree.r = 0 ;
elem->rad_subtree.g = 0 ;
elem->rad_subtree.b = 0 ;
global->prev_total_energy = global->total_energy ;
global->total_energy.r = 0 ;
global->total_energy.g = 0 ;
global->total_energy.b = 0 ;
}