XIV · AMD acceleration (welvet.rocm) / CHAPTER 94
AMD ROCm: mount and forward
github.com/openfluke/welvet/nativerocmlinux/windows amd64
Why it exists
Run a Go layer on an AMD GPU with an explicit lifetime via the independent welvet.rocm library.
What it is
Mount an identity Dense layer, inspect the ROCm version and device identity, and forward a Float32 tensor.
Session ownership
Create a session with nativerocm.Mount, call Forward repeatedly and close it when finished. Mount accepts supported layers, Stack, Parallel and Grid layouts. The library is independent of welvet.cpp, welvet.metal and welvet.cuda.
Requirements and backend boundaries
Go Welvet v1.5.0 adds the independent welvet.rocm 0.79 library (mounted model ABI 1) at github.com/openfluke/welvet.rocm. Install from its checkout:
cd ../welvet.rocm
./scripts/linux_install_go.sh
# Windows amd64 (MSVC + ROCm / HIP):
./scripts/windows_install_go.ps1
Execution requires Linux x86_64 or Windows amd64, Go with cgo, and an AMD driver/runtime with HIP (libamdhip64). Set WELVET_ROCM_LIBRARY to override library discovery. Ordinary Go CPU use does not require an AMD GPU. Unsupported hosts print SKIP; missing libraries or no GPU on a supported host also soft-SKIP in these book examples.
Honest coverage: library build/load is validated; GPU compute remains untested until a ROCm-capable HSA device is available (Polaris/Picasso-class hosts do not qualify).
Go schedules work and manages memory; numerical ROCm forward, backward and weight updates execute device kernels when HSA is present. Activations are Float32; FormatNone parameter storage follows the ROCm dtype matrix. Small examples demonstrate APIs; GPU launch costs can outweigh useful work at small shapes.
cpu-tiled / go_cpu means Go CPU; native_cpu means welvet.cpp; rocm means the independent AMD GPU library. Examples 96-100 can use go run -tags welvet_rocm . to exclude C++ linkage. Chapter 101 requires the normal cgo build for both native engines. JSON routing (§100-§101) is Linux amd64 today; explicit Mount works on Windows amd64 as well.
Go example
cd welvet/examples/96-amd-rocm && source ../env.sh && go run .// Mount one layer, execute its forward pass on AMD ROCm, and release it.
package main
import (
"flag"
"fmt"
"log"
"runtime"
"github.com/openfluke/welvet/core"
"github.com/openfluke/welvet/layers/dense"
"github.com/openfluke/welvet/nativerocm"
"github.com/openfluke/welvet/quant"
)
func main() {
if e := run(); e != nil {
log.Fatal(e)
}
}
func run() error {
library := flag.String("library", "", "optional libwelvet_rocm.so/.dll path")
flag.Parse()
if !rocmPlatformOK() {
fmt.Println("SKIP: AMD ROCm needs linux/amd64 or windows/amd64 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 := nativerocm.Mount(l, nativerocm.Options{LibraryPath: *library})
if e != nil {
fmt.Printf("SKIP: ROCm unavailable (%v)\n", e)
return nil
}
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=rocm version=%s\ndevice=%s\ninput=%v output=%v shape=%v\n", session.Version(), session.Identity(), x.Data, post.Data, post.Shape)
return nil
}
func rocmPlatformOK() bool {
return runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "windows")
}
Output
SKIP: ROCm unavailable (nativerocm: load: libamdhip64.so.7: cannot open shared object file: No such file or directory)
Validate (harness)
cd welvet/examples/96-amd-rocm && source ../env.sh && go run .