コード例 #1
0
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);
}
コード例 #2
0
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);
}
コード例 #3
0
ファイル: datetime_type.cpp プロジェクト: pombredanne/libdynd
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());
}
コード例 #4
0
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());
    }
}
コード例 #5
0
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());
  }
}
コード例 #6
0
ファイル: string_type.cpp プロジェクト: garaud/libdynd
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);
}
コード例 #7
0
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);
}
コード例 #8
0
ファイル: cstruct_type.cpp プロジェクト: pombredanne/libdynd
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());
}
コード例 #9
0
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);
}
コード例 #10
0
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);
}
コード例 #11
0
ファイル: outer.hpp プロジェクト: jonathandedwards/libdynd
    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;
        }
    }
コード例 #12
0
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);
}
コード例 #13
0
ファイル: json_formatter.cpp プロジェクト: garaud/libdynd
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());
        }
    }
}
コード例 #14
0
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());
  }
}
コード例 #15
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());
  }
}
コード例 #16
0
ファイル: view_type.hpp プロジェクト: aterrel/libdynd
 /**
  * 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));
     }
 }
コード例 #17
0
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());
}
コード例 #18
0
ファイル: callable.cpp プロジェクト: jonathandedwards/libdynd
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);
}
コード例 #19
0
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;
    }
}
コード例 #20
0
ファイル: json_parser.cpp プロジェクト: Laeeth/libdynd
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());
}
コード例 #21
0
ファイル: base_memory_type.hpp プロジェクト: aterrel/libdynd
 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());
   }
 }
コード例 #22
0
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());
    }
}
コード例 #23
0
ファイル: type_alignment.cpp プロジェクト: will133/libdynd
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;
  }
}
コード例 #24
0
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;
  }
}
コード例 #25
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());
}
コード例 #26
0
ファイル: json_parser.cpp プロジェクト: talumbau/libdynd
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());
        }
    }
}
コード例 #27
0
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;
}
コード例 #28
0
ファイル: convert_type.hpp プロジェクト: pombredanne/libdynd
 /**
  * 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;
     }
 }
コード例 #29
0
ファイル: cstruct_type.cpp プロジェクト: pombredanne/libdynd
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);
}
コード例 #30
0
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);
}