def mutate_with_body(self, func_ir, blocks, blk_start, blk_end, body_blocks, dispatcher_factory, extra): assert extra is None vlt = func_ir.variable_lifetime inputs, outputs = find_region_inout_vars( blocks=blocks, livemap=vlt.livemap, callfrom=blk_start, returnto=blk_end, body_block_ids=set(body_blocks), ) lifted_blks = {k: blocks[k] for k in body_blocks} _mutate_with_block_callee(lifted_blks, blk_start, blk_end, inputs, outputs) # XXX: transform body-blocks to return the output variables lifted_ir = func_ir.derive( blocks=lifted_blks, arg_names=tuple(inputs), arg_count=len(inputs), force_non_generator=True, ) dispatcher = dispatcher_factory(lifted_ir) newblk = _mutate_with_block_caller( dispatcher, blocks, blk_start, blk_end, inputs, outputs, ) blocks[blk_start] = newblk _clear_blocks(blocks, body_blocks) return dispatcher
def mutate_with_body(self, func_ir, blocks, blk_start, blk_end, body_blocks, dispatcher_factory, extra): cellnames = func_ir.func_id.func.__code__.co_freevars closures = func_ir.func_id.func.__closure__ func_globals = func_ir.func_id.func.__globals__ if closures is not None: # Resolve free variables func_closures = {} for cellname, closure in zip(cellnames, closures): try: cellval = closure.cell_contents except ValueError as e: # empty cell will raise if str(e) != "Cell is empty": raise else: func_closures[cellname] = cellval else: # Missing closure object func_closures = {} args = extra['args'] if extra else () kwargs = extra['kwargs'] if extra else {} typeanns = self._legalize_args(func_ir=func_ir, args=args, kwargs=kwargs, loc=blocks[blk_start].loc, func_globals=func_globals, func_closures=func_closures, ) vlt = func_ir.variable_lifetime inputs, outputs = find_region_inout_vars( blocks=blocks, livemap=vlt.livemap, callfrom=blk_start, returnto=blk_end, body_block_ids=set(body_blocks), ) # Determine types in the output tuple def strip_var_ver(x): return x.split('.', 1)[0] stripped_outs = list(map(strip_var_ver, outputs)) # Verify that only outputs are annotated extra_annotated = set(typeanns) - set(stripped_outs) if extra_annotated: msg = ( 'Invalid type annotation on non-outgoing variables: {}.' 'Suggestion: remove annotation of the listed variables' ) raise errors.TypingError(msg.format(extra_annotated)) # Verify that all outputs are annotated # Note on "$cp" variable: # ``transforms.consolidate_multi_exit_withs()`` introduces the variable # for the control-point to determine the correct exit block. This # variable crosses the with-region boundary. Thus, it will be consider # an output variable leaving the lifted with-region. typeanns["$cp"] = types.int32 not_annotated = set(stripped_outs) - set(typeanns) if not_annotated: msg = ( 'Missing type annotation on outgoing variable(s): {0}\n\n' 'Example code: with objmode({1}=\'<' 'add_type_as_string_here>\')\n' ) stable_ann = sorted(not_annotated) raise errors.TypingError(msg.format(stable_ann, stable_ann[0])) # Get output types outtup = types.Tuple([typeanns[v] for v in stripped_outs]) lifted_blks = {k: blocks[k] for k in body_blocks} _mutate_with_block_callee(lifted_blks, blk_start, blk_end, inputs, outputs) lifted_ir = func_ir.derive( blocks=lifted_blks, arg_names=tuple(inputs), arg_count=len(inputs), force_non_generator=True, ) dispatcher = dispatcher_factory(lifted_ir, objectmode=True, output_types=outtup) newblk = _mutate_with_block_caller( dispatcher, blocks, blk_start, blk_end, inputs, outputs, ) blocks[blk_start] = newblk _clear_blocks(blocks, body_blocks) return dispatcher
def mutate_with_body(self, func_ir, blocks, blk_start, blk_end, body_blocks, dispatcher_factory, extra): typeanns = self._legalize_args(extra, loc=blocks[blk_start].loc) vlt = func_ir.variable_lifetime inputs, outputs = find_region_inout_vars( blocks=blocks, livemap=vlt.livemap, callfrom=blk_start, returnto=blk_end, body_block_ids=set(body_blocks), ) # Determine types in the output tuple def strip_var_ver(x): return x.split('.', 1)[0] stripped_outs = list(map(strip_var_ver, outputs)) # Verify that only outputs are annotated extra_annotated = set(typeanns) - set(stripped_outs) if extra_annotated: msg = ('Invalid type annotation on non-outgoing variables: {}.' 'Suggestion: remove annotation of the listed variables') raise errors.TypingError(msg.format(extra_annotated)) # Verify that all outputs are annotated not_annotated = set(stripped_outs) - set(typeanns) if not_annotated: msg = ('missing type annotation on outgoing variables: {0}' 'Example code: with objmode({0}=<add_type_as_str_here>):') raise errors.TypingError(msg.format(not_annotated)) # Get output types outtup = types.Tuple([typeanns[v] for v in stripped_outs]) lifted_blks = {k: blocks[k] for k in body_blocks} _mutate_with_block_callee(lifted_blks, blk_start, blk_end, inputs, outputs) lifted_ir = func_ir.derive( blocks=lifted_blks, arg_names=tuple(inputs), arg_count=len(inputs), force_non_generator=True, ) dispatcher = dispatcher_factory(lifted_ir, objectmode=True, output_types=outtup) newblk = _mutate_with_block_caller( dispatcher, blocks, blk_start, blk_end, inputs, outputs, ) blocks[blk_start] = newblk _clear_blocks(blocks, body_blocks) return dispatcher