Earlier quoted context omitted.
What would one need to use c or c++ to write a julia package? It's as fast as native code so no need to use multiple languages.
Julia is really fast in 95% cases, but 5% still "make the weather". The pairwise summation is an example. I will post benchmarks D vs Julia next week ;)
Using D and std.ndslice as a Numpy Replacement
41–50 of 59 posts
Re: Using D and std.ndslice as a Numpy Replacement
#42Does D have code for: plotting, optimization, probability distributions, machine learning, Fourier transformations, masked arrays, finanial calculations, structured arrays (read a CSV from disk, get named columns based on the header), SVD, QR and Cholesky decomposition, eigens, least squares, Levenberg Marquardt, matrix inverse and pseudoinverses, integration, Runge Kutta, interpolation, bsplines, fft convolves, mult…
A lot of that is up and coming. https://github.com/DlangScience [x] Plotting: http://code.dlang.org/packages/plot2kill [+] Optimization: Nothing directly for the purpose, but the intermediate steps are done. And a little bit of work from http://code.dlang.org/packages/atmosphere [x] Probability Distributions: http://dlangscience.github.io/dstats/api/dstats/random.html and http://dlang.org/phobos/std_mathspecial.html…
> [+] Cholesky Decomposition: Trivial to implement
How is it that you can judge Cholesky decomposition to be trivial to implement, while being unfamiliar with QR decomposition?
Cholesky decomposition is not trivial to implement well.
> Your post comes across to me as being rather cynical - but why not be supportive of the good work that's being done?
I had a similar experience to what's happening here myself. I worked on a project that had some very specific requirements for a high performance simulation (described by a differential equation). I worked on a very specialized piece of code for a long time to optimize this differential equation solver, eventually writing a JIT compiler to generate specialized code for each simulation.
I had a D advocate come along and rather vigorously argue that D can solve this problem, without really understanding it, and missing some key requirements.
This sort of comes off the same way, "a numpy replacement". numpy is big and does a lot of stuff. Like Cholesky decomposition, many of these things have trivial implementations, and then they have good implementations. The trivial implementations will take a few hours to write. The good implementations will take a few months, or even longer. Sometimes "not good" means slow, sometimes "not good" means numerical stability issues, etc. If you don't have the right background, these things may not even be obvious.
This is a bit of a pattern with D folks. Several times (this, my previous experience, and others), I've gotten the impression that a D fan comes along, invests a bit of time (a few weeks, months) in a particular domain, and starts making comparisons with other tools that they only scratch the surface of. It can rub people the wrong way.
edit: The symbolic expression reference in this post is another example. Computer algebra is an incredibly difficult thing to implement. I don't know of anything that is harder to implement well than a computer algebra system. Yet, you link a single file under 1000 lines as partially checking the box in your list for symbolic expression manipulation. D might be a highly productive, but it's not that productive.
Re: Using D and std.ndslice as a Numpy Replacement
#43Earlier quoted context omitted.
Very nicely put and I agree. What I was expecting to see in the list of numpy problems mentioned in the article wasn't there. The major problem that makes Numpy performance lag behind C++ or Fortran is the extra level of indirection that is needed for accessing an element (via stride ptr), and the need for extra copies that is forced on you by vectorization. Numexpr can help for certain cases of the latter, but its s…
Numba obviate these issues
What I think the current post is about is that similar nice and performant abstractions for D. I love Python a lot but I have to pay extra attention so that it is performant, so that I don't make stupid typos. I have to rewrite parts in Cython or Weave (sadly the latter gets no love anymore). Larger the code base becomes I have to spent more time in the tail part of the 'tooth to tail' ratio. In D many of these are taken care by default, I have to worry a lot less about these things. The other fantastic thing is DMD has super fast compilation times. It used to be faster than Go in compilation time but the latter has caught up in that department (grossly lacking in others). D binaries execute a lot faster (when compiled with LDC or GDC). It may lack some libraries here and there, but that does not worry me as much, everyone has to start somewhere, and to be honest Python is lacking in that respect compared to R. What would be worrisome is the presence of structural aspects that may get in the way of such an eco-system emerging. I don't see anything of that kind in D.
In anycase I don't quite see how Numba obviates the issues I mentioned. It does not change the Ndarray representation, and the extra indirections lay right there. OTOH some copy elision I would grant.
I can give concrete examples. The isotonic regression implementation in scikits.learn was absolutely pathetic. It has been rewritten several times and its performance is still severely lacking in spite of being Cythonized. You can take a stab at it with Numba and see what you can do. In C++ (D would have been nicer) the very first idiomatic implementation in STL was faster than any of these rewrites. I wrote it once and moved on. But C++ is a horrifying mess, now if there was a language that gave me C++ performance (not asking for much) but none of the mess and numpy level expressiveness to boot, that would be sweet. Julia, Nim, D, PyPy are some of the contenders trying to reach this holy grail
Re: Using D and std.ndslice as a Numpy Replacement
#44I'm guessing the GC might rule it out for many cases where you do signal processing in C++, but I may as well ask: what's the deployment side of things like? Can I easily build a shared library and use it from a C++ application?
Re: Using D and std.ndslice as a Numpy Replacement
#45I occasionally rewrite Python+NumPy signal processing code in C++ for purposes of packaging and integration with native apps, so I read these examples with an eye to how they compare with typical C++, rather than with NumPy. They compare very well, and it would never have occurred to me to look into D as a possibility for this sort of code. I'm guessing the GC might rule it out for many cases where you do signal proc…
Compiling a shared library is as easy as passing the "--app:lib" option to the Nim compiler: http://nim-lang.org/docs/nimc.html#compiler-usage-command-li...
The GC is optional; you can manage your memory manually if you prefer: http://nim-lang.org/docs/manual.html#types-reference-and-poi...
The Nim tutorial is here if you want to have a quick skim: http://nim-lang.org/docs/tut1.html
Re: Using D and std.ndslice as a Numpy Replacement
#46Earlier quoted context omitted.
A lot of that is up and coming. https://github.com/DlangScience [x] Plotting: http://code.dlang.org/packages/plot2kill [+] Optimization: Nothing directly for the purpose, but the intermediate steps are done. And a little bit of work from http://code.dlang.org/packages/atmosphere [x] Probability Distributions: http://dlangscience.github.io/dstats/api/dstats/random.html and http://dlang.org/phobos/std_mathspecial.html…
> [?] QR: Afraid I'm not sure what you're referring to. > [+] Cholesky Decomposition: Trivial to implement How is it that you can judge Cholesky decomposition to be trivial to implement, while being unfamiliar with QR decomposition? Cholesky decomposition is not trivial to implement well . > Your post comes across to me as being rather cynical - but why not be supportive of the good work that's being done? I had a si…
Nothing D specific here. That's the pattern for every language, be it Haskell, Go, Common Lisp, JavaScript or Java ...
Re: Using D and std.ndslice as a Numpy Replacement
#47Earlier quoted context omitted.
you're benchmarking is python's speed of array instantiation vs. Ds mathematical speed. Its obvious that D will win. Not true, the D code also has the overhead of array initialization. std.array.array is called which allocates the results of the range into an array on the GC, which everyone bemoans as being slow as a dog. Plus, I don't see why this is an invalid benchmark when this is perfectly normal Numpy code, the…
He's absolutely right, this is a crappy benchmark. Increase the array sizes by at least a factor of 100 to get anything meaningful. The fact that someone who is "the review manager for std.ndslice's inclusion into the standard library" does not understand how to profile numerical algorithms makes me very skeptical of using D for any numerical project. Plus, the syntax looks god-awfully unintuitive. A main advantage o…
Ok, let's do that and see what happens:
python -m timeit -s 'import numpy; data = numpy.arange(10000000).reshape((1000, 10000))' 'means = numpy.mean(data, axis=0)'
D code import std.range : iota;
import std.array : array;
import std.algorithm;
import std.experimental.ndslice;
import std.datetime;
import std.conv : to;
import std.stdio;
enum testCount = 10_000;
void f0() {
auto means = 10_000_000.iota
.sliced(1000, 10000)
.transposed
.map!(r => sum(r) / r.length)
.array;
}
void main() {
auto r = benchmark!(f0)(testCount);
auto f0Result = to!Duration(r[0] / testCount);
f0Result.writeln;
}
Results Python: 14.1 msec
D: 39 μs
D is 361.5x fasterRe: Using D and std.ndslice as a Numpy Replacement
#48Earlier quoted context omitted.
Numba obviate these issues
I see your excitement about Numba, I guess you follow it closely, or perhaps have other valid reasons. So all the best. However, the last time I tried to use it, about 4 months ago, installation was a bitch and it would crap out compiling some functions. It holds promise of course, so does alternatives. What I think the current post is about is that similar nice and performant abstractions for D. I love Python a lot…
The thing is, which `tadlan` seems unaware of, a lot of this stuff just fails in production environments and hits corner cases that the Numba compiler does not handle (I'm talking about the first part of the Numba compiler pipeline, where it converts to Numba IR, and not yet to LLVM IR, and does things like examine the CPython bytecode to alter the representation from a CPython stack-based representation to a register-based representation that will be compatible with LLVM and ultimately with the actual machine itself). In that compilation step, the only things that are able to be handled are things that the Numba team (I used to be a member of it) explicitly support. They don't support a full-blown compiler for the entire Python language, nor even for every type of NumPy operation. That's not a knock against Numba at all -- it's a specializing compiler and obviously they need to prioritize what to support, and make longer term goals about supporting more general things. But the point still remains that you cannot just assume that if you call `jit` on any arbitrary Python code, it will always become faster. In some cases, it can even become slower.
I suspect `tadlan` is very interested in Numba and enthusiastic about knowing the taxonomy of Numba details, but it does not seem like that user has had real world experience trying to get Numba to work in production, and seeing all of the numerous buggy and missing features. I don't want to diminish anyone's enthusiasm for Numba, so it's probably best just not to engage with `tadlan` about it. That user's mind seems made up already.
Re: Using D and std.ndslice as a Numpy Replacement
#49Earlier quoted context omitted.
He's absolutely right, this is a crappy benchmark. Increase the array sizes by at least a factor of 100 to get anything meaningful. The fact that someone who is "the review manager for std.ndslice's inclusion into the standard library" does not understand how to profile numerical algorithms makes me very skeptical of using D for any numerical project. Plus, the syntax looks god-awfully unintuitive. A main advantage o…
"Increase the array sizes by at least a factor of 100 to get anything meaningful." Ok, let's do that and see what happens: python -m timeit -s 'import numpy; data = numpy.arange(10000000).reshape((1000, 10000))' 'means = numpy.mean(data, axis=0)' D code import std.range : iota; import std.array : array; import std.algorithm; import std.experimental.ndslice; import std.datetime; import std.conv : to; import std.stdio;…
* how do I know that the calculations aren't actually optimized away in all that code I can't understand? E.g. what happens if you make f0() return the means array instead of being a void function?
* Given the same number of lines (or characters), are you sure you can't write equally fast Python code?
* I tested the Fortran version on a slightly slower computer (got 14.7 msec on the Python version). Fortran runs at 0.7 μs, i.e. > 55x faster than D, with less code that's more readable to boot.
Re: Using D and std.ndslice as a Numpy Replacement
#50Earlier quoted context omitted.
"Increase the array sizes by at least a factor of 100 to get anything meaningful." Ok, let's do that and see what happens: python -m timeit -s 'import numpy; data = numpy.arange(10000000).reshape((1000, 10000))' 'means = numpy.mean(data, axis=0)' D code import std.range : iota; import std.array : array; import std.algorithm; import std.experimental.ndslice; import std.datetime; import std.conv : to; import std.stdio;…
Ok. So three points remain: * how do I know that the calculations aren't actually optimized away in all that code I can't understand? E.g. what happens if you make f0() return the means array instead of being a void function? * Given the same number of lines (or characters), are you sure you can't write equally fast Python code? * I tested the Fortran version on a slightly slower computer (got 14.7 msec on the Python…
If you can't understand the code, how did you know it was a void function. Please stop with the hyperbole, it's not adding anything to the discussion.
Updated code:
import std.range : iota;
import std.array : array;
import std.algorithm;
import std.experimental.ndslice;
import std.datetime;
import std.conv : to;
import std.stdio;
enum testCount = 10_000;
auto f0() {
auto means = 10_000_000.iota
.sliced(1000, 10000)
.transposed
.map!(r => sum(r) / r.length)
.array;
return means;
}
void main() {
auto r = benchmark!(f0)(testCount);
auto f0Result = to!Duration(r[0] / testCount);
f0Result.writeln;
}
Results: Python: 14.1 msec
D: 41 μs
D is 343.9x faster
"Given the same number of lines (or characters), are you sure you can't write equally fast Python code?"IMO program size is an almost meaningless statistic outside of code golf challenges. LOC is not an indicative measure of code readability, usefulness, or organization.
For example, your Fortran code was 11 lines while the D function (with the return) is eight lines.
"I tested the Fortran version on a slightly slower computer (got 14.7 msec on the Python version). Fortran runs at 0.7 μs, i.e. > 55x faster than D, with less code that's more readable to boot."
Just goes to show why Fortran is still used in a lot of scientific areas.
But two things:
1. Fortran is a much simpler language than D or Python and is much harder to do multipurpose work in it (so I'm told from Fortran programmers, I don't know Fortran myself). So when your program needs to do anything other than number crunching, it's normally done in a separate language. Using D you can have everything in one code base.
2. This article was about Numpy and std.ndslice because those are two areas that I know about and Numpy is a very popular library. Bringing up Fortran's speed here is like commenting on how much faster C++ is in a thread about Ruby.
Also, readability is a subjective idea; I believe the D code is more readable than the Fortran you wrote. Different strokes.