//------------------------------------------------------------------------------ bool isDominated(const BasicBlock *block, const BlockVector &blocks, const DominatorTree *dt) { return std::any_of(blocks.begin(), blocks.end(), [block, dt](BasicBlock *iter) { return block != iter && dt->dominates(iter, block); }); }
void DataFlowPass::initStates(const BlockVector& blocks, BlockStates& states) { for (BlockVector::const_iterator FI = blocks.begin(), FE = blocks.end(); FI != FE; ++FI) { const BasicBlock& block = **FI; BlockState state; initState(block, state); states.insert(BlockStatePair(&block, state)); } }
void subprod(const SiconosMatrix& A, const BlockVector& x, SiconosVector& y, const Index& coord, bool init) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); // Number of the subvector of x that handles element at position coord[4] std::size_t firstBlockNum = x.getNumVectorAtPos(coord[4]); // Number of the subvector of x that handles element at position coord[5] unsigned int lastBlockNum = x.getNumVectorAtPos(coord[5]); Index subCoord = coord; SPC::SiconosVector tmp = x[firstBlockNum]; std::size_t subSize = tmp->size(); // Size of the sub-vector const SP::Index xTab = x.tabIndex(); if (firstBlockNum != 0) { subCoord[4] -= (*xTab)[firstBlockNum - 1]; subCoord[5] = std::min(coord[5] - (*xTab)[firstBlockNum - 1], subSize); } else subCoord[5] = std::min(coord[5], subSize); if (firstBlockNum == lastBlockNum) { subprod(A, *tmp, y, subCoord, init); } else { unsigned int xPos = 0 ; // Position in x of the current sub-vector of x bool firstLoop = true; subCoord[3] = coord[2] + subCoord[5] - subCoord[4]; for (VectorOfVectors::const_iterator it = x.begin(); it != x.end(); ++it) { if ((*it)->getNum() == 0) SiconosMatrixException::selfThrow("subprod(A,x,y) error: not yet implemented for x block of blocks ..."); if (xPos >= firstBlockNum && xPos <= lastBlockNum) { tmp = x[xPos]; if (firstLoop) { subprod(A, *tmp, y, subCoord, init); firstLoop = false; } else { subCoord[2] += subCoord[5] - subCoord[4]; // !! old values for 4 and 5 subSize = tmp->size(); subCoord[4] = 0; subCoord[5] = std::min(coord[5] - (*xTab)[xPos - 1], subSize); subCoord[3] = subCoord[2] + subCoord[5] - subCoord[4]; subprod(A, *tmp, y, subCoord, false); } } xPos++; } } }
void prod(const SiconosVector& x, const SiconosMatrix& A, BlockVector& y, bool init) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); unsigned int startRow = 0; VectorOfVectors::const_iterator it; // For Each subvector of y, y[i], private_prod computes y[i] = subA x, subA being a submatrix of A corresponding to y[i] position. // private_prod takes into account the fact that x and y[i] may be block vectors. for (it = y.begin(); it != y.end(); ++it) { private_prod(createSPtrConstSiconosVector(x), createSPtrConstSiconosMatrix(A), startRow, *it, init); startRow += (*it)->size(); } }
// Copy from BlockVector SiconosVector::SiconosVector(const BlockVector & vIn) : std11::enable_shared_from_this<SiconosVector>() { if (ask<IsDense>(**(vIn.begin()))) // dense { _dense = true; vect.Dense = new DenseVect(vIn.size()); } else { _dense = false; vect.Sparse = new SparseVect(vIn.size()); } VectorOfVectors::const_iterator it; unsigned int pos = 0; for (it = vIn.begin(); it != vIn.end(); ++it) { setBlock(pos, **it); pos += (*it)->size(); } }
void private_addprod(const SiconosMatrix& A, unsigned int startRow, unsigned int startCol, const BlockVector& x, SiconosVector& y) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); assert(!A.isBlock() && "private_addprod(A,start,x,y) error: not yet implemented for block matrix."); VectorOfVectors::const_iterator it; unsigned int startColBis = startCol; for (it = x.begin(); it != x.end(); ++it) { private_addprod(A, startRow, startColBis, **it, y); startColBis += (*it)->size(); } }
// // Helper function for printing out dominator information. // void LicmPass::showDominators(const BlockVector& blocks, BlockStates& states, BasicBlock* preheader) { for (BlockVector::const_iterator I = blocks.begin(), IE = blocks.end(); I != IE; ++I) { BasicBlock* block = *I; BasicBlock* idom = dominance.getIdom(states, block); cerr << block->getName().data() << " idom "; if (idom) { cerr << idom->getName().data(); } else { cerr << preheader->getName().data(); } cerr << endl; } cerr << endl; }
void prod(const SiconosMatrix& A, const BlockVector& x, SiconosVector& y, bool init) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); if (init) y.zero(); unsigned int startRow = 0; unsigned int startCol = 0; // In private_addprod, the sum of all blocks of x, x[i], is computed: y = Sum_i (subA x[i]), with subA a submatrix of A, // starting from position startRow in rows and startCol in columns. // private_prod takes also into account the fact that each block of x can also be a block. VectorOfVectors::const_iterator it; for (it = x.begin(); it != x.end(); ++it) { private_addprod(A, startRow, startCol, **it, y); startCol += (*it)->size(); } }
void SFUtils::DoTopologicalSort( SLSF::Subsystem subsystem ) { int vertexIndex = 0; VertexIndexBlockMap vertexIndexBlockMap; BlockVertexIndexMap blockVertexIndexMap; BlockVector blockVector = subsystem.Block_kind_children(); for( BlockVector::iterator blvItr = blockVector.begin(); blvItr != blockVector.end(); ++blvItr, ++vertexIndex ) { SLSF::Block block = *blvItr; vertexIndexBlockMap[ vertexIndex ] = block; blockVertexIndexMap[ block ] = vertexIndex; std::string blockType = block.BlockType(); if ( blockType == "UnitDelay" ) { // check on other delay blocks as well ... ++vertexIndex; // UnitDelay is vertexed twice - one for outputs (timestep n-1), and one for inputs: vertexIndex is as destination, vertexIndex + 1 is as source } } Graph graph( vertexIndex ); LineSet lineSet = subsystem.Line_kind_children(); for( LineSet::iterator lnsItr = lineSet.begin(); lnsItr != lineSet.end() ; ++lnsItr ) { SLSF::Line line = *lnsItr; SLSF::Port sourcePort = line.srcLine_end(); SLSF::Port destinationPort = line.dstLine_end(); SLSF::Block sourceBlock = sourcePort.Block_parent(); SLSF::Block destinationBlock = destinationPort.Block_parent(); if ( sourceBlock == subsystem || destinationBlock == subsystem ) continue; int sourceBlockVertexIndex = blockVertexIndexMap[ sourceBlock ]; if ( static_cast< std::string >( sourceBlock.BlockType() ) == "UnitDelay" ) { ++sourceBlockVertexIndex; } int destinationBlockVertexIndex = blockVertexIndexMap[ destinationBlock ]; boost::add_edge( sourceBlockVertexIndex, destinationBlockVertexIndex, graph ); } LoopDetector loopDetector( graph ); if ( loopDetector.check() ) { // TODO: add support for loops involving integrator and other stateful blocks // Determine what Blocks caused the loop typedef std::map< Vertex, int > VertexStrongComponentIndexMap; VertexStrongComponentIndexMap vertexStrongComponentIndexMap; boost::associative_property_map< VertexStrongComponentIndexMap > apmVertexStrongComponentIndexMap( vertexStrongComponentIndexMap ); strong_components( graph, apmVertexStrongComponentIndexMap ); typedef std::vector< Vertex > VertexVector; typedef std::map< int, VertexVector > StrongComponentIndexVertexGroupMap; StrongComponentIndexVertexGroupMap strongComponentIndexVertexGroupMap; for( VertexStrongComponentIndexMap::iterator vsmItr = vertexStrongComponentIndexMap.begin(); vsmItr != vertexStrongComponentIndexMap.end(); ++vsmItr ) { strongComponentIndexVertexGroupMap[ vsmItr->second ].push_back( vsmItr->first ); } std::string error( "Dataflow Graph '" + static_cast< std::string >( subsystem.Name() ) + "' has unhandled loops: " ); for( StrongComponentIndexVertexGroupMap::iterator svmItr = strongComponentIndexVertexGroupMap.begin(); svmItr != strongComponentIndexVertexGroupMap.end(); ++svmItr ) { VertexVector vertexVector = svmItr->second; if ( vertexVector.size() <= 1 ) continue; error.append( "\n" ); for( VertexVector::iterator vtvItr = vertexVector.begin(); vtvItr != vertexVector.end(); ++vtvItr ) { error.append( blockVector[ *vtvItr ].getPath("/") ); error.append( ", " ); } error.erase( error.size() - 2 ); } throw udm_exception(error); } typedef std::set< Vertex > VertexSet; typedef std::map< int, VertexSet > PriorityVertexSetMap; PriorityVertexSetMap priorityVertexSetMap; for( BlockVector::iterator blvItr = blockVector.begin() ; blvItr != blockVector.end() ; ++blvItr ) { SLSF::Block block = *blvItr; int priority = block.Priority(); if ( priority == 0 ) continue; Vertex vertex = blockVertexIndexMap[ block ]; priorityVertexSetMap[ priority ].insert( vertex ); } if ( priorityVertexSetMap.size() > 1 ) { PriorityVertexSetMap::iterator lstPvmItr = priorityVertexSetMap.end(); --lstPvmItr; for( PriorityVertexSetMap::iterator pvmItr = priorityVertexSetMap.begin() ; pvmItr != lstPvmItr ; ) { PriorityVertexSetMap::iterator nxtPvmItr = pvmItr; ++nxtPvmItr; VertexSet &higherPriorityVertexSet = pvmItr->second; VertexSet &lowerPriorityVertexSet = nxtPvmItr->second; for( VertexSet::iterator hvsItr = higherPriorityVertexSet.begin() ; hvsItr != higherPriorityVertexSet.end() ; ++hvsItr ) { for( VertexSet::iterator lvsItr = lowerPriorityVertexSet.begin() ; lvsItr != lowerPriorityVertexSet.end() ; ++lvsItr ) { boost::add_edge( *hvsItr, *lvsItr, graph ); LoopDetector loopDetector( graph ); if ( loopDetector.check( *hvsItr ) ) { SLSF::Block higherPriorityBlock = vertexIndexBlockMap[ *hvsItr ]; SLSF::Block lowerPriorityBlock = vertexIndexBlockMap[ *lvsItr ]; std::cerr << "WARNING: Cannot implement priority difference between block \"" << higherPriorityBlock.getPath( "/" ) << "\" (Priority = " << *hvsItr << ") and " << std::endl; std::cerr << " block \"" << lowerPriorityBlock.getPath( "/" ) << "\" (Priority = " << *lvsItr << "): contradicts topology of subsystem or other implemented block priority order." << std::endl; boost::remove_edge( *hvsItr, *lvsItr, graph ); } } } pvmItr = nxtPvmItr; } } VertexList vertexList; boost::topological_sort( graph, std::back_inserter( vertexList ) ); /* PUT ALL "DataStoreMemory" BLOCKS AT END OF "C" SO THEY HAVE HIGHEST PRIORITY */ VertexList::reverse_iterator vtlRit = vertexList.rbegin(); while( vtlRit != vertexList.rend() ) { int index = *vtlRit; SLSF::Block block = vertexIndexBlockMap[ index ]; (void)++vtlRit; if ( block != Udm::null && static_cast< std::string >( block.BlockType() ) == "DataStoreMemory" ) { VertexList::reverse_iterator vtlRit2 = vtlRit; vertexList.splice( vertexList.end(), vertexList, vtlRit2.base() ); } } int priority = 0; for( VertexList::reverse_iterator vtlRit = vertexList.rbegin() ; vtlRit != vertexList.rend() ; ++vtlRit ) { int index = *vtlRit; SLSF::Block block = vertexIndexBlockMap[ index ]; if ( block == Udm::null ) { // unit delay as source is not registered - we will invoke it initially, and invoke it as destination in the priority order // const std::string& bt = blk.BlockType(); // assert(bt.compare("UnitDelay") == 0); /* Unit Delay Block as destination */ continue; } block.Priority() = priority++; } }
/** Extract the master block from <code>problem</code>. * The constructor also sets up the solver for the newly created master * block. The master block can only be extracted if all sub-blocks have * already been extracted. * @param problem The problem from which to extract the master. * @param blocks The sub blocks that have already been extracted. */ BendersOpt::Block::Block(Problem const *problem, BlockVector const &blocks) : env(), number(-1), vars(0), rows(0), cplex(0), cb(0) { IloNumVarArray problemVars = problem->getVariables(); IloRangeArray problemRanges = problem->getRows(); IloExpr masterObj(env); IloNumVarArray masterVars(env); IloRangeArray masterRows(env); // Find columns that do not intersect block variables and // copy them to the master block. IdxMap idxMap; RowSet rowSet; for (IloInt j = 0; j < problemVars.getSize(); ++j) { IloNumVar x = problemVars[j]; if ( problem->getBlock(x) < 0 ) { // Column is not in a block. Copy it to the master. IloNumVar v(env, x.getLB(), x.getUB(), x.getType(), x.getName()); varMap.insert(VarMap::value_type(v, x)); masterObj += problem->getObjCoef(x) * v; idxMap[x] = masterVars.getSize(); masterVars.add(v); } else { // Column is in a block. Collect all rows that intersect // this column. RowSet const &intersected = problem->getIntersectedRows(x); for (RowSet::const_iterator it = intersected.begin(); it != intersected.end(); ++it) rowSet.insert(*it); idxMap[x] = -1; } } // Pick up the rows that we need to copy. // These are the rows that are only intersected by master variables, // that is, the rows that are not in any block's rowset. for (IloInt i = 0; i < problemRanges.getSize(); ++i) { IloRange r = problemRanges[i]; if ( rowSet.find(r) == rowSet.end() ) { IloRange masterRow(env, r.getLB(), r.getUB(), r.getName()); IloExpr lhs(env); for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it) { lhs += it.getCoef() * masterVars[idxMap[it.getVar()]]; } masterRow.setExpr(lhs); masterRows.add(masterRow); } } // Adjust variable indices in blocks so that reference to variables // in the original problem become references to variables in the master. for (BlockVector::const_iterator b = blocks.begin(); b != blocks.end(); ++b) { for (std::vector<FixData>::iterator it = (*b)->fixed.begin(); it != (*b)->fixed.end(); ++it) it->col = idxMap[problemVars[it->col]]; } // Create the eta variables, one for each block. // See the comments at the top of this file for details about the // eta variables. IloInt const firsteta = masterVars.getSize(); for (BlockVector::size_type i = 0; i < blocks.size(); ++i) { std::stringstream s; s << "_eta" << i; IloNumVar eta(env, 0.0, IloInfinity, s.str().c_str()); masterObj += eta; masterVars.add(eta); } // Create model and solver instance vars = masterVars; rows = masterRows; IloModel model(env); model.add(obj = IloObjective(env, masterObj, problem->getObjSense())); model.add(vars); model.add(rows); cplex = IloCplex(model); cplex.use(cb = new (env) LazyConstraintCallback(env, this, blocks, firsteta)); for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it) objMap.insert(ObjMap::value_type(it.getVar(), it.getCoef())); }
//------------------------------------------------------------------------------ bool postdominatesAll(const BasicBlock *block, const BlockVector &blocks, const PostDominatorTree *pdt) { return std::all_of( blocks.begin(), blocks.end(), [block, pdt](BasicBlock *iter) { return pdt->dominates(block, iter); }); }