Beispiel #1
0
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;
  }
}
Beispiel #2
0
void
update_rates(stinger_registered_alg * a, int64_t nv, double * vel, double * accel, double vel_keep, double accel_keep)
{
  int64_t * count = calloc(nv, sizeof(int64_t));

  OMP("omp parallel for")
  for(int64_t i = 0; i < a->num_insertions; i++) {
    stinger_int64_fetch_add(count + a->insertions[i].source,1);
    stinger_int64_fetch_add(count + a->insertions[i].destination,1);
  }

  OMP("omp parallel for")
  for(int64_t i = 0; i < a->num_deletions; i++) {
    stinger_int64_fetch_add(count + a->deletions[i].source,1);
    stinger_int64_fetch_add(count + a->deletions[i].destination,1);
  }

  OMP("omp parallel for")
  for(int64_t v = 0; v < nv; v++) {
    accel[v] = (accel_keep * accel[v]) + (1 - accel_keep) * (count[v] - vel[v]);
    vel[v] = (vel_keep * vel[v]) + (1 - vel_keep) * count[v];
  }


  free(count);
}
Beispiel #3
0
int64_t
st_conn_csr (const int64_t nv, const int64_t ne, const int64_t * off,
             const int64_t * ind, const int64_t * sources, const int64_t num,
             const int64_t numSteps)
{
  int64_t k, x;

  int64_t *Q_big = (int64_t *) xmalloc (INC * nv * sizeof (int64_t));
  int64_t *marks_s_big = (int64_t *) xmalloc (INC * nv * sizeof (int64_t));
  int64_t *marks_t_big = (int64_t *) xmalloc (INC * nv * sizeof (int64_t));
  int64_t *QHead_big =
    (int64_t *) xmalloc (INC * 2 * numSteps * sizeof (int64_t));
  int64_t *neighbors_big = (int64_t *) xmalloc (INC * ne * sizeof (int64_t));

  int64_t count = 0;

  k = 0;

  MTA ("mta assert parallel")
    MTA ("mta loop future")
    for (x = 0; x < INC; x++) {
      int64_t *Q = Q_big + x * nv;
      int64_t *marks_s = marks_s_big + x * nv;
      int64_t *marks_t = marks_t_big + x * nv;
      int64_t *QHead = QHead_big + x * 2 * numSteps;
      int64_t *neighbors = neighbors_big + x * ne;

      for (int64_t claimedk = stinger_int64_fetch_add (&k, 2);
           claimedk < 2 * num; claimedk = stinger_int64_fetch_add (&k, 2)) {

        int64_t s = sources[claimedk];
        int64_t t = sources[claimedk + 1];
        bfs_csr (nv, ne, off, ind, s, marks_s, numSteps, Q, QHead);
        bfs_csr (nv, ne, off, ind, t, marks_t, numSteps, Q, QHead);

        int64_t local_count = 0;

        MTA ("mta assert nodep")
          for (int64_t j = 0; j < nv; j++) {
            if (marks_s[j] && marks_t[j])
              stinger_int64_fetch_add (&local_count, 1);
          }

        if (local_count == 0)
          stinger_int64_fetch_add (&count, 1);
      }
    }

  free (neighbors_big);
  free (QHead_big);
  free (marks_t_big);
  free (marks_s_big);
  free (Q_big);

  return count;

}
Beispiel #4
0
void
bfs_csr (const int64_t nv, const int64_t ne, const int64_t * off,
         const int64_t * ind, const int64_t startV, int64_t * marks,
         const int64_t numSteps, int64_t * Q, int64_t * QHead)
{
  int64_t j, k, s;
  int64_t nQ, Qnext, Qstart, Qend;


  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];

  MTA ("mta assert no dependence")
    MTA ("mta block dynamic schedule")
    for (j = Qstart; j < Qend; j++) {
      int64_t v = Q[j];
      int64_t myStart = off[v];
      int64_t myEnd = off[v + 1];

      MTA ("mta assert nodep")
        for (k = myStart; k < myEnd; k++) {
          int64_t d, w, l;
          w = ind[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;
  }
}
Beispiel #5
0
int64_t
st_conn_stinger_source (const struct stinger * G, const int64_t nv,
                        const int64_t ne, const int64_t from,
                        const int64_t * sources, const int64_t num,
                        const int64_t numSteps)
{
  int64_t k;

  int64_t *Q = (int64_t *) xmalloc (nv * sizeof (int64_t));
  int64_t *marks_s = (int64_t *) xmalloc (nv * sizeof (int64_t));
  int64_t *marks_t = (int64_t *) xmalloc (nv * sizeof (int64_t));
  int64_t *QHead = (int64_t *) xmalloc (2 * numSteps * sizeof (int64_t));
  int64_t *neighbors = (int64_t *) xmalloc (ne * sizeof (int64_t));

  int64_t count = 0;

  int64_t deg_s = stinger_outdegree (G, from);
  if (deg_s == 0) {
    return num;
  }

  bfs_stinger (G, nv, ne, from, marks_s, numSteps, Q, QHead, neighbors);

  for (k = 0; k < num; k++) {
    int64_t t = sources[k];
    int64_t deg_t = stinger_outdegree (G, t);

    if (deg_t == 0) {
      stinger_int64_fetch_add (&count, 1);
    } else {
      bfs_stinger (G, nv, ne, t, marks_t, numSteps, Q, QHead, neighbors);

      int64_t local_count = 0;

      MTA ("mta assert nodep")
        for (int64_t j = 0; j < nv; j++) {
          if (marks_s[j] && marks_t[j])
            stinger_int64_fetch_add (&local_count, 1);
        }

      if (local_count == 0)
        stinger_int64_fetch_add (&count, 1);
    }
  }

  free (neighbors);
  free (QHead);
  free (marks_t);
  free (marks_s);
  free (Q);

  return count;

}
Beispiel #6
0
int64_t
parallel_breadth_first_search (struct stinger * S, int64_t nv,
				      int64_t source, int64_t * marks,
                                      int64_t * queue, int64_t * Qhead, int64_t * level)
{
  for (int64_t i = 0; i < nv; i++) {
    level[i] = -1;
    marks[i] = 0;
  }
  
  int64_t nQ, Qnext, Qstart, Qend;
  /* initialize */
  queue[0] = source;
  level[source] = 0;
  marks[source] = 1;
  Qnext = 1;  /* next open slot in the queue */
  nQ = 1;     /* level we are currently processing */
  Qhead[0] = 0;  /* beginning of the current frontier */
  Qhead[1] = 1;  /* end of the current frontier */
 
  Qstart = Qhead[nQ-1];
  Qend = Qhead[nQ];

  while (Qstart != Qend) {
    OMP ("omp parallel for")
    for (int64_t j = Qstart; j < Qend; j++) {
      STINGER_FORALL_EDGES_OF_VTX_BEGIN (S, queue[j]) {
	int64_t d = level[STINGER_EDGE_DEST];
	if (d < 0) {
	  if (stinger_int64_fetch_add (&marks[STINGER_EDGE_DEST], 1) == 0) {
	    level[STINGER_EDGE_DEST] = nQ;

	    int64_t mine = stinger_int64_fetch_add(&Qnext, 1);
	    queue[mine] = STINGER_EDGE_DEST;
	  }
	}
      } STINGER_FORALL_EDGES_OF_VTX_END();
    }
    
    Qstart = Qhead[nQ-1];
    Qend = Qnext;
    Qhead[nQ++] = Qend;
  }
/**
* @brief Perform a single source of the BC calculation per Brandes.
*
* Note that this follows the approach suggested by Green and Bader in which
* parent lists are not maintained, but instead the neighbors are searched
* to rediscover parents.
*
* Note also that found count will not include the source and that increments
* to this array are handled atomically.
*
* Operations to the bc array are NOT ATOMIC
*
* @param S The STINGER graph
* @param nv The maximum vertex ID in the graph plus one.
* @param source The vertex from where this search will start.
* @param bc The array into which the partial BCs will be added.
* @param found_count  An array to track how many times a vertex is found for normalization.
*/
void
single_bc_search(stinger_t * S, int64_t nv, int64_t source, double * bc, int64_t * found_count)
{
  int64_t * paths = (int64_t * )xcalloc(nv * 2, sizeof(int64_t));
  int64_t * q = paths + nv;
  double * partial = (double *)xcalloc(nv, sizeof(double));

  int64_t * d = (int64_t *)xmalloc(nv * sizeof(int64_t));
  for(int64_t i = 0; i < nv; i ++) d[i] = -1;

  int64_t q_front = 1;
  int64_t q_rear = 0;
  q[0] = source;
  d[source] = 0;
  paths[source] = 1;

  while(q_rear != q_front) {
    int64_t v = q[q_rear++];
    int64_t d_next = d[v] + 1;

    STINGER_FORALL_EDGES_OF_VTX_BEGIN(S, v) {

      if(d[STINGER_EDGE_DEST] < 0) {
	d[STINGER_EDGE_DEST]     = d_next;
	paths[STINGER_EDGE_DEST] = paths[v];
	q[q_front++]             = STINGER_EDGE_DEST;

	stinger_int64_fetch_add(found_count + STINGER_EDGE_DEST, 1);
      }

      else if(d[STINGER_EDGE_DEST] == d_next) {
	paths[STINGER_EDGE_DEST] += paths[v];
      }

    } STINGER_FORALL_EDGES_OF_VTX_END();
  }

  /* don't process source */
  while(q_front > 1) {
    int64_t w = q[--q_front];

    /* don't maintain parents, do search instead */
    STINGER_FORALL_EDGES_OF_VTX_BEGIN(S, w) {
      if(d[STINGER_EDGE_DEST] == (d[w] - 1)) {
	partial[STINGER_EDGE_DEST] += frac(paths[STINGER_EDGE_DEST],paths[w]) * (1 + partial[w]);
      }
    } STINGER_FORALL_EDGES_OF_VTX_END();
    bc[w] += partial[w];
  }

  free(d);
  free(partial);
  free(paths);
}
Beispiel #8
0
int64_t
st_conn_stinger (const struct stinger *G, const int64_t nv, const int64_t ne,
                 const int64_t * sources, const int64_t num,
                 const int64_t numSteps)
{
  int64_t k, x;

  int64_t *Q_big = (int64_t *) xmalloc (INC * nv * sizeof (int64_t));
  int64_t *marks_s_big = (int64_t *) xmalloc (INC * nv * sizeof (int64_t));
  int64_t *marks_t_big = (int64_t *) xmalloc (INC * nv * sizeof (int64_t));
  int64_t *QHead_big =
    (int64_t *) xmalloc (INC * 2 * numSteps * sizeof (int64_t));
  int64_t *neighbors_big = (int64_t *) xmalloc (INC * ne * sizeof (int64_t));

  int64_t count = 0;

  k = 0;
  x = 0;

  OMP ("omp parallel for")
    MTA ("mta assert parallel")
    MTA ("mta loop future")
    MTA ("mta assert nodep")
    MTA ("mta assert no alias")
    for (x = 0; x < INC; x++) {
      int64_t *Q = Q_big + x * nv;
      int64_t *marks_s = marks_s_big + x * nv;
      int64_t *marks_t = marks_t_big + x * nv;
      int64_t *QHead = QHead_big + x * 2 * numSteps;
      int64_t *neighbors = neighbors_big + x * ne;

      for (int64_t claimedk = stinger_int64_fetch_add (&k, 2);
           claimedk < 2 * num; claimedk = stinger_int64_fetch_add (&k, 2)) {
        int64_t s = sources[claimedk];
        int64_t deg_s = stinger_outdegree (G, s);
        int64_t t = sources[claimedk + 1];
        int64_t deg_t = stinger_outdegree (G, t);

        if (deg_s == 0 || deg_t == 0) {
          stinger_int64_fetch_add (&count, 1);
        } else {
          bfs_stinger (G, nv, ne, s, marks_s, numSteps, Q, QHead, neighbors);
          bfs_stinger (G, nv, ne, t, marks_t, numSteps, Q, QHead, neighbors);
          int64_t local_count = 0;

          MTA ("mta assert nodep")
            for (int64_t j = 0; j < nv; j++) {
              if (marks_s[j] && marks_t[j])
                stinger_int64_fetch_add (&local_count, 1);
            }

          if (local_count == 0)
            stinger_int64_fetch_add (&count, 1);
        }
      }
    }

  free (neighbors_big);
  free (QHead_big);
  free (marks_t_big);
  free (marks_s_big);
  free (Q_big);

  return count;

}