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"); } }
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"); } }
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(); }
inline bool operator!=(const memory_block_data *memblock, const memory_block_ptr& rhs) { return memblock != rhs.get(); }