void bfs_stinger (const struct stinger *G, const int64_t nv, const int64_t ne, const int64_t startV, int64_t * marks, const int64_t numSteps, int64_t * Q, int64_t * QHead, int64_t * neighbors) { int64_t j, k, s; int64_t nQ, Qnext, Qstart, Qend; int64_t w_start; MTA ("mta assert nodep") for (j = 0; j < nv; j++) { marks[j] = 0; } s = startV; /* Push node s onto Q and set bounds for first Q sublist */ Q[0] = s; Qnext = 1; nQ = 1; QHead[0] = 0; QHead[1] = 1; marks[s] = 1; PushOnStack: /* Push nodes onto Q */ /* Execute the nested loop for each node v on the Q AND for each neighbor w of v */ Qstart = QHead[nQ - 1]; Qend = QHead[nQ]; w_start = 0; MTA ("mta assert no dependence") MTA ("mta block dynamic schedule") for (j = Qstart; j < Qend; j++) { int64_t v = Q[j]; size_t d; size_t deg_v = stinger_outdegree (G, v); int64_t my_w = stinger_int64_fetch_add (&w_start, deg_v); stinger_gather_typed_successors (G, 0, v, &d, &neighbors[my_w], deg_v); assert (d == deg_v); MTA ("mta assert nodep") for (k = 0; k < deg_v; k++) { int64_t d, w, l; w = neighbors[my_w + k]; /* If node has not been visited, set distance and push on Q */ if (stinger_int64_fetch_add (marks + w, 1) == 0) { Q[stinger_int64_fetch_add (&Qnext, 1)] = w; } } } if (Qnext != QHead[nQ] && nQ < numSteps) { nQ++; QHead[nQ] = Qnext; goto PushOnStack; } }
int64_t count_triangles (stinger_t * S, uint64_t v) { int64_t out = 0; int64_t deg = stinger_outdegree(S, v); int64_t * neighbors = xmalloc(deg * sizeof(int64_t)); size_t d; stinger_gather_typed_successors(S, 0, v, &d, neighbors, deg); qsort(neighbors, d, sizeof(int64_t), compare); STINGER_FORALL_EDGES_OF_VTX_BEGIN(S, v) { if (STINGER_EDGE_DEST != v) { //out += count_intersections (S, v, STINGER_EDGE_DEST); out += count_intersections (S, v, STINGER_EDGE_DEST, neighbors, d); } } STINGER_FORALL_EDGES_OF_VTX_END(); free (neighbors); return out; }