Live data from Hacker News

Test for lists in Cython

github.com

71–80 of 147 posts

Re: Test for lists in Cython

#71

Earlier quoted context omitted.

I've been using JAX ( https://jax.readthedocs.io/en/latest/ ) for scientific computing in general (in particular MCMC algorithms), as it's really fast. Even on a CPU you get massive speedups compared to numpy (can be up to 2 or 3 orders of magnitude faster in some cases). The main selling point of the library is automatic differential and compilation to XLA, but I've been using it even when I don't need gradients, as…

Have you tried numba+numpy? In my experience, it is much faster than Jax and can compile to cuda. It's not caveat free, but it also removes the hustle of labeling arrays as donated in Jax. You may find this interesting https://github.com/scikit-hep/iminuit/blob/develop/tutorial/...

I haven't tried numba but I've heard good things about it! Nice linked tutorial. If I understand correctly, you pass in jitted functions (using numba, and jax) into iminuit which does the optimisation?

With Jax you can write native for loops that can also be jitted (I imagine you can also do this in numba?); this can then be really fast. Though in that case you would have to write the optimisation algorithm yourself which is not always practical!

Another big speedup in Jax is due to vmap/pmap, which allow to vectorise/parallelise computation. For example you can build a massive gram matrix really quickly using vmap.

Another point: Jax can also run on GPU (like numba :) ) without having to rewrite anything.

Re: Test for lists in Cython

#72
post #51

Earlier quoted context omitted.

Have you tried numba+numpy? In my experience, it is much faster than Jax and can compile to cuda. It's not caveat free, but it also removes the hustle of labeling arrays as donated in Jax. You may find this interesting https://github.com/scikit-hep/iminuit/blob/develop/tutorial/...

Have you been successful in implementing non-trivial computational code in numba/numpy? I've always found it starts to really break for anything which isn't really trivial, and the errors are mostly non-prescriptive and highly verbose.

I just implemented both a CSV parser and an address standardizer in numba (both CPU and GPU) running in parallel feed through a message queue with a bunch of workers subprocs.

It takes a bit of getting used to but the performance gains on impressive. Basically, my bottlenecks shift from compute to i/o.

I think you have to balance it against writing in C/C++. Mentally, it is basically the same work as writing in C (you manage memory/you write complicated for-loops) but you have good array support with numpy. The primary advantage for me that everything stays in the python runtime environment. You just run the code without any extra steps.

...

What is missing from the timing type 'toy' benchmarks is an understanding that there is typically more than one bottleneck in a real problem and it is easy to choose the wrong one to optimize and get little gains.

After starting C (30 years ago now), spending a long time in C#, then switching to Python a few years ago, I think the unappreciated advantage of python is that I have to abandon all pretense of caring about speed and just get stuff working. It basically solves the pre-mature optimization problem for me by being a fast interpreted language rather than a slow compiled language.

Re: Test for lists in Cython

#73
post #9

Rust doesn’t need to copy the data. It’s trivial to pass e.g. Numpy arrays to Rust as slices via Cython (let alone originating in Cython!), modify them, and return them, or use them as input for a new returned struct. https://github.com/urschrei/simplification https://github.com/urschrei/lonlat_bng https://github.com/urschrei/pypolyline Each of those repos has links to the corresponding Rust “shim” libraries that pro…

Given that it's via pyO3, you could even pass the numpy arrays using https://github.com/PyO3/rust-numpy and get ndarrays at the other side.

Same no copy, slightly more user friendly approach.

Further criticism of the actual approach - even if we didn't do zero copy, there's no preallocation for the vector despite the size being known upfront, and nested vectors are very slow by default.

So you could speed up the entire thing by passing it to ndarray, and then running a single call to sum over the 2D array you'd find at the other end. (https://docs.rs/ndarray/0.15.1/ndarray/struct.ArrayBase.html...)

Re: Test for lists in Cython

#74
post #64

Earlier quoted context omitted.

> As a more general comment, using a GC language as the FFI target from a GC language is begging for difficult-if-not-impossible-to-debug crashes down the line. Not true! What you do is that you keep a registry for objects passed from the host vm to the foreign vm in which you register objects thus transferred. And you use a similar mechanism for objects passed from the foreign vm to the host vm. In CPython, you simp…

> This ... is how many gc:ed runtimes interact with other gc:ed runtimes. It's not that easy. You'd need to register the object as a GC root as long as it's being managed by the foreign GC, and similarly ensure that objects in the foreign VM are properly "de-registered" when the local GC finalizes them. It's far from trivial, particularly when compared with other memory-management strategies.

Yes, that is what the scheme I described is doing. You'd need a similar mechanism in Rust too to prevent it from collecting objects prematurely. I think implementing this is fairly trivial. The difficult part of writing an FFI is handling closures: Java calling Python calling Java calling Python which throws an exception...

Re: Test for lists in Cython

#75

I was a huge fan of Matlab way back. I wrote a hundred small Matlab programs for usage in the research department of the company I worked in. Doing data operations in Matlab was way more elegant than in say, Numpy which I tried later. Development was fast and ergonomics were good. After using Ruby for years, returning to Matlab style code in Julia felt somewhat awkward. Instead of my_array.length you have length(my_a…

The standard way to make a histogram in Julia is histogram(data) Using the latest version (1.6 - although 1.6.1 just came out) the time to first plot is just a few seconds. After that, plotting in the REPL is instantaneous. I probably don’t understand what you’re getting at when you speak of making frequent changes to code. REPL-based development in Julia is excellent, and there are Pluto notebooks as well.

The way I would like to work is to have the repl open on the left hand side of the screen and code editor (like Sublime text, I'm sure many use Vim) on the right hand side.

I would run the code in repl (just using up-arrow and enter), get some plot, modify the code in the editor, save it, and rerun it repl.

Repl is used for connecting inputs to the program, not for editing. Often times you want to develop some small program that is part of a bigger program. So you run the big program up to the point it calls the small program. Or you run with some mock data. Then you have all your inputs for the small program, so you can start iterating it. Run - observe - edit - run - observe - edit.

In Matlab this worked because it detected if the file had changed, and reloaded it. You didn't specifically have to call load("my_function.m") before every call to it. This means you can just lift code from the big program and iterate on it in repl.

Re: Test for lists in Cython

#76

Earlier quoted context omitted.

You seem to understand Julia well. Is there a reason there is no nexus plugin or way to mirror the julia repo for dev networks that dont have unrestricted access to the internet, or are even airgapped. I see multiple people asking this online, so it is a common enough problem, but it seems like people are saying the Julia approach makes it hard to support.

Frankly, Julia is a young language, so these things have yet to materialize. Also, for those that really do want it, the Julia package mirror is one of the few products that the company behind Julia sells as part of JuliaHub. It is inconvenient though that it doesn't fit in with the rest of the languages in Nexus.

Isn't julia hub still remote? You can't install it on an airgap or behindnyour firewall on your own equipment can you?

Re: Test for lists in Cython

#77
post #60

Earlier quoted context omitted.

> Instead of my_array.length you have length(my_array). In my personal preference the method call is just a nicer way of doing the same thing. Well...they're both method calls, aren't they? (So they're both the nicer way?)

Those who are attached to the class-based OOP model used, for example, in Python will find the dot notation more natural. But Julia’s multiple dispatch is a superset of this, and unarguably more powerful and flexible. Python OOP leads to monstrosities like >>> ', '.join(['1', '2', '3']) '1, 2, 3' >>> '1, 2, 3'.split(', ') ['1', '2', '3']

As I’m clearly missing the bigger picture, what do you find to be super offensive about this?

I read the first as the concat symbol applied to an iterable leads to string concated by the concat symbol.

I read the second as an iterable broken by split symbol leads to an iterable of the chunks.

Re: Test for lists in Cython

#78
post #58
post #23

Earlier quoted context omitted.

Godbolt example?

Here you go: https://play.rust-lang.org/?version=stable&mode=debug&editio... Because the data structure LotsOfData doesn't implement the Clone trait, attempting to create a copy will fail at compile-time.

OK. I was curious whether it was part of the type system or one of those #[feature] thingies.

https://run.dlang.io/is/jOXfJz is a D equivalent

Re: Test for lists in Cython

#79
post #60

Earlier quoted context omitted.

> Instead of my_array.length you have length(my_array). In my personal preference the method call is just a nicer way of doing the same thing. Well...they're both method calls, aren't they? (So they're both the nicer way?)

Those who are attached to the class-based OOP model used, for example, in Python will find the dot notation more natural. But Julia’s multiple dispatch is a superset of this, and unarguably more powerful and flexible. Python OOP leads to monstrosities like >>> ', '.join(['1', '2', '3']) '1, 2, 3' >>> '1, 2, 3'.split(', ') ['1', '2', '3']

Multiple dispatch is usually class-based as well.

Re: Test for lists in Cython

#80
post #37

I feel like the #1 downside of Python for the last few years is that you cannot take advantage of multiple cores of a CPU easily. Especially when you think it is heavily used in data analysis. We use Python for data analysis as well, and for 95% of operations we are doing, numpy is fast enough that we don't have any complaints. But sometimes, we do wish to be able to take advantage of all the cores in our CPUs, espec…

Numpy operations release the GIL (usually at least) so you can use a threadpool and, indeed, share memory. Just try it and you may be pleasantly surprised. Dask is great if you’re processing large amounts of data, and it recommends and supports threads for this reason.

I didn't know that. So let's say I have 4 regular Python threads calling the same function, and in this function, let's say I call numpy.add on the same array (but different parts of the array), then will it actually use different cores for these 4 different threads? I will try it out, if it works, then that's actually great and would be super easy.
Post reply on HN