/// Modifer to mark a function for forward-mode differentiation. /// i.e. the compiler will automatically generate a new function /// that computes the jacobian-vector product of the original. __attributeTarget(FunctionDeclBase) attribute_syntax [ForwardDifferentiable] : ForwardDifferentiableAttribute; // Custom Forward Derivative Function reference __attributeTarget(FunctionDeclBase) attribute_syntax [ForwardDerivative(function)] : ForwardDerivativeAttribute; __attributeTarget(FunctionDeclBase) attribute_syntax [BackwardDifferentiable] : BackwardDifferentiableAttribute; __attributeTarget(FunctionDeclBase) attribute_syntax [ForwardDerivativeOf(function)] : ForwardDerivativeOfAttribute; __attributeTarget(DeclBase) attribute_syntax [DerivativeMember(memberName)] : DerivativeMemberAttribute; /// Pair type that serves to wrap the primal and /// differential types of an arbitrary type T. __generic __magic_type(DifferentialPairType) __intrinsic_type($(kIROp_DifferentialPairType)) struct DifferentialPair : IDifferentiable { typedef DifferentialPair Differential; typedef T.Differential DifferentialElementType; __intrinsic_op($(kIROp_MakeDifferentialPair)) __init(T _primal, T.Differential _differential); property p : T { __intrinsic_op($(kIROp_DifferentialPairGetPrimal)) get; } property v : T { __intrinsic_op($(kIROp_DifferentialPairGetPrimal)) get; } property d : T.Differential { __intrinsic_op($(kIROp_DifferentialPairGetDifferential)) get; } [__unsafeForceInlineEarly] T.Differential getDifferential() { return d; } [__unsafeForceInlineEarly] T getPrimal() { return p; } [__unsafeForceInlineEarly] static Differential dzero() { return Differential(T.dzero(), T.Differential.dzero()); } [__unsafeForceInlineEarly] static Differential dadd(Differential a, Differential b) { return Differential( T.dadd( a.p, b.p ), T.Differential.dadd(a.d, b.d)); } [__unsafeForceInlineEarly] static Differential dmul(This a, Differential b) { return Differential( T.dmul(a.p, b.p), T.Differential.dmul(a.d, b.d)); } }; #define VECTOR_MAP_UNARY(TYPE, COUNT, FUNC, VALUE) \ vector result; for(int i = 0; i < COUNT; ++i) { result[i] = FUNC(VALUE[i]); } return result // Natural Exponent __generic [ForwardDerivativeOf(exp)] DifferentialPair __d_exp(DifferentialPair dpx) { return DifferentialPair( exp(dpx.p), T.dmul(exp(dpx.p), dpx.d)); } __generic [ForwardDerivativeOf(exp)] DifferentialPair> __d_exp_vector(DifferentialPair> dpx) { vector result; vector.Differential d_result; for(int i = 0; i < N; ++i) { DifferentialPair dpexp = __d_exp(DifferentialPair(dpx.p[i], __slang_noop_cast(dpx.d[i]))); result[i] = dpexp.p; d_result[i] = __slang_noop_cast(dpexp.d); } return DifferentialPair>(result, d_result); } __generic [ForwardDerivativeOf(sin)] DifferentialPair d_sin(DifferentialPair dpx) { return DifferentialPair( sin(dpx.p), T.dmul(cos(dpx.p), dpx.d)); } __generic [ForwardDerivativeOf(cos)] DifferentialPair d_cos(DifferentialPair dpx) { return DifferentialPair( cos(dpx.p), T.dmul(-sin(dpx.p), dpx.d)); }