예제 #1
0
  // Constructor which takes a filename, and opens a file.
  InformStream(const char *fname, int mode, Inform::Context_t oc)
    : stream_m(0), close_m(true), outputContext_m(oc), level_m(0)
  {
    PAssert(fname != 0);
    PAssert(mode == Inform::out || mode == Inform::app);

    if (oc < 0 || oc == Inform::context()) {
      if (mode == Inform::out)
	stream_m = new std::ofstream(fname, std::ios::out);
      else
	stream_m = new std::ofstream(fname, std::ios::app);
    }
  }
bool findIntersectionEndpoints(int a0, int a1, int s, int b0, int b1, int t,
                               int &left, int &right, int &stride)
{
  // We should have both domains moving in positive directions, although
  // we might have to reverse the sign on the strides.
  PAssert(a0 <= a1 && b0 <= b1);
  if (s < 0)  s = -s;
  if (t < 0)  t = -t;

  // find the left endpoint first.  If we cannot, we're done.
  if (!findLeftCommonEndpoint(a0, a1, s, b0, b1, t, left))
    return false;

  // find the least-common-multiple of the strides s and t.  This will
  // be the stride of the resulting domain, if there is one possible.  But
  // first make sure the strides are positive, since we're assuming in this
  // routine that it was called with a0 <= a1, b0 <= b1.
  stride = findLCM(s, t);

  // find the minimum of the right endpoints, and then how far we must
  // move in from this endpoint to get a point in both domains.
  int m = a1;
  if (b1 < a1)
    m = b1;
  right = m - ((m - left) % stride);

  // we were able to find an intersection
  return true;
}
int findLCM(int s, int t)
{
  // Both of the values must be positive
  PAssert(s > 0 && t > 0);

  // This code works for s < t.  If the opposite is true, swap 'em.
  int i1 = s, i2 = t;
  if (s > t) {
    s = t;
    t = i1;
    i1 = s;
    i2 = t;
  }

  // Start advancing the two probes i1 and i2 in steps of s and t, until they
  // both get to the same value.
  while (i1 != i2) {
    while (i1 < i2)
      i1 += s;
    if (i1 > i2)
      i2 += t;
  }

  // At this point, we should have i1 == i2 == LCM.
  return i1;
}
void Engine<Dim,T,CompressibleBrick>::
notify(T* &data, const ObserverEvent &event)
{
  switch (event.event())
    {
    default:
    case CompressibleBlock<T>::notifyDestruct:
      // cblock has destructed. this should never happen
      // if the engine still exists.
      PAssert(false);
      break;
    case CompressibleBlock<T>::notifyUncompress: 
      lock();
      this->restoreStrides();
      data0_m = data + this->baseOffset();
      unlock();
      break;
    case CompressibleBlock<T>::notifyCompress:
      lock();
      this->zeroStrides();
      data0_m = data;
      unlock();
      break;
    }
}
GlobalIDDataBase::GlobalID_t
GlobalIDDataBase::globalID(LayoutID_t layoutID, NodeKey_t key) const
{
  // First check if the layout is in the list of layouts that were
  // bypassed:

  Shared_t::const_iterator p = shared_m.find(layoutID);
  if (p != shared_m.end())
  {
    layoutID = p->second;
  }

  while( key != nullNodeKey() )
  {
    if (data_m[key].layoutID() == layoutID)
    {
      return data_m[key].globalID();
    }
    else
    {
      key = data_m[key].parent();
    }
  }

  // If we reach this point, then the database has been corrupted
  // or we're asking for the id from a layout that wasn't intersected.

  PAssert(false);
  return -1;
}
bool UniformGridLayoutData<Dim>::
repartition(const Partitioner &p,
	    const ContextMapper<Dim>& cmap)
{
  // We can only repartition if we have been initialized to some domain.

  PAssert(this->domain_m.size() > 0);

  // Delete existing nodes and clear all the lists.

  for (int i = 0; i < this->all_m.size(); ++i)
    delete this->all_m[i];
    
  this->all_m.clear();
  this->local_m.clear();
  this->remote_m.clear();

  // Do the new partitioning.

  partition(p,cmap);

  if (this->hasInternalGuards_m) 
    {
      this->gcFillList_m.clear();
      calcGCFillList();
    }

  // Notify all users.

  this->notify(repartitionEvent);

  return true;
}
예제 #7
0
void bar(RCBlock_t &b,Pooma::Tester & tester)
{
  PAssert(!b.isShared());

  for (int i = 0; i < 10; i++)
    tester.out() << *(b+i) << " ";

  tester.out() << std::endl;

  for (int i = 0; i < 10; i++)
    tester.out() << *b++ << " ";

  tester.out() << std::endl;

  for (int i = -10; i < 0; i++)
    tester.out() << b[i] << " ";

  tester.out() << std::endl;
#if POOMA_EXCEPTIONS
  try {
    double a = b[0];
    throw "Bounds check failed!";
  }
  catch(const Pooma::Assertion &a)
    { tester.out() << "Bounds check worked." << std::endl; }
#endif
  b -= 10;
}
int
GlobalIDDataBase::context(NodeKey_t key) const
{
  PAssert(key != nullNodeKey());
  
  return data_m[key].context();
}
ConnectorBase *ConnectionBase::connect(ConnectorBase *cb)
{
  PAssert(connected());

  // make sure we do not already have this connector; if we do, just return

  for (iterator a = begin(); a != end(); ++a)
    if (cb == *a)
      return cb;

  // this is a new one; add it to our list

  PAssert(cb != 0);
  connectors_m.push_back(cb);
  return cb;
}
ConnectionBase::~ConnectionBase()
{
  // At this point, the subclasses should have removed all
  // connections

  PAssert(size() == 0);
}
예제 #11
0
Inform::Level_t Inform::outputLevel(ID_t id) const
{
  // Find the proper connection
  InformStream *s = findStream(id);
  PAssert(s != 0);

  // Return the output level
  return s->outputLevel();
}
예제 #12
0
void Inform::setOutputLevel(Level_t newval, ID_t id)
{
  // Find the proper connection
  InformStream *s = findStream(id);
  PAssert(s != 0);

  // Change the output level
  s->setOutputLevel(newval);
}
예제 #13
0
Inform::Context_t Inform::outputContext(ID_t id) const
{
  // Find the proper connection
  InformStream *s = findStream(id);
  PAssert(s != 0);

  // Return the output context
  return s->outputContext();
}
예제 #14
0
void Inform::setOutputContext(Context_t outputContext, ID_t id)
{
  // Find the proper connection
  InformStream *s = findStream(id);
  PAssert(s != 0);

  // Change the output context
  s->setOutputContext(outputContext);
}
예제 #15
0
void Inform::close(ID_t id)
{
  // find the proper connection to close
  iterator s = streams_m.find(id);
  PAssert(s != streams_m.end());

  // delete the connection, and remove it from the map
  delete ((*s).second);
  streams_m.erase(s);
}
Engine<Dim,T,CompressibleBrickView> & 
Engine<Dim,T,CompressibleBrickView>::
operator=(const Engine<Dim,T,CompressibleBrickView> &modelEngine)
{
  if (this != &modelEngine) 
    {
      // This only works if the RHS has a valid controller pointer.
      // (Perhaps this should be legal, but I don't want to figure that
      // out right now.)
      
      PAssert(modelEngine.cblock_m.isControllerPtrValid());
      
      // Lock the new cblock until we're done copying.
      
      modelEngine.cblock_m.lock();
      
      // Lock the old one and disable notification.
      // (Only do this if the RefCountedPtr actually points to something.)
      
      if (cblock_m.isControllerPtrValid())
        {
          cblock_m.lock();
          if (cblock_m.isControllerValidUnlocked())
            {
              cblock_m.detach(this);
            }
          cblock_m.unlock();
        }
      
      // This just copies the RCPtr<CBC> so it can be done while locked.
      
      cblock_m = modelEngine.cblock_m;
      entire_m = modelEngine.entire_m;
     
        
      // Lock our own mutex to ensure that no on else tries to copy
      // or use these strides/data while this update is occuring.
      // (It is important to lock the CBC first as that is the order 
      // when notify is called())
       
      lock();
      
      data0_m  = modelEngine.data0_m;
      Base_t::operator=(modelEngine);
      
      unlock();
      
      if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
      
      // Unlock our cblock (which is also modelEngine's cblock):
        
      cblock_m.unlock();
    }
  return *this;
}
void ConnectionBase::update(ConnectorBase *cb)
{
  PAssert(connected());

  // loop through all the connectors; update them all, or just the
  // one mentioned.

  for (iterator a = begin(); a != end(); ++a)
    if (cb == 0 || cb == *a)
      (*a)->update();
}
int SparseTileLayoutData<Dim>::globalID(int i0) const
{
  // Make sure the point is in our domain.

  PAssert(Dim == 1);

  // Call the Loc version.

  Loc<Dim> loc;
  loc[0] = i0;
  return globalID(loc);
}
void Engine<Dim,T,CompressibleBrick>::init()
{
  // resetDataAndStrides gets compression dependent data from
  // the CBC. 
  // This is only called by CompressibleBrick constructors, so there
  // can't be any other viewers, and thus we don't need to lock
  // the CBC.
  
  resetDataAndStrides();
  PAssert(cblock_m.isControllerValidUnlocked());
  cblock_m.attach(this);
}
int SparseTileLayoutData<Dim>::touchesAlloc(const OtherDomain &fulld, 
					    OutIter o, 
					    const ConstructTag &ctag) const
{
  int i;

  // Figure the type of the domain resulting from the intersection

  typedef typename 
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;

  // We only need to do touches for the overlapping domain.  If there is
  // nothing left, we can just return.

  OutDomain_t d = intersect(this->domain_m, fulld);
  if (d.empty())
    return 0;

  // Create an object of this output domain type for use later.

  OutDomain_t outDomain = Pooma::NoInit();

  // Generate the type of the node pushed on the output iterator.

  typedef Node<OutDomain_t,Domain_t> OutNode_t;

  typename DomainMap<Interval<Dim>,pidx_t>::Touch_t dmti = map_m.touch(d);
  typename DomainMap<Interval<Dim>,pidx_t>::touch_iterator a;

  int count = 0;

  for( a = dmti.first ;a != dmti.second; ++a)
    {
      int nodeListIndex = (*a).second;

     
      outDomain =  intersect(a.domain(), fulld);
      PAssert(!outDomain.empty());

      // Output this block.
      
      *o = touchesConstruct(outDomain,
			    this->all_m[nodeListIndex]->allocated(),
			    this->all_m[nodeListIndex]->affinity(),
			    this->all_m[nodeListIndex]->context(),
			    this->all_m[nodeListIndex]->globalID(),
			    this->all_m[nodeListIndex]->localID(),
			    ctag);
      ++count;
    }
  return count;
}
int SparseTileLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
{
  // Make sure the point is in our domain.

  PAssert(contains(this->domain_m, loc));

  DomainMapTouchIterator<Interval<Dim>,pidx_t> dmti = 
	(map_m.touch(Interval<Dim>(loc))).first;
  DomainMapTouchIterator<Interval<Dim>,pidx_t> baditerator;
  
  PInsist(dmti!=baditerator,"Bad location requested in SparseTileLayout");
  return (*dmti).first;
}
예제 #22
0
  // A boolean function that determines if we should print out the
  // current message based on:
  //   1. The output level
  //   2. The current context settings
  //   3. Do we have somewhere to print to
  bool shouldPrint(Inform::Level_t level)
  {
    PAssert(level >= 0);

    // Definitely do not print if there is no stream
    if (stream_m == 0)
      return false;

    // Do not print if the specified message level does not match
    // our output level requirements, or we're on the wrong context.
    return (level <= level_m &&
	    (outputContext_m == Inform::context() ||
	     outputContext_m == Inform::allContexts));
  }
ConnectorBase *ConnectionBase::disconnect(ConnectorBase *cb)
{
  PAssert(connected());

  // find the connection; if we do not have it, it is an error

  for (iterator a = begin(); a != end(); ++a)
    {
      if (cb == *a)
	{
	  // we have the item; notify it and remove it from our list

	  (*a)->notify(*this, ConnectionBase::disconnectEvent);
	  connectors_m.erase(a);

	  return cb;
	}
    }

  // if we're here, its an error

  PAssert(false);
  return 0;
}
int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
{
  // Make sure the point is in our domain.

  PAssert(Dim == 4);

  // Call the Loc version.

  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  return globalID(loc);
}
예제 #25
0
bool VideoGrabber::openPlayer()
{
	PAssert( !videoPlayer, "Opening video player that already exists." );

	if( videoOutputDeviceCreate )
		videoPlayer = videoOutputDeviceCreate();

	if ( !videoPlayer ) {
		PTRACE( 1, "no video player set" );
		return false;
	}
	
	channel->AttachVideoPlayer( videoPlayer );
	
	return videoPlayer->Open( "", 0 );
}
예제 #26
0
EndPoint::EndPoint( PConfigArgs& args )
	: args(args),
#ifdef ENTERPRISE
	ldapQueried(false),
#endif
	gkForwardUnconditionaly(false),
	gkForwardNoResponse(false),
	gkForwardBusy(false),
	d( new EndPointPrivate )
{
	PAssert( !endPoint, "EndPoint already created!" );

	endPoint = this;
	Plugin::endPoint = this;

	// install some statistics notification, see OnRTPStatistics()
	ancaInfo->install( JITTER_BUFFER_SIZE );
	ancaInfo->install( JITTER_AVERAGE_TIME );
	ancaInfo->install( JITTER_MAXIMUM_TIME );
	ancaInfo->install( TRANSMITTER_SESSION_INTERVAL );
	ancaInfo->install( RECEIVER_SESSION_INTERVAL );
	ancaInfo->install( PACKETS_SENT );
	ancaInfo->install( PACKETS_RECEIVED );
	ancaInfo->install( PACKETS_LOST );
	ancaInfo->install( PACKETS_TOO_LATE );

	d->callTimer = new CallTimer();
#ifdef ENTERPRISE
	d->ldap = new PLDAPSession( /*const PString& defaultBaseDN */ );
#endif

	// set up basic alias
	QStringList aliases = ancaConf->readListEntry( USER_ALIASES );
	if( aliases.isEmpty() ) {
		aliases.append( ( const char * ) PProcess::Current().GetUserName() );
		ancaConf->writeListEntry( USER_ALIASES, aliases );
	}
}
예제 #27
0
 // Constructor which takes the ostream to use and the destination context
 InformStream(std::ostream *s, Inform::Context_t oc)
   : stream_m(s), close_m(false), outputContext_m(oc), level_m(0)
 {
   PAssert(s != 0);
 }
예제 #28
0
void Particles<ParticleTraits>::performDestroy(PatchID_t pid, bool renum)
{
  PatchID_t i, npatch = attributeLayout_m.sizeLocal();

  if (pid < 0)
    {
      for (i = 0; i < npatch; ++i)
	{
	  // skip this patch if there are no destroy requests for it.

	  if (destroyList(i).domain().empty())
	    continue;

	  // do the destroys on this patch

	  if (destroyMethod_m == DynamicEvents::backfill)
	    {
	      attributeLayout_m.destroy(IndirectionList<int>(destroyList(i)),
					i, BackFill());
	    }
	  else if (destroyMethod_m == DynamicEvents::shiftup)
	    {
	      attributeLayout_m.destroy(IndirectionList<int>(destroyList(i)),
					i, ShiftUp());
	    }
	  else
	    {
	      PInsist(false, "Unknown destroy method in Particles::destroy!");
	    }

	  // clear the destroy list for this patch

	  destroyList(i).destroy(destroyList(i).domain());
	}
    }
  else
    {
      // Just destroy for the given patch

      PAssert(pid < npatch);
      i = pid;

      // Do the destroy if we have something to do

      if (!destroyList(i).domain().empty())
	{
	  if (destroyMethod_m == DynamicEvents::backfill)
	    {
	      attributeLayout_m.destroy(IndirectionList<int>(destroyList(i)),
					i, BackFill());
	    }
	  else if (destroyMethod_m == DynamicEvents::shiftup)
	    {
	      attributeLayout_m.destroy(IndirectionList<int>(destroyList(i)),
					i, ShiftUp());
	    }
	  else
	    {
	      PInsist(false, "Unknown destroy method in Particles::destroy!");
	    }

	  // clear the destroy list for this patch
	  
	  destroyList(i).destroy(destroyList(i).domain());
	}
    }

  // if requested, recompute the global domain of the Attributes

  if (renum)
    renumber();
}
예제 #29
0
int main(int argc, char* argv[])
{
  Pooma::initialize(argc,argv);
  Pooma::Tester tester(argc,argv);

  int test_number = 0;

#if POOMA_EXCEPTIONS
  try {
#endif
    tester.out() << "\nTesting resizable DataBlockPtr." 
		 << std::endl;

    RCBlock_t p;
    
    p.reserve(100);
    
    PAssert(p.size() == 0);
    PAssert(p.capacity() == 100);
    PAssert(p.empty());
    
    p.resize(10,RCBlock_t::NoInitTag());
    p.resize(20);
    p.resize(30,100);
    p.resize(10);
    
    PAssert(p.size() == 10);
    PAssert(!p.empty());
    
    RCBlock_t q(100,RCBlock_t::NoInitTag());
    
    PAssert(q.size() == 0);
    PAssert(q.capacity() == 100);
    PAssert(q.empty());
    
    q.resize(10,RCBlock_t::NoInitTag());
    q.resize(20);
    q.resize(30,100);
    q.resize(10);
    
    PAssert(q.size() == 10);
    PAssert(!q.empty());
    
    RCBlock_t bb(100);
    
    PAssert(bb.size() == 100);
    PAssert(bb.capacity() == 100);
    PAssert(!bb.empty());
    
    bb.resize(10,10);
    bb.resize(5,5);
    bb.resize(0);
    
    PAssert(bb.empty());
    
    bb.resize(10);
    
    test_number++;

    PAssert(!p.isShared());
    PAssert(!q.isShared());
    PAssert(!bb.isShared());   
    
    test_number++;

    for (int i = 0; i < 10; i++)
      p[i] = (i-5)*(i-5);

    test_number++;

    print(p,tester);
    print(q,tester);
    print(bb,tester);

#if POOMA_EXCEPTIONS
    test_number++;

    try {

      for (int i = 0; i < 11; i++)
	p[i] = -p[i];

      throw "Bounds checking failed!";
    }
    catch(const Pooma::Assertion &) 
      { 
	tester.out() << "Bounds check worked." << std::endl; 
      }
#endif

    test_number++;

    for (int i = 0; i < 10; i++)
      PInsist( p[i] == *(p+i), "p[i] != *(p+i)" );

    for (int i = 0; i < 10; i++)
      PInsist( p[i] == *(p+i), "p[i] != *(p+i)" );

    test_number++;

    PAssert(!p.isShared());

    test_number++;

    foo(p,tester);
    
    test_number++;

    PAssert(!p.isShared());

    test_number++;

    bar(p,tester);

    PAssert(!p.isShared());

    test_number++;

    print(p,tester);

    test_number++;

    RCBlock_t a(1000,RCBlock_t::NoInitTag());
    a++;

#if POOMA_EXCEPTIONS
    try {
      tester.out() << a[4];
      throw "Bounds checking failed!";
    }
    catch(const Pooma::Assertion &) 
      { 
	tester.out() << "Bounds check worked." << std::endl; 
	tester.check(1);
      }
#endif
      
    // Reset start pointer...
    a--;
    
    a.resize(10,RCBlock_t::NoInitTag());
    
    for (int i = 0; i < 10; i++)
      a[i] = (i-5)*(i-5);
    
    bar(a,tester);
    print(a,tester);
    
    test_number++;

    RCBlock_t q1 = p;

#if POOMA_EXCEPTIONS
    try
      {
	RCBlock_t q2; q2 = p;

	PAssert(q1 == p);
	PAssert(q2 == p);
	PAssert(q1 == q2);

	PAssert(p.isShared());
	PAssert(q1.isShared());
	PAssert(q2.isShared());

	for (int i = 0; i < 10; i++)
	  PAssert(q1[i] == q2[i]);
	
	PAssert(p.capacity() == q1.capacity());
	PAssert(p.capacity() == q2.capacity());
	PAssert(p.size() == q1.size());
	PAssert(p.size() == q2.size());
      }
    catch (...) 
      { 
	tester.out() << "Something is very wrong!" << std::endl; 
	tester.check(0);
      }
#endif

    PAssert(p.isShared());
    PAssert(q1.isShared());

    p[1] = -999;
    PAssert(q1[1] == -999);

    test_number++;

    p.invalidate();

    PAssert(!p.isValid());

#if POOMA_EXCEPTIONS
    try {
      tester.out() << p[3];
      throw "Bounds checking failed!";
    }
    catch(const Pooma::Assertion &) 
      { 
	tester.out() << "Bounds check worked." << std::endl; 
      }
#endif

    PAssert(!q1.isShared());

    test_number++;

    recurse(q1,tester);

    PAssert(!q1.isShared());
    tester.out() << "q1.isShared = " << q1.isShared() << std::endl;

    print(q1,tester);

    test_number++;

    {
      const RCBlock_t r = q1;

      PAssert(r.isShared());

      print(r,tester);

      for (int i = 0; i < 10; i++)
	tester.out() << *(r+i) << " ";

      tester.out() << std::endl;

      p = r;

      PAssert(p.isShared());
    }

    PAssert(p.isShared());

    test_number++;

    q1.invalidate();

    PAssert(!p.isShared());

    test_number++;

    tester.out() << "\nTesting conversions to non-boundschecked" << std::endl;
    RCFBlock_t s = p;

    PAssert(s.isShared());
    PAssert(p.isShared());
    PAssert(s == p);

    print(s,tester);

    recurse(s,tester);

    PAssert(s.isShared());

    test_number++;

    s.makeOwnCopy();
    PAssert(!s.isShared());
    PAssert(!p.isShared());
    PAssert(s != p);

    for (int i = 0; i < 10; i++)
      s[i] = i*i;

    tester.out() << "These should not be the same." << std::endl;

    for (int i = 0; i < 10; i++)
      tester.out() << p[i] << " ";

    tester.out() << std::endl;
    for (int i = 0; i < 10; i++)
      tester.out() << s[i] << " ";

    tester.out() << std::endl;

    tester.out() << "printed ok that time." << std::endl;

    print(s,tester);
    print(p,tester);

    s.invalidate();
    
    PAssert(!p.isShared());

    p.invalidate();

#if POOMA_EXCEPTIONS
  }
  catch(const char *err) 
    { 
      tester.exceptionHandler( err );
      tester.set( false );
    }
  catch(const Pooma::Assertion &err)
    { 
      tester.exceptionHandler( err );
      tester.set( false );
    }
#endif    
    
  tester.out() << "All Done!" << std::endl;
  int res = tester.results("dbptr_test5 ");
  Pooma::finalize();  
  return res;
}
예제 #30
0
void Particles<ParticleTraits>::deferredDestroy(Iter begin, Iter end,
                                                PatchID_t pid)
{
  if (pid >= 0)
    {
      Pooma::IteratorPairDomain<const int*> domain(begin,end);

      PAssert(pid < attributeLayout_m.sizeLocal());

      // This is only for one patch request, and the domain values are
      // already relative, so we can just stuff them at the end of the
      // patch destroy list for the specified patch.

      int i = 0;
      int destroys = domain[0].size();
      int next = destroyList(pid).domain().size();
      destroyList(pid).create(destroys);
      while (i < destroys)
        destroyList(pid)(next++) = domain[0](i++);
    }
  else
    {
      Pooma::IteratorPairDomain<Iter> domain(begin,end);

      // Check that the destroy list is contained by the global domain.

      PInsist(contains(attributeLayout_m.domain(),domain),
	      "Destroy request outside of global domain!");

      // We assume the domain is sorted in ascending order.
      // Convert this list into a set of patch-specific destroy requests
      // by intersecting the list with the domain of each of the 
      // separate patches.  This code was borrowed from the destroy()
      // method in DynamicLayout.

      // Find pieces of this total destroy domain in each subdomain,
      // and destroy them.

      int is = 0, ie = 0;
      PatchID_t patch = 0, numPatches = attributeLayout_m.sizeLocal();

      // Skip to the first non-empty local patch

      bool found = false;
      while (!found && patch < numPatches) {
        found = !attributeLayout_m.ownedDomain(patch).empty();
        if (!found) patch++;
      }
      if (!found) return;

      // Some portion of the destroy domain may precede all of the 
      // domain controlled by this context, so skip that part.

      while (domain(is) < attributeLayout_m.ownedDomain(patch).first() && 
             is < domain.size()) is++;
      ie = is;

      while (patch < numPatches && ie < domain.size())
        {
	  // find last item on this patch
	  for ( ; patch < numPatches && ie < domain.size(); ++ie)
	    if (domain(ie)>attributeLayout_m.ownedDomain(patch).last()) break;

	  // if we didn't find any intersection, go to next patch
	  if (ie == is)
	    {
	      ++patch;
	      continue;
	    }

	  // put the intersection points into this patch's destroy list
	  int patchOffset = attributeLayout_m.ownedDomain(patch).first();
	  int currSize = destroyList(patch).domain().size();
	  int newDestroys = ie - is;
	  destroyList(patch).create(newDestroys);

          // insert local offset index values into destroy list patch
          for (int ii = 0; ii < newDestroys; ++ii)
            destroyList(patch)(currSize+ii) = domain(is+ii) - patchOffset;

	  // Move on to next local patch
	  ++patch;
	  is = ie;
        }

    }
}