implementing mlp; // A wrapper of CoopVec to allow it being used in differentiable context. // public struct MLVec : IDifferentiable { public CoopVec data; public typealias Differential = MLVec; public static MLVec fromArray(NFloat[N] values) { MLVec result; [ForceUnroll] for (int i = 0; i < N; i++) result.data[i] = values[i]; return result; } internal static NFloat[N] coopVecToArray(CoopVec v) { NFloat[N] arr; [ForceUnroll] for (int i = 0; i < N; i++) arr[i] = v[i]; return arr; } [BackwardDerivativeOf(fromArray)] internal static void fromArrayBwd(inout DifferentialPair values, MLVec dResult) { values = diffPair(values.p, coopVecToArray(dResult.data)); } internal static NFloat[N] toArray(MLVec vec) { return coopVecToArray(vec.data); } [BackwardDerivativeOf(toArray)] internal static void toArrayBwd(inout DifferentialPair> vec, NFloat[N] dResult) { vec = diffPair(vec.p, MLVec.fromArray(dResult)); } [Differentiable] public NFloat[N] toArray() { return toArray(this); } public override static Differential dadd(Differential d0, Differential d1) { return {d0.data + d1.data}; } public override static Differential dmul(U s, Differential d) { return {d.data * __realCast(s)}; } public override static Differential dzero() { return {}; } }