I am soon going to release a new version of Neanderthal.
I reinstalled ATLAS, so I decided to also update benchmarks with threaded ATLAS bindings.
The results are still the same for doubles on one core: 10x faster than Vectorz and 2x faster than JBlas.
The page now covers some more cases: multicore ATLAS (on my 4-core i7-4790k) and floats. Neanderthal is 60 times faster with multi-threaded ATLAS and floats than Vectorz (core.matrix).
For the rest of the results, please follow the link. This will work with older versions of Neanderthal.
It would be great if Neanderthal simply implemented the core.matrix protocols, then people could use it as a core.matrix implementation for situations where it makes sense. I really think it is an architectural dead-end for Neanderthal to develop a separate API. You'll simply get less users for Neanderthal and fragment the Clojure library ecosystem which doesn't help anyone.
In the absence of that, we'll just need to develop separate BLAS implementations for core.matrix.
Would be great if you could implement the core.matrix protocols and solve this issue. It really isn't much work, I'd even be happy to do it myself if Neanderthal worked on Windows (last time I tried it doesn't).
On Monday, March 14, 2016 at 12:28:24 AM UTC+1, Mikera wrote:It would be great if Neanderthal simply implemented the core.matrix protocols, then people could use it as a core.matrix implementation for situations where it makes sense. I really think it is an architectural dead-end for Neanderthal to develop a separate API. You'll simply get less users for Neanderthal and fragment the Clojure library ecosystem which doesn't help anyone.Mike, I explained that many times in detail what's wrong with core.matrix, and I think it is a bit funny that you jump in every time Neanderthal is mentioned with the same dreams about core.matrix, without even trying Neanderthal, or discussing the issues that I raised. Every time your answer is that core.matrix is fine for *YOUR* use cases. That's fine with me and I support your choice, but core.matrix fell short for *MY* use cases, and after detailed inspection I decided it was unsalvageable. If I thought I could improve it, it would have been easier for me to do that than to spend my time fiddling with JNI and GPU minutes.
I understand your emotions about core.matrix, and I empathize with you. I support your contributions to Clojure open-source space, and am glad if core.matrix is a fine solution for a number of people. Please also understand that it is not a solution to every problem, and that it can also be an obstacle, when it fells short in a challenge.
In the absence of that, we'll just need to develop separate BLAS implementations for core.matrix.I support you. If you do a good job, I might even learn something now and improve Neanderthal.Would be great if you could implement the core.matrix protocols and solve this issue. It really isn't much work, I'd even be happy to do it myself if Neanderthal worked on Windows (last time I tried it doesn't).I am happy that it is not much work, since it will be easy for you or someone else to implement it ;) Contrary to what you said on slack, I am *not against it*. I said that many times. Go for it. The only thing that I said is that *I* do not have time for that nor I have any use of core.matrix.Regarding Windows - Neanderthal works on Windows. I know this because a student of mine compiled it (he's experimenting with an alternative GPU backend for Neanderthal and prefers to work on Windows). As I explained to you in the issue that you raised on GitHub last year, You have to install ATLAS on your machine, and Neanderthal has nothing un-Windowsy in its code. There is nothing Neanderthal specific there, it is all about comiling ATLAS. Follow any ATLAS or Nympu + ATLAS or R + ATLAS guide for instructions. Many people did that installation, so I doubt it'd be a real obstacle for you.
I also think the core.matrix crusade is unnecessary. Here are my two cents:
1. No one jumps in every time someone writes a new web routing library saying "No! You'll fragment the clojure
web routing community! Use compojure!" I think we should pick and choose based on our needs.
2. We should build on well-tested, stable APIs, true. Dragan has built on top of BLAS (basically stable for over
35 years) and LAPACK (25-35 years depending on how you count).
3. Dragan has no need or desire to implement the core.matrix API, but I'm sure someone that wants native speed
and compatibility with core.matrix will do so when the need arises.
4. If you want accessibility to the widest possible community of numerical programmers, bear in mind that most
of them aren't clojure or even java programmers anyway. BLAS and LAPACK are the way to make them feel
at home. Pure-java numerical programming is a rather strange cul-de-sac community already.
5. Numerical programming is a field where you, unfortunately, have to drop layers of abstraction more
frequently than other fields. I'd rather drop down into ATLAS than <<insert random java backend with its own
matrix class here>>.
In short, having two libraries that do the same thing is not a problem, and if it becomes a problem, I think we as a community can deal with it fairly quickly.
--Leif
Please remember that core.matrix is primarily intended as an API, not a matrix implementation itself. The point is that different matrix implementations can implement the standard protocols, and users and library writers can then code to a standard API while maintaining flexibility to use the implementation that best suits their use cases (of which Neanderthal could certainly be one).
I understand your emotions about core.matrix, and I empathize with you. I support your contributions to Clojure open-source space, and am glad if core.matrix is a fine solution for a number of people. Please also understand that it is not a solution to every problem, and that it can also be an obstacle, when it fells short in a challenge.Interested to understand that statement. Please let me know what use cases you think don't work for core.matrix. A lot of people have worked on the API to make it suitable for a large class of problems, so I'm interested to know if there are any we have missed.For any point you have here, I'm happy to either:a) Explain how it *does* workb) Take it as an issue to address in the near future.
In the absence of that, we'll just need to develop separate BLAS implementations for core.matrix.I support you. If you do a good job, I might even learn something now and improve Neanderthal.Would be great if you could implement the core.matrix protocols and solve this issue. It really isn't much work, I'd even be happy to do it myself if Neanderthal worked on Windows (last time I tried it doesn't).I am happy that it is not much work, since it will be easy for you or someone else to implement it ;) Contrary to what you said on slack, I am *not against it*. I said that many times. Go for it. The only thing that I said is that *I* do not have time for that nor I have any use of core.matrix.Regarding Windows - Neanderthal works on Windows. I know this because a student of mine compiled it (he's experimenting with an alternative GPU backend for Neanderthal and prefers to work on Windows). As I explained to you in the issue that you raised on GitHub last year, You have to install ATLAS on your machine, and Neanderthal has nothing un-Windowsy in its code. There is nothing Neanderthal specific there, it is all about comiling ATLAS. Follow any ATLAS or Nympu + ATLAS or R + ATLAS guide for instructions. Many people did that installation, so I doubt it'd be a real obstacle for you.Every time I have tried it has failed on my machine. I'm probably doing something wrong, but it certainly isn't obvious how to fix it. Can you point me to a canonical guide and binary distribution that works "out of the box"?
There is a set of BLAS-like API functions in core.matrix already. See: https://github.com/mikera/core.matrix/blob/develop/src/main/clojure/clojure/core/matrix/blas.cljc
Having said that, I don't personally think the BLAS API is a particularly good fit for Clojure (it depends on mutability, and I think it is a pretty clumsy design by modern API standards). But if you simply want to copy the syntax, it's certainly trivial to do in core.matrix.
An important point to note is that they don't do the same thing at all: core.matrix is an API providing an general purpose array programming abstraction with pluggable implementation support. Neanderthal is a specific implementation tied to native BLAS/ATLAS. They should ideally work in harmony, not be seen as alternatives.
Neanderthal is more closely comparable to Vectorz, which *is* a matrix implementation (and I think it matches or beats Neanderthal in performance for virtually every operation *apart* from large matrix multiplication for which ATLAS is obviously fantastic for).
If anyone has other ideas / a better strategy I'd love to hear, and I welcome a good constructive debate. I'm not precious about any of my own contributions. But I do genuinely think this is the best way forward for Clojure data science overall, based on where we are right now.
There is a set of BLAS-like API functions in core.matrix already. See: https://github.com/mikera/core.matrix/blob/develop/src/main/clojure/clojure/core/matrix/blas.cljcGitHub history says they were added 7 days ago. Nevermind that they just delegate, so the only BLAS-y thing is the 4 method names taken out of Neanderthal (BLAS has a bit more stuff than that), but why you reinvented the wheel instead just creating core.matrix (or vectorz) implementation of Neanderthal's API?
Having said that, I don't personally think the BLAS API is a particularly good fit for Clojure (it depends on mutability, and I think it is a pretty clumsy design by modern API standards). But if you simply want to copy the syntax, it's certainly trivial to do in core.matrix.If you look at Neanderthal's API you'll see that I took a great care to make it fit into Clojure, which I think I succeeded.Regarding mutability:1) Neanderthal provides both mutable and pure functions2) Trying to do numeric computing without mutability (and primitives) for anything than toy problems is... well, sometimes it is better to plant a Sequoia seed, wait for the tree to grow, cut it, make an abacus and compute with it...
An important point to note is that they don't do the same thing at all: core.matrix is an API providing an general purpose array programming abstraction with pluggable implementation support. Neanderthal is a specific implementation tied to native BLAS/ATLAS. They should ideally work in harmony, not be seen as alternatives.* Neanderthal has an agnostic api and it is not in any way tied to BLAS/ATLAS *Neanderthal also has pluggable implementation support - and it already provides two high-performance implementations that elegantly unify two very different *hardware* platforms: CPU and GPU. And it does it quite transparently (more about that can be read here: http://neanderthal.uncomplicate.org/articles/tutorial_opencl.html)
Neanderthal is more closely comparable to Vectorz, which *is* a matrix implementation (and I think it matches or beats Neanderthal in performance for virtually every operation *apart* from large matrix multiplication for which ATLAS is obviously fantastic for).You think without having tried that. I tried that, and *Neanderthal is faster for virtually *ALL* operations, even 1D. Yesterday I did a quick measure of asum (1D vector operation), for example, and neanderthal was, if I remember correctly, * 9x faster than Vectorz in that simple summing *. I even pointed to you that Neanderthal is faster even in ALL those cases when you raised that argument the last time, but you seem to ignore it.
If anyone has other ideas / a better strategy I'd love to hear, and I welcome a good constructive debate. I'm not precious about any of my own contributions. But I do genuinely think this is the best way forward for Clojure data science overall, based on where we are right now.I would like to propose a strategy where more love is given to the actual libraries (incanter is rather indisposed and stagnant IMO) that solve actual problems instead of trying to unify what does not exist (yet!). Then, people will use what works best, and what does not work will not be important. That's how things go in open-source...
2) I disagree with. Most real world data science is about data manipulation and transformation, not raw computation. 1% of people need to optimise the hell out of a specific algorithm for a specific use case, 99% just want convenient tools and the ability to get an answer "fast enough".
But if you only offer native and GPU dependencies then you aren't really offering an agnostic API. Won't even work on my machine..... could you add Windows support? Maybe you want to add pure JVM implementations as well? And for Clojure data structures? What about ClojureScript support? Sparse arrays? Oh, could you maybe support n-dimensional arrays? Datasets?
Interesting. I don't recall you posting such benchmarks, apologies if I missed these.I'd be happy to benchmark myself if I could get Neanderthal to build. I don't believe 9x though... this operation is usually bound by memory bandwidth IIRC
If anyone has other ideas / a better strategy I'd love to hear, and I welcome a good constructive debate. I'm not precious about any of my own contributions. But I do genuinely think this is the best way forward for Clojure data science overall, based on where we are right now.I would like to propose a strategy where more love is given to the actual libraries (incanter is rather indisposed and stagnant IMO) that solve actual problems instead of trying to unify what does not exist (yet!). Then, people will use what works best, and what does not work will not be important. That's how things go in open-source...core.matrix already exists, is widely used and already unifies several different implementations that cover a wide variety of use cases. It provides an extensible toolkit that can be used either directly or by library / tool implementers. It's really very powerful, and it's solving real problems for a lot of people right now. It has the potential to make Clojure one of the best languages for data science.
Don't get me wrong, I think Neanderthal is a great implementation with a lot of good ideas. I'd just like to see it work well *with* the core.matrix API, not be presented as an alternative. The Clojure data science ecosystem as a whole will benefit if we can make that work.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Just a side comment, Dragan, if you don't want to be compared against some other tech, it might be wise to not make the subtitle of a release "X times faster than Y". Make the defining feature of a release that it's better than some other tech, and the proponents of that tech will probably start to get a bit irritated.
And I think the distinction made here about floats vs doubles is very important. We can all construct benchmarks that show tech X being faster than tech Y. But if I am evaluating those things I really want to know why X is faster than Y. I want to know what tradeoffs were made, what restrictions I have in using the faster tech, etc. Free performance gains are very rare, so the moment I see "we are X times faster" I immediately start looking for a caveats section or a rationale on why something is faster. Not seeing that, or benchmark documentation, I almost immediately consider the perf numbers to be hyperbole.
core.matrix already exists, is widely used and already unifies several different implementations that cover a wide variety of use cases. It provides an extensible toolkit that can be used either directly or by library / tool implementers. It's really very powerful, and it's solving real problems for a lot of people right now. It has the potential to make Clojure one of the best languages for data science.I agree that this sounds great, but, come on... It sounds like a marketing pitch. Clojure currently doesn't offer a single data science library that would be even a distant match to the state of the art. Nice toys - sure. I hope you didn't mean Incanter?...
Its a fact that the JVM is not the state of the art for numerical computing, including big swaths of data science/machine learning. There is 0 chance of this changing until at least Panama and Valhalla come to fruition (5 year timeline).
I too shunned JNI as a dirty, clunky, ugly slime, and believed that pure Java is fast enough, until I came across problems that are slow even in native land, and take eternity in Java. And I started measuring more diligently, and, instead of following gossip and dis-use of JNI, I took time to learn that stuff and saw that it is not that ugly, and most of the ugliness could be hidden from the user, so I am not that pessimistic about JVM. It is a good mule :)