/* * BSD 3-Clause License * * Copyright (c) 2017-2018, plures * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef NDTYPES_H #define NDTYPES_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #ifdef __cplusplus #include #else #include #include #include #endif #if SIZE_MAX > ULLONG_MAX #error "need SIZE_MAX <= ULLONG_MAX" #endif #if SIZE_MAX == UINT32_MAX typedef int32_t ndt_ssize_t; #define PRI_ndt_ssize PRIi32 #elif SIZE_MAX == UINT64_MAX typedef int64_t ndt_ssize_t; #define PRI_ndt_ssize PRIi64 #else #error "need SIZE_MAX == UINT32_MAX or SIZE_MAX == UINT64_MAX" #endif #ifdef _MSC_VER #if defined (NDT_EXPORT) #define NDTYPES_API __declspec(dllexport) #elif defined(NDT_IMPORT) #define NDTYPES_API __declspec(dllimport) #else #define NDTYPES_API #endif #define alignof __alignof #define alignas(n) __declspec(align(n)) #define MAX_ALIGN 8 #define NDT_SYS_BIG_ENDIAN 0 #ifdef __cplusplus #define ATOMIC_INT64 int64_t #else #define ATOMIC_INT64 __int64 volatile typedef _Dcomplex ndt_complex128_t; typedef _Fcomplex ndt_complex64_t; #endif #else #define NDTYPES_API #if !defined(__APPLE__) && !defined(__STDC_IEC_559__) #error "ndtypes requires IEEE floating point arithmetic" #endif #include #define MAX_ALIGN (alignof(max_align_t)) #define NDT_SYS_BIG_ENDIAN @NDT_SYS_BIG_ENDIAN@ #ifdef __cplusplus #define ATOMIC_INT64 int64_t #else #include #define ATOMIC_INT64 _Atomic int64_t typedef double complex ndt_complex128_t; typedef float complex ndt_complex64_t; #endif #endif #if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \ defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER) #define NDT_PRAGMA(x) _Pragma(x) #define NDT_HIDE_SYMBOLS_START "GCC visibility push(hidden)" #define NDT_HIDE_SYMBOLS_END "GCC visibility pop" #else #define NDT_PRAGMA(x) #define NDT_HIDE_SYMBOLS_START #define NDT_HIDE_SYMBOLS_END #endif /*****************************************************************************/ /* Datashape */ /*****************************************************************************/ #define NDT_MAX_DIM 128 #define NDT_MAX_ARGS 128 #define NDT_OPTION 0x00000001U #define NDT_SUBTREE_OPTION 0x00000002U #define NDT_LITTLE_ENDIAN 0x00000004U #define NDT_BIG_ENDIAN 0x00000008U #define NDT_ELLIPSIS 0x00000010U #define NDT_POINTER 0x00000020U #define NDT_REF 0x00000040U #define NDT_CHAR 0x00000080U /* Types: ndt_t */ typedef struct _ndt ndt_t; typedef struct _ndt_context ndt_context_t; /* Internal option type */ enum ndt_option { None, Some }; typedef struct { enum ndt_option tag; char Some; } char_opt_t; typedef struct { enum ndt_option tag; int64_t Some; } int64_opt_t; typedef struct { enum ndt_option tag; uint16_t Some; } uint16_opt_t; /* Flag for variadic tuples and records */ enum ndt_variadic { Nonvariadic, Variadic }; /* Offsets for a variable dimension. Shared between copies or slices. */ typedef struct _ndt_offsets ndt_offsets_t; struct _ndt_offsets { ATOMIC_INT64 refcnt; int32_t n; /* number of offsets */ const int32_t *v; /* offset array */ }; NDTYPES_API ndt_offsets_t *ndt_offsets_new(int32_t size, ndt_context_t *ctx); NDTYPES_API ndt_offsets_t *ndt_offsets_from_ptr(int32_t *ptr, int32_t size, ndt_context_t *ctx); NDTYPES_API void ndt_incref_offsets(const ndt_offsets_t *); NDTYPES_API void ndt_decref_offsets(const ndt_offsets_t *); /* * The arrays are addressed by t->ndim-1, where t->ndim > 0. It follows that * offsets[0] are the offsets of the innermost dimension and offsets[ndims-1] * the offsets of the outermost dimension. */ typedef struct { int ndims; /* number of offset structs */ ndt_offsets_t *offsets[NDT_MAX_DIM]; /* offset structs */ } ndt_meta_t; /* Encoding for characters and strings */ enum ndt_encoding { Ascii, Utf8, Ucs2, Utf16, Utf32, }; /* Datashape kinds */ enum ndt { /* Name space */ Module, /* Function */ Function, /* Any */ AnyKind, FixedDim, VarDim, VarDimElem, SymbolicDim, EllipsisDim, /* Dtype */ Array, Tuple, Record, Union, Ref, Constr, Nominal, /* Scalar */ ScalarKind, Categorical, FixedStringKind, FixedString, FixedBytesKind, FixedBytes, String, Bytes, Char, /* Primitive */ Bool, SignedKind, Int8, Int16, Int32, Int64, UnsignedKind, Uint8, Uint16, Uint32, Uint64, FloatKind, BFloat16, Float16, Float32, Float64, ComplexKind, BComplex32, Complex32, Complex64, Complex128, /* Dtype variable */ Typevar, }; enum ndt_alias { Size, Intptr, Uintptr }; /* Protect access to concrete type fields. */ enum ndt_access { Abstract, Concrete }; /* * Require C or Fortran contiguity in abstract signatures. For concrete types * the field is irrelevant and set to RequireNA. */ enum ndt_contig { RequireNA, RequireC, RequireF }; /* Tuple or record field, used in the parser. */ typedef struct { enum ndt_access access; char *name; const ndt_t *type; struct { uint16_t align; bool explicit_align; uint16_t pad; bool explicit_pad; } Concrete; } ndt_field_t; /* Selected values for the categorical type. */ enum ndt_value { ValBool, ValInt64, ValFloat64, ValString, ValNA, }; typedef struct { enum ndt_value tag; union { bool ValBool; int64_t ValInt64; double ValFloat64; char *ValString; }; } ndt_value_t; typedef struct { int64_t start; int64_t stop; int64_t step; } ndt_slice_t; /* * Constraint support for function signatures. A constraint needs to specify: * * 1) The symbols in the function arguments and return value(s) that are * needed to decide the constraint. * 2) ndt_typecheck() resolves the 'nin' incoming symbols and passes their * shape values in the 'shapes' array. It then calls the constraint * function. * 3) The constraint function can look at the incoming shapes as well * as the incoming function arguments (usually xnd_t). * 4) The function then needs to decide whether the constraint is met; if so, * it must fill in 'nout' shapes for the return symbols (if any). * 5) ndt_typecheck() uses the resolved 'nout' shapes to update the symbol * table and now has sufficient information to compute the return type. */ #define NDT_MAX_SYMBOLS 16 typedef int (* ndt_func_constraint_t)(int64_t *shapes, const void *args, ndt_context_t *ctx); typedef struct { ndt_func_constraint_t f; int nin; int nout; const char *symbols[NDT_MAX_SYMBOLS]; } ndt_constraint_t; /* Object features for the Nominal type. */ typedef bool (* ndt_init_t)(void *dest, const void *src, ndt_context_t *); typedef bool (* ndt_tdef_constraint_t)(const void *, ndt_context_t *); typedef void *(* ndt_repr_t)(const void *, ndt_context_t *); typedef struct { ndt_init_t init; ndt_tdef_constraint_t constraint; ndt_repr_t repr; } ndt_methods_t; /* Datashape type */ struct _ndt { /* Always defined */ enum ndt tag; enum ndt_access access; uint32_t flags; int ndim; /* Undefined if the type is abstract */ int64_t datasize; uint16_t align; /* Abstract */ union { struct { char *name; const ndt_t *type; } Module; struct { bool elemwise; int64_t nin; int64_t nout; int64_t nargs; const ndt_t **types; } Function; struct { enum ndt_contig tag; int64_t shape; const ndt_t *type; } FixedDim; struct { const ndt_t *type; } VarDim; struct { const ndt_t *type; int64_t index; } VarDimElem; struct { enum ndt_contig tag; char *name; const ndt_t *type; } SymbolicDim; struct { enum ndt_contig tag; char *name; const ndt_t *type; } EllipsisDim; struct { enum ndt_variadic flag; int64_t shape; const ndt_t **types; } Tuple; struct { enum ndt_variadic flag; int64_t shape; char **names; const ndt_t **types; } Record; struct { int64_t ntags; char **tags; const ndt_t **types; } Union; struct { const ndt_t *type; } Ref; struct { char *name; const ndt_t *type; } Constr; struct { char *name; const ndt_t *type; const ndt_methods_t *meth; } Nominal; struct { int64_t ntypes; const ndt_value_t *types; } Categorical; struct { int64_t size; enum ndt_encoding encoding; } FixedString; struct { int64_t size; uint16_t align; } FixedBytes; struct { uint16_t target_align; } Bytes; struct { int64_t itemsize; const ndt_t *type; } Array; struct { enum ndt_encoding encoding; } Char; struct { char *name; } Typevar; }; /* Concrete */ struct { union { struct { int64_t itemsize; int64_t step; } FixedDim; struct { int64_t itemsize; const ndt_offsets_t *offsets; int nslices; ndt_slice_t *slices; } VarDim; struct { int64_t *offset; uint16_t *align; uint16_t *pad; } Tuple; struct { int64_t *offset; uint16_t *align; uint16_t *pad; } Record; }; } Concrete; /* Reference counting */ ATOMIC_INT64 refcnt; /* Extra space */ alignas(MAX_ALIGN) char extra[]; }; /*****************************************************************************/ /* Context and error handling */ /*****************************************************************************/ #define NDT_Dynamic 0x00000001U #define NDT_STATIC_CONTEXT(name) \ ndt_context_t name = { .flags=0, .err=NDT_Success, .msg=ConstMsg, .ConstMsg="Success" } enum ndt_error { NDT_Success, NDT_ValueError, NDT_TypeError, NDT_InvalidArgumentError, NDT_NotImplementedError, NDT_IndexError, NDT_LexError, NDT_ParseError, NDT_OSError, NDT_RuntimeError, NDT_MemoryError }; enum ndt_msg { ConstMsg, DynamicMsg }; struct _ndt_context { uint32_t flags; enum ndt_error err; enum ndt_msg msg; union { const char *ConstMsg; char *DynamicMsg; }; }; NDTYPES_API ndt_context_t *ndt_context_new(void); NDTYPES_API void ndt_context_del(ndt_context_t *ctx); NDTYPES_API void ndt_err_format(ndt_context_t *ctx, enum ndt_error err, const char *fmt, ...); NDTYPES_API int ndt_err_occurred(const ndt_context_t *ctx); NDTYPES_API void ndt_err_clear(ndt_context_t *ctx); NDTYPES_API void *ndt_memory_error(ndt_context_t *ctx); NDTYPES_API const char *ndt_err_as_string(enum ndt_error err); NDTYPES_API const char *ndt_context_msg(ndt_context_t *ctx); NDTYPES_API void ndt_err_fprint(FILE *fp, ndt_context_t *ctx); /* Unstable API */ NDTYPES_API void ndt_err_append(ndt_context_t *ctx, const char *msg); /******************************************************************************/ /* Array conversions and properties */ /******************************************************************************/ /* This may go into xnd at some point. */ typedef struct { int ndim; int64_t itemsize; int64_t shape[NDT_MAX_DIM]; int64_t strides[NDT_MAX_DIM]; int64_t steps[NDT_MAX_DIM]; } ndt_ndarray_t; /* * Type properties that determine what kind of kernel can be used safely. A * property flag is set if it applies to all input and output arguments. */ #define NDT_INNER_C 0x00000001U /* inner dims C-contiguous */ #define NDT_INNER_F 0x00000002U /* inner dims F-contiguous */ #define NDT_INNER_STRIDED 0x00000004U /* inner dims strided */ /* * Modifiers to the above properties that determine whether an extended * optimized kernel (inner+1) can be used safely. * * C inner dimensions can be extended to a pure inner+1 C array. Fortran * inner dimensions cannot be extended to yield another Fortran array, * hence the unfortunate asymmetry. */ #define NDT_EXT_C 0x00000010U /* inner+1 dims are C */ #define NDT_EXT_ZERO 0x00000020U /* inner dims are C, loop has C or zero stride (GPU) */ #define NDT_EXT_STRIDED 0x00000040U /* inner dims are {C,F,strided}, loop is strided */ #define NDT_INNER_XND 0x00000100U /* inner dims are xnd */ #define NDT_SPEC_FLAGS_ALL (NDT_INNER_C|NDT_INNER_F|NDT_INNER_STRIDED| \ NDT_EXT_C|NDT_EXT_ZERO|NDT_EXT_STRIDED| \ NDT_INNER_XND) typedef struct { uint32_t flags; int outer_dims; int nin; /* number of 'in' types */ int nout; /* number of 'out' types */ int nargs; /* nin+nout, for convenience */ const ndt_t *types[NDT_MAX_ARGS]; } ndt_apply_spec_t; NDTYPES_API extern const ndt_apply_spec_t ndt_apply_spec_empty; NDTYPES_API ndt_apply_spec_t *ndt_apply_spec_new(ndt_context_t *ctx); NDTYPES_API void ndt_apply_spec_clear(ndt_apply_spec_t *spec); NDTYPES_API void ndt_apply_spec_del(ndt_apply_spec_t *spec); NDTYPES_API const char *ndt_apply_flags_as_string(const ndt_apply_spec_t *spec); NDTYPES_API int ndt_broadcast_all(ndt_apply_spec_t *spec, const ndt_t *sig, bool check_broadcast, const int64_t *shape, const int outer_dims, ndt_context_t *ctx); NDTYPES_API int ndt_select_kernel_strategy(ndt_apply_spec_t *spec, ndt_context_t *ctx); /*****************************************************************************/ /* Utilities */ /*****************************************************************************/ /* String and formatting utilities */ NDTYPES_API char *ndt_strdup(const char *s, ndt_context_t *ctx); NDTYPES_API char *ndt_asprintf(ndt_context_t *ctx, const char *fmt, ...); /* Type functions (unstable API) */ NDTYPES_API int64_t ndt_nelem(const ndt_t *t); NDTYPES_API int ndt_logical_ndim(const ndt_t *t); NDTYPES_API const ndt_t *ndt_logical_dim_at(const ndt_t *t, int n); NDTYPES_API const ndt_t *ndt_dtype(const ndt_t *t); NDTYPES_API const ndt_t *ndt_hidden_dtype(const ndt_t *t); NDTYPES_API int ndt_dims_dtype(const ndt_t *dims[NDT_MAX_DIM], const ndt_t **dtype, const ndt_t *t); NDTYPES_API int ndt_as_ndarray(ndt_ndarray_t *a, const ndt_t *t, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_transpose(const ndt_t *t, const int *p, int ndim, ndt_context_t *ctx); NDTYPES_API ndt_ssize_t ndt_hash(const ndt_t *t, ndt_context_t *ctx); /*****************************************************************************/ /* Fields and values */ /*****************************************************************************/ /* Fields */ NDTYPES_API ndt_field_t *ndt_field(char *name, const ndt_t *type, uint16_opt_t align, uint16_opt_t pack, uint16_opt_t pad, ndt_context_t *ctx); NDTYPES_API void ndt_field_del(ndt_field_t *field); NDTYPES_API void ndt_field_array_del(ndt_field_t *fields, int64_t shape); /* Typed values */ NDTYPES_API void ndt_value_del(ndt_value_t *mem); NDTYPES_API void ndt_value_array_del(const ndt_value_t *types, int64_t ntypes); NDTYPES_API ndt_value_t *ndt_value_from_number(enum ndt_value tag, char *v, ndt_context_t *ctx); NDTYPES_API ndt_value_t *ndt_value_from_string(char *v, ndt_context_t *ctx); NDTYPES_API ndt_value_t *ndt_value_na(ndt_context_t *ctx); NDTYPES_API int ndt_value_equal(const ndt_value_t *x, const ndt_value_t *y); NDTYPES_API int ndt_value_mem_equal(const ndt_value_t *x, const ndt_value_t *y); NDTYPES_API int ndt_value_compare(const ndt_value_t *x, const ndt_value_t *y); /* Type array */ NDTYPES_API void ndt_type_array_clear(const ndt_t **types, int64_t shape); NDTYPES_API void ndt_type_array_del(const ndt_t **types, int64_t shape); /*****************************************************************************/ /* Encodings */ /*****************************************************************************/ NDTYPES_API enum ndt_encoding ndt_encoding_from_string(const char *s, ndt_context_t *ctx); NDTYPES_API const char *ndt_encoding_as_string(enum ndt_encoding encoding); NDTYPES_API size_t ndt_sizeof_encoding(enum ndt_encoding encoding); NDTYPES_API uint16_t ndt_alignof_encoding(enum ndt_encoding encoding); /*****************************************************************************/ /* Predicates */ /*****************************************************************************/ NDTYPES_API bool ndt_is_static(const ndt_t *t); NDTYPES_API bool ndt_is_static_tag(enum ndt tag); NDTYPES_API int ndt_is_abstract(const ndt_t *t); NDTYPES_API int ndt_is_concrete(const ndt_t *t); NDTYPES_API int ndt_is_optional(const ndt_t *t); NDTYPES_API int ndt_subtree_is_optional(const ndt_t *t); NDTYPES_API int ndt_is_pointer_free(const ndt_t *t); NDTYPES_API int ndt_is_ref_free(const ndt_t *t); NDTYPES_API int ndt_is_ndarray(const ndt_t *t); NDTYPES_API int ndt_is_c_contiguous(const ndt_t *t); NDTYPES_API int ndt_is_f_contiguous(const ndt_t *t); NDTYPES_API int ndt_really_fortran(const ndt_t *t); NDTYPES_API int ndt_is_var_contiguous(const ndt_t *t); NDTYPES_API int ndt_is_scalar(const ndt_t *t); NDTYPES_API int ndt_is_signed(const ndt_t *t); NDTYPES_API int ndt_is_unsigned(const ndt_t *t); NDTYPES_API int ndt_is_float(const ndt_t *t); NDTYPES_API int ndt_is_complex(const ndt_t *t); NDTYPES_API int ndt_endian_is_set(const ndt_t *t); NDTYPES_API int ndt_is_little_endian(const ndt_t *t); NDTYPES_API int ndt_is_big_endian(const ndt_t *t); /*****************************************************************************/ /* Functions */ /*****************************************************************************/ NDTYPES_API const ndt_t *ndt_copy(const ndt_t *t, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_copy_contiguous(const ndt_t *t, int64_t linear_index, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_copy_contiguous_dtype(const ndt_t *t, const ndt_t *dtype, int64_t linear_index, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_copy_contiguous_at(const ndt_t *t, int n, const ndt_t *dtype, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_copy_abstract_var_dtype(const ndt_t *t, const ndt_t *dtype, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_convert_to_var_elem(const ndt_t *t, const ndt_t *type, int64_t index, ndt_context_t *ctx); NDTYPES_API int ndt_equal(const ndt_t *t, const ndt_t *u); NDTYPES_API int ndt_match(const ndt_t *p, const ndt_t *c, ndt_context_t *ctx); NDTYPES_API int ndt_typecheck(ndt_apply_spec_t *spec, const ndt_t *sig, const ndt_t *types[], const int64_t li[], const int nin, const int nout, bool check_broadcast, const ndt_constraint_t *c, const void *args, ndt_context_t *ctx); NDTYPES_API int ndt_fast_unary_fixed_typecheck(ndt_apply_spec_t *spec, const ndt_t *sig, const ndt_t *types[], const int nin, const int nout, const bool check_broadcast, ndt_context_t *ctx); NDTYPES_API int ndt_fast_binary_fixed_typecheck(ndt_apply_spec_t *spec, const ndt_t *sig, const ndt_t *types[], const int nin, const int nout, const bool check_broadcast, ndt_context_t *ctx); NDTYPES_API int64_t ndt_itemsize(const ndt_t *t); NDTYPES_API const ndt_t *ndt_unify(const ndt_t *t, const ndt_t *u, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_unify_replace_any(const ndt_t *t, const ndt_t *u, ndt_context_t *ctx); /*****************************************************************************/ /* Input/Output */ /*****************************************************************************/ /*** String to primitive conversion ***/ NDTYPES_API bool ndt_strtobool(const char *v, ndt_context_t *ctx); NDTYPES_API char ndt_strtochar(const char *v, ndt_context_t *ctx); NDTYPES_API long ndt_strtol(const char *v, long min, long max, ndt_context_t *ctx); NDTYPES_API long long ndt_strtoll(const char *v, long long min, long long max, ndt_context_t *ctx); NDTYPES_API unsigned long ndt_strtoul(const char *v, unsigned long max, ndt_context_t *ctx); NDTYPES_API unsigned long long ndt_strtoull(const char *v, unsigned long long max, ndt_context_t *ctx); NDTYPES_API float ndt_strtof(const char *v, ndt_context_t *ctx); NDTYPES_API double ndt_strtod(const char *v, ndt_context_t *ctx); /*** Type to string conversion ***/ NDTYPES_API char *ndt_as_string(const ndt_t *t, ndt_context_t *ctx); NDTYPES_API char *ndt_list_as_string(const ndt_t *types[], int64_t len, ndt_context_t *ctx); NDTYPES_API char *ndt_indent(const ndt_t *t, ndt_context_t *ctx); NDTYPES_API char *ndt_ast_repr(const ndt_t *t, ndt_context_t *ctx); NDTYPES_API int64_t ndt_serialize(char **dest, const ndt_t * const t, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_deserialize(const char * const ptr, int64_t len, ndt_context_t *ctx); /*****************************************************************************/ /* Typedef */ /*****************************************************************************/ typedef struct { const ndt_t *type; ndt_methods_t meth; } ndt_typedef_t; /* Typedef for nominal types */ NDTYPES_API int ndt_typedef_add(const char *name, const ndt_t *type, const ndt_methods_t *m, ndt_context_t *ctx); NDTYPES_API const ndt_typedef_t *ndt_typedef_find(const char *name, ndt_context_t *ctx); NDTYPES_API int ndt_typedef(const char *name, const ndt_t *type, const ndt_methods_t *m, ndt_context_t *ctx); NDTYPES_API int ndt_typedef_from_string(const char *name, const char *type, const ndt_methods_t *m, ndt_context_t *ctx); /*****************************************************************************/ /* Allocate types */ /*****************************************************************************/ NDTYPES_API ndt_t *ndt_new(enum ndt tag, uint32_t flags, ndt_context_t *ctx); NDTYPES_API ndt_t *ndt_function_new(int64_t nargs, ndt_context_t *ctx); NDTYPES_API ndt_t *ndt_tuple_new(enum ndt_variadic flag, int64_t shape, bool opt, ndt_context_t *ctx); NDTYPES_API ndt_t *ndt_record_new(enum ndt_variadic flag, int64_t shape, bool opt, ndt_context_t *ctx); NDTYPES_API ndt_t *ndt_union_new(int64_t ntags, bool opt, ndt_context_t *ctx); NDTYPES_API void ndt_incref(const ndt_t *t); NDTYPES_API void ndt_decref(const ndt_t *t); NDTYPES_API void ndt_move(const ndt_t **dst, const ndt_t *src); /*****************************************************************************/ /* Construct types */ /*****************************************************************************/ /* Special types */ NDTYPES_API const ndt_t *ndt_module(char *name, const ndt_t *type, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_function(const ndt_t **types, int64_t nargs, int64_t nin, int64_t nout, ndt_context_t *ctx); /* Any */ NDTYPES_API const ndt_t *ndt_any_kind(bool opt, ndt_context_t *ctx); /* Dimensions */ NDTYPES_API const ndt_t *ndt_to_fortran(const ndt_t *type, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_fixed_dim(const ndt_t *type, int64_t shape, int64_t step, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_fixed_dim_tag(const ndt_t *type, enum ndt_contig tag, int64_t shape, int64_t step, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_abstract_var_dim(const ndt_t *type, bool opt, ndt_context_t *ctx); NDTYPES_API int64_t ndt_var_indices(int64_t *res_start, int64_t *res_step, const ndt_t *t, int64_t index, ndt_context_t *ctx); NDTYPES_API int64_t ndt_var_indices_non_empty(int64_t *res_start, int64_t *res_step, const ndt_t *t, int64_t index, ndt_context_t *ctx); NDTYPES_API ndt_slice_t *ndt_var_add_slice(int32_t *nslices, const ndt_t *t, int64_t start, int64_t stop, int64_t step, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_var_dim(const ndt_t *type, const ndt_offsets_t *offsets, int32_t nslices, ndt_slice_t *slices, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_symbolic_dim(char *name, const ndt_t *type, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_symbolic_dim_tag(char *name, const ndt_t *type, enum ndt_contig tag, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_ellipsis_dim(char *name, const ndt_t *type, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_ellipsis_dim_tag(char *name, const ndt_t *type, enum ndt_contig tag, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_array(const ndt_t *type, bool opt, ndt_context_t *ctx); /* Dtypes */ NDTYPES_API const ndt_t *ndt_tuple(enum ndt_variadic flag, const ndt_field_t *fields, int64_t shape, uint16_opt_t align, uint16_opt_t pack, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_record(enum ndt_variadic flag, const ndt_field_t *fields, int64_t shape, uint16_opt_t align, uint16_opt_t pack, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_union(const ndt_field_t *fields, int64_t ntags, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_ref(const ndt_t *type, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_constr(char *name, const ndt_t *type, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_nominal(char *name, const ndt_t *type, bool opt, ndt_context_t *ctx); /* Scalars */ NDTYPES_API const ndt_t *ndt_scalar_kind(bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_categorical(const ndt_value_t *types, int64_t ntypes, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_fixed_string_kind(bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_fixed_string(int64_t size, enum ndt_encoding encoding, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_fixed_bytes_kind(bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_fixed_bytes(int64_t size, uint16_opt_t align, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_string(bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_bytes(uint16_opt_t target_align, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_char(enum ndt_encoding encoding, bool opt, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_signed_kind(uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_unsigned_kind(uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_float_kind(uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_complex_kind(uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_primitive(enum ndt tag, uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_signed(int size, uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_unsigned(int size, uint32_t flags, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_from_alias(enum ndt_alias tag, uint32_t flags, ndt_context_t *ctx); /* Type variable */ NDTYPES_API const ndt_t *ndt_typevar(char *name, ndt_context_t *ctx); /******************************************************************************/ /* Parsing */ /******************************************************************************/ /* Metadata is currently limited to var-dimension offsets. */ /* * Metadata is read from the type string and managed by the type. This is * convenient but can waste a lot of space when offset arrays are large. */ NDTYPES_API const ndt_t *ndt_from_file(const char *name, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_from_string(const char *input, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_from_bpformat(const char *input, ndt_context_t *ctx); NDTYPES_API char *ndt_to_bpformat(const ndt_t *t, ndt_context_t *ctx); NDTYPES_API int ndt_to_nbformat(char **sig, char **dtype, const ndt_t *t, ndt_context_t *ctx); /* Unstable API */ NDTYPES_API const ndt_t *ndt_from_string_v(const char *input, ndt_context_t *ctx); /* * Metadata is read from the type string and extracted for external management. * The type still has pointers to the metadata. This scheme is used for sharing * offsets between copies or subtypes of a type. */ NDTYPES_API const ndt_t *ndt_from_file_fill_meta(ndt_meta_t *m, const char *name, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_from_string_fill_meta(ndt_meta_t *m, const char *input, ndt_context_t *ctx); /* Metadata is provided and managed by an external source. */ NDTYPES_API const ndt_t *ndt_from_metadata_and_dtype(const ndt_meta_t *m, const char *dtype, ndt_context_t *ctx); NDTYPES_API const ndt_t *ndt_from_metadata_opt_and_dtype(const ndt_meta_t *m, bool *opt, const ndt_t *dtype, ndt_context_t *ctx); NDTYPES_API ndt_meta_t *ndt_meta_new(ndt_context_t *ctx); NDTYPES_API void ndt_meta_clear(ndt_meta_t *m); NDTYPES_API void ndt_meta_del(ndt_meta_t *m); /******************************************************************************/ /* Library initialization and tables */ /******************************************************************************/ NDTYPES_API int ndt_init(ndt_context_t *ctx); NDTYPES_API void ndt_finalize(void); /******************************************************************************/ /* Error Macros */ /******************************************************************************/ #define ndt_internal_error(msg) \ do { \ fprintf(stderr, "%s:%d: internal error: %s\n", __FILE__, __LINE__, msg); \ abort(); \ } while (0) #define ndt_warn(msg) \ do { \ fprintf(stderr, "%s:%d: warning: %s\n", __FILE__, __LINE__, msg); \ } while (0) /******************************************************************************/ /* Memory handling */ /******************************************************************************/ NDTYPES_API extern void *(* ndt_mallocfunc)(size_t size); NDTYPES_API extern void *(* ndt_callocfunc)(size_t nmemb, size_t size); NDTYPES_API extern void *(* ndt_reallocfunc)(void *ptr, size_t size); NDTYPES_API extern void (* ndt_freefunc)(void *ptr); NDTYPES_API void *ndt_alloc(int64_t nmemb, int64_t size); NDTYPES_API void *ndt_alloc_size(size_t size); NDTYPES_API void *ndt_calloc(int64_t nmemb, int64_t size); NDTYPES_API void *ndt_realloc(void *ptr, int64_t nmemb, int64_t size); NDTYPES_API void ndt_free(void *ptr); NDTYPES_API void *ndt_aligned_calloc(uint16_t alignment, int64_t size); NDTYPES_API void ndt_aligned_free(void *ptr); /******************************************************************************/ /* Low level details */ /******************************************************************************/ typedef struct { int64_t size; uint8_t *data; } ndt_bytes_t; typedef struct { int64_t shape; char *data; } ndt_array_t; typedef int64_t ndt_categorical_t; #ifdef __cplusplus } /* END extern "C" */ #endif #endif /* NDTYPES_H */