/*************************************************************************/ /* */ /* 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. */ /* */ /*************************************************************************/ #include "defs.h" #include "memory.h" #include "box.h" #include "partition_grid.h" #include "cost_zones.h" #define NUM_DIRECTIONS 4 typedef enum { RIGHT, LEFT, UP, DOWN } direction; static long Child_Sequence[NUM_DIRECTIONS][NUM_OFFSPRING] = { { 0, 1, 2, 3 }, { 2, 3, 0, 1 }, { 0, 3, 2, 1 }, { 2, 1, 0, 3 }, }; static long Direction_Sequence[NUM_DIRECTIONS][NUM_OFFSPRING] = { { UP, RIGHT, RIGHT, DOWN }, { DOWN, LEFT, LEFT, UP }, { RIGHT, UP, UP, LEFT }, { LEFT, DOWN, DOWN, RIGHT }, }; void ComputeSubTreeCosts(long my_id, box *b); void CostZonesHelper(long my_id, box *b, long work, direction dir); void CostZones (long my_id) { PartitionIterate(my_id, ComputeSubTreeCosts, BOTTOM); BARRIER(G_Memory->synch, Number_Of_Processors); Local[my_id].Total_Work = Grid->subtree_cost; Local[my_id].Min_Work = ((Local[my_id].Total_Work / Number_Of_Processors) * my_id); if (my_id == (Number_Of_Processors - 1)) Local[my_id].Max_Work = Local[my_id].Total_Work; else Local[my_id].Max_Work = (Local[my_id].Min_Work + (Local[my_id].Total_Work / Number_Of_Processors)); InitPartition(my_id); CostZonesHelper(my_id, Grid, 0, RIGHT); BARRIER(G_Memory->synch, Number_Of_Processors); } void ComputeSubTreeCosts (long my_id, box *b) { box *pb; if (b->type == PARENT) { while (b->interaction_synch != b->num_children) { } } b->interaction_synch = 0; ComputeCostOfBox(b); b->subtree_cost += b->cost; pb = b->parent; if (pb != NULL) { ALOCK(G_Memory->lock_array, pb->exp_lock_index); pb->subtree_cost += b->subtree_cost; pb->interaction_synch += 1; AULOCK(G_Memory->lock_array, pb->exp_lock_index); } } void CostZonesHelper (long my_id, box *b, long work, direction dir) { box *cb; long i; long *next_child; long *child_dir; if (b->type == CHILDLESS) { if (work >= Local[my_id].Min_Work) InsertBoxInPartition(my_id, b); } else { next_child = Child_Sequence[dir]; child_dir = Direction_Sequence[dir]; for (i = 0; (i < NUM_OFFSPRING) && (work < Local[my_id].Max_Work); i++) { cb = b->children[next_child[i]]; if (cb != NULL) { if ((work + cb->subtree_cost) >= Local[my_id].Min_Work) CostZonesHelper(my_id, cb, work, child_dir[i]); work += cb->subtree_cost; } if (i == 2) { if ((work >= Local[my_id].Min_Work) && (work < Local[my_id].Max_Work)) InsertBoxInPartition(my_id, b); work += b->cost; } } } } #undef DOWN #undef UP #undef LEFT #undef RIGHT #undef NUM_DIRECTIONS