Value Filter::evaluate() const { Value v = m_expr->evaluate(); NodeSet& nodes = v.modifiableNodeSet(); nodes.sort(); EvaluationContext& evaluationContext = Expression::evaluationContext(); for (unsigned i = 0; i < m_predicates.size(); i++) { OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create()); evaluationContext.size = nodes.size(); evaluationContext.position = 0; for (unsigned j = 0; j < nodes.size(); j++) { Node* node = nodes[j]; evaluationContext.node = node; ++evaluationContext.position; if (m_predicates[i]->evaluate()) newNodes->append(node); } nodes.swap(*newNodes); } return v; }
void Step::evaluate(EvaluationContext& evaluationContext, Node* context, NodeSet& nodes) const { evaluationContext.position = 0; nodesInAxis(evaluationContext, context, nodes); // Check predicates that couldn't be merged into node test. for (unsigned i = 0; i < m_predicates.size(); i++) { Predicate* predicate = m_predicates[i].get(); OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create()); if (!nodes.isSorted()) newNodes->markSorted(false); for (unsigned j = 0; j < nodes.size(); j++) { Node* node = nodes[j]; evaluationContext.node = node; evaluationContext.size = nodes.size(); evaluationContext.position = j + 1; if (predicate->evaluate(evaluationContext)) newNodes->append(node); } nodes.swap(*newNodes); } }
void LocationPath::evaluate(NodeSet& nodes) const { bool resultIsSorted = nodes.isSorted(); for (unsigned i = 0; i < m_steps.size(); i++) { Step* step = m_steps[i]; OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create()); HashSet<Node*> newNodesSet; bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis && step->axis() != Step::DescendantAxis && step->axis() != Step::DescendantOrSelfAxis && step->axis() != Step::AttributeAxis); if (needToCheckForDuplicateNodes) resultIsSorted = false; // This is a simplified check that can be improved to handle more cases. if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis)) newNodes->markSubtreesDisjoint(true); for (unsigned j = 0; j < nodes.size(); j++) { OwnPtrWillBeRawPtr<NodeSet> matches(NodeSet::create()); step->evaluate(nodes[j], *matches); if (!matches->isSorted()) resultIsSorted = false; for (size_t nodeIndex = 0; nodeIndex < matches->size(); ++nodeIndex) { Node* node = (*matches)[nodeIndex]; if (!needToCheckForDuplicateNodes || newNodesSet.add(node).isNewEntry) newNodes->append(node); } } nodes.swap(*newNodes); } nodes.markSorted(resultIsSorted); }
int DA_blockPartStage3(std::vector<TreeNode> &nodes, std::vector<TreeNode>& globalCoarse, std::vector<ot::TreeNode>& minsAllBlocks, unsigned int dim, unsigned int maxDepth, MPI_Comm commActive) { #ifdef __PROF_WITH_BARRIER__ MPI_Barrier(commActive); #endif PROF_BLKPART3_BEGIN int npesActive, rankActive; MPI_Comm_rank(commActive, &rankActive); MPI_Comm_size(commActive, &npesActive); int *sendCnt = new int[npesActive]; int *recvCnt = new int[npesActive]; int *sendOffsets = new int[npesActive]; int *recvOffsets = new int[npesActive]; TreeNode rootNode (dim,maxDepth); // Now communicate the nodes ... //7. Determine locally which keys to send to which proc ... //Compute Dist on globalCoarse.... TreeNode *sendMin; std::vector<ot::TreeNode> vtkDist(npesActive); if (!globalCoarse.empty()) { sendMin = (TreeNode *)&(*(globalCoarse.begin())); } else { sendMin = &(rootNode); } par::Mpi_Allgather<ot::TreeNode>(sendMin, &(* vtkDist.begin()), 1, commActive); minsAllBlocks.clear(); for(int j = 0; j < npesActive; j++) { if(vtkDist[j] != rootNode) { minsAllBlocks.push_back(vtkDist[j]); } }//end for j for (unsigned int j = 1; j < npesActive ; j++) { if (vtkDist[j] == rootNode) { vtkDist[j] = vtkDist[j-1]; } }//end for j // correct dist ... if (npesActive > 1) { if (vtkDist[npesActive - 1] == vtkDist[npesActive - 2]) { vtkDist[npesActive - 1] = rootNode; }//end if for (int i = npesActive - 2; i > 0; i--) { if (vtkDist[i] == vtkDist[i-1]) { vtkDist[i] = vtkDist[i+1]; }//end if }//end for }//end if npes > 1 unsigned int *part = NULL; if(!nodes.empty()) { part = new unsigned int[nodes.size()]; } if (npesActive > 1) { unsigned int pCnt=0; for (unsigned int i=0; i< nodes.size(); i++) { #ifdef __DEBUG_DA__ assert(pCnt < npesActive); #endif if ( (nodes[i] >= vtkDist[pCnt]) && ( (pCnt == (npesActive - 1)) || ( nodes[i] < vtkDist[pCnt+1] ) || (vtkDist[pCnt+1] == rootNode) ) ) { part[i] = pCnt; } else { while ( (pCnt < (npesActive -1)) && (nodes[i] >= vtkDist[pCnt+1]) && (vtkDist[pCnt+1] != rootNode) ) { pCnt++; }//end while part[i] = pCnt; }//end if-else }//end for i }//end if np>1 vtkDist.clear(); //_________________________________________________________________________ // Now the partitions should be contiguous since the two lists are globally // sorted ... and it's simply a shift between the two. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //compute the total number of nodes being sent to each proc ... for (int i = 0; i < npesActive; i++) { sendCnt[i]=0; recvCnt[i]=0; } if (npesActive > 1) { for (unsigned int i=0; i<nodes.size(); i++) { #ifdef __DEBUG_DA__ assert(part[i] < npesActive); #endif sendCnt[part[i]]++; }//end for i } else { sendCnt[0] += (nodes.size()); }//end if-else if(part) { delete [] part; part = NULL; } // communicate with other procs how many you shall be sending and get how // many to recieve from whom. par::Mpi_Alltoall<int>( sendCnt, recvCnt, 1, commActive); unsigned int totalRecv = 0; for (unsigned int i = 0; i < npesActive; i++) { totalRecv += recvCnt[i]; }//end for i sendOffsets[0] = 0; recvOffsets[0] = 0; // compute offsets ... for (int i=1; i < npesActive; i++) { sendOffsets[i] = sendOffsets[i-1] + sendCnt[i-1]; recvOffsets[i] = recvOffsets[i-1] + recvCnt[i-1]; }//end for i // Allocate for new array ... std::vector<ot::TreeNode > newNodes(totalRecv); // perform All2Allv ot::TreeNode* nodesPtr = NULL; ot::TreeNode* newNodesPtr = NULL; if(!nodes.empty()) { nodesPtr = &(*(nodes.begin())); } if(!newNodes.empty()) { newNodesPtr = &(*(newNodes.begin())); } par::Mpi_Alltoallv_sparse<ot::TreeNode>( nodesPtr, sendCnt, sendOffsets, newNodesPtr, recvCnt, recvOffsets, commActive); // reset the pointer ... nodes = newNodes; // clean up ... delete [] sendCnt; sendCnt = NULL; delete [] recvCnt; recvCnt = NULL; delete [] sendOffsets; sendOffsets = NULL; delete [] recvOffsets; recvOffsets = NULL; newNodes.clear(); PROF_BLKPART3_END } // end blockPart