提交 1bb982eb 编写于 作者: W wangguibao

Codestyle check

Change-Id: Iff5fdd63bb96832212d31bfa114f663f1190c678
上级 3f2c56e7
...@@ -70,7 +70,8 @@ include(generic) ...@@ -70,7 +70,8 @@ include(generic)
include(paddlepaddle) include(paddlepaddle)
include(external/opencv) include(external/opencv)
include_directories("${PADDLE_SERVING_SOURCE_DIR}") include_directories(${PADDLE_SERVING_SOURCE_DIR})
include_directories(${PADDLE_SERVING_BINARY_DIR})
set(EXTERNAL_LIBS set(EXTERNAL_LIBS
gflags gflags
...@@ -94,6 +95,3 @@ add_subdirectory(predictor) ...@@ -94,6 +95,3 @@ add_subdirectory(predictor)
add_subdirectory(inferencer-fluid-cpu) add_subdirectory(inferencer-fluid-cpu)
add_subdirectory(serving) add_subdirectory(serving)
add_subdirectory(sdk-cpp) add_subdirectory(sdk-cpp)
...@@ -336,4 +336,3 @@ Paddle serving框架为策略工程师提供以下三层面的功能性扩展: ...@@ -336,4 +336,3 @@ Paddle serving框架为策略工程师提供以下三层面的功能性扩展:
{:name => 'main', :conf => 'predictor_valid.conf', :target => 'port'}, // valid工具向这个端口发送测试请求,确保服务已正常启动 {:name => 'main', :conf => 'predictor_valid.conf', :target => 'port'}, // valid工具向这个端口发送测试请求,确保服务已正常启动
] ]
``` ```
...@@ -11,6 +11,9 @@ list(APPEND configure_srcs ${CMAKE_CURRENT_LIST_DIR}/src/configure_parser.cpp) ...@@ -11,6 +11,9 @@ list(APPEND configure_srcs ${CMAKE_CURRENT_LIST_DIR}/src/configure_parser.cpp)
add_library(configure ${configure_srcs}) add_library(configure ${configure_srcs})
add_dependencies(configure brpc) add_dependencies(configure brpc)
target_include_directories(configure PUBLIC
${CMAKE_CURRENT_LIST_DIR}/
)
add_executable(test_configure add_executable(test_configure
${CMAKE_CURRENT_LIST_DIR}/tests/test_configure.cpp) ${CMAKE_CURRENT_LIST_DIR}/tests/test_configure.cpp)
...@@ -23,4 +26,3 @@ target_link_libraries(test_configure configure protobuf) ...@@ -23,4 +26,3 @@ target_link_libraries(test_configure configure protobuf)
install(TARGETS configure install(TARGETS configure
ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib
) )
// 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 #pragma once
#include <google/protobuf/message.h> #include <google/protobuf/message.h>
#include <string>
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -12,6 +27,6 @@ int write_proto_conf(google::protobuf::Message *message, ...@@ -12,6 +27,6 @@ int write_proto_conf(google::protobuf::Message *message,
const std::string &output_path, const std::string &output_path,
const std::string &output_file); const std::string &output_file);
} // configure } // namespace configure
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
syntax="proto2"; // 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.
syntax = "proto2";
package baidu.paddle_serving.configure; package baidu.paddle_serving.configure;
message SigmoidConf { message SigmoidConf {
...@@ -8,4 +22,3 @@ message SigmoidConf { ...@@ -8,4 +22,3 @@ message SigmoidConf {
required float exp_max_input = 4; required float exp_max_input = 4;
required float exp_min_input = 5; required float exp_min_input = 5;
}; };
syntax="proto2"; // 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.
syntax = "proto2";
package baidu.paddle_serving.configure; package baidu.paddle_serving.configure;
message ConnectionConf { message ConnectionConf {
...@@ -25,7 +39,7 @@ message RpcParameter { ...@@ -25,7 +39,7 @@ message RpcParameter {
required uint32 max_channel_per_request = 4; required uint32 max_channel_per_request = 4;
}; };
message SplitConf{ message SplitConf {
optional string split_tag_name = 1; optional string split_tag_name = 1;
optional string tag_candidates = 2; optional string tag_candidates = 2;
}; };
...@@ -39,9 +53,7 @@ message VariantConf { ...@@ -39,9 +53,7 @@ message VariantConf {
optional string variant_router = 6; optional string variant_router = 6;
}; };
message WeightedRandomRenderConf { message WeightedRandomRenderConf { required string variant_weight_list = 1; };
required string variant_weight_list = 1;
};
message Predictor { message Predictor {
required string name = 1; required string name = 1;
...@@ -56,4 +68,3 @@ message SDKConf { ...@@ -56,4 +68,3 @@ message SDKConf {
required VariantConf default_variant_conf = 1; required VariantConf default_variant_conf = 1;
repeated Predictor predictors = 2; repeated Predictor predictors = 2;
}; };
syntax="proto2"; // 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.
syntax = "proto2";
package baidu.paddle_serving.configure; package baidu.paddle_serving.configure;
message EngineDesc { message EngineDesc {
...@@ -15,9 +29,7 @@ message EngineDesc { ...@@ -15,9 +29,7 @@ message EngineDesc {
}; };
// model_toolkit conf // model_toolkit conf
message ModelToolkitConf { message ModelToolkitConf { repeated EngineDesc engines = 1; };
repeated EngineDesc engines = 1;
};
// reource conf // reource conf
message ResourceConf { message ResourceConf {
...@@ -46,10 +58,7 @@ message Workflow { ...@@ -46,10 +58,7 @@ message Workflow {
}; };
// Workflow conf // Workflow conf
message WorkflowConf { message WorkflowConf { repeated Workflow workflows = 1; }
repeated Workflow workflows = 1;
}
// request_field_key: specifies use which request field as mapping key (see // request_field_key: specifies use which request field as mapping key (see
// request_field_key in InferService below) // request_field_key in InferService below)
...@@ -68,7 +77,7 @@ message InferService { ...@@ -68,7 +77,7 @@ message InferService {
required string name = 1; required string name = 1;
optional string merger = 2; optional string merger = 2;
optional bool enable_map_request_to_workflow = 3 [default = false]; optional bool enable_map_request_to_workflow = 3 [ default = false ];
// If enable_map_request_to_workfow = true // If enable_map_request_to_workfow = true
// //
......
#include <sys/types.h> // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#include <sys/stat.h> //
// 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/configure_parser.h"
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fstream> #include <fstream>
#include "butil/logging.h" #include "butil/logging.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/io/zero_copy_stream_impl.h"
#include <google/protobuf/io/zero_copy_stream_impl.h> #include "google/protobuf/text_format.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -13,8 +28,7 @@ namespace configure { ...@@ -13,8 +28,7 @@ namespace configure {
int read_proto_conf(const std::string &conf_path, int read_proto_conf(const std::string &conf_path,
const std::string &conf_file, const std::string &conf_file,
google::protobuf::Message *conf) google::protobuf::Message *conf) {
{
std::string file_str = conf_path + "/" + conf_file; std::string file_str = conf_path + "/" + conf_file;
int fd = open(file_str.c_str(), O_RDONLY); int fd = open(file_str.c_str(), O_RDONLY);
if (fd == -1) { if (fd == -1) {
...@@ -34,8 +48,7 @@ int read_proto_conf(const std::string &conf_path, ...@@ -34,8 +48,7 @@ int read_proto_conf(const std::string &conf_path,
int write_proto_conf(google::protobuf::Message *message, int write_proto_conf(google::protobuf::Message *message,
const std::string &output_path, const std::string &output_path,
const std::string &output_file) const std::string &output_file) {
{
std::string binary_str; std::string binary_str;
google::protobuf::TextFormat::PrintToString(*message, &binary_str); google::protobuf::TextFormat::PrintToString(*message, &binary_str);
...@@ -46,13 +59,13 @@ int write_proto_conf(google::protobuf::Message *message, ...@@ -46,13 +59,13 @@ int write_proto_conf(google::protobuf::Message *message,
return -1; return -1;
} }
fout_bin.write((char *)binary_str.c_str(), binary_str.size()); fout_bin.write(binary_str.c_str(), binary_str.size());
fout_bin.close(); fout_bin.close();
return 0; return 0;
} }
} // configure } // namespace configure
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ /* vim: set expandtab ts=2 sw=2 sts=2 tw=100: */
#include <sys/types.h> // 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 <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <iostream> #include <iostream>
#include "server_configure.pb.h" #include "configure/inferencer_configure.pb.h"
#include "sdk_configure.pb.h" #include "configure/sdk_configure.pb.h"
#include "inferencer_configure.pb.h" #include "configure/server_configure.pb.h"
#include "configure_parser.h" #include "include/configure_parser.h"
using baidu::paddle_serving::configure::EngineDesc; using baidu::paddle_serving::configure::EngineDesc;
using baidu::paddle_serving::configure::ModelToolkitConf; using baidu::paddle_serving::configure::ModelToolkitConf;
...@@ -30,16 +44,15 @@ using baidu::paddle_serving::configure::SDKConf; ...@@ -30,16 +44,15 @@ using baidu::paddle_serving::configure::SDKConf;
using baidu::paddle_serving::configure::SigmoidConf; using baidu::paddle_serving::configure::SigmoidConf;
const std::string output_dir = "./conf/"; const char *output_dir = "./conf/";
const std::string model_toolkit_conf_file = "model_toolkit.prototxt"; const char *model_toolkit_conf_file = "model_toolkit.prototxt";
const std::string resource_conf_file = "resource.prototxt"; const char *resource_conf_file = "resource.prototxt";
const std::string workflow_conf_file = "workflow.prototxt"; const char *workflow_conf_file = "workflow.prototxt";
const std::string service_conf_file = "service.prototxt"; const char *service_conf_file = "service.prototxt";
const std::string sdk_conf_file = "predictors.prototxt"; const char *sdk_conf_file = "predictors.prototxt";
const std::string sigmoid_conf_file = "inferencer.prototxt"; const char *sigmoid_conf_file = "inferencer.prototxt";
int test_write_conf() int test_write_conf() {
{
// model_toolkit conf // model_toolkit conf
ModelToolkitConf model_toolkit_conf; ModelToolkitConf model_toolkit_conf;
...@@ -54,7 +67,8 @@ int test_write_conf() ...@@ -54,7 +67,8 @@ int test_write_conf()
engine->set_batch_infer_size(0); engine->set_batch_infer_size(0);
engine->set_enable_batch_align(0); engine->set_enable_batch_align(0);
int ret = baidu::paddle_serving::configure::write_proto_conf(&model_toolkit_conf, output_dir, model_toolkit_conf_file); int ret = baidu::paddle_serving::configure::write_proto_conf(
&model_toolkit_conf, output_dir, model_toolkit_conf_file);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -63,7 +77,8 @@ int test_write_conf() ...@@ -63,7 +77,8 @@ int test_write_conf()
ResourceConf resource_conf; ResourceConf resource_conf;
resource_conf.set_model_toolkit_path(output_dir); resource_conf.set_model_toolkit_path(output_dir);
resource_conf.set_model_toolkit_file("model_toolkit.prototxt"); resource_conf.set_model_toolkit_file("model_toolkit.prototxt");
ret = baidu::paddle_serving::configure::write_proto_conf(&resource_conf, output_dir, resource_conf_file); ret = baidu::paddle_serving::configure::write_proto_conf(
&resource_conf, output_dir, resource_conf_file);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -100,7 +115,8 @@ int test_write_conf() ...@@ -100,7 +115,8 @@ int test_write_conf()
dag_node->set_name("dense_op"); dag_node->set_name("dense_op");
dag_node->set_type("DenseOp"); dag_node->set_type("DenseOp");
ret = baidu::paddle_serving::configure::write_proto_conf(&workflow_conf, output_dir, workflow_conf_file); ret = baidu::paddle_serving::configure::write_proto_conf(
&workflow_conf, output_dir, workflow_conf_file);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -116,7 +132,8 @@ int test_write_conf() ...@@ -116,7 +132,8 @@ int test_write_conf()
infer_service->set_name("BuiltinDenseFormatService"); infer_service->set_name("BuiltinDenseFormatService");
infer_service->add_workflows("workflow2"); infer_service->add_workflows("workflow2");
ret = baidu::paddle_serving::configure::write_proto_conf(&infer_service_conf, output_dir, service_conf_file); ret = baidu::paddle_serving::configure::write_proto_conf(
&infer_service_conf, output_dir, service_conf_file);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -125,7 +142,8 @@ int test_write_conf() ...@@ -125,7 +142,8 @@ int test_write_conf()
VariantConf *default_variant_conf = sdk_conf.mutable_default_variant_conf(); VariantConf *default_variant_conf = sdk_conf.mutable_default_variant_conf();
default_variant_conf->set_tag("default"); default_variant_conf->set_tag("default");
ConnectionConf *connection_conf = default_variant_conf->mutable_connection_conf(); ConnectionConf *connection_conf =
default_variant_conf->mutable_connection_conf();
connection_conf->set_connect_timeout_ms(2000); connection_conf->set_connect_timeout_ms(2000);
connection_conf->set_rpc_timeout_ms(20000); connection_conf->set_rpc_timeout_ms(20000);
connection_conf->set_connect_retry_count(2); connection_conf->set_connect_retry_count(2);
...@@ -146,10 +164,13 @@ int test_write_conf() ...@@ -146,10 +164,13 @@ int test_write_conf()
Predictor *predictor = sdk_conf.add_predictors(); Predictor *predictor = sdk_conf.add_predictors();
predictor->set_name("ximage"); predictor->set_name("ximage");
predictor->set_service_name("baidu.paddle_serving.predictor.image_classification.ImageClassifyService"); predictor->set_service_name(
"baidu.paddle_serving.predictor.image_classification."
"ImageClassifyService");
predictor->set_endpoint_router("WeightedRandomRender"); predictor->set_endpoint_router("WeightedRandomRender");
WeightedRandomRenderConf *weighted_random_render_conf = predictor->mutable_weighted_random_render_conf(); WeightedRandomRenderConf *weighted_random_render_conf =
predictor->mutable_weighted_random_render_conf();
weighted_random_render_conf->set_variant_weight_list("50"); weighted_random_render_conf->set_variant_weight_list("50");
VariantConf *variant_conf = predictor->add_variants(); VariantConf *variant_conf = predictor->add_variants();
...@@ -157,7 +178,8 @@ int test_write_conf() ...@@ -157,7 +178,8 @@ int test_write_conf()
naming_conf = variant_conf->mutable_naming_conf(); naming_conf = variant_conf->mutable_naming_conf();
naming_conf->set_cluster("list://127.0.0.1:8010"); naming_conf->set_cluster("list://127.0.0.1:8010");
ret = baidu::paddle_serving::configure::write_proto_conf(&sdk_conf, output_dir, sdk_conf_file); ret = baidu::paddle_serving::configure::write_proto_conf(
&sdk_conf, output_dir, sdk_conf_file);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -169,7 +191,8 @@ int test_write_conf() ...@@ -169,7 +191,8 @@ int test_write_conf()
sigmoid_conf.set_exp_max_input(0.75); sigmoid_conf.set_exp_max_input(0.75);
sigmoid_conf.set_exp_min_input(0.25); sigmoid_conf.set_exp_min_input(0.25);
ret = baidu::paddle_serving::configure::write_proto_conf(&sigmoid_conf, output_dir, sigmoid_conf_file); ret = baidu::paddle_serving::configure::write_proto_conf(
&sigmoid_conf, output_dir, sigmoid_conf_file);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -177,47 +200,52 @@ int test_write_conf() ...@@ -177,47 +200,52 @@ int test_write_conf()
return 0; return 0;
} }
int test_read_conf() int test_read_conf() {
{
int ret = 0; int ret = 0;
ModelToolkitConf model_toolkit_conf; ModelToolkitConf model_toolkit_conf;
ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, model_toolkit_conf_file, &model_toolkit_conf); ret = baidu::paddle_serving::configure::read_proto_conf(
output_dir, model_toolkit_conf_file, &model_toolkit_conf);
if (ret != 0) { if (ret != 0) {
std::cout << "Read conf fail: " << model_toolkit_conf_file << std::endl; std::cout << "Read conf fail: " << model_toolkit_conf_file << std::endl;
return -1; return -1;
} }
ResourceConf resource_conf; ResourceConf resource_conf;
ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, resource_conf_file, &resource_conf); ret = baidu::paddle_serving::configure::read_proto_conf(
output_dir, resource_conf_file, &resource_conf);
if (ret != 0) { if (ret != 0) {
std::cout << "Read conf fail: " << resource_conf_file << std::endl; std::cout << "Read conf fail: " << resource_conf_file << std::endl;
return -1; return -1;
} }
WorkflowConf workflow_conf; WorkflowConf workflow_conf;
ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, workflow_conf_file, &workflow_conf); ret = baidu::paddle_serving::configure::read_proto_conf(
output_dir, workflow_conf_file, &workflow_conf);
if (ret != 0) { if (ret != 0) {
std::cout << "Read conf fail: " << workflow_conf_file << std::endl; std::cout << "Read conf fail: " << workflow_conf_file << std::endl;
return -1; return -1;
} }
InferServiceConf service_conf; InferServiceConf service_conf;
ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, service_conf_file, &service_conf); ret = baidu::paddle_serving::configure::read_proto_conf(
output_dir, service_conf_file, &service_conf);
if (ret != 0) { if (ret != 0) {
std::cout << "Read conf fail: " << service_conf_file << std::endl; std::cout << "Read conf fail: " << service_conf_file << std::endl;
return -1; return -1;
} }
SDKConf sdk_conf; SDKConf sdk_conf;
ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, sdk_conf_file, &sdk_conf); ret = baidu::paddle_serving::configure::read_proto_conf(
output_dir, sdk_conf_file, &sdk_conf);
if (ret != 0) { if (ret != 0) {
std::cout << "Read conf fail: " << sdk_conf_file << std::endl; std::cout << "Read conf fail: " << sdk_conf_file << std::endl;
return -1; return -1;
} }
SigmoidConf sigmoid_conf; SigmoidConf sigmoid_conf;
ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, sigmoid_conf_file, &sigmoid_conf); ret = baidu::paddle_serving::configure::read_proto_conf(
output_dir, sigmoid_conf_file, &sigmoid_conf);
if (ret != 0) { if (ret != 0) {
std::cout << "Read conf fail: " << sdk_conf_file << std::endl; std::cout << "Read conf fail: " << sdk_conf_file << std::endl;
return -1; return -1;
...@@ -226,11 +254,10 @@ int test_read_conf() ...@@ -226,11 +254,10 @@ int test_read_conf()
return 0; return 0;
} }
int main() int main() {
{
int ret = 0; int ret = 0;
struct stat stat_buf; struct stat stat_buf;
if (stat(output_dir.c_str(), &stat_buf) != 0) { if (stat(output_dir, &stat_buf) != 0) {
int ret = mkdir("./conf", 0777); int ret = mkdir("./conf", 0777);
if (ret != 0) { if (ret != 0) {
std::cout << "mkdir ./conf fail" << std::endl; std::cout << "mkdir ./conf fail" << std::endl;
......
...@@ -10,4 +10,3 @@ target_link_libraries(fluid_cpu_engine pdserving paddle_fluid -liomp5 -lmklml_in ...@@ -10,4 +10,3 @@ target_link_libraries(fluid_cpu_engine pdserving paddle_fluid -liomp5 -lmklml_in
install(TARGETS fluid_cpu_engine install(TARGETS fluid_cpu_engine
ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib
) )
// 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 #pragma once
#include <pthread.h> #include <pthread.h>
#include <fstream>
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include "configure/include/configure_parser.h"
#include <fstream> #include "configure/inferencer_configure.pb.h"
#include "framework/infer.h" #include "framework/infer.h"
#include "paddle/fluid/inference/paddle_inference_api.h" #include "paddle/fluid/inference/paddle_inference_api.h"
#include "inferencer_configure.pb.h"
#include "configure_parser.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -17,59 +31,49 @@ namespace fluid_cpu { ...@@ -17,59 +31,49 @@ namespace fluid_cpu {
using configure::SigmoidConf; using configure::SigmoidConf;
class AutoLock { class AutoLock {
public: public:
AutoLock(pthread_mutex_t& mutex) : _mut(mutex){ explicit AutoLock(pthread_mutex_t& mutex) : _mut(mutex) {
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
} }
~AutoLock() { ~AutoLock() { pthread_mutex_unlock(&_mut); }
pthread_mutex_unlock(&_mut);
}
private: private:
pthread_mutex_t& _mut; pthread_mutex_t& _mut;
}; };
class GlobalPaddleCreateMutex { class GlobalPaddleCreateMutex {
public: public:
pthread_mutex_t& mutex() { pthread_mutex_t& mutex() { return _mut; }
return _mut;
}
static pthread_mutex_t& instance() { static pthread_mutex_t& instance() {
static GlobalPaddleCreateMutex gmutex; static GlobalPaddleCreateMutex gmutex;
return gmutex.mutex(); return gmutex.mutex();
} }
private: private:
GlobalPaddleCreateMutex() { GlobalPaddleCreateMutex() { pthread_mutex_init(&_mut, NULL); }
pthread_mutex_init(&_mut, NULL);
}
pthread_mutex_t _mut; pthread_mutex_t _mut;
}; };
class GlobalSigmoidCreateMutex { class GlobalSigmoidCreateMutex {
public: public:
pthread_mutex_t& mutex() { pthread_mutex_t& mutex() { return _mut; }
return _mut;
}
static pthread_mutex_t& instance() { static pthread_mutex_t& instance() {
static GlobalSigmoidCreateMutex gmutex; static GlobalSigmoidCreateMutex gmutex;
return gmutex.mutex(); return gmutex.mutex();
} }
private:
GlobalSigmoidCreateMutex() { private:
pthread_mutex_init(&_mut, NULL); GlobalSigmoidCreateMutex() { pthread_mutex_init(&_mut, NULL); }
}
pthread_mutex_t _mut; pthread_mutex_t _mut;
}; };
// data interface // data interface
class FluidFamilyCore { class FluidFamilyCore {
public: public:
virtual ~FluidFamilyCore() {} virtual ~FluidFamilyCore() {}
virtual bool Run(const void* in_data, void* out_data) { virtual bool Run(const void* in_data, void* out_data) {
if (!_core->Run(*(std::vector<paddle::PaddleTensor>*)in_data, if (!_core->Run(*(std::vector<paddle::PaddleTensor>*)in_data,
...@@ -88,7 +92,8 @@ public: ...@@ -88,7 +92,8 @@ public:
LOG(ERROR) << "origin paddle Predictor is null."; LOG(ERROR) << "origin paddle Predictor is null.";
return -1; return -1;
} }
paddle::PaddlePredictor* p_predictor = (paddle::PaddlePredictor*)origin_core; paddle::PaddlePredictor* p_predictor =
(paddle::PaddlePredictor*)origin_core;
_core = p_predictor->Clone(); _core = p_predictor->Clone();
if (_core.get() == NULL) { if (_core.get() == NULL) {
LOG(ERROR) << "fail to clone paddle predictor: " << origin_core; LOG(ERROR) << "fail to clone paddle predictor: " << origin_core;
...@@ -97,17 +102,15 @@ public: ...@@ -97,17 +102,15 @@ public:
return 0; return 0;
} }
virtual void* get() { virtual void* get() { return _core.get(); }
return _core.get();
}
protected: protected:
std::unique_ptr<paddle::PaddlePredictor> _core; std::unique_ptr<paddle::PaddlePredictor> _core;
}; };
// infer interface // infer interface
class FluidCpuAnalysisCore : public FluidFamilyCore { class FluidCpuAnalysisCore : public FluidFamilyCore {
public: public:
int create(const std::string& data_path) { int create(const std::string& data_path) {
if (access(data_path.c_str(), F_OK) == -1) { if (access(data_path.c_str(), F_OK) == -1) {
LOG(ERROR) << "create paddle predictor failed, path not exits: " LOG(ERROR) << "create paddle predictor failed, path not exits: "
...@@ -122,21 +125,20 @@ public: ...@@ -122,21 +125,20 @@ public:
analysis_config.device = 0; analysis_config.device = 0;
analysis_config.specify_input_name = true; analysis_config.specify_input_name = true;
AutoLock lock(GlobalPaddleCreateMutex::instance()); AutoLock lock(GlobalPaddleCreateMutex::instance());
_core = paddle::CreatePaddlePredictor< _core = paddle::CreatePaddlePredictor<paddle::contrib::AnalysisConfig>(
paddle::contrib::AnalysisConfig>(analysis_config); analysis_config);
if (NULL == _core.get()) { if (NULL == _core.get()) {
LOG(ERROR) << "create paddle predictor failed, path: " LOG(ERROR) << "create paddle predictor failed, path: " << data_path;
<< data_path;
return -1; return -1;
} }
LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; LOG(WARNING) << "create paddle predictor sucess, path: " << data_path;
return 0; return 0;
} }
}; };
class FluidCpuNativeCore : public FluidFamilyCore { class FluidCpuNativeCore : public FluidFamilyCore {
public: public:
int create(const std::string& data_path) { int create(const std::string& data_path) {
if (access(data_path.c_str(), F_OK) == -1) { if (access(data_path.c_str(), F_OK) == -1) {
LOG(ERROR) << "create paddle predictor failed, path not exits: " LOG(ERROR) << "create paddle predictor failed, path not exits: "
...@@ -150,21 +152,21 @@ public: ...@@ -150,21 +152,21 @@ public:
native_config.use_gpu = false; native_config.use_gpu = false;
native_config.device = 0; native_config.device = 0;
AutoLock lock(GlobalPaddleCreateMutex::instance()); AutoLock lock(GlobalPaddleCreateMutex::instance());
_core = paddle::CreatePaddlePredictor< _core = paddle::CreatePaddlePredictor<paddle::NativeConfig,
paddle::NativeConfig, paddle::PaddleEngineKind::kNative>(native_config); paddle::PaddleEngineKind::kNative>(
native_config);
if (NULL == _core.get()) { if (NULL == _core.get()) {
LOG(ERROR) << "create paddle predictor failed, path: " LOG(ERROR) << "create paddle predictor failed, path: " << data_path;
<< data_path;
return -1; return -1;
} }
LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; LOG(WARNING) << "create paddle predictor sucess, path: " << data_path;
return 0; return 0;
} }
}; };
class FluidCpuAnalysisDirCore : public FluidFamilyCore { class FluidCpuAnalysisDirCore : public FluidFamilyCore {
public: public:
int create(const std::string& data_path) { int create(const std::string& data_path) {
if (access(data_path.c_str(), F_OK) == -1) { if (access(data_path.c_str(), F_OK) == -1) {
LOG(ERROR) << "create paddle predictor failed, path not exits: " LOG(ERROR) << "create paddle predictor failed, path not exits: "
...@@ -178,22 +180,20 @@ public: ...@@ -178,22 +180,20 @@ public:
analysis_config.device = 0; analysis_config.device = 0;
analysis_config.specify_input_name = true; analysis_config.specify_input_name = true;
AutoLock lock(GlobalPaddleCreateMutex::instance()); AutoLock lock(GlobalPaddleCreateMutex::instance());
_core = paddle::CreatePaddlePredictor< _core = paddle::CreatePaddlePredictor<paddle::contrib::AnalysisConfig>(
paddle::contrib::AnalysisConfig>(analysis_config); analysis_config);
if (NULL == _core.get()) { if (NULL == _core.get()) {
LOG(ERROR) << "create paddle predictor failed, path: " LOG(ERROR) << "create paddle predictor failed, path: " << data_path;
<< data_path;
return -1; return -1;
} }
LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; LOG(WARNING) << "create paddle predictor sucess, path: " << data_path;
return 0; return 0;
} }
}; };
class FluidCpuNativeDirCore : public FluidFamilyCore { class FluidCpuNativeDirCore : public FluidFamilyCore {
public: public:
int create(const std::string& data_path) { int create(const std::string& data_path) {
if (access(data_path.c_str(), F_OK) == -1) { if (access(data_path.c_str(), F_OK) == -1) {
LOG(ERROR) << "create paddle predictor failed, path not exits: " LOG(ERROR) << "create paddle predictor failed, path not exits: "
...@@ -206,22 +206,21 @@ public: ...@@ -206,22 +206,21 @@ public:
native_config.use_gpu = false; native_config.use_gpu = false;
native_config.device = 0; native_config.device = 0;
AutoLock lock(GlobalPaddleCreateMutex::instance()); AutoLock lock(GlobalPaddleCreateMutex::instance());
_core = paddle::CreatePaddlePredictor< _core = paddle::CreatePaddlePredictor<paddle::NativeConfig,
paddle::NativeConfig, paddle::PaddleEngineKind::kNative>(native_config); paddle::PaddleEngineKind::kNative>(
native_config);
if (NULL == _core.get()) { if (NULL == _core.get()) {
LOG(ERROR) << "create paddle predictor failed, path: " LOG(ERROR) << "create paddle predictor failed, path: " << data_path;
<< data_path;
return -1; return -1;
} }
LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; LOG(WARNING) << "create paddle predictor sucess, path: " << data_path;
return 0; return 0;
} }
}; };
class Parameter { class Parameter {
public: public:
Parameter() : _row(0), _col(0), _params(NULL) {} Parameter() : _row(0), _col(0), _params(NULL) {}
~Parameter() { ~Parameter() {
LOG(INFO) << "before destroy Parameter, file_name[" << _file_name << "]"; LOG(INFO) << "before destroy Parameter, file_name[" << _file_name << "]";
...@@ -233,7 +232,7 @@ public: ...@@ -233,7 +232,7 @@ public:
_file_name = file_name; _file_name = file_name;
_row = row; _row = row;
_col = col; _col = col;
_params = (float*)malloc(_row * _col * sizeof(float)); _params = reinterpret_cast<float*>(malloc(_row * _col * sizeof(float)));
if (_params == NULL) { if (_params == NULL) {
LOG(ERROR) << "Load " << _file_name << " malloc error."; LOG(ERROR) << "Load " << _file_name << " malloc error.";
return -1; return -1;
...@@ -294,7 +293,7 @@ public: ...@@ -294,7 +293,7 @@ public:
return 0; return 0;
} }
public: public:
std::string _file_name; std::string _file_name;
int _row; int _row;
int _col; int _col;
...@@ -302,40 +301,44 @@ public: ...@@ -302,40 +301,44 @@ public:
}; };
class SigmoidModel { class SigmoidModel {
public: public:
~SigmoidModel() { ~SigmoidModel() {}
} int load(const char* sigmoid_w_file,
int load(const char* sigmoid_w_file, const char* sigmoid_b_file, const char* sigmoid_b_file,
float exp_max, float exp_min) { float exp_max,
float exp_min) {
AutoLock lock(GlobalSigmoidCreateMutex::instance()); AutoLock lock(GlobalSigmoidCreateMutex::instance());
if (0 != _sigmoid_w.init(2, 1, sigmoid_w_file) || 0 != _sigmoid_w.load()) { if (0 != _sigmoid_w.init(2, 1, sigmoid_w_file) || 0 != _sigmoid_w.load()) {
LOG(ERROR) << "load params sigmoid_w failed."; LOG(ERROR) << "load params sigmoid_w failed.";
return -1; return -1;
} }
LOG(WARNING) << "load sigmoid_w [" << _sigmoid_w._params[0] LOG(WARNING) << "load sigmoid_w [" << _sigmoid_w._params[0] << "] ["
<< "] [" << _sigmoid_w._params[1] << "]."; << _sigmoid_w._params[1] << "].";
if (0 != _sigmoid_b.init(2, 1, sigmoid_b_file) || 0 != _sigmoid_b.load()) { if (0 != _sigmoid_b.init(2, 1, sigmoid_b_file) || 0 != _sigmoid_b.load()) {
LOG(ERROR) << "load params sigmoid_b failed."; LOG(ERROR) << "load params sigmoid_b failed.";
return -1; return -1;
} }
LOG(WARNING) << "load sigmoid_b [" << _sigmoid_b._params[0] LOG(WARNING) << "load sigmoid_b [" << _sigmoid_b._params[0] << "] ["
<< "] [" << _sigmoid_b._params[1] << "]."; << _sigmoid_b._params[1] << "].";
_exp_max_input = exp_max; _exp_max_input = exp_max;
_exp_min_input = exp_min; _exp_min_input = exp_min;
return 0; return 0;
} }
int softmax(float x, double& o) { int softmax(float x, double& o) { // NOLINT
float _y0 = x * _sigmoid_w._params[0] + _sigmoid_b._params[0]; float _y0 = x * _sigmoid_w._params[0] + _sigmoid_b._params[0];
float _y1 = x * _sigmoid_w._params[1] + _sigmoid_b._params[1]; float _y1 = x * _sigmoid_w._params[1] + _sigmoid_b._params[1];
_y0 = (_y0 > _exp_max_input) ? _exp_max_input _y0 = (_y0 > _exp_max_input)
? _exp_max_input
: ((_y0 < _exp_min_input) ? _exp_min_input : _y0); : ((_y0 < _exp_min_input) ? _exp_min_input : _y0);
_y1 = (_y1 > _exp_max_input) ? _exp_max_input _y1 = (_y1 > _exp_max_input)
? _exp_max_input
: ((_y1 < _exp_min_input) ? _exp_min_input : _y1); : ((_y1 < _exp_min_input) ? _exp_min_input : _y1);
o = 1.0f / (1.0f + exp(_y0 - _y1)); o = 1.0f / (1.0f + exp(_y0 - _y1));
return 0; return 0;
} }
public:
public:
Parameter _sigmoid_w; Parameter _sigmoid_w;
Parameter _sigmoid_b; Parameter _sigmoid_b;
float _exp_max_input; float _exp_max_input;
...@@ -343,10 +346,10 @@ public: ...@@ -343,10 +346,10 @@ public:
}; };
class SigmoidFluidModel { class SigmoidFluidModel {
public: public:
int softmax(float x, double& o) { int softmax(float x, double& o) { // NOLINT
return _sigmoid_core->softmax(x, o); return _sigmoid_core->softmax(x, o);
} } // NOLINT
std::unique_ptr<SigmoidFluidModel> Clone() { std::unique_ptr<SigmoidFluidModel> Clone() {
std::unique_ptr<SigmoidFluidModel> clone_model; std::unique_ptr<SigmoidFluidModel> clone_model;
...@@ -356,16 +359,16 @@ public: ...@@ -356,16 +359,16 @@ public:
return std::move(clone_model); return std::move(clone_model);
} }
public: public:
std::unique_ptr<paddle::PaddlePredictor> _fluid_core; std::unique_ptr<paddle::PaddlePredictor> _fluid_core;
std::shared_ptr<SigmoidModel> _sigmoid_core; std::shared_ptr<SigmoidModel> _sigmoid_core;
}; };
class FluidCpuWithSigmoidCore : public FluidFamilyCore { class FluidCpuWithSigmoidCore : public FluidFamilyCore {
public: public:
virtual ~FluidCpuWithSigmoidCore() { virtual ~FluidCpuWithSigmoidCore() {}
}
public: public:
int create(const std::string& model_path) { int create(const std::string& model_path) {
size_t pos = model_path.find_last_of("/\\"); size_t pos = model_path.find_last_of("/\\");
std::string conf_path = model_path.substr(0, pos); std::string conf_path = model_path.substr(0, pos);
...@@ -391,7 +394,8 @@ public: ...@@ -391,7 +394,8 @@ public:
_core->_sigmoid_core.reset(new SigmoidModel); _core->_sigmoid_core.reset(new SigmoidModel);
LOG(INFO) << "create sigmoid core[" << _core->_sigmoid_core.get() LOG(INFO) << "create sigmoid core[" << _core->_sigmoid_core.get()
<< "], use count[" << _core->_sigmoid_core.use_count() << "]."; << "], use count[" << _core->_sigmoid_core.use_count() << "].";
ret = _core->_sigmoid_core->load(sigmoid_w_file, sigmoid_b_file, exp_max, exp_min); ret = _core->_sigmoid_core->load(
sigmoid_w_file, sigmoid_b_file, exp_max, exp_min);
if (ret < 0) { if (ret < 0) {
LOG(ERROR) << "fail to load sigmoid model."; LOG(ERROR) << "fail to load sigmoid model.";
return -1; return -1;
...@@ -400,7 +404,8 @@ public: ...@@ -400,7 +404,8 @@ public:
} }
virtual bool Run(const void* in_data, void* out_data) { virtual bool Run(const void* in_data, void* out_data) {
if (!_core->_fluid_core->Run(*(std::vector<paddle::PaddleTensor>*)in_data, if (!_core->_fluid_core->Run(
*(std::vector<paddle::PaddleTensor>*)in_data,
(std::vector<paddle::PaddleTensor>*)out_data)) { (std::vector<paddle::PaddleTensor>*)out_data)) {
LOG(ERROR) << "Failed call Run with paddle predictor"; LOG(ERROR) << "Failed call Run with paddle predictor";
return false; return false;
...@@ -424,22 +429,20 @@ public: ...@@ -424,22 +429,20 @@ public:
return 0; return 0;
} }
virtual SigmoidFluidModel* get() { virtual SigmoidFluidModel* get() { return _core.get(); }
return _core.get();
}
virtual int load_fluid_model(const std::string& data_path) = 0; virtual int load_fluid_model(const std::string& data_path) = 0;
int softmax(float x, double& o) { int softmax(float x, double& o) { // NOLINT
return _core->_sigmoid_core->softmax(x, o); return _core->_sigmoid_core->softmax(x, o);
} }
protected: protected:
std::unique_ptr<SigmoidFluidModel> _core; std::unique_ptr<SigmoidFluidModel> _core;
}; };
class FluidCpuNativeDirWithSigmoidCore : public FluidCpuWithSigmoidCore { class FluidCpuNativeDirWithSigmoidCore : public FluidCpuWithSigmoidCore {
public: public:
int load_fluid_model(const std::string& data_path) { int load_fluid_model(const std::string& data_path) {
if (access(data_path.c_str(), F_OK) == -1) { if (access(data_path.c_str(), F_OK) == -1) {
LOG(ERROR) << "create paddle predictor failed, path not exits: " LOG(ERROR) << "create paddle predictor failed, path not exits: "
...@@ -452,22 +455,22 @@ public: ...@@ -452,22 +455,22 @@ public:
native_config.use_gpu = false; native_config.use_gpu = false;
native_config.device = 0; native_config.device = 0;
AutoLock lock(GlobalPaddleCreateMutex::instance()); AutoLock lock(GlobalPaddleCreateMutex::instance());
_core->_fluid_core = paddle::CreatePaddlePredictor< _core->_fluid_core =
paddle::NativeConfig, paddle::PaddleEngineKind::kNative>(native_config); paddle::CreatePaddlePredictor<paddle::NativeConfig,
paddle::PaddleEngineKind::kNative>(
native_config);
if (NULL == _core.get()) { if (NULL == _core.get()) {
LOG(ERROR) << "create paddle predictor failed, path: " LOG(ERROR) << "create paddle predictor failed, path: " << data_path;
<< data_path;
return -1; return -1;
} }
LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; LOG(WARNING) << "create paddle predictor sucess, path: " << data_path;
return 0; return 0;
} }
}; };
class FluidCpuAnalysisDirWithSigmoidCore : public FluidCpuWithSigmoidCore { class FluidCpuAnalysisDirWithSigmoidCore : public FluidCpuWithSigmoidCore {
public: public:
int load_fluid_model(const std::string& data_path) { int load_fluid_model(const std::string& data_path) {
if (access(data_path.c_str(), F_OK) == -1) { if (access(data_path.c_str(), F_OK) == -1) {
LOG(ERROR) << "create paddle predictor failed, path not exits: " LOG(ERROR) << "create paddle predictor failed, path not exits: "
...@@ -481,15 +484,15 @@ public: ...@@ -481,15 +484,15 @@ public:
analysis_config.device = 0; analysis_config.device = 0;
analysis_config.specify_input_name = true; analysis_config.specify_input_name = true;
AutoLock lock(GlobalPaddleCreateMutex::instance()); AutoLock lock(GlobalPaddleCreateMutex::instance());
_core->_fluid_core = paddle::CreatePaddlePredictor< _core->_fluid_core =
paddle::contrib::AnalysisConfig>(analysis_config); paddle::CreatePaddlePredictor<paddle::contrib::AnalysisConfig>(
analysis_config);
if (NULL == _core.get()) { if (NULL == _core.get()) {
LOG(ERROR) << "create paddle predictor failed, path: " LOG(ERROR) << "create paddle predictor failed, path: " << data_path;
<< data_path;
return -1; return -1;
} }
LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; LOG(WARNING) << "create paddle predictor sucess, path: " << data_path;
return 0; return 0;
} }
}; };
......
// 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 "inferencer-fluid-cpu/include/fluid_cpu_engine.h"
#include "framework/factory.h" #include "framework/factory.h"
#include "fluid_cpu_engine.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -7,27 +21,36 @@ namespace fluid_cpu { ...@@ -7,27 +21,36 @@ namespace fluid_cpu {
REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(
::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuAnalysisCore>, ::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuAnalysisCore>,
::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS"); ::baidu::paddle_serving::predictor::InferEngine,
"FLUID_CPU_ANALYSIS");
REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(
::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuAnalysisDirCore>, ::baidu::paddle_serving::predictor::FluidInferEngine<
::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS_DIR"); FluidCpuAnalysisDirCore>,
::baidu::paddle_serving::predictor::InferEngine,
"FLUID_CPU_ANALYSIS_DIR");
REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(
::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuAnalysisDirWithSigmoidCore>, ::baidu::paddle_serving::predictor::FluidInferEngine<
::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS_DIR_SIGMOID"); FluidCpuAnalysisDirWithSigmoidCore>,
::baidu::paddle_serving::predictor::InferEngine,
"FLUID_CPU_ANALYSIS_DIR_SIGMOID");
REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(
::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuNativeCore>, ::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuNativeCore>,
::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_NATIVE"); ::baidu::paddle_serving::predictor::InferEngine,
"FLUID_CPU_NATIVE");
REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(
::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuNativeDirCore>, ::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuNativeDirCore>,
::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_NATIVE_DIR"); ::baidu::paddle_serving::predictor::InferEngine,
"FLUID_CPU_NATIVE_DIR");
REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(
::baidu::paddle_serving::predictor::FluidInferEngine<FluidCpuNativeDirWithSigmoidCore>, ::baidu::paddle_serving::predictor::FluidInferEngine<
::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_NATIVE_DIR_SIGMOID"); FluidCpuNativeDirWithSigmoidCore>,
::baidu::paddle_serving::predictor::InferEngine,
"FLUID_CPU_NATIVE_DIR_SIGMOID");
} // namespace fluid_cpu } // namespace fluid_cpu
} // namespace paddle_serving } // namespace paddle_serving
......
...@@ -34,5 +34,3 @@ install(TARGETS pdserving pdcodegen ...@@ -34,5 +34,3 @@ install(TARGETS pdserving pdcodegen
ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib
LIBRARY DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/so LIBRARY DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/so
) )
[TOC]
# 概述
PaddlePaddle是公司开源的机器学习框架,广泛支持各种深度学习模型的定制化开发;
Paddle cloud是基于PaddlePaddle框架实现的一整套云平台,对外提供全流程的AI开发平台,对内托管集团内各产品线的机器学习云服务。
Paddle serving是Paddle cloud的在线预测部分,与Paddle cloud模型训练环节无缝衔接,对外提供机器学习预测共有云服务,对内为公司各业务线提供统一的模型预测开发框架和云服务。
# Getting Started
## 运行示例
说明:Imagenet图像分类模型,默认采用CPU模式(GPU模式请修改BCLOUD配置项,并用Dockerfile构建运行环境,[Docker部署请参考Wiki](http://agroup.baidu.com/share/md/044f552e866f4078900be503784e2468))。
Step1:启动Server端:
```shell
git clone ssh://icode.baidu.com:8235/baidu/paddle-serving/serving ~/my_paddle_serving/baidu/paddle-serving/serving && cd ~/my_paddle_serving/baidu/paddle-serving/serving && bcloud build && ./output/bin/image_class &
```
Step2:启动Client端:
```shell
git clone ssh://icode.baidu.com:8235/baidu/paddle-serving/sdk-cpp ~/my_paddle_serving/baidu/paddle-serving/sdk-cpp && cd ~/my_paddle_serving/baidu/paddle-serving/sdk-cpp && bcloud build && ./output/bin/ximage && pkill image_class
```
## 示例说明
### 预测接口定义
```c++
syntax="proto2";
package baidu.paddle_serving.predictor.image_class;
option cc_generic_services = true;
// x-image request相关(批量接口)
message XImageReqInstance {
required bytes image_binary = 1;
required uint32 image_length = 2;
};
message Request {
repeated XImageReqInstance instances = 1;
};
// x-image response相关(批量接口)
message DensePrediction {
repeated float categories = 1;
};
message ClassResponse {
repeated DensePrediction predictions = 1;
};
message XImageResInstance {
required string response_json = 1;
};
message Response {
// Each json string is serialized from ClassResponse
repeated XImageResInstance predictions = 1;
};
// Service/method相关
service ImageClassifyService {
rpc inference(Request) returns (Response);
rpc debug(Request) returns (Response);
};
```
### Server端实现
用户只需定制或配置以下三类信息的实现,即可快速搭建完整的Paddle-Serving预测模块。
#### 接口改造([proto目录](http://icode.baidu.com/repos/baidu/paddle-serving/serving/tree/master:proto/))
Server端需对预测接口作如下修改即可:
```c++
// 改动1:依赖paddle-serving option接口文件
import "pds_option.proto";
...
service ClassService {
rpc inference(Request) returns (Response);
rpc debug(Request) returns (Response);
// 改动2:打开generate_impl开关(以支持配置驱动)
option (pds.options).generate_impl = true;
};
```
#### 示例配置([conf目录](http://icode.baidu.com/repos/baidu/paddle-serving/serving/tree/master:conf/))
- gflags配置项
| name | 默认值 | 含义 |
|------|--------|------|
| workflow_path | ./conf | workflow配置目录名 |
|workflow_file|workflow.conf|workflow配置文件名|
|inferservice_path|./conf|service配置目录名|
|inferservice_file|service.conf|service配置文件名|
|logger_path|./conf|日志配置目录名|
|logger_file|log.conf|日志配置文件名|
|resource_path|./conf|资源管理器目录名|
|resource_file|resource.conf|资源管理器文件名|
|reload_interval_s|10|重载线程间隔时间(s)|
- 配置文件实例(Image图像分类demo)
```shell
# >>> service.conf
[@Service]
name: ImageClassifyService
@workflow: workflow_image_classification
# >>> workflow.conf
[@Workflow]
name: workflow_image_classification
path: ./conf
file: imagec_dag.conf
# >>> imagec_dag.conf
workflow_type: Sequence
[@Node]
name: image_reader_op
type: ImageReaderOp
[@Node]
name: image_classify_op
type: ImageClassifyOp
[.@Depend]
name: image_reader_op
mode: RO
[@Node]
name: write_json_op
type: WriteJsonOp
[.@Depend]
name: image_classify_op
mode: RO
# >>> resource.conf
model_manager_path: ./conf
model_manager_file: model_toolkit.conf
```
#### 定制Op算子([op目录](http://icode.baidu.com/repos/baidu/paddle-serving/serving/tree/master:op/))
- 预处理算子(ImageReaderOp):从Request中读取图像字节流,通过opencv解码,填充tensor对象并输出到channel;
- 预测调用算子(ImageClassifyOp):从ImageReaderOp的channel获得输入tensor,临时申请输出tensor,调用ModelToolkit进行预测,并将输出tensor写入channel
- 后处理算子(WriteJsonOp):从ImageClassifyop的channel获得输出tensor,将其序列化为json字符串,写入作为rpc的output;
### Client端实现
用户只需定制或配置以下三类信息,即可方便的接入预估请求,并在本地配置多套服务连接:
#### 接口改造([proto目录](http://icode.baidu.com/repos/baidu/paddle-serving/sdk-cpp/tree/master:proto))
Client端接口只需对预测接口作如下修改即可:
```c++
// 改动1:依赖paddle-serving option接口文件
import "pds_option.proto";
...
service ImageClassifyService {
rpc inference(Request) returns (Response);
rpc debug(Request) returns (Response);
// 改动2:打开generate_stub开关(以支持配置驱动)
option (pds.options).generate_stub = true;
};
```
#### 连接配置([conf目录](http://icode.baidu.com/repos/baidu/paddle-serving/sdk-cpp/tree/master:conf))
```shell
# predictions.conf
## 默认配置共享
[DefaultVariantInfo]
Tag : default
[.Connection]
ConnectTimeoutMicroSec : 200
ReadTimeoutMicroSec : 2000
WriteTimeoutMicroSec : 500
ConnectRetryCount : 2
MaxConnectionPerHost : 100
HedgeRequestTimeoutMicroSec : -1
HedgeFetchRetryCount : 2
BnsReloadIntervalSeconds : 10
ConnectionType : pooled
[.NamingInfo]
ClusterFilterStrategy : Default
LoadBalanceStrategy : la
[.RpcParameter]
# 0-NONE, 1-SNAPPY, 2-GZIP, 3-ZLIB, 4-LZ4
CompressType : 0
Protocol : baidu_std
MaxChannelPerRequest : 3
[@Predictor]
name : ximage
service_name : baidu.paddle_serving.predictor.image_class.ImageClassifyService
endpoint_router : WeightedRandomRender
[.WeightedRandomRender]
VariantWeightList : 30|70 # 30% vs 70% pvs
[.@VariantInfo]
Tag : var1 # 变体版本标识,提供上游辨识
[..NamingInfo]
Cluster : list://127.0.0.1:8010
[.@VariantInfo]
Tag : var2
[..NamingInfo]
Cluster : list://127.0.0.1:8011
```
#### 请求逻辑([demo/ximage.cpp](http://icode.baidu.com/repos/baidu/paddle-serving/sdk-cpp/blob/master:demo/ximage.cpp))
```c++
// 进程级初始化
assert(PredictorAPI::instance().create("./conf/predictions.conf") == 0);
// 线程级预测调用:
Request req;
// fill request
// ...
Response res;
Predictor* ximage = PredictorAPI::instance().fetch_predictor("ximage");
assert(ximage != NULL);
ximage->inference(req, res);
// parse response
// ...
assert(PredictorAPI::instance().free_predictor(ximage) == 0);
// 进程级销毁
assert(PredictorAPI::instance().destroy() == 0);
```
## 凤巢协议兼容
Paddle Serving由凤巢观星框架发展而来,而之前框架的通信协议是nshead+compack+idl,为方便新老接口的兼容,Paddle Serving的server和client均支持向后兼容:
- 老API访问新Server,为适配老观星客户端数据包格式,新Server需通过mcpack2pb生成能解析idl格式的pb对象,详见:[wtitleq server实现](http://icode.baidu.com/repos/baidu/paddle-serving/lr-model/tree/master)
- 新SDK访问老Server,为能够访问老观星server服务,SDK需通过mcpack2pb插件生成基于idl格式的序列化逻辑;详见:[wtitleq api实现](http://icode.baidu.com/repos/baidu/infinite-inference/as-wtitleq-demo/tree/master)
凤巢广告拆包支持:Paddle Serving的SDK-Cpp为用户提供了简单易用的拆包功能,通过修改proto/conf文件开启:
```c++
// interface.proto文件
message PredictorRequest {
message AdvRequest {
// 广告级别字段
repeated uint32 ideaid = 1;
repeated string title = 2;
}
// query级别字段
required uint64 sid = 1;
required string query = 2;
// ...
// 广告级别字段
repeated AdvRequest advs = 3 [(pds.pack_on)=true]; // 改动1:对advs字段进行拆包
}
// ...
service WtitleqService {
rpc ...
rpc ...
option (pds.options).package_size = 10; // 改动2:限制单包大小
}
```
[wtitleq sdk的proto实例](http://icode.baidu.com/repos/baidu/infinite-inference/as-wtitleq-demo/blob/master:proto/predictor_api.proto)
```bash
# predictions.conf文件
[@Predictor]
# ...
[.@VariantInfo]
#...
[..RpcParameter]
Protocol : itp # 改动3:修改rpc请求参数为itp协议
```
[wtitleq sdk的conf实例](http://icode.baidu.com/repos/baidu/infinite-inference/as-wtitleq-demo/blob/master:conf/predictors.conf)
# 框架简介
![图片](http://agroup-bos.cdn.bcebos.com/63a5076471e96a08124b89101e12c1a0ec7b642a)
- 基础框架:屏蔽一个RPC服务所需的所有元素,让用户只关注自己的业务算子的开发;
- 业务框架:基于Protobuf定制请求接口,基于有限DAG定制业务逻辑,并行化调度;
- 模型框架:CPU/FPGA/GPU等硬件异构,多模型间异步优先级调度,新引擎灵活扩展,配置化驱动;
- 用户接口:搭建服务=定义proto文件+实现/复用Op+撰写配置,支持sdk/http请求;
## 名词解释
- 预测引擎:对PaddlePaddle/Abacus/Tensorflow等各种推理计算Lib的封装,屏蔽预测模型动态Reload细节,对上层暴露统一的预测接口;
- 预测模型:由离线训练框架生成、在线预测引擎加载的数据文件或目录,以PaddleFluid模型为例,通常包括拓扑文件和参数文件;
- Op 算子:Paddle-serving对在线(预处理/后处理等)业务逻辑的最小粒度封装,框架提供OpWithChannel和OpWithChannelAndConf这两种常用的Op基类;框架默认实现通用Op算子;
- Node:由某个Op算子类结合参数配置组成的Op算子实例,也是Workflow中的一个执行单元;
- DAG/Workflow:由若干个相互依赖的Node组成,每个Node均可通过特定接口获得Request对象,节点Op通过依赖关系获得其前置Op的输出对象,最后一个Node的输出默认就是Response对象;
- Service:对一次pv的请求封装,可配置若干条Workflow,彼此之间复用当前PV的Request对象,然后各自并行/串行执行,最后将Response写入对应的输出slot中;一个Paddle-serving进程可配置多套Service接口,上游根据ServiceName决定当前访问的Service接口。
![图片](http://agroup-bos.cdn.bcebos.com/2e5e3cdcc9426d16e2090e64e7d33098ae5ad826)
## 主要功能
Paddle serving框架为策略工程师提供以下三层面的功能性扩展:
### 模型
- 预测引擎:集成PaddlePaddle、Abacus、Tensorrt、Anakin、Tensorflow等常用机器学习框架的预测Lib;
- 模型种类:支持PaddlePaddle(V1、V2、Fluid)、TensorrtUFF、Anakin、Tensorflow、Caffe等常见模型格式;
- 用户接口:支持模型加载、重载的配置化驱动,不同种类模型的预测接口完全一致;
- 模型调度:支持基于异步线程模型的多模型预估调度,实现异构资源的优先级调度;
### 业务
- 预测流程:通过有限DAG图描述一次预测从Request到Response的业务流程,节点Node是一个最小逻辑单元——OP;
- 预测逻辑:框架封装常用预处理、预测计算、后处理等常用OP,用户通过自定义OP算子实现特化处理逻辑;
### 服务
- RPC:底层通过Baidu-rpc封装网络交互,Server端可配置化启动多个独立Service,框架会搜集Service粒度的详细业务指标,并按照BVar接口对接到Noah等监控平台;
- SDK:基于Baidu-rpc的client进行封装,提供多下游连接管理、可扩展路由策略、可定制参数实验、自动分包等机制,支持同步、半同步、纯异步等交互模式,以及多种兼容协议,所有连接策略均通过配置驱动
# 平台简介
![图片](http://agroup-bos.cdn.bcebos.com/42a0e34a7c6b36976e3932639209fd823d8f25e0)
- [运维API](http://agroup.baidu.com/share/md/e582f543fb574e9b92445286955a976d)
- [预测API](http://agroup.baidu.com/share/md/eb91a51739514319844ceccdb331564c)
## 名词解释
- 用户(User):云平台注册用户,可基于平台Dashboard对账户下的端点信息进行增、删、查、改;
- 端点(Endpoit):对一个预测需求的逻辑抽象,通常包含一到多个服务变体,以方便多版本模型管理;
- 变体(Variant):一套同质化的Paddle-serving集群服务,每个实例起一个Paddle-serving进程;
- 实验(A/B Test):支持变体实验和参数化实验两种模式,变体实验根据Endpoint所属变体流量百分比实现流量随机抽样;参数化实验通过对pv绑定实验参数、由Paddle-serving进程解析参数、选择不同的代码分支进行实验;
## 主要功能
在公有云落地场景为Infinite(天衍)云平台,主要为策略工程师提供以下三方面的全流程托管:
- 统一接入代理:提供代理服务,通过zk和云平台实时同步元信息,支持多模型版本管理和A/B测试路由策略,提供统一入口和标准预测API;
- 自动化部署:对接K8S/Opera等常见PaaS部署平台,支持服务的一键部署、回滚、下线等运维操作,支持endpoint/variant/model等维度的资源管理;
- 可视化运维:对接console、notebook、dashboard等前端工具和页面,满足可视化运维需求;
# 设计文档
- [总体设计文档](http://agroup.baidu.com/paddleserving/view/office/895070)
- [框架详设文档](http://agroup.baidu.com:8964/static/a3/e40876e464ba08ae5de14aa7710cf326456751.pdf?filename=PaddleServing%E6%9C%8D%E5%8A%A1%E6%A1%86%E6%9E%B6%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3v0_1.pdf)
- [平台详设文档](http://agroup.baidu.com/share/office/042a0941579e49adb8c255c8b5e92d51)
# FAQ
1. 如何修改端口配置?
- 使用该框架搭建的服务需要申请一个端口,可以通过以下方式修改端口号:
- 如果在inferservice_file里指定了port:xxx,那么就去申请该端口号;
- 否则,如果在gflags.conf里指定了--port:xxx,那就去申请该端口号;
- 否则,使用程序里指定的默认端口号:8010。
2. 如何在部署的时候配置动态端口?
- 如果使用FCCI部署协议(凤巢检索端内部的部署协议),需要(1)通过inferservice_file指定端口号;(2)修改[Rakefile.opera](http://wiki.baidu.com/pages/viewpage.action?pageId=399979183#id-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E5%86%99production-%E7%BC%96%E5%86%99Rakefile)的dynamic_port_config配置
- `@dynamic_port_config为动态端口配置,向Opera申请名为:name的动态端口,其端口号会被写到:conf文件中的:target配置项。`例子如下:
```
@dynamic_port_config = [
{:name => 'main', :conf => 'framework/service.conf', :target => 'port'}, // 部署时自动向Opera申请端口,服务将会监听这个端口
{:name => 'main', :conf => 'predictor_valid.conf', :target => 'port'}, // valid工具向这个端口发送测试请求,确保服务已正常启动
]
```
// 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 "common/constant.h" #include "common/constant.h"
namespace baidu { namespace baidu {
...@@ -16,16 +30,21 @@ DEFINE_string(logger_path, "./conf", ""); ...@@ -16,16 +30,21 @@ DEFINE_string(logger_path, "./conf", "");
DEFINE_string(logger_file, "log.conf", ""); DEFINE_string(logger_file, "log.conf", "");
DEFINE_string(resource_path, "./conf", ""); DEFINE_string(resource_path, "./conf", "");
DEFINE_string(resource_file, "resource.prototxt", ""); DEFINE_string(resource_file, "resource.prototxt", "");
DEFINE_int32(max_concurrency, 0, "Limit of request processing in parallel, 0: unlimited"); DEFINE_int32(max_concurrency,
DEFINE_int32(num_threads, 0, "Number of pthreads that server runs on, not change if this value <= 0"); 0,
"Limit of request processing in parallel, 0: unlimited");
DEFINE_int32(
num_threads,
0,
"Number of pthreads that server runs on, not change if this value <= 0");
DEFINE_int32(reload_interval_s, 10, ""); DEFINE_int32(reload_interval_s, 10, "");
DEFINE_bool(enable_model_toolkit, false, "enable model toolkit"); DEFINE_bool(enable_model_toolkit, false, "enable model toolkit");
DEFINE_string(enable_protocol_list, "baidu_std", "set protocol list"); DEFINE_string(enable_protocol_list, "baidu_std", "set protocol list");
const char* START_OP_NAME = "startup_op"; const char* START_OP_NAME = "startup_op";
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
// Baidurpc // Baidurpc
BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_INTERNAL_FAILURE, BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_INTERNAL_FAILURE,
......
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_CONSTANT_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_CONSTANT_H //
// 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 "common/inner_common.h" #include "common/inner_common.h"
namespace baidu { namespace baidu {
...@@ -52,8 +63,6 @@ static const size_t MAX_WORKFLOW_NUM_IN_ONE_SERVICE = 20; ...@@ -52,8 +63,6 @@ static const size_t MAX_WORKFLOW_NUM_IN_ONE_SERVICE = 20;
static const uint32_t DEFAULT_CACHE_CAPACITY = 10000; static const uint32_t DEFAULT_CACHE_CAPACITY = 10000;
static const uint32_t DEFAULT_CACHE_UNITSIZE = 8192; static const uint32_t DEFAULT_CACHE_UNITSIZE = 8192;
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_INNER_COMMON_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_INNER_COMMON_H //
// 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 <sys/types.h> #include <error.h>
#include <unistd.h> #include <getopt.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h> #include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <strings.h> #include <strings.h>
#include <getopt.h> #include <sys/types.h>
#include <unistd.h>
#include <typeinfo> #include <typeinfo>
#include <google/protobuf/text_format.h> #include "boost/algorithm/string.hpp" // for boost::split&trim
#include <boost/unordered_map.hpp> #include "boost/function.hpp"
#include <boost/function.hpp> #include "boost/unordered_map.hpp"
#include <boost/algorithm/string.hpp> // for boost::split&trim #include "google/protobuf/text_format.h"
#include <gflags/gflags.h> #include "gflags/gflags.h"
#include <butil/logging.h> #include "brpc/channel.h"
#include <butil/time.h> #include "brpc/policy/giano_authenticator.h"
#include <butil/object_pool.h> #include "brpc/server.h"
#include <brpc/channel.h> #include "bthread/bthread.h"
#include <brpc/server.h> #include "butil/logging.h"
#include <brpc/policy/giano_authenticator.h> #include "butil/object_pool.h"
#include <bthread/bthread.h> #include "butil/time.h"
#include <error.h>
#include "server_configure.pb.h" #include "configure/include/configure_parser.h"
#include "configure_parser.h" #include "configure/server_configure.pb.h"
#include "common/utils.h"
#include "common/types.h"
#include "common/constant.h" #include "common/constant.h"
#include "common/types.h"
#endif #include "common/utils.h"
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_MACROS_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_MACROS_H //
// 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 "common/inner_common.h" #include "common/inner_common.h"
namespace baidu { namespace baidu {
...@@ -61,8 +73,6 @@ namespace predictor { ...@@ -61,8 +73,6 @@ namespace predictor {
#endif #endif
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TYPES_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_TYPES_H //
// 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
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace predictor { namespace predictor {
...@@ -14,8 +26,6 @@ struct Sequence { ...@@ -14,8 +26,6 @@ struct Sequence {
Size size; Size size;
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif // BAIDU_PADDLE_SERVING_PREDICTOR_TYPES_H
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_UTILS_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_UTILS_H //
// Licensed under the Apache License, Version 2.0 (the "License");
#include "common/macros.h" // 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 <string>
#include "common/inner_common.h" #include "common/inner_common.h"
#include "common/macros.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace predictor { namespace predictor {
class TimerFlow { class TimerFlow {
public: public:
static const int MAX_SIZE = 1024; static const int MAX_SIZE = 1024;
TimerFlow() { TimerFlow() { init(); }
init();
}
void init() { void init() {
_csize = 0; _csize = 0;
...@@ -23,15 +34,13 @@ public: ...@@ -23,15 +34,13 @@ public:
_auto = false; _auto = false;
} }
TimerFlow(const char* name) : _csize(0), _name(name) { explicit TimerFlow(const char* name) : _csize(0), _name(name) {
_last = _start = butil::cpuwide_time_us(); _last = _start = butil::cpuwide_time_us();
_auto = true; _auto = true;
_started = true; _started = true;
} }
void set_name(const char* name) { void set_name(const char* name) { _name = name; }
_name = name;
}
void start() { void start() {
_last = _start = butil::cpuwide_time_us(); _last = _start = butil::cpuwide_time_us();
...@@ -45,10 +54,8 @@ public: ...@@ -45,10 +54,8 @@ public:
} }
uint64_t now = butil::cpuwide_time_us(); uint64_t now = butil::cpuwide_time_us();
if (!appendf("%s:%lu|", tag, now - _last)) { if (!appendf("%s:%lu|", tag, now - _last)) {
LOG(WARNING) LOG(WARNING) << "Failed check timer: " << _name << ", value = [" << tag
<< "Failed check timer: " << _name << ":" << (now - _last) << "]!";
<< ", value = [" << tag << ":"
<< (now - _last) << "]!";
return false; return false;
} }
...@@ -56,9 +63,7 @@ public: ...@@ -56,9 +63,7 @@ public:
return true; return true;
} }
std::string info() { std::string info() { return std::string(_buf); }
return std::string(_buf);
}
void end() { void end() {
uint64_t now = butil::cpuwide_time_us(); uint64_t now = butil::cpuwide_time_us();
...@@ -74,14 +79,13 @@ public: ...@@ -74,14 +79,13 @@ public:
} }
uint64_t now = butil::cpuwide_time_us(); uint64_t now = butil::cpuwide_time_us();
if (appendf("total:%lu,%s", now - _start, _name)) { if (appendf("total:%lu,%s", now - _start, _name)) {
LOG(INFO) LOG(INFO) << " " << _name << "_tc=[" << _buf << "]";
<< " " << _name << "_tc=[" << _buf << "]";
} else { } else {
LOG(WARNING) << "Failed dump time_info[" << _name << "]"; LOG(WARNING) << "Failed dump time_info[" << _name << "]";
} }
} }
private: private:
bool appendf(const char* fmt, ...) { bool appendf(const char* fmt, ...) {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
...@@ -92,13 +96,14 @@ private: ...@@ -92,13 +96,14 @@ private:
return false; return false;
} }
_csize += bytes; _csize += bytes;
} CATCH_ANY_AND_RET(false); }
CATCH_ANY_AND_RET(false);
va_end(ap); va_end(ap);
return true; return true;
} }
private: private:
char _buf[1024]; char _buf[1024];
int _csize; int _csize;
uint64_t _start; uint64_t _start;
...@@ -108,47 +113,37 @@ private: ...@@ -108,47 +113,37 @@ private:
bool _auto; bool _auto;
}; };
template<bool flag> template <bool flag>
struct derived_from_message {}; struct derived_from_message {};
template<typename T, typename TBase> template <typename T, typename TBase>
class TIsDerivedFromB { class TIsDerivedFromB {
private: private:
static uint8_t check(TBase*) { static uint8_t check(TBase*) { return 1; }
return 1;
}
static uint32_t check(void*) { static uint32_t check(void*) { return 0; }
return 0;
}
public: public:
enum { enum {
// function call cannot apprear in a constant-expression // function call cannot apprear in a constant-expression
RESULT = (sizeof(uint8_t) == sizeof(check((T*)(NULL)))), RESULT = (sizeof(uint8_t) == sizeof(check(reinterpret_cast<T*>(NULL)))),
}; };
}; };
template<typename TBase> template <typename TBase>
class IsDerivedFrom { class IsDerivedFrom {
private: private:
static bool check(TBase*) { static bool check(TBase*) { return true; }
return true;
}
static bool check(void*) { static bool check(void*) { return false; }
return false;
}
public: public:
template<typename T> template <typename T>
static bool yes(T* x) { static bool yes(T* x) {
return check(x); return check(x);
} }
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif
#!/bin/bash
# 启动路径
start_path="$(pwd)"
sh build.sh stop
# 定位到cts目录下
cd "$(dirname "$0")"/
if [[ "x"$@ = x*--module_name=* ]]
then
all_arg=$@
tmp=${all_arg##*--module_name=}
mod_name=${tmp%% *}
sed -i "/^run_mod=/s/run_mod.*/run_mod=$mod_name/" install-all.conf
else
sed -i "/^run_mod=/s/run_mod.*/run_mod=lr_engine/" install-all.conf
fi
env_num=`grep env_num install-all.conf | awk -F '=' '{print $2}'`
# 设置环境变量
export PATH="$(pwd)"/frame/tools/python27/bin:$PATH
export PYTHONPATH="$(pwd)"
alias | grep "alias cp=" >/dev/null
if [ $? -eq 0 ];then
unalias cp
fi
# 回到启动路径,执行main.py
cd "$start_path"
mem_free=`free -m | awk '{print $4}'| head -3 | awk 'END{print}'`
let thread_max=$mem_free/5000
if [ $thread_max -eq 0 ];then
echo "系统内存不足, 不能运行任何case"
exit 1
fi
if [ $thread_max -lt $env_num ];then
env_num=$thread_max
echo "目前系统内存最多支持运行$env_num个线程"
fi
temp_args="--paral=$env_num"
python "$(dirname "$0")"/control/main.py $temp_args $@
ret=$?
sh build.sh stop
if [ $ret -ne 0 ]
then
exit 1
fi
#!/bin/bash
function cfont()
{
while (($#!=0))
do
case $1 in
-b)
echo -ne " ";
;;
-t)
echo -ne "\t";
;;
-n)
echo -ne "\n";
;;
-black)
echo -ne "\033[30m";
;;
-red)
echo -ne "\033[31m";
echo -ne "\033[1m";
;;
-green)
echo -ne "\033[32m";
echo -ne "\033[1m";
;;
-yellow)
echo -ne "\033[33m";
;;
-blue)
echo -ne "\033[34m";
echo -ne "\033[1m";
;;
-purple)
echo -ne "\033[35m";
;;
-cyan)
echo -ne "\033[36m";
echo -ne "\033[1m";
;;
-white|-gray)
echo -ne "\033[37m";
;;
-reset)
echo -ne "\033[0m";
;;
-h|-help|--help)
echo "Usage: cfont -color1 message1 -color2 message2 ...";
echo "eg: cfont -red [ -blue message1 message2 -red ]";
;;
*)
echo -ne "$1"
;;
esac
shift
done
echo -ne "\033[0m";
}
cur_path=`pwd`
work_root=${cur_path%%/baidu/*}
CITOOLS="${work_root}/baidu/fengchao-qa/citools"
if [ ! -e ${CITOOLS}/lib/localbuild_lib.sh ];then
cfont -blue "=============== localbuild_lib.sh is not exist, downloading ...================" -n
git clone ssh://git@icode.baidu.com:8235/baidu/fengchao-qa/citools $CITOOLS >/dev/null
fi
source ${CITOOLS}/lib/localbuild_lib.sh
function get_framework_baseenv()
{
onlineFtp="ftp://tc-orp-app2.tc.baidu.com/home/heqing"
wgetOptions="--tries=3 --retry-connrefused -r -l0 -nv --limit-rate=50m -nH"
cfont -blue "##################################################" -n ;
cfont -blue "### build pdserving_framework xts base env ###" -n ;
cfont -blue "##################################################" -n ;
cfont -reset;
run_path="$(grep "run_path" "./install-all.conf" | cut -d "=" -f 2)"
cd $run_path
wget $wgetOptions --cut-dirs=4 "$onlineFtp"/scmbak/pdserving/framework_tester -o wget.log
ret=$?
retry=0
while [[ $retry -lt 3 ]]; do
if [[ $ret -eq 0 ]];then
break;
fi
wget $wgetOptions --cut-dirs=4 "$onlineFtp"/scmbak/pdserving/framework_tester -o wget.log
ret=$?
((retry++))
done
[[ $ret -ne 0 ]] && return 1
cfont -blue "[XTS] " -green "[ finish download: pdserving-framework ]" -n
cd -
return 0
}
# 搭建cts环境
function build_ctsenv()
{
# 搭建cts环境
if [ -z $1 ]; then
ENV_NUM=0
else
ENV_NUM=$1
fi
#更新安装配置设置
hostname=$(uname -n)
username="$(echo "`whoami`" | awk '{print $1}')"
LIBPATH=${PWD}/lib
echo "libpath is : $LIBPATH"
# 生成install-all.conf
{
echo "[config]"
echo "host=$hostname"
echo "user=$username"
echo "passwd=CAPHI2008"
echo "env_file=${PWD}/envfile"
echo "lib_path=$LIBPATH"
echo "run_path=${PWD}/run_env"
echo "env_num=$ENV_NUM"
} > ./install-all.conf
# 安装cts环境
{
cfont -blue "============= predictor env install =============" -n
rm -rf run_env && mkdir -p run_env
echo "current path is :${cur_path}"
#get_framework_baseenv
#if [ $? -ne 0 ]; then
# echo "pdserving-framework is not ready!!!"
# exit 1
#fi
mkdir -p run_env/predictor/bin
mkdir -p run_env/predictor/conf
# 拷贝pdserving到环境中
[[ -e ../output/bin/pdserving ]] && cp -rf ../output/bin/pdserving run_env/predictor/bin/predictor
[[ -e ../output/lib ]] && cp -rf ../output/lib/ run_env/predictor/
[[ -e ../conf ]] && cp -rf ../conf/* run_env/predictor/conf/
#搭建并行环境
if [ $ENV_NUM -ne 0 ]; then
cfont -blue "=============== build multi env ===============" -n
mkdir -p ${PWD}/run_env/1
mv -f ${PWD}/run_env/framework_tester ${PWD}/run_env/1/framework_tester
mv -f ${PWD}/run_env/model ${PWD}/run_env/1/model
mv -f ${PWD}/run_env/dict ${PWD}/run_env/1/dict
for ((i=2; i<=$ENV_NUM; i=i+1))
do
cp -rf ${PWD}/run_env/1 ${PWD}/run_env/$i
done
fi
}
#安装XTS环境
{
echo "now pwd is :`pwd`"
cfont -blue "=============== XTS(cts) install ================" -n
svn co https://svn.baidu.com/general-test/trunk/xts/frame frame> /dev/null
svn co https://svn.baidu.com/general-test/trunk/xts/im/core/control control>/dev/null
echo "now dir list is :`ls`"
cd lib
svn co https://svn.baidu.com/general-test/trunk/xts/im/core/lib/commonlib commonlib>/dev/null
cd -
}
cfont -blue "[XTS] " -green "[ finish XTS(cts) install ]" -n
onlineFtp="ftp://tc-orp-app2.tc.baidu.com/home/heqing"
wgetOptions="--tries=3 --retry-connrefused -r -l0 -nv --limit-rate=50m -nH"
#安装bidinfo 和基础protolib
{
cd lib
[[ -e bidinfo ]] && rm -rf bidinfo
[[ -e protolib ]] && rm -rf protolib
[[ -e pluginlib ]] && rm -rf pluginlib
wget $wgetOptions --cut-dirs=5 "$onlineFtp"/scmbak/common_lib/pdserving_cts/bidinfo -o wget.log
wget $wgetOptions --cut-dirs=5 "$onlineFtp"/scmbak/common_lib/pdserving_cts/protolib -o wget.log
wget $wgetOptions --cut-dirs=6 "$onlineFtp"/scmbak/common_lib/pdserving_cts/framework/pluginlib -o wget.log
cd -
}
#安装protolib
{
cfont -blue "============== protoc install ==================" -n
[[ -e protoc_tools ]] && rm -rf protoc_tools
wget $wgetOptions --cut-dirs=5 "$onlineFtp"/scmbak/common_lib/pdserving_cts/protoc_tools -o wget.log
[[ -e ../proto ]] && cp -rf ../proto/* ./protoc_tools/proto/
cd protoc_tools
chmod +x ./protobuf-2.4.1/bin/protoc
chmod +x ./protobuf-2.4.1/lib/*
[[ -e protolib ]] && rm -rf protolib
mkdir ./protolib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/protobuf-2.4.1/lib
./protobuf-2.4.1/bin/protoc -I=./proto --python_out=./protolib/ ./proto/*.proto
cd -
cp ./protoc_tools/protolib/*.py ./lib/protolib/
}
cfont -reset
return 0
}
function get_pid
{
local prog=$1
local user=$2
local prog_path=$3
local ret=-1
local trash_path="/home/$(echo "`whoami`" | awk '{print $1}')/.__trash/"
pids=`pgrep $prog -u $user`
for pid in $pids
do
tmp_path=`ls -l /proc/$pid/exe 2>/dev/null | awk '{print $NF}'`
if [ "$tmp_path" == "$prog_path" ] || [ ! -e $tmp_path ] || [ 0 == `echo $tmp_path | grep -qs $trash_path;echo $?` ]
then
echo $pid
ret=0
fi
done
return $ret
}
function kill_prog()
{
name=$1
username=$2
prog_path=$3
pids=`get_pid $name $username $prog_path`
echo $pids>/dev/null
if [ $? -eq 0 ] ;then
for pid in $pids
do
#echo "$name,$pid"
kill -9 $pid
done
fi
}
function kill_predictor_prog()
{
username="$(echo "`whoami`" | awk '{print $1}')"
if [ -f install-all.conf ]
then
env_num=`grep env_num= install-all.conf|awk -F '=' '{print $2}'`
else
env_num=0
fi
for ((i=0; i<=$env_num; i=i+1))
do
if [ $i -eq 0 ]
then
run_path="${PWD}/run_env"
else
run_path="${PWD}/run_env/$i"
fi
kill_prog predictor $username $run_path/framework_tester/bin/predictor
done
}
function clean_ctsenv()
{
rm -rf install-all.conf ccover
rm -rf run_env fail_env output log frame control lib/commonlib lib/protolib
return 0
}
if [ $# -eq 1 ] && [ $1 == "clean" ]
then
clean_ctsenv
exit 0
fi
if [ $# -eq 1 ] && [ $1 == "stop" ]
then
kill_predictor_prog
exit 0
fi
clean_ctsenv
build_ctsenv "$1"
exit $?
#!/usr/bin/env python
# -*- coding:gbk -*-
"""
case created by templete
"""
import sys
sys.path.append(r'./lib/protolib')
print("sys path is : %s " % str(sys.path))
import os
import json
import commands
from lib.protolib.dense_service_pb2 import Request
from lib.protolib.dense_service_pb2 import Response
from lib.pluginlib.plugin_util import Util as ut
from lib.pluginlib.plugin_case import PluginCase
from lib.pluginlib.plugin_module import PluginModule
from lib.pluginlib.plugin_apistub import ApiStub
class TestDenseService(PluginCase):
"""test wtitleq case class"""
OWNER="zhangwenbo03"
quick=['ALL']
low=[]
daily=[]
ignorelist=[]
RESTART=True
def setUp(self):
"""setup something before run case"""
pass
def tearDown(self):
"""tear down after run case"""
self.t.stop()
print "stop finished"
pass
def testDemoCase(self):
"""demo case"""
req = Request()
denseIns = req.instances.add()
denseIns.features.append(10)
denseIns.features.append(13)
denseIns.features.append(200)
service = "BuiltinDenseFormatService"
type = "debug"
ut_obj = ut()
dict_val = ut_obj.pb2dict(req)
json_val = ut_obj.dict2json(dict_val)
self.t.restart()
self.t.tester.sendJsonData(json_val, service, type)
print "execute demo case"
"""plugin register """
from lib.plugin_tester import *
#!/usr/bin/env python
# -*- coding:gbk -*-
"""
注册类:RegxxxConfData,RegxxxReq,RegxxxXbox,RegxxxAd,xxx为组件名
"""
from lib.pluginlib.plugin_common import ConfData
from lib.pluginlib.plugin_common import TreeConfData
from lib.pluginlib.plugin_common import CommonIndex
class RegpredictorConfData(object):
"""
注册wtitleq组件的conf和data文件
"""
def __init__(self, path):
self.path = path
self.conf = {}
self.data = {}
self.conf['ub'] = ConfData(path=self.path + "/conf/ub.conf", connect_flag=":")
self.data['lr_model'] = CommonIndex(path=self.path + \
'/data/lr-model/wtitleq_model_file.sign',
col_list=['key', 'value'],
format='B')
class RegpredictorReq(object):
"""
注册wtitleq组件的默认请求
"""
def __init__(self):
self.plugin_term = {}
cmd_tag = 'cmd_tag0'
query_schema_list = []
query_value_list = []
pair_schema_list = ['query',
'wadptid',
'wbwsid',
'omit_buf',
'title',
'desc',
'cmatch',
'bidword',
'dynamic_new_title']
pair_value_list = ['鲜花',
'0',
'3',
'鲜花',
'鲜花%2C本地实体鲜花店100%25保证%21',
'鲜花品质100%25%2C主城最快2小时送到%2C全天24时在线订花%21市区内免费送花上门%21鲜%2E%2E',
'223',
'鲜花',
'美丽鲜花']
cmd_str = '/titleq/wise/ctr'
req_term = {"query_schema": query_schema_list,
"pair_schema": pair_schema_list,
"query_value": query_value_list,
"pair_value": pair_value_list,
"cmd": cmd_str}
self.plugin_term.update({cmd_tag: req_term})
self.plugin_list = self.plugin_term.keys()
class RegpredictorNewXbox(object):
"""
注册wtitleq组件的xbox
"""
def __init__(self):
self.need_xbox = True
self.stub_conf = 'xboxstub.conf'
self.stub_name = 'xboxstub'
self.conf_list = ['xbox-wtitleq_pegasus.conf']
class RegpredictorAd(object):
"""
注册wtitleq组件是否需要构造广告库
"""
def __init__(self):
self.need_adstub = False
// 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 #pragma once
#include <butil/atomicops.h>
#include <errno.h> #include <errno.h>
#include <vector> #include <algorithm>
#include <deque> #include <deque>
#include <butil/atomicops.h> #include <vector>
#include "common/inner_common.h" #include "common/inner_common.h"
#include "framework/infer_data.h" #include "framework/infer_data.h"
#include "framework/memory.h" #include "framework/memory.h"
...@@ -13,12 +28,12 @@ ...@@ -13,12 +28,12 @@
namespace im { namespace im {
namespace bsf { namespace bsf {
template<> template <>
struct Task<baidu::paddle_serving::predictor::Tensor, struct Task<baidu::paddle_serving::predictor::Tensor,
baidu::paddle_serving::predictor::Tensor> { baidu::paddle_serving::predictor::Tensor> {
typedef Task<baidu::paddle_serving::predictor::Tensor, typedef Task<baidu::paddle_serving::predictor::Tensor,
baidu::paddle_serving::predictor::Tensor> TaskT; baidu::paddle_serving::predictor::Tensor>
TaskT;
typedef baidu::paddle_serving::predictor::Tensor Tensor; typedef baidu::paddle_serving::predictor::Tensor Tensor;
typedef baidu::paddle_serving::predictor::Tensor InType; typedef baidu::paddle_serving::predictor::Tensor InType;
typedef baidu::paddle_serving::predictor::Tensor OutType; typedef baidu::paddle_serving::predictor::Tensor OutType;
...@@ -27,8 +42,7 @@ struct Task<baidu::paddle_serving::predictor::Tensor, ...@@ -27,8 +42,7 @@ struct Task<baidu::paddle_serving::predictor::Tensor,
typedef baidu::paddle_serving::predictor::BatchTensor OutArrayT; typedef baidu::paddle_serving::predictor::BatchTensor OutArrayT;
struct Segment { struct Segment {
Segment(void* p, size_t b, size_t s) Segment(void* p, size_t b, size_t s) : ptr(p), begin(b), size(s) {}
: ptr(p), begin(b), size(s) {}
void* ptr; void* ptr;
size_t begin; size_t begin;
size_t size; size_t size;
...@@ -75,11 +89,10 @@ struct Task<baidu::paddle_serving::predictor::Tensor, ...@@ -75,11 +89,10 @@ struct Task<baidu::paddle_serving::predictor::Tensor,
} }
}; };
template<> template <>
class BatchTasks<Task< class BatchTasks<Task<baidu::paddle_serving::predictor::Tensor,
baidu::paddle_serving::predictor::Tensor, baidu::paddle_serving::predictor::Tensor>> {
baidu::paddle_serving::predictor::Tensor> > { public:
public:
typedef baidu::paddle_serving::predictor::Tensor Tensor; typedef baidu::paddle_serving::predictor::Tensor Tensor;
typedef baidu::paddle_serving::predictor::Tensor InType; typedef baidu::paddle_serving::predictor::Tensor InType;
typedef baidu::paddle_serving::predictor::Tensor OutType; typedef baidu::paddle_serving::predictor::Tensor OutType;
...@@ -87,15 +100,16 @@ public: ...@@ -87,15 +100,16 @@ public:
typedef baidu::paddle_serving::predictor::MempoolWrapper MempoolWrapper; typedef baidu::paddle_serving::predictor::MempoolWrapper MempoolWrapper;
typedef Task<baidu::paddle_serving::predictor::Tensor, typedef Task<baidu::paddle_serving::predictor::Tensor,
baidu::paddle_serving::predictor::Tensor> TaskT; baidu::paddle_serving::predictor::Tensor>
TaskT;
typedef TaskMeta<TaskT> TaskMetaT; typedef TaskMeta<TaskT> TaskMetaT;
typedef TaskT::InArrayT InArrayT; typedef TaskT::InArrayT InArrayT;
typedef TaskT::OutArrayT OutArrayT; typedef TaskT::OutArrayT OutArrayT;
BatchTasks(size_t batch_size, bool batch_align = false) explicit BatchTasks(size_t batch_size, bool batch_align = false)
: _batch_size(batch_size) : _batch_size(batch_size),
, _rem_size(batch_size) _rem_size(batch_size),
, _batch_align(batch_align) { _batch_align(batch_align) {
_batch_in.clear(); _batch_in.clear();
_batch_out.clear(); _batch_out.clear();
_tasks.clear(); _tasks.clear();
...@@ -107,8 +121,9 @@ public: ...@@ -107,8 +121,9 @@ public:
_tasks.clear(); _tasks.clear();
} }
static bool check_valid( static bool check_valid(const InArrayT& in,
const InArrayT& in, OutArrayT& out, bool align) { OutArrayT& out, // NOLINT
bool align) { // NOLINT
if (align) { if (align) {
if (out.count() <= 0 || out.size() <= 0) { if (out.count() <= 0 || out.size() <= 0) {
LOG(ERROR) << "Out tensor is empty, when aligned"; LOG(ERROR) << "Out tensor is empty, when aligned";
...@@ -116,7 +131,8 @@ public: ...@@ -116,7 +131,8 @@ public:
} }
if (out.size() != in.size()) { if (out.size() != in.size()) {
LOG(ERROR) << "In/Out tensor size not eq: " << out.size() << "!=" << in.size(); LOG(ERROR) << "In/Out tensor size not eq: " << out.size()
<< "!=" << in.size();
return false; return false;
} }
...@@ -127,7 +143,8 @@ public: ...@@ -127,7 +143,8 @@ public:
} }
if (out.size() != out[fi].shape0()) { if (out.size() != out[fi].shape0()) {
LOG(ERROR) << "Shape0 not consistency, " << out.size() << "!=" << out[fi].shape0() << ", " << fi; LOG(ERROR) << "Shape0 not consistency, " << out.size()
<< "!=" << out[fi].shape0() << ", " << fi;
return false; return false;
} }
} }
...@@ -156,13 +173,13 @@ public: ...@@ -156,13 +173,13 @@ public:
void merge_input() { void merge_input() {
if (_tasks.size() <= 0 || _tasks[0].task->in->count() <= 0) { if (_tasks.size() <= 0 || _tasks[0].task->in->count() <= 0) {
return ; return;
} }
if (_tasks.size() == 1 && !_batch_align) { if (_tasks.size() == 1 && !_batch_align) {
TaskMetaT& tm = _tasks[0]; TaskMetaT& tm = _tasks[0];
_batch_in = *(tm.task->in); _batch_in = *(tm.task->in);
return ; return;
} }
merge_tensor(true); merge_tensor(true);
...@@ -171,30 +188,30 @@ public: ...@@ -171,30 +188,30 @@ public:
void merge_output() { void merge_output() {
if (_batch_align) { if (_batch_align) {
if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) { if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) {
return ; return;
} }
} }
if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) { if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) {
return ; return;
} }
TaskMetaT& tm = _tasks[0]; TaskMetaT& tm = _tasks[0];
if (_tasks.size() == 1 && !_batch_align) { if (_tasks.size() == 1 && !_batch_align) {
_batch_out = *(tm.task->out); _batch_out = *(tm.task->out);
return ; return;
} }
if (tm.task->out->size() <= 0) { if (tm.task->out->size() <= 0) {
// shape is empty // shape is empty
_batch_out = *(tm.task->out); _batch_out = *(tm.task->out);
return ; return;
} }
if ((*tm.task->out)[0].data.data() == 0 if ((*tm.task->out)[0].data.data() == 0 ||
|| (*tm.task->out)[0].data.size() == 0) { (*tm.task->out)[0].data.size() == 0) {
_batch_out = *(tm.task->out); _batch_out = *(tm.task->out);
return ; return;
} }
merge_tensor(false); merge_tensor(false);
...@@ -228,11 +245,10 @@ public: ...@@ -228,11 +245,10 @@ public:
size_t ins_byte = ins_ele_count * head.ele_byte(); size_t ins_byte = ins_ele_count * head.ele_byte();
size_t tensor_byte = tensor_ele_count * head.ele_byte(); size_t tensor_byte = tensor_ele_count * head.ele_byte();
void* data_buf void* data_buf = MempoolWrapper::instance().malloc(tensor_byte);
= MempoolWrapper::instance().malloc(tensor_byte);
if (!data_buf) { if (!data_buf) {
LOG(ERROR) << "Malloc failed, size: " << tensor_byte; LOG(ERROR) << "Malloc failed, size: " << tensor_byte;
return ; return;
} }
size_t data_byte = 0; size_t data_byte = 0;
...@@ -240,23 +256,27 @@ public: ...@@ -240,23 +256,27 @@ public:
TaskMetaT& tm = _tasks[ti]; TaskMetaT& tm = _tasks[ti];
size_t acc_byte = ins_byte * (tm.end - tm.begin); size_t acc_byte = ins_byte * (tm.end - tm.begin);
if (data_byte + acc_byte > tensor_byte) { if (data_byte + acc_byte > tensor_byte) {
LOG(ERROR) << "Invalid bytes: " << data_byte << " + " << acc_byte << " >= " << tensor_byte; LOG(ERROR) << "Invalid bytes: " << data_byte << " + " << acc_byte
return ; << " >= " << tensor_byte;
return;
} }
const Tensor& tensor = (*(tm.task->get(is_in)))[fi]; const Tensor& tensor = (*(tm.task->get(is_in)))[fi];
memcpy((char *)data_buf + data_byte, memcpy(
(char *)(tensor.data.data()) + tm.begin * ins_byte, reinterpret_cast<char*>(data_buf) + data_byte,
reinterpret_cast<char*>(tensor.data.data()) + tm.begin * ins_byte,
acc_byte); acc_byte);
data_byte += acc_byte; data_byte += acc_byte;
} }
if (data_byte != tensor_byte) { if (data_byte != tensor_byte) {
LOG(ERROR) << "Invalid tensor byte: " << data_byte << " != " << tensor_byte; LOG(ERROR) << "Invalid tensor byte: " << data_byte
return ; << " != " << tensor_byte;
return;
} }
batch_tensor.data = DataBuf((char *)data_buf, tensor_byte); batch_tensor.data =
DataBuf(reinterpret_cast<char*>(data_buf), tensor_byte);
if (is_in) { if (is_in) {
_batch_in.push_back(batch_tensor); _batch_in.push_back(batch_tensor);
} else { } else {
...@@ -264,14 +284,15 @@ public: ...@@ -264,14 +284,15 @@ public:
} }
} }
LOG(INFO) << "merge input(" << is_in << ") samples: " LOG(INFO) << "merge input(" << is_in << ") samples: " << batch_size
<< batch_size << " from " << _tasks.size() << " pvs"; << " from " << _tasks.size() << " pvs";
} }
void notify_tasks() { void notify_tasks() {
if (_batch_out.size() != _batch_in.size()) { if (_batch_out.size() != _batch_in.size()) {
LOG(ERROR) << "batch size not consistency: " << _batch_out.size() << " != " << _batch_in.size(); LOG(ERROR) << "batch size not consistency: " << _batch_out.size()
return ; << " != " << _batch_in.size();
return;
} }
size_t tensor_count = _batch_out.count(); size_t tensor_count = _batch_out.count();
...@@ -283,8 +304,8 @@ public: ...@@ -283,8 +304,8 @@ public:
ins_byte *= tensor.shape[si]; ins_byte *= tensor.shape[si];
} }
for (size_t ti = 0, bi = 0, add = 0; for (size_t ti = 0, bi = 0, add = 0; ti < _tasks.size();
ti < _tasks.size(); ++ti, bi += add) { ++ti, bi += add) {
OutArrayT* dst = _tasks[ti].task->out; OutArrayT* dst = _tasks[ti].task->out;
add = _tasks[ti].end - _tasks[ti].begin; add = _tasks[ti].end - _tasks[ti].begin;
size_t offset_src = ins_byte * bi; size_t offset_src = ins_byte * bi;
...@@ -293,8 +314,10 @@ public: ...@@ -293,8 +314,10 @@ public:
if (_batch_align) { // merge all batchs if (_batch_align) { // merge all batchs
size_t offset_dst = ins_byte * _tasks[ti].begin; size_t offset_dst = ins_byte * _tasks[ti].begin;
void* ptr = const_cast<void*>((*dst)[fi].data.data()); void* ptr = const_cast<void*>((*dst)[fi].data.data());
memcpy((char *)ptr + offset_dst, memcpy(
(char *)(_batch_out[fi].data.data()) + offset_src, add_byte); reinterpret_cast<char*>(ptr) + offset_dst,
reinterpret_cast<char*>(_batch_out[fi].data.data()) + offset_src,
add_byte);
} else { // overwrite } else { // overwrite
if (dst->count() <= 0) { if (dst->count() <= 0) {
dst->push_back(_batch_out[fi]); dst->push_back(_batch_out[fi]);
...@@ -304,7 +327,8 @@ public: ...@@ -304,7 +327,8 @@ public:
(*dst)[fi].shape[0] = add; (*dst)[fi].shape[0] = add;
(*dst)[fi].data = DataBuf( (*dst)[fi].data = DataBuf(
(char *)(_batch_out[fi].data.data()) + offset_src, add_byte); reinterpret_cast<char*>(_batch_out[fi].data.data()) + offset_src,
add_byte);
} }
} }
} }
...@@ -319,26 +343,19 @@ public: ...@@ -319,26 +343,19 @@ public:
if ((index + add) >= task->in->size()) { if ((index + add) >= task->in->size()) {
char c = 0; char c = 0;
while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) { while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) {
;
} }
butil::return_object(task); butil::return_object(task);
} }
} }
} }
const typename TaskT::InArrayT& in() const { const typename TaskT::InArrayT& in() const { return _batch_in; }
return _batch_in;
}
typename TaskT::OutArrayT& out() { typename TaskT::OutArrayT& out() { return _batch_out; }
return _batch_out;
}
size_t task_size() { size_t task_size() { return _tasks.size(); }
return _tasks.size();
}
private: private:
std::vector<TaskMetaT> _tasks; std::vector<TaskMetaT> _tasks;
InArrayT _batch_in; InArrayT _batch_in;
OutArrayT _batch_out; OutArrayT _batch_out;
......
// 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 #pragma once
#include <boost/bind.hpp>
#include <butil/atomicops.h> #include <butil/atomicops.h>
#include <sys/syscall.h>
#include <boost/bind.hpp>
#include "common/inner_common.h" #include "common/inner_common.h"
#include <sys/syscall.h>
namespace im { namespace im {
namespace bsf { namespace bsf {
template<typename TaskT> template <typename TaskT>
void* TaskExecutor<TaskT>::thread_entry(void* args) { void* TaskExecutor<TaskT>::thread_entry(void* args) {
ThreadContext<TaskT>* context = static_cast<ThreadContext<TaskT>*>(args); ThreadContext<TaskT>* context = static_cast<ThreadContext<TaskT>*>(args);
TaskExecutor<TaskT>* executor = static_cast<TaskExecutor<TaskT>*>(context->executor); TaskExecutor<TaskT>* executor =
static_cast<TaskExecutor<TaskT>*>(context->executor);
executor->work(context); executor->work(context);
return NULL; return NULL;
} }
template<typename TaskT> template <typename TaskT>
int TaskExecutor<TaskT>::start(uint32_t thread_num, uint32_t init_timeout_sec) { int TaskExecutor<TaskT>::start(uint32_t thread_num, uint32_t init_timeout_sec) {
_stop = false; _stop = false;
if (!_thread_contexts.empty()) { if (!_thread_contexts.empty()) {
...@@ -42,7 +56,9 @@ int TaskExecutor<TaskT>::start(uint32_t thread_num, uint32_t init_timeout_sec) { ...@@ -42,7 +56,9 @@ int TaskExecutor<TaskT>::start(uint32_t thread_num, uint32_t init_timeout_sec) {
int rc = THREAD_CREATE( int rc = THREAD_CREATE(
&contexts[i].tid, NULL, &TaskExecutor::thread_entry, &contexts[i]); &contexts[i].tid, NULL, &TaskExecutor::thread_entry, &contexts[i]);
if (rc != 0) { if (rc != 0) {
LOG(ERROR) << "failed to create BSF worker thread: index=" << i << ", rc=" << rc << ", errno=" << errno << ":" << strerror(errno); LOG(ERROR) << "failed to create BSF worker thread: index=" << i
<< ", rc=" << rc << ", errno=" << errno << ":"
<< strerror(errno);
return -1; return -1;
} }
...@@ -90,7 +106,7 @@ int TaskExecutor<TaskT>::start(uint32_t thread_num, uint32_t init_timeout_sec) { ...@@ -90,7 +106,7 @@ int TaskExecutor<TaskT>::start(uint32_t thread_num, uint32_t init_timeout_sec) {
return -1; return -1;
} }
template<typename TaskT> template <typename TaskT>
void TaskExecutor<TaskT>::stop() { void TaskExecutor<TaskT>::stop() {
_stop = true; _stop = true;
for (size_t i = 0; i < _thread_contexts.size(); ++i) { for (size_t i = 0; i < _thread_contexts.size(); ++i) {
...@@ -103,9 +119,9 @@ void TaskExecutor<TaskT>::stop() { ...@@ -103,9 +119,9 @@ void TaskExecutor<TaskT>::stop() {
_thread_contexts.clear(); _thread_contexts.clear();
} }
template<typename TaskT> template <typename TaskT>
TaskHandler<TaskT> TaskExecutor<TaskT>::schedule( TaskHandler<TaskT> TaskExecutor<TaskT>::schedule(const InArrayT& in,
const InArrayT& in, OutArrayT& out) { OutArrayT& out) { // NOLINT
TaskT* task = butil::get_object<TaskT>(); TaskT* task = butil::get_object<TaskT>();
if (!task) { if (!task) {
LOG(ERROR) << "Failed get TaskT from object pool"; LOG(ERROR) << "Failed get TaskT from object pool";
...@@ -120,7 +136,8 @@ TaskHandler<TaskT> TaskExecutor<TaskT>::schedule( ...@@ -120,7 +136,8 @@ TaskHandler<TaskT> TaskExecutor<TaskT>::schedule(
int fds[2]; int fds[2];
int rc = pipe(fds); int rc = pipe(fds);
if (rc != 0) { if (rc != 0) {
LOG(ERROR) << "call pipe() failed, errno=" << errno << ":" << strerror(errno); LOG(ERROR) << "call pipe() failed, errno=" << errno << ":"
<< strerror(errno);
return TaskHandler<TaskT>::valid_handle(); return TaskHandler<TaskT>::valid_handle();
} }
...@@ -141,8 +158,8 @@ TaskHandler<TaskT> TaskExecutor<TaskT>::schedule( ...@@ -141,8 +158,8 @@ TaskHandler<TaskT> TaskExecutor<TaskT>::schedule(
return TaskHandler<TaskT>(*task); return TaskHandler<TaskT>(*task);
} }
template<typename TaskT> template <typename TaskT>
bool TaskExecutor<TaskT>::fetch_batch(BatchTasks<TaskT>& batch) { bool TaskExecutor<TaskT>::fetch_batch(BatchTasks<TaskT>& batch) { // NOLINT
AutoMutex lock(_mut); AutoMutex lock(_mut);
while (_task_queue.empty()) { while (_task_queue.empty()) {
THREAD_COND_WAIT(&_cond, &_mut); THREAD_COND_WAIT(&_cond, &_mut);
...@@ -165,7 +182,7 @@ bool TaskExecutor<TaskT>::fetch_batch(BatchTasks<TaskT>& batch) { ...@@ -165,7 +182,7 @@ bool TaskExecutor<TaskT>::fetch_batch(BatchTasks<TaskT>& batch) {
return true; return true;
} }
template<typename TaskT> template <typename TaskT>
int TaskExecutor<TaskT>::work(ThreadContext<TaskT>* context) { int TaskExecutor<TaskT>::work(ThreadContext<TaskT>* context) {
if (_thread_init_fn != NULL) { if (_thread_init_fn != NULL) {
if (_thread_init_fn(context->user_thread_context) != 0) { if (_thread_init_fn(context->user_thread_context) != 0) {
...@@ -196,9 +213,9 @@ int TaskExecutor<TaskT>::work(ThreadContext<TaskT>* context) { ...@@ -196,9 +213,9 @@ int TaskExecutor<TaskT>::work(ThreadContext<TaskT>* context) {
return 0; return 0;
} }
template<typename InItemT, typename OutItemT> template <typename InItemT, typename OutItemT>
bool TaskManager<InItemT, OutItemT>::schedule(const InArrayT& in, bool TaskManager<InItemT, OutItemT>::schedule(const InArrayT& in,
OutArrayT& out) { OutArrayT& out) { // NOLINT
TaskHandler<TaskT> handler = _executor.schedule(in, out); TaskHandler<TaskT> handler = _executor.schedule(in, out);
if (handler.valid()) { if (handler.valid()) {
...@@ -210,12 +227,11 @@ bool TaskManager<InItemT, OutItemT>::schedule(const InArrayT& in, ...@@ -210,12 +227,11 @@ bool TaskManager<InItemT, OutItemT>::schedule(const InArrayT& in,
} }
} }
template<typename InItemT, typename OutItemT> template <typename InItemT, typename OutItemT>
void TaskManager<InItemT, OutItemT>::wait() { void TaskManager<InItemT, OutItemT>::wait() {
char buffer[128]; char buffer[128];
while (read(_task_owned.read_fd, buffer, sizeof(buffer)) < 0 while (read(_task_owned.read_fd, buffer, sizeof(buffer)) < 0 &&
&& errno == EINTR) { errno == EINTR) {
;
} }
close(_task_owned.read_fd); close(_task_owned.read_fd);
...@@ -225,6 +241,5 @@ void TaskManager<InItemT, OutItemT>::wait() { ...@@ -225,6 +241,5 @@ void TaskManager<InItemT, OutItemT>::wait() {
_task_owned.write_fd = -1; _task_owned.write_fd = -1;
return; return;
} }
} // namespace bsf
} } // namespace im
}
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_BSF_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_BSF_H //
// 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 <errno.h> #include <errno.h>
#include <vector> #include <algorithm>
#include <deque> #include <deque>
#include <butil/atomicops.h> #include <vector>
#include "butil/atomicops.h"
#include "common/inner_common.h" #include "common/inner_common.h"
#include <boost/function.hpp> #include "boost/function.hpp"
namespace im { namespace im {
namespace bsf { namespace bsf {
static const size_t DEFAULT_BATCH_SIZE = 100; static const size_t DEFAULT_BATCH_SIZE = 100;
template<typename InItemT, typename OutItemT> template <typename InItemT, typename OutItemT>
struct Task { struct Task {
typedef std::vector<InItemT> InArrayT; typedef std::vector<InItemT> InArrayT;
typedef std::vector<OutItemT> OutArrayT; typedef std::vector<OutItemT> OutArrayT;
...@@ -33,9 +47,7 @@ struct Task { ...@@ -33,9 +47,7 @@ struct Task {
size_t rem; size_t rem;
size_t size; size_t size;
size_t batch_size() { size_t batch_size() { return in->size(); }
return in->size();
}
butil::atomic<size_t> index; butil::atomic<size_t> index;
...@@ -51,29 +63,27 @@ struct Task { ...@@ -51,29 +63,27 @@ struct Task {
} }
}; };
template<typename TaskT> template <typename TaskT>
struct TaskMeta { struct TaskMeta {
TaskMeta(TaskT* ptr, size_t start, size_t add) TaskMeta(TaskT* ptr, size_t start, size_t add)
: task(ptr) : task(ptr), begin(start), end(start + add) {}
, begin(start)
, end(start + add) {}
TaskT* task; TaskT* task;
size_t begin; size_t begin;
size_t end; size_t end;
}; };
template<typename TaskT> template <typename TaskT>
class BatchTasks { class BatchTasks {
public: public:
typedef typename TaskT::InType InType; typedef typename TaskT::InType InType;
typedef typename TaskT::OutType OutType; typedef typename TaskT::OutType OutType;
typedef TaskMeta<TaskT> TaskMetaT; typedef TaskMeta<TaskT> TaskMetaT;
BatchTasks(size_t batch_size, bool batch_align = true) explicit BatchTasks(size_t batch_size, bool batch_align = true)
: _batch_size(batch_size) : _batch_size(batch_size),
, _rem_size(batch_size) _rem_size(batch_size),
, _batch_align(batch_align) { _batch_align(batch_align) {
_batch_in.clear(); _batch_in.clear();
_batch_out.clear(); _batch_out.clear();
_tasks.clear(); _tasks.clear();
...@@ -100,9 +110,9 @@ public: ...@@ -100,9 +110,9 @@ public:
return _rem_size; return _rem_size;
} }
static bool check_valid( static bool check_valid(const typename TaskT::InArrayT& in,
const typename TaskT::InArrayT& in, const typename TaskT::OutArrayT& out,
typename TaskT::OutArrayT& out, bool align) { bool align) {
(void)in; (void)in;
(void)out; (void)out;
(void)align; (void)align;
...@@ -121,8 +131,9 @@ public: ...@@ -121,8 +131,9 @@ public:
void notify_tasks() { void notify_tasks() {
if (_batch_out.size() != _batch_in.size()) { if (_batch_out.size() != _batch_in.size()) {
LOG(ERROR) << "batch size not consistency: " << _batch_out.size() << " != " << _batch_in.size(); LOG(ERROR) << "batch size not consistency: " << _batch_out.size()
return ; << " != " << _batch_in.size();
return;
} }
for (size_t ti = 0, bi = 0; ti < _tasks.size(); ++ti) { for (size_t ti = 0, bi = 0; ti < _tasks.size(); ++ti) {
...@@ -133,8 +144,9 @@ public: ...@@ -133,8 +144,9 @@ public:
for (size_t oi = begin; oi < end; ++oi, ++bi) { for (size_t oi = begin; oi < end; ++oi, ++bi) {
if (bi >= _batch_in.size()) { if (bi >= _batch_in.size()) {
LOG(ERROR) << "batch index overflow: " << bi << " > " <<_batch_in.size(); LOG(ERROR) << "batch index overflow: " << bi << " > "
return ; << _batch_in.size();
return;
} }
(*task->out)[oi] = _batch_out[bi]; (*task->out)[oi] = _batch_out[bi];
} }
...@@ -143,26 +155,19 @@ public: ...@@ -143,26 +155,19 @@ public:
if ((index + add) >= task->in->size()) { if ((index + add) >= task->in->size()) {
char c = 0; char c = 0;
while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) { while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) {
;
} }
butil::return_object(task); butil::return_object(task);
} }
} }
} }
const typename TaskT::InArrayT& in() const { const typename TaskT::InArrayT& in() const { return _batch_in; }
return _batch_in;
}
typename TaskT::OutArrayT& out() { typename TaskT::OutArrayT& out() { return _batch_out; }
return _batch_out;
}
size_t task_size() { size_t task_size() { return _tasks.size(); }
return _tasks.size();
}
private: private:
std::vector<TaskMetaT> _tasks; std::vector<TaskMetaT> _tasks;
typename TaskT::InArrayT _batch_in; typename TaskT::InArrayT _batch_in;
typename TaskT::OutArrayT _batch_out; typename TaskT::OutArrayT _batch_out;
...@@ -171,26 +176,22 @@ private: ...@@ -171,26 +176,22 @@ private:
bool _batch_align; bool _batch_align;
}; };
// BSF 任务句柄, 用来等待时指定任务列表 // BSF task handle
template<typename TaskT> template <typename TaskT>
struct TaskHandler { struct TaskHandler {
int read_fd; int read_fd;
int write_fd; int write_fd;
TaskHandler() TaskHandler() : read_fd(-1), write_fd(-1) {
: read_fd(-1), write_fd(-1) {
// do nothing // do nothing
} }
TaskHandler(TaskT const& task) explicit TaskHandler(TaskT const& task)
: read_fd(task.read_fd) : read_fd(task.read_fd), write_fd(task.write_fd) {
, write_fd(task.write_fd) {
// do nothing // do nothing
} }
inline bool valid() const { inline bool valid() const { return read_fd >= 0 && write_fd >= 0; }
return read_fd >= 0 && write_fd >= 0;
}
static TaskHandler<TaskT>& valid_handle() { static TaskHandler<TaskT>& valid_handle() {
static TaskHandler<TaskT> vhandle; static TaskHandler<TaskT> vhandle;
...@@ -198,13 +199,13 @@ struct TaskHandler { ...@@ -198,13 +199,13 @@ struct TaskHandler {
} }
}; };
template<typename TaskT> template <typename TaskT>
class TaskExecutor; class TaskExecutor;
template<typename InItemT, typename OutItemT> template <typename InItemT, typename OutItemT>
class TaskManager; class TaskManager;
template<typename TaskT> template <typename TaskT>
struct ThreadContext { struct ThreadContext {
TaskExecutor<TaskT>* executor; TaskExecutor<TaskT>* executor;
void* user_thread_context; void* user_thread_context;
...@@ -212,9 +213,7 @@ struct ThreadContext { ...@@ -212,9 +213,7 @@ struct ThreadContext {
int init_status; int init_status;
ThreadContext() ThreadContext()
: executor(NULL) : executor(NULL), user_thread_context(NULL), tid(-1), init_status(0) {
, user_thread_context(NULL)
, tid(-1), init_status(0) {
// do nothing // do nothing
} }
...@@ -226,10 +225,9 @@ struct ThreadContext { ...@@ -226,10 +225,9 @@ struct ThreadContext {
} }
}; };
template<typename TaskT> template <typename TaskT>
class TaskExecutor { class TaskExecutor {
public: public:
typedef typename TaskT::InType InType; typedef typename TaskT::InType InType;
typedef typename TaskT::OutType OutType; typedef typename TaskT::OutType OutType;
typedef typename TaskT::InArrayT InArrayT; typedef typename TaskT::InArrayT InArrayT;
...@@ -237,13 +235,13 @@ public: ...@@ -237,13 +235,13 @@ public:
typedef std::vector<TaskT> TaskArrayT; typedef std::vector<TaskT> TaskArrayT;
TaskExecutor() TaskExecutor()
: _stop(false) : _stop(false),
, _thread_init_fn(NULL) _thread_init_fn(NULL),
, _thread_reset_fn(NULL) _thread_reset_fn(NULL),
, _user_thread_contexts(NULL) _user_thread_contexts(NULL),
, _batch_size(DEFAULT_BATCH_SIZE) _batch_size(DEFAULT_BATCH_SIZE),
, _batch_align(false) _batch_align(false),
, _fn(NULL) { _fn(NULL) {
THREAD_MUTEX_INIT(&_mut, NULL); THREAD_MUTEX_INIT(&_mut, NULL);
THREAD_COND_INIT(&_cond, NULL); THREAD_COND_INIT(&_cond, NULL);
_task_queue.clear(); _task_queue.clear();
...@@ -259,15 +257,12 @@ public: ...@@ -259,15 +257,12 @@ public:
return &singleton; return &singleton;
} }
void set_batch_size(size_t batch_size) { void set_batch_size(size_t batch_size) { _batch_size = batch_size; }
_batch_size = batch_size;
}
void set_batch_align(size_t batch_align) { void set_batch_align(size_t batch_align) { _batch_align = batch_align; }
_batch_align = batch_align;
}
void set_thread_init_fn(boost::function<int(void*)> init_fn, void** contexts = NULL) { void set_thread_init_fn(boost::function<int(void*)> init_fn,
void** contexts = NULL) {
_thread_init_fn = init_fn; _thread_init_fn = init_fn;
_user_thread_contexts = contexts; _user_thread_contexts = contexts;
} }
...@@ -276,7 +271,8 @@ public: ...@@ -276,7 +271,8 @@ public:
_thread_reset_fn = reset_fn; _thread_reset_fn = reset_fn;
} }
void set_thread_callback_fn(boost::function<void(const InArrayT&, OutArrayT&)> cb) { void set_thread_callback_fn(
boost::function<void(const InArrayT&, OutArrayT&)> cb) {
_fn = cb; _fn = cb;
} }
...@@ -285,7 +281,7 @@ public: ...@@ -285,7 +281,7 @@ public:
static void* thread_entry(void* args); static void* thread_entry(void* args);
private: private:
TaskExecutor(TaskExecutor<TaskT> const& other); TaskExecutor(TaskExecutor<TaskT> const& other);
TaskExecutor* operator=(TaskExecutor<TaskT> const& other); TaskExecutor* operator=(TaskExecutor<TaskT> const& other);
...@@ -293,7 +289,7 @@ private: ...@@ -293,7 +289,7 @@ private:
TaskHandler<TaskT> schedule(const InArrayT&, OutArrayT&); TaskHandler<TaskT> schedule(const InArrayT&, OutArrayT&);
bool fetch_batch(BatchTasks<TaskT>& batch); bool fetch_batch(BatchTasks<TaskT>& batch); // NOLINT
bool _stop; bool _stop;
...@@ -316,56 +312,44 @@ private: ...@@ -316,56 +312,44 @@ private:
boost::function<void(const InArrayT&, OutArrayT&)> _fn; boost::function<void(const InArrayT&, OutArrayT&)> _fn;
}; };
template<typename InItemT, typename OutItemT> template <typename InItemT, typename OutItemT>
class TaskManager { class TaskManager {
public: public:
typedef Task<InItemT, OutItemT> TaskT; typedef Task<InItemT, OutItemT> TaskT;
typedef typename TaskT::InArrayT InArrayT; typedef typename TaskT::InArrayT InArrayT;
typedef typename TaskT::OutArrayT OutArrayT; typedef typename TaskT::OutArrayT OutArrayT;
explicit TaskManager(TaskExecutor<TaskT>& exe, size_t batch_size) : _executor(exe) { explicit TaskManager(TaskExecutor<TaskT>& exe, size_t batch_size) // NOLINT
} : _executor(exe) {}
TaskManager() TaskManager() : _executor(*TaskExecutor<TaskT>::instance()) {}
: _executor(*TaskExecutor<TaskT>::instance()) {
}
~TaskManager() { ~TaskManager() { wait(); }
wait();
}
bool schedule(const InArrayT& in, OutArrayT& out); bool schedule(const InArrayT& in, OutArrayT& out); // NOLINT
void wait(); void wait();
inline void clear() { inline void clear() { wait(); }
wait();
}
private: private:
TaskExecutor<TaskT>& _executor; TaskExecutor<TaskT>& _executor;
TaskHandler<TaskT> _task_owned; TaskHandler<TaskT> _task_owned;
}; // class TaskManager }; // class TaskManager
class AutoMutex { class AutoMutex {
public: public:
AutoMutex(THREAD_MUTEX_T& mut) explicit AutoMutex(THREAD_MUTEX_T& mut) : _mut(mut) {
: _mut(mut) {
THREAD_MUTEX_LOCK(&_mut); THREAD_MUTEX_LOCK(&_mut);
} }
~AutoMutex() { ~AutoMutex() { THREAD_MUTEX_UNLOCK(&_mut); }
THREAD_MUTEX_UNLOCK(&_mut);
}
private: private:
THREAD_MUTEX_T& _mut; THREAD_MUTEX_T& _mut;
}; };
} // namespace bsf } // namespace bsf
} // namespace im } // namespace im
#include "bsf-inl.h" #include "predictor/framework/bsf-inl-tensor.h"
#include "bsf-inl-tensor.h" #include "predictor/framework/bsf-inl.h"
#endif //BAIDU_PADDLE_SERVING_PREDICTOR_BSF_H
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_CHANNEL_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_CHANNEL_H //
// 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 <string>
#include <utility>
#include "common/inner_common.h" #include "common/inner_common.h"
namespace baidu { namespace baidu {
...@@ -10,14 +24,12 @@ namespace predictor { ...@@ -10,14 +24,12 @@ namespace predictor {
class Channel; class Channel;
class Bus { class Bus {
public: public:
Bus() { Bus() { clear(); }
clear();
}
int regist(const std::string& op, Channel* channel) { int regist(const std::string& op, Channel* channel) {
std::pair<boost::unordered_map<std::string, Channel*>::iterator, bool> r std::pair<boost::unordered_map<std::string, Channel*>::iterator, bool> r =
= _op_channels.insert(std::make_pair(op, channel)); _op_channels.insert(std::make_pair(op, channel));
if (!r.second) { if (!r.second) {
LOG(ERROR) << "Failed insert op&channel into bus:" << op; LOG(ERROR) << "Failed insert op&channel into bus:" << op;
return -1; return -1;
...@@ -26,32 +38,26 @@ public: ...@@ -26,32 +38,26 @@ public:
} }
Channel* channel_by_name(const std::string& op_name) { Channel* channel_by_name(const std::string& op_name) {
typename boost::unordered_map<std::string, Channel*>::iterator it typename boost::unordered_map<std::string, Channel*>::iterator it =
= _op_channels.find(op_name); _op_channels.find(op_name);
if (it == _op_channels.end()) { if (it == _op_channels.end()) {
LOG(WARNING) LOG(WARNING) << "Not found channel in bus, op_name:" << op_name << ".";
<< "Not found channel in bus, op_name:"
<< op_name << ".";
return NULL; return NULL;
} }
return it->second; return it->second;
} }
void clear() { void clear() { _op_channels.clear(); }
_op_channels.clear();
}
size_t size() const { size_t size() const { return _op_channels.size(); }
return _op_channels.size();
}
private: private:
boost::unordered_map<std::string, Channel*> _op_channels; boost::unordered_map<std::string, Channel*> _op_channels;
}; };
class Channel { class Channel {
public: public:
Channel() {} Channel() {}
void init(uint32_t id, const char* op) { void init(uint32_t id, const char* op) {
...@@ -60,23 +66,15 @@ public: ...@@ -60,23 +66,15 @@ public:
clear_data(); clear_data();
} }
void deinit() { void deinit() { clear_data(); }
clear_data();
}
uint32_t id() const { uint32_t id() const { return _id; }
return _id;
}
const std::string& op() { const std::string& op() { return _op; }
return _op;
}
int share_to_bus(Bus* bus) { int share_to_bus(Bus* bus) {
if (bus->regist(_op, this) != 0) { if (bus->regist(_op, this) != 0) {
LOG(ERROR) LOG(ERROR) << "Failed regist channel[" << _op << "] to bus!";
<< "Failed regist channel[" << _op
<< "] to bus!";
return -1; return -1;
} }
...@@ -95,31 +93,25 @@ public: ...@@ -95,31 +93,25 @@ public:
virtual std::string debug_string() const = 0; virtual std::string debug_string() const = 0;
private: private:
uint32_t _id; uint32_t _id;
std::string _op; std::string _op;
}; };
template<typename T> template <typename T>
class OpChannel : public Channel { class OpChannel : public Channel {
public: public:
OpChannel() { OpChannel() {}
}
void clear_data() { void clear_data() { _data.Clear(); }
_data.Clear();
}
void* param() { void* param() { return &_data; }
return &_data;
}
const void* param() const { const void* param() const { return &_data; }
return &_data;
}
google::protobuf::Message* message() { google::protobuf::Message* message() {
return message_impl(derived_from_message< return message_impl(
derived_from_message<
TIsDerivedFromB<T, google::protobuf::Message>::RESULT>()); TIsDerivedFromB<T, google::protobuf::Message>::RESULT>());
} }
...@@ -134,15 +126,18 @@ public: ...@@ -134,15 +126,18 @@ public:
} }
const google::protobuf::Message* message() const { const google::protobuf::Message* message() const {
return message_impl(derived_from_message< return message_impl(
derived_from_message<
TIsDerivedFromB<T, google::protobuf::Message>::RESULT>()); TIsDerivedFromB<T, google::protobuf::Message>::RESULT>());
} }
const google::protobuf::Message* message_impl(derived_from_message<true>) const { const google::protobuf::Message* message_impl(
derived_from_message<true>) const {
return dynamic_cast<const google::protobuf::Message*>(&_data); return dynamic_cast<const google::protobuf::Message*>(&_data);
} }
const google::protobuf::Message* message_impl(derived_from_message<false>) const { const google::protobuf::Message* message_impl(
derived_from_message<false>) const {
LOG(ERROR) << "Current type: " << typeid(T).name() LOG(ERROR) << "Current type: " << typeid(T).name()
<< " is not derived from protobuf."; << " is not derived from protobuf.";
return NULL; return NULL;
...@@ -153,58 +148,41 @@ public: ...@@ -153,58 +148,41 @@ public:
return *this; return *this;
} }
std::string debug_string() const { std::string debug_string() const { return _data.ShortDebugString(); }
return _data.ShortDebugString();
}
// functions of derived class // functions of derived class
T* data() { T* data() { return &_data; }
return &_data;
}
const T* data() const { const T* data() const { return &_data; }
return &_data;
}
Channel& operator=(const T& obj) { Channel& operator=(const T& obj) {
_data = obj; _data = obj;
return *this; return *this;
} }
private: private:
T _data; T _data;
}; };
template<> template <>
class OpChannel<google::protobuf::Message> : public Channel { class OpChannel<google::protobuf::Message> : public Channel {
public: public:
OpChannel<google::protobuf::Message>() : _data(NULL) { OpChannel<google::protobuf::Message>() : _data(NULL) {}
}
virtual ~OpChannel<google::protobuf::Message>() { virtual ~OpChannel<google::protobuf::Message>() { _data = NULL; }
_data = NULL;
}
void clear_data() { void clear_data() { _data = NULL; }
_data = NULL;
}
void* param() { void* param() { return const_cast<void*>((const void*)_data); }
return const_cast<void*>((const void*)_data);
}
const void* param() const { const void* param() const { return _data; }
return _data;
}
google::protobuf::Message* message() { google::protobuf::Message* message() {
return const_cast<google::protobuf::Message*>(_data); return const_cast<google::protobuf::Message*>(_data);
} }
const google::protobuf::Message* message() const { const google::protobuf::Message* message() const { return _data; }
return _data;
}
Channel& operator=(const Channel& channel) { Channel& operator=(const Channel& channel) {
_data = channel.message(); _data = channel.message();
...@@ -224,9 +202,7 @@ public: ...@@ -224,9 +202,7 @@ public:
return const_cast<google::protobuf::Message*>(_data); return const_cast<google::protobuf::Message*>(_data);
} }
const google::protobuf::Message* data() const { const google::protobuf::Message* data() const { return _data; }
return _data;
}
OpChannel<google::protobuf::Message>& operator=( OpChannel<google::protobuf::Message>& operator=(
google::protobuf::Message* message) { google::protobuf::Message* message) {
...@@ -240,12 +216,10 @@ public: ...@@ -240,12 +216,10 @@ public:
return *this; return *this;
} }
private: private:
const google::protobuf::Message* _data; const google::protobuf::Message* _data;
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif
#include "common/inner_common.h" // 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 "framework/dag.h" #include "framework/dag.h"
#include "op/op.h" #include <string>
#include <vector>
#include "common/inner_common.h"
#include "framework/predictor_metric.h" // PredictorMetric #include "framework/predictor_metric.h" // PredictorMetric
#include "op/op.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -13,12 +29,12 @@ Dag::Dag() { ...@@ -13,12 +29,12 @@ Dag::Dag() {
_stages.clear(); _stages.clear();
} }
Dag::~Dag() { Dag::~Dag() { deinit(); }
deinit();
}
int Dag::deinit() { int Dag::deinit() {
for (std::vector<DagStage*>::iterator iter = _stages.begin(); iter != _stages.end(); ++iter) { for (std::vector<DagStage*>::iterator iter = _stages.begin();
iter != _stages.end();
++iter) {
if (*iter != NULL) { if (*iter != NULL) {
delete *iter; delete *iter;
} }
...@@ -118,8 +134,7 @@ int Dag::init(const configure::Workflow& conf, const std::string& name) { ...@@ -118,8 +134,7 @@ int Dag::init(const configure::Workflow& conf, const std::string& name) {
conf.nodes(i).dependencies(j); conf.nodes(i).dependencies(j);
std::string name = depend.name(); std::string name = depend.name();
std::string mode = depend.mode(); std::string mode = depend.mode();
node->depends.insert( node->depends.insert(std::make_pair(name, parse_mode(mode)));
std::make_pair(name, parse_mode(mode)));
} }
Op* op = OpRepository::instance().get_op(node->type); Op* op = OpRepository::instance().get_op(node->type);
if (op == NULL) { if (op == NULL) {
...@@ -143,8 +158,7 @@ int Dag::init(const configure::Workflow& conf, const std::string& name) { ...@@ -143,8 +158,7 @@ int Dag::init(const configure::Workflow& conf, const std::string& name) {
LOG(INFO) << ", Op Num: " << _index_nodes.size(); LOG(INFO) << ", Op Num: " << _index_nodes.size();
for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) { for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) {
DagNode* node = _index_nodes[nid]; DagNode* node = _index_nodes[nid];
LOG(INFO) LOG(INFO) << ", OP-" << node->id << "-" << node->name << "-"
<< ", OP-" << node->id << "-" << node->name << "-"
<< node->type; << node->type;
LOG(INFO) << " depends: " << node->depends.size(); LOG(INFO) << " depends: " << node->depends.size();
...@@ -159,17 +173,11 @@ int Dag::init(const configure::Workflow& conf, const std::string& name) { ...@@ -159,17 +173,11 @@ int Dag::init(const configure::Workflow& conf, const std::string& name) {
return ERR_OK; return ERR_OK;
} }
uint32_t Dag::nodes_size() { uint32_t Dag::nodes_size() { return _index_nodes.size(); }
return _index_nodes.size();
}
const DagNode* Dag::node_by_id(uint32_t id) { const DagNode* Dag::node_by_id(uint32_t id) { return _index_nodes[id]; }
return _index_nodes[id];
}
const DagNode* Dag::node_by_id(uint32_t id) const { const DagNode* Dag::node_by_id(uint32_t id) const { return _index_nodes[id]; }
return _index_nodes[id];
}
const DagNode* Dag::node_by_name(std::string& name) { const DagNode* Dag::node_by_name(std::string& name) {
return _name_nodes[name]; return _name_nodes[name];
...@@ -185,16 +193,11 @@ const DagNode* Dag::node_by_name(const std::string& name) const { ...@@ -185,16 +193,11 @@ const DagNode* Dag::node_by_name(const std::string& name) const {
return it->second; return it->second;
} }
uint32_t Dag::stage_size() { uint32_t Dag::stage_size() { return _stages.size(); }
return _stages.size();
}
const DagStage* Dag::stage_by_index(uint32_t index) { const DagStage* Dag::stage_by_index(uint32_t index) { return _stages[index]; }
return _stages[index];
}
int Dag::topo_sort() { int Dag::topo_sort() {
// TODO ƽ
std::stringstream ss; std::stringstream ss;
for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) { for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) {
DagStage* stage = new (std::nothrow) DagStage(); DagStage* stage = new (std::nothrow) DagStage();
...@@ -212,7 +215,8 @@ int Dag::topo_sort() { ...@@ -212,7 +215,8 @@ int Dag::topo_sort() {
// assign stage number after stage created // assign stage number after stage created
_index_nodes[nid]->stage = nid; _index_nodes[nid]->stage = nid;
// assign dag node full name after stage created // assign dag node full name after stage created
_index_nodes[nid]->full_name = stage->full_name + NAME_DELIMITER + _index_nodes[nid]->name; _index_nodes[nid]->full_name =
stage->full_name + NAME_DELIMITER + _index_nodes[nid]->name;
} }
return ERR_OK; return ERR_OK;
} }
...@@ -239,6 +243,6 @@ void Dag::regist_metric(const std::string& service_name) { ...@@ -239,6 +243,6 @@ void Dag::regist_metric(const std::string& service_name) {
} }
} }
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_DAG_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_DAG_H //
// 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 <string>
#include <vector>
#include "common/inner_common.h" #include "common/inner_common.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace predictor { namespace predictor {
enum EdgeMode { enum EdgeMode { RO = 0, RW = 1, UNKNOWN };
RO = 0,
RW = 1,
UNKNOWN
};
struct DagNode { struct DagNode {
uint32_t id; uint32_t id;
...@@ -30,12 +40,12 @@ struct DagStage { ...@@ -30,12 +40,12 @@ struct DagStage {
}; };
class Dag { class Dag {
public: public:
Dag(); Dag();
virtual ~Dag(); virtual ~Dag();
EdgeMode parse_mode(std::string& mode); EdgeMode parse_mode(std::string& mode); // NOLINT
int init(const char* path, const char* file, const std::string& name); int init(const char* path, const char* file, const std::string& name);
...@@ -49,7 +59,7 @@ public: ...@@ -49,7 +59,7 @@ public:
const DagNode* node_by_id(uint32_t id) const; const DagNode* node_by_id(uint32_t id) const;
const DagNode* node_by_name(std::string& name); const DagNode* node_by_name(std::string& name); // NOLINT
const DagNode* node_by_name(const std::string& name) const; const DagNode* node_by_name(const std::string& name) const;
...@@ -57,28 +67,22 @@ public: ...@@ -57,28 +67,22 @@ public:
const DagStage* stage_by_index(uint32_t index); const DagStage* stage_by_index(uint32_t index);
const std::string& name() const { const std::string& name() const { return _dag_name; }
return _dag_name;
}
const std::string& full_name() const { const std::string& full_name() const { return _dag_name; }
return _dag_name;
}
void regist_metric(const std::string& service_name); void regist_metric(const std::string& service_name);
private: private:
int topo_sort(); int topo_sort();
private: private:
std::string _dag_name; std::string _dag_name;
boost::unordered_map<std::string, DagNode*> _name_nodes; boost::unordered_map<std::string, DagNode*> _name_nodes;
std::vector<DagNode*> _index_nodes; std::vector<DagNode*> _index_nodes;
std::vector<DagStage*> _stages; std::vector<DagStage*> _stages;
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif // BAIDU_PADDLE_SERVING_PREDICTOR_DAG_H
// 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 "framework/dag_view.h" #include "framework/dag_view.h"
#include <brpc/traceprintf.h> // TRACEPRINTF #include <brpc/traceprintf.h> // TRACEPRINTF
#include <string>
#include "common/inner_common.h" #include "common/inner_common.h"
#include "framework/op_repository.h" #include "framework/op_repository.h"
...@@ -22,8 +37,7 @@ int DagView::init(Dag* dag, const std::string& service_name) { ...@@ -22,8 +37,7 @@ int DagView::init(Dag* dag, const std::string& service_name) {
} }
ViewStage* vstage = butil::get_object<ViewStage>(); ViewStage* vstage = butil::get_object<ViewStage>();
if (vstage == NULL) { if (vstage == NULL) {
LOG(ERROR) LOG(ERROR) << "Failed get vstage from object pool"
<< "Failed get vstage from object pool"
<< "at:" << si; << "at:" << si;
return ERR_MEM_ALLOC_FAILURE; return ERR_MEM_ALLOC_FAILURE;
} }
...@@ -40,13 +54,13 @@ int DagView::init(Dag* dag, const std::string& service_name) { ...@@ -40,13 +54,13 @@ int DagView::init(Dag* dag, const std::string& service_name) {
// factory type // factory type
Op* op = OpRepository::instance().get_op(node->type); Op* op = OpRepository::instance().get_op(node->type);
if (op == NULL) { if (op == NULL) {
LOG(ERROR) << "Failed get op with type:" LOG(ERROR) << "Failed get op with type:" << node->type;
<< node->type;
return ERR_INTERNAL_FAILURE; return ERR_INTERNAL_FAILURE;
} }
// initialize a TLS op object // initialize a TLS op object
if (op->init(_bus, dag, node->id, node->name, node->type, node->conf) != 0) { if (op->init(_bus, dag, node->id, node->name, node->type, node->conf) !=
0) {
LOG(WARNING) << "Failed init op, type:" << node->type; LOG(WARNING) << "Failed init op, type:" << node->type;
return ERR_INTERNAL_FAILURE; return ERR_INTERNAL_FAILURE;
} }
...@@ -91,9 +105,7 @@ int DagView::execute(butil::IOBufBuilder* debug_os) { ...@@ -91,9 +105,7 @@ int DagView::execute(butil::IOBufBuilder* debug_os) {
int errcode = execute_one_stage(_view[si], debug_os); int errcode = execute_one_stage(_view[si], debug_os);
TRACEPRINTF("finish to execute stage[%u]", si); TRACEPRINTF("finish to execute stage[%u]", si);
if (errcode < 0) { if (errcode < 0) {
LOG(ERROR) LOG(ERROR) << "failed execute stage[" << _view[si]->debug();
<< "failed execute stage["
<< _view[si]->debug();
return errcode; return errcode;
} }
} }
...@@ -115,26 +127,22 @@ int DagView::execute_one_stage(ViewStage* vstage, ...@@ -115,26 +127,22 @@ int DagView::execute_one_stage(ViewStage* vstage,
int errcode = op->process(debug_os != NULL); int errcode = op->process(debug_os != NULL);
TRACEPRINTF("finish to execute op[%s]", op->name()); TRACEPRINTF("finish to execute op[%s]", op->name());
if (errcode < 0) { if (errcode < 0) {
LOG(ERROR) LOG(ERROR) << "Execute failed, Op:" << op->debug_string();
<< "Execute failed, Op:" << op->debug_string();
return errcode; return errcode;
} }
if (errcode > 0) { if (errcode > 0) {
LOG(INFO) LOG(INFO) << "Execute ignore, Op:" << op->debug_string();
<< "Execute ignore, Op:" << op->debug_string();
continue; continue;
} }
if (debug_os) { if (debug_os) {
(*debug_os) (*debug_os) << "{\"op_name\": \"" << op->name()
<< "{\"op_name\": \"" << op->name() << "\", \"debug_str:\": \"" << op->debug_string()
<< "\", \"debug_str:\": \""
<< op->debug_string()
<< "\", \"time_info\": \"" << op->time_info() << "\"}"; << "\", \"time_info\": \"" << op->time_info() << "\"}";
} }
//LOG(DEBUG) << "Execute succ, Op:" << op->debug_string(); // LOG(DEBUG) << "Execute succ, Op:" << op->debug_string();
} }
stage_time.stop(); stage_time.stop();
PredictorMetric::GetInstance()->update_latency_metric( PredictorMetric::GetInstance()->update_latency_metric(
...@@ -161,10 +169,8 @@ const Channel* DagView::get_response_channel() const { ...@@ -161,10 +169,8 @@ const Channel* DagView::get_response_channel() const {
} }
ViewStage* last_stage = _view[_view.size() - 1]; ViewStage* last_stage = _view[_view.size() - 1];
if (last_stage->nodes.size() != 1 if (last_stage->nodes.size() != 1 || last_stage->nodes[0] == NULL) {
|| last_stage->nodes[0] == NULL) { LOG(ERROR) << "Invalid last stage, size[" << last_stage->nodes.size()
LOG(ERROR) << "Invalid last stage, size["
<< last_stage->nodes.size()
<< "] != 1"; << "] != 1";
return NULL; return NULL;
} }
...@@ -177,6 +183,6 @@ const Channel* DagView::get_response_channel() const { ...@@ -177,6 +183,6 @@ const Channel* DagView::get_response_channel() const {
return last_op->mutable_channel(); return last_op->mutable_channel();
} }
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_DAG_VIEW_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_DAG_VIEW_H //
// Licensed under the Apache License, Version 2.0 (the "License");
#include "op/op.h" // 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 <string>
#include <vector>
#include "common/inner_common.h" #include "common/inner_common.h"
#include "framework/channel.h" #include "framework/channel.h"
#include "framework/dag.h" #include "framework/dag.h"
#include "op/op.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -24,16 +38,12 @@ struct ViewNode { ...@@ -24,16 +38,12 @@ struct ViewNode {
struct ViewStage { struct ViewStage {
std::vector<ViewNode*> nodes; std::vector<ViewNode*> nodes;
std::string full_name; // service_workflow_stageindex std::string full_name; // service_workflow_stageindex
std::string debug() { std::string debug() { return "TOBE IMPLEMENTED!"; }
return "TOBE IMPLEMENTED!";
}
}; };
class DagView { class DagView {
public: public:
DagView() : _bus(NULL) { DagView() : _bus(NULL) { _view.clear(); }
_view.clear();
}
~DagView() {} ~DagView() {}
...@@ -49,19 +59,15 @@ public: ...@@ -49,19 +59,15 @@ public:
virtual int execute_one_stage(ViewStage* vstage, virtual int execute_one_stage(ViewStage* vstage,
butil::IOBufBuilder* debug_os); butil::IOBufBuilder* debug_os);
int set_request_channel(Channel& request); int set_request_channel(Channel& request); // NOLINT
const Channel* get_response_channel() const; const Channel* get_response_channel() const;
const std::string& name() const { const std::string& name() const { return _name; }
return _name;
}
const std::string& full_name() const { const std::string& full_name() const { return _full_name; }
return _full_name;
}
private: private:
std::string _name; std::string _name;
std::string _full_name; std::string _full_name;
std::vector<ViewStage*> _view; std::vector<ViewStage*> _view;
...@@ -71,14 +77,10 @@ private: ...@@ -71,14 +77,10 @@ private:
// The derived DagView supports parallel execution // The derived DagView supports parallel execution
// strategy, by implments the execute_one_stage(). // strategy, by implments the execute_one_stage().
class ParallelDagView : public DagView { class ParallelDagView : public DagView {
public: public:
int execute_one_stage(ViewStage* vstage, butil::IOBufBuilder*) { int execute_one_stage(ViewStage* vstage, butil::IOBufBuilder*) { return 0; }
return 0;
}
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif // BAIDU_PADDLE_SERVING_PREDICTOR_DAG_VIEW_H
/*************************************************************************** // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
* //
* Copyright (c) 2018 Baidu.com, Inc. 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
* @file include/factory.h //
* @author wanlijin01(wanlijin01@baidu.com) // Unless required by applicable law or agreed to in writing, software
* @date 2018/07/10 22:09:57 // distributed under the License is distributed on an "AS IS" BASIS,
* @brief // 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 BAIDU_PADDLE_SERVING_PREDICTOR_FACTORY_H #pragma once
#define BAIDU_PADDLE_SERVING_PREDICTOR_FACTORY_H #include <map>
#include <string>
#include <utility>
#include "common/inner_common.h" #include "common/inner_common.h"
#include "glog/raw_logging.h" #include "glog/raw_logging.h"
namespace baidu { namespace baidu {
...@@ -24,11 +25,9 @@ namespace predictor { ...@@ -24,11 +25,9 @@ namespace predictor {
//////////////// DECLARE INTERFACE //////////////// //////////////// DECLARE INTERFACE ////////////////
#define DECLARE_FACTORY_OBJECT(D, B) \ #define DECLARE_FACTORY_OBJECT(D, B) \
static int regist(const std::string& tag) { \ static int regist(const std::string& tag) { \
FactoryDerive<D, B>* factory = \ FactoryDerive<D, B>* factory = new (std::nothrow) FactoryDerive<D, B>(); \
new (std::nothrow) FactoryDerive<D, B>();\ if (factory == NULL || \
if (factory == NULL \ FactoryPool<B>::instance().register_factory(tag, factory) != 0) { \
|| FactoryPool<B>::instance().register_factory(\
tag, factory) != 0) { \
RAW_LOG_FATAL("Failed regist factory: %s in macro!", #D); \ RAW_LOG_FATAL("Failed regist factory: %s in macro!", #D); \
return -1; \ return -1; \
} \ } \
...@@ -36,119 +35,119 @@ namespace predictor { ...@@ -36,119 +35,119 @@ namespace predictor {
} }
#define PDS_STR_CAT(a, b) PDS_STR_CAT_I(a, b) #define PDS_STR_CAT(a, b) PDS_STR_CAT_I(a, b)
#define PDS_STR_CAT_I(a, b) a ## b #define PDS_STR_CAT_I(a, b) a##b
#define DEFINE_FACTORY_OBJECT(D) \ #define DEFINE_FACTORY_OBJECT(D) \
__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \
{ \ __LINE__)(void) { \
D::regist(#D); \ D::regist(#D); \
} }
//////////////// REGISTER INTERFACE //////////////// //////////////// REGISTER INTERFACE ////////////////
#define REGIST_FACTORY_OBJECT_IMPL(D, B) \ #define REGIST_FACTORY_OBJECT_IMPL(D, B) \
__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \
{ \ __LINE__)(void) { \
::baidu::paddle_serving::predictor::FactoryDerive<D, B>* factory =\ ::baidu::paddle_serving::predictor::FactoryDerive<D, B>* factory = new ( \
new (::std::nothrow) ::baidu::paddle_serving::predictor::FactoryDerive<D, B>();\ ::std::nothrow)::baidu::paddle_serving::predictor::FactoryDerive<D, \
if (factory == NULL \ B>(); \
|| ::baidu::paddle_serving::predictor::FactoryPool<B>::instance().register_factory(\ if (factory == NULL || \
#D, factory) != 0) { \ ::baidu::paddle_serving::predictor::FactoryPool<B>::instance() \
.register_factory(#D, factory) != 0) { \
RAW_LOG_FATAL("Failed regist factory: %s->%s in macro!", #D, #B); \ RAW_LOG_FATAL("Failed regist factory: %s->%s in macro!", #D, #B); \
return ; \ return; \
} \ } \
return ; \ return; \
} }
#define REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(D, B, N) \ #define REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(D, B, N) \
__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \
{ \ __LINE__)(void) { \
::baidu::paddle_serving::predictor::FactoryDerive<D, B>* factory =\ ::baidu::paddle_serving::predictor::FactoryDerive<D, B>* factory = new ( \
new (::std::nothrow) ::baidu::paddle_serving::predictor::FactoryDerive<D, B>();\ ::std::nothrow)::baidu::paddle_serving::predictor::FactoryDerive<D, \
if (factory == NULL \ B>(); \
|| ::baidu::paddle_serving::predictor::FactoryPool<B>::instance().register_factory(\ if (factory == NULL || \
N, factory) != 0) { \ ::baidu::paddle_serving::predictor::FactoryPool<B>::instance() \
RAW_LOG_FATAL("Failed regist factory: %s->%s, tag: %s in macro!", #D, #B, N); \ .register_factory(N, factory) != 0) { \
return ; \ RAW_LOG_FATAL( \
"Failed regist factory: %s->%s, tag: %s in macro!", #D, #B, N); \
return; \
} \ } \
RAW_LOG_WARNING("Succ regist factory: %s->%s, tag: %s in macro!", #D, #B, N); \ RAW_LOG_WARNING( \
return ; \ "Succ regist factory: %s->%s, tag: %s in macro!", #D, #B, N); \
} return; \
}
template<typename B> template <typename B>
class FactoryBase { class FactoryBase {
public: public:
virtual B* gen() = 0; virtual B* gen() = 0;
virtual void del(B* obj) = 0; virtual void del(B* obj) = 0;
}; };
template<typename D, typename B> template <typename D, typename B>
class FactoryDerive : public FactoryBase<B> { class FactoryDerive : public FactoryBase<B> {
public: public:
B* gen() { B* gen() { return new (std::nothrow) D(); }
return new(std::nothrow) D();
}
void del(B* obj) { void del(B* obj) { delete dynamic_cast<D*>(obj); }
delete dynamic_cast<D*>(obj);
}
}; };
template<typename B> template <typename B>
class FactoryPool { class FactoryPool {
public: public:
static FactoryPool<B>& instance() { static FactoryPool<B>& instance() {
static FactoryPool<B> singleton; static FactoryPool<B> singleton;
return singleton; return singleton;
} }
int register_factory(const std::string& tag, int register_factory(const std::string& tag, FactoryBase<B>* factory) {
FactoryBase<B>* factory) { typename std::map<std::string, FactoryBase<B>*>::iterator it =
typename std::map<std::string, FactoryBase<B>*>::iterator it _pool.find(tag);
= _pool.find(tag);
if (it != _pool.end()) { if (it != _pool.end()) {
RAW_LOG_FATAL("Insert duplicate with tag: %s", tag.c_str()); RAW_LOG_FATAL("Insert duplicate with tag: %s", tag.c_str());
return -1; return -1;
} }
std::pair< std::pair<typename std::map<std::string, FactoryBase<B>*>::iterator, bool>
typename std::map<std::string, FactoryBase<B>*>::iterator, r = _pool.insert(std::make_pair(tag, factory));
bool> r = _pool.insert(std::make_pair(tag, factory));
if (!r.second) { if (!r.second) {
RAW_LOG_FATAL("Failed insert new factory with: %s", tag.c_str()); RAW_LOG_FATAL("Failed insert new factory with: %s", tag.c_str());
return -1; return -1;
} }
RAW_LOG_INFO("Succ insert one factory, tag: %s, base type %s", tag.c_str(), typeid(B).name()); RAW_LOG_INFO("Succ insert one factory, tag: %s, base type %s",
tag.c_str(),
typeid(B).name());
return 0; return 0;
} }
B* generate_object(const std::string& tag) { B* generate_object(const std::string& tag) {
typename std::map<std::string, FactoryBase<B>*>::iterator it typename std::map<std::string, FactoryBase<B>*>::iterator it =
= _pool.find(tag); _pool.find(tag);
if (it == _pool.end() || it->second == NULL) { if (it == _pool.end() || it->second == NULL) {
RAW_LOG_FATAL("Not found factory pool, tag: %s, pool size %u", tag.c_str(), _pool.size()); RAW_LOG_FATAL("Not found factory pool, tag: %s, pool size %u",
tag.c_str(),
_pool.size());
return NULL; return NULL;
} }
return it->second->gen(); return it->second->gen();
} }
template<typename D> template <typename D>
void return_object(B* object) { void return_object(B* object) {
FactoryDerive<D, B> factory; FactoryDerive<D, B> factory;
factory.del(object); factory.del(object);
} }
private: private:
std::map<std::string, FactoryBase<B>*> _pool; std::map<std::string, FactoryBase<B>*> _pool;
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif //BAIDU_PADDLE_SERVING_PREDICTOR_FACTORY_H
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ /* vim: set expandtab ts=2 sw=2 sts=2 tw=100: */
此差异已折叠。
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_INFER_DATA_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_INFER_DATA_H //
// 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 <string>
#include <vector>
#include "common/inner_common.h" #include "common/inner_common.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
namespace predictor { namespace predictor {
enum DataType { enum DataType { FLOAT32, INT64 };
FLOAT32,
INT64
};
class DataBuf { class DataBuf {
public: public:
DataBuf() : _data(NULL), _size(0), _owned(true) {} DataBuf() : _data(NULL), _size(0), _owned(true) {}
DataBuf(size_t size) explicit DataBuf(size_t size)
: _data(new char[size]), _size(size), _owned(true) {} : _data(new char[size]), _size(size), _owned(true) {}
DataBuf(void* data, size_t size) DataBuf(void* data, size_t size) : _data(data), _size(size), _owned(false) {}
: _data(data), _size(size), _owned(false) {}
DataBuf(void* data, size_t size, bool owned) DataBuf(void* data, size_t size, bool owned)
: _data(data), _size(size), _owned(owned) {} : _data(data), _size(size), _owned(owned) {}
void* data() const { void* data() const { return _data; }
return _data;
}
size_t size() const { size_t size() const { return _size; }
return _size;
}
void free() { void free() {
_size = 0; _size = 0;
if (_owned) { if (_owned) {
delete[] (char*)_data; delete[](reinterpret_cast<char*>(_data));
} }
} }
~DataBuf() { ~DataBuf() { free(); }
free();
}
private: private:
void* _data; void* _data;
size_t _size; size_t _size;
bool _owned; bool _owned;
...@@ -71,9 +75,7 @@ struct Tensor { ...@@ -71,9 +75,7 @@ struct Tensor {
} }
} }
~Tensor() { ~Tensor() { shape.clear(); }
shape.clear();
}
size_t ele_byte() const { size_t ele_byte() const {
if (type == INT64) { if (type == INT64) {
...@@ -103,7 +105,8 @@ struct Tensor { ...@@ -103,7 +105,8 @@ struct Tensor {
} }
if (byte_size * ele_byte() != data.size()) { if (byte_size * ele_byte() != data.size()) {
LOG(ERROR) << "wrong data size: " << byte_size * ele_byte() << " vs. " << data.size(); LOG(ERROR) << "wrong data size: " << byte_size * ele_byte() << " vs. "
<< data.size();
return false; return false;
} }
...@@ -121,36 +124,25 @@ struct Tensor { ...@@ -121,36 +124,25 @@ struct Tensor {
std::vector<int> shape; std::vector<int> shape;
DataBuf data; DataBuf data;
DataType type; DataType type;
std::vector<std::vector<size_t> > lod; std::vector<std::vector<size_t>> lod;
}; };
class BatchTensor { class BatchTensor {
public: public:
BatchTensor() {} BatchTensor() {}
~BatchTensor() { ~BatchTensor() { _features.clear(); }
_features.clear();
}
BatchTensor(const BatchTensor& tv) { BatchTensor(const BatchTensor& tv) {
_features.assign( _features.assign(tv.features().begin(), tv.features().end());
tv.features().begin(), tv.features().end());
} }
Tensor& operator[](int index) { Tensor& operator[](int index) { return _features[index]; }
return _features[index];
}
const Tensor& operator[](int index) const { const Tensor& operator[](int index) const { return _features[index]; }
return _features[index];
}
void push_back(const Tensor& tensor) { void push_back(const Tensor& tensor) { _features.push_back(tensor); }
_features.push_back(tensor);
}
size_t count() const { size_t count() const { return _features.size(); }
return _features.size();
}
size_t size() const { size_t size() const {
// shape0 indicates batch_size // shape0 indicates batch_size
...@@ -160,20 +152,14 @@ public: ...@@ -160,20 +152,14 @@ public:
return _features[0].shape[0]; return _features[0].shape[0];
} }
const std::vector<Tensor>& features() const { const std::vector<Tensor>& features() const { return _features; }
return _features;
}
void clear() { void clear() { _features.clear(); }
_features.clear();
}
private: private:
std::vector<Tensor> _features; std::vector<Tensor> _features;
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif // BAIDU_PADDLE_SERVING_PREDICTOR_INFER_DATA_H
此差异已折叠。
#include "common/inner_common.h" // 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 "framework/memory.h" #include "framework/memory.h"
#include "common/inner_common.h"
namespace baidu { namespace baidu {
namespace paddle_serving { namespace paddle_serving {
...@@ -37,8 +51,7 @@ int MempoolWrapper::thread_initialize() { ...@@ -37,8 +51,7 @@ int MempoolWrapper::thread_initialize() {
} }
int MempoolWrapper::thread_clear() { int MempoolWrapper::thread_clear() {
im::Mempool* p_mempool = (im::Mempool*) THREAD_GETSPECIFIC( im::Mempool* p_mempool = (im::Mempool*)THREAD_GETSPECIFIC(_bspec_key);
_bspec_key);
if (p_mempool) { if (p_mempool) {
p_mempool->release_block(); p_mempool->release_block();
_region.reset(); _region.reset();
...@@ -48,8 +61,7 @@ int MempoolWrapper::thread_clear() { ...@@ -48,8 +61,7 @@ int MempoolWrapper::thread_clear() {
} }
void* MempoolWrapper::malloc(size_t size) { void* MempoolWrapper::malloc(size_t size) {
im::Mempool* p_mempool = (im::Mempool*) THREAD_GETSPECIFIC( im::Mempool* p_mempool = (im::Mempool*)THREAD_GETSPECIFIC(_bspec_key);
_bspec_key);
if (!p_mempool) { if (!p_mempool) {
LOG(WARNING) << "Cannot malloc memory:" << size LOG(WARNING) << "Cannot malloc memory:" << size
<< ", since mempool is not thread initialized"; << ", since mempool is not thread initialized";
...@@ -58,6 +70,6 @@ void* MempoolWrapper::malloc(size_t size) { ...@@ -58,6 +70,6 @@ void* MempoolWrapper::malloc(size_t size) {
return p_mempool->malloc(size); return p_mempool->malloc(size);
} }
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_MEMORY_H // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#define BAIDU_PADDLE_SERVING_PREDICTOR_MEMORY_H //
// 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 "common/inner_common.h" #include "common/inner_common.h"
#include "mempool/mempool.h" #include "mempool/mempool.h"
...@@ -9,7 +22,7 @@ namespace paddle_serving { ...@@ -9,7 +22,7 @@ namespace paddle_serving {
namespace predictor { namespace predictor {
class MempoolWrapper { class MempoolWrapper {
public: public:
MempoolWrapper() {} MempoolWrapper() {}
static MempoolWrapper& instance() { static MempoolWrapper& instance() {
...@@ -25,13 +38,11 @@ public: ...@@ -25,13 +38,11 @@ public:
void* malloc(size_t size); void* malloc(size_t size);
private: private:
im::fugue::memory::Region _region; im::fugue::memory::Region _region;
THREAD_KEY_T _bspec_key; THREAD_KEY_T _bspec_key;
}; };
} // predictor } // namespace predictor
} // paddle_serving } // namespace paddle_serving
} // baidu } // namespace baidu
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册