commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <phil.ste...@gmail.com>
Subject Re: [nabla] INVOKEVIRTUAL not handled yet
Date Sun, 16 Oct 2011 07:24:52 GMT
On 10/9/11 7:46 AM, Phil Steitz wrote:
> On 10/9/11 5:39 AM, Luc Maisonobe wrote:
>> Hi Phil,
>>
>> Le 08/10/2011 23:42, Phil Steitz a écrit :
>>> On 10/8/11 2:24 PM, Luc Maisonobe wrote:
>>>>
>>>> Phil Steitz<phil.steitz@gmail.com>  a écrit :
>>>>
>>>>> I am getting RTE with message above when I try to run the example
>>>>> under "updating the base and differentiated objects" in the docs.
>> Digging into the code, here are the bytecode operations that are
>> not supported yet:
>>
>>    DALOAD, DASTORE:
>>       element access in double arrays
>>    GETSTATIC, PUTSTATIC, GETFIELD, PUTFIELD:
>>       field access (instance fields and class fields)
>>    INVOKEVIRTUAL/INVOKESPECIAL/INVOKESTATIC/INVOKEINTERFACE:
>>       method calls
>>    NEWARRAY/ANEWARRAY/MULTIANEWARRAY:
>>       array creation
>>
>>>>> Is this example supposed to work with the code in trunk?  Also,
>>>>> I am
>>>> I'll look at this tomorrow, but I think for now you need to have
>>>> a standalone function, it cannot be split
>>>> as a main function calling subfunctions. The only allowed calls
>>>> are the static methods from Math/StrictMath.
>>>> I did not add our own FastMath, but it is trivial to do.
>>>>
>>>> Another limitation is that your function cannot store
>>>> intermediate results as clas attributes yet.
>>> Thanks, Luc!  What I was trying to illustrate was partial
>>> derivatives, which IIUC you need something like that example to do.
>>> The following almost works:
>>>
>>>     public void testPartialDerivatives() throws Exception {
>>>          PartialFunction function = new PartialFunction(1);
>>>          final UnivariateDerivative derivative = new
>>> ForwardModeAlgorithmicDifferentiator().differentiate(function);
>>>          DifferentialPair t = DifferentialPair.newVariable(1);
>>>          Assert.assertEquals(3,
>>> derivative.f(t).getFirstDerivative(), 0);
>>>          Assert.assertEquals(2, derivative.f(t).getValue(), 0);
>>>          function.setX(2);
>>>          Assert.assertEquals(4,
>>> derivative.f(t).getFirstDerivative(), 0);
>>>          Assert.assertEquals(3, derivative.f(t).getValue(), 0);
>>>      }
>>>
>>> with
>>>
>>> public class PartialFunction implements UnivariateDifferentiable {
>>>      private double x;
>>>      public PartialFunction(double x) {
>>>          this.x = x;
>>>      }
>>>      public void setX(double x) {
>>>          this.x = x;
>>>      }
>>>      public double getX() {
>>>          return x;
>>>      }
>>>      public double f(double y) {
>>>          return x * y + y * y;
>>>      }
>>> }
>>>
>>> But I end up with java.lang.VerifyError: (class:
>>> ExampleTest$1PartialFunction$NablaForwardModeUnivariateDerivative,
>>> method: f signature:
>>> (Lorg/apache/commons/nabla/core/DifferentialPair;)Lorg/apache/commons/nabla/core/DifferentialPair;)
>>>
>>> Incompatible type for getting or setting field
>>>      at java.lang.Class.getDeclaredConstructors0(Native Method)
>>>      at
>>> java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
>>>      at java.lang.Class.getDeclaredConstructors(Class.java:1836)
>>>      at
>>> org.apache.commons.nabla.algorithmic.forward.ForwardModeAlgorithmicDifferentiator.differentiate(ForwardModeAlgorithmicDifferentiator.java:107)
>>>
>>>      at ExampleTest.testPartialDerivatives(ExampleTest.java:66)
>> This error seems to be due to the lack of support for the GETFIELD
>> instruction. As x is an instance field, the f method reads this
>> field before multiplying the result.

Right.  As an exercise to help me understand the internals of the
code, I have been trying to figure out how to add this support. 
Working backwards from the generated bytecode, the GETFIELD and the
ALOAD 0 before it seem to get copied unchanged:

    ALOAD 0
    GETFIELD PartialFunction.x : D

Working backwards to where it should get changed,
MethodDifferentiator#getReplacement throws RuntimeException when it
sees a GETFIELD; but in my example it does not throw.  This means
the instruction is not making it into the changes set.  The question
then is a) how to modify MethodDifferentiator#identifyChanges to
identify the need to change the instruction and b) how to transform
it (and other instructions that depend on it).  A reference to the
enclosing class also has to be made available.  Is that already
there somewhere?

Phil
>>
>> I have added a debug display message (to be removed later on) that
>> should print the generated bytecode to standard error when a
>> VerifyError exception occurs. It' clearly not targeted towards end
>> users, but it could help during development.
> Thanks, Luc!
>
> Phil
>> Luc
>>
>>>>
>>>> You can look at the junit tests for what is supported.  Simple
>>>> expressions, calls to traditional functions like sin, cos, exp ...,
>>>> Simple loops and conditionals, local automatic variables should
>>>> all work (I hope ...)
>>> Yep, I have gotten all of this to work.  Even "knows" the chain
>>> rule :)
>>>
>>>
>>> Phil
>>>>> assuming
>>>>> s/ForwardAlgorithmicDifferentiator/ForwardModeAlgorithmicDifferentiator
>>>>>
>>>>> throughout.  Correct?
>>>> Yes, the name was changed because a distant goal will be to also
>>>> support reverse mode, which is especially
>>>> useful when computing gradients (i.e. when one scalar function
>>>> depends on many inputs and we want all partial
>>>> derivatives).
>>>>
>>>> Luc
>>>>
>>>>> Phil
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>>
>>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>> ---------------------------------------------------------------------
>>>>
>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>>
>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message