-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C-API for inference. #1062
C-API for inference. #1062
Changes from 23 commits
fbb1b0e
aa6e252
3fcd81f
a873a40
106620e
fdb64ac
a22c889
657d204
873368f
fe8d5ff
d23bae7
06b1a6a
4fd6888
005ac1f
3bc0d8b
987a908
3b5bed6
0874a7e
6243853
6402214
88c3862
30a6f9b
510ccfe
4380e73
8a1e32d
c32ade7
97c6425
3519c63
8feb583
d34322e
5a9987a
7bb12fd
5ac9c22
08113b2
b528828
0afd5c3
c5eac0a
58e5b87
d49c627
9c1c19b
470bbcf
34b3ee3
852a94f
0d73f4c
6b78a11
6623096
505d207
e7bc880
ddbb610
18a3588
87dfc12
bda2008
28c4cee
91927cc
d6a7648
dfd79c8
4e0f72e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -185,3 +185,4 @@ if(CUDA_ARCH) | |
endif() | ||
|
||
set(CUDA_NVCC_FLAGS ${__arch_flags} ${CUDA_NVCC_FLAGS}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. | ||
|
||
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 "PaddleCAPI.h" | ||
#include "PaddleCAPIPrivate.h" | ||
|
||
using paddle::capi::cast; | ||
|
||
#define castArg(v) cast<paddle::capi::CArguments>(v) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 上文提到的, |
||
#define castIVec(v) cast<paddle::capi::CIVector>(v) | ||
|
||
extern "C" { | ||
int PDArgsCreateNone(PD_Arguments* args) { | ||
auto ptr = new paddle::capi::CArguments(); | ||
*args = ptr; | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDArgsDestroy(PD_Arguments args) { | ||
if (args == nullptr) return kPD_NULLPTR; | ||
delete castArg(args); | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDArgsGetSize(PD_Arguments args, uint64_t* size) { | ||
if (args == nullptr || size == nullptr) return kPD_NULLPTR; | ||
*size = castArg(args)->args.size(); | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDArgsResize(PD_Arguments args, uint64_t size) { | ||
if (args == nullptr) return kPD_NULLPTR; | ||
castArg(args)->args.resize(size); | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDArgsSetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat) { | ||
if (args == nullptr || mat == nullptr) return kPD_NULLPTR; | ||
auto m = paddle::capi::cast<paddle::capi::CMatrix>(mat); | ||
if (m->mat == nullptr) return kPD_NULLPTR; | ||
auto a = castArg(args); | ||
if (ID >= a->args.size()) return kPD_OUT_OF_RANGE; | ||
a->args[ID].value = m->mat; | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDArgsGetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat) { | ||
if (args == nullptr || mat == nullptr) return kPD_NULLPTR; | ||
auto m = paddle::capi::cast<paddle::capi::CMatrix>(mat); | ||
auto a = castArg(args); | ||
if (ID >= a->args.size()) return kPD_OUT_OF_RANGE; | ||
m->mat = a->args[ID].value; | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDArgsGetIds(PD_Arguments args, uint64_t ID, PD_IVector ids) { | ||
if (args == nullptr || ids == nullptr) return kPD_NULLPTR; | ||
auto iv = castIVec(ids); | ||
auto a = castArg(args); | ||
if (ID >= a->args.size()) return kPD_OUT_OF_RANGE; | ||
iv->vec = a->args[ID].ids; | ||
return kPD_NO_ERROR; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 目前还不支持sparse与sequence数据 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 是的,这个预测目前只支持Dense输入输出的预测。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 先checkin这个版本吧。。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
if (WITH_DOUBLE) | ||
set(PADDLE_FLOAT_TYPE double) | ||
else () | ||
set(PADDLE_FLOAT_TYPE float) | ||
endif() | ||
|
||
# config.h used for C-API. It will store Paddle building configuration as a | ||
# header. Make user just include PaddleCAPI.h then can get building | ||
# configuration without explicitly set -DPADDLE_WITH_DOUBLE when building their | ||
# libraries. | ||
configure_file(config.h.in config.h @ONLY) | ||
|
||
# PaddleCAPI.h is the only header we exposed. It currently only used for model | ||
# inference. | ||
set(CAPI_HEADER PaddleCAPI.h) | ||
|
||
|
||
set(CAPI_PRIVATE_HEADER PaddleCAPIPrivate.h) | ||
file(GLOB CAPI_SOURCES *.cpp) | ||
|
||
# building paddle_capi | ||
add_library(paddle_capi STATIC ${CAPI_SOURCES}) | ||
|
||
target_include_directories(paddle_capi PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) | ||
|
||
add_style_check_target(paddle_capi ${CAPI_SOURCES} ${CAPI_HEADER} | ||
${CAPI_PRIVATE_HEADER}) | ||
|
||
add_dependencies(paddle_capi gen_proto_cpp) | ||
|
||
|
||
# combine all paddle static libraries together, into libpaddle_capi_whole.a | ||
# user should use PaddleCAPI as -lpaddle_capi_whole | ||
set(capi_whole_library libpaddle_capi_whole.a) | ||
add_custom_target(paddle_capi_whole ALL | ||
COMMAND mkdir -p o_files/capi && cd o_files/capi/ && ar -x $<TARGET_FILE:paddle_capi> | ||
COMMAND mkdir -p o_files/utils && cd o_files/utils/ && ar -x $<TARGET_FILE:paddle_utils> | ||
COMMAND mkdir -p o_files/parameter && cd o_files/parameter/ && ar -x $<TARGET_FILE:paddle_parameter> | ||
COMMAND mkdir -p o_files/math && cd o_files/math/ && ar -x $<TARGET_FILE:paddle_math> | ||
COMMAND mkdir -p o_files/cuda && cd o_files/cuda/ && ar -x $<TARGET_FILE:paddle_cuda> | ||
COMMAND mkdir -p o_files/function && cd o_files/function/ && ar -x $<TARGET_FILE:paddle_function> | ||
COMMAND mkdir -p o_files/gserver && cd o_files/gserver/ && ar -x $<TARGET_FILE:paddle_gserver> | ||
COMMAND mkdir -p o_files/proto && cd o_files/proto/ && ar -x $<TARGET_FILE:paddle_proto> | ||
COMMAND mkdir -p o_files/network && cd o_files/network/ && ar -x | ||
+$<TARGET_FILE:paddle_network> | ||
+ COMMAND mkdir -p o_files/pserver && cd o_files/pserver/ && ar -x | ||
+$<TARGET_FILE:paddle_pserver | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里应该是笔误吧,这个+号是应该删除的 COMMAND mkdir -p o_files/network && cd o_files/network/ && ar -x $<TARGET_FILE:paddle_network> |
||
COMMAND ar crs ${capi_whole_library} `find ./o_files -name '*.o'` | ||
COMMAND rm -rf o_files | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
DEPENDS paddle_capi paddle_utils paddle_parameter paddle_math | ||
paddle_cuda paddle_function paddle_gserver | ||
paddle_proto paddle_pserver paddle_network | ||
) | ||
set_target_properties(paddle_capi_whole | ||
PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${capi_whole_library}) | ||
|
||
add_library(paddle_capi_shared SHARED ${CAPI_SOURCES}) | ||
target_include_directories(paddle_capi_shared PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) | ||
link_paddle_exe(paddle_capi_shared) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 有个疑问,这个PR目前是只支持inference的吧,后面还会支持train?train会编译成另外一个库? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. train也会放到一个库里。 |
||
|
||
# install library & headers. | ||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${capi_whole_library} DESTINATION lib) | ||
install(FILES ${CAPI_HEADER} DESTINATION include/paddle) | ||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h DESTINATION include/paddle) | ||
|
||
|
||
# this variable used for unittest | ||
set(PADDLE_CAPI_INC_PATH | ||
${CMAKE_CURRENT_BINARY_DIR} | ||
${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
if (WITH_TESTING) | ||
add_subdirectory(tests) | ||
endif() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. | ||
|
||
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 "PaddleCAPI.h" | ||
#include "PaddleCAPIPrivate.h" | ||
#include "paddle/gserver/gradientmachines/NeuralNetwork.h" | ||
|
||
#define cast(v) paddle::capi::cast<paddle::capi::CGradientMachine>(v) | ||
|
||
enum GradientMatchineCreateMode { | ||
CREATE_MODE_NORMAL = 0, | ||
CREATE_MODE_TESTING = 4 | ||
}; | ||
|
||
namespace paddle { | ||
|
||
class MyNeuralNetwork : public NeuralNetwork { | ||
public: | ||
MyNeuralNetwork(const std::string& name, NeuralNetwork* network) | ||
: NeuralNetwork(name, network) {} | ||
}; | ||
|
||
NeuralNetwork* newCustomNerualNetwork(const std::string& name, | ||
NeuralNetwork* network) { | ||
return new MyNeuralNetwork(name, network); | ||
} | ||
} // namespace paddle | ||
|
||
extern "C" { | ||
int PDGradientMachineCreateForPredict(PD_GradientMachine* machine, | ||
void* modelConfigProtobuf, | ||
int size) { | ||
if (modelConfigProtobuf == nullptr) return kPD_NULLPTR; | ||
paddle::ModelConfig config; | ||
if (!config.ParseFromArray(modelConfigProtobuf, size) || | ||
!config.IsInitialized()) { | ||
return kPD_PROTOBUF_ERROR; | ||
} | ||
|
||
auto ptr = new paddle::capi::CGradientMachine(); | ||
ptr->machine.reset(paddle::GradientMachine::create( | ||
config, CREATE_MODE_TESTING, {paddle::PARAMETER_VALUE})); | ||
*machine = ptr; | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDGradientMachineDestroy(PD_GradientMachine machine) { | ||
delete cast(machine); | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDGradientMachineLoadParameterFromDisk(PD_GradientMachine machine, | ||
const char* path) { | ||
auto m = cast(machine); | ||
if (m == nullptr || path == nullptr || m->machine == nullptr) | ||
return kPD_NULLPTR; | ||
m->machine->loadParameters(path); | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDGradientMachineForward(PD_GradientMachine machine, | ||
PD_Arguments inArgs, | ||
PD_Arguments outArgs, | ||
bool isTrain) { | ||
auto m = cast(machine); | ||
auto in = paddle::capi::cast<paddle::capi::CArguments>(inArgs); | ||
auto out = paddle::capi::cast<paddle::capi::CArguments>(outArgs); | ||
if (m == nullptr || in == nullptr || out == nullptr || m->machine == nullptr) | ||
return kPD_NULLPTR; | ||
m->machine->forward( | ||
in->args, &out->args, isTrain ? paddle::PASS_TRAIN : paddle::PASS_TEST); | ||
return kPD_NO_ERROR; | ||
} | ||
|
||
int PDGradientMachineCreateSharedParam(PD_GradientMachine origin, | ||
void* modelConfigProtobuf, | ||
int size, | ||
PD_GradientMachine* slave) { | ||
auto o = cast(origin); | ||
if (origin == nullptr || slave == nullptr || o->machine == nullptr) { | ||
return kPD_NULLPTR; | ||
} | ||
paddle::ModelConfig config; | ||
if (!config.ParseFromArray(modelConfigProtobuf, size) || | ||
!config.IsInitialized()) { | ||
return kPD_PROTOBUF_ERROR; | ||
} | ||
|
||
std::unique_ptr<paddle::capi::CGradientMachine> ptr( | ||
new paddle::capi::CGradientMachine()); | ||
auto nn = paddle::NeuralNetwork::create(config); | ||
nn->init(config, | ||
[&o](int paramId, paddle::Parameter* param) { | ||
auto p = o->machine->getParameters()[paramId]; | ||
param->enableSharedType(paddle::PARAMETER_VALUE, | ||
p->getBuf(paddle::PARAMETER_VALUE)); | ||
}, | ||
{paddle::PARAMETER_VALUE}, | ||
false); | ||
ptr->machine.reset(nn); | ||
*slave = ptr.release(); | ||
return kPD_NO_ERROR; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. | ||
|
||
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 <fenv.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <vector> | ||
#include "PaddleCAPI.h" | ||
#include "PaddleCAPIPrivate.h" | ||
#include "paddle/trainer/TrainerConfigHelper.h" | ||
#include "paddle/utils/Excepts.h" | ||
#include "paddle/utils/PythonUtil.h" | ||
|
||
static void initPaddle(int argc, char** argv) { | ||
paddle::initMain(argc, argv); | ||
paddle::initPython(argc, argv); | ||
feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); | ||
} | ||
|
||
extern "C" { | ||
int PDInit(int argc, char** argv) { | ||
std::vector<char*> realArgv; | ||
realArgv.reserve(argc + 1); | ||
realArgv.push_back(strdup("")); | ||
for (int i = 0; i < argc; ++i) { | ||
realArgv.push_back(argv[i]); | ||
} | ||
initPaddle(argc + 1, realArgv.data()); | ||
free(realArgv[0]); | ||
return kPD_NO_ERROR; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
看到大家都把这个目录叫做 "c", 这个作为参考
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/dmlc/mxnet/tree/master/src/c_api
一般项目目录第一层是编码语言,就比如Paddle
所以有一些项目的会把这部分放到c目录下。而对于Paddle,一来C/CPP区分界限不明显,二来但就这个C-API来说,本身也是C与C++的混合写法。所以很难独立成C目录。