Skip to content

Safe usage of zero_tangent for Ptr{T} #999

@AstitvaAggarwal

Description

@AstitvaAggarwal

see #471 (comment)

Importantly note that the below MWE shows that there is another issue beyond pointerset.

using Mooncake: build_rrule, value_and_gradient!!
using Core.Intrinsics: pointerset, atomic_pointerset

f_pointerset = x -> begin
    c_1 = [x]
    c_2 = [x * 2.0]
    p = [pointer(c_1)] 
    pointerset(pointer(p), pointer(c_2), 1, 1)
    unsafe_load(p[1])
end

f_atomic_pointerset = x -> begin
    c_1 = [x]
    c_2 = [x * 2.0]
    p = [pointer(c_1)]
    atomic_pointerset(pointer(p), pointer(c_2), :monotonic)
    unsafe_load(p[1])
end

value_and_gradient!!(build_rrule(f_pointerset, 3.0), f_pointerset, 3.0)
value_and_gradient!!(build_rrule(f_atomic_pointerset, 3.0), f_atomic_pointerset, 3.0)
  1. All handwritten rules that call zero_tangent inside their definition will error out when any of the arguments contain or are pointers. (eg: arrayset rule)

  2. Derived rules that use @zero_adjoint will fail when the function returns a pointer-containing value. Since @zero_adjoint calls zero_fcodual on the primal output internally (e.g. Base.vect in the MWE).

  3. In general, direct usage of zero_fcodual/zero_codual will fail for pointers.

Finally, all the above is due to the fact that these call the single arg zero_tangent that always fails for pointers. The solution is to always call the 2 arg zero_tangent, which fallbacks to 1 arg rdata aware dispatch for zero_tangent.
I have create an issue #999 to seperate it from the current Issue, PR.

Will add more details as #471 progresses.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions