C

Introduction

Band provides a C API for developers who want to use Band in their C/C++ projects. The API is a thin wrapper around the core C++ API. The C API is available in the libband.h header file.

Link provides a complete example of how to dynamically load the library and use the C API.

Example

#include <libband.h>

int main() {
  // 1. Create a configuration for the engine.
  BandConfigBuilder* b = BandConfigBuilderCreate();
  BandAddConfig(b, BAND_PLANNER_LOG_PATH, /*count=*/1, "log.json");
  BandAddConfig(b, BAND_PLANNER_SCHEDULERS, /*count=*/1, kBandHeterogeneousEarliestFinishTime);
  BandConfig* config = BandConfigCreate(b);

  // 2. Create an engine.
  BandEngine* engine = BandEngineCreate(config);

  // 3. Create and register a model.
  BandModel* model = BandModelCreate();
  BandModelAddFromFile(model, kBandTfLite,
                        "mobilenet_v2_1.0_224_quant.tflite");
  BandEngineRegisterModel(engine, model);

  // 4. Create input and output tensors for the model.
  BandTensor* input_tensor = BandEngineCreateInputTensor(engine, model, 0);
  BandTensor* output_tensor = BandEngineCreateOutputTensor(engine, model, 0);
  std::tuple<unsigned char*, int, int> image_buffer =
      LoadRGBImageRaw("cat.jpg");

  // 5. (Optional) Create a buffer and an image processor to initialize the
  // input tensor with the image data.
  BandBuffer* buffer = BandBufferCreate();
  BandBufferSetFromRawData(buffer, std::get<0>(image_buffer),
                            std::get<1>(image_buffer), std::get<2>(image_buffer),
                            kBandRGB);

  BandImageProcessorBuilder* builder = BandImageProcessorBuilderCreate();
  BandImageProcessor* processor = BandImageProcessorBuilderBuild(builder);
  BandImageProcessorProcess(processor, buffer, input_tensor);

  // 6. Run the model.
  BandEngineRequestSync(engine, model, &input_tensor, &output_tensor);
  
  // 7. Get the result (class index).
  unsigned char* output =
      static_cast<unsigned char*>(BandTensorGetData(output_tensor));
  // should be 282 (tiger cat) for cat.jpg
  size_t class_index = ArgMax<unsigned char>(output, 1001);

  // 8. Clean up.
  BandTensorDelete(input_tensor);
  BandTensorDelete(output_tensor);

  BandImageProcessorBuilderDelete(builder);
  BandImageProcessorDelete(processor);
  delete[] std::get<0>(image_buffer);

  BandEngineDelete(engine);
  BandConfigDelete(config);
}

API Types

Band provides the following types in the C API:

  • BandConfig: Configuration object for the engine.
  • BandConfigBuilder: Builder for the configuration object.
  • BandEngine: Engine object.
  • BandModel: Model object that holds the model data. It must outlive the engine.
  • BandTensor: Tensor object that holds the input/output data of a model.
  • BandBuffer: Wrapper for any data buffer interchangable with BandTensor.
  • BandImageProcessor: Image processor object that converts an image buffer to a tensor.
  • BandImageProcessorBuilder: Builder for the image processor object.
  • BandRequestHandle: Handle for an asynchronous request.

API Functions (Engine)

BandEngineCreate

BandEngine* BandEngineCreate(BandConfig* config);

Creates a BandEngine instance with the given configuration.

BandEngineDelete

void BandEngineDelete(BandEngine* engine);

Deletes the BandEngine instance.

BandEngineRegisterModel

void BandEngineRegisterModel(BandEngine* engine, BandModel* model);

Registers a model to the engine. The engine will load the model and allocate resources for it.

BandEngingeGetNumInputTensors

int BandEngingeGetNumInputTensors(BandEngine* engine, BandModel* model);

Returns the number of input tensors for the given model.

BandEngingeGetNumOutputTensors

int BandEngingeGetNumOutputTensors(BandEngine* engine, BandModel* model);

Returns the number of output tensors for the given model.

BandEngineGetNumWorkers

int BandEngineGetNumWorkers(BandEngine* engine);

Returns the number of workers in the engine.

BandEngineGetWorkerDevice

BandDeviceFlag BandEngineGetWorkerDevice(BandEngine* engine, int worker_index);

Returns the device flag (e.g., kBandCPU, kBandGPU, …) of the worker at the given index.

BandEngineCreateInputTensor

BandTensor* BandEngineCreateInputTensor(BandEngine* engine, BandModel* model,
                                        int index);

Creates an input tensor for the given model. The tensor is allocated by the engine and must be deleted by the caller.

BandEngineCreateOutputTensor

BandTensor* BandEngineCreateOutputTensor(BandEngine* engine, BandModel* model,
                                         int index);

Creates an output tensor for the given model. The tensor is allocated by the engine and must be deleted by the caller.

BandEngineRequestSync

BandStatus BandEngineRequestSync(
    BandEngine* engine, BandModel* model, BandTensor** input_tensors,
    BandTensor** output_tensors)

Runs the model with the given input tensors and stores the result in the output tensors. The function blocks until the execution is finished. Returns kBandOk if the execution is successful.

BandEngineRequestAsync

BandRequestHandle BandEngineRequestAsync(
    BandEngine* engine, BandModel* model, BandTensor** input_tensors);

Runs the model with the given input tensors. The function returns immediately and the result will be stored in the output tensors when the execution is finished. Returns a handle to the request.

BandEngineWait

BandStatus BandEngineWait(BandEngine* engine, BandRequestHandle handle, 
    BandTensor** output_tensors, size_t num_outputs);

Blocks until the request is finished. Returns kBandOk if the execution is successful and the result is stored in the output tensors.

BandEngineSetOnEndRequest

void BandEngineSetOnEndRequest(
    BandEngine* engine,
    void (*on_end_invoke)(void* user_data, BandRequestHandle job_id, BandStatus status),
    void* user_data);

Sets a callback function that will be invoked when a request is finished. The callback function will be invoked in the engine thread. The status is the status of the request.

API Functions (Buffer)

Band provides a buffer type that can be used to hold data for a tensor. The buffer can be created from a raw data pointer. The buffer can be converted to a tensor using an image processor.

ImageProcessorBuilder is used to build an ImageProcessor. ImageProcessor defines a series of operations to be applied to a BandBuffer and convert it to a BandTensor.

By default, builder without any operation will create a ImageProcessor provides a direct mapping from BandBuffer to BandTensor without normalization. E.g., automated color space conversion, resize to the output tensor shape, and data type conversion.

BandBufferCreate

BandBuffer* BandBufferCreate();

Creates a buffer instance.

BandBufferDelete

void BandBufferDelete(BandBuffer* buffer);

Deletes the buffer instance.

BandBufferSetFromRawData

BandStatus BandBufferSetFromRawData(BandBuffer* buffer, const void* data,
                                    size_t width, size_t height,
                                    BandBufferFormat format);

Sets the buffer from raw image data. Supported formats are:

  • kBandRGB (3 channels - 8 bits per channel, interleaved)
  • kBandRGBA (4 channels - 8 bits per channel, interleaved)
  • kBandGRAY (1 channel - 8 bits per channel)
  • kBandNV21 (YUV 4:2:0 - 8 bits per channel, interleaved)
  • kBandNV12 (YUV 4:2:0 - 8 bits per channel, interleaved)
  • kBandYV12 (YUV 4:2:0 - 8 bits per channel, planar)
  • kBandYV21 (YUV 4:2:0 - 8 bits per channel, planar)

BandBufferSetFromYUVData

BandStatus BandBufferSetFromYUVData(BandBuffer* buffer, const void* y_data,
                                    const void* u_data, const void* v_data,
                                    size_t width, size_t height,
                                    size_t row_stride_y, size_t row_stride_uv,
                                    size_t pixel_stride_uv,
                                    BandBufferFormat buffer_format);

Sets the buffer from YUV data. Supported formats are:

  • kBandNV21 (YUV 4:2:0 - 8 bits per channel, interleaved)
  • kBandNV12 (YUV 4:2:0 - 8 bits per channel, interleaved)
  • kBandYV12 (YUV 4:2:0 - 8 bits per channel, planar)
  • kBandYV21 (YUV 4:2:0 - 8 bits per channel, planar)

BandImageProcessorBuilderCreate

BandImageProcessorBuilder* BandImageProcessorBuilderCreate();

Creates an image processor builder instance.

BandImageProcessorBuilderDelete

void BandImageProcessorBuilderDelete(BandImageProcessorBuilder* builder);

Deletes the image processor builder instance.

BandImageProcessorBuilderBuild

BandImageProcessor* BandImageProcessorBuilderBuild(
    BandImageProcessorBuilder* builder);

Builds an image processor instance from the builder.

BandAddOperator


BandStatus BandAddOperator(BandImageProcessorBuilder* b,
                           BandImageProcessorBuilderField field, int count, ...);

Adds an operator to the builder. The order of the operators will be the order of the operations applied to the input buffer. E.g., BandAddOperator(builder, BAND_IMAGE_PROCESSOR_CROP, 4, 0, 0, 100, 100); will crop the input buffer from (0, 0) to (100, 100). This will return kBandError if the given variadic arguments are invalid. Available operators are:

  • BAND_IMAGE_PROCESSOR_CROP: Crops the input buffer. int x0, int y0, int x1, int y1 - crop from top-left corner, inclusive
  • BAND_IMAGE_PROCESSOR_RESIZE: Resizes the input buffer. int width, int height - resize to a new size
  • BAND_IMAGE_PROCESSOR_ROTATE: Rotates the input buffer. float angle - counter-clockwise, between 0 and 360 in multiples of 90
  • BAND_IMAGE_PROCESSOR_FLIP: Flips the input buffer. bool horizontal, bool vertical - flip horizontally and/or vertically
  • BAND_IMAGE_PROCESSOR_CONVERT_COLOR_SPACE: Converts the color space of the input buffer. BandBufferFormat target_format - convert the color space
  • BAND_IMAGE_PROCESSOR_NORMALIZE: Normalizes the input buffer. float mean, float std - normalize the input buffer
  • BAND_IMAGE_PROCESSOR_DATA_TYPE_CONVERT: Converts the data type of the input buffer. No argument required Convert the data type to the output data type. E.g., convert from 8-bit RGB to 32-bit float RGB (tensor).

BandImageProcessorProcess

BandStatus BandImageProcessorProcess(BandImageProcessor* image_processor,
                                     BandBuffer* buffer,
                                     BandTensor* target_tensor);

Applies the image processor to the input buffer and stores the result in the target tensor. Returns kBandOk if the operation is successful.

BandImageProcessorDelete

void BandImageProcessorDelete(BandImageProcessor* processor);

Deletes the image processor instance.