To facilitate the use of vAccel, we provide bindings for popular languages, apart from C. Essentially, the vAccel C API can be called from any language that interacts with C libraries. Building on this, we are thrilled to present support for Go.

Essentially, the C/Go interaction is already pretty smooth, given the native CGO support available. We introduce v0.1 of the vAccel-go bindings, pending a feature-full update in the coming months. In this post, we go through the initial implementation details, as well as a hands-on tutorial on how to write your first vAccel program in Go!

vAccel overview Link to heading

vAccel is a library for hardware acceleration. Actually, it is a set of software tools that semantically expose hardware acceleration functionality to isolated workloads running on VM sandboxes. For more insights or examples about vAccel, there is a splash page, along with more elaborate documentation.

Golang overview Link to heading

The Go Programming Language is designed for scalability, making it suitable for cloud computing and large-scale servers. Go enhances development speed and efficiency, since it compiles quickly (compared to other languages), and provides a great Standard Library, along with built-in concurrency tools. Golang is also a cloud-native Programming Language. Information about Go installation can be found here, but there are also instructions on how to install Go in the vAccel-go bindings installation guide.

vAccel Go package Link to heading

The vaccel package in Golang provides access to vAccel operations, which can be used by the developers on their own Go programs. The vaccel package uses the native C bindings in order to use the vAccel C API. The following diagram demonstrates the functionality of the vaccel package:

vaccel-go-package
Figure 1: High-level overview of the vAccel Go package

Installation Guide Link to heading

vAccel Installation Link to heading

First of all, a vAccelRT installation is required before proceeding to the next sections.

Build from source Link to heading

In Ubuntu-based systems, you need to have the following packages to build vaccelrt:

  1. cmake
  2. build-essential

You can install them using the following command:

1sudo apt-get install -y cmake build-essential

Get the source code for vaccelrt:

1git clone https://github.com/cloudkernels/vaccelrt --recursive

Prepare the build directory:

1cd vaccelrt
2mkdir build
3cd build

Building the core runtime library Link to heading

1# This sets the installation path to /usr/local, and the current build
2# type to 'Release'. The other option is the 'Debug' build
3cmake ../ -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -DBUILD_PLUGIN_EXEC=ON -DBUILD_PLUGIN_NOOP=ON
1make
2sudo make install

vAccel-Go Bindings Installation Link to heading

Go Installation Link to heading

Of course, prior to installing the bindings, we have to make sure that Golang 1.20 or newer is installed in our system. We can check this using the following command:

1go version

Otherwise, go 1.20 needs to be installed. You can find instructions on how to install Go here.

Build the Bindings from source Link to heading

Download the source code:

1git clone https://github.com/nubificus/go-vaccel.git

First, you can build the examples:

1# Set vaccel location
2export PKG_CONFIG_PATH=/usr/local/share/
3cd go-vaccel
4make all

Now you have successfully built some vaccel programs using Go. The executables are located in go-vaccel/bin. You can run the noop example:

1export VACCEL_BACKENDS=/usr/local/lib/libvaccel-noop.so
2./bin/noop

Or the exec example, providing a path for the shared object and an integer:

1export VACCEL_BACKENDS=/usr/local/lib/libvaccel-exec.so
2./bin/exec /usr/local/lib/libmytestlib.so 100
3# if everything go as expected, the
4# plugin will probably double the integer 

Tutorial Link to heading

The following example demonstrates the usage of the vaccel package to build vaccel-enabled Go programs. The tutorial will perform an image classification operation, using the no-op plugin. Keep in mind the following three conditions before building:

1. Make sure to import the package in your programs:

1import "github.com/nubificus/go-vaccel/vaccel"

2. Define vaccel location:

1export PKG_CONFIG_PATH=/usr/local/share

3. And finally, always define the location of the vaccel-plugin you are willing to use:

1# In case of No-Op for testing:
2export VACCEL_BACKENDS=/usr/local/lib/libvaccel-noop.so

Example Link to heading

Create the project directory

1cd ~
2mkdir go-vaccel-test
3cd go-vaccel-test

Initialize the Module

1go mod init go-vaccel-test

Download the bindings

1go get github.com/nubificus/go-vaccel

And create a Go file

1touch main.go

Add the following lines to perform Image Classification

 1package main
 2
 3import (
 4	"fmt"
 5	"os"
 6
 7	"github.com/nubificus/go-vaccel/vaccel"
 8)
 9
10func main() {
11
12	if len(os.Args) < 2 {
13		fmt.Println("Usage: ./main <filename>")
14		return
15	}
16
17	/* Get the filename from command line argument */
18	filePath := os.Args[1]
19
20	/* Session */
21	var session vaccel.Session
22
23	err := vaccel.SessionInit(&session, 0)
24
25	if err != 0 {
26		fmt.Println("error initializing session")
27		os.Exit(err)
28	}
29
30	var outText string
31
32	/* Read the image-bytes */
33	imageBytes, e := os.ReadFile(filePath)
34	if e != nil {
35		fmt.Printf("Error reading file: %s\n", e)
36		os.Exit(1)
37	}
38
39	/* Perform Image Classification */
40	outText, err = vaccel.ImageClassification(&session, imageBytes)
41
42	if err != 0 {
43		fmt.Println("Image Classification failed")
44		os.Exit(err)
45	}
46
47	fmt.Println("Output: ", outText)
48
49	/* Free Session */
50	if vaccel.SessionFree(&session) != 0 {
51		fmt.Println("An error occurred while freeing the session")
52	}
53}

Then, specify vaccel location:

1export PKG_CONFIG_PATH=/usr/local/share

Define the location of the plugin:

1export VACCEL_BACKENDS=/usr/local/lib/libvaccel-noop.so

Build the source file:

1go build main.go

And run:

1./main </path/to/image>

You must see the following message:

1[noop] Calling Image classification for session 1
2[noop] Dumping arguments for Image classification:
3[noop] len_img: <numBytes>
4[noop] will return a dummy result
5Output:  This is a dummy classification tag!

Conclusion Link to heading

The above example shows how to use the vaccel package in Go to use various vaccel features. As you can see, the example doesn’t run an actual image classification operation, since we use the no-op plugin for testing purposes. However, we could use a vaccel backend that performs the operation. Here, you can find more vaccel tools and operations that you could possibly use in your Go programs. For example, except image classification, you can write programs that use the exec plugin, which gives you the opportunity to use functions contained in a shared object. Or, finally, you could also use the noop example if you just want to test the installation of the package.