This is the mail archive of the gsl-discuss@sources.redhat.com mailing list for the GSL project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

blocks/views and wrappers


G. Jungman wrote:

> Brian Gough wrote:
>
> > I think we can accomodate this in GSL
> > by not setting the block field to NULL for views
> > and having a separate field in the struct
> > to indicate ownership of the memory instead.
> > Then one would always be able
> > to determine the underlying block for any view.
> 
> Yes, every view should have an associated block.
> The model should be completely uniform in that regard.
> All we need to do is make sure that
> we maintain ownership information in the right way.
> You should be able to obtain the block
> and you should be able to get information
> about how the current object fits in the block, i.e. an offset.
> 
> It may be worth pointing out that "block address + offset" semantics
> are already present in some parts of GSL,
> for instance, with gsl_vector_alloc_from_block().
> This underlying semantic needs to be made more uniform
> across the vector/matrix implementations.
> Then it would be easier to work with underlying blocks when necessary.
> 
> It is important not to confuse this with reference counting,
> or any other memory management scheme. For instance,
> if a parent view is reclaimed, then sub views will dangle.
> I just say that to avoid any confusion
> over the use of the word ownership.
> In our model, sub views will never inherit ownership of block data
> from a parent view.
> 
> From the discussion of vsipl blockbind,
> I assume that even though it insists on exclusive access,
> it won't try to do anything like free the data,
> under any circumstances. But there is also the alternate worry,
> that a the GSL application might try to free the block
> after it has been bound to an external environment like the VSIPL.
> It may seem that this is an application issue,
> i.e. the application programmer simply must take care not to do this
> but maybe there are circumstances under which he would have no choice.
> For instance, suppose I wrote a C++ application
> where a destructor gets called automatically
> (in an inconvenient spot, like after exit from main),
> freeing some block data.  If vsipl is not yet finished with it
> (for instance in a multi-threaded app),
> there could be mysterious problems.
> 
> This raises the issue of whether or not GSL should be able
> to release actual memory management responsibility in some cases.
> If no GSL entity claims ownership of a block,
> then no GSL entity will release it.  It is not that
> we are necessarily transferring ownership  to an external entity
> but simply that we are unilaterally dis-owning the object.
> So I think there should be something like
> 
>   typedef enum { GSL_BLOCK_OWN, GSL_BLOCK_DISOWN }
>     gsl_block_ownership_t;
>   void gsl_block_ownership_set(gsl_block *, gsl_block_ownership_t);
> 
> Then maybe the standard incantation
> for binding to an external entity should be something like:
> 
>    gsl_block * b;
>    ...
>    gsl_block_ownership(v, GSL_BLOCK_DISOWN);
>    vsipl_blockbind(..., b, ...);
>    ...
>    vispl_blockunbind(vsipl_block *, ...);
>    gsl_block_ownership(v, GSL_BLOCK_OWN);
> 
> It may be tedious to keep track of this sort of thing in general.
> But my guess is that it would not be so bad in practice,
> and obviously it only occurs in specialized circumstances.
> This is completely trivial from the GSL implementation point of view,
> so why not do it. Can anbody point to a a concrete exmaple
> where this would be required (beyond my semi-fake example
> of automatic destruction in multi-threaded apps)?

There are two types of views

  1.) views that own their block and
  2.) views that simply reference a block owned by another view.

You could give these types different names.
For example, you could call vector views
that reference a block owned by another view subvectors
and simply call them vectors if they own their block.
In C++, you would simply derive a vector class from a subvector class
so that all operators and functions defined on a subvector class
would work on a vector class as well
but ANSI C doesn't support inheritance
so you would need to define operators and functions
on both subvector and vector objects.
Still it might be a good idea to provide a synonym

	typedef gsl_vector gsl_subvector;

for example, which application programmers could use
to help document the distinction
between views that own the block that they reference
and views which simply reference a block owned by another view.

In some numerical libraries, views share ownership of the block.
Shared ownership requires reference counting
so no two threads can reference the same view
unless the reference counter is protected by mutual exclusion
which usually implies unacceptable extra overhead.

It is almost certainly a programming error if a block is destroyed
before all of the views associated with it are destroyed
and reference counting would help to detect this error.
But shared ownership is a bad idea
because it is almost certainly a programming error
if the first view (for which a block was created) is destroyed
before all of the other views
subsequently associated with the block are destroyed.

The notion of ownership cannot be enforced in an ANSI C program
except by the self discipline of the application programmer.
The only reason for including ownership information in a view object
is to help check for programming errors at run time.
Reference counting cannot be implemented reliably in ANSI C
if the type definitions are exposed
because the application programmer can create and destroy views
without calling any GSL function to update the reference counter.

In short,
the inclusion of ownership information and/or reference counting
are implementation details best left up to the library developer.
Application programmers don't care or need to know how the GSL
was able to figure out that they tried to destroy a view
that didn't own the block of data that it referenced.
They just need to see a diagnostic
that will help them correct the problem.

> > lower level functions too.
> > So far we have not done that because it was not essential --
> > it could be done but it is easy enough to get by
> > using the C arguments, by typing v->data, v->stride, v->size instead.
> > A gsl_vector version of low-level functions
> > would mainly be a convenience.
> 
> Well, it's more than just a convenience.
> Just as it is important to insulate the user
> from implementation details,
> it is also important to insulate the different parts of the library
> from their respective implementation details.
> As Brian knows, I am very insistent on this point.
> Anyway, everybody in this forum understands this.
> 
> Those struct elements should be hidden
> and managed in as well-contained an area as possible.
> 
> There should be wrappers, and the reason they are not done
> is not because they were deemed inessential by anyone
> but simply because they are not done.  Somebody needs to type them in.
> At some point before 1.0, somebody will.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]