greetings all, +1 re David's suggestion of PDL::PP ... there's also an Inline::Pdlpp <https://metacpan.org/pod/Inline::Pdlpp> on (meta)cpan which has worked well for me in the past.
If your "proper" C code is sneakier than times_ten() and needs batch access to whole memory regions, you might try calling $im2->make_physical() before you pass it to (the sneaky variant of) times_ten() ... iirc, pdl dataflow should then take care of updating the parent slice. marmosets, Bryan On Fri, Jun 19, 2020 at 3:13 PM David Mertens <[email protected]> wrote: > Hello Derek, > > As I recall (but this is a hazy recollection, Craig could answer this with > greater authority and detail), the PDL version of the method will do quite > a bit of work for you before calling pdl_times_ten_readdata. In particular, > it'll make physical copies of all non-contiguous slice piddles, i.e. those > generated by where. However, your slice should be is "affine", so I'm a bit > surprised that the "dimincs" piece isn't working as expected. > > I'll echo what Ingo said: why not create a PDL::PP wrapper? There is a > handy example here > <http://pdl.perl.org/PDLdocs/PP.html#Interfacing-your-own-library-functions-using-PP>. > Otherwise your C code will probably have to consult the "vafftrans" member > of the PDL object and figure things out on its own, something I've never > done before. For more hints on where to get started, consulate the > paragraph just before section 6 on page 38 of Practical Magick with C, > PDL and PDL::PP > <https://www.boulder.swri.edu/~deforest/ewExternalFiles/PP-practical-magick.pdf> > . > > David > > On Fri, Jun 19, 2020 at 2:23 AM Derek Lamb <[email protected]> wrote: > >> Question: Is there a straightforward way to operate on a piddle in C >> without knowing whether it's a physical or a child piddle, just like we do >> in PDL? And if so, what is it? >> >> As background: I have a subroutine, implemented in C, called from Perl >> using Inline::C. It takes an arbitrary-sized array ref of 2D-piddles as >> input, and modifies the piddles, like so: >> >> ### >> my $aref = [$pdl1, $pdl2, $pdl3]; >> my_sub( $aref ); >> ### >> >> So far, so good. That is, until I accidentally threw a child >> (non-physical) piddle at it: >> >> ### >> my $aref = [$big_3D_pdl->dog]; >> my_sub( $aref ); >> ### >> >> Then, at best, my_sub completes successfully but does not change any of >> the data in the piddles in $aref. Other times it segfaults. It has no >> trouble changing the data in $aref in the first example, when the piddles >> are physical. >> >> For simplicity, here is an example that doesn't use array refs, just >> takes a single piddle as input. When called on a physical piddle $im0, it >> works fine, but does not change the data in $im2 and frequently segfaults. >> This script contains a subroutine "times_ten" that just multiplies each >> element of the piddle by 10. >> >> ### >> use strict; >> use warnings; >> use PDL::LiteF; >> use PDL::Core::Dev; >> use PDL::Dbg; >> $PDL::debug=1; #for px calls >> >> my $im0 = sequence(5,4); >> my $im1 = sequence(8,7); >> my $im2 = $im1->slice("0:3,0:2"); >> >> $_->px foreach ($im0,$im2); >> >> times_ten($im0); >> times_ten($im2); >> >> print "\nNow that I'm done, \$im0 is:\n$im0\n"; >> print "\nNow that I'm done, \$im2 is:\n$im2\n"; >> >> no strict 'subs'; >> use Inline with => 'PDL'; >> use Inline C; >> Inline->init; # useful if you want to be able to 'do'-load this script >> 1; >> >> __DATA__ >> >> __C__ >> >> void times_ten(pdl* im){ >> >> printf("im xsize = %ld, ysize = %ld\n",im->dims[0],im->dims[1]); >> PDL_Double *data = (PDL_Double *) im->data; >> for (PDL_Indx x = 0; x < im->dims[0]; x++){ >> for (PDL_Indx y = 0; y < im->dims[1]; y++){ >> PDL_Indx offset = x * im->dimincs[0] + y * im->dimincs[1]; >> data[offset] *= 10; >> } >> } >> return; >> } >> ### >> >> What I would like is something near the beginning of the C code that >> abstracts the input piddle so the subsequent code doesn't care whether the >> input is physical or child. >> >> I made a similar example using Inline::Pdlpp and looked at the generated >> C code, and there in the subroutine "pdl_times_ten_readdata", in the >> THREADLOOP section is code that seems to take care of the pointer >> addressing whether the input piddle is physical or a virtual/child piddle. >> I was hoping for something less involved than a bunch of "__privtrans" >> lines—it's a bit hard for the casual reader to understand what's going on. >> (That "casual reader" may be me, in 6 or 12 months!) Is there a clean way >> to do this, or is it best in this case to make sure that the input piddles >> are always physical? >> >> thanks much, >> Derek >> >> _______________________________________________ >> pdl-general mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/pdl-general >> > > > -- > "Debugging is twice as hard as writing the code in the first place. > Therefore, if you write the code as cleverly as possible, you are, > by definition, not smart enough to debug it." -- Brian Kernighan > _______________________________________________ > pdl-general mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/pdl-general > -- Bryan Jurish "There is *always* one more bug." [email protected] -Lubarsky's Law of Cybernetic Entomology
_______________________________________________ pdl-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/pdl-general
