This is a step by step tutorial to do a very simple computation with Gorgonia.
Our goal is to use all the plumbing of Gorgonia to do a simple operation:
$ f(x,y) = x + y $
with x = 2 and y = 5
The equation x + y = z can be represented as a graph:
To compute the result, we use 4 steps:
x and y thenz
*Create an empty expression graph with this method:
g := gorgonia.NewGraph()We will create some nodes and associate them to the ExprGraph.
var x, y, z *gorgonia.Nodex and y are scalar variables, we can create the corresponding node with:
x = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("x"))
y = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("y"))the functions take the exprgraph as argument; the resulting node is automatically associated to the graph.
Now create the addition operator; this operator takes two nodes and returns a new node z:
if z, err = gorgonia.Add(x, y); err != nil {
log.Fatal(err)
}the returning node z is added to the graph even if g is not passed to z or to the Add function.
We have a ExprGraph that represents the equation z = x + y. Now it’s time to assign some values to x and y.
We use the Let function:
gorgonia.Let(x, 2.0)
gorgonia.Let(y, 2.5)To run the graph and compute the result, we need to instanciate a VM. Let’s use the TapeMachine:
machine := gorgonia.NewTapeMachine(g)
defer machine.Close()and run the graph:
if err = machine.RunAll(); err != nil {
log.Fatal(err)
}If a second run is needed, it is mandatory to call the Reset() method of the vm object:
machine.Reset()
Now the node z holds the result.
We can extract its value by calling the Value() method:
fmt.Printf("%v", z.Value())we could also access the underlying “Go” value with a call to z.Value().Data() which would return an interface{} holding a float64 in our case
package main
import (
"fmt"
"log"
"gorgonia.org/gorgonia"
)
func main() {
g := gorgonia.NewGraph()
var x, y, z *gorgonia.Node
var err error
// define the expression
x = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("x"))
y = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("y"))
if z, err = gorgonia.Add(x, y); err != nil {
log.Fatal(err)
}
// create a VM to run the program on
machine := gorgonia.NewTapeMachine(g)
defer machine.Close()
// set initial values then run
gorgonia.Let(x, 2.0)
gorgonia.Let(y, 2.5)
if err = machine.RunAll(); err != nil {
log.Fatal(err)
}
fmt.Printf("%v", z.Value())
}$ go run main.go
4.5