Ejemplo n.º 1
0
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());
        }
    }
}
Ejemplo n.º 2
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));
  }
}
Ejemplo n.º 3
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)
{
}
Ejemplo n.º 4
0
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");
    }
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
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());
    }
}
Ejemplo n.º 7
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));
}
 objectarray_memory_block(const ndt::type &dt, size_t arrmeta_size, const char *arrmeta, intptr_t stride,
                          intptr_t initial_count)
     : m_dt(dt), arrmeta_size(arrmeta_size), m_arrmeta(arrmeta), m_stride(stride), m_total_allocated_count(0),
       m_finalized(false), m_memory_handles() {
   if ((dt.get_flags() & type_flag_destructor) == 0) {
     std::stringstream ss;
     ss << "Cannot create objectarray memory block with dynd type " << dt;
     ss << " because it does not have a destructor, use a POD memory block instead";
     throw std::runtime_error(ss.str());
   }
   append_memory(initial_count);
 }
Ejemplo n.º 9
0
 ~buffer_storage()
 {
   if (m_storage && m_type.get_flags()&type_flag_destructor) {
     m_type.extended()->data_destruct_strided(m_arrmeta, m_storage, m_stride,
                                              DYND_BUFFER_CHUNK_SIZE);
   }
   delete[] m_storage;
   if (m_arrmeta) {
     m_type.extended()->arrmeta_destruct(m_arrmeta);
     delete[] m_arrmeta;
   }
 }
    char *resize(char *previous_allocated, size_t count) {
      memory_chunk *mc = &m_memory_handles.back();
      size_t previous_index = (previous_allocated - mc->memory) / m_stride;
      size_t previous_count = mc->used_count - previous_index;
      char *result = previous_allocated;

      if (mc->capacity_count - previous_index < count) {
        append_memory(std::max(m_total_allocated_count, count));
        memory_chunk *new_mc = &m_memory_handles.back();
        // Move the old memory to the newly allocated block
        if (previous_count > 0) {
          // Subtract the previously used memory from the old chunk's count
          mc->used_count -= previous_count;
          memcpy(new_mc->memory, previous_allocated, previous_count);
          // If the old memory only had the memory being resized,
          // free it completely.
          if (previous_allocated == mc->memory) {
            free(mc->memory);
            // Remove the second-last element of the vector
            m_memory_handles.erase(m_memory_handles.begin() + m_memory_handles.size() - 2);
          }
        }
        mc = &m_memory_handles.back();
        result = mc->memory;
        mc->used_count = count;
      } else {
        // Adjust the used count (this may mean to grow it or shrink it)
        if (count >= previous_count) {
          mc->used_count += (count - previous_count);
        } else {
          // Call the destructor on the elements no longer used
          m_dt.extended()->data_destruct_strided(m_arrmeta + arrmeta_size, previous_allocated + m_stride * count,
                                                 m_stride, previous_count - count);
          mc->used_count -= (previous_count - count);
        }
      }

      if ((m_dt.get_flags() & type_flag_zeroinit) != 0) {
        // Zero-init the new memory
        intptr_t new_count = count - (intptr_t)previous_count;
        if (new_count > 0) {
          memset(mc->memory + m_stride * previous_count, 0, m_stride * new_count);
        }
      } else {
        // TODO: Add a default data constructor to base_type
        //       as well, with a flag for it
        std::stringstream ss;
        ss << "Expected objectarray data to be zeroinit, but is not with dynd type " << m_dt;
        throw std::runtime_error(ss.str());
      }
      return result;
    }
Ejemplo n.º 11
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());
    }
}
Ejemplo n.º 12
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);
}
    char *alloc(size_t count) {
      //    cout << "allocating " << size_bytes << " of memory with alignment " << alignment << endl;
      // Allocate new POD memory of the requested size and alignment
      memory_chunk *mc = &m_memory_handles.back();
      if (mc->capacity_count - mc->used_count < count) {
        append_memory(std::max(m_total_allocated_count, count));
        mc = &m_memory_handles.back();
      }

      char *result = mc->memory + m_stride * mc->used_count;
      mc->used_count += count;
      if ((m_dt.get_flags() & type_flag_zeroinit) != 0) {
        memset(result, 0, m_stride * count);
      } else {
        // TODO: Add a default data constructor to base_type
        //       as well, with a flag for it
        std::stringstream ss;
        ss << "Expected objectarray data to be zeroinit, but is not with dynd type " << m_dt;
        throw std::runtime_error(ss.str());
      }
      return result;
    }
Ejemplo n.º 14
0
cuda_host_type::cuda_host_type(const ndt::type& storage_tp, unsigned int cuda_host_flags)
    : base_memory_type(cuda_host_type_id, storage_tp, storage_tp.get_data_size(),
                       get_cuda_device_data_alignment(storage_tp), 0, storage_tp.get_flags()),
      m_cuda_host_flags(cuda_host_flags)
{
}
ndt::cuda_device_type::cuda_device_type(type_id_t id, const ndt::type &element_tp)
    : base_memory_type(id, element_tp, element_tp.get_data_size(), get_cuda_device_data_alignment(element_tp), 0,
                       element_tp.get_flags() | type_flag_not_host_readable) {}
Ejemplo n.º 16
0
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();
}