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); }
size_t dynd::make_tuple_assignment_kernel(void *ckb, intptr_t ckb_offset, const ndt::type &dst_tuple_tp, const char *dst_arrmeta, const ndt::type &src_tuple_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) { if (src_tuple_tp.get_kind() != tuple_kind && src_tuple_tp.get_kind() != struct_kind) { stringstream ss; ss << "make_tuple_assignment_kernel: provided source type " << src_tuple_tp << " is not of tuple or struct kind"; throw runtime_error(ss.str()); } if (dst_tuple_tp.get_kind() != tuple_kind && dst_tuple_tp.get_kind() != struct_kind) { stringstream ss; ss << "make_tuple_assignment_kernel: provided destination type " << dst_tuple_tp << " is not of tuple or struct kind"; throw runtime_error(ss.str()); } auto dst_sd = dst_tuple_tp.extended<ndt::base_tuple_type>(); auto src_sd = src_tuple_tp.extended<ndt::base_tuple_type>(); intptr_t field_count = dst_sd->get_field_count(); if (field_count != src_sd->get_field_count()) { stringstream ss; ss << "cannot assign dynd " << src_tuple_tp << " to " << dst_tuple_tp << " because they have different numbers of fields"; throw type_error(ss.str()); } const uintptr_t *src_arrmeta_offsets = src_sd->get_arrmeta_offsets_raw(); shortvector<const char *> src_fields_arrmeta(field_count); for (intptr_t i = 0; i != field_count; ++i) { src_fields_arrmeta[i] = src_arrmeta + src_arrmeta_offsets[i]; } const uintptr_t *dst_arrmeta_offsets = dst_sd->get_arrmeta_offsets_raw(); shortvector<const char *> dst_fields_arrmeta(field_count); for (intptr_t i = 0; i != field_count; ++i) { dst_fields_arrmeta[i] = dst_arrmeta + dst_arrmeta_offsets[i]; } return make_tuple_unary_op_ckernel( nd::copy::get().get(), nd::copy::get().get_type(), ckb, ckb_offset, field_count, dst_sd->get_data_offsets(dst_arrmeta), dst_sd->get_field_types_raw(), dst_fields_arrmeta.get(), src_sd->get_data_offsets(src_arrmeta), src_sd->get_field_types_raw(), src_fields_arrmeta.get(), kernreq, ectx); }
size_t datetime_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 (src_tp == dst_tp) { return make_pod_typed_data_assignment_kernel(out, offset_out, get_data_size(), get_data_alignment(), kernreq); } else if (src_tp.get_kind() == string_kind) { // Assignment from strings return make_string_to_datetime_assignment_kernel(out, offset_out, dst_tp, dst_metadata, src_tp, src_metadata, kernreq, errmode, ectx); } else if (src_tp.get_kind() == struct_kind) { // Convert to struct using the "struct" property return ::make_assignment_kernel(out, offset_out, ndt::make_property(dst_tp, "struct"), 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); } } else { if (dst_tp.get_kind() == string_kind) { // Assignment to strings return make_datetime_to_string_assignment_kernel(out, offset_out, dst_tp, dst_metadata, src_tp, src_metadata, kernreq, errmode, ectx); } else if (dst_tp.get_kind() == struct_kind) { // Convert to struct using the "struct" property return ::make_assignment_kernel(out, offset_out, dst_tp, dst_metadata, ndt::make_property(src_tp, "struct"), src_metadata, kernreq, errmode, ectx); } // TODO } stringstream ss; ss << "Cannot assign from " << src_tp << " to " << dst_tp; throw runtime_error(ss.str()); }
size_t dynd::make_builtin_to_string_assignment_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& dst_string_tp, const char *dst_metadata, type_id_t src_type_id, kernel_request_t kernreq, assign_error_mode errmode, const eval::eval_context *DYND_UNUSED(ectx)) { if (dst_string_tp.get_kind() != string_kind) { stringstream ss; ss << "make_builtin_to_string_assignment_kernel: destination type " << dst_string_tp << " is not a string type"; throw runtime_error(ss.str()); } if (src_type_id >= 0 && src_type_id < builtin_type_id_count) { offset_out = make_kernreq_to_single_kernel_adapter(out, offset_out, kernreq); out->ensure_capacity_leaf(offset_out + sizeof(builtin_to_string_kernel_extra)); builtin_to_string_kernel_extra *e = out->get_at<builtin_to_string_kernel_extra>(offset_out); e->base.set_function<unary_single_operation_t>(builtin_to_string_kernel_extra::single); e->base.destructor = builtin_to_string_kernel_extra::destruct; // The kernel data owns this reference e->dst_string_tp = static_cast<const base_string_type *>(ndt::type(dst_string_tp).release()); e->src_type_id = src_type_id; e->errmode = errmode; e->dst_metadata = dst_metadata; return offset_out + sizeof(builtin_to_string_kernel_extra); } else { stringstream ss; ss << "make_builtin_to_string_assignment_kernel: source type id " << src_type_id << " is not builtin"; throw runtime_error(ss.str()); } }
size_t dynd::make_builtin_to_string_assignment_kernel( void *ckb, intptr_t ckb_offset, const ndt::type &dst_string_tp, const char *dst_arrmeta, type_id_t src_type_id, kernel_request_t kernreq, const eval::eval_context *ectx) { if (dst_string_tp.get_kind() != string_kind) { stringstream ss; ss << "make_builtin_to_string_assignment_kernel: destination type " << dst_string_tp << " is not a string type"; throw runtime_error(ss.str()); } if (src_type_id >= 0 && src_type_id < builtin_type_id_count) { ckb_offset = make_kernreq_to_single_kernel_adapter(ckb, ckb_offset, 1, kernreq); builtin_to_string_kernel_extra *e = reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb) ->alloc_ck<builtin_to_string_kernel_extra>(ckb_offset); e->base.set_function<expr_single_t>(builtin_to_string_kernel_extra::single); e->base.destructor = builtin_to_string_kernel_extra::destruct; // The kernel data owns this reference e->dst_string_tp = static_cast<const ndt::base_string_type *>( ndt::type(dst_string_tp).release()); e->src_type_id = src_type_id; e->ectx = *ectx; e->dst_arrmeta = dst_arrmeta; return ckb_offset; } else { stringstream ss; ss << "make_builtin_to_string_assignment_kernel: source type id " << src_type_id << " is not builtin"; throw runtime_error(ss.str()); } }
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); }
size_t dynd::make_broadcast_to_tuple_assignment_kernel( void *ckb, intptr_t ckb_offset, const ndt::type &dst_tuple_tp, const char *dst_arrmeta, const ndt::type &src_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) { // This implementation uses the same struct to struct kernel, just with // an offset of 0 for each source value. A kernel tailored to this // case can be made if better performance is needed. if (dst_tuple_tp.get_kind() != tuple_kind && dst_tuple_tp.get_kind() != struct_kind) { stringstream ss; ss << "make_tuple_assignment_kernel: provided destination type " << dst_tuple_tp << " is not of tuple or struct kind"; throw runtime_error(ss.str()); } auto dst_sd = dst_tuple_tp.extended<ndt::base_tuple_type>(); intptr_t field_count = dst_sd->get_field_count(); const uintptr_t *dst_arrmeta_offsets = dst_sd->get_arrmeta_offsets_raw(); shortvector<const char *> dst_fields_arrmeta(field_count); for (intptr_t i = 0; i != field_count; ++i) { dst_fields_arrmeta[i] = dst_arrmeta + dst_arrmeta_offsets[i]; } vector<ndt::type> src_fields_tp(field_count, src_tp); vector<const char *> src_fields_arrmeta(field_count, src_arrmeta); vector<uintptr_t> src_data_offsets(field_count, 0); return make_tuple_unary_op_ckernel( nd::copy::get().get(), nd::copy::get().get_type(), ckb, ckb_offset, field_count, dst_sd->get_data_offsets(dst_arrmeta), dst_sd->get_field_types_raw(), dst_fields_arrmeta.get(), &src_data_offsets[0], &src_fields_tp[0], &src_fields_arrmeta[0], kernreq, ectx); }
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()); }
size_t dynd::make_string_to_datetime_assignment_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& dst_datetime_dt, const char *DYND_UNUSED(dst_metadata), const ndt::type& src_string_dt, const char *src_metadata, kernel_request_t kernreq, assign_error_mode errmode, const eval::eval_context *DYND_UNUSED(ectx)) { if (src_string_dt.get_kind() != string_kind) { stringstream ss; ss << "make_string_to_datetime_assignment_kernel: source type " << src_string_dt << " is not a string type"; throw runtime_error(ss.str()); } offset_out = make_kernreq_to_single_kernel_adapter(out, offset_out, kernreq); out->ensure_capacity(offset_out + sizeof(string_to_datetime_kernel_extra)); string_to_datetime_kernel_extra *e = out->get_at<string_to_datetime_kernel_extra>(offset_out); e->base.set_function<unary_single_operation_t>(&string_to_datetime_kernel_extra::single); e->base.destructor = &string_to_datetime_kernel_extra::destruct; // The kernel data owns a reference to this type e->dst_datetime_dt = static_cast<const datetime_type *>(ndt::type(dst_datetime_dt).release()); // The kernel data owns a reference to this type e->src_string_dt = static_cast<const base_string_type *>(ndt::type(src_string_dt).release()); e->src_metadata = src_metadata; e->errmode = errmode; e->unit = dynd_unit_to_datetime_unit(e->dst_datetime_dt->get_unit()); switch (errmode) { case assign_error_fractional: case assign_error_inexact: e->casting = datetime::datetime_conversion_strict; break; default: e->casting = datetime::datetime_conversion_relaxed; } return offset_out + sizeof(string_to_datetime_kernel_extra); }
size_t dynd::make_datetime_to_string_assignment_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& dst_string_dt, const char *dst_metadata, const ndt::type& src_datetime_dt, const char *DYND_UNUSED(src_metadata), kernel_request_t kernreq, assign_error_mode errmode, const eval::eval_context *DYND_UNUSED(ectx)) { if (dst_string_dt.get_kind() != string_kind) { stringstream ss; ss << "get_datetime_to_string_assignment_kernel: dest type " << dst_string_dt << " is not a string type"; throw runtime_error(ss.str()); } offset_out = make_kernreq_to_single_kernel_adapter(out, offset_out, kernreq); out->ensure_capacity(offset_out + sizeof(datetime_to_string_kernel_extra)); datetime_to_string_kernel_extra *e = out->get_at<datetime_to_string_kernel_extra>(offset_out); e->base.set_function<unary_single_operation_t>(&datetime_to_string_kernel_extra::single); e->base.destructor = &datetime_to_string_kernel_extra::destruct; // The kernel data owns a reference to this type e->dst_string_dt = static_cast<const base_string_type *>(ndt::type(dst_string_dt).release()); // The kernel data owns a reference to this type e->src_datetime_dt = static_cast<const datetime_type *>(ndt::type(src_datetime_dt).release()); e->dst_metadata = dst_metadata; e->unit = dynd_unit_to_datetime_unit(e->src_datetime_dt->get_unit()); e->errmode = errmode; return offset_out + sizeof(datetime_to_string_kernel_extra); }
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); }
static void format_json(output_data& out, const ndt::type& dt, const char *metadata, const char *data) { switch (dt.get_kind()) { case bool_kind: format_json_bool(out, dt, metadata, data); break; case int_kind: case uint_kind: case real_kind: case complex_kind: format_json_number(out, dt, metadata, data); break; case string_kind: format_json_string(out, dt, metadata, data); break; case datetime_kind: format_json_datetime(out, dt, metadata, data); break; case struct_kind: format_json_struct(out, dt, metadata, data); break; case uniform_dim_kind: format_json_uniform_dim(out, dt, metadata, data); break; default: { stringstream ss; ss << "Formatting dynd type " << dt << " as JSON is not implemented yet"; throw runtime_error(ss.str()); } } }
size_t dynd::make_string_to_builtin_assignment_kernel( void *ckb, intptr_t ckb_offset, type_id_t dst_type_id, const ndt::type &src_string_tp, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) { if (src_string_tp.get_kind() != string_kind) { stringstream ss; ss << "make_string_to_builtin_assignment_kernel: source type " << src_string_tp << " is not a string type"; throw runtime_error(ss.str()); } if (dst_type_id >= bool_type_id && dst_type_id <= complex_float64_type_id) { ckb_offset = make_kernreq_to_single_kernel_adapter(ckb, ckb_offset, 1, kernreq); string_to_builtin_kernel *e = reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb) ->alloc_ck<string_to_builtin_kernel>(ckb_offset); e->base.set_function<expr_single_t>( static_string_to_builtin_kernels[dst_type_id - bool_type_id]); e->base.destructor = &string_to_builtin_kernel::destruct; // The kernel data owns this reference e->src_string_tp = static_cast<const ndt::base_string_type *>( ndt::type(src_string_tp).release()); e->errmode = ectx->errmode; e->src_arrmeta = src_arrmeta; return ckb_offset; } else { stringstream ss; ss << "make_string_to_builtin_assignment_kernel: destination type id " << dst_type_id << " is not builtin"; throw runtime_error(ss.str()); } }
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()); } }
/** * 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 time_type::make_assignment_kernel( void *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()) { if (src_tp.get_type_id() == time_type_id) { return make_pod_typed_data_assignment_kernel(ckb, ckb_offset, get_data_size(), get_data_alignment(), kernreq); } else if (src_tp.get_kind() == string_kind) { // Assignment from strings return make_string_to_time_assignment_kernel( ckb, ckb_offset, dst_tp, src_tp, src_arrmeta, kernreq, ectx); } else if (src_tp.get_kind() == struct_kind) { // Convert to struct using the "struct" property return ::make_assignment_kernel( ckb, ckb_offset, ndt::make_property(dst_tp, "struct"), dst_arrmeta, src_tp, src_arrmeta, kernreq, ectx); } else if (!src_tp.is_builtin()) { return src_tp.extended()->make_assignment_kernel( ckb, ckb_offset, dst_tp, dst_arrmeta, src_tp, src_arrmeta, kernreq, ectx); } } else { if (dst_tp.get_kind() == string_kind) { // Assignment to strings return make_time_to_string_assignment_kernel( ckb, ckb_offset, dst_tp, dst_arrmeta, src_tp, kernreq, ectx); } else if (dst_tp.get_kind() == struct_kind) { // Convert to struct using the "struct" property return ::make_assignment_kernel( ckb, ckb_offset, dst_tp, dst_arrmeta, ndt::make_property(src_tp, "struct"), src_arrmeta, kernreq, ectx); } // TODO } stringstream ss; ss << "Cannot assign from " << src_tp << " to " << dst_tp; throw dynd::type_error(ss.str()); }
nd::callable dynd::make_callable_from_property(const ndt::type &tp, const std::string &propname) { if (tp.get_kind() == expr_kind) { stringstream ss; ss << "Creating an callable from a property requires a non-expression" << ", got " << tp; throw type_error(ss.str()); } ndt::type prop_tp = ndt::property_type::make(tp, propname); return nd::callable::make<property_kernel>(ndt::callable_type::make(prop_tp.value_type(), tp), prop_tp); }
bool bytes_type::is_lossless_assignment(const ndt::type& dst_tp, const ndt::type& src_tp) const { if (dst_tp.extended() == this) { if (src_tp.get_kind() == bytes_kind) { return true; } else { return false; } } else { return false; } }
static void parse_json(const ndt::type &tp, const char *arrmeta, char *out_data, const char *&begin, const char *end, const eval::eval_context *ectx) { begin = skip_whitespace(begin, end); switch (tp.get_kind()) { case dim_kind: parse_dim_json(tp, arrmeta, out_data, begin, end, ectx); return; case struct_kind: parse_struct_json(tp, arrmeta, out_data, begin, end, ectx); return; case tuple_kind: parse_tuple_json(tp, arrmeta, out_data, begin, end, ectx); return; case bool_kind: parse_bool_json(tp, arrmeta, out_data, begin, end, false, ectx); return; case sint_kind: case uint_kind: case real_kind: case complex_kind: parse_number_json(tp, arrmeta, out_data, begin, end, false, ectx); return; case string_kind: parse_string_json(tp, arrmeta, out_data, begin, end, ectx); return; case datetime_kind: parse_datetime_json(tp, arrmeta, out_data, begin, end, false, ectx); return; case type_kind: parse_type(tp, arrmeta, out_data, begin, end, false, ectx); return; case option_kind: parse_option_json(tp, arrmeta, out_data, begin, end, ectx); return; case dynamic_kind: if (tp.get_type_id() == json_type_id) { // The json type is a special string type that contains JSON directly // Copy the JSON verbatim in this case. parse_jsonstring_json(tp, arrmeta, out_data, begin, end, ectx); return; } break; default: break; } stringstream ss; ss << "parse_json: unsupported dynd type \"" << tp << "\""; throw runtime_error(ss.str()); }
base_memory_type(type_id_t type_id, const ndt::type &element_tp, size_t data_size, size_t alignment, size_t storage_arrmeta_offset, flags_type flags) : base_type(type_id, memory_kind, data_size, alignment, flags, storage_arrmeta_offset + element_tp.get_arrmeta_size(), element_tp.get_ndim(), 0), m_element_tp(element_tp), m_storage_arrmeta_offset(storage_arrmeta_offset) { if (element_tp.get_kind() == memory_kind || element_tp.get_kind() == symbolic_kind) { stringstream ss; ss << "a memory space cannot be specified for type " << element_tp; throw runtime_error(ss.str()); } }
pointer_type::pointer_type(const ndt::type& target_tp) : base_expr_type(pointer_type_id, expr_kind, sizeof(void *), sizeof(void *), inherited_flags(target_tp.get_flags(), type_flag_zeroinit|type_flag_blockref), sizeof(pointer_type_arrmeta) + target_tp.get_arrmeta_size(), target_tp.get_ndim()), m_target_tp(target_tp) { // I'm not 100% sure how blockref pointer types should interact with // the computational subsystem, the details will have to shake out // when we want to actually do something with them. if (target_tp.get_kind() == expr_kind && target_tp.get_type_id() != pointer_type_id) { stringstream ss; ss << "A dynd pointer type's target cannot be the expression type "; ss << target_tp; throw dynd::type_error(ss.str()); } }
ndt::type ndt::make_unaligned(const ndt::type& value_type) { if (value_type.get_data_alignment() > 1) { // Only do something if it requires alignment if (value_type.get_kind() != expr_kind) { return ndt::make_view( value_type, ndt::make_fixed_bytes(value_type.get_data_size(), 1)); } else { const ndt::type &sdt = value_type.storage_type(); return ndt::type( value_type.extended<base_expr_type>()->with_replaced_storage_type( ndt::make_view(sdt, ndt::make_fixed_bytes(sdt.get_data_size(), 1)))); } } else { return value_type; } }
size_t pydynd::get_nonragged_dim_count(const ndt::type &tp, size_t max_count) { switch (tp.get_kind()) { case kind_kind: case pattern_kind: if (tp.is_scalar()) { return 0; } case dim_kind: if (max_count <= 1) { return max_count; } else { return min(max_count, 1 + get_nonragged_dim_count( static_cast<const ndt::base_dim_type *>(tp.extended()) ->get_element_type(), max_count - 1)); } case struct_kind: case tuple_kind: if (max_count <= 1) { return max_count; } else { auto bsd = tp.extended<ndt::tuple_type>(); size_t field_count = bsd->get_field_count(); for (size_t i = 0; i != field_count; ++i) { size_t candidate = 1 + get_nonragged_dim_count(bsd->get_field_type(i), max_count - 1); if (candidate < max_count) { max_count = candidate; if (max_count <= 1) { return max_count; } } } return max_count; } default: return 0; } }
static void parse_json(const ndt::type &tp, const char *arrmeta, char *out_data, const char *&begin, const char *end, const eval::eval_context *ectx) { begin = skip_whitespace(begin, end); switch (tp.get_kind()) { case dim_kind: parse_dim_json(tp, arrmeta, out_data, begin, end, ectx); return; case struct_kind: parse_struct_json(tp, arrmeta, out_data, begin, end, ectx); return; case tuple_kind: parse_tuple_json(tp, arrmeta, out_data, begin, end, ectx); return; case bool_kind: parse_bool_json(tp, arrmeta, out_data, begin, end, false, ectx); return; case sint_kind: case uint_kind: case real_kind: case complex_kind: parse_number_json(tp, arrmeta, out_data, begin, end, false, ectx); return; case string_kind: parse_string_json(tp, arrmeta, out_data, begin, end, ectx); return; case datetime_kind: parse_datetime_json(tp, arrmeta, out_data, begin, end, false, ectx); return; case type_kind: parse_type(tp, arrmeta, out_data, begin, end, false, ectx); return; case option_kind: parse_option_json(tp, arrmeta, out_data, begin, end, ectx); return; default: break; } stringstream ss; ss << "parse_json: unsupported dynd type \"" << tp << "\""; throw runtime_error(ss.str()); }
static void parse_json(const ndt::type& tp, const char *metadata, char *out_data, const char *&json_begin, const char *json_end, const eval::eval_context *ectx) { switch (tp.get_kind()) { case uniform_dim_kind: parse_uniform_dim_json(tp, metadata, out_data, json_begin, json_end, ectx); break; case struct_kind: parse_struct_json(tp, metadata, out_data, json_begin, json_end, ectx); break; case bool_kind: parse_bool_json(tp, metadata, out_data, json_begin, json_end); return; case int_kind: case uint_kind: parse_integer_json(tp, metadata, out_data, json_begin, json_end); return; case real_kind: parse_real_json(tp, metadata, out_data, json_begin, json_end); return; case complex_kind: parse_complex_json(tp, metadata, out_data, json_begin, json_end); return; case string_kind: if (tp.get_type_id() == json_type_id) { // The json type is a special string type that contains JSON directly // Copy the JSON verbatim in this case. parse_jsonstring_json(tp, metadata, out_data, json_begin, json_end); } else { parse_string_json(tp, metadata, out_data, json_begin, json_end); } return; case datetime_kind: parse_datetime_json(tp, metadata, out_data, json_begin, json_end, ectx); return; default: { stringstream ss; ss << "parse_json: unsupported dynd type " << tp; throw runtime_error(ss.str()); } } }
size_t dynd::make_any_to_string_assignment_kernel(void *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) { typedef date_to_string_ck self_type; if (dst_tp.get_kind() != string_kind) { stringstream ss; ss << "make_any_to_string_assignment_kernel: dest type " << dst_tp << " is not a string type"; throw runtime_error(ss.str()); } self_type *self = self_type::make(ckb, kernreq, ckb_offset); self->m_dst_string_tp = dst_tp; self->m_dst_arrmeta = dst_arrmeta; self->m_src_tp = src_tp; self->m_src_arrmeta = src_arrmeta; self->m_ectx = *ectx; return ckb_offset; }
/** * Makes a conversion type to convert from the operand_type to the value_type. * If the value_type has expression_kind, it chains operand_type.value_type() * into value_type.storage_type(). */ inline ndt::type make_convert(const ndt::type& value_type, const ndt::type& operand_type, assign_error_mode errmode = assign_error_default) { if (operand_type.value_type() != value_type) { if (value_type.get_kind() != expression_kind) { // Create a conversion type when the value kind is different return ndt::type(new convert_type(value_type, operand_type, errmode), false); } else if (value_type.storage_type() == operand_type.value_type()) { // No conversion required at the connection return static_cast<const base_expression_type *>( value_type.extended())->with_replaced_storage_type(operand_type); } else { // A conversion required at the connection return static_cast<const base_expression_type *>( value_type.extended())->with_replaced_storage_type( ndt::type(new convert_type( value_type.storage_type(), operand_type, errmode), false)); } } else { return operand_type; } }
size_t cstruct_type::make_comparison_kernel( ckernel_builder *out, size_t offset_out, const ndt::type& src0_tp, const char *src0_metadata, const ndt::type& src1_tp, const char *src1_metadata, comparison_type_t comptype, const eval::eval_context *ectx) const { if (this == src0_tp.extended()) { if (*this == *src1_tp.extended()) { return make_struct_comparison_kernel(out, offset_out, src0_tp, src0_metadata, src1_metadata, comptype, ectx); } else if (src1_tp.get_kind() == struct_kind) { return make_general_struct_comparison_kernel(out, offset_out, src0_tp, src0_metadata, src1_tp, src1_metadata, comptype, ectx); } } throw not_comparable_error(src0_tp, src1_tp, comptype); }
size_t dynd::make_tuple_identical_assignment_kernel( void *ckb, intptr_t ckb_offset, const ndt::type &val_tup_tp, const char *dst_arrmeta, const char *src_arrmeta, kernel_request_t kernreq, const eval::eval_context *ectx) { if (val_tup_tp.get_kind() != tuple_kind && val_tup_tp.get_kind() != struct_kind) { stringstream ss; ss << "make_tuple_identical_assignment_kernel: provided type " << val_tup_tp << " is not of tuple or struct kind"; throw runtime_error(ss.str()); } if (val_tup_tp.is_pod()) { // For POD structs, get a trivial memory copy kernel return make_pod_typed_data_assignment_kernel( ckb, ckb_offset, val_tup_tp.get_data_size(), val_tup_tp.get_data_alignment(), kernreq); } auto sd = val_tup_tp.extended<ndt::base_tuple_type>(); intptr_t field_count = sd->get_field_count(); const uintptr_t *arrmeta_offsets = sd->get_arrmeta_offsets_raw(); shortvector<const char *> dst_fields_arrmeta(field_count); for (intptr_t i = 0; i != field_count; ++i) { dst_fields_arrmeta[i] = dst_arrmeta + arrmeta_offsets[i]; } shortvector<const char *> src_fields_arrmeta(field_count); for (intptr_t i = 0; i != field_count; ++i) { src_fields_arrmeta[i] = src_arrmeta + arrmeta_offsets[i]; } return make_tuple_unary_op_ckernel( nd::copy::get().get(), nd::copy::get().get_type(), ckb, ckb_offset, field_count, sd->get_data_offsets(dst_arrmeta), sd->get_field_types_raw(), dst_fields_arrmeta.get(), sd->get_data_offsets(src_arrmeta), sd->get_field_types_raw(), src_fields_arrmeta.get(), kernreq, ectx); }