コード例 #1
0
size_t bytes_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()) {
        switch (src_tp.get_type_id()) {
            case bytes_type_id: {
                return make_blockref_bytes_assignment_kernel(ckb, ckb_offset,
                                get_data_alignment(), dst_arrmeta,
                                src_tp.get_data_alignment(), src_arrmeta,
                                kernreq, ectx);
            }
            case fixedbytes_type_id: {
                return make_fixedbytes_to_blockref_bytes_assignment_kernel(ckb, ckb_offset,
                                get_data_alignment(), dst_arrmeta,
                                src_tp.get_data_size(), src_tp.get_data_alignment(),
                                kernreq, ectx);
            }
            default: {
                if (!src_tp.is_builtin()) {
                    src_tp.extended()->make_assignment_kernel(
                        ckb, ckb_offset, dst_tp, dst_arrmeta, src_tp,
                        src_arrmeta, kernreq, ectx);
                }
                break;
            }
        }
    }

    stringstream ss;
    ss << "Cannot assign from " << src_tp << " to " << dst_tp;
    throw runtime_error(ss.str());
}
コード例 #2
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");
    }
}
コード例 #3
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);
}
コード例 #4
0
ファイル: view.cpp プロジェクト: hainm/libdynd
/**
 * Scans through the types, and tries to view data
 * for 'tp'/'arrmeta' as 'view_tp'. For this to be
 * possible, one must be able to construct
 * arrmeta for 'tp' corresponding to the same data.
 *
 * \param tp  The type of the data.
 * \param arrmeta  The array arrmeta of the data.
 * \param view_tp  The type the data should be viewed as.
 * \param view_arrmeta The array arrmeta of the view, which should be populated.
 * \param embedded_reference  The containing memory block in case the data was embedded.
 *
 * \returns If it worked, returns true, otherwise false.
 */
static bool try_view(const ndt::type &tp, const char *arrmeta, const ndt::type &view_tp, char *view_arrmeta,
                     dynd::memory_block_data *embedded_reference)
{
  switch (tp.get_type_id()) {
  case fixed_dim_type_id: {
    // All the strided dim types share the same arrmeta, so can be
    // treated uniformly here
    const ndt::base_dim_type *sdt = tp.extended<ndt::base_dim_type>();
    const fixed_dim_type_arrmeta *md = reinterpret_cast<const fixed_dim_type_arrmeta *>(arrmeta);
    switch (view_tp.get_type_id()) {
    case fixed_dim_type_id: { // strided as fixed
      const ndt::fixed_dim_type *view_fdt = view_tp.extended<ndt::fixed_dim_type>();
      // The size must match exactly in this case
      if (md->dim_size != view_fdt->get_fixed_dim_size()) {
        return false;
      }
      fixed_dim_type_arrmeta *view_md = reinterpret_cast<fixed_dim_type_arrmeta *>(view_arrmeta);
      if (try_view(sdt->get_element_type(), arrmeta + sizeof(fixed_dim_type_arrmeta), view_fdt->get_element_type(),
                   view_arrmeta + sizeof(fixed_dim_type_arrmeta), embedded_reference)) {
        *view_md = *md;
        return true;
      } else {
        return false;
      }
    }
    default: // other cases cannot be handled
      return false;
    }
  }
  default:
    if (tp == view_tp) {
      // require equal types otherwise
      if (tp.get_arrmeta_size() > 0) {
        tp.extended()->arrmeta_copy_construct(view_arrmeta, arrmeta, embedded_reference);
      }
      return true;
    } else if (tp.is_pod() && view_tp.is_pod() && tp.get_data_size() == view_tp.get_data_size() &&
               tp.get_data_alignment() >= view_tp.get_data_alignment()) {
      // POD types with matching properties
      if (view_tp.get_arrmeta_size() > 0) {
        view_tp.extended()->arrmeta_default_construct(view_arrmeta, true);
      }
      return true;
    } else {
      return false;
    }
  }
}
コード例 #5
0
ファイル: expr_type.cpp プロジェクト: garaud/libdynd
expr_type::expr_type(const ndt::type& value_type, const ndt::type& operand_type,
                const expr_kernel_generator *kgen)
    : base_expression_type(expr_type_id, expression_kind,
                        operand_type.get_data_size(), operand_type.get_data_alignment(),
                        inherited_flags(value_type.get_flags(), operand_type.get_flags()),
                        operand_type.get_metadata_size(), value_type.get_ndim()),
                    m_value_type(value_type), m_operand_type(operand_type),
                    m_kgen(kgen)
{
    if (operand_type.get_type_id() != cstruct_type_id) {
        stringstream ss;
        ss << "expr_type can only be constructed with a cstruct as its operand, given ";
        ss << operand_type;
        throw runtime_error(ss.str());
    }
    const cstruct_type *fsd = static_cast<const cstruct_type *>(operand_type.extended());
    size_t field_count = fsd->get_field_count();
    if (field_count == 1) {
        throw runtime_error("expr_type is for 2 or more operands, use unary_expr_type for 1 operand");
    }
    const ndt::type *field_types = fsd->get_field_types();
    for (size_t i = 0; i != field_count; ++i) {
        if (field_types[i].get_type_id() != pointer_type_id) {
            stringstream ss;
            ss << "each field of the expr_type's operand must be a pointer, field " << i;
            ss << " is " << field_types[i];
            throw runtime_error(ss.str());
        }
    }
}
コード例 #6
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);
}
コード例 #7
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);
}
コード例 #8
0
ファイル: adapt_type.cpp プロジェクト: corsy/libdynd
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)
{
}
コード例 #9
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));
  }
}
コード例 #10
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);
}
コード例 #11
0
byteswap_type::byteswap_type(const ndt::type& value_type, const ndt::type& operand_type)
    : base_expr_type(byteswap_type_id, expr_kind, operand_type.get_data_size(),
                    operand_type.get_data_alignment(), type_flag_scalar, 0),
            m_value_type(value_type), m_operand_type(operand_type)
{
    // Only a bytes type be the operand to the byteswap
    if (operand_type.value_type().get_type_id() != fixedbytes_type_id) {
        std::stringstream ss;
        ss << "byteswap_type: The operand to the type must have a value type of bytes, not " << operand_type.value_type();
        throw dynd::type_error(ss.str());
    }
    // Automatically realign if needed
    if (operand_type.value_type().get_data_alignment() < value_type.get_data_alignment()) {
        m_operand_type = ndt::make_view(operand_type,
                        ndt::make_fixedbytes(operand_type.get_data_size(), value_type.get_data_alignment()));
    }
}
コード例 #12
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));
}
コード例 #13
0
unary_expr_type::unary_expr_type(const ndt::type& value_type, const ndt::type& operand_type,
                const expr_kernel_generator *kgen)
    : base_expression_type(unary_expr_type_id, expression_kind,
                        operand_type.get_data_size(), operand_type.get_data_alignment(),
                        inherited_flags(value_type.get_flags(), operand_type.get_flags()),
                        operand_type.get_metadata_size(), value_type.get_ndim()),
                    m_value_type(value_type), m_operand_type(operand_type),
                    m_kgen(kgen)
{
}
コード例 #14
0
void dynd::typed_data_assign(const ndt::type &dst_tp, const char *dst_arrmeta,
                             char *dst_data, const ndt::type &src_tp,
                             const char *src_arrmeta, const char *src_data,
                             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);

  unary_ckernel_builder k;
  make_assignment_kernel(&k, 0, dst_tp, dst_arrmeta, src_tp, src_arrmeta,
                         kernel_request_single, ectx);
  k(dst_data, src_data);
}
コード例 #15
0
ファイル: view_type.cpp プロジェクト: pombredanne/libdynd
view_type::view_type(const ndt::type& value_type, const ndt::type& operand_type)
    : base_expression_type(view_type_id, expression_kind, operand_type.get_data_size(),
                    operand_type.get_data_alignment(),
                    inherited_flags(value_type.get_flags(), operand_type.get_flags()),
                    operand_type.get_metadata_size()),
            m_value_type(value_type), m_operand_type(operand_type)
{
    if (value_type.get_data_size() != operand_type.value_type().get_data_size()) {
        std::stringstream ss;
        ss << "view_type: Cannot view " << operand_type.value_type() << " as " << value_type << " because they have different sizes";
        throw std::runtime_error(ss.str());
    }
    if (!value_type.is_pod()) {
        throw std::runtime_error("view_type: Only POD types are supported");
    }
}
コード例 #16
0
ファイル: typed_data_assign.cpp プロジェクト: Laeeth/libdynd
void dynd::typed_data_assign(const ndt::type &dst_tp, const char *dst_arrmeta,
                             char *dst_data, const ndt::type &src_tp,
                             const char *src_arrmeta, const char *src_data,
                             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);

  ckernel_builder<kernel_request_host> k;
  make_assignment_kernel(&k, 0, dst_tp, dst_arrmeta, src_tp, src_arrmeta,
                         kernel_request_single, ectx);
  expr_single_t fn = k.get()->get_function<expr_single_t>();
  char *src = const_cast<char *>(src_data);
  fn(dst_data, &src, k.get());
}
コード例 #17
0
memory_block_ptr dynd::make_zeroinit_memory_block(const ndt::type &element_tp, intptr_t initial_capacity_bytes)
{
  // This is a temporary hack until the new bytes and string types are working
  size_t data_size;
  switch (element_tp.get_type_id()) {
  case bytes_type_id:
  case string_type_id:
    data_size = 1;
    break;
  default:
    data_size = element_tp.get_default_data_size();
  }

  zeroinit_memory_block *pmb =
      new zeroinit_memory_block(data_size, element_tp.get_data_alignment(), initial_capacity_bytes);
  return memory_block_ptr(reinterpret_cast<memory_block_data *>(pmb), false);
}
コード例 #18
0
ファイル: convert_type.cpp プロジェクト: nevermindewe/libdynd
convert_type::convert_type(const ndt::type &value_type,
                           const ndt::type &operand_type)
    : base_expr_type(
          convert_type_id, expr_kind, operand_type.get_data_size(),
          operand_type.get_data_alignment(),
          inherited_flags(value_type.get_flags(), operand_type.get_flags()),
          operand_type.get_arrmeta_size(), value_type.get_ndim()),
      m_value_type(value_type), m_operand_type(operand_type)
{
    // An alternative to this error would be to use value_type.value_type(), cutting
    // away the expression part of the given value_type.
    if (m_value_type.get_kind() == expr_kind) {
        std::stringstream ss;
        ss << "convert_type: The destination type " << m_value_type;
        ss << " should not be an expr_kind";
        throw dynd::type_error(ss.str());
    }
}
コード例 #19
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;
  }
}
コード例 #20
0
ファイル: view.cpp プロジェクト: hainm/libdynd
static nd::array view_as_bytes(const nd::array &arr, const ndt::type &tp)
{
  if (arr.get_type().get_flags() & type_flag_destructor) {
    // Can't view arrays of object type
    return nd::array();
  }

  // Get the essential components of the array to analyze
  memory_block_ptr data_ref = arr.get_data_memblock();
  char *data_ptr = arr.get_ndo()->data.ptr;
  ndt::type data_tp = arr.get_type();
  const char *data_meta = arr.get_arrmeta();
  intptr_t data_dim_size = -1, data_stride = 0;
  // Repeatedly refine the data
  while (data_tp.get_type_id() != uninitialized_type_id) {
    refine_bytes_view(data_ref, data_ptr, data_tp, data_meta, data_dim_size, data_stride);
  }
  // Check that it worked, and that the resulting data pointer is aligned
  if (data_dim_size < 0 ||
      !offset_is_aligned(reinterpret_cast<size_t>(data_ptr), tp.extended<ndt::bytes_type>()->get_target_alignment())) {
    // This signals we could not view the data as a
    // contiguous chunk of bytes
    return nd::array();
  }

  char *result_data_ptr = NULL;
  nd::array result(make_array_memory_block(tp.extended()->get_arrmeta_size(), tp.get_data_size(),
                                           tp.get_data_alignment(), &result_data_ptr));
  // Set the bytes extents
  ((char **)result_data_ptr)[0] = data_ptr;
  ((char **)result_data_ptr)[1] = data_ptr + data_dim_size;
  // Set the array arrmeta
  array_preamble *ndo = result.get_ndo();
  ndo->m_type = ndt::type(tp).release();
  ndo->data.ptr = result_data_ptr;
  ndo->data.ref = NULL;
  ndo->m_flags = arr.get_flags();
  // Set the bytes arrmeta
  bytes_type_arrmeta *ndo_meta = reinterpret_cast<bytes_type_arrmeta *>(result.get_arrmeta());
  ndo_meta->blockref = data_ref.release();
  return result;
}
コード例 #21
0
fixed_dim_type::fixed_dim_type(size_t dimension_size, const ndt::type& element_tp)
    : base_uniform_dim_type(fixed_dim_type_id, element_tp, 0, element_tp.get_data_alignment(),
                    0, type_flag_none),
            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());
    }
    m_stride = m_dim_size > 1 ? element_tp.get_data_size() : 0;
    m_members.data_size = m_stride * (m_dim_size-1) + child_element_size;
    // Propagate the operand flags from the element
    m_members.flags |= (element_tp.get_flags()&type_flags_operand_inherited);

    // Copy ndobject properties and functions from the first non-array dimension
    get_scalar_properties_and_functions(m_array_properties, m_array_functions);
}
コード例 #22
0
size_t dynd::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)
{
    if (errmode == assign_error_default && ectx != NULL) {
        errmode = ectx->default_errmode;
    }

    if (dst_tp.is_builtin()) {
        if (src_tp.is_builtin()) {
            // If the casting can be done losslessly, disable the error check to find faster code paths
            if (errmode != assign_error_none && is_lossless_assignment(dst_tp, src_tp)) {
                errmode = assign_error_none;
            }

            if (dst_tp.extended() == src_tp.extended()) {
                return make_pod_typed_data_assignment_kernel(out, offset_out,
                                dst_tp.get_data_size(), dst_tp.get_data_alignment(),
                                kernreq);
            } else {
                return make_builtin_type_assignment_kernel(out, offset_out,
                                dst_tp.get_type_id(), src_tp.get_type_id(),
                                kernreq, errmode);
            }
        } else {
            return src_tp.extended()->make_assignment_kernel(out, offset_out,
                            dst_tp, dst_metadata,
                            src_tp, src_metadata,
                            kernreq, errmode, ectx);
        }
    } else {
        return dst_tp.extended()->make_assignment_kernel(out, offset_out,
                        dst_tp, dst_metadata,
                        src_tp, src_metadata,
                        kernreq, errmode, ectx);
    }
}
コード例 #23
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);
}
コード例 #24
0
ファイル: view.cpp プロジェクト: hainm/libdynd
static nd::array view_from_bytes(const nd::array &arr, const ndt::type &tp)
{
  if (tp.get_flags() & (type_flag_blockref | type_flag_destructor | type_flag_not_host_readable)) {
    // Bytes cannot be viewed as blockref types, types which require
    // destruction, or types not on host memory.
    return nd::array();
  }

  const bytes_type_arrmeta *bytes_meta = reinterpret_cast<const bytes_type_arrmeta *>(arr.get_arrmeta());
  bytes_type_data *bytes_d = reinterpret_cast<bytes_type_data *>(arr.get_ndo()->data.ptr);
  memory_block_ptr data_ref;
  if (bytes_meta->blockref != NULL) {
    data_ref = bytes_meta->blockref;
  } else {
    data_ref = arr.get_data_memblock();
  }
  char *data_ptr = bytes_d->begin;
  intptr_t data_size = bytes_d->end - data_ptr;

  size_t tp_data_size = tp.get_data_size();
  if (tp_data_size > 0) {
    // If the data type has a single chunk of POD memory, it's ok
    if ((intptr_t)tp_data_size == data_size &&
        offset_is_aligned(reinterpret_cast<size_t>(data_ptr), tp.get_data_alignment())) {
      // Allocate a result array to attempt the view in it
      nd::array result(make_array_memory_block(tp.get_arrmeta_size()));
      // Initialize the fields
      result.get_ndo()->data.ptr = data_ptr;
      result.get_ndo()->data.ref = data_ref.release();
      result.get_ndo()->m_type = ndt::type(tp).release();
      result.get_ndo()->m_flags = arr.get_ndo()->m_flags;
      if (tp.get_arrmeta_size() > 0) {
        tp.extended()->arrmeta_default_construct(result.get_arrmeta(), true);
      }
      return result;
    }
  } else if (tp.get_type_id() == fixed_dim_type_id) {
    ndt::type arr_tp = tp;
    ndt::type el_tp = arr_tp.extended<ndt::base_dim_type>()->get_element_type();
    size_t el_data_size = el_tp.get_data_size();
    // If the element type has a single chunk of POD memory, and
    // it divides into the memory size, it's ok
    if (data_size % (intptr_t)el_data_size == 0 &&
        offset_is_aligned(reinterpret_cast<size_t>(data_ptr), arr_tp.get_data_alignment())) {
      intptr_t dim_size = data_size / el_data_size;
      if (arr_tp.get_kind() != kind_kind) {
        if (arr_tp.extended<ndt::fixed_dim_type>()->get_fixed_dim_size() != dim_size) {
          return nd::array();
        }
      } else {
        // Transform the symbolic fixed type into a concrete one
        arr_tp = ndt::make_fixed_dim(dim_size, el_tp);
      }
      // Allocate a result array to attempt the view in it
      nd::array result(make_array_memory_block(arr_tp.get_arrmeta_size()));
      // Initialize the fields
      result.get_ndo()->data.ptr = data_ptr;
      result.get_ndo()->data.ref = data_ref.release();
      result.get_ndo()->m_type = ndt::type(arr_tp).release();
      result.get_ndo()->m_flags = arr.get_ndo()->m_flags;
      if (el_tp.get_arrmeta_size() > 0) {
        el_tp.extended()->arrmeta_default_construct(result.get_arrmeta() + sizeof(fixed_dim_type_arrmeta), true);
      }
      fixed_dim_type_arrmeta *fixed_meta = reinterpret_cast<fixed_dim_type_arrmeta *>(result.get_arrmeta());
      fixed_meta->dim_size = dim_size;
      fixed_meta->stride = el_data_size;
      return result;
    }
  }

  // No view could be produced
  return nd::array();
}
コード例 #25
0
size_t dynd::make_expression_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)
{
  intptr_t root_ckb_offset = ckb_offset;
  buffered_kernel_extra *e =
      reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb)
          ->alloc_ck<buffered_kernel_extra>(ckb_offset);
  e->base.function = reinterpret_cast<void *>(&buffered_kernel_extra::kernel);
  e->base.destructor = &buffered_kernel_extra::destruct;
  // Initialize the information for buffering the operands
  if (src0_dt.get_kind() == expr_kind) {
    e->init_buffer(0, src0_dt.value_type());
    e->buf[0].kernel_offset = ckb_offset - root_ckb_offset;
    ckb_offset = make_assignment_kernel(
        ckb, ckb_offset, src0_dt.value_type(), e->buf[0].arrmeta, src0_dt,
        src0_arrmeta, kernel_request_single, ectx);
    // Have to re-retrieve 'e', because creating another kernel may invalidate
    // it
    e = reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb)
            ->get_at<buffered_kernel_extra>(root_ckb_offset);
  }
  if (src1_dt.get_kind() == expr_kind) {
    e->init_buffer(1, src1_dt.value_type());
    e->buf[1].kernel_offset = ckb_offset - root_ckb_offset;
    ckb_offset = make_assignment_kernel(
        ckb, ckb_offset, src1_dt.value_type(), e->buf[1].arrmeta, src1_dt,
        src1_arrmeta, kernel_request_single, ectx);
    // Have to re-retrieve 'e', because creating another kernel may invalidate
    // it
    e = reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb)
            ->get_at<buffered_kernel_extra>(root_ckb_offset);
  }
  // Allocate the data for the buffers
  if (e->buf[0].kernel_offset != 0) {
    ckb_offset = inc_to_alignment(ckb_offset, src0_dt.get_data_alignment());
    e->buf[0].data_offset = ckb_offset - root_ckb_offset;
    ckb_offset += e->buf[0].data_size;
  }
  if (e->buf[1].kernel_offset != 0) {
    ckb_offset = inc_to_alignment(ckb_offset, src1_dt.get_data_alignment());
    e->buf[1].data_offset = ckb_offset - root_ckb_offset;
    ckb_offset += e->buf[1].data_size;
  }
  reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb)
      ->reserve(ckb_offset + sizeof(ckernel_prefix));
  // Have to re-retrieve 'e', because allocating the buffer data may invalidate
  // it
  e = reinterpret_cast<ckernel_builder<kernel_request_host> *>(ckb)
          ->get_at<buffered_kernel_extra>(root_ckb_offset);
  e->cmp_kernel_offset = ckb_offset - root_ckb_offset;
  return make_comparison_kernel(
      ckb, ckb_offset, src0_dt.value_type(),
      (e->buf[0].kernel_offset != 0) ? e->buf[0].arrmeta : src0_arrmeta,
      src1_dt.value_type(),
      (e->buf[1].kernel_offset != 0) ? e->buf[1].arrmeta : src1_arrmeta,
      comptype, ectx);
}
コード例 #26
0
 pod_memory_block(const ndt::type &tp, intptr_t initial_capacity_bytes = 2048)
     : pod_memory_block(tp.get_default_data_size(), tp.get_data_alignment(), initial_capacity_bytes) {}
コード例 #27
0
intrusive_ptr<memory_block_data> dynd::make_pod_memory_block(const ndt::type &tp, intptr_t initial_capacity_bytes)
{
  pod_memory_block *pmb =
      new pod_memory_block(tp.get_default_data_size(), tp.get_data_alignment(), initial_capacity_bytes);
  return intrusive_ptr<memory_block_data>(reinterpret_cast<memory_block_data *>(pmb), false);
}