JuliaAttic / ReverseDiffSource.jl

Reverse automated differentiation from source
MIT License
47 stars 12 forks source link

using ReverseDiffSource in Lora throws error #27

Closed papamarkou closed 8 years ago

papamarkou commented 8 years ago

Hi @fredo-dedup, I hope all is well with you. As you will see, I updated Lora after pushing the work of the last 9 months. I want to now re-enable autodiff in our Lora package using your ReverseDiffSource (and ForwardDiff as an additional option for the user); I should be able to re-integrate autodiff in the next one or two weeks. To start with, enabling using ReverseDiffSource in src/Lora.jl throws the following error, you may be able to understand better than me if sth is wrong on the AD side of the packages:

julia> using Lora
ERROR: LoadError: InitError: LoadError: UndefVarError: ReverseDiffSource not defined
 in include at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
 in __init__ at /Users/theodore/.julia/v0.4/ReverseDiffSource/src/ReverseDiffSource.jl:65
 in _require_from_serialized at loading.jl:84
 in _require_from_serialized at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
 in require at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
 in require at /Applications/Julia-0.4.1.app/Contents/Resources/julia/lib/julia/sys.dylib
while loading /Users/theodore/.julia/v0.4/ReverseDiffSource/src/base_rules.jl, in expression starting on line 9
during initialization of module ReverseDiffSource
while loading /Users/theodore/.julia/v0.4/Lora/src/Lora.jl, in expression starting on line 6
papamarkou commented 8 years ago

P.S. I forgot to mention that using ReverseDiffSource works fine from the Julia REPL. The problem appears only when using ReverseDiffSource is added to src/Lora.jl.

fredo-dedup commented 8 years ago

I suspect this is related to pre-compilation. It is also probably the cause of another issue. I'll look into it. Sorry to slow you down in your huge endeavor on Lora !

A quick workaround that might work is to do the following in the file ReverseDiffSource.jl :

papamarkou commented 8 years ago

Thanks a lot @fredo-dedup, your help with ReverseDiffSource is appreciated. I am very happy to say that your proposed workaround works for now. This allows me to add using ReverseDiffSource inside Lora without errors, which is great!

I will work using your solution for now, to develop the constructors needed in Lora that will allow generation of parameters with gradients computed via ReverseDiffSource. This way you can sort out the matter from the ReverseDiffSource end at your own time without rushing, while I can carry on development for integrating ReverseDiffSource with Lora.

fredo-dedup commented 8 years ago

I set pre-compilation = false with latest commit in master. Should work now.

papamarkou commented 8 years ago

Thanks @fredo-dedup! I will try them now and will push the relevant changes to Lora so that it works with ReverseDiffSource!

I wanted to seize the opportunity and ask you a question about the init option of rdiff(), as I don't know well how it is used internally, is it needed to be specified by the user or can it be deduced? This question is only for my own understanding as the Lora-ReverseDiffSource is not affected by it.

fredo-dedup commented 8 years ago

Sorry @scidom but I can't see which init you are referring to. Could you point me to a specific line in the code or in the docs ? Edit: ok I found it. This parameter (or parameters) has 2 roles : list the symbols to be derived against and give initial values so that the code can actually be evaluated (this is needed by AD to get the type of each intermediate calculation).

papamarkou commented 8 years ago

Sorry, @fredo-dedup, this is my bad. I was referring for ex to this page in doc:

http://reversediffsourcejl.readthedocs.org/en/master/maincall.html

Put another way, in the example

res = rdiff(:(x[1]^3+x[2]^2) , x=[2., 3.], order=1, allorders=false)
@eval foo(x) = $res
foo([1.5, 2.8])

why do we need to pass the argument x=[2., 3.] to rdiff(). Is there a way we can avoid specifying it as it may simplify the API?

One more question, ReverseDiffSource (and Lora) seem to have failed to build on nightly. This is almost certainly my fault - I develop using Julia v0.4, so I have to catch up with v0.5...

fredo-dedup commented 8 years ago

As of today, this parameter is needed because the derivation rules of functions differ depending on the types of the function arguments. ReverseDiffSource does not implement type inference by itself as it is a rather complicated process and it is not always reliable. The package rather requires the user to supply typical values of the input variables so that all the intermediate values can be calculated and their type known. This allows in turn to find the correct derivation rule.

papamarkou commented 8 years ago

Ok, @fredo-dedup, you are more knowledgeable than me on ReverseDiffSource (and more generally on reverse mode AD), so I will trust with you this is the more reasonable choice.

Just to be sure that what I am doing is correct, in this file

https://github.com/JuliaStats/Lora.jl/blob/master/src/autodiff/reverse.jl

I define via codegen an AD-related function that invokes rdiff(). For example, if this code generation method generates a function g(x::Vector) to compute the gradient of f, then I pass the type (:Vector) of x as an input argument to the code generation method. I think this is ok, because unltimately ReverseDiffSource returns a derivative function (which will become g) which takes any input argument as input, i.e. rdiff() returns a function with signature g(x) where x is of type Any, correct?