// Copyright (c) Facebook, Inc. and its affiliates.
// All rights reserved.
//
// Copyright 2019 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <pthreadpool.h>
#ifdef __cplusplus
extern "C" {
#endif
/// The number of bytes XNNPACK may read beyond array bounds.
/// The caller must allocate at least this many extra bytes after the tensor data passed to XNNPACK.
///
/// Note: XNNPACK reads, but never writes beyond array bounds.
#define XNN_EXTRA_BYTES 16
/// Maximum number of dimensions in tensor shape.
#define XNN_MAX_TENSOR_DIMS 6
/// Allow sparse inference in a Runtime.
///
/// Note: this flag hints XNNPACK to consider sparse inference, but does not guarantee it.
#define XNN_FLAG_SPARSE_INFERENCE 0x00000001
#define XNN_FLAG_HINT_SPARSE_INFERENCE XNN_FLAG_SPARSE_INFERENCE
/// Allow IEEE FP16 inference in a Runtime.
///
/// Note: this flag hints XNNPACK to consider IEEE FP16 inference, but does not guarantee it.
#define XNN_FLAG_FP16_INFERENCE 0x00000002
#define XNN_FLAG_HINT_FP16_INFERENCE XNN_FLAG_FP16_INFERENCE
/// Force IEEE FP16 inference in a Runtime, and fail if FP16 inference is not possible.
///
/// Note: this flag guarantees that XNNPACK will use IEEE FP16 inference, or fail to create the Runtime object.
/// Warning: on x86 systems FP16 computations will be emulated at a substantial performance cost.
#define XNN_FLAG_FORCE_FP16_INFERENCE 0x00000004
/// Enable timing of each operator's runtime.
#define XNN_FLAG_BASIC_PROFILING 0x00000008
/// The convolution operator represents a depthwise convolution, and use HWGo layout for filters.
#define XNN_FLAG_DEPTHWISE_CONVOLUTION 0x00000001
/// Assume transposed weights in a fully connected operator.
#define XNN_FLAG_TRANSPOSE_WEIGHTS 0x00000001
/// The operator assumes NHWC layout for the input, regardless of the output layout.
#define XNN_FLAG_INPUT_NHWC 0x00000002
/// Match "SAME" padding in TensorFlow. Exact padding values are computed dynamically depending on input size.
#define XNN_FLAG_TENSORFLOW_SAME_PADDING 0x00000004
/// Implicitly flatten and reshape input of a Fully Connected operator into a 2D tensor.
#define XNN_FLAG_TENSORFLOW_RESHAPE_2D 0x00000004
/// Match behaviour of TensorFlow 1.x.
#define XNN_FLAG_TENSORFLOW_LEGACY_MODE 0x00000004
/// Static weights of the FP16 operator are in FP32 format.
#define XNN_FLAG_FP32_STATIC_WEIGHTS 0x00000008
/// Align corners of input and output images in resize operations.
#define XNN_FLAG_ALIGN_CORNERS 0x00000008
/// Yield worker threads of the thread pool to the system scheduler after the inference.
#define XNN_FLAG_YIELD_WORKERS 0x00000010
/// Status code for any XNNPACK function call.
enum xnn_status {
/// The call succeeded, and all output arguments now contain valid data.
xnn_status_success = 0,
xnn_status_uninitialized = 1,
xnn_status_invalid_parameter = 2,
xnn_status_invalid_state = 3,
xnn_status_unsupported_parameter = 4,
xnn_status_unsupported_hardware = 5,
xnn_status_out_of_memory = 6,
};
struct xnn_allocator {
/// User-specified pointer that will be passed as-is to all functions in this structure.
void* context;
/// Pointer to a function to be called for general memory allocation.
///
/// @param context - The user-specified pointer from xnn_allocator structure.
/// @param size - The size of the memory block to allocate, in bytes.
///
/// @returns Pointer to the allocated memory block of at least @ref size bytes.
/// If allocation fails, the function must return NULL.
void* (*allocate)(void* context, size_t size);
/// Pointer to a function to be called for general memory re-allocation, i.e. to increase or shrink a previously
/// allocated memory block. The content of the old memory block is copied to the new memory block.
///
/// @param context - The user-specified pointer from xnn_allocator structure.
/// @param pointer - Pointer to a memory block allocated by @ref allocate or @ref reallocate functions. Can be NULL.
/// If the pointer is NULL, the @ref reallocate call is equivalent to an @ref allocate call.
/// @param size - The new size of the memory block to allocate, in bytes.
///
/// @returns Pointer to the newly allocated memory block of at least @ref size bytes with the content of the previous
/// memory block.
/// If allocation fails, the function must return NULL, but must not release the previous memory block.
void* (*reallocate)(void* context, void* pointer, size_t size);
/// Pointer to a function to be called for general memory de-allocation.
///
/// @param context - The user-specified pointer from xnn_allocator structure.
/// @param pointer - Pointer to a memory block allocated by @ref allocate or @ref reallocate functions. Can be NULL.
/// If the pointer is NULL, the @ref deallocate call is a no-op.
void (*deallocate)(void* context, void* pointer);
/// Pointer to a function to be called for aligned memory allocation.
///
/// @param context - The user-specified pointer from xnn_allocator structure.
/// @param alignment - The alignment of the memory block to allocate, in bytes. Alignment is always a power-of-2.
/// @param size - The size of the memory block to allocate, in bytes.
///
/// @returns Pointer to the allocated memory block of at least @ref size bytes.
/// If allocation fails, the function must return NULL.
void* (*aligned_allocate)(void* context, size_t alignment, size_t size);
/// Pointer to a function to be called for aligned memory de-allocation.
///
/// @param context - The user-specified pointer from xnn_allocator structure.
/// @param pointer - Pointer to a memory block allocated by @ref aligned_allocate function. Can be NULL.
/// If the pointer is NULL, the @ref aligned_deallocate call is a no-op.
void (*aligned_deallocate)(void* context, void* pointer);
};
/// Initialize XNNPACK library.
///
/// XNNPACK must be successfully initialized before use. During initialization, XNNPACK populates internal structures
/// depending on the host processor. Initialization can be time-consuming.
///
/// @param[in] allocator - structure with function pointers to be use for memory allocation and de-allocation.
/// If this argument is NULL, system-provided memory management functions (e.g. malloc/free)
/// will be used.
///
/// @retval xnn_status_success - XNNPACK is successfully initialized and ready to use.
/// @retval xnn_status_out_of_memory - initialization failed due to out-of-memory condition.
/// @retval xnn_status_unsupported_hardware - initialization failed because the host processor does not satisfy the
/// minimum hardware requirements for XNNPACK. E.g. this may happen on x86
/// processors without SSE2 extension, or on 32-bit ARM processors without
/// the NEON SIMD extension.
enum xnn_status xnn_initialize(const struct xnn_allocator* allocator);
/// Deinitialize XNNPACK library.
///
/// To avoid memory and resource leaks, users must call xnn_deinitialize once for each successful xnn_initialize call.
///
/// @retval xnn_status_success - deinitialization call succeeded.
enum xnn_status xnn_deinitialize(void);
/// Subgraph is an abstract representation of a neural network model.
/// Subgraph objects are used to define Values (tensors) and Nodes (operators) comprising the model.
typedef struct xnn_subgraph* xnn_subgraph_t;
/// Create a empty Subgraph object.
///
/// @param external_value_ids - number of Value IDs to reserve for communication with external graph representation.
/// The Subgraph object would avoid creating internal Value IDs in the
/// [0, reserved_value_ids-1] range.
/// @param flags - binary features of the subgraph. No supported flags are currently defined.
/// @param subgraph_out - pointer to the variable that will be initialized with a handle to the Subgraph object upon
/// successful return.
enum xnn_status xnn_create_subgraph(
uint32_t external_value_ids,
uint32_t flags,
xnn_subgraph_t* subgraph_out);
/// Destroy a Subgraph object, as well as Values, and Nodes associated with the subgraph.
///
/// @param subgraph - the Subgraph object to destroy.
enum xnn_status xnn_delete_subgraph(
xnn_subgraph_t subgraph);
#define XNN_VALUE_FLAG_EXTERNAL_INPUT 0x00000001
#define XNN_VALUE_FLAG_EXTERNAL_OUTPUT 0x00000002
#define XNN_VALUE_FLAG_PERSISTENT 0x00000004
#define XNN_INVALID_VALUE_ID UINT32_MAX
/// Type of elements in a Value object.
enum xnn_datatype {
/// Invalid data type. Valid Values never have this datatype.
xnn_datatype_invalid = 0,
/// IEEE754 single-precision floating-point.
xnn_datatype_fp32 = 1,
/// IEEE754 half-precision floating-point.
xnn_datatype_fp16 = 2,
/// Quantized 8-bit signed integer with shared per-Value quantization parameters.
xnn_datatype_qint8 = 3,
/// Quantized 8-bit unsigned integer with shared per-Value quantization parameters.
xnn_datatype_quint8 = 4,
/// Quantized 32-bit signed integer with shared per-Value quantization parameters.
xnn_datatype_qint32 = 5,
/// Quantized 8-bit signed integer with shared per-channel quantization parameters.
xnn_datatype_qcint8 = 6,
/// Quantized 32-bit signed integer with shared per-channel quantization parameters.
xnn_datatype_qcint32 = 7,
};
/// Define a tensor-type Value and add it to a Subgraph.
///
/// @param subgraph - a Subgraph object that will own the created Value.
/// @param datatype - type of the tensor elements.
/// @param num_dims - number of dimensions in the shape.
/// @param dims - pointer to an array of @a num_dims shape dimensions. If num_dims is 0, this pointer can be NULL.
/// XNNPACK does not keep any pointers to this array after the function returns.
/// @param data - pointer to static data used for tensor initialization. If the tensor is not statically initialized,
/// this pointer must be is NULL. If non-NULL, the life-time of the static data must exceed the life-time
/// of the Subgraph object, and of any Runtime objects created from the Subgraph.
/// @param external_id - external ID for the Value. The ID must be within the range of reversed Value IDs specified on
/// the Subgraph creation. If the external ID is XNN_INVALID_VALUE_ID, an internal ID will be
/// created for the Value.
/// @param flags - binary features of the Value. Supported values are any combination of XNN_VALUE_FLAG_EXTERNAL_INPUT
/// and XNN_VALUE_FLAG_EXTERNAL_OUTPUT.
/// @param id_out - pointer to the variable that will be initialized with the Value ID upon successful return. If a
/// valid @a external_id was provided, the variable will be initialized with the @a external_id value.
enum xnn_status xnn_define_tensor_value(
xnn_subgraph_t subgraph,
enum xnn_datatype datatype,
size_t num_dims,
const size_t* dims,
const void* data,
uint32_t external_id,
uint32_t flags,
uint32_t* id_out);
/// Define a quantized tensor-type Value and add it to a Subgraph.
///
/// @param subgraph - a Subgraph object that will own the created Value.
/// @param datatype - type of the tensor elements.
/// @param zero_point - offset from zero to subtract from the quantized elements in the Value.
/// @param scale - multiplication factor to convert quantized elements to real representation.
/// @param num_dims - number of dimensions in the shape.
/// @param dims - pointer to an array of @a num_dims shape dimensions. If num_dims is 0, this pointer can be NULL.
/// XNNPACK does not keep any pointers to this array after the function returns.
/// @param data - pointer to static data used for tensor initialization. If the tensor is not statically initialized,
/// this pointer must be is NULL. If non-NULL, the life-time of the static data must exceed the life-time
/// of the Subgraph object, and of any Runtime objects created from the Subgraph.
/// @param external_id - external ID for the Value. The ID must be within the range of reversed Value IDs specified on
/// the Subgraph creation. If the external ID is XNN_INVALID_VALUE_ID, an internal ID will be
/// created for the Value.
/// @param flags - binary features of the Value. Supported values are any combination of XNN_VALUE_FLAG_EXTERNAL_INPUT
/// and XNN_VALUE_FLAG_EXTERNAL_OUTPUT.
/// @param id_out - pointer to the variable that will be initialized with the Value ID upon successful return. If a
/// valid @a external_id was provided, the variable will be initialized with the @a external_id value.
enum xnn_status xnn_define_quantized_tensor_value(
xnn_subgraph_t subgraph,
enum xnn_datatype datatype,
int32_t zero_point,
float scale,
size_t num_dims,
const size_t* dims,
const void* data,
uint32_t external_id,
uint32_t flags,
uint32_t* id_out);
/// Define a channelwise quantized tensor-type Value and add it to a Subgraph.
///
/// @param subgraph - a Subgraph object that will own the created Value.
/// @param datatype - type of the tensor elements.
/// @param scale - per-channel multiplication factors to convert quantized elements to real representation.
/// @param num_dims - number of dimensions in the shape.
/// @param channel_dim - index of the channel dimension in the tensor with per-channel quantization parameters.
/// Typically this is the first dimension (dimension #0) of the filter tensors in the Convolution,
/// Deconvolution, and Fully Connected operators and the last dimension of the filter tensors in
/// the Depthwise Convolution operators.
/// @param dims - pointer to an array of @a num_dims shape dimensions. If num_dims is 0, this pointer can be NULL.
/// XNNPACK does not keep any pointers to this array after the function returns.
/// @param data - pointer to static data used for tensor initialization. If the tensor is not statically initialized,
/// this pointer must be is NULL. If non-NULL, the life-time of the static data must exceed the life-time
/// of the Subgraph object, and of any Runtime objects created from the Subgraph.
/// @param external_id - external ID for the Value. The ID must be within the range of reversed Value IDs specified on
/// the Subgraph creation. If the external ID is XNN_INVALID_VALUE_ID, an internal ID will be
/// created for the Value.
/// @param flags - binary features of the Value. Supported values are any combination of XNN_VALUE_FLAG_EXTERNAL_INPUT
/// and XNN_VALUE_FLAG_EXTERNAL_OUTPUT.
/// @param id_out - pointer to the variable that will be initialized with the Value ID upon successful return. If a
/// valid @a external_id was provided, the variable will be initialized with the @a external_id value.
enum xnn_status xnn_define_channelwise_quantized_tensor_value(
xnn_subgraph_t subgraph,
enum xnn_datatype datatype,
const float* scale,
size_t num_dims,
size_t channel_dim,
const size_t* dims,
const void* data,
uint32_t external_id,
uint32_t flags,
uint32_t* id_out);
/// Define a Convert Node and add it to a Subgraph.
///
/// @param subgraph - a Subgraph object that will own the created Node.
/// @param input_id - Value ID for the input tensor. The input tensor must be defined in the @a subgraph.
/// @param output_id - Value ID for the output tensor. The output tensor must be defined in the @a subgraph, and its
/// shape must match the shape of the input tensor.
/// @param flags - binary features of the Convert Node. No supported flags are currently defined.
enum xnn_status xnn_define_convert(
xnn_subgraph_t subgraph,
uint32_t input_id,
uint32_t output_id,
uint32_t flags);
/// Define a 2D Convolution Node and add it to a Subgraph.
///
/// @param subgraph - a Subgraph object that will own the created Node.
/// @param input_padding_top - implicit zero-padding above 2D input data. Must be 0 if XNN_FLAG_TENSORFLOW_SAME_PADDING
/// flag is specified.
/// @param input_padding_right - implicit zero-padding to the right of 2D input data. Must be 0 if
/// XNN_FLAG_TENSORFLOW_SAME_PADDING flag is specified.
/// @param input_padding_bottom - implicit zero-padding below 2D input data. Must be 0 if
/// XNN_FLAG_TENSORFLOW_SAME_PADDING flag is specified.
/// @param input_padding_left - implicit zero-padding to the left of 2D input data. Must be 0 if
/// XNN_FLAG_TENSORFLOW_SAME_PADDING flag is specified.
/// @param kernel_height - kernel (filter) height.
/// @param kernel_width - kernel (filter) width.
/// @param subsampling_height - height of subsampling region for convolution output (convolution height stride).
/// @param subsampling_width - width of subsampling region for convolution output (convolution width stride).
/// @param dilation_height - dilation of kernel elements along the height dimension.
/// @param dilation_width - dilation of kernel elements along the width dimension.
/// @param groups - number of convolution groups.
/// @param group_input_channels - number of input channels per group.
/// @param group_output_channels - number of output channels per group.
/// @param output_min - lower bound for clipping output values.
/// @param output_max - upper bound for clipping output values.
/// @param input_id - Value ID for the input tensor. The input tensor must be a 4D tensor defined in the @a subgraph
/// with [N, IH, IW, groups * group_input_channels] dimensions
/// @param filter_id - Value ID for the filter tensor. The filter tensor must ge a 4D tensor defined in the @a subgraph
/// with [groups * group_output_channels, kernel_height, kernel_width, group_input_channels]
/// dimensions.
/// @param bias_id - Value ID for the bias tensor, or XNN_INVALID_VALUE_ID for a 2D Convolution Node without a bias. If
/// present, the bias tensor must be a 1D tensor defined in the @a subgraph with [groups *
/// group_output_channels] dimensions.
/// @param output_id - Value ID for the output tensor. The output tensor must be a 4D tensor defined in the @a subgraph
/// with [N, OH, OW, groups * group_output_channels] dimensions.
Loading ...