~/bend-docscommunity

kernel_gather.bend source

kernel_gather.bend on the hub · documented module

import Baseimport ./traversal_array.bend as Traversal# Clip once per leaf. A channel is one contiguous copy; padding never becomes# a store into the next channel. Both owners stay affine across the channel loop.def gather_width_when(inside: Bool,offset: U32,output_positions: U32,span: U32) -> U32:  match inside:    case False{}: 0    case True{}: U32.min(span,(output_positions - offset : U32))def gather_width(+offset: U32,+output_positions: U32,span: U32) -> U32:  gather_width_when(U32.is_lt(offset,output_positions),offset,output_positions,span)def gather_channel(+channel: U32,+width: U32,+offset: U32,+output_positions: U32,+span: U32,  owners: Array<F32> & Array<F32>) -> Array<F32> & Array<F32>:  (input_storage,output_storage) = owners  Traversal.copy(~F32,U32.to_nat(width),(channel * span : U32),    (channel * output_positions + offset : U32),input_storage,output_storage)def gather_channels(remaining: Nat,+channel: U32,+width: U32,+offset: U32,+output_positions: U32,+span: U32,  owners: Array<F32> & Array<F32>) -> Array<F32> & Array<F32>:  match remaining:    case 0n: owners    case 1n+rest:      gather_channels(rest,(channel + 1 : U32),width,offset,output_positions,span,        gather_channel(channel,width,offset,output_positions,span,owners))def gathered_output(owners: Array<F32> & Array<F32>) -> Array<F32>:  (input_storage,output_storage) = owners  output_storagedef gather_block(channels: U32,+offset: U32,+output_positions: U32,+span: U32,input_storage: Array<F32>,output_storage: Array<F32>) -> Array<F32>:  gathered_output(gather_channels(U32.to_nat(channels),0,gather_width(offset,output_positions,span),offset,output_positions,span,    (input_storage,output_storage)))