def omnisci_buffer_idx_set_null(typingctx, arr, row_idx): T = arr.eltype sig = types.none(arr, row_idx) target_info = TargetInfo() null_value = target_info.null_values[f'{T}'] # The server sends numbers as unsigned values rather than signed ones. # Thus, 129 should be read as -127 (overflow). See rbc issue #254 bitwidth = T.bitwidth null_value = np.dtype(f'uint{bitwidth}').type(null_value).view( f'int{bitwidth}') def codegen(context, builder, signature, args): # get the operator.setitem intrinsic fnop = context.typing_context.resolve_value_type( omnisci_buffer_ptr_setitem_) setitem_sig = types.none(arr, row_idx, T) # register the intrinsic in the typing ctx fnop.get_call_type(context.typing_context, setitem_sig.args, {}) intrinsic = context.get_function(fnop, setitem_sig) data, index = args # data = {T*, i64, i8}* ty = data.type.pointee.elements[0].pointee nv = ir.Constant(ir.IntType(T.bitwidth), null_value) if isinstance(T, types.Float): nv = builder.bitcast(nv, ty) intrinsic(builder, ( data, index, nv, )) return sig, codegen
def resolve_getattr(tyctx, obj, name, default): if not isinstance(name, types.StringLiteral): raise RequireLiteralValue("argument 'name' must be a literal string") lname = name.literal_value fn = tyctx.resolve_getattr(obj, lname) # Cannot handle things like `getattr(np, 'cos')` as the return type is # types.Function. if isinstance(fn, types.Function): msg = ("Returning function objects is not implemented. " f"getattr() was requested to return {fn} from attribute " f"'{lname}' of {obj}.") raise TypingError(msg) if fn is None: # No attribute # if default is not _getattr_default then return the default if not (isinstance(default, types.NamedTuple) and default.instance_class == _getattr_default_type): # it's not the marker default value, so return it sig = default(obj, name, default) def impl(cgctx, builder, sig, llargs): tmp = llargs[-1] cgctx.nrt.incref(builder, default, tmp) return tmp else: # else wire in raising an AttributeError fnty = tyctx.resolve_value_type(_getattr_raise_attr_exc) raise_sig = fnty.get_call_type(tyctx, (obj, name), {}) sig = types.none(obj, name, default) def impl(cgctx, builder, sig, llargs): native_impl = cgctx.get_function(fnty, raise_sig) return native_impl(builder, llargs[:-1]) else: # Attribute present, wire in handing it back to the overload(getattr) sig = fn(obj, name, default) if isinstance(fn, types.BoundFunction): # It's a method on an object def impl(cgctx, builder, sig, ll_args): cast_type = fn.this casted = cgctx.cast(builder, ll_args[0], obj, cast_type) res = cgctx.get_bound_function(builder, casted, cast_type) cgctx.nrt.incref(builder, fn, res) return res else: # Else it's some other type of attribute. # Ensure typing calls occur at typing time, not at lowering attrty = tyctx.resolve_getattr(obj, lname) def impl(cgctx, builder, sig, ll_args): attr_impl = cgctx.get_getattr(obj, lname) res = attr_impl(cgctx, builder, obj, ll_args[0], lname) casted = cgctx.cast(builder, res, attrty, fn) cgctx.nrt.incref(builder, fn, casted) return casted return sig, impl
def omnisci_buffer_set_null_(typingctx, data): sig = types.none(data) def codegen(context, builder, sig, args): rawptr = cgutils.alloca_once_value(builder, value=args[0]) ptr = builder.load(rawptr) builder.store(int8_t(1), builder.gep(ptr, [int32_t(0), int32_t(2)])) return sig, codegen
def impl(cgctx, builder, sig, args): lld, = args impl = cgctx.get_function('static_getitem', types.none(d, types.literal('dummy'))) items = [] for k in range(len(keys)): item = impl(builder, (lld, k),) casted = cgctx.cast(builder, item, literal_tys[k], d.types[k]) items.append(casted) cgctx.nrt.incref(builder, d.types[k], item) ret = cgctx.make_tuple(builder, sig.return_type, items) return ret
def omnisci_buffer_setitem_(typingctx, data, index, value): sig = types.none(data, index, value) eltype = data.members[0].dtype nb_value = value def codegen(context, builder, signature, args): data, index, value = args ptr = irutils.get_member_value(builder, data, 0) value = truncate_or_extend(builder, nb_value, eltype, value, ptr.type.pointee) builder.store(value, builder.gep(ptr, [index])) return sig, codegen
def codegen(context, builder, signature, args): # get the operator.setitem intrinsic fnop = context.typing_context.resolve_value_type(omnisci_buffer_ptr_setitem_) setitem_sig = types.none(arr, row_idx, T) # register the intrinsic in the typing ctx fnop.get_call_type(context, setitem_sig.args, {}) intrinsic = context.get_function(fnop, setitem_sig) data, index = args # data = {T*, i64, i8}* ty = data.type.pointee.elements[0].pointee nv = ir.Constant(ir.IntType(T.bitwidth), null_value) if isinstance(T, types.Float): nv = builder.bitcast(nv, ty) intrinsic(builder, (data, index, nv,))
def omnisci_array_setitem_(typingctx, data, index, value): sig = types.none(data, index, value) def codegen(context, builder, signature, args): zero = int32_t(0) data, index, value = args rawptr = cgutils.alloca_once_value(builder, value=data) ptr = builder.load(rawptr) arr = builder.load(builder.gep(ptr, [zero, zero])) builder.store(value, builder.gep(arr, [index])) return sig, codegen
def impl(cgctx, builder, sig, args): lld, = args impl = cgctx.get_function('static_getitem', types.none(d, types.literal('dummy'))) items = [] for k in range(len(keys)): item = impl(builder, (lld, k),) casted = cgctx.cast(builder, item, literal_tys[k], d.types[k]) cgctx.nrt.incref(builder, d.types[k], item) keydata = make_string_from_constant(cgctx, builder, types.unicode_type, keys[k].literal_value) pair = cgctx.make_tuple(builder, types.Tuple([types.unicode_type, d.types[k]]), (keydata, casted)) items.append(pair) ret = cgctx.make_tuple(builder, sig.return_type, items) return ret
def omnisci_buffer_ptr_setitem_(typingctx, data, index, value): sig = types.none(data, index, value) eltype = data.eltype nb_value = value def codegen(context, builder, signature, args): zero = int32_t(0) data, index, value = args rawptr = cgutils.alloca_once_value(builder, value=data) ptr = builder.load(rawptr) buf = builder.load(builder.gep(ptr, [zero, zero])) value = truncate_or_extend(builder, nb_value, eltype, value, buf.type.pointee) builder.store(value, builder.gep(buf, [index])) return sig, codegen
def omnisci_buffer_setitem_(typingctx, data, index, value): sig = types.none(data, index, value) eltype = data.members[0].dtype nb_value = value def codegen(context, builder, signature, args): zero = int32_t(0) data, index, value = args assert data.opname == 'load' buf = data.operands[0] ptr = builder.load(builder.gep(buf, [zero, zero])) value = truncate_or_extend(builder, nb_value, eltype, value, ptr.type.pointee) builder.store(value, builder.gep(ptr, [index])) return sig, codegen
def _get_signature(self, *args): parsed_sig = parse_signature(self.gufunc_builder.signature) # ewise_types is a list of [int32, int32, int32, ...] ewise_types = self._get_ewise_dtypes(args) # first time calling the gufunc # generate a signature based on input arguments l = [] for idx, sig_dim in enumerate(parsed_sig[0]): ndim = len(sig_dim) if ndim == 0: # append scalar l.append(ewise_types[idx]) else: l.append(types.Array(ewise_types[idx], ndim, 'A')) # add return type to signature retty = ewise_types[-1] ret_ndim = len(parsed_sig[-1][0]) or 1 # small hack to return scalar l.append(types.Array(retty, ret_ndim, 'A')) return types.none(*l)