summaryrefslogtreecommitdiff
path: root/otherlibs/bigarray/bigarray_stubs.c
diff options
context:
space:
mode:
Diffstat (limited to 'otherlibs/bigarray/bigarray_stubs.c')
-rw-r--r--otherlibs/bigarray/bigarray_stubs.c1073
1 files changed, 0 insertions, 1073 deletions
diff --git a/otherlibs/bigarray/bigarray_stubs.c b/otherlibs/bigarray/bigarray_stubs.c
deleted file mode 100644
index 969c111b12..0000000000
--- a/otherlibs/bigarray/bigarray_stubs.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/***********************************************************************/
-/* */
-/* Objective Caml */
-/* */
-/* Manuel Serrano and Xavier Leroy, INRIA Rocquencourt */
-/* */
-/* Copyright 2000 Institut National de Recherche en Informatique et */
-/* en Automatique. All rights reserved. This file is distributed */
-/* under the terms of the GNU Library General Public License, with */
-/* the special exception on linking described in file ../../LICENSE. */
-/* */
-/***********************************************************************/
-
-/* $Id$ */
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include "alloc.h"
-#include "bigarray.h"
-#include "custom.h"
-#include "fail.h"
-#include "intext.h"
-#include "memory.h"
-#include "mlvalues.h"
-
-CAMLextern int compare_unordered; /* from byterun/compare.c */
-
-extern void bigarray_unmap_file(void * addr, unsigned long len);
- /* from mmap_xxx.c */
-
-/* Compute the number of elements of a big array */
-
-static unsigned long bigarray_num_elts(struct caml_bigarray * b)
-{
- unsigned long num_elts;
- int i;
- num_elts = 1;
- for (i = 0; i < b->num_dims; i++) num_elts = num_elts * b->dim[i];
- return num_elts;
-}
-
-/* Size in bytes of a bigarray element, indexed by bigarray kind */
-
-int bigarray_element_size[] =
-{ 4 /*FLOAT32*/, 8 /*FLOAT64*/,
- 1 /*SINT8*/, 1 /*UINT8*/,
- 2 /*SINT16*/, 2 /*UINT16*/,
- 4 /*INT32*/, 8 /*INT64*/,
- sizeof(value) /*CAML_INT*/, sizeof(value) /*NATIVE_INT*/,
- 8 /*COMPLEX32*/, 16 /*COMPLEX64*/
-};
-
-/* Compute the number of bytes for the elements of a big array */
-
-unsigned long bigarray_byte_size(struct caml_bigarray * b)
-{
- return bigarray_num_elts(b)
- * bigarray_element_size[b->flags & BIGARRAY_KIND_MASK];
-}
-
-/* Operation table for bigarrays */
-
-static void bigarray_finalize(value v);
-static int bigarray_compare(value v1, value v2);
-static long bigarray_hash(value v);
-static void bigarray_serialize(value, unsigned long *, unsigned long *);
-unsigned long bigarray_deserialize(void * dst);
-static struct custom_operations bigarray_ops = {
- "_bigarray",
- bigarray_finalize,
- bigarray_compare,
- bigarray_hash,
- bigarray_serialize,
- bigarray_deserialize
-};
-
-/* Multiplication of unsigned longs with overflow detection */
-
-static unsigned long
-bigarray_multov(unsigned long a, unsigned long b, int * overflow)
-{
-#define HALF_SIZE (sizeof(unsigned long) * 4)
-#define LOW_HALF(x) ((x) & ((1UL << HALF_SIZE) - 1))
-#define HIGH_HALF(x) ((x) >> HALF_SIZE)
- /* Cut in half words */
- unsigned long al = LOW_HALF(a);
- unsigned long ah = HIGH_HALF(a);
- unsigned long bl = LOW_HALF(b);
- unsigned long bh = HIGH_HALF(b);
- /* Exact product is:
- al * bl
- + ah * bl << HALF_SIZE
- + al * bh << HALF_SIZE
- + ah * bh << 2*HALF_SIZE
- Overflow occurs if:
- ah * bh is not 0, i.e. ah != 0 and bh != 0
- OR ah * bl has high half != 0
- OR ah * bl has high half != 0
- OR the sum al * bl + LOW_HALF(ah * bl) << HALF_SIZE
- + LOW_HALF(al * bh) << HALF_SIZE overflows.
- This sum is equal to p = (a * b) modulo word size. */
- unsigned long p1 = al * bh;
- unsigned long p2 = ah * bl;
- unsigned long p = a * b;
- if (ah != 0 && bh != 0) *overflow = 1;
- if (p1 >= (1UL << HALF_SIZE) || p2 >= (1UL << HALF_SIZE)) *overflow = 1;
- p1 <<= HALF_SIZE;
- p2 <<= HALF_SIZE;
- p1 += p2;
- if (p < p1 || p1 < p2) *overflow = 1; /* overflow in sums */
- return p;
-#undef HALF_SIZE
-#undef LOW_HALF
-#undef HIGH_HALF
-}
-
-/* Allocation of a big array */
-
-#define MAX_BIGARRAY_MEMORY 256*1024*1024
-/* 256 Mb -- after allocating that much, it's probably worth speeding
- up the major GC */
-
-/* [alloc_bigarray] will allocate a new bigarray object in the heap.
- If [data] is NULL, the memory for the contents is also allocated
- (with [malloc]) by [alloc_bigarray].
- [data] cannot point into the Caml heap.
- [dim] may point into an object in the Caml heap.
-*/
-CAMLexport value
-alloc_bigarray(int flags, int num_dims, void * data, long * dim)
-{
- unsigned long num_elts, size;
- int overflow, i;
- value res;
- struct caml_bigarray * b;
- long dimcopy[MAX_NUM_DIMS];
-
- Assert(num_dims >= 1 && num_dims <= MAX_NUM_DIMS);
- Assert((flags & BIGARRAY_KIND_MASK) <= BIGARRAY_COMPLEX64);
- for (i = 0; i < num_dims; i++) dimcopy[i] = dim[i];
- size = 0;
- if (data == NULL) {
- overflow = 0;
- num_elts = 1;
- for (i = 0; i < num_dims; i++) {
- num_elts = bigarray_multov(num_elts, dimcopy[i], &overflow);
- }
- size = bigarray_multov(num_elts,
- bigarray_element_size[flags & BIGARRAY_KIND_MASK],
- &overflow);
- if (overflow) raise_out_of_memory();
- data = malloc(size);
- if (data == NULL && size != 0) raise_out_of_memory();
- flags |= BIGARRAY_MANAGED;
- }
- res = alloc_custom(&bigarray_ops,
- sizeof(struct caml_bigarray)
- + (num_dims - 1) * sizeof(long),
- size, MAX_BIGARRAY_MEMORY);
- b = Bigarray_val(res);
- b->data = data;
- b->num_dims = num_dims;
- b->flags = flags;
- b->proxy = NULL;
- for (i = 0; i < num_dims; i++) b->dim[i] = dimcopy[i];
- return res;
-}
-
-/* Same as alloc_bigarray, but dimensions are passed as a list of
- arguments */
-
-CAMLexport value alloc_bigarray_dims(int flags, int num_dims, void * data, ...)
-{
- va_list ap;
- long dim[MAX_NUM_DIMS];
- int i;
- value res;
-
- va_start(ap, data);
- for (i = 0; i < num_dims; i++) dim[i] = va_arg(ap, long);
- va_end(ap);
- res = alloc_bigarray(flags, num_dims, data, dim);
- return res;
-}
-
-/* Allocate a bigarray from Caml */
-
-CAMLprim value bigarray_create(value vkind, value vlayout, value vdim)
-{
- long dim[MAX_NUM_DIMS];
- mlsize_t num_dims;
- int i, flags;
-
- num_dims = Wosize_val(vdim);
- if (num_dims < 1 || num_dims > MAX_NUM_DIMS)
- invalid_argument("Bigarray.create: bad number of dimensions");
- for (i = 0; i < num_dims; i++) {
- dim[i] = Long_val(Field(vdim, i));
- if (dim[i] < 0 || dim[i] > 0x7FFFFFFFL)
- invalid_argument("Bigarray.create: negative dimension");
- }
- flags = Int_val(vkind) | Int_val(vlayout);
- return alloc_bigarray(flags, num_dims, NULL, dim);
-}
-
-/* Given a big array and a vector of indices, check that the indices
- are within the bounds and return the offset of the corresponding
- array element in the data part of the array. */
-
-static long bigarray_offset(struct caml_bigarray * b, long * index)
-{
- long offset;
- int i;
-
- offset = 0;
- if ((b->flags & BIGARRAY_LAYOUT_MASK) == BIGARRAY_C_LAYOUT) {
- /* C-style layout: row major, indices start at 0 */
- for (i = 0; i < b->num_dims; i++) {
- if ((unsigned long) index[i] >= (unsigned long) b->dim[i])
- array_bound_error();
- offset = offset * b->dim[i] + index[i];
- }
- } else {
- /* Fortran-style layout: column major, indices start at 1 */
- for (i = b->num_dims - 1; i >= 0; i--) {
- if ((unsigned long) (index[i] - 1) >= (unsigned long) b->dim[i])
- array_bound_error();
- offset = offset * b->dim[i] + (index[i] - 1);
- }
- }
- return offset;
-}
-
-/* Helper function to allocate a record of two double floats */
-
-static value copy_two_doubles(double d0, double d1)
-{
- value res = alloc_small(2 * Double_wosize, Double_array_tag);
- Store_double_field(res, 0, d0);
- Store_double_field(res, 1, d1);
- return res;
-}
-
-/* Generic code to read from a big array */
-
-value bigarray_get_N(value vb, value * vind, int nind)
-{
- struct caml_bigarray * b = Bigarray_val(vb);
- long index[MAX_NUM_DIMS];
- int i;
- long offset;
-
- /* Check number of indices = number of dimensions of array
- (maybe not necessary if ML typing guarantees this) */
- if (nind != b->num_dims)
- invalid_argument("Bigarray.get: wrong number of indices");
- /* Compute offset and check bounds */
- for (i = 0; i < b->num_dims; i++) index[i] = Long_val(vind[i]);
- offset = bigarray_offset(b, index);
- /* Perform read */
- switch ((b->flags) & BIGARRAY_KIND_MASK) {
- default:
- Assert(0);
- case BIGARRAY_FLOAT32:
- return copy_double(((float *) b->data)[offset]);
- case BIGARRAY_FLOAT64:
- return copy_double(((double *) b->data)[offset]);
- case BIGARRAY_SINT8:
- return Val_int(((schar *) b->data)[offset]);
- case BIGARRAY_UINT8:
- return Val_int(((unsigned char *) b->data)[offset]);
- case BIGARRAY_SINT16:
- return Val_int(((int16 *) b->data)[offset]);
- case BIGARRAY_UINT16:
- return Val_int(((uint16 *) b->data)[offset]);
- case BIGARRAY_INT32:
- return copy_int32(((int32 *) b->data)[offset]);
- case BIGARRAY_INT64:
- return copy_int64(((int64 *) b->data)[offset]);
- case BIGARRAY_NATIVE_INT:
- return copy_nativeint(((long *) b->data)[offset]);
- case BIGARRAY_CAML_INT:
- return Val_long(((long *) b->data)[offset]);
- case BIGARRAY_COMPLEX32:
- { float * p = ((float *) b->data) + offset * 2;
- return copy_two_doubles(p[0], p[1]); }
- case BIGARRAY_COMPLEX64:
- { double * p = ((double *) b->data) + offset * 2;
- return copy_two_doubles(p[0], p[1]); }
- }
-}
-
-CAMLprim value bigarray_get_1(value vb, value vind1)
-{
- return bigarray_get_N(vb, &vind1, 1);
-}
-
-CAMLprim value bigarray_get_2(value vb, value vind1, value vind2)
-{
- value vind[2];
- vind[0] = vind1; vind[1] = vind2;
- return bigarray_get_N(vb, vind, 2);
-}
-
-CAMLprim value bigarray_get_3(value vb, value vind1, value vind2, value vind3)
-{
- value vind[3];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3;
- return bigarray_get_N(vb, vind, 3);
-}
-
-#if 0
-CAMLprim value bigarray_get_4(value vb, value vind1, value vind2,
- value vind3, value vind4)
-{
- value vind[4];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3; vind[3] = vind4;
- return bigarray_get_N(vb, vind, 4);
-}
-
-CAMLprim value bigarray_get_5(value vb, value vind1, value vind2,
- value vind3, value vind4, value vind5)
-{
- value vind[5];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3;
- vind[3] = vind4; vind[4] = vind5;
- return bigarray_get_N(vb, vind, 5);
-}
-
-CAMLprim value bigarray_get_6(value vb, value vind1, value vind2,
- value vind3, value vind4, value vind5, value vind6)
-{
- value vind[6];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3;
- vind[3] = vind4; vind[4] = vind5; vind[5] = vind6;
- return bigarray_get_N(vb, vind, 6);
-}
-#endif
-
-CAMLprim value bigarray_get_generic(value vb, value vind)
-{
- return bigarray_get_N(vb, &Field(vind, 0), Wosize_val(vind));
-}
-
-/* Generic write to a big array */
-
-static value bigarray_set_aux(value vb, value * vind, long nind, value newval)
-{
- struct caml_bigarray * b = Bigarray_val(vb);
- long index[MAX_NUM_DIMS];
- int i;
- long offset;
-
- /* Check number of indices = number of dimensions of array
- (maybe not necessary if ML typing guarantees this) */
- if (nind != b->num_dims)
- invalid_argument("Bigarray.set: wrong number of indices");
- /* Compute offset and check bounds */
- for (i = 0; i < b->num_dims; i++) index[i] = Long_val(vind[i]);
- offset = bigarray_offset(b, index);
- /* Perform write */
- switch (b->flags & BIGARRAY_KIND_MASK) {
- default:
- Assert(0);
- case BIGARRAY_FLOAT32:
- ((float *) b->data)[offset] = Double_val(newval); break;
- case BIGARRAY_FLOAT64:
- ((double *) b->data)[offset] = Double_val(newval); break;
- case BIGARRAY_SINT8:
- case BIGARRAY_UINT8:
- ((schar *) b->data)[offset] = Int_val(newval); break;
- case BIGARRAY_SINT16:
- case BIGARRAY_UINT16:
- ((int16 *) b->data)[offset] = Int_val(newval); break;
- case BIGARRAY_INT32:
- ((int32 *) b->data)[offset] = Int32_val(newval); break;
- case BIGARRAY_INT64:
- ((int64 *) b->data)[offset] = Int64_val(newval); break;
- case BIGARRAY_NATIVE_INT:
- ((long *) b->data)[offset] = Nativeint_val(newval); break;
- case BIGARRAY_CAML_INT:
- ((long *) b->data)[offset] = Long_val(newval); break;
- case BIGARRAY_COMPLEX32:
- { float * p = ((float *) b->data) + offset * 2;
- p[0] = Double_field(newval, 0);
- p[1] = Double_field(newval, 1);
- break; }
- case BIGARRAY_COMPLEX64:
- { double * p = ((double *) b->data) + offset * 2;
- p[0] = Double_field(newval, 0);
- p[1] = Double_field(newval, 1);
- break; }
- }
- return Val_unit;
-}
-
-CAMLprim value bigarray_set_1(value vb, value vind1, value newval)
-{
- return bigarray_set_aux(vb, &vind1, 1, newval);
-}
-
-CAMLprim value bigarray_set_2(value vb, value vind1, value vind2, value newval)
-{
- value vind[2];
- vind[0] = vind1; vind[1] = vind2;
- return bigarray_set_aux(vb, vind, 2, newval);
-}
-
-CAMLprim value bigarray_set_3(value vb, value vind1, value vind2, value vind3,
- value newval)
-{
- value vind[3];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3;
- return bigarray_set_aux(vb, vind, 3, newval);
-}
-
-#if 0
-CAMLprim value bigarray_set_4(value vb, value vind1, value vind2,
- value vind3, value vind4, value newval)
-{
- value vind[4];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3; vind[3] = vind4;
- return bigarray_set_aux(vb, vind, 4, newval);
-}
-
-CAMLprim value bigarray_set_5(value vb, value vind1, value vind2,
- value vind3, value vind4, value vind5, value newval)
-{
- value vind[5];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3;
- vind[3] = vind4; vind[4] = vind5;
- return bigarray_set_aux(vb, vind, 5, newval);
-}
-
-CAMLprim value bigarray_set_6(value vb, value vind1, value vind2,
- value vind3, value vind4, value vind5,
- value vind6, value newval)
-{
- value vind[6];
- vind[0] = vind1; vind[1] = vind2; vind[2] = vind3;
- vind[3] = vind4; vind[4] = vind5; vind[5] = vind6;
- return bigarray_set_aux(vb, vind, 6, newval);
-}
-
-value bigarray_set_N(value vb, value * vind, int nargs)
-{
- return bigarray_set_aux(vb, vind, nargs - 1, vind[nargs - 1]);
-}
-#endif
-
-CAMLprim value bigarray_set_generic(value vb, value vind, value newval)
-{
- return bigarray_set_aux(vb, &Field(vind, 0), Wosize_val(vind), newval);
-}
-
-/* Return the number of dimensions of a big array */
-
-CAMLprim value bigarray_num_dims(value vb)
-{
- struct caml_bigarray * b = Bigarray_val(vb);
- return Val_long(b->num_dims);
-}
-
-/* Return the n-th dimension of a big array */
-
-CAMLprim value bigarray_dim(value vb, value vn)
-{
- struct caml_bigarray * b = Bigarray_val(vb);
- long n = Long_val(vn);
- if (n >= b->num_dims) invalid_argument("Bigarray.dim");
- return Val_long(b->dim[n]);
-}
-
-/* Return the kind of a big array */
-
-CAMLprim value bigarray_kind(value vb)
-{
- return Val_int(Bigarray_val(vb)->flags & BIGARRAY_KIND_MASK);
-}
-
-/* Return the layout of a big array */
-
-CAMLprim value bigarray_layout(value vb)
-{
- return Val_int(Bigarray_val(vb)->flags & BIGARRAY_LAYOUT_MASK);
-}
-
-/* Finalization of a big array */
-
-static void bigarray_finalize(value v)
-{
- struct caml_bigarray * b = Bigarray_val(v);
-
- switch (b->flags & BIGARRAY_MANAGED_MASK) {
- case BIGARRAY_EXTERNAL:
- break;
- case BIGARRAY_MANAGED:
- if (b->proxy == NULL) {
- free(b->data);
- } else {
- if (-- b->proxy->refcount == 0) {
- free(b->proxy->data);
- stat_free(b->proxy);
- }
- }
- break;
- case BIGARRAY_MAPPED_FILE:
- if (b->proxy == NULL) {
- bigarray_unmap_file(b->data, bigarray_byte_size(b));
- } else {
- if (-- b->proxy->refcount == 0) {
- bigarray_unmap_file(b->proxy->data, b->proxy->size);
- stat_free(b->proxy);
- }
- }
- break;
- }
-}
-
-/* Comparison of two big arrays */
-
-static int bigarray_compare(value v1, value v2)
-{
- struct caml_bigarray * b1 = Bigarray_val(v1);
- struct caml_bigarray * b2 = Bigarray_val(v2);
- unsigned long n, num_elts;
- int i;
-
- /* Compare number of dimensions */
- if (b1->num_dims != b2->num_dims) return b2->num_dims - b1->num_dims;
- /* Same number of dimensions: compare dimensions lexicographically */
- for (i = 0; i < b1->num_dims; i++) {
- long d1 = b1->dim[i];
- long d2 = b2->dim[i];
- if (d1 != d2) return d1 < d2 ? -1 : 1;
- }
- /* Same dimensions: compare contents lexicographically */
- num_elts = bigarray_num_elts(b1);
-
-#define DO_INTEGER_COMPARISON(type) \
- { type * p1 = b1->data; type * p2 = b2->data; \
- for (n = 0; n < num_elts; n++) { \
- type e1 = *p1++; type e2 = *p2++; \
- if (e1 < e2) return -1; \
- if (e1 > e2) return 1; \
- } \
- return 0; \
- }
-#define DO_FLOAT_COMPARISON(type) \
- { type * p1 = b1->data; type * p2 = b2->data; \
- for (n = 0; n < num_elts; n++) { \
- type e1 = *p1++; type e2 = *p2++; \
- if (e1 < e2) return -1; \
- if (e1 > e2) return 1; \
- if (e1 != e2) { \
- compare_unordered = 1; \
- if (e1 == e1) return 1; \
- if (e2 == e2) return -1; \
- } \
- } \
- return 0; \
- }
-
- switch (b1->flags & BIGARRAY_KIND_MASK) {
- case BIGARRAY_COMPLEX32:
- num_elts *= 2; /*fallthrough*/
- case BIGARRAY_FLOAT32:
- DO_FLOAT_COMPARISON(float);
- case BIGARRAY_COMPLEX64:
- num_elts *= 2; /*fallthrough*/
- case BIGARRAY_FLOAT64:
- DO_FLOAT_COMPARISON(double);
- case BIGARRAY_SINT8:
- DO_INTEGER_COMPARISON(schar);
- case BIGARRAY_UINT8:
- DO_INTEGER_COMPARISON(unsigned char);
- case BIGARRAY_SINT16:
- DO_INTEGER_COMPARISON(int16);
- case BIGARRAY_UINT16:
- DO_INTEGER_COMPARISON(uint16);
- case BIGARRAY_INT32:
- DO_INTEGER_COMPARISON(int32);
- case BIGARRAY_INT64:
-#ifdef ARCH_INT64_TYPE
- DO_INTEGER_COMPARISON(int64);
-#else
- { int64 * p1 = b1->data; int64 * p2 = b2->data;
- for (n = 0; n < num_elts; n++) {
- int64 e1 = *p1++; int64 e2 = *p2++;
- if ((int32)e1.h > (int32)e2.h) return 1;
- if ((int32)e1.h < (int32)e2.h) return -1;
- if (e1.l > e2.l) return 1;
- if (e1.l < e2.l) return -1;
- }
- return 0;
- }
-#endif
- case BIGARRAY_CAML_INT:
- case BIGARRAY_NATIVE_INT:
- DO_INTEGER_COMPARISON(long);
- default:
- Assert(0);
- return 0; /* should not happen */
- }
-#undef DO_INTEGER_COMPARISON
-#undef DO_FLOAT_COMPARISON
-}
-
-/* Hashing of a bigarray */
-
-static long bigarray_hash(value v)
-{
- struct caml_bigarray * b = Bigarray_val(v);
- long num_elts, n, h;
- int i;
-
- num_elts = 1;
- for (i = 0; i < b->num_dims; i++) num_elts = num_elts * b->dim[i];
- if (num_elts >= 50) num_elts = 50;
- h = 0;
-
-#define COMBINE(h,v) ((h << 4) + h + (v))
-
- switch (b->flags & BIGARRAY_KIND_MASK) {
- case BIGARRAY_SINT8:
- case BIGARRAY_UINT8: {
- unsigned char * p = b->data;
- for (n = 0; n < num_elts; n++) h = COMBINE(h, *p++);
- break;
- }
- case BIGARRAY_SINT16:
- case BIGARRAY_UINT16: {
- unsigned short * p = b->data;
- for (n = 0; n < num_elts; n++) h = COMBINE(h, *p++);
- break;
- }
- case BIGARRAY_FLOAT32:
- case BIGARRAY_COMPLEX32:
- case BIGARRAY_INT32:
-#ifndef ARCH_SIXTYFOUR
- case BIGARRAY_CAML_INT:
- case BIGARRAY_NATIVE_INT:
-#endif
- {
- uint32 * p = b->data;
- for (n = 0; n < num_elts; n++) h = COMBINE(h, *p++);
- break;
- }
- case BIGARRAY_FLOAT64:
- case BIGARRAY_COMPLEX64:
- case BIGARRAY_INT64:
-#ifdef ARCH_SIXTYFOUR
- case BIGARRAY_CAML_INT:
- case BIGARRAY_NATIVE_INT:
-#endif
-#ifdef ARCH_SIXTYFOUR
- {
- unsigned long * p = b->data;
- for (n = 0; n < num_elts; n++) h = COMBINE(h, *p++);
- break;
- }
-#else
- {
- uint32 * p = b->data;
- for (n = 0; n < num_elts; n++) {
-#ifdef ARCH_BIG_ENDIAN
- h = COMBINE(h, p[1]); h = COMBINE(h, p[0]); p += 2;
-#else
- h = COMBINE(h, p[0]); h = COMBINE(h, p[1]); p += 2;
-#endif
- }
- break;
- }
-#endif
- }
-#undef COMBINE
- return h;
-}
-
-static void bigarray_serialize_longarray(void * data,
- long num_elts,
- long min_val, long max_val)
-{
-#ifdef ARCH_SIXTYFOUR
- int overflow_32 = 0;
- long * p, n;
- for (n = 0, p = data; n < num_elts; n++, p++) {
- if (*p < min_val || *p > max_val) { overflow_32 = 1; break; }
- }
- if (overflow_32) {
- serialize_int_1(1);
- serialize_block_8(data, num_elts);
- } else {
- serialize_int_1(0);
- for (n = 0, p = data; n < num_elts; n++, p++) serialize_int_4((int32) *p);
- }
-#else
- serialize_int_1(0);
- serialize_block_4(data, num_elts);
-#endif
-}
-
-static void bigarray_serialize(value v,
- unsigned long * wsize_32,
- unsigned long * wsize_64)
-{
- struct caml_bigarray * b = Bigarray_val(v);
- long num_elts;
- int i;
-
- /* Serialize header information */
- serialize_int_4(b->num_dims);
- serialize_int_4(b->flags & (BIGARRAY_KIND_MASK | BIGARRAY_LAYOUT_MASK));
- for (i = 0; i < b->num_dims; i++) serialize_int_4(b->dim[i]);
- /* Compute total number of elements */
- num_elts = 1;
- for (i = 0; i < b->num_dims; i++) num_elts = num_elts * b->dim[i];
- /* Serialize elements */
- switch (b->flags & BIGARRAY_KIND_MASK) {
- case BIGARRAY_SINT8:
- case BIGARRAY_UINT8:
- serialize_block_1(b->data, num_elts); break;
- case BIGARRAY_SINT16:
- case BIGARRAY_UINT16:
- serialize_block_2(b->data, num_elts); break;
- case BIGARRAY_FLOAT32:
- case BIGARRAY_INT32:
- serialize_block_4(b->data, num_elts); break;
- case BIGARRAY_COMPLEX32:
- serialize_block_4(b->data, num_elts * 2); break;
- case BIGARRAY_FLOAT64:
- case BIGARRAY_INT64:
- serialize_block_8(b->data, num_elts); break;
- case BIGARRAY_COMPLEX64:
- serialize_block_8(b->data, num_elts * 2); break;
- case BIGARRAY_CAML_INT:
- bigarray_serialize_longarray(b->data, num_elts, -0x40000000, 0x3FFFFFFF);
- break;
- case BIGARRAY_NATIVE_INT:
- bigarray_serialize_longarray(b->data, num_elts, -0x80000000, 0x7FFFFFFF);
- break;
- }
- /* Compute required size in Caml heap. Assumes struct caml_bigarray
- is exactly 4 + num_dims words */
- Assert(sizeof(struct caml_bigarray) == 5 * sizeof(value));
- *wsize_32 = (4 + b->num_dims) * 4;
- *wsize_64 = (4 + b->num_dims) * 8;
-}
-
-static void bigarray_deserialize_longarray(void * dest, long num_elts)
-{
- int sixty = deserialize_uint_1();
-#ifdef ARCH_SIXTYFOUR
- if (sixty) {
- deserialize_block_8(dest, num_elts);
- } else {
- long * p, n;
- for (n = 0, p = dest; n < num_elts; n++, p++) *p = deserialize_sint_4();
- }
-#else
- if (sixty)
- deserialize_error("input_value: cannot read bigarray "
- "with 64-bit Caml ints");
- deserialize_block_4(dest, num_elts);
-#endif
-}
-
-unsigned long bigarray_deserialize(void * dst)
-{
- struct caml_bigarray * b = dst;
- int i, elt_size;
- unsigned long num_elts;
-
- /* Read back header information */
- b->num_dims = deserialize_uint_4();
- b->flags = deserialize_uint_4() | BIGARRAY_MANAGED;
- b->proxy = NULL;
- for (i = 0; i < b->num_dims; i++) b->dim[i] = deserialize_uint_4();
- /* Compute total number of elements */
- num_elts = bigarray_num_elts(b);
- /* Determine element size in bytes */
- if ((b->flags & BIGARRAY_KIND_MASK) > BIGARRAY_COMPLEX64)
- deserialize_error("input_value: bad bigarray kind");
- elt_size = bigarray_element_size[b->flags & BIGARRAY_KIND_MASK];
- /* Allocate room for data */
- b->data = malloc(elt_size * num_elts);
- if (b->data == NULL)
- deserialize_error("input_value: out of memory for bigarray");
- /* Read data */
- switch (b->flags & BIGARRAY_KIND_MASK) {
- case BIGARRAY_SINT8:
- case BIGARRAY_UINT8:
- deserialize_block_1(b->data, num_elts); break;
- case BIGARRAY_SINT16:
- case BIGARRAY_UINT16:
- deserialize_block_2(b->data, num_elts); break;
- case BIGARRAY_FLOAT32:
- case BIGARRAY_INT32:
- deserialize_block_4(b->data, num_elts); break;
- case BIGARRAY_COMPLEX32:
- deserialize_block_4(b->data, num_elts * 2); break;
- case BIGARRAY_FLOAT64:
- case BIGARRAY_INT64:
- deserialize_block_8(b->data, num_elts); break;
- case BIGARRAY_COMPLEX64:
- deserialize_block_8(b->data, num_elts * 2); break;
- case BIGARRAY_CAML_INT:
- case BIGARRAY_NATIVE_INT:
- bigarray_deserialize_longarray(b->data, num_elts); break;
- }
- return sizeof(struct caml_bigarray) + (b->num_dims - 1) * sizeof(long);
-}
-
-/* Create / update proxy to indicate that b2 is a sub-array of b1 */
-
-static void bigarray_update_proxy(struct caml_bigarray * b1,
- struct caml_bigarray * b2)
-{
- struct caml_bigarray_proxy * proxy;
- /* Nothing to do for un-managed arrays */
- if ((b1->flags & BIGARRAY_MANAGED_MASK) == BIGARRAY_EXTERNAL) return;
- if (b1->proxy != NULL) {
- /* If b1 is already a proxy for a larger array, increment refcount of
- proxy */
- b2->proxy = b1->proxy;
- ++ b1->proxy->refcount;
- } else {
- /* Otherwise, create proxy and attach it to both b1 and b2 */
- proxy = stat_alloc(sizeof(struct caml_bigarray_proxy));
- proxy->refcount = 2; /* original array + sub array */
- proxy->data = b1->data;
- proxy->size =
- b1->flags & BIGARRAY_MAPPED_FILE ? bigarray_byte_size(b1) : 0;
- b1->proxy = proxy;
- b2->proxy = proxy;
- }
-}
-
-/* Slicing */
-
-CAMLprim value bigarray_slice(value vb, value vind)
-{
- CAMLparam2 (vb, vind);
- #define b ((struct caml_bigarray *) Bigarray_val(vb))
- CAMLlocal1 (res);
- long index[MAX_NUM_DIMS];
- int num_inds, i;
- long offset;
- long * sub_dims;
- char * sub_data;
-
- /* Check number of indices < number of dimensions of array */
- num_inds = Wosize_val(vind);
- if (num_inds >= b->num_dims)
- invalid_argument("Bigarray.slice: too many indices");
- /* Compute offset and check bounds */
- if ((b->flags & BIGARRAY_LAYOUT_MASK) == BIGARRAY_C_LAYOUT) {
- /* We slice from the left */
- for (i = 0; i < num_inds; i++) index[i] = Long_val(Field(vind, i));
- for (/*nothing*/; i < b->num_dims; i++) index[i] = 0;
- offset = bigarray_offset(b, index);
- sub_dims = b->dim + num_inds;
- } else {
- /* We slice from the right */
- for (i = 0; i < num_inds; i++)
- index[b->num_dims - num_inds + i] = Long_val(Field(vind, i));
- for (i = 0; i < b->num_dims - num_inds; i++) index[i] = 1;
- offset = bigarray_offset(b, index);
- sub_dims = b->dim;
- }
- sub_data =
- (char *) b->data +
- offset * bigarray_element_size[b->flags & BIGARRAY_KIND_MASK];
- /* Allocate a Caml bigarray to hold the result */
- res = alloc_bigarray(b->flags, b->num_dims - num_inds, sub_data, sub_dims);
- /* Create or update proxy in case of managed bigarray */
- bigarray_update_proxy(b, Bigarray_val(res));
- /* Return result */
- CAMLreturn (res);
-
- #undef b
-}
-
-/* Extracting a sub-array of same number of dimensions */
-
-CAMLprim value bigarray_sub(value vb, value vofs, value vlen)
-{
- CAMLparam3 (vb, vofs, vlen);
- CAMLlocal1 (res);
- #define b ((struct caml_bigarray *) Bigarray_val(vb))
- long ofs = Long_val(vofs);
- long len = Long_val(vlen);
- int i, changed_dim;
- long mul;
- char * sub_data;
-
- /* Compute offset and check bounds */
- if ((b->flags & BIGARRAY_LAYOUT_MASK) == BIGARRAY_C_LAYOUT) {
- /* We reduce the first dimension */
- mul = 1;
- for (i = 1; i < b->num_dims; i++) mul *= b->dim[i];
- changed_dim = 0;
- } else {
- /* We reduce the last dimension */
- mul = 1;
- for (i = 0; i < b->num_dims - 1; i++) mul *= b->dim[i];
- changed_dim = b->num_dims - 1;
- ofs--; /* Fortran arrays start at 1 */
- }
- if (ofs < 0 || len < 0 || ofs + len > b->dim[changed_dim])
- invalid_argument("Bigarray.sub: bad sub-array");
- sub_data =
- (char *) b->data +
- ofs * mul * bigarray_element_size[b->flags & BIGARRAY_KIND_MASK];
- /* Allocate a Caml bigarray to hold the result */
- res = alloc_bigarray(b->flags, b->num_dims, sub_data, b->dim);
- /* Doctor the changed dimension */
- Bigarray_val(res)->dim[changed_dim] = len;
- /* Create or update proxy in case of managed bigarray */
- bigarray_update_proxy(b, Bigarray_val(res));
- /* Return result */
- CAMLreturn (res);
-
- #undef b
-}
-
-/* Copying a big array into another one */
-
-CAMLprim value bigarray_blit(value vsrc, value vdst)
-{
- struct caml_bigarray * src = Bigarray_val(vsrc);
- struct caml_bigarray * dst = Bigarray_val(vdst);
- int i;
- long num_bytes;
-
- /* Check same numbers of dimensions and same dimensions */
- if (src->num_dims != dst->num_dims) goto blit_error;
- for (i = 0; i < src->num_dims; i++)
- if (src->dim[i] != dst->dim[i]) goto blit_error;
- /* Compute number of bytes in array data */
- num_bytes =
- bigarray_num_elts(src)
- * bigarray_element_size[src->flags & BIGARRAY_KIND_MASK];
- /* Do the copying */
- memmove (dst->data, src->data, num_bytes);
- return Val_unit;
- blit_error:
- invalid_argument("Bigarray.blit: dimension mismatch");
- return Val_unit; /* not reached */
-}
-
-/* Filling a big array with a given value */
-
-CAMLprim value bigarray_fill(value vb, value vinit)
-{
- struct caml_bigarray * b = Bigarray_val(vb);
- long num_elts = bigarray_num_elts(b);
-
- switch (b->flags & BIGARRAY_KIND_MASK) {
- default:
- Assert(0);
- case BIGARRAY_FLOAT32: {
- float init = Double_val(vinit);
- float * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_FLOAT64: {
- double init = Double_val(vinit);
- double * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_SINT8:
- case BIGARRAY_UINT8: {
- int init = Int_val(vinit);
- char * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_SINT16:
- case BIGARRAY_UINT16: {
- int init = Int_val(vinit);
- short * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_INT32: {
- int32 init = Int32_val(vinit);
- int32 * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_INT64: {
- int64 init = Int64_val(vinit);
- int64 * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_NATIVE_INT: {
- long init = Nativeint_val(vinit);
- long * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_CAML_INT: {
- long init = Long_val(vinit);
- long * p;
- for (p = b->data; num_elts > 0; p++, num_elts--) *p = init;
- break;
- }
- case BIGARRAY_COMPLEX32: {
- float init0 = Double_field(vinit, 0);
- float init1 = Double_field(vinit, 1);
- float * p;
- for (p = b->data; num_elts > 0; num_elts--) { *p++ = init0; *p++ = init1; }
- break;
- }
- case BIGARRAY_COMPLEX64: {
- double init0 = Double_field(vinit, 0);
- double init1 = Double_field(vinit, 1);
- double * p;
- for (p = b->data; num_elts > 0; num_elts--) { *p++ = init0; *p++ = init1; }
- break;
- }
- }
- return Val_unit;
-}
-
-/* Reshape an array: change dimensions and number of dimensions, preserving
- array contents */
-
-CAMLprim value bigarray_reshape(value vb, value vdim)
-{
- CAMLparam2 (vb, vdim);
- CAMLlocal1 (res);
- #define b ((struct caml_bigarray *) Bigarray_val(vb))
- long dim[MAX_NUM_DIMS];
- mlsize_t num_dims;
- unsigned long num_elts;
- int i;
-
- num_dims = Wosize_val(vdim);
- if (num_dims < 1 || num_dims > MAX_NUM_DIMS)
- invalid_argument("Bigarray.reshape: bad number of dimensions");
- num_elts = 1;
- for (i = 0; i < num_dims; i++) {
- dim[i] = Long_val(Field(vdim, i));
- if (dim[i] < 0 || dim[i] > 0x7FFFFFFFL)
- invalid_argument("Bigarray.reshape: negative dimension");
- num_elts *= dim[i];
- }
- /* Check that sizes agree */
- if (num_elts != bigarray_num_elts(b))
- invalid_argument("Bigarray.reshape: size mismatch");
- /* Create bigarray with same data and new dimensions */
- res = alloc_bigarray(b->flags, num_dims, b->data, dim);
- /* Create or update proxy in case of managed bigarray */
- bigarray_update_proxy(b, Bigarray_val(res));
- /* Return result */
- CAMLreturn (res);
-
- #undef b
-}
-
-/* Initialization */
-
-CAMLprim value bigarray_init(value unit)
-{
- register_custom_operations(&bigarray_ops);
- return Val_unit;
-}