Migration Guide: Optimium Runtime 0.3.x → 0.4.x
In this page, describes how to migrate code written for prior Optimium Runtime 0.4.2
Changes on Context
ContextStarting from Optimium Runtime 0.4.0, the Context class has been removed. As a result, several APIs have changed.
C++
The runtime must be explicitly initialized before use. You can either call rt::initialize() / rt::finalize() directly, or use rt::AutoInit which calls them automatically via RAII.
Warning:
rt::AutoInitcallsrt::finalize()in its destructor, which shuts down the runtime entirely. IfAutoInitis declared as a local variable in a narrow scope, the runtime will be finalized when that variable goes out of scope — causing any in-progress inference to fail. For this reason, declarert::AutoInitas astaticglobal variable, or at the very top ofmain().
// old:
/*
rt::Context Context = rt::Context::create(...);
*/
// new (option 1): explicit initialize / finalize
int main(...) {
rt::initialize();
// ... load models, run inference ...
rt::finalize();
}
// new (option 2): static AutoInit — runtime lives for the entire process lifetime.
static rt::AutoInit Init;
int main(...) {
// ... load models, run inference ...
// rt::finalize() is called automatically when the process exits.
}Context::loadModel() has been replaced by the free function loadModel(). The Devices argument has been moved into the ModelLoadOptions struct.
int main() {
// old:
/*
std::vector<Device> Devices{ ... };
rt::Model Model = Context.loadModel("path/to/model", Devices).value();
*/
// new:
rt::ModelLoadOptions Options;
std::vector<DeviceID> Devices{ ... };
Options.Devices = Devices;
rt::Model Model = rt::loadModel("path/to/model", Options);
}Context::getAvailableDevices() has been replaced by the free function getLocalInfo(), which provides richer information about the local host.
int main(...) {
// old:
/*
std::vector<Device> Devices = Context.getAvailableDevices().value();
*/
// new:
rt::HostInfo LocalInfo = rt::getLocalInfo();
rt::ArrayRef<DeviceID> Devices = LocalInfo.Devices;
}Context::loadExtension() has been replaced by the free function loadExtension().
int main(...) {
// old:
/*
Context.loadExtension("path/to/extension.so");
*/
// new:
rt::loadExtension("path/to/extension.so");
}Context::connectRemote() has been replaced by the free function connect(). RemoteContext has also been removed; the function now returns a RemoteSession object.
This API requires the Remote component header (
Optimium/Remote.h).
#include <Optimium/Remote.h>
int main(...) {
// old:
/*
rt::RemoteContext Remote = Context.connectRemote("addr").value();
*/
// new:
rt::RemoteSession Session = rt::connect("addr");
}Python
Context.load_model() has been replaced by the free function load_model().
def main():
# old:
# context = rt.Context(...)
# devices = [...]
# model = context.load_model("path/to/model", devices)
# new:
# 'devices' is a keyword-only argument now.
devices = [...]
model = rt.load_model("path/to/model", devices=devices)Context.available_devices has been replaced by the get_local_info() function, which provides richer information about the local host.
def main():
# old:
# devices = context.available_devices
# new:
local_info = rt.get_local_info()
devices = local_info.devicesContext.load_extension() has been replaced by the free function load_extension().
def main():
# old:
# context.load_extension("path/to/extension.so")
# new:
rt.load_extension("path/to/extension.so")Context.connect_remote() has been replaced by the free function connect(). RemoteContext has also been removed; the function now returns a RemoteSession object.
def main():
# old:
# remote = context.connect_remote("addr")
# new:
session = rt.connect("addr")Changes on logging API
Logging API changes differ by language. Please choose your language below.
C++
Starting from Optimium Runtime 0.4.0, the LogSettings class has been replaced by the logging namespace.
int main(...) {
// old:
/*
rt::LogSettings::setLogLevel(rt::LogLevel::Debug);
*/
// new:
rt::logging::setLogLevel(rt::LogLevel::Debug);
// old:
/*
rt::LogSettings::addWriter(rt::WriterOption::ConsoleWriter());
rt::LogSettings::addWriter(rt::WriterOption::FileWriter("path/to/log"));
rt::LogSettings::addWriter(rt::WriterOption::AndroidWriter());
*/
// new:
rt::logging::addLogWriter(std::make_unique<rt::logging::ConsoleWriter>());
rt::logging::addLogWriter(std::make_unique<rt::logging::FileWriter>("path/to/log"));
// AndroidLogWriter is available only on Android.
// Previously this was a no-op on other platforms.
rt::logging::addLogWriter(std::make_unique<rt::logging::AndroidLogWriter>());
}You can also add a custom LogWriter to process logs in your own way.
#include <Optimium/Runtime/Logging/LogWriter.h>
namespace rt = optimium::runtime;
class CustomWriter final : public rt::logging::LogWriter {
public:
void onWriteMessage(rt::LogLevel Level,
std::chrono::system_clock::time_point Time,
rt::StringRef Tag,
rt::StringRef Message) override {
// do something
}
};
int main(...) {
// ...
// add custom writer
rt::logging::addLogWriter(std::make_unique<CustomWriter>());
}Python
Starting from Optimium Runtime 0.4.0, the logging submodule has been introduced to configure logger settings. This module is automatically imported when optimium.runtime is imported.
import optimium.runtime as rt
def main():
# old:
# ctx = rt.Context(verbosity=rt.LogLevel.Debug,
# log_path="path/to/log")
# new:
# - Context(verbosity=...) has been replaced by
# logging.set_loglevel().
# - rt.LogLevel enum values are now UPPER_SNAKE_CASE
# to follow Python conventions.
rt.logging.set_loglevel(rt.logging.LogLevel.DEBUG)
# - Context(log_path=...) has been replaced by
# logging.enable_*() functions.
# - Starting from Optimium Runtime 0.4.0,
# logging is disabled by default.
# To enable logging, use the functions below:
# enable console logging
rt.logging.enable_console_log()
# enable file logging
rt.logging.enable_file_log("path/to/log")Changes on Model
ModelStarting from Optimium Runtime 0.4.0, some APIs have changed.
This part is subject to change.
Several member functions (properties and methods) have been replaced.
C++
getInputTensorsInfo()has been replaced bygetInputNames()getOutputTensorsInfo()has been replaced bygetOutputNames()getInputTensorInfo()andgetOutputTensorInfo()have been removed. UsegetTensorInfo()with the tensor name instead.
int main(..) {
// old:
/*
std::vector<rt::TensorInfo> Infos = Model.getInputTensorsInfo().value();
*/
// new:
rt::ArrayRef<rt::StringRef> Names = Model.getInputNames();
std::vector<rt::TensorInfo> Infos;
for (rt::StringRef Name : Names)
Infos.push_back(Model.getTensorInfo(Name));
}Python
input_tensors_infohas been replaced byinput_namesoutput_tensors_infohas been replaced byoutput_namesget_input_tensor_info()andget_output_tensor_info()have been removed. Useget_tensor()with the tensor name instead.
def main():
# old:
# infos = model.input_tensors_info
# new:
infos = [model.get_tensor(name) for name in model.input_names]Changes on InferRequest
InferRequestStarting from Optimium Runtime 0.4.0, users must prepare input and output tensors themselves.
Prior to 0.4.0, input and output tensors were provided by the runtime. However, this required copying data from outputs to inputs when models were executed sequentially. To eliminate this inefficiency, Optimium Runtime now requires users to provide their own input and output tensors.
C++
int main(...) {
// old:
/*
rt::InferRequest Request = Model.createRequest().value();
rt::Tensor Input0 = Request.getInputTensor("input_0").value();
Input0.copyFrom(...);
Request.infer();
Request.wait();
rt::Tensor Output = Request.getOutputTensor("output").value();
Output.copyTo(...);
*/
// new:
rt::InferRequest Request = Model.createRequest();
rt::TypedTensor<float> Input0 = rt::tensor<float>({/* shape of input */});
rt::TypedTensor<float> Output = rt::tensor<float>({/* shape of output */});
// using array - tensors must be in the same order
// as the model's inputs or outputs.
std::vector<rt::Tensor> Inputs;
Inputs.push_back(Input0);
std::vector<rt::Tensor> Outputs;
Outputs.push_back(Output);
Request.infer(rt::make_array(Inputs), rt::make_array(Outputs));
Request.wait();
// using map - keys must match the names of
// the model's inputs or outputs.
std::map<std::string, rt::Tensor> InputMap;
std::map<std::string, rt::Tensor> OutputMap;
InputMap["input_0"] = Input0;
OutputMap["output"] = Output;
Request.infer(InputMap, OutputMap);
Request.wait();
}Python
def main(...):
# old:
# request = model.create_request()
# request.set_inputs(...)
# request.infer()
# request.wait()
# outputs = request.get_outputs()
# new:
request = model.create_request()
input_tensor = rt.tensor(shape=(...)) # default dtype is float32
output_tensor = rt.tensor(shape=(...))
# using sequence - tensors must be in the same order
# as the model's inputs or outputs.
request.infer([input_tensor], [output_tensor])
request.wait()
# using dict - keys must match the names of
# the model's inputs or outputs.
request.infer({"input_0": input_tensor},
{"output": output_tensor})
request.wait()
# numpy.ndarray can also be used directly as tensors.
input_tensor = np.random.random((...)).astype(np.float32)
output_tensor = np.zeros((...), dtype=np.float32)
request.infer([input_tensor], [output_tensor])
request.wait()Changes on remote API
Starting from Optimium Runtime 0.4.0, the Remote API is provided as a separate component (Optimium/Remote.h in C++, optimium.runtime.connect in Python). The RemoteContext class has been removed and replaced by RemoteSession, which is returned by the connect() function.
Name changes
Devicehas been renamed toDeviceID.Shapehas been renamed toTensorShape.
C++ specific changes
rt::Resulthas been removed and exceptions have been introduced. Based on long-term experience, users tended not to check error results. To prevent segfaults caused by unchecked errors, the runtime now throws exceptions instead of returning error codes.
Python specific changes
- Enum values (e.g. for
PlatformKind,DeviceKind,ElementType) have been changed to UPPER_SNAKE_CASE to follow Python conventions.
Kotlin specific changes
- The Kotlin binding has been replaced by a Java binding to reduce dependencies and avoid version conflicts.
Updated about 1 month ago