Forums > Java

[BUGS] very weird copyVectorToArray and co..

August 9, 2008 | 1:15 am

Hi,

First i have to tell that i "tear off my hair" with all theses copy***To*** jitter methods since more than one month, (this instead of going ahead in my musical programming), first trying to understand them, then finding bugs on it and writing topics on this forum (*) , then noticing the extremly slowness of some methods (**) , and finally, trying to compare all the different methods to find the most efficient one to simply copy a matrix to an array, and array to a matrix… But the more i look inside theses simple methods, the more they are looking weird, and the more a get the convition that something in it could be greatly improve by Cycling’74, in term of efficiency, more than just correcting the following bugs. So i was trying to interrest Topher Lafata on this, before i met casually Emmanuel Jourdan in Paris, who told me that Topher was not anymore working at Cycling, and that other people at Cycling, coming back in august, might be able to answer me. So this would be really nice. I made a test patch for all this, see bellow.

Bugs :

- "copyVectorToArrayPlanar" is only copying from the alpha plane, even if we ask for an other plane.
- Same with "copyArrayToVectorPlanar"
- Not really a "bug", but the weirdest thing here : it is about copying a 4 plane vector to an array using "copyVectorToArray" : Copying a vector of 1023 pixels is TEN TIMES SLOWER than copying a vector of 1022 pixels… !?!!!!!
- Same king of thing happen with "copyArrayToVector"

Attached, a patcher and a java code, are showing the efficiency for most of the copy***To*** methods (for int arrays). All the methods seem unexpectedly slow, except perhaps copyArrayToVectorPlanar and copyVectorToArrayPlanar, but that’s the ones that are buggy..

Hoping for any help from someone at Cycling,
Regards,

Alexandre
Configuration: MacBookPro Intel Core Duo 2 at 2.2 Ghz, Mac Os 10.5.3

(*) like this bug:
http://www.cycling74.com/forums/index.php?t=msg&goto=144653&rid=2682&S=c99c8ef5033c139c28e669eafc8cb65c

(**) like here :

http://www.cycling74.com/forums/index.php?t=msg&goto=145822&rid=2682&S=c99c8ef5033c139c28e669eafc8cb65c

P.S: Knowing theses bug on copyVectorToArrayPlanar, for now, the most efficient way to copy a 4 planes matrix to an array might be to use… an msp buffer~(then copying it to an array with MSPBuffer.peek method) instead of any jitter method… (see the msp_buffer_tests subpatch, down left in the patch) , i see you smiling but no, this is not funny.


August 27, 2008 | 4:01 pm

Hi Alexandre,

Thanks for your reports. These copy planar method, and copy matrix signed bugs will be fixed in version 5.0.5.

AFAICT, the performance issue you mention have to do with large Java arrays moving between the C and Java boundary. I assume there is additional copying that happens for large arrays. In your example, it would appear that the critical size is 4096 bytes (or in your example, it would appear within 8 bytes since they are probably allocated on 8 byte boundaries). So the reason the planar method is faster is that it is an array of 1200 bytes for each copy, rather than 4*1200=5200 bytes. I’m sure the all planes at once method would be just as fast if not faster, if you were to break your image in half and copy the left side then the right side, rather than each plane at a time. This is apparently an issue with the Java implementation, so we won’t be improving this performance anytime soon. Please copy in smaller chunks using whichever method you prefer for maximum performance.

Thanks,
Joshua


August 28, 2008 | 8:36 am

Thanks!

Well, i will learn from this strange experience that crossing the C/Java boundary is always something to really care about, because using jitter in java with big images.. can be like having a 220Mhz processor instead of a 2,2Ghz…

> "This is apparently an issue with the Java implementation, so we won’t be improving this performance anytime soon."

Then let me suggest that you could mention this performance issue in the api-jitter java doc, explaining that the ones who want performance should not use jitter-arrays conversions bigger than xxx… …959 pixels when using 4 planes char matrix ? (and so, 950*4 for 1 plane char matrix ?)

mmh.. this is still not really on what maximum size we should use.. 4*1024= 4096, so the performance problem should appear with 1025.. but in my example above it seem to appear suddenly with 1023 when using copyVectorToArray, and with 960 when using copyArrayToVector… ? And also, what is strange, when you look at my example, is that "copyVectorToArray_1_plane_test" is 4 times slower than "copyVectorToArrayPlanar", while copying exacty the same byte size.

Well, in the case you don’t have the answer, i think i should copy only little vectors of 200 pixels, the ones after the others, in order to be sure to stay far from the problem(**). I guess that, due to the low frequentation of this java forum, this is not one your "urgent-to-do" list, but let me suggest that one day you could also implement this "splitting" way of doing directly inside the copy***To*** methods. this way, everybody would never have to care about this anymore.

Thanks,
Alexandre

(**) : Hum.. 200 pixels: in fact, i’m not sure that this is the right thing to do when using copyVectorToArrayPlanar, as i just noticed that, in my example, copying vectors of 500 pixels with copyVectorToArrayPlanar takes 533 millisec while copying vectors of 250 pixels takes 435 millisec.. Strange again..


August 28, 2008 | 6:31 pm

On Aug 28, 2008, at 1:36 AM, Alexandre wrote:
>
> mmh.. this is still not really on what maximum size we should use..
> 4*1024= 4096, so the performance problem should appear with 1025..
> but in my example above it seem to appear suddenly with 1023 when
> using copyVectorToArray, and with 960 when using
> copyArrayToVector… ?

There’s no law anywhere, nor do I have anything more than empirical
evidence on this. The 4096 limit is just a guess based on your
example. Memory is typically allocated in blocks, so 1023 could be the
same as allocating 1024. If the allocation is 4096 bytes or larger, it
might use a different path in the JVM for managing the transmission of
the data between C and the JVM. Or there might be some additional
overhead w/r/t the JVM memory manager. I really don’t know, nor is it
a priority for us to explicitly quantify or document the JVM behavior.
Whatever you discover to be fastest, feel free to use. It’s really
more about the JVM than anything in the Jitter code. Please let us
know any bugs you discover, and we will fix them.

Btw, if you always use one relatively small array to copy back and
forth across the C/JVM boundary, it might be much faster than your
multidimensional array strategy–i.e. try using int row[] = new int
[size] to do the copying back and forth and then copy to/from any
bigger Java structure on the Java side. I’m particularly wary of
portions of the large multidimensional array being passed across the C/
JVM boundary as in int row[][] = new int [700] [size] ;

Sorry, but in general mxj Jitter performance is not a main priority
for us, as we are a small team of engineers working on a very large
feature set across multiple languages. If it is a big priority for
you, you are welcome to experiment further, as well as research other
resources on Java performance when crossing the C/JVM boundary and
make your own utility classes as you describe. For maximum
performance, please use C or GLSL.

-Joshua


August 28, 2008 | 8:56 pm

Thanks a lot for your advices. I understand better now.

> " I really don’t know, nor is it a priority for us to
> explicitly quantify or document the JVM behavior."

Let me suggest one last thing then: I’m wondering that a kind of "open wiki-documention for Max" might be usefull for everybody. I guess there are now so much Max users around the world, that if you just initiate it at cycling74.com (by only copying the actual doc in it), it might then be full of additionnal informations and extras tutorials, added by people, within few months… Actually, there’s always lots of things that we have to look for on the forum, or ask for, that are not on the standard Max doc(or a bit hidden), like "size-of-Max-lists behaviours" or so on… instead of searching every time on the forum or asking same things on it, we could just look in this wiki doc. And write new information. i would add two sentences to the "CopyArrayToMatrix" wiki-article resuming this discussion, and even if it helps only one other guy in the world reading it, that’s good. If you don’t have time to write detailed docs, just propose a nice wiki-page where people will do it for free, in your place. This will then make the software you sell, more powerfull, then more famous. if your are septic, just look at the following page, i wrote 85% of it, you’ll see the nice things that people like me like to do on their free time (in the case you can read french a bit!): http://fr.wikipedia.org/wiki/Tango

Regards,

Alexandre


May 30, 2009 | 6:25 am

I am also having some run time errors when I tried to use this function

int loc = 0;
int[] ripplePlane = new int[width*height];
int offset[] = new int[]{0,0};
rippleImage.copyVectorToArrayPlanar(1, 0, offset, ripplePlane, width*height, 0);

        for(int j=0;j

Can anyone suggest what is wrong with my code?


June 4, 2009 | 11:36 am

I am using max 5.0.5 but I have problem with "copyVectorToArrayPlanar"
I used following to copy but it crashed max/msp.
Are the issues with copyVectorToArrayPlanar fixed with this version of max?


June 4, 2009 | 2:51 pm

Sorry, i’m not sure what’s wrong with your code. For me, the methods are working. (And from what i remember, it have never crached with me) Maybe you could post a "complete" exemple code that crashes for you, to the Cycling technical support.

just one thing (but it have nothing to do with jitter methods) :
i think you wanted to write:
ripplePlane[i*j] = ripplePlane[j*loc];
instead of
ripplePlane[i+j] = ripplePlane[j+loc];
(to fill your image width*height)


June 4, 2009 | 5:18 pm

You are right.
There is some other problem with the code it is not crashing now.
But I am not sure whether the function is working or not ..
When I put the following it is running very fast.

int offset[] = new int[]{0,0};

        for(int k=1;k

When I put the following no effect on the display.

int offset[] = new int[]{0,0};

        for(int k=1;k

Any idea what is happening?

What is the second parameter in copyVectorToArrayPlanar?
Why do we put 0 when we copy 2D plane to the array
if it is 2D shouldn't we put 2 ?

also is copyVectorToArrayPlanar faster than copyVectorToArray?


June 4, 2009 | 5:20 pm

I get the feeling that copyVectorToArrayPlanar does not copy the data to rippleAllPlanes
The way I am using the function is it correct?


June 4, 2009 | 5:35 pm

hmm..
not totally sure but i think that "width*height" should not exceed the size of your vector in the image…, and that it can only copy a line from the image, so it should be only "width", and then you should use "for{…}" on that. you can look at my example patch and java code, attached to the first message of this topic to see how i was using them, and to compare efficiency.

>> What is the second parameter in copyVectorToArrayPlanar?

"dim – the dimension of the vector to copy"

=>look at Max5/java-doc/api-jitter/index.html
(if you don’t find it, dl the last 5.0.7 max version)

>> Why do we put 0 when we copy 2D plane to the array

0 stands for "a line", 1 stands for "a column"
got it?


June 4, 2009 | 6:08 pm

I thought the idea is to copy entire plane to an array. If we copy line by line isn’t it similar to copyVectorToArray?
What is the advantage of copyVectorToArrayPlanar?

Is the documentation available online?


June 9, 2009 | 4:34 pm

I somewhat sorted out my jit.matrix pixel changes. But now I am faced with a different type of problem when I try to change pixels…
In my java external application I am drawing into JitterMatrix using jit.gl.sketch then display the JitterMatrix in a window. My order of operations are;

(1)Draw some stuff using sketch to JitterMatrix
(2)Change the pixels in JitterMatrix
(3)Draw more stuff using sketch to JitterMatrix
(4) send the JitterMatrix to window

Logically I expected that (2) will change what I have drawn in (1) , then on top of the changes (3) will appear without any affect from (2)
But what I see is (3) is completely missing ????? only (1) and (2) working …
But If I comment out (2) I can see everything is drawn properly

Have you come across something like this before?
Any idea what is happening?

– Pasted Max Patch, click to expand. –

June 11, 2009 | 8:06 pm

>> I thought the idea is to copy entire plane to an array.
no, just a "line" or "vector". CopyMatrixToArray is copying the full image.

>> If we copy line by line isn’t it similar to copyVectorToArray?
copyVectorToArray and copyVectorToArrayPlanar are just able to copy a "line" or "vector" from the image. (i think)

>>What is the advantage of copyVectorToArrayPlanar?
copyVectorToArrayPlanar is doing it from just one plane (a,r,g or b).

>>Is the documentation available online?
now yes, just down here, as attachment in this message.

For your last message, sorry but i’m still a beginner with jitter and gl. good luck.


June 11, 2009 | 8:11 pm

Alexandre thanks for explaining this.
It all seems clear now …


Viewing 15 posts - 1 through 15 (of 15 total)