Inline-SLang

 view release on metacpan or  search on metacpan

pdl.c  view on Meta::CPAN

  /* 
   * 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 )