Skip to content

Use C++ in UbiOps Deployments

UbiOps doesn't provide native support to use C++ in a deployment. However, it is possible to use C++
in a deployment by using PyBind11. This method allows for a very fast and efficient way to use C++ in a deployment.
This how-to shows how to set up a very basic Python 3.8 / C++ deployment.

PyBind11 Documentation

It is highly recommended to read the PyBind11 Documentation for a full understanding of the exact capabilities of the PyBind11 library. This is a very basic example, but it is possible to do much more with PyBind11 library.

C++ Code

The C++ code that will be used is a simple add function. The code is shown below:

int add(int i, int j) {
    return i + j;
}

Now in order to use this function in Python, we need to bind it to Python using PyBind11.
The complete code is shown below:

#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(ubiopscpp, m) {
    m.doc() = "pybind11 ubiops example add function"; // optional module docstring

    m.def("add", &add, "A function that adds two numbers");
}

The PYBIND11_MODULE macro is used to bind the C++ code to Python. The first argument is the name of the module, in this case ubiopscpp.
Furthermore, a docstring is specified for the module, which is optional.
At last, the C++ int add(...) function is bound to the Python function add.

Save this file in a separate folder called compile as ubiops_src.cpp.
The file structure is now as follows:

    └── compile
       └── ubiops_src.cpp

Compilation

C++ is different from Python in the sense that it needs to be compiled before it can be used. This is furthermore system dependent, so it is not possible to use compiled C++ code on many different systems. Since the C++ is to be run on the UbiOps infrastructure, the code needs to be compile for this system.
The Pybind11 documentation provides a list of supported compilers. With one of these methods, the C++ code can be compiled to a shared library that can be used in Python inside an UbiOps deployment.

UbiOps Infrastructure

Note that the UbiOps infrastructure runs on Ubuntu 20.04. Compiling for this system is therefore recommended.
A support article on how to reliably compile for this system can be found here.

The resulting file structure after compilation will be as follows:

    ├── Dockerfile
    └── compile
       ├── ubiopscpp.so
       └── ubiops_src.cpp

Python Deployment Code

Now that the C++ code is compiled, it can be used in a UbiOps deployment.
First, create a new folder for the deployment (deployment_package in this how-to).
Secondly, we create a folder called libraries in the deployment_package folder and copy the compiled ubiopscpp.so file to this folder.
At last, we create deployment.py in the main deployment_package folder with the following content:

from libraries import ubiopscpp


class Deployment:
    def __init__(self, base_directory, context):
        pass

    def request(self, data):
        first_value = data['first_value']
        second_value = data['second_value']
        return {
            "output": ubiopscpp.add(first_value, second_value)
        }

The file structure is now as follows:

    ├── deployment_package
       ├── deployment.py
       └── libraries
           └── ubiopscpp.so
    ├── Dockerfile
    └── compile
       ├── ubiopscpp.so
       └── ubiops_src.cpp

Now we only need to zip the deployment_package folder and upload it to UbiOps!

Upload to UbiOps

Create a new deployment, with the following settings: Set the input to:
first_value: Integer
second_value: Integer

Set the output to:
output: Integer

Now create a new version with Python 3.8 and upload the zipped deployment_package folder.
The deployment is now ready to be used!