Re: Clojure, floats, ints and OpenGL
... as well core.matrix supports normalise, which I just reali*z*ed since I am American English. haha On Saturday, October 19, 2013 8:05:47 AM UTC-4, Chris Gill wrote: I am in this boat as well, clojure + opengl, currently using lwjgl for bindings and management. I am curious why you need float support actually, what specific methods are you hoping to utilize this with? Currently I create float-arrays from the loaded mesh and build the VBOs and push that all the to card the one time, this would be done for every mesh or combination of meshes. After that all work, for me at least, I use uniforms to manipulate the scene and so far have planned to do this through core.matrix to work with the uniforms-- I don't plan on using very many lwjgl functions since much of it seems geared towards pre-opengl 3 stuff. Performing matrix ops on 1000 objects doesn't seem out of the realm of what core.matrix can handle-- it's using ndarrays and seems quick so far. So my question is maybe you can skirt the issue? I don't really know your scenario, but what version of openGL do you plan on supporting? Keep in mind core.matrix even has some euclidean math built in such as length and distance. I based this off of a c++ example so it may be wrong as of yet-- haven't implemented as of now; here is normalize and lookat to fill in some more functions (using core.matrix): https://gist.github.com/viperscape/7055130 On Monday, September 9, 2013 9:43:12 AM UTC-4, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would like to know answers to the following questions: 1) What is the current reason for the support for these types to be missing? 2) Are there any plans for improvement of support for floats, ints and maybe, localized unboxed calculations? Or is there some advice on how to enable their support? 3) What is you vision for Clojure + OpenGL applications? 4) Is it possible to request support for floats, ints and maybe shorts for the language? 5) Is it possible to request support for localized unboxed calculations, like (with-unboxed ... ) and localized float-only and int-only calculations, like, say in special macros (with-floats--ints ... here go (+) (-) and stuff ONLY with floats/ints ... ) ? Preferably, I would like to hear the answers from somebody from the development team, because I have already
Re: Clojure, floats, ints and OpenGL
You can always fork Clojure and patch IFn.java and Compiler.java to support floats for at least some types of functions. It probably won't be so hard. As your case is a very specific one, this may be a viable solution. JW On Mon, Sep 16, 2013 at 11:40 PM, Alex Fowler alex.murat...@gmail.comwrote: Timothy, thank you very much for such a good explanation! I fully agree with you. Actually, except for a few details, that is really how I thought the things are. It is good that you describe the technical base for problems with the issue. As well as clearified the human factor. What you're saying is very much like what I would say if I were in your shoes. Currently, what you're saying, is the present. In the present we make our choices for currents. And I also agree with Mikera, that an attempt should be taken. I would participate in it myself if I was into JVM and Clojure internals. I plan to learn it, but it will take time. Mikera, thanks for the reference for the library, I will have a look. Also I strongly encourage you in the attempt and I will be happy if I can be of any help, although, you seem to know much more than me. I agree with Tim that some more decisive steps have to be taken into this direction. James, ah.. yes, we did benchmarks. We use highly optimized mathematical calculations, derived from numerical analysis. Every single instruction matters there. Due to the nature of the calculations, the amout of casts, however, varies from 3 to N in one computation. There can be 1 to M such computation for a data unit. And thre can be 1 to P data units. At the end, what worked on plain Java or Java-stylized Scala, worked that times faster, NxMxP more instructions to be computed. Where there were 500 fps, sometimes happen to be 480 fps and sometimes 0.01 fps. And I am not even talking about operations on vast arrays or NIO buffers. But imagine for example, you have a 1.5GB float NIO-buffer, that came from an OpenGL data-type and will go back to it. Operation on each float takes, say 5 casts double-float in Clojure. Also, as Mikera points out, bus speeds come into play too. Of course, as Timothy said, why don't we go back to C for that kind of stuff? This is a popular question in such cases. I am not going to go into details on that, except for saying that we have mostly migrated from C to JVM and it satisfies our requirements, while giving huge benifits. However, we still do some things in C. To prevent arguments, here is an articlehttp://beautynbits.blogspot.ru/2013/01/performance-java-vs-c.html that somewhat describes what one can lose in computation, but does not describe what one gains in other aspects. The loss is what can be tolerated. But that loss for JVM is understandable. The one more loss for Clojure is understandable too, but it can be changed. I think that the discussion branch of Java vs C may be laid to rest. On Mon, Sep 16, 2013 at 9:03 PM, James Reeves ja...@booleanknot.comwrote: On 16 September 2013 09:03, Mikera mike.r.anderson...@gmail.com wrote: Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java That's a pretty interesting result. I ran some tests of my own, based on your code, as I wondered whether or not the time to instantiate the array of doubles was biasing the test. My goal was to see whether or not I'd get a similar result running an array of floats through a method that processed doubles. (See: https://gist.github.com/weavejester/6583367) It turns out that I get a similar result. Passing floats to a method that takes doubles slows things down by a similar amount, unless I've somehow botched up the test. Considering that converting between single and double precision should be pretty cheap on the CPU, I'm surprised at the difference. This somewhat changes my view on things. It doesn't affect me in practice, but I can see how someone might be frustrated by having to drop down to Java to achieve performance for floating point calculations. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To
Re: Clojure, floats, ints and OpenGL
Please, no! Sure, forking Clojure is technically possible and might even solve the specific problem for the OP. But that's not the point. This isn't a technical problem, it's a social/organisational problem. The idea that we should fork Clojure (or even create an intricate clever new library that does some funky code generation) every time someone has a new performance requirement is going to be disastrous for the Clojure ecosystem. It will cause massive fragmentation and/or cause people to give up and abandon Clojure altogether. People have written extensively about the Lisp Curse and this is exactly the kind of dysfunction we should try to avoid. See e.g.: http://kresimirbojcic.com/2012/08/14/why-lisp-did-not-and-never-will-gain-enough-traction.html http://www.winestockwebdesign.com/Essays/Lisp_Curse.html The right answer is to figure out how to get these kind of core improvements into Clojure itself. That's harder to do. It requires people to work together and understand each others' requirements rather than just dismissing them (the well I don't need this so you should just find a workaround attitude isn't at all helpful). It requires engaging, cultivating and encouraging the people with the skill and motivation to to make these kind of improvements. It may require developing a proper roadmap for Clojure. It requires people to sign CAs and follow JIRA processes etc. But the effort to do this is worth it: this way everyone benefits from the development effort, we avoid creating a thousand different incompatible software stacks, and we make traction happen on Clojure development itself. Please note: my only reason for arguing passionately about this kind of stuff is to help Clojure succeed. Presumably that's what we would all like to see, or we wouldn't be here, right? On Tuesday, 17 September 2013 14:48:32 UTC+8, Jozef Wagner wrote: You can always fork Clojure and patch IFn.java and Compiler.java to support floats for at least some types of functions. It probably won't be so hard. As your case is a very specific one, this may be a viable solution. JW On Mon, Sep 16, 2013 at 11:40 PM, Alex Fowler alex.m...@gmail.comjavascript: wrote: Timothy, thank you very much for such a good explanation! I fully agree with you. Actually, except for a few details, that is really how I thought the things are. It is good that you describe the technical base for problems with the issue. As well as clearified the human factor. What you're saying is very much like what I would say if I were in your shoes. Currently, what you're saying, is the present. In the present we make our choices for currents. And I also agree with Mikera, that an attempt should be taken. I would participate in it myself if I was into JVM and Clojure internals. I plan to learn it, but it will take time. Mikera, thanks for the reference for the library, I will have a look. Also I strongly encourage you in the attempt and I will be happy if I can be of any help, although, you seem to know much more than me. I agree with Tim that some more decisive steps have to be taken into this direction. James, ah.. yes, we did benchmarks. We use highly optimized mathematical calculations, derived from numerical analysis. Every single instruction matters there. Due to the nature of the calculations, the amout of casts, however, varies from 3 to N in one computation. There can be 1 to M such computation for a data unit. And thre can be 1 to P data units. At the end, what worked on plain Java or Java-stylized Scala, worked that times faster, NxMxP more instructions to be computed. Where there were 500 fps, sometimes happen to be 480 fps and sometimes 0.01 fps. And I am not even talking about operations on vast arrays or NIO buffers. But imagine for example, you have a 1.5GB float NIO-buffer, that came from an OpenGL data-type and will go back to it. Operation on each float takes, say 5 casts double-float in Clojure. Also, as Mikera points out, bus speeds come into play too. Of course, as Timothy said, why don't we go back to C for that kind of stuff? This is a popular question in such cases. I am not going to go into details on that, except for saying that we have mostly migrated from C to JVM and it satisfies our requirements, while giving huge benifits. However, we still do some things in C. To prevent arguments, here is an articlehttp://beautynbits.blogspot.ru/2013/01/performance-java-vs-c.html that somewhat describes what one can lose in computation, but does not describe what one gains in other aspects. The loss is what can be tolerated. But that loss for JVM is understandable. The one more loss for Clojure is understandable too, but it can be changed. I think that the discussion branch of Java vs C may be laid to rest. On Mon, Sep 16, 2013 at 9:03 PM, James Reeves ja...@booleanknot.comjavascript: wrote: On 16 September 2013 09:03,
Re: Clojure, floats, ints and OpenGL
Here is the mundane patch I described earlier: https://github.com/cgrand/clojure/commit/4c202ad9757ce47ac9e669847c0e5bf68785e2d6 It adds four functions (add-, multiply-, divide- and subtract-float), backs them with their corresponding bytecodes and enhance the conversion emitted when going from long/int to double/float. Please give it a try. It doesn't help with functions taking primitive but it's another problem. Christophe On Mon, Sep 16, 2013 at 7:03 PM, James Reeves ja...@booleanknot.com wrote: On 16 September 2013 09:03, Mikera mike.r.anderson...@gmail.com wrote: Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java That's a pretty interesting result. I ran some tests of my own, based on your code, as I wondered whether or not the time to instantiate the array of doubles was biasing the test. My goal was to see whether or not I'd get a similar result running an array of floats through a method that processed doubles. (See: https://gist.github.com/weavejester/6583367) It turns out that I get a similar result. Passing floats to a method that takes doubles slows things down by a similar amount, unless I've somehow botched up the test. Considering that converting between single and double precision should be pretty cheap on the CPU, I'm surprised at the difference. This somewhat changes my view on things. It doesn't affect me in practice, but I can see how someone might be frustrated by having to drop down to Java to achieve performance for floating point calculations. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
I ported Mikera's benchmark to Clojure using my patch https://gist.github.com/cgrand/6595939 The ratio between time-float and time-double (0.632) is very similar to the ratio between timeFloat and timeDouble Mikera reported (0.618) On Tue, Sep 17, 2013 at 1:25 PM, Christophe Grand christo...@cgrand.netwrote: Here is the mundane patch I described earlier: https://github.com/cgrand/clojure/commit/4c202ad9757ce47ac9e669847c0e5bf68785e2d6 It adds four functions (add-, multiply-, divide- and subtract-float), backs them with their corresponding bytecodes and enhance the conversion emitted when going from long/int to double/float. Please give it a try. It doesn't help with functions taking primitive but it's another problem. Christophe On Mon, Sep 16, 2013 at 7:03 PM, James Reeves ja...@booleanknot.comwrote: On 16 September 2013 09:03, Mikera mike.r.anderson...@gmail.com wrote: Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java That's a pretty interesting result. I ran some tests of my own, based on your code, as I wondered whether or not the time to instantiate the array of doubles was biasing the test. My goal was to see whether or not I'd get a similar result running an array of floats through a method that processed doubles. (See: https://gist.github.com/weavejester/6583367) It turns out that I get a similar result. Passing floats to a method that takes doubles slows things down by a similar amount, unless I've somehow botched up the test. Considering that converting between single and double precision should be pretty cheap on the CPU, I'm surprised at the difference. This somewhat changes my view on things. It doesn't affect me in practice, but I can see how someone might be frustrated by having to drop down to Java to achieve performance for floating point calculations. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
Hi Christophe, Looks like a good patch to me - would you be able to submit it to JIRA? I already submitted an issue to add primitive support for statically compiled functions (http://dev.clojure.org/jira/browse/CLJ-1263) which I think would complement yours nicely. The combination of the two should give float support that is comparable to Java in most cases. On Tuesday, 17 September 2013 19:25:04 UTC+8, Christophe Grand wrote: Here is the mundane patch I described earlier: https://github.com/cgrand/clojure/commit/4c202ad9757ce47ac9e669847c0e5bf68785e2d6 It adds four functions (add-, multiply-, divide- and subtract-float), backs them with their corresponding bytecodes and enhance the conversion emitted when going from long/int to double/float. Please give it a try. It doesn't help with functions taking primitive but it's another problem. Christophe On Mon, Sep 16, 2013 at 7:03 PM, James Reeves ja...@booleanknot.comjavascript: wrote: On 16 September 2013 09:03, Mikera mike.r.an...@gmail.com javascript:wrote: Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java That's a pretty interesting result. I ran some tests of my own, based on your code, as I wondered whether or not the time to instantiate the array of doubles was biasing the test. My goal was to see whether or not I'd get a similar result running an array of floats through a method that processed doubles. (See: https://gist.github.com/weavejester/6583367) It turns out that I get a similar result. Passing floats to a method that takes doubles slows things down by a similar amount, unless I've somehow botched up the test. Considering that converting between single and double precision should be pretty cheap on the CPU, I'm surprised at the difference. This somewhat changes my view on things. It doesn't affect me in practice, but I can see how someone might be frustrated by having to drop down to Java to achieve performance for floating point calculations. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
Hi Alex, Just one more thing to think about: Dmitry Groshev has been doing some good early work on Clojure float support in the core.matrix NDArray implementation (basically a NumPy-style multidimensional array implementation backed by a single large float[] array). The per-object overhead is probably too high for it to be useful as a Vertex3f replacement, but it might fit some of your use cases, particularly when you have a large number of float values to manipulate at the same time (physics, wave simulation, mesh deformation etc). It avoids the current Clojure limitations on float function arguments by using custom macros to compile all the inner loops. Quite clever stuff. Mike. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would like to know answers to the following questions: 1) What is the current reason for the support for these types to be missing? 2) Are there any plans for improvement of support for floats, ints and maybe, localized unboxed calculations? Or is there some advice on how to enable their support? 3) What is you vision for Clojure + OpenGL applications? 4) Is it possible to request support for floats, ints and maybe shorts for the language? 5) Is it possible to request support for localized unboxed calculations, like (with-unboxed ... ) and localized float-only and int-only calculations, like, say in special macros (with-floats--ints ... here go (+) (-) and stuff ONLY with floats/ints ... ) ? Preferably, I would like to hear the answers from somebody from the development team, because I have already received enough support from the community, on the IRC, I appreciate it, but now I have to make a serious choice for our company and I feel quite responsible for that. I also feel that these questions are very important for any specialist that works with OpenGL and influence Clojure acceptance for OpenGL-enabled applications world-wide. Thank you. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at
Re: Clojure, floats, ints and OpenGL
On Saturday, 14 September 2013 00:36:05 UTC+8, James Reeves wrote: On 13 September 2013 08:54, Mikera mike.r.an...@gmail.com javascript:wrote: Either way, if Clojure's semantics prove to be a fundamental issue for performance, then I think it is better to start work to improve Clojure's semantics (perhaps targeting 2.0 if we think it's a really big breaking change). This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. I'd rather see a bit of breakage and fix my code when upgrading to Clojure 2.0 than be stuck with poor performance forever. Out of curiosity, what is the performance hit in these cases? Here's a quick highly artificial benchmark I did with Caliper in Java (Obviously can't benchmark in Clojure since we don't have proper float support) 0% Scenario{vm=java, trial=0, benchmark=Float} 267222.79 ns; σ=1629.43 ns @ 3 trials 50% Scenario{vm=java, trial=0, benchmark=Double} 416110.28 ns; σ=2087.75 ns @ 3 trials benchmark us linear runtime Float 267 === Double 416 == vm: java trial: 0 Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java Floats obviously save memory, and I believe they're also between 15% to 40% more efficient for division, at least on Intel CPUs. Is there also a cost to be paid passing doubles to OpenGL? Do you know what that cost is? I'm not exactly an expert in OpenGL, but I would make the following points: - Many GPU applications are actually memory-bandwidth bound (the compute power is insane). So using floats means you can pump through 2x as much data to keep your GPUs busy - Hardware and driver support is usually not on a par with floats, even if it is technically supported by the OpenGL API This is an interesting article to back up the latter point: For example on NVidia GeForce hardware doubles are 1/8 the speed of floats http://blog.hvidtfeldts.net/index.php/2012/07/double-precision-in-opengl-and-webgl/ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
Hi Mikera, I don't have a whole lot of skin in this game as, unfortunately, I haven't run into any performance bottlenecks that I couldn't fix in a satisfying way whilst writing Clojure. My impression, however, is that there are some people in the community who feel the performance limitations of some of Clojure's core design decisions. I've been following this discussion as it's going on and it seems like it's winding down in the same way I've watched many such discussions wind down in the past: Can we please get an official word from Rich whether this would be worth someone's time? That's usually where these things die. So have you considered writing up a more formal proposal, maybe with some very rough sketches of how you might envision implementing things, and actually sending it to Rich (or maybe at this point Alex Miller)? Ideally this wouldn't be something as time consuming as a full prototype but would be more than just some thoughts scratched out on mail. I think he basically doesn't read this list or visit IRC anymore and getting heard here on something like design directions for Clojure seems like a fool's errand. Anyway, I like being able to follow these discussions on the mailing list and I think the mailing list is still a good place to gauge interest and get some thoughts on design direction (Timothy's been doing a great job lately of bringing up edge cases that may not have been considered), but I think you'll probably never see an official word on Clojure here. Keep up the good work! -- In Christ, Timmy V. http://blog.twonegatives.com/ http://five.sentenc.es/ -- Spend less time on mail -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
On 16 September 2013 09:03, Mikera mike.r.anderson...@gmail.com wrote: Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java That's a pretty interesting result. I ran some tests of my own, based on your code, as I wondered whether or not the time to instantiate the array of doubles was biasing the test. My goal was to see whether or not I'd get a similar result running an array of floats through a method that processed doubles. (See: https://gist.github.com/weavejester/6583367) It turns out that I get a similar result. Passing floats to a method that takes doubles slows things down by a similar amount, unless I've somehow botched up the test. Considering that converting between single and double precision should be pretty cheap on the CPU, I'm surprised at the difference. This somewhat changes my view on things. It doesn't affect me in practice, but I can see how someone might be frustrated by having to drop down to Java to achieve performance for floating point calculations. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
Timothy, thank you very much for such a good explanation! I fully agree with you. Actually, except for a few details, that is really how I thought the things are. It is good that you describe the technical base for problems with the issue. As well as clearified the human factor. What you're saying is very much like what I would say if I were in your shoes. Currently, what you're saying, is the present. In the present we make our choices for currents. And I also agree with Mikera, that an attempt should be taken. I would participate in it myself if I was into JVM and Clojure internals. I plan to learn it, but it will take time. Mikera, thanks for the reference for the library, I will have a look. Also I strongly encourage you in the attempt and I will be happy if I can be of any help, although, you seem to know much more than me. I agree with Tim that some more decisive steps have to be taken into this direction. James, ah.. yes, we did benchmarks. We use highly optimized mathematical calculations, derived from numerical analysis. Every single instruction matters there. Due to the nature of the calculations, the amout of casts, however, varies from 3 to N in one computation. There can be 1 to M such computation for a data unit. And thre can be 1 to P data units. At the end, what worked on plain Java or Java-stylized Scala, worked that times faster, NxMxP more instructions to be computed. Where there were 500 fps, sometimes happen to be 480 fps and sometimes 0.01 fps. And I am not even talking about operations on vast arrays or NIO buffers. But imagine for example, you have a 1.5GB float NIO-buffer, that came from an OpenGL data-type and will go back to it. Operation on each float takes, say 5 casts double-float in Clojure. Also, as Mikera points out, bus speeds come into play too. Of course, as Timothy said, why don't we go back to C for that kind of stuff? This is a popular question in such cases. I am not going to go into details on that, except for saying that we have mostly migrated from C to JVM and it satisfies our requirements, while giving huge benifits. However, we still do some things in C. To prevent arguments, here is an articlehttp://beautynbits.blogspot.ru/2013/01/performance-java-vs-c.html that somewhat describes what one can lose in computation, but does not describe what one gains in other aspects. The loss is what can be tolerated. But that loss for JVM is understandable. The one more loss for Clojure is understandable too, but it can be changed. I think that the discussion branch of Java vs C may be laid to rest. On Mon, Sep 16, 2013 at 9:03 PM, James Reeves ja...@booleanknot.com wrote: On 16 September 2013 09:03, Mikera mike.r.anderson...@gmail.com wrote: Obviously this is just a microbenchmark, but it fits my general experience that floats are a reasonable bit faster than doubles, typically 20-100% (doubles are closer when it is pure number crunching since 64-bit CPUs are actually pretty good at doubles, floats have a bigger advantage when you are manipulating a lot of data points and hence memory bandwidth matters more) Code here for those interested: src/test/java/mikera/vectorz/performance/FloatVsDoubleBenchmark.java That's a pretty interesting result. I ran some tests of my own, based on your code, as I wondered whether or not the time to instantiate the array of doubles was biasing the test. My goal was to see whether or not I'd get a similar result running an array of floats through a method that processed doubles. (See: https://gist.github.com/weavejester/6583367) It turns out that I get a similar result. Passing floats to a method that takes doubles slows things down by a similar amount, unless I've somehow botched up the test. Considering that converting between single and double precision should be pretty cheap on the CPU, I'm surprised at the difference. This somewhat changes my view on things. It doesn't affect me in practice, but I can see how someone might be frustrated by having to drop down to Java to achieve performance for floating point calculations. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/H5P25eYKBj4/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the
Re: Clojure, floats, ints and OpenGL
How are you going to recompile at all, when the compiler doesn't store the source code of functions after it compiles them? This is why this proposal needs to have a working prototype, to prove that these ideas actually work, until then proposals don't do much at all. Personally I don't see how the ideas in this proposal would work from the repl, and the repl is where most people do their work. On Sep 14, 2013 10:55 PM, Mikera mike.r.anderson...@gmail.com wrote: On Saturday, 14 September 2013 01:04:16 UTC+8, tbc++ wrote: This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. You're going to have a hard time convincing people to give up some of the dynamism of Clojure just for the sake of more performance. Especially considering that many Clojure users are perfectly okay with boxed values, let alone need floats or other primitives. Let's be clear - I'm not asking anyone to give up on any dynamism. I am asking for an agreement that we want to allow high performance *options* in Clojure, so that we can at least match Scala/Java, for those use cases where people have genuine performance requirements. Some people don't care about performance enough for the distinction between float and double to matter. But others do. I think we (as a community) should try to support both use cases. Clojure has the potential to be *both* dynamic and fast if we design it right. It would be a shame if people in the community took a general stance that performance is good enough for me, so we aren't interested in supporting further performance improvements. I'm sure that isn't what is intended, but it could appear like that to people who raise performance issues only to get challenged / told that they don't have a valid problem. But what you are describing creates a whole ton of new problems, problems I don't see a good solution for. What you are describing would require the recompilation of entire source trees when a inner function is modified. So now we're in the Scala/Java land of recompile after every edit. Perhaps there's a use-case for invoke dynamic here, but now you're talking about breaking backwards compatibility for everyone not using Java 7+. I'm not suggesting recompile everything after edit. I'm suggesting lazily recompile stuff that is dependent on the one thing you changed. That's a much smaller compilation unit in most cases - maybe you are recompiling 2-5 functions instead of 1. If you change something that is used everywhere in your whole app, then yes: maybe it's going to recompile 100 or so functions. But even then, I doubt it will be a significant compile time compared to Java/Scala land. And note that we're talking about incurring this cost only for people doing dynamic changes to existing vars. This isn't common production usage (if you are mutating production state, I would hope you are using something with proper concurrency semantics like atoms or agents or refs to mutate data!). So performance probably shouldn't matter at all, apart from the subjective experience of compiling fast enough to be usable at the REPL. Which I'm pretty sure is a fairly easy target to hit. Like I said, this would be a big change, but it would be a good way to combine dynamism with excellent runtime performance. I'll be the first to admit that I'd like to rewrite the Clojure compiler as a true multi-pass optimizing compiler. But that's a task I haven't undertaken for two reasons 1) it's a ton of work that would take months (if not years) to reach the level of performance currently offered by Clojure. 2) I really don't need it. Every time I need that level of performance I drop to Java, CUDA or some other high performance toolkit. Personally I think it would be much better for someone to come up with a typed lisp that interops very cleanly with Clojure. That way you can build your inner kernels using a lisp-like language, and then glue it together with Clojure. But let me close by saying, if you really want better primitives, I'd suggest writing up a proposal for how it would work, perhaps even with some example using macros and genclass. Until then we don't have anything to go off of, people say I'd love to have feature X, well we all would, but all the suggestions thus far won't work, so how do you plan on fixing that? My pragmatic proposal for now is very simple: allow metadata to specify functions to be compiled in a way that invocation is compiled statically to an invokevirtual. You lose the dynamic var deref, but gain better runtime performance and the ability to use arbitrary types / primitives (which solves the OP's problem). This limited-scope proposal won't effect any existing dynamic usage, so people who like their fully mutable vars with their dynamic lookups can keep them. It is on JIRA as CLJ-1263 , comments / improvements welcome.
Re: Clojure, floats, ints and OpenGL
Hi Timothy, Clearly, the partial dynamic recompilation feature depends on storing enough information to actually perform the recompile. You could store either the source, or some sort of transformed AST. There are many ways to make this kind of system work - at the REPL or otherwise (but I agree the main benefit would be in supporting dynamic REPL-based usage). I personally think the best solution would be to store raw source forms as function metadata, but happy to be convinced otherwise. Incidentally, storing the source and/or AST could have various other beneficial uses - see e.g. this discussion from a few months back: https://groups.google.com/d/topic/clojure-dev/WvpqRUSH-y8/discussion I agree we'd want a prototype, but that's the wrong next step IMHO. Ideally Rich (or some other official maintainer) should confirm that this is a direction we want to explore, otherwise there is little point taking the time to speculatively build a non-trivial prototype of functionality that might never be accepted. I'm certain there would be people with the skill, motivation and energy in the community to prototype and develop the feature, as long as it had official blessing (perhaps as some sort of Clojure 2.0 roadmap, if such a thing exists?). This sort of thing should probably also be coordinated with other efforts that touch upon related issues (core.typed, CinC, tools.analyzer etc.) If there is genuine interest in this, I'm happy to write up a more detailed explanation / proposal of why it is valuable, how it might work and what the trade-offs would be. If it subsequently gets official approval on a Clojure roadmap, I'll be happy to contribute prototype work / patches (at least as far as my modest compiler-writing skills allow). Money where mouth is, and all that :-) On Sunday, 15 September 2013 22:16:38 UTC+8, tbc++ wrote: How are you going to recompile at all, when the compiler doesn't store the source code of functions after it compiles them? This is why this proposal needs to have a working prototype, to prove that these ideas actually work, until then proposals don't do much at all. Personally I don't see how the ideas in this proposal would work from the repl, and the repl is where most people do their work. On Sep 14, 2013 10:55 PM, Mikera mike.r.an...@gmail.com javascript: wrote: On Saturday, 14 September 2013 01:04:16 UTC+8, tbc++ wrote: This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. You're going to have a hard time convincing people to give up some of the dynamism of Clojure just for the sake of more performance. Especially considering that many Clojure users are perfectly okay with boxed values, let alone need floats or other primitives. Let's be clear - I'm not asking anyone to give up on any dynamism. I am asking for an agreement that we want to allow high performance *options* in Clojure, so that we can at least match Scala/Java, for those use cases where people have genuine performance requirements. Some people don't care about performance enough for the distinction between float and double to matter. But others do. I think we (as a community) should try to support both use cases. Clojure has the potential to be *both* dynamic and fast if we design it right. It would be a shame if people in the community took a general stance that performance is good enough for me, so we aren't interested in supporting further performance improvements. I'm sure that isn't what is intended, but it could appear like that to people who raise performance issues only to get challenged / told that they don't have a valid problem. But what you are describing creates a whole ton of new problems, problems I don't see a good solution for. What you are describing would require the recompilation of entire source trees when a inner function is modified. So now we're in the Scala/Java land of recompile after every edit. Perhaps there's a use-case for invoke dynamic here, but now you're talking about breaking backwards compatibility for everyone not using Java 7+. I'm not suggesting recompile everything after edit. I'm suggesting lazily recompile stuff that is dependent on the one thing you changed. That's a much smaller compilation unit in most cases - maybe you are recompiling 2-5 functions instead of 1. If you change something that is used everywhere in your whole app, then yes: maybe it's going to recompile 100 or so functions. But even then, I doubt it will be a significant compile time compared to Java/Scala land. And note that we're talking about incurring this cost only for people doing dynamic changes to existing vars. This isn't common production usage (if you are mutating production state, I would hope you are using something with proper concurrency semantics like atoms or agents or refs to mutate data!). So
Re: Clojure, floats, ints and OpenGL
Hi Timothy, Clearly, the partial dynamic recompilation feature depends on storing enough information to actually perform the recompile. You could store either the source, or some sort of transformed AST. There are many ways to make this kind of system work - at the REPL or otherwise (but I agree the main benefit would be in supporting dynamic REPL-based usage). I personally think the best solution would be to store raw source forms as function metadata, but happy to be convinced otherwise. Incidentally, storing the source and/or AST could have various other beneficial uses - see e.g. this discussion from a few months back: https://groups.google.com/d/topic/clojure-dev/WvpqRUSH-y8/discussion I agree we'd want a prototype, but that's the wrong next step IMHO. Ideally Rich (or some other official maintainer) should confirm that this is a direction we want to explore, otherwise there is little point taking the time to speculatively build a non-trivial prototype of functionality that might never be accepted. I'm certain there would be people with the skill, motivation and energy in the community to prototype and develop the feature, as long as it had official blessing (perhaps as some sort of Clojure 2.0 roadmap, if such a thing exists?). This sort of thing should probably also be coordinated with other efforts that touch upon related issues (core.typed, CinC, tools.analyzer etc.) If there is genuine interest in this, I'm happy to write up a more detailed explanation / proposal of why it is valuable, how it might work and what the trade-offs would be. If it subsequently gets official approval on a Clojure roadmap, I'll be happy to contribute prototype work / patches (at least as far as my modest compiler-writing skills allow). Money where mouth is, and all that :-) On Sunday, 15 September 2013 22:16:38 UTC+8, tbc++ wrote: How are you going to recompile at all, when the compiler doesn't store the source code of functions after it compiles them? This is why this proposal needs to have a working prototype, to prove that these ideas actually work, until then proposals don't do much at all. Personally I don't see how the ideas in this proposal would work from the repl, and the repl is where most people do their work. On Sep 14, 2013 10:55 PM, Mikera mike.r.an...@gmail.com javascript: wrote: On Saturday, 14 September 2013 01:04:16 UTC+8, tbc++ wrote: This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. You're going to have a hard time convincing people to give up some of the dynamism of Clojure just for the sake of more performance. Especially considering that many Clojure users are perfectly okay with boxed values, let alone need floats or other primitives. Let's be clear - I'm not asking anyone to give up on any dynamism. I am asking for an agreement that we want to allow high performance *options* in Clojure, so that we can at least match Scala/Java, for those use cases where people have genuine performance requirements. Some people don't care about performance enough for the distinction between float and double to matter. But others do. I think we (as a community) should try to support both use cases. Clojure has the potential to be *both* dynamic and fast if we design it right. It would be a shame if people in the community took a general stance that performance is good enough for me, so we aren't interested in supporting further performance improvements. I'm sure that isn't what is intended, but it could appear like that to people who raise performance issues only to get challenged / told that they don't have a valid problem. But what you are describing creates a whole ton of new problems, problems I don't see a good solution for. What you are describing would require the recompilation of entire source trees when a inner function is modified. So now we're in the Scala/Java land of recompile after every edit. Perhaps there's a use-case for invoke dynamic here, but now you're talking about breaking backwards compatibility for everyone not using Java 7+. I'm not suggesting recompile everything after edit. I'm suggesting lazily recompile stuff that is dependent on the one thing you changed. That's a much smaller compilation unit in most cases - maybe you are recompiling 2-5 functions instead of 1. If you change something that is used everywhere in your whole app, then yes: maybe it's going to recompile 100 or so functions. But even then, I doubt it will be a significant compile time compared to Java/Scala land. And note that we're talking about incurring this cost only for people doing dynamic changes to existing vars. This isn't common production usage (if you are mutating production state, I would hope you are using something with proper concurrency semantics like atoms or agents or refs to mutate data!). So
Re: Clojure, floats, ints and OpenGL
Timothy, thanks,for giving a thorough answer to my questions, I appreciate this! As far as I understood, you did some work for Clojure team, and you have the necessary knowledge to express a knowing opinion on what are the implications of the matter. That was one of the things I wanted to know - the cause of the present situation. However, still I don't understand (although you mentioned a reason) why no one from the core team gives a definite, cut-off answer, like the one, Mikera is also asking for - what is for the future? Probably, as somebody mentioned here (sorry, I look and can't find the message, deleted?), the question would probably be better addressed to clojure-dev. But I have no good knowledge of Clojure internals and would be easily suppressed by an answer of a person, showing a technical knowledge, like yours. Yes, I understand what you're saying, but I do not have knowledge of Clojure or JVM to answer you on par. Simply I do not know what to say, although I feel there is a break between JVM and Clojure that should not be. And I feel, that you have a right in what you're saying - you know the language, you know the people here, more than me. But not to let a discussion on such a topic to die, here I am glad that Mikera, someone who has that knowledge, can sympathise me and say what I cannot say. James, for some numbers on OpenGL penalties, please refer to message #6 in thread (my initial answer for Timothy). You can also google on it, I am sure, you will find more information, or, why not, simply call NVIDIA or ATI support lines, and ask them. A perfectly valid question for them to consult you on :) As for more Java-friendly answers, you might also be interested in asking on LWJGL or JOGL forums. Personally I work with OpenGL for quite a long time already. Even when we were on C/C++ we never used doubles. Then we went Java, and there too, doubles are nowhere. One of the cornerstone computational workhorses of LWJGL, for example, the class Vertex3f, has no double version. And that is for a reason, not because Java bindings are bad and we must go C-plus-plusing now. Probably, after 10 years we will have only doubles and longs on GPUs... do you believe in it? Why we need them there at all? I still strongly believe that primitives support should be made one of the highest priorities to support. Lets look from a perspective of someone who researches the language, considering if to adhere to it. Here is a couple of frustrations that hit me so much that I think could even diverse somone from using the language. Warning: the following three points may cause rage in some individuals (they do cause a rage in me at least, because I really like Clojure) : 1) Clojure is said to be data-oriented. Rich Hickey says that in the videos. Cool! I have a stream of millions floats and ints to be processed on the fly! Now we find that it is not data-oriented. It is double, long and Object oriented. Data does not just come as information it comes with its data-type. Bending data-sources and data-consumers to your will usually does not sign a good data-processing. 2) Clojure is said to make simple things easy. Alright, that's a PC in front of me? With a JVM? Alright, I want to add,multiply, divide and subtract some billion floats. What could be simpler?... Uh... typehints.. alright, sure JVM is typed, we have types in Java and Scala, that's ok! Oh, only local... oh, still always returns doubles... err.. boxed? Cast? Oh... 3) As Mikera pointed out, some libraries, like fast arrays on Clojure is just.. a little bit too much. Are they faster than Java arrays? A library that implements fast arrays for a language that runs on a VM that has fast arrays? For a language, claimed to be perfect for data-processing? There is nothing wrong with the library, I think it is a masterpiece, but something scares me here. Surely, preserving semantics while letting full primitives support for Clojure, as it is right now, is a challenge. I really like the symantics as it is now, but the cost is too great. The examples that Timothy and Mikera are discussing right now is a problem. Some my ideas, although I am not as professional with them and some of them might not make sense at all (sorry): 1) In computations you do not often use functions that compute floats to compute ints instead. Usually you know what are you computing. I wouldn't switch, say spatial vector calculations from floats to ints under any circumstances. Remember Java - when you write signatures of your computational functions - how often do you change types? float-double or int-long maybe, but still not likely. Even on a lisp. 2) That leads to the other question - what if you *still* somehow want to reuse a computational function for other types? Well, maybe you could make functions named (+f) or (+i)? Or have a macros that builds them for you and calls them for you? 3) To simplify furhter: can a
Re: Clojure, floats, ints and OpenGL
7) Maybe genclass and stuff can still get away as it is now, falling back to boxing and reduced number of types? Or special genclass metadata hints be introduced? Still, not everyone will use that. But those who will, could spare a couple more hints to the compiler.. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
Excuse me, when I said Vertex3f I meant Vector3f. суббота, 14 сентября 2013 г., 15:14:01 UTC+4 пользователь Alex Fowler написал: Timothy, thanks,for giving a thorough answer to my questions, I appreciate this! As far as I understood, you did some work for Clojure team, and you have the necessary knowledge to express a knowing opinion on what are the implications of the matter. That was one of the things I wanted to know - the cause of the present situation. However, still I don't understand (although you mentioned a reason) why no one from the core team gives a definite, cut-off answer, like the one, Mikera is also asking for - what is for the future? Probably, as somebody mentioned here (sorry, I look and can't find the message, deleted?), the question would probably be better addressed to clojure-dev. But I have no good knowledge of Clojure internals and would be easily suppressed by an answer of a person, showing a technical knowledge, like yours. Yes, I understand what you're saying, but I do not have knowledge of Clojure or JVM to answer you on par. Simply I do not know what to say, although I feel there is a break between JVM and Clojure that should not be. And I feel, that you have a right in what you're saying - you know the language, you know the people here, more than me. But not to let a discussion on such a topic to die, here I am glad that Mikera, someone who has that knowledge, can sympathise me and say what I cannot say. James, for some numbers on OpenGL penalties, please refer to message #6 in thread (my initial answer for Timothy). You can also google on it, I am sure, you will find more information, or, why not, simply call NVIDIA or ATI support lines, and ask them. A perfectly valid question for them to consult you on :) As for more Java-friendly answers, you might also be interested in asking on LWJGL or JOGL forums. Personally I work with OpenGL for quite a long time already. Even when we were on C/C++ we never used doubles. Then we went Java, and there too, doubles are nowhere. One of the cornerstone computational workhorses of LWJGL, for example, the class Vertex3f, has no double version. And that is for a reason, not because Java bindings are bad and we must go C-plus-plusing now. Probably, after 10 years we will have only doubles and longs on GPUs... do you believe in it? Why we need them there at all? I still strongly believe that primitives support should be made one of the highest priorities to support. Lets look from a perspective of someone who researches the language, considering if to adhere to it. Here is a couple of frustrations that hit me so much that I think could even diverse somone from using the language. Warning: the following three points may cause rage in some individuals (they do cause a rage in me at least, because I really like Clojure) : 1) Clojure is said to be data-oriented. Rich Hickey says that in the videos. Cool! I have a stream of millions floats and ints to be processed on the fly! Now we find that it is not data-oriented. It is double, long and Object oriented. Data does not just come as information it comes with its data-type. Bending data-sources and data-consumers to your will usually does not sign a good data-processing. 2) Clojure is said to make simple things easy. Alright, that's a PC in front of me? With a JVM? Alright, I want to add,multiply, divide and subtract some billion floats. What could be simpler?... Uh... typehints.. alright, sure JVM is typed, we have types in Java and Scala, that's ok! Oh, only local... oh, still always returns doubles... err.. boxed? Cast? Oh... 3) As Mikera pointed out, some libraries, like fast arrays on Clojure is just.. a little bit too much. Are they faster than Java arrays? A library that implements fast arrays for a language that runs on a VM that has fast arrays? For a language, claimed to be perfect for data-processing? There is nothing wrong with the library, I think it is a masterpiece, but something scares me here. Surely, preserving semantics while letting full primitives support for Clojure, as it is right now, is a challenge. I really like the symantics as it is now, but the cost is too great. The examples that Timothy and Mikera are discussing right now is a problem. Some my ideas, although I am not as professional with them and some of them might not make sense at all (sorry): 1) In computations you do not often use functions that compute floats to compute ints instead. Usually you know what are you computing. I wouldn't switch, say spatial vector calculations from floats to ints under any circumstances. Remember Java - when you write signatures of your computational functions - how often do you change types? float-double or int-long maybe, but still not likely. Even on a lisp. 2) That leads to the other question - what if you *still* somehow want to reuse
Re: Clojure, floats, ints and OpenGL
1) Clojure is said to be data-oriented. Well it is, it's just that your definition of data is radically different from the normal business use case. In the line of work I'm in, big data is millions of hash maps filled with heterogeneous data types. In these cases, Clojure really shines. 2) Clojure is said to make simple things easy. That's a tad debatable. I would say that Clojure simplifies your code, therefore allowing for easier reasoning about that code. One of the ways it accomplishes this by being a dynamic language. And that right there hits on the main reason you're experiencing problems. This simplicity doesn't come without a cost. There are many trade-offs Clojure makes. Immutable data-structures are fast, but not as fast as mutable structures. Clojure allows for REPL based development at the cost of requiring that every function must go through a var deref. This cost is low (very low thanks to the JVM), but it still exists. And we see this cost when it comes to primitives. In languages like Scala and Java you know exactly what functions every function will call, and so you can link it to the exact overload needed for the primitives in use. However, in Clojure, at any moment a def (var) could be changed at the REPL, and we have to pick that up without problems. In return you have the ability to program without having to re-compile at every step. The same thing applies with type hinting in general. No other dynamic language offers the performance of Clojure. Python is used heavily by the scientific community, and yet it boxes everything. It doesn't support floats, let alone unboxing. So Clojure really should be viewed as a super fast dynamic language, not as a slow Scala/Java clone. I think this is clearly exemplified by Fressian ( https://github.com/Datomic/fressian), this is the serialization library used by Datomic (also written by Rich Hickey). Notice something interesting about this codebase. It almost 100% java (except for the tests, those are in Clojure). Why? Because serialization libraries need to be lean, fast, and are mostly side-effecting, this is a use case Java excels at. Now I've never seen the inner workings of Datomic, but I've heard it said the database is written in Clojure. So that's interesting...it's a set of Java libraries (for performance) glued together and controlled by Clojure (for simplicity). When Clojure people talk about simplicity what we're really railing against is the complexity of orchestrating large projects using a OOP language like Java. Write your data processing routines as static java members that take float arrays and emit float arrays and you're going to do quite well. One other thing you touched on is the idea that no one has given you a straight answer on this yet. And I think this comes down to several things: a) No one wants to speak for Rich. When it comes down to it, Clojure is his baby, so no one but him has the authority to say this is a focus for version X. He doesn't hang out on the mailing lists a whole lot, so perhaps an email to him might do well, or even to clojure-dev. b) No one has a clue on how to implement this without changing Clojure semantics. And changing the semantics of a language just to support a single use case is one of the best ways to get your patch rejected by Rich. :-) c) I want to make this point as carefully as possible...there's little incentive for anyone (including Rich) to implement this. If you came to me an said Tim...we want to pay double your current salary for the next year and have you re-write the Clojure compiler from scratch to support these features, I might actually do that. But sadly, I have a day job, and making massive changes to the Clojure compiler is not something I plan on spending my time on this year. Perhaps at some point a corporation will offer paid support for Clojure and then things like this can be possible. As the saying goes, money talks. Offer enough money and people will get more motivated to help. I know this point isn't very nice to hear from the OSS world, but the sad fact of it is, you seem to have a unique use case, and until the people with the knowledge of the system have the need of that same use case, nothing is going to happen. That being said, if someone hired me to write a video editor (as I've done some work in that area in the past), I'd probably write it in either C (for SSE support), CUDA/OpenCL, or perhaps bare Java, and once again, I'd glue my library together with Clojure code. Writing the image processing code for 4K video at 48fps in a dynamic language is a joke. Unless you're the people who write PyPy, but then again, I'm convinced that those people are mostly insane :-). So there it is, it's not going to change soon (if ever), and you probably won't get much feedback from others unless you start offering money. But once again I want to come back to something I've said a lot in this conversation: I work with Clojure a lot. If someone came to me
Re: Clojure, floats, ints and OpenGL
On 14 September 2013 12:14, Alex Fowler alex.murat...@gmail.com wrote: Timothy, thanks,for giving a thorough answer to my questions, I appreciate this! As far as I understood, you did some work for Clojure team, and you have the necessary knowledge to express a knowing opinion on what are the implications of the matter. James, for some numbers on OpenGL penalties, please refer to message #6 in thread (my initial answer for Timothy). You can also google on it, I am sure, you will find more information, or, why not, simply call NVIDIA or ATI support lines, and ask them. A perfectly valid question for them to consult you on :) As for more Java-friendly answers, you might also be interested in asking on LWJGL or JOGL forums. Personally I work with OpenGL for quite a long time already. Even when we were on C/C++ we never used doubles. Then we went Java, and there too, doubles are nowhere. One of the cornerstone computational workhorses of LWJGL, for example, the class Vertex3f, has no double version. And that is for a reason, not because Java bindings are bad and we must go C-plus-plusing now. Probably, after 10 years we will have only doubles and longs on GPUs... do you believe in it? Why we need them there at all? But presumably you've done some benchmarks that show a loss in performance? Otherwise I don't understand why you'd be arguing so passionately. I did some some benchmarks myself, but any performance loss was below the noise level of my machine. In theory, if HotSpot is doing its job, then the conversion from a double to the float is compiled down to a single machine instruction. On the i7 architecture at least, the reciprocal throughput for converting a float from double to single precision is one clock cycle. If you're pushing data to the GPU, aren't your primary performance bottlenecks going to be the latency and bandwidth of the link? I'm having difficulty seeing how a double-to-float conversion would be an significant issue. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
+1 on all the answers from Timothy to these items Been working with Clojure for 5 years by now handling huge data loads in real time. You want to get lean and mean performance in specific areas then thunk down to Java or native libs. We never had to do from Clojure btwy, there's been always an alternate implementation in Clojure to improve speed. In the 1980s/1990s you needed perf in some critical code chunks ? You would look at the machine code issued by the compiler, tweak your code and use compiler options if possible to make these faster. Or else write assembler code to be closer to the metal and glue this code to your top level code. Been doing this on SCADA systems for a number of years with success... Some advice, use the right tool instead of trying to shift the universe by a few degrees, life is too short :) Luc P. 1) Clojure is said to be data-oriented. Well it is, it's just that your definition of data is radically different from the normal business use case. In the line of work I'm in, big data is millions of hash maps filled with heterogeneous data types. In these cases, Clojure really shines. 2) Clojure is said to make simple things easy. That's a tad debatable. I would say that Clojure simplifies your code, therefore allowing for easier reasoning about that code. One of the wa it accomplishes this by being a dynamic language. And that right there hits on the main reason you're experiencing problems. This simplicity doesn't come without a cost. There are many trade-offs Clojure makes. Immutable data-structures are fast, but not as fast as mutable structures. Clojure allows for REPL based development at the cost of requiring that every function must go through a var deref. This cost is low (very low thanks to the JVM), but it still exists. And we see this cost when it comes to primitives. In languages like Scala and Java you know exactly what functions every function will call, and so you can link it to the exact overload needed for the primitives in use. However, in Clojure, at any moment a def (var) could be changed at the REPL, and we have to pick that up without problems. In return you have the ability to program without having to re-compile at every step. The same thing applies with type hinting in general. No other dynamic language offers the performance of Clojure. Python is used heavily by the scientific community, and yet it boxes everything. It doesn't support floats, let alone unboxing. So Clojure really should be viewed as a super fast dynamic language, not as a slow Scala/Java clone. I think this is clearly exemplified by Fressian ( https://github.com/Datomic/fressian), this is the serialization library used by Datomic (also written by Rich Hickey). Notice something interesting about this codebase. It almost 100% java (except for the tests, those are in Clojure). Why? Because serialization libraries need to be lean, fast, and are mostly side-effecting, this is a use case Java excels at. Now I've never seen the inner workings of Datomic, but I've heard it said the database is written in Clojure. So that's interesting...it's a set of Java libraries (for performance) glued together and controlled by Clojure (for simplicity). When Clojure people talk about simplicity what we're really railing against is the complexity of orchestrating large projects using a OOP language like Java. Write your data processing routines as static java members that take float arrays and emit float arrays and you're going to do quite well. One other thing you touched on is the idea that no one has given you a straight answer on this yet. And I think this comes down to several things: a) No one wants to speak for Rich. When it comes down to it, Clojure is his baby, so no one but him has the authority to say this is a focus for version X. He doesn't hang out on the mailing lists a whole lot, so perhaps an email to him might do well, or even to clojure-dev. b) No one has a clue on how to implement this without changing Clojure semantics. And changing the semantics of a language just to support a single use case is one of the best ways to get your patch rejected by Rich. :-) c) I want to make this point as carefully as possible...there's little incentive for anyone (including Rich) to implement this. If you came to me an said Tim...we want to pay double your current salary for the next year and have you re-write the Clojure compiler from scratch to support these features, I might actually do that. But sadly, I have a day job, and making massive changes to the Clojure compiler is not something I plan on spending my time on this year. Perhaps at some point a corporation will offer paid support for Clojure and then things like this can be possible. As the saying goes, money talks. Offer enough money and people will get more motivated to help. I know this point isn't very nice to hear from the OSS world, but the sad fact of
Re: Clojure, floats, ints and OpenGL
On Saturday, 14 September 2013 01:04:16 UTC+8, tbc++ wrote: This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. You're going to have a hard time convincing people to give up some of the dynamism of Clojure just for the sake of more performance. Especially considering that many Clojure users are perfectly okay with boxed values, let alone need floats or other primitives. Let's be clear - I'm not asking anyone to give up on any dynamism. I am asking for an agreement that we want to allow high performance *options* in Clojure, so that we can at least match Scala/Java, for those use cases where people have genuine performance requirements. Some people don't care about performance enough for the distinction between float and double to matter. But others do. I think we (as a community) should try to support both use cases. Clojure has the potential to be *both* dynamic and fast if we design it right. It would be a shame if people in the community took a general stance that performance is good enough for me, so we aren't interested in supporting further performance improvements. I'm sure that isn't what is intended, but it could appear like that to people who raise performance issues only to get challenged / told that they don't have a valid problem. But what you are describing creates a whole ton of new problems, problems I don't see a good solution for. What you are describing would require the recompilation of entire source trees when a inner function is modified. So now we're in the Scala/Java land of recompile after every edit. Perhaps there's a use-case for invoke dynamic here, but now you're talking about breaking backwards compatibility for everyone not using Java 7+. I'm not suggesting recompile everything after edit. I'm suggesting lazily recompile stuff that is dependent on the one thing you changed. That's a much smaller compilation unit in most cases - maybe you are recompiling 2-5 functions instead of 1. If you change something that is used everywhere in your whole app, then yes: maybe it's going to recompile 100 or so functions. But even then, I doubt it will be a significant compile time compared to Java/Scala land. And note that we're talking about incurring this cost only for people doing dynamic changes to existing vars. This isn't common production usage (if you are mutating production state, I would hope you are using something with proper concurrency semantics like atoms or agents or refs to mutate data!). So performance probably shouldn't matter at all, apart from the subjective experience of compiling fast enough to be usable at the REPL. Which I'm pretty sure is a fairly easy target to hit. Like I said, this would be a big change, but it would be a good way to combine dynamism with excellent runtime performance. I'll be the first to admit that I'd like to rewrite the Clojure compiler as a true multi-pass optimizing compiler. But that's a task I haven't undertaken for two reasons 1) it's a ton of work that would take months (if not years) to reach the level of performance currently offered by Clojure. 2) I really don't need it. Every time I need that level of performance I drop to Java, CUDA or some other high performance toolkit. Personally I think it would be much better for someone to come up with a typed lisp that interops very cleanly with Clojure. That way you can build your inner kernels using a lisp-like language, and then glue it together with Clojure. But let me close by saying, if you really want better primitives, I'd suggest writing up a proposal for how it would work, perhaps even with some example using macros and genclass. Until then we don't have anything to go off of, people say I'd love to have feature X, well we all would, but all the suggestions thus far won't work, so how do you plan on fixing that? My pragmatic proposal for now is very simple: allow metadata to specify functions to be compiled in a way that invocation is compiled statically to an invokevirtual. You lose the dynamic var deref, but gain better runtime performance and the ability to use arbitrary types / primitives (which solves the OP's problem). This limited-scope proposal won't effect any existing dynamic usage, so people who like their fully mutable vars with their dynamic lookups can keep them. It is on JIRA as CLJ-1263 , comments / improvements welcome. http://dev.clojure.org/jira/browse/CLJ-1263 Timothy On Fri, Sep 13, 2013 at 1:54 AM, Mikera mike.r.an...@gmail.comjavascript: wrote: On Friday, 13 September 2013 12:11:50 UTC+8, tbc++ wrote: If we can do away with the interface generation, then support for arbitrary primitive arguments should become relatively straightforward. How would we even call a function without an interface? Remember everything is defined behind vars, so you simply can't assume that a
Re: Clojure, floats, ints and OpenGL
On Friday, 13 September 2013 12:11:50 UTC+8, tbc++ wrote: If we can do away with the interface generation, then support for arbitrary primitive arguments should become relatively straightforward. How would we even call a function without an interface? Remember everything is defined behind vars, so you simply can't assume that a function won't be re-defed without notice. This is the reason interfaces exist notice how the following works: user= (defn foo ^long [^long x] x) #'user/foo user= (defn baz [x] (foo x)) #'user/baz user= (baz 42) 42 user= (defn foo ^double [^double x] x) #'user/foo user= (baz 42) ClassCastException user$foo cannot be cast to clojure.lang.IFn$LL user/baz (NO_SOURCE_FILE:1) user= Good example to discuss! I agree there is a subtle tradeoff between performance and dynamism here. Any interface dispatch via a var uses an extra level of indirection (in the dynamic var case, this includes a thread-local check for any bindings) and already adds some overhead. If you are happy using Clojure's dynamic features to pass arbitrary (boxed / Object) arguments and redefine vars on the fly like that, you probably don't really care about optimal performance very much anyway and a standard IFn invoke should be OK. For performance-sensitive code, you ideally want primitive-typed code to be compiled to a direct method call (invokevirtual) and not go via any var lookup / interface invoke at all. This would mean you would also need to redefine/recompile baz if you wanted to use a changed version of foo, but that's a relatively minor inconvenience IMHO. If you redefine baz after redefining foo (e.g. by reloading the whole namespace), then everything will still work. I'm not sure if it is possible to get this precise behaviour in Clojure at present - but it would certainly be great for high performance code. If we want *both* maximum performance and dynamic flexibility, then I think we need a completely different approach. Clojure vars as currently designed won't cut it. Probably something like an on-demand re-compilation strategy based on a var dependency graph would be needed. I personally think that's the right long-term direction, but that's definitely Clojure 2.0 territory. Do a prototype with definterface/genclass or something and then report your results. My suspicions are that you'll find doing this without interfaces, while maintaining Clojure's semantics, is impossible. You may be right. Though it also probably depends on what you consider documented (promised not to change in public API) vs. undocumented (implementation detail) semantics. Some of the subtleties on what happens to existing code when you redefine vars are arguably in the latter category. Observe: (defn foo ^double [^double x] (inc x)) (defn baz [x] (foo x)) (baz 42) = 43.0 (ns-unmap *ns* 'foo) (defn foo ^double [^double x] (dec x)) (baz 42) = 43.0 i.e. it's fairly easy to trick Clojure into keeping an old version of a var around. Does that count as officially documented behaviour we are obliged to maintain? Either way, if Clojure's semantics prove to be a fundamental issue for performance, then I think it is better to start work to improve Clojure's semantics (perhaps targeting 2.0 if we think it's a really big breaking change). This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. I'd rather see a bit of breakage and fix my code when upgrading to Clojure 2.0 than be stuck with poor performance forever. Timothy On Thu, Sep 12, 2013 at 8:41 PM, Mikera mike.r.an...@gmail.comjavascript: wrote: People *have* run into this problem a lot. People have just worked around it. The existence of great libraries like HipHip and vectorz-clj and some of Zach's stuff is IMHO to a large extent because people have needed high performance operations (often involving primitives / primitive arrays / custom JVM types) and have found it easier to implement these in a new library than wait for the support to appear in Clojure itself. So we have lots of great, performance-oriented libraries. Cool. But not having comprehensive JVM primitive support is still a big problem for Clojure. It means that: a) We'll get lots of ecosystem fragmentation as people with slightly different requirements implement their own solutions in slightly different/incompatible ways. We're seeing this already. Lisp Curse etc. b) People with very strong performance requirements on the JVM (e.g. OpenGL, big data numerics, scientific computing, heavy duty websites) are more likely to avoid Clojure and do their work in Scala / Java instead. The community will lose exactly the people who have both the motivation and skills to fix these kind of issues. c) We won't get the wider reputation for performance that I think Clojure deserves and should aspire to. And this is important - rightly or wrongly,
Re: Clojure, floats, ints and OpenGL
On 13 September 2013 08:54, Mikera mike.r.anderson...@gmail.com wrote: Either way, if Clojure's semantics prove to be a fundamental issue for performance, then I think it is better to start work to improve Clojure's semantics (perhaps targeting 2.0 if we think it's a really big breaking change). This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. I'd rather see a bit of breakage and fix my code when upgrading to Clojure 2.0 than be stuck with poor performance forever. Out of curiosity, what is the performance hit in these cases? Floats obviously save memory, and I believe they're also between 15% to 40% more efficient for division, at least on Intel CPUs. Is there also a cost to be paid passing doubles to OpenGL? Do you know what that cost is? - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
This would be better, IMHO, than forever accepting semantics that prevent idiomatic code from ever being truly fast. You're going to have a hard time convincing people to give up some of the dynamism of Clojure just for the sake of more performance. Especially considering that many Clojure users are perfectly okay with boxed values, let alone need floats or other primitives. But what you are describing creates a whole ton of new problems, problems I don't see a good solution for. What you are describing would require the recompilation of entire source trees when a inner function is modified. So now we're in the Scala/Java land of recompile after every edit. Perhaps there's a use-case for invoke dynamic here, but now you're talking about breaking backwards compatibility for everyone not using Java 7+. I'll be the first to admit that I'd like to rewrite the Clojure compiler as a true multi-pass optimizing compiler. But that's a task I haven't undertaken for two reasons 1) it's a ton of work that would take months (if not years) to reach the level of performance currently offered by Clojure. 2) I really don't need it. Every time I need that level of performance I drop to Java, CUDA or some other high performance toolkit. Personally I think it would be much better for someone to come up with a typed lisp that interops very cleanly with Clojure. That way you can build your inner kernels using a lisp-like language, and then glue it together with Clojure. But let me close by saying, if you really want better primitives, I'd suggest writing up a proposal for how it would work, perhaps even with some example using macros and genclass. Until then we don't have anything to go off of, people say I'd love to have feature X, well we all would, but all the suggestions thus far won't work, so how do you plan on fixing that? Timothy On Fri, Sep 13, 2013 at 1:54 AM, Mikera mike.r.anderson...@gmail.comwrote: On Friday, 13 September 2013 12:11:50 UTC+8, tbc++ wrote: If we can do away with the interface generation, then support for arbitrary primitive arguments should become relatively straightforward. How would we even call a function without an interface? Remember everything is defined behind vars, so you simply can't assume that a function won't be re-defed without notice. This is the reason interfaces exist notice how the following works: user= (defn foo ^long [^long x] x) #'user/foo user= (defn baz [x] (foo x)) #'user/baz user= (baz 42) 42 user= (defn foo ^double [^double x] x) #'user/foo user= (baz 42) ClassCastException user$foo cannot be cast to clojure.lang.IFn$LL user/baz (NO_SOURCE_FILE:1) user= Good example to discuss! I agree there is a subtle tradeoff between performance and dynamism here. Any interface dispatch via a var uses an extra level of indirection (in the dynamic var case, this includes a thread-local check for any bindings) and already adds some overhead. If you are happy using Clojure's dynamic features to pass arbitrary (boxed / Object) arguments and redefine vars on the fly like that, you probably don't really care about optimal performance very much anyway and a standard IFn invoke should be OK. For performance-sensitive code, you ideally want primitive-typed code to be compiled to a direct method call (invokevirtual) and not go via any var lookup / interface invoke at all. This would mean you would also need to redefine/recompile baz if you wanted to use a changed version of foo, but that's a relatively minor inconvenience IMHO. If you redefine baz after redefining foo (e.g. by reloading the whole namespace), then everything will still work. I'm not sure if it is possible to get this precise behaviour in Clojure at present - but it would certainly be great for high performance code. If we want *both* maximum performance and dynamic flexibility, then I think we need a completely different approach. Clojure vars as currently designed won't cut it. Probably something like an on-demand re-compilation strategy based on a var dependency graph would be needed. I personally think that's the right long-term direction, but that's definitely Clojure 2.0 territory. Do a prototype with definterface/genclass or something and then report your results. My suspicions are that you'll find doing this without interfaces, while maintaining Clojure's semantics, is impossible. You may be right. Though it also probably depends on what you consider documented (promised not to change in public API) vs. undocumented (implementation detail) semantics. Some of the subtleties on what happens to existing code when you redefine vars are arguably in the latter category. Observe: (defn foo ^double [^double x] (inc x)) (defn baz [x] (foo x)) (baz 42) = 43.0 (ns-unmap *ns* 'foo) (defn foo ^double [^double x] (dec x)) (baz 42) = 43.0 i.e. it's fairly easy to trick Clojure into keeping an old version of a var around. Does that count as officially
Re: Clojure, floats, ints and OpenGL
Does somebody from the development team read this user group? Or maybe I have addressed my questions to a wrong place? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
As others have already said: long double only is a restriction for function args. Not for interop. Not for local computations. Not for args to definterface methods. The reason for this restriction is the combinatorial explosion. (So you may have to roll your own interface and a couple of helper macros to have some kiind of fns handling ints and floats as args/return values.) On the bright side: there are even functions specialized for ints: unchecked-add-intfor example, and the compiler hs intrinsics for them (ie emits an IADD opcode). However there's no such support (fns and intrinsics) for floats. I think floats support on par with ints support could be added without being controversial. hth, Christophe On Thu, Sep 12, 2013 at 5:11 PM, Timothy Baldridge tbaldri...@gmail.comwrote: There are a combination of issues all contributing to the lack of response on this subject. But before I continue let me state that these opinions are my own. I have worked on Clojure and core.async, but these comments are going to be personal conjecture and opinions: 1) As mentioned there is a high amount of complexity required to implement all the interfaces needed for the different variants of functions you want. Primitive hinted functions currently implement Java interfaces, implementing every combination of float, double, object, short, int, long, and byte for arities up to 5 would require the addition of over 16,000 interfaces. With the current config, we only need 81 interfaces. I'm not saying this couldn't be changed to happen on-the-fly, it would just take some serious work, and would cause problems with Java Interop 2) The current system works, there are production databases (see Datomic), neural networks (see the work by Prismatic), and many high performance libraries (Zach Tellman has a reputation for bending Clojure to his will in this area), all written in Clojure. 3) Because of #2, some may even go so far as to say that we should drop everything but longs and doubles. Other dynamic languages (Python for instance) do this without problems, they simply relegate all the high performance stuff to highly optimized libraries. This is what Prismatic did with HipHop ( http://blog.getprismatic.com/blog/2013/7/10/introducing-hiphip-array-fast-and-flexible-numerical-computation-in-clojure ). 4) Writing small functional libraries in Java that interop with Clojure is actually quite nice. So perhaps the answer is to build the inner kernels of your system in Java and then wrap them? I know that doesn't sound fun, but you won't get much faster code than that. So all the above make me sit back and say what is it about your problem that is unique and really requires floats? Why haven't we had problems like this in the past. 5) And I think the problem really comes down to your API and target platform (GPU). See, most of us would just typehint to doubles and take the memory hit. Doubles are fast on modern CPUs and memory is cheap. Not so in your case, as you mentioned you have concerns about memory size and performance of certain primitives. My conclusion is that you'd probably be best looking at the HipHop library, and figuring out how you can adapt their ideas to your own code. That is, write a small Java library that contains all the kernel code you need, and then stitch together these primitives with Clojure. As it stands, Clojure's support for type hinting floats is poor, but that's not likely to change soon. TL;DR - The reason you haven't heard back is because no one has a good answer as to how to fix it, or if it even needs to be fixed. That's not the answer anyone likes to hear, but I'm afraid that's the truth. Anyone else on this list can feel free to correct me. Timothy Baldridge On Thu, Sep 12, 2013 at 8:38 AM, Alex Fowler alex.murat...@gmail.comwrote: Does somebody from the development team read this user group? Or maybe I have addressed my questions to a wrong place? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post
Re: Clojure, floats, ints and OpenGL
On Friday, 13 September 2013 00:07:03 UTC+8, Christophe Grand wrote: As others have already said: long double only is a restriction for function args. Not for interop. Not for local computations. Not for args to definterface methods. The reason for this restriction is the combinatorial explosion. I still don't understand why combinatorial explosion is even a problem: why are these interfaces necessary? If we can do away with the interface generation, then support for arbitrary primitive arguments should become relatively straightforward. IMHO, in cases where performance matters enough to need primitive function arguments, you aren't going to want to be using a higher-order function / IFn-based polymorphism anyway. You just want a direct invocation, which shouldn't need to go via any interfaces. It just needs the compiler to figure out the right method to invoke at the function callsite. Dynamic / higher order use cases (which I agree need an interface) can be handled via the regular [Object ] argument version of the function, which is already provided by IFn. Bonus: if you take this approach, I think it's also possible to support arbitrarily typed return values using the same infrastructure. That would be another big performance win. (So you may have to roll your own interface and a couple of helper macros to have some kiind of fns handling ints and floats as args/return values.) On the bright side: there are even functions specialized for ints: unchecked-add-intfor example, and the compiler hs intrinsics for them (ie emits an IADD opcode). However there's no such support (fns and intrinsics) for floats. I think floats support on par with ints support could be added without being controversial. hth, Christophe On Thu, Sep 12, 2013 at 5:11 PM, Timothy Baldridge tbald...@gmail.comjavascript: wrote: There are a combination of issues all contributing to the lack of response on this subject. But before I continue let me state that these opinions are my own. I have worked on Clojure and core.async, but these comments are going to be personal conjecture and opinions: 1) As mentioned there is a high amount of complexity required to implement all the interfaces needed for the different variants of functions you want. Primitive hinted functions currently implement Java interfaces, implementing every combination of float, double, object, short, int, long, and byte for arities up to 5 would require the addition of over 16,000 interfaces. With the current config, we only need 81 interfaces. I'm not saying this couldn't be changed to happen on-the-fly, it would just take some serious work, and would cause problems with Java Interop 2) The current system works, there are production databases (see Datomic), neural networks (see the work by Prismatic), and many high performance libraries (Zach Tellman has a reputation for bending Clojure to his will in this area), all written in Clojure. 3) Because of #2, some may even go so far as to say that we should drop everything but longs and doubles. Other dynamic languages (Python for instance) do this without problems, they simply relegate all the high performance stuff to highly optimized libraries. This is what Prismatic did with HipHop ( http://blog.getprismatic.com/blog/2013/7/10/introducing-hiphip-array-fast-and-flexible-numerical-computation-in-clojure ). 4) Writing small functional libraries in Java that interop with Clojure is actually quite nice. So perhaps the answer is to build the inner kernels of your system in Java and then wrap them? I know that doesn't sound fun, but you won't get much faster code than that. So all the above make me sit back and say what is it about your problem that is unique and really requires floats? Why haven't we had problems like this in the past. 5) And I think the problem really comes down to your API and target platform (GPU). See, most of us would just typehint to doubles and take the memory hit. Doubles are fast on modern CPUs and memory is cheap. Not so in your case, as you mentioned you have concerns about memory size and performance of certain primitives. My conclusion is that you'd probably be best looking at the HipHop library, and figuring out how you can adapt their ideas to your own code. That is, write a small Java library that contains all the kernel code you need, and then stitch together these primitives with Clojure. As it stands, Clojure's support for type hinting floats is poor, but that's not likely to change soon. TL;DR - The reason you haven't heard back is because no one has a good answer as to how to fix it, or if it even needs to be fixed. That's not the answer anyone likes to hear, but I'm afraid that's the truth. Anyone else on this list can feel free to correct me. Timothy Baldridge On Thu, Sep 12, 2013 at 8:38 AM, Alex Fowler
Re: Clojure, floats, ints and OpenGL
People *have* run into this problem a lot. People have just worked around it. The existence of great libraries like HipHip and vectorz-clj and some of Zach's stuff is IMHO to a large extent because people have needed high performance operations (often involving primitives / primitive arrays / custom JVM types) and have found it easier to implement these in a new library than wait for the support to appear in Clojure itself. So we have lots of great, performance-oriented libraries. Cool. But not having comprehensive JVM primitive support is still a big problem for Clojure. It means that: a) We'll get lots of ecosystem fragmentation as people with slightly different requirements implement their own solutions in slightly different/incompatible ways. We're seeing this already. Lisp Curse etc. b) People with very strong performance requirements on the JVM (e.g. OpenGL, big data numerics, scientific computing, heavy duty websites) are more likely to avoid Clojure and do their work in Scala / Java instead. The community will lose exactly the people who have both the motivation and skills to fix these kind of issues. c) We won't get the wider reputation for performance that I think Clojure deserves and should aspire to. And this is important - rightly or wrongly, many people are attracted to languages with good performance credentials. I'd really love to be able to write everything in pure idiomatic Clojure and still guarantee great performance. Currently I can't, and in a large part this is due to JVM type-related issues like the following: 1) Not all primitive types are fully supported as function args and return values (the issue raised in this thread) 2) Lack of an efficient way to extend abstract base types (CLJ-1255 in Jira, for those interested) 3) Lack of support for statically compiled reference types as function args (avoiding unnecessary instance checks and casting, CLJ-1256) 4) The compiler still isn't very clever about using type inference to eliminate boxing / typecasts (perhaps CinC can help here?) Personally I'm less interested in floats (when I'm doing numerical stuff, double precision is usually more important), but I've certainly wanted ints many many times. I'm sure other people have wanted chars or bytes for various reasons (text processing? IO?). The point is that there are many valid reasons to use the primitive types on the JVM. I guess somebody even has a use for short somewhere.. ;-) Now let's get practical. What we need, I think, is some kind of official recognition that full JVM primitive support (i.e. all primitives supported in all situations) is an objective for Clojure in 1.6 or maybe 1.7. Then people can put in the time / effort to implement it. I'm personally very happy to help implement this myself providing that there is agreement that full primitive support is the way we want to go. Without official blessing, I'm unlikely to spend my weekends on speculative work that might not be accepted or appreciated. I suspect this is true for others too. If, on the other hand, the official answer is Clojure will never support anything other than Objects, doubles and longs then I'd want to know that too. I think that would be a *really* poor design decision because good compiled performance and good JVM interop (embracing the host platform) seem to be two key principles of Clojure that have attracted many people. But hey, then I could at least save my weekends and focus on writing performance-oriented code in other languages (whether that is Java, Scala, pure bytecode, or some crazy new performance-oriented JVM Lisp). On Thursday, 12 September 2013 23:11:40 UTC+8, tbc++ wrote: There are a combination of issues all contributing to the lack of response on this subject. But before I continue let me state that these opinions are my own. I have worked on Clojure and core.async, but these comments are going to be personal conjecture and opinions: 1) As mentioned there is a high amount of complexity required to implement all the interfaces needed for the different variants of functions you want. Primitive hinted functions currently implement Java interfaces, implementing every combination of float, double, object, short, int, long, and byte for arities up to 5 would require the addition of over 16,000 interfaces. With the current config, we only need 81 interfaces. I'm not saying this couldn't be changed to happen on-the-fly, it would just take some serious work, and would cause problems with Java Interop 2) The current system works, there are production databases (see Datomic), neural networks (see the work by Prismatic), and many high performance libraries (Zach Tellman has a reputation for bending Clojure to his will in this area), all written in Clojure. 3) Because of #2, some may even go so far as to say that we should drop everything but longs and doubles. Other dynamic languages (Python for
Re: Clojure, floats, ints and OpenGL
If we can do away with the interface generation, then support for arbitrary primitive arguments should become relatively straightforward. How would we even call a function without an interface? Remember everything is defined behind vars, so you simply can't assume that a function won't be re-defed without notice. This is the reason interfaces exist notice how the following works: user= (defn foo ^long [^long x] x) #'user/foo user= (defn baz [x] (foo x)) #'user/baz user= (baz 42) 42 user= (defn foo ^double [^double x] x) #'user/foo user= (baz 42) ClassCastException user$foo cannot be cast to clojure.lang.IFn$LL user/baz (NO_SOURCE_FILE:1) user= Do a prototype with definterface/genclass or something and then report your results. My suspicions are that you'll find doing this without interfaces, while maintaining Clojure's semantics, is impossible. Timothy On Thu, Sep 12, 2013 at 8:41 PM, Mikera mike.r.anderson...@gmail.comwrote: People *have* run into this problem a lot. People have just worked around it. The existence of great libraries like HipHip and vectorz-clj and some of Zach's stuff is IMHO to a large extent because people have needed high performance operations (often involving primitives / primitive arrays / custom JVM types) and have found it easier to implement these in a new library than wait for the support to appear in Clojure itself. So we have lots of great, performance-oriented libraries. Cool. But not having comprehensive JVM primitive support is still a big problem for Clojure. It means that: a) We'll get lots of ecosystem fragmentation as people with slightly different requirements implement their own solutions in slightly different/incompatible ways. We're seeing this already. Lisp Curse etc. b) People with very strong performance requirements on the JVM (e.g. OpenGL, big data numerics, scientific computing, heavy duty websites) are more likely to avoid Clojure and do their work in Scala / Java instead. The community will lose exactly the people who have both the motivation and skills to fix these kind of issues. c) We won't get the wider reputation for performance that I think Clojure deserves and should aspire to. And this is important - rightly or wrongly, many people are attracted to languages with good performance credentials. I'd really love to be able to write everything in pure idiomatic Clojure and still guarantee great performance. Currently I can't, and in a large part this is due to JVM type-related issues like the following: 1) Not all primitive types are fully supported as function args and return values (the issue raised in this thread) 2) Lack of an efficient way to extend abstract base types (CLJ-1255 in Jira, for those interested) 3) Lack of support for statically compiled reference types as function args (avoiding unnecessary instance checks and casting, CLJ-1256) 4) The compiler still isn't very clever about using type inference to eliminate boxing / typecasts (perhaps CinC can help here?) Personally I'm less interested in floats (when I'm doing numerical stuff, double precision is usually more important), but I've certainly wanted ints many many times. I'm sure other people have wanted chars or bytes for various reasons (text processing? IO?). The point is that there are many valid reasons to use the primitive types on the JVM. I guess somebody even has a use for short somewhere.. ;-) Now let's get practical. What we need, I think, is some kind of official recognition that full JVM primitive support (i.e. all primitives supported in all situations) is an objective for Clojure in 1.6 or maybe 1.7. Then people can put in the time / effort to implement it. I'm personally very happy to help implement this myself providing that there is agreement that full primitive support is the way we want to go. Without official blessing, I'm unlikely to spend my weekends on speculative work that might not be accepted or appreciated. I suspect this is true for others too. If, on the other hand, the official answer is Clojure will never support anything other than Objects, doubles and longs then I'd want to know that too. I think that would be a *really* poor design decision because good compiled performance and good JVM interop (embracing the host platform) seem to be two key principles of Clojure that have attracted many people. But hey, then I could at least save my weekends and focus on writing performance-oriented code in other languages (whether that is Java, Scala, pure bytecode, or some crazy new performance-oriented JVM Lisp). On Thursday, 12 September 2013 23:11:40 UTC+8, tbc++ wrote: There are a combination of issues all contributing to the lack of response on this subject. But before I continue let me state that these opinions are my own. I have worked on Clojure and core.async, but these comments are going to be personal conjecture and opinions: 1) As mentioned there is a high amount
Re: Clojure, floats, ints and OpenGL
There are a combination of issues all contributing to the lack of response on this subject. But before I continue let me state that these opinions are my own. I have worked on Clojure and core.async, but these comments are going to be personal conjecture and opinions: 1) As mentioned there is a high amount of complexity required to implement all the interfaces needed for the different variants of functions you want. Primitive hinted functions currently implement Java interfaces, implementing every combination of float, double, object, short, int, long, and byte for arities up to 5 would require the addition of over 16,000 interfaces. With the current config, we only need 81 interfaces. I'm not saying this couldn't be changed to happen on-the-fly, it would just take some serious work, and would cause problems with Java Interop 2) The current system works, there are production databases (see Datomic), neural networks (see the work by Prismatic), and many high performance libraries (Zach Tellman has a reputation for bending Clojure to his will in this area), all written in Clojure. 3) Because of #2, some may even go so far as to say that we should drop everything but longs and doubles. Other dynamic languages (Python for instance) do this without problems, they simply relegate all the high performance stuff to highly optimized libraries. This is what Prismatic did with HipHop ( http://blog.getprismatic.com/blog/2013/7/10/introducing-hiphip-array-fast-and-flexible-numerical-computation-in-clojure ). 4) Writing small functional libraries in Java that interop with Clojure is actually quite nice. So perhaps the answer is to build the inner kernels of your system in Java and then wrap them? I know that doesn't sound fun, but you won't get much faster code than that. So all the above make me sit back and say what is it about your problem that is unique and really requires floats? Why haven't we had problems like this in the past. 5) And I think the problem really comes down to your API and target platform (GPU). See, most of us would just typehint to doubles and take the memory hit. Doubles are fast on modern CPUs and memory is cheap. Not so in your case, as you mentioned you have concerns about memory size and performance of certain primitives. My conclusion is that you'd probably be best looking at the HipHop library, and figuring out how you can adapt their ideas to your own code. That is, write a small Java library that contains all the kernel code you need, and then stitch together these primitives with Clojure. As it stands, Clojure's support for type hinting floats is poor, but that's not likely to change soon. TL;DR - The reason you haven't heard back is because no one has a good answer as to how to fix it, or if it even needs to be fixed. That's not the answer anyone likes to hear, but I'm afraid that's the truth. Anyone else on this list can feel free to correct me. Timothy Baldridge On Thu, Sep 12, 2013 at 8:38 AM, Alex Fowler alex.murat...@gmail.comwrote: Does somebody from the development team read this user group? Or maybe I have addressed my questions to a wrong place? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure, floats, ints and OpenGL
On Tuesday, 10 September 2013 01:03:12 UTC+8, Jozef Wagner wrote: You can typehing ints for locals (let, loop), restrictions are just for function arguments. AFAIK the reason is combinatorial explosion at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L91 I never understood the point of these restrictions surely primitive function invocation is much better handled by: a) generating the exact primitive function required in an AFn subclass (e.g. invokePrim(long, char, byte, Object); ) b) Creating a direct invocation of the method in a) at any function call site c) The usual IFn.invoke(...) methods can handle the dynamic use cases when you pass this AFn to a higher order function i.e. you don't really need these interfaces at all. As a bonus, the same method could also improve performance by avoiding type casts for non-primitive type-hinted arguments like String, since you aren't limited to casting every non-primitive argument via Object either. Or am I missing something obvious? I have the same problem with char. Because I cannot typehint e.g. my whitespace? function with ^char, I recieve a boxed Object and thus cannot use == for comparison. JW On Mon, Sep 9, 2013 at 6:02 PM, Mikera mike.r.an...@gmail.comjavascript: wrote: +1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would
Re: Clojure, floats, ints and OpenGL
It's worth noting that the restrictions to IFn do not apply to definterface and deftype. Not that solves all (or any) of your problems, I've used definterface before to lock down the actual types used. Timothy On Mon, Sep 9, 2013 at 11:03 AM, Jozef Wagner jozef.wag...@gmail.comwrote: You can typehing ints for locals (let, loop), restrictions are just for function arguments. AFAIK the reason is combinatorial explosion at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L91 I have the same problem with char. Because I cannot typehint e.g. my whitespace? function with ^char, I recieve a boxed Object and thus cannot use == for comparison. JW On Mon, Sep 9, 2013 at 6:02 PM, Mikera mike.r.anderson...@gmail.comwrote: +1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would like to know answers to the following questions: 1) What is the current reason for the support for these types to be missing? 2) Are there any plans for improvement of support for floats, ints and maybe, localized unboxed calculations? Or is there some advice on how to enable their support? 3) What is you vision for Clojure + OpenGL applications? 4) Is it possible to request support for floats, ints and maybe shorts for the language? 5) Is it possible to request support for localized unboxed calculations, like (with-unboxed ... ) and localized float-only and int-only
Re: Clojure, floats, ints and OpenGL
Also, how much of this is a limit of the OpenGL library you are using? The raw OpenGL API supports glVertex3d and glVertex3f. Is the double version not supported by your java interface library? Timothy On Mon, Sep 9, 2013 at 11:07 AM, Timothy Baldridge tbaldri...@gmail.comwrote: It's worth noting that the restrictions to IFn do not apply to definterface and deftype. Not that solves all (or any) of your problems, I've used definterface before to lock down the actual types used. Timothy On Mon, Sep 9, 2013 at 11:03 AM, Jozef Wagner jozef.wag...@gmail.comwrote: You can typehing ints for locals (let, loop), restrictions are just for function arguments. AFAIK the reason is combinatorial explosion at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L91 I have the same problem with char. Because I cannot typehint e.g. my whitespace? function with ^char, I recieve a boxed Object and thus cannot use == for comparison. JW On Mon, Sep 9, 2013 at 6:02 PM, Mikera mike.r.anderson...@gmail.comwrote: +1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would like to know answers to the following questions: 1) What is the current reason for the support for these types to be missing? 2) Are there any plans for improvement of support for floats, ints and maybe, localized unboxed calculations? Or is there some advice on how to enable their support?
Re: Clojure, floats, ints and OpenGL
You can typehing ints for locals (let, loop), restrictions are just for function arguments. AFAIK the reason is combinatorial explosion at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L91 I have the same problem with char. Because I cannot typehint e.g. my whitespace? function with ^char, I recieve a boxed Object and thus cannot use == for comparison. JW On Mon, Sep 9, 2013 at 6:02 PM, Mikera mike.r.anderson...@gmail.com wrote: +1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would like to know answers to the following questions: 1) What is the current reason for the support for these types to be missing? 2) Are there any plans for improvement of support for floats, ints and maybe, localized unboxed calculations? Or is there some advice on how to enable their support? 3) What is you vision for Clojure + OpenGL applications? 4) Is it possible to request support for floats, ints and maybe shorts for the language? 5) Is it possible to request support for localized unboxed calculations, like (with-unboxed ... ) and localized float-only and int-only calculations, like, say in special macros (with-floats--ints ... here go (+) (-) and stuff ONLY with floats/ints ... ) ? Preferably, I would like to hear the answers from somebody from the development team, because I have already received enough support from the community, on the IRC, I
Re: Clojure, floats, ints and OpenGL
+1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine falling back to Java for fast computations, just like we fall back to ASM in, say C, that is very undesirable and discouraging, since we want to pick Clojure for Clojure and it will be too cumbersome to make 50/50% Java/Clojure apps just to work around that design decision. Therefore, while deciding if to pick Clojure as the base for our development, I would like to know answers to the following questions: 1) What is the current reason for the support for these types to be missing? 2) Are there any plans for improvement of support for floats, ints and maybe, localized unboxed calculations? Or is there some advice on how to enable their support? 3) What is you vision for Clojure + OpenGL applications? 4) Is it possible to request support for floats, ints and maybe shorts for the language? 5) Is it possible to request support for localized unboxed calculations, like (with-unboxed ... ) and localized float-only and int-only calculations, like, say in special macros (with-floats--ints ... here go (+) (-) and stuff ONLY with floats/ints ... ) ? Preferably, I would like to hear the answers from somebody from the development team, because I have already received enough support from the community, on the IRC, I appreciate it, but now I have to make a serious choice for our company and I feel quite responsible for that. I also feel that these questions are very important for any specialist that works with OpenGL and influence Clojure acceptance for OpenGL-enabled applications world-wide. Thank you. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to
Re: Clojure, floats, ints and OpenGL
Think for youself: how much you gain for storing color in 64 bit instead of 32? How much you gain of storing positions to be projected on a, say, 1920x1080 screen, in 64 bit, not 32? Considering this, how much you gain from manufacturing 64-bit enabled GPUs for average humans to use? And putting at least twice much hardware in them, when nobody ever notices the difference? And what about the cost? Also, no magical conversion 64-32 is done anywhere in the drivers or hardware interface. On Monday, September 9, 2013 9:12:49 PM UTC+4, tbc++ wrote: Also, how much of this is a limit of the OpenGL library you are using? The raw OpenGL API supports glVertex3d and glVertex3f. Is the double version not supported by your java interface library? Timothy On Mon, Sep 9, 2013 at 11:07 AM, Timothy Baldridge tbald...@gmail.comjavascript: wrote: It's worth noting that the restrictions to IFn do not apply to definterface and deftype. Not that solves all (or any) of your problems, I've used definterface before to lock down the actual types used. Timothy On Mon, Sep 9, 2013 at 11:03 AM, Jozef Wagner jozef@gmail.comjavascript: wrote: You can typehing ints for locals (let, loop), restrictions are just for function arguments. AFAIK the reason is combinatorial explosion at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L91 I have the same problem with char. Because I cannot typehint e.g. my whitespace? function with ^char, I recieve a boxed Object and thus cannot use == for comparison. JW On Mon, Sep 9, 2013 at 6:02 PM, Mikera mike.r.an...@gmail.comjavascript: wrote: +1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so satisfied with everything - the language, the community, the Java interop, there is still something that hinders and makes me linger. Namely, the lack of good support of floats and ints in the language. While many people would not consider it to be a huge disadvantage or even notice it, things are not so bright when it comes to OpenGL. The case is that OpenGL and 3D graphics hardware in general has no support for doubles or longs. Therefore, all libraries, all data and all computations are meant to be performed with floats and ints (shaders too). Due to the lack of good support of these data types in Clojure (for example, there are no ^float and ^int typehints, float and int values can only be typecasted to, all calculations always retain doubles and longs), results in too many extra typecasts, which are absolutely unnecessary and take too much time. So, calculations become very cumbersome, even if we do not take mandatory boxing into account. Considering that such kinds of calculations are usually abuntant in the aforementioned types of applications, the penalty grows really huge. I have endeavoured several discussions on the IRC to find out possible workarounds. Although many good proposals by many good people were made, aimed at improving the situation, none of them could solve the fundamental lack of the ability to manipulate 32bit primitive (or even boxed) data types. That lack renders Clojure not really suitable for heavy-load OpenGL applications that require somewhat extensive calculations: some kinds of games, simulations, generative graphics and so on. Considering how superior Clojure is to any other language available for JVM, that black spot looks especially embarrasing. And I could imagine
Re: Clojure, floats, ints and OpenGL
While there are double types for OpenGL, like GLdouble (reference-1http://opengl.czweb.org/ch03/031-034.html, reference-2 http://opengl.czweb.org/ch03/031-034.html), their use is, softly speaking, not wide-spread: reference-3http://blog.hvidtfeldts.net/index.php/2012/07/double-precision-in-opengl-and-webgl/, reference-4http://stackoverflow.com/questions/10012985/why-does-opengl-use-float-rather-than-double and reference-5http://stackoverflow.com/questions/2079906/float-vs-double-on-graphics-hardware. I think that the real situation is very clearly described in these papers. You won't find an OpenGL programmer using double precision, unless he either has a *very* specific task or he does not know what he's doing. Doubles may be considered an archaism in OpenGL. At least, that's the current plot. I know no programmers who used doulbes in OpenGL since version 2.x, as far as I remember. As for the binding that I am using, - it is LWJGL, please see their javadoc http://lwjgl.org/javadoc/to find no mentions of double (for real usage at least). Also, the function glVertex*d is not often used from Java bindings, as far as I know. I did not browse through all their reference pages, but I am almost sure, you won't find a single mention of use of 64-bit types. You can only find such references in rather old info. Yeah, for what reason? Imagine you buy, say 4Gb super-cool NVIDIA videocard to play a game or run a scientific sumulation and... suddenly it becomes as if being 2Gb? No, doubles are not present on GPUs. Sorry, I am pretty tired argumenting that on IRC already... :) I work in multimedia company, believe me, I know what I'm saying. And Mikera is right. I did not mention that in my original message, but we also work with simply lots of hardware (sometimes we equip huge building and complexes, full with all kinds of electronics and comms and devices and stuff). Yes, they are 32, 16 and often even 8 bit hardware components. That is a huge market, really. I understand that there can be some challenge implementing the support for the datatypes, but, the benifit of doing that outweights the costs so much.. like having two hands instead of one. And don't say that most things in the world require one hand to do them.. On Monday, September 9, 2013 9:12:49 PM UTC+4, tbc++ wrote: Also, how much of this is a limit of the OpenGL library you are using? The raw OpenGL API supports glVertex3d and glVertex3f. Is the double version not supported by your java interface library? Timothy On Mon, Sep 9, 2013 at 11:07 AM, Timothy Baldridge tbald...@gmail.comjavascript: wrote: It's worth noting that the restrictions to IFn do not apply to definterface and deftype. Not that solves all (or any) of your problems, I've used definterface before to lock down the actual types used. Timothy On Mon, Sep 9, 2013 at 11:03 AM, Jozef Wagner jozef@gmail.comjavascript: wrote: You can typehing ints for locals (let, loop), restrictions are just for function arguments. AFAIK the reason is combinatorial explosion at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L91 I have the same problem with char. Because I cannot typehint e.g. my whitespace? function with ^char, I recieve a boxed Object and thus cannot use == for comparison. JW On Mon, Sep 9, 2013 at 6:02 PM, Mikera mike.r.an...@gmail.comjavascript: wrote: +1 for supporting all the JVM primitive types properly. It is worth noting that the benefits would extend much further than just OpenGL, e.g.: - int is a commonly used type in Java interop. Casting to/from it all the time is a minor annoyance/overhead - int is the type used for array indexing on the JVM - all the small ( 8 byte) primitive types save memory footprint, which is important since memory bandwidth is the limiting factor in some workloads - int/float fit into a register (and therefore perform much better) on 32 bit machines (which still exist, believe it or not) - char is a pretty useful primitive type if you are doing text processing - byte is also frequently useful, especially for IO I believe that with some enhancements to the Clojure compiler, supporting all the JVM primitive types shouldn't be too difficult, and it would provide many benefits both in terms of overall performance and interop convenience. On Monday, 9 September 2013 21:43:12 UTC+8, Alex Fowler wrote: Hello! With this letter I would like to receive an answer from somebody from the development team (if anyone else has something to say, you're surely welcome :) ). I am working for a big multimedia company and recently I have been considering moving to Clojure as the main language of development. We have been doing Java and Scala before, but now when I tried Clojure and see the possibilities it provides, I would definitely stand for it to be our ground. However, while I am so