Merge pull request #1062 from reyoung/feature/c_api
C-API for inference.feature/design_of_v2_layer_converter
commit
f979b126c1
@ -0,0 +1,117 @@
|
|||||||
|
/* 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 "arguments.h"
|
||||||
|
#include "capi_private.h"
|
||||||
|
|
||||||
|
using paddle::capi::cast;
|
||||||
|
|
||||||
|
#define castArg(v) cast<paddle::capi::CArguments>(v)
|
||||||
|
#define castIVec(v) cast<paddle::capi::CIVector>(v)
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
paddle_arguments paddle_arguments_create_none() {
|
||||||
|
return new paddle::capi::CArguments();
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_destroy(paddle_arguments args) {
|
||||||
|
if (args == nullptr) return kPD_NULLPTR;
|
||||||
|
delete castArg(args);
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_get_size(paddle_arguments args, uint64_t* size) {
|
||||||
|
if (args == nullptr || size == nullptr) return kPD_NULLPTR;
|
||||||
|
*size = castArg(args)->args.size();
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_resize(paddle_arguments args, uint64_t size) {
|
||||||
|
if (args == nullptr) return kPD_NULLPTR;
|
||||||
|
castArg(args)->args.resize(size);
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_set_value(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_get_value(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_get_ids(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_set_ids(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_ivector ids) {
|
||||||
|
//! TODO(lizhao): Complete this method.
|
||||||
|
if (args == nullptr || ids == nullptr) return kPD_NULLPTR;
|
||||||
|
auto iv = paddle::capi::cast<paddle::capi::CIVector>(ids);
|
||||||
|
if (iv->vec == nullptr) return kPD_NULLPTR;
|
||||||
|
auto a = castArg(args);
|
||||||
|
if (ID >= a->args.size()) return kPD_OUT_OF_RANGE;
|
||||||
|
a->args[ID].ids = iv->vec;
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_set_sequence_start_pos(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
uint32_t nestedLevel,
|
||||||
|
paddle_ivector seqPos) {
|
||||||
|
if (args == nullptr || seqPos == nullptr) return kPD_NULLPTR;
|
||||||
|
auto iv = paddle::capi::cast<paddle::capi::CIVector>(seqPos);
|
||||||
|
if (iv->vec == nullptr) return kPD_NULLPTR;
|
||||||
|
auto a = castArg(args);
|
||||||
|
return a->accessSeqPos(ID, nestedLevel, [&iv](paddle::ICpuGpuVectorPtr& ptr) {
|
||||||
|
ptr = std::make_shared<paddle::ICpuGpuVector>(iv->vec);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_arguments_get_sequence_start_pos(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
uint32_t nestedLevel,
|
||||||
|
paddle_ivector seqPos) {
|
||||||
|
if (args == nullptr || seqPos == nullptr) return kPD_NULLPTR;
|
||||||
|
auto iv = paddle::capi::cast<paddle::capi::CIVector>(seqPos);
|
||||||
|
auto a = castArg(args);
|
||||||
|
return a->accessSeqPos(ID, nestedLevel, [&iv](paddle::ICpuGpuVectorPtr& ptr) {
|
||||||
|
iv->vec = ptr->getMutableVector(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
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.
|
||||||
|
file(GLOB CAPI_HEADERS *.h)
|
||||||
|
set(CAPI_PRIVATE_HEADER capi_private.h)
|
||||||
|
list(REMOVE_ITEM CAPI_HEADERS ${CAPI_PRIVATE_HEADER})
|
||||||
|
file(GLOB CAPI_SOURCES *.cpp)
|
||||||
|
|
||||||
|
# building paddle_capi
|
||||||
|
add_library(paddle_capi STATIC ${CAPI_HEADERS} ${CAPI_PRIVATE_HEADER}
|
||||||
|
${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>
|
||||||
|
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)
|
||||||
|
|
||||||
|
# install library & headers.
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${capi_whole_library} DESTINATION lib)
|
||||||
|
install(FILES ${CAPI_HEADERS} DESTINATION include/paddle)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h DESTINATION include/paddle)
|
||||||
|
install(TARGETS paddle_capi_shared DESTINATION lib)
|
||||||
|
|
||||||
|
# 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()
|
@ -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 "capi_private.h"
|
||||||
|
#include "main.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" {
|
||||||
|
paddle_error paddle_init(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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
/* 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 "capi_private.h"
|
||||||
|
#include "hl_cuda.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
|
||||||
|
#define cast(v) paddle::capi::cast<paddle::capi::CMatrix>(v)
|
||||||
|
extern "C" {
|
||||||
|
paddle_matrix paddle_matrix_create(uint64_t height,
|
||||||
|
uint64_t width,
|
||||||
|
bool useGpu) {
|
||||||
|
auto ptr = new paddle::capi::CMatrix();
|
||||||
|
ptr->mat = paddle::Matrix::create(height, width, false, useGpu);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_matrix paddle_matrix_create_none() {
|
||||||
|
return new paddle::capi::CMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_matrix_destroy(paddle_matrix mat) {
|
||||||
|
if (mat == nullptr) return kPD_NULLPTR;
|
||||||
|
auto ptr = cast(mat);
|
||||||
|
delete ptr;
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_matrix_set_row(paddle_matrix mat,
|
||||||
|
uint64_t rowID,
|
||||||
|
paddle_real* rowArray) {
|
||||||
|
if (mat == nullptr) return kPD_NULLPTR;
|
||||||
|
auto ptr = cast(mat);
|
||||||
|
if (ptr->mat == nullptr) return kPD_NULLPTR;
|
||||||
|
if (rowID >= ptr->mat->getHeight()) return kPD_OUT_OF_RANGE;
|
||||||
|
paddle::real* buf = ptr->mat->getRowBuf(rowID);
|
||||||
|
size_t width = ptr->mat->getWidth();
|
||||||
|
#ifndef PADDLE_ONLY_CPU
|
||||||
|
hl_memcpy(buf, rowArray, sizeof(paddle::real) * width);
|
||||||
|
#else
|
||||||
|
std::copy(rowArray, rowArray + width, buf);
|
||||||
|
#endif
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_matrix_get_row(paddle_matrix mat,
|
||||||
|
uint64_t rowID,
|
||||||
|
paddle_real** rawRowBuffer) {
|
||||||
|
if (mat == nullptr) return kPD_NULLPTR;
|
||||||
|
auto ptr = cast(mat);
|
||||||
|
if (ptr->mat == nullptr) return kPD_NULLPTR;
|
||||||
|
if (rowID >= ptr->mat->getHeight()) return kPD_OUT_OF_RANGE;
|
||||||
|
*rawRowBuffer = ptr->mat->getRowBuf(rowID);
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_matrix_get_shape(paddle_matrix mat,
|
||||||
|
uint64_t* height,
|
||||||
|
uint64_t* width) {
|
||||||
|
if (mat == nullptr) return kPD_NULLPTR;
|
||||||
|
if (height != nullptr) {
|
||||||
|
*height = cast(mat)->mat->getHeight();
|
||||||
|
}
|
||||||
|
if (width != nullptr) {
|
||||||
|
*width = cast(mat)->mat->getWidth();
|
||||||
|
}
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_matrix paddle_matrix_create_sparse(
|
||||||
|
uint64_t height, uint64_t width, uint64_t nnz, bool isBinary, bool useGpu) {
|
||||||
|
auto ptr = new paddle::capi::CMatrix();
|
||||||
|
ptr->mat = paddle::Matrix::createSparseMatrix(
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
nnz,
|
||||||
|
isBinary ? paddle::NO_VALUE : paddle::FLOAT_VALUE,
|
||||||
|
paddle::SPARSE_CSR,
|
||||||
|
false,
|
||||||
|
useGpu);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_matrix_sparse_copy_from(paddle_matrix mat,
|
||||||
|
int* rowArray,
|
||||||
|
uint64_t rowSize,
|
||||||
|
int* colArray,
|
||||||
|
uint64_t colSize,
|
||||||
|
float* valueArray,
|
||||||
|
uint64_t valueSize) {
|
||||||
|
if (mat == nullptr) return kPD_NULLPTR;
|
||||||
|
auto ptr = cast(mat);
|
||||||
|
if (rowArray == nullptr || colArray == nullptr ||
|
||||||
|
(valueSize != 0 && valueArray == nullptr) || ptr->mat == nullptr) {
|
||||||
|
return kPD_NULLPTR;
|
||||||
|
}
|
||||||
|
if (auto sparseMat = dynamic_cast<paddle::CpuSparseMatrix*>(ptr->mat.get())) {
|
||||||
|
std::vector<int> row(rowSize);
|
||||||
|
row.assign(rowArray, rowArray + rowSize);
|
||||||
|
std::vector<int> col(colSize);
|
||||||
|
col.assign(colArray, colArray + colSize);
|
||||||
|
std::vector<paddle_real> val(valueSize);
|
||||||
|
if (valueSize) {
|
||||||
|
val.assign(valueArray, valueArray + valueSize);
|
||||||
|
}
|
||||||
|
sparseMat->copyFrom(row, col, val);
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
} else {
|
||||||
|
return kPD_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/* 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 "capi_private.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
using paddle::capi::cast;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
paddle_ivector paddle_ivector_create_none() {
|
||||||
|
return new paddle::capi::CIVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_ivector paddle_ivector_create(int* array,
|
||||||
|
uint64_t size,
|
||||||
|
bool copy,
|
||||||
|
bool useGPU) {
|
||||||
|
auto ptr = new paddle::capi::CIVector();
|
||||||
|
if (copy) {
|
||||||
|
ptr->vec = paddle::IVector::create(size, useGPU);
|
||||||
|
ptr->vec->copyFrom(array, size);
|
||||||
|
} else {
|
||||||
|
ptr->vec = paddle::IVector::create(array, size, useGPU);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_ivector_destroy(paddle_ivector ivec) {
|
||||||
|
if (ivec == nullptr) return kPD_NULLPTR;
|
||||||
|
delete cast<paddle::capi::CIVector>(ivec);
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_ivector_get(paddle_ivector ivec, int** buffer) {
|
||||||
|
if (ivec == nullptr || buffer == nullptr) return kPD_NULLPTR;
|
||||||
|
auto v = cast<paddle::capi::CIVector>(ivec);
|
||||||
|
if (v->vec == nullptr) return kPD_NULLPTR;
|
||||||
|
*buffer = v->vec->getData();
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_ivector_resize(paddle_ivector ivec, uint64_t size) {
|
||||||
|
if (ivec == nullptr) return kPD_NULLPTR;
|
||||||
|
auto v = cast<paddle::capi::CIVector>(ivec);
|
||||||
|
if (v->vec == nullptr) return kPD_NULLPTR;
|
||||||
|
v->vec->resize(size);
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddle_error paddle_ivector_get_size(paddle_ivector ivec, uint64_t* size) {
|
||||||
|
if (ivec == nullptr) return kPD_NULLPTR;
|
||||||
|
auto v = cast<paddle::capi::CIVector>(ivec);
|
||||||
|
if (v->vec == nullptr) return kPD_NULLPTR;
|
||||||
|
*size = v->vec->getSize();
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#ifndef __PADDLE_CAPI_ARGUMENTS_H__
|
||||||
|
#define __PADDLE_CAPI_ARGUMENTS_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arguments functions. Each argument means layer output. Arguments means a
|
||||||
|
* array of arguemnt.
|
||||||
|
*/
|
||||||
|
typedef void* paddle_arguments;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief paddle_arguments_create_none Create a array of arguments, which size
|
||||||
|
* is zero.
|
||||||
|
* @return Arguemnts
|
||||||
|
*/
|
||||||
|
PD_API paddle_arguments paddle_arguments_create_none();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief paddle_arguments_destroy Destroy the arguments
|
||||||
|
* @param args arguments to destroy
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_destroy(paddle_arguments args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief paddle_arguments_get_size Get size of arguments array
|
||||||
|
* @param [in] args arguments array
|
||||||
|
* @param [out] size array size
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_get_size(paddle_arguments args,
|
||||||
|
uint64_t* size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PDArgsResize Resize a arguments array.
|
||||||
|
* @param args arguments array.
|
||||||
|
* @param size target size of array
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_resize(paddle_arguments args,
|
||||||
|
uint64_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PDArgsSetValue Set value matrix of one argument in array, which index
|
||||||
|
* is `ID`.
|
||||||
|
* @param args arguments array
|
||||||
|
* @param ID array index
|
||||||
|
* @param mat matrix pointer
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_set_value(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_matrix mat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PDArgsGetValue Get value matrix of one argument in array, which index
|
||||||
|
* is `ID`.
|
||||||
|
* @param [in] args arguments array
|
||||||
|
* @param [in] ID array index
|
||||||
|
* @param [out] mat matrix pointer
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_get_value(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_matrix mat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PDArgsGetIds Get the integer vector of one argument in array, which
|
||||||
|
* index is `ID`.
|
||||||
|
* @param args arguments array
|
||||||
|
* @param ID array index
|
||||||
|
* @param ids integer vector pointer
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_get_ids(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_ivector ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PDArgsSetIds Set the integer vector of one argument in array, which
|
||||||
|
* index is `ID`.
|
||||||
|
* @param [in] args arguments array
|
||||||
|
* @param [in] ID array index
|
||||||
|
* @param [out] ids integer vector pointer
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error paddle_arguments_set_ids(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
paddle_ivector ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PDArgsSetSequenceStartPos Set sequence start position vector of one
|
||||||
|
* argument in array, which index is `ID`.
|
||||||
|
* @param args arguments array
|
||||||
|
* @param ID array index
|
||||||
|
* @param seqPos sequence position array.
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error
|
||||||
|
paddle_arguments_set_sequence_start_pos(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
uint32_t nestedLevel,
|
||||||
|
paddle_ivector seqPos);
|
||||||
|
/**
|
||||||
|
* @brief PDArgsGetSequenceStartPos Get sequence start position vector of one
|
||||||
|
* argument in array, which index is `ID`.
|
||||||
|
* @param [in] args arguments array
|
||||||
|
* @param [in] ID array index
|
||||||
|
* @param [out] seqPos sequence position array
|
||||||
|
* @return paddle_error
|
||||||
|
*/
|
||||||
|
PD_API paddle_error
|
||||||
|
paddle_arguments_get_sequence_start_pos(paddle_arguments args,
|
||||||
|
uint64_t ID,
|
||||||
|
uint32_t nestedLevel,
|
||||||
|
paddle_ivector seqPos);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,32 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#ifndef __PADDLE_CAPI_H__
|
||||||
|
#define __PADDLE_CAPI_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paddle C API. It will replace SWIG as Multiple Language API for model
|
||||||
|
* training & inference. Currently it is only used in model infernece.
|
||||||
|
*
|
||||||
|
* NOTE: This is an experimental API, it could be changed.
|
||||||
|
*/
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "gradient_machine.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
#endif // PADDLECAPI_H_
|
@ -0,0 +1,82 @@
|
|||||||
|
/* 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 "capi.h"
|
||||||
|
#include "paddle/gserver/gradientmachines/GradientMachine.h"
|
||||||
|
#include "paddle/math/Matrix.h"
|
||||||
|
#include "paddle/math/Vector.h"
|
||||||
|
#include "paddle/parameter/Argument.h"
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
namespace capi {
|
||||||
|
|
||||||
|
enum CType { kIVECTOR = 0, kMATRIX, kARGUMENTS, kGRADIENT_MACHINE };
|
||||||
|
|
||||||
|
#define STRUCT_HEADER CType type;
|
||||||
|
|
||||||
|
struct CHeader {
|
||||||
|
STRUCT_HEADER
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CIVector {
|
||||||
|
STRUCT_HEADER
|
||||||
|
IVectorPtr vec;
|
||||||
|
|
||||||
|
CIVector() : type(kIVECTOR) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMatrix {
|
||||||
|
STRUCT_HEADER
|
||||||
|
MatrixPtr mat;
|
||||||
|
|
||||||
|
CMatrix() : type(kMATRIX) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CArguments {
|
||||||
|
STRUCT_HEADER
|
||||||
|
std::vector<paddle::Argument> args;
|
||||||
|
|
||||||
|
CArguments() : type(kARGUMENTS) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
paddle_error accessSeqPos(uint64_t ID, uint32_t nestedLevel, T callback) {
|
||||||
|
if (ID >= args.size()) return kPD_OUT_OF_RANGE;
|
||||||
|
switch (nestedLevel) {
|
||||||
|
case 0:
|
||||||
|
callback(args[ID].sequenceStartPositions);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
callback(args[ID].subSequenceStartPositions);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return kPD_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
|
return kPD_NO_ERROR;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CGradientMachine {
|
||||||
|
STRUCT_HEADER
|
||||||
|
paddle::GradientMachinePtr machine;
|
||||||
|
|
||||||
|
CGradientMachine() : type(kGRADIENT_MACHINE) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* cast(void* ptr) {
|
||||||
|
return reinterpret_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
} // namespace capi
|
||||||
|
} // namespace paddle
|
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __PADDLE_PADDLE_CAPI_CONFIG_H_INCLUDED__
|
||||||
|
#define __PADDLE_PADDLE_CAPI_CONFIG_H_INCLUDED__
|
||||||
|
|
||||||
|
typedef @PADDLE_FLOAT_TYPE@ paddle_real;
|
||||||
|
|
||||||
|
// Since we only support linux and macos in compile, always use clang or
|
||||||
|
// gcc 4.8+. DLL_IMPORT/DLL_EXPORT is as simple as below.
|
||||||
|
#define PD_API __attribute__((visibility("default")))
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,30 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#ifndef __PADDLE_CAPI_ERROR_H__
|
||||||
|
#define __PADDLE_CAPI_ERROR_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error Type for Paddle API.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
kPD_NO_ERROR = 0,
|
||||||
|
kPD_NULLPTR = 1,
|
||||||
|
kPD_OUT_OF_RANGE = 2,
|
||||||
|
kPD_PROTOBUF_ERROR = 3,
|
||||||
|
kPD_NOT_SUPPORTED = 4,
|
||||||
|
kPD_UNDEFINED_ERROR = -1,
|
||||||
|
} paddle_error;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,2 @@
|
|||||||
|
*.bin
|
||||||
|
build-*
|
@ -0,0 +1,3 @@
|
|||||||
|
# C-API Example Usage
|
||||||
|
|
||||||
|
* [Model Inference](./model_inference/README.md)
|
@ -0,0 +1,42 @@
|
|||||||
|
# Use C-API for Model Inference
|
||||||
|
|
||||||
|
There are several examples in this directory about how to use Paddle C-API for model inference.
|
||||||
|
|
||||||
|
## Convert configuration file to protobuf binary.
|
||||||
|
|
||||||
|
Firstly, the user should convert Paddle's model configuration file into a protobuf binary file. In each example directory, there is a file named `convert_protobin.sh`. It will convert `trainer_config.conf` into `trainer_config.bin`.
|
||||||
|
|
||||||
|
The `convert_protobin.sh` is very simple, just invoke `dump_config` Python module to dump the binary file. The command line usages are:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m paddle.utils.dump_config YOUR_CONFIG_FILE 'CONFIG_EXTRA_ARGS' --binary > YOUR_CONFIG_FILE.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Initialize paddle
|
||||||
|
|
||||||
|
```c++
|
||||||
|
char* argv[] = {"--use_gpu=False"};
|
||||||
|
paddle_init(1, (char**)argv);
|
||||||
|
```
|
||||||
|
|
||||||
|
We must initialize global context before we invoke other interfaces in Paddle. The initialize commands just like the `paddle_trainer` command line arguments. `paddle train --help`, will show the list of arguments. The most important argument is `use_gpu` or not.
|
||||||
|
|
||||||
|
## Load network and parameters
|
||||||
|
|
||||||
|
```c
|
||||||
|
paddle_gradient_machine machine;
|
||||||
|
paddle_gradient_machine_create_for_inference(&machine, config_file_content, content_size));
|
||||||
|
paddle_gradient_machine_load_parameter_from_disk(machine, "./some_where_to_params"));
|
||||||
|
```
|
||||||
|
|
||||||
|
The gradient machine is a Paddle concept, which represents a neural network can be forwarded and backward. We can create a gradient machine fo model inference, and load the parameter files from disk.
|
||||||
|
|
||||||
|
Moreover, if we want to inference in multi-thread, we could create a thread local gradient machine which shared the same parameter by using `paddle_gradient_machine_create_shared_param` API. Please reference `multi_thread` as an example.
|
||||||
|
|
||||||
|
## Create input
|
||||||
|
|
||||||
|
The input of a neural network is an `arguments`. The examples in this directory will show how to construct different types of inputs for prediction. Please look at `dense`, `sparse_binary`, `sequence` for details.
|
||||||
|
|
||||||
|
## Get inference
|
||||||
|
|
||||||
|
After invoking `paddle_gradient_machine_forward`, we could get the output of the neural network. The `value` matrix of output arguments will store the neural network output values. If the output is a `SoftmaxActivation`, the `value` matrix are the probabilities of each input samples. The height of output matrix is number of sample. The width is the number of categories.
|
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef __CAPI_EXAMPLE_COMMON_H__
|
||||||
|
#define __CAPI_EXAMPLE_COMMON_H__
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define CHECK(stmt) \
|
||||||
|
do { \
|
||||||
|
paddle_error __err__ = stmt; \
|
||||||
|
if (__err__ != kPD_NO_ERROR) { \
|
||||||
|
fprintf(stderr, "Invoke paddle error %d \n" #stmt, __err__); \
|
||||||
|
exit(__err__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
void* read_config(const char* filename, long* size) {
|
||||||
|
FILE* file = fopen(filename, "r");
|
||||||
|
if (file == NULL) return NULL;
|
||||||
|
fseek(file, 0L, SEEK_END);
|
||||||
|
*size = ftell(file);
|
||||||
|
fseek(file, 0L, SEEK_SET);
|
||||||
|
void* buf = malloc(*size);
|
||||||
|
fread(buf, 1, *size, file);
|
||||||
|
fclose(file);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,6 @@
|
|||||||
|
project(dense)
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
aux_source_directory(. SRC_LIST)
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||||
|
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)
|
||||||
|
target_link_libraries(${PROJECT_NAME} -lpaddle_capi_shared)
|
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
python -m paddle.utils.dump_config trainer_config.py '' --binary > trainer_config.bin
|
@ -0,0 +1,69 @@
|
|||||||
|
#include <paddle/capi.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "../common/common.h"
|
||||||
|
|
||||||
|
#define CONFIG_BIN "./trainer_config.bin"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Initalize Paddle
|
||||||
|
char* argv[] = {"--use_gpu=False"};
|
||||||
|
CHECK(paddle_init(1, (char**)argv));
|
||||||
|
|
||||||
|
// Reading config binary file. It is generated by `convert_protobin.sh`
|
||||||
|
long size;
|
||||||
|
void* buf = read_config(CONFIG_BIN, &size);
|
||||||
|
|
||||||
|
// Create a gradient machine for inference.
|
||||||
|
paddle_gradient_machine machine;
|
||||||
|
CHECK(paddle_gradient_machine_create_for_inference(&machine, buf, (int)size));
|
||||||
|
CHECK(paddle_gradient_machine_randomize_param(machine));
|
||||||
|
|
||||||
|
// Loading parameter. Uncomment the following line and change the directory.
|
||||||
|
// CHECK(paddle_gradient_machine_load_parameter_from_disk(machine,
|
||||||
|
// "./some_where_to_params"));
|
||||||
|
paddle_arguments in_args = paddle_arguments_create_none();
|
||||||
|
|
||||||
|
// There is only one input of this network.
|
||||||
|
CHECK(paddle_arguments_resize(in_args, 1));
|
||||||
|
|
||||||
|
// Create input matrix.
|
||||||
|
paddle_matrix mat = paddle_matrix_create(/* sample_num */ 1,
|
||||||
|
/* size */ 784,
|
||||||
|
/* useGPU */ false);
|
||||||
|
srand(time(0));
|
||||||
|
paddle_real* array;
|
||||||
|
|
||||||
|
// Get First row.
|
||||||
|
CHECK(paddle_matrix_get_row(mat, 0, &array));
|
||||||
|
|
||||||
|
for (int i = 0; i < 784; ++i) {
|
||||||
|
array[i] = rand() / ((float)RAND_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(paddle_arguments_set_value(in_args, 0, mat));
|
||||||
|
|
||||||
|
paddle_arguments out_args = paddle_arguments_create_none();
|
||||||
|
CHECK(paddle_gradient_machine_forward(machine,
|
||||||
|
in_args,
|
||||||
|
out_args,
|
||||||
|
/* isTrain */ false));
|
||||||
|
paddle_matrix prob = paddle_matrix_create_none();
|
||||||
|
|
||||||
|
CHECK(paddle_arguments_get_value(out_args, 0, prob));
|
||||||
|
|
||||||
|
CHECK(paddle_matrix_get_row(prob, 0, &array));
|
||||||
|
|
||||||
|
printf("Prob: ");
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
printf("%.2f ", array[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
CHECK(paddle_matrix_destroy(prob));
|
||||||
|
CHECK(paddle_arguments_destroy(out_args));
|
||||||
|
CHECK(paddle_matrix_destroy(mat));
|
||||||
|
CHECK(paddle_arguments_destroy(in_args));
|
||||||
|
CHECK(paddle_gradient_machine_destroy(machine));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
from paddle.trainer_config_helpers import *
|
||||||
|
|
||||||
|
img = data_layer(name='pixel', size=784)
|
||||||
|
|
||||||
|
hidden = fc_layer(
|
||||||
|
input=img,
|
||||||
|
size=200,
|
||||||
|
param_attr=ParamAttr(name='hidden.w'),
|
||||||
|
bias_attr=ParamAttr(name='hidden.b'))
|
||||||
|
|
||||||
|
prob = fc_layer(
|
||||||
|
input=hidden,
|
||||||
|
size=10,
|
||||||
|
act=SoftmaxActivation(),
|
||||||
|
param_attr=ParamAttr(name='prob.w'),
|
||||||
|
bias_attr=ParamAttr(name='prob.b'))
|
||||||
|
|
||||||
|
outputs(prob)
|
@ -0,0 +1,73 @@
|
|||||||
|
# This file is used to ignore files which are generated
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.autosave
|
||||||
|
*.a
|
||||||
|
*.core
|
||||||
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*_pch.h.cpp
|
||||||
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
|
.#*
|
||||||
|
*.*#
|
||||||
|
core
|
||||||
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
|
/.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
|
||||||
|
# qtcreator generated files
|
||||||
|
*.pro.user*
|
||||||
|
|
||||||
|
# xemacs temporary files
|
||||||
|
*.flc
|
||||||
|
|
||||||
|
# Vim temporary files
|
||||||
|
.*.swp
|
||||||
|
|
||||||
|
# Visual Studio generated files
|
||||||
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
|
# MinGW generated files
|
||||||
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
project(multi_thread)
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
aux_source_directory(. SRC_LIST)
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||||
|
find_package (Threads)
|
||||||
|
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)
|
||||||
|
target_link_libraries(${PROJECT_NAME} -lpaddle_capi_shared
|
||||||
|
${CMAKE_THREAD_LIBS_INIT})
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue