예제 #1
0
//------------------------------------------------------------------------------
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);
  });
}
예제 #2
0
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));
  }
}
예제 #3
0
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++;
    }
  }
}
예제 #4
0
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();
  }
}
예제 #5
0
// 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();
  }

}
예제 #6
0
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;
}
예제 #8
0
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();
  }
}
예제 #9
0
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++;
    }
}
예제 #10
0
/** 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()));
}
예제 #11
0
//------------------------------------------------------------------------------
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); });
}