Пример #1
0
    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;
        }
    }
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #6
0
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);
}
Пример #8
0
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);
}
Пример #9
0
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;
}
Пример #10
0
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());
    }
}
Пример #11
0
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);
}
Пример #12
0
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());
}
Пример #13
0
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);
  }
}
Пример #14
0
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());
}
Пример #15
0
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());
}
Пример #16
0
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);
}
Пример #17
0
    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;
        }
    }
Пример #18
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);
}
Пример #19
0
/**
 * 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);
}
Пример #20
0
 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);
     }
 }
Пример #21
0
 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)
 {
 }
Пример #22
0
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");
    }
}
Пример #23
0
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));
}
Пример #24
0
 /**
  * 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);
}
Пример #26
0
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));
  }
}
Пример #27
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());
  }
}
Пример #28
0
 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);
     }
 }
Пример #29
0
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;
}
Пример #30
0
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(']');
}