There's a little bit in the PP documentation, but it's mainly a black  
art.

It's helpful to realize that slicing operations maintain dataflow, so  
they have to set up callback routines.

There are three major pieces:
        * MakeComp - when you invoke a slicing method, it only sets up the  
data structures that it will need later.  That snippet of code is in  
the MakeComp segment of the pp_def hash, and its job is to allocate  
(where necessary) and initialize the data structures in the $COMP macro.
        * RedoDims - this snippet calculates the dimensionality of the output  
slice, together with the elements of the dimincs array that is used to  
associate N-D addresses of PDL elements to particular memory  
locations.  For affine transformations, this is the main calculation  
that has to be done -- the slice gets a new header and dimincs  
numbers, but the ->data field points back to the interior of the  
parent PDL's ->data.
        * EquivCPOffsCode - this snippet is used for non-affine  
transformations, where data are explicitly copied between the parent  
and child PDLs (or vice versa).  It can be threadlooped just like a  
normal PP snippet, though for range)() all threading is handled  
explicitly by the C code.  This is typically a loop over all the child  
PDL's element locations, with a call to the $EQUIVCPOFFS or  
$EQUIVCPTRUNC macro.  Those macros (you only need one) associate two  
pointers into the ->data arrays of two different PDLs.  The whole  
EquivCPOffs segment gets compiled into two separate routines -- one  
that flows data from parent to child, and one that flows data from  
child to parent.

The MakeComp and RedoDims routines get called immediately when you  
invoke the slicing method; the EquivCPOffs routine doesn't get called  
until a dataflow event is triggered (i.e. you *evaluate* the child or  
change the parent).  That's why some types of slicing or range error  
don't get thrown until long after the original slice() call.

Note that, in some ways, range() is quite simple and could be a good  
template for you.  It may appear complex just because it has to handle  
a bunch of strangeness in order to be fully general.

  * The MakeComp just stores some basic size and index information;  
most of its messiness is in making sure the index PDLs are longs and  
the boundary conditions are legal.

  * The RedoDims just stacks up the output dim list and dimincs()  
arrays, so that we know how big the ->data field has to be (note that  
the PP engine handles allocating the ->data field)

*  The EquivCPOffsCode is actually longer than it has to be - now that  
I look in it again, there's a bunch of stuff up top about whether to  
use EQUIVCPOFFS or EQUIVCPTRUNC, but in fact we always use  
EQUIVCPTRUNC now, so the top stuff can be diked out... oops)  But the  
meat of it starts with the "Find offsets into the child and parent  
arrays" comment, and consists of a single do loop that calls  
EQUIVCPTRUNC.  The only reason it looks a little complex is that the  
loop iteration step itself involves a for() loop to iterate over all  
the input dimensions.

If you're trying to slice in a novel way along single dimension or (at  
most complex) a known number of dimensions, all this stuff is much  
easier than it was for range(), because then you can use the usual  
loop(<var>) %{%} construct to loop over your active (declared) dims,  
and the thread engine will handle threading automagically for you.


Er, I hope that helps.  I'd be happy to try to answer any questions  
that come up.


On Nov 17, 2009, at 1:57 PM, David Mertens wrote:

> I have a slicing operation that's really tedious to do at the perl  
> level.  I thought to myself, "It can't be that hard to write a PP'd  
> slicing function.  Then I looked at slices.pd.  Holy cow.   
> (Incidentally, if I ever get numerical regular expressions in place,  
> the slice I need to perform at the moment would be super easy to  
> specify.  But, it's barely more than a specification at the moment...)
>
> I know that slicing operations are not documented, but where can I  
> find decent example code?  Are there any good test files that check  
> how PP processes slicing operations?  At the moment, slices.pd and  
> the PP.pm appear to be my only sources of information on the topic.
>
> Thanks.
> David
>
> _______________________________________________
> Perldl mailing list
> [email protected]
> http://mailman.jach.hawaii.edu/mailman/listinfo/perldl


_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to