[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-29 Thread Jed Brown
On Sun, 29 Aug 2010 09:16:18 -0400, Kai Germaschewski kai.germaschewski at 
unh.edu wrote:
 Some malloc()'s, like GNU libc, allow you to hook into it. Even if not, if
 you define your own malloc(), it'll get used instead of the C library one
 (depends on the order of libs on the command line). However, in that case
 you may have trouble to do your thing and then continue on to the original
 version. Actually, with dynamic libs you can do it:
 
 http://stackoverflow.com/questions/262439/create-a-wrapper-function-for-malloc-and-free-in-c
 
 I don't know how to handle C++, I imagine there's a way to do it on common
 systems.

GNU new calls malloc, though not necessarily every time.  Unfortunately
this is all non-portable, changes the linking procedure, and is not
appropriate for a library to do.

Note also that object creation and destruction are collective
operations, but malloc() may be called from user code on one process.
This may require GC'ing an unused cache, which involves destroying
parallel objects.

 I take your point, it'll be major hassle, and it's quite likely you can't
 make it work on every system. However, you could check at configure time,
 and just not use the cache but free() things on destroy() if the system
 doesn't support it. I'm also not sure I like the random timing distortion
 caused by having something GC-like.
 
 Before considering the complex solutions, I think it's important to first
 answer
 (1) Is the cache something that really make a difference in performance? (I
 suppose whenever someone DAGet{Global,Local}Vector(), they will do something
 to fill that vector with values, if that near always takes  than even a
 VecCreate(), there may be no point in caching those things in the first
 place.

Depends on the size of the vector, coarse level residual evaluation
works with very small vectors, you'd rather not add a few collective
operations to that operation.

 (2) Is there an easier way to fix the problem? One way may be to look at why
 a DACreate{Local,Global}Vector() isn't performing as well as we'd need, and
 there may ways to streamline/optimize it for the common case. A second way
 could be a do_cache flag on Vec's (and maybe Mat's, too). That is, do your
 VecCreate(), or DACreate{...}Vector(), and then VecSetCached(vec). That flag
 would be checked at Destroy() time and the Vector would go into the pool
 instead of being free'd. In that case, you don't eat up all mem for the
 unsuspecting user, but an advanced user would easily be able to use the
 benefit of caching where it actually matters (That's not as nice as having
 everything fully automatic, but...)

If this cache is specific to the DA, then I don't see this being
preferable to DAGet*.  If the cache is not specific to the DA, then you
need to somehow match compatible Vecs lying around in the cache, and I
still don't think the interface is as nice, and it seems less precise
when you want to reclaim that memory.


As an aside, talloc (http://talloc.samba.org) is an interesting
hierarchical, reference counting allocator.  You allocate hierarchically
(new memory references a parent), and then automatically collect all
children when the parent is freed.  There is support for various sharing
schemes, the interesting thing is that it makes it much easier to clean
up gracefully in error conditions.  If you're interesting in C memory
management systems, it's worth a look.

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-28 Thread Matthew Knepley
I would support a name change to Create().  However, we should be really
sure before we do stuff
like that since nothing pisses people off (Wolfgang) like name changes.

   Matt

On Fri, Aug 27, 2010 at 5:49 PM, Barry Smith bsmith at mcs.anl.gov wrote:


  Hmmm,

 petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT
  DMGetColoring(DM,ISColoringType,const MatType,ISColoring*);
 petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT  DMGetMatrix(DM, const
 MatType,Mat*);
 petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT
  DMGetInterpolation(DM,DM,Mat*,Vec*);
 petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT
  DMGetInterpolationScale(DM,DM,Mat,Vec*);
 petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT
  DMGetAggregates(DM,DM,Mat*);

   should all of these be Create?

   In my mind usually Get means get something intrinsic to the underlying
 object (some property of it for example);  Create means generate a new thing
 that while it may be associated with the DA is not owned or controlled
 by the DA.

Another way to organize is Create() implies you later Destroy() that
 object, while for things you Get you do something else (like restore).

I'm inclined to change all of these ones to Create() since they are all
 Destroyed()
Barry



 On Aug 27, 2010, at 11:10 AM, Jed Brown wrote:

  On Fri, 27 Aug 2010 12:00:32 -0400, Kai Germaschewski 
 kai.germaschewski at unh.edu wrote:
  And it also requires some more memory management framework which would
  call upon caches to expire long-unused objects when memory is running
  low.
 
  How would you detect this?  Note that further allocation may be done
  external to PETSc, and perhaps even in a separate process.  We're not in
  a managed environment, we can't get a reliable time to GC.  If we
  could get that sort of signal, then I would be for such caching at all
  times, but I don't think we can, in which case I still think
  managed/pooled access versus owned creation needs to be explicitly
  different.
 
  Jed




-- 
What most experimenters take for granted before they begin their experiments
is infinitely more interesting than any results to which their experiments
lead.
-- Norbert Wiener
-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100828/0ed5ce22/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Aron Ahmadia
I'm posting this to -dev since I'm working in -dev, let me know if I should
be pushing this sort of question to -users.  I was debugging a code today
and noticed the following note in DAGetGlobalVector:

The vector values are NOT initialized and may have garbage in them, so you
may need to zero them.

What exactly is the purpose of these routines then?  Is there a global
Vector associated with a DA?  If so, why are the values uninitialized?  On
the other hand, if there isn't one, what's the sense of 'get/restore'?  The
following code does NOT work the way I'd expect:

DAGetGlobalVector(x)

/* modify x */

DARestoreGlobalVector(x)

DAGetGlobalVector(x)

/* access previous values, except everything is zero*/

I guess I'm not grokking something about the concept of a DA or PETSc
objects, could somebody explain the purpose or correct usage of Get/Restore
here.

Thanks in advance,
Aron
-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/268d23b4/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia aron.ahmadia at kaust.edu.sa 
wrote:
 What exactly is the purpose of these routines then?  Is there a global
 Vector associated with a DA?  If so, why are the values uninitialized? 

It's common to need work vectors in places like residual evaluation and
Jacobian assembly.  There is a little bit of setup cost to allocate a
new vector each time, so usually we'd prefer that they be persistent and
just reuse them.  One option would be to make the user manage this
themselves, but that's error prone because it's easy to accidentally
alias the work vectors, so instead the DA keeps a cache of vectors.  It
starts out empty, and each time you call DAGetGlobalVector(), the cache
is searched for an available vector.  If none are found, a new one is
allocated and the cache grows by one.  DARestoreGlobalVector() checks a
vector back in so it may be used elsewhere.  These vectors are destroyed
in DADestroy().

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Matthew Knepley
Simply, in PETSc, getFoo() and restoreFoo() operate an object pool.

   Matt

On Fri, Aug 27, 2010 at 11:23 AM, Jed Brown jed at 59a2.org wrote:

 On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia 
 aron.ahmadia at kaust.edu.sa wrote:
  What exactly is the purpose of these routines then?  Is there a global
  Vector associated with a DA?  If so, why are the values uninitialized?

 It's common to need work vectors in places like residual evaluation and
 Jacobian assembly.  There is a little bit of setup cost to allocate a
 new vector each time, so usually we'd prefer that they be persistent and
 just reuse them.  One option would be to make the user manage this
 themselves, but that's error prone because it's easy to accidentally
 alias the work vectors, so instead the DA keeps a cache of vectors.  It
 starts out empty, and each time you call DAGetGlobalVector(), the cache
 is searched for an available vector.  If none are found, a new one is
 allocated and the cache grows by one.  DARestoreGlobalVector() checks a
 vector back in so it may be used elsewhere.  These vectors are destroyed
 in DADestroy().

 Jed




-- 
What most experimenters take for granted before they begin their experiments
is infinitely more interesting than any results to which their experiments
lead.
-- Norbert Wiener
-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/3e5116e5/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Aron Ahmadia
Thanks Matt and Jed,

I think I'm straight on usage/philosophy here.

A

On Fri, Aug 27, 2010 at 2:42 PM, Matthew Knepley knepley at gmail.com wrote:

 Simply, in PETSc, getFoo() and restoreFoo() operate an object pool.

Matt


 On Fri, Aug 27, 2010 at 11:23 AM, Jed Brown jed at 59a2.org wrote:

 On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia 
 aron.ahmadia at kaust.edu.sa wrote:
  What exactly is the purpose of these routines then?  Is there a global
  Vector associated with a DA?  If so, why are the values uninitialized?

 It's common to need work vectors in places like residual evaluation and
 Jacobian assembly.  There is a little bit of setup cost to allocate a
 new vector each time, so usually we'd prefer that they be persistent and
 just reuse them.  One option would be to make the user manage this
 themselves, but that's error prone because it's easy to accidentally
 alias the work vectors, so instead the DA keeps a cache of vectors.  It
 starts out empty, and each time you call DAGetGlobalVector(), the cache
 is searched for an available vector.  If none are found, a new one is
 allocated and the cache grows by one.  DARestoreGlobalVector() checks a
 vector back in so it may be used elsewhere.  These vectors are destroyed
 in DADestroy().

 Jed




 --
 What most experimenters take for granted before they begin their
 experiments is infinitely more interesting than any results to which their
 experiments lead.
 -- Norbert Wiener

-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/dcd73c11/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Dmitry Karpeev
Except VecGetArray, etc, which operate a pool of one object.
I think this may be the root cause of confusion.

Dmitry.

On Fri, Aug 27, 2010 at 6:42 AM, Matthew Knepley knepley at gmail.com wrote:
 Simply, in PETSc, getFoo() and restoreFoo() operate an object pool.
 ?? Matt

 On Fri, Aug 27, 2010 at 11:23 AM, Jed Brown jed at 59a2.org wrote:

 On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia
 aron.ahmadia at kaust.edu.sa wrote:
  What exactly is the purpose of these routines then? ?Is there a global
  Vector associated with a DA? ?If so, why are the values uninitialized?

 It's common to need work vectors in places like residual evaluation and
 Jacobian assembly. ?There is a little bit of setup cost to allocate a
 new vector each time, so usually we'd prefer that they be persistent and
 just reuse them. ?One option would be to make the user manage this
 themselves, but that's error prone because it's easy to accidentally
 alias the work vectors, so instead the DA keeps a cache of vectors. ?It
 starts out empty, and each time you call DAGetGlobalVector(), the cache
 is searched for an available vector. ?If none are found, a new one is
 allocated and the cache grows by one. ?DARestoreGlobalVector() checks a
 vector back in so it may be used elsewhere. ?These vectors are destroyed
 in DADestroy().

 Jed



 --
 What most experimenters take for granted before they begin their experiments
 is infinitely more interesting than any results to which their experiments
 lead.
 -- Norbert Wiener




[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Aron Ahmadia
Not to mention the various Get routines that are actually used to create
things, such as DAGetMatrix.  Still, the idea of a pool of work vectors
makes sense, I was just trying to wrap my head around the actual use for
those routines.

A

On Fri, Aug 27, 2010 at 4:06 PM, Dmitry Karpeev karpeev at mcs.anl.gov wrote:

 Except VecGetArray, etc, which operate a pool of one object.
 I think this may be the root cause of confusion.

 Dmitry.

 On Fri, Aug 27, 2010 at 6:42 AM, Matthew Knepley knepley at gmail.com
 wrote:
  Simply, in PETSc, getFoo() and restoreFoo() operate an object pool.
 Matt
 
  On Fri, Aug 27, 2010 at 11:23 AM, Jed Brown jed at 59a2.org wrote:
 
  On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia
  aron.ahmadia at kaust.edu.sa wrote:
   What exactly is the purpose of these routines then?  Is there a global
   Vector associated with a DA?  If so, why are the values uninitialized?
 
  It's common to need work vectors in places like residual evaluation and
  Jacobian assembly.  There is a little bit of setup cost to allocate a
  new vector each time, so usually we'd prefer that they be persistent and
  just reuse them.  One option would be to make the user manage this
  themselves, but that's error prone because it's easy to accidentally
  alias the work vectors, so instead the DA keeps a cache of vectors.  It
  starts out empty, and each time you call DAGetGlobalVector(), the cache
  is searched for an available vector.  If none are found, a new one is
  allocated and the cache grows by one.  DARestoreGlobalVector() checks a
  vector back in so it may be used elsewhere.  These vectors are destroyed
  in DADestroy().
 
  Jed
 
 
 
  --
  What most experimenters take for granted before they begin their
 experiments
  is infinitely more interesting than any results to which their
 experiments
  lead.
  -- Norbert Wiener
 

-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/39eceb50/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 16:13:14 +0300, Aron Ahmadia aron.ahmadia at kaust.edu.sa 
wrote:
 Not to mention the various Get routines that are actually used to create
 things, such as DAGetMatrix.

I think that should have been named DACreateMatrix().  Other XGetY() are
just accessors which create a managed object if needed.  When there is a
Get/Restore pair, it implies that the access to that managed resource
has some sort of exclusivity.  I think
{Get,Restore}{Local,Global}Vector() are actually the only functions with
that naming scheme that really manage a pool.

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Matthew Knepley
I agree with DACreateMatrix().

  Matt

On Fri, Aug 27, 2010 at 1:24 PM, Jed Brown jed at 59a2.org wrote:

 On Fri, 27 Aug 2010 16:13:14 +0300, Aron Ahmadia 
 aron.ahmadia at kaust.edu.sa wrote:
  Not to mention the various Get routines that are actually used to create
  things, such as DAGetMatrix.

 I think that should have been named DACreateMatrix().  Other XGetY() are
 just accessors which create a managed object if needed.  When there is a
 Get/Restore pair, it implies that the access to that managed resource
 has some sort of exclusivity.  I think
 {Get,Restore}{Local,Global}Vector() are actually the only functions with
 that naming scheme that really manage a pool.

 Jed




-- 
What most experimenters take for granted before they begin their experiments
is infinitely more interesting than any results to which their experiments
lead.
-- Norbert Wiener
-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/3c4594d7/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Barry Smith

On Aug 27, 2010, at 8:13 AM, Aron Ahmadia wrote:

 Not to mention the various Get routines that are actually used to create 
 things, such as DAGetMatrix.  Still, the idea of a pool of work vectors makes 
 sense, I was just trying to wrap my head around the actual use for those 
 routines.

   Aron,

DAGetMatrix() is actually a bug and should be DACreateMatrix()   (or maybe 
better DACreateMat() while the DACreateGlobalVector() and friends should really 
be DACreateGlobalVec()). 

Are there others beside DAGetMatrix() that are incorrect with gets that 
should be creates?

 Thanks

   Barry

 It would actually be nice if we made DACreateGlobal/LocalVector() so 
light-weight that it could be used for work vectors (instead of needing a 
different set of light weight get routines)  but then we would need 
DADestroyGlobal/Vector() to handle putting back in the free list or need to 
modify VecDestroy() to handle not actually destroying but managing a free 
list). And there is also the issue of zeroing or not zeroing the Vec initially.
This is why we still have the Create and Get versions.


 
 A
 
 On Fri, Aug 27, 2010 at 4:06 PM, Dmitry Karpeev karpeev at mcs.anl.gov 
 wrote:
 Except VecGetArray, etc, which operate a pool of one object.
 I think this may be the root cause of confusion.
 
 Dmitry.
 
 On Fri, Aug 27, 2010 at 6:42 AM, Matthew Knepley knepley at gmail.com wrote:
  Simply, in PETSc, getFoo() and restoreFoo() operate an object pool.
 Matt
 
  On Fri, Aug 27, 2010 at 11:23 AM, Jed Brown jed at 59a2.org wrote:
 
  On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia
  aron.ahmadia at kaust.edu.sa wrote:
   What exactly is the purpose of these routines then?  Is there a global
   Vector associated with a DA?  If so, why are the values uninitialized?
 
  It's common to need work vectors in places like residual evaluation and
  Jacobian assembly.  There is a little bit of setup cost to allocate a
  new vector each time, so usually we'd prefer that they be persistent and
  just reuse them.  One option would be to make the user manage this
  themselves, but that's error prone because it's easy to accidentally
  alias the work vectors, so instead the DA keeps a cache of vectors.  It
  starts out empty, and each time you call DAGetGlobalVector(), the cache
  is searched for an available vector.  If none are found, a new one is
  allocated and the cache grows by one.  DARestoreGlobalVector() checks a
  vector back in so it may be used elsewhere.  These vectors are destroyed
  in DADestroy().
 
  Jed
 
 
 
  --
  What most experimenters take for granted before they begin their experiments
  is infinitely more interesting than any results to which their experiments
  lead.
  -- Norbert Wiener
 
 

-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/27177aa0/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Lisandro Dalcin
On 27 August 2010 10:27, Barry Smith bsmith at mcs.anl.gov wrote:

 On Aug 27, 2010, at 8:13 AM, Aron Ahmadia wrote:

 Not to mention the various Get routines that are actually used to create
 things, such as?DAGetMatrix. ?Still, the idea of a pool of work vectors
 makes sense, I was just trying to wrap my head around the actual use for
 those routines.

 ?? Aron,
 ?? ?DAGetMatrix() is actually a bug and should be DACreateMatrix() ? (or
 maybe better DACreateMat() while the DACreateGlobalVector() and friends
 should really be DACreateGlobalVec()).

I think you are right.


 ?? ?Are there others beside DAGetMatrix() that are incorrect with gets that
 should be creates?

MatGetVecs()


-- 
Lisandro Dalcin
---
CIMEC (INTEC/CONICET-UNL)
Predio CONICET-Santa Fe
Colectora RN 168 Km 472, Paraje El Pozo
Tel: +54-342-4511594 (ext 1011)
Tel/Fax: +54-342-4511169



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Aron Ahmadia
Barry,

I was being snippy, DAGetMatrix is the only one I know of that acts
unexpectedly.

Still, when working with Vec, you expect Get/Restore to modify data in the
Vec itself, which breaks for DAs since a DA has no internal Vec storage.
 Unless you are willing to append 'Work' somewhere into the names of the
work vector routines, I don't see an obvious solution.

A

On Fri, Aug 27, 2010 at 4:27 PM, Barry Smith bsmith at mcs.anl.gov wrote:


 On Aug 27, 2010, at 8:13 AM, Aron Ahmadia wrote:

 Not to mention the various Get routines that are actually used to create
 things, such as DAGetMatrix.  Still, the idea of a pool of work vectors
 makes sense, I was just trying to wrap my head around the actual use for
 those routines.


Aron,

 DAGetMatrix() is actually a bug and should be DACreateMatrix()   (or
 maybe better DACreateMat() while the DACreateGlobalVector() and friends
 should really be DACreateGlobalVec()).

 Are there others beside DAGetMatrix() that are incorrect with gets that
 should be creates?

  Thanks

Barry

  It would actually be nice if we made DACreateGlobal/LocalVector() so
 light-weight that it could be used for work vectors (instead of needing a
 different set of light weight get routines)  but then we would need
 DADestroyGlobal/Vector() to handle putting back in the free list or need to
 modify VecDestroy() to handle not actually destroying but managing a free
 list). And there is also the issue of zeroing or not zeroing the Vec
 initially.
 This is why we still have the Create and Get versions.



 A

 On Fri, Aug 27, 2010 at 4:06 PM, Dmitry Karpeev karpeev at mcs.anl.govwrote:

 Except VecGetArray, etc, which operate a pool of one object.
 I think this may be the root cause of confusion.

 Dmitry.

 On Fri, Aug 27, 2010 at 6:42 AM, Matthew Knepley knepley at gmail.com
 wrote:
  Simply, in PETSc, getFoo() and restoreFoo() operate an object pool.
 Matt
 
  On Fri, Aug 27, 2010 at 11:23 AM, Jed Brown jed at 59a2.org wrote:
 
  On Fri, 27 Aug 2010 14:13:01 +0300, Aron Ahmadia
  aron.ahmadia at kaust.edu.sa wrote:
   What exactly is the purpose of these routines then?  Is there a
 global
   Vector associated with a DA?  If so, why are the values
 uninitialized?
 
  It's common to need work vectors in places like residual evaluation and
  Jacobian assembly.  There is a little bit of setup cost to allocate a
  new vector each time, so usually we'd prefer that they be persistent
 and
  just reuse them.  One option would be to make the user manage this
  themselves, but that's error prone because it's easy to accidentally
  alias the work vectors, so instead the DA keeps a cache of vectors.  It
  starts out empty, and each time you call DAGetGlobalVector(), the cache
  is searched for an available vector.  If none are found, a new one is
  allocated and the cache grows by one.  DARestoreGlobalVector() checks a
  vector back in so it may be used elsewhere.  These vectors are
 destroyed
  in DADestroy().
 
  Jed
 
 
 
  --
  What most experimenters take for granted before they begin their
 experiments
  is infinitely more interesting than any results to which their
 experiments
  lead.
  -- Norbert Wiener
 




-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/69ed0811/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 08:27:22 -0500, Barry Smith bsmith at mcs.anl.gov wrote:
  It would actually be nice if we made DACreateGlobal/LocalVector()
 so light-weight that it could be used for work vectors (instead of
 needing a different set of light weight get routines) but then we
 would need DADestroyGlobal/Vector() to handle putting back in the free
 list or need to modify VecDestroy() to handle not actually destroying
 but managing a free list).

Hmm, I'm not sure that only having Create versions would be a good
thing.  Overhead could be reduced to a VecDuplicate, but you still have
to allocate the memory.  Malloc is plenty fast (~400 cycles everywhere
I've checked) if you don't touch the memory, but traversing it extra
times is not ideal, yet the reproducibility of always zeroing newly
created vectors is handy.  Maybe there are places that malloc() is more
expensive, or that fragmentation (if you have some very small vectors,
or are using huge pages) would become a factor.

If the vectors are going to be persistent, their life has to be managed
somehow, in which case the Get versions are needed.  It also helps (me)
to clarify intent: if I see a Get, then I know the vector is temporary
without needing to check for a matching Destroy.

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Lisandro Dalcin
On 27 August 2010 10:47, Jed Brown jed at 59a2.org wrote:

 ?It also helps (me)
 to clarify intent: if I see a Get, then I know the vector is temporary
 without needing to check for a matching Destroy.


You need a matching Restore()


-- 
Lisandro Dalcin
---
CIMEC (INTEC/CONICET-UNL)
Predio CONICET-Santa Fe
Colectora RN 168 Km 472, Paraje El Pozo
Tel: +54-342-4511594 (ext 1011)
Tel/Fax: +54-342-4511169



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 10:56:56 -0300, Lisandro Dalcin dalcinl at gmail.com 
wrote:
 On 27 August 2010 10:47, Jed Brown jed at 59a2.org wrote:
 
  ?It also helps (me)
  to clarify intent: if I see a Get, then I know the vector is temporary
  without needing to check for a matching Destroy.
 
 
 You need a matching Restore()

Right, but I know when I see the Get that there will be a matching
Restore (I don't have to infer from context or looking ahead that the
object isn't handed off in some other way).

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Dmitry Karpeev
I think DAGetXXX etc should really be thought of as constructors,
that under the hood manage a pool to amortize the construction time.
Perhaps more precisely, DA acts as a factory.
It would be natural to rename them DACreateXXX, except that
then XXXDestroy is the wrong thing to do (unless the destructor
is overloaded in the corresponding object).

Dmitry.


On Fri, Aug 27, 2010 at 8:24 AM, Jed Brown jed at 59a2.org wrote:
 On Fri, 27 Aug 2010 16:13:14 +0300, Aron Ahmadia aron.ahmadia at 
 kaust.edu.sa wrote:
 Not to mention the various Get routines that are actually used to create
 things, such as DAGetMatrix.

 I think that should have been named DACreateMatrix(). ?Other XGetY() are
 just accessors which create a managed object if needed. ?When there is a
 Get/Restore pair, it implies that the access to that managed resource
 has some sort of exclusivity. ?I think
 {Get,Restore}{Local,Global}Vector() are actually the only functions with
 that naming scheme that really manage a pool.

 Jed




[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 09:45:36 -0500, Dmitry Karpeev karpeev at mcs.anl.gov 
wrote:
 I think DAGetXXX etc should really be thought of as constructors,
 that under the hood manage a pool to amortize the construction time.
 Perhaps more precisely, DA acts as a factory.
 It would be natural to rename them DACreateXXX, except that
 then XXXDestroy is the wrong thing to do (unless the destructor
 is overloaded in the corresponding object).

Hmm, I think there is an important distinction, in terms of overall
memory use, between objects that live a long time and those that do not.
I might allocate a bunch of memory in a preprocessing stage, release it,
and then build solver objects.  If all that preprocessing memory stayed
alive for the life of the program, I would run out of memory.

You can't overload Destroy in place of Restore unless you maintain
upward links or guarantee that the managing object will never need to do
anything when you restore.  One way to do this would be to
double-reference gotten objects and consider them to be checked in any
time the reference count drops to 1.  But this excludes more elaborate
data structures and extra consistency checks.

I don't see any great nastiness of Get/Restore for managed objects and
Create/Destroy for objects that the user wants to own.

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Dmitry Karpeev
Maybe Create/Destroy isn't the right solution, but there appears to be
some confusion
about the meaning of Get/Restore in this context.  It definitely
differs from VecGet/RestoreArray.
For example: there is no guarantee that subsequent DAGetXXXs,
punctuated by DARestoreXXXs,
will give one the same object.

Dmitry.

On Fri, Aug 27, 2010 at 10:02 AM, Jed Brown jed at 59a2.org wrote:
 On Fri, 27 Aug 2010 09:45:36 -0500, Dmitry Karpeev karpeev at mcs.anl.gov 
 wrote:
 I think DAGetXXX etc should really be thought of as constructors,
 that under the hood manage a pool to amortize the construction time.
 Perhaps more precisely, DA acts as a factory.
 It would be natural to rename them DACreateXXX, except that
 then XXXDestroy is the wrong thing to do (unless the destructor
 is overloaded in the corresponding object).

 Hmm, I think there is an important distinction, in terms of overall
 memory use, between objects that live a long time and those that do not.
 I might allocate a bunch of memory in a preprocessing stage, release it,
 and then build solver objects. ?If all that preprocessing memory stayed
 alive for the life of the program, I would run out of memory.

 You can't overload Destroy in place of Restore unless you maintain
 upward links or guarantee that the managing object will never need to do
 anything when you restore. ?One way to do this would be to
 double-reference gotten objects and consider them to be checked in any
 time the reference count drops to 1. ?But this excludes more elaborate
 data structures and extra consistency checks.

 I don't see any great nastiness of Get/Restore for managed objects and
 Create/Destroy for objects that the user wants to own.

 Jed




[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 10:14:30 -0500, Dmitry Karpeev karpeev at mcs.anl.gov 
wrote:
 Maybe Create/Destroy isn't the right solution, but there appears to be
 some confusion
 about the meaning of Get/Restore in this context.  It definitely
 differs from VecGet/RestoreArray.
 For example: there is no guarantee that subsequent DAGetXXXs,
 punctuated by DARestoreXXXs,
 will give one the same object.

Indeed, managing a pool has different semantics.  Is it worth looking
for a less ambiguous/overloaded name?

  Checkout/Checkin
  Borrow/Return
  Claim/Release

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Barry Smith

On Aug 27, 2010, at 8:47 AM, Jed Brown wrote:

 On Fri, 27 Aug 2010 08:27:22 -0500, Barry Smith bsmith at mcs.anl.gov wrote:
 It would actually be nice if we made DACreateGlobal/LocalVector()
 so light-weight that it could be used for work vectors (instead of
 needing a different set of light weight get routines) but then we
 would need DADestroyGlobal/Vector() to handle putting back in the free
 list or need to modify VecDestroy() to handle not actually destroying
 but managing a free list).
 
 Hmm, I'm not sure that only having Create versions would be a good
 thing.  Overhead could be reduced to a VecDuplicate, but you still have
 to allocate the memory.  Malloc is plenty fast (~400 cycles everywhere
 I've checked) if you don't touch the memory, but traversing it extra
 times is not ideal, yet the reproducibility of always zeroing newly
 created vectors is handy.  Maybe there are places that malloc() is more
 expensive, or that fragmentation (if you have some very small vectors,
 or are using huge pages) would become a factor.

If the DACreateVec managed a pool and the destroy put it back in a pool 
then you would not all this overhead. 

It is fine to have a DACreate and DAGet but I think it is possible to have 
just one.

Barry

 
 If the vectors are going to be persistent, their life has to be managed
 somehow, in which case the Get versions are needed.  It also helps (me)
 to clarify intent: if I see a Get, then I know the vector is temporary
 without needing to check for a matching Destroy.
 
 Jed




[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 10:50:22 -0500, Barry Smith bsmith at mcs.anl.gov wrote:
 If the DACreateVec managed a pool and the destroy put it back in a pool 
 then you would not all this overhead. 

The problem with this is that it doesn't actually release the memory.
So in the preprocessing scenario where I create, say, 50 local vectors,
use them all temporarily, then destroy them and build a solver, I would
run out of memory.  I think there needs to be some way for the user to
guarantee that the memory is actually released.

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Kai Germaschewski
I think it's conceptually not right to have Get()/Restore() pairs to do
caching, but provide that feature only in special cases. Shouldn't other
places that needs temp work vectors have a similar facility? I think a
better way of handling this would be to get rid of the special
Get()/Restore() caching pairs, and rather make caching a feature of the
object itself. I.e., VecCreate() might have a pool of allocated vector data
structures + associated data storage arrays. VecDestroy() would not really
destroy a Vec but return it to the pool. Unfortunately that doesn't mix too
well with how the real setup of a vector is done later, after options and
potentially command line options have been processed, so by the time you
know what kind of vector you want, you've pretty much already filled the
data structure. And it also requires some more memory management framework
which would call upon caches to expire long-unused objects when memory is
running low.

I think a more consistent user interface would be to just have
DACreateVec(), and something like MatCreateVecs(), and then VecDestroy() the
Vec when you're done, no matter where it came from. Whether it's cached or
not is an implementation detail. Probably the first thing to figure out
would be whether caching is making an actual difference in the real world,
and if not, there's a pretty straight forward solution...

--Kai




On Fri, Aug 27, 2010 at 11:36 AM, Jed Brown jed at 59a2.org wrote:

 On Fri, 27 Aug 2010 10:14:30 -0500, Dmitry Karpeev karpeev at mcs.anl.gov
 wrote:
  Maybe Create/Destroy isn't the right solution, but there appears to be
  some confusion
  about the meaning of Get/Restore in this context.  It definitely
  differs from VecGet/RestoreArray.
  For example: there is no guarantee that subsequent DAGetXXXs,
  punctuated by DARestoreXXXs,
  will give one the same object.

 Indeed, managing a pool has different semantics.  Is it worth looking
 for a less ambiguous/overloaded name?

  Checkout/Checkin
  Borrow/Return
  Claim/Release

 Jed




-- 
Kai Germaschewski
Assistant Professor, Dept of Physics / Space Science Center
University of New Hampshire, Durham, NH 03824
office: Morse Hall 245E
phone:  +1-603-862-2912
fax: +1-603-862-2771
-- next part --
An HTML attachment was scrubbed...
URL: 
http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20100827/707ed688/attachment.html


[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Jed Brown
On Fri, 27 Aug 2010 12:00:32 -0400, Kai Germaschewski kai.germaschewski at 
unh.edu wrote:
 And it also requires some more memory management framework which would
 call upon caches to expire long-unused objects when memory is running
 low.

How would you detect this?  Note that further allocation may be done
external to PETSc, and perhaps even in a separate process.  We're not in
a managed environment, we can't get a reliable time to GC.  If we
could get that sort of signal, then I would be for such caching at all
times, but I don't think we can, in which case I still think
managed/pooled access versus owned creation needs to be explicitly
different.

Jed



[petsc-dev] What's the point of D(A/M)GetGlobalVector?

2010-08-27 Thread Barry Smith

  Hmmm,

petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT  
DMGetColoring(DM,ISColoringType,const MatType,ISColoring*);
petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT  DMGetMatrix(DM, const 
MatType,Mat*);
petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT  
DMGetInterpolation(DM,DM,Mat*,Vec*);
petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT  
DMGetInterpolationScale(DM,DM,Mat,Vec*);
petscda.h:EXTERN PetscErrorCode PETSCDM_DLLEXPORT  DMGetAggregates(DM,DM,Mat*);

   should all of these be Create? 

   In my mind usually Get means get something intrinsic to the underlying 
object (some property of it for example);  Create means generate a new thing 
that while it may be associated with the DA is not owned or controlled by 
the DA. 

Another way to organize is Create() implies you later Destroy() that 
object, while for things you Get you do something else (like restore).

I'm inclined to change all of these ones to Create() since they are all 
Destroyed()
   Barry



On Aug 27, 2010, at 11:10 AM, Jed Brown wrote:

 On Fri, 27 Aug 2010 12:00:32 -0400, Kai Germaschewski kai.germaschewski at 
 unh.edu wrote:
 And it also requires some more memory management framework which would
 call upon caches to expire long-unused objects when memory is running
 low.
 
 How would you detect this?  Note that further allocation may be done
 external to PETSc, and perhaps even in a separate process.  We're not in
 a managed environment, we can't get a reliable time to GC.  If we
 could get that sort of signal, then I would be for such caching at all
 times, but I don't think we can, in which case I still think
 managed/pooled access versus owned creation needs to be explicitly
 different.
 
 Jed