Skip to content

Commit fbb1b0e

Browse files
committed
Start Doing C-API for predict.
1 parent 495649a commit fbb1b0e

18 files changed

+535
-1
lines changed

paddle/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ add_subdirectory(gserver)
88
add_subdirectory(pserver)
99
add_subdirectory(trainer)
1010
add_subdirectory(scripts)
11-
11+
add_subdirectory(capi)
1212
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in
1313
${CMAKE_CURRENT_SOURCE_DIR}/setup.py)
1414

paddle/capi/Arguments.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "PaddleCAPI.h"
2+
#include "PaddleCAPIPrivate.h"
3+
4+
#define cast(v) paddle::capi::cast<paddle::capi::CArguments>(v)
5+
6+
extern "C" {
7+
int PDArgsCreateNone(PD_Arguments* args) {
8+
auto ptr = new paddle::capi::CArguments();
9+
*args = ptr;
10+
return PD_NO_ERROR;
11+
}
12+
13+
int PDArgsDestroy(PD_Arguments args) {
14+
if (args == nullptr) return PD_NULLPTR;
15+
delete cast(args);
16+
return PD_NO_ERROR;
17+
}
18+
19+
int PDArgsGetSize(PD_Arguments args, uint64_t* size) {
20+
if (args == nullptr || size == nullptr) return PD_NULLPTR;
21+
*size = cast(args)->args.size();
22+
return PD_NO_ERROR;
23+
}
24+
25+
int PDArgsResize(PD_Arguments args, uint64_t size) {
26+
if (args == nullptr) return PD_NULLPTR;
27+
cast(args)->args.resize(size);
28+
return PD_NO_ERROR;
29+
}
30+
31+
int PDArgsSetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat) {
32+
if (args == nullptr || mat == nullptr) return PD_NULLPTR;
33+
auto m = paddle::capi::cast<paddle::capi::CMatrix>(mat);
34+
if (m->mat == nullptr) return PD_NULLPTR;
35+
auto a = cast(args);
36+
if (ID >= a->args.size()) return PD_OUT_OF_RANGE;
37+
a->args[ID].value = m->mat;
38+
return PD_NO_ERROR;
39+
}
40+
41+
int PDArgsGetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat) {
42+
if (args == nullptr || mat == nullptr) return PD_NULLPTR;
43+
auto m = paddle::capi::cast<paddle::capi::CMatrix>(mat);
44+
auto a = cast(args);
45+
if (ID >= a->args.size()) return PD_OUT_OF_RANGE;
46+
m->mat = a->args[ID].value;
47+
return PD_NO_ERROR;
48+
}
49+
}

paddle/capi/CMakeLists.txt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
if (WITH_DOUBLE)
2+
set(PADDLE_FLOAT_TYPE double)
3+
else ()
4+
set(PADDLE_FLOAT_TYPE float)
5+
endif()
6+
7+
configure_file(config.h.in config.h @ONLY)
8+
9+
set(CAPI_HEADER
10+
PaddleCAPI.h)
11+
set(CAPI_PRIVATE_HEADER
12+
PaddleCAPIPrivate.h)
13+
file(GLOB CAPI_SOURCES *.cpp)
14+
15+
add_library(paddle_capi SHARED ${CAPI_SOURCES})
16+
17+
target_include_directories(paddle_capi PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
18+
add_dependencies(paddle_capi gen_proto_cpp)
19+
20+
target_link_libraries(paddle_capi
21+
paddle_gserver
22+
paddle_function
23+
paddle_pserver
24+
paddle_trainer_lib
25+
paddle_network
26+
paddle_math
27+
paddle_utils
28+
paddle_parameter
29+
paddle_proto
30+
paddle_cuda
31+
${PROTOBUF_LIBRARY}
32+
${LIBGLOG_LIBRARY}
33+
${GFLAGS_LIBRARIES}
34+
${CMAKE_THREAD_LIBS_INIT}
35+
${CBLAS_LIBS}
36+
${ZLIB_LIBRARIES}
37+
${INTERAL_LIBS}
38+
${CMAKE_DL_LIBS})
39+
40+
41+
set(PADDLE_CAPI_INC_PATH
42+
${CMAKE_CURRENT_BINARY_DIR}
43+
${CMAKE_CURRENT_SOURCE_DIR})
44+
45+
if (WITH_TESTING)
46+
add_subdirectory(tests)
47+
endif()

paddle/capi/Matrix.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "PaddleCAPI.h"
2+
#include "PaddleCAPIPrivate.h"
3+
#include "hl_cuda.h"
4+
5+
#define cast(v) paddle::capi::cast<paddle::capi::CMatrix>(v)
6+
extern "C" {
7+
int PDMatCreate(PD_Matrix* mat, uint64_t height, uint64_t width, bool useGpu) {
8+
auto ptr = new paddle::capi::CMatrix();
9+
ptr->mat = paddle::Matrix::create(height, width, false, useGpu);
10+
*mat = ptr;
11+
return PD_NO_ERROR;
12+
}
13+
14+
int PDMatCreateNone(PD_Matrix* mat) {
15+
auto ptr = new paddle::capi::CMatrix();
16+
*mat = ptr;
17+
return PD_NO_ERROR;
18+
}
19+
20+
int PDMatDestroy(PD_Matrix mat) {
21+
if (mat == nullptr) return PD_NULLPTR;
22+
auto ptr = cast(mat);
23+
delete ptr;
24+
return PD_NO_ERROR;
25+
}
26+
27+
int PDMatCopyToRow(PD_Matrix mat, uint64_t rowID, pd_real* rowArray) {
28+
if (mat == nullptr) return PD_NULLPTR;
29+
auto ptr = cast(mat);
30+
if (ptr->mat == nullptr) return PD_NULLPTR;
31+
if (rowID >= ptr->mat->getHeight()) return PD_OUT_OF_RANGE;
32+
paddle::real* buf = ptr->mat->getRowBuf(rowID);
33+
size_t width = ptr->mat->getWidth();
34+
#ifndef PADDLE_ONLY_CPU
35+
hl_memcpy(buf, rowArray, sizeof(paddle::real) * width);
36+
#else
37+
std::copy(rowArray, rowArray + width, buf);
38+
#endif
39+
return PD_NO_ERROR;
40+
}
41+
42+
int PDMatGetRow(PD_Matrix mat, uint64_t rowID, pd_real** rawRowBuffer) {
43+
if (mat == nullptr) return PD_NULLPTR;
44+
auto ptr = cast(mat);
45+
if (ptr->mat == nullptr) return PD_NULLPTR;
46+
if (rowID >= ptr->mat->getHeight()) return PD_OUT_OF_RANGE;
47+
*rawRowBuffer = ptr->mat->getRowBuf(rowID);
48+
return PD_NO_ERROR;
49+
}
50+
51+
int PDMatGetShape(PD_Matrix mat, uint64_t* height, uint64_t* width) {
52+
if (mat == nullptr) return PD_NULLPTR;
53+
if (height != nullptr) {
54+
*height = cast(mat)->mat->getHeight();
55+
}
56+
if (width != nullptr) {
57+
*width = cast(mat)->mat->getWidth();
58+
}
59+
return PD_NO_ERROR;
60+
}
61+
}

paddle/capi/PaddleCAPI.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#ifndef __PADDLE_PADDLE_CAPI_PADDLECAPI_H_INCLUDED__
2+
#define __PADDLE_PADDLE_CAPI_PADDLECAPI_H_INCLUDED__
3+
#include <stdbool.h>
4+
#include <stdint.h>
5+
#include "config.h"
6+
#ifdef __cplusplus
7+
extern "C" {
8+
#endif
9+
10+
#define PD_NO_ERROR 0
11+
#define PD_NULLPTR 1
12+
#define PD_OUT_OF_RANGE 2
13+
#define PD_UNDEFINED_ERROR -1
14+
15+
typedef void* PD_Vector;
16+
17+
int PDVecCreate(PD_Vector* vec, uint64_t size, bool useGpu);
18+
19+
int PDVecDestroy(PD_Vector vec);
20+
21+
int PDVecIsSparse(PD_Vector vec, bool* isSparse);
22+
23+
typedef void* PD_Matrix;
24+
25+
int PDMatCreate(PD_Matrix* mat, uint64_t height, uint64_t width, bool useGpu);
26+
27+
int PDMatDestroy(PD_Matrix mat);
28+
29+
int PDMatCopyToRow(PD_Matrix mat, uint64_t rowID, pd_real* rowArray);
30+
31+
int PDMatGetRow(PD_Matrix mat, uint64_t rowID, pd_real** rawRowBuffer);
32+
33+
int PDMatCreateNone(PD_Matrix* mat);
34+
35+
int PDMatGetShape(PD_Matrix mat, uint64_t* height, uint64_t* width);
36+
37+
typedef void* PD_Arguments;
38+
39+
int PDArgsCreateNone(PD_Arguments* args);
40+
41+
int PDArgsDestroy(PD_Arguments args);
42+
43+
int PDArgsGetSize(PD_Arguments args, uint64_t* size);
44+
45+
int PDArgsResize(PD_Arguments args, uint64_t size);
46+
47+
int PDArgsSetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat);
48+
49+
int PDArgsGetValue(PD_Arguments args, uint64_t ID, PD_Matrix mat);
50+
51+
#ifdef __cplusplus
52+
}
53+
#endif
54+
#endif

paddle/capi/PaddleCAPIPrivate.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "PaddleCAPI.h"
2+
#include "paddle/math/Matrix.h"
3+
#include "paddle/math/Vector.h"
4+
#include "paddle/parameter/Argument.h"
5+
#pragma once
6+
7+
namespace paddle {
8+
namespace capi {
9+
10+
struct CVector {
11+
VectorPtr vec;
12+
};
13+
14+
struct CMatrix {
15+
MatrixPtr mat;
16+
};
17+
18+
struct CArguments {
19+
std::vector<paddle::Argument> args;
20+
};
21+
22+
template <typename T>
23+
inline T* cast(void* ptr) {
24+
return reinterpret_cast<T*>(ptr);
25+
}
26+
}
27+
}

paddle/capi/Vector.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "PaddleCAPI.h"
2+
#include "PaddleCAPIPrivate.h"
3+
4+
#define cast(v) paddle::capi::cast<paddle::capi::CVector>(v)
5+
extern "C" {
6+
int PDVecCreate(PD_Vector* vec, uint64_t size, bool useGpu) {
7+
auto ptr = new paddle::capi::CVector();
8+
ptr->vec = paddle::Vector::create(size, useGpu);
9+
*vec = ptr;
10+
return PD_NO_ERROR;
11+
}
12+
int PDVecDestroy(PD_Vector vec) {
13+
auto v = cast(vec);
14+
v->vec.reset();
15+
delete v;
16+
return PD_NO_ERROR;
17+
}
18+
19+
int PDVecIsSparse(PD_Vector vec, bool* isSparse) {
20+
if (isSparse == nullptr || vec == nullptr) {
21+
return PD_NULLPTR;
22+
}
23+
*isSparse = cast(vec)->vec->isSparse();
24+
return PD_NO_ERROR;
25+
}
26+
}

paddle/capi/config.h.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef __PADDLE_PADDLE_CAPI_CONFIG_H_INCLUDED__
2+
#define __PADDLE_PADDLE_CAPI_CONFIG_H_INCLUDED__
3+
4+
typedef @PADDLE_FLOAT_TYPE@ pd_real;
5+
6+
#endif

paddle/capi/tests/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function(add_capi_unittest TARGET_NAME)
2+
add_executable(
3+
${TARGET_NAME}
4+
${ARGN})
5+
target_link_libraries(
6+
${TARGET_NAME}
7+
paddle_capi
8+
paddle_test_main
9+
${GTEST_LIBRARIES})
10+
target_include_directories(${TARGET_NAME} PUBLIC ${PADDLE_CAPI_INC_PATH})
11+
add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME})
12+
endfunction()
13+
14+
add_capi_unittest(capi_test_mats test_Vector.cpp
15+
test_Matrix.cpp test_Arguments.cpp)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "PaddleCAPI.h"
2+
#include "gtest/gtest.h"
3+
#include "paddle/utils/ThreadLocal.h"
4+
5+
static std::vector<pd_real> randomBuffer(size_t bufSize) {
6+
auto& eng = paddle::ThreadLocalRandomEngine::get();
7+
std::uniform_real_distribution<pd_real> dist(-1.0, 1.0);
8+
std::vector<pd_real> retv;
9+
retv.reserve(bufSize);
10+
for (size_t i = 0; i < bufSize; ++i) {
11+
retv.push_back(dist(eng));
12+
}
13+
return retv;
14+
}
15+
16+
TEST(CAPIArguments, create) {
17+
PD_Arguments args;
18+
ASSERT_EQ(PD_NO_ERROR, PDArgsCreateNone(&args));
19+
uint64_t size;
20+
ASSERT_EQ(PD_NO_ERROR, PDArgsGetSize(args, &size));
21+
ASSERT_EQ(0UL, size);
22+
ASSERT_EQ(PD_NO_ERROR, PDArgsDestroy(args));
23+
}
24+
25+
TEST(CAPIArguments, value) {
26+
PD_Arguments args;
27+
ASSERT_EQ(PD_NO_ERROR, PDArgsCreateNone(&args));
28+
ASSERT_EQ(PD_NO_ERROR, PDArgsResize(args, 1));
29+
30+
PD_Matrix mat;
31+
ASSERT_EQ(PD_NO_ERROR, PDMatCreate(&mat, 128, 64, false));
32+
for (size_t i = 0; i < 128; ++i) {
33+
std::vector<pd_real> sampleBuf = randomBuffer(64);
34+
PDMatCopyToRow(mat, i, sampleBuf.data());
35+
}
36+
ASSERT_EQ(PD_NO_ERROR, PDArgsSetValue(args, 0, mat));
37+
38+
PD_Matrix val;
39+
ASSERT_EQ(PD_NO_ERROR, PDMatCreateNone(&val));
40+
41+
ASSERT_EQ(PD_NO_ERROR, PDArgsGetValue(args, 0, val));
42+
43+
for (size_t i = 0; i < 128; ++i) {
44+
pd_real* row1;
45+
pd_real* row2;
46+
47+
ASSERT_EQ(PD_NO_ERROR, PDMatGetRow(mat, i, &row1));
48+
ASSERT_EQ(PD_NO_ERROR, PDMatGetRow(val, i, &row2));
49+
ASSERT_EQ(row1, row2);
50+
}
51+
ASSERT_EQ(PD_NO_ERROR, PDMatDestroy(val));
52+
ASSERT_EQ(PD_NO_ERROR, PDMatDestroy(mat));
53+
ASSERT_EQ(PD_NO_ERROR, PDArgsDestroy(args));
54+
}

0 commit comments

Comments
 (0)