forked from uber/neuropod
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[C API] Initial implementation (uber#400)
### Summary: An initial basic implementation of a C API for Neuropod. ### Test Plan: Added a test that loads a model, runs inference, and verifies the output. More unit tests and integration tests should be added in the future
- Loading branch information
1 parent
d7bf8b0
commit eae86ce
Showing
15 changed files
with
489 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# 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. | ||
|
||
cc_library( | ||
name = "c_api", | ||
srcs = glob(["*.cc"]), | ||
hdrs = glob(["*.h"]), | ||
visibility = [ | ||
"//neuropod:__subpackages__", | ||
], | ||
deps = [ | ||
"//neuropod:neuropod_hdrs", | ||
"//neuropod/internal", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* 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 | ||
|
||
#include "neuropod/bindings/c/c_api.h" | ||
|
||
#include "neuropod/bindings/c/c_api_internal.h" | ||
#include "neuropod/bindings/c/np_tensor_allocator_internal.h" | ||
#include "neuropod/bindings/c/np_valuemap_internal.h" | ||
|
||
// Load a model given a path | ||
void NP_LoadNeuropod(const char *neuropod_path, NP_Neuropod **model, NP_Status *status) | ||
{ | ||
*model = new NP_Neuropod(); | ||
|
||
(*model)->model = std::make_unique<neuropod::Neuropod>(neuropod_path); | ||
} | ||
|
||
// Free a model | ||
void NP_FreeNeuropod(NP_Neuropod *model) | ||
{ | ||
delete 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) | ||
{ | ||
*outputs = new NP_NeuropodValueMap(); | ||
(*outputs)->data = std::move(*model->model->infer(inputs->data)); | ||
} | ||
|
||
// Get an allocator for a model | ||
NP_TensorAllocator *NP_GetAllocator(NP_Neuropod *model) | ||
{ | ||
auto out = new NP_TensorAllocator(); | ||
out->allocator = model->model->get_tensor_allocator(); | ||
return out; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "neuropod/neuropod.hh" | ||
|
||
#include <memory> | ||
|
||
struct NP_Neuropod | ||
{ | ||
std::unique_ptr<neuropod::Neuropod> model; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* 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. | ||
*/ | ||
|
||
#include "neuropod/bindings/c/np_status_internal.h" | ||
|
||
// Used for creating and deleting new status messages | ||
NP_Status *NP_NewStatus() | ||
{ | ||
return new NP_Status(); | ||
} | ||
|
||
void NP_DeleteStatus(NP_Status *status) | ||
{ | ||
delete status; | ||
} | ||
|
||
// Clear a status | ||
void NP_ClearStatus(NP_Status *status) | ||
{ | ||
status->code = NEUROPOD_OK; | ||
status->message.clear(); | ||
} | ||
|
||
// Used for getting details about a status | ||
NP_Code NP_GetCode(const NP_Status *status) | ||
{ | ||
return status->code; | ||
} | ||
|
||
// Get the error message (if any) | ||
const char *NP_GetMessage(const NP_Status *status) | ||
{ | ||
return status->message.c_str(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "neuropod/bindings/c/np_status.h" | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
struct NP_Status | ||
{ | ||
std::string message; | ||
NP_Code code; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* 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. | ||
*/ | ||
|
||
#include "neuropod/bindings/c/np_tensor.h" | ||
|
||
#include "neuropod/bindings/c/np_tensor_internal.h" | ||
#include "neuropod/internal/neuropod_tensor_raw_data_access.hh" | ||
|
||
// 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) | ||
{ | ||
return neuropod::internal::NeuropodTensorRawDataAccess::get_untyped_data_ptr(*tensor->tensor->as_tensor()); | ||
} | ||
|
||
// 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) | ||
{ | ||
delete tensor; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* 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. | ||
*/ | ||
|
||
#include "neuropod/bindings/c/np_tensor_allocator_internal.h" | ||
#include "neuropod/bindings/c/np_tensor_internal.h" | ||
|
||
// Free an allocator | ||
void NP_FreeAllocator(NP_TensorAllocator *allocator) | ||
{ | ||
delete 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) | ||
{ | ||
std::vector<int64_t> d(dims, dims + num_dims); | ||
|
||
auto out = new NP_NeuropodTensor(); | ||
out->tensor = allocator->allocator->allocate_tensor(d, static_cast<neuropod::TensorType>(type)); | ||
|
||
return out; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "neuropod/backends/tensor_allocator.hh" | ||
#include "neuropod/bindings/c/np_tensor_allocator.h" | ||
|
||
#include <memory> | ||
|
||
struct NP_TensorAllocator | ||
{ | ||
std::shared_ptr<neuropod::NeuropodTensorAllocator> allocator; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "neuropod/bindings/c/np_tensor.h" | ||
#include "neuropod/internal/neuropod_tensor.hh" | ||
|
||
#include <memory> | ||
|
||
struct NP_NeuropodTensor | ||
{ | ||
std::shared_ptr<neuropod::NeuropodValue> tensor; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* 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. | ||
*/ | ||
|
||
#include "neuropod/bindings/c/np_tensor_internal.h" | ||
#include "neuropod/bindings/c/np_valuemap_internal.h" | ||
|
||
// Create a new NeuropodValueMap | ||
NP_NeuropodValueMap *NP_NewValueMap() | ||
{ | ||
return new NP_NeuropodValueMap(); | ||
} | ||
|
||
// Free a NeuropodValueMap | ||
void NP_FreeValueMap(NP_NeuropodValueMap *nvm) | ||
{ | ||
delete nvm; | ||
} | ||
|
||
// Insert a tensor into the provided map | ||
// Overwrites any existing tensors with the same name | ||
// Note: this does not transfer ownership and the caller is still responsible for calling NP_FreeTensor on | ||
// `tensor` | ||
void NP_InsertTensor(NP_NeuropodValueMap *nvm, const char *name, NP_NeuropodTensor *tensor) | ||
{ | ||
nvm->data[name] = tensor->tensor; | ||
} | ||
|
||
// Given a NP_NeuropodValueMap, find a tensor with name `name` and return it | ||
// If such a tensor is not found, returns nullptr | ||
// Note: the caller is responsible for calling NP_FreeTensor on the returned tensor | ||
NP_NeuropodTensor *NP_GetTensor(const NP_NeuropodValueMap *nvm, const char *name) | ||
{ | ||
auto &map = nvm->data; | ||
auto item = map.find(name); | ||
if (item == map.end()) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
auto retval = new NP_NeuropodTensor(); | ||
retval->tensor = item->second; | ||
|
||
return retval; | ||
} | ||
|
||
// Removes a specified tensor from the provided map (if it exists) | ||
void NP_RemoveTensor(NP_NeuropodValueMap *nvm, const char *name) | ||
{ | ||
nvm->data.erase(name); | ||
} |
Oops, something went wrong.