Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite ICP in ReverseDiff style #97

Closed
wants to merge 7 commits into from

Conversation

eeshan9815
Copy link

No description provided.

@chriscoey
Copy link

@jrevels what about cassette?

@jrevels
Copy link

jrevels commented Jul 11, 2018

@jrevels what about cassette?

Cassette would definitely be useful here if it was released/usable with a released version of Julia, but that's not currently the case.

Always down to help folks play around with a Cassette-based implementation if somebody wants to make the attempt, though.

@dpsanders
Copy link
Member

I discussed using Cassette with @eeshan9815. We decided that this would be a good first step.

We are very interested in discussing that with you, though, @jrevels.

@@ -20,9 +20,12 @@ export
SubPaving, Paving,
pave, refine!,
Vol,
show_code
show_code, icp!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to export icp too / instead.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will add both versions.

src/icp.jl Outdated
julia> constraint = -∞..1
[-∞, 1]

julia> icp(f, X, constraint)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be icp!?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, sorry about the typo.

const NULL_INDEX = typemin(Int)
const NULL_TAPE = InstructionTape()

type TrackedReal{V<:Real,O} <: Real
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

immutable? And spacing problem.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The values in the TrackedReal are modified as the tape is traversed, so it can't be an immutable


TrackedReal{V}(v::V, tp::InstructionTape = NULL_TAPE) = TrackedReal{V,Void}(v, tp)

immutable TrackedArray{V,N,VA} <: AbstractArray{TrackedReal{V,TrackedArray{V,N,VA}},N}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space

@dpsanders
Copy link
Member

type -> mutable struct

const NULL_INDEX = typemin(Int)
const NULL_TAPE = InstructionTape()

type TrackedReal{V<:Real,O} <: Real
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type -> mutable struct

src/tape/icp.jl Outdated
@@ -106,16 +106,47 @@ function reverse_pass!(tape::InstructionTape, input::AbstractArray)
t = tape
t[i].output.value = t[i].output.value ∩ t[i].cache
op = IntervalContractors.reverse_operations[Symbol(t[i].func)]
if op == :mul_rev
if istracked(t[i].input[1]) && istracked(t[i].input[2])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if seems to just be a combination of the two below, so can be eliminated (replacing the elseifs by ifs).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't that require four comparisions, instead of the current three?
The current flow of control is -

if a && b

else if a #if a && !b

else if b #if !a && b

else #if !a && !b

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, there's just two things to check: a or !a, and separately b or !b

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But isn't that four comparisions in the worst case, instead of 3 if elseif is used?

src/tape/icp.jl Outdated
elseif istracked(t[i].input[1])
rev_result = mul_rev_2(value(t[i].output), value.(t[i].input)...)
t[i].input[1].value = rev_result
if 0 < t[i].input[1].index <= n
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this line for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the index of the variables is between 0 and n, that means that the variable is one of the input variables, for which, the changes need to be reflected in the input array as well.


"""

function icp!(f::Function, input::AbstractArray, constraint::Interval)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention is that the first argument is modified, so I think we should reverse the order of the first two arguments.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, if the mutating function accepts a function argument, then that usually comes first, e.g.

help?> map!
search: map! asyncmap! map mapfoldr mapfoldl mapslices mapreduce mapreducedim asyncmap macroexpand @macroexpand

  map!(function, destination, collection...)

  Like map, but stores the result in destination rather than a new collection. destination must be at least as large
  as the first collection.

with the reason being that it allows use of the convenient do notation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, OK, thanks!

@dpsanders
Copy link
Member

dpsanders commented Jul 16, 2018 via email

@dpsanders
Copy link
Member

dpsanders commented Jul 16, 2018 via email

@eeshan9815
Copy link
Author

Ohh, I just realized what you mean!
Yes you're right, I will update accordingly.

@dpsanders
Copy link
Member

Please remove 0.5 from testing, and make nightly an allowed failure.

t = tape
t[i].output.value = t[i].output.value ∩ t[i].cache #Propogation of constraints up
op = IntervalContractors.reverse_operations[Symbol(t[i].func)] #Looking up the reverse function in IntervalContractors
if op == :mul_rev #Special behavior to deal with constants
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this generic for any binary operator?

@dpsanders
Copy link
Member

I believe this is not up to date with Julia 1.0, so I am planning to close it. Feel free to re-open when possible.

@dpsanders
Copy link
Member

No longer relevant.

@dpsanders dpsanders closed this Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants