Live data from Hacker News

Gonum – Numerical Computing for Go

gonum.org

21–30 of 47 posts

Re: Gonum – Numerical Computing for Go

#21
post #12
post #9

Earlier quoted context omitted.

Here 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

This sounds really cool. Anywhere I could read more about the Python -> Go integration? Or are you just exporting the raw weight matrices?

We are just exporting the matrices. Nothing fancy.

Re: Gonum – Numerical Computing for Go

#22

Earlier quoted context omitted.

I 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.

As 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.

I 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/

Would love your thoughts on it

Re: Gonum – Numerical Computing for Go

#23

How 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 y…

You're right in that people have seen high p90 latency as a result of things like base64 encoding large blocks.

But one thing to remember is that go inserts gc and pre-emption points at function call sites. So basically as long as a function is occasionally called you're good.

Cgo threading does complicate the matter. My understanding is that cgo calls are done in a threadpool with a larger stack size. I don't know the details about how that threadpool is managed. Not sure if this would help or hurt your concern.

Also, don't forget GOMAXPROCS. There's nothing stopping you from letting the go runtime spin up arbitrarily large number of OS threads.

So it's not an ideal situation, but if you're careful I don't think tight loops are likely to torpedo an otherwise sound go project.

Re: Gonum – Numerical Computing for Go

#24
I 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.

Re: Gonum – Numerical Computing for Go

#25

Earlier quoted context omitted.

I 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.

As 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.

If 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.

Re: Gonum – Numerical Computing for Go

#26

How 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 y…

I'm not sure to understand that p90 latency problem, the cpu is used somewhere anyway so even if you use another language you won't be able to server a request while doing some intense cpu work?

Re: Gonum – Numerical Computing for Go

#27

Earlier quoted context omitted.

I 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.

As 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.

One of the big perks of Julia comes from its built-in multiple dispatch. Overloading is one thing, but full-blown multiple dispatch is really powerful in a math context, where the concept of "multiplication" is entirely dependent on the types of things you are multiplying.

In Python (despite there being an excellent `multipledispatch` module) this is mostly just handled by aggressive duck typing ("if it has a .foo method, it's good enough"). In R it's handled with S4 classes, which are cool and kind of CLOS-like but are even slower than single dispatch.

So I guess my question is: why do you need generics when you have interfaces? These other (admittedly dynamically typed) languages make do without.

Re: Gonum – Numerical Computing for Go

#28

Earlier quoted context omitted.

As 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.

One of the big perks of Julia comes from its built-in multiple dispatch. Overloading is one thing, but full-blown multiple dispatch is really powerful in a math context, where the concept of "multiplication" is entirely dependent on the types of things you are multiplying. In Python (despite there being an excellent `multipledispatch` module) this is mostly just handled by aggressive duck typing ("if it has a .foo me…

"So I guess my question is: why do you need generics when you have interfaces? These other (admittedly dynamically typed) languages make do without."

Going backwards, as you allude to, dynamic languages fulfill the use cases for generics, as long as you don't care about type safety, which is a thing that is true for the whole language anyhow so it's not much to give up.

For Go, the main problem is that when you're trying to be mathematical, with interfaces you get the worst of both the static and the dynamic worlds. You might like to define an interface that lets you add two vectors, right?

    type Vector interface {
        Components() []float64
    }


    type Add interface {
        Add(Vector) Vector
    }
which might let you implement an Add method on something that is a Vector as well, but you don't get a satisfactory result from either perspective. From the static perspective you can not, using interfaces, guarantee that someone doesn't add a Vector3 to a Vector2, meaning you must either panic at run time or have Add potentially return an error (that will generally not be necessary to check if used correctly, which is not a pleasant error to work with). From the dynamic perspective, you have to remember that what comes out the other end of that operation is always an Add interface value, not a concrete type, so if you have a Vector2 and .Add(Vector2) to it, you don't get a concrete Vector2, you get a value of type "interface Add", which you have to manually cast back to a Vector2 if you want to do anything more than just keep adding to it.

You can make Vector2 have a distinct .Add(Vector2) method which does return a Vector2, but then if you also have a "func (v Vector3) Add(Vector3) Vector3" function, there is no way to declare an interface that both of those methods can meet, so you can not write any dimensionally-oblivious code that uses generic vector adding.

In "normal software engineering", Go's interface limitations are often not so bad, certainly not as bad as is often portrayed on HN. However, when you try to create a strongly-type numeric system (and you want it to be strongly-typed because that's also how you get good performance), Go's interface mechanism is basically worthless.

Re: Gonum – Numerical Computing for Go

#29
post #26

How 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 y…

I'm not sure to understand that p90 latency problem, the cpu is used somewhere anyway so even if you use another language you won't be able to server a request while doing some intense cpu work?

The cpu will pause it to give all threads some cpu time. The difference is that it's the OS doing the work of cleaning up between threads, as opposed to the go runtime pausing and switching. Keeping it all in Go is faster, but it doesn't have the capability to pause, cleanup, and prepare for re-execution in the middle of a block of code that the OS does.

Re: Gonum – Numerical Computing for Go

#30
post #25

Earlier quoted context omitted.

As 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.

If 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 diffi…

I can see the argument for operator overloading being necessary, but I don't understand the argument for generics. There's basically no time I've wanted generics coding Go, except a couple times with float64 vs []float64. I also see the need for float32 vs. float64, but that's a very small use case for generics in terms of scope (we can and do autogenerate float32 code).

There's a couple of cases with float64 vs. complex128 matrices, but I have been annoyed with those silent changes in Matlab where the answer is wrong but the code continues anyway.

Post reply on HN