PDLA
view release on metacpan or search on metacpan
Basic/Pod/API.pod view on Meta::CPAN
use PDLA;
sub mkmypiddle {
...
}
=head1 Creating a piddle manually from Perl
Sometimes you want to create a piddle I<manually>
from binary data. You can do that at the Perl level.
Examples in the distribution include some of the
IO routines. The code snippet below illustrates the
required steps.
use Carp;
sub mkmypiddle {
my $class = shift;
my $pdl = $class->new;
$pdl->set_datatype($PDLA_B);
my @dims = (1,3,4);
my $size = 1;
for (@dims) { $size *= $_ }
$pdl->setdims([@dims]);
my $dref = $pdl->get_dataref();
# read data directly from file
open my $file, '<data.dat' or die "couldn't open data.dat";
my $len = $size*PDLA::Core::howbig($pdl->get_datatype);
croak "couldn't read enough data" if
read( $file, $$dref, $len) != $len;
close $file;
$pdl->upd_data();
return $pdl;
}
=head1 Creating a piddle in C
The following example creates a piddle at the C level.
We use the C<Inline> module which is really the way to interface
Perl and C these days, using the C<with> capability in L<Inline> 0.68+.
use PDLA::LiteF;
$a = myfloatseq(); # exercise our C piddle constructor
print $a->info,"\n";
use Inline with => 'PDLA';
use Inline C;
Inline->init; # useful if you want to be able to 'do'-load this script
__DATA__
__C__
static pdl* new_pdl(int datatype, PDLA_Indx dims[], int ndims)
{
pdl *p = PDLA->pdlnew();
PDLA->setdims (p, dims, ndims); /* set dims */
p->datatype = datatype; /* and data type */
PDLA->allocdata (p); /* allocate the data chunk */
return p;
}
pdl* myfloatseq()
{
PDLA_Indx dims[] = {5,5,5};
pdl *p = new_pdl(PDLA_F,dims,3);
PDLA_Float *dataf = (PDLA_Float *) p->data;
PDLA_Indx i; /* dimensions might be 64bits */
for (i=0;i<5*5*5;i++)
dataf[i] = i; /* the data must be initialized ! */
return p;
}
=head2 Wrapping your own data into a piddle
Sometimes you obtain a chunk of data from another
source, for example an image processing library, etc.
All you want to do in that case is wrap your data
into a piddle struct at the C level. Examples using this approach
can be found in the IO modules (where FastRaw and FlexRaw
use it for mmapped access) and the Gimp Perl module (that
uses it to wrap Gimp pixel regions into piddles).
The following script demonstrates a simple example:
use PDLA::LiteF;
use PDLA::Core::Dev;
use PDLA::Graphics::PGPLOT;
$b = mkpiddle();
print $b->info,"\n";
imag1 $b;
use Inline with => 'PDLA';
use Inline C;
Inline->init;
__DATA__
__C__
/* wrap a user supplied chunk of data into a piddle
* You must specify the dimensions (dims,ndims) and
* the datatype (constants for the datatypes are declared
* in pdl.h; e.g. PDLA_B for byte type, etc)
*
* when the created piddle 'npdl' is destroyed on the
* Perl side the function passed as the 'delete_magic'
* parameter will be called with the pointer to the pdl structure
* and the 'delparam' argument.
* This gives you an opportunity to perform any clean up
* that is necessary. For example, you might have to
* explicitly call a function to free the resources
* associated with your data pointer.
* At the very least 'delete_magic' should zero the piddle's data pointer:
*
Basic/Pod/API.pod view on Meta::CPAN
INC => &PDLA_INCLUDE,
TYPEMAPS => &PDLA_TYPEMAP,
AUTO_INCLUDE => &PDLA_AUTO_INCLUDE 'PDLA_Corep',
BOOT => &PDLA_BOOT 'PDLA_Corep';
Make sure you use the same identifier with C<PDLA_AUTO_INCLUDE>
and C<PDLA_BOOT> and use that same identifier in your own code.
E.g., continuing from the example above:
pdl *p = PDLA_Corep->pdlnew();
=head2 Some selected core routines explained
The full definition of the C<Core> struct can be found in the file
F<pdlcore.h>. In the following the most frequently used member
functions of this struct are briefly explained.
=over 5
=item *
C<pdl *SvPDLAV(SV *sv)>
=item *
C<pdl *SetSV_PDLA(SV *sv, pdl *it)>
=item *
C<pdl *pdlnew()>
C<pdlnew> returns an empty pdl object that needs further initialization
to turn it into a proper piddle. Example:
pdl *p = PDLA->pdlnew();
PDLA->setdims(p,dims,ndims);
p->datatype = PDLA_B;
=item *
C<pdl *null()>
=item *
C<SV *copy(pdl* p, char* )>
=item *
C<void *smalloc(STRLEN nbytes)>
=item *
C<int howbig(int pdl_datatype)>
=item *
C<void add_deletedata_magic(pdl *p, void (*func)(pdl*, int), int param)>
=item *
C<void allocdata(pdl *p)>
=item *
C<void make_physical(pdl *p)>
=item *
C<void make_physdims(pdl *p)>
=item *
C<void make_physvaffine(pdl *p)>
=item *
C<void qsort_X(PDLA_Xtype *data, PDLA_Indx a, PDLA_Indx b)> and
C<void qsort_ind_X(PDLA_Xtype *data, PDLA_Indx *ix, PDLA_Indx a, PDLA_Indx b)>
where X is one of B,S,U,L,F,D and Xtype is one of Byte, Short, Ushort,
Long, Float or Double. PDLA_Indx is the C integer type corresponding to
appropriate indexing size for the perl configuration (ivsize and ivtype).
It can be either 'long' or 'long long' depending on whether your perl
is 32bit or 64bit enabled.
=item *
C<float NaN_float> and
C<double NaN_double>
These are constants to produce the required NaN values.
=item *
C<void pdl_barf(const char* pat,...)> and
C<void pdl_warn(const char* pat,...)>
These are C-code equivalents of C<barf> and C<warn>. They include special handling of error or warning
messages during pthreading (i.e. processor multi-threading) that defer the messages until after pthreading
is completed. When pthreading is complete, perl's C<barf> or C<warn> is called with the deferred messages. This
is needed to keep from calling perl's C<barf> or C<warn> during pthreading, which can cause segfaults.
Note that C<barf> and C<warn> have been redefined (using c-preprocessor macros) in pdlcore.h to C<< PDLA->barf >>
and C<< PDLA->warn >>. This is to keep any XS or PP code from calling perl's C<barf> or C<warn> directly, which can
cause segfaults during pthreading.
See L<PDLA::ParallelCPU> for more information on pthreading.
=back
=cut
# ones that are not clear:
# safe_indterm
# converttypei_new
# converttype
# get_convertedpdl
# affine_new
# make_trans_mutual
# make_now
# get
( run in 1.012 second using v1.01-cache-2.11-cpan-39bf76dae61 )