unsigned long long parTreeSearch(int depth, Node *parent, int numChildren) { Node *n = (Node *)malloc(numChildren * sizeof(Node)); Node *nodePtr; int i, j; unsigned long long subtreesize = 1; unsigned long long *partialCount = (unsigned long long *)malloc(numChildren * sizeof(unsigned long long)); // Recurse on the children for (i = 0; i < numChildren; i++) { nodePtr = &n[i]; nodePtr->height = parent->height + 1; // The following line is the work (one or more SHA-1 ops) for (j = 0; j < computeGranularity; j++) { rng_spawn(parent->state.state, nodePtr->state.state, i); } nodePtr->numChildren = uts_numChildren(nodePtr); hclib_pragma_marker("omp", "task untied firstprivate(i, nodePtr) shared(partialCount)", "pragma221_omp_task"); partialCount[i] = parTreeSearch(depth+1, nodePtr, nodePtr->numChildren); } hclib_pragma_marker("omp", "taskwait", "pragma225_omp_taskwait"); for (i = 0; i < numChildren; i++) { subtreesize += partialCount[i]; } free(n); free(partialCount); return subtreesize; }
unsigned long long parTreeSearch(int depth, Node *parent, int numChildren) { Node n[numChildren], *nodePtr; int i, j; unsigned long long subtreesize = 1, partialCount[numChildren]; // Recurse on the children for (i = 0; i < numChildren; i++) { nodePtr = &n[i]; nodePtr->height = parent->height + 1; // The following line is the work (one or more SHA-1 ops) for (j = 0; j < computeGranularity; j++) { rng_spawn(parent->state.state, nodePtr->state.state, i); } nodePtr->numChildren = uts_numChildren(nodePtr); #pragma omp task untied firstprivate(i, nodePtr) shared(partialCount) partialCount[i] = parTreeSearch(depth+1, nodePtr, nodePtr->numChildren); } #pragma omp taskwait for (i = 0; i < numChildren; i++) { subtreesize += partialCount[i]; } return subtreesize; }
int main(int argc, char *argv[]) { double t1, t2; Node root; StealStack *ss; /* initialize stealstacks and comm. layer */ ss = ss_init(&argc, &argv); /* determine benchmark parameters */ uts_parseParams(argc, argv); /* Initialize trace collection structures */ ss_initStats(ss); /* show parameter settings */ if (ss_get_thread_num() == 0) { uts_printParams(); } fflush(NULL); // Workers will return 1 from ss_start(), all others (managers) // will return 0 here once the computation ends if (ss_start(sizeof(Node), chunkSize)) { /* initialize root node and push on thread 0 stack */ if (ss_get_thread_num() == 0) { uts_initRoot(&root, type); #ifdef TRACE ss_markSteal(ss, 0); // first session is own "parent session" #endif ss_put_work(ss, &root); } /* time parallel search */ t1 = uts_wctime(); parTreeSearch(ss); t2 = uts_wctime(); ss->walltime = t2 - t1; #ifdef TRACE ss->startTime = t1; ss->sessionRecords[SS_IDLE][ss->entries[SS_IDLE] - 1].endTime = t2; #endif } ss_stop(); /* display results */ showStats(); ss_finalize(); return 0; }
counter_t parallel_uts ( Node *root ) { counter_t num_nodes; bots_message("Computing Unbalance Tree Search algorithm "); #pragma omp parallel #pragma omp single nowait #pragma omp task untied num_nodes = parTreeSearch( 0, root, getNumRootChildren(root) ); bots_message(" completed!"); return num_nodes; }
unsigned long long parallel_uts ( Node *root ) { unsigned long long num_nodes = 0 ; root->numChildren = uts_numChildren(root); bots_message("Computing Unbalance Tree Search algorithm "); #pragma omp parallel #pragma omp single nowait #pragma omp task untied num_nodes = parTreeSearch( 0, root, root->numChildren ); bots_message(" completed!"); return num_nodes; }
void parallel_uts( int children, int factor ) { struct thread_data input; counter_t num_nodes = 0; input.depth = 1; input.numChildren = children; input.factor = factor; input.subtree = true; //printf("main: %d %d %d\n", input.depth, input.numChildren, input.factor); printf("numChildren: %d, factor: %d, ", input.numChildren, input.factor); num_nodes = parTreeSearch(&input); printf("Tree size = %llu\n", (unsigned long long)num_nodes ); }
counter_t parTreeSearch(int depth, Node *parent, int numChildren) { //JK //Node n[numChildren], *nodePtr; Node *n, *nodePtr; int i, j; counter_t subtreesize = 1; counter_t *partialCount; //counter_t partialCount[numChildren]; n = (Node*)malloc(numChildren * sizeof(Node)); partialCount = (counter_t*)malloc(numChildren * sizeof(counter_t)); // Recurse on the children for (i = 0; i < numChildren; i++) { nodePtr = &n[i]; nodePtr->height = parent->height + 1; // The following line is the work (one or more SHA-1 ops) for (j = 0; j < computeGranularity; j++) { rng_spawn(parent->state.state, nodePtr->state.state, i); } nodePtr->numChildren = uts_numChildren(nodePtr); #pragma omp task firstprivate(i, nodePtr) shared(partialCount) untied partialCount[i] = parTreeSearch(depth+1, nodePtr, nodePtr->numChildren); } #pragma omp taskwait for (i = 0; i < numChildren; i++) { subtreesize += partialCount[i]; } free(n); free(partialCount); return subtreesize; }
unsigned long long parallel_uts ( Node *root ) { unsigned long long num_nodes = 0 ; root->numChildren = uts_numChildren(root); bots_message("Computing Unbalance Tree Search algorithm "); hclib_pragma_marker("omp_to_hclib", "", "pragma183_omp_to_hclib"); { hclib_pragma_marker("omp", "parallel", "pragma185_omp_parallel"); { hclib_pragma_marker("omp", "single nowait", "pragma187_omp_single"); { hclib_pragma_marker("omp", "task untied", "pragma189_omp_task"); num_nodes = parTreeSearch( 0, root, root->numChildren ); } } } bots_message(" completed!"); return num_nodes; }
counter_t parTreeSearch( struct thread_data *args ) { counter_t subtreesize = 1, partialCount[args->numChildren]; struct thread_data temp, input; int i; temp.depth = args->depth; temp.numChildren = args->numChildren; temp.factor = args->factor; //printf("par: %d %d %d\n", temp.depth, temp.numChildren, temp.factor); if(!args->subtree) return subtreesize; if(args->depth == args->factor) return subtreesize; int pivot = 0; time_t t; srand((unsigned) time(&t)); pivot = rand() % temp.numChildren; for (i = 0; i < temp.numChildren; i++) { input.depth = temp.depth+1; input.numChildren = temp.numChildren; input.factor = temp.factor; if(i == pivot) input.subtree = false; else input.subtree = true; partialCount[i] = parTreeSearch(&input); //printf("[%d] %llu\n", i, partialCount[i]); } for (i = 0; i < temp.numChildren; i++) { subtreesize += partialCount[i]; } return subtreesize; }
counter_t parTreeSearch(int depth, Node *parent, int numChildren) { Node n[numChildren], *nodePtr; int i, j; counter_t subtreesize = 1, partialCount[numChildren]; //printf("[p] *** depth = %d ***\n", depth); //printf("[p] *** height = %d ***\n", parent->height); //printf("[p] *** numChildren = %d ***\n", parent->numChildren); // Recurse on the children for (i = 0; i < numChildren; i++) { nodePtr = &n[i]; nodePtr->height = parent->height + 1; // The following line is the work (one or more SHA-1 ops) for (j = 0; j < computeGranularity; j++) { rng_spawn(parent->state.state, nodePtr->state.state, i); } nodePtr->numChildren = uts_numChildren(nodePtr); //#pragma omp task firstprivate(i, nodePtr) shared(partialCount) untied partialCount[i] = parTreeSearch(depth+1, nodePtr, nodePtr->numChildren); } //#pragma omp taskwait for (i = 0; i < numChildren; i++) { subtreesize += partialCount[i]; } return subtreesize; }