def interpret(func, env, args, storage=None, **kwds): assert len(args) == len(func.args) # Make a copy, since we're going to mutate our IR! func, _ = copy_function(func) # If it's a BLZ output, we want an interpreter that streams # the processing through in chunks if storage is not None: if len(func.type.restype.shape) == 0: raise TypeError('Require an array, not a scalar, for outputting to BLZ') env['stream-outer'] = True result_ndim = env['result-ndim'] = len(func.type.restype.shape) else: # Convert any persistent inputs to memory # TODO: should stream the computation in this case for i, arg in enumerate(args): if isinstance(arg._data, BLZDataDescriptor): args[i] = arg[:] # Update environment with dynd type information dynd_types = dict((arg, get_dynd_type(array)) for arg, array in zip(func.args, args) if isinstance(array._data, DyNDDataDescriptor)) env['dynd-types'] = dynd_types # Lift ckernels func, env = run_pipeline(func, env, run_time_passes) if storage is None: # Evaluate once values = dict(zip(func.args, args)) interp = CKernelInterp(values) visit(interp, func) return interp.result else: res_shape, res_dt = datashape.to_numpy(func.type.restype) dim_size = operator.index(res_shape[0]) row_size = ndt.type(str(func.type.restype.subarray(1))).data_size chunk_size = min(max(1, (1024*1024) // row_size), dim_size) # Evaluate by streaming the outermost dimension, # and using the BLZ data descriptor's append dst_dd = BLZDataDescriptor(blz.zeros((0,)+res_shape[1:], res_dt, rootdir=storage.path)) # Loop through all the chunks for chunk_start in range(0, dim_size, chunk_size): # Tell the interpreter which chunk size to use (last # chunk might be smaller) chunk_size = min(chunk_size, dim_size - chunk_start) # Evaluate the chunk args_chunk = [arg[chunk_start:chunk_start+chunk_size] if len(arg.dshape.shape) == result_ndim else arg for arg in args] values = dict(zip(func.args, args_chunk)) interp = CKernelChunkInterp(values, chunk_size, result_ndim) visit(interp, func) chunk = interp.result._data.dynd_arr() dst_dd.append(chunk) return blaze.Array(dst_dd)
def inline(func, call): """ Inline the call instruction into func. :return: { old_op : new_op } """ callee = call.args[0] callblock = call.block # assert_inlinable(func, call, callee, uses) builder = Builder(func) builder.position_before(call) inline_header, inline_exit = builder.splitblock() new_callee, valuemap = copy_function(callee, temper=func.temp) result = rewrite_return(new_callee) # Fix up arguments for funcarg, arg in zip(new_callee.args, call.args[1]): funcarg.replace_uses(arg) # Copy blocks new_blocks = list(new_callee.blocks) after = inline_header for block in new_blocks: block.parent = None func.add_block(block, after=after) after = block # Fix up wiring builder.jump(new_callee.startblock) with builder.at_end(new_callee.exitblock): builder.jump(inline_exit) stretch_exception_block(builder, callblock, new_blocks) # Fix up final result of call if result is not None: # non-void return result.unlink() result.result = call.result call.replace(result) else: call.delete() func.reset_uses() #verify(func) return valuemap
def inline(func, call, uses=None): """ Inline the call instruction into func. :param uses: defuse information """ callee = call.args[0] # assert_inlinable(func, call, callee, uses) builder = Builder(func) builder.position_before(call) inline_header, inline_exit = builder.splitblock() new_callee = copy_function(callee, temper=func.temp) result = rewrite_return(new_callee) # Fix up arguments for funcarg, arg in zip(new_callee.args, call.args[1]): funcarg.replace_uses(arg) # Copy blocks after = inline_header for block in new_callee.blocks: block.parent = None func.add_block(block, after=after) after = block # Fix up wiring builder.jump(new_callee.startblock) with builder.at_end(new_callee.exitblock): builder.jump(inline_exit) # Fix up final result of call if result is not None: # non-void return result.unlink() result.result = call.result call.replace(result) else: call.delete() func.reset_uses() verify(func)
def interpret(func, env, args, **kwds): assert len(args) == len(func.args) # Make a copy, since we're going to mutate our IR! func = copy_function(func) # Update environment with dynd type information dynd_types = dict((arg, get_dynd_type(array)) for arg, array in zip(func.args, args) if isinstance(array._data, DyNDDataDescriptor)) env['dynd-types'] = dynd_types # Lift ckernels func, env = run_pipeline(func, env, run_time_passes) print(func) # Evaluate values = dict(zip(func.args, args)) interp = CKernelInterp(values) visit(interp, func) return interp.result
def copy_func(func, env): new_func, _ = copy_function(func) new_func.name = temper(new_func.name) return new_func