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