From 301eeb5bea40a7215c53d17cc775049eaa21cdc4 Mon Sep 17 00:00:00 2001 From: liu zhengxi <380185688@qq.com> Date: Sat, 5 Oct 2019 08:56:55 +0800 Subject: [PATCH] Add capi for fluid inference api (#20092) * add capi for fluid inference api, including AnalysisConfig, AnalysisPredictor, PaddleBuf, PaddleTensor, ZeroCopyTensor --- paddle/fluid/inference/CMakeLists.txt | 1 + paddle/fluid/inference/capi/CMakeLists.txt | 10 + paddle/fluid/inference/capi/c_api.cc | 97 ++++++ paddle/fluid/inference/capi/c_api.h | 255 +++++++++++++++ paddle/fluid/inference/capi/c_api_internal.h | 43 +++ paddle/fluid/inference/capi/pd_config.cc | 296 ++++++++++++++++++ paddle/fluid/inference/capi/pd_predictor.cc | 136 ++++++++ paddle/fluid/inference/capi/pd_tensor.cc | 74 +++++ .../fluid/inference/tests/api/CMakeLists.txt | 25 ++ .../tests/api/analyzer_capi_gpu_tester.cc | 100 ++++++ .../tests/api/analyzer_capi_int_tester.cc | 106 +++++++ .../api/analyzer_capi_pd_tensor_tester.cc | 153 +++++++++ .../tests/api/analyzer_capi_tester.cc | 108 +++++++ 13 files changed, 1404 insertions(+) create mode 100644 paddle/fluid/inference/capi/CMakeLists.txt create mode 100644 paddle/fluid/inference/capi/c_api.cc create mode 100644 paddle/fluid/inference/capi/c_api.h create mode 100644 paddle/fluid/inference/capi/c_api_internal.h create mode 100644 paddle/fluid/inference/capi/pd_config.cc create mode 100644 paddle/fluid/inference/capi/pd_predictor.cc create mode 100644 paddle/fluid/inference/capi/pd_tensor.cc create mode 100644 paddle/fluid/inference/tests/api/analyzer_capi_gpu_tester.cc create mode 100644 paddle/fluid/inference/tests/api/analyzer_capi_int_tester.cc create mode 100644 paddle/fluid/inference/tests/api/analyzer_capi_pd_tensor_tester.cc create mode 100644 paddle/fluid/inference/tests/api/analyzer_capi_tester.cc diff --git a/paddle/fluid/inference/CMakeLists.txt b/paddle/fluid/inference/CMakeLists.txt index d1db924e6b2..5a3525a686d 100644 --- a/paddle/fluid/inference/CMakeLists.txt +++ b/paddle/fluid/inference/CMakeLists.txt @@ -36,6 +36,7 @@ else(WIN32) endif(WIN32) add_subdirectory(api) +add_subdirectory(capi) if(WITH_MKLDNN) set(mkldnn_quantizer_src ${CMAKE_CURRENT_SOURCE_DIR}/api/mkldnn_quantizer.cc) diff --git a/paddle/fluid/inference/capi/CMakeLists.txt b/paddle/fluid/inference/capi/CMakeLists.txt new file mode 100644 index 00000000000..bb3620b530c --- /dev/null +++ b/paddle/fluid/inference/capi/CMakeLists.txt @@ -0,0 +1,10 @@ + +cc_library(pd_config SRCS pd_config.cc) +cc_library(pd_predictor SRCS pd_predictor.cc) +cc_library(pd_tensor SRCS pd_tensor.cc) +cc_library(pd_c_api SRCS c_api.cc) + +cc_library(paddle_fluid_c SRCS c_api.cc DEPS paddle_fluid pd_config pd_predictor pd_tensor pd_c_api) +# (TODO) dll +# cc_library(paddle_fluid_c_shared SHARED SRCS c_api.cc DEPS paddle_fluid pd_config pd_predictor pd_tensor pd_c_api) +# set_target_properties(paddle_fluid_c_shared PROPERTIES OUTPUT_NAME paddle_fluid_c) diff --git a/paddle/fluid/inference/capi/c_api.cc b/paddle/fluid/inference/capi/c_api.cc new file mode 100644 index 00000000000..07f58bf2368 --- /dev/null +++ b/paddle/fluid/inference/capi/c_api.cc @@ -0,0 +1,97 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// 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 "paddle/fluid/inference/capi/c_api.h" +#include +#include +#include "paddle/fluid/inference/capi/c_api_internal.h" + +using paddle::ConvertToPaddleDType; +using paddle::ConvertToPDDataType; +using paddle::ConvertToACPrecision; + +extern "C" { + +PD_PaddleBuf* PD_NewPaddleBuf() { return new PD_PaddleBuf; } + +void PD_DeletePaddleBuf(PD_PaddleBuf* buf) { + if (buf) { + delete buf; + buf = nullptr; + } +} + +void PD_PaddleBufResize(PD_PaddleBuf* buf, size_t length) { + buf->buf.Resize(length); +} + +void PD_PaddleBufReset(PD_PaddleBuf* buf, void* data, size_t length) { + buf->buf.Reset(data, length); +} + +bool PD_PaddleBufEmpty(PD_PaddleBuf* buf) { return buf->buf.empty(); } + +void* PD_PaddleBufData(PD_PaddleBuf* buf) { return buf->buf.data(); } + +size_t PD_PaddleBufLength(PD_PaddleBuf* buf) { return buf->buf.length(); } + +} // extern "C" + +namespace paddle { +paddle::PaddleDType ConvertToPaddleDType(PD_DataType dtype) { + switch (dtype) { + case PD_FLOAT32: + return PD_PaddleDType::FLOAT32; + case PD_INT32: + return PD_PaddleDType::INT32; + case PD_INT64: + return PD_PaddleDType::INT64; + case PD_UINT8: + return PD_PaddleDType::UINT8; + default: + CHECK(false) << "Unsupport dtype."; + return PD_PaddleDType::FLOAT32; + } +} + +PD_DataType ConvertToPDDataType(PD_PaddleDType dtype) { + switch (dtype) { + case PD_PaddleDType::FLOAT32: + return PD_DataType::PD_FLOAT32; + case PD_PaddleDType::INT32: + return PD_DataType::PD_INT32; + case PD_PaddleDType::INT64: + return PD_DataType::PD_INT64; + case PD_PaddleDType::UINT8: + return PD_DataType::PD_UINT8; + default: + CHECK(false) << "Unsupport dtype."; + return PD_DataType::PD_UNKDTYPE; + } +} + +PD_ACPrecision ConvertToACPrecision(Precision dtype) { + switch (dtype) { + case Precision::kFloat32: + return PD_ACPrecision::kFloat32; + case Precision::kInt8: + return PD_ACPrecision::kInt8; + case Precision::kHalf: + return PD_ACPrecision::kHalf; + default: + CHECK(false) << "Unsupport precision."; + return PD_ACPrecision::kFloat32; + } +} +} // namespace paddle diff --git a/paddle/fluid/inference/capi/c_api.h b/paddle/fluid/inference/capi/c_api.h new file mode 100644 index 00000000000..a58e9a54e05 --- /dev/null +++ b/paddle/fluid/inference/capi/c_api.h @@ -0,0 +1,255 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// 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 +#include +#include + +#if defined(_WIN32) +#ifdef PADDLE_ON_INFERENCE +#define PADDLE_CAPI_EXPORT __declspec(dllexport) +#else +#define PADDLE_CAPI_EXPORT __declspec(dllimport) +#endif // PADDLE_ON_INFERENCE +#else +#define PADDLE_CAPI_EXPORT __attribute__((visibility("default"))) +#endif // _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +enum PD_DataType { PD_FLOAT32, PD_INT32, PD_INT64, PD_UINT8, PD_UNKDTYPE }; +typedef struct PD_PaddleBuf PD_PaddleBuf; +typedef struct PD_AnalysisConfig PD_AnalysisConfig; + +typedef struct PD_ZeroCopyData { + char* name = new char[50]; + void* data; + PD_DataType dtype; + int* shape; + int shape_size; +} PD_ZeroCopyData; +typedef struct InTensorShape { + char* name; + int* tensor_shape; + int shape_size; +} InTensorShape; + +PADDLE_CAPI_EXPORT extern PD_PaddleBuf* PD_NewPaddleBuf(); + +PADDLE_CAPI_EXPORT extern void PD_DeletePaddleBuf(PD_PaddleBuf* buf); + +PADDLE_CAPI_EXPORT extern void PD_PaddleBufResize(PD_PaddleBuf* buf, + size_t length); + +PADDLE_CAPI_EXPORT extern void PD_PaddleBufReset(PD_PaddleBuf* buf, void* data, + size_t length); + +PADDLE_CAPI_EXPORT extern bool PD_PaddleBufEmpty(PD_PaddleBuf* buf); + +PADDLE_CAPI_EXPORT extern void* PD_PaddleBufData(PD_PaddleBuf* buf); + +PADDLE_CAPI_EXPORT extern size_t PD_PaddleBufLength(PD_PaddleBuf* buf); + +// PaddleTensor +typedef struct PD_Tensor PD_Tensor; + +PADDLE_CAPI_EXPORT extern PD_Tensor* PD_NewPaddleTensor(); + +PADDLE_CAPI_EXPORT extern void PD_DeletePaddleTensor(PD_Tensor* tensor); + +PADDLE_CAPI_EXPORT extern void PD_SetPaddleTensorName(PD_Tensor* tensor, + char* name); + +PADDLE_CAPI_EXPORT extern void PD_SetPaddleTensorDType(PD_Tensor* tensor, + PD_DataType dtype); + +PADDLE_CAPI_EXPORT extern void PD_SetPaddleTensorData(PD_Tensor* tensor, + PD_PaddleBuf* buf); + +PADDLE_CAPI_EXPORT extern void PD_SetPaddleTensorShape(PD_Tensor* tensor, + int* shape, int size); + +PADDLE_CAPI_EXPORT extern const char* PD_GetPaddleTensorName( + const PD_Tensor* tensor); + +PADDLE_CAPI_EXPORT extern PD_DataType PD_GetPaddleTensorDType( + const PD_Tensor* tensor); + +PADDLE_CAPI_EXPORT extern PD_PaddleBuf* PD_GetPaddleTensorData( + const PD_Tensor* tensor); + +PADDLE_CAPI_EXPORT extern int* PD_GetPaddleTensorShape(const PD_Tensor* tensor, + int** size); + +// AnalysisPredictor +PADDLE_CAPI_EXPORT extern bool PD_PredictorRun(const PD_AnalysisConfig* config, + PD_Tensor* inputs, int in_size, + PD_Tensor* output_data, + int** out_size, int batch_size); + +PADDLE_CAPI_EXPORT extern bool PD_PredictorZeroCopyRun( + const PD_AnalysisConfig* config, PD_ZeroCopyData* inputs, int in_size, + PD_ZeroCopyData* output, int** out_size); + +// AnalysisConfig +enum Precision { kFloat32 = 0, kInt8, kHalf }; + +PADDLE_CAPI_EXPORT extern PD_AnalysisConfig* PD_NewAnalysisConfig(); + +PADDLE_CAPI_EXPORT extern void PD_DeleteAnalysisConfig( + PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SetModel(PD_AnalysisConfig* config, + const char* model_dir, + const char* params_path = NULL); + +PADDLE_CAPI_EXPORT +extern void PD_SetProgFile(PD_AnalysisConfig* config, const char* x); + +PADDLE_CAPI_EXPORT extern void PD_SetParamsFile(PD_AnalysisConfig* config, + const char* x); + +PADDLE_CAPI_EXPORT extern void PD_SetOptimCacheDir(PD_AnalysisConfig* config, + const char* opt_cache_dir); + +PADDLE_CAPI_EXPORT extern const char* PD_ModelDir( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern const char* PD_ProgFile( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern const char* PD_ParamsFile( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableUseGpu( + PD_AnalysisConfig* config, uint64_t memory_pool_init_size_mb, + int device_id = 0); + +PADDLE_CAPI_EXPORT extern void PD_DisableGpu(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_UseGpu(const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern int PD_GpuDeviceId(const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern int PD_MemoryPoolInitSizeMb( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern float PD_FractionOfGpuMemoryForPool( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableCUDNN(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_CudnnEnabled(const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SwitchIrOptim(PD_AnalysisConfig* config, + bool x = true); + +PADDLE_CAPI_EXPORT extern bool PD_IrOptim(const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SwitchUseFeedFetchOps( + PD_AnalysisConfig* config, bool x = true); + +PADDLE_CAPI_EXPORT extern bool PD_UseFeedFetchOpsEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SwitchSpecifyInputNames( + PD_AnalysisConfig* config, bool x = true); + +PADDLE_CAPI_EXPORT extern bool PD_SpecifyInputName( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableTensorRtEngine( + PD_AnalysisConfig* config, int workspace_size = 1 << 20, + int max_batch_size = 1, int min_subgraph_size = 3, + Precision precision = Precision::kFloat32, bool use_static = false, + bool use_calib_mode = false); + +PADDLE_CAPI_EXPORT extern bool PD_TensorrtEngineEnabled( + const PD_AnalysisConfig* config); + +typedef struct PD_MaxInputShape { + char* name; + int* shape; + int shape_size; +} PD_MaxInputShape; + +PADDLE_CAPI_EXPORT extern void PD_EnableAnakinEngine( + PD_AnalysisConfig* config, int max_batch_size = 1, + PD_MaxInputShape* max_input_shape = NULL, int max_input_shape_size = 0, + int min_subgraph_size = 6, Precision precision = Precision::kFloat32, + bool auto_config_layout = false, char** passes_filter = NULL, + int passes_filter_size = 0, char** ops_filter = NULL, + int ops_filter_size = 0); + +PADDLE_CAPI_EXPORT extern bool PD_AnakinEngineEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SwitchIrDebug(PD_AnalysisConfig* config, + bool x = true); + +PADDLE_CAPI_EXPORT extern void PD_EnableNgraph(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_NgraphEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableMKLDNN(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SetMkldnnCacheCapacity( + PD_AnalysisConfig* config, int capacity); + +PADDLE_CAPI_EXPORT extern bool PD_MkldnnEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SetCpuMathLibraryNumThreads( + PD_AnalysisConfig* config, int cpu_math_library_num_threads); + +PADDLE_CAPI_EXPORT extern int PD_CpuMathLibraryNumThreads( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableMkldnnQuantizer( + PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_MkldnnQuantizerEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SetModelBuffer(PD_AnalysisConfig* config, + const char* prog_buffer, + size_t prog_buffer_size, + const char* params_buffer, + size_t params_buffer_size); + +PADDLE_CAPI_EXPORT extern bool PD_ModelFromMemory( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableMemoryOptim(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_MemoryOptimEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_EnableProfile(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_ProfileEnabled( + const PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern void PD_SetInValid(PD_AnalysisConfig* config); + +PADDLE_CAPI_EXPORT extern bool PD_IsValid(const PD_AnalysisConfig* config); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/paddle/fluid/inference/capi/c_api_internal.h b/paddle/fluid/inference/capi/c_api_internal.h new file mode 100644 index 00000000000..1f8ec3ff728 --- /dev/null +++ b/paddle/fluid/inference/capi/c_api_internal.h @@ -0,0 +1,43 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// 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 +#include "paddle/fluid/inference/api/paddle_analysis_config.h" +#include "paddle/fluid/inference/api/paddle_api.h" +#include "paddle/fluid/platform/enforce.h" + +using PD_PaddleDType = paddle::PaddleDType; +using PD_ACPrecision = paddle::AnalysisConfig::Precision; + +struct PD_AnalysisConfig { + paddle::AnalysisConfig config; +}; + +struct PD_Tensor { + paddle::PaddleTensor tensor; +}; + +struct PD_PaddleBuf { + paddle::PaddleBuf buf; +}; + +namespace paddle { +paddle::PaddleDType ConvertToPaddleDType(PD_DataType dtype); + +PD_DataType ConvertToPDDataType(PD_PaddleDType dtype); + +PD_ACPrecision ConvertToACPrecision(Precision dtype); +} diff --git a/paddle/fluid/inference/capi/pd_config.cc b/paddle/fluid/inference/capi/pd_config.cc new file mode 100644 index 00000000000..22dfab2f248 --- /dev/null +++ b/paddle/fluid/inference/capi/pd_config.cc @@ -0,0 +1,296 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// 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 +#include +#include +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/capi/c_api_internal.h" + +using paddle::ConvertToPaddleDType; +using paddle::ConvertToPDDataType; +using paddle::ConvertToACPrecision; + +extern "C" { + +PD_AnalysisConfig* PD_NewAnalysisConfig() { return new PD_AnalysisConfig; } // + +void PD_DeleteAnalysisConfig(PD_AnalysisConfig* config) { + if (config) { + delete config; + config = nullptr; + } +} + +void PD_SetModel(PD_AnalysisConfig* config, const char* model_dir, + const char* params_path) { + LOG(INFO) << model_dir; + PADDLE_ENFORCE_NOT_NULL(config); + LOG(INFO) << std::string(model_dir); + if (!params_path) { + config->config.SetModel(std::string(model_dir)); + } else { + config->config.SetModel(std::string(model_dir), std::string(params_path)); + } +} + +void PD_SetProgFile(PD_AnalysisConfig* config, const char* x) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetProgFile(std::string(x)); +} + +void PD_SetParamsFile(PD_AnalysisConfig* config, const char* x) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetParamsFile(std::string(x)); +} + +void PD_SetOptimCacheDir(PD_AnalysisConfig* config, const char* opt_cache_dir) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetOptimCacheDir(std::string(opt_cache_dir)); +} + +const char* PD_ModelDir(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.model_dir().c_str(); +} + +const char* PD_ProgFile(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.prog_file().c_str(); +} + +const char* PD_ParamsFile(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.params_file().c_str(); +} + +void PD_EnableUseGpu(PD_AnalysisConfig* config, + uint64_t memory_pool_init_size_mb, int device_id) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableUseGpu(memory_pool_init_size_mb, device_id); +} + +void PD_DisableGpu(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.DisableGpu(); +} + +bool PD_UseGpu(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.use_gpu(); +} + +int PD_GpuDeviceId(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.gpu_device_id(); +} + +int PD_MemoryPoolInitSizeMb(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.memory_pool_init_size_mb(); +} + +float PD_FractionOfGpuMemoryForPool(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.fraction_of_gpu_memory_for_pool(); +} + +void PD_EnableCUDNN(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableCUDNN(); +} + +bool PD_CudnnEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.cudnn_enabled(); +} + +void PD_SwitchIrOptim(PD_AnalysisConfig* config, bool x) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SwitchIrOptim(x); +} + +bool PD_IrOptim(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.ir_optim(); +} + +void PD_SwitchUseFeedFetchOps(PD_AnalysisConfig* config, bool x) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SwitchUseFeedFetchOps(x); +} + +bool PD_UseFeedFetchOpsEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.use_feed_fetch_ops_enabled(); +} + +void PD_SwitchSpecifyInputNames(PD_AnalysisConfig* config, bool x) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SwitchSpecifyInputNames(x); +} + +bool PD_SpecifyInputName(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.specify_input_name(); +} + +void PD_EnableTensorRtEngine(PD_AnalysisConfig* config, int workspace_size, + int max_batch_size, int min_subgraph_size, + Precision precision, bool use_static, + bool use_calib_mode) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableTensorRtEngine( + workspace_size, max_batch_size, min_subgraph_size, + paddle::ConvertToACPrecision(precision), use_static, use_calib_mode); +} + +bool PD_TensorrtEngineEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.tensorrt_engine_enabled(); +} + +void PD_EnableAnakinEngine(PD_AnalysisConfig* config, int max_batch_size, + PD_MaxInputShape* max_input_shape, + int max_input_shape_size, int min_subgraph_size, + Precision precision, bool auto_config_layout, + char** passes_filter, int passes_filter_size, + char** ops_filter, int ops_filter_size) { + PADDLE_ENFORCE_NOT_NULL(config); + std::map> mis; + if (max_input_shape) { + for (int i = 0; i < max_input_shape_size; ++i) { + std::vector tmp_shape; + tmp_shape.assign( + max_input_shape[i].shape, + max_input_shape[i].shape + max_input_shape[i].shape_size); + mis[std::string(max_input_shape[i].name)] = std::move(tmp_shape); + } + } + std::vector pf; + std::vector of; + if (passes_filter) { + pf.assign(passes_filter, passes_filter + passes_filter_size); + } + if (ops_filter) { + of.assign(ops_filter, ops_filter + ops_filter_size); + } + + config->config.EnableAnakinEngine(max_batch_size, mis, min_subgraph_size, + paddle::ConvertToACPrecision(precision), + auto_config_layout, pf, of); +} + +bool PD_AnakinEngineEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.anakin_engine_enabled(); +} + +void PD_SwitchIrDebug(PD_AnalysisConfig* config, bool x) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SwitchIrDebug(x); +} + +void PD_EnableNgraph(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableNgraph(); +} + +bool PD_NgraphEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.ngraph_enabled(); +} + +void PD_EnableMKLDNN(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableMKLDNN(); +} + +void PD_SetMkldnnCacheCapacity(PD_AnalysisConfig* config, int capacity) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetMkldnnCacheCapacity(capacity); +} + +bool PD_MkldnnEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.mkldnn_enabled(); +} + +void PD_SetCpuMathLibraryNumThreads(PD_AnalysisConfig* config, + int cpu_math_library_num_threads) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetCpuMathLibraryNumThreads(cpu_math_library_num_threads); +} + +int PD_CpuMathLibraryNumThreads(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.cpu_math_library_num_threads(); +} + +void PD_EnableMkldnnQuantizer(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableMkldnnQuantizer(); +} + +bool PD_MkldnnQuantizerEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.mkldnn_quantizer_enabled(); +} + +void PD_SetModelBuffer(PD_AnalysisConfig* config, const char* prog_buffer, + size_t prog_buffer_size, const char* params_buffer, + size_t params_buffer_size) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetModelBuffer(prog_buffer, prog_buffer_size, params_buffer, + params_buffer_size); +} + +bool PD_ModelFromMemory(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.model_from_memory(); +} + +void PD_EnableMemoryOptim(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableMemoryOptim(); +} + +bool PD_MemoryOptimEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.enable_memory_optim(); +} + +void PD_EnableProfile(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.EnableProfile(); +} + +bool PD_ProfileEnabled(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.profile_enabled(); +} + +void PD_SetInValid(PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + config->config.SetInValid(); +} + +bool PD_IsValid(const PD_AnalysisConfig* config) { + PADDLE_ENFORCE_NOT_NULL(config); + return config->config.is_valid(); +} +} // extern "C" diff --git a/paddle/fluid/inference/capi/pd_predictor.cc b/paddle/fluid/inference/capi/pd_predictor.cc new file mode 100644 index 00000000000..52b249f3bb2 --- /dev/null +++ b/paddle/fluid/inference/capi/pd_predictor.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// 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 +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/capi/c_api_internal.h" + +using paddle::ConvertToPaddleDType; +using paddle::ConvertToPDDataType; +using paddle::ConvertToACPrecision; + +extern "C" { + +bool PD_PredictorRun(const PD_AnalysisConfig* config, PD_Tensor* inputs, + int in_size, PD_Tensor* output_data, int** out_size, + int batch_size) { + auto predictor = paddle::CreatePaddlePredictor(config->config); + std::vector in; + for (int i = 0; i < in_size; ++i) { + in.emplace_back(inputs->tensor); + } + std::vector out; + if (predictor->Run(in, &out, batch_size)) { + int osize = out.size(); + for (int i = 0; i < osize; ++i) { + output_data[i].tensor = out[i]; + } + *out_size = &osize; + return true; + } + return false; +} + +bool PD_PredictorZeroCopyRun(const PD_AnalysisConfig* config, + PD_ZeroCopyData* inputs, int in_size, + PD_ZeroCopyData* output, int** out_size) { + auto predictor = paddle::CreatePaddlePredictor(config->config); + auto input_names = predictor->GetInputNames(); + PADDLE_ENFORCE_EQ( + input_names.size(), in_size, + "The number of input and the number of model's input must match. "); + for (int i = 0; i < in_size; ++i) { + auto input_t = predictor->GetInputTensor(inputs[i].name); + std::vector tensor_shape; + tensor_shape.assign(inputs[i].shape, + inputs[i].shape + inputs[i].shape_size); + input_t->Reshape(tensor_shape); + switch (inputs[i].dtype) { + case PD_FLOAT32: + input_t->copy_from_cpu(static_cast(inputs[i].data)); + break; + case PD_INT32: + input_t->copy_from_cpu(static_cast(inputs[i].data)); + break; + case PD_INT64: + input_t->copy_from_cpu(static_cast(inputs[i].data)); + break; + case PD_UINT8: + input_t->copy_from_cpu(static_cast(inputs[i].data)); + break; + default: + CHECK(false) << "Unsupport data type."; + break; + } + } + CHECK(predictor->ZeroCopyRun()); + auto output_names = predictor->GetOutputNames(); + int osize = output_names.size(); + *out_size = &osize; + output = new PD_ZeroCopyData[osize]; + for (int i = 0; i < osize; ++i) { + LOG(INFO) << 1; + output[i].name = new char[output_names[i].length() + 1]; + snprintf(output[i].name, output_names[i].length() + 1, "%s", + output_names[i].c_str()); + auto output_t = predictor->GetOutputTensor(output_names[i]); + output[i].dtype = ConvertToPDDataType(output_t->type()); + std::vector output_shape = output_t->shape(); + output[i].shape = new int[output_shape.size()]; + output[i].shape = output_shape.data(); + output[i].shape_size = output_shape.size(); + switch (output[i].dtype) { + case PD_FLOAT32: { + std::vector out_data; + int out_num = std::accumulate(output_shape.begin(), output_shape.end(), + 1, std::multiplies()); + out_data.resize(out_num); + output_t->copy_to_cpu(out_data.data()); + output[i].data = static_cast(out_data.data()); + } break; + case PD_INT32: { + std::vector out_data; + int out_num = std::accumulate(output_shape.begin(), output_shape.end(), + 1, std::multiplies()); + out_data.resize(out_num); + output_t->copy_to_cpu(out_data.data()); + output[i].data = static_cast(out_data.data()); + } break; + case PD_INT64: { + std::vector out_data; + int out_num = std::accumulate(output_shape.begin(), output_shape.end(), + 1, std::multiplies()); + out_data.resize(out_num); + output_t->copy_to_cpu(out_data.data()); + output[i].data = static_cast(out_data.data()); + } break; + case PD_UINT8: { + std::vector out_data; + int out_num = std::accumulate(output_shape.begin(), output_shape.end(), + 1, std::multiplies()); + out_data.resize(out_num); + output_t->copy_to_cpu(out_data.data()); + output[i].data = static_cast(out_data.data()); + } break; + default: + CHECK(false) << "Unsupport data type."; + break; + } + } + return true; +} +} // extern "C" diff --git a/paddle/fluid/inference/capi/pd_tensor.cc b/paddle/fluid/inference/capi/pd_tensor.cc new file mode 100644 index 00000000000..9f1b6436fcc --- /dev/null +++ b/paddle/fluid/inference/capi/pd_tensor.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// 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 +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/capi/c_api_internal.h" + +using paddle::ConvertToPaddleDType; +using paddle::ConvertToPDDataType; +using paddle::ConvertToACPrecision; + +extern "C" { +// PaddleTensor +PD_Tensor* PD_NewPaddleTensor() { return new PD_Tensor; } + +void PD_DeletePaddleTensor(PD_Tensor* tensor) { + if (tensor) { + delete tensor; + tensor = nullptr; + } +} + +void PD_SetPaddleTensorName(PD_Tensor* tensor, char* name) { + tensor->tensor.name = std::string(name); +} + +void PD_SetPaddleTensorDType(PD_Tensor* tensor, PD_DataType dtype) { + tensor->tensor.dtype = paddle::ConvertToPaddleDType(dtype); +} + +void PD_SetPaddleTensorData(PD_Tensor* tensor, PD_PaddleBuf* buf) { + tensor->tensor.data = buf->buf; +} + +void PD_SetPaddleTensorShape(PD_Tensor* tensor, int* shape, int size) { + tensor->tensor.shape.assign(shape, shape + size); +} + +const char* PD_GetPaddleTensorName(const PD_Tensor* tensor) { + return tensor->tensor.name.c_str(); +} + +PD_DataType PD_GetPaddleTensorDType(const PD_Tensor* tensor) { + return ConvertToPDDataType(tensor->tensor.dtype); +} + +PD_PaddleBuf* PD_GetPaddleTensorData(const PD_Tensor* tensor) { + PD_PaddleBuf* ret = PD_NewPaddleBuf(); + ret->buf = tensor->tensor.data; + return ret; +} + +int* PD_GetPaddleTensorShape(const PD_Tensor* tensor, int** size) { + std::vector shape = tensor->tensor.shape; + int s = shape.size(); + *size = &s; + return shape.data(); +} + +} // extern "C" diff --git a/paddle/fluid/inference/tests/api/CMakeLists.txt b/paddle/fluid/inference/tests/api/CMakeLists.txt index e064d01bc76..e7f6e22aad2 100644 --- a/paddle/fluid/inference/tests/api/CMakeLists.txt +++ b/paddle/fluid/inference/tests/api/CMakeLists.txt @@ -283,4 +283,29 @@ if(WITH_GPU AND TENSORRT_FOUND) inference_analysis_test(trt_cascade_rcnn_test SRCS trt_cascade_rcnn_test.cc EXTRA_DEPS ${INFERENCE_EXTRA_DEPS} ARGS --infer_model=${TRT_MODEL_INSTALL_DIR}/trt_inference_test_models) + inference_analysis_test(test_analyzer_capi_gpu SRCS analyzer_capi_gpu_tester.cc + EXTRA_DEPS ${INFERENCE_EXTRA_DEPS} paddle_fluid_c + ARGS --infer_model=${TRT_MODEL_INSTALL_DIR}/trt_inference_test_models) +endif() + +set(CAPI_MODEL_INSTALL_DIR "${INFERENCE_DEMO_INSTALL_DIR}/capi_tests_models") +if (NOT EXISTS ${CAPI_MODEL_INSTALL_DIR}) + inference_download_and_uncompress(${CAPI_MODEL_INSTALL_DIR} ${INFERENCE_URL}/tensorrt_test "trt_inference_test_models.tar.gz") endif() +inference_analysis_test(test_analyzer_capi SRCS analyzer_capi_tester.cc + EXTRA_DEPS ${INFERENCE_EXTRA_DEPS} paddle_fluid_c + ARGS --infer_model=${CAPI_MODEL_INSTALL_DIR}/trt_inference_test_models) + +set(CAPI_MODEL_INSTALL_PD_DIR "${INFERENCE_DEMO_INSTALL_DIR}/capi_mobilenet") +if (NOT EXISTS ${CAPI_MODEL_INSTALL_PD_DIR}) + inference_download_and_uncompress(${CAPI_MODEL_INSTALL_PD_DIR} "http://paddlemodels.bj.bcebos.com/" "inference-vis-demos%2Fmobilenet.tar.gz") +endif() +inference_analysis_test(test_analyzer_capi_pd_tensor SRCS analyzer_capi_pd_tensor_tester.cc + EXTRA_DEPS ${INFERENCE_EXTRA_DEPS} paddle_fluid_c + ARGS --infer_model=${CAPI_MODEL_INSTALL_PD_DIR}/model) + +if(WITH_MKLDNN) + inference_analysis_test(test_analyzer_capi_int SRCS analyzer_capi_int_tester.cc + EXTRA_DEPS ${INFERENCE_EXTRA_DEPS} paddle_fluid_c + ARGS --infer_model=${INT8_DATA_DIR}/resnet50/model) + endif() diff --git a/paddle/fluid/inference/tests/api/analyzer_capi_gpu_tester.cc b/paddle/fluid/inference/tests/api/analyzer_capi_gpu_tester.cc new file mode 100644 index 00000000000..89c739fb951 --- /dev/null +++ b/paddle/fluid/inference/tests/api/analyzer_capi_gpu_tester.cc @@ -0,0 +1,100 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +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 +#include +#include +#include +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/tests/api/tester_helper.h" + +namespace paddle { +namespace inference { +namespace analysis { + +TEST(PD_AnalysisConfig, use_gpu) { + std::string model_dir = FLAGS_infer_model + "/mobilenet"; + PD_AnalysisConfig *config = PD_NewAnalysisConfig(); + + PD_DisableGpu(config); + PD_SetCpuMathLibraryNumThreads(config, 10); + int num_thread = PD_CpuMathLibraryNumThreads(config); + CHECK(10 == num_thread) << "NO"; + PD_SwitchUseFeedFetchOps(config, false); + PD_SwitchSpecifyInputNames(config, true); + PD_SwitchIrDebug(config, true); + PD_SetModel(config, model_dir.c_str()); + PD_SetOptimCacheDir(config, (FLAGS_infer_model + "/OptimCacheDir").c_str()); + const char *model_dir_ = PD_ModelDir(config); + LOG(INFO) << model_dir_; + PD_EnableUseGpu(config, 100, 0); + bool use_gpu = PD_UseGpu(config); + CHECK(use_gpu) << "NO"; + int device = PD_GpuDeviceId(config); + CHECK(0 == device) << "NO"; + int init_size = PD_MemoryPoolInitSizeMb(config); + CHECK(100 == init_size) << "NO"; + float frac = PD_FractionOfGpuMemoryForPool(config); + LOG(INFO) << frac; + PD_EnableCUDNN(config); + bool cudnn = PD_CudnnEnabled(config); + CHECK(cudnn) << "NO"; + PD_SwitchIrOptim(config, true); + bool ir_optim = PD_IrOptim(config); + CHECK(ir_optim) << "NO"; + PD_EnableTensorRtEngine(config); + bool trt_enable = PD_TensorrtEngineEnabled(config); + CHECK(trt_enable) << "NO"; + PD_EnableNgraph(config); + bool ngraph_enable = PD_NgraphEnabled(config); + LOG(INFO) << ngraph_enable << " Ngraph"; + PD_EnableMemoryOptim(config); + bool memory_optim_enable = PD_MemoryOptimEnabled(config); + CHECK(memory_optim_enable) << "NO"; + PD_EnableProfile(config); + bool profiler_enable = PD_ProfileEnabled(config); + CHECK(profiler_enable) << "NO"; + PD_SetInValid(config); + bool is_valid = PD_IsValid(config); + CHECK(!is_valid) << "NO"; + PD_DeleteAnalysisConfig(config); +} + +TEST(PD_AnalysisConfig, trt_int8) { + std::string model_dir = FLAGS_infer_model + "/mobilenet"; + PD_AnalysisConfig *config = PD_NewAnalysisConfig(); + PD_EnableUseGpu(config, 100, 0); + PD_EnableTensorRtEngine(config, 1 << 20, 1, 3, Precision::kInt8, false, true); + bool trt_enable = PD_TensorrtEngineEnabled(config); + CHECK(trt_enable) << "NO"; + PD_DeleteAnalysisConfig(config); +} + +TEST(PD_AnalysisConfig, trt_fp16) { + std::string model_dir = FLAGS_infer_model + "/mobilenet"; + PD_AnalysisConfig *config = PD_NewAnalysisConfig(); + PD_EnableUseGpu(config, 100, 0); + PD_EnableTensorRtEngine(config, 1 << 20, 1, 3, Precision::kHalf, false, + false); + bool trt_enable = PD_TensorrtEngineEnabled(config); + CHECK(trt_enable) << "NO"; + PD_DeleteAnalysisConfig(config); +} + +} // namespace analysis +} // namespace inference +} // namespace paddle diff --git a/paddle/fluid/inference/tests/api/analyzer_capi_int_tester.cc b/paddle/fluid/inference/tests/api/analyzer_capi_int_tester.cc new file mode 100644 index 00000000000..3c62984c0e3 --- /dev/null +++ b/paddle/fluid/inference/tests/api/analyzer_capi_int_tester.cc @@ -0,0 +1,106 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +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 +#include +#include +#include +#include +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/tests/api/tester_helper.h" + +namespace paddle { +namespace inference { +namespace analysis { + +template +void zero_copy_run() { + std::string model_dir = FLAGS_infer_model; + PD_AnalysisConfig *config = PD_NewAnalysisConfig(); + PD_DisableGpu(config); + PD_SetCpuMathLibraryNumThreads(config, 10); + PD_SwitchUseFeedFetchOps(config, false); + PD_SwitchSpecifyInputNames(config, true); + PD_SwitchIrDebug(config, true); + PD_SetModel(config, model_dir.c_str()); //, params_file1.c_str()); + bool use_feed_fetch = PD_UseFeedFetchOpsEnabled(config); + CHECK(!use_feed_fetch) << "NO"; + bool specify_input_names = PD_SpecifyInputName(config); + CHECK(specify_input_names) << "NO"; + + const int batch_size = 1; + const int channels = 3; + const int height = 224; + const int width = 224; + T input[batch_size * channels * height * width] = {0}; + int shape[4] = {batch_size, channels, height, width}; + int shape_size = 4; + int in_size = 2; + int *out_size; + PD_ZeroCopyData *inputs = new PD_ZeroCopyData[2]; + PD_ZeroCopyData *outputs = new PD_ZeroCopyData; + inputs[0].data = static_cast(input); + std::string nm = typeid(T).name(); + if ("f" == nm) { + inputs[0].dtype = PD_FLOAT32; + } else if ("i" == nm) { + inputs[0].dtype = PD_INT32; + } else if ("x" == nm) { + inputs[0].dtype = PD_INT64; + } else if ("h" == nm) { + inputs[0].dtype = PD_UINT8; + } else { + CHECK(false) << "Unsupport dtype. "; + } + inputs[0].name = new char[6]; + inputs[0].name[0] = 'i'; + inputs[0].name[1] = 'm'; + inputs[0].name[2] = 'a'; + inputs[0].name[3] = 'g'; + inputs[0].name[4] = 'e'; + inputs[0].name[5] = '\0'; + inputs[0].shape = shape; + inputs[0].shape_size = shape_size; + + int *label = new int[1]; + label[0] = 0; + inputs[1].data = static_cast(label); + inputs[1].dtype = PD_INT64; + inputs[1].name = new char[6]; + inputs[1].name[0] = 'l'; + inputs[1].name[1] = 'a'; + inputs[1].name[2] = 'b'; + inputs[1].name[3] = 'e'; + inputs[1].name[4] = 'l'; + inputs[1].name[5] = '\0'; + int label_shape[2] = {1, 1}; + int label_shape_size = 2; + inputs[1].shape = label_shape; + inputs[1].shape_size = label_shape_size; + + PD_PredictorZeroCopyRun(config, inputs, in_size, outputs, &out_size); +} + +TEST(PD_ZeroCopyRun, zero_copy_run) { + // zero_copy_run(); + // zero_copy_run(); + zero_copy_run(); +} + +} // namespace analysis +} // namespace inference +} // namespace paddle diff --git a/paddle/fluid/inference/tests/api/analyzer_capi_pd_tensor_tester.cc b/paddle/fluid/inference/tests/api/analyzer_capi_pd_tensor_tester.cc new file mode 100644 index 00000000000..a94e0b8ebd4 --- /dev/null +++ b/paddle/fluid/inference/tests/api/analyzer_capi_pd_tensor_tester.cc @@ -0,0 +1,153 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +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 +#include +#include +#include +#include +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/tests/api/tester_helper.h" + +namespace paddle { +namespace inference { +namespace analysis { + +void PD_run() { + PD_AnalysisConfig* config = PD_NewAnalysisConfig(); + std::string prog_file = FLAGS_infer_model + "/__model__"; + std::string params_file = FLAGS_infer_model + "/__params__"; + PD_SetModel(config, prog_file.c_str(), params_file.c_str()); + PD_SetProgFile(config, prog_file.c_str()); + PD_SetParamsFile(config, params_file.c_str()); + LOG(INFO) << PD_ProgFile(config); + LOG(INFO) << PD_ParamsFile(config); + PD_Tensor* input = PD_NewPaddleTensor(); + PD_PaddleBuf* buf = PD_NewPaddleBuf(); + LOG(INFO) << "PaddleBuf empty: " << PD_PaddleBufEmpty(buf); + int batch = 1; + int channel = 3; + int height = 300; + int width = 300; + int shape[4] = {batch, channel, height, width}; + int shape_size = 4; + float* data = new float[batch * channel * height * width]; + PD_PaddleBufReset(buf, static_cast(data), + sizeof(float) * (batch * channel * height * width)); + + char name[6] = {'i', 'm', 'a', 'g', 'e', '\0'}; + PD_SetPaddleTensorName(input, name); + PD_SetPaddleTensorDType(input, PD_FLOAT32); + PD_SetPaddleTensorShape(input, shape, shape_size); + PD_SetPaddleTensorData(input, buf); + + PD_Tensor* out_data = PD_NewPaddleTensor(); + int* out_size; + PD_PredictorRun(config, input, 1, out_data, &out_size, 1); + LOG(INFO) << *out_size; + LOG(INFO) << PD_GetPaddleTensorName(out_data); + LOG(INFO) << PD_GetPaddleTensorDType(out_data); + PD_PaddleBuf* b = PD_GetPaddleTensorData(out_data); + LOG(INFO) << PD_PaddleBufLength(b); + float* result = static_cast(PD_PaddleBufData(b)); + LOG(INFO) << *result; + PD_PaddleBufResize(b, 500); + PD_DeletePaddleTensor(input); + int* size; + PD_GetPaddleTensorShape(out_data, &size); + PD_DeletePaddleBuf(buf); +} + +TEST(PD_Tensor, PD_run) { PD_run(); } + +TEST(PD_Tensor, int32) { + PD_Tensor* input = PD_NewPaddleTensor(); + PD_SetPaddleTensorDType(input, PD_INT32); + LOG(INFO) << PD_GetPaddleTensorDType(input); +} + +TEST(PD_Tensor, int64) { + PD_Tensor* input = PD_NewPaddleTensor(); + PD_SetPaddleTensorDType(input, PD_INT64); + LOG(INFO) << PD_GetPaddleTensorDType(input); +} + +TEST(PD_Tensor, int8) { + PD_Tensor* input = PD_NewPaddleTensor(); + PD_SetPaddleTensorDType(input, PD_UINT8); + LOG(INFO) << PD_GetPaddleTensorDType(input); +} + +std::string read_file(std::string filename) { + std::ifstream file(filename); + return std::string((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); +} + +void buffer_run() { + PD_AnalysisConfig* config = PD_NewAnalysisConfig(); + std::string prog_file = FLAGS_infer_model + "/__model__"; + std::string params_file = FLAGS_infer_model + "/__params__"; + + std::string prog_str = read_file(prog_file); + std::string params_str = read_file(params_file); + + PD_SetModelBuffer(config, prog_str.c_str(), prog_str.size(), + params_str.c_str(), params_str.size()); + LOG(INFO) << PD_ProgFile(config); + LOG(INFO) << PD_ParamsFile(config); + CHECK(PD_ModelFromMemory(config)) << "NO"; + + PD_Tensor* input = PD_NewPaddleTensor(); + PD_PaddleBuf* buf = PD_NewPaddleBuf(); + LOG(INFO) << "PaddleBuf empty: " << PD_PaddleBufEmpty(buf); + int batch = 1; + int channel = 3; + int height = 300; + int width = 300; + int shape[4] = {batch, channel, height, width}; + int shape_size = 4; + float* data = new float[batch * channel * height * width]; + PD_PaddleBufReset(buf, static_cast(data), + sizeof(float) * (batch * channel * height * width)); + + char name[6] = {'i', 'm', 'a', 'g', 'e', '\0'}; + PD_SetPaddleTensorName(input, name); + PD_SetPaddleTensorDType(input, PD_FLOAT32); + PD_SetPaddleTensorShape(input, shape, shape_size); + PD_SetPaddleTensorData(input, buf); + + PD_Tensor* out_data = PD_NewPaddleTensor(); + int* out_size; + PD_PredictorRun(config, input, 1, out_data, &out_size, 1); + LOG(INFO) << *out_size; + LOG(INFO) << PD_GetPaddleTensorName(out_data); + LOG(INFO) << PD_GetPaddleTensorDType(out_data); + PD_PaddleBuf* b = PD_GetPaddleTensorData(out_data); + LOG(INFO) << PD_PaddleBufLength(b); + float* result = static_cast(PD_PaddleBufData(b)); + LOG(INFO) << *result; + PD_PaddleBufResize(b, 500); + PD_DeletePaddleTensor(input); + PD_DeletePaddleBuf(buf); +} + +TEST(SetModelBuffer, read) { buffer_run(); } + +} // namespace analysis +} // namespace inference +} // namespace paddle diff --git a/paddle/fluid/inference/tests/api/analyzer_capi_tester.cc b/paddle/fluid/inference/tests/api/analyzer_capi_tester.cc new file mode 100644 index 00000000000..e491ae70095 --- /dev/null +++ b/paddle/fluid/inference/tests/api/analyzer_capi_tester.cc @@ -0,0 +1,108 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +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 +#include +#include +#include +#include +#include +#include "paddle/fluid/inference/capi/c_api.h" +#include "paddle/fluid/inference/tests/api/tester_helper.h" + +namespace paddle { +namespace inference { +namespace analysis { + +template +void zero_copy_run() { + std::string model_dir = FLAGS_infer_model + "/mobilenet"; + PD_AnalysisConfig *config = PD_NewAnalysisConfig(); + PD_DisableGpu(config); + PD_SetCpuMathLibraryNumThreads(config, 10); + PD_SwitchUseFeedFetchOps(config, false); + PD_SwitchSpecifyInputNames(config, true); + PD_SwitchIrDebug(config, true); + PD_SetModel(config, model_dir.c_str()); //, params_file1.c_str()); + bool use_feed_fetch = PD_UseFeedFetchOpsEnabled(config); + CHECK(!use_feed_fetch) << "NO"; + bool specify_input_names = PD_SpecifyInputName(config); + CHECK(specify_input_names) << "NO"; + + const int batch_size = 1; + const int channels = 3; + const int height = 224; + const int width = 224; + T input[batch_size * channels * height * width] = {0}; + + int shape[4] = {batch_size, channels, height, width}; + int shape_size = 4; + int in_size = 1; + int *out_size; + PD_ZeroCopyData *inputs = new PD_ZeroCopyData; + PD_ZeroCopyData *outputs = new PD_ZeroCopyData; + inputs->data = static_cast(input); + std::string nm = typeid(T).name(); + if ("f" == nm) { + inputs->dtype = PD_FLOAT32; + } else if ("i" == nm) { + inputs->dtype = PD_INT32; + } else if ("x" == nm) { + inputs->dtype = PD_INT64; + } else if ("h" == nm) { + inputs->dtype = PD_UINT8; + } else { + CHECK(false) << "Unsupport dtype. "; + } + inputs->name = new char[2]; + inputs->name[0] = 'x'; + inputs->name[1] = '\0'; + LOG(INFO) << inputs->name; + inputs->shape = shape; + inputs->shape_size = shape_size; + + PD_PredictorZeroCopyRun(config, inputs, in_size, outputs, &out_size); +} + +TEST(PD_ZeroCopyRun, zero_copy_run) { zero_copy_run(); } + +#ifdef PADDLE_WITH_MKLDNN +TEST(PD_AnalysisConfig, profile_mkldnn) { + std::string model_dir = FLAGS_infer_model + "/mobilenet"; + PD_AnalysisConfig *config = PD_NewAnalysisConfig(); + PD_DisableGpu(config); + PD_SetCpuMathLibraryNumThreads(config, 10); + PD_SwitchUseFeedFetchOps(config, false); + PD_SwitchSpecifyInputNames(config, true); + PD_SwitchIrDebug(config, true); + PD_EnableMKLDNN(config); + bool mkldnn_enable = PD_MkldnnEnabled(config); + CHECK(mkldnn_enable) << "NO"; + PD_EnableMkldnnQuantizer(config); + bool quantizer_enable = PD_MkldnnQuantizerEnabled(config); + CHECK(quantizer_enable) << "NO"; + PD_SetMkldnnCacheCapacity(config, 0); + PD_SetModel(config, model_dir.c_str()); + PD_EnableAnakinEngine(config); + bool anakin_enable = PD_AnakinEngineEnabled(config); + LOG(INFO) << anakin_enable; + PD_DeleteAnalysisConfig(config); +} +#endif + +} // namespace analysis +} // namespace inference +} // namespace paddle -- GitLab