Inline-SLang
view release on metacpan or search on metacpan
/*
* this code fragment is essentially the output of:
* use PDL::Core::Dev; print &PDL_BOOT();
* minus the require_pv line and the aTHX_ defines
*/
CoreSV = perl_get_sv("PDL::SHARE",FALSE);
if( NULL == CoreSV )
Perl_croak(aTHX_ "The Inline::SLang module requires the PDL::Core module, which was not found");
PDL = INT2PTR(Core*,SvIV( CoreSV ));
if ( PDL_CORE_VERSION != PDL->Version )
Perl_croak(aTHX_ "The Inline::SLang module needs to be recompiled against the latest installed PDL");
} /* initialize_pdl_core() */
/* Used by sl2pl.c - convert a S-Lang array into a piddle */
/*
* see 'pdldoc API' for explanation of what's going on here
*
* SV *sl2pl_array_pdl( SLang_Array_Type * )
* convert the S-Lang array into a piddle
*
* void pl2sl_array_pdl( SV * )
* convert the piddle into a S-Lang array and
* push this array onto the S-Lang stack
*/
SV *
sl2pl_array_pdl( SLang_Array_Type *at ) {
PDL_Long dims[SLARRAY_MAX_DIMS];
pdl *out;
SV *sv;
size_t dsize;
int i;
/*
* copy over the dims
* (we reverse them since PDL and S-Lang use different
* array-access schemes)
*/
Printf( ("*** converting S-Lang array tp Piddle: ndims=%d [", at->num_dims) );
for ( i = 0; i < at->num_dims; i++ ) {
dims[at->num_dims-1-i] = at->dims[i];
Printf( (" %d", at->dims[i]) );
}
Printf( ("] dtype=%d", at->data_type) );
/* should we check for failure? */
out = PDL->pdlnew();
PDL->setdims( out, dims, at->num_dims );
#include "topdl.h"
/*
* copy the memory from the array since I don't know when S-Lang may delete it
* (would be quicker to just point to it but that leads to memory-managment issues)
*
* It is not entirely clear to me from the S-Lang docs whether I can safely
* access the data field of the array directly.
*/
PDL->allocdata( out );
(void) memcpy( out->data, at->data, (size_t) at->num_elements * dsize );
/* covert the piddle into a 'SV *' */
sv = sv_newmortal();
PDL->SetSV_PDL( sv, out );
SvREFCNT_inc( sv );
return sv;
} /* sl2pl_array_pdl() */
void
pl2sl_array_pdl( SV *item ) {
int dims[SLARRAY_MAX_DIMS];
SLang_Array_Type *at;
pdl *pdl;
SLtype otype;
size_t dsize;
int i;
/*
* we have a piddle. I appear to have to call PDL->make_physdims()
* on it (eg if it is a slice of another piddle), but is that
* all, or should I call PDL.make_physvaffine() instead?
*
* If we do have a piddle that is just a transformation of another
* one then I 'cheat' and make it physical; in that way we can use
* memcpy() to copy the data across rather than process the
* transformation ourselves. It would be nice if there were a function
* in the PDL API which would copy the contents of a "virtual" piddle
* into a contiguous block of memory. Maybe there is one?
*
*/
pdl = PDL->SvPDLV(item);
PDL->make_physdims(pdl);
/* PDL->make_physvaffine(pdl); - do not need this since call make_physical() below */
if ( pdl->ndims > SLARRAY_MAX_DIMS )
croak( "Error: max number of dimensions for a S-Lang array is %d",
SLARRAY_MAX_DIMS );
if ( pdl->ndims == 0 )
croak( "Error: S-Lang does not allow a 0d array - perhaps should promote to 1d or convert to a scalar?" );
/*
* as in sl2pl_array_pdl() we need to reverse the dimensions
*/
Printf( ("*** converting Piddle to S-Lang: ndims=%d [", pdl->ndims) );
for ( i = 0; i < pdl->ndims; i++ ) {
dims[pdl->ndims-1-i] = pdl->dims[i];
Printf( (" %d", dims[i]) );
}
Printf( ("] dtype=%d", pdl->datatype) );
#include "toslang.h"
Printf( (" -> %s\n", SLclass_get_datatype_name(otype)) );
at = SLang_create_array( otype, 0, NULL, dims, pdl->ndims );
if ( at == NULL )
croak( "Error: Unable to create a S-Lang array of %ld elements",
( run in 1.531 second using v1.01-cache-2.11-cpan-9581c071862 )