def codegen(context, builder, signature, args): buffers = builder_buffers[builder] # TODO: using stdlib `free` that works only for CPU. For CUDA # devices, we need to use omniscidb provided deallocator. target_info = TargetInfo() try: free_buffer_fn_name = target_info.info['fn_free_buffer'] except KeyError as msg: raise UnsupportedError(f'{target_info} does not provide {msg}') free_buffer_fnty = llvm_ir.FunctionType(void_t, [int8_t.as_pointer()]) free_buffer_fn = irutils.get_or_insert_function( builder.module, free_buffer_fnty, free_buffer_fn_name) if isinstance(value_to_keep_alive, BufferPointer): # free all the buffers apart value_to_keep_alive [keep_alive] = args keep_alive_ptr = builder.load( builder.gep(keep_alive, [int32_t(0), int32_t(0)])) keep_alive_ptr = builder.bitcast(keep_alive_ptr, int8_t.as_pointer()) for ptr8 in buffers: with builder.if_then( builder.icmp_signed('!=', keep_alive_ptr, ptr8)): builder.call(free_buffer_fn, [ptr8]) else: # free all the buffers unconditionally for ptr8 in buffers: builder.call(free_buffer_fn, [ptr8]) del builder_buffers[builder]
def _cg_fflush(builder): int8_t = ir.IntType(8) fflush_fnty = ir.FunctionType(int32_t, [int8_t.as_pointer()]) fflush_fn = irutils.get_or_insert_function(builder.module, fflush_fnty, name="fflush") builder.call(fflush_fn, [int8_t.as_pointer()(None)])
def codegen(context, builder, signature, args): assert len(args) == 2 arg_a, arg_b = args int64_t = ir.IntType(64) fntype = ir.FunctionType(int64_t, [int64_t, int64_t]) fn = irutils.get_or_insert_function(builder.module, fntype, name="_rbclib_add_ints") return builder.call(fn, [arg_a, arg_b])
def codegen(context, builder, sig, args): mgr_ptr, num_rows_arg = args mgr_i8ptr = builder.bitcast(mgr_ptr, i8p) fnty = ir.FunctionType(ir.VoidType(), [i8p, i64]) fn = irutils.get_or_insert_function( builder.module, fnty, "TableFunctionManager_set_output_row_size") builder.call(fn, [mgr_i8ptr, num_rows_arg])
def codegen(context, builder, sig, args): target_info = TargetInfo() if target_info.software[1][:3] < (5, 7, 0): msg = 'set_output_row_size is only available in OmniSciDB 5.7 or newer' raise UnsupportedError(msg) fnty = ir.FunctionType(ir.VoidType(), [ir.IntType(64)]) fn = irutils.get_or_insert_function(builder.module, fnty, name="set_output_row_size") assert fn.is_declaration builder.call(fn, args) # don't return anything
def codegen(context, builder, sig, args): int8ptr = ir.PointerType(ir.IntType(8)) fntype = ir.FunctionType(ir.IntType(32), [int8ptr]) fn = irutils.get_or_insert_function(builder.module, fntype, name="table_function_error") assert fn.is_declaration # msg_bytes = message.literal_value.encode('utf-8') msg_const = make_bytearray(msg_bytes + b'\0') msg_global_var = global_constant(builder.module, "table_function_error_message", msg_const) msg_ptr = builder.bitcast(msg_global_var, int8ptr) return builder.call(fn, [msg_ptr])
def codegen(context, builder, signature, args): # TODO: using stdlib `free` that works only for CPU. For CUDA # devices, we need to use omniscidb provided deallocator. target_info = TargetInfo() free_buffer_fn_name = target_info.info['fn_free_buffer'] free_buffer_fnty = llvm_ir.FunctionType(void_t, [int8_t.as_pointer()]) free_buffer_fn = irutils.get_or_insert_function( builder.module, free_buffer_fnty, free_buffer_fn_name) [buf] = args buf_ptr = builder.load(builder.gep( buf, [int32_t(0), int32_t(0)])) # buf.ptr buf_ptr = builder.bitcast(buf_ptr, int8_t.as_pointer()) builder.call(free_buffer_fn, [buf_ptr])
def omnisci_buffer_constructor(context, builder, sig, args): """ Usage: extending.lower_builtin(MyBuffer, numba.types.Integer, ...)(omnisci_buffer_constructor) will enable creating MyBuffer instance from a Omnisci UDF/UDTF definition: b = MyBuffer(<size>, ...) """ target_info = TargetInfo() try: alloc_fn_name = target_info.info['fn_allocate_varlen_buffer'] except KeyError as msg: raise UnsupportedError(f'{target_info} does not provide {msg}') ptr_type, sz_type = sig.return_type.dtype.members[:2] if len(sig.return_type.dtype.members) > 2: assert len(sig.return_type.dtype.members) == 3 null_type = sig.return_type.dtype.members[2] else: null_type = None assert isinstance(args[0].type, ir.IntType), (args[0].type) element_count = builder.zext(args[0], int64_t) element_size = int64_t(ptr_type.dtype.bitwidth // 8) alloc_fnty = ir.FunctionType(int8_t.as_pointer(), [int64_t, int64_t]) alloc_fn = irutils.get_or_insert_function(builder.module, alloc_fnty, alloc_fn_name) ptr8 = builder.call(alloc_fn, [element_count, element_size]) # remember possible temporary allocations so that when leaving a # UDF/UDTF, these will be deallocated, see pipeline.py. builder_buffers[builder].append(ptr8) ptr = builder.bitcast(ptr8, context.get_value_type(ptr_type)) fa = cgutils.create_struct_proxy(sig.return_type.dtype)(context, builder) fa.ptr = ptr # T* fa.sz = element_count # size_t if null_type is not None: is_zero = builder.icmp_signed('==', element_count, int64_t(0)) with builder.if_else(is_zero) as (then, orelse): with then: is_null = context.get_value_type(null_type)(1) with orelse: is_null = context.get_value_type(null_type)(0) fa.is_null = is_null # int8_t return fa._getpointer()
def codegen(context, builder, signature, args): mgr_ptr = args[0] mgr_i8ptr = builder.bitcast(mgr_ptr, i8p) msg_bytes = msg.literal_value.encode('utf-8') msg_const = make_bytearray(msg_bytes + b'\0') msg_global_var = global_constant( builder.module, "table_function_manager_error_message", msg_const) msg_ptr = builder.bitcast(msg_global_var, i8p) fnty = ir.FunctionType(i32, [i8p, i8p]) fn = irutils.get_or_insert_function( builder.module, fnty, "TableFunctionManager_error_message") return builder.call(fn, [mgr_i8ptr, msg_ptr])