Data-NDArray-Shared
view release on metacpan or search on metacpan
RETVAL
SV *
subtract(self, other)
SV *self
SV *other
PREINIT:
EXTRACT(self);
CODE:
nda_do_elementwise(aTHX_ self, h, other, '-', "Data::NDArray::Shared->subtract");
SvREFCNT_inc(self);
RETVAL = self;
OUTPUT:
RETVAL
SV *
multiply(self, other)
SV *self
SV *other
PREINIT:
EXTRACT(self);
CODE:
nda_do_elementwise(aTHX_ self, h, other, '*', "Data::NDArray::Shared->multiply");
SvREFCNT_inc(self);
RETVAL = self;
OUTPUT:
RETVAL
SV *
to_list(self)
SV *self
PREINIT:
EXTRACT(self);
CODE:
{
uint64_t size = h->size, e; /* cached immutable count, not peer hdr->size */
int dt = h->dtype;
uint32_t nb = nda_dtype_bytes(dt);
char *snap = NULL;
AV *av = newAV();
if (size) {
av_extend(av, (SSize_t)(size - 1)); /* pre-extend BEFORE the lock */
Newx(snap, size * (STRLEN)nb, char);
SAVEFREEPV(snap); /* freed on scope exit / croak */
}
nda_rwlock_rdlock(h);
if (size) memcpy(snap, nda_data(h), (size_t)(size * nb)); /* snapshot raw bytes under the lock */
nda_rwlock_rdunlock(h);
for (e = 0; e < size; e++) /* build the SVs AFTER unlocking */
av_store(av, (SSize_t)e, nda_sv_from_raw(aTHX_ dt, snap + e * nb));
RETVAL = newRV_noinc((SV *)av);
}
OUTPUT:
RETVAL
void
shape(self)
SV *self
PREINIT:
EXTRACT(self);
PPCODE:
{
uint64_t snap[NDA_MAX_DIMS]; uint32_t ndim, d;
/* Snapshot ndim+shape under the read lock: reshape mutates them under
* the write lock, so an unlocked read could tear (a new ndim with a
* stale shape[]). Copy out, unlock, then build the SVs. */
nda_rwlock_rdlock(h);
ndim = h->hdr->ndim;
if (ndim > NDA_MAX_DIMS) ndim = NDA_MAX_DIMS; /* clamp a peer-corrupted ndim */
for (d = 0; d < ndim; d++) snap[d] = (uint64_t)h->hdr->shape[d];
nda_rwlock_rdunlock(h);
EXTEND(SP, (SSize_t)ndim);
for (d = 0; d < ndim; d++)
PUSHs(sv_2mortal(newSVuv((UV)snap[d])));
}
void
strides(self)
SV *self
PREINIT:
EXTRACT(self);
PPCODE:
{
uint64_t snap[NDA_MAX_DIMS]; uint32_t ndim, d;
/* Snapshot ndim+strides under the read lock (see shape): reshape mutates
* them under the write lock; an unlocked read could tear. */
nda_rwlock_rdlock(h);
ndim = h->hdr->ndim;
if (ndim > NDA_MAX_DIMS) ndim = NDA_MAX_DIMS; /* clamp a peer-corrupted ndim */
for (d = 0; d < ndim; d++) snap[d] = (uint64_t)h->hdr->strides[d];
nda_rwlock_rdunlock(h);
EXTEND(SP, (SSize_t)ndim);
for (d = 0; d < ndim; d++)
PUSHs(sv_2mortal(newSVuv((UV)snap[d])));
}
UV
ndim(self)
SV *self
PREINIT:
EXTRACT(self);
CODE:
RETVAL = (UV)h->hdr->ndim; /* current rank (1..8); reshape() can change it */
OUTPUT:
RETVAL
UV
size(self)
SV *self
PREINIT:
EXTRACT(self);
CODE:
RETVAL = (UV)h->hdr->size; /* immutable after creation -- lock-free */
OUTPUT:
RETVAL
UV
itemsize(self)
SV *self
PREINIT:
EXTRACT(self);
CODE:
RETVAL = (UV)h->hdr->itemsize; /* immutable after creation -- lock-free */
OUTPUT:
RETVAL
# Raw contiguous data region as a byte string (read-locked snapshot copy). The
# bytes are row-major C-order; pair with shape()/dtype() to interpret them.
SV *
buffer(self)
SV *self
PREINIT:
EXTRACT(self);
CODE:
{
uint64_t bytes = h->size * h->itemsize; /* cached immutable geometry, not peer hdr fields */
char *base = nda_data(h);
RETVAL = newSVpvn("", 0);
(void)SvGROW(RETVAL, (STRLEN)(bytes + 1)); /* size the buffer BEFORE the lock */
nda_rwlock_rdlock(h);
Copy(base, SvPVX(RETVAL), bytes, char);
nda_rwlock_rdunlock(h);
( run in 1.341 second using v1.01-cache-2.11-cpan-92ad3014f07 )