Skip to content

Commit

Permalink
[C API] Initial interface proposal (uber#396)
Browse files Browse the repository at this point in the history
### Summary:

An initial interface for a Neuropod C API.
  • Loading branch information
VivekPanyam authored Jul 17, 2020
1 parent a7af923 commit d7bf8b0
Show file tree
Hide file tree
Showing 6 changed files with 400 additions and 0 deletions.
92 changes: 92 additions & 0 deletions source/neuropod/bindings/c/c_api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Copyright (c) 2020 UATC, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Inspired by the TensorFlow C API

#pragma once

#include "neuropod/bindings/c/np_status.h"
#include "neuropod/bindings/c/np_tensor.h"
#include "neuropod/bindings/c/np_tensor_allocator.h"
#include "neuropod/bindings/c/np_tensor_spec.h"
#include "neuropod/bindings/c/np_valuemap.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct NP_Neuropod NP_Neuropod;

// Load a model given a path
void NP_LoadNeuropod(const char *neuropod_path, NP_Neuropod **model, NP_Status *status);

// TODO: Add more options
typedef struct NP_RuntimeOptions
{
// Whether or not to use out-of-process execution
// (using shared memory to communicate between the processes)
bool use_ope;

} NP_RuntimeOptions;

// Load a model given a path and options
void NP_LoadNeuropodWithOpts(const char * neuropod_path,
const NP_RuntimeOptions *options,
NP_Neuropod ** model,
NP_Status * status);

// Free a model
void NP_FreeNeuropod(NP_Neuropod *model);

// Run inference
// Note: The caller is responsible for freeing the returned NP_NeuropodValueMap
void NP_Infer(NP_Neuropod *model, const NP_NeuropodValueMap *inputs, NP_NeuropodValueMap **outputs, NP_Status *status);

// Run inference with a set of requested outputs
// requested_outputs should be a null terminated array of char ptr containing the names of requested outputs
// Note: The caller is responsible for freeing the returned NP_NeuropodValueMap
void NP_InferWithRequestedOutputs(NP_Neuropod * model,
const NP_NeuropodValueMap *inputs,
const char ** requested_outputs,
NP_NeuropodValueMap ** outputs,
NP_Status * status);

// Get information about the model
const char *NP_GetName(NP_Neuropod *model);
const char *NP_GetPlatform(NP_Neuropod *model);

// Get the number of items in the input spec of a model
size_t NP_GetNumInputs(NP_Neuropod *model);

// Get the number of items in the output spec of a model
size_t NP_GetNumOutputs(NP_Neuropod *model);

// Get an item from the input spec of a model
// Returns nullptr if index is out of range
// Note: The caller is responsible for freeing the returned TensorSpec
NP_TensorSpec *NP_GetInputSpec(NP_Neuropod *model, size_t index);

// Get an item from the output spec of a model
// Returns nullptr if index is out of range
// Note: The caller is responsible for freeing the returned TensorSpec
NP_TensorSpec *NP_GetOutputSpec(NP_Neuropod *model, size_t index);

// Get an allocator for a model
// Note: The caller is responsible for freeing the returned TensorAllocator
NP_TensorAllocator *NP_GetAllocator(NP_Neuropod *model);

#ifdef __cplusplus
}
#endif
45 changes: 45 additions & 0 deletions source/neuropod/bindings/c/np_status.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Copyright (c) 2020 UATC, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Inspired by the TensorFlow C API

#pragma once
#ifdef __cplusplus
extern "C" {
#endif

// Used for returning error messages across the C API boundary
typedef struct NP_Status NP_Status;

// Used for creating and deleting new status messages
NP_Status *NP_NewStatus();
void NP_DeleteStatus(NP_Status *status);

// Possible status codes
typedef enum NP_Code
{
NEUROPOD_OK = 0,
NEUROPOD_ERROR = 1,
} NP_Code;

// Used for getting details about a status
NP_Code NP_GetCode(const NP_Status *status);

// Get the error message (if any)
const char *NP_Message(const NP_Status *status);

#ifdef __cplusplus
}
#endif
82 changes: 82 additions & 0 deletions source/neuropod/bindings/c/np_tensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* Copyright (c) 2020 UATC, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Inspired by the TensorFlow C API

#pragma once

#include "neuropod/bindings/c/np_status.h"

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// A tensor
typedef struct NP_NeuropodTensor NP_NeuropodTensor;

// Get the dimensions of a tensor
void NP_GetDims(const NP_NeuropodTensor *tensor, size_t *num_dims, const int64_t **dims);

// All the tensor types that Neuropod supports
typedef enum NP_TensorType
{
FLOAT_TENSOR = 0,
DOUBLE_TENSOR,
STRING_TENSOR,

INT8_TENSOR,
INT16_TENSOR,
INT32_TENSOR,
INT64_TENSOR,

UINT8_TENSOR,
UINT16_TENSOR,
UINT32_TENSOR,
UINT64_TENSOR,
} NP_TensorType;

// Get the type of a tensor
NP_TensorType NP_GetType(const NP_NeuropodTensor *tensor);

// For non-string tensors, get a pointer to the underlying data
// Returns nullptr if called on a string tensor
void *NP_GetData(NP_NeuropodTensor *tensor);

// For non-string tensors, get a pointer to the underlying data
// Returns nullptr if called on a string tensor
const void *NP_GetDataReadOnly(const NP_NeuropodTensor *tensor);

// For string tensors, set the value of a specified element in the flattened tensor
void NP_SetStringElement(NP_NeuropodTensor *tensor, size_t index, const char *item, NP_Status *status);

// Get the length of a specified element in a string tensor
void NP_GetStringElementSize(const NP_NeuropodTensor *tensor, size_t index, size_t *elem_size, NP_Status *status);

// Copy the value of a specified element of a string tensor into a user provided buffer
void NP_GetStringElement(
const NP_NeuropodTensor *tensor, size_t index, char *buffer, size_t buffer_size, NP_Status *status);

// Releases a tensor. The memory might not be deallocated immediately if the tensor is still
// referenced by a value-map object or used by an infer operation.
// This should be called on every tensor returned by the C API.
// See the notes in `np_valuemap.h` and `np_tensor_allocator.h` for more detail.
void NP_FreeTensor(NP_NeuropodTensor *tensor);

#ifdef __cplusplus
}
#endif
51 changes: 51 additions & 0 deletions source/neuropod/bindings/c/np_tensor_allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* Copyright (c) 2020 UATC, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Inspired by the TensorFlow C API

#pragma once

#include "neuropod/bindings/c/np_tensor.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct NP_TensorAllocator NP_TensorAllocator;

// Free an allocator
void NP_FreeAllocator(NP_TensorAllocator *allocator);

// Allocate a tensor with a specified type and shape
// Note: the caller is responsible for calling NP_FreeTensor on the returned tensor
NP_NeuropodTensor *NP_AllocateTensor(NP_TensorAllocator *allocator, size_t num_dims, int64_t *dims, NP_TensorType type);

// Allocate a tensor of a specific type and wrap existing memory.
// Note: Some backends may have specific alignment requirements (e.g. tensorflow).
// To support all the built-in backends, `data` should be aligned to 64 bytes.
// `deleter` will be called with a pointer to `data` and `deleter_arg` when the tensor is
// deallocated.
// Note: the caller is responsible for calling NP_FreeTensor on the returned tensor
NP_NeuropodTensor *NP_TensorFromMemory(NP_TensorAllocator *allocator,
size_t num_dims,
int64_t * dims,
NP_TensorType type,
void * data,
void (*deleter)(void *data, void *arg),
void *deleter_arg);

#ifdef __cplusplus
}
#endif
59 changes: 59 additions & 0 deletions source/neuropod/bindings/c/np_tensor_spec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* Copyright (c) 2020 UATC, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Inspired by the TensorFlow C API

#pragma once

#include "neuropod/bindings/c/np_tensor.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct NP_Dimension
{
// The value of the dimension
//
// Special cases
// -1 == Any value is allowed (None/null)
// -2 == Symbol (see below)
int64_t value;

// The name of this symbol (if it is a symbol)
const char *symbol;
} NP_Dimension;

typedef struct NP_TensorSpec
{
// The name of the tensor
const char *name;

// The type of the tensor
NP_TensorType type;

// The number of dimensions
size_t num_dims;

// The dimensions of the tensor
NP_Dimension dims[];
} NP_TensorSpec;

// Free a NP_TensorSpec
void NP_FreeTensorSpec(NP_TensorSpec *spec);

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit d7bf8b0

Please sign in to comment.