PDL

 view release on metacpan or  search on metacpan

lib/PDL/Core/pdl.h.PL  view on Meta::CPAN

   void*    sv;      /* (optional) pointer back to original sv.
                          ALWAYS check for non-null before use.
                          We cannot inc refcnt on this one or we'd
                          never get destroyed */
   void *datasv;        /* Pointer to SV containing data. We own one inc of refcnt */
   void *data;            /* Pointer to actual data (in SV), or NULL if we have no data      */
   PDL_Anyval badvalue; /* BAD value is stored as a PDL_Anyval for portability */
   int has_badvalue;     /* whether this pdl has non-default badval CORE21 make into state flag */
   PDL_Indx nvals; /* Real number of elements (not quite nelem in case of dummy) */
   PDL_Indx nbytes; /* number of bytes allocated in data */
   pdl_datatypes datatype; /* One of the usual suspects (PDL_L, PDL_D, etc.) */
   PDL_Indx   *dims;      /* Array of data dimensions - could point below or to an allocated array */
   PDL_Indx   *dimincs;   /* Array of data default increments, aka strides through memory for each dim (0 for dummies) */
   PDL_Indx    ndims;     /* Number of data dimensions in dims and dimincs */

   PDL_Indx *broadcastids;  /* Starting index of the broadcast index set n */
   PDL_Indx nbroadcastids;

   pdl_trans *def_trans_children[PDL_NCHILDREN];
   PDL_Indx ntrans_children_allocated;
   PDL_Indx first_trans_child_available;
   pdl_trans **trans_children;

   PDL_Indx   def_dims[PDL_NDIMS];   /* Preallocated space for efficiency */
   PDL_Indx   def_dimincs[PDL_NDIMS];   /* Preallocated space for efficiency */
   PDL_Indx   def_broadcastids[PDL_NBROADCASTIDS];

   struct pdl_magic *magic;

   void *hdrsv; /* "header", settable from Perl */
   PDL_Value value; /* to store at least one value */
   PDL_Indx ntrans_children; /* CORE21 put next to other trans-tracking stuff */
};

typedef struct pdl_slice_args {
  PDL_Indx start; /* maps to start index of slice range (inclusive) */
  PDL_Indx end; /* maps to end index of slice range (inclusive) */
  PDL_Indx inc; /* maps to increment of slice range */
  char dummy, squish; /* boolean */
  struct pdl_slice_args *next; /* NULL is last */
} pdl_slice_args;

#define PDL_USESTRUCTVALUE(it) \
        (it->nbytes <= sizeof(it->value))

#define PDLMAX(a,b) ((a) > (b) ? (a) : (b))
#define PDLMIN(a,b) ((a) < (b) ? (a) : (b))
#define PDL_ABS(A) ( (A)>=0 ? (A) : -(A) )

#define PDL_RETERROR2(rv, expr, iferr) \
  do { rv = expr; if (rv.error) { iferr } } while (0)
#define PDL_RETERROR(rv, expr) PDL_RETERROR2(rv, expr, return rv;)
#define PDL_ACCUMERROR(rv, expr) \
  do { \
    pdl_error rv##_local = expr; \
    if (rv##_local.error) rv = pdl_error_accumulate(rv, rv##_local); \
  } while (0)

#define PDL_ENSURE_ALLOCATED(it) \
  if (!(it->state & PDL_ALLOCATED)) { \
    PDL_RETERROR(PDL_err, pdl_allocdata(it)); \
  }

/* for use with PDL_TYPELIST_REAL */
#define PDL_QSORT(symbol, ctype, ppsym, ...) \
  static inline void qsort_ ## ppsym(ctype* xx, PDL_Indx a, PDL_Indx b) { \
     PDL_Indx i,j; \
     ctype t, median; \
     i = a; j = b; \
     median = xx[(i+j) / 2]; \
     do { \
        while (xx[i] < median) \
           i++; \
        while (median < xx[j]) \
           j--; \
        if (i <= j) { \
           t = xx[i]; xx[i] = xx[j]; xx[j] = t; \
           i++; j--; \
        } \
     } while (i <= j); \
     if (a < j) \
        qsort_ ## ppsym(xx,a,j); \
     if (i < b) \
        qsort_ ## ppsym(xx,i,b); \
  }

#define PDL_BROADCASTLOOP_START(funcName, brc, vtable, ptrStep1, ptrStep2, ptrStep3) \
  __brcloopval = PDL->startbroadcastloop(&(brc),(vtable)->funcName, __privtrans, &PDL_err); \
  if (PDL_err.error) return PDL_err; \
  if ( __brcloopval < 0 ) return PDL->make_error_simple(PDL_EFATAL, "Error starting broadcastloop"); \
  if ( __brcloopval ) return PDL_err; \
  do { \
    PDL_Indx *__tdims = PDL->get_broadcastdims(&(brc)); \
    if (!__tdims) return PDL->make_error_simple(PDL_EFATAL, "Error in get_broadcastdims"); \
    register PDL_Indx __tdims0 = __tdims[0]; \
    register PDL_Indx __tdims1 = __tdims[1]; \
    register PDL_Indx *__offsp = PDL->get_threadoffsp(&(brc)); \
    if (!__offsp ) return PDL->make_error_simple(PDL_EFATAL, "Error in get_threadoffsp"); \
    /* incs are each pdl's stride, declared at func start */ \
    /* offs are each pthread's starting offset into each pdl */ \
    ptrStep1 \
    for( __tind1 = 0 ; \
      __tind1 < __tdims1 ; \
      __tind1++ \
      /* step by tinc1, undoing inner-loop of tinc0*tdims0 */ \
      PDL_EXPAND ptrStep2 \
    ) \
    { \
      for( __tind0 = 0 ; \
        __tind0 < __tdims0 ; \
        __tind0++ \
        PDL_EXPAND ptrStep3 \
      ) { \
        /* This is the tightest loop. Make sure inside is optimal. */
#define PDL_BROADCASTLOOP_END(brc, ptrStep1) \
      } \
    } \
    /* undo outer-loop of tinc1*tdims1, and original per-pthread offset */ \
    ptrStep1 \
    __brcloopval = PDL->iterbroadcastloop(&(brc),2); \
    if ( __brcloopval < 0 ) return PDL->make_error_simple(PDL_EFATAL, "Error in iterbroadcastloop"); \



( run in 1.266 second using v1.01-cache-2.11-cpan-39bf76dae61 )