/* * Generate all children of the parent * * details depend on tree type, node type and shape function * */ void genChildren(Node * parent, void * child_buf, Node * child, StealStack * ss) { int parentHeight = parent->height; int numChildren, childType; ss->maxTreeDepth = max(ss->maxTreeDepth, parent->height); numChildren = uts_numChildren(parent); childType = uts_childType(parent); // record number of children in parent parent->numChildren = numChildren; // construct children and push onto stack if (numChildren > 0) { int i, j; child->type = childType; child->height = parentHeight + 1; for (i = 0; i < numChildren; i++) { for (j = 0; j < computeGranularity; j++) { // TBD: add parent height to spawn // computeGranularity controls number of rng_spawn calls per node rng_spawn(parent->state.state, child->state.state, i); } ss_put_work(ss, child_buf); } } else { ss->nLeaves++; } }
TASK_2(Result, parTreeSearch, int, depth, Node *, parent) { int numChildren, childType; counter_t parentHeight = parent->height; Result r = { depth, 1, 0 }; numChildren = uts_numChildren(parent); childType = uts_childType(parent); // record number of children in parent parent->numChildren = numChildren; // Recurse on the children if (numChildren > 0) { int i, j; for (i = 0; i < numChildren; i++) { Node *child = (Node*)alloca(sizeof(Node)); child->type = childType; child->height = parentHeight + 1; child->numChildren = -1; // not yet determined for (j = 0; j < computeGranularity; j++) { rng_spawn(parent->state.state, child->state.state, i); } SPAWN(parTreeSearch, depth+1, child); } /* Wait a bit */ struct timespec tim = (struct timespec){0, 100L*numChildren}; nanosleep(&tim, NULL); for (i = 0; i < numChildren; i++) { Result c = SYNC(parTreeSearch); if (c.maxdepth>r.maxdepth) r.maxdepth = c.maxdepth; r.size += c.size; r.leaves += c.leaves; } } else {
/* * Generate all children of the parent * * details depend on tree type, node type and shape function * */ void genChildren(Node * parent, Node * child) { int parentHeight = parent->height; int numChildren, childType; #ifdef THREAD_METADATA t_metadata[omp_get_thread_num()].ntasks += 1; #endif thread_info[hclib::get_current_worker()].n_nodes++; numChildren = uts_numChildren(parent); childType = uts_childType(parent); // record number of children in parent parent->numChildren = numChildren; // construct children and push onto stack if (numChildren > 0) { int i, j; child->type = childType; child->height = parentHeight + 1; #ifdef UTS_STAT if (stats) { child->pp = parent; // pointer to parent } #endif const unsigned char * parent_state = parent->state.state; unsigned char * child_state = child->state.state; for (i = 0; i < numChildren; i++) { for (j = 0; j < computeGranularity; j++) { // TBD: add parent height to spawn // computeGranularity controls number of rng_spawn calls per node rng_spawn(parent_state, child_state, i); } Node parent = *child; int made_available_for_stealing = 0; if (hclib::get_current_worker() == 0 && n_buffered_steals < N_BUFFERED_STEALS) { hclib::shmem_set_lock(&steal_buffer_locks[pe]); if (n_buffered_steals < N_BUFFERED_STEALS) { steal_buffer[n_buffered_steals++] = parent; made_available_for_stealing = 1; } hclib::shmem_clear_lock(&steal_buffer_locks[pe]); } if (!made_available_for_stealing) { if (parent.height < 9) { hclib::async([parent] { Node child; initNode(&child); Node tmp = parent; genChildren(&tmp, &child); }); } else { Node child; initNode(&child); genChildren(&parent, &child); } } } } else { thread_info[hclib::get_current_worker()].n_leaves++; } }