kernel_parameter_gradient.bend

stelliferous@0.0.3.0 · 51 lines · 0 definitions

1# Bias gradient traversal over ordered spatial groups.
2import Base
3import stelliferous@0.0.3.0/traversal_grouped.bend as Grouped
4import stelliferous@0.0.3.0/storage_buffer.bend as Storage
5
6type Work is Data:
7  Work{images: Nat,channels: Nat,outputs: Nat,height: Nat,width: Nat,kernel: Nat,stride: Nat,padding: Nat,rows: Nat,columns: Nat,group: Nat}
8
9type Context is Data:
10  Context{work: Work,image: Nat,element: Nat}
11
12def bias_address(context: Context,position: Nat) -> U32:
13  Context{Work{n,c,+o,h,w,k,s,p,+rows,+columns,g},image,element} = context
14  U32.from_nat(Nat.add(Nat.mul(Nat.mul(Nat.add(Nat.mul(image,o),element),rows),columns),position))
15
16def bias_at(reader: Array<F32>,context: Context,position: Nat) -> Array<F32> & F32:
17  Array.get(F32,reader,bias_address(context,position))
18
19def image_tail(~Reader: Type,pair: Reader & F32,tail: Reader -> Reader & List<&2,F32>) -> Reader & List<&2,F32>:
20  (reader,value) = pair
21  Grouped.prepend(~Reader,value,tail(reader))
22
23def image_values(~Reader: Type,~read: Reader -> Context -> Nat -> Reader & F32,remaining: Nat,+image: Nat,+element: Nat,+work: Work,
24  +ranges: List<&2,Grouped.Range>,reader: Reader) -> Reader & List<&2,F32>:
25  match remaining:
26    case 0n: (reader,[])
27    case 1n+rest:
28      image_tail(~Reader,Grouped.run(~Reader,~Context,~read,ranges,reader,Context{work,image,element}),
29        reader => image_values(~Reader,~read,rest,1n+image,element,work,ranges,reader))
30
31def element(~Reader: Type,~read: Reader -> Context -> Nat -> Reader & F32,+work: Work,index: Nat,+ranges: List<&2,Grouped.Range>,reader: Reader) -> Reader & F32:
32  Work{images,c,o,h,w,k,s,p,rows,columns,g} = work
33  Grouped.reduced(~Reader,image_values(~Reader,~read,images,0n,index,work,ranges,reader))
34
35# One reduced output written at its position, then the rest of the outputs.
36def stored(~Reader: Type,+position: U32,result: Storage.Buffer<F32>,pair: Reader & F32,
37  tail: Reader -> Storage.Buffer<F32> -> Reader & Storage.Buffer<F32>) -> Reader & Storage.Buffer<F32>:
38  (reader,value) = pair
39  tail(reader,Storage.write(~F32,position,value,result))
40
41def written(~Reader: Type,~read: Reader -> Context -> Nat -> Reader & F32,remaining: Nat,+index: Nat,+position: U32,+work: Work,+ranges: List<&2,Grouped.Range>,
42  reader: Reader,result: Storage.Buffer<F32>) -> Reader & Storage.Buffer<F32>:
43  match remaining:
44    case 0n: (reader,result)
45    case 1n+rest:
46      stored(~Reader,position,result,element(~Reader,~read,work,index,ranges,reader),
47        reader => result => written(~Reader,~read,rest,1n+index,(position + 1 : U32),work,ranges,reader,result))
48
49def bias(+work: Work,d: Array<F32>,result: Storage.Buffer<F32>) -> Array<F32> & Storage.Buffer<F32>:
50  Work{n,c,o,h,w,k,s,p,rows,columns,g} = work
51  written(~Array<F32>,~bias_at,o,0n,0,work,Grouped.ranges(rows,columns,g),d,result)