def get_refcount(typingctx, obj): """Get the current refcount of an object. FIXME: only handles the first object """ def codegen(context, builder, signature, args): [obj] = args [ty] = signature.args # A sequence of (type, meminfo) meminfos = [] if context.enable_nrt: tmp_mis = context.nrt.get_meminfos(builder, ty, obj) meminfos.extend(tmp_mis) refcounts = [] if meminfos: for ty, mi in meminfos: miptr = builder.bitcast(mi, _meminfo_struct_type.as_pointer()) refctptr = cgutils.gep_inbounds(builder, miptr, 0, 0) refct = builder.load(refctptr) refct_32bit = builder.trunc(refct, ir.IntType(32)) refcounts.append(refct_32bit) return refcounts[0] sig = types.int32(obj) return sig, codegen
def non_void_func(typingctx, a): sig = types.int32(types.int32) def codegen(context, builder, signature, args): pass # oops, should be returning a value here, raise exception return sig, codegen
def omnisci_udtfmanager_error_message_(typingctx, mgr, msg): sig = types.int32(mgr, msg) target_info = TargetInfo() if target_info.software[1][:3] < (5, 9, 0): raise UnsupportedError(error_msg % (".".join(map(str, target_info.software[1])))) if not isinstance(msg, types.StringLiteral): raise TypeError(f"expected StringLiteral but got {type(msg).__name__}") 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]) return sig, codegen
def table_function_error(typingctx, message): """ Return an error from a UDTF. ``message`` must be a string literal. """ if not isinstance(message, nb_types.StringLiteral): raise NumbaTypeError(f"expected StringLiteral but got {type(message).__name__}") 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]) sig = nb_types.int32(message) return sig, codegen
def sizeof(typingctx, arg_type): """Return sizeof type.""" if isinstance(arg_type, nb_types.TypeRef): arg_val_type = arg_type.key elif isinstance(arg_type, nb_types.Type): arg_val_type = arg_type else: return sig = nb_types.int32(arg_type) def codegen(context, builder, signature, args): value_type = context.get_value_type(arg_val_type) size = context.get_abi_sizeof(value_type) return ir.Constant(ir.IntType(32), size) return sig, codegen
def test_isinstance_numba_types(self): # This makes use of type aliasing between python scalars and NumPy # scalars, see also test_numba_types() pyfunc = isinstance_usecase_numba_types cfunc = jit(nopython=True)(pyfunc) inputs = ((types.int32(1), 'int32'), (types.int64(2), 'int64'), (types.float32(3.0), 'float32'), (types.float64(4.0), 'float64'), (types.complex64(5j), 'no match'), (typed.List([1, 2]), 'typed list'), (typed.Dict.empty(types.int64, types.int64), 'typed dict')) for inpt, expected in inputs: got = cfunc(inpt) self.assertEqual(expected, got)
import math import warnings from numba.core.imputils import Registry from numba.core import types from numba.core.itanium_mangler import mangle from .hsaimpl import _declare_function registry = Registry() lower = registry.lower # ----------------------------------------------------------------------------- _unary_b_f = types.int32(types.float32) _unary_b_d = types.int32(types.float64) _unary_f_f = types.float32(types.float32) _unary_d_d = types.float64(types.float64) _binary_f_ff = types.float32(types.float32, types.float32) _binary_d_dd = types.float64(types.float64, types.float64) function_descriptors = { 'isnan': (_unary_b_f, _unary_b_d), 'isinf': (_unary_b_f, _unary_b_d), 'ceil': (_unary_f_f, _unary_d_d), 'floor': (_unary_f_f, _unary_d_d), 'fabs': (_unary_f_f, _unary_d_d), 'sqrt': (_unary_f_f, _unary_d_d), 'exp': (_unary_f_f, _unary_d_d), 'expm1': (_unary_f_f, _unary_d_d), 'log': (_unary_f_f, _unary_d_d), 'log10': (_unary_f_f, _unary_d_d),
def float_to_int(x): return types.int32(x)
def _dopileup(start_coords, end_coords, rightmost_coord: int32, scale: float32, baseline: float32): # build pileup # positions -> start positions of the constant region # values -> constant region value real_len = 0 # reserve maxlen aot to save time ends_of_intervals = np.empty(2 * start_coords.size + 1, dtype=np.int32) values = np.empty(2 * start_coords.size + 1, dtype=np.float32) start_idx, end_idx = 0, 0 pileup = int32(0) prev_coord = min(start_coords[start_idx], end_coords[end_idx]) if prev_coord != 0: ends_of_intervals[real_len] = prev_coord values[real_len] = baseline real_len += 1 total_read = start_coords.size while start_idx < total_read and end_idx < total_read: if start_coords[start_idx] < end_coords[end_idx]: coord = start_coords[start_idx] if coord != prev_coord: ends_of_intervals[real_len] = coord values[real_len] = max(pileup * scale, baseline) real_len += 1 prev_coord = coord pileup += 1 start_idx += 1 elif start_coords[start_idx] > end_coords[end_idx]: coord = end_coords[end_idx] if coord != prev_coord: ends_of_intervals[real_len] = coord values[real_len] = max(pileup * scale, baseline) real_len += 1 prev_coord = coord pileup -= 1 end_idx += 1 else: start_idx += 1 end_idx += 1 if end_idx < total_read: for i in range(end_idx, total_read): coord = end_coords[i] if coord != prev_coord: ends_of_intervals[real_len] = coord values[real_len] = max(pileup * scale, baseline) prev_coord = coord real_len += 1 pileup -= 1 assert pileup == 0 # force intervals to occupy all space if ends_of_intervals[real_len - 1] < rightmost_coord: ends_of_intervals[real_len] = rightmost_coord values[real_len] = 0 real_len += 1 assert ends_of_intervals[real_len - 1] == rightmost_coord return ends_of_intervals[:real_len], values[:real_len]
def per_interval_max(ends_of_intervals, values, scale: float32, baseline: float32): for p, v in zip(ends_of_intervals, values): assert p.size == v.size # 1. Make buffers for current intervals and results tracks = len(ends_of_intervals) track_nextind = np.zeros(tracks, dtype=np.int32) track_curent = np.empty(tracks, dtype=np.int32) track_curval = np.empty(tracks, dtype=np.float32) for track in range(tracks): track_curent[track] = ends_of_intervals[track][0] track_curval[track] = values[track][0] maxlength = int32(0) # sum(x.size for x in positions) for p in ends_of_intervals: maxlength += p.size res_ends = np.empty(maxlength, dtype=np.int32) res_values = np.empty(maxlength, dtype=np.float32) curval = max(baseline, np.max(track_curval)) nextval = curval curend = min(track_curent) real_length = 0 # ahead declaration of buffer to avoid memory allocation on each iteration to_drop = np.empty(tracks, dtype=np.int32) while tracks > 0: # 1. Next value is a max among present intervals and baseline value nextval = max(baseline, np.max(track_curval)) # 2. End of the interval is a min among active intervals ends nextend = min(track_curent) # 3. Save interval if new value is encountered if nextval != curval: res_values[real_length] = curval * scale res_ends[real_length] = curend real_length += 1 curval = nextval curend = nextend # 4. Push intervals if needed and drop finished intervals to_drop_total = 0 for track in range(tracks): if track_curent[track] == nextend: nextind = track_nextind[track] + 1 # finished interval if nextind == ends_of_intervals[track].size: to_drop[to_drop_total] = track to_drop_total += 1 continue track_curent[track] = ends_of_intervals[track][nextind] track_curval[track] = values[track][nextind] track_nextind[track] = nextind # update max value for the current interval # if values[track][nextind - 1] == nextval: # nextval = max(baseline, np.max(track_curval)) # else: # nextval = max(nextval, track_curval[track]) if to_drop_total != 0: tracks -= to_drop_total indices = to_drop[:to_drop_total] track_curent = np.delete(track_curent, indices) track_curval = np.delete(track_curval, indices) track_nextind = np.delete(track_nextind, indices) for track in to_drop[:to_drop_total][::-1]: assert track < len(ends_of_intervals) and track < len(values) and \ len(ends_of_intervals) == len(values) and \ len(ends_of_intervals) > 0 ends_of_intervals.pop(track) values.pop(track) res_values[real_length] = curval * scale res_ends[real_length] = curend real_length += 1 assert res_ends.size >= real_length return res_ends[:real_length], res_values[:real_length]