PDL
view release on metacpan or search on metacpan
lib/PDL/Core/pdlapi.c view on Meta::CPAN
child->state &= ~PDL_PARENTDIMSCHANGED; \
} \
} while (0)
#define FREETRANS(trans, destroy) \
if (trans->vtable->freetrans) { \
PDLDEBUG_f(printf("call freetrans\n")); \
PDL_ACCUMERROR(PDL_err, trans->vtable->freetrans(trans, destroy)); \
/* ignore error for now as need to still free rest */ \
if (destroy) PDL_CLRMAGIC(trans); \
}
#define CHANGED(...) \
PDL_ACCUMERROR(PDL_err, pdl_changed(__VA_ARGS__))
extern Core PDL;
pdl_error pdl__make_physical_recprotect(pdl *it, int recurse_count);
pdl_error pdl__make_physvaffine_recprotect(pdl *it, int recurse_count);
/* Make sure transformation is done */
pdl_error pdl__ensure_trans(pdl_trans *trans, int what, char inputs_only, int recurse_count)
{
pdl_error PDL_err = {0, NULL, 0};
PDLDEBUG_f(printf("pdl__ensure_trans %p what=", trans); pdl_dump_flags_fixspace(what, 0, PDL_FLAGS_PDL));
PDL_TR_CHKMAGIC(trans);
pdl_transvtable *vtable = trans->vtable;
if (trans->flags & PDL_ITRANS_ISAFFINE) {
if (!(vtable->nparents == 1 && vtable->npdls == 2))
return pdl_make_error_simple(PDL_EUSERERROR, "Affine trans other than 1 input 1 output");
return pdl__make_physical_recprotect(trans->pdls[1], recurse_count+1);
}
PDL_Indx j, flag=what, par_pvaf=0, j_end = inputs_only ? vtable->nparents : vtable->npdls;
for (j=0; j<j_end; j++) {
if (vtable->par_flags[j] & PDL_PARAM_ISPHYS)
PDL_RETERROR(PDL_err, pdl__make_physical_recprotect(trans->pdls[j], recurse_count+1));
else {
PDL_RETERROR(PDL_err, pdl__make_physvaffine_recprotect(trans->pdls[j], recurse_count+1));
if (PDL_VAFFOK(trans->pdls[j])) par_pvaf++;
}
}
for (j=vtable->nparents; j<vtable->npdls; j++)
flag |= trans->pdls[j]->state & PDL_ANYCHANGED;
PDLDEBUG_f(printf("pdl__ensure_trans after accum, par_pvaf=%"IND_FLAG" flag=", par_pvaf); pdl_dump_flags_fixspace(flag, 0, PDL_FLAGS_PDL));
if (par_pvaf || flag & PDL_PARENTDIMSCHANGED)
REDODIMS(PDL_RETERROR, trans); /* CORE21 change to make_physdims_recetc */
if (flag & PDL_ANYCHANGED)
READDATA(trans);
return PDL_err;
}
pdl *pdl_null(void) {
PDLDEBUG_f(printf("pdl_null\n"));
return pdl_pdlnew();
}
pdl *pdl_scalar(PDL_Anyval anyval) {
PDLDEBUG_f(printf("pdl_scalar type=%d val=", anyval.type); pdl_dump_anyval(anyval); printf("\n"););
pdl *it = pdl_pdlnew();
if (!it) return it;
it->datatype = anyval.type;
it->broadcastids[0] = it->ndims = 0; /* 0 dims in a scalar */
pdl_resize_defaultincs(it);
pdl_error PDL_err = pdl_allocdata(it);
if (PDL_err.error) { pdl_destroy(it); return NULL; }
it->value = anyval.value;
it->state &= ~(PDL_NOMYDIMS); /* has dims */
return it;
}
pdl_error pdl__converttypei_new_recprotect(pdl *PARENT, pdl *CHILD, pdl_datatypes totype, pdl_datatypes force_intype, int recurse_count);
pdl_error pdl__get_convertedpdl_recprotect(pdl *old, pdl **retval, pdl_datatypes type, char switch_sense, int recurse_count) {
pdl_error PDL_err = {0, NULL, 0};
PDL_RECURSE_CHECK(recurse_count);
PDLDEBUG_f(printf("pdl_get_convertedpdl switch_sense=%d\n", (int)switch_sense));
if (old->datatype == type) { *retval = old; return PDL_err; }
char was_flowing = (old->state & PDL_DATAFLOW_F);
pdl *it = pdl_pdlnew();
if (!it) return pdl_make_error_simple(PDL_EFATAL, "Out of Memory\n");
if (switch_sense) {
PDL_err = pdl__converttypei_new_recprotect(it, old, old->datatype, type, recurse_count + 1);
if (PDL_err.error) { pdl_destroy(it); return PDL_err; }
PDL_err = pdl_setdims(it, old->dims, old->ndims);
if (!PDL_err.error && switch_sense > 1 && old->data) { /* NULL data = unallocated "zeroes" */
PDLDEBUG_f(printf("pdl_get_convertedpdl back-pump because inplace\n"));
PDL_err = pdl__make_physical_recprotect(it, recurse_count + 1);
if (!PDL_err.error) WRITEDATA(old->trans_parent);
}
} else
PDL_err = pdl__converttypei_new_recprotect(old, it, type, old->datatype, recurse_count + 1);
if (PDL_err.error) { pdl_destroy(it); return PDL_err; }
if (was_flowing)
it->state |= PDL_DATAFLOW_F;
*retval = it;
return PDL_err;
}
pdl *pdl_get_convertedpdl(pdl *old, pdl_datatypes type) {
pdl *retval;
pdl_error PDL_err = pdl__get_convertedpdl_recprotect(old, &retval, type, 0, 0);
return PDL_err.error ? NULL : retval;
}
pdl_error pdl_allocdata(pdl *it) {
pdl_error PDL_err = {0, NULL, 0};
PDLDEBUG_f(printf("pdl_allocdata %p, %"IND_FLAG", %d\n",it, it->nvals,
it->datatype));
if (it->nvals < 0)
return pdl_make_error(PDL_EUSERERROR, "Tried to allocdata with %"IND_FLAG" values", it->nvals);
PDL_Indx nbytes = it->nvals * pdl_howbig(it->datatype);
PDL_Indx ncurr = it->nbytes;
if (ncurr == nbytes)
return PDL_err; /* Nothing to be done */
if (it->state & PDL_DONTTOUCHDATA)
return pdl_make_error_simple(PDL_EUSERERROR, "Trying to touch data of an untouchable (mmapped?) pdl");
char was_useheap = (ncurr > sizeof(it->value)),
will_useheap = (nbytes > sizeof(it->value));
if (!was_useheap && !will_useheap) {
it->data = &it->value;
} else if (!will_useheap) {
/* was heap, now not */
void *data_old = it->data;
memmove(it->data = &it->value, data_old, PDLMIN(ncurr, nbytes));
SvREFCNT_dec((SV*)it->datasv);
it->datasv = NULL;
} else {
/* now change to be heap */
if (it->datasv == NULL)
it->datasv = newSVpvn("", 0);
(void)SvGROW((SV*)it->datasv, nbytes);
SvCUR_set((SV*)it->datasv, nbytes);
if (it->data && !was_useheap)
memmove(SvPV_nolen((SV*)it->datasv), it->data, PDLMIN(ncurr, nbytes));
it->data = SvPV_nolen((SV*)it->datasv);
}
if (nbytes > ncurr) memset(it->data + ncurr, 0, nbytes - ncurr);
it->nbytes = nbytes;
it->state |= PDL_ALLOCATED;
PDLDEBUG_f(pdl_dump(it));
return PDL_err;
}
pdl* pdl_pdlnew(void) {
pdl *it = (pdl*) malloc(sizeof(pdl));
if (!it) return it;
memset(it, 0, sizeof(pdl));
it->magicno = PDL_MAGICNO;
it->datatype = PDL_D;
it->trans_parent = NULL;
it->vafftrans = NULL;
it->data = it->datasv = it->sv = NULL;
it->has_badvalue = 0;
it->state = PDL_NOMYDIMS;
it->dims = it->def_dims;
it->nbytes = it->nvals = it->dims[0] = 0;
it->dimincs = it->def_dimincs;
it->dimincs[0] = 1;
it->nbroadcastids = 1;
it->broadcastids = it->def_broadcastids;
it->broadcastids[0] = it->ndims = 1;
it->trans_children = it->def_trans_children;
it->ntrans_children_allocated = PDL_NCHILDREN;
it->ntrans_children = 0;
it->magic = 0;
it->hdrsv = 0;
PDLDEBUG_f(printf("pdl_pdlnew %p (size=%zu)\n",it,sizeof(pdl)));
return it;
}
( run in 0.803 second using v1.01-cache-2.11-cpan-39bf76dae61 )