6 ms·
Gonum – Numerical Computing for Go
- deleted 9y ago[deleted]
- Khanthulhu 9y agoWhat's the use case for this? Machine learning? But data? General math use?
- howeman 9y agoGeneral math use, like numpy/scipy.
- jbochi 9y agoHere at The New York Times we are using it to power some of our recommendation algorithms. We are actually training the models with Python and serving them with Go using gonum. Our library was just open sourced (and still in my personal account, until we add more documentation): https://github.com/jbochi/facts https://github.com/jbochi/facts
- avyfain 9y agoThis sounds really cool. Anywhere I could read more about the Python -> Go integration? Or are you just exporting the raw weight matrices?
- bochi 9y agoWe are just exporting the matrices. Nothing fancy.
- Khanthulhu 9y agoBeautiful. Thanks for the reply
- paultopia 9y agoA solid, featureful & performant numerics library seems like a really good match for Go---if it can match numpy but also provide benefits like the safety of types, binary compilation, and better performance in non-numeric code, that's a really exciting case for sliding away from python?
- danieldk 9y agoI have done some numeric programming in Go and compared to Python it's really hampered by the lack of operator overloading. Of course, it just provides convenience, but it's what makes writing stuff in numpy, Tensorflow, Eigen, etc elegant.
- paulsutter 9y agoAs of reading your comment, I'm 100% convinced that Go needs generics. I'm a longtime Go advocate, love coding in Go, but until now thought the lack of generics is just fine. Lately I do a lot of numpy/tensorflow, and have begun to really dislike the slowness of python. It would be great to do that work in Go specifically.
- sythe2o0 9y agoGenerics wouldn't necessarily bring in operator overloading, though. I haven't seen a Go proposal for generics that actually included it.
- chewxy 9y agoI wrote Gorgonia and recently wrote a large piece on my thoughts on having generics in Go - https://blog.chewxy.com/2017/09/11/tensor-refactor/ https://blog.chewxy.com/2017/09/11/tensor-refactor/ Would love your thoughts on it
- jerf 9y agoIf Go was to become big in the scientific programming community, it would need generics eventually. One interesting thing that NumPy demonstrates is that such things are capable of becoming popular enough that they essentially become their own sub-language. One option in that case, if GoNum collected enough of a community, is to fork Go and add generics. There are some complicated generics options that would be difficult to use, but there's some simpler options that would work, and arguably "generics via templated code generation" is pretty much what you'd want for this use case anyhow since it gives the optimizers the most to work with. Said fork might also add some custom optimizations for this use case. I wouldn't want to deviate too far from core Go because I'd like to be able to keep pulling from that code base if at all possible, but some judicious work here might be a net positive.
- optimuspaul 9y agowonder how this compares to numpy/scipy in terms of features and performance. Looks pretty comprehensive.
- howeman 9y agoWe aren't at full feature parity, but we're pretty close. There are some big things we are missing (ODE, FFT), and we have a bunch of things they don't have (statistical distance measures being one example). We are trying to be pure-go, so it's not at simple as providing a wrapper API. Working on it though!
- dm319 9y agostatistical distance measures? is that like tSNE and similar?
- egl2016 9y ago"By default, blas64 and lapack64 call the native Go implementations of the routines. Alternatively, it is possible to use C-based implementations of the APIs through the respective cgo packages and "Use" functions." Performance comparison? Algorithmic equivalence? How close are the results numerically (e.g. how do they compare on badly conditioned matrices)?
- howeman 9y agoThe algorithms are (basically) equivalent, and are translations from the Fortran (though row major instead of column major). As far as I know there are no major differences in the answers, though for extremely poorly conditioned matrices (1e14 or so) you shouldn't expect consistent answers across any implementation. The performance story is complex. Typically we're the same speed on small matrices (and using Go is faster if you include the cgo overhead). We currently have significant speed penalties on large matrices (300x300 or so), but Kunde21 is working on assembly kernels for the BLAS functions to close that gap
- openasocket 9y agoI'm surprised your performance is anywhere near that of standard BLAS implementations. The Golang compiler doesn't have support for explicit SIMD or auto-vectorization, so that's a big performance gain just sitting there.
- howeman 9y agoFor small vectors and matrices the cgo overhead swamps the assembly speedups. For large vectors cache misses dominate, and the assembly doesn't matter as much. It does matter significantly for medium vectors and large matrices. In that case we provide cgo wrappers and are working on SIMD kernels.
- openasocket 9y agoHow does this play with Go's scheduler? My understanding is that the Go scheduler is not preemptive, and goroutines are switched out at yield point, like the start of a function body. So tight loops that don't call other functions can effectively hog the OS thread until it leaves that loop body (No idea what happens when doing FFI, maybe that's done in a separate thread pool?). For most cases where you would use Go you aren't generally doing a bunch of CPU-bound work so that doesn't matter, but here you might run into some hiccups. I'm specifically thinking of a case where you use this library to do some heavy matrix operations as part of a web service, and those tight loops hog the OS threads and hurt your bandwidth and p90 latency. My question to the developer: is that issue something you've encountered with this library? If not, did you design the library to periodically yield in tight loops, or am I just completely wrong about the Go scheduler?
- howeman 9y agoI don't use Gonum with a webserver + large calculations so I can't definitively answer. No one has reported problems, but that could be a lack of usage. One thing though is that matrix multiplication (which is a kernel for higher-level operations) is written in a blocked format, and the code can be pre-empted on any of those blocks, so I wouldn't suspect it's a problem.
- openasocket 9y agoYeah, skimming your source it seems most of your loops involve calling some function, and even if that's inlined I believe the Go compiler will put a speculative yield call in there. I suppose my hypothetical would be an issue if you used a non-Go BLAS implementation, as calling out to C will hog the OS thread. But this is a known issue (e.x. https://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/ https://www.cockroachlabs.com/blog/the-cost-and-complexity-o...).
- chewxy 9y agoThe solution to that is to write a C-batcher. Gorgonia uses that (optional) - https://github.com/chewxy/gorgonia/tree/master/blase https://github.com/chewxy/gorgonia/tree/master/blase (also it's undergoing major reconstruction/refactoring right now)
- pbnjay 9y agoI can't wait till the Go team starts giving these packages more love from the performance perspective. Now that the compiler has an SSA backend we might start seeing more SIMD and other optimizations, but it's still a ways to go before performance is comparable to bare C libraries for heavy computation and tight inner loops.
- brian-armstrong 9y agoHonestly, I don't think that Go is the right language for this. I've used Go quite a lot and it feels like it mostly just gets in your way. You can't really do memory management, which will likely impede performance for numerical work. There's no operator overloading either. C++, for all its flaws, seems to just generally be a more well-conceived language and more generalist than Go. The only place I really feel like Go works is specifically in the context of moving bytes from one socket to another.
- d4l3k 9y agoWhat kind of memory management do you need that Go doesn't provide? It's not too hard to write Go to minimize allocations (and most short lived allocations end up on the stack anyways unlike other languages [1]). If you really need a lot of allocations you can always use https://golang.org/pkg/sync/#Pool https://golang.org/pkg/sync/#Pool to avoid GC overhead. [1] https://groups.google.com/d/msg/golang-nuts/KJiyv2mV2pU/wdBUH1mHCAAJ https://groups.google.com/d/msg/golang-nuts/KJiyv2mV2pU/wdBU...
- brian-armstrong 9y agoBut if you're doing that, you might as well just use a language with RAII, good scoping and unique pointers. A language like... C++
- sbinet 9y agoI have been using Gonum for some time now (also contributed, mostly in the plotting area). Last summer, I tried an experiment: have a student migrate a little python-based analysis to a Go-based one. The analysis was fitting some cosmological constants out of the so called Hubble diagram. I was pleased to see that, in the span of 2-3 months, the student who had limited knowledge in programming (a bit of python), managed to pull off the minimization of a 740 supernovae dataset with a 2220x2220 nuisance parameters matrix. and the run time was 2x faster than the python one (with scipy/minuit for the minimization, so everything in C/C++, really). success. :) (and this motivated us to completely switch to Go as a teaching language for our master in particle physics / cosmology.)
- Recurecur 9y agoI suggest you take a look at Julia. I think it's a much better fit for that type of work...