/* * store_clique() * * Stores a clique according to given user options. * * clique - the clique to store * opts - storage options * * Returns FALSE if opts->user_function() returned FALSE; otherwise * returns TRUE. */ static boolean store_clique(set_t clique, graph_t *g, clique_options *opts) { clique_list_count++; /* clique_list[] */ if (opts->clique_list) { /* * This has been a major source of bugs: * Has clique_list_count been set to 0 before calling * the recursions? */ if (clique_list_count <= 0) { fprintf(stderr,"CLIQUER INTERNAL ERROR: " "clique_list_count has negative value!\n"); fprintf(stderr,"Please report as a bug.\n"); abort(); } if (clique_list_count <= opts->clique_list_length) opts->clique_list[clique_list_count-1] = set_duplicate(clique); } /* user_function() */ if (opts->user_function) { if (!opts->user_function(clique,g,opts)) { /* User function requested abort. */ return FALSE; } } return TRUE; }
static boolean sage_record_clique_func(set_t s,graph_t *g,clique_options *opts) { if (sage_clique_count>=sage_clique_list_size) { sage_clique_list=realloc(sage_clique_list,(sage_clique_list_size+512) * sizeof(set_t)); sage_clique_list_size+=512; } sage_clique_list[sage_clique_count]=set_duplicate(s); sage_clique_count++; return TRUE; }
boolean record_clique_func(set_t s,graph_t *g,clique_options *opts) { if (clique_count>=clique_list_size) { clique_list=(set_t*)realloc(clique_list,(clique_list_size+512) * sizeof(set_t)); clique_list_size+=512; } clique_list[clique_count]=set_duplicate(s); clique_count++; return TRUE; }
/* Function that allows the purpose to be succintly stated. We only * store the max as the true weight of the node, so this allows it to * be clearly expressed. */ void dag_node_footprint_max( struct dag_node *n) { if(n->footprint->prog_max_footprint > n->footprint->footprint_max_size){ set_delete(n->footprint->footprint_max_files); n->footprint->footprint_max_size = n->footprint->prog_max_footprint; n->footprint->footprint_max_files = set_duplicate(n->footprint->prog_max_files); } if(n->footprint->delete_footprint > n->footprint->footprint_max_size){ set_delete(n->footprint->footprint_max_files); n->footprint->footprint_max_size = n->footprint->delete_footprint; n->footprint->footprint_max_files = set_duplicate(n->footprint->delete_files); } if(n->footprint->run_footprint > n->footprint->footprint_max_size){ set_delete(n->footprint->footprint_max_files); n->footprint->footprint_max_size = n->footprint->run_footprint; n->footprint->footprint_max_files = set_duplicate(n->footprint->run_files); } }
struct set *set_union(struct set *s1, struct set *s2) { struct set *s = set_duplicate(s1); set_first_element(s2); const void *element; while((element = set_next_element(s2))) set_insert(s, element); return s; }
/* The descendant footprint of a node is defined as a balance between * the widest point of the children branches, while still maintaining * the existance of the sibling branches. The assumption is that by * knowing the larget size needed, all other branches can be executed * within that designated size, so we only need to add the residual * size of a branch to hold onto it while the heavier weights are * computed. */ void dag_node_footprint_determine_descendant(struct dag_node *n) { struct dag_node *node1, *node2; //, *res_node; struct list *tmp_direct_children = list_create(); struct set *footprint = set_create(0); uint64_t footprint_size = 0; /* Create a second list of direct children that allows us to sort on footprint properties. This is used when we compare footprint and the residual nodes. */ set_first_element(n->footprint->direct_children); while((node1 = set_next_element(n->footprint->direct_children))){ list_push_tail(tmp_direct_children, node1); list_first_item(node1->footprint->residual_nodes); } /* There are two cases for descendant nodes: 1. Multiple direct_children indicating that multiple branches will need to be maintained concurrently and we need to account. 2. One descendant indicating we want to continue the chain of residual and footprints that out child holds. create empty lists for this case. */ set_first_element(n->footprint->direct_children); if(set_size(n->footprint->direct_children) > 1){ dag_node_footprint_determine_desc_residual_intersect(n); dag_node_footprint_set_desc_res_wgt_diff(n); set_insert_list(footprint, n->target_files); list_sort(tmp_direct_children, dag_node_footprint_comp_diff); list_first_item(tmp_direct_children); /* Loop over each child giving it the chance to be the largest footprint. */ while((node1 = list_next_item(tmp_direct_children))){ footprint_size = dag_file_set_size(footprint); if((footprint_size + node1->footprint->wgt) > n->footprint->delete_footprint){ set_delete(n->footprint->delete_files); n->footprint->delete_files = set_duplicate(footprint); set_insert_set(n->footprint->delete_files, node1->footprint->wgt_files); n->footprint->delete_footprint = dag_file_set_size(n->footprint->delete_files); } // This is where we would remove an input file if it wasn't needed for other branches set_insert_set(footprint, node1->footprint->res_files); list_push_tail(n->footprint->delete_run_order, node1); } list_sort(tmp_direct_children, dag_node_footprint_comp_wgt_rev); list_first_item(tmp_direct_children); node1 = list_next_item(tmp_direct_children); set_insert_set(n->footprint->prog_max_files, node1->footprint->max_wgt_files); set_insert_set(n->footprint->prog_min_files, node1->footprint->wgt_files); list_push_tail(n->footprint->prog_run_order, node1); /* Find what the total space is needed to hold all residuals and the largest footprint branch concurrently. */ while((node2 = list_next_item(tmp_direct_children))){ set_insert_set(n->footprint->prog_max_files, node2->footprint->max_wgt_files); set_insert_set(n->footprint->prog_min_files, node2->footprint->res_files); list_push_tail(n->footprint->prog_run_order, node2); } n->footprint->prog_max_footprint = dag_file_set_size(n->footprint->prog_max_files); n->footprint->prog_min_footprint = dag_file_set_size(n->footprint->prog_min_files); } else { if(set_size(n->footprint->direct_children) == 1){ node1 = set_next_element(n->footprint->direct_children); list_delete(n->footprint->residual_nodes); n->footprint->residual_nodes = list_duplicate(node1->footprint->residual_nodes); } set_insert_list(n->footprint->residual_files, n->target_files); set_insert_set(n->footprint->residual_files, n->footprint->terminal_files); n->footprint->residual_size = dag_file_set_size(n->footprint->residual_files); } /* Adding the current nodes list so parents can quickly access these decisions. */ list_push_tail(n->footprint->residual_nodes, n); list_delete(tmp_direct_children); set_delete(footprint); }