提交 aa6e2521 编写于 作者: Y Yu Yang

Doing C-API

上级 fbb1b0e4
......@@ -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
......
#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);
}
}
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;
}
}
#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 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;
}
}
......@@ -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
......
#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<paddle::Argument> args;
};
struct CGradientMachine {
paddle::GradientMachinePtr machine;
};
template <typename T>
inline T* cast(void* ptr) {
return reinterpret_cast<T*>(ptr);
......
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)
#include <gtest/gtest.h>
#include <stdlib.h>
#include <string.h>
#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<char*> argvs;
argvs.push_back(strdup("--use_gpu=false"));
PDInit((int)argvs.size(), argvs.data());
for (auto each : argvs) {
free(each);
}
return RUN_ALL_TESTS();
}
../../../demo/image_classification/vgg_16_cifar.py
\ No newline at end of file
/* 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__();
......@@ -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)
/* 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 <gtest/gtest.h>
#include <paddle/utils/ForceLink.h>
#include "test_ClassRegistrarLib.h"
// Enable link test_ClassRegistrarLib.cpp
PADDLE_ENABLE_FORCE_LINK_FILE(test_registrar);
TEST(ClassRegistrar, test) {
std::vector<std::string> types;
gTestRegistrar_.forEachType(
[&types](const std::string& tp) { types.push_back(tp); });
ASSERT_EQ(1, types.size());
ASSERT_EQ("test", types[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<BaseClass> gTestRegistrar_;
/* 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 <paddle/utils/ForceLink.h>
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);
/* 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<BaseClass> gTestRegistrar_;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册