/* ============================================================================= * net_findAncestors * -- Contents of bitmapPtr set to 1 if ancestor, else 0 * -- Returns false if id is not root node (i.e., has cycle back id) * ============================================================================= */ bool_t net_findAncestors (net_t* netPtr, long id, bitmap_t* ancestorBitmapPtr, queue_t* workQueuePtr) { bool_t status; vector_t* nodeVectorPtr = LocalLoad(&netPtr->nodeVectorPtr); assert(LocalLoad(&ancestorBitmapPtr->numBit) == vector_getSize(nodeVectorPtr)); bitmap_clearAll(ancestorBitmapPtr); queue_clear(workQueuePtr); { net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, id); list_t* parentIdListPtr = LocalLoad(&nodePtr->parentIdListPtr); list_iter_t it; list_iter_reset(&it, parentIdListPtr); while (list_iter_hasNext(&it, parentIdListPtr)) { long parentId = (long)list_iter_next(&it, parentIdListPtr); status = bitmap_set(ancestorBitmapPtr, parentId); assert(status); status = queue_push(workQueuePtr, (void*)parentId); assert(status); } } while (!queue_isEmpty(workQueuePtr)) { long parentId = (long)queue_pop(workQueuePtr); if (parentId == id) { queue_clear(workQueuePtr); return FALSE; } net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, parentId); list_t* grandParentIdListPtr = LocalLoad(&nodePtr->parentIdListPtr); list_iter_t it; list_iter_reset(&it, grandParentIdListPtr); while (list_iter_hasNext(&it, grandParentIdListPtr)) { long grandParentId = (long)list_iter_next(&it, grandParentIdListPtr); if (!bitmap_isSet(ancestorBitmapPtr, grandParentId)) { status = bitmap_set(ancestorBitmapPtr, grandParentId); assert(status); status = queue_push(workQueuePtr, (void*)grandParentId); assert(status); } } } return TRUE; }
/* ============================================================================= * net_findDescendants * -- Contents of bitmapPtr set to 1 if descendants, else 0 * -- Returns false if id is not root node (i.e., has cycle back id) * ============================================================================= */ bool_t net_findDescendants (net_t* netPtr, long id, bitmap_t* descendantBitmapPtr, queue_t* workQueuePtr) { bool_t status; vector_t* nodeVectorPtr = netPtr->nodeVectorPtr; assert(descendantBitmapPtr->numBit == vector_getSize(nodeVectorPtr)); bitmap_clearAll(descendantBitmapPtr); queue_clear(workQueuePtr); { net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, id); list_t* childIdListPtr = nodePtr->childIdListPtr; list_iter_t it; list_iter_reset(&it, childIdListPtr); while (list_iter_hasNext(&it, childIdListPtr)) { long childId = (long)list_iter_next(&it, childIdListPtr); status = bitmap_set(descendantBitmapPtr, childId); assert(status); status = queue_push(workQueuePtr, (void*)childId); assert(status); } } while (!queue_isEmpty(workQueuePtr)) { long childId = (long)queue_pop(workQueuePtr); if (childId == id) { queue_clear(workQueuePtr); return FALSE; } net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, childId); list_t* grandChildIdListPtr = nodePtr->childIdListPtr; list_iter_t it; list_iter_reset(&it, grandChildIdListPtr); while (list_iter_hasNext(&it, grandChildIdListPtr)) { long grandChildId = (long)list_iter_next(&it, grandChildIdListPtr); if (!bitmap_isSet(descendantBitmapPtr, grandChildId)) { status = bitmap_set(descendantBitmapPtr, grandChildId); assert(status); status = queue_push(workQueuePtr, (void*)grandChildId); assert(status); } } } return TRUE; }
/* ============================================================================= * hashtable_iter_next * ============================================================================= */ void* hashtable_iter_next (hashtable_iter_t* itPtr, hashtable_t* hashtablePtr) { long bucket; long numBucket = hashtablePtr->numBucket; list_t** buckets = hashtablePtr->buckets; list_iter_t it = itPtr->it; void* dataPtr = NULL; for (bucket = itPtr->bucket; bucket < numBucket; /* inside body */) { list_t* chainPtr = hashtablePtr->buckets[bucket]; if (list_iter_hasNext(&it, chainPtr)) { pair_t* pairPtr = (pair_t*)list_iter_next(&it, chainPtr); dataPtr = pairPtr->secondPtr; break; } /* May use dummy bucket; see allocBuckets() */ list_iter_reset(&it, buckets[++bucket]); } itPtr->bucket = bucket; itPtr->it = it; return dataPtr; }
static void printHashtable (hashtable_t* hashtablePtr) { long i; hashtable_iter_t it; printf("["); hashtable_iter_reset(&it, hashtablePtr); while (hashtable_iter_hasNext(&it, hashtablePtr)) { printf("%li ", *((long*)(hashtable_iter_next(&it, hashtablePtr)))); } puts("]"); /* Low-level to see structure */ for (i = 0; i < hashtablePtr->numBucket; i++) { list_iter_t it; printf("%2li: [", i); list_iter_reset(&it, hashtablePtr->buckets[i]); while (list_iter_hasNext(&it, hashtablePtr->buckets[i])) { void* pairPtr = list_iter_next(&it, hashtablePtr->buckets[i]); printf("%li ", *(long*)(((pair_t*)pairPtr)->secondPtr)); } puts("]"); } }
/* ============================================================================= * isCycle * ============================================================================= */ static bool_t isCycle (vector_t* nodeVectorPtr, net_node_t* nodePtr) { switch (nodePtr->mark) { case NET_NODE_MARK_INIT: { nodePtr->mark = NET_NODE_MARK_TEST; list_t* childIdListPtr = nodePtr->childIdListPtr; list_iter_t it; list_iter_reset(&it, childIdListPtr); while (list_iter_hasNext(&it, childIdListPtr)) { long childId = (long)list_iter_next(&it, childIdListPtr); net_node_t* childNodePtr = (net_node_t*)vector_at(nodeVectorPtr, childId); if (isCycle(nodeVectorPtr, childNodePtr)) { return TRUE; } } break; } case NET_NODE_MARK_TEST: return TRUE; case NET_NODE_MARK_DONE: return FALSE; break; default: assert(0); } nodePtr->mark = NET_NODE_MARK_DONE; return FALSE; }
static void printList (list_t* listPtr) { list_iter_t it; printf("["); list_iter_reset(&it, listPtr); while (list_iter_hasNext(&it, listPtr)) { printf("%li ", *((long*)(list_iter_next(&it, listPtr)))); } puts("]"); }
static void printTable (table_t* tablePtr) { long i; for (i = 0; i < tablePtr->numBucket; i++) { list_iter_t it; printf("%2i: [", i); list_iter_reset(&it, tablePtr->buckets[i]); while (list_iter_hasNext(&it, tablePtr->buckets[i])) { printf("%li ", *(long*)list_iter_next(&it, tablePtr->buckets[i])); } puts("]"); } }
/* ============================================================================= * net_hasEdge * ============================================================================= */ bool_t net_hasEdge (net_t* netPtr, long fromId, long toId) { vector_t* nodeVectorPtr = netPtr->nodeVectorPtr; net_node_t* childNodePtr = (net_node_t*)vector_at(nodeVectorPtr, toId); list_t* parentIdListPtr = childNodePtr->parentIdListPtr; list_iter_t it; list_iter_reset(&it, parentIdListPtr); while (list_iter_hasNext(&it, parentIdListPtr)) { long parentId = (long)list_iter_next(&it, parentIdListPtr); if (parentId == fromId) { return TRUE; } } return FALSE; }
/* ============================================================================= * hashtable_iter_hasNext * ============================================================================= */ bool_t hashtable_iter_hasNext (hashtable_iter_t* itPtr, hashtable_t* hashtablePtr) { long bucket; long numBucket = hashtablePtr->numBucket; list_t** buckets = hashtablePtr->buckets; list_iter_t it = itPtr->it; for (bucket = itPtr->bucket; bucket < numBucket; /* inside body */) { list_t* chainPtr = buckets[bucket]; if (list_iter_hasNext(&it, chainPtr)) { return TRUE; } /* May use dummy bucket; see allocBuckets() */ list_iter_reset(&it, buckets[++bucket]); } return FALSE; }
/* ============================================================================= * net_isPath * ============================================================================= */ bool_t net_isPath (net_t* netPtr, long fromId, long toId, bitmap_t* visitedBitmapPtr, queue_t* workQueuePtr) { bool_t status; vector_t* nodeVectorPtr = netPtr->nodeVectorPtr; assert(visitedBitmapPtr->numBit == vector_getSize(nodeVectorPtr)); bitmap_clearAll(visitedBitmapPtr); queue_clear(workQueuePtr); status = queue_push(workQueuePtr, (void*)fromId); assert(status); while (!queue_isEmpty(workQueuePtr)) { long id = (long)queue_pop(workQueuePtr); if (id == toId) { queue_clear(workQueuePtr); return TRUE; } status = bitmap_set(visitedBitmapPtr, id); assert(status); net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, id); list_t* childIdListPtr = nodePtr->childIdListPtr; list_iter_t it; list_iter_reset(&it, childIdListPtr); while (list_iter_hasNext(&it, childIdListPtr)) { long childId = (long)list_iter_next(&it, childIdListPtr); if (!bitmap_isSet(visitedBitmapPtr, childId)) { status = queue_push(workQueuePtr, (void*)childId); assert(status); } } } return FALSE; }
/* ============================================================================= * main * ============================================================================= */ MAIN(argc, argv) { GOTO_REAL(); /* * Initialization */ parseArgs(argc, (char** const)argv); long numThread = global_params[PARAM_THREAD]; SIM_GET_NUM_CPU(numThread); TM_STARTUP(numThread); P_MEMORY_STARTUP(numThread); thread_startup(numThread); maze_t* mazePtr = maze_alloc(); assert(mazePtr); long numPathToRoute = maze_read(mazePtr, global_inputFile); router_t* routerPtr = router_alloc(global_params[PARAM_XCOST], global_params[PARAM_YCOST], global_params[PARAM_ZCOST], global_params[PARAM_BENDCOST]); assert(routerPtr); list_t* pathVectorListPtr = list_alloc(NULL); assert(pathVectorListPtr); /* * Run transactions */ router_solve_arg_t routerArg = {routerPtr, mazePtr, pathVectorListPtr}; TIMER_T startTime; TIMER_READ(startTime); GOTO_SIM(); #ifdef OTM #pragma omp parallel { router_solve((void *)&routerArg); } #else thread_start(router_solve, (void*)&routerArg); #endif GOTO_REAL(); TIMER_T stopTime; TIMER_READ(stopTime); long numPathRouted = 0; list_iter_t it; list_iter_reset(&it, pathVectorListPtr); while (list_iter_hasNext(&it, pathVectorListPtr)) { vector_t* pathVectorPtr = (vector_t*)list_iter_next(&it, pathVectorListPtr); numPathRouted += vector_getSize(pathVectorPtr); } printf("Paths routed = %li\n", numPathRouted); printf("Elapsed time = %f seconds\n", TIMER_DIFF_SECONDS(startTime, stopTime)); /* * Check solution and clean up */ assert(numPathRouted <= numPathToRoute); bool_t status = maze_checkPaths(mazePtr, pathVectorListPtr, global_doPrint); assert(status == TRUE); puts("Verification passed."); maze_free(mazePtr); router_free(routerPtr); TM_SHUTDOWN(); P_MEMORY_SHUTDOWN(); GOTO_SIM(); thread_shutdown(); MAIN_RETURN(0); }
/* ============================================================================= * hashtable_iter_reset * ============================================================================= */ void hashtable_iter_reset (hashtable_iter_t* itPtr, hashtable_t* hashtablePtr) { itPtr->bucket = 0; list_iter_reset(&(itPtr->it), hashtablePtr->buckets[0]); }
void prio_iter_reset(prio_queue_t *q) { list_iter_reset(q); }
/* ============================================================================= * TMretriangulate * -- Returns net amount of elements added to mesh * ============================================================================= */ long TMretriangulate (TM_ARGDECL element_t* elementPtr, region_t* regionPtr, mesh_t* meshPtr, MAP_T* edgeMapPtr) { vector_t* badVectorPtr = regionPtr->badVectorPtr; /* private */ list_t* beforeListPtr = regionPtr->beforeListPtr; /* private */ list_t* borderListPtr = regionPtr->borderListPtr; /* private */ list_iter_t it; long numDelta = 0L; assert(edgeMapPtr); coordinate_t centerCoordinate = element_getNewPoint(elementPtr); /* * Remove the old triangles */ TMLIST_ITER_RESET(&it, beforeListPtr); while (TMLIST_ITER_HASNEXT(&it, beforeListPtr)) { element_t* beforeElementPtr = (element_t*)TMLIST_ITER_NEXT(&it, beforeListPtr); TMMESH_REMOVE(meshPtr, beforeElementPtr); } numDelta -= PLIST_GETSIZE(beforeListPtr); /* * If segment is encroached, split it in half */ if (element_getNumEdge(elementPtr) == 1) { coordinate_t coordinates[2]; edge_t* edgePtr = element_getEdge(elementPtr, 0); coordinates[0] = centerCoordinate; coordinates[1] = *(coordinate_t*)(edgePtr->firstPtr); element_t* aElementPtr = TMELEMENT_ALLOC(coordinates, 2); assert(aElementPtr); TMMESH_INSERT(meshPtr, aElementPtr, edgeMapPtr); coordinates[1] = *(coordinate_t*)(edgePtr->secondPtr); element_t* bElementPtr = TMELEMENT_ALLOC(coordinates, 2); assert(bElementPtr); TMMESH_INSERT(meshPtr, bElementPtr, edgeMapPtr); bool_t status; status = TMMESH_REMOVEBOUNDARY(meshPtr, element_getEdge(elementPtr, 0)); assert(status); status = TMMESH_INSERTBOUNDARY(meshPtr, element_getEdge(aElementPtr, 0)); assert(status); status = TMMESH_INSERTBOUNDARY(meshPtr, element_getEdge(bElementPtr, 0)); assert(status); numDelta += 2; } /* * Insert the new triangles. These are contructed using the new * point and the two points from the border segment. */ list_iter_reset(&it, borderListPtr); while (list_iter_hasNext(&it, borderListPtr)) { element_t* afterElementPtr; coordinate_t coordinates[3]; edge_t* borderEdgePtr = (edge_t*)list_iter_next(&it, borderListPtr); assert(borderEdgePtr); coordinates[0] = centerCoordinate; coordinates[1] = *(coordinate_t*)(borderEdgePtr->firstPtr); coordinates[2] = *(coordinate_t*)(borderEdgePtr->secondPtr); afterElementPtr = TMELEMENT_ALLOC(coordinates, 3); assert(afterElementPtr); TMMESH_INSERT(meshPtr, afterElementPtr, edgeMapPtr); if (element_isBad(afterElementPtr)) { TMaddToBadVector(TM_ARG badVectorPtr, afterElementPtr); } } numDelta += PLIST_GETSIZE(borderListPtr); return numDelta; }
/* ============================================================================= * main * ============================================================================= */ MAIN(argc, argv) { /* * Initialization */ parseArgs(argc, (char** const)argv); long numThread = global_params[PARAM_THREAD]; SIM_GET_NUM_CPU(numThread); TM_STARTUP(numThread); P_MEMORY_STARTUP(numThread); thread_startup(numThread); maze_t* mazePtr = maze_alloc(); assert(mazePtr); long numPathToRoute = maze_read(mazePtr, global_inputFile); router_t* routerPtr = router_alloc(global_params[PARAM_XCOST], global_params[PARAM_YCOST], global_params[PARAM_ZCOST], global_params[PARAM_BENDCOST]); assert(routerPtr); list_t* pathVectorListPtr = list_alloc(NULL); assert(pathVectorListPtr); /* * Run transactions */ router_solve_arg_t routerArg = {routerPtr, mazePtr, pathVectorListPtr}; // NB: Since ASF/PTLSim "REAL" is native execution, and since we are using // wallclock time, we want to be sure we read time inside the // simulator, or else we report native cycles spent on the benchmark // instead of simulator cycles. GOTO_SIM(); TIMER_T startTime; TIMER_READ(startTime); #ifdef OTM #pragma omp parallel { router_solve((void *)&routerArg); } #else thread_start(router_solve, (void*)&routerArg); #endif TIMER_T stopTime; TIMER_READ(stopTime); // NB: As above, timer reads must be done inside of the simulated region // for PTLSim/ASF GOTO_REAL(); long numPathRouted = 0; list_iter_t it; list_iter_reset(&it, pathVectorListPtr); while (list_iter_hasNext(&it, pathVectorListPtr)) { vector_t* pathVectorPtr = (vector_t*)list_iter_next(&it, pathVectorListPtr); numPathRouted += vector_getSize(pathVectorPtr); } printf("Paths routed = %li\n", numPathRouted); printf("Elapsed time = %f seconds\n", TIMER_DIFF_SECONDS(startTime, stopTime)); /* * Check solution and clean up */ assert(numPathRouted <= numPathToRoute); bool status = maze_checkPaths(mazePtr, pathVectorListPtr, global_doPrint); assert(status); puts("Verification passed."); maze_free(mazePtr); router_free(routerPtr); TM_SHUTDOWN(); P_MEMORY_SHUTDOWN(); thread_shutdown(); MAIN_RETURN(0); }
/* ============================================================================= * maze_checkPaths * ============================================================================= */ bool_t maze_checkPaths (maze_t* mazePtr, list_t* pathVectorListPtr, bool_t doPrintPaths) { grid_t* gridPtr = mazePtr->gridPtr; long width = gridPtr->width; long height = gridPtr->height; long depth = gridPtr->depth; long i; /* Mark walls */ grid_t* testGridPtr = grid_alloc(width, height, depth); grid_addPath(testGridPtr, mazePtr->wallVectorPtr); /* Mark sources */ vector_t* srcVectorPtr = mazePtr->srcVectorPtr; long numSrc = vector_getSize(srcVectorPtr); for (i = 0; i < numSrc; i++) { coordinate_t* srcPtr = (coordinate_t*)vector_at(srcVectorPtr, i); grid_setPoint(testGridPtr, srcPtr->x, srcPtr->y, srcPtr->z, 0); } /* Mark destinations */ vector_t* dstVectorPtr = mazePtr->dstVectorPtr; long numDst = vector_getSize(dstVectorPtr); for (i = 0; i < numDst; i++) { coordinate_t* dstPtr = (coordinate_t*)vector_at(dstVectorPtr, i); grid_setPoint(testGridPtr, dstPtr->x, dstPtr->y, dstPtr->z, 0); } /* Make sure path is contiguous and does not overlap */ long id = 0; list_iter_t it; list_iter_reset(&it, pathVectorListPtr); while (list_iter_hasNext(&it)) { vector_t* pathVectorPtr = (vector_t*)list_iter_next(&it); long numPath = vector_getSize(pathVectorPtr); long i; for (i = 0; i < numPath; i++) { id++; vector_t* pointVectorPtr = (vector_t*)vector_at(pathVectorPtr, i); /* Check start */ long* prevGridPointPtr = (long*)vector_at(pointVectorPtr, 0); long x; long y; long z; grid_getPointIndices(gridPtr, prevGridPointPtr, &x, &y, &z); if (grid_getPoint(testGridPtr, x, y, z) != 0) { grid_free(testGridPtr); return FALSE; } coordinate_t prevCoordinate; grid_getPointIndices(gridPtr, prevGridPointPtr, &prevCoordinate.x, &prevCoordinate.y, &prevCoordinate.z); long numPoint = vector_getSize(pointVectorPtr); long j; for (j = 1; j < (numPoint-1); j++) { /* no need to check endpoints */ long* currGridPointPtr = (long*)vector_at(pointVectorPtr, j); coordinate_t currCoordinate; grid_getPointIndices(gridPtr, currGridPointPtr, &currCoordinate.x, &currCoordinate.y, &currCoordinate.z); if (!coordinate_areAdjacent(&currCoordinate, &prevCoordinate)) { grid_free(testGridPtr); return FALSE; } prevCoordinate = currCoordinate; long x = currCoordinate.x; long y = currCoordinate.y; long z = currCoordinate.z; if (grid_getPoint(testGridPtr, x, y, z) != GRID_POINT_EMPTY) { grid_free(testGridPtr); return FALSE; } else { grid_setPoint(testGridPtr, x, y, z, id); } } /* Check end */ long* lastGridPointPtr = (long*)vector_at(pointVectorPtr, j); grid_getPointIndices(gridPtr, lastGridPointPtr, &x, &y, &z); if (grid_getPoint(testGridPtr, x, y, z) != 0) { grid_free(testGridPtr); return FALSE; } } /* iteratate over pathVector */ } /* iterate over pathVectorList */ if (doPrintPaths) { puts("\nRouted Maze:"); grid_print(testGridPtr); } grid_free(testGridPtr); return TRUE; }
/* ============================================================================= * data_generate * -- Binary variables of random PDFs * -- If seed is <0, do not reseed * -- Returns random network * ============================================================================= */ net_t* data_generate (data_t* dataPtr, long seed, long maxNumParent, long percentParent) { random_t* randomPtr = dataPtr->randomPtr; if (seed >= 0) { random_seed(randomPtr, seed); } /* * Generate random Bayesian network */ long numVar = dataPtr->numVar; net_t* netPtr = net_alloc(numVar); assert(netPtr); net_generateRandomEdges(netPtr, maxNumParent, percentParent, randomPtr); /* * Create a threshold for each of the possible permutation of variable * value instances */ long** thresholdsTable = (long**)SEQ_MALLOC(numVar * sizeof(long*)); assert(thresholdsTable); long v; for (v = 0; v < numVar; v++) { list_t* parentIdListPtr = net_getParentIdListPtr(netPtr, v); long numThreshold = 1 << list_getSize(parentIdListPtr); long* thresholds = (long*)SEQ_MALLOC(numThreshold * sizeof(long)); assert(thresholds); long t; for (t = 0; t < numThreshold; t++) { long threshold = random_generate(randomPtr) % (DATA_PRECISION + 1); thresholds[t] = threshold; } thresholdsTable[v] = thresholds; } /* * Create variable dependency ordering for record generation */ long* order = (long*)SEQ_MALLOC(numVar * sizeof(long)); assert(order); long numOrder = 0; queue_t* workQueuePtr = queue_alloc(-1); assert(workQueuePtr); vector_t* dependencyVectorPtr = vector_alloc(1); assert(dependencyVectorPtr); bitmap_t* orderedBitmapPtr = bitmap_alloc(numVar); assert(orderedBitmapPtr); bitmap_clearAll(orderedBitmapPtr); bitmap_t* doneBitmapPtr = bitmap_alloc(numVar); assert(doneBitmapPtr); bitmap_clearAll(doneBitmapPtr); v = -1; while ((v = bitmap_findClear(doneBitmapPtr, (v + 1))) >= 0) { list_t* childIdListPtr = net_getChildIdListPtr(netPtr, v); long numChild = list_getSize(childIdListPtr); if (numChild == 0) { bool status; /* * Use breadth-first search to find net connected to this leaf */ queue_clear(workQueuePtr); status = queue_push(workQueuePtr, (void*)v); assert(status); while (!queue_isEmpty(workQueuePtr)) { long id = (long)queue_pop(workQueuePtr); status = bitmap_set(doneBitmapPtr, id); assert(status); status = vector_pushBack(dependencyVectorPtr, (void*)id); assert(status); list_t* parentIdListPtr = net_getParentIdListPtr(netPtr, id); list_iter_t it; list_iter_reset(&it, parentIdListPtr); while (list_iter_hasNext(&it, parentIdListPtr)) { long parentId = (long)list_iter_next(&it, parentIdListPtr); status = queue_push(workQueuePtr, (void*)parentId); assert(status); } } /* * Create ordering */ long i; long n = vector_getSize(dependencyVectorPtr); for (i = 0; i < n; i++) { long id = (long)vector_popBack(dependencyVectorPtr); if (!bitmap_isSet(orderedBitmapPtr, id)) { bitmap_set(orderedBitmapPtr, id); order[numOrder++] = id; } } } } assert(numOrder == numVar); /* * Create records */ char* record = dataPtr->records; long r; long numRecord = dataPtr->numRecord; for (r = 0; r < numRecord; r++) { long o; for (o = 0; o < numOrder; o++) { long v = order[o]; list_t* parentIdListPtr = net_getParentIdListPtr(netPtr, v); long index = 0; list_iter_t it; list_iter_reset(&it, parentIdListPtr); while (list_iter_hasNext(&it, parentIdListPtr)) { long parentId = (long)list_iter_next(&it, parentIdListPtr); long value = record[parentId]; assert(value != DATA_INIT); index = (index << 1) + value; } long rnd = random_generate(randomPtr) % DATA_PRECISION; long threshold = thresholdsTable[v][index]; record[v] = ((rnd < threshold) ? 1 : 0); } record += numVar; assert(record <= (dataPtr->records + numRecord * numVar)); } /* * Clean up */ bitmap_free(doneBitmapPtr); bitmap_free(orderedBitmapPtr); vector_free(dependencyVectorPtr); queue_free(workQueuePtr); SEQ_FREE(order); for (v = 0; v < numVar; v++) { SEQ_FREE(thresholdsTable[v]); } SEQ_FREE(thresholdsTable); return netPtr; }
/* ============================================================================= * decoder_process * ============================================================================= */ int_error_t decoder_process (decoder_t* decoderPtr, char* bytes, long numByte) { bool_t status; /* * Basic error checking */ if (numByte < (long)PACKET_HEADER_LENGTH) { return ERROR_SHORT; } packet_t* packetPtr = (packet_t*)bytes; long flowId = packetPtr->flowId; long fragmentId = packetPtr->fragmentId; long numFragment = packetPtr->numFragment; long length = packetPtr->length; if (flowId < 0) { return ERROR_FLOWID; } if ((fragmentId < 0) || (fragmentId >= numFragment)) { return ERROR_FRAGMENTID; } if (length < 0) { return ERROR_LENGTH; } #if 0 /* * With the above checks, this one is redundant */ if (numFragment < 1) { return ERROR_NUMFRAGMENT; } #endif /* * Add to fragmented map for reassembling */ if (numFragment > 1) { MAP_T* fragmentedMapPtr = decoderPtr->fragmentedMapPtr; list_t* fragmentListPtr = (list_t*)MAP_FIND(fragmentedMapPtr, (void*)flowId); if (fragmentListPtr == NULL) { fragmentListPtr = list_alloc(&decoder_comparator); assert(fragmentListPtr); status = list_insert(fragmentListPtr, (void*)packetPtr); assert(status); status = MAP_INSERT(fragmentedMapPtr, (void*)flowId, (void*)fragmentListPtr); assert(status); } else { list_iter_t it; list_iter_reset(&it, fragmentListPtr); assert(list_iter_hasNext(&it, fragmentListPtr)); packet_t* firstFragmentPtr = (packet_t*)list_iter_next(&it, fragmentListPtr); long expectedNumFragment = firstFragmentPtr->numFragment; if (numFragment != expectedNumFragment) { status = MAP_REMOVE(fragmentedMapPtr, (void*)flowId); assert(status); return ERROR_NUMFRAGMENT; } status = list_insert(fragmentListPtr, (void*)packetPtr); assert(status); /* * If we have all the fragments we can reassemble them */ if (list_getSize(fragmentListPtr) == numFragment) { long numByte = 0; long i = 0; list_iter_reset(&it, fragmentListPtr); while (list_iter_hasNext(&it, fragmentListPtr)) { packet_t* fragmentPtr = (packet_t*)list_iter_next(&it, fragmentListPtr); assert(fragmentPtr->flowId == flowId); if (fragmentPtr->fragmentId != i) { status = MAP_REMOVE(fragmentedMapPtr, (void*)flowId); assert(status); return ERROR_INCOMPLETE; /* should be sequential */ } numByte += fragmentPtr->length; i++; } char* data = (char*)SEQ_MALLOC(numByte + 1); assert(data); data[numByte] = '\0'; char* dst = data; list_iter_reset(&it, fragmentListPtr); while (list_iter_hasNext(&it, fragmentListPtr)) { packet_t* fragmentPtr = (packet_t*)list_iter_next(&it, fragmentListPtr); memcpy(dst, (void*)fragmentPtr->data, fragmentPtr->length); dst += fragmentPtr->length; } assert(dst == data + numByte); decoded_t* decodedPtr = (decoded_t*)SEQ_MALLOC(sizeof(decoded_t)); assert(decodedPtr); decodedPtr->flowId = flowId; decodedPtr->data = data; queue_t* decodedQueuePtr = decoderPtr->decodedQueuePtr; status = queue_push(decodedQueuePtr, (void*)decodedPtr); assert(status); list_free(fragmentListPtr); status = MAP_REMOVE(fragmentedMapPtr, (void*)flowId); assert(status); } } } else { /* * This is the only fragment, so it is ready */ if (fragmentId != 0) { return ERROR_FRAGMENTID; } char* data = (char*)SEQ_MALLOC(length + 1); assert(data); data[length] = '\0'; memcpy(data, (void*)packetPtr->data, length); decoded_t* decodedPtr = (decoded_t*)SEQ_MALLOC(sizeof(decoded_t)); assert(decodedPtr); decodedPtr->flowId = flowId; decodedPtr->data = data; queue_t* decodedQueuePtr = decoderPtr->decodedQueuePtr; status = queue_push(decodedQueuePtr, (void*)decodedPtr); assert(status); } return ERROR_NONE; }
/* ============================================================================= * sequencer_run * ============================================================================= */ void sequencer_run (void* argPtr) { TM_THREAD_ENTER(); long threadId = thread_getId(); sequencer_t* sequencerPtr = (sequencer_t*)argPtr; hashtable_t* uniqueSegmentsPtr; endInfoEntry_t* endInfoEntries; table_t** startHashToConstructEntryTables; constructEntry_t* constructEntries; table_t* hashToConstructEntryTable; uniqueSegmentsPtr = sequencerPtr->uniqueSegmentsPtr; endInfoEntries = sequencerPtr->endInfoEntries; startHashToConstructEntryTables = sequencerPtr->startHashToConstructEntryTables; constructEntries = sequencerPtr->constructEntries; hashToConstructEntryTable = sequencerPtr->hashToConstructEntryTable; segments_t* segmentsPtr = sequencerPtr->segmentsPtr; assert(segmentsPtr); vector_t* segmentsContentsPtr = segmentsPtr->contentsPtr; long numSegment = vector_getSize(segmentsContentsPtr); long segmentLength = segmentsPtr->length; long i; long j; long i_start; long i_stop; long numUniqueSegment; long substringLength; long entryIndex; /* * Step 1: Remove duplicate segments */ // #if defined(HTM) || defined(STM) long numThread = thread_getNumThread(); { /* Choose disjoint segments [i_start,i_stop) for each thread */ long partitionSize = (numSegment + numThread/2) / numThread; /* with rounding */ i_start = threadId * partitionSize; if (threadId == (numThread - 1)) { i_stop = numSegment; } else { i_stop = i_start + partitionSize; } } // #else /* !(HTM || STM) */ // i_start = 0; // i_stop = numSegment; // #endif /* !(HTM || STM) */ for (i = i_start; i < i_stop; i+=CHUNK_STEP1) { TM_BEGIN(); { long ii; long ii_stop = MIN(i_stop, (i+CHUNK_STEP1)); for (ii = i; ii < ii_stop; ii++) { void* segment = vector_at(segmentsContentsPtr, ii); TMHASHTABLE_INSERT(uniqueSegmentsPtr, segment, segment); } /* ii */ } TM_END(); } thread_barrier_wait(); /* * Step 2a: Iterate over unique segments and compute hashes. * * For the gene "atcg", the hashes for the end would be: * * "t", "tc", and "tcg" * * And for the gene "tcgg", the hashes for the start would be: * * "t", "tc", and "tcg" * * The names are "end" and "start" because if a matching pair is found, * they are the substring of the end part of the pair and the start * part of the pair respectively. In the above example, "tcg" is the * matching substring so: * * (end) (start) * a[tcg] + [tcg]g = a[tcg]g (overlap = "tcg") */ /* uniqueSegmentsPtr is constant now */ numUniqueSegment = hashtable_getSize(uniqueSegmentsPtr); entryIndex = 0; // #if defined(HTM) || defined(STM) { /* Choose disjoint segments [i_start,i_stop) for each thread */ long num = uniqueSegmentsPtr->numBucket; long partitionSize = (num + numThread/2) / numThread; /* with rounding */ i_start = threadId * partitionSize; if (threadId == (numThread - 1)) { i_stop = num; } else { i_stop = i_start + partitionSize; } } { /* Approximate disjoint segments of element allocation in constructEntries */ long partitionSize = (numUniqueSegment + numThread/2) / numThread; /* with rounding */ entryIndex = threadId * partitionSize; } // #else /* !(HTM || STM) */ // i_start = 0; // i_stop = uniqueSegmentsPtr->numBucket; // entryIndex = 0; //#endif /* !(HTM || STM) */ for (i = i_start; i < i_stop; i++) { list_t* chainPtr = uniqueSegmentsPtr->buckets[i]; list_iter_t it; list_iter_reset(&it, chainPtr); while (list_iter_hasNext(&it, chainPtr)) { char* segment = (char*)((pair_t*)list_iter_next(&it, chainPtr))->firstPtr; constructEntry_t* constructEntryPtr; long j; ulong_t startHash; bool_t status; /* Find an empty constructEntries entry */ TM_BEGIN(); while (((void*)TM_SHARED_READ_P(constructEntries[entryIndex].segment)) != NULL) { entryIndex = (entryIndex + 1) % numUniqueSegment; /* look for empty */ } constructEntryPtr = &constructEntries[entryIndex]; TM_SHARED_WRITE_P(constructEntryPtr->segment, segment); TM_END(); entryIndex = (entryIndex + 1) % numUniqueSegment; /* * Save hashes (sdbm algorithm) of segment substrings * * endHashes will be computed for shorter substrings after matches * have been made (in the next phase of the code). This will reduce * the number of substrings for which hashes need to be computed. * * Since we can compute startHashes incrementally, we go ahead * and compute all of them here. */ /* constructEntryPtr is local now */ constructEntryPtr->endHash = (ulong_t)hashString(&segment[1]); startHash = 0; for (j = 1; j < segmentLength; j++) { startHash = (ulong_t)segment[j-1] + (startHash << 6) + (startHash << 16) - startHash; TM_BEGIN(); status = TMTABLE_INSERT(startHashToConstructEntryTables[j], (ulong_t)startHash, (void*)constructEntryPtr ); TM_END(); assert(status); } /* * For looking up construct entries quickly */ startHash = (ulong_t)segment[j-1] + (startHash << 6) + (startHash << 16) - startHash; TM_BEGIN(); status = TMTABLE_INSERT(hashToConstructEntryTable, (ulong_t)startHash, (void*)constructEntryPtr); TM_END(); assert(status); } } thread_barrier_wait(); /* * Step 2b: Match ends to starts by using hash-based string comparison. */ for (substringLength = segmentLength-1; substringLength > 0; substringLength--) { table_t* startHashToConstructEntryTablePtr = startHashToConstructEntryTables[substringLength]; list_t** buckets = startHashToConstructEntryTablePtr->buckets; long numBucket = startHashToConstructEntryTablePtr->numBucket; long index_start; long index_stop; // #if defined(HTM) || defined(STM) { /* Choose disjoint segments [index_start,index_stop) for each thread */ long partitionSize = (numUniqueSegment + numThread/2) / numThread; /* with rounding */ index_start = threadId * partitionSize; if (threadId == (numThread - 1)) { index_stop = numUniqueSegment; } else { index_stop = index_start + partitionSize; } } // #else /* !(HTM || STM) */ // index_start = 0; // index_stop = numUniqueSegment; //#endif /* !(HTM || STM) */ /* Iterating over disjoint itervals in the range [0, numUniqueSegment) */ for (entryIndex = index_start; entryIndex < index_stop; entryIndex += endInfoEntries[entryIndex].jumpToNext) { if (!endInfoEntries[entryIndex].isEnd) { continue; } /* ConstructEntries[entryIndex] is local data */ constructEntry_t* endConstructEntryPtr = &constructEntries[entryIndex]; char* endSegment = endConstructEntryPtr->segment; ulong_t endHash = endConstructEntryPtr->endHash; list_t* chainPtr = buckets[endHash % numBucket]; /* buckets: constant data */ list_iter_t it; list_iter_reset(&it, chainPtr); /* Linked list at chainPtr is constant */ while (list_iter_hasNext(&it, chainPtr)) { constructEntry_t* startConstructEntryPtr = (constructEntry_t*)list_iter_next(&it, chainPtr); char* startSegment = startConstructEntryPtr->segment; long newLength = 0; /* endConstructEntryPtr is local except for properties startPtr/endPtr/length */ TM_BEGIN(); /* Check if matches */ if (TM_SHARED_READ(startConstructEntryPtr->isStart) && (TM_SHARED_READ_P(endConstructEntryPtr->startPtr) != startConstructEntryPtr) && (strncmp(startSegment, &endSegment[segmentLength - substringLength], substringLength) == 0)) { TM_SHARED_WRITE(startConstructEntryPtr->isStart, FALSE); constructEntry_t* startConstructEntry_endPtr; constructEntry_t* endConstructEntry_startPtr; /* Update endInfo (appended something so no longer end) */ TM_LOCAL_WRITE(endInfoEntries[entryIndex].isEnd, FALSE); /* Update segment chain construct info */ startConstructEntry_endPtr = (constructEntry_t*)TM_SHARED_READ_P(startConstructEntryPtr->endPtr); endConstructEntry_startPtr = (constructEntry_t*)TM_SHARED_READ_P(endConstructEntryPtr->startPtr); assert(startConstructEntry_endPtr); assert(endConstructEntry_startPtr); TM_SHARED_WRITE_P(startConstructEntry_endPtr->startPtr, endConstructEntry_startPtr); TM_LOCAL_WRITE_P(endConstructEntryPtr->nextPtr, startConstructEntryPtr); TM_SHARED_WRITE_P(endConstructEntry_startPtr->endPtr, startConstructEntry_endPtr); TM_SHARED_WRITE(endConstructEntryPtr->overlap, substringLength); newLength = (long)TM_SHARED_READ(endConstructEntry_startPtr->length) + (long)TM_SHARED_READ(startConstructEntryPtr->length) - substringLength; TM_SHARED_WRITE(endConstructEntry_startPtr->length, newLength); } /* if (matched) */ TM_END(); if (!endInfoEntries[entryIndex].isEnd) { /* if there was a match */ break; } } /* iterate over chain */ } /* for (endIndex < numUniqueSegment) */ thread_barrier_wait(); /* * Step 2c: Update jump values and hashes * * endHash entries of all remaining ends are updated to the next * substringLength. Additionally jumpToNext entries are updated such * that they allow to skip non-end entries. Currently this is sequential * because parallelization did not perform better. . */ if (threadId == 0) { if (substringLength > 1) { long index = segmentLength - substringLength + 1; /* initialization if j and i: with i being the next end after j=0 */ for (i = 1; !endInfoEntries[i].isEnd; i+=endInfoEntries[i].jumpToNext) { /* find first non-null */ } /* entry 0 is handled seperately from the loop below */ endInfoEntries[0].jumpToNext = i; if (endInfoEntries[0].isEnd) { constructEntry_t* constructEntryPtr = &constructEntries[0]; char* segment = constructEntryPtr->segment; constructEntryPtr->endHash = (ulong_t)hashString(&segment[index]); } /* Continue scanning (do not reset i) */ for (j = 0; i < numUniqueSegment; i+=endInfoEntries[i].jumpToNext) { if (endInfoEntries[i].isEnd) { constructEntry_t* constructEntryPtr = &constructEntries[i]; char* segment = constructEntryPtr->segment; constructEntryPtr->endHash = (ulong_t)hashString(&segment[index]); endInfoEntries[j].jumpToNext = MAX(1, (i - j)); j = i; } } endInfoEntries[j].jumpToNext = i - j; } } thread_barrier_wait(); } /* for (substringLength > 0) */ thread_barrier_wait(); /* * Step 3: Build sequence string */ if (threadId == 0) { long totalLength = 0; for (i = 0; i < numUniqueSegment; i++) { constructEntry_t* constructEntryPtr = &constructEntries[i]; if (constructEntryPtr->isStart) { totalLength += constructEntryPtr->length; } } sequencerPtr->sequence = (char*)P_MALLOC((totalLength+1) * sizeof(char)); char* sequence = sequencerPtr->sequence; assert(sequence); char* copyPtr = sequence; long sequenceLength = 0; for (i = 0; i < numUniqueSegment; i++) { constructEntry_t* constructEntryPtr = &constructEntries[i]; /* If there are several start segments, we append in arbitrary order */ if (constructEntryPtr->isStart) { long newSequenceLength = sequenceLength + constructEntryPtr->length; assert( newSequenceLength <= totalLength ); copyPtr = sequence + sequenceLength; sequenceLength = newSequenceLength; do { long numChar = segmentLength - constructEntryPtr->overlap; if ((copyPtr + numChar) > (sequence + newSequenceLength)) { TM_PRINT0("ERROR: sequence length != actual length\n"); break; } memcpy(copyPtr, constructEntryPtr->segment, (numChar * sizeof(char))); copyPtr += numChar; } while ((constructEntryPtr = constructEntryPtr->nextPtr) != NULL); assert(copyPtr <= (sequence + sequenceLength)); } } assert(sequence != NULL); sequence[sequenceLength] = '\0'; } TM_THREAD_EXIT(); }
/* ============================================================================= * maze_read * -- Return number of path to route * ============================================================================= */ long maze_read (maze_t* mazePtr, char* inputFileName) { FILE* inputFile = fopen(inputFileName, "rt"); if (!inputFile) { fprintf(stderr, "Error: Could not read %s\n", inputFileName); exit(1); } /* * Parse input file */ long lineNumber = 0; long height = -1; long width = -1; long depth = -1; char line[256]; list_t* workListPtr = list_alloc(&coordinate_comparePair); vector_t* wallVectorPtr = mazePtr->wallVectorPtr; vector_t* srcVectorPtr = mazePtr->srcVectorPtr; vector_t* dstVectorPtr = mazePtr->dstVectorPtr; while (fgets(line, sizeof(line), inputFile)) { char code; long x1, y1, z1; long x2, y2, z2; long numToken = sscanf(line, " %c %li %li %li %li %li %li", &code, &x1, &y1, &z1, &x2, &y2, &z2); lineNumber++; if (numToken < 1) { continue; } switch (code) { case '#': { /* comment */ /* ignore line */ break; } case 'd': { /* dimensions (format: d x y z) */ if (numToken != 4) { goto PARSE_ERROR; } width = x1; height = y1; depth = z1; if (width < 1 || height < 1 || depth < 1) { goto PARSE_ERROR; } break; } case 'p': { /* paths (format: p x1 y1 z1 x2 y2 z2) */ if (numToken != 7) { goto PARSE_ERROR; } coordinate_t* srcPtr = coordinate_alloc(x1, y1, z1); coordinate_t* dstPtr = coordinate_alloc(x2, y2, z2); assert(srcPtr); assert(dstPtr); if (coordinate_isEqual(srcPtr, dstPtr)) { goto PARSE_ERROR; } pair_t* coordinatePairPtr = pair_alloc(srcPtr, dstPtr); assert(coordinatePairPtr); bool_t status = list_insert(workListPtr, (void*)coordinatePairPtr); assert(status == TRUE); vector_pushBack(srcVectorPtr, (void*)srcPtr); vector_pushBack(dstVectorPtr, (void*)dstPtr); break; } case 'w': { /* walls (format: w x y z) */ if (numToken != 4) { goto PARSE_ERROR; } coordinate_t* wallPtr = coordinate_alloc(x1, y1, z1); vector_pushBack(wallVectorPtr, (void*)wallPtr); break; } PARSE_ERROR: default: { /* error */ fprintf(stderr, "Error: line %li of %s invalid\n", lineNumber, inputFileName); exit(1); } } } /* iterate over lines in input file */ fclose(inputFile); /* * Initialize grid contents */ if (width < 1 || height < 1 || depth < 1) { fprintf(stderr, "Error: Invalid dimensions (%li, %li, %li)\n", width, height, depth); exit(1); } grid_t* gridPtr = grid_alloc(width, height, depth); assert(gridPtr); mazePtr->gridPtr = gridPtr; addToGrid(gridPtr, wallVectorPtr, "wall"); addToGrid(gridPtr, srcVectorPtr, "source"); addToGrid(gridPtr, dstVectorPtr, "destination"); printf("Maze dimensions = %li x %li x %li\n", width, height, depth); printf("Paths to route = %li\n", list_getSize(workListPtr)); /* * Initialize work queue */ queue_t* workQueuePtr = mazePtr->workQueuePtr; list_iter_t it; list_iter_reset(&it, workListPtr); while (list_iter_hasNext(&it)) { pair_t* coordinatePairPtr = (pair_t*)list_iter_next(&it); queue_push(workQueuePtr, (void*)coordinatePairPtr); } list_free(workListPtr); return vector_getSize(srcVectorPtr); }