inline void init(const ndt::type& tp0, const char *metadata0, char *data0) { m_array_tp = tp0; m_iter_ndim = m_array_tp.get_ndim(); m_itersize = 1; if (m_iter_ndim != 0) { m_iterindex.init(m_iter_ndim); memset(m_iterindex.get(), 0, sizeof(intptr_t) * m_iter_ndim); m_itershape.init(m_iter_ndim); m_array_tp.extended()->get_shape(m_iter_ndim, 0, m_itershape.get(), metadata0); size_t iterdata_size = m_array_tp.extended()->get_iterdata_size(m_iter_ndim); m_iterdata = reinterpret_cast<iterdata_common *>(malloc(iterdata_size)); if (!m_iterdata) { throw std::bad_alloc(); } m_metadata = metadata0; m_array_tp.iterdata_construct(m_iterdata, &m_metadata, m_iter_ndim, m_itershape.get(), m_uniform_tp); m_data = m_iterdata->reset(m_iterdata, data0, m_iter_ndim); for (size_t i = 0, i_end = m_iter_ndim; i != i_end; ++i) { m_itersize *= m_itershape[i]; } } else { m_iterdata = NULL; m_uniform_tp = m_array_tp; m_data = data0; m_metadata = metadata0; } }
static void array_getbuffer_pep3118_bytes(const ndt::type &tp, const char *arrmeta, char *data, Py_buffer *buffer, int flags) { buffer->itemsize = 1; if (flags & PyBUF_FORMAT) { buffer->format = (char *)"c"; } else { buffer->format = NULL; } buffer->ndim = 1; #if PY_VERSION_HEX == 0x02070000 buffer->internal = NULL; buffer->shape = &buffer->smalltable[0]; buffer->strides = &buffer->smalltable[1]; #else buffer->internal = malloc(2 * sizeof(intptr_t)); buffer->shape = reinterpret_cast<Py_ssize_t *>(buffer->internal); buffer->strides = buffer->shape + 1; #endif buffer->strides[0] = 1; if (tp.get_id() == bytes_id) { // Variable-length bytes type buffer->buf = reinterpret_cast<bytes *>(data)->begin(); buffer->len = reinterpret_cast<bytes *>(data)->size(); } else { // Fixed-length bytes type buffer->len = tp.get_data_size(); } buffer->shape[0] = buffer->len; }
ndt::adapt_type::adapt_type(const ndt::type &value_tp, const ndt::type &storage_tp, const nd::callable &forward, const nd::callable &inverse) : base_expr_type(adapt_id, storage_tp.get_data_size(), storage_tp.get_data_alignment(), type_flag_none, storage_tp.get_arrmeta_size(), storage_tp.get_ndim()), m_value_tp(value_tp), m_storage_tp(storage_tp), m_forward(forward), m_inverse(inverse) { }
size_t dynd::make_var_to_fixed_dim_assignment_kernel(void *ckb, intptr_t ckb_offset, const ndt::type &dst_strided_dim_tp, const char *dst_arrmeta, const ndt::type &src_var_dim_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) { typedef var_to_strided_assign_ck self_type; if (src_var_dim_tp.get_type_id() != var_dim_type_id) { stringstream ss; ss << "make_var_to_fixed_dim_assignment_kernel: provided source type " << src_var_dim_tp << " is not a var_dim"; throw runtime_error(ss.str()); } const ndt::var_dim_type *src_vad = src_var_dim_tp.extended<ndt::var_dim_type>(); const var_dim_type_arrmeta *src_md = reinterpret_cast<const var_dim_type_arrmeta *>(src_arrmeta); self_type *self = self_type::make(ckb, kernreq, ckb_offset); ndt::type dst_element_tp; const char *dst_element_arrmeta; if (!dst_strided_dim_tp.get_as_strided(dst_arrmeta, &self->m_dst_dim_size, &self->m_dst_stride, &dst_element_tp, &dst_element_arrmeta)) { stringstream ss; ss << "make_var_to_fixed_dim_assignment_kernel: provided destination " "type " << dst_strided_dim_tp << " is not a strided_dim or fixed_array"; throw runtime_error(ss.str()); } self->m_src_md = src_md; return ::make_assignment_kernel(ckb, ckb_offset, dst_element_tp, dst_element_arrmeta, src_vad->get_element_type(), src_arrmeta + sizeof(var_dim_type_arrmeta), kernel_request_strided, ectx); }
static inline bool broadcast_tagged_dims_from_type(intptr_t ndim, ndt::type tp, const intptr_t *tagged_dims, intptr_t *out_tagged_dims) { tp = tp.without_memory_type(); for (intptr_t i = 0; i < ndim; ++i) { intptr_t tagged_dim = tagged_dims[i], dim_size; switch (tp.get_id()) { case fixed_dim_kind_id: { if (tagged_dim < 0) { out_tagged_dims[i] = -2; } } break; case fixed_dim_id: { dim_size = tp.extended<ndt::fixed_dim_type>()->get_fixed_dim_size(); if (tagged_dim < 0 || tagged_dim == 1) { out_tagged_dims[i] = dim_size; } else if (tagged_dim != dim_size && dim_size != 1) { return false; } } break; case var_dim_id: // All broadcasting is done dynamically for var break; default: { stringstream ss; ss << "dim_fragment_type failed to get shape from type " << tp; throw type_error(ss.str()); } } tp = tp.extended<ndt::base_dim_type>()->get_element_type(); } return true; }
intptr_t dynd::make_cuda_from_device_builtin_type_assignment_kernel( const callable_type_data *DYND_UNUSED(self), const ndt::callable_type *DYND_UNUSED(af_tp), char *DYND_UNUSED(data), void *ckb, intptr_t ckb_offset, const ndt::type &dst_tp, const char *DYND_UNUSED(dst_arrmeta), intptr_t DYND_UNUSED(nsrc), const ndt::type *src_tp, const char *const *DYND_UNUSED(src_arrmeta), kernel_request_t kernreq, const eval::eval_context *ectx, const nd::array &DYND_UNUSED(kwds), const std::map<std::string, ndt::type> &DYND_UNUSED(tp_vars)) { assign_error_mode errmode = ectx->errmode; if (errmode != assign_error_nocheck && is_lossless_assignment(dst_tp, *src_tp)) { errmode = assign_error_nocheck; } if (!dst_tp.is_builtin() || !src_tp->is_builtin() || errmode == assign_error_default) { stringstream ss; ss << "cannot assign from CUDA device with types " << *src_tp << " to " << dst_tp; throw type_error(ss.str()); } nd::cuda_device_to_host_assign_ck::make(ckb, kernreq, ckb_offset, src_tp->get_data_size()); return make_builtin_type_assignment_kernel( ckb, ckb_offset, dst_tp.without_memory_type().get_type_id(), src_tp->without_memory_type().get_type_id(), kernel_request_single, errmode); }
size_t dynd::make_var_dim_assignment_kernel(void *ckb, intptr_t ckb_offset, const ndt::type &dst_var_dim_tp, const char *dst_arrmeta, const ndt::type &src_var_dim_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) { typedef var_assign_ck self_type; if (dst_var_dim_tp.get_type_id() != var_dim_type_id) { stringstream ss; ss << "make_broadcast_to_blockref_array_assignment_kernel: provided " "destination type " << dst_var_dim_tp << " is not a var_dim"; throw runtime_error(ss.str()); } if (src_var_dim_tp.get_type_id() != var_dim_type_id) { stringstream ss; ss << "make_broadcast_to_blockref_array_assignment_kernel: provided " "source type " << src_var_dim_tp << " is not a var_dim"; throw runtime_error(ss.str()); } const ndt::var_dim_type *dst_vad = dst_var_dim_tp.extended<ndt::var_dim_type>(); const ndt::var_dim_type *src_vad = src_var_dim_tp.extended<ndt::var_dim_type>(); const var_dim_type_arrmeta *dst_md = reinterpret_cast<const var_dim_type_arrmeta *>(dst_arrmeta); const var_dim_type_arrmeta *src_md = reinterpret_cast<const var_dim_type_arrmeta *>(src_arrmeta); self_type *self = self_type::make(ckb, kernreq, ckb_offset); self->m_dst_target_alignment = dst_vad->get_target_alignment(); self->m_dst_md = dst_md; self->m_src_md = src_md; return ::make_assignment_kernel(ckb, ckb_offset, dst_vad->get_element_type(), dst_arrmeta + sizeof(var_dim_type_arrmeta), src_vad->get_element_type(), src_arrmeta + sizeof(var_dim_type_arrmeta), kernel_request_strided, ectx); }
size_t string_type::make_comparison_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& src0_dt, const char *src0_metadata, const ndt::type& src1_dt, const char *src1_metadata, comparison_type_t comptype, const eval::eval_context *ectx) const { if (this == src0_dt.extended()) { if (*this == *src1_dt.extended()) { return make_string_comparison_kernel(out, offset_out, m_encoding, comptype, ectx); } else if (src1_dt.get_kind() == string_kind) { return make_general_string_comparison_kernel(out, offset_out, src0_dt, src0_metadata, src1_dt, src1_metadata, comptype, ectx); } else if (!src1_dt.is_builtin()) { return src1_dt.extended()->make_comparison_kernel(out, offset_out, src0_dt, src0_metadata, src1_dt, src1_metadata, comptype, ectx); } } throw not_comparable_error(src0_dt, src1_dt, comptype); }
static void parse_number_json(const ndt::type &tp, const char *arrmeta, char *out_data, const char *&rbegin, const char *end, bool option, const eval::eval_context *ectx) { const char *begin = rbegin; const char *nbegin, *nend; bool escaped = false; if (option && parse::parse_token_no_ws(begin, end, "null")) { ndt::option_type::make(tp).extended<ndt::option_type>()->assign_na(arrmeta, out_data, ectx); } else if (parse::parse_json_number_no_ws(begin, end, nbegin, nend)) { parse::string_to_number(out_data, tp.get_type_id(), nbegin, nend, false, ectx->errmode); } else if (parse::parse_doublequote_string_no_ws(begin, end, nbegin, nend, escaped)) { // Interpret the data inside the string as an int try { if (!escaped) { parse::string_to_number(out_data, tp.get_type_id(), nbegin, nend, option, ectx->errmode); } else { std::string s; parse::unescape_string(nbegin, nend, s); parse::string_to_number(out_data, tp.get_type_id(), nbegin, nend, option, ectx->errmode); } } catch (const std::exception &e) { throw json_parse_error(rbegin, e.what(), tp); } catch (const dynd::dynd_exception &e) { throw json_parse_error(rbegin, e.what(), tp); } } else { throw json_parse_error(rbegin, "expected a number", tp); } rbegin = begin; }
size_t fixedbytes_type::make_assignment_kernel( ckernel_builder *ckb, intptr_t ckb_offset, const ndt::type &dst_tp, const char *dst_arrmeta, const ndt::type &src_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) const { if (this == dst_tp.extended()) { switch (src_tp.get_type_id()) { case fixedbytes_type_id: { const fixedbytes_type *src_fs = src_tp.tcast<fixedbytes_type>(); if (get_data_size() != src_fs->get_data_size()) { throw runtime_error("cannot assign to a fixedbytes type of a different size"); } return ::make_pod_typed_data_assignment_kernel(ckb, ckb_offset, get_data_size(), std::min(get_data_alignment(), src_fs->get_data_alignment()), kernreq); } default: { return src_tp.extended()->make_assignment_kernel( ckb, ckb_offset, dst_tp, dst_arrmeta, src_tp, src_arrmeta, kernreq, ectx); } } } else { stringstream ss; ss << "Cannot assign from " << src_tp << " to " << dst_tp; throw dynd::type_error(ss.str()); } }
void dynd::typed_data_assign(const ndt::type& dst_tp, const char *dst_metadata, char *dst_data, const ndt::type& src_tp, const char *src_metadata, const char *src_data, assign_error_mode errmode, const eval::eval_context *ectx) { DYND_ASSERT_ALIGNED(dst, 0, dst_tp.get_data_alignment(), "dst type: " << dst_tp << ", src type: " << src_tp); DYND_ASSERT_ALIGNED(src, 0, src_dt.get_data_alignment(), "src type: " << src_tp << ", dst type: " << dst_tp); if (errmode == assign_error_default) { if (ectx != NULL) { if (dst_tp.get_dtype().get_type_id() == cuda_device_type_id && src_tp.get_dtype().get_type_id() == cuda_device_type_id) { errmode = ectx->default_cuda_device_errmode; } else { errmode = ectx->default_errmode; } } else if (dst_tp == src_tp) { errmode = assign_error_none; } else { stringstream ss; ss << "assignment from " << src_tp << " to " << dst_tp << " with default error mode requires an eval_context"; throw dynd::type_error(ss.str()); } } assignment_ckernel_builder k; make_assignment_kernel(&k, 0, dst_tp, dst_metadata, src_tp, src_metadata, kernel_request_single, errmode, ectx); k(dst_data, src_data); }
nd::array nd::view(const nd::array& arr, const ndt::type& tp) { // If the types match exactly, simply return 'arr' if (arr.get_type() == tp) { return arr; } else if (arr.get_ndim() == tp.get_ndim()) { // Allocate a result array to attempt the view in it array result(make_array_memory_block(tp.get_metadata_size())); // Copy the fields result.get_ndo()->m_data_pointer = arr.get_ndo()->m_data_pointer; if (arr.get_ndo()->m_data_reference == NULL) { // Embedded data, need reference to the array result.get_ndo()->m_data_reference = arr.get_memblock().release(); } else { // Use the same data reference, avoid producing a chain result.get_ndo()->m_data_reference = arr.get_data_memblock().release(); } result.get_ndo()->m_type = ndt::type(tp).release(); result.get_ndo()->m_flags = arr.get_ndo()->m_flags; // Now try to copy the metadata as a view if (try_view(arr.get_type(), arr.get_ndo_meta(), tp, result.get_ndo_meta(), arr.get_memblock().get())) { // If it succeeded, return it return result; } // Otherwise fall through, let it get destructed, and raise an error } stringstream ss; ss << "Unable to view nd::array of type " << arr.get_type(); ss << "as type " << tp; throw type_error(ss.str()); }
static void parse_bool_json(const ndt::type &tp, const char *arrmeta, char *out_data, const char *&rbegin, const char *end, bool option, const eval::eval_context *ectx) { const char *begin = rbegin; char value = 3; const char *nbegin, *nend; bool escaped; if (parse_token(begin, end, "true")) { value = 1; } else if (parse_token(begin, end, "false")) { value = 0; } else if (parse_token(begin, end, "null")) { if (option || ectx->errmode != assign_error_nocheck) { value = 2; } else { value = 0; } } else if (parse::parse_json_number_no_ws(begin, end, nbegin, nend)) { if (nend - nbegin == 1) { if (*nbegin == '0') { value = 0; } else if (*nbegin == '1' || ectx->errmode == assign_error_nocheck) { value = 1; } } } else if (parse::parse_doublequote_string_no_ws(begin, end, nbegin, nend, escaped)) { if (!escaped) { parse::string_to_bool(&value, nbegin, nend, option, ectx->errmode); } else { string s; parse::unescape_string(nbegin, nend, s); parse::string_to_bool(&value, s.data(), s.data() + s.size(), option, ectx->errmode); } } if (value < 2) { if (tp.get_type_id() == bool_type_id) { *out_data = value; } else { typed_data_assign(tp, arrmeta, out_data, ndt::type::make<bool1>(), NULL, &value); } rbegin = begin; } else if (value == 2 && option) { if (!tp.is_expression()) { *out_data = value; } else { typed_data_assign(tp, arrmeta, out_data, ndt::option_type::make(ndt::type::make<bool1>()), NULL, &value); } rbegin = begin; } else { throw json_parse_error(rbegin, "expected a boolean true or false", tp); } }
size_t cstruct_type::make_assignment_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& dst_tp, const char *dst_metadata, const ndt::type& src_tp, const char *src_metadata, kernel_request_t kernreq, assign_error_mode errmode, const eval::eval_context *ectx) const { if (this == dst_tp.extended()) { if (this == src_tp.extended()) { return make_struct_identical_assignment_kernel(out, offset_out, dst_tp, dst_metadata, src_metadata, kernreq, errmode, ectx); } else if (src_tp.get_kind() == struct_kind) { return make_struct_assignment_kernel(out, offset_out, dst_tp, dst_metadata, src_tp, src_metadata, kernreq, errmode, ectx); } else if (!src_tp.is_builtin()) { return src_tp.extended()->make_assignment_kernel(out, offset_out, dst_tp, dst_metadata, src_tp, src_metadata, kernreq, errmode, ectx); } } stringstream ss; ss << "Cannot assign from " << src_tp << " to " << dst_tp; throw runtime_error(ss.str()); }
nd::array nd::view(const nd::array &arr, const ndt::type &tp) { if (arr.get_type() == tp) { // If the types match exactly, simply return 'arr' return arr; } else if (tp.get_type_id() == bytes_type_id) { // If it's a request to view the data as raw bytes nd::array result = view_as_bytes(arr, tp); if (!result.is_null()) { return result; } } else if (arr.get_type().get_type_id() == bytes_type_id) { // If it's a request to view raw bytes as something else nd::array result = view_from_bytes(arr, tp); if (!result.is_null()) { return result; } } else if (arr.get_ndim() == tp.get_ndim()) { // If the type is symbolic, e.g. has a "Fixed" symbolic dimension, // first substitute in the shape from the array if (tp.is_symbolic()) { dimvector shape(arr.get_ndim()); arr.get_shape(shape.get()); return view_concrete(arr, substitute_shape(tp, arr.get_ndim(), shape.get())); } else { return view_concrete(arr, tp); } } stringstream ss; ss << "Unable to view nd::array of type " << arr.get_type(); ss << " as type " << tp; throw type_error(ss.str()); }
fixed_dim_type::fixed_dim_type(size_t dimension_size, const ndt::type& element_tp, intptr_t stride) : base_uniform_dim_type(fixed_dim_type_id, element_tp, 0, element_tp.get_data_alignment(), 0, type_flag_none), m_stride(stride), m_dim_size(dimension_size) { size_t child_element_size = element_tp.get_data_size(); if (child_element_size == 0) { stringstream ss; ss << "Cannot create dynd fixed_dim type with element type " << element_tp; ss << ", as it does not have a fixed size"; throw runtime_error(ss.str()); } if (dimension_size <= 1 && stride != 0) { stringstream ss; ss << "Cannot create dynd fixed_dim type with size " << dimension_size; ss << " and stride " << stride << ", as the stride must be zero when the dimension size is 1"; throw runtime_error(ss.str()); } if (dimension_size > 1 && stride == 0) { stringstream ss; ss << "Cannot create dynd fixed_dim type with size " << dimension_size; ss << " and stride 0, as the stride must be non-zero when the dimension size is > 1"; throw runtime_error(ss.str()); } m_members.data_size = m_stride * (m_dim_size-1) + child_element_size; // Propagate the zeroinit flag from the element m_members.flags |= (element_tp.get_flags()&type_flag_zeroinit); // Copy ndobject properties and functions from the first non-array dimension get_scalar_properties_and_functions(m_array_properties, m_array_functions); }
static void resolve_dst_type(char *static_data, char *DYND_UNUSED(data), ndt::type &dst_tp, intptr_t nsrc, const ndt::type *src_tp, intptr_t nkwd, const dynd::nd::array *kwds, const std::map<std::string, ndt::type> &tp_vars) { base_callable *child = reinterpret_cast<callable *>(static_data)->get(); const ndt::callable_type *child_tp = reinterpret_cast<callable *>(static_data)->get_type(); if (child->resolve_dst_type != NULL) { child->resolve_dst_type(child->static_data(), NULL, dst_tp, nsrc, src_tp, nkwd, kwds, tp_vars); } else { dst_tp = ndt::substitute(child_tp->get_return_type(), tp_vars, false); } ndt::type tp = dst_tp.without_memory_type(); for (intptr_t i = nsrc - 1; i >= 0; --i) { if (!src_tp[i].without_memory_type().is_scalar()) { tp = src_tp[i].without_memory_type().with_replaced_dtype(tp); } } if (dst_tp.get_kind() == memory_kind) { dst_tp = dst_tp.extended<ndt::base_memory_type>()->with_replaced_storage_type(tp); } else { dst_tp = tp; } }
size_t fixedstring_type::make_comparison_kernel( void *ckb, intptr_t ckb_offset, const ndt::type &src0_dt, const char *src0_arrmeta, const ndt::type &src1_dt, const char *src1_arrmeta, comparison_type_t comptype, const eval::eval_context *ectx) const { if (this == src0_dt.extended()) { if (*this == *src1_dt.extended()) { return make_fixedstring_comparison_kernel(ckb, ckb_offset, m_stringsize, m_encoding, comptype, ectx); } else if (src1_dt.get_kind() == string_kind) { return make_general_string_comparison_kernel(ckb, ckb_offset, src0_dt, src0_arrmeta, src1_dt, src1_arrmeta, comptype, ectx); } else if (!src1_dt.is_builtin()) { return src1_dt.extended()->make_comparison_kernel(ckb, ckb_offset, src0_dt, src0_arrmeta, src1_dt, src1_arrmeta, comptype, ectx); } } throw not_comparable_error(src0_dt, src1_dt, comptype); }
/** * Creates a result array for an elementwise * reduce operation. */ static ndarray_node_ptr make_elwise_reduce_result(const ndt::type& result_dt, uint32_t access_flags, bool keepdims, int ndim, const dynd_bool *reduce_axes, const intptr_t *src_shape, const int *src_axis_perm, char *&result_originptr, intptr_t *result_strides) { dimvector result_shape(ndim); // Calculate the shape and strides of the reduction result // without removing the dimensions intptr_t num_elements = 1; intptr_t stride = result_dt.get_data_size(); for (int i = 0; i < ndim; ++i) { int p = src_axis_perm[i]; if (reduce_axes[p]) { result_shape[p] = 1; result_strides[p] = 0; } else { intptr_t size = src_shape[p]; result_shape[p] = size; if (size == 1) { result_strides[p] = 0; } else { result_strides[p] = stride; stride *= size; num_elements *= size; } } } // Allocate the memoryblock for the data char *originptr = NULL; memory_block_ptr memblock = make_fixed_size_pod_memory_block(result_dt.get_data_size() * num_elements, result_dt.get_data_alignment(), &originptr, NULL, NULL); ndarray_node_ptr result; // Create the strided ndarray node, compressing the dimensions if requested if (!keepdims) { dimvector compressed_shape(ndim), compressed_strides(ndim); int compressed_ndim = 0; for (int i = 0; i < ndim; ++i) { if (!reduce_axes[i]) { compressed_shape[compressed_ndim] = result_shape[i]; compressed_strides[compressed_ndim] = result_strides[i]; ++compressed_ndim; } } result = make_strided_ndarray_node(result_dt, compressed_ndim, compressed_shape.get(), compressed_strides.get(), originptr, access_flags, memblock); } else { result = make_strided_ndarray_node(result_dt, ndim, result_shape.get(), result_strides, originptr, access_flags, memblock); } // Because we just allocated this buffer, we can write to it even though it // might be marked as readonly because the src memory block is readonly result_originptr = const_cast<char *>(result->get_readonly_originptr()); return DYND_MOVE(result); }
void get_dynamic_array_functions( const std::pair<std::string, gfunc::callable> **out_functions, size_t *out_count) const { if (!m_value_type.is_builtin()) { m_value_type.extended()->get_dynamic_array_functions(out_functions, out_count); } }
inline base_uniform_dim_type(type_id_t type_id, const ndt::type& element_tp, size_t data_size, size_t alignment, size_t element_metadata_offset, flags_type flags) : base_type(type_id, uniform_dim_kind, data_size, alignment, flags, element_metadata_offset + element_tp.get_metadata_size(), 1 + element_tp.get_ndim()), m_element_tp(element_tp), m_element_metadata_offset(element_metadata_offset) { }
byteswap_type::byteswap_type(const ndt::type& value_type) : base_expr_type(byteswap_type_id, expr_kind, value_type.get_data_size(), value_type.get_data_alignment(), type_flag_scalar, 0), m_value_type(value_type), m_operand_type(ndt::make_fixedbytes(value_type.get_data_size(), value_type.get_data_alignment())) { if (!value_type.is_builtin()) { throw dynd::type_error("byteswap_type: Only built-in types are supported presently"); } }
strided_dim_type::strided_dim_type(const ndt::type& element_tp) : base_dim_type(strided_dim_type_id, element_tp, 0, element_tp.get_data_alignment(), sizeof(strided_dim_type_arrmeta), type_flag_none, true) { // Propagate the inherited flags from the element m_members.flags |= (element_tp.get_flags() & ((type_flags_operand_inherited | type_flags_value_inherited) & ~type_flag_scalar)); }
/** * Makes an unaligned type to view the given type without alignment requirements. */ inline ndt::type make_view(const ndt::type& value_type, const ndt::type& operand_type) { if (value_type.get_kind() != expr_kind) { return ndt::type(new view_type(value_type, operand_type), false); } else { // When the value type has an expr_kind, we need to chain things together // so that the view operation happens just at the primitive level. return value_type.extended<base_expr_type>()->with_replaced_storage_type( ndt::type(new view_type(value_type.storage_type(), operand_type), false)); } }
size_t dynd::make_expression_comparison_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& src0_dt, const char *src0_metadata, const ndt::type& src1_dt, const char *src1_metadata, comparison_type_t comptype, const eval::eval_context *ectx) { size_t current_offset = offset_out + sizeof(buffered_kernel_extra); out->ensure_capacity(current_offset); buffered_kernel_extra *e = out->get_at<buffered_kernel_extra>(offset_out); e->base.set_function<binary_single_predicate_t>(&buffered_kernel_extra::kernel); e->base.destructor = &buffered_kernel_extra::destruct; // Initialize the information for buffering the operands if (src0_dt.get_kind() == expression_kind) { e->init_buffer(0, src0_dt.value_type()); e->buf[0].kernel_offset = current_offset - offset_out; current_offset = make_assignment_kernel(out, current_offset, src0_dt.value_type(), e->buf[0].metadata, src0_dt, src0_metadata, kernel_request_single, assign_error_none, ectx); // Have to re-retrieve 'e', because creating another kernel may invalidate it e = out->get_at<buffered_kernel_extra>(offset_out); } if (src1_dt.get_kind() == expression_kind) { e->init_buffer(1, src1_dt.value_type()); e->buf[1].kernel_offset = current_offset - offset_out; current_offset = make_assignment_kernel(out, current_offset, src1_dt.value_type(), e->buf[1].metadata, src1_dt, src1_metadata, kernel_request_single, assign_error_none, ectx); // Have to re-retrieve 'e', because creating another kernel may invalidate it e = out->get_at<buffered_kernel_extra>(offset_out); } // Allocate the data for the buffers if (e->buf[0].kernel_offset != 0) { current_offset = inc_to_alignment(current_offset, src0_dt.get_data_alignment()); e->buf[0].data_offset = current_offset - offset_out; current_offset += e->buf[0].data_size; } if (e->buf[1].kernel_offset != 0) { current_offset = inc_to_alignment(current_offset, src1_dt.get_data_alignment()); e->buf[1].data_offset = current_offset - offset_out; current_offset += e->buf[1].data_size; } out->ensure_capacity(current_offset); // Have to re-retrieve 'e', because allocating the buffer data may invalidate it e = out->get_at<buffered_kernel_extra>(offset_out); e->cmp_kernel_offset = current_offset - offset_out; return make_comparison_kernel(out, current_offset, src0_dt.value_type(), (e->buf[0].kernel_offset != 0) ? e->buf[0].metadata : src0_metadata, src1_dt.value_type(), (e->buf[1].kernel_offset != 0) ? e->buf[1].metadata : src1_metadata, comptype, ectx); }
adapt_type::adapt_type(const ndt::type &operand_type, const ndt::type &value_type, const nd::string &op) : base_expr_type( adapt_type_id, expr_kind, operand_type.get_data_size(), operand_type.get_data_alignment(), inherited_flags(value_type.get_flags(), operand_type.get_flags()), 0), m_value_type(value_type), m_operand_type(operand_type), m_op(op) { if (!value_type.is_builtin() && value_type.extended()->adapt_type(operand_type.value_type(), op, m_forward, m_reverse)) { } else if (!operand_type.value_type().is_builtin() && operand_type.value_type().extended()->reverse_adapt_type( value_type, op, m_forward, m_reverse)) { } else { stringstream ss; ss << "Cannot create type "; print_type(ss); throw type_error(ss.str()); } // If the operand is an expression, make a buffering arrfunc if (m_operand_type.get_kind() == expr_kind && !m_forward.is_null() && m_operand_type != m_forward.get_type()->get_arg_type(0)) { m_forward = make_chain_arrfunc( make_arrfunc_from_assignment(m_forward.get_type()->get_arg_type(0), m_operand_type, assign_error_default), m_forward, m_forward.get_type()->get_arg_type(0)); } }
size_t cfixed_dim_type::make_assignment_kernel( ckernel_builder *ckb, intptr_t ckb_offset, const ndt::type &dst_tp, const char *dst_arrmeta, const ndt::type &src_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) const { if (this == dst_tp.extended()) { intptr_t src_size, src_stride; ndt::type src_el_tp; const char *src_el_arrmeta; if (src_tp.get_ndim() < dst_tp.get_ndim()) { kernels::strided_assign_ck *self = kernels::strided_assign_ck::create(ckb, kernreq, ckb_offset); self->m_size = get_fixed_dim_size(); self->m_dst_stride = get_fixed_stride(); // If the src has fewer dimensions, broadcast it across this one self->m_src_stride = 0; return ::make_assignment_kernel( ckb, ckb_offset, m_element_tp, dst_arrmeta + sizeof(cfixed_dim_type_arrmeta), src_tp, src_arrmeta, kernel_request_strided, ectx); } else if (src_tp.get_as_strided(src_arrmeta, &src_size, &src_stride, &src_el_tp, &src_el_arrmeta)) { kernels::strided_assign_ck *self = kernels::strided_assign_ck::create(ckb, kernreq, ckb_offset); self->m_size = get_fixed_dim_size(); self->m_dst_stride = get_fixed_stride(); self->m_src_stride = src_stride; // Check for a broadcasting error if (src_size != 1 && get_fixed_dim_size() != src_size) { throw broadcast_error(dst_tp, dst_arrmeta, src_tp, src_arrmeta); } return ::make_assignment_kernel( ckb, ckb_offset, m_element_tp, dst_arrmeta + sizeof(cfixed_dim_type_arrmeta), src_el_tp, src_el_arrmeta, kernel_request_strided, ectx); } else if (!src_tp.is_builtin()) { // Give the src type a chance to make a kernel return src_tp.extended()->make_assignment_kernel( ckb, ckb_offset, dst_tp, dst_arrmeta, src_tp, src_arrmeta, kernreq, ectx); } else { stringstream ss; ss << "Cannot assign from " << src_tp << " to " << dst_tp; throw dynd::type_error(ss.str()); } } else if (dst_tp.get_kind() == string_kind) { return make_any_to_string_assignment_kernel(ckb, ckb_offset, dst_tp, dst_arrmeta, src_tp, src_arrmeta, kernreq, ectx); } else if (dst_tp.get_ndim() < src_tp.get_ndim()) { throw broadcast_error(dst_tp, dst_arrmeta, src_tp, src_arrmeta); } else { stringstream ss; ss << "Cannot assign from " << src_tp << " to " << dst_tp; throw dynd::type_error(ss.str()); } }
static void set(const ndt::type& paramtype, char *metadata, char *data, const char (&value)[N]) { // Setting from a known-sized character string array if (paramtype.get_type_id() == string_type_id && static_cast<const string_type *>(paramtype.extended())->get_encoding() == string_encoding_utf_8) { reinterpret_cast<string_type_data*>(data)->begin = const_cast<char *>(value); reinterpret_cast<string_type_data*>(data)->end = const_cast<char *>(value + N - 1); } else { typed_data_assign(paramtype, metadata, data, ndt::make_fixedstring(N, string_encoding_utf_8), NULL, value); } }
nd::array dynd::parse_json(const ndt::type &tp, const char *json_begin, const char *json_end, const eval::eval_context *ectx) { nd::array result; result = nd::empty(tp); parse_json(result, json_begin, json_end, ectx); if (!tp.is_builtin()) { tp.extended()->arrmeta_finalize_buffers(result.get()->metadata()); } return result; }
static void format_json_uniform_dim(output_data& out, const ndt::type& dt, const char *metadata, const char *data) { out.write('['); switch (dt.get_type_id()) { case strided_dim_type_id: { const strided_dim_type *sad = static_cast<const strided_dim_type *>(dt.extended()); const strided_dim_type_metadata *md = reinterpret_cast<const strided_dim_type_metadata *>(metadata); ndt::type element_tp = sad->get_element_type(); intptr_t size = md->size, stride = md->stride; metadata += sizeof(strided_dim_type_metadata); for (intptr_t i = 0; i < size; ++i) { ::format_json(out, element_tp, metadata, data + i * stride); if (i != size - 1) { out.write(','); } } break; } case fixed_dim_type_id: { const fixed_dim_type *fad = static_cast<const fixed_dim_type *>(dt.extended()); ndt::type element_tp = fad->get_element_type(); intptr_t size = (intptr_t)fad->get_fixed_dim_size(), stride = fad->get_fixed_stride(); for (intptr_t i = 0; i < size; ++i) { ::format_json(out, element_tp, metadata, data + i * stride); if (i != size - 1) { out.write(','); } } break; } case var_dim_type_id: { const var_dim_type *vad = static_cast<const var_dim_type *>(dt.extended()); const var_dim_type_metadata *md = reinterpret_cast<const var_dim_type_metadata *>(metadata); const var_dim_type_data *d = reinterpret_cast<const var_dim_type_data *>(data); ndt::type element_tp = vad->get_element_type(); intptr_t size = d->size, stride = md->stride; const char *begin = d->begin + md->offset; metadata += sizeof(var_dim_type_metadata); for (intptr_t i = 0; i < size; ++i) { ::format_json(out, element_tp, metadata, begin + i * stride); if (i != size - 1) { out.write(','); } } break; } default: { stringstream ss; ss << "Formatting dynd type " << dt << " as JSON is not implemented yet"; throw runtime_error(ss.str()); } } out.write(']'); }