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.Node
x
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