Menu

#4 polymorphic numeric functions

open-accepted
nobody
None
5
2003-05-10
2003-03-06
Isaac Gouy
No

I'm not sure if this is a problem with Nice, or a problem
with what I did. Sending it as a bug report let's me
attach the files more easily.

I've tried this with the development nice.jar

The first version (matrix.nice int) multiplies 2 int arrays,
and works fine.

I tried (various ways) to change it to work with 2 arrays
of any primitive numeric type, but get the wrong answer
0 0 0 0

Discussion

  • Isaac Gouy

    Isaac Gouy - 2003-03-06
     
  • Isaac Gouy

    Isaac Gouy - 2003-03-06
     
  • Daniel Bonniot

    Daniel Bonniot - 2003-03-07
    • status: open --> open-accepted
     
  • Daniel Bonniot

    Daniel Bonniot - 2003-03-07

    Logged In: YES
    user_id=88952

    The problem is that the JVM does not allow to use int[]
    where double[] is expected (and of course it does not have
    type parameters).
    So what happens is that nicec compiles mmult as taking
    parameters of type double[][]. If you can it with int[][],
    the array is first copied into a double[][]. This works okay
    if you just read from the array. But if you write, you of
    course write in the copy, and the change is lost after you
    return from the function.
    You can look at the bytecode generated t osee it for yourself.

    Knowing this, you could change your code, so that mmult
    creates the result array. In that case, it would be
    converted to int[][] at the return of the call, so the
    semantic would be correct. This would mean allocating a
    result matrix for each call (but the polymorphic code also
    does that implicitely, by copying).
    If you intend to submit to shootout, you should probably
    consider the monomorphic int version.

    Of course this does not solve the issue for Nice. I think
    the current behaviour is not acceptable. Since there is a
    limited number of primitive types, a possibility would be to
    generate several instances of the polymorphic function, one
    for T=double, one for T=float, ...
    That would probably be the best for efficiency, since it
    would be similar to monomorphic code.

    Another possibility is to treat int[][] and double[][] as
    Object[]. Then it is possible to use the methods in
    java.lang.reflect.Array to access the array.
    That would probably be slower, but also easier to implement.
    Would you be able to do some benchmarks on the
    java.lang.reflect.Array, so we know how much slower they
    are? Is it 10%? 10x?

    I cannot guarantee when this will be fixed. It depends if
    somebody is interested to look into that, or if I find the
    time for it. Having some benchmarks would be a good start to
    make decisions.

     
  • Isaac Gouy

    Isaac Gouy - 2003-03-07

    Logged In: YES
    user_id=536291

    >Would you be able to do some benchmarks
    maybe I'll look into that

    I'm starting to appreciate how much work you (as compiler
    writer) have to do to work around JVM limitations.

     
  • Daniel Bonniot

    Daniel Bonniot - 2003-03-13

    Logged In: YES
    user_id=88952

    I did some investigation about java.lang.reflect.Array, and
    it seems that we cannot use it for this purpose:
    Array.setLong(array, 0, someLong)
    will fail at runtime if array is not of type double[].

    It would work to use
    Array.set(array, 0, numericValue)
    if numeric value is a Number object. But then it would
    basically mean doing all the computations on wrapped
    numbers, which would be catastrophic for performance.

    At this point, it seems that duplication of code for the
    several type cases (always a few, since we are dealing with
    primitive types here) would be the best option. It would
    allow to preserve the semantics, and it would have perfect
    performance (as good as the monomorphic version).
    It's also more work of course, as I said before.

     
  • Daniel Bonniot

    Daniel Bonniot - 2003-05-10
    • summary: generic matrix mult problem --> polymorphic numeric functions
     

Log in to post a comment.