def _infer_h5_typ(self, rhs): # infer the type if it is of the from f['A']['B'][:] # with constant filename # TODO: static_getitem has index_var for sure? # make sure it's slice, TODO: support non-slice like integer require(rhs.op in ('getitem', 'static_getitem')) index_var = rhs.index if rhs.op == 'getitem' else rhs.index_var index_def = get_definition(self.func_ir, index_var) require(isinstance(index_def, ir.Expr) and index_def.op == 'call') require( find_callname(self.func_ir, index_def) == ('slice', 'builtins')) # collect object names until the call val_def = rhs obj_name_list = [] while True: val_def = get_definition(self.func_ir, val_def.value) require(isinstance(val_def, ir.Expr)) if val_def.op == 'call': return self._get_h5_type_file(val_def, obj_name_list) # object_name should be constant str require(val_def.op in ('getitem', 'static_getitem')) val_index_var = val_def.index if val_def.op == 'getitem' else val_def.index_var obj_name = find_const(self.func_ir, val_index_var) require(isinstance(obj_name, str)) obj_name_list.append(obj_name)
def is_whole_slice(typemap, func_ir, var): """ return True if var can be determined to be a whole slice """ require(typemap[var.name] == types.slice2_type) call_expr = get_definition(func_ir, var) require(isinstance(call_expr, ir.Expr) and call_expr.op == 'call') assert len(call_expr.args) == 2 assert find_callname(func_ir, call_expr) == ('slice', 'builtins') arg0_def = get_definition(func_ir, call_expr.args[0]) arg1_def = get_definition(func_ir, call_expr.args[1]) require(isinstance(arg0_def, ir.Const) and arg0_def.value == None) require(isinstance(arg1_def, ir.Const) and arg1_def.value == None) return True
def is_const_slice(typemap, func_ir, var, accept_stride=False): """ return True if var can be determined to be a constant size slice """ require(typemap[var.name] == types.slice2_type or (accept_stride and typemap[var.name] == types.slice3_type)) call_expr = get_definition(func_ir, var) require(isinstance(call_expr, ir.Expr) and call_expr.op == 'call') assert (len(call_expr.args) == 2 or (accept_stride and len(call_expr.args) == 3)) assert find_callname(func_ir, call_expr) == ('slice', 'builtins') arg0_def = get_definition(func_ir, call_expr.args[0]) require(isinstance(arg0_def, ir.Const) and arg0_def.value is None) size_const = find_const(func_ir, call_expr.args[1]) require(isinstance(size_const, int)) return True
def test_obj_func_match(self): """Test matching of an object method (other than Array see #3449) """ def test_func(): d = Dummy([1]) d.val.append(2) test_ir = compiler.run_frontend(test_func) typingctx = cpu_target.typing_context typemap, _, _ = type_inference_stage( typingctx, test_ir, (), None) matched_call = ir_utils.find_callname( test_ir, test_ir.blocks[0].body[14].value, typemap) self.assertTrue(isinstance(matched_call, tuple) and len(matched_call) == 2 and matched_call[0] == 'append')
def _get_h5_type_file(self, val_def, obj_name_list): require(len(obj_name_list) > 0) require(find_callname(self.func_ir, val_def) == ('File', 'h5py')) require(len(val_def.args) > 0) f_name = find_str_const(self.func_ir, val_def.args[0]) obj_name_list.reverse() import h5py f = h5py.File(f_name, 'r') obj = f for obj_name in obj_name_list: obj = obj[obj_name] require(isinstance(obj, h5py.Dataset)) ndims = len(obj.shape) numba_dtype = numba.numpy_support.from_dtype(obj.dtype) f.close() return types.Array(numba_dtype, ndims, 'C')