/* * THIS FILE IS GENERATED FROM pdl.h.PL! Do NOT edit! */ #ifndef __PDL_H #define __PDL_H #define PDL_DEBUGGING 1 #ifdef PDL_DEBUGGING extern int pdl_debugging; #define PDLDEBUG_f(a) if(pdl_debugging) a #else #define PDLDEBUG_f(a) #endif #define ANYVAL_TO_SV(outsv,inany) do { switch (inany.type) { \ case PDL_B: outsv = newSViv( (IV)(inany.value.B) ); break; \ case PDL_S: outsv = newSViv( (IV)(inany.value.S) ); break; \ case PDL_US: outsv = newSViv( (IV)(inany.value.U) ); break; \ case PDL_L: outsv = newSViv( (IV)(inany.value.L) ); break; \ case PDL_IND: outsv = newSViv( (IV)(inany.value.N) ); break; \ case PDL_LL: outsv = newSViv( (IV)(inany.value.Q) ); break; \ case PDL_F: outsv = newSVnv( (NV)(inany.value.F) ); break; \ case PDL_D: outsv = newSVnv( (NV)(inany.value.D) ); break; \ default: outsv = &PL_sv_undef; \ } \ } while (0) #define ANYVAL_FROM_CTYPE(outany,avtype,inval) do { switch (avtype) { \ case PDL_B: outany.type = avtype; outany.value.B = (PDL_Byte)(inval); break; \ case PDL_S: outany.type = avtype; outany.value.S = (PDL_Short)(inval); break; \ case PDL_US: outany.type = avtype; outany.value.U = (PDL_Ushort)(inval); break; \ case PDL_L: outany.type = avtype; outany.value.L = (PDL_Long)(inval); break; \ case PDL_IND: outany.type = avtype; outany.value.N = (PDL_Indx)(inval); break; \ case PDL_LL: outany.type = avtype; outany.value.Q = (PDL_LongLong)(inval); break; \ case PDL_F: outany.type = avtype; outany.value.F = (PDL_Float)(inval); break; \ case PDL_D: outany.type = avtype; outany.value.D = (PDL_Double)(inval); break; \ default: outany.type = -1; outany.value.B = 0; \ } \ } while (0) #define ANYVAL_TO_CTYPE(outval,ctype,inany) do { switch (inany.type) { \ case PDL_B: outval = (ctype)(inany.value.B); break; \ case PDL_S: outval = (ctype)(inany.value.S); break; \ case PDL_US: outval = (ctype)(inany.value.U); break; \ case PDL_L: outval = (ctype)(inany.value.L); break; \ case PDL_IND: outval = (ctype)(inany.value.N); break; \ case PDL_LL: outval = (ctype)(inany.value.Q); break; \ case PDL_F: outval = (ctype)(inany.value.F); break; \ case PDL_D: outval = (ctype)(inany.value.D); break; \ default: outval = 0; \ } \ } while (0) /* Auto-PThreading (i.e. multi-threading) settings for PDL functions */ /* Target number of pthreads: Actual will be this number or less. A 0 here means no pthreading */ extern int pdl_autopthread_targ; /* Actual number of pthreads: This is the number of pthreads created for the last operation where pthreading was used A 0 here means no pthreading */ extern int pdl_autopthread_actual; /* Minimum size of the target PDL involved in pdl function to attempt pthreading (in MBytes ) For small PDLs, it probably isn't worth starting multiple pthreads, so this variable is used to define that threshold (in M-elements, or 2^20 elements ) */ extern int pdl_autopthread_size; typedef struct pdl pdl; /*****************************************************************************/ /*** This section of .h file generated automatically by ***/ /*** PDL::Types::datatypes_header() - don't edit manually ***/ /* Data types/sizes [must be in order of complexity] */ typedef enum { PDL_INVALID=-1, PDL_B, PDL_S, PDL_US, PDL_L, PDL_IND, PDL_LL, PDL_F, PDL_D } pdl_datatypes; /* Define the pdl data types */ typedef unsigned char PDL_Byte; typedef short PDL_Short; typedef unsigned short PDL_Ushort; typedef int PDL_Long; typedef long long PDL_Indx; typedef long long PDL_LongLong; typedef float PDL_Float; typedef double PDL_Double; typedef struct { pdl_datatypes type; union { PDL_Byte B; PDL_Short S; PDL_Ushort U; PDL_Long L; PDL_Indx N; PDL_LongLong Q; PDL_Float F; PDL_Double D; } value; } PDL_Anyval; #define IND_FLAG "lld" /* typedef long long PDL_Indx; */ /*****************************************************************************/ #define PDL_U PDL_US #define PDL_N PDL_IND #define PDL_Q PDL_LL extern int _anyval_eq_anyval(PDL_Anyval, PDL_Anyval); #define ANYVAL_EQ_ANYVAL(x,y) (_anyval_eq_anyval(x,y)) typedef struct badvals { double Double; double default_Double; float Float; float default_Float; long long LongLong; long long default_LongLong; long long Indx; long long default_Indx; int Long; int default_Long; unsigned short Ushort; unsigned short default_Ushort; short Short; short default_Short; unsigned char Byte; unsigned char default_Byte; } badvals; /* * Define the pdl C data structure which maps onto the original PDL * perl data structure. * * Note: pdl.sv is defined as a void pointer to avoid having to * include perl.h in C code which just needs the pdl data. * * We start with the meanings of the pdl.flags bitmapped flagset, * continue with a prerequisite "trans" structure that represents * transformations between linked PDLs, and finish withthe PD * structure itself. */ #define PDL_NDIMS 6 /* Number of dims[] to preallocate */ #define PDL_NCHILDREN 8 /* Number of children ptrs to preallocate */ #define PDL_NTHREADIDS 4 /* Number of different threadids/pdl to preallocate */ /* Constants for pdl.state - not all combinations make sense */ /* data allocated for this pdl. this implies that the data */ /* is up to date if !PDL_PARENTCHANGED */ #define PDL_ALLOCATED 0x0001 /* Parent data has been altered without changing this pdl */ #define PDL_PARENTDATACHANGED 0x0002 /* Parent dims or incs has been altered without changing this pdl. */ #define PDL_PARENTDIMSCHANGED 0x0004 /* Physical data representation of the parent has changed (e.g. */ /* physical transposition), so incs etc. need to be recalculated. */ #define PDL_PARENTREPRCHANGED 0x0008 #define PDL_ANYCHANGED (PDL_PARENTDATACHANGED|PDL_PARENTDIMSCHANGED|PDL_PARENTREPRCHANGED) /* Dataflow tracking flags -- F/B for forward/back. These get set */ /* by transformations when they are set up. */ #define PDL_DATAFLOW_F 0x0010 #define PDL_DATAFLOW_B 0x0020 #define PDL_DATAFLOW_ANY (PDL_DATAFLOW_F|PDL_DATAFLOW_B) /* Was this PDL null originally? */ #define PDL_NOMYDIMS 0x0040 /* Dims should be received via trans. */ #define PDL_MYDIMS_TRANS 0x0080 /* OK to attach a vaffine transformation (i.e. a slice) */ #define PDL_OPT_VAFFTRANSOK 0x0100 #define PDL_OPT_ANY_OK (PDL_OPT_VAFFTRANSOK) /* This is the hdrcpy flag */ #define PDL_HDRCPY 0x0200 /* This is a badval flag for this PDL (hmmm -- there is also a flag */ /* in the struct itself -- must be clearer about what this is for. --CED) */ #define PDL_BADVAL 0x0400 /* Debugging flag */ #define PDL_TRACEDEBUG 0x0800 /* inplace flag */ #define PDL_INPLACE 0x1000 /* Flag indicating destruction in progress */ #define PDL_DESTROYING 0x2000 /* If this flag is set, you must not alter the data pointer nor */ /* free this piddle nor use datasv (which should be null). */ /* This means e.g. that the piddle is mmapped from a file */ #define PDL_DONTTOUCHDATA 0x4000 /* Not sure what this does, but PP uses it a lot. -- CED */ #define PDL_CR_SETDIMSCOND(wtrans,pdl) (((pdl)->state & PDL_MYDIMS_TRANS) \ && (pdl)->trans == (pdl_trans *)(wtrans)) /************************************************** * * Transformation structure * * The structure is general enough to deal with functional transforms * (which were originally intended) but only slices and retype transforms * were implemented. * */ typedef enum pdl_transtype { PDL_SLICE, PDL_RETYPE } pdl_transtype; /* Transformation flags */ #define PDL_TRANS_AFFINE 0x0001 /* Transpdl flags */ #define PDL_TPDL_VAFFINE_OK 0x01 typedef struct pdl_trans pdl_trans; typedef struct pdl_transvtable { pdl_transtype transtype; int flags; int nparents; int npdls; char *per_pdl_flags; void (*redodims)(pdl_trans *tr); /* Only dims and internal trans (makes phys) */ void (*readdata)(pdl_trans *tr); /* Only data, to "data" ptr */ void (*writebackdata)(pdl_trans *tr); /* "data" ptr to parent or granny */ void (*freetrans)(pdl_trans *tr); /* Free both the contents and it of the trans member */ void (*dump)(pdl_trans *tr); /* Dump this transformation */ void (*findvparent)(pdl_trans *tr); /* Find a virtual parent and make ready for readdata etc. */ pdl_trans *(*copy)(pdl_trans *tr); /* Full copy */ int structsize; char *name; /* For debuggers, mostly */ } pdl_transvtable; /* All trans must start with this */ /* Trans flags */ /* Reversible transform -- flag indicates data can flow both ways. */ /* This is critical in routines that both input from and output to */ /* a non-single-valued pdl: updating must occur. (Note that the */ /* transform is not necessarily mathematically reversible) */ #define PDL_ITRANS_REVERSIBLE 0x0001 /* Whether, if a child is changed, this trans should be destroyed or not */ /* (flow if set; sever if clear) */ #define PDL_ITRANS_DO_DATAFLOW_F 0x0002 #define PDL_ITRANS_DO_DATAFLOW_B 0x0004 #define PDL_ITRANS_DO_DATAFLOW_ANY (PDL_ITRANS_DO_DATAFLOW_F|PDL_ITRANS_DO_DATAFLOW_B) #define PDL_ITRANS_ISAFFINE 0x1000 #define PDL_ITRANS_VAFFINEVALID 0x2000 #define PDL_ITRANS_NONMUTUAL 0x4000 /* flag for destruction */ // These define struct pdl_trans and all derived structures. There are many // structures that defined in other parts of the code that can be referenced // like a pdl_trans* because all of these structures have the same pdl_trans // initial piece. These structures can contain multiple pdl* elements in them. // Thus pdl_trans itself ends with a flexible pdl*[] array, which can be used to // reference any number of pdl objects. As a result pdl_trans itself can NOT be // instantiated // vparent is the "virtual parent" which is either // the parent or grandparent or whatever. The trans -structure must store // both the relationship with our current parent and, if necessary, the // virtual parent. #define PDL_TRANS_START_COMMON \ int magicno; \ short flags; \ pdl_transvtable *vtable; \ void (*freeproc)(struct pdl_trans *); /* Call to free this \ (means whether malloced or not) */ \ int bvalflag; /* required for binary compatability even if WITH_BADVAL=0 */ \ int has_badvalue; \ PDL_Anyval badvalue; \ int __datatype #define PDL_TRANS_START(np) \ PDL_TRANS_START_COMMON; \ /* The pdls involved in the transformation */ \ pdl *pdls[np] #define PDL_TRANS_START_FLEXIBLE() \ PDL_TRANS_START_COMMON; \ /* The pdls involved in the transformation */ \ pdl *pdls[] #ifdef PDL_DEBUGGING #define PDL_CHKMAGIC_GENERAL(it,this_magic,type) if((it)->magicno != this_magic) croak("INVALID " #type "MAGIC NO 0x%p %d\n",it,(int)((it)->magicno)); else (void)0 #else #define PDL_CHKMAGIC_GENERAL(it,this_magic,type) #endif #define PDL_TR_MAGICNO 0x91827364 #define PDL_TR_SETMAGIC(it) it->magicno = PDL_TR_MAGICNO #define PDL_TR_CLRMAGIC(it) it->magicno = 0x99876134 #define PDL_TR_CHKMAGIC(it) PDL_CHKMAGIC_GENERAL(it, PDL_TR_MAGICNO, "TRANS ") // This is a generic parent of all the trans structures. It is a flexible array // (can store an arbitrary number of pdl objects). Thus this can NOT be // instantiated, only "child" structures can struct pdl_trans { PDL_TRANS_START_FLEXIBLE(); } ; typedef struct pdl_trans_affine { PDL_TRANS_START(2); /* affine relation to parent */ PDL_Indx *incs; PDL_Indx offs; } pdl_trans_affine; /* Need to make compatible with pdl_trans_affine */ typedef struct pdl_vaffine { PDL_TRANS_START(2); PDL_Indx *incs; PDL_Indx offs; int ndims; PDL_Indx def_incs[PDL_NDIMS]; pdl *from; } pdl_vaffine; #define PDL_VAFFOK(pdl) (pdl->state & PDL_OPT_VAFFTRANSOK) #define PDL_REPRINC(pdl,which) (PDL_VAFFOK(pdl) ? \ pdl->vafftrans->incs[which] : pdl->dimincs[which]) #define PDL_REPROFFS(pdl) (PDL_VAFFOK(pdl) ? pdl->vafftrans->offs : 0) #define PDL_REPRP(pdl) (PDL_VAFFOK(pdl) ? pdl->vafftrans->from->data : pdl->data) #define PDL_REPRP_TRANS(pdl,flag) ((PDL_VAFFOK(pdl) && \ (flag & PDL_TPDL_VAFFINE_OK)) ? pdl->vafftrans->from->data : pdl->data) #define VAFFINE_FLAG_OK(flags,i) ((flags == NULL) ? 1 : (flags[i] & \ PDL_TPDL_VAFFINE_OK)) typedef struct pdl_children { pdl_trans *trans[PDL_NCHILDREN]; struct pdl_children *next; } pdl_children; struct pdl_magic; /**************************************** * PDL structure * Should be kept under 250 bytes if at all possible, for * easier segmentation... * * The 'sv', 'datasv', and 'hdrsv' fields are all void * to avoid having to * load perl.h for C codes that only use PDLs and not the Perl API. * * Similarly, the 'magic' field is void * to avoid having to typedef pdl_magic * here -- it is declared in "pdl_magic.h". */ #define PDL_MAGICNO 0x24645399 #define PDL_CHKMAGIC(it) PDL_CHKMAGIC_GENERAL(it,PDL_MAGICNO,"") struct pdl { unsigned long magicno; /* Always stores PDL_MAGICNO as a sanity check */ /* This is first so most pointer accesses to wrong type are caught */ int state; /* What's in this pdl */ pdl_trans *trans; /* Opaque pointer to internals of transformation from parent */ pdl_vaffine *vafftrans; /* pointer to vaffine transformation a vafftrans is an optimization that is possible for some types of trans (slice etc) - unused for non-affine transformations */ 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 */ /* bad value stored as double, since get_badvalue returns a double */ PDL_Anyval badvalue; /* BAD value is stored as a PDL_Anyval for portability */ int has_badvalue; /* flag is required by pdlapi.c (compare to PDL_BADVAL above -- why two? --CED) */ PDL_Indx nvals; /* Actual size of data (not quite nelem in case of dummy) */ 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) */ short ndims; /* Number of data dimensions in dims and dimincs */ unsigned char *threadids; /* Starting index of the thread index set n */ unsigned char nthreadids; pdl_children children; PDL_Indx def_dims[PDL_NDIMS]; /* Preallocated space for efficiency */ PDL_Indx def_dimincs[PDL_NDIMS]; /* Preallocated space for efficiency */ unsigned char def_threadids[PDL_NTHREADIDS]; struct pdl_magic *magic; void *hdrsv; /* "header", settable from Perl */ }; /************* * Some macros for looping over the children of a given PDL */ #define PDL_DECL_CHILDLOOP(p) \ int p##__i; pdl_children *p##__c; #define PDL_START_CHILDLOOP(p) \ p##__c = &p->children; \ do { \ for(p##__i=0; p##__itrans[p##__i]) { #define PDL_CHILDLOOP_THISCHILD(p) p##__c->trans[p##__i] #define PDL_END_CHILDLOOP(p) \ } \ } \ if(!p##__c) break; \ if(!p##__c->next) break; \ p##__c=p##__c->next; \ } while(1); #define PDLMAX(a,b) ((a) > (b) ? (a) : (b)) /*************** * Some macros to guard against dataflow infinite recursion. */ #define DECL_RECURSE_GUARD static int __nrec=0; #define START_RECURSE_GUARD __nrec++; if(__nrec > 1000) {__nrec=0; die("PDL:Internal Error: data structure recursion limit exceeded (max 1000 levels)\n\tThis could mean that you have found an infinite-recursion error in PDL, or\n\tthat you are building data structures with very long dataflow dependency\n\tchains. You may want to try using sever() to break the dependency.\n");} #define ABORT_RECURSE_GUARD __nrec=0; #define END_RECURSE_GUARD __nrec--; #define PDL_ENSURE_ALLOCATED(it) ( (void)((it->state & PDL_ALLOCATED) || ((pdl_allocdata(it)),1)) ) #define PDL_ENSURE_VAFFTRANS(it) \ ( ((!it->vafftrans) || (it->vafftrans->ndims < it->ndims)) && \ (pdl_vafftrans_alloc(it),1) ) /* __PDL_H */ #endif