Welvet examples
82. Apple Metal: mount and forward
Part: XII · Apple acceleration (welvet.metal)
Package: nativemetal
Status: ok: verified macOS/arm64 on Apple M5
When
Mount a Go layer and execute its forward pass on Apple GPU.
Where
From example/welvet/82-apple-metal:
go run .
go run . -library /path/to/libwelvet_metal.dylib
Why
See the backend version and actual Metal device identity; release the session explicitly.
What
Creates an identity Dense layer, mounts it, forwards a Float32 tensor, and closes the session.
Requirements
Apple silicon macOS, Go with cgo, and the installed independent Metal dylib.
Set WELVET_METAL_LIBRARY or install it from the Metal checkout:
cd /Users/openfluke/gs/welvet.metal
./scripts/macos_install_go.sh
Use the Go v1.3.0 checkout containing nativemetal. Examples 82-86 can also use
go run -tags welvet_metal . to exclude the independent C++ binding. Example 87
needs the normal build to keep both native backends. Unsupported operating
systems print SKIP. Missing libraries on a supported host report an error.
These are usage examples with small shapes. For speed measurements, use
../apple_stress_test. The results are numerical
CPU/GPU comparisons, not model prediction accuracy.
Backend labels in routed examples: cpu-tiled is Go CPU, native_cpu is
welvet.cpp, and metal is the independent Apple GPU backend.
Captured sample
backend=metal version=0.68
device=metal:Apple M5:reg=4294968322:ws=19069665280
input=[0.5 -0.25] output=[0.5 -0.25] shape=[1 2]
main.go
Download source ↓// Mount one layer, execute its forward pass on Apple Metal, and release it.
package main
import (
"flag"
"fmt"
"github.com/openfluke/welvet/core"
"github.com/openfluke/welvet/layers/dense"
"github.com/openfluke/welvet/nativemetal"
"github.com/openfluke/welvet/quant"
"log"
"runtime"
)
func main() {
if e := run(); e != nil {
log.Fatal(e)
}
}
func run() error {
library := flag.String("library", "", "optional libwelvet_metal.dylib path")
flag.Parse()
if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" {
fmt.Println("SKIP: Apple Metal needs Apple silicon macOS and cgo")
return nil
}
l, e := dense.NewConfigured(2, 2, core.ActivationLinear, core.DTypeFloat32, quant.FormatNone, []float32{1, 0, 0, 1})
if e != nil {
return e
}
session, e := nativemetal.Mount(l, nativemetal.Options{LibraryPath: *library})
if e != nil {
return e
}
defer session.Close()
x := &core.Tensor[float32]{Shape: []int{1, 2}, Data: []float32{.5, -.25}}
post, e := session.Forward(x)
if e != nil {
return e
}
fmt.Printf("backend=metal version=%s\ndevice=%s\ninput=%v output=%v shape=%v\n", session.Version(), session.Identity(), x.Data, post.Data, post.Shape)
return nil
}