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(); } }
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); }
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); }
//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()); }