Hi,

this is a very brief response, please come back if you need more
details. What is the reason for not using Inline::Pdlpp (spelling?)

Ingo

On 6/19/2020 8:22 AM, Derek Lamb 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


_______________________________________________
pdl-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pdl-general

Reply via email to