/* ============================================================================= * prefix_sums * ============================================================================= */ static void prefix_sums (ULONGINT_T* result, LONGINT_T* input, ULONGINT_T arraySize) { long myId = thread_getId(); long numThread = thread_getNumThread(); ULONGINT_T* p = NULL; if (myId == 0) { p = (ULONGINT_T*)P_MALLOC(NOSHARE(numThread) * sizeof(ULONGINT_T)); assert(p); global_p = p; } thread_barrier_wait(); p = global_p; long start; long end; long r = arraySize / numThread; start = myId * r + 1; end = (myId + 1) * r; if (myId == (numThread - 1)) { end = arraySize; } ULONGINT_T j; for (j = start; j < end; j++) { result[j] = input[j-1] + result[j-1]; } p[NOSHARE(myId)] = result[end-1]; thread_barrier_wait(); if (myId == 0) { for (j = 1; j < numThread; j++) { p[NOSHARE(j)] += p[NOSHARE(j-1)]; } } thread_barrier_wait(); if (myId > 0) { ULONGINT_T add_value = p[NOSHARE(myId-1)]; for (j = start-1; j < end; j++) { result[j] += add_value; } } thread_barrier_wait(); if (myId == 0) { P_FREE(p); } }
/* ============================================================================= * Pregion_free * ============================================================================= */ void Pregion_free (region_t* regionPtr) { PVECTOR_FREE(regionPtr->badVectorPtr); PLIST_FREE(regionPtr->borderListPtr); PLIST_FREE(regionPtr->beforeListPtr); PQUEUE_FREE(regionPtr->expandQueuePtr); P_FREE(regionPtr); }
void controller_free() { for (long i = 1 ; i < global_numThreads ; i++) { SEM_DESTROY(global_metadata[i].semaphore); } P_FREE(global_metadata); global_metadata = NULL; pthread_join(controllerThread, NULL); }
/* ============================================================================= * Pqueue_push * ============================================================================= */ bool_t Pqueue_push (queue_t* queuePtr, void* dataPtr) { long pop = queuePtr->pop; long push = queuePtr->push; long capacity = queuePtr->capacity; assert(pop != push); /* Need to resize */ long newPush = (push + 1) % capacity; if (newPush == pop) { long newCapacity = capacity * QUEUE_GROWTH_FACTOR; void** newElements = (void**)P_MALLOC(newCapacity * sizeof(void*)); if (newElements == NULL) { return FALSE; } long dst = 0; void** elements = queuePtr->elements; if (pop < push) { long src; for (src = (pop + 1); src < push; src++, dst++) { newElements[dst] = elements[src]; } } else { long src; for (src = (pop + 1); src < capacity; src++, dst++) { newElements[dst] = elements[src]; } for (src = 0; src < push; src++, dst++) { newElements[dst] = elements[src]; } } P_FREE(elements); queuePtr->elements = newElements; queuePtr->pop = newCapacity - 1; queuePtr->capacity = newCapacity; push = dst; newPush = push + 1; /* no need modulo */ } queuePtr->elements[push] = dataPtr; queuePtr->push = newPush; return TRUE; }
/* ============================================================================= * Pvector_pushBack * -- Returns FALSE if fail, else TRUE * ============================================================================= */ bool_t Pvector_pushBack (vector_t* vectorPtr, void* dataPtr) { if (vectorPtr->size == vectorPtr->capacity) { long i; long newCapacity = vectorPtr->capacity * 2; void** newElements = (void**)P_MALLOC(newCapacity * sizeof(void*)); if (newElements == NULL) { return FALSE; } vectorPtr->capacity = newCapacity; for (i = 0; i < vectorPtr->size; i++) { newElements[i] = vectorPtr->elements[i]; } P_FREE(vectorPtr->elements); vectorPtr->elements = newElements; } vectorPtr->elements[vectorPtr->size++] = dataPtr; return TRUE; }
/* ============================================================================= * Pvector_copy * ============================================================================= */ bool_t Pvector_copy (vector_t* dstVectorPtr, vector_t* srcVectorPtr) { long dstCapacity = dstVectorPtr->capacity; long srcSize = srcVectorPtr->size; if (dstCapacity < srcSize) { long srcCapacity = srcVectorPtr->capacity; void** elements = (void**)P_MALLOC(srcCapacity * sizeof(void*)); if (elements == NULL) { return FALSE; } P_FREE(dstVectorPtr->elements); dstVectorPtr->elements = elements; dstVectorPtr->capacity = srcCapacity; } memcpy(dstVectorPtr->elements, srcVectorPtr->elements, (srcSize * sizeof(void*))); dstVectorPtr->size = srcSize; return TRUE; }
/* ============================================================================= * findSubGraphs2 * ============================================================================= */ void findSubGraphs2 (void* argPtr) { graph* GPtr = ((findSubGraphs2_arg_t*)argPtr)->GPtr; Vd* intWtVDList = ((findSubGraphs2_arg_t*)argPtr)->intWtVDList; Vd* strWtVDList = ((findSubGraphs2_arg_t*)argPtr)->strWtVDList; edge* maxIntWtList = ((findSubGraphs2_arg_t*)argPtr)->maxIntWtList; long maxIntWtListSize = ((findSubGraphs2_arg_t*)argPtr)->maxIntWtListSize; edge* soughtStrWtList = ((findSubGraphs2_arg_t*)argPtr)->soughtStrWtList; long soughtStrWtListSize = ((findSubGraphs2_arg_t*)argPtr)->soughtStrWtListSize; long myId = thread_getId(); long numThread = thread_getNumThread(); long numSubArray = 30; long arraySize = 5*MAX_CLUSTER_SIZE; long i; long i_start; long i_stop; createPartition(0, (maxIntWtListSize + soughtStrWtListSize), myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { if (i < maxIntWtListSize) { /* Initialize the DS and create one sub-array */ intWtVDList[i].numArrays = 1; intWtVDList[i].arraySize = (ULONGINT_T*)P_MALLOC(numSubArray * sizeof(ULONGINT_T)); assert(intWtVDList[i].arraySize); intWtVDList[i].arraySize[0] = 0; intWtVDList[i].vList = (V**)P_MALLOC(numSubArray*sizeof(V *)); assert(intWtVDList[i].vList); intWtVDList[i].vList[0] = (V*)P_MALLOC(arraySize*sizeof(V)); assert(intWtVDList[i].vList[0]); long j; for (j = 0; j < arraySize; j++) { intWtVDList[i].vList[0][j].num = 0; intWtVDList[i].vList[0][j].depth = 0; } } else { long t = i - maxIntWtListSize; strWtVDList[t].numArrays = 1; strWtVDList[t].arraySize = (ULONGINT_T*)P_MALLOC(numSubArray * sizeof(ULONGINT_T)); assert(strWtVDList[t].arraySize); strWtVDList[t].arraySize[0] = 0; strWtVDList[t].vList = (V**)P_MALLOC(numSubArray * sizeof(V*)); assert(strWtVDList[t].vList); strWtVDList[t].vList[0] = (V*)P_MALLOC(arraySize * sizeof(V)); assert(strWtVDList[t].vList[0]); long j; for (j = 0; j < arraySize; j++) { strWtVDList[t].vList[0][j].num = 0; strWtVDList[t].vList[0][j].depth = 0; } } } thread_barrier_wait(); char* visited = (char*)P_MALLOC(GPtr->numVertices * sizeof(char)); assert(visited); /* * Each thread runs a BFS from endvertex of maxIntWtList edgeList */ for (i = i_start; i < i_stop; i++) { unsigned long k; for (k = 0; k < GPtr->numVertices; k++) { visited[k] = 'u'; } if (i < maxIntWtListSize) { intWtVDList[i].vList[0][0].num = maxIntWtList[i].startVertex; intWtVDList[i].vList[0][0].depth = -1; intWtVDList[i].vList[0][1].num = maxIntWtList[i].endVertex; intWtVDList[i].vList[0][1].depth = 1; intWtVDList[i].arraySize[0] = 2; visited[intWtVDList[i].vList[0][0].num] = 'v'; visited[intWtVDList[i].vList[0][1].num] = 'v'; long depth = 1; long verticesVisited = 2; long currIndex = 1; while ((depth < SUBGR_EDGE_LENGTH) || (verticesVisited == (long)GPtr->numVertices)) { long currVListX = currIndex / arraySize; long currVListY = currIndex % arraySize; V* currV = &intWtVDList[i].vList[currVListX][currVListY]; long vNum = currV->num; depth = currV->depth + 1; long j; long j_start = GPtr->outVertexIndex[vNum]; long j_stop = j_start + GPtr->outDegree[vNum]; for (j = j_start; j < j_stop; j++) { if (visited[GPtr->outVertexList[j]] == 'u') { visited[GPtr->outVertexList[j]] = 'v'; long vListX = verticesVisited/arraySize; long vListY = verticesVisited % arraySize; V* v = &intWtVDList[i].vList[vListX][vListY]; v->num = GPtr->outVertexList[j]; v->depth = depth; intWtVDList[i].arraySize[vListX]++; verticesVisited++; } } /* Check if we need to create a new array */ if (((float) verticesVisited / (float) arraySize) > 0.5) { /* create a new sub-array */ if (intWtVDList[i].numArrays != (unsigned long)(verticesVisited/arraySize + 2)) { intWtVDList[i].numArrays++; intWtVDList[i].vList[intWtVDList[i].numArrays-1] = (V*)P_MALLOC(arraySize * sizeof(V)); assert(intWtVDList[i].vList[intWtVDList[i].numArrays-1]); intWtVDList[i].arraySize[intWtVDList[i].numArrays-1] = 0; } } if ((currIndex < verticesVisited - 1) && (verticesVisited < (long)GPtr->numVertices)) { currIndex++; long vListX = currIndex / arraySize; long vListY = currIndex % arraySize; depth = intWtVDList[i].vList[vListX][vListY].depth; } else { break; } } } else { long t = i - maxIntWtListSize; strWtVDList[t].vList[0][0].num = soughtStrWtList[t].startVertex; strWtVDList[t].vList[0][0].depth = -1; strWtVDList[t].vList[0][1].num = soughtStrWtList[t].endVertex; strWtVDList[t].vList[0][1].depth = 1; strWtVDList[t].arraySize[0] = 2; visited[strWtVDList[t].vList[0][0].num] = 'v'; visited[strWtVDList[t].vList[0][1].num] = 'v'; long depth = 1; long verticesVisited = 2; long currIndex = 1; while ((depth < SUBGR_EDGE_LENGTH) || (verticesVisited == (long)GPtr->numVertices)) { long currVListX = currIndex / arraySize; long currVListY = currIndex % arraySize; V* currV = &strWtVDList[t].vList[currVListX][currVListY]; long vNum = currV->num; depth = currV->depth + 1; long j; long j_start = GPtr->outVertexIndex[vNum]; long j_stop = j_start + GPtr->outDegree[vNum]; for (j = j_start; j < j_stop; j++) { if (visited[GPtr->outVertexList[j]] == 'u') { visited[GPtr->outVertexList[j]] = 'v'; long vListX = verticesVisited / arraySize; long vListY = verticesVisited % arraySize; V* v = &strWtVDList[t].vList[vListX][vListY]; v->num = GPtr->outVertexList[j]; v->depth = depth; strWtVDList[t].arraySize[vListX]++; verticesVisited++; } } /* Check if we need to create a new array */ if (((float)verticesVisited /(float) arraySize) > 0.5) { /* create a new sub-array */ if (strWtVDList[t].numArrays != (unsigned long)(verticesVisited/arraySize + 2)) { strWtVDList[t].numArrays++; strWtVDList[t].vList[strWtVDList[t].numArrays-1] = (V*)P_MALLOC(arraySize * sizeof(V)); assert(strWtVDList[t].vList[strWtVDList[t].numArrays-1]); strWtVDList[t].arraySize[strWtVDList[t].numArrays-1] = 0; } } if ((currIndex < verticesVisited - 1) && ((unsigned long)verticesVisited < GPtr->numVertices)) { currIndex++; long currVListX = currIndex / arraySize; long currVListY = currIndex % arraySize; depth = strWtVDList[t].vList[currVListX][currVListY].depth; } else { break; } } } } /* for i */ P_FREE(visited); }
/* ============================================================================= * genScalData * ============================================================================= */ void genScalData (void* argPtr) { TM_THREAD_ENTER(); graphSDG* SDGdataPtr = (graphSDG*)argPtr; long myId = thread_getId(); long numThread = thread_getNumThread(); /* * STEP 0: Create the permutations required to randomize the vertices */ random_t* stream = PRANDOM_ALLOC(); assert(stream); PRANDOM_SEED(stream, myId); ULONGINT_T* permV; /* the vars associated with the graph tuple */ if (myId == 0) { permV = (ULONGINT_T*)P_MALLOC(TOT_VERTICES * sizeof(ULONGINT_T)); assert(permV); global_permV = permV; } thread_barrier_wait(); permV = global_permV; long i; long i_start; long i_stop; createPartition(0, TOT_VERTICES, myId, numThread, &i_start, &i_stop); /* Initialize the array */ for (i = i_start; i < i_stop; i++) { permV[i] = i; } thread_barrier_wait(); for (i = i_start; i < i_stop; i++) { long t1 = PRANDOM_GENERATE(stream); long t = i + t1 % (TOT_VERTICES - i); if (t != i) { AL_LOCK(0); TM_BEGIN(); long t2 = (long)TM_SHARED_READ(permV[t]); TM_SHARED_WRITE(permV[t], TM_SHARED_READ(permV[i])); TM_SHARED_WRITE(permV[i], t2); TM_END(); } } /* * STEP 1: Create Cliques */ long* cliqueSizes; long estTotCliques = ceil(1.5 * TOT_VERTICES / ((1+MAX_CLIQUE_SIZE)/2)); /* * Allocate mem for Clique array * Estimate number of clique required and pad by 50% */ if (myId == 0) { cliqueSizes = (long*)P_MALLOC(estTotCliques * sizeof(long)); assert(cliqueSizes); global_cliqueSizes = cliqueSizes; } thread_barrier_wait(); cliqueSizes = global_cliqueSizes; createPartition(0, estTotCliques, myId, numThread, &i_start, &i_stop); /* Generate random clique sizes. */ for (i = i_start; i < i_stop; i++) { cliqueSizes[i] = 1 + (PRANDOM_GENERATE(stream) % MAX_CLIQUE_SIZE); } thread_barrier_wait(); long totCliques = 0; /* * Allocate memory for cliqueList */ ULONGINT_T* lastVsInCliques; ULONGINT_T* firstVsInCliques; if (myId == 0) { lastVsInCliques = (ULONGINT_T*)P_MALLOC(estTotCliques * sizeof(ULONGINT_T)); assert(lastVsInCliques); global_lastVsInCliques = lastVsInCliques; firstVsInCliques = (ULONGINT_T*)P_MALLOC(estTotCliques * sizeof(ULONGINT_T)); assert(firstVsInCliques); global_firstVsInCliques = firstVsInCliques; /* * Sum up vertices in each clique to determine the lastVsInCliques array */ lastVsInCliques[0] = cliqueSizes[0] - 1; for (i = 1; i < estTotCliques; i++) { lastVsInCliques[i] = cliqueSizes[i] + lastVsInCliques[i-1]; if (lastVsInCliques[i] >= TOT_VERTICES-1) { break; } } totCliques = i + 1; global_totCliques = totCliques; /* * Fix the size of the last clique */ cliqueSizes[totCliques-1] = TOT_VERTICES - lastVsInCliques[totCliques-2] - 1; lastVsInCliques[totCliques-1] = TOT_VERTICES - 1; firstVsInCliques[0] = 0; } thread_barrier_wait(); lastVsInCliques = global_lastVsInCliques; firstVsInCliques = global_firstVsInCliques; totCliques = global_totCliques; /* Compute start Vertices in cliques. */ createPartition(1, totCliques, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { firstVsInCliques[i] = lastVsInCliques[i-1] + 1; } #ifdef WRITE_RESULT_FILES thread_barrier_wait(); /* Write the generated cliques to file for comparison with Kernel 4 */ if (myId == 0) { FILE* outfp = fopen("cliques.txt", "w"); fprintf(outfp, "No. of cliques - %lu\n", totCliques); for (i = 0; i < totCliques; i++) { fprintf(outfp, "Clq %lu - ", i); long j; for (j = firstVsInCliques[i]; j <= lastVsInCliques[i]; j++) { fprintf(outfp, "%lu ", permV[j]); } fprintf(outfp, "\n"); } fclose(outfp); } thread_barrier_wait(); #endif /* * STEP 2: Create the edges within the cliques */ /* * Estimate number of edges - using an empirical measure */ long estTotEdges; if (SCALE >= 12) { estTotEdges = ceil(((MAX_CLIQUE_SIZE-1) * TOT_VERTICES)); } else { estTotEdges = ceil(1.2 * (((MAX_CLIQUE_SIZE-1)*TOT_VERTICES) * ((1 + MAX_PARAL_EDGES)/2) + TOT_VERTICES*2)); } /* * Initialize edge counter */ long i_edgePtr = 0; float p = PROB_UNIDIRECTIONAL; /* * Partial edgeLists */ ULONGINT_T* startV; ULONGINT_T* endV; if (numThread > 3) { long numByte = 1.5 * (estTotEdges/numThread) * sizeof(ULONGINT_T); startV = (ULONGINT_T*)P_MALLOC(numByte); endV = (ULONGINT_T*)P_MALLOC(numByte); } else { long numByte = (estTotEdges/numThread) * sizeof(ULONGINT_T); startV = (ULONGINT_T*)P_MALLOC(numByte); endV = (ULONGINT_T*)P_MALLOC(numByte); } assert(startV); assert(endV); /* * Tmp array to keep track of the no. of parallel edges in each direction */ ULONGINT_T** tmpEdgeCounter = (ULONGINT_T**)P_MALLOC(MAX_CLIQUE_SIZE * sizeof(ULONGINT_T *)); assert(tmpEdgeCounter); for (i = 0; i < MAX_CLIQUE_SIZE; i++) { tmpEdgeCounter[i] = (ULONGINT_T*)P_MALLOC(MAX_CLIQUE_SIZE * sizeof(ULONGINT_T)); assert(tmpEdgeCounter[i]); } /* * Create edges in parallel */ long i_clique; createPartition(0, totCliques, myId, numThread, &i_start, &i_stop); for (i_clique = i_start; i_clique < i_stop; i_clique++) { /* * Get current clique parameters */ long i_cliqueSize = cliqueSizes[i_clique]; long i_firstVsInClique = firstVsInCliques[i_clique]; /* * First create at least one edge between two vetices in a clique */ for (i = 0; i < i_cliqueSize; i++) { long j; for (j = 0; j < i; j++) { float r = (float)(PRANDOM_GENERATE(stream) % 1000) / (float)1000; if (r >= p) { startV[i_edgePtr] = i + i_firstVsInClique; endV[i_edgePtr] = j + i_firstVsInClique; i_edgePtr++; tmpEdgeCounter[i][j] = 1; startV[i_edgePtr] = j + i_firstVsInClique; endV[i_edgePtr] = i + i_firstVsInClique; i_edgePtr++; tmpEdgeCounter[j][i] = 1; } else if (r >= 0.5) { startV[i_edgePtr] = i + i_firstVsInClique; endV[i_edgePtr] = j + i_firstVsInClique; i_edgePtr++; tmpEdgeCounter[i][j] = 1; tmpEdgeCounter[j][i] = 0; } else { startV[i_edgePtr] = j + i_firstVsInClique; endV[i_edgePtr] = i + i_firstVsInClique; i_edgePtr++; tmpEdgeCounter[j][i] = 1; tmpEdgeCounter[i][j] = 0; } } /* for j */ } /* for i */ if (i_cliqueSize != 1) { long randNumEdges = (long)(PRANDOM_GENERATE(stream) % (2*i_cliqueSize*MAX_PARAL_EDGES)); long i_paralEdge; for (i_paralEdge = 0; i_paralEdge < randNumEdges; i_paralEdge++) { i = (PRANDOM_GENERATE(stream) % i_cliqueSize); long j = (PRANDOM_GENERATE(stream) % i_cliqueSize); if ((i != j) && (tmpEdgeCounter[i][j] < MAX_PARAL_EDGES)) { float r = (float)(PRANDOM_GENERATE(stream) % 1000) / (float)1000; if (r >= p) { /* Copy to edge structure. */ startV[i_edgePtr] = i + i_firstVsInClique; endV[i_edgePtr] = j + i_firstVsInClique; i_edgePtr++; tmpEdgeCounter[i][j]++; } } } } } /* for i_clique */ for (i = 0; i < MAX_CLIQUE_SIZE; i++) { P_FREE(tmpEdgeCounter[i]); } P_FREE(tmpEdgeCounter); /* * Merge partial edge lists */ ULONGINT_T* i_edgeStartCounter; ULONGINT_T* i_edgeEndCounter; if (myId == 0) { i_edgeStartCounter = (ULONGINT_T*)P_MALLOC(numThread * sizeof(ULONGINT_T)); assert(i_edgeStartCounter); global_i_edgeStartCounter = i_edgeStartCounter; i_edgeEndCounter = (ULONGINT_T*)P_MALLOC(numThread * sizeof(ULONGINT_T)); assert(i_edgeEndCounter); global_i_edgeEndCounter = i_edgeEndCounter; } thread_barrier_wait(); i_edgeStartCounter = global_i_edgeStartCounter; i_edgeEndCounter = global_i_edgeEndCounter; i_edgeEndCounter[myId] = i_edgePtr; i_edgeStartCounter[myId] = 0; thread_barrier_wait(); if (myId == 0) { for (i = 1; i < numThread; i++) { i_edgeEndCounter[i] = i_edgeEndCounter[i-1] + i_edgeEndCounter[i]; i_edgeStartCounter[i] = i_edgeEndCounter[i-1]; } } AL_LOCK(0); TM_BEGIN(); TM_SHARED_WRITE(global_edgeNum, ((long)TM_SHARED_READ(global_edgeNum) + i_edgePtr)); TM_END(); thread_barrier_wait(); long edgeNum = global_edgeNum; /* * Initialize edge list arrays */ ULONGINT_T* startVertex; ULONGINT_T* endVertex; if (myId == 0) { if (SCALE < 10) { long numByte = 2 * edgeNum * sizeof(ULONGINT_T); startVertex = (ULONGINT_T*)P_MALLOC(numByte); endVertex = (ULONGINT_T*)P_MALLOC(numByte); } else { long numByte = (edgeNum + MAX_PARAL_EDGES * TOT_VERTICES) * sizeof(ULONGINT_T); startVertex = (ULONGINT_T*)P_MALLOC(numByte); endVertex = (ULONGINT_T*)P_MALLOC(numByte); } assert(startVertex); assert(endVertex); global_startVertex = startVertex; global_endVertex = endVertex; } thread_barrier_wait(); startVertex = global_startVertex; endVertex = global_endVertex; for (i = i_edgeStartCounter[myId]; i < i_edgeEndCounter[myId]; i++) { startVertex[i] = startV[i-i_edgeStartCounter[myId]]; endVertex[i] = endV[i-i_edgeStartCounter[myId]]; } ULONGINT_T numEdgesPlacedInCliques = edgeNum; thread_barrier_wait(); /* * STEP 3: Connect the cliques */ i_edgePtr = 0; p = PROB_INTERCL_EDGES; /* * Generating inter-clique edges as given in the specs */ createPartition(0, TOT_VERTICES, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { ULONGINT_T tempVertex1 = i; long h = totCliques; long l = 0; long t = -1; while (h - l > 1) { long m = (h + l) / 2; if (tempVertex1 >= firstVsInCliques[m]) { l = m; } else { if ((tempVertex1 < firstVsInCliques[m]) && (m > 0)) { if (tempVertex1 >= firstVsInCliques[m-1]) { t = m - 1; break; } else { h = m; } } } } if (t == -1) { long m; for (m = (l + 1); m < h; m++) { if (tempVertex1<firstVsInCliques[m]) { break; } } t = m-1; } long t1 = firstVsInCliques[t]; ULONGINT_T d; for (d = 1, p = PROB_INTERCL_EDGES; d < TOT_VERTICES; d *= 2, p /= 2) { float r = (float)(PRANDOM_GENERATE(stream) % 1000) / (float)1000; if (r <= p) { ULONGINT_T tempVertex2 = (i+d) % TOT_VERTICES; h = totCliques; l = 0; t = -1; while (h - l > 1) { long m = (h + l) / 2; if (tempVertex2 >= firstVsInCliques[m]) { l = m; } else { if ((tempVertex2 < firstVsInCliques[m]) && (m > 0)) { if (firstVsInCliques[m-1] <= tempVertex2) { t = m - 1; break; } else { h = m; } } } } if (t == -1) { long m; for (m = (l + 1); m < h; m++) { if (tempVertex2 < firstVsInCliques[m]) { break; } } t = m - 1; } long t2 = firstVsInCliques[t]; if (t1 != t2) { long randNumEdges = PRANDOM_GENERATE(stream) % MAX_PARAL_EDGES + 1; long j; for (j = 0; j < randNumEdges; j++) { startV[i_edgePtr] = tempVertex1; endV[i_edgePtr] = tempVertex2; i_edgePtr++; } } } /* r <= p */ float r0 = (float)(PRANDOM_GENERATE(stream) % 1000) / (float)1000; if ((r0 <= p) && (i-d>=0)) { ULONGINT_T tempVertex2 = (i-d) % TOT_VERTICES; h = totCliques; l = 0; t = -1; while (h - l > 1) { long m = (h + l) / 2; if (tempVertex2 >= firstVsInCliques[m]) { l = m; } else { if ((tempVertex2 < firstVsInCliques[m]) && (m > 0)) { if (firstVsInCliques[m-1] <= tempVertex2) { t = m - 1; break; } else { h = m; } } } } if (t == -1) { long m; for (m = (l + 1); m < h; m++) { if (tempVertex2 < firstVsInCliques[m]) { break; } } t = m - 1; } long t2 = firstVsInCliques[t]; if (t1 != t2) { long randNumEdges = PRANDOM_GENERATE(stream) % MAX_PARAL_EDGES + 1; long j; for (j = 0; j < randNumEdges; j++) { startV[i_edgePtr] = tempVertex1; endV[i_edgePtr] = tempVertex2; i_edgePtr++; } } } /* r0 <= p && (i-d) > 0 */ } /* for d, p */ } /* for i */ i_edgeEndCounter[myId] = i_edgePtr; i_edgeStartCounter[myId] = 0; if (myId == 0) { global_edgeNum = 0; } thread_barrier_wait(); if (myId == 0) { for (i = 1; i < numThread; i++) { i_edgeEndCounter[i] = i_edgeEndCounter[i-1] + i_edgeEndCounter[i]; i_edgeStartCounter[i] = i_edgeEndCounter[i-1]; } } AL_LOCK(0); TM_BEGIN(); TM_SHARED_WRITE(global_edgeNum, ((long)TM_SHARED_READ(global_edgeNum) + i_edgePtr)); TM_END(); thread_barrier_wait(); edgeNum = global_edgeNum; ULONGINT_T numEdgesPlacedOutside = global_edgeNum; for (i = i_edgeStartCounter[myId]; i < i_edgeEndCounter[myId]; i++) { startVertex[i+numEdgesPlacedInCliques] = startV[i-i_edgeStartCounter[myId]]; endVertex[i+numEdgesPlacedInCliques] = endV[i-i_edgeStartCounter[myId]]; } thread_barrier_wait(); ULONGINT_T numEdgesPlaced = numEdgesPlacedInCliques + numEdgesPlacedOutside; if (myId == 0) { SDGdataPtr->numEdgesPlaced = numEdgesPlaced; printf("Finished generating edges\n"); printf("No. of intra-clique edges - %lu\n", numEdgesPlacedInCliques); printf("No. of inter-clique edges - %lu\n", numEdgesPlacedOutside); printf("Total no. of edges - %lu\n", numEdgesPlaced); P_FREE(i_edgeStartCounter); P_FREE(i_edgeEndCounter); P_FREE(cliqueSizes); P_FREE(firstVsInCliques); P_FREE(lastVsInCliques); } thread_barrier_wait(); P_FREE(startV); P_FREE(endV); /* * STEP 4: Generate edge weights */ if (myId == 0) { SDGdataPtr->intWeight = (LONGINT_T*)P_MALLOC(numEdgesPlaced * sizeof(LONGINT_T)); assert(SDGdataPtr->intWeight); } thread_barrier_wait(); p = PERC_INT_WEIGHTS; ULONGINT_T numStrWtEdges = 0; createPartition(0, numEdgesPlaced, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { float r = (float)(PRANDOM_GENERATE(stream) % 1000) / (float)1000; if (r <= p) { SDGdataPtr->intWeight[i] = 1 + (PRANDOM_GENERATE(stream) % (MAX_INT_WEIGHT-1)); } else { SDGdataPtr->intWeight[i] = -1; numStrWtEdges++; } } thread_barrier_wait(); if (myId == 0) { long t = 0; for (i = 0; i < numEdgesPlaced; i++) { if (SDGdataPtr->intWeight[i] < 0) { SDGdataPtr->intWeight[i] = -t; t++; } } } AL_LOCK(0); TM_BEGIN(); TM_SHARED_WRITE(global_numStrWtEdges, ((long)TM_SHARED_READ(global_numStrWtEdges) + numStrWtEdges)); TM_END(); thread_barrier_wait(); numStrWtEdges = global_numStrWtEdges; if (myId == 0) { SDGdataPtr->strWeight = (char*)P_MALLOC(numStrWtEdges * MAX_STRLEN * sizeof(char)); assert(SDGdataPtr->strWeight); } thread_barrier_wait(); createPartition(0, numEdgesPlaced, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { if (SDGdataPtr->intWeight[i] <= 0) { long j; for (j = 0; j < MAX_STRLEN; j++) { SDGdataPtr->strWeight[(-SDGdataPtr->intWeight[i])*MAX_STRLEN+j] = (char) (1 + PRANDOM_GENERATE(stream) % 127); } } } /* * Choose SOUGHT STRING randomly if not assigned */ if (myId == 0) { if (strlen(SOUGHT_STRING) != MAX_STRLEN) { SOUGHT_STRING = (char*)P_MALLOC(MAX_STRLEN * sizeof(char)); assert(SOUGHT_STRING); } long t = PRANDOM_GENERATE(stream) % numStrWtEdges; long j; for (j = 0; j < MAX_STRLEN; j++) { SOUGHT_STRING[j] = (char) ((long) SDGdataPtr->strWeight[t*MAX_STRLEN+j]); } } thread_barrier_wait(); /* * STEP 5: Permute Vertices */ for (i = i_start; i < i_stop; i++) { startVertex[i] = permV[(startVertex[i])]; endVertex[i] = permV[(endVertex[i])]; } thread_barrier_wait(); /* * STEP 6: Sort Vertices */ /* * Radix sort with StartVertex as primary key */ if (myId == 0) { long numByte = numEdgesPlaced * sizeof(ULONGINT_T); SDGdataPtr->startVertex = (ULONGINT_T*)P_MALLOC(numByte); assert(SDGdataPtr->startVertex); SDGdataPtr->endVertex = (ULONGINT_T*)P_MALLOC(numByte); assert(SDGdataPtr->endVertex); } thread_barrier_wait(); all_radixsort_node_aux_s3(numEdgesPlaced, startVertex, SDGdataPtr->startVertex, endVertex, SDGdataPtr->endVertex); thread_barrier_wait(); if (myId == 0) { P_FREE(startVertex); P_FREE(endVertex); } thread_barrier_wait(); if (SCALE < 12) { /* * Sort with endVertex as secondary key */ if (myId == 0) { long i0 = 0; long i1 = 0; i = 0; while (i < numEdgesPlaced) { for (i = i0; i < numEdgesPlaced; i++) { if (SDGdataPtr->startVertex[i] != SDGdataPtr->startVertex[i1]) { i1 = i; break; } } long j; for (j = i0; j < i1; j++) { long k; for (k = j+1; k < i1; k++) { if (SDGdataPtr->endVertex[k] < SDGdataPtr->endVertex[j]) { long t = SDGdataPtr->endVertex[j]; SDGdataPtr->endVertex[j] = SDGdataPtr->endVertex[k]; SDGdataPtr->endVertex[k] = t; } } } if (SDGdataPtr->startVertex[i0] != TOT_VERTICES-1) { i0 = i1; } else { long j; for (j=i0; j<numEdgesPlaced; j++) { long k; for (k=j+1; k<numEdgesPlaced; k++) { if (SDGdataPtr->endVertex[k] < SDGdataPtr->endVertex[j]) { long t = SDGdataPtr->endVertex[j]; SDGdataPtr->endVertex[j] = SDGdataPtr->endVertex[k]; SDGdataPtr->endVertex[k] = t; } } } } } /* while i < numEdgesPlaced */ } } else { ULONGINT_T* tempIndex; if (myId == 0) { tempIndex = (ULONGINT_T*)P_MALLOC((TOT_VERTICES + 1) * sizeof(ULONGINT_T)); assert(tempIndex); global_tempIndex = tempIndex; /* * Update degree of each vertex */ tempIndex[0] = 0; tempIndex[TOT_VERTICES] = numEdgesPlaced; long i0 = 0; for (i=0; i < TOT_VERTICES; i++) { tempIndex[i+1] = tempIndex[i]; long j; for (j = i0; j < numEdgesPlaced; j++) { if (SDGdataPtr->startVertex[j] != SDGdataPtr->startVertex[i0]) { if (SDGdataPtr->startVertex[i0] == i) { tempIndex[i+1] = j; i0 = j; break; } } } } } thread_barrier_wait(); tempIndex = global_tempIndex; /* * Insertion sort for now, replace with something better later on */ #if 0 createPartition(0, TOT_VERTICES, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { long j; for (j = tempIndex[i]; j < tempIndex[i+1]; j++) { long k; for (k = (j + 1); k < tempIndex[i+1]; k++) { if (SDGdataPtr->endVertex[k] < SDGdataPtr->endVertex[j]) { long t = SDGdataPtr->endVertex[j]; SDGdataPtr->endVertex[j] = SDGdataPtr->endVertex[k]; SDGdataPtr->endVertex[k] = t; } } } } #else if (myId == 0) { for (i = 0; i < TOT_VERTICES; i++) { long j; for (j = tempIndex[i]; j < tempIndex[i+1]; j++) { long k; for (k = (j + 1); k < tempIndex[i+1]; k++) { if (SDGdataPtr->endVertex[k] < SDGdataPtr->endVertex[j]) { long t = SDGdataPtr->endVertex[j]; SDGdataPtr->endVertex[j] = SDGdataPtr->endVertex[k]; SDGdataPtr->endVertex[k] = t; } } } } } #endif if (myId == 0) { P_FREE(tempIndex); } } /* SCALE >= 12 */ PRANDOM_FREE(stream); if (myId == 0) { P_FREE(permV); } TM_THREAD_EXIT(); }
/* ============================================================================= * findSubGraphs1 * ============================================================================= */ void findSubGraphs1 (void* argPtr) { graph* GPtr = ((findSubGraphs1_arg_t*)argPtr)->GPtr; Vl** intWtVLList = ((findSubGraphs1_arg_t*)argPtr)->intWtVLList; Vl** strWtVLList = ((findSubGraphs1_arg_t*)argPtr)->strWtVLList; edge* maxIntWtList = ((findSubGraphs1_arg_t*)argPtr)->maxIntWtList; long maxIntWtListSize = ((findSubGraphs1_arg_t*)argPtr)->maxIntWtListSize; edge* soughtStrWtList = ((findSubGraphs1_arg_t*)argPtr)->soughtStrWtList; long soughtStrWtListSize = ((findSubGraphs1_arg_t*)argPtr)->soughtStrWtListSize; long myId = thread_getId(); long numThread = thread_getNumThread(); char* visited = (char*)P_MALLOC(GPtr->numVertices * sizeof(char)); assert(visited); long i; long i_start; long i_stop; createPartition(0, (maxIntWtListSize + soughtStrWtListSize), myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { unsigned long k; for (k = 0; k < GPtr->numVertices; k++) { visited[k] = 'u'; } if (i < maxIntWtListSize) { intWtVLList[i] = (Vl*)P_MALLOC(sizeof(Vl)); assert(intWtVLList[i]); (intWtVLList[i])->num = maxIntWtList[i].startVertex; (intWtVLList[i])->depth = 0; visited[(intWtVLList[i])->num] = 'v'; (intWtVLList[i])->next = (Vl*)P_MALLOC(sizeof(Vl)); P_FREE((intWtVLList[i])->next); ((intWtVLList[i])->next)->num = maxIntWtList[i].endVertex; ((intWtVLList[i])->next)->depth = 1; visited[((intWtVLList[i])->next)->num] = 'v'; Vl* currV = (intWtVLList[i])->next; Vl* startV = (intWtVLList[i])->next; long depth = 1; long verticesVisited = 2; long currIndex = 1; while ((startV->depth < SUBGR_EDGE_LENGTH) || (verticesVisited == (long)GPtr->numVertices)) { depth = startV->depth + 1; long j; long j_start = GPtr->outVertexIndex[startV->num]; long j_stop = j_start + GPtr->outDegree[startV->num]; for (j = j_start; j < j_stop; j++) { if (visited[GPtr->outVertexList[j]] == 'u') { visited[GPtr->outVertexList[j]] = 'v'; currV->next = (Vl*)P_MALLOC(sizeof(Vl)); assert(currV->next); (currV->next)->num = GPtr->outVertexList[j]; (currV->next)->depth = depth; verticesVisited++; currV = currV->next; } } if ((currIndex < verticesVisited - 1) && (verticesVisited < (long)GPtr->numVertices)) { currIndex++; startV = startV->next; } else { break; } } currV->next = NULL; } else { long t = i - maxIntWtListSize; strWtVLList[t] = (Vl*)P_MALLOC(sizeof(Vl)); assert(strWtVLList[t]); (strWtVLList[t])->num = soughtStrWtList[t].startVertex; (strWtVLList[t])->depth = 0; visited[(strWtVLList[t])->num] = 'v'; (strWtVLList[t])->next = (Vl*)P_MALLOC(sizeof(Vl)); assert((strWtVLList[t])->next); ((strWtVLList[t])->next)->num = soughtStrWtList[t].endVertex; ((strWtVLList[t])->next)->depth = 1; visited[((strWtVLList[t])->next)->num] = 'v'; Vl* currV = (strWtVLList[t])->next; Vl* startV = (strWtVLList[t])->next; long depth = 1; long verticesVisited = 2; long currIndex = 1; while ((startV->depth < SUBGR_EDGE_LENGTH) || (verticesVisited == (long)GPtr->numVertices)) { depth = startV->depth + 1; long j; long j_start = GPtr->outVertexIndex[startV->num]; long j_stop = j_start + GPtr->outDegree[startV->num]; for (j = j_start; j < j_stop; j++) { if (visited[GPtr->outVertexList[j]] == 'u') { visited[GPtr->outVertexList[j]] = 'v'; currV->next = (Vl*)P_MALLOC(sizeof(Vl)); assert(currV->next); (currV->next)->num = GPtr->outVertexList[j]; (currV->next)->depth = depth; verticesVisited++; currV = currV->next; } } if ((currIndex < verticesVisited - 1) && (verticesVisited < (long)GPtr->numVertices)) { currIndex++; startV = startV->next; } else { break; } } currV->next = NULL; } } /* for i */ P_FREE(visited); }
/* ============================================================================= * computeGraph * ============================================================================= */ void computeGraph (void* argPtr) { TM_THREAD_ENTER(); graph* GPtr = ((computeGraph_arg_t*)argPtr)->GPtr; graphSDG* SDGdataPtr = ((computeGraph_arg_t*)argPtr)->SDGdataPtr; long myId = thread_getId(); long numThread = thread_getNumThread(); ULONGINT_T j; ULONGINT_T maxNumVertices = 0; ULONGINT_T numEdgesPlaced = SDGdataPtr->numEdgesPlaced; /* * First determine the number of vertices by scanning the tuple * startVertex list */ long i; long i_start; long i_stop; createPartition(0, numEdgesPlaced, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { if (SDGdataPtr->startVertex[i] > maxNumVertices) { maxNumVertices = SDGdataPtr->startVertex[i]; } } TM_BEGIN(); long tmp_maxNumVertices = (long)TM_SHARED_READ_L(global_maxNumVertices); long new_maxNumVertices = MAX(tmp_maxNumVertices, maxNumVertices) + 1; TM_SHARED_WRITE_L(global_maxNumVertices, new_maxNumVertices); TM_END(); thread_barrier_wait(); maxNumVertices = global_maxNumVertices; if (myId == 0) { GPtr->numVertices = maxNumVertices; GPtr->numEdges = numEdgesPlaced; GPtr->intWeight = SDGdataPtr->intWeight; GPtr->strWeight = SDGdataPtr->strWeight; for (i = 0; i < numEdgesPlaced; i++) { if (GPtr->intWeight[numEdgesPlaced-i-1] < 0) { GPtr->numStrEdges = -(GPtr->intWeight[numEdgesPlaced-i-1]) + 1; GPtr->numIntEdges = numEdgesPlaced - GPtr->numStrEdges; break; } } GPtr->outDegree = (LONGINT_T*)P_MALLOC((GPtr->numVertices) * sizeof(LONGINT_T)); assert(GPtr->outDegree); GPtr->outVertexIndex = (ULONGINT_T*)P_MALLOC((GPtr->numVertices) * sizeof(ULONGINT_T)); assert(GPtr->outVertexIndex); } thread_barrier_wait(); createPartition(0, GPtr->numVertices, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { GPtr->outDegree[i] = 0; GPtr->outVertexIndex[i] = 0; } ULONGINT_T outVertexListSize = 0; thread_barrier_wait(); ULONGINT_T i0 = -1UL; for (i = i_start; i < i_stop; i++) { ULONGINT_T k = i; if ((outVertexListSize == 0) && (k != 0)) { while (i0 == -1UL) { for (j = 0; j < numEdgesPlaced; j++) { if (k == SDGdataPtr->startVertex[j]) { i0 = j; break; } } k--; } } if ((outVertexListSize == 0) && (k == 0)) { i0 = 0; } for (j = i0; j < numEdgesPlaced; j++) { if (i == GPtr->numVertices-1) { break; } if ((i != SDGdataPtr->startVertex[j])) { if ((j > 0) && (i == SDGdataPtr->startVertex[j-1])) { if (j-i0 >= 1) { outVertexListSize++; GPtr->outDegree[i]++; ULONGINT_T t; for (t = i0+1; t < j; t++) { if (SDGdataPtr->endVertex[t] != SDGdataPtr->endVertex[t-1]) { outVertexListSize++; GPtr->outDegree[i] = GPtr->outDegree[i]+1; } } } } i0 = j; break; } } if (i == GPtr->numVertices-1) { if (numEdgesPlaced-i0 >= 0) { outVertexListSize++; GPtr->outDegree[i]++; ULONGINT_T t; for (t = i0+1; t < numEdgesPlaced; t++) { if (SDGdataPtr->endVertex[t] != SDGdataPtr->endVertex[t-1]) { outVertexListSize++; GPtr->outDegree[i]++; } } } } } /* for i */ thread_barrier_wait(); prefix_sums(GPtr->outVertexIndex, GPtr->outDegree, GPtr->numVertices); thread_barrier_wait(); TM_BEGIN(); TM_SHARED_WRITE_L( global_outVertexListSize, ((long)TM_SHARED_READ_L(global_outVertexListSize) + outVertexListSize) ); TM_END(); thread_barrier_wait(); outVertexListSize = global_outVertexListSize; if (myId == 0) { GPtr->numDirectedEdges = outVertexListSize; GPtr->outVertexList = (ULONGINT_T*)P_MALLOC(outVertexListSize * sizeof(ULONGINT_T)); assert(GPtr->outVertexList); GPtr->paralEdgeIndex = (ULONGINT_T*)P_MALLOC(outVertexListSize * sizeof(ULONGINT_T)); assert(GPtr->paralEdgeIndex); GPtr->outVertexList[0] = SDGdataPtr->endVertex[0]; } thread_barrier_wait(); /* * Evaluate outVertexList */ i0 = -1UL; for (i = i_start; i < i_stop; i++) { ULONGINT_T k = i; while ((i0 == -1UL) && (k != 0)) { for (j = 0; j < numEdgesPlaced; j++) { if (k == SDGdataPtr->startVertex[j]) { i0 = j; break; } } k--; } if ((i0 == -1) && (k == 0)) { i0 = 0; } for (j = i0; j < numEdgesPlaced; j++) { if (i == GPtr->numVertices-1) { break; } if (i != SDGdataPtr->startVertex[j]) { if ((j > 0) && (i == SDGdataPtr->startVertex[j-1])) { if (j-i0 >= 1) { long ii = GPtr->outVertexIndex[i]; ULONGINT_T r = 0; GPtr->paralEdgeIndex[ii] = i0; GPtr->outVertexList[ii] = SDGdataPtr->endVertex[i0]; r++; ULONGINT_T t; for (t = i0+1; t < j; t++) { if (SDGdataPtr->endVertex[t] != SDGdataPtr->endVertex[t-1]) { GPtr->paralEdgeIndex[ii+r] = t; GPtr->outVertexList[ii+r] = SDGdataPtr->endVertex[t]; r++; } } } } i0 = j; break; } } /* for j */ if (i == GPtr->numVertices-1) { ULONGINT_T r = 0; if (numEdgesPlaced-i0 >= 0) { long ii = GPtr->outVertexIndex[i]; GPtr->paralEdgeIndex[ii+r] = i0; GPtr->outVertexList[ii+r] = SDGdataPtr->endVertex[i0]; r++; ULONGINT_T t; for (t = i0+1; t < numEdgesPlaced; t++) { if (SDGdataPtr->endVertex[t] != SDGdataPtr->endVertex[t-1]) { GPtr->paralEdgeIndex[ii+r] = t; GPtr->outVertexList[ii+r] = SDGdataPtr->endVertex[t]; r++; } } } } } /* for i */ thread_barrier_wait(); if (myId == 0) { P_FREE(SDGdataPtr->startVertex); P_FREE(SDGdataPtr->endVertex); GPtr->inDegree = (LONGINT_T*)P_MALLOC(GPtr->numVertices * sizeof(LONGINT_T)); assert(GPtr->inDegree); GPtr->inVertexIndex = (ULONGINT_T*)P_MALLOC(GPtr->numVertices * sizeof(ULONGINT_T)); assert(GPtr->inVertexIndex); } thread_barrier_wait(); for (i = i_start; i < i_stop; i++) { GPtr->inDegree[i] = 0; GPtr->inVertexIndex[i] = 0; } /* A temp. array to store the inplied edges */ ULONGINT_T* impliedEdgeList; if (myId == 0) { impliedEdgeList = (ULONGINT_T*)P_MALLOC(GPtr->numVertices * MAX_CLUSTER_SIZE * sizeof(ULONGINT_T)); global_impliedEdgeList = impliedEdgeList; } thread_barrier_wait(); impliedEdgeList = global_impliedEdgeList; createPartition(0, (GPtr->numVertices * MAX_CLUSTER_SIZE), myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { impliedEdgeList[i] = 0; } /* * An auxiliary array to store implied edges, in case we overshoot * MAX_CLUSTER_SIZE */ ULONGINT_T** auxArr; if (myId == 0) { auxArr = (ULONGINT_T**)P_MALLOC(GPtr->numVertices * sizeof(ULONGINT_T*)); assert(auxArr); global_auxArr = auxArr; } thread_barrier_wait(); auxArr = global_auxArr; createPartition(0, GPtr->numVertices, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { /* Inspect adjacency list of vertex i */ for (j = GPtr->outVertexIndex[i]; j < (GPtr->outVertexIndex[i] + GPtr->outDegree[i]); j++) { ULONGINT_T v = GPtr->outVertexList[j]; ULONGINT_T k; for (k = GPtr->outVertexIndex[v]; k < (GPtr->outVertexIndex[v] + GPtr->outDegree[v]); k++) { if (GPtr->outVertexList[k] == i) { break; } } if (k == GPtr->outVertexIndex[v]+GPtr->outDegree[v]) { TM_BEGIN(); /* Add i to the impliedEdgeList of v */ long inDegree = (long)TM_SHARED_READ_L(GPtr->inDegree[v]); TM_SHARED_WRITE_L(GPtr->inDegree[v], (inDegree + 1)); if (inDegree < MAX_CLUSTER_SIZE) { TM_SHARED_WRITE_L(impliedEdgeList[v*MAX_CLUSTER_SIZE+inDegree], i); } else { /* Use auxiliary array to store the implied edge */ /* Create an array if it's not present already */ ULONGINT_T* a = NULL; if ((inDegree % MAX_CLUSTER_SIZE) == 0) { a = (ULONGINT_T*)TM_MALLOC(MAX_CLUSTER_SIZE * sizeof(ULONGINT_T)); assert(a); TM_SHARED_WRITE_P(auxArr[v], a); } else { a = auxArr[v]; } TM_SHARED_WRITE_L(a[inDegree % MAX_CLUSTER_SIZE], i); } TM_END(); } } } /* for i */ thread_barrier_wait(); prefix_sums(GPtr->inVertexIndex, GPtr->inDegree, GPtr->numVertices); if (myId == 0) { GPtr->numUndirectedEdges = GPtr->inVertexIndex[GPtr->numVertices-1] + GPtr->inDegree[GPtr->numVertices-1]; GPtr->inVertexList = (ULONGINT_T *)P_MALLOC(GPtr->numUndirectedEdges * sizeof(ULONGINT_T)); } thread_barrier_wait(); /* * Create the inVertex List */ for (i = i_start; i < i_stop; i++) { for (j = GPtr->inVertexIndex[i]; j < (GPtr->inVertexIndex[i] + GPtr->inDegree[i]); j++) { if ((j - GPtr->inVertexIndex[i]) < MAX_CLUSTER_SIZE) { GPtr->inVertexList[j] = impliedEdgeList[i*MAX_CLUSTER_SIZE+j-GPtr->inVertexIndex[i]]; } else { GPtr->inVertexList[j] = auxArr[i][(j-GPtr->inVertexIndex[i]) % MAX_CLUSTER_SIZE]; } } } thread_barrier_wait(); if (myId == 0) { P_FREE(impliedEdgeList); } for (i = i_start; i < i_stop; i++) { if (GPtr->inDegree[i] > MAX_CLUSTER_SIZE) { P_FREE(auxArr[i]); } } thread_barrier_wait(); if (myId == 0) { P_FREE(auxArr); } TM_THREAD_EXIT(); }
/* ============================================================================= * Pelement_free * ============================================================================= */ void Pelement_free (element_t* elementPtr) { PLIST_FREE(elementPtr->neighborListPtr); P_FREE(elementPtr); }
/* ============================================================================= * Prandom_free * ============================================================================= */ void Prandom_free (random_t* randomPtr) { P_FREE(randomPtr); }
/* ============================================================================= * Plist_free * ============================================================================= */ void list_stm_v2::Plist_free (list_t* listPtr) { PfreeList(listPtr->head.nextPtr); P_FREE(listPtr); }
/* ============================================================================= * processPackets * ============================================================================= */ void processPackets (void* argPtr) { TM_THREAD_ENTER(); long threadId = thread_getId(); stream_t* streamPtr = ((arg_t*)argPtr)->streamPtr; decoder_t* decoderPtr = ((arg_t*)argPtr)->decoderPtr; vector_t** errorVectors = ((arg_t*)argPtr)->errorVectors; detector_t* detectorPtr = PDETECTOR_ALLOC(); assert(detectorPtr); PDETECTOR_ADDPREPROCESSOR(detectorPtr, &preprocessor_toLower); vector_t* errorVectorPtr = errorVectors[threadId]; while (1) { char* bytes; unsigned int locks[1]; TM_BEGIN(); SINGLE_LOCK(streamPtr); bytes = TMSTREAM_GETPACKET(streamPtr); SINGLE_UNLOCK(streamPtr); TM_END(); if (!bytes) { break; } packet_t* packetPtr = (packet_t*)bytes; long flowId = packetPtr->flowId; error_t error; TM_BEGIN(); error = TMDECODER_PROCESS(decoderPtr, bytes, (PACKET_HEADER_LENGTH + packetPtr->length)); TM_END(); if (error) { /* * Currently, stream_generate() does not create these errors. */ assert(0); bool_t status = PVECTOR_PUSHBACK(errorVectorPtr, (void*)flowId); assert(status); } char* data; long decodedFlowId; TM_BEGIN(); SINGLE_LOCK(decoderPtr); data = TMDECODER_GETCOMPLETE(decoderPtr, &decodedFlowId); SINGLE_UNLOCK(decoderPtr); TM_END(); if (data) { error_t error = PDETECTOR_PROCESS(detectorPtr, data); P_FREE(data); if (error) { bool_t status = PVECTOR_PUSHBACK(errorVectorPtr, (void*)decodedFlowId); assert(status); } } } PDETECTOR_FREE(detectorPtr); TM_THREAD_EXIT(); }
/* ============================================================================= * getStartLists * ============================================================================= */ void getStartLists (void* argPtr) { TM_THREAD_ENTER(); graph* GPtr = ((getStartLists_arg_t*)argPtr)->GPtr; edge** maxIntWtListPtr = ((getStartLists_arg_t*)argPtr)->maxIntWtListPtr; long* maxIntWtListSize = ((getStartLists_arg_t*)argPtr)->maxIntWtListSize; edge** soughtStrWtListPtr = ((getStartLists_arg_t*)argPtr)->soughtStrWtListPtr; long* soughtStrWtListSize = ((getStartLists_arg_t*)argPtr)->soughtStrWtListSize; long myId = thread_getId(); long numThread = thread_getNumThread(); /* * Find Max Wt on each thread */ LONGINT_T maxWeight = 0; long i; long i_start; long i_stop; createPartition(0, GPtr->numEdges, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { if (GPtr->intWeight[i] > maxWeight) { maxWeight = GPtr->intWeight[i]; } } AL_LOCK(0); TM_BEGIN(9); long tmp_maxWeight = (long)TM_SHARED_READ(global_maxWeight); if (maxWeight > tmp_maxWeight) { TM_SHARED_WRITE(global_maxWeight, maxWeight); } TM_END(); thread_barrier_wait(); maxWeight = global_maxWeight; /* * Create partial lists */ /* * Allocate mem. for temp edge list for each thread */ long numTmpEdge = (5+ceil(1.5*(GPtr->numIntEdges)/MAX_INT_WEIGHT)); edge* tmpEdgeList = (edge*)P_MALLOC(numTmpEdge * sizeof(edge)); long i_edgeCounter = 0; for (i = i_start; i < i_stop; i++) { if (GPtr->intWeight[i] == maxWeight) { /* Find the corresponding endVertex */ long j; for (j = 0; j < GPtr->numDirectedEdges; j++) { if (GPtr->paralEdgeIndex[j] > i) { break; } } tmpEdgeList[i_edgeCounter].endVertex = GPtr->outVertexList[j-1]; tmpEdgeList[i_edgeCounter].edgeNum = j-1; long t; for (t = 0; t < GPtr->numVertices; t++) { if (GPtr->outVertexIndex[t] > j-1) { break; } } tmpEdgeList[i_edgeCounter].startVertex = t-1; i_edgeCounter++; } } /* * Merge partial edge lists */ long* i_edgeStartCounter; long* i_edgeEndCounter; if (myId == 0) { i_edgeStartCounter = (long*)P_MALLOC(numThread * sizeof(long)); assert(i_edgeStartCounter); global_i_edgeStartCounter = i_edgeStartCounter; i_edgeEndCounter = (long*)P_MALLOC(numThread * sizeof(long)); assert(i_edgeEndCounter); global_i_edgeEndCounter = i_edgeEndCounter; *maxIntWtListSize = 0; } thread_barrier_wait(); i_edgeStartCounter = global_i_edgeStartCounter; i_edgeEndCounter = global_i_edgeEndCounter; i_edgeEndCounter[myId] = i_edgeCounter; i_edgeStartCounter[myId] = 0; thread_barrier_wait(); if (myId == 0) { for (i = 1; i < numThread; i++) { i_edgeEndCounter[i] = i_edgeEndCounter[i-1] + i_edgeEndCounter[i]; i_edgeStartCounter[i] = i_edgeEndCounter[i-1]; } } *maxIntWtListSize += i_edgeCounter; thread_barrier_wait(); edge* maxIntWtList; if (myId == 0) { P_FREE(*maxIntWtListPtr); maxIntWtList = (edge*)P_MALLOC((*maxIntWtListSize) * sizeof(edge)); assert(maxIntWtList); global_maxIntWtList = maxIntWtList; } thread_barrier_wait(); maxIntWtList = global_maxIntWtList; for (i = i_edgeStartCounter[myId]; i<i_edgeEndCounter[myId]; i++) { (maxIntWtList[i]).startVertex = tmpEdgeList[i-i_edgeStartCounter[myId]].startVertex; (maxIntWtList[i]).endVertex = tmpEdgeList[i-i_edgeStartCounter[myId]].endVertex; (maxIntWtList[i]).edgeNum = tmpEdgeList[i-i_edgeStartCounter[myId]].edgeNum; } if (myId == 0) { *maxIntWtListPtr = maxIntWtList; } i_edgeCounter = 0; createPartition(0, GPtr->numStrEdges, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { if (strncmp(GPtr->strWeight+i*MAX_STRLEN, SOUGHT_STRING, MAX_STRLEN) == 0) { /* * Find the corresponding endVertex */ long t; for (t = 0; t < GPtr->numEdges; t++) { if (GPtr->intWeight[t] == -i) { break; } } long j; for (j = 0; j < GPtr->numDirectedEdges; j++) { if (GPtr->paralEdgeIndex[j] > t) { break; } } tmpEdgeList[i_edgeCounter].endVertex = GPtr->outVertexList[j-1]; tmpEdgeList[i_edgeCounter].edgeNum = j-1; for (t = 0; t < GPtr->numVertices; t++) { if (GPtr->outVertexIndex[t] > j-1) { break; } } tmpEdgeList[i_edgeCounter].startVertex = t-1; i_edgeCounter++; } } thread_barrier_wait(); i_edgeEndCounter[myId] = i_edgeCounter; i_edgeStartCounter[myId] = 0; if (myId == 0) { *soughtStrWtListSize = 0; } thread_barrier_wait(); if (myId == 0) { for (i = 1; i < numThread; i++) { i_edgeEndCounter[i] = i_edgeEndCounter[i-1] + i_edgeEndCounter[i]; i_edgeStartCounter[i] = i_edgeEndCounter[i-1]; } } *soughtStrWtListSize += i_edgeCounter; thread_barrier_wait(); edge* soughtStrWtList; if (myId == 0) { P_FREE(*soughtStrWtListPtr); soughtStrWtList = (edge*)P_MALLOC((*soughtStrWtListSize) * sizeof(edge)); assert(soughtStrWtList); global_soughtStrWtList = soughtStrWtList; } thread_barrier_wait(); soughtStrWtList = global_soughtStrWtList; for (i = i_edgeStartCounter[myId]; i < i_edgeEndCounter[myId]; i++) { (soughtStrWtList[i]).startVertex = tmpEdgeList[i-i_edgeStartCounter[myId]].startVertex; (soughtStrWtList[i]).endVertex = tmpEdgeList[i-i_edgeStartCounter[myId]].endVertex; (soughtStrWtList[i]).edgeNum = tmpEdgeList[i-i_edgeStartCounter[myId]].edgeNum; } thread_barrier_wait(); if (myId == 0) { *soughtStrWtListPtr = soughtStrWtList; P_FREE(i_edgeStartCounter); P_FREE(i_edgeEndCounter); } P_FREE(tmpEdgeList); TM_THREAD_EXIT(); }
/* ============================================================================= * TMgrid_free * ============================================================================= */ void Pgrid_free (grid_t* gridPtr) { P_FREE(gridPtr->points_unaligned); P_FREE(gridPtr); }
/* ============================================================================= * cutClusters * ============================================================================= */ void cutClusters (void* argPtr) { TM_THREAD_ENTER(); graph* GPtr = (graph*)argPtr; long myId = thread_getId(); long numThread = thread_getNumThread(); /* * Sort the vertex list by their degree */ ULONGINT_T* Index; ULONGINT_T* neighbourArray; ULONGINT_T* IndexSorted; ULONGINT_T* neighbourArraySorted; if (myId == 0) { long numByte = GPtr->numVertices * sizeof(ULONGINT_T); Index = (ULONGINT_T*)P_MALLOC(numByte); assert(Index); global_Index = Index; neighbourArray = (ULONGINT_T*)P_MALLOC(numByte); assert(neighbourArray); global_neighbourArray = neighbourArray; IndexSorted = (ULONGINT_T*)P_MALLOC(numByte); assert(IndexSorted); global_IndexSorted = IndexSorted; neighbourArraySorted = (ULONGINT_T*)P_MALLOC(numByte); assert(neighbourArraySorted); global_neighbourArraySorted = neighbourArraySorted; } thread_barrier_wait(); Index = global_Index; neighbourArray = global_neighbourArray; IndexSorted = global_IndexSorted; neighbourArraySorted = global_neighbourArraySorted; long i; long i_start; long i_stop; createPartition(0, GPtr->numVertices, myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { neighbourArray[i] = GPtr->inDegree[i] + GPtr->outDegree[i]; Index[i] = i; } thread_barrier_wait(); all_radixsort_node_aux_s3(GPtr->numVertices, neighbourArray, neighbourArraySorted, Index, IndexSorted); thread_barrier_wait(); /* * Global array to keep track of vertex status: * -1 if a vertex hasn't been assigned to a cluster yet * t if it belongs to a cluster; t = iteration*numThread + myId */ long* vStatus; edge* pCutSet; ULONGINT_T* startV; ULONGINT_T* clusterSize; if (myId == 0) { P_FREE(Index); P_FREE(neighbourArray); vStatus = (long*)P_MALLOC(GPtr->numVertices * sizeof(long)); assert(vStatus); global_vStatus = vStatus; /* * Allocate mem. for the cut set list * Maintain local arrays initially and merge them in the end */ if (SCALE < 12) { pCutSet =(edge*)P_MALLOC((1*(GPtr->numDirectedEdges)/numThread) * sizeof(edge)); } else { pCutSet = (edge*)P_MALLOC((0.2*(GPtr->numDirectedEdges)/numThread) * sizeof(edge)); } assert(pCutSet); global_pCutSet = pCutSet; /* * Vertex to start from, on each thread */ startV = (ULONGINT_T*)P_MALLOC(numThread * sizeof(ULONGINT_T)); assert(startV); global_startV = startV; clusterSize = (ULONGINT_T*)P_MALLOC(numThread * sizeof(ULONGINT_T)); assert(clusterSize); global_clusterSize = clusterSize; } thread_barrier_wait(); vStatus = global_vStatus; pCutSet = global_pCutSet; startV = global_startV; clusterSize = global_clusterSize; for (i = i_start; i < i_stop; i++) { vStatus[i] = -1; } thread_barrier_wait(); ULONGINT_T verticesVisited = 0; #ifdef WRITE_RESULT_FILES FILE* outfp1 = NULL; if (myId == 0) { outfp1 = fopen("clusters.txt", "w"); fprintf(outfp1, "\nKernel 4 - Extracted Clusters\n"); } #endif long iter = 0; ULONGINT_T currIndex = 0; ULONGINT_T cutSetIndex = 0; while (verticesVisited < GPtr->numVertices) { /* Clear start vertex array */ startV[myId] = -1; clusterSize[myId] = 0; if (currIndex == GPtr->numVertices) { currIndex = 0; } thread_barrier_wait(); /* * Choose vertices to start from * Done sequentially right now, can be parallelized */ if (myId == 0) { long t; for (t = 0; t < numThread; t++) { long r; for (r = currIndex; r < GPtr->numVertices; r++) { if (vStatus[IndexSorted[GPtr->numVertices - r - 1]] == -1) { startV[t] = IndexSorted[GPtr->numVertices - r - 1]; vStatus[startV[t]] = iter * numThread + t; long j; for (j = 0; j < GPtr->outDegree[startV[t]]; j++) { long outVertexListIndex = j+GPtr->outVertexIndex[startV[t]]; long vStatusIndex = GPtr->outVertexList[outVertexListIndex]; if (vStatus[vStatusIndex] == -1) { vStatus[vStatusIndex] = iter * numThread + t; clusterSize[t]++; } } for (j = 0; j < GPtr->inDegree[startV[t]]; j++) { long inVertexIndex = j+GPtr->inVertexIndex[startV[t]]; long vStatusIndex = GPtr->inVertexList[inVertexIndex]; if (vStatus[vStatusIndex] == -1) { vStatus[vStatusIndex] = iter * numThread + t; clusterSize[t]++; } } currIndex = r+1; break; } } } } thread_barrier_wait(); /* * Determine clusters and cut sets in parallel */ i = startV[myId]; ULONGINT_T cliqueSize = 0; /* If the thread has some vertex to start from */ if (i != -1) { cliqueSize = 1; /* clusterSize[myId] gives the no. of 'unassigned' vertices adjacent to the current vertex */ if ((clusterSize[myId] >= 0.6*(GPtr->inDegree[i]+GPtr->outDegree[i])) || ((iter > (GPtr->numVertices)/(numThread*MAX_CLUSTER_SIZE)) && (clusterSize[myId] > 0))) { /* * Most of the adjacent vertices are unassigned, * should be able to extract a cluster easily */ /* Inspect adjacency list */ long j; for (j = 0; j < GPtr->outDegree[i]; j++) { ULONGINT_T clusterCounter = 0; ULONGINT_T cutSetIndexPrev = cutSetIndex; ULONGINT_T cutSetCounter = 0; if (vStatus[GPtr->outVertexList[j+GPtr->outVertexIndex[i]]] == iter * numThread + myId) { long v = GPtr->outVertexList[j+GPtr->outVertexIndex[i]]; /* * Inspect vertices adjacent to v and determine if it belongs * to a cluster or not */ long k; for (k = 0; k < GPtr->outDegree[v]; k++) { long outVertexListIndex = k+GPtr->outVertexIndex[v]; long vStatusIndex = GPtr->outVertexList[outVertexListIndex]; if (vStatus[vStatusIndex] == (iter * numThread + myId)) { clusterCounter++; } else { cutSetCounter++; if (vStatus[vStatusIndex] == -1) { /* Ensure that an edge is not added twice to the list */ pCutSet[cutSetIndex].startVertex = v; pCutSet[cutSetIndex].endVertex = vStatusIndex; cutSetIndex++; } } } if ((cutSetCounter >= clusterCounter) || ((SCALE < 9) && (clusterCounter <= 2) && (GPtr->inDegree[v]+GPtr->outDegree[v] > clusterCounter + cutSetCounter) && (clusterSize[myId] > clusterCounter + 2)) || ((SCALE > 9) && (clusterCounter < 0.5*clusterSize[myId]))) { /* v doesn't belong to this clique, free it */ vStatus[v] = -1; /* Also add this edge to cutset list, removing previously added edges */ cutSetIndex = cutSetIndexPrev; pCutSet[cutSetIndex].startVertex = i; pCutSet[cutSetIndex].endVertex = v; cutSetIndex++; } else { cliqueSize++; /* Add edges in inVertexList also to cut Set */ for (k = 0; k < GPtr->inDegree[v]; k++) { long inVertexListIndex = k+GPtr->inVertexIndex[v]; long vStatusIndex = GPtr->inVertexList[inVertexListIndex]; if (vStatus[vStatusIndex] == -1) { pCutSet[cutSetIndex].startVertex = v; pCutSet[cutSetIndex].endVertex = vStatusIndex; cutSetIndex++; } } } } } /* Do the same for the implied edges too */ for (j = 0; j < GPtr->inDegree[i]; j++) { ULONGINT_T clusterCounter = 0; ULONGINT_T cutSetIndexPrev = cutSetIndex; ULONGINT_T cutSetCounter = 0; if (vStatus[GPtr->inVertexList[j+GPtr->inVertexIndex[i]]] == iter*numThread+myId) { long v = GPtr->inVertexList[j+GPtr->inVertexIndex[i]]; /* Inspect vertices adjacent to v and determine if it belongs to a cluster or not */ long k; for (k = 0; k < GPtr->outDegree[v]; k++) { long outVertexListIndex = k+GPtr->outVertexIndex[v]; long vStatusIndex = GPtr->outVertexList[outVertexListIndex]; if (vStatus[vStatusIndex] == iter*numThread+myId) { clusterCounter++; } else { cutSetCounter++; if (vStatus[vStatusIndex] == -1) { /* To ensure that an edge is not added twice to the list */ pCutSet[cutSetIndex].startVertex = v; pCutSet[cutSetIndex].endVertex = vStatusIndex; cutSetIndex++; } } } if ((cutSetCounter >= clusterCounter) || ((SCALE < 9) && (clusterCounter <= 2) && (GPtr->inDegree[v]+GPtr->outDegree[v] > clusterCounter + cutSetCounter) && (clusterSize[myId] > clusterCounter + 2)) || ((SCALE > 9) && (clusterCounter < 0.5*clusterSize[myId]))) { /* v doesn't belong to this clique, free it */ vStatus[v] = -1; cutSetIndex = cutSetIndexPrev; pCutSet[cutSetIndex].startVertex = i; pCutSet[cutSetIndex].endVertex = v; cutSetIndex++; } else { cliqueSize++; /* Add edges in inVertexList also to cut Set */ for (k = 0; k < GPtr->inDegree[v]; k++) { long inVertexListIndex = k+GPtr->inVertexIndex[v]; long vStatusIndex = GPtr->inVertexList[inVertexListIndex]; if (vStatus[vStatusIndex] == -1) { pCutSet[cutSetIndex].startVertex = v; pCutSet[cutSetIndex].endVertex = vStatusIndex; cutSetIndex++; } } } } } } /* i != -1 */ if (clusterSize[myId] == 0) { /* Only one vertex in cluster */ cliqueSize = 1; } else { if ((clusterSize[myId] < 0.6*(GPtr->inDegree[i]+GPtr->outDegree[i])) && (iter <= GPtr->numVertices/(numThread*MAX_CLUSTER_SIZE))) { /* High perc. of intra-clique edges, do not commit clique */ cliqueSize = 0; vStatus[i] = -1; long j; for (j=0; j<GPtr->outDegree[i]; j++) { long outVertexListIndex = j+GPtr->outVertexIndex[i]; long vStatusIndex = GPtr->outVertexList[outVertexListIndex]; if (vStatus[vStatusIndex] == iter*numThread+myId) { vStatus[vStatusIndex] = -1; } } for (j=0; j<GPtr->inDegree[i]; j++) { long inVertexListIndex = j+GPtr->inVertexIndex[i]; long vStatusIndex = GPtr->inVertexList[inVertexListIndex]; if (vStatus[vStatusIndex] == iter*numThread+myId) { vStatus[vStatusIndex] = -1; } } } } } /* if i != -1 */ if (myId == 0) { global_cliqueSize = 0; } thread_barrier_wait(); #ifdef WRITE_RESULT_FILES /* Print to results.clq file */ if (myId == 0) { long t; for (t = 0; t < numThread; t++) { if (startV[t] != -1) { if (vStatus[startV[t]] == iter*numThread+t) { fprintf(outfp1, "%lu ", startV[t]); long j; for (j = 0; j < GPtr->outDegree[startV[t]]; j++) { long outVertexListIndex = j+GPtr->outVertexIndex[startV[t]]; long vStatusIndex = GPtr->outVertexList[outVertexListIndex]; if (vStatus[vStatusIndex] == iter*numThread+t) { fprintf(outfp1, "%lu ", vStatusIndex); } } for (j = 0; j < GPtr->inDegree[startV[t]]; j++) { long inVertexListIndex = j+GPtr->inVertexIndex[startV[t]]; long vStatusIndex = GPtr->inVertexList[inVertexListIndex]; if (vStatus[vStatusIndex] == iter*numThread+t) { fprintf(outfp1, "%lu ", vStatusIndex); } } fprintf(outfp1, "\n"); } } } } thread_barrier_wait(); #endif /* WRITE_RESULTS_FILE */ if (myId == 0) { iter++; global_iter = iter; } TM_BEGIN(); long tmp_cliqueSize = (long)TM_SHARED_READ(global_cliqueSize); TM_SHARED_WRITE(global_cliqueSize, (tmp_cliqueSize + cliqueSize)); TM_END(); thread_barrier_wait(); iter = global_iter; verticesVisited += global_cliqueSize; if ((verticesVisited >= 0.95*GPtr->numVertices) || (iter > GPtr->numVertices/2)) { break; } } /* while (verticesVisited < GPtr->numVertices) */ thread_barrier_wait(); #ifdef WRITE_RESULT_FILES /* Take care of unmarked vertices */ if (myId == 0) { if (verticesVisited < GPtr->numVertices) { for(i = 0; i < GPtr->numVertices; i++) { if (vStatus[i] == -1) { vStatus[i] = iter*numThread+myId; fprintf(outfp1, "%lu\n", i); iter++; } } } } thread_barrier_wait(); #endif /* * Merge partial Cutset Lists */ /* Temp vars for merging edge lists */ ULONGINT_T* edgeStartCounter; ULONGINT_T* edgeEndCounter; if (myId == 0) { edgeStartCounter = (ULONGINT_T*)P_MALLOC(numThread * sizeof(ULONGINT_T)); assert(edgeStartCounter); global_edgeStartCounter = edgeStartCounter; edgeEndCounter = (ULONGINT_T*)P_MALLOC(numThread * sizeof(ULONGINT_T)); assert(edgeEndCounter); global_edgeEndCounter = edgeEndCounter; } thread_barrier_wait(); edgeStartCounter = global_edgeStartCounter; edgeEndCounter = global_edgeEndCounter; edgeEndCounter[myId] = cutSetIndex; edgeStartCounter[myId] = 0; thread_barrier_wait(); if (myId == 0) { long t; for (t = 1; t < numThread; t++) { edgeEndCounter[t] = edgeEndCounter[t-1] + edgeEndCounter[t]; edgeStartCounter[t] = edgeEndCounter[t-1]; } } TM_BEGIN(); long tmp_cutSetIndex = (long)TM_SHARED_READ(global_cutSetIndex); TM_SHARED_WRITE(global_cutSetIndex, (tmp_cutSetIndex + cutSetIndex)); TM_END(); thread_barrier_wait(); cutSetIndex = global_cutSetIndex; ULONGINT_T cutSetCounter = cutSetIndex; /* Data struct. for storing edgeCut */ edge* cutSet; if (myId == 0) { cutSet = (edge*)P_MALLOC(cutSetCounter * sizeof(edge)); assert(cutSet); global_cutSet = cutSet; } thread_barrier_wait(); cutSet = global_cutSet; long j; for (j = edgeStartCounter[myId]; j < edgeEndCounter[myId]; j++) { cutSet[j].startVertex = pCutSet[j-edgeStartCounter[myId]].startVertex; cutSet[j].endVertex = pCutSet[j-edgeStartCounter[myId]].endVertex; } thread_barrier_wait(); #ifdef WRITE_RESULT_FILES FILE* outfp2 = NULL; if (myId == 0) { outfp2 = fopen("edgeCut.txt", "w"); fprintf(outfp2, "\nEdges in Cut Set - \n"); for (i = 0; i < cutSetCounter; i++) { fprintf(outfp2, "[%lu %lu] ", cutSet[i].startVertex, cutSet[i].endVertex); } fclose(outfp2); fclose(outfp1); } #endif if (myId == 0) { P_FREE(edgeStartCounter); P_FREE(edgeEndCounter); P_FREE(pCutSet); P_FREE(IndexSorted); P_FREE(neighbourArraySorted); P_FREE(startV); P_FREE(clusterSize); P_FREE(cutSet); P_FREE(vStatus); } TM_THREAD_EXIT(); }
MAIN(argc, argv) { GOTO_REAL(); SETUP_NUMBER_TASKS(10); /* * Tuple for Scalable Data Generation * stores startVertex, endVertex, long weight and other info */ graphSDG* SDGdata; /* * The graph data structure for this benchmark - see defs.h */ graph* G; #ifdef ENABLE_KERNEL2 /* * Kernel 2 */ edge* maxIntWtList; edge* soughtStrWtList; long maxIntWtListSize; long soughtStrWtListSize; #endif /* ENABLE_KERNEL2 */ #ifdef ENABLE_KERNEL3 # ifndef ENABLE_KERNEL2 # error KERNEL3 requires KERNEL2 # endif /* * Kernel 3 */ V* intWtVList = NULL; V* strWtVList = NULL; Vl** intWtVLList = NULL; Vl** strWtVLList = NULL; Vd* intWtVDList = NULL; Vd* strWtVDList = NULL; #endif /* ENABLE_KERNEL3 */ double totalTime = 0.0; /* ------------------------------------------------------------------------- * Preamble * ------------------------------------------------------------------------- */ /* * User Interface: Configurable parameters, and global program control */ getUserParameters(argc, (char** const) argv); SIM_GET_NUM_CPU(THREADS); TM_STARTUP(THREADS, 0); P_MEMORY_STARTUP(THREADS); SETUP_NUMBER_THREADS(THREADS); thread_startup(THREADS); double time_total = 0.0; int repeat = REPEATS; for (; repeat > 0; --repeat) { SDGdata = (graphSDG*)malloc(sizeof(graphSDG)); assert(SDGdata); genScalData_seq(SDGdata); G = (graph*)malloc(sizeof(graph)); assert(G); computeGraph_arg_t computeGraphArgs; computeGraphArgs.GPtr = G; computeGraphArgs.SDGdataPtr = SDGdata; TIMER_T start; TIMER_READ(start); GOTO_SIM(); thread_start(computeGraph, (void*)&computeGraphArgs); GOTO_REAL(); TIMER_T stop; TIMER_READ(stop); double time_tmp = TIMER_DIFF_SECONDS(start, stop); PRINT_STATS(); time_total += time_tmp; } totalTime += time_total; #ifdef ENABLE_KERNEL2 /* ------------------------------------------------------------------------- * Kernel 2 - Find Max weight and sought string * ------------------------------------------------------------------------- */ printf("\nKernel 2 - getStartLists() beginning execution...\n"); maxIntWtListSize = 0; soughtStrWtListSize = 0; maxIntWtList = (edge*)malloc(sizeof(edge)); assert(maxIntWtList); soughtStrWtList = (edge*)malloc(sizeof(edge)); assert(soughtStrWtList); getStartLists_arg_t getStartListsArg; getStartListsArg.GPtr = G; getStartListsArg.maxIntWtListPtr = &maxIntWtList; getStartListsArg.maxIntWtListSize = &maxIntWtListSize; getStartListsArg.soughtStrWtListPtr = &soughtStrWtList; getStartListsArg.soughtStrWtListSize = &soughtStrWtListSize; TIMER_READ(start); GOTO_SIM(); #ifdef OTM #pragma omp parallel { getStartLists((void*)&getStartListsArg); } #else thread_start(getStartLists, (void*)&getStartListsArg); #endif GOTO_REAL(); TIMER_T stop; TIMER_READ(stop); time = TIMER_DIFF_SECONDS(start, stop); totalTime += time; printf("\n\tgetStartLists() completed execution.\n"); printf("\nTime taken for kernel 2 is %9.6f sec.\n\n", time); #endif /* ENABLE_KERNEL2 */ #ifdef ENABLE_KERNEL3 /* ------------------------------------------------------------------------- * Kernel 3 - Graph Extraction * ------------------------------------------------------------------------- */ printf("\nKernel 3 - findSubGraphs() beginning execution...\n"); if (K3_DS == 0) { intWtVList = (V*)malloc(G->numVertices * maxIntWtListSize * sizeof(V)); assert(intWtVList); strWtVList = (V*)malloc(G->numVertices * soughtStrWtListSize * sizeof(V)); assert(strWtVList); findSubGraphs0_arg_t findSubGraphs0Arg; findSubGraphs0Arg.GPtr = G; findSubGraphs0Arg.intWtVList = intWtVList; findSubGraphs0Arg.strWtVList = strWtVList; findSubGraphs0Arg.maxIntWtList = maxIntWtList; findSubGraphs0Arg.maxIntWtListSize = maxIntWtListSize; findSubGraphs0Arg.soughtStrWtList = soughtStrWtList; findSubGraphs0Arg.soughtStrWtListSize = soughtStrWtListSize; TIMER_READ(start); GOTO_SIM(); #ifdef OTM #pragma omp parallel { findSubGraphs0((void*)&findSubGraphs0Arg); } #else thread_start(findSubGraphs0, (void*)&findSubGraphs0Arg); #endif GOTO_REAL(); TIMER_READ(stop); } else if (K3_DS == 1) { intWtVLList = (Vl**)malloc(maxIntWtListSize * sizeof(Vl*)); assert(intWtVLList); strWtVLList = (Vl**)malloc(soughtStrWtListSize * sizeof(Vl*)); assert(strWtVLList); findSubGraphs1_arg_t findSubGraphs1Arg; findSubGraphs1Arg.GPtr = G; findSubGraphs1Arg.intWtVLList = intWtVLList; findSubGraphs1Arg.strWtVLList = strWtVLList; findSubGraphs1Arg.maxIntWtList = maxIntWtList; findSubGraphs1Arg.maxIntWtListSize = maxIntWtListSize; findSubGraphs1Arg.soughtStrWtList = soughtStrWtList; findSubGraphs1Arg.soughtStrWtListSize = soughtStrWtListSize; TIMER_READ(start); GOTO_SIM(); #ifdef OTM #pragma omp parallel { findSubGraphs1((void*)&findSubGraphs1Arg); } #else thread_start(findSubGraphs1, (void*)&findSubGraphs1Arg); #endif GOTO_REAL(); TIMER_READ(stop); /* Verification on_one_thread { for (i=0; i<maxIntWtListSize; i++) { printf("%ld -- ", i); currV = intWtVLList[i]; while (currV != NULL) { printf("[%ld %ld] ", currV->num, currV->depth); currV = currV->next; } printf("\n"); } for (i=0; i<soughtStrWtListSize; i++) { printf("%ld -- ", i); currV = strWtVLList[i]; while (currV != NULL) { printf("[%ld %ld] ", currV->num, currV->depth); currV = currV->next; } printf("\n"); } } */ } else if (K3_DS == 2) { intWtVDList = (Vd *) malloc(maxIntWtListSize * sizeof(Vd)); assert(intWtVDList); strWtVDList = (Vd *) malloc(soughtStrWtListSize * sizeof(Vd)); assert(strWtVDList); findSubGraphs2_arg_t findSubGraphs2Arg; findSubGraphs2Arg.GPtr = G; findSubGraphs2Arg.intWtVDList = intWtVDList; findSubGraphs2Arg.strWtVDList = strWtVDList; findSubGraphs2Arg.maxIntWtList = maxIntWtList; findSubGraphs2Arg.maxIntWtListSize = maxIntWtListSize; findSubGraphs2Arg.soughtStrWtList = soughtStrWtList; findSubGraphs2Arg.soughtStrWtListSize = soughtStrWtListSize; TIMER_READ(start); GOTO_SIM(); #ifdef OTM #pragma omp parallel { findSubGraphs2((void*)&findSubGraphs2Arg); } #else thread_start(findSubGraphs2, (void*)&findSubGraphs2Arg); #endif GOTO_REAL(); TIMER_READ(stop); /* Verification */ /* on_one_thread { printf("\nInt weight sub-graphs \n"); for (i=0; i<maxIntWtListSize; i++) { printf("%ld -- ", i); for (j=0; j<intWtVDList[i].numArrays; j++) { printf("\n [Array %ld] - \n", j); for (k=0; k<intWtVDList[i].arraySize[j]; k++) { printf("[%ld %ld] ", intWtVDList[i].vList[j][k].num, intWtVDList[i].vList[j][k].depth); } } printf("\n"); } printf("\nStr weight sub-graphs \n"); for (i=0; i<soughtStrWtListSize; i++) { printf("%ld -- ", i); for (j=0; j<strWtVDList[i].numArrays; j++) { printf("\n [Array %ld] - \n", j); for (k=0; k<strWtVDList[i].arraySize[j]; k++) { printf("[%ld %ld] ", strWtVDList[i].vList[j][k].num, strWtVDList[i].vList[j][k].depth); } } printf("\n"); } } */ } else { assert(0); } time = TIMER_DIFF_SECONDS(start, stop); totalTime += time; printf("\n\tfindSubGraphs() completed execution.\n"); printf("\nTime taken for kernel 3 is %9.6f sec.\n\n", time); #endif /* ENABLE_KERNEL3 */ #ifdef ENABLE_KERNEL4 /* ------------------------------------------------------------------------- * Kernel 4 - Graph Clustering * ------------------------------------------------------------------------- */ printf("\nKernel 4 - cutClusters() beginning execution...\n"); TIMER_READ(start); GOTO_SIM(); #ifdef OTM #pragma omp parallel { cutClusters((void*)G); } #else thread_start(cutClusters, (void*)G); #endif GOTO_REAL(); TIMER_READ(stop); time = TIMER_DIFF_SECONDS(start, stop); totalTime += time; printf("\n\tcutClusters() completed execution.\n"); printf("\nTime taken for Kernel 4 is %9.6f sec.\n\n", time); #endif /* ENABLE_KERNEL4 */ printf("Time = %9.6f \n", totalTime); /* ------------------------------------------------------------------------- * Cleanup * ------------------------------------------------------------------------- */ P_FREE(G->outDegree); P_FREE(G->outVertexIndex); P_FREE(G->outVertexList); P_FREE(G->paralEdgeIndex); P_FREE(G->inDegree); P_FREE(G->inVertexIndex); P_FREE(G->inVertexList); P_FREE(G->intWeight); P_FREE(G->strWeight); #ifdef ENABLE_KERNEL3 LONGINT_T i; LONGINT_T j; Vl* currV; Vl* tempV; if (K3_DS == 0) { P_FREE(strWtVList); P_FREE(intWtVList); } if (K3_DS == 1) { for (i = 0; i < maxIntWtListSize; i++) { currV = intWtVLList[i]; while (currV != NULL) { tempV = currV->next; P_FREE(currV); currV = tempV; } } for (i = 0; i < soughtStrWtListSize; i++) { currV = strWtVLList[i]; while (currV != NULL) { tempV = currV->next; P_FREE(currV); currV = tempV; } } P_FREE(strWtVLList); P_FREE(intWtVLList); } if (K3_DS == 2) { for (i = 0; i < maxIntWtListSize; i++) { for (j = 0; j < intWtVDList[i].numArrays; j++) { P_FREE(intWtVDList[i].vList[j]); } P_FREE(intWtVDList[i].vList); P_FREE(intWtVDList[i].arraySize); } for (i = 0; i < soughtStrWtListSize; i++) { for (j = 0; j < strWtVDList[i].numArrays; j++) { P_FREE(strWtVDList[i].vList[j]); } P_FREE(strWtVDList[i].vList); P_FREE(strWtVDList[i].arraySize); } P_FREE(strWtVDList); P_FREE(intWtVDList); } P_FREE(soughtStrWtList); P_FREE(maxIntWtList); #endif /* ENABLE_KERNEL2 */ P_FREE(SOUGHT_STRING); P_FREE(G); P_FREE(SDGdata); TM_SHUTDOWN(); P_MEMORY_SHUTDOWN(); GOTO_SIM(); thread_shutdown(); MAIN_RETURN(0); }
/* ============================================================================= * Pbitmap_free * ============================================================================= */ void Pbitmap_free (bitmap_t* bitmapPtr) { P_FREE(bitmapPtr->bits); P_FREE(bitmapPtr); }
/* * n_vars is the number of variables to be considered, * d is the data array of variables d[0],...,d[n_vars-1], * pred determines which estimate is required: BLUE, BLUP, or BLP */ void gls(DATA **d /* pointer to DATA array */, int n_vars, /* length of DATA array (to consider) */ enum GLS_WHAT pred, /* what type of prediction is requested */ DPOINT *where, /* prediction location */ double *est /* output: array that holds the predicted values and variances */) { GLM *glm = NULL; /* to be copied to/from d */ static MAT *X0 = MNULL, *C0 = MNULL, *MSPE = MNULL, *CinvC0 = MNULL, *Tmp1 = MNULL, *Tmp2 = MNULL, *Tmp3 = MNULL, *R = MNULL; static VEC *blup = VNULL, *tmpa = VNULL, *tmpb = VNULL; PERM *piv = PNULL; volatile unsigned int i, rows_C; unsigned int j, k, l = 0, row, col, start_i, start_j, start_X, global, one_nbh_empty; VARIOGRAM *v = NULL; static enum GLS_WHAT last_pred = GLS_INIT; /* the initial value */ double c_value, *X_ori; int info; if (d == NULL) { /* clean up */ if (X0 != MNULL) M_FREE(X0); if (C0 != MNULL) M_FREE(C0); if (MSPE != MNULL) M_FREE(MSPE); if (CinvC0 != MNULL) M_FREE(CinvC0); if (Tmp1 != MNULL) M_FREE(Tmp1); if (Tmp2 != MNULL) M_FREE(Tmp2); if (Tmp3 != MNULL) M_FREE(Tmp3); if (R != MNULL) M_FREE(R); if (blup != VNULL) V_FREE(blup); if (tmpa != VNULL) V_FREE(tmpa); if (tmpb != VNULL) V_FREE(tmpb); last_pred = GLS_INIT; return; } if (DEBUG_COV) { printlog("we're at %s X: %g Y: %g Z: %g\n", IS_BLOCK(where) ? "block" : "point", where->x, where->y, where->z); } if (pred != UPDATE) /* it right away: */ last_pred = pred; assert(last_pred != GLS_INIT); if (d[0]->glm == NULL) { /* allocate and initialize: */ glm = new_glm(); d[0]->glm = (void *) glm; } else glm = (GLM *) d[0]->glm; glm->mu0 = v_resize(glm->mu0, n_vars); MSPE = m_resize(MSPE, n_vars, n_vars); if (pred == GLS_BLP || UPDATE_BLP) { X_ori = where->X; for (i = 0; i < n_vars; i++) { /* mu(0) */ glm->mu0->ve[i] = calc_mu(d[i], where); blup = v_copy(glm->mu0, v_resize(blup, glm->mu0->dim)); where->X += d[i]->n_X; /* shift to next x0 entry */ } where->X = X_ori; /* ... and set back */ for (i = 0; i < n_vars; i++) { /* Cij(0,0): */ for (j = 0; j <= i; j++) { v = get_vgm(LTI(d[i]->id,d[j]->id)); ME(MSPE, i, j) = ME(MSPE, j, i) = COVARIANCE0(v, where, where, d[j]->pp_norm2); } } fill_est(NULL, blup, MSPE, n_vars, est); /* in case of empty neighbourhood */ } /* xxx */ /* logprint_variogram(v, 1); */ /* * selection dependent problem dimensions: */ for (i = rows_C = 0, one_nbh_empty = 0; i < n_vars; i++) { rows_C += d[i]->n_sel; if (d[i]->n_sel == 0) one_nbh_empty = 1; } if (rows_C == 0 /* all selection lists empty */ || one_nbh_empty == 1) { /* one selection list empty */ if (pred == GLS_BLP || UPDATE_BLP) debug_result(blup, MSPE, pred); return; } for (i = 0, global = 1; i < n_vars && global; i++) global = (d[i]->sel == d[i]->list && d[i]->n_list == d[i]->n_original && d[i]->n_list == d[i]->n_sel); /* * global things: enter whenever (a) first time, (b) local selections or * (c) the size of the problem grew since the last call (e.g. simulation) */ if (glm->C == NULL || !global || rows_C > glm->C->m) { /* * fill y: */ glm->y = get_y(d, glm->y, n_vars); if (pred != UPDATE) { glm->C = m_resize(glm->C, rows_C, rows_C); if (gl_choleski == 0) /* use LDL' decomposition, allocate piv: */ piv = px_resize(piv, rows_C); m_zero(glm->C); glm->X = get_X(d, glm->X, n_vars); M_DEBUG(glm->X, "X"); glm->CinvX = m_resize(glm->CinvX, rows_C, glm->X->n); glm->XCinvX = m_resize(glm->XCinvX, glm->X->n, glm->X->n); glm->beta = v_resize(glm->beta, glm->X->n); for (i = start_X = start_i = 0; i < n_vars; i++) { /* row var */ /* fill C, mu: */ for (j = start_j = 0; j <= i; j++) { /* col var */ v = get_vgm(LTI(d[i]->id,d[j]->id)); for (k = 0; k < d[i]->n_sel; k++) { /* rows */ row = start_i + k; for (l = 0, col = start_j; col <= row && l < d[j]->n_sel; l++, col++) { if (pred == GLS_BLUP) c_value = GCV(v, d[i]->sel[k], d[j]->sel[l]); else c_value = COVARIANCE(v, d[i]->sel[k], d[j]->sel[l]); /* on the diagonal, if necessary, add measurement error variance */ if (d[i]->colnvariance && i == j && k == l) c_value += d[i]->sel[k]->variance; ME(glm->C, col, row) = c_value; /* fill upper */ if (col != row) ME(glm->C, row, col) = c_value; /* fill all */ } /* for l */ } /* for k */ start_j += d[j]->n_sel; } /* for j */ start_i += d[i]->n_sel; if (d[i]->n_sel > 0) start_X += d[i]->n_X - d[i]->n_merge; } /* for i */ /* if (d[0]->colnvmu) glm->C = convert_vmuC(glm->C, d[0]); */ if (d[0]->variance_fn) { glm->mu = get_mu(glm->mu, glm->y, d, n_vars); convert_C(glm->C, glm->mu, d[0]->variance_fn); } if (DEBUG_COV && pred == GLS_BLUP) printlog("[using generalized covariances: max_val - semivariance()]"); M_DEBUG(glm->C, "Covariances (x_i, x_j) matrix C (upper triangle)"); /* * factorize C: */ CHfactor(glm->C, piv, &info); if (info != 0) { /* singular: */ pr_warning("Covariance matrix singular at location [%g,%g,%g]: skipping...", where->x, where->y, where->z); m_free(glm->C); glm->C = MNULL; /* assure re-entrance if global */ P_FREE(piv); return; } if (piv == NULL) M_DEBUG(glm->C, "glm->C, Choleski decomposed:") else M_DEBUG(glm->C, "glm->C, LDL' decomposed:") } /* if (pred != UPDATE) */
/* ============================================================================= * findSubGraphs0 * ============================================================================= */ void findSubGraphs0 (void* argPtr) { graph* GPtr = ((findSubGraphs0_arg_t*)argPtr)->GPtr; V* intWtVList = ((findSubGraphs0_arg_t*)argPtr)->intWtVList; V* strWtVList = ((findSubGraphs0_arg_t*)argPtr)->strWtVList; edge* maxIntWtList = ((findSubGraphs0_arg_t*)argPtr)->maxIntWtList; long maxIntWtListSize = ((findSubGraphs0_arg_t*)argPtr)->maxIntWtListSize; edge* soughtStrWtList = ((findSubGraphs0_arg_t*)argPtr)->soughtStrWtList; long soughtStrWtListSize = ((findSubGraphs0_arg_t*)argPtr)->soughtStrWtListSize; long myId = thread_getId(); long numThread = thread_getNumThread(); long i; long i_start; long i_stop; createPartition(0, (maxIntWtListSize + soughtStrWtListSize), myId, numThread, &i_start, &i_stop); for (i = i_start; i < i_stop; i++) { if (i < maxIntWtListSize) { unsigned long j; for (j = 0; j < GPtr->numVertices; j++) { intWtVList[i*(GPtr->numVertices)+j].num = 0; intWtVList[i*(GPtr->numVertices)+j].depth = 0; } } else { long t = i - maxIntWtListSize; unsigned long j; for (j = 0; j < GPtr->numVertices; j++) { strWtVList[t*(GPtr->numVertices)+j].num = 0; strWtVList[t*(GPtr->numVertices)+j].depth = 0; } } } thread_barrier_wait(); LONGINT_T* visited = (LONGINT_T*)P_MALLOC(GPtr->numVertices * sizeof(LONGINT_T)); assert(visited); /* * Each thread runs a BFS from endvertex of maxIntWtList edgeList */ for (i = i_start; i < i_stop; i++) { unsigned long k; for (k = 0; k < GPtr->numVertices; k++) { visited[k] = 0; } if (i < maxIntWtListSize) { intWtVList[i*(GPtr->numVertices)+0].num = maxIntWtList[i].startVertex; intWtVList[i*(GPtr->numVertices)+0].depth = -1; intWtVList[i*(GPtr->numVertices)+1].num = maxIntWtList[i].endVertex; intWtVList[i*(GPtr->numVertices)+1].depth = 1; visited[(intWtVList[i*(GPtr->numVertices)+0]).num] = 1; visited[(intWtVList[i*(GPtr->numVertices)+1]).num] = 1; long depth = 1; long verticesVisited = 2; long currIndex = 1; while ((depth < SUBGR_EDGE_LENGTH) || (verticesVisited == (long)GPtr->numVertices)) { long intWtListIndex = i*(GPtr->numVertices)+currIndex; depth = intWtVList[intWtListIndex].depth + 1; long j; long j_start = GPtr->outVertexIndex[intWtVList[intWtListIndex].num]; long j_stop = j_start + GPtr->outDegree[intWtVList[intWtListIndex].num]; for (j = j_start; j < j_stop; j++) { if (visited[GPtr->outVertexList[j]] == 0) { visited[GPtr->outVertexList[j]] = 1; intWtVList[i*(GPtr->numVertices)+verticesVisited].num = GPtr->outVertexList[j]; intWtVList[i*(GPtr->numVertices)+verticesVisited].depth = depth; verticesVisited++; } } if ((currIndex < verticesVisited - 1) && (verticesVisited < (long)GPtr->numVertices)) { currIndex++; depth = intWtVList[i*(GPtr->numVertices)+currIndex].depth; } else { break; } } } else { long t = i - maxIntWtListSize; strWtVList[t*(GPtr->numVertices)+0].num = (soughtStrWtList[t]).startVertex; strWtVList[t*(GPtr->numVertices)+0].depth = -1; strWtVList[t*(GPtr->numVertices)+1].num = (soughtStrWtList[t]).endVertex; strWtVList[t*(GPtr->numVertices)+1].depth = 1; visited[(strWtVList[t*(GPtr->numVertices)+0]).num] = 1; visited[(strWtVList[t*(GPtr->numVertices)+1]).num] = 1; long depth = 1; long verticesVisited = 2; long currIndex = 1; while ((depth < SUBGR_EDGE_LENGTH) || (verticesVisited == (long)GPtr->numVertices)) { long strWtVListIndex = t*(GPtr->numVertices)+currIndex; depth = strWtVList[strWtVListIndex].depth + 1; long j; long j_start = GPtr->outVertexIndex[strWtVList[strWtVListIndex].num]; long j_stop = j_start + GPtr->outDegree[strWtVList[strWtVListIndex].num]; for (j = j_start; j < j_stop; j++) { if (visited[GPtr->outVertexList[j]] == 0) { visited[GPtr->outVertexList[j]] = 1; strWtVList[t*(GPtr->numVertices)+verticesVisited].num = GPtr->outVertexList[j]; strWtVList[t*(GPtr->numVertices)+verticesVisited].depth = depth; verticesVisited++; } } if (currIndex < verticesVisited - 1) { currIndex++; depth = strWtVList[t*(GPtr->numVertices)+currIndex].depth; } else { break; } } } } P_FREE(visited); }
/* ============================================================================= * PfreeNode * ============================================================================= */ static void PfreeNode (list_node_t* nodePtr) { P_FREE(nodePtr); }
/* ============================================================================= * Pvector_free * ============================================================================= */ void Pvector_free (vector_t* vectorPtr) { P_FREE(vectorPtr->elements); P_FREE(vectorPtr); }
/* ============================================================================= * Plist_free * ============================================================================= */ void Plist_free (list_t* listPtr) { PfreeList(listPtr->head.nextPtr); P_FREE(listPtr); }
/* ============================================================================= * Pqueue_free * ============================================================================= */ void queue_stm_v2::Pqueue_free (queue_t* queuePtr) { P_FREE(queuePtr->elements); P_FREE(queuePtr); }
/* ============================================================================= * Pqueue_free * ============================================================================= */ void Pqueue_free (queue_t* queuePtr) { P_FREE(queuePtr->elements); P_FREE(queuePtr); }