Example #1
0
/*
 * Finds the set of SSATmps that should be considered for allocation
 * to a full XMM register.  These are the SSATmps that satisfy all the
 * following conditions:
 *   a) it requires 2 64-bit registers
 *   b) it's defined in a load instruction
 *   c) all its uses are simple stores to memory
 *
 * The computed set of SSATmps is stored in m_fullXMMCandidates.
 */
void LinearScan::findFullXMMCandidates() {
  boost::dynamic_bitset<> notCandidates(m_irFactory->numTmps());
  m_fullXMMCandidates.reset();
  for (auto* block : m_blocks) {
    for (auto& inst : *block) {
      for (SSATmp& tmp : inst.dsts()) {
        if (tmp.numNeededRegs() == 2 && inst.isLoad()) {
          m_fullXMMCandidates[tmp.id()] = true;
        }
      }
      int idx = 0;
      for (SSATmp* tmp : inst.srcs()) {
        if (tmp->numNeededRegs() == 2 && !inst.storesCell(idx)) {
          notCandidates[tmp->id()] = true;
        }
        idx++;
      }
    }
  }
  m_fullXMMCandidates -= notCandidates;
}
Example #2
0
 void reset ()
 {
     flags_.reset();
 }
Example #3
0
std::vector<unsigned int> generateBondHashes(const ROMol &mol, boost::dynamic_bitset<>& atomsInPath,
    const std::vector<const Bond *>& bondCache,
    const std::vector<short>& isQueryBond,
    const PATH_TYPE &path, bool useBondOrder,
    std::vector<boost::uint32_t> *atomInvariants){

  PRECONDITION(!atomInvariants || atomInvariants->size() >= mol.getNumAtoms(),
               "bad atomInvariants size");

  std::vector<unsigned int> bondHashes;
  atomsInPath.reset();
  bool queryInPath=false;
  std::vector<unsigned int> atomDegrees(mol.getNumAtoms(),0);
  for(unsigned int i=0;i<path.size() && !queryInPath;++i){
    const Bond *bi = bondCache[path[i]];
    atomDegrees[bi->getBeginAtomIdx()]++;
    atomDegrees[bi->getEndAtomIdx()]++;
    atomsInPath.set(bi->getBeginAtomIdx());
    atomsInPath.set(bi->getEndAtomIdx());
    if(isQueryBond[path[i]]) queryInPath=true;
  }
  if(queryInPath){
    return bondHashes;
  }

  // -----------------
  // calculate the bond hashes:
  std::vector<unsigned int> bondNbrs(path.size(),0);
  bondHashes.reserve(path.size()+1);

  for(unsigned int i=0;i<path.size();++i){
    const Bond *bi = bondCache[path[i]];
#ifdef REPORT_FP_STATS
        if (std::find(atomsToUse.begin(), atomsToUse.end(),
                      bi->getBeginAtomIdx()) == atomsToUse.end()) {
          atomsToUse.push_back(bi->getBeginAtomIdx());
        }
        if (std::find(atomsToUse.begin(), atomsToUse.end(),
                      bi->getEndAtomIdx()) == atomsToUse.end()) {
          atomsToUse.push_back(bi->getEndAtomIdx());
        }
#endif
    for(unsigned int j=i+1;j<path.size();++j){
      const Bond *bj = bondCache[path[j]];
      if(bi->getBeginAtomIdx()==bj->getBeginAtomIdx() ||
          bi->getBeginAtomIdx()==bj->getEndAtomIdx() ||
          bi->getEndAtomIdx()==bj->getBeginAtomIdx() ||
          bi->getEndAtomIdx()==bj->getEndAtomIdx() ){
        ++bondNbrs[i];
        ++bondNbrs[j];
      }
    }
#ifdef VERBOSE_FINGERPRINTING
        std::cerr << "   bond(" << i << "):" << bondNbrs[i] << std::endl;
#endif
    // we have the count of neighbors for bond bi, compute its hash:
    unsigned int a1Hash = (*atomInvariants)[bi->getBeginAtomIdx()];
    unsigned int a2Hash = (*atomInvariants)[bi->getEndAtomIdx()];
    unsigned int deg1=atomDegrees[bi->getBeginAtomIdx()];
    unsigned int deg2=atomDegrees[bi->getEndAtomIdx()];
    if(a1Hash<a2Hash){
      std::swap(a1Hash,a2Hash);
      std::swap(deg1,deg2);
    }
    else if(a1Hash==a2Hash && deg1<deg2){
      std::swap(deg1,deg2);
    }
    unsigned int bondHash=1;
    if(useBondOrder){
      if(bi->getIsAromatic() || bi->getBondType()==Bond::AROMATIC){
        // makes sure aromatic bonds always hash as aromatic
        bondHash = Bond::AROMATIC;
      }
      else {
        bondHash = bi->getBondType();
      }
    }
    boost::uint32_t ourHash=bondNbrs[i];
    gboost::hash_combine(ourHash,bondHash);
    gboost::hash_combine(ourHash,a1Hash);
    gboost::hash_combine(ourHash,deg1);
    gboost::hash_combine(ourHash,a2Hash);
    gboost::hash_combine(ourHash,deg2);
    bondHashes.push_back(ourHash);
    //std::cerr<<"    "<<bi->getIdx()<<" "<<a1Hash<<"("<<deg1<<")"<<"-"<<a2Hash<<"("<<deg2<<")"<<" "<<bondHash<<" -> "<<ourHash<<std::endl;
  }
  return bondHashes;
}
Example #4
0
// finds all possible chiral special cases.
// at the moment this is just candidates for ring stereochemistry
void findChiralAtomSpecialCases(ROMol &mol,
                                boost::dynamic_bitset<> &possibleSpecialCases) {
  PRECONDITION(possibleSpecialCases.size() >= mol.getNumAtoms(),
               "bit vector too small");
  possibleSpecialCases.reset();
  if (!mol.getRingInfo()->isInitialized()) {
    VECT_INT_VECT sssrs;
    MolOps::symmetrizeSSSR(mol, sssrs);
  }
  boost::dynamic_bitset<> atomsSeen(mol.getNumAtoms());
  boost::dynamic_bitset<> atomsUsed(mol.getNumAtoms());
  boost::dynamic_bitset<> bondsSeen(mol.getNumBonds());

  for (ROMol::AtomIterator ait = mol.beginAtoms(); ait != mol.endAtoms();
       ++ait) {
    const Atom *atom = *ait;
    if (atomsSeen[atom->getIdx()]) continue;
    if (atom->getChiralTag() == Atom::CHI_UNSPECIFIED ||
        atom->hasProp(common_properties::_CIPCode) ||
        !mol.getRingInfo()->numAtomRings(atom->getIdx()) ||
        !atomIsCandidateForRingStereochem(mol, atom)) {
      continue;
    }
    // do a BFS from this ring atom along ring bonds and find other
    // stereochemistry candidates.
    std::list<const Atom *> nextAtoms;
    // start with finding viable neighbors
    ROMol::OEDGE_ITER beg, end;
    boost::tie(beg, end) = mol.getAtomBonds(atom);
    while (beg != end) {
      unsigned int bidx = mol[*beg]->getIdx();
      if (!bondsSeen[bidx]) {
        bondsSeen.set(bidx);
        if (mol.getRingInfo()->numBondRings(bidx)) {
          const Atom *oatom = mol[*beg]->getOtherAtom(atom);
          if (!atomsSeen[oatom->getIdx()]) {
            nextAtoms.push_back(oatom);
            atomsUsed.set(oatom->getIdx());
          }
        }
      }
      ++beg;
    }
    INT_VECT ringStereoAtoms(0);
    if (!nextAtoms.empty()) {
      atom->getPropIfPresent(common_properties::_ringStereoAtoms,
                             ringStereoAtoms);
    }

    while (!nextAtoms.empty()) {
      const Atom *ratom = nextAtoms.front();
      nextAtoms.pop_front();
      atomsSeen.set(ratom->getIdx());
      if (ratom->getChiralTag() != Atom::CHI_UNSPECIFIED &&
          !ratom->hasProp(common_properties::_CIPCode) &&
          atomIsCandidateForRingStereochem(mol, ratom)) {
        int same = (ratom->getChiralTag() == atom->getChiralTag()) ? 1 : -1;
        ringStereoAtoms.push_back(same * (ratom->getIdx() + 1));
        INT_VECT oringatoms(0);
        ratom->getPropIfPresent(common_properties::_ringStereoAtoms,
                                oringatoms);
        oringatoms.push_back(same * (atom->getIdx() + 1));
        ratom->setProp(common_properties::_ringStereoAtoms, oringatoms, true);
        possibleSpecialCases.set(ratom->getIdx());
        possibleSpecialCases.set(atom->getIdx());
      }
      // now push this atom's neighbors
      boost::tie(beg, end) = mol.getAtomBonds(ratom);
      while (beg != end) {
        unsigned int bidx = mol[*beg]->getIdx();
        if (!bondsSeen[bidx]) {
          bondsSeen.set(bidx);
          if (mol.getRingInfo()->numBondRings(bidx)) {
            const Atom *oatom = mol[*beg]->getOtherAtom(ratom);
            if (!atomsSeen[oatom->getIdx()] && !atomsUsed[oatom->getIdx()]) {
              nextAtoms.push_back(oatom);
              atomsUsed.set(oatom->getIdx());
            }
          }
        }
        ++beg;
      }
    }  // end of BFS
    if (ringStereoAtoms.size() != 0) {
      atom->setProp(common_properties::_ringStereoAtoms, ringStereoAtoms, true);
      // because we're only going to hit each ring atom once, the first atom we
      // encounter in a ring is going to end up with all the other atoms set as
      // stereoAtoms, but each of them will only have the first atom present. We
      // need to fix that. because the traverse from the first atom only
      // followed ring bonds, these things are all by definition in one ring
      // system. (Q: is this true if there's a spiro center in there?)
      INT_VECT same(mol.getNumAtoms(), 0);
      BOOST_FOREACH (int ringAtomEntry, ringStereoAtoms) {
        int ringAtomIdx =
            ringAtomEntry < 0 ? -ringAtomEntry - 1 : ringAtomEntry - 1;
        same[ringAtomIdx] = ringAtomEntry;
      }
      for (INT_VECT_CI rae = ringStereoAtoms.begin();
           rae != ringStereoAtoms.end(); ++rae) {
        int ringAtomEntry = *rae;
        int ringAtomIdx =
            ringAtomEntry < 0 ? -ringAtomEntry - 1 : ringAtomEntry - 1;
        INT_VECT lringatoms(0);
        mol.getAtomWithIdx(ringAtomIdx)
            ->getPropIfPresent(common_properties::_ringStereoAtoms, lringatoms);
        CHECK_INVARIANT(lringatoms.size() > 0, "no other ring atoms found.");
        for (INT_VECT_CI orae = rae + 1; orae != ringStereoAtoms.end();
             ++orae) {
          int oringAtomEntry = *orae;
          int oringAtomIdx =
              oringAtomEntry < 0 ? -oringAtomEntry - 1 : oringAtomEntry - 1;
          int theseDifferent = (ringAtomEntry < 0) ^ (oringAtomEntry < 0);
          lringatoms.push_back(theseDifferent ? -(oringAtomIdx + 1)
                                              : (oringAtomIdx + 1));
          INT_VECT olringatoms(0);
          mol.getAtomWithIdx(oringAtomIdx)
              ->getPropIfPresent(common_properties::_ringStereoAtoms,
                                 olringatoms);
          CHECK_INVARIANT(olringatoms.size() > 0, "no other ring atoms found.");
          olringatoms.push_back(theseDifferent ? -(ringAtomIdx + 1)
                                               : (ringAtomIdx + 1));
          mol.getAtomWithIdx(oringAtomIdx)
              ->setProp(common_properties::_ringStereoAtoms, olringatoms);
        }
        mol.getAtomWithIdx(ringAtomIdx)
            ->setProp(common_properties::_ringStereoAtoms, lringatoms);
      }

    } else {
/******************************************************************************
* Performs the actual rejection of particles.
******************************************************************************/
size_t SliceModifier::filterParticles(boost::dynamic_bitset<>& mask, TimePoint time, TimeInterval& validityInterval)
{
	// Get the required input properties.
	ParticlePropertyObject* const posProperty = expectStandardProperty(ParticleProperty::PositionProperty);
	ParticlePropertyObject* const selProperty = applyToSelection() ? inputStandardProperty(ParticleProperty::SelectionProperty) : nullptr;
	OVITO_ASSERT(posProperty->size() == mask.size());
	OVITO_ASSERT(!selProperty || selProperty->size() == mask.size());

	FloatType sliceWidth = 0;
	if(_widthCtrl) sliceWidth = _widthCtrl->getFloatValue(time, validityInterval);
	sliceWidth *= 0.5;

	Plane3 plane = slicingPlane(time, validityInterval);

	size_t na = 0;
	boost::dynamic_bitset<>::size_type i = 0;
	const Point3* p = posProperty->constDataPoint3();
	const Point3* p_end = p + posProperty->size();

	if(sliceWidth <= 0) {
		if(selProperty) {
			const int* s = selProperty->constDataInt();
			for(; p != p_end; ++p, ++s, ++i) {
				if(*s && plane.pointDistance(*p) > 0) {
					mask.set(i);
					na++;
				}
				else mask.reset(i);
			}
		}
		else {
			for(; p != p_end; ++p, ++i) {
				if(plane.pointDistance(*p) > 0) {
					mask.set(i);
					na++;
				}
				else mask.reset(i);
			}
		}
	}
	else {
		bool invert = inverse();
		if(selProperty) {
			const int* s = selProperty->constDataInt();
			for(; p != p_end; ++p, ++s, ++i) {
				if(*s && invert == (plane.classifyPoint(*p, sliceWidth) == 0)) {
					mask.set(i);
					na++;
				}
				else mask.reset(i);
			}
		}
		else {
			for(; p != p_end; ++p, ++i) {
				if(invert == (plane.classifyPoint(*p, sliceWidth) == 0)) {
					mask.set(i);
					na++;
				}
				else mask.reset(i);
			}
		}
	}
	return na;
}