예제 #1
0
inline void convert_one_string(pyunicode_string_ptrs *out, PyObject *obj, const memory_block_ptr& dst_memblock)
{
    if (PyString_Check(obj)) {
        char *data = NULL;
        Py_ssize_t len = 0;
        if (PyString_AsStringAndSize(obj, &data, &len) < 0) {
            throw runtime_error("Error getting string data");
        }

        memory_block_pod_allocator_api *allocator = get_memory_block_pod_allocator_api(dst_memblock.get());
        allocator->allocate(dst_memblock.get(), len * Py_UNICODE_SIZE,
                        Py_UNICODE_SIZE, (char **)&out->begin, (char **)&out->end);
        for (Py_ssize_t i = 0; i < len; ++i) {
            out->begin[i] = data[i];
        }
    } else if (PyUnicode_Check(obj)) {
        const char *data = reinterpret_cast<const char *>(PyUnicode_AsUnicode(obj));
        Py_ssize_t len = PyUnicode_GetSize(obj);
        if (data == NULL || len == -1) {
            throw runtime_error("Error getting unicode string data");
        }
        memory_block_pod_allocator_api *allocator = get_memory_block_pod_allocator_api(dst_memblock.get());
        allocator->allocate(dst_memblock.get(), len * Py_UNICODE_SIZE,
                        Py_UNICODE_SIZE, (char **)&out->begin, (char **)&out->end);
        memcpy(out->begin, data, len * Py_UNICODE_SIZE);
    } else {
        throw runtime_error("wrong kind of string provided");
    }
}
예제 #2
0
inline void convert_one_string(ascii_string_ptrs *out, PyObject *obj, const memory_block_ptr& dst_memblock)
{
    if (PyString_Check(obj)) {
        char *data = NULL;
        intptr_t len = 0;
        if (PyString_AsStringAndSize(obj, &data, &len) < 0) {
            throw runtime_error("Error getting string data");
        }

        memory_block_pod_allocator_api *allocator = get_memory_block_pod_allocator_api(dst_memblock.get());
        allocator->allocate(dst_memblock.get(), len, 1, &out->begin, &out->end);
        memcpy(out->begin, data, len);
    } else {
        throw runtime_error("wrong kind of string provided");
    }
}
예제 #3
0
static ndarray_node_ptr initialize_dst_memblock(bool copy, const ndt::type& dst_tp, int ndim, const intptr_t *shape,
                    const int *axis_perm, uint32_t access_flags,
                    KernelType& operation,
                    const memory_block_ptr& src_data_memblock,
                    memory_block_ptr& out_dst_memblock, char *&out_originptr)
{
    ndarray_node_ptr result;

    if (dst_dt.get_memory_management() != blockref_memory_management) {
        result = make_strided_ndarray_node(dst_tp, ndim, shape, axis_perm,
                            access_flags, NULL, NULL);
        // 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
        out_originptr = const_cast<char *>(result->get_readonly_originptr());
    } else {
        auxdata_kernel_api *api = operation.auxdata.get_kernel_api();
        if (!copy && api->supports_referencing_src_memory_blocks(operation.auxdata)) {
            // If the kernel can reference existing memory, add a blockref to the src data
            result = make_strided_ndarray_node(dst_tp, ndim, shape, axis_perm,
                            access_flags, &src_data_memblock, &src_data_memblock + 1);
            // 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
            out_originptr = const_cast<char *>(result->get_readonly_originptr());
        } else {
            // Otherwise allocate a new memory block for the destination
            out_dst_memblock = make_pod_memory_block();
            api->set_dst_memory_block(operation.auxdata, out_dst_memblock.get());
            result = make_strided_ndarray_node(dst_tp, ndim, shape, axis_perm,
                            access_flags, &out_dst_memblock, &out_dst_memblock + 1);
            // 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
            out_originptr = const_cast<char *>(result->get_readonly_originptr());
        }
    }

    return DYND_MOVE(result);
}
unary_operation_pair_t dynd::codegen_unary_function_adapter(const memory_block_ptr& exec_mem_block,
                                                  const ndt::type& restype,
                                                  const ndt::type& arg0type,
                                                  calling_convention_t DYND_UNUSED(callconv)
                                                 )
{
    size_t arg0_idx = idx_for_type_id(arg0type.get_type_id());
    size_t ret_idx  = idx_for_type_id(restype.get_type_id());

    if (arg0_idx >= sizeof(arg0_snippets)/sizeof(arg0_snippets[0])
        || ret_idx >= sizeof(ret_snippets)/sizeof(ret_snippets[0]))
    {
        return unary_operation_pair_t();
    }

    // an (over)estimation of the size of the generated function. 64 is an
    // overestimation of the code that gets chosen based on args and ret value.
    // that is
    size_t estimated_size = sizeof(unary_adapter_prolog)
                          + sizeof(unary_adapter_loop_setup)
                          + sizeof(unary_adapter_function_call)
                          + sizeof(unary_adapter_loop_finish)
                          + sizeof(unary_adapter_epilog)
                          + 64;

    size_t entry_point= 0;
    size_t loop_start = 0;
    size_t loop_end   = 0;
    size_t table      = 0;
    function_builder fbuilder(exec_mem_block.get(), estimated_size);
    fbuilder.label(entry_point)
            .append(unary_adapter_prolog, sizeof(unary_adapter_prolog))
            .append(unary_adapter_loop_setup, sizeof(unary_adapter_loop_setup))
            .label(loop_start)
            .append(arg0_snippets[arg0_idx].ptr, arg0_snippets[arg0_idx].size)
            .append(unary_adapter_function_call, sizeof(unary_adapter_function_call))
            .append(ret_snippets[ret_idx].ptr, ret_snippets[ret_idx].size)
            .append(unary_adapter_update_streams, sizeof(unary_adapter_update_streams))
            .append(unary_adapter_loop_finish, sizeof(unary_adapter_loop_finish))
            .label(loop_end)
            .append(unary_adapter_epilog, sizeof(unary_adapter_epilog))
            .align(4)
            .label(table);

    if (fbuilder.is_ok())
    {
        // fix-up the offset of the jump closing the loop
        int loop_size = loop_end - loop_start;
        void* base    = fbuilder.base();

        assert(loop_size > 0 && loop_size < 128);
        char* loop_continue_offset = static_cast<char*>(ptr_offset(base, loop_end)) - 1;
        *loop_continue_offset = - loop_size;
        
        //unary_single_operation_deprecated_t func_ptr = reinterpret_cast<unary_single_operation_deprecated_t>(ptr_offset(base, entry_point));

        fbuilder.finish();

        throw std::runtime_error("TODO: dynd::codegen_unary_function_adapter needs fixing for updated kernel prototype");
        //return specializations;
    }

    // function construction failed.. fbuilder destructor will take care of
    // releasing memory (it acts as RAII, kind of -- exception safe as well)
    return unary_operation_pair_t();
}
예제 #5
0
inline bool operator!=(const memory_block_data *memblock, const memory_block_ptr& rhs)
{
    return memblock != rhs.get();
}