Very belatedly – yes, Bryan does remember correctly. Also, you could guarantee the “physical”ness of the ndarray on the C side, with this at the start of your C function:
PDL->make_physical(im); But the most idiomatic way by far, if you’re already doing Inline::*, is Inline::Pdlpp. For a working (albeit somewhat complex) example, see posts here about John Walker’s floating-point benchmarks done in PDL. Best regards, Ed From: Bryan Jurish<mailto:[email protected]> Sent: 19 June 2020 14:26 To: Derek Lamb<mailto:[email protected]> Cc: perldl<mailto:[email protected]> Subject: Re: [Pdl-general] How to change a child piddle's data in C? 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]<mailto:[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]<mailto:[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]<mailto:[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]<mailto:[email protected]> https://lists.sourceforge.net/lists/listinfo/pdl-general -- Bryan Jurish "There is *always* one more bug." [email protected]<mailto:[email protected]> -Lubarsky's Law of Cybernetic Entomology
_______________________________________________ pdl-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/pdl-general
