From aa6e25215e906d1ec0fc501849ca19e20abd0a0d Mon Sep 17 00:00:00 2001 From: Yu Yang Date: Wed, 4 Jan 2017 18:02:45 +0800 Subject: [PATCH] Doing C-API --- paddle/capi/CMakeLists.txt | 3 +- paddle/capi/GradientMachine.cpp | 48 +++++++++++++++++++ paddle/capi/Main.cpp | 43 +++++++++++++++++ paddle/capi/PaddleCAPI.h | 25 ++++++++-- paddle/capi/PaddleCAPIPrivate.h | 5 ++ paddle/capi/tests/CMakeLists.txt | 29 +++++++++-- paddle/capi/tests/test_GradientMachine.cpp | 24 ++++++++++ paddle/capi/tests/test_Init.cpp | 0 paddle/capi/tests/vgg_16_cifar.py | 1 + paddle/utils/ForceLink.h | 46 ------------------ paddle/utils/tests/CMakeLists.txt | 8 ---- paddle/utils/tests/test_ClassRegistrar.cpp | 27 ----------- .../tests/test_ClassRegistrarGlobals.cpp | 16 ------- paddle/utils/tests/test_ClassRegistrarLib.cpp | 31 ------------ paddle/utils/tests/test_ClassRegistrarLib.h | 23 --------- 15 files changed, 169 insertions(+), 160 deletions(-) create mode 100644 paddle/capi/GradientMachine.cpp create mode 100644 paddle/capi/Main.cpp create mode 100644 paddle/capi/tests/test_GradientMachine.cpp create mode 100644 paddle/capi/tests/test_Init.cpp create mode 120000 paddle/capi/tests/vgg_16_cifar.py delete mode 100644 paddle/utils/ForceLink.h delete mode 100644 paddle/utils/tests/test_ClassRegistrar.cpp delete mode 100644 paddle/utils/tests/test_ClassRegistrarGlobals.cpp delete mode 100644 paddle/utils/tests/test_ClassRegistrarLib.cpp delete mode 100644 paddle/utils/tests/test_ClassRegistrarLib.h diff --git a/paddle/capi/CMakeLists.txt b/paddle/capi/CMakeLists.txt index 6162267da..62e9e5cce 100644 --- a/paddle/capi/CMakeLists.txt +++ b/paddle/capi/CMakeLists.txt @@ -35,7 +35,8 @@ target_link_libraries(paddle_capi ${CBLAS_LIBS} ${ZLIB_LIBRARIES} ${INTERAL_LIBS} - ${CMAKE_DL_LIBS}) + ${CMAKE_DL_LIBS} + ${PYTHON_LIBRARIES}) set(PADDLE_CAPI_INC_PATH diff --git a/paddle/capi/GradientMachine.cpp b/paddle/capi/GradientMachine.cpp new file mode 100644 index 000000000..2969b5f19 --- /dev/null +++ b/paddle/capi/GradientMachine.cpp @@ -0,0 +1,48 @@ +#include "PaddleCAPI.h" +#include "PaddleCAPIPrivate.h" +#include "paddle/gserver/gradientmachines/NeuralNetwork.h" + +#define cast(v) paddle::capi::cast(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); +} +} + +extern "C" { +int PDGradientMachineCreateForPredict(PD_GradiemtMachine* machine, + void* modelConfigProtobuf, + int size) { + if (modelConfigProtobuf == nullptr) return PD_NULLPTR; + paddle::ModelConfig config; + if (!config.ParseFromArray(modelConfigProtobuf, size) || + !config.IsInitialized()) { + return PD_PROTOBUF_ERROR; + } + + auto ptr = new paddle::capi::CGradientMachine(); + ptr->machine.reset(paddle::GradientMachine::create( + config, CREATE_MODE_TESTING, {paddle::PARAMETER_VALUE})); + *machine = ptr; + return PD_NO_ERROR; +} + +int PDGradientMachineDestroy(PD_GradiemtMachine machine) { + delete cast(machine); + return PD_NO_ERROR; +} +} diff --git a/paddle/capi/Main.cpp b/paddle/capi/Main.cpp new file mode 100644 index 000000000..49606e1f9 --- /dev/null +++ b/paddle/capi/Main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#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 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 PD_NO_ERROR; +} + +int PDParseTrainerConfigFromFile(char* filename, + void** modelConfigProtobuf, + int* size) { + if (filename == nullptr || modelConfigProtobuf == nullptr || size == nullptr) + return PD_NULLPTR; + paddle::TrainerConfigHelper conf(filename); + if (!conf.getConfig().IsInitialized()) return PD_PROTOBUF_ERROR; + *size = conf.getConfig().ByteSize(); + *modelConfigProtobuf = malloc(*size); + if (!conf.getConfig().SerializeToArray(*modelConfigProtobuf, *size)) + return PD_PROTOBUF_ERROR; + return PD_NO_ERROR; +} +} diff --git a/paddle/capi/PaddleCAPI.h b/paddle/capi/PaddleCAPI.h index 2eff0bc7d..fa43b3b40 100644 --- a/paddle/capi/PaddleCAPI.h +++ b/paddle/capi/PaddleCAPI.h @@ -7,10 +7,13 @@ extern "C" { #endif -#define PD_NO_ERROR 0 -#define PD_NULLPTR 1 -#define PD_OUT_OF_RANGE 2 -#define PD_UNDEFINED_ERROR -1 +typedef enum { + PD_NO_ERROR = 0, + PD_NULLPTR = 1, + PD_OUT_OF_RANGE = 2, + PD_PROTOBUF_ERROR = 3, + PD_UNDEFINED_ERROR = -1, +} PD_Error; typedef void* PD_Vector; @@ -48,6 +51,20 @@ int PDArgsSetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat); int PDArgsGetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat); +typedef void* PD_GradiemtMachine; + +int PDGradientMachineCreateForPredict(PD_GradiemtMachine* machine, + void* modelConfigProtobuf, + int size); + +int PDGradientMachineDestroy(PD_GradiemtMachine machine); + +int PDInit(int argc, char** argv); + +int PDParseTrainerConfigFromFile(char* filename, + void** modelConfigProtobuf, + int* size); + #ifdef __cplusplus } #endif diff --git a/paddle/capi/PaddleCAPIPrivate.h b/paddle/capi/PaddleCAPIPrivate.h index efec60fbb..07e731f6c 100644 --- a/paddle/capi/PaddleCAPIPrivate.h +++ b/paddle/capi/PaddleCAPIPrivate.h @@ -1,4 +1,5 @@ #include "PaddleCAPI.h" +#include "paddle/gserver/gradientmachines/GradientMachine.h" #include "paddle/math/Matrix.h" #include "paddle/math/Vector.h" #include "paddle/parameter/Argument.h" @@ -19,6 +20,10 @@ struct CArguments { std::vector args; }; +struct CGradientMachine { + paddle::GradientMachinePtr machine; +}; + template inline T* cast(void* ptr) { return reinterpret_cast(ptr); diff --git a/paddle/capi/tests/CMakeLists.txt b/paddle/capi/tests/CMakeLists.txt index cd6b1d7c6..e1fa3d6b7 100644 --- a/paddle/capi/tests/CMakeLists.txt +++ b/paddle/capi/tests/CMakeLists.txt @@ -1,15 +1,36 @@ -function(add_capi_unittest TARGET_NAME) +function(add_capi_unittest_without_exec TARGET_NAME) + set(with_test_main ON) + set(sources) + foreach(source_file ${ARGN}) + if (${source_file} STREQUAL "NO_MAIN") + set(with_test_main OFF) + else() + list(APPEND sources ${source_file}) + endif() + endforeach() + add_executable( ${TARGET_NAME} - ${ARGN}) + ${sources}) + + target_link_libraries( ${TARGET_NAME} paddle_capi - paddle_test_main ${GTEST_LIBRARIES}) + + if (with_test_main) + target_link_libraries( + ${TARGET_NAME} paddle_test_main) + endif() target_include_directories(${TARGET_NAME} PUBLIC ${PADDLE_CAPI_INC_PATH}) - add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME}) endfunction() +function(add_capi_unittest TARGET_NAME) + add_capi_unittest_without_exec(${TARGET_NAME} ${ARGN}) + add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME}) +endfunction() add_capi_unittest(capi_test_mats test_Vector.cpp test_Matrix.cpp test_Arguments.cpp) + +add_capi_unittest(capi_test_gradientMachine NO_MAIN test_GradientMachine.cpp) diff --git a/paddle/capi/tests/test_GradientMachine.cpp b/paddle/capi/tests/test_GradientMachine.cpp new file mode 100644 index 000000000..8c1ea73ae --- /dev/null +++ b/paddle/capi/tests/test_GradientMachine.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include "PaddleCAPI.h" + +TEST(GradientMachine, load) { + void* buf; + int size; + ASSERT_EQ( + PD_NO_ERROR, + PDParseTrainerConfigFromFile(strdup("./vgg_16_cifar.py"), &buf, &size)); + free(buf); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + std::vector argvs; + argvs.push_back(strdup("--use_gpu=false")); + PDInit((int)argvs.size(), argvs.data()); + for (auto each : argvs) { + free(each); + } + return RUN_ALL_TESTS(); +} diff --git a/paddle/capi/tests/test_Init.cpp b/paddle/capi/tests/test_Init.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/paddle/capi/tests/vgg_16_cifar.py b/paddle/capi/tests/vgg_16_cifar.py new file mode 120000 index 000000000..81250eefd --- /dev/null +++ b/paddle/capi/tests/vgg_16_cifar.py @@ -0,0 +1 @@ +../../../demo/image_classification/vgg_16_cifar.py \ No newline at end of file diff --git a/paddle/utils/ForceLink.h b/paddle/utils/ForceLink.h deleted file mode 100644 index 66005e299..000000000 --- a/paddle/utils/ForceLink.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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. */ - -#pragma once - -/// Declare a force link file ID. It can be enabled by -/// `PADDLE_ENABLE_FORCE_LINK_FILE`. It is -/// -/// Example: -/// -/// In some_file.cpp -/// @code{cpp} -/// static paddle::InitFunction init([]{...}); -/// PADDLE_REGISTER_FORCE_LINK_FILE(some_file) -/// @endcode{cpp} -/// -/// In main.cpp -/// @code{cpp} -/// PADDLE_ENABLE_FORCE_LINK_FILE(some_file); -/// -/// int main() { -/// ... -/// } -/// @endcode{cpp} -/// -/// Then the InitFunction in some_file.cpp can be invoked. -#define PADDLE_REGISTER_FORCE_LINK_FILE(ID) \ - int __paddle_register_force_link_file_##ID##_method__() { return 0; } - -/// Enable a force link file. The file with ID's static variables could -/// be all initialized. -#define PADDLE_ENABLE_FORCE_LINK_FILE(ID) \ - extern int __paddle_register_force_link_file_##ID##_method__(); \ - static int __paddle_register_force_link_file_##ID##_handler__ = \ - __paddle_register_force_link_file_##ID##_method__(); diff --git a/paddle/utils/tests/CMakeLists.txt b/paddle/utils/tests/CMakeLists.txt index d9b018ebb..26fafbd1a 100644 --- a/paddle/utils/tests/CMakeLists.txt +++ b/paddle/utils/tests/CMakeLists.txt @@ -15,11 +15,3 @@ if(NOT APPLE) COMMAND ${PROJ_ROOT}/paddle/utils/tests/test_CustomStackTracePrint.sh WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) endif() - -add_library(test_class_registrar_lib STATIC - test_ClassRegistrarLib.cpp - test_ClassRegistrarGlobals.cpp) - -add_simple_unittest(test_ClassRegistrar) -target_link_libraries(test_ClassRegistrar - test_class_registrar_lib) diff --git a/paddle/utils/tests/test_ClassRegistrar.cpp b/paddle/utils/tests/test_ClassRegistrar.cpp deleted file mode 100644 index c867045cb..000000000 --- a/paddle/utils/tests/test_ClassRegistrar.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* 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 -#include -#include "test_ClassRegistrarLib.h" -// Enable link test_ClassRegistrarLib.cpp -PADDLE_ENABLE_FORCE_LINK_FILE(test_registrar); - -TEST(ClassRegistrar, test) { - std::vector types; - gTestRegistrar_.forEachType( - [&types](const std::string& tp) { types.push_back(tp); }); - ASSERT_EQ(1, types.size()); - ASSERT_EQ("test", types[0]); -} diff --git a/paddle/utils/tests/test_ClassRegistrarGlobals.cpp b/paddle/utils/tests/test_ClassRegistrarGlobals.cpp deleted file mode 100644 index 0f36da137..000000000 --- a/paddle/utils/tests/test_ClassRegistrarGlobals.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* 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 "test_ClassRegistrarLib.h" -paddle::ClassRegistrar gTestRegistrar_; diff --git a/paddle/utils/tests/test_ClassRegistrarLib.cpp b/paddle/utils/tests/test_ClassRegistrarLib.cpp deleted file mode 100644 index 27071579f..000000000 --- a/paddle/utils/tests/test_ClassRegistrarLib.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* 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 "test_ClassRegistrarLib.h" -#include -BaseClass::~BaseClass() {} - -class TestRegistrar : public BaseClass { -public: - TestRegistrar() {} - - virtual ~TestRegistrar() {} -}; - -static paddle::InitFunction init([] { - gTestRegistrar_.registerClass( - "test", []() -> BaseClass* { return new TestRegistrar(); }); -}); - -PADDLE_REGISTER_FORCE_LINK_FILE(test_registrar); diff --git a/paddle/utils/tests/test_ClassRegistrarLib.h b/paddle/utils/tests/test_ClassRegistrarLib.h deleted file mode 100644 index de2d02e70..000000000 --- a/paddle/utils/tests/test_ClassRegistrarLib.h +++ /dev/null @@ -1,23 +0,0 @@ -/* 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. */ - -#pragma once -#include "paddle/utils/ClassRegistrar.h" - -class BaseClass { -public: - virtual ~BaseClass(); -}; - -extern paddle::ClassRegistrar gTestRegistrar_; -- GitLab