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

Reply via email to