Exemplo 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());
        }
    }
}
Exemplo n.º 2
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());
}
Exemplo n.º 3
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)
 {
 }
Exemplo n.º 4
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)
{
}
Exemplo n.º 5
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");
    }
}
Exemplo n.º 6
0
/**
 * Scans through the types, and tries to view data
 * for 'tp'/'metadata' as 'view_tp'. For this to be
 * possible, one must be able to construct
 * metadata for 'tp' corresponding to the same data.
 *
 * \param tp  The type of the data.
 * \param metadata  The array metadata of the data.
 * \param view_tp  The type the data should be viewed as.
 * \param view_metadata The array metadata 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 *metadata,
                     const ndt::type &view_tp, char *view_metadata,
                     dynd::memory_block_data *embedded_reference)
{
    switch (tp.get_type_id()) {
    case strided_dim_type_id: {
        const strided_dim_type *sdt =
            static_cast<const strided_dim_type *>(tp.extended());
        const strided_dim_type_metadata *md =
            reinterpret_cast<const strided_dim_type_metadata *>(metadata);
        switch (view_tp.get_type_id()) {
        case strided_dim_type_id: { // strided as strided
            const strided_dim_type *view_sdt =
                static_cast<const strided_dim_type *>(view_tp.extended());
            strided_dim_type_metadata *view_md =
                reinterpret_cast<strided_dim_type_metadata *>(view_metadata);
            if (try_view(sdt->get_element_type(),
                         metadata + sizeof(strided_dim_type_metadata),
                         view_sdt->get_element_type(),
                         view_metadata + sizeof(strided_dim_type_metadata),
                         embedded_reference)) {
                view_md->size = md->size;
                view_md->stride = md->stride;
                return true;
            } else {
                return false;
            }
        }
        case fixed_dim_type_id: { // strided as fixed
            const fixed_dim_type *view_fdt =
                static_cast<const fixed_dim_type *>(view_tp.extended());
            // The size and stride must match exactly in this case
            if (md->size != (intptr_t)view_fdt->get_fixed_dim_size() ||
                    md->stride != view_fdt->get_fixed_stride()) {
                return false;
            }
            return try_view(sdt->get_element_type(),
                            metadata + sizeof(strided_dim_type_metadata),
                            view_fdt->get_element_type(), view_metadata,
                            embedded_reference);
        }
        default: // other cases cannot be handled
            return false;
        }
    }
    case fixed_dim_type_id: {
        const fixed_dim_type *fdt =
            static_cast<const fixed_dim_type *>(tp.extended());
        switch (view_tp.get_type_id()) {
        case fixed_dim_type_id: { // fixed as fixed
            const fixed_dim_type *view_fdt =
                static_cast<const fixed_dim_type *>(view_tp.extended());
            // The size and stride must match exactly in this case
            if (fdt->get_fixed_dim_size() != view_fdt->get_fixed_dim_size() ||
                    fdt->get_fixed_stride() != view_fdt->get_fixed_stride()) {
                return false;
            }
            return try_view(fdt->get_element_type(), metadata,
                            view_fdt->get_element_type(), view_metadata,
                            embedded_reference);
        }
        case strided_dim_type_id: { // fixed as strided
            const strided_dim_type *view_sdt =
                static_cast<const strided_dim_type *>(view_tp.extended());
            strided_dim_type_metadata *view_md =
                reinterpret_cast<strided_dim_type_metadata *>(view_metadata);
            if (try_view(fdt->get_element_type(), metadata,
                         view_sdt->get_element_type(),
                         view_metadata + sizeof(strided_dim_type_metadata),
                         embedded_reference)) {
                view_md->size = fdt->get_fixed_dim_size();
                view_md->stride = fdt->get_fixed_stride();
                return true;
            } else {
                return false;
            }

        }
        default: // other cases cannot be handled
            return false;
        }
        }
    default: // require equal types otherwise
        if (tp == view_tp) {
            if (tp.get_metadata_size() > 0) {
                tp.extended()->metadata_copy_construct(view_metadata, metadata,
                                                       embedded_reference);
            }
            return true;
        } else {
            return false;
        }
    }
}