void ParallelBFS::calculate(NodeId root) {
  distance.assign((size_t) vertex_count, infinity);
  NodeId level = 1;
  NodeList frontier;
  frontier.reserve((size_t)vertex_count);
  if (comm.rank() == find_owner(root)) {
    frontier.push_back(root - first_vertex);
    distance[root - first_vertex] = 0;
  }
  std::vector<NodeList> send_buf((size_t)comm.size());
  NodeList new_frontier;

  NodeList sizes((size_t)comm.size()),
           displacements((size_t)comm.size());

  while (mpi::all_reduce(comm, (NodeId)frontier.size(),
                         std::plus<NodeId>()) > 0) {
    for (NodeId u : frontier)
      for (int e = vertices[u]; e < vertices[u + 1]; ++e) {
        int v = edges[e];
        send_buf[find_owner(v)].push_back(v);
      }
    for (int i = 0; i < comm.size(); ++i) {
      mpi::gather(comm, (NodeId)send_buf[i].size(), sizes.data(), i);
      if (i == comm.rank()) {
        for (int j = 1; j < comm.size(); ++j)
          displacements[j] = displacements[j - 1] + sizes[j - 1];
        new_frontier.resize(
            (size_t)(displacements[comm.size()-1] + sizes[comm.size() - 1]));
        mpi::gatherv(comm, send_buf[i], new_frontier, sizes, displacements, i);
      } else {
        mpi::gatherv(comm, send_buf[i], i);
      }
    }
    for (size_t i = 0; i < comm.size(); ++i)
      send_buf[i].clear();
    frontier.clear();
    for (int v : new_frontier) {
      v -= first_vertex;
      if (distance[v] == infinity) {
        distance[v] = level;
        frontier.push_back(v);
      }
    }
    ++level;
  }
}
Esempio n. 2
0
	void sgNode::getInheritsNodes( NodeList &outlist, size_t count /*= 0*/, const StringHandleSet &classTypefilter /*= StringHandleSet()*/ )
	{
		outlist.clear();
		if(count > 0)
			outlist.reserve(count);
		else
			count = size_t(-1) - 1;

		bool doFilter = true;
		if(classTypefilter.empty())
			doFilter = false;

		size_t mycount = 0;

		if(mycount == count)
			return ;

		sg_list(sgNode*) nodeQueue;
		nodeQueue.push_back(this);

		ChildNodeMap *childMap = &m_Children;
		ChildNodeMap::const_iterator it = childMap->begin();
		while(mycount < count && !nodeQueue.empty())
		{
			sgNode *node = nodeQueue.front();
			nodeQueue.pop_front();
			// do sth.
			if(!doFilter)
			{
				outlist.push_back(node);
				++mycount;
			}
			else if(classTypefilter.find(node->GetMyClassName()) != classTypefilter.end())
			{
				outlist.push_back(node);
				++mycount;
			}

			childMap = &(node->m_Children);
			it = childMap->begin();
			for(; it!=childMap->end(); ++it)
			{
				nodeQueue.push_back(it->second);
			}

		}
	}