void reduce(const Vertex rootVertex, const Vertex srcVertex, Op op, const std::vector<T_Data> sendData, std::vector<T_Data>& recvData){
	    static std::vector<T_Data> reduce;
	    static std::vector<T_Data>* rootRecvData;
	    static unsigned vertexCount = 0;
	    static bool hasRootVertex = false;


	    VAddr rootVAddr   = locateVertex(graph, rootVertex);
	    VAddr srcVAddr    = locateVertex(graph, srcVertex);
	    Context context   = getGraphContext(graph);
	    std::vector<Vertex> vertices = getHostedVertices(graph, srcVAddr);

	    vertexCount++;

	    if(reduce.empty()){
		reduce = std::vector<T_Data>(sendData.size(), 0);
	    }

	    // Reduce locally
	    std::transform(reduce.begin(), reduce.end(), sendData.begin(), reduce.begin(), op);

	    // Remember pointer of recvData from rootVertex
	    if(rootVertex.id == srcVertex.id){
		hasRootVertex = true;
		rootRecvData = &recvData;
	    }

	    // Finally start reduction
	    if(vertexCount == vertices.size()){

		if(hasRootVertex){
		    cal.reduce(rootVAddr, context, op, reduce, *rootRecvData);
		}
		else{
		    cal.reduce(rootVAddr, context, op, reduce, recvData);

		}

		reduce.clear();
		vertexCount = 0;
	    }
	    assert(vertexCount <= vertices.size());

	}
	/**
	 * @brief Returns a set of all host peer VAddrs of the *graph*
	 *
	 */
	std::vector<VAddr> getGraphHostVAddrs(Graph& graph){
	    std::vector<Vertex> vertices = graph.getVertices();

	    std::set<VAddr> vAddrs;
	    for(Vertex vertex : vertices){
		vAddrs.insert(locateVertex(graph, vertex));
	    }

	    return std::vector<VAddr>(vAddrs.begin(), vAddrs.end());

	}
	void allGather(const Vertex srcVertex, T_Send sendData, T_Recv& recvData, const bool reorder){
	    typedef typename T_Send::value_type T_Send_Container;
	
	    static std::vector<T_Send_Container> gather;
	    static std::vector<T_Recv*> recvDatas;

	    VAddr srcVAddr  = locateVertex(graph, srcVertex);
	    Context context = getGraphContext(graph);
	    std::vector<Vertex> vertices = getHostedVertices(graph, srcVAddr);

	    gather.insert(gather.end(), sendData.begin(), sendData.end());
	    recvDatas.push_back(&recvData);


	    if(gather.size() == vertices.size()){
		std::vector<unsigned> recvCount;

		cal.allGatherVar(context, gather, *(recvDatas[0]), recvCount);

		if(reorder){
		    std::vector<typename T_Recv::value_type> recvDataReordered(recvData.size());
		    unsigned vAddr = 0;
		    for(unsigned recv_i = 0; recv_i < recvData.size(); ){
			std::vector<Vertex> hostedVertices = getHostedVertices(graph, vAddr);
			for(Vertex v: hostedVertices){
			    recvDataReordered.at(v.id) = recvDatas[0]->data()[recv_i];
			    recv_i++;
			}
			vAddr++;
		    }
		    for(unsigned i = 0; i < recvDataReordered.size(); ++i){
			recvDatas[0]->data()[i] = recvDataReordered[i];
		    }
		    
		}

		// Distribute Received Data to Hosted Vertices
		//unsigned nElements = std::accumulate(recvCount.begin(), recvCount.end(), 0);
		for(unsigned i = 1; i < recvDatas.size(); ++i){
		    std::copy(recvDatas[0]->begin(), recvDatas[0]->end(), recvDatas[i]->begin());

		}
	    
		gather.clear();


	    }

	}
Exemplo n.º 4
0
void VertexCluster::calculateWeights()
{
	//为了速度,尽可能不调用外部函数,少用循环
	//Common::timeBegin();

	int i,j,k;
	int a,b,c;
	D3DXVECTOR3 vab,vbc,vca;
	float lab,lbc,lca;
	float abc,bca,cab;
	double lsum=0.0f;

	for(i=0;i<mIndicesNum;i+=3)
	{
		a=mIndices[i];
		b=mIndices[i+1];
		c=mIndices[i+2];

		vab=*locateVertex(b)-*locateVertex(a);
		vbc=*locateVertex(c)-*locateVertex(b);
		vca=*locateVertex(c)-*locateVertex(a);
		//为了速度,把sqrt省了
		lab=sqrt(vab.x*vab.x+vab.y*vab.y+vab.z*vab.z);  lsum+=lab;
		lbc=sqrt(vbc.x*vbc.x+vbc.y*vbc.y+vbc.z*vbc.z);  lsum+=lbc;
		lca=sqrt(vca.x*vca.x+vca.y*vca.y+vca.z*vca.z);  lsum+=lca;

		mEdgeLengths[a]=max(mEdgeLengths[a],lab);  mEdgeLengths[b]=max(mEdgeLengths[b],lab);
		mEdgeLengths[b]=max(mEdgeLengths[b],lbc);  mEdgeLengths[c]=max(mEdgeLengths[c],lbc);
		mEdgeLengths[c]=max(mEdgeLengths[c],lca);  mEdgeLengths[a]=max(mEdgeLengths[a],lca);

		vab/=lab; vbc/=lbc; vca/=lca;

		abc=-vab.x*vbc.x-vab.y*vbc.y-vab.z*vbc.z;
		bca=-vbc.x*vca.x-vbc.y*vca.y-vbc.z*vca.z;
		cab=-vca.x*vab.x-vca.y*vab.y-vca.z*vab.z;

		mAngles[b]=max(mAngles[b],abc);
		mAngles[c]=max(mAngles[c],bca);
		mAngles[a]=max(mAngles[a],cab);
	}
	mAvgEdgeLength=lsum/double(mIndicesNum);

	for(i=0;i<mVerticesNum;i++)
	{
		mWeights[i].mID=i;
		mWeights[i].mWeight=mAngles[i]*MESH_LOD_ANGLE_FACTOR+mEdgeLengths[i]*MESH_LOD_EDGE_LENGTH_FACTOR;
		// Common::log("*****id ",i);
		// Common::log("mAngles ",mAngles[i]);
		// Common::log("mEdgeLengths ",mEdgeLengths[i]);
		// Common::log("mWeight ",mWeights[i].mWeight);
	}
	//Common::log("mAvgEdgeLength",mAvgEdgeLength);

	//Common::log("dTime", Common::timeEnd());
}
	void allReduce(const Vertex srcVertex, Op op, const std::vector<T_Data> sendData, T_Recv& recvData){

	    static std::vector<T_Data> reduce;
	    static unsigned vertexCount = 0;
	    static std::vector<T_Recv*> recvDatas;

	    VAddr srcVAddr    = locateVertex(graph, srcVertex);
	    Context context   = getGraphContext(graph);
	    std::vector<Vertex> vertices = getHostedVertices(graph, srcVAddr);

	    recvDatas.push_back(&recvData);
	
	    vertexCount++;

	    if(reduce.empty()){
		reduce = std::vector<T_Data>(sendData.size(), 0);
	    }

	    // Reduce locally
	    std::transform(reduce.begin(), reduce.end(), sendData.begin(), reduce.begin(), op);

	    // Finally start reduction
	    if(vertexCount == vertices.size()){

		cal.allReduce(context, op, reduce, *(recvDatas[0]));

		// Distribute Received Data to Hosted Vertices
		for(unsigned i = 1; i < recvDatas.size(); ++i){
		    std::copy(recvDatas[0]->begin(), recvDatas[0]->end(), recvDatas[i]->begin());

		}
	    

		reduce.clear();
		vertexCount = 0;
	    }
	    assert(vertexCount <= vertices.size());

	}
      void gather(const Vertex rootVertex, const Vertex srcVertex, const T_Send sendData, T_Recv& recvData, const bool reorder){
	typedef typename T_Send::value_type SendValueType;
	typedef typename T_Recv::value_type RecvValueType;
	
	static std::vector<SendValueType> gather;
	static T_Recv* rootRecvData     = NULL;
	static bool peerHostsRootVertex = false;
	static unsigned nGatherCalls    = 0;

	nGatherCalls++;

	VAddr rootVAddr  = locateVertex(graph, rootVertex);
	Context context  = getGraphContext(graph);

	// Insert data of srcVertex to the end of the gather vector
	gather.insert(gather.end(), sendData.begin(), sendData.end());

	// Store recv pointer of rootVertex
	if(srcVertex.id == rootVertex.id){
	  rootRecvData = &recvData;
	  peerHostsRootVertex = true;
	}

	if(nGatherCalls == hostedVertices.size()){
	  std::vector<unsigned> recvCount;
	  std::vector<unsigned> prefixsum(context.size(),0);

	  if(peerHostsRootVertex){
	    cal.gatherVar(rootVAddr, context, gather, *rootRecvData, recvCount);

	    // TODO
	    // std::partial_sum might do the job
	    unsigned sum = 0;
	    for(unsigned count_i = 0; count_i < recvCount.size(); ++count_i){
	      prefixsum[count_i] = sum;
	      sum += recvCount[count_i];
	    }
		    
	    // Reordering code
	    if(reorder){
	      std::vector<RecvValueType> recvDataReordered(recvData.size());
	      for(unsigned vAddr = 0; vAddr < context.size(); vAddr++){
		std::vector<Vertex> hostedVertices = getHostedVertices(graph, vAddr);
		unsigned nElementsPerVertex = recvCount.at(vAddr) / hostedVertices.size();

		unsigned hVertex_i=0;
		for(Vertex v: hostedVertices){

		  std::copy(rootRecvData->begin()+(prefixsum[vAddr] + (hVertex_i * nElementsPerVertex)),
			    rootRecvData->begin()+(prefixsum[vAddr] + (hVertex_i * nElementsPerVertex)) + (nElementsPerVertex),
			    recvDataReordered.begin()+(v.id*nElementsPerVertex));
		  hVertex_i++;

		}
			    
	      }
	      std::copy(recvDataReordered.begin(), recvDataReordered.end(), rootRecvData->begin());

	    }
		
	  }
	  else {
	    cal.gatherVar(rootVAddr, context, gather, recvData, recvCount);
	  }
	    
	  gather.clear();
	  nGatherCalls = 0;

	}

      }
	Event asyncRecv(const Vertex srcVertex, const Edge edge, T& data){
	    VAddr srcVAddr = locateVertex(graph, srcVertex);
	    Context context  = getGraphContext(graph);
	    return cal.asyncRecv(srcVAddr, edge.id, context, data);

	}
	inline void recv(const Vertex srcVertex, const Edge edge, T& data){
	    VAddr srcVAddr   = locateVertex(graph, srcVertex);
	    Context context  = getGraphContext(graph);
	    cal.recv(srcVAddr, edge.id, context, data);

	}
	Event asyncSend(const Vertex destVertex, const Edge edge, const T& data){
	    VAddr destVAddr  = locateVertex(graph, destVertex);
	    Context context  = getGraphContext(graph);
	    return cal.asyncSend(destVAddr, edge.id, context, data);
	
	}
Exemplo n.º 10
0
	inline void send(const Vertex destVertex, const Edge edge, const T& data){
	    VAddr destVAddr   = locateVertex(graph, destVertex);
	    Context context   = getGraphContext(graph);
	    cal.send(destVAddr, edge.id, context, data);

	}
Exemplo n.º 11
0
//debug!vb也应该生成一个新的!
void VertexCluster::generateLOD(float level,ID3D10BufferPtr &vb,ID3D10BufferPtr &ib,UINT &ibLength)  //mVertexValueCreated=true
{

	 //Common::timeBegin();


	D3D10_BUFFER_DESC desc;
	desc.BindFlags= D3D10_BIND_INDEX_BUFFER;
	desc.CPUAccessFlags=0;
	desc.MiscFlags=0;
	desc.Usage=D3D10_USAGE_DEFAULT;

	D3D10_SUBRESOURCE_DATA initData;

	if(level<=0.0f)
	{
		vb=mOriginalVB;
		ib=mOriginalIB;
		ibLength=mIndicesNum;
		return ;
	}

	mTolerance=getGridSize(level);
	mHashTable->init(mTolerance);

	//Common::log("mTolerance",mTolerance);

	int i,ri;
	for(i=0;i<mVerticesNum;i++)
	{
		ri=mWeights[i].mID;
		mHashTable->addVertex(ri,locateVertex(ri),mWeights[i].mWeight); 
	}

	ibLength=0;
	int a,b,c;
	int ra,rb,rc;
	for(i=0;i<mIndicesNum;i+=3)
	{
		a=mIndices[i];
		b=mIndices[i+1];
		c=mIndices[i+2];

		ra=mHashTable->getReplacedID(a);
		rb=mHashTable->getReplacedID(b);
		rc=mHashTable->getReplacedID(c);

		if(ra!=rb && ra!=rc && rb!=rc)
		{
			mLODIB[ibLength++]=ra;
			mLODIB[ibLength++]=rb;
			mLODIB[ibLength++]=rc;


			//Common::log("lod face index a",ra);
			//Common::log("lod face index b",rb);
			//Common::log("lod face index c",rc);
		}
	}

	//for(i=0;i<mVerticesNum;i++)
	//	Common::log("ReplacedID",mHashTable->getReplacedID(i));

	//Common::log("LOD generated! with Indices num",ibLength);
	if(ibLength==0)
	{
		vb=NULL;
		ib=NULL;
		return;
	}
	desc.ByteWidth=sizeof(DWORD)*ibLength;
	initData.pSysMem=mLODIB;
	mDevice->CreateBuffer(&desc,&initData,&ib);


	// for(i=0;i<ibLength;i++)
	//	Common::log("IB",mLODIB[i]);


	desc.BindFlags=D3D10_BIND_VERTEX_BUFFER;
	desc.ByteWidth=mStride*mHashTable->getCellsNum();
	initData.pSysMem=mHashTable->getCellsVB();
	mDevice->CreateBuffer(&desc,&initData,&vb);



	//  for(i=0;i<mHashTable->getCellsNum();i++)
	//	Common::log("LOD VB",*mHashTable->locateVertex(i));



	//Common::log("LOD generating time",Common::timeEnd());
}