diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ad0f39ada004eabc4b604b38e3fdc006b5b7605..65cb869103c11b32aa5dc90866903157214faa32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,8 @@ include(generic) include(paddlepaddle) include(external/opencv) -include_directories("${PADDLE_SERVING_SOURCE_DIR}") +include_directories(${PADDLE_SERVING_SOURCE_DIR}) +include_directories(${PADDLE_SERVING_BINARY_DIR}) set(EXTERNAL_LIBS gflags @@ -94,6 +95,3 @@ add_subdirectory(predictor) add_subdirectory(inferencer-fluid-cpu) add_subdirectory(serving) add_subdirectory(sdk-cpp) - - - diff --git a/README.md b/README.md index dce0087b638a9f8573813683e85e2412ccaca8f2..8715b2f703ab241d236542784bb82270c165ed9c 100644 --- a/README.md +++ b/README.md @@ -336,4 +336,3 @@ Paddle serving框架为策略工程师提供以下三层面的功能性扩展: {:name => 'main', :conf => 'predictor_valid.conf', :target => 'port'}, // valid工具向这个端口发送测试请求,确保服务已正常启动 ] ``` - diff --git a/configure/CMakeLists.txt b/configure/CMakeLists.txt index 427f994e768208b332d7ae170ee41418f555841b..f2afda8ffd2321b823934d23232c31110b406a2e 100644 --- a/configure/CMakeLists.txt +++ b/configure/CMakeLists.txt @@ -11,6 +11,9 @@ list(APPEND configure_srcs ${CMAKE_CURRENT_LIST_DIR}/src/configure_parser.cpp) add_library(configure ${configure_srcs}) add_dependencies(configure brpc) +target_include_directories(configure PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/ + ) add_executable(test_configure ${CMAKE_CURRENT_LIST_DIR}/tests/test_configure.cpp) @@ -23,4 +26,3 @@ target_link_libraries(test_configure configure protobuf) install(TARGETS configure ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib ) - diff --git a/configure/include/configure_parser.h b/configure/include/configure_parser.h index f84871fcb8991058eb01451816dcfd359953dd9f..fc9f786a192e40e14fd6c79206ccc5edf13809d5 100644 --- a/configure/include/configure_parser.h +++ b/configure/include/configure_parser.h @@ -1,17 +1,32 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once #include +#include namespace baidu { namespace paddle_serving { namespace configure { int read_proto_conf(const std::string &conf_path, - const std::string &conf_file, - google::protobuf::Message *conf); + const std::string &conf_file, + google::protobuf::Message *conf); int write_proto_conf(google::protobuf::Message *message, - const std::string &output_path, - const std::string &output_file); + const std::string &output_path, + const std::string &output_file); -} // configure -} // paddle_serving -} // baidu +} // namespace configure +} // namespace paddle_serving +} // namespace baidu diff --git a/configure/proto/inferencer_configure.proto b/configure/proto/inferencer_configure.proto index 168807d5cbd7cb3194f052ff9de199e84a2ca362..cfb03cb35da9623130da85a6abf3bb4448c05369 100644 --- a/configure/proto/inferencer_configure.proto +++ b/configure/proto/inferencer_configure.proto @@ -1,11 +1,24 @@ -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; message SigmoidConf { - required string dnn_model_path = 1; - required string sigmoid_w_file = 2; - required string sigmoid_b_file = 3; - required float exp_max_input = 4; - required float exp_min_input = 5; + required string dnn_model_path = 1; + required string sigmoid_w_file = 2; + required string sigmoid_b_file = 3; + required float exp_max_input = 4; + required float exp_min_input = 5; }; - diff --git a/configure/proto/sdk_configure.proto b/configure/proto/sdk_configure.proto index 1c7b9a38e97524ba6f390a04a3d6e2660e7dec2c..99f26c6f4cddcae9bf01785764a6c4167a58f76b 100644 --- a/configure/proto/sdk_configure.proto +++ b/configure/proto/sdk_configure.proto @@ -1,59 +1,70 @@ -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; message ConnectionConf { - required uint32 connect_timeout_ms = 1; - required uint32 rpc_timeout_ms = 2; - required uint32 connect_retry_count = 3; - required uint32 max_connection_per_host = 4; - required uint32 hedge_request_timeout_ms = 5; - required uint32 hedge_fetch_retry_count = 6; - required string connection_type = 7; + required uint32 connect_timeout_ms = 1; + required uint32 rpc_timeout_ms = 2; + required uint32 connect_retry_count = 3; + required uint32 max_connection_per_host = 4; + required uint32 hedge_request_timeout_ms = 5; + required uint32 hedge_fetch_retry_count = 6; + required string connection_type = 7; }; message NamingConf { - optional string cluster_filter_strategy = 1; - optional string load_balance_strategy = 2; - optional string cluster = 3; + optional string cluster_filter_strategy = 1; + optional string load_balance_strategy = 2; + optional string cluster = 3; }; message RpcParameter { - // 0-NONE, 1-SNAPPY, 2-GZIP, 3-ZLIB, 4-LZ4 - required uint32 compress_type = 1; - required uint32 package_size = 2; - required string protocol = 3; - required uint32 max_channel_per_request = 4; + // 0-NONE, 1-SNAPPY, 2-GZIP, 3-ZLIB, 4-LZ4 + required uint32 compress_type = 1; + required uint32 package_size = 2; + required string protocol = 3; + required uint32 max_channel_per_request = 4; }; -message SplitConf{ - optional string split_tag_name = 1; - optional string tag_candidates = 2; +message SplitConf { + optional string split_tag_name = 1; + optional string tag_candidates = 2; }; message VariantConf { - required string tag = 1; - optional ConnectionConf connection_conf = 2; - optional NamingConf naming_conf = 3; - optional RpcParameter rpc_parameter = 4; - optional SplitConf split_conf = 5; - optional string variant_router = 6; + required string tag = 1; + optional ConnectionConf connection_conf = 2; + optional NamingConf naming_conf = 3; + optional RpcParameter rpc_parameter = 4; + optional SplitConf split_conf = 5; + optional string variant_router = 6; }; -message WeightedRandomRenderConf { - required string variant_weight_list = 1; -}; +message WeightedRandomRenderConf { required string variant_weight_list = 1; }; message Predictor { - required string name = 1; - required string service_name = 2; - required string endpoint_router = 3; - required WeightedRandomRenderConf weighted_random_render_conf = 4; - repeated VariantConf variants = 5; + required string name = 1; + required string service_name = 2; + required string endpoint_router = 3; + required WeightedRandomRenderConf weighted_random_render_conf = 4; + repeated VariantConf variants = 5; }; // SDK conf message SDKConf { - required VariantConf default_variant_conf = 1; - repeated Predictor predictors = 2; + required VariantConf default_variant_conf = 1; + repeated Predictor predictors = 2; }; - diff --git a/configure/proto/server_configure.proto b/configure/proto/server_configure.proto index 32e7384506d00d7d17360e3096f429f8b4443632..ccd97b83ba1050b5bf00b54ea0d3b0478ccfa2ca 100644 --- a/configure/proto/server_configure.proto +++ b/configure/proto/server_configure.proto @@ -1,55 +1,64 @@ -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; message EngineDesc { - required string name = 1; - required string type = 2; - required string reloadable_meta = 3; - required string reloadable_type = 4; - required string model_data_path = 5; - required uint32 runtime_thread_num = 6; - required uint32 batch_infer_size = 7; - required uint32 enable_batch_align = 8; - optional string version_file = 9; - optional string version_type = 10; + required string name = 1; + required string type = 2; + required string reloadable_meta = 3; + required string reloadable_type = 4; + required string model_data_path = 5; + required uint32 runtime_thread_num = 6; + required uint32 batch_infer_size = 7; + required uint32 enable_batch_align = 8; + optional string version_file = 9; + optional string version_type = 10; }; // model_toolkit conf -message ModelToolkitConf { - repeated EngineDesc engines = 1; -}; +message ModelToolkitConf { repeated EngineDesc engines = 1; }; // reource conf message ResourceConf { - required string model_toolkit_path = 1; - required string model_toolkit_file = 2; + required string model_toolkit_path = 1; + required string model_toolkit_file = 2; }; // DAG node depency info message DAGNodeDependency { - required string name = 1; - required string mode = 2; + required string name = 1; + required string mode = 2; }; // DAG Node message DAGNode { - required string name = 1; - required string type = 2; - repeated DAGNodeDependency dependencies = 3; + required string name = 1; + required string type = 2; + repeated DAGNodeDependency dependencies = 3; }; // workflow entry message Workflow { - required string name = 1; - required string workflow_type = 2; - repeated DAGNode nodes = 3; + required string name = 1; + required string workflow_type = 2; + repeated DAGNode nodes = 3; }; // Workflow conf -message WorkflowConf { - repeated Workflow workflows = 1; -} - +message WorkflowConf { repeated Workflow workflows = 1; } // request_field_key: specifies use which request field as mapping key (see // request_field_key in InferService below) @@ -58,32 +67,32 @@ message WorkflowConf { // matches the value of `request_field_value` in one of the // ValueMappedWorkflows, the request will be directed to the workflow specified // in the `workflow` field of that ValueMappedWorkflow -// +// message ValueMappedWorkflow { - required string request_field_value = 1; - required string workflow = 2; + required string request_field_value = 1; + required string workflow = 2; }; message InferService { - required string name = 1; - optional string merger = 2; + required string name = 1; + 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 - // - // Each request will be mapped to a workflow according to the value in - // in user request field specified by `request_field_key` (see the - // comments for ValueMappedWorkflow above) - optional string request_field_key = 4; - repeated ValueMappedWorkflow value_mapped_workflows = 5; + // If enable_map_request_to_workfow = true + // + // Each request will be mapped to a workflow according to the value in + // in user request field specified by `request_field_key` (see the + // comments for ValueMappedWorkflow above) + optional string request_field_key = 4; + repeated ValueMappedWorkflow value_mapped_workflows = 5; - // If enable_map_request_to_workflow = false - repeated string workflows = 6; + // If enable_map_request_to_workflow = false + repeated string workflows = 6; }; // InferService conf message InferServiceConf { - optional uint32 port = 1; - repeated InferService services = 2; + optional uint32 port = 1; + repeated InferService services = 2; }; diff --git a/configure/src/configure_parser.cpp b/configure/src/configure_parser.cpp index d527b8ee581f43f469de470bf10e4143677e4c82..d7e8aa1085df7668ea9fb737a28bc7f74729b652 100644 --- a/configure/src/configure_parser.cpp +++ b/configure/src/configure_parser.cpp @@ -1,11 +1,26 @@ -#include -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "include/configure_parser.h" #include +#include +#include #include #include "butil/logging.h" -#include -#include +#include "google/protobuf/io/zero_copy_stream_impl.h" +#include "google/protobuf/text_format.h" namespace baidu { namespace paddle_serving { @@ -13,46 +28,44 @@ namespace configure { int read_proto_conf(const std::string &conf_path, const std::string &conf_file, - google::protobuf::Message *conf) -{ - std::string file_str = conf_path + "/" + conf_file; - int fd = open(file_str.c_str(), O_RDONLY); - if (fd == -1) { - LOG(WARNING) << "File not found: " << file_str.c_str(); - return -1; - } - - google::protobuf::io::FileInputStream input(fd); - bool success = google::protobuf::TextFormat::Parse(&input, conf); - close(fd); - if (!success) { - return -1; - } - - return 0; + google::protobuf::Message *conf) { + std::string file_str = conf_path + "/" + conf_file; + int fd = open(file_str.c_str(), O_RDONLY); + if (fd == -1) { + LOG(WARNING) << "File not found: " << file_str.c_str(); + return -1; + } + + google::protobuf::io::FileInputStream input(fd); + bool success = google::protobuf::TextFormat::Parse(&input, conf); + close(fd); + if (!success) { + return -1; + } + + return 0; } int write_proto_conf(google::protobuf::Message *message, - const std::string &output_path, - const std::string &output_file) -{ - std::string binary_str; - google::protobuf::TextFormat::PrintToString(*message, &binary_str); - - std::string file_str = output_path + "/" + output_file; - std::ofstream fout_bin((file_str.c_str())); - if (!fout_bin) { - LOG(WARNING) << "Open file error: " << file_str.c_str(); - return -1; - } - - fout_bin.write((char *)binary_str.c_str(), binary_str.size()); - fout_bin.close(); - - return 0; + const std::string &output_path, + const std::string &output_file) { + std::string binary_str; + google::protobuf::TextFormat::PrintToString(*message, &binary_str); + + std::string file_str = output_path + "/" + output_file; + std::ofstream fout_bin((file_str.c_str())); + if (!fout_bin) { + LOG(WARNING) << "Open file error: " << file_str.c_str(); + return -1; + } + + fout_bin.write(binary_str.c_str(), binary_str.size()); + fout_bin.close(); + + return 0; } -} // configure -} // paddle_serving -} // baidu -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace configure +} // namespace paddle_serving +} // namespace baidu +/* vim: set expandtab ts=2 sw=2 sts=2 tw=100: */ diff --git a/configure/tests/test_configure.cpp b/configure/tests/test_configure.cpp index 8adf52a16536367b90d7c706ef0c35bd25f6ec2a..de7555c10f1ddbd9db4214af8a0407c7e43a838c 100644 --- a/configure/tests/test_configure.cpp +++ b/configure/tests/test_configure.cpp @@ -1,11 +1,25 @@ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include #include -#include "server_configure.pb.h" -#include "sdk_configure.pb.h" -#include "inferencer_configure.pb.h" -#include "configure_parser.h" +#include "configure/inferencer_configure.pb.h" +#include "configure/sdk_configure.pb.h" +#include "configure/server_configure.pb.h" +#include "include/configure_parser.h" using baidu::paddle_serving::configure::EngineDesc; using baidu::paddle_serving::configure::ModelToolkitConf; @@ -30,234 +44,247 @@ using baidu::paddle_serving::configure::SDKConf; using baidu::paddle_serving::configure::SigmoidConf; -const std::string output_dir = "./conf/"; -const std::string model_toolkit_conf_file = "model_toolkit.prototxt"; -const std::string resource_conf_file = "resource.prototxt"; -const std::string workflow_conf_file = "workflow.prototxt"; -const std::string service_conf_file = "service.prototxt"; -const std::string sdk_conf_file = "predictors.prototxt"; -const std::string sigmoid_conf_file = "inferencer.prototxt"; - -int test_write_conf() -{ - // model_toolkit conf - ModelToolkitConf model_toolkit_conf; - - // This engine has a default version - EngineDesc *engine = model_toolkit_conf.add_engines(); - engine->set_name("image_classification_resnet"); - engine->set_type("FLUID_CPU_NATIVE_DIR"); - engine->set_reloadable_meta("./data/model/paddle/fluid_time_file"); - engine->set_reloadable_type("timestamp_ne"); - engine->set_model_data_path("./data/model/paddle/fluid/SE_ResNeXt50_32x4d"); - engine->set_runtime_thread_num(0); - engine->set_batch_infer_size(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); - if (ret != 0) { - return ret; - } - - // resource conf - ResourceConf resource_conf; - resource_conf.set_model_toolkit_path(output_dir); - resource_conf.set_model_toolkit_file("model_toolkit.prototxt"); - ret = baidu::paddle_serving::configure::write_proto_conf(&resource_conf, output_dir, resource_conf_file); - if (ret != 0) { - return ret; - } - - // workflow entries conf - WorkflowConf workflow_conf; - Workflow *workflow = workflow_conf.add_workflows(); - workflow->set_name("workflow1"); - workflow->set_workflow_type("Sequence"); - - DAGNode *dag_node = workflow->add_nodes(); - dag_node->set_name("image_reader_op"); - dag_node->set_type("ReaderOp"); - - dag_node = workflow->add_nodes(); - dag_node->set_name("imag_classify_op"); - dag_node->set_type("ClassifyOp"); - DAGNodeDependency *node_dependency = dag_node->add_dependencies(); - node_dependency->set_name("image_reader_op"); - node_dependency->set_mode("RO"); - - dag_node = workflow->add_nodes(); - dag_node->set_name("write_json_op"); - dag_node->set_type("WriteOp"); - node_dependency = dag_node->add_dependencies(); - node_dependency->set_name("image_classify_op"); - node_dependency->set_mode("RO"); - - workflow = workflow_conf.add_workflows(); - workflow->set_name("workflow2"); - workflow->set_workflow_type("Sequence"); - - dag_node = workflow->add_nodes(); - dag_node->set_name("dense_op"); - dag_node->set_type("DenseOp"); - - ret = baidu::paddle_serving::configure::write_proto_conf(&workflow_conf, output_dir, workflow_conf_file); - if (ret != 0) { - return ret; - } - - InferServiceConf infer_service_conf; - infer_service_conf.set_port(0); - InferService *infer_service = infer_service_conf.add_services(); - infer_service->set_name("ImageClassifyService"); - infer_service->add_workflows("workflow1"); - infer_service->add_workflows("workflow2"); - - infer_service = infer_service_conf.add_services(); - infer_service->set_name("BuiltinDenseFormatService"); - infer_service->add_workflows("workflow2"); - - ret = baidu::paddle_serving::configure::write_proto_conf(&infer_service_conf, output_dir, service_conf_file); - if (ret != 0) { - return ret; - } - - SDKConf sdk_conf; - VariantConf *default_variant_conf = sdk_conf.mutable_default_variant_conf(); - default_variant_conf->set_tag("default"); - - ConnectionConf *connection_conf = default_variant_conf->mutable_connection_conf(); - connection_conf->set_connect_timeout_ms(2000); - connection_conf->set_rpc_timeout_ms(20000); - connection_conf->set_connect_retry_count(2); - connection_conf->set_max_connection_per_host(100); - connection_conf->set_hedge_request_timeout_ms(-1); - connection_conf->set_hedge_fetch_retry_count(2); - connection_conf->set_connection_type("pooled"); - - NamingConf *naming_conf = default_variant_conf->mutable_naming_conf(); - naming_conf->set_cluster_filter_strategy("Default"); - naming_conf->set_load_balance_strategy("la"); - - RpcParameter *rpc_parameter = default_variant_conf->mutable_rpc_parameter(); - rpc_parameter->set_compress_type(0); - rpc_parameter->set_package_size(20); - rpc_parameter->set_protocol("baidu_std"); - rpc_parameter->set_max_channel_per_request(3); - - Predictor *predictor = sdk_conf.add_predictors(); - predictor->set_name("ximage"); - predictor->set_service_name("baidu.paddle_serving.predictor.image_classification.ImageClassifyService"); - predictor->set_endpoint_router("WeightedRandomRender"); - - WeightedRandomRenderConf *weighted_random_render_conf = predictor->mutable_weighted_random_render_conf(); - weighted_random_render_conf->set_variant_weight_list("50"); - - VariantConf *variant_conf = predictor->add_variants(); - variant_conf->set_tag("var1"); - naming_conf = variant_conf->mutable_naming_conf(); - 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); - if (ret != 0) { - return ret; - } - - SigmoidConf sigmoid_conf; - sigmoid_conf.set_dnn_model_path("data/dnn_model"); - sigmoid_conf.set_sigmoid_w_file("data/dnn_model/_sigmoid_.w_0"); - sigmoid_conf.set_sigmoid_b_file("data/dnn_model/_sigmoid_.b_0"); - sigmoid_conf.set_exp_max_input(0.75); - sigmoid_conf.set_exp_min_input(0.25); - - ret = baidu::paddle_serving::configure::write_proto_conf(&sigmoid_conf, output_dir, sigmoid_conf_file); - if (ret != 0) { - return ret; - } - - return 0; +const char *output_dir = "./conf/"; +const char *model_toolkit_conf_file = "model_toolkit.prototxt"; +const char *resource_conf_file = "resource.prototxt"; +const char *workflow_conf_file = "workflow.prototxt"; +const char *service_conf_file = "service.prototxt"; +const char *sdk_conf_file = "predictors.prototxt"; +const char *sigmoid_conf_file = "inferencer.prototxt"; + +int test_write_conf() { + // model_toolkit conf + ModelToolkitConf model_toolkit_conf; + + // This engine has a default version + EngineDesc *engine = model_toolkit_conf.add_engines(); + engine->set_name("image_classification_resnet"); + engine->set_type("FLUID_CPU_NATIVE_DIR"); + engine->set_reloadable_meta("./data/model/paddle/fluid_time_file"); + engine->set_reloadable_type("timestamp_ne"); + engine->set_model_data_path("./data/model/paddle/fluid/SE_ResNeXt50_32x4d"); + engine->set_runtime_thread_num(0); + engine->set_batch_infer_size(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); + if (ret != 0) { + return ret; + } + + // resource conf + ResourceConf resource_conf; + resource_conf.set_model_toolkit_path(output_dir); + resource_conf.set_model_toolkit_file("model_toolkit.prototxt"); + ret = baidu::paddle_serving::configure::write_proto_conf( + &resource_conf, output_dir, resource_conf_file); + if (ret != 0) { + return ret; + } + + // workflow entries conf + WorkflowConf workflow_conf; + Workflow *workflow = workflow_conf.add_workflows(); + workflow->set_name("workflow1"); + workflow->set_workflow_type("Sequence"); + + DAGNode *dag_node = workflow->add_nodes(); + dag_node->set_name("image_reader_op"); + dag_node->set_type("ReaderOp"); + + dag_node = workflow->add_nodes(); + dag_node->set_name("imag_classify_op"); + dag_node->set_type("ClassifyOp"); + DAGNodeDependency *node_dependency = dag_node->add_dependencies(); + node_dependency->set_name("image_reader_op"); + node_dependency->set_mode("RO"); + + dag_node = workflow->add_nodes(); + dag_node->set_name("write_json_op"); + dag_node->set_type("WriteOp"); + node_dependency = dag_node->add_dependencies(); + node_dependency->set_name("image_classify_op"); + node_dependency->set_mode("RO"); + + workflow = workflow_conf.add_workflows(); + workflow->set_name("workflow2"); + workflow->set_workflow_type("Sequence"); + + dag_node = workflow->add_nodes(); + dag_node->set_name("dense_op"); + dag_node->set_type("DenseOp"); + + ret = baidu::paddle_serving::configure::write_proto_conf( + &workflow_conf, output_dir, workflow_conf_file); + if (ret != 0) { + return ret; + } + + InferServiceConf infer_service_conf; + infer_service_conf.set_port(0); + InferService *infer_service = infer_service_conf.add_services(); + infer_service->set_name("ImageClassifyService"); + infer_service->add_workflows("workflow1"); + infer_service->add_workflows("workflow2"); + + infer_service = infer_service_conf.add_services(); + infer_service->set_name("BuiltinDenseFormatService"); + infer_service->add_workflows("workflow2"); + + ret = baidu::paddle_serving::configure::write_proto_conf( + &infer_service_conf, output_dir, service_conf_file); + if (ret != 0) { + return ret; + } + + SDKConf sdk_conf; + VariantConf *default_variant_conf = sdk_conf.mutable_default_variant_conf(); + default_variant_conf->set_tag("default"); + + ConnectionConf *connection_conf = + default_variant_conf->mutable_connection_conf(); + connection_conf->set_connect_timeout_ms(2000); + connection_conf->set_rpc_timeout_ms(20000); + connection_conf->set_connect_retry_count(2); + connection_conf->set_max_connection_per_host(100); + connection_conf->set_hedge_request_timeout_ms(-1); + connection_conf->set_hedge_fetch_retry_count(2); + connection_conf->set_connection_type("pooled"); + + NamingConf *naming_conf = default_variant_conf->mutable_naming_conf(); + naming_conf->set_cluster_filter_strategy("Default"); + naming_conf->set_load_balance_strategy("la"); + + RpcParameter *rpc_parameter = default_variant_conf->mutable_rpc_parameter(); + rpc_parameter->set_compress_type(0); + rpc_parameter->set_package_size(20); + rpc_parameter->set_protocol("baidu_std"); + rpc_parameter->set_max_channel_per_request(3); + + Predictor *predictor = sdk_conf.add_predictors(); + predictor->set_name("ximage"); + predictor->set_service_name( + "baidu.paddle_serving.predictor.image_classification." + "ImageClassifyService"); + predictor->set_endpoint_router("WeightedRandomRender"); + + WeightedRandomRenderConf *weighted_random_render_conf = + predictor->mutable_weighted_random_render_conf(); + weighted_random_render_conf->set_variant_weight_list("50"); + + VariantConf *variant_conf = predictor->add_variants(); + variant_conf->set_tag("var1"); + naming_conf = variant_conf->mutable_naming_conf(); + 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); + if (ret != 0) { + return ret; + } + + SigmoidConf sigmoid_conf; + sigmoid_conf.set_dnn_model_path("data/dnn_model"); + sigmoid_conf.set_sigmoid_w_file("data/dnn_model/_sigmoid_.w_0"); + sigmoid_conf.set_sigmoid_b_file("data/dnn_model/_sigmoid_.b_0"); + sigmoid_conf.set_exp_max_input(0.75); + sigmoid_conf.set_exp_min_input(0.25); + + ret = baidu::paddle_serving::configure::write_proto_conf( + &sigmoid_conf, output_dir, sigmoid_conf_file); + if (ret != 0) { + return ret; + } + + return 0; } -int test_read_conf() -{ - int ret = 0; - - ModelToolkitConf model_toolkit_conf; - ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, model_toolkit_conf_file, &model_toolkit_conf); - if (ret != 0) { - std::cout << "Read conf fail: " << model_toolkit_conf_file << std::endl; - return -1; - } - - ResourceConf resource_conf; - ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, resource_conf_file, &resource_conf); - if (ret != 0) { - std::cout << "Read conf fail: " << resource_conf_file << std::endl; - return -1; - } - - WorkflowConf workflow_conf; - ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, workflow_conf_file, &workflow_conf); - if (ret != 0) { - std::cout << "Read conf fail: " << workflow_conf_file << std::endl; - return -1; - } - - InferServiceConf service_conf; - ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, service_conf_file, &service_conf); - if (ret != 0) { - std::cout << "Read conf fail: " << service_conf_file << std::endl; - return -1; - } +int test_read_conf() { + int ret = 0; + + ModelToolkitConf model_toolkit_conf; + ret = baidu::paddle_serving::configure::read_proto_conf( + output_dir, model_toolkit_conf_file, &model_toolkit_conf); + if (ret != 0) { + std::cout << "Read conf fail: " << model_toolkit_conf_file << std::endl; + return -1; + } + + ResourceConf resource_conf; + ret = baidu::paddle_serving::configure::read_proto_conf( + output_dir, resource_conf_file, &resource_conf); + if (ret != 0) { + std::cout << "Read conf fail: " << resource_conf_file << std::endl; + return -1; + } + + WorkflowConf workflow_conf; + ret = baidu::paddle_serving::configure::read_proto_conf( + output_dir, workflow_conf_file, &workflow_conf); + if (ret != 0) { + std::cout << "Read conf fail: " << workflow_conf_file << std::endl; + return -1; + } + + InferServiceConf service_conf; + ret = baidu::paddle_serving::configure::read_proto_conf( + output_dir, service_conf_file, &service_conf); + if (ret != 0) { + std::cout << "Read conf fail: " << service_conf_file << std::endl; + return -1; + } + + SDKConf sdk_conf; + ret = baidu::paddle_serving::configure::read_proto_conf( + output_dir, sdk_conf_file, &sdk_conf); + if (ret != 0) { + std::cout << "Read conf fail: " << sdk_conf_file << std::endl; + return -1; + } + + SigmoidConf sigmoid_conf; + ret = baidu::paddle_serving::configure::read_proto_conf( + output_dir, sigmoid_conf_file, &sigmoid_conf); + if (ret != 0) { + std::cout << "Read conf fail: " << sdk_conf_file << std::endl; + return -1; + } + + return 0; +} - SDKConf sdk_conf; - ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, sdk_conf_file, &sdk_conf); +int main() { + int ret = 0; + struct stat stat_buf; + if (stat(output_dir, &stat_buf) != 0) { + int ret = mkdir("./conf", 0777); if (ret != 0) { - std::cout << "Read conf fail: " << sdk_conf_file << std::endl; - return -1; + std::cout << "mkdir ./conf fail" << std::endl; + return -1; } - - SigmoidConf sigmoid_conf; - ret = baidu::paddle_serving::configure::read_proto_conf(output_dir, sigmoid_conf_file, &sigmoid_conf); - if (ret != 0) { - std::cout << "Read conf fail: " << sdk_conf_file << std::endl; - return -1; + if (stat("./conf", &stat_buf) != 0) { + std::cout << "./conf not exist and creating it failed" << std::endl; + return -1; } + } - return 0; -} + ret = test_write_conf(); + if (ret != 0) { + std::cout << "test_write_conf fail" << std::endl; + return -1; + } -int main() -{ - int ret = 0; - struct stat stat_buf; - if (stat(output_dir.c_str(), &stat_buf) != 0) { - int ret = mkdir("./conf", 0777); - if (ret != 0) { - std::cout << "mkdir ./conf fail" << std::endl; - return -1; - } - if (stat("./conf", &stat_buf) != 0) { - std::cout << "./conf not exist and creating it failed" << std::endl; - return -1; - } - } + std::cout << "test_write_conf success" << std::endl; - ret = test_write_conf(); - if (ret != 0) { - std::cout << "test_write_conf fail" << std::endl; - return -1; - } - - std::cout << "test_write_conf success" << std::endl; - - ret = test_read_conf(); - if (ret != 0) { - std::cout << "test_read_conf fail" << std::endl; - return -1; - } - std::cout << "test_read_conf success" << std::endl; + ret = test_read_conf(); + if (ret != 0) { + std::cout << "test_read_conf fail" << std::endl; + return -1; + } + std::cout << "test_read_conf success" << std::endl; - return 0; + return 0; } /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/inferencer-fluid-cpu/CMakeLists.txt b/inferencer-fluid-cpu/CMakeLists.txt index ebfde7d9ea8f1700f8bbcdad1f7477fc57067804..bb5f108c8c5051b5db4df01c605e703a2b9df743 100644 --- a/inferencer-fluid-cpu/CMakeLists.txt +++ b/inferencer-fluid-cpu/CMakeLists.txt @@ -10,4 +10,3 @@ target_link_libraries(fluid_cpu_engine pdserving paddle_fluid -liomp5 -lmklml_in install(TARGETS fluid_cpu_engine ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib ) - diff --git a/inferencer-fluid-cpu/include/fluid_cpu_engine.h b/inferencer-fluid-cpu/include/fluid_cpu_engine.h index 0f1e6613b684d329b7b280abfa0e168b24082860..d7f3725e02634b4c403205a4ab7c5adbdc1706e8 100644 --- a/inferencer-fluid-cpu/include/fluid_cpu_engine.h +++ b/inferencer-fluid-cpu/include/fluid_cpu_engine.h @@ -1,14 +1,28 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once #include +#include +#include #include #include -#include -#include +#include "configure/include/configure_parser.h" +#include "configure/inferencer_configure.pb.h" #include "framework/infer.h" #include "paddle/fluid/inference/paddle_inference_api.h" -#include "inferencer_configure.pb.h" -#include "configure_parser.h" namespace baidu { namespace paddle_serving { @@ -17,483 +31,472 @@ namespace fluid_cpu { using configure::SigmoidConf; class AutoLock { -public: - AutoLock(pthread_mutex_t& mutex) : _mut(mutex){ - pthread_mutex_lock(&mutex); - } + public: + explicit AutoLock(pthread_mutex_t& mutex) : _mut(mutex) { + pthread_mutex_lock(&mutex); + } - ~AutoLock() { - pthread_mutex_unlock(&_mut); - } + ~AutoLock() { pthread_mutex_unlock(&_mut); } -private: - pthread_mutex_t& _mut; + private: + pthread_mutex_t& _mut; }; class GlobalPaddleCreateMutex { -public: - pthread_mutex_t& mutex() { - return _mut; - } + public: + pthread_mutex_t& mutex() { return _mut; } - static pthread_mutex_t& instance() { - static GlobalPaddleCreateMutex gmutex; - return gmutex.mutex(); - } + static pthread_mutex_t& instance() { + static GlobalPaddleCreateMutex gmutex; + return gmutex.mutex(); + } -private: - GlobalPaddleCreateMutex() { - pthread_mutex_init(&_mut, NULL); - } + private: + GlobalPaddleCreateMutex() { pthread_mutex_init(&_mut, NULL); } - pthread_mutex_t _mut; + pthread_mutex_t _mut; }; class GlobalSigmoidCreateMutex { -public: - pthread_mutex_t& mutex() { - return _mut; - } - static pthread_mutex_t& instance() { + public: + pthread_mutex_t& mutex() { return _mut; } + static pthread_mutex_t& instance() { static GlobalSigmoidCreateMutex gmutex; - return gmutex.mutex(); - } -private: - GlobalSigmoidCreateMutex() { - pthread_mutex_init(&_mut, NULL); - } + return gmutex.mutex(); + } - pthread_mutex_t _mut; + private: + GlobalSigmoidCreateMutex() { pthread_mutex_init(&_mut, NULL); } + + pthread_mutex_t _mut; }; // data interface class FluidFamilyCore { -public: - - virtual ~FluidFamilyCore() {} - virtual bool Run(const void* in_data, void* out_data) { - if (!_core->Run(*(std::vector*)in_data, + public: + virtual ~FluidFamilyCore() {} + virtual bool Run(const void* in_data, void* out_data) { + if (!_core->Run(*(std::vector*)in_data, (std::vector*)out_data)) { - LOG(ERROR) << "Failed call Run with paddle predictor"; - return false; - } - - return true; + LOG(ERROR) << "Failed call Run with paddle predictor"; + return false; } - virtual int create(const std::string& data_path) = 0; - - virtual int clone(void* origin_core) { - if (origin_core == NULL) { - LOG(ERROR) << "origin paddle Predictor is null."; - return -1; - } - paddle::PaddlePredictor* p_predictor = (paddle::PaddlePredictor*)origin_core; - _core = p_predictor->Clone(); - if (_core.get() == NULL) { - LOG(ERROR) << "fail to clone paddle predictor: " << origin_core; - return -1; - } - return 0; + return true; + } + + virtual int create(const std::string& data_path) = 0; + + virtual int clone(void* origin_core) { + if (origin_core == NULL) { + LOG(ERROR) << "origin paddle Predictor is null."; + return -1; + } + paddle::PaddlePredictor* p_predictor = + (paddle::PaddlePredictor*)origin_core; + _core = p_predictor->Clone(); + if (_core.get() == NULL) { + LOG(ERROR) << "fail to clone paddle predictor: " << origin_core; + return -1; } + return 0; + } - virtual void* get() { - return _core.get(); - } + virtual void* get() { return _core.get(); } -protected: - std::unique_ptr _core; + protected: + std::unique_ptr _core; }; // infer interface class FluidCpuAnalysisCore : public FluidFamilyCore { -public: - int create(const std::string& data_path) { - if (access(data_path.c_str(), F_OK) == -1) { - LOG(ERROR) << "create paddle predictor failed, path not exits: " - << data_path; - return -1; - } - - paddle::contrib::AnalysisConfig analysis_config; - analysis_config.param_file = data_path + "/__params__"; - analysis_config.prog_file = data_path + "/__model__"; - analysis_config.use_gpu = false; - analysis_config.device = 0; - analysis_config.specify_input_name = true; - AutoLock lock(GlobalPaddleCreateMutex::instance()); - _core = paddle::CreatePaddlePredictor< - paddle::contrib::AnalysisConfig>(analysis_config); - if (NULL == _core.get()) { - LOG(ERROR) << "create paddle predictor failed, path: " - << data_path; - return -1; - } - - LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; - return 0; + public: + int create(const std::string& data_path) { + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path not exits: " + << data_path; + return -1; } + + paddle::contrib::AnalysisConfig analysis_config; + analysis_config.param_file = data_path + "/__params__"; + analysis_config.prog_file = data_path + "/__model__"; + analysis_config.use_gpu = false; + analysis_config.device = 0; + analysis_config.specify_input_name = true; + AutoLock lock(GlobalPaddleCreateMutex::instance()); + _core = paddle::CreatePaddlePredictor( + analysis_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; + } + + LOG(WARNING) << "create paddle predictor sucess, path: " << data_path; + return 0; + } }; class FluidCpuNativeCore : public FluidFamilyCore { -public: - int create(const std::string& data_path) { - if (access(data_path.c_str(), F_OK) == -1) { - LOG(ERROR) << "create paddle predictor failed, path not exits: " - << data_path; - return -1; - } - - paddle::NativeConfig native_config; - native_config.param_file = data_path + "/__params__"; - native_config.prog_file = data_path + "/__model__"; - native_config.use_gpu = false; - native_config.device = 0; - AutoLock lock(GlobalPaddleCreateMutex::instance()); - _core = paddle::CreatePaddlePredictor< - paddle::NativeConfig, paddle::PaddleEngineKind::kNative>(native_config); - if (NULL == _core.get()) { - LOG(ERROR) << "create paddle predictor failed, path: " - << data_path; - return -1; - } - - LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; - return 0; + public: + int create(const std::string& data_path) { + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path not exits: " + << data_path; + return -1; } + + paddle::NativeConfig native_config; + native_config.param_file = data_path + "/__params__"; + native_config.prog_file = data_path + "/__model__"; + native_config.use_gpu = false; + native_config.device = 0; + AutoLock lock(GlobalPaddleCreateMutex::instance()); + _core = paddle::CreatePaddlePredictor( + native_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; + } + + LOG(WARNING) << "create paddle predictor sucess, path: " << data_path; + return 0; + } }; class FluidCpuAnalysisDirCore : public FluidFamilyCore { -public: - int create(const std::string& data_path) { - if (access(data_path.c_str(), F_OK) == -1) { - LOG(ERROR) << "create paddle predictor failed, path not exits: " - << data_path; - return -1; - } - - paddle::contrib::AnalysisConfig analysis_config; - analysis_config.model_dir = data_path; - analysis_config.use_gpu = false; - analysis_config.device = 0; - analysis_config.specify_input_name = true; - AutoLock lock(GlobalPaddleCreateMutex::instance()); - _core = paddle::CreatePaddlePredictor< - paddle::contrib::AnalysisConfig>(analysis_config); - if (NULL == _core.get()) { - LOG(ERROR) << "create paddle predictor failed, path: " - << data_path; - return -1; - } - - LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; - return 0; + public: + int create(const std::string& data_path) { + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path not exits: " + << data_path; + return -1; } + paddle::contrib::AnalysisConfig analysis_config; + analysis_config.model_dir = data_path; + analysis_config.use_gpu = false; + analysis_config.device = 0; + analysis_config.specify_input_name = true; + AutoLock lock(GlobalPaddleCreateMutex::instance()); + _core = paddle::CreatePaddlePredictor( + analysis_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; + } + + LOG(WARNING) << "create paddle predictor sucess, path: " << data_path; + return 0; + } }; class FluidCpuNativeDirCore : public FluidFamilyCore { -public: - int create(const std::string& data_path) { - if (access(data_path.c_str(), F_OK) == -1) { - LOG(ERROR) << "create paddle predictor failed, path not exits: " - << data_path; - return -1; - } - - paddle::NativeConfig native_config; - native_config.model_dir = data_path; - native_config.use_gpu = false; - native_config.device = 0; - AutoLock lock(GlobalPaddleCreateMutex::instance()); - _core = paddle::CreatePaddlePredictor< - paddle::NativeConfig, paddle::PaddleEngineKind::kNative>(native_config); - if (NULL == _core.get()) { - LOG(ERROR) << "create paddle predictor failed, path: " - << data_path; - return -1; - } - - LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; - return 0; + public: + int create(const std::string& data_path) { + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path not exits: " + << data_path; + return -1; + } + + paddle::NativeConfig native_config; + native_config.model_dir = data_path; + native_config.use_gpu = false; + native_config.device = 0; + AutoLock lock(GlobalPaddleCreateMutex::instance()); + _core = paddle::CreatePaddlePredictor( + native_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; } + LOG(WARNING) << "create paddle predictor sucess, path: " << data_path; + return 0; + } }; class Parameter { -public: - Parameter() : _row(0), _col(0), _params(NULL) {} - ~Parameter() { - LOG(INFO) << "before destroy Parameter, file_name[" << _file_name << "]"; - destroy(); + public: + Parameter() : _row(0), _col(0), _params(NULL) {} + ~Parameter() { + LOG(INFO) << "before destroy Parameter, file_name[" << _file_name << "]"; + destroy(); + } + + int init(int row, int col, const char* file_name) { + destroy(); + _file_name = file_name; + _row = row; + _col = col; + _params = reinterpret_cast(malloc(_row * _col * sizeof(float))); + if (_params == NULL) { + LOG(ERROR) << "Load " << _file_name << " malloc error."; + return -1; } - - int init(int row, int col, const char* file_name) { - destroy(); - _file_name = file_name; - _row = row; - _col = col; - _params = (float*)malloc(_row * _col * sizeof(float)); - if (_params == NULL) { - LOG(ERROR) << "Load " << _file_name << " malloc error."; - return -1; - } - LOG(WARNING) << "Load parameter file[" << _file_name << "] success."; - return 0; + LOG(WARNING) << "Load parameter file[" << _file_name << "] success."; + return 0; + } + + void destroy() { + _row = 0; + _col = 0; + if (_params != NULL) { + free(_params); + _params = NULL; } + } - void destroy() { - _row = 0; - _col = 0; - if (_params != NULL) { - free(_params); - _params = NULL; - } + int load() { + if (_params == NULL || _row <= 0 || _col <= 0) { + LOG(ERROR) << "load parameter error [not inited]."; + return -1; } - int load() { - if (_params == NULL || _row <= 0 || _col <= 0) { - LOG(ERROR) << "load parameter error [not inited]."; - return -1; - } - - FILE* fs = fopen(_file_name.c_str(), "rb"); - if (fs == NULL) { - LOG(ERROR) << "load " << _file_name << " fopen error."; - return -1; - } - static const uint32_t MODEL_FILE_HEAD_LEN = 16; - char head[MODEL_FILE_HEAD_LEN] = {0}; - if (fread(head, 1, MODEL_FILE_HEAD_LEN, fs) != MODEL_FILE_HEAD_LEN) { - destroy(); - LOG(ERROR) << "Load " << _file_name << " read head error."; - if (fs != NULL) { - fclose(fs); - fs = NULL; - } - return -1; - } - - uint32_t matrix_size = _row * _col; - if (matrix_size == fread(_params, sizeof(float), matrix_size, fs)) { - if (fs != NULL) { - fclose(fs); - fs = NULL; - } - LOG(INFO) << "load " << _file_name << " read ok."; - return 0; - } else { - LOG(ERROR) << "load " << _file_name << " read error."; - destroy(); - if (fs != NULL) { - fclose(fs); - fs = NULL; - } - return -1; - } - return 0; + FILE* fs = fopen(_file_name.c_str(), "rb"); + if (fs == NULL) { + LOG(ERROR) << "load " << _file_name << " fopen error."; + return -1; + } + static const uint32_t MODEL_FILE_HEAD_LEN = 16; + char head[MODEL_FILE_HEAD_LEN] = {0}; + if (fread(head, 1, MODEL_FILE_HEAD_LEN, fs) != MODEL_FILE_HEAD_LEN) { + destroy(); + LOG(ERROR) << "Load " << _file_name << " read head error."; + if (fs != NULL) { + fclose(fs); + fs = NULL; + } + return -1; } -public: - std::string _file_name; - int _row; - int _col; - float* _params; + uint32_t matrix_size = _row * _col; + if (matrix_size == fread(_params, sizeof(float), matrix_size, fs)) { + if (fs != NULL) { + fclose(fs); + fs = NULL; + } + LOG(INFO) << "load " << _file_name << " read ok."; + return 0; + } else { + LOG(ERROR) << "load " << _file_name << " read error."; + destroy(); + if (fs != NULL) { + fclose(fs); + fs = NULL; + } + return -1; + } + return 0; + } + + public: + std::string _file_name; + int _row; + int _col; + float* _params; }; class SigmoidModel { -public: - ~SigmoidModel() { + public: + ~SigmoidModel() {} + int load(const char* sigmoid_w_file, + const char* sigmoid_b_file, + float exp_max, + float exp_min) { + AutoLock lock(GlobalSigmoidCreateMutex::instance()); + if (0 != _sigmoid_w.init(2, 1, sigmoid_w_file) || 0 != _sigmoid_w.load()) { + LOG(ERROR) << "load params sigmoid_w failed."; + return -1; } - int load(const char* sigmoid_w_file, const char* sigmoid_b_file, - float exp_max, float exp_min) { - AutoLock lock(GlobalSigmoidCreateMutex::instance()); - if (0 != _sigmoid_w.init(2, 1, sigmoid_w_file) || 0 != _sigmoid_w.load()) { - LOG(ERROR) << "load params sigmoid_w failed."; - return -1; - } - LOG(WARNING) << "load sigmoid_w [" << _sigmoid_w._params[0] - << "] [" << _sigmoid_w._params[1] << "]."; - if (0 != _sigmoid_b.init(2, 1, sigmoid_b_file) || 0 != _sigmoid_b.load()) { - LOG(ERROR) << "load params sigmoid_b failed."; - return -1; - } - LOG(WARNING) << "load sigmoid_b [" << _sigmoid_b._params[0] - << "] [" << _sigmoid_b._params[1] << "]."; - _exp_max_input = exp_max; - _exp_min_input = exp_min; - return 0; + LOG(WARNING) << "load sigmoid_w [" << _sigmoid_w._params[0] << "] [" + << _sigmoid_w._params[1] << "]."; + if (0 != _sigmoid_b.init(2, 1, sigmoid_b_file) || 0 != _sigmoid_b.load()) { + LOG(ERROR) << "load params sigmoid_b failed."; + return -1; } - - int softmax(float x, double& o) { - float _y0 = x * _sigmoid_w._params[0] + _sigmoid_b._params[0]; - float _y1 = x * _sigmoid_w._params[1] + _sigmoid_b._params[1]; - _y0 = (_y0 > _exp_max_input) ? _exp_max_input - : ((_y0 < _exp_min_input) ? _exp_min_input : _y0); - _y1 = (_y1 > _exp_max_input) ? _exp_max_input - : ((_y1 < _exp_min_input) ? _exp_min_input : _y1); - o = 1.0f / (1.0f + exp(_y0 - _y1)); - return 0; - } -public: - Parameter _sigmoid_w; - Parameter _sigmoid_b; - float _exp_max_input; - float _exp_min_input; + LOG(WARNING) << "load sigmoid_b [" << _sigmoid_b._params[0] << "] [" + << _sigmoid_b._params[1] << "]."; + _exp_max_input = exp_max; + _exp_min_input = exp_min; + return 0; + } + + int softmax(float x, double& o) { // NOLINT + float _y0 = x * _sigmoid_w._params[0] + _sigmoid_b._params[0]; + float _y1 = x * _sigmoid_w._params[1] + _sigmoid_b._params[1]; + _y0 = (_y0 > _exp_max_input) + ? _exp_max_input + : ((_y0 < _exp_min_input) ? _exp_min_input : _y0); + _y1 = (_y1 > _exp_max_input) + ? _exp_max_input + : ((_y1 < _exp_min_input) ? _exp_min_input : _y1); + o = 1.0f / (1.0f + exp(_y0 - _y1)); + return 0; + } + + public: + Parameter _sigmoid_w; + Parameter _sigmoid_b; + float _exp_max_input; + float _exp_min_input; }; class SigmoidFluidModel { -public: - int softmax(float x, double& o) { - return _sigmoid_core->softmax(x, o); - } - - std::unique_ptr Clone() { - std::unique_ptr clone_model; - clone_model.reset(new SigmoidFluidModel()); - clone_model->_sigmoid_core = _sigmoid_core; - clone_model->_fluid_core = _fluid_core->Clone(); - return std::move(clone_model); - } - -public: - std::unique_ptr _fluid_core; - std::shared_ptr _sigmoid_core; + public: + int softmax(float x, double& o) { // NOLINT + return _sigmoid_core->softmax(x, o); + } // NOLINT + + std::unique_ptr Clone() { + std::unique_ptr clone_model; + clone_model.reset(new SigmoidFluidModel()); + clone_model->_sigmoid_core = _sigmoid_core; + clone_model->_fluid_core = _fluid_core->Clone(); + return std::move(clone_model); + } + + public: + std::unique_ptr _fluid_core; + std::shared_ptr _sigmoid_core; }; class FluidCpuWithSigmoidCore : public FluidFamilyCore { -public: - virtual ~FluidCpuWithSigmoidCore() { - } -public: - int create(const std::string& model_path) { - size_t pos = model_path.find_last_of("/\\"); - std::string conf_path = model_path.substr(0, pos); - std::string conf_file = model_path.substr(pos); - configure::SigmoidConf conf; - if (configure::read_proto_conf(conf_path, conf_file, &conf) != 0) { - LOG(ERROR) << "failed load model path: " << model_path; - return -1; - } - - _core.reset(new SigmoidFluidModel); - - std::string fluid_model_data_path = conf.dnn_model_path(); - int ret = load_fluid_model(fluid_model_data_path); - if (ret < 0) { - LOG(ERROR) << "fail to load fluid model."; - return -1; - } - const char* sigmoid_w_file = conf.sigmoid_w_file().c_str(); - const char* sigmoid_b_file = conf.sigmoid_b_file().c_str(); - float exp_max = conf.exp_max_input(); - float exp_min = conf.exp_min_input(); - _core->_sigmoid_core.reset(new SigmoidModel); - LOG(INFO) << "create sigmoid core[" << _core->_sigmoid_core.get() - << "], use count[" << _core->_sigmoid_core.use_count() << "]."; - ret = _core->_sigmoid_core->load(sigmoid_w_file, sigmoid_b_file, exp_max, exp_min); - if (ret < 0) { - LOG(ERROR) << "fail to load sigmoid model."; - return -1; - } - return 0; + public: + virtual ~FluidCpuWithSigmoidCore() {} + + public: + int create(const std::string& model_path) { + size_t pos = model_path.find_last_of("/\\"); + std::string conf_path = model_path.substr(0, pos); + std::string conf_file = model_path.substr(pos); + configure::SigmoidConf conf; + if (configure::read_proto_conf(conf_path, conf_file, &conf) != 0) { + LOG(ERROR) << "failed load model path: " << model_path; + return -1; } - virtual bool Run(const void* in_data, void* out_data) { - if (!_core->_fluid_core->Run(*(std::vector*)in_data, - (std::vector*)out_data)) { - LOG(ERROR) << "Failed call Run with paddle predictor"; - return false; - } + _core.reset(new SigmoidFluidModel); - return true; + std::string fluid_model_data_path = conf.dnn_model_path(); + int ret = load_fluid_model(fluid_model_data_path); + if (ret < 0) { + LOG(ERROR) << "fail to load fluid model."; + return -1; } - - virtual int clone(SigmoidFluidModel* origin_core) { - if (origin_core == NULL) { - LOG(ERROR) << "origin paddle Predictor is null."; - return -1; - } - _core = origin_core->Clone(); - if (_core.get() == NULL) { - LOG(ERROR) << "fail to clone paddle predictor: " << origin_core; - return -1; - } - LOG(INFO) << "clone sigmoid core[" << _core->_sigmoid_core.get() - << "] use count[" << _core->_sigmoid_core.use_count() << "]."; - return 0; + const char* sigmoid_w_file = conf.sigmoid_w_file().c_str(); + const char* sigmoid_b_file = conf.sigmoid_b_file().c_str(); + float exp_max = conf.exp_max_input(); + float exp_min = conf.exp_min_input(); + _core->_sigmoid_core.reset(new SigmoidModel); + LOG(INFO) << "create sigmoid core[" << _core->_sigmoid_core.get() + << "], use count[" << _core->_sigmoid_core.use_count() << "]."; + ret = _core->_sigmoid_core->load( + sigmoid_w_file, sigmoid_b_file, exp_max, exp_min); + if (ret < 0) { + LOG(ERROR) << "fail to load sigmoid model."; + return -1; } - - virtual SigmoidFluidModel* get() { - return _core.get(); + return 0; + } + + virtual bool Run(const void* in_data, void* out_data) { + if (!_core->_fluid_core->Run( + *(std::vector*)in_data, + (std::vector*)out_data)) { + LOG(ERROR) << "Failed call Run with paddle predictor"; + return false; } - virtual int load_fluid_model(const std::string& data_path) = 0; + return true; + } - int softmax(float x, double& o) { - return _core->_sigmoid_core->softmax(x, o); + virtual int clone(SigmoidFluidModel* origin_core) { + if (origin_core == NULL) { + LOG(ERROR) << "origin paddle Predictor is null."; + return -1; } + _core = origin_core->Clone(); + if (_core.get() == NULL) { + LOG(ERROR) << "fail to clone paddle predictor: " << origin_core; + return -1; + } + LOG(INFO) << "clone sigmoid core[" << _core->_sigmoid_core.get() + << "] use count[" << _core->_sigmoid_core.use_count() << "]."; + return 0; + } + + virtual SigmoidFluidModel* get() { return _core.get(); } + + virtual int load_fluid_model(const std::string& data_path) = 0; -protected: - std::unique_ptr _core; + int softmax(float x, double& o) { // NOLINT + return _core->_sigmoid_core->softmax(x, o); + } + + protected: + std::unique_ptr _core; }; class FluidCpuNativeDirWithSigmoidCore : public FluidCpuWithSigmoidCore { -public: - int load_fluid_model(const std::string& data_path) { - if (access(data_path.c_str(), F_OK) == -1) { - LOG(ERROR) << "create paddle predictor failed, path not exits: " - << data_path; - return -1; - } - - paddle::NativeConfig native_config; - native_config.model_dir = data_path; - native_config.use_gpu = false; - native_config.device = 0; - AutoLock lock(GlobalPaddleCreateMutex::instance()); - _core->_fluid_core = paddle::CreatePaddlePredictor< - paddle::NativeConfig, paddle::PaddleEngineKind::kNative>(native_config); - if (NULL == _core.get()) { - LOG(ERROR) << "create paddle predictor failed, path: " - << data_path; - return -1; - } - - LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; - return 0; + public: + int load_fluid_model(const std::string& data_path) { + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path not exits: " + << data_path; + return -1; + } + + paddle::NativeConfig native_config; + native_config.model_dir = data_path; + native_config.use_gpu = false; + native_config.device = 0; + AutoLock lock(GlobalPaddleCreateMutex::instance()); + _core->_fluid_core = + paddle::CreatePaddlePredictor( + native_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; } + LOG(WARNING) << "create paddle predictor sucess, path: " << data_path; + return 0; + } }; class FluidCpuAnalysisDirWithSigmoidCore : public FluidCpuWithSigmoidCore { -public: - int load_fluid_model(const std::string& data_path) { - if (access(data_path.c_str(), F_OK) == -1) { - LOG(ERROR) << "create paddle predictor failed, path not exits: " - << data_path; - return -1; - } - - paddle::contrib::AnalysisConfig analysis_config; - analysis_config.model_dir = data_path; - analysis_config.use_gpu = false; - analysis_config.device = 0; - analysis_config.specify_input_name = true; - AutoLock lock(GlobalPaddleCreateMutex::instance()); - _core->_fluid_core = paddle::CreatePaddlePredictor< - paddle::contrib::AnalysisConfig>(analysis_config); - if (NULL == _core.get()) { - LOG(ERROR) << "create paddle predictor failed, path: " - << data_path; - return -1; - } - - LOG(WARNING) << "create paddle predictor sucess, path: "<< data_path; - return 0; + public: + int load_fluid_model(const std::string& data_path) { + if (access(data_path.c_str(), F_OK) == -1) { + LOG(ERROR) << "create paddle predictor failed, path not exits: " + << data_path; + return -1; } + + paddle::contrib::AnalysisConfig analysis_config; + analysis_config.model_dir = data_path; + analysis_config.use_gpu = false; + analysis_config.device = 0; + analysis_config.specify_input_name = true; + AutoLock lock(GlobalPaddleCreateMutex::instance()); + _core->_fluid_core = + paddle::CreatePaddlePredictor( + analysis_config); + if (NULL == _core.get()) { + LOG(ERROR) << "create paddle predictor failed, path: " << data_path; + return -1; + } + + LOG(WARNING) << "create paddle predictor sucess, path: " << data_path; + return 0; + } }; -} // namespace fluid_cpu -} // namespace paddle_serving -} // namespace baidu +} // namespace fluid_cpu +} // namespace paddle_serving +} // namespace baidu diff --git a/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp b/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp index 49117ec373b9e677a907235a98ddc3c4ce0a7ed8..5ec5678a2a75d30b98beffa45bf00d2f38c93f85 100644 --- a/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp +++ b/inferencer-fluid-cpu/src/fluid_cpu_engine.cpp @@ -1,34 +1,57 @@ +// 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 "fluid_cpu_engine.h" namespace baidu { namespace paddle_serving { namespace fluid_cpu { REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( - ::baidu::paddle_serving::predictor::FluidInferEngine, - ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS"); + ::baidu::paddle_serving::predictor::FluidInferEngine, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_ANALYSIS"); REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( - ::baidu::paddle_serving::predictor::FluidInferEngine, - ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS_DIR"); + ::baidu::paddle_serving::predictor::FluidInferEngine< + FluidCpuAnalysisDirCore>, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_ANALYSIS_DIR"); REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( - ::baidu::paddle_serving::predictor::FluidInferEngine, - ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_ANALYSIS_DIR_SIGMOID"); + ::baidu::paddle_serving::predictor::FluidInferEngine< + FluidCpuAnalysisDirWithSigmoidCore>, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_ANALYSIS_DIR_SIGMOID"); REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( - ::baidu::paddle_serving::predictor::FluidInferEngine, - ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_NATIVE"); + ::baidu::paddle_serving::predictor::FluidInferEngine, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_NATIVE"); REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( - ::baidu::paddle_serving::predictor::FluidInferEngine, - ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_NATIVE_DIR"); + ::baidu::paddle_serving::predictor::FluidInferEngine, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_NATIVE_DIR"); REGIST_FACTORY_OBJECT_IMPL_WITH_NAME( - ::baidu::paddle_serving::predictor::FluidInferEngine, - ::baidu::paddle_serving::predictor::InferEngine, "FLUID_CPU_NATIVE_DIR_SIGMOID"); - -} // namespace fluid_cpu -} // namespace paddle_serving -} // namespace baidu + ::baidu::paddle_serving::predictor::FluidInferEngine< + FluidCpuNativeDirWithSigmoidCore>, + ::baidu::paddle_serving::predictor::InferEngine, + "FLUID_CPU_NATIVE_DIR_SIGMOID"); + +} // namespace fluid_cpu +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/CMakeLists.txt b/predictor/CMakeLists.txt index 7a335fee22e38742c559e59503aff10d6f3af6ba..013e52545c131d78e3591e689dadc43ba5a4fd6f 100644 --- a/predictor/CMakeLists.txt +++ b/predictor/CMakeLists.txt @@ -34,5 +34,3 @@ install(TARGETS pdserving pdcodegen ARCHIVE DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/lib LIBRARY DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/so ) - - diff --git a/predictor/README.md b/predictor/README.md deleted file mode 100644 index dce0087b638a9f8573813683e85e2412ccaca8f2..0000000000000000000000000000000000000000 --- a/predictor/README.md +++ /dev/null @@ -1,339 +0,0 @@ -[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工具向这个端口发送测试请求,确保服务已正常启动 -] -``` - diff --git a/predictor/common/constant.cpp b/predictor/common/constant.cpp index 66132e8e710d891edc4a1163624a4f804fffdd46..0dff9c8abb1d02749048d50d087850aa57512867 100644 --- a/predictor/common/constant.cpp +++ b/predictor/common/constant.cpp @@ -1,3 +1,17 @@ +// 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" namespace baidu { @@ -16,23 +30,28 @@ DEFINE_string(logger_path, "./conf", ""); DEFINE_string(logger_file, "log.conf", ""); DEFINE_string(resource_path, "./conf", ""); DEFINE_string(resource_file, "resource.prototxt", ""); -DEFINE_int32(max_concurrency, 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(max_concurrency, + 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_bool(enable_model_toolkit, false, "enable model toolkit"); DEFINE_string(enable_protocol_list, "baidu_std", "set protocol list"); const char* START_OP_NAME = "startup_op"; -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu -// Baidurpc -BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_INTERNAL_FAILURE, - "Paddle Serving Framework Internal Error."); -BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_MEM_ALLOC_FAILURE, - "Paddle Serving Memory Alloc Error."); -BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_OVERFLOW_FAILURE, - "Paddle Serving Array Overflow Error."); -BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_OP_INFER_FAILURE, - "Paddle Serving Op Inference Error."); +// Baidurpc +BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_INTERNAL_FAILURE, + "Paddle Serving Framework Internal Error."); +BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_MEM_ALLOC_FAILURE, + "Paddle Serving Memory Alloc Error."); +BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_OVERFLOW_FAILURE, + "Paddle Serving Array Overflow Error."); +BAIDU_REGISTER_ERRNO(baidu::paddle_serving::predictor::ERR_OP_INFER_FAILURE, + "Paddle Serving Op Inference Error."); diff --git a/predictor/common/constant.h b/predictor/common/constant.h index 49db8b935ceca59f0df860dd50d50279628579da..90eb45f4ffb6f20df88496c151b260baaf1a2bd5 100644 --- a/predictor/common/constant.h +++ b/predictor/common/constant.h @@ -1,6 +1,17 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_CONSTANT_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_CONSTANT_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. +#pragma once #include "common/inner_common.h" namespace baidu { @@ -34,26 +45,24 @@ extern const char* START_OP_NAME; // ERRORCODE enum { - // internal error - ERR_INTERNAL_FAILURE = -5000, - ERR_MEM_ALLOC_FAILURE = -5001, - ERR_OVERFLOW_FAILURE = -5002, - // op error - ERR_OP_INFER_FAILURE = -5100, - // no error - ERR_OK = 0, - // internal ignore - ERR_IGNORE_FAILURE = 5000, - // op ignore - ERR_OP_IGNORE_FAILURE = 5100, + // internal error + ERR_INTERNAL_FAILURE = -5000, + ERR_MEM_ALLOC_FAILURE = -5001, + ERR_OVERFLOW_FAILURE = -5002, + // op error + ERR_OP_INFER_FAILURE = -5100, + // no error + ERR_OK = 0, + // internal ignore + ERR_IGNORE_FAILURE = 5000, + // op ignore + ERR_OP_IGNORE_FAILURE = 5100, }; -static const size_t MAX_WORKFLOW_NUM_IN_ONE_SERVICE = 20; +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_UNITSIZE = 8192; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/common/inner_common.h b/predictor/common/inner_common.h index b91e1de3f0c18a4fff926fe8df407bb758b5f4fe..282bb74f77e9044531fe0554cd3b3b98be358eeb 100644 --- a/predictor/common/inner_common.h +++ b/predictor/common/inner_common.h @@ -1,37 +1,47 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_INNER_COMMON_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_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. +#pragma once -#include -#include -#include -#include +#include +#include #include +#include +#include #include -#include +#include +#include #include -#include -#include -#include -#include // for boost::split&trim +#include "boost/algorithm/string.hpp" // for boost::split&trim +#include "boost/function.hpp" +#include "boost/unordered_map.hpp" +#include "google/protobuf/text_format.h" -#include +#include "gflags/gflags.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "brpc/channel.h" +#include "brpc/policy/giano_authenticator.h" +#include "brpc/server.h" +#include "bthread/bthread.h" +#include "butil/logging.h" +#include "butil/object_pool.h" +#include "butil/time.h" -#include "server_configure.pb.h" -#include "configure_parser.h" +#include "configure/include/configure_parser.h" +#include "configure/server_configure.pb.h" -#include "common/utils.h" -#include "common/types.h" #include "common/constant.h" - -#endif +#include "common/types.h" +#include "common/utils.h" diff --git a/predictor/common/macros.h b/predictor/common/macros.h index a6607f60d51ed4657047b23aa445596556562b38..b737d7cd80ef7660244fe9f491b70a0910231aaf 100644 --- a/predictor/common/macros.h +++ b/predictor/common/macros.h @@ -1,6 +1,18 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_MACROS_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_MACROS_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. +#pragma once #include "common/inner_common.h" namespace baidu { @@ -8,11 +20,11 @@ namespace paddle_serving { namespace predictor { #ifndef CATCH_ANY_AND_RET -#define CATCH_ANY_AND_RET(errno) \ - catch (...) { \ - LOG(ERROR) << "exception catched"; \ - return errno; \ - } +#define CATCH_ANY_AND_RET(errno) \ + catch (...) { \ + LOG(ERROR) << "exception catched"; \ + return errno; \ + } #endif #ifdef USE_PTHREAD @@ -26,7 +38,7 @@ namespace predictor { #define THREAD_CREATE pthread_create #define THREAD_CANCEL pthread_cancel #define THREAD_JOIN pthread_join -#define THREAD_KEY_DELETE pthread_key_delete +#define THREAD_KEY_DELETE pthread_key_delete #define THREAD_MUTEX_INIT pthread_mutex_init #define THREAD_MUTEX_LOCK pthread_mutex_lock #define THREAD_MUTEX_UNLOCK pthread_mutex_unlock @@ -48,7 +60,7 @@ namespace predictor { #define THREAD_CREATE bthread_start_background #define THREAD_CANCEL bthread_stop #define THREAD_JOIN bthread_join -#define THREAD_KEY_DELETE bthread_key_delete +#define THREAD_KEY_DELETE bthread_key_delete #define THREAD_MUTEX_INIT bthread_mutex_init #define THREAD_MUTEX_LOCK bthread_mutex_lock #define THREAD_MUTEX_UNLOCK bthread_mutex_unlock @@ -61,8 +73,6 @@ namespace predictor { #endif -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/common/types.h b/predictor/common/types.h index 9866ddc6dadbf226ceb8b6dfc1ef78cd589b0092..9fac6be7d49f9a679b7b10e5846224b888968aa0 100644 --- a/predictor/common/types.h +++ b/predictor/common/types.h @@ -1,6 +1,18 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TYPES_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_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. +#pragma once namespace baidu { namespace paddle_serving { namespace predictor { @@ -10,12 +22,10 @@ typedef size_t Size; typedef const char* ConstByte; struct Sequence { - Byte data; - Size size; + Byte data; + Size size; }; -} // predictor -} // paddle_serving -} // baidu - -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_TYPES_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/common/utils.h b/predictor/common/utils.h index a1f7e341855ddca4ebc7eea340db84d77165e19d..271ac4ae999d27292372bb7d183d2f0d4873de29 100644 --- a/predictor/common/utils.h +++ b/predictor/common/utils.h @@ -1,154 +1,149 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_UTILS_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_UTILS_H - -#include "common/macros.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. + +#pragma once +#include #include "common/inner_common.h" +#include "common/macros.h" namespace baidu { namespace paddle_serving { namespace predictor { class TimerFlow { -public: - static const int MAX_SIZE = 1024; - - TimerFlow() { - init(); + public: + static const int MAX_SIZE = 1024; + + TimerFlow() { init(); } + + void init() { + _csize = 0; + _name = NULL; + _started = false; + _auto = false; + } + + explicit TimerFlow(const char* name) : _csize(0), _name(name) { + _last = _start = butil::cpuwide_time_us(); + _auto = true; + _started = true; + } + + void set_name(const char* name) { _name = name; } + + void start() { + _last = _start = butil::cpuwide_time_us(); + _started = true; + } + + bool check(const char* tag) { + if (!_started) { + LOG(WARNING) << "Timer not started yet!"; + return false; } - - void init() { - _csize = 0; - _name = NULL; - _started = false; - _auto = false; + uint64_t now = butil::cpuwide_time_us(); + if (!appendf("%s:%lu|", tag, now - _last)) { + LOG(WARNING) << "Failed check timer: " << _name << ", value = [" << tag + << ":" << (now - _last) << "]!"; + return false; } - TimerFlow(const char* name) : _csize(0), _name(name) { - _last = _start = butil::cpuwide_time_us(); - _auto = true; - _started = true; - } + _last = now; + return true; + } - void set_name(const char* name) { - _name = name; - } - - void start() { - _last = _start = butil::cpuwide_time_us(); - _started = true; - } - - bool check(const char* tag) { - if (!_started) { - LOG(WARNING) << "Timer not started yet!"; - return false; - } - uint64_t now = butil::cpuwide_time_us(); - if (!appendf("%s:%lu|", tag, now - _last)) { - LOG(WARNING) - << "Failed check timer: " << _name - << ", value = [" << tag << ":" - << (now - _last) << "]!"; - return false; - } - - _last = now; - return true; - } + std::string info() { return std::string(_buf); } - std::string info() { - return std::string(_buf); + void end() { + uint64_t now = butil::cpuwide_time_us(); + if (!appendf("total:%lu", now - _start)) { + LOG(WARNING) << "Failed dump time_info[" << _name << "]"; } + _started = false; + } - void end() { - uint64_t now = butil::cpuwide_time_us(); - if (!appendf("total:%lu", now - _start)) { - LOG(WARNING) << "Failed dump time_info[" << _name << "]"; - } - _started = false; + ~TimerFlow() { + if (!_auto) { + return; } - - ~TimerFlow() { - if (!_auto) { - return; - } - uint64_t now = butil::cpuwide_time_us(); - if (appendf("total:%lu,%s", now - _start, _name)) { - LOG(INFO) - << " " << _name << "_tc=[" << _buf << "]"; - } else { - LOG(WARNING) << "Failed dump time_info[" << _name << "]"; - } + uint64_t now = butil::cpuwide_time_us(); + if (appendf("total:%lu,%s", now - _start, _name)) { + LOG(INFO) << " " << _name << "_tc=[" << _buf << "]"; + } else { + LOG(WARNING) << "Failed dump time_info[" << _name << "]"; } - -private: - bool appendf(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - try { - int bytes = vsnprintf(_buf + _csize, MAX_SIZE - _csize, fmt, ap); - if (bytes >= MAX_SIZE - _csize || bytes < 0) { - LOG(WARNING) << "Overflow when appendf!"; - return false; - } - _csize += bytes; - } CATCH_ANY_AND_RET(false); - - va_end(ap); - return true; + } + + private: + bool appendf(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + try { + int bytes = vsnprintf(_buf + _csize, MAX_SIZE - _csize, fmt, ap); + if (bytes >= MAX_SIZE - _csize || bytes < 0) { + LOG(WARNING) << "Overflow when appendf!"; + return false; + } + _csize += bytes; } - -private: - char _buf[1024]; - int _csize; - uint64_t _start; - uint64_t _last; - const char* _name; - bool _started; - bool _auto; + CATCH_ANY_AND_RET(false); + + va_end(ap); + return true; + } + + private: + char _buf[1024]; + int _csize; + uint64_t _start; + uint64_t _last; + const char* _name; + bool _started; + bool _auto; }; -template +template struct derived_from_message {}; -template +template class TIsDerivedFromB { -private: - static uint8_t check(TBase*) { - return 1; - } + private: + static uint8_t check(TBase*) { return 1; } - static uint32_t check(void*) { - return 0; - } + static uint32_t check(void*) { return 0; } -public: - enum { - // function call cannot apprear in a constant-expression - RESULT = (sizeof(uint8_t) == sizeof(check((T*)(NULL)))), - }; + public: + enum { + // function call cannot apprear in a constant-expression + RESULT = (sizeof(uint8_t) == sizeof(check(reinterpret_cast(NULL)))), + }; }; -template +template class IsDerivedFrom { -private: - static bool check(TBase*) { - return true; - } + private: + static bool check(TBase*) { return true; } - static bool check(void*) { - return false; - } + static bool check(void*) { return false; } -public: - template - static bool yes(T* x) { - return check(x); - } + public: + template + static bool yes(T* x) { + return check(x); + } }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/cts/autorun.sh b/predictor/cts/autorun.sh deleted file mode 100755 index e60d9b9a664a800d2ebe59f5f6445290420492e2..0000000000000000000000000000000000000000 --- a/predictor/cts/autorun.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/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 diff --git a/predictor/cts/build.sh b/predictor/cts/build.sh deleted file mode 100755 index a99726ec9d7607ce851c56dbdbf2091379f8d0ed..0000000000000000000000000000000000000000 --- a/predictor/cts/build.sh +++ /dev/null @@ -1,290 +0,0 @@ -#!/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 $? diff --git a/predictor/cts/case/TestDenseService.py b/predictor/cts/case/TestDenseService.py deleted file mode 100644 index 3c65eeb6bb7c4464a4e2af091cd4d6b0f265941e..0000000000000000000000000000000000000000 --- a/predictor/cts/case/TestDenseService.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/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" - diff --git a/predictor/cts/lib/__init__.py b/predictor/cts/lib/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/predictor/cts/lib/plugin_register.py b/predictor/cts/lib/plugin_register.py deleted file mode 100644 index 50fea2e61988f3c1a59404a8d02dd237f5f44988..0000000000000000000000000000000000000000 --- a/predictor/cts/lib/plugin_register.py +++ /dev/null @@ -1,2 +0,0 @@ -"""plugin register """ -from lib.plugin_tester import * diff --git a/predictor/cts/lib/plugin_tester.py b/predictor/cts/lib/plugin_tester.py deleted file mode 100644 index 1f8f0dd60b4fa30ab5dd5ea682da280ef31426b1..0000000000000000000000000000000000000000 --- a/predictor/cts/lib/plugin_tester.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# -*- coding:gbk -*- -""" -עࣺRegxxxConfDataRegxxxReqRegxxxXboxRegxxxAdxxxΪ -""" -from lib.pluginlib.plugin_common import ConfData -from lib.pluginlib.plugin_common import TreeConfData -from lib.pluginlib.plugin_common import CommonIndex - - -class RegpredictorConfData(object): - """ - עwtitleqconfdataļ - """ - 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%2C2Сʱ͵%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): - """ - עwtitleqxbox - """ - 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 - - diff --git a/predictor/framework/bsf-inl-tensor.h b/predictor/framework/bsf-inl-tensor.h index 5568cc7aae85aa0e0f5109619036fcacd58556b7..7c193e4011a52ce6fd02f2b07e5107d082fb1ea6 100644 --- a/predictor/framework/bsf-inl-tensor.h +++ b/predictor/framework/bsf-inl-tensor.h @@ -1,9 +1,24 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once +#include #include -#include +#include #include -#include +#include #include "common/inner_common.h" #include "framework/infer_data.h" #include "framework/memory.h" @@ -13,339 +28,341 @@ namespace im { namespace bsf { -template<> -struct Task { +template <> +struct Task { + typedef Task + TaskT; + typedef baidu::paddle_serving::predictor::Tensor Tensor; + typedef baidu::paddle_serving::predictor::Tensor InType; + typedef baidu::paddle_serving::predictor::Tensor OutType; + typedef baidu::paddle_serving::predictor::BatchTensor BatchTensor; + typedef baidu::paddle_serving::predictor::BatchTensor InArrayT; + typedef baidu::paddle_serving::predictor::BatchTensor OutArrayT; + + struct Segment { + Segment(void* p, size_t b, size_t s) : ptr(p), begin(b), size(s) {} + void* ptr; + size_t begin; + size_t size; + }; - typedef Task TaskT; - typedef baidu::paddle_serving::predictor::Tensor Tensor; - typedef baidu::paddle_serving::predictor::Tensor InType; - typedef baidu::paddle_serving::predictor::Tensor OutType; - typedef baidu::paddle_serving::predictor::BatchTensor BatchTensor; - typedef baidu::paddle_serving::predictor::BatchTensor InArrayT; - typedef baidu::paddle_serving::predictor::BatchTensor OutArrayT; + int read_fd; + int write_fd; - struct Segment { - Segment(void* p, size_t b, size_t s) - : ptr(p), begin(b), size(s) {} - void* ptr; - size_t begin; - size_t size; - }; + pid_t owner_tid; - int read_fd; - int write_fd; + const InArrayT* in; + OutArrayT* out; - pid_t owner_tid; + size_t rem; + size_t size; - const InArrayT* in; - OutArrayT* out; + butil::atomic index; - size_t rem; - size_t size; + const BatchTensor* get(bool is_in) const { + if (is_in) { + return in; + } else { + return out; + } + } - butil::atomic index; + BatchTensor* get(bool is_in) { + if (is_in) { + return const_cast(in); + } else { + return out; + } + } + + Task() { + read_fd = -1; + write_fd = -1; + owner_tid = -1; + in = NULL; + out = NULL; + rem = -1; + size = -1; + index.store(0, butil::memory_order_relaxed); + } +}; - const BatchTensor* get(bool is_in) const { - if (is_in) { - return in; - } else { - return out; +template <> +class BatchTasks> { + public: + typedef baidu::paddle_serving::predictor::Tensor Tensor; + typedef baidu::paddle_serving::predictor::Tensor InType; + typedef baidu::paddle_serving::predictor::Tensor OutType; + typedef baidu::paddle_serving::predictor::DataBuf DataBuf; + typedef baidu::paddle_serving::predictor::MempoolWrapper MempoolWrapper; + + typedef Task + TaskT; + typedef TaskMeta TaskMetaT; + typedef TaskT::InArrayT InArrayT; + typedef TaskT::OutArrayT OutArrayT; + + explicit BatchTasks(size_t batch_size, bool batch_align = false) + : _batch_size(batch_size), + _rem_size(batch_size), + _batch_align(batch_align) { + _batch_in.clear(); + _batch_out.clear(); + _tasks.clear(); + } + + ~BatchTasks() { + _batch_in.clear(); + _batch_out.clear(); + _tasks.clear(); + } + + static bool check_valid(const InArrayT& in, + OutArrayT& out, // NOLINT + bool align) { // NOLINT + if (align) { + if (out.count() <= 0 || out.size() <= 0) { + LOG(ERROR) << "Out tensor is empty, when aligned"; + return false; + } + + if (out.size() != in.size()) { + LOG(ERROR) << "In/Out tensor size not eq: " << out.size() + << "!=" << in.size(); + return false; + } + + for (size_t fi = 0, shape0 = 0; fi < out.count(); ++fi) { + if (!out[fi].valid()) { + LOG(ERROR) << "Out[" << fi << "] tensor not valid"; + return false; } - } - BatchTensor* get(bool is_in) { - if (is_in) { - return const_cast(in); - } else { - return out; + if (out.size() != out[fi].shape0()) { + LOG(ERROR) << "Shape0 not consistency, " << out.size() + << "!=" << out[fi].shape0() << ", " << fi; + return false; } + } } - Task() { - read_fd = -1; - write_fd = -1; - owner_tid = -1; - in = NULL; - out = NULL; - rem = -1; - size = -1; - index.store(0, butil::memory_order_relaxed); - } -}; + return true; + } -template<> -class BatchTasks > { -public: - typedef baidu::paddle_serving::predictor::Tensor Tensor; - typedef baidu::paddle_serving::predictor::Tensor InType; - typedef baidu::paddle_serving::predictor::Tensor OutType; - typedef baidu::paddle_serving::predictor::DataBuf DataBuf; - typedef baidu::paddle_serving::predictor::MempoolWrapper MempoolWrapper; - - typedef Task TaskT; - typedef TaskMeta TaskMetaT; - typedef TaskT::InArrayT InArrayT; - typedef TaskT::OutArrayT OutArrayT; - - BatchTasks(size_t batch_size, bool batch_align = false) - : _batch_size(batch_size) - , _rem_size(batch_size) - , _batch_align(batch_align) { - _batch_in.clear(); - _batch_out.clear(); - _tasks.clear(); + size_t append_task(TaskT* task) { + size_t add = std::min(task->rem, _rem_size); + if (!_batch_align) { + add = task->rem; } - - ~BatchTasks() { - _batch_in.clear(); - _batch_out.clear(); - _tasks.clear(); + TaskMetaT tm(task, task->in->size() - task->rem, add); + _tasks.push_back(tm); + + task->rem -= add; + _rem_size -= add; + return _rem_size; + } + + void merge_tasks() { + merge_input(); + merge_output(); + } + + void merge_input() { + if (_tasks.size() <= 0 || _tasks[0].task->in->count() <= 0) { + return; } - static bool check_valid( - const InArrayT& in, OutArrayT& out, bool align) { - if (align) { - if (out.count() <= 0 || out.size() <= 0) { - LOG(ERROR) << "Out tensor is empty, when aligned"; - return false; - } - - if (out.size() != in.size()) { - LOG(ERROR) << "In/Out tensor size not eq: " << out.size() << "!=" << in.size(); - return false; - } - - for (size_t fi = 0, shape0 = 0; fi < out.count(); ++fi) { - if (!out[fi].valid()) { - LOG(ERROR) << "Out[" << fi << "] tensor not valid"; - return false; - } - - if (out.size() != out[fi].shape0()) { - LOG(ERROR) << "Shape0 not consistency, " << out.size() << "!=" << out[fi].shape0() << ", " << fi; - return false; - } - } - } - - return true; + if (_tasks.size() == 1 && !_batch_align) { + TaskMetaT& tm = _tasks[0]; + _batch_in = *(tm.task->in); + return; } - size_t append_task(TaskT* task) { - size_t add = std::min(task->rem, _rem_size); - if (!_batch_align) { - add = task->rem; - } - TaskMetaT tm(task, task->in->size() - task->rem, add); - _tasks.push_back(tm); + merge_tensor(true); + } - task->rem -= add; - _rem_size -= add; - return _rem_size; + void merge_output() { + if (_batch_align) { + if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) { + return; + } } - void merge_tasks() { - merge_input(); - merge_output(); + if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) { + return; } - void merge_input() { - if (_tasks.size() <= 0 || _tasks[0].task->in->count() <= 0) { - return ; - } + TaskMetaT& tm = _tasks[0]; + if (_tasks.size() == 1 && !_batch_align) { + _batch_out = *(tm.task->out); + return; + } - if (_tasks.size() == 1 && !_batch_align) { - TaskMetaT& tm = _tasks[0]; - _batch_in = *(tm.task->in); - return ; - } + if (tm.task->out->size() <= 0) { + // shape is empty + _batch_out = *(tm.task->out); + return; + } - merge_tensor(true); + if ((*tm.task->out)[0].data.data() == 0 || + (*tm.task->out)[0].data.size() == 0) { + _batch_out = *(tm.task->out); + return; } - void merge_output() { - if (_batch_align) { - if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) { - return ; - } - } + merge_tensor(false); + } - if (_tasks.size() <= 0 || _tasks[0].task->out->count() <= 0) { - return ; - } + void merge_tensor(bool is_in) { + // accumulate batch size from fetched tasks + size_t batch_size = 0; + for (size_t ti = 0; ti < _tasks.size(); ++ti) { + TaskMetaT& tm = _tasks[ti]; + size_t add = tm.end - tm.begin; + batch_size += add; + } - TaskMetaT& tm = _tasks[0]; - if (_tasks.size() == 1 && !_batch_align) { - _batch_out = *(tm.task->out); - return ; + // merge all instanses in each tensor data + size_t tensor_count = _tasks[0].task->get(is_in)->count(); + for (size_t fi = 0; fi < tensor_count; ++fi) { + const Tensor& head = (*(_tasks[0].task->get(is_in)))[fi]; + Tensor batch_tensor; + batch_tensor.name = head.name; + batch_tensor.type = head.type; + batch_tensor.shape.push_back(batch_size); + + size_t ins_ele_count = 1; + for (size_t si = 1; si < head.shape.size(); ++si) { + batch_tensor.shape.push_back(head.shape[si]); + ins_ele_count *= head.shape[si]; + } + + size_t tensor_ele_count = ins_ele_count * batch_size; + size_t ins_byte = ins_ele_count * head.ele_byte(); + + size_t tensor_byte = tensor_ele_count * head.ele_byte(); + void* data_buf = MempoolWrapper::instance().malloc(tensor_byte); + if (!data_buf) { + LOG(ERROR) << "Malloc failed, size: " << tensor_byte; + return; + } + + size_t data_byte = 0; + for (size_t ti = 0; ti < _tasks.size(); ++ti) { + TaskMetaT& tm = _tasks[ti]; + size_t acc_byte = ins_byte * (tm.end - tm.begin); + if (data_byte + acc_byte > tensor_byte) { + LOG(ERROR) << "Invalid bytes: " << data_byte << " + " << acc_byte + << " >= " << tensor_byte; + return; } - if (tm.task->out->size() <= 0) { - // shape is empty - _batch_out = *(tm.task->out); - return ; - } + const Tensor& tensor = (*(tm.task->get(is_in)))[fi]; + memcpy( + reinterpret_cast(data_buf) + data_byte, + reinterpret_cast(tensor.data.data()) + tm.begin * ins_byte, + acc_byte); + data_byte += acc_byte; + } + + if (data_byte != tensor_byte) { + LOG(ERROR) << "Invalid tensor byte: " << data_byte + << " != " << tensor_byte; + return; + } + + batch_tensor.data = + DataBuf(reinterpret_cast(data_buf), tensor_byte); + if (is_in) { + _batch_in.push_back(batch_tensor); + } else { + _batch_out.push_back(batch_tensor); + } + } - if ((*tm.task->out)[0].data.data() == 0 - || (*tm.task->out)[0].data.size() == 0) { - _batch_out = *(tm.task->out); - return ; - } + LOG(INFO) << "merge input(" << is_in << ") samples: " << batch_size + << " from " << _tasks.size() << " pvs"; + } - merge_tensor(false); + void notify_tasks() { + if (_batch_out.size() != _batch_in.size()) { + LOG(ERROR) << "batch size not consistency: " << _batch_out.size() + << " != " << _batch_in.size(); + return; } - void merge_tensor(bool is_in) { - // accumulate batch size from fetched tasks - size_t batch_size = 0; - for (size_t ti = 0; ti < _tasks.size(); ++ti) { - TaskMetaT& tm = _tasks[ti]; - size_t add = tm.end - tm.begin; - batch_size += add; + size_t tensor_count = _batch_out.count(); + size_t batch_size = _batch_out.size(); + for (size_t fi = 0; fi < tensor_count; ++fi) { + const Tensor& tensor = _batch_out[fi]; + size_t ins_byte = tensor.ele_byte(); + for (size_t si = 1; si < tensor.shape.size(); ++si) { + ins_byte *= tensor.shape[si]; + } + + for (size_t ti = 0, bi = 0, add = 0; ti < _tasks.size(); + ++ti, bi += add) { + OutArrayT* dst = _tasks[ti].task->out; + add = _tasks[ti].end - _tasks[ti].begin; + size_t offset_src = ins_byte * bi; + size_t add_byte = add * ins_byte; + + if (_batch_align) { // merge all batchs + size_t offset_dst = ins_byte * _tasks[ti].begin; + void* ptr = const_cast((*dst)[fi].data.data()); + memcpy( + reinterpret_cast(ptr) + offset_dst, + reinterpret_cast(_batch_out[fi].data.data()) + offset_src, + add_byte); + } else { // overwrite + if (dst->count() <= 0) { + dst->push_back(_batch_out[fi]); + } else { + (*dst)[fi] = _batch_out[fi]; + } + + (*dst)[fi].shape[0] = add; + (*dst)[fi].data = DataBuf( + reinterpret_cast(_batch_out[fi].data.data()) + offset_src, + add_byte); } - - // merge all instanses in each tensor data - size_t tensor_count = _tasks[0].task->get(is_in)->count(); - for (size_t fi = 0; fi < tensor_count; ++fi) { - const Tensor& head = (*(_tasks[0].task->get(is_in)))[fi]; - Tensor batch_tensor; - batch_tensor.name = head.name; - batch_tensor.type = head.type; - batch_tensor.shape.push_back(batch_size); - - size_t ins_ele_count = 1; - for (size_t si = 1; si < head.shape.size(); ++si) { - batch_tensor.shape.push_back(head.shape[si]); - ins_ele_count *= head.shape[si]; - } - - size_t tensor_ele_count = ins_ele_count * batch_size; - size_t ins_byte = ins_ele_count * head.ele_byte(); - - size_t tensor_byte = tensor_ele_count * head.ele_byte(); - void* data_buf - = MempoolWrapper::instance().malloc(tensor_byte); - if (!data_buf) { - LOG(ERROR) << "Malloc failed, size: " << tensor_byte; - return ; - } - - size_t data_byte = 0; - for (size_t ti = 0; ti < _tasks.size(); ++ti) { - TaskMetaT& tm = _tasks[ti]; - size_t acc_byte = ins_byte * (tm.end - tm.begin); - if (data_byte + acc_byte > tensor_byte) { - LOG(ERROR) << "Invalid bytes: " << data_byte << " + " << acc_byte << " >= " << tensor_byte; - return ; - } - - const Tensor& tensor = (*(tm.task->get(is_in)))[fi]; - memcpy((char *)data_buf + data_byte, - (char *)(tensor.data.data()) + tm.begin * ins_byte, - acc_byte); - data_byte += acc_byte; - } - - if (data_byte != tensor_byte) { - LOG(ERROR) << "Invalid tensor byte: " << data_byte << " != " << tensor_byte; - return ; - } - - batch_tensor.data = DataBuf((char *)data_buf, tensor_byte); - if (is_in) { - _batch_in.push_back(batch_tensor); - } else { - _batch_out.push_back(batch_tensor); - } - } - - LOG(INFO) << "merge input(" << is_in << ") samples: " - << batch_size << " from " << _tasks.size() << " pvs"; + } } - void notify_tasks() { - if (_batch_out.size() != _batch_in.size()) { - LOG(ERROR) << "batch size not consistency: " << _batch_out.size() << " != " << _batch_in.size(); - return ; - } + for (size_t ti = 0; ti < _tasks.size(); ++ti) { + TaskT* task = _tasks[ti].task; + size_t begin = _tasks[ti].begin; + size_t end = _tasks[ti].end; + size_t add = end - begin; - size_t tensor_count = _batch_out.count(); - size_t batch_size = _batch_out.size(); - for (size_t fi = 0; fi < tensor_count; ++fi) { - const Tensor& tensor = _batch_out[fi]; - size_t ins_byte = tensor.ele_byte(); - for (size_t si = 1; si < tensor.shape.size(); ++si) { - ins_byte *= tensor.shape[si]; - } - - for (size_t ti = 0, bi = 0, add = 0; - ti < _tasks.size(); ++ti, bi += add) { - OutArrayT* dst = _tasks[ti].task->out; - add = _tasks[ti].end - _tasks[ti].begin; - size_t offset_src = ins_byte * bi; - size_t add_byte = add * ins_byte; - - if (_batch_align) { // merge all batchs - size_t offset_dst = ins_byte * _tasks[ti].begin; - void* ptr = const_cast((*dst)[fi].data.data()); - memcpy((char *)ptr + offset_dst, - (char *)(_batch_out[fi].data.data()) + offset_src, add_byte); - } else { // overwrite - if (dst->count() <= 0) { - dst->push_back(_batch_out[fi]); - } else { - (*dst)[fi] = _batch_out[fi]; - } - - (*dst)[fi].shape[0] = add; - (*dst)[fi].data = DataBuf( - (char *)(_batch_out[fi].data.data()) + offset_src, add_byte); - } - } - } - - for (size_t ti = 0; ti < _tasks.size(); ++ti) { - TaskT* task = _tasks[ti].task; - size_t begin = _tasks[ti].begin; - size_t end = _tasks[ti].end; - size_t add = end - begin; - - size_t index = task->index.fetch_add(add); - if ((index + add) >= task->in->size()) { - char c = 0; - while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) { - ; - } - butil::return_object(task); - } + size_t index = task->index.fetch_add(add); + if ((index + add) >= task->in->size()) { + char c = 0; + while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) { } + butil::return_object(task); + } } + } - const typename TaskT::InArrayT& in() const { - return _batch_in; - } + const typename TaskT::InArrayT& in() const { return _batch_in; } - typename TaskT::OutArrayT& out() { - return _batch_out; - } + typename TaskT::OutArrayT& out() { return _batch_out; } - size_t task_size() { - return _tasks.size(); - } + size_t task_size() { return _tasks.size(); } -private: - std::vector _tasks; - InArrayT _batch_in; - OutArrayT _batch_out; - size_t _batch_size; - size_t _rem_size; - bool _batch_align; + private: + std::vector _tasks; + InArrayT _batch_in; + OutArrayT _batch_out; + size_t _batch_size; + size_t _rem_size; + bool _batch_align; }; -} // namespace bsf -} // namespace im +} // namespace bsf +} // namespace im diff --git a/predictor/framework/bsf-inl.h b/predictor/framework/bsf-inl.h index bc95886ca23e5fd795175d0edbf1a516241352af..5a6e4931abed0f3afa62de325bc7af9c07e4ee64 100644 --- a/predictor/framework/bsf-inl.h +++ b/predictor/framework/bsf-inl.h @@ -1,230 +1,245 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once -#include #include +#include +#include #include "common/inner_common.h" -#include - namespace im { namespace bsf { -template +template void* TaskExecutor::thread_entry(void* args) { - ThreadContext* context = static_cast*>(args); - TaskExecutor* executor = static_cast*>(context->executor); - executor->work(context); + ThreadContext* context = static_cast*>(args); + TaskExecutor* executor = + static_cast*>(context->executor); + executor->work(context); - return NULL; + return NULL; } -template +template int TaskExecutor::start(uint32_t thread_num, uint32_t init_timeout_sec) { - _stop = false; - if (!_thread_contexts.empty()) { - LOG(WARNING) << "BSF has started"; - return 0; - } + _stop = false; + if (!_thread_contexts.empty()) { + LOG(WARNING) << "BSF has started"; + return 0; + } - if (thread_num == 0) { - LOG(ERROR) << "cannot init BSF with zero thread"; - return -1; - } + if (thread_num == 0) { + LOG(ERROR) << "cannot init BSF with zero thread"; + return -1; + } - ThreadContext* contexts = new ThreadContext[thread_num]; - for (uint32_t i = 0; i < thread_num; ++i) { - contexts[i].executor = this; - if (_user_thread_contexts != NULL) { - contexts[i].user_thread_context = _user_thread_contexts[i]; - } - - int rc = THREAD_CREATE( - &contexts[i].tid, NULL, &TaskExecutor::thread_entry, &contexts[i]); - if (rc != 0) { - LOG(ERROR) << "failed to create BSF worker thread: index=" << i << ", rc=" << rc << ", errno=" << errno << ":" << strerror(errno); - return -1; - } - - _thread_contexts.push_back(&contexts[i]); + ThreadContext* contexts = new ThreadContext[thread_num]; + for (uint32_t i = 0; i < thread_num; ++i) { + contexts[i].executor = this; + if (_user_thread_contexts != NULL) { + contexts[i].user_thread_context = _user_thread_contexts[i]; } - int init_timeout = init_timeout_sec * 1000 * 1000; - bool has_error = false; - - bool has_timeout = true; - if (init_timeout == 0) { - has_timeout = false; + int rc = THREAD_CREATE( + &contexts[i].tid, NULL, &TaskExecutor::thread_entry, &contexts[i]); + if (rc != 0) { + LOG(ERROR) << "failed to create BSF worker thread: index=" << i + << ", rc=" << rc << ", errno=" << errno << ":" + << strerror(errno); + return -1; } - while (!has_timeout || init_timeout > 0) { - bool done = true; - for (size_t i = 0; i < _thread_contexts.size(); ++i) { - if (_thread_contexts[i]->init_status < 0) { - has_error = true; - break; - } - - if (_thread_contexts[i]->init_status == 0) { - done = false; - } - } - - if (has_error) { - LOG(ERROR) << "BSF thread init error"; - return -1; - } - - if (done) { - LOG(INFO) << "BSF thread init done"; - return 0; - } - - // 100ms - const int sleep_interval = 100 * 1000; - usleep(sleep_interval); - init_timeout -= sleep_interval; - } + _thread_contexts.push_back(&contexts[i]); + } - LOG(ERROR) << "BSF thread init timed out"; - return -1; -} + int init_timeout = init_timeout_sec * 1000 * 1000; + bool has_error = false; -template -void TaskExecutor::stop() { - _stop = true; - for (size_t i = 0; i < _thread_contexts.size(); ++i) { - THREAD_CANCEL(_thread_contexts[i]->tid); - } + bool has_timeout = true; + if (init_timeout == 0) { + has_timeout = false; + } + while (!has_timeout || init_timeout > 0) { + bool done = true; for (size_t i = 0; i < _thread_contexts.size(); ++i) { - THREAD_JOIN(_thread_contexts[i]->tid, NULL); - } - _thread_contexts.clear(); -} + if (_thread_contexts[i]->init_status < 0) { + has_error = true; + break; + } -template -TaskHandler TaskExecutor::schedule( - const InArrayT& in, OutArrayT& out) { - TaskT* task = butil::get_object(); - if (!task) { - LOG(ERROR) << "Failed get TaskT from object pool"; - return TaskHandler::valid_handle(); + if (_thread_contexts[i]->init_status == 0) { + done = false; + } } - if (!BatchTasks::check_valid(in, out, _batch_align)) { - LOG(ERROR) << "Invalid input & output"; - return TaskHandler::valid_handle(); + if (has_error) { + LOG(ERROR) << "BSF thread init error"; + return -1; } - int fds[2]; - int rc = pipe(fds); - if (rc != 0) { - LOG(ERROR) << "call pipe() failed, errno=" << errno << ":" << strerror(errno); - return TaskHandler::valid_handle(); + if (done) { + LOG(INFO) << "BSF thread init done"; + return 0; } - task->read_fd = fds[0]; - task->write_fd = fds[1]; - task->owner_tid = ::syscall(SYS_gettid); + // 100ms + const int sleep_interval = 100 * 1000; + usleep(sleep_interval); + init_timeout -= sleep_interval; + } - task->in = ∈ - task->out = &out; - task->rem = in.size(); - task->size = in.size(); - task->index.store(0, butil::memory_order_relaxed); + LOG(ERROR) << "BSF thread init timed out"; + return -1; +} - AutoMutex lock(_mut); - _task_queue.push_back(task); - THREAD_COND_SIGNAL(&_cond); +template +void TaskExecutor::stop() { + _stop = true; + for (size_t i = 0; i < _thread_contexts.size(); ++i) { + THREAD_CANCEL(_thread_contexts[i]->tid); + } + + for (size_t i = 0; i < _thread_contexts.size(); ++i) { + THREAD_JOIN(_thread_contexts[i]->tid, NULL); + } + _thread_contexts.clear(); +} - return TaskHandler(*task); +template +TaskHandler TaskExecutor::schedule(const InArrayT& in, + OutArrayT& out) { // NOLINT + TaskT* task = butil::get_object(); + if (!task) { + LOG(ERROR) << "Failed get TaskT from object pool"; + return TaskHandler::valid_handle(); + } + + if (!BatchTasks::check_valid(in, out, _batch_align)) { + LOG(ERROR) << "Invalid input & output"; + return TaskHandler::valid_handle(); + } + + int fds[2]; + int rc = pipe(fds); + if (rc != 0) { + LOG(ERROR) << "call pipe() failed, errno=" << errno << ":" + << strerror(errno); + return TaskHandler::valid_handle(); + } + + task->read_fd = fds[0]; + task->write_fd = fds[1]; + task->owner_tid = ::syscall(SYS_gettid); + + task->in = ∈ + task->out = &out; + task->rem = in.size(); + task->size = in.size(); + task->index.store(0, butil::memory_order_relaxed); + + AutoMutex lock(_mut); + _task_queue.push_back(task); + THREAD_COND_SIGNAL(&_cond); + + return TaskHandler(*task); } -template -bool TaskExecutor::fetch_batch(BatchTasks& batch) { - AutoMutex lock(_mut); - while (_task_queue.empty()) { - THREAD_COND_WAIT(&_cond, &_mut); - } +template +bool TaskExecutor::fetch_batch(BatchTasks& batch) { // NOLINT + AutoMutex lock(_mut); + while (_task_queue.empty()) { + THREAD_COND_WAIT(&_cond, &_mut); + } - if (_task_queue.empty()) { - LOG(ERROR) << "invalid task queue!"; - return false; - } + if (_task_queue.empty()) { + LOG(ERROR) << "invalid task queue!"; + return false; + } - while (!_task_queue.empty()) { - TaskT* task = _task_queue.front(); - size_t rem = batch.append_task(task); - if (task->rem <= 0) { - _task_queue.pop_front(); - } - if (rem <= 0) break; + while (!_task_queue.empty()) { + TaskT* task = _task_queue.front(); + size_t rem = batch.append_task(task); + if (task->rem <= 0) { + _task_queue.pop_front(); } + if (rem <= 0) break; + } - return true; + return true; } -template +template int TaskExecutor::work(ThreadContext* context) { - if (_thread_init_fn != NULL) { - if (_thread_init_fn(context->user_thread_context) != 0) { - LOG(ERROR) << "execute thread init thunk failed, BSF thread will exit"; - context->init_status = -1; - return -1; - } else { - LOG(INFO) << "execute thread init thunk succeed"; - } + if (_thread_init_fn != NULL) { + if (_thread_init_fn(context->user_thread_context) != 0) { + LOG(ERROR) << "execute thread init thunk failed, BSF thread will exit"; + context->init_status = -1; + return -1; + } else { + LOG(INFO) << "execute thread init thunk succeed"; } + } - context->init_status = 1; - while (!_stop) { - if (_thread_reset_fn != NULL) { - if (_thread_reset_fn(context->user_thread_context) != 0) { - LOG(ERROR) << "execute user thread reset failed"; - } - } - - BatchTasks batch(_batch_size, _batch_align); - if (fetch_batch(batch)) { - batch.merge_tasks(); - _fn(batch.in(), batch.out()); - batch.notify_tasks(); - } + context->init_status = 1; + while (!_stop) { + if (_thread_reset_fn != NULL) { + if (_thread_reset_fn(context->user_thread_context) != 0) { + LOG(ERROR) << "execute user thread reset failed"; + } } - return 0; + BatchTasks batch(_batch_size, _batch_align); + if (fetch_batch(batch)) { + batch.merge_tasks(); + _fn(batch.in(), batch.out()); + batch.notify_tasks(); + } + } + + return 0; } -template -bool TaskManager::schedule(const InArrayT& in, - OutArrayT& out) { - TaskHandler handler = _executor.schedule(in, out); +template +bool TaskManager::schedule(const InArrayT& in, + OutArrayT& out) { // NOLINT + TaskHandler handler = _executor.schedule(in, out); - if (handler.valid()) { - _task_owned = handler; - return true; - } else { - LOG(ERROR) << "failed to schedule task"; - return false; - } + if (handler.valid()) { + _task_owned = handler; + return true; + } else { + LOG(ERROR) << "failed to schedule task"; + return false; + } } -template +template void TaskManager::wait() { - char buffer[128]; - while (read(_task_owned.read_fd, buffer, sizeof(buffer)) < 0 - && errno == EINTR) { - ; - } - - close(_task_owned.read_fd); - close(_task_owned.write_fd); + char buffer[128]; + while (read(_task_owned.read_fd, buffer, sizeof(buffer)) < 0 && + errno == EINTR) { + } - _task_owned.read_fd = -1; - _task_owned.write_fd = -1; - return; -} + close(_task_owned.read_fd); + close(_task_owned.write_fd); + _task_owned.read_fd = -1; + _task_owned.write_fd = -1; + return; } -} +} // namespace bsf +} // namespace im diff --git a/predictor/framework/bsf.h b/predictor/framework/bsf.h index 4b21d2651cc7a769d8fd3a534b8df5998f08eb61..c594c24f1232aec90b0afb262822e3208186d055 100644 --- a/predictor/framework/bsf.h +++ b/predictor/framework/bsf.h @@ -1,371 +1,355 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_BSF_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_BSF_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. + +#pragma once #include -#include +#include #include -#include +#include +#include "butil/atomicops.h" #include "common/inner_common.h" -#include +#include "boost/function.hpp" namespace im { namespace bsf { static const size_t DEFAULT_BATCH_SIZE = 100; -template +template struct Task { - typedef std::vector InArrayT; - typedef std::vector OutArrayT; - typedef InItemT InType; - typedef OutItemT OutType; - typedef Task TaskT; + typedef std::vector InArrayT; + typedef std::vector OutArrayT; + typedef InItemT InType; + typedef OutItemT OutType; + typedef Task TaskT; - int read_fd; - int write_fd; + int read_fd; + int write_fd; - pid_t owner_tid; + pid_t owner_tid; - const InArrayT* in; - OutArrayT* out; + const InArrayT* in; + OutArrayT* out; - size_t rem; - size_t size; + size_t rem; + size_t size; - size_t batch_size() { - return in->size(); - } + size_t batch_size() { return in->size(); } - butil::atomic index; - - Task() { - read_fd = -1; - write_fd = -1; - owner_tid = -1; - in = NULL; - out = NULL; - rem = -1; - size = -1; - index.store(0, butil::memory_order_relaxed); - } + butil::atomic index; + + Task() { + read_fd = -1; + write_fd = -1; + owner_tid = -1; + in = NULL; + out = NULL; + rem = -1; + size = -1; + index.store(0, butil::memory_order_relaxed); + } }; -template +template struct TaskMeta { - TaskMeta(TaskT* ptr, size_t start, size_t add) - : task(ptr) - , begin(start) - , end(start + add) {} - - TaskT* task; - size_t begin; - size_t end; + TaskMeta(TaskT* ptr, size_t start, size_t add) + : task(ptr), begin(start), end(start + add) {} + + TaskT* task; + size_t begin; + size_t end; }; -template +template class BatchTasks { -public: - typedef typename TaskT::InType InType; - typedef typename TaskT::OutType OutType; - typedef TaskMeta TaskMetaT; - - BatchTasks(size_t batch_size, bool batch_align = true) - : _batch_size(batch_size) - , _rem_size(batch_size) - , _batch_align(batch_align) { - _batch_in.clear(); - _batch_out.clear(); - _tasks.clear(); + public: + typedef typename TaskT::InType InType; + typedef typename TaskT::OutType OutType; + typedef TaskMeta TaskMetaT; + + explicit BatchTasks(size_t batch_size, bool batch_align = true) + : _batch_size(batch_size), + _rem_size(batch_size), + _batch_align(batch_align) { + _batch_in.clear(); + _batch_out.clear(); + _tasks.clear(); + } + + ~BatchTasks() { + _batch_in.clear(); + _batch_out.clear(); + _tasks.clear(); + } + + // synchronized operation + size_t append_task(TaskT* task) { + size_t add = std::min(task->rem, _rem_size); + if (!_batch_align) { + add = task->rem; } - ~BatchTasks() { - _batch_in.clear(); - _batch_out.clear(); - _tasks.clear(); + TaskMetaT tm(task, task->in->size() - task->rem, add); + _tasks.push_back(tm); + + task->rem -= add; + _rem_size -= add; + return _rem_size; + } + + static bool check_valid(const typename TaskT::InArrayT& in, + const typename TaskT::OutArrayT& out, + bool align) { + (void)in; + (void)out; + (void)align; + return true; + } + + void merge_tasks() { + for (size_t ti = 0; ti < _tasks.size(); ++ti) { + TaskMetaT& tm = _tasks[ti]; + for (size_t vi = tm.begin; vi < tm.end; ++vi) { + _batch_in.push_back((*tm.task->in)[vi]); + _batch_out.push_back((*tm.task->out)[vi]); + } } + } - // synchronized operation - size_t append_task(TaskT* task) { - size_t add = std::min(task->rem, _rem_size); - if (!_batch_align) { - add = task->rem; - } - - TaskMetaT tm(task, task->in->size() - task->rem, add); - _tasks.push_back(tm); - - task->rem -= add; - _rem_size -= add; - return _rem_size; + void notify_tasks() { + if (_batch_out.size() != _batch_in.size()) { + LOG(ERROR) << "batch size not consistency: " << _batch_out.size() + << " != " << _batch_in.size(); + return; } - static bool check_valid( - const typename TaskT::InArrayT& in, - typename TaskT::OutArrayT& out, bool align) { - (void)in; - (void)out; - (void)align; - return true; - } - - void merge_tasks() { - for (size_t ti = 0; ti < _tasks.size(); ++ti) { - TaskMetaT& tm = _tasks[ti]; - for (size_t vi = tm.begin; vi < tm.end; ++vi) { - _batch_in.push_back((*tm.task->in)[vi]); - _batch_out.push_back((*tm.task->out)[vi]); - } + for (size_t ti = 0, bi = 0; ti < _tasks.size(); ++ti) { + TaskT* task = _tasks[ti].task; + size_t begin = _tasks[ti].begin; + size_t end = _tasks[ti].end; + size_t add = end - begin; + + for (size_t oi = begin; oi < end; ++oi, ++bi) { + if (bi >= _batch_in.size()) { + LOG(ERROR) << "batch index overflow: " << bi << " > " + << _batch_in.size(); + return; } - } + (*task->out)[oi] = _batch_out[bi]; + } - void notify_tasks() { - if (_batch_out.size() != _batch_in.size()) { - LOG(ERROR) << "batch size not consistency: " << _batch_out.size() << " != " << _batch_in.size(); - return ; - } - - for (size_t ti = 0, bi = 0; ti < _tasks.size(); ++ti) { - TaskT* task = _tasks[ti].task; - size_t begin = _tasks[ti].begin; - size_t end = _tasks[ti].end; - size_t add = end - begin; - - for (size_t oi = begin; oi < end; ++oi, ++bi) { - if (bi >= _batch_in.size()) { - LOG(ERROR) << "batch index overflow: " << bi << " > " <<_batch_in.size(); - return ; - } - (*task->out)[oi] = _batch_out[bi]; - } - - size_t index = task->index.fetch_add(add); - if ((index + add) >= task->in->size()) { - char c = 0; - while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) { - ; - } - butil::return_object(task); - } + size_t index = task->index.fetch_add(add); + if ((index + add) >= task->in->size()) { + char c = 0; + while (write(task->write_fd, &c, 1) != 1 && errno == EINTR) { } + butil::return_object(task); + } } + } - const typename TaskT::InArrayT& in() const { - return _batch_in; - } + const typename TaskT::InArrayT& in() const { return _batch_in; } - typename TaskT::OutArrayT& out() { - return _batch_out; - } + typename TaskT::OutArrayT& out() { return _batch_out; } - size_t task_size() { - return _tasks.size(); - } - -private: - std::vector _tasks; - typename TaskT::InArrayT _batch_in; - typename TaskT::OutArrayT _batch_out; - size_t _rem_size; - size_t _batch_size; - bool _batch_align; + size_t task_size() { return _tasks.size(); } + + private: + std::vector _tasks; + typename TaskT::InArrayT _batch_in; + typename TaskT::OutArrayT _batch_out; + size_t _rem_size; + size_t _batch_size; + bool _batch_align; }; -// BSF , ȴʱָб -template +// BSF task handle +template struct TaskHandler { - int read_fd; - int write_fd; + int read_fd; + int write_fd; - TaskHandler() - : read_fd(-1), write_fd(-1) { - // do nothing - } + TaskHandler() : read_fd(-1), write_fd(-1) { + // do nothing + } - TaskHandler(TaskT const& task) - : read_fd(task.read_fd) - , write_fd(task.write_fd) { - // do nothing - } + explicit TaskHandler(TaskT const& task) + : read_fd(task.read_fd), write_fd(task.write_fd) { + // do nothing + } - inline bool valid() const { - return read_fd >= 0 && write_fd >= 0; - } + inline bool valid() const { return read_fd >= 0 && write_fd >= 0; } - static TaskHandler& valid_handle() { - static TaskHandler vhandle; - return vhandle; - } + static TaskHandler& valid_handle() { + static TaskHandler vhandle; + return vhandle; + } }; -template +template class TaskExecutor; -template +template class TaskManager; -template +template struct ThreadContext { - TaskExecutor* executor; - void* user_thread_context; - THREAD_T tid; - int init_status; - - ThreadContext() - : executor(NULL) - , user_thread_context(NULL) - , tid(-1), init_status(0) { - // do nothing - } - - ~ThreadContext() { - tid = -1; - executor = NULL; - user_thread_context = NULL; - init_status = 0; - } + TaskExecutor* executor; + void* user_thread_context; + THREAD_T tid; + int init_status; + + ThreadContext() + : executor(NULL), user_thread_context(NULL), tid(-1), init_status(0) { + // do nothing + } + + ~ThreadContext() { + tid = -1; + executor = NULL; + user_thread_context = NULL; + init_status = 0; + } }; -template +template class TaskExecutor { -public: - - typedef typename TaskT::InType InType; - typedef typename TaskT::OutType OutType; - typedef typename TaskT::InArrayT InArrayT; - typedef typename TaskT::OutArrayT OutArrayT; - typedef std::vector TaskArrayT; - - TaskExecutor() - : _stop(false) - , _thread_init_fn(NULL) - , _thread_reset_fn(NULL) - , _user_thread_contexts(NULL) - , _batch_size(DEFAULT_BATCH_SIZE) - , _batch_align(false) - , _fn(NULL) { - THREAD_MUTEX_INIT(&_mut, NULL); - THREAD_COND_INIT(&_cond, NULL); - _task_queue.clear(); - } + public: + typedef typename TaskT::InType InType; + typedef typename TaskT::OutType OutType; + typedef typename TaskT::InArrayT InArrayT; + typedef typename TaskT::OutArrayT OutArrayT; + typedef std::vector TaskArrayT; - ~TaskExecutor() { - THREAD_MUTEX_DESTROY(&_mut); - THREAD_COND_DESTROY(&_cond); - } + TaskExecutor() + : _stop(false), + _thread_init_fn(NULL), + _thread_reset_fn(NULL), + _user_thread_contexts(NULL), + _batch_size(DEFAULT_BATCH_SIZE), + _batch_align(false), + _fn(NULL) { + THREAD_MUTEX_INIT(&_mut, NULL); + THREAD_COND_INIT(&_cond, NULL); + _task_queue.clear(); + } - static TaskExecutor* instance() { - static TaskExecutor singleton; - return &singleton; - } + ~TaskExecutor() { + THREAD_MUTEX_DESTROY(&_mut); + THREAD_COND_DESTROY(&_cond); + } - void set_batch_size(size_t batch_size) { - _batch_size = batch_size; - } + static TaskExecutor* instance() { + static TaskExecutor singleton; + return &singleton; + } - void set_batch_align(size_t batch_align) { - _batch_align = batch_align; - } + void set_batch_size(size_t batch_size) { _batch_size = batch_size; } - void set_thread_init_fn(boost::function init_fn, void** contexts = NULL) { - _thread_init_fn = init_fn; - _user_thread_contexts = contexts; - } + void set_batch_align(size_t batch_align) { _batch_align = batch_align; } - void set_thread_reset_fn(boost::function reset_fn) { - _thread_reset_fn = reset_fn; - } + void set_thread_init_fn(boost::function init_fn, + void** contexts = NULL) { + _thread_init_fn = init_fn; + _user_thread_contexts = contexts; + } - void set_thread_callback_fn(boost::function cb) { - _fn = cb; - } + void set_thread_reset_fn(boost::function reset_fn) { + _thread_reset_fn = reset_fn; + } + + void set_thread_callback_fn( + boost::function cb) { + _fn = cb; + } - int start(uint32_t thread_num, uint32_t init_timeout_sec = 0); - void stop(); + int start(uint32_t thread_num, uint32_t init_timeout_sec = 0); + void stop(); - static void* thread_entry(void* args); + static void* thread_entry(void* args); -private: - TaskExecutor(TaskExecutor const& other); - TaskExecutor* operator=(TaskExecutor const& other); + private: + TaskExecutor(TaskExecutor const& other); + TaskExecutor* operator=(TaskExecutor const& other); - int work(ThreadContext* context); + int work(ThreadContext* context); - TaskHandler schedule(const InArrayT&, OutArrayT&); + TaskHandler schedule(const InArrayT&, OutArrayT&); - bool fetch_batch(BatchTasks& batch); + bool fetch_batch(BatchTasks& batch); // NOLINT - bool _stop; + bool _stop; - // can't use boost::mutex, because some stupid macro - THREAD_MUTEX_T _mut; - THREAD_COND_T _cond; + // can't use boost::mutex, because some stupid macro + THREAD_MUTEX_T _mut; + THREAD_COND_T _cond; - std::deque _task_queue; + std::deque _task_queue; - boost::function _thread_init_fn; - boost::function _thread_reset_fn; - void** _user_thread_contexts; + boost::function _thread_init_fn; + boost::function _thread_reset_fn; + void** _user_thread_contexts; - std::vector*> _thread_contexts; - friend class TaskManager; + std::vector*> _thread_contexts; + friend class TaskManager; - size_t _batch_size; - bool _batch_align; + size_t _batch_size; + bool _batch_align; - boost::function _fn; + boost::function _fn; }; -template +template class TaskManager { -public: + public: + typedef Task TaskT; + typedef typename TaskT::InArrayT InArrayT; + typedef typename TaskT::OutArrayT OutArrayT; - typedef Task TaskT; - typedef typename TaskT::InArrayT InArrayT; - typedef typename TaskT::OutArrayT OutArrayT; + explicit TaskManager(TaskExecutor& exe, size_t batch_size) // NOLINT + : _executor(exe) {} - explicit TaskManager(TaskExecutor& exe, size_t batch_size) : _executor(exe) { - } - - TaskManager() - : _executor(*TaskExecutor::instance()) { - } + TaskManager() : _executor(*TaskExecutor::instance()) {} - ~TaskManager() { - wait(); - } + ~TaskManager() { wait(); } - bool schedule(const InArrayT& in, OutArrayT& out); - void wait(); + bool schedule(const InArrayT& in, OutArrayT& out); // NOLINT + void wait(); - inline void clear() { - wait(); - } + inline void clear() { wait(); } -private: - TaskExecutor& _executor; - TaskHandler _task_owned; -}; // class TaskManager + private: + TaskExecutor& _executor; + TaskHandler _task_owned; +}; // class TaskManager class AutoMutex { -public: - AutoMutex(THREAD_MUTEX_T& mut) - : _mut(mut) { - THREAD_MUTEX_LOCK(&_mut); - } + public: + explicit AutoMutex(THREAD_MUTEX_T& mut) : _mut(mut) { + THREAD_MUTEX_LOCK(&_mut); + } - ~AutoMutex() { - THREAD_MUTEX_UNLOCK(&_mut); - } + ~AutoMutex() { THREAD_MUTEX_UNLOCK(&_mut); } -private: - THREAD_MUTEX_T& _mut; + private: + THREAD_MUTEX_T& _mut; }; -} // namespace bsf -} // namespace im - -#include "bsf-inl.h" -#include "bsf-inl-tensor.h" +} // namespace bsf +} // namespace im -#endif //BAIDU_PADDLE_SERVING_PREDICTOR_BSF_H +#include "predictor/framework/bsf-inl-tensor.h" +#include "predictor/framework/bsf-inl.h" diff --git a/predictor/framework/channel.h b/predictor/framework/channel.h index 2327a02d9fc3424742cd07685219f35f4c449ee0..8282ddaf667870c981db28608edc63c6ed734a97 100644 --- a/predictor/framework/channel.h +++ b/predictor/framework/channel.h @@ -1,6 +1,20 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_CHANNEL_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_CHANNEL_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. + +#pragma once +#include +#include #include "common/inner_common.h" namespace baidu { @@ -10,242 +24,202 @@ namespace predictor { class Channel; class Bus { -public: - Bus() { - clear(); - } + public: + Bus() { clear(); } - int regist(const std::string& op, Channel* channel) { - std::pair::iterator, bool> r - = _op_channels.insert(std::make_pair(op, channel)); - if (!r.second) { - LOG(ERROR) << "Failed insert op&channel into bus:" << op; - return -1; - } - return 0; + int regist(const std::string& op, Channel* channel) { + std::pair::iterator, bool> r = + _op_channels.insert(std::make_pair(op, channel)); + if (!r.second) { + LOG(ERROR) << "Failed insert op&channel into bus:" << op; + return -1; } + return 0; + } - Channel* channel_by_name(const std::string& op_name) { - typename boost::unordered_map::iterator it - = _op_channels.find(op_name); - if (it == _op_channels.end()) { - LOG(WARNING) - << "Not found channel in bus, op_name:" - << op_name << "."; - return NULL; - } - - return it->second; + Channel* channel_by_name(const std::string& op_name) { + typename boost::unordered_map::iterator it = + _op_channels.find(op_name); + if (it == _op_channels.end()) { + LOG(WARNING) << "Not found channel in bus, op_name:" << op_name << "."; + return NULL; } - void clear() { - _op_channels.clear(); - } + return it->second; + } - size_t size() const { - return _op_channels.size(); - } + void clear() { _op_channels.clear(); } + + size_t size() const { return _op_channels.size(); } -private: - boost::unordered_map _op_channels; + private: + boost::unordered_map _op_channels; }; class Channel { -public: - Channel() {} + public: + Channel() {} - void init(uint32_t id, const char* op) { - _id = id; - _op = std::string(op); - clear_data(); - } + void init(uint32_t id, const char* op) { + _id = id; + _op = std::string(op); + clear_data(); + } - void deinit() { - clear_data(); - } + void deinit() { clear_data(); } - uint32_t id() const { - return _id; - } + uint32_t id() const { return _id; } - const std::string& op() { - return _op; - } + const std::string& op() { return _op; } - int share_to_bus(Bus* bus) { - if (bus->regist(_op, this) != 0) { - LOG(ERROR) - << "Failed regist channel[" << _op - << "] to bus!"; - return -1; - } - - return 0; + int share_to_bus(Bus* bus) { + if (bus->regist(_op, this) != 0) { + LOG(ERROR) << "Failed regist channel[" << _op << "] to bus!"; + return -1; } - virtual void clear_data() = 0; + return 0; + } + + virtual void clear_data() = 0; - virtual void* param() = 0; - virtual const void* param() const = 0; + virtual void* param() = 0; + virtual const void* param() const = 0; - virtual google::protobuf::Message* message() = 0; - virtual const google::protobuf::Message* message() const = 0; + virtual google::protobuf::Message* message() = 0; + virtual const google::protobuf::Message* message() const = 0; - virtual Channel& operator=(const Channel& channel) = 0; + virtual Channel& operator=(const Channel& channel) = 0; - virtual std::string debug_string() const = 0; + virtual std::string debug_string() const = 0; -private: - uint32_t _id; - std::string _op; + private: + uint32_t _id; + std::string _op; }; -template +template class OpChannel : public Channel { -public: - OpChannel() { - } + public: + OpChannel() {} - void clear_data() { - _data.Clear(); - } + void clear_data() { _data.Clear(); } - void* param() { - return &_data; - } + void* param() { return &_data; } - const void* param() const { - return &_data; - } + const void* param() const { return &_data; } - google::protobuf::Message* message() { - return message_impl(derived_from_message< - TIsDerivedFromB::RESULT>()); - } + google::protobuf::Message* message() { + return message_impl( + derived_from_message< + TIsDerivedFromB::RESULT>()); + } - google::protobuf::Message* message_impl(derived_from_message) { - return dynamic_cast(&_data); - } + google::protobuf::Message* message_impl(derived_from_message) { + return dynamic_cast(&_data); + } - google::protobuf::Message* message_impl(derived_from_message) { - LOG(ERROR) << "Current type: " << typeid(T).name() - << " is not derived from protobuf."; - return NULL; - } + google::protobuf::Message* message_impl(derived_from_message) { + LOG(ERROR) << "Current type: " << typeid(T).name() + << " is not derived from protobuf."; + return NULL; + } - const google::protobuf::Message* message() const { - return message_impl(derived_from_message< - TIsDerivedFromB::RESULT>()); - } + const google::protobuf::Message* message() const { + return message_impl( + derived_from_message< + TIsDerivedFromB::RESULT>()); + } - const google::protobuf::Message* message_impl(derived_from_message) const { - return dynamic_cast(&_data); - } + const google::protobuf::Message* message_impl( + derived_from_message) const { + return dynamic_cast(&_data); + } - const google::protobuf::Message* message_impl(derived_from_message) const { - LOG(ERROR) << "Current type: " << typeid(T).name() - << " is not derived from protobuf."; - return NULL; - } - - Channel& operator=(const Channel& channel) { - _data = *(dynamic_cast&>(channel)).data(); - return *this; - } + const google::protobuf::Message* message_impl( + derived_from_message) const { + LOG(ERROR) << "Current type: " << typeid(T).name() + << " is not derived from protobuf."; + return NULL; + } - std::string debug_string() const { - return _data.ShortDebugString(); - } - - // functions of derived class + Channel& operator=(const Channel& channel) { + _data = *(dynamic_cast&>(channel)).data(); + return *this; + } - T* data() { - return &_data; - } + std::string debug_string() const { return _data.ShortDebugString(); } - const T* data() const { - return &_data; - } + // functions of derived class - Channel& operator=(const T& obj) { - _data = obj; - return *this; - } + T* data() { return &_data; } -private: - T _data; + const T* data() const { return &_data; } + + Channel& operator=(const T& obj) { + _data = obj; + return *this; + } + + private: + T _data; }; -template<> +template <> class OpChannel : public Channel { -public: - OpChannel() : _data(NULL) { - } + public: + OpChannel() : _data(NULL) {} - virtual ~OpChannel() { - _data = NULL; - } + virtual ~OpChannel() { _data = NULL; } - void clear_data() { - _data = NULL; - } + void clear_data() { _data = NULL; } - void* param() { - return const_cast((const void*)_data); - } + void* param() { return const_cast((const void*)_data); } - const void* param() const { - return _data; - } + const void* param() const { return _data; } - google::protobuf::Message* message() { - return const_cast(_data); - } + google::protobuf::Message* message() { + return const_cast(_data); + } - const google::protobuf::Message* message() const { - return _data; - } + const google::protobuf::Message* message() const { return _data; } - Channel& operator=(const Channel& channel) { - _data = channel.message(); - return *this; - } + Channel& operator=(const Channel& channel) { + _data = channel.message(); + return *this; + } - std::string debug_string() const { - if (_data) { - return _data->ShortDebugString(); - } else { - return "{\"Error\": \"Null Message Ptr\"}"; - } + std::string debug_string() const { + if (_data) { + return _data->ShortDebugString(); + } else { + return "{\"Error\": \"Null Message Ptr\"}"; } + } - // derived function imiplements - google::protobuf::Message* data() { - return const_cast(_data); - } + // derived function imiplements + google::protobuf::Message* data() { + return const_cast(_data); + } - const google::protobuf::Message* data() const { - return _data; - } + const google::protobuf::Message* data() const { return _data; } - OpChannel& operator=( - google::protobuf::Message* message) { - _data = message; - return *this; - } + OpChannel& operator=( + google::protobuf::Message* message) { + _data = message; + return *this; + } - OpChannel& operator=( - const google::protobuf::Message* message) { - _data = message; - return *this; - } + OpChannel& operator=( + const google::protobuf::Message* message) { + _data = message; + return *this; + } -private: - const google::protobuf::Message* _data; + private: + const google::protobuf::Message* _data; }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/dag.cpp b/predictor/framework/dag.cpp index 4dcf4e012f7c56f22281bb97320e056ff1014b9d..98b6835b34f94fd62ab7838447085345c04e03fa 100644 --- a/predictor/framework/dag.cpp +++ b/predictor/framework/dag.cpp @@ -1,61 +1,77 @@ -#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 +#include +#include "common/inner_common.h" +#include "framework/predictor_metric.h" // PredictorMetric #include "op/op.h" -#include "framework/predictor_metric.h" // PredictorMetric namespace baidu { namespace paddle_serving { namespace predictor { Dag::Dag() { - _index_nodes.clear(); - _name_nodes.clear(); - _stages.clear(); + _index_nodes.clear(); + _name_nodes.clear(); + _stages.clear(); } -Dag::~Dag() { - deinit(); -} +Dag::~Dag() { deinit(); } int Dag::deinit() { - for (std::vector::iterator iter = _stages.begin(); iter != _stages.end(); ++iter) { - if (*iter != NULL) { - delete *iter; - } + for (std::vector::iterator iter = _stages.begin(); + iter != _stages.end(); + ++iter) { + if (*iter != NULL) { + delete *iter; } - _stages.clear(); - - for (std::vector::iterator iter = _index_nodes.begin(); - iter != _index_nodes.end(); - ++iter) { - DagNode* node = *iter; - if (node != NULL) { - void* conf = node->conf; - if (conf != NULL) { - Op* op = OpRepository::instance().get_op(node->type); - if (op == NULL) { - LOG(ERROR) << "Failed to get_op, op type[" << node->type << "]"; - return -1; - } - op->delete_config(conf); - OpRepository::instance().return_op(node->type, op); - } - delete node; + } + _stages.clear(); + + for (std::vector::iterator iter = _index_nodes.begin(); + iter != _index_nodes.end(); + ++iter) { + DagNode* node = *iter; + if (node != NULL) { + void* conf = node->conf; + if (conf != NULL) { + Op* op = OpRepository::instance().get_op(node->type); + if (op == NULL) { + LOG(ERROR) << "Failed to get_op, op type[" << node->type << "]"; + return -1; } + op->delete_config(conf); + OpRepository::instance().return_op(node->type, op); + } + delete node; } - _index_nodes.clear(); - _name_nodes.clear(); - return 0; + } + _index_nodes.clear(); + _name_nodes.clear(); + return 0; } EdgeMode Dag::parse_mode(std::string& mode) { - if (mode == "RO") { - return RO; - } else if (mode == "RW") { - return RW; - } else { - return UNKNOWN; - } + if (mode == "RO") { + return RO; + } else if (mode == "RW") { + return RW; + } else { + return UNKNOWN; + } } // [@Node] @@ -89,7 +105,7 @@ EdgeMode Dag::parse_mode(std::string& mode) { int Dag::init(const char* path, const char* file, const std::string& name) { comcfg::Configure conf; if (conf.load(path, file) != 0) { - LOG(ERROR) << "Failed load conf from" + LOG(ERROR) << "Failed load conf from" << path << "/" << file << " in dag: " << name; return ERR_INTERNAL_FAILURE; @@ -100,145 +116,133 @@ int Dag::init(const char* path, const char* file, const std::string& name) { #endif int Dag::init(const configure::Workflow& conf, const std::string& name) { - _dag_name = name; - _index_nodes.clear(); - _name_nodes.clear(); - for (uint32_t i = 0; i < conf.nodes_size(); i++) { - DagNode* node = new (std::nothrow) DagNode(); - if (node == NULL) { - LOG(ERROR) << "Failed create new dag node"; - return ERR_MEM_ALLOC_FAILURE; - } - node->id = i + 1; // 0 is reserved for begginer-op - node->name = conf.nodes(i).name(); - node->type = conf.nodes(i).type(); - uint32_t depend_size = conf.nodes(i).dependencies_size(); - for (uint32_t j = 0; j < depend_size; j++) { - const configure::DAGNodeDependency& depend = - conf.nodes(i).dependencies(j); - std::string name = depend.name(); - std::string mode = depend.mode(); - node->depends.insert( - std::make_pair(name, parse_mode(mode))); - } - Op* op = OpRepository::instance().get_op(node->type); - if (op == NULL) { - LOG(ERROR) << "Failed to get_op, op type[" << node->type << "]"; - return ERR_INTERNAL_FAILURE; - } - // node->conf could be NULL - node->conf = op->create_config(conf.nodes(i)); - OpRepository::instance().return_op(node->type, op); - _name_nodes.insert(std::make_pair(node->name, node)); - _index_nodes.push_back(node); + _dag_name = name; + _index_nodes.clear(); + _name_nodes.clear(); + for (uint32_t i = 0; i < conf.nodes_size(); i++) { + DagNode* node = new (std::nothrow) DagNode(); + if (node == NULL) { + LOG(ERROR) << "Failed create new dag node"; + return ERR_MEM_ALLOC_FAILURE; } - - if (topo_sort() != 0) { - LOG(ERROR) << "Topo sort dag[" << _dag_name << "] failed!"; - return ERR_INTERNAL_FAILURE; + node->id = i + 1; // 0 is reserved for begginer-op + node->name = conf.nodes(i).name(); + node->type = conf.nodes(i).type(); + uint32_t depend_size = conf.nodes(i).dependencies_size(); + for (uint32_t j = 0; j < depend_size; j++) { + const configure::DAGNodeDependency& depend = + conf.nodes(i).dependencies(j); + std::string name = depend.name(); + std::string mode = depend.mode(); + node->depends.insert(std::make_pair(name, parse_mode(mode))); } - - if (FLAGS_el_log_level == 16) { - LOG(INFO) << "DAG: " << _dag_name; - LOG(INFO) << ", Op Num: " << _index_nodes.size(); - for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) { - DagNode* node = _index_nodes[nid]; - LOG(INFO) - << ", OP-" << node->id << "-" << node->name << "-" + Op* op = OpRepository::instance().get_op(node->type); + if (op == NULL) { + LOG(ERROR) << "Failed to get_op, op type[" << node->type << "]"; + return ERR_INTERNAL_FAILURE; + } + // node->conf could be NULL + node->conf = op->create_config(conf.nodes(i)); + OpRepository::instance().return_op(node->type, op); + _name_nodes.insert(std::make_pair(node->name, node)); + _index_nodes.push_back(node); + } + + if (topo_sort() != 0) { + LOG(ERROR) << "Topo sort dag[" << _dag_name << "] failed!"; + return ERR_INTERNAL_FAILURE; + } + + if (FLAGS_el_log_level == 16) { + LOG(INFO) << "DAG: " << _dag_name; + LOG(INFO) << ", Op Num: " << _index_nodes.size(); + for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) { + DagNode* node = _index_nodes[nid]; + LOG(INFO) << ", OP-" << node->id << "-" << node->name << "-" << node->type; - LOG(INFO) << " depends: " << node->depends.size(); + LOG(INFO) << " depends: " << node->depends.size(); - boost::unordered_map::iterator it; - for (it = node->depends.begin(); it != node->depends.end(); it++) { - LOG(INFO) << " " << it->first << " " << it->second; - } - } - LOG(INFO) << ""; + boost::unordered_map::iterator it; + for (it = node->depends.begin(); it != node->depends.end(); it++) { + LOG(INFO) << " " << it->first << " " << it->second; + } } + LOG(INFO) << ""; + } - return ERR_OK; + return ERR_OK; } -uint32_t Dag::nodes_size() { - return _index_nodes.size(); -} +uint32_t Dag::nodes_size() { return _index_nodes.size(); } -const DagNode* Dag::node_by_id(uint32_t id) { - return _index_nodes[id]; -} +const DagNode* Dag::node_by_id(uint32_t id) { return _index_nodes[id]; } -const DagNode* Dag::node_by_id(uint32_t id) const { - return _index_nodes[id]; -} +const DagNode* Dag::node_by_id(uint32_t id) const { return _index_nodes[id]; } const DagNode* Dag::node_by_name(std::string& name) { - return _name_nodes[name]; + return _name_nodes[name]; } const DagNode* Dag::node_by_name(const std::string& name) const { - boost::unordered_map::const_iterator it; - it = _name_nodes.find(name); - if (it == _name_nodes.end()) { - LOG(WARNING) << "Not found op by name:" << name; - return NULL; - } - return it->second; + boost::unordered_map::const_iterator it; + it = _name_nodes.find(name); + if (it == _name_nodes.end()) { + LOG(WARNING) << "Not found op by name:" << name; + return NULL; + } + return it->second; } -uint32_t Dag::stage_size() { - return _stages.size(); -} +uint32_t Dag::stage_size() { return _stages.size(); } + +const DagStage* Dag::stage_by_index(uint32_t index) { return _stages[index]; } -const DagStage* Dag::stage_by_index(uint32_t index) { - return _stages[index]; -} - int Dag::topo_sort() { - // TODO ƽ - std::stringstream ss; - for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) { - DagStage* stage = new (std::nothrow) DagStage(); - if (stage == NULL) { - LOG(ERROR) << "Invalid stage!"; - return ERR_MEM_ALLOC_FAILURE; - } - stage->nodes.push_back(_index_nodes[nid]); - ss.str(""); - ss << _stages.size(); - stage->name = ss.str(); - stage->full_name = full_name() + NAME_DELIMITER + stage->name; - _stages.push_back(stage); - - // assign stage number after stage created - _index_nodes[nid]->stage = nid; - // assign dag node full name after stage created - _index_nodes[nid]->full_name = stage->full_name + NAME_DELIMITER + _index_nodes[nid]->name; + std::stringstream ss; + for (uint32_t nid = 0; nid < _index_nodes.size(); nid++) { + DagStage* stage = new (std::nothrow) DagStage(); + if (stage == NULL) { + LOG(ERROR) << "Invalid stage!"; + return ERR_MEM_ALLOC_FAILURE; } - return ERR_OK; + stage->nodes.push_back(_index_nodes[nid]); + ss.str(""); + ss << _stages.size(); + stage->name = ss.str(); + stage->full_name = full_name() + NAME_DELIMITER + stage->name; + _stages.push_back(stage); + + // assign stage number after stage created + _index_nodes[nid]->stage = nid; + // assign dag node full name after stage created + _index_nodes[nid]->full_name = + stage->full_name + NAME_DELIMITER + _index_nodes[nid]->name; + } + return ERR_OK; } void Dag::regist_metric(const std::string& service_name) { - for (int stage_idx = 0; stage_idx < _stages.size(); ++stage_idx) { - DagStage* stage = _stages[stage_idx]; - PredictorMetric::GetInstance()->regist_latency_metric( - STAGE_METRIC_PREFIX + service_name + NAME_DELIMITER + stage->full_name); - for (int node_idx = 0; node_idx < stage->nodes.size(); ++node_idx) { - DagNode* node = stage->nodes[node_idx]; - PredictorMetric::GetInstance()->regist_latency_metric( - OP_METRIC_PREFIX + service_name + NAME_DELIMITER + node->full_name); - Op* op = OpRepository::instance().get_op(node->type); - if (op == NULL) { - LOG(ERROR) << "Failed to get_op, op type[" << node->type << "]"; - return; - } - op->set_full_name(service_name + NAME_DELIMITER + node->full_name); - op->set_config(node->conf); - op->regist_metric(); - OpRepository::instance().return_op(node->type, op); - } - } + for (int stage_idx = 0; stage_idx < _stages.size(); ++stage_idx) { + DagStage* stage = _stages[stage_idx]; + PredictorMetric::GetInstance()->regist_latency_metric( + STAGE_METRIC_PREFIX + service_name + NAME_DELIMITER + stage->full_name); + for (int node_idx = 0; node_idx < stage->nodes.size(); ++node_idx) { + DagNode* node = stage->nodes[node_idx]; + PredictorMetric::GetInstance()->regist_latency_metric( + OP_METRIC_PREFIX + service_name + NAME_DELIMITER + node->full_name); + Op* op = OpRepository::instance().get_op(node->type); + if (op == NULL) { + LOG(ERROR) << "Failed to get_op, op type[" << node->type << "]"; + return; + } + op->set_full_name(service_name + NAME_DELIMITER + node->full_name); + op->set_config(node->conf); + op->regist_metric(); + OpRepository::instance().return_op(node->type, op); + } + } } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/dag.h b/predictor/framework/dag.h index 1373ee2ed408ab5006fcc66889b49d6b808b7981..98dfdb8076e7022a2a718b61571cfbf686d92387 100644 --- a/predictor/framework/dag.h +++ b/predictor/framework/dag.h @@ -1,84 +1,88 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_DAG_H -#define 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. + +#pragma once +#include +#include #include "common/inner_common.h" namespace baidu { namespace paddle_serving { namespace predictor { -enum EdgeMode { - RO = 0, - RW = 1, - UNKNOWN -}; +enum EdgeMode { RO = 0, RW = 1, UNKNOWN }; struct DagNode { - uint32_t id; - uint32_t stage; - std::string name; // opname - std::string full_name; // workflow_stageindex_opname - std::string type; - void* conf; - boost::unordered_map depends; + uint32_t id; + uint32_t stage; + std::string name; // opname + std::string full_name; // workflow_stageindex_opname + std::string type; + void* conf; + boost::unordered_map depends; }; struct DagStage { - std::vector nodes; - std::string name; // stageindex - std::string full_name; // workflow_stageindex + std::vector nodes; + std::string name; // stageindex + std::string full_name; // workflow_stageindex }; class Dag { -public: - Dag(); + public: + Dag(); - virtual ~Dag(); + virtual ~Dag(); - EdgeMode parse_mode(std::string& mode); - - int init(const char* path, const char* file, const std::string& name); + EdgeMode parse_mode(std::string& mode); // NOLINT - int init(const configure::Workflow& conf, const std::string& name); - - int deinit(); + int init(const char* path, const char* file, const std::string& name); - uint32_t nodes_size(); + int init(const configure::Workflow& conf, const std::string& name); - const DagNode* node_by_id(uint32_t id); + int deinit(); - const DagNode* node_by_id(uint32_t id) const; + uint32_t nodes_size(); - const DagNode* node_by_name(std::string& name); + const DagNode* node_by_id(uint32_t id); - const DagNode* node_by_name(const std::string& name) const; + const DagNode* node_by_id(uint32_t id) const; - uint32_t stage_size(); + const DagNode* node_by_name(std::string& name); // NOLINT - const DagStage* stage_by_index(uint32_t index); + const DagNode* node_by_name(const std::string& name) const; - const std::string& name() const { - return _dag_name; - } + uint32_t stage_size(); - const std::string& full_name() const { - return _dag_name; - } + const DagStage* stage_by_index(uint32_t index); - void regist_metric(const std::string& service_name); - -private: - int topo_sort(); + const std::string& name() const { return _dag_name; } -private: - std::string _dag_name; - boost::unordered_map _name_nodes; - std::vector _index_nodes; - std::vector _stages; -}; + const std::string& full_name() const { return _dag_name; } -} // predictor -} // paddle_serving -} // baidu + void regist_metric(const std::string& service_name); + + private: + int topo_sort(); + + private: + std::string _dag_name; + boost::unordered_map _name_nodes; + std::vector _index_nodes; + std::vector _stages; +}; -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_DAG_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/dag_view.cpp b/predictor/framework/dag_view.cpp index 1d9e55ad2cff6c1a1bc8cb9b660a090b65163e49..141f8d14d16c6e84b8aba6ca3ba58212941412ad 100644 --- a/predictor/framework/dag_view.cpp +++ b/predictor/framework/dag_view.cpp @@ -1,5 +1,20 @@ +// 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 // TRACEPRINTF +#include // TRACEPRINTF +#include #include "common/inner_common.h" #include "framework/op_repository.h" @@ -8,175 +23,166 @@ namespace paddle_serving { namespace predictor { int DagView::init(Dag* dag, const std::string& service_name) { - _name = dag->name(); - _full_name = service_name + NAME_DELIMITER + dag->name(); - _bus = butil::get_object(); - _bus->clear(); - uint32_t stage_size = dag->stage_size(); - // create tls stage view - for (uint32_t si = 0; si < stage_size; si++) { - const DagStage* stage = dag->stage_by_index(si); - if (stage == NULL) { - LOG(ERROR) << "Failed get stage by index:" << si; - return ERR_INTERNAL_FAILURE; - } - ViewStage* vstage = butil::get_object(); - if (vstage == NULL) { - LOG(ERROR) - << "Failed get vstage from object pool" - << "at:" << si; - return ERR_MEM_ALLOC_FAILURE; - } - vstage->full_name = service_name + NAME_DELIMITER + stage->full_name; - uint32_t node_size = stage->nodes.size(); - // create tls view node - for (uint32_t ni = 0; ni < node_size; ni++) { - DagNode* node = stage->nodes[ni]; - ViewNode* vnode = butil::get_object(); - if (vnode == NULL) { - LOG(ERROR) << "Failed get vnode at:" << ni; - return ERR_MEM_ALLOC_FAILURE; - } - // factory type - Op* op = OpRepository::instance().get_op(node->type); - if (op == NULL) { - LOG(ERROR) << "Failed get op with type:" - << node->type; - return ERR_INTERNAL_FAILURE; - } - - // initialize a TLS op object - if (op->init(_bus, dag, node->id, node->name, node->type, node->conf) != 0) { - LOG(WARNING) << "Failed init op, type:" << node->type; - return ERR_INTERNAL_FAILURE; - } - op->set_full_name(service_name + NAME_DELIMITER + node->full_name); - vnode->conf = node; - vnode->op = op; - vstage->nodes.push_back(vnode); - } - _view.push_back(vstage); + _name = dag->name(); + _full_name = service_name + NAME_DELIMITER + dag->name(); + _bus = butil::get_object(); + _bus->clear(); + uint32_t stage_size = dag->stage_size(); + // create tls stage view + for (uint32_t si = 0; si < stage_size; si++) { + const DagStage* stage = dag->stage_by_index(si); + if (stage == NULL) { + LOG(ERROR) << "Failed get stage by index:" << si; + return ERR_INTERNAL_FAILURE; + } + ViewStage* vstage = butil::get_object(); + if (vstage == NULL) { + LOG(ERROR) << "Failed get vstage from object pool" + << "at:" << si; + return ERR_MEM_ALLOC_FAILURE; + } + vstage->full_name = service_name + NAME_DELIMITER + stage->full_name; + uint32_t node_size = stage->nodes.size(); + // create tls view node + for (uint32_t ni = 0; ni < node_size; ni++) { + DagNode* node = stage->nodes[ni]; + ViewNode* vnode = butil::get_object(); + if (vnode == NULL) { + LOG(ERROR) << "Failed get vnode at:" << ni; + return ERR_MEM_ALLOC_FAILURE; + } + // factory type + Op* op = OpRepository::instance().get_op(node->type); + if (op == NULL) { + LOG(ERROR) << "Failed get op with type:" << node->type; + return ERR_INTERNAL_FAILURE; + } + + // initialize a TLS op object + if (op->init(_bus, dag, node->id, node->name, node->type, node->conf) != + 0) { + LOG(WARNING) << "Failed init op, type:" << node->type; + return ERR_INTERNAL_FAILURE; + } + op->set_full_name(service_name + NAME_DELIMITER + node->full_name); + vnode->conf = node; + vnode->op = op; + vstage->nodes.push_back(vnode); } + _view.push_back(vstage); + } - return ERR_OK; + return ERR_OK; } int DagView::deinit() { - uint32_t stage_size = _view.size(); - for (uint32_t si = 0; si < stage_size; si++) { - ViewStage* vstage = _view[si]; - uint32_t node_size = vstage->nodes.size(); - for (uint32_t ni = 0; ni < node_size; ni++) { - ViewNode* vnode = vstage->nodes[ni]; - vnode->op->deinit(); - OpRepository::instance().return_op(vnode->op); - vnode->reset(); - // clear item - butil::return_object(vnode); - } - // clear vector - vstage->nodes.clear(); - butil::return_object(vstage); + uint32_t stage_size = _view.size(); + for (uint32_t si = 0; si < stage_size; si++) { + ViewStage* vstage = _view[si]; + uint32_t node_size = vstage->nodes.size(); + for (uint32_t ni = 0; ni < node_size; ni++) { + ViewNode* vnode = vstage->nodes[ni]; + vnode->op->deinit(); + OpRepository::instance().return_op(vnode->op); + vnode->reset(); + // clear item + butil::return_object(vnode); } - _view.clear(); - _bus->clear(); - butil::return_object(_bus); - return ERR_OK; + // clear vector + vstage->nodes.clear(); + butil::return_object(vstage); + } + _view.clear(); + _bus->clear(); + butil::return_object(_bus); + return ERR_OK; } int DagView::execute(butil::IOBufBuilder* debug_os) { - uint32_t stage_size = _view.size(); - for (uint32_t si = 0; si < stage_size; si++) { - TRACEPRINTF("start to execute stage[%u]", si); - int errcode = execute_one_stage(_view[si], debug_os); - TRACEPRINTF("finish to execute stage[%u]", si); - if (errcode < 0) { - LOG(ERROR) - << "failed execute stage[" - << _view[si]->debug(); - return errcode; - } + uint32_t stage_size = _view.size(); + for (uint32_t si = 0; si < stage_size; si++) { + TRACEPRINTF("start to execute stage[%u]", si); + int errcode = execute_one_stage(_view[si], debug_os); + TRACEPRINTF("finish to execute stage[%u]", si); + if (errcode < 0) { + LOG(ERROR) << "failed execute stage[" << _view[si]->debug(); + return errcode; } - return ERR_OK; + } + return ERR_OK; } // The default execution strategy is in sequencing // You can derive a subclass to implement this func. // ParallelDagView maybe the one you want. int DagView::execute_one_stage(ViewStage* vstage, - butil::IOBufBuilder* debug_os) { - butil::Timer stage_time(butil::Timer::STARTED); - uint32_t node_size = vstage->nodes.size(); - for (uint32_t ni = 0; ni < node_size; ni++) { - ViewNode* vnode = vstage->nodes[ni]; - DagNode* conf = vnode->conf; - Op* op = vnode->op; - TRACEPRINTF("start to execute op[%s]", op->name()); - int errcode = op->process(debug_os != NULL); - TRACEPRINTF("finish to execute op[%s]", op->name()); - if (errcode < 0) { - LOG(ERROR) - << "Execute failed, Op:" << op->debug_string(); - return errcode; - } - - if (errcode > 0) { - LOG(INFO) - << "Execute ignore, Op:" << op->debug_string(); - continue; - } - - if (debug_os) { - (*debug_os) - << "{\"op_name\": \"" << op->name() - << "\", \"debug_str:\": \"" - << op->debug_string() - << "\", \"time_info\": \"" << op->time_info() << "\"}"; - } - - //LOG(DEBUG) << "Execute succ, Op:" << op->debug_string(); + butil::IOBufBuilder* debug_os) { + butil::Timer stage_time(butil::Timer::STARTED); + uint32_t node_size = vstage->nodes.size(); + for (uint32_t ni = 0; ni < node_size; ni++) { + ViewNode* vnode = vstage->nodes[ni]; + DagNode* conf = vnode->conf; + Op* op = vnode->op; + TRACEPRINTF("start to execute op[%s]", op->name()); + int errcode = op->process(debug_os != NULL); + TRACEPRINTF("finish to execute op[%s]", op->name()); + if (errcode < 0) { + LOG(ERROR) << "Execute failed, Op:" << op->debug_string(); + return errcode; + } + + if (errcode > 0) { + LOG(INFO) << "Execute ignore, Op:" << op->debug_string(); + continue; } - stage_time.stop(); - PredictorMetric::GetInstance()->update_latency_metric( - STAGE_METRIC_PREFIX + vstage->full_name, stage_time.u_elapsed()); - return ERR_OK; + + if (debug_os) { + (*debug_os) << "{\"op_name\": \"" << op->name() + << "\", \"debug_str:\": \"" << op->debug_string() + << "\", \"time_info\": \"" << op->time_info() << "\"}"; + } + + // LOG(DEBUG) << "Execute succ, Op:" << op->debug_string(); + } + stage_time.stop(); + PredictorMetric::GetInstance()->update_latency_metric( + STAGE_METRIC_PREFIX + vstage->full_name, stage_time.u_elapsed()); + return ERR_OK; } int DagView::set_request_channel(Channel& request) { - // Each workflow should get the very beginning - // request (channel), and commit it to bus, for - // the first stage ops consuming. + // Each workflow should get the very beginning + // request (channel), and commit it to bus, for + // the first stage ops consuming. - request.share_to_bus(_bus); + request.share_to_bus(_bus); - return ERR_OK; + return ERR_OK; } const Channel* DagView::get_response_channel() const { - // Caller obtains response channel from bus, and - // writes it to rpc response(protbuf/json) - if (_view.size() < 1) { - LOG(ERROR) << "invalid empty view stage!"; - return NULL; - } - - ViewStage* last_stage = _view[_view.size() - 1]; - if (last_stage->nodes.size() != 1 - || last_stage->nodes[0] == NULL) { - LOG(ERROR) << "Invalid last stage, size[" - << last_stage->nodes.size() - << "] != 1"; - return NULL; - } - - Op* last_op = last_stage->nodes[0]->op; - if (last_op == NULL) { - LOG(ERROR) << "Last op is NULL"; - return NULL; - } - return last_op->mutable_channel(); + // Caller obtains response channel from bus, and + // writes it to rpc response(protbuf/json) + if (_view.size() < 1) { + LOG(ERROR) << "invalid empty view stage!"; + return NULL; + } + + ViewStage* last_stage = _view[_view.size() - 1]; + if (last_stage->nodes.size() != 1 || last_stage->nodes[0] == NULL) { + LOG(ERROR) << "Invalid last stage, size[" << last_stage->nodes.size() + << "] != 1"; + return NULL; + } + + Op* last_op = last_stage->nodes[0]->op; + if (last_op == NULL) { + LOG(ERROR) << "Last op is NULL"; + return NULL; + } + return last_op->mutable_channel(); } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/dag_view.h b/predictor/framework/dag_view.h index 372954199697a432d77f92ff18496cb3ccf0f248..660f0e7716b6834b5ffc5db0baf7e741d2ee43b3 100644 --- a/predictor/framework/dag_view.h +++ b/predictor/framework/dag_view.h @@ -1,10 +1,24 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_DAG_VIEW_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_DAG_VIEW_H - -#include "op/op.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. + +#pragma once +#include +#include #include "common/inner_common.h" #include "framework/channel.h" #include "framework/dag.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { @@ -13,7 +27,7 @@ namespace predictor { class Op; struct ViewNode { - Op* op; // op->full_name == service_workflow_stageindex_opname + Op* op; // op->full_name == service_workflow_stageindex_opname DagNode* conf; void reset() { op = NULL; @@ -23,20 +37,16 @@ struct ViewNode { struct ViewStage { std::vector nodes; - std::string full_name; // service_workflow_stageindex - std::string debug() { - return "TOBE IMPLEMENTED!"; - } + std::string full_name; // service_workflow_stageindex + std::string debug() { return "TOBE IMPLEMENTED!"; } }; class DagView { -public: - DagView() : _bus(NULL) { - _view.clear(); - } + public: + DagView() : _bus(NULL) { _view.clear(); } ~DagView() {} - + int init(Dag* dag, const std::string& service_name); int deinit(); @@ -47,21 +57,17 @@ public: // You can derive a subclass to implement this func. // ParallelDagView maybe the one you want. 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 std::string& name() const { - return _name; - } + const std::string& name() const { return _name; } - const std::string& full_name() const { - return _full_name; - } + const std::string& full_name() const { return _full_name; } -private: + private: std::string _name; std::string _full_name; std::vector _view; @@ -71,14 +77,10 @@ private: // The derived DagView supports parallel execution // strategy, by implments the execute_one_stage(). class ParallelDagView : public DagView { -public: - int execute_one_stage(ViewStage* vstage, butil::IOBufBuilder*) { - return 0; - } + public: + int execute_one_stage(ViewStage* vstage, butil::IOBufBuilder*) { return 0; } }; -} // predictor -} // paddle_serving -} // baidu - -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_DAG_VIEW_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/factory.h b/predictor/framework/factory.h index c776f44a081750fa55359421004c917e2f8c3a3d..0bb157afee848056482a1f5765ba8128118d2285 100644 --- a/predictor/framework/factory.h +++ b/predictor/framework/factory.h @@ -1,20 +1,21 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/factory.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/10 22:09:57 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_FACTORY_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_FACTORY_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. + +#pragma once +#include +#include +#include #include "common/inner_common.h" #include "glog/raw_logging.h" namespace baidu { @@ -22,133 +23,131 @@ namespace paddle_serving { namespace predictor { //////////////// DECLARE INTERFACE //////////////// -#define DECLARE_FACTORY_OBJECT(D, B) \ - static int regist(const std::string& tag) { \ - FactoryDerive* factory = \ - new (std::nothrow) FactoryDerive();\ - if (factory == NULL \ - || FactoryPool::instance().register_factory(\ - tag, factory) != 0) { \ - RAW_LOG_FATAL("Failed regist factory: %s in macro!", #D); \ - return -1; \ - } \ - return 0; \ - } +#define DECLARE_FACTORY_OBJECT(D, B) \ + static int regist(const std::string& tag) { \ + FactoryDerive* factory = new (std::nothrow) FactoryDerive(); \ + if (factory == NULL || \ + FactoryPool::instance().register_factory(tag, factory) != 0) { \ + RAW_LOG_FATAL("Failed regist factory: %s in macro!", #D); \ + return -1; \ + } \ + return 0; \ + } #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) \ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - D::regist(#D); \ -} +#define DEFINE_FACTORY_OBJECT(D) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + D::regist(#D); \ + } //////////////// REGISTER INTERFACE //////////////// -#define REGIST_FACTORY_OBJECT_IMPL(D, B) \ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - ::baidu::paddle_serving::predictor::FactoryDerive* factory =\ - new (::std::nothrow) ::baidu::paddle_serving::predictor::FactoryDerive();\ - if (factory == NULL \ - || ::baidu::paddle_serving::predictor::FactoryPool::instance().register_factory(\ - #D, factory) != 0) { \ - RAW_LOG_FATAL("Failed regist factory: %s->%s in macro!", #D, #B); \ - return ; \ - } \ - return ; \ -} - -#define REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(D, B, N) \ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - ::baidu::paddle_serving::predictor::FactoryDerive* factory =\ - new (::std::nothrow) ::baidu::paddle_serving::predictor::FactoryDerive();\ - if (factory == NULL \ - || ::baidu::paddle_serving::predictor::FactoryPool::instance().register_factory(\ - N, factory) != 0) { \ - 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); \ - return ; \ -} - -template +#define REGIST_FACTORY_OBJECT_IMPL(D, B) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + ::baidu::paddle_serving::predictor::FactoryDerive* factory = new ( \ + ::std::nothrow)::baidu::paddle_serving::predictor::FactoryDerive(); \ + if (factory == NULL || \ + ::baidu::paddle_serving::predictor::FactoryPool::instance() \ + .register_factory(#D, factory) != 0) { \ + RAW_LOG_FATAL("Failed regist factory: %s->%s in macro!", #D, #B); \ + return; \ + } \ + return; \ + } + +#define REGIST_FACTORY_OBJECT_IMPL_WITH_NAME(D, B, N) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + ::baidu::paddle_serving::predictor::FactoryDerive* factory = new ( \ + ::std::nothrow)::baidu::paddle_serving::predictor::FactoryDerive(); \ + if (factory == NULL || \ + ::baidu::paddle_serving::predictor::FactoryPool::instance() \ + .register_factory(N, factory) != 0) { \ + 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); \ + return; \ + } + +template class FactoryBase { -public: - virtual B* gen() = 0; - virtual void del(B* obj) = 0; + public: + virtual B* gen() = 0; + virtual void del(B* obj) = 0; }; -template +template class FactoryDerive : public FactoryBase { -public: - B* gen() { - return new(std::nothrow) D(); - } + public: + B* gen() { return new (std::nothrow) D(); } - void del(B* obj) { - delete dynamic_cast(obj); - } + void del(B* obj) { delete dynamic_cast(obj); } }; -template +template class FactoryPool { -public: - static FactoryPool& instance() { - static FactoryPool singleton; - return singleton; + public: + static FactoryPool& instance() { + static FactoryPool singleton; + return singleton; + } + + int register_factory(const std::string& tag, FactoryBase* factory) { + typename std::map*>::iterator it = + _pool.find(tag); + if (it != _pool.end()) { + RAW_LOG_FATAL("Insert duplicate with tag: %s", tag.c_str()); + return -1; } - int register_factory(const std::string& tag, - FactoryBase* factory) { - typename std::map*>::iterator it - = _pool.find(tag); - if (it != _pool.end()) { - RAW_LOG_FATAL("Insert duplicate with tag: %s", tag.c_str()); - return -1; - } - - std::pair< - typename std::map*>::iterator, - bool> r = _pool.insert(std::make_pair(tag, factory)); - if (!r.second) { - RAW_LOG_FATAL("Failed insert new factory with: %s", tag.c_str()); - return -1; - } - - RAW_LOG_INFO("Succ insert one factory, tag: %s, base type %s", tag.c_str(), typeid(B).name()); - - return 0; + std::pair*>::iterator, bool> + r = _pool.insert(std::make_pair(tag, factory)); + if (!r.second) { + RAW_LOG_FATAL("Failed insert new factory with: %s", tag.c_str()); + return -1; } - B* generate_object(const std::string& tag) { - typename std::map*>::iterator it - = _pool.find(tag); - if (it == _pool.end() || it->second == NULL) { - RAW_LOG_FATAL("Not found factory pool, tag: %s, pool size %u", tag.c_str(), _pool.size()); - return NULL; - } - - return it->second->gen(); + RAW_LOG_INFO("Succ insert one factory, tag: %s, base type %s", + tag.c_str(), + typeid(B).name()); + + return 0; + } + + B* generate_object(const std::string& tag) { + typename std::map*>::iterator it = + _pool.find(tag); + if (it == _pool.end() || it->second == NULL) { + RAW_LOG_FATAL("Not found factory pool, tag: %s, pool size %u", + tag.c_str(), + _pool.size()); + return NULL; } - template - void return_object(B* object) { - FactoryDerive factory; - factory.del(object); - } + return it->second->gen(); + } -private: - std::map*> _pool; -}; + template + void return_object(B* object) { + FactoryDerive factory; + factory.del(object); + } -} // predictor -} // paddle_serving -} // baidu + private: + std::map*> _pool; +}; -#endif //BAIDU_PADDLE_SERVING_PREDICTOR_FACTORY_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +/* vim: set expandtab ts=2 sw=2 sts=2 tw=100: */ diff --git a/predictor/framework/infer.h b/predictor/framework/infer.h index 134c5880c5e3b3c20bf01ac72e67a6018325e931..8fd6bc5b2c9389a930add0a1c6e08fbb8c1b012b 100644 --- a/predictor/framework/infer.h +++ b/predictor/framework/infer.h @@ -1,13 +1,27 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_INFER_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_INFER_H - -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once #include +#include #include +#include +#include #include "common/inner_common.h" -#include "framework/infer_data.h" -#include "framework/factory.h" #include "framework/bsf.h" +#include "framework/factory.h" +#include "framework/infer_data.h" namespace baidu { namespace paddle_serving { @@ -16,1001 +30,960 @@ namespace predictor { using configure::ModelToolkitConf; class InferEngine { -public: + public: + virtual ~InferEngine() {} + + virtual int proc_initialize(const configure::EngineDesc& conf, bool version) { + return proc_initialize_impl(conf, version); + } + virtual int proc_finalize() { return proc_finalize_impl(); } + virtual int thrd_initialize() { return thrd_initialize_impl(); } + virtual int thrd_clear() { return thrd_clear_impl(); } + virtual int thrd_finalize() { return thrd_finalize_impl(); } + virtual int infer(const void* in, void* out, uint32_t batch_size = -1) { + return infer_impl1(in, out, batch_size); + } + + virtual int reload() = 0; + + virtual uint64_t version() const = 0; + + // begin: framework inner call + virtual int proc_initialize_impl(const configure::EngineDesc& conf, + bool version) = 0; + virtual int thrd_initialize_impl() = 0; + virtual int thrd_finalize_impl() = 0; + virtual int thrd_clear_impl() = 0; + virtual int proc_finalize_impl() = 0; + virtual int infer_impl1(const void* in, + void* out, + uint32_t batch_size = -1) = 0; + virtual int infer_impl2(const BatchTensor& in, + BatchTensor& out) = 0; // NOLINT + // end: framework inner call +}; + +class ReloadableInferEngine : public InferEngine { + public: + virtual ~ReloadableInferEngine() {} - virtual ~InferEngine() {} + union last_check_status { + time_t last_timestamp; + uint64_t last_md5sum; + uint64_t last_revision; + }; - virtual int proc_initialize(const configure::EngineDesc& conf, bool version) { - return proc_initialize_impl(conf, version); - } - virtual int proc_finalize() { - return proc_finalize_impl(); + typedef im::bsf::Task TaskT; + + virtual int load(const std::string& data_path) = 0; + + int proc_initialize_impl(const configure::EngineDesc& conf, bool version) { + _reload_tag_file = conf.reloadable_meta(); + _reload_mode_tag = conf.reloadable_type(); + _model_data_path = conf.model_data_path(); + _infer_thread_num = conf.runtime_thread_num(); + _infer_batch_size = conf.batch_infer_size(); + _infer_batch_align = conf.enable_batch_align(); + if (!check_need_reload() || load(_model_data_path) != 0) { + LOG(ERROR) << "Failed load model_data_path" << _model_data_path; + return -1; } - virtual int thrd_initialize() { - return thrd_initialize_impl(); + + if (parse_version_info(conf, version) != 0) { + LOG(ERROR) << "Failed parse version info"; + return -1; } - virtual int thrd_clear() { - return thrd_clear_impl(); + + LOG(WARNING) << "Succ load model_data_path" << _model_data_path; + return 0; + } + + int proc_initialize(const configure::EngineDesc& conf, bool version) { + if (proc_initialize_impl(conf, version) != 0) { + LOG(ERROR) << "Failed proc initialize impl"; + return -1; } - virtual int thrd_finalize() { - return thrd_finalize_impl(); + + // init bsf framework + if (_infer_thread_num <= 0) { + return 0; } - virtual int infer(const void* in, void* out, uint32_t batch_size = -1) { - return infer_impl1(in, out, batch_size); + + im::bsf::TaskExecutor::instance()->set_thread_init_fn( + boost::bind(&InferEngine::thrd_initialize_impl, this)); + im::bsf::TaskExecutor::instance()->set_thread_reset_fn( + boost::bind(&InferEngine::thrd_clear_impl, this)); + im::bsf::TaskExecutor::instance()->set_thread_callback_fn( + boost::bind(&InferEngine::infer_impl2, this, _1, _2)); + im::bsf::TaskExecutor::instance()->set_batch_size(_infer_batch_size); + im::bsf::TaskExecutor::instance()->set_batch_align( + _infer_batch_align); + if (im::bsf::TaskExecutor::instance()->start(_infer_thread_num) != + 0) { + LOG(ERROR) << "Failed start bsf executor, threads:" << _infer_thread_num; + return -1; } - virtual int reload() = 0; + LOG(WARNING) << "Enable batch schedule framework, thread_num:" + << _infer_thread_num << ", batch_size:" << _infer_batch_size + << ", enable_batch_align:" << _infer_batch_align; - virtual uint64_t version() const = 0; + return 0; + } - // begin: framework inner call - virtual int proc_initialize_impl( - const configure::EngineDesc& conf, bool version) = 0; - virtual int thrd_initialize_impl() = 0; - virtual int thrd_finalize_impl() = 0; - virtual int thrd_clear_impl() = 0; - virtual int proc_finalize_impl() = 0; - virtual int infer_impl1( - const void* in, void* out, uint32_t batch_size = -1) = 0; - virtual int infer_impl2(const BatchTensor& in, BatchTensor& out) = 0; - // end: framework inner call -}; + int infer(const void* in, void* out, uint32_t batch_size = -1) { + if (_infer_thread_num <= 0) { + return infer_impl1(in, out, batch_size); + } -class ReloadableInferEngine : public InferEngine { -public: - virtual ~ReloadableInferEngine() {} + im::bsf::TaskManager task_manager; + task_manager.schedule(*(reinterpret_cast(in)), + *(reinterpret_cast(out))); + task_manager.wait(); + return 0; + } - union last_check_status { - time_t last_timestamp; - uint64_t last_md5sum; - uint64_t last_revision; - }; + int thrd_initialize() { + if (_infer_thread_num > 0) { + return 0; + } - typedef im::bsf::Task TaskT; + return thrd_initialize_impl(); + } - virtual int load(const std::string& data_path) = 0; + int thrd_clear() { + if (_infer_thread_num > 0) { + return 0; + } - int proc_initialize_impl(const configure::EngineDesc& conf, bool version) { - _reload_tag_file = conf.reloadable_meta(); - _reload_mode_tag = conf.reloadable_type(); - _model_data_path = conf.model_data_path(); - _infer_thread_num = conf.runtime_thread_num(); - _infer_batch_size = conf.batch_infer_size(); - _infer_batch_align = conf.enable_batch_align(); - if (!check_need_reload() || load(_model_data_path) != 0) { - LOG(ERROR) << "Failed load model_data_path" << _model_data_path; - return -1; - } + return thrd_clear_impl(); + } - if (parse_version_info(conf, version) != 0) { - LOG(ERROR) << "Failed parse version info"; - return -1; - } + int proc_finalize() { + if (proc_finalize_impl() != 0) { + LOG(ERROR) << "Failed proc finalize impl"; + return -1; + } - LOG(WARNING) << "Succ load model_data_path" << _model_data_path; - return 0; + if (_infer_thread_num > 0) { + im::bsf::TaskExecutor::instance()->stop(); } - int proc_initialize(const configure::EngineDesc& conf, bool version) { - if (proc_initialize_impl(conf, version) != 0) { - LOG(ERROR) << "Failed proc initialize impl"; - return -1; - } + return 0; + } - // init bsf framework - if (_infer_thread_num <= 0) { - return 0; - } + int reload() { + if (check_need_reload()) { + LOG(WARNING) << "begin reload model[" << _model_data_path << "]."; + return load(_model_data_path); + } + return 0; + } + + uint64_t version() const { return _version; } + + uint32_t thread_num() const { return _infer_thread_num; } - im::bsf::TaskExecutor::instance()->set_thread_init_fn( - boost::bind(&InferEngine::thrd_initialize_impl, this)); - im::bsf::TaskExecutor::instance()->set_thread_reset_fn( - boost::bind(&InferEngine::thrd_clear_impl, this)); - im::bsf::TaskExecutor::instance()->set_thread_callback_fn( - boost::bind(&InferEngine::infer_impl2, this, _1, _2)); - im::bsf::TaskExecutor::instance()->set_batch_size(_infer_batch_size); - im::bsf::TaskExecutor::instance()->set_batch_align(_infer_batch_align); - if (im::bsf::TaskExecutor::instance()->start(_infer_thread_num) - != 0) { - LOG(ERROR) << "Failed start bsf executor, threads:" << _infer_thread_num; - return -1; - } + private: + int parse_version_info(const configure::EngineDesc& config, bool version) { + _version = uint64_t(-1); + return 0; + } - LOG(WARNING) << "Enable batch schedule framework, thread_num:" - << _infer_thread_num << ", batch_size:" << _infer_batch_size - << ", enable_batch_align:" << _infer_batch_align; + bool check_need_reload() { + if (_reload_mode_tag == "timestamp_ne") { + return check_timestamp_ne(); + } else if (_reload_mode_tag == "timestamp_gt") { + return check_timestamp_gt(); + } else if (_reload_mode_tag == "md5sum") { + return check_md5sum(); + } else if (_reload_mode_tag == "revision") { + return check_revision(); + } else if (_reload_mode_tag == "none") { + return false; + } else { + LOG(ERROR) << "Not support check type: " << _reload_mode_tag; + return false; + } + } + + bool check_timestamp_ne() { + struct stat st; + if (stat(_reload_tag_file.c_str(), &st) != 0) { + LOG(ERROR) << "Failed stat config file:" << _reload_tag_file; + return false; + } - return 0; + if ((st.st_mode & S_IFREG) && st.st_mtime != _last_status.last_timestamp) { + _last_status.last_timestamp = st.st_mtime; + return true; } - int infer(const void* in, void* out, uint32_t batch_size = -1) { - if (_infer_thread_num <= 0) { - return infer_impl1(in, out, batch_size); - } + return false; + } - im::bsf::TaskManager task_manager; - task_manager.schedule(*(const BatchTensor*)in, *(BatchTensor*)out); - task_manager.wait(); - return 0; - } - - int thrd_initialize() { - if (_infer_thread_num > 0) { - return 0; - } + bool check_timestamp_gt() { + struct stat st; + if (stat(_reload_tag_file.c_str(), &st) != 0) { + LOG(ERROR) << "Failed stat config file:" << _reload_tag_file; + return false; + } - return thrd_initialize_impl(); + if ((st.st_mode & S_IFREG) && st.st_mtime > _last_status.last_timestamp) { + _last_status.last_timestamp = st.st_mtime; + return true; } - int thrd_clear() { - if (_infer_thread_num > 0) { - return 0; - } + return false; + } + + bool check_md5sum() { return false; } + + bool check_revision() { return false; } + + protected: + std::string _model_data_path; + + private: + std::string _reload_tag_file; + std::string _reload_mode_tag; + last_check_status _last_status; + uint32_t _infer_thread_num; + uint32_t _infer_batch_size; + bool _infer_batch_align; + uint64_t _version; +}; - return thrd_clear_impl(); +template +struct ModelData { + ModelData() : current_idx(1) { + cores[0] = NULL; + cores[1] = NULL; + } + + ~ModelData() { + delete cores[0]; + delete cores[1]; + } + + EngineCore* cores[2]; + uint32_t current_idx; +}; + +template +class DBReloadableInferEngine : public ReloadableInferEngine { + public: + virtual ~DBReloadableInferEngine() {} + + int proc_initialize(const configure::EngineDesc& conf, bool version) { + THREAD_KEY_CREATE(&_skey, NULL); + THREAD_MUTEX_INIT(&_mutex, NULL); + return ReloadableInferEngine::proc_initialize(conf, version); + } + + virtual int load(const std::string& model_data_dir) { + if (_reload_vec.empty()) { + return 0; } - int proc_finalize() { - if (proc_finalize_impl() != 0) { - LOG(ERROR) << "Failed proc finalize impl"; - return -1; - } + for (uint32_t ti = 0; ti < _reload_vec.size(); ++ti) { + if (load_data(_reload_vec[ti], model_data_dir) != 0) { + LOG(ERROR) << "Failed reload engine model: " << ti; + return -1; + } + } + + LOG(WARNING) << "Succ load engine, path: " << model_data_dir; - if (_infer_thread_num > 0) { - im::bsf::TaskExecutor::instance()->stop(); - } + return 0; + } - return 0; + int load_data(ModelData* md, const std::string& data_path) { + uint32_t next_idx = (md->current_idx + 1) % 2; + if (md->cores[next_idx]) { + delete md->cores[next_idx]; } - int reload() { - if (check_need_reload()) { - LOG(WARNING) << "begin reload model[" << _model_data_path << "]."; - return load(_model_data_path); - } - return 0; + md->cores[next_idx] = new (std::nothrow) EngineCore; + if (!md->cores[next_idx] || md->cores[next_idx]->create(data_path) != 0) { + LOG(ERROR) << "Failed create model, path: " << data_path; + return -1; } + md->current_idx = next_idx; + return 0; + } - uint64_t version() const { - return _version; + virtual int thrd_initialize_impl() { + // memory pool to be inited in non-serving-threads + if (MempoolWrapper::instance().thread_initialize() != 0) { + LOG(ERROR) << "Failed thread initialize mempool"; + return -1; } - uint32_t thread_num() const { - return _infer_thread_num; + ModelData* md = new (std::nothrow) ModelData; + if (!md || load_data(md, _model_data_path) != 0) { + LOG(ERROR) << "Failed create thread data from " << _model_data_path; + return -1; } -private: - int parse_version_info(const configure::EngineDesc& config, bool version) { - _version = uint64_t(-1); - return 0; + THREAD_SETSPECIFIC(_skey, md); + im::bsf::AutoMutex lock(_mutex); + _reload_vec.push_back(md); + return 0; + } + + int thrd_clear_impl() { + // for non-serving-threads + if (MempoolWrapper::instance().thread_clear() != 0) { + LOG(ERROR) << "Failed thread clear mempool"; + return -1; } + return 0; + } + + int thrd_finalize_impl() { return 0; } + int proc_finalize_impl() { + THREAD_KEY_DELETE(_skey); + THREAD_MUTEX_DESTROY(&_mutex); + return 0; + } - bool check_need_reload() { - if (_reload_mode_tag == "timestamp_ne") { - return check_timestamp_ne(); - } else if (_reload_mode_tag == "timestamp_gt") { - return check_timestamp_gt(); - } else if (_reload_mode_tag == "md5sum") { - return check_md5sum(); - } else if (_reload_mode_tag == "revision") { - return check_revision(); - } else if (_reload_mode_tag == "none") { - return false; - } else { - LOG(ERROR) << "Not support check type: " - << _reload_mode_tag; - return false; - } + EngineCore* get_core() { + ModelData* md = + (ModelData*)THREAD_GETSPECIFIC(_skey); + if (!md) { + LOG(ERROR) << "Failed get thread specific data"; + return NULL; } + return md->cores[md->current_idx]; + } - bool check_timestamp_ne() { - struct stat st; - if (stat(_reload_tag_file.c_str(), &st) != 0) { - LOG(ERROR) << "Failed stat config file:" - << _reload_tag_file; - return false; - } + protected: + THREAD_KEY_T _skey; + THREAD_MUTEX_T _mutex; + std::vector*> _reload_vec; - if ((st.st_mode & S_IFREG) && - st.st_mtime != _last_status.last_timestamp) { - _last_status.last_timestamp = st.st_mtime; - return true; - } + private: +}; - return false; +// 多个EngineCore共用同一份模型数据 +template +class CloneDBReloadableInferEngine + : public DBReloadableInferEngine { + public: + virtual ~CloneDBReloadableInferEngine() {} + + virtual int proc_initialize(const configure::EngineDesc& conf, bool version) { + _pd = new (std::nothrow) ModelData; + if (!_pd) { + LOG(ERROR) << "Failed to allocate for ProcData"; + return -1; + } + return DBReloadableInferEngine::proc_initialize(conf, version); + } + + virtual int load(const std::string& model_data_dir) { + // 加载进程级模型数据 + if (!_pd || + DBReloadableInferEngine::load_data(_pd, model_data_dir) != + 0) { + LOG(ERROR) << "Failed to create common model from [" << model_data_dir + << "]."; + return -1; + } + LOG(WARNING) << "Succ load common model[" << _pd->cores[_pd->current_idx] + << "], path[" << model_data_dir << "]."; + + if (DBReloadableInferEngine::_reload_vec.empty()) { + return 0; + } + + for (uint32_t ti = 0; + ti < DBReloadableInferEngine::_reload_vec.size(); + ++ti) { + if (load_data(DBReloadableInferEngine::_reload_vec[ti], + _pd->cores[_pd->current_idx]) != 0) { + LOG(ERROR) << "Failed reload engine model: " << ti; + return -1; + } } - bool check_timestamp_gt() { - struct stat st; - if (stat(_reload_tag_file.c_str(), &st) != 0) { - LOG(ERROR) << "Failed stat config file:" - << _reload_tag_file; - return false; - } + LOG(WARNING) << "Succ load clone model, path[" << model_data_dir << "]"; - if ((st.st_mode & S_IFREG) && - st.st_mtime > _last_status.last_timestamp) { - _last_status.last_timestamp = st.st_mtime; - return true; - } + return 0; + } - return false; + // 加载线程级对象,多个线程级对象共用pd_core的模型数据 + int load_data(ModelData* td, EngineCore* pd_core) { + uint32_t next_idx = (td->current_idx + 1) % 2; + if (td->cores[next_idx]) { + delete td->cores[next_idx]; } - bool check_md5sum() { - return false; + td->cores[next_idx] = new (std::nothrow) EngineCore; + if (!td->cores[next_idx] || + td->cores[next_idx]->clone(pd_core->get()) != 0) { + LOG(ERROR) << "Failed clone model from pd_core[ " << pd_core << "], idx[" + << next_idx << "]"; + return -1; } + td->current_idx = next_idx; + LOG(WARNING) << "td_core[" << td->cores[td->current_idx] + << "] clone model from pd_core[" << pd_core + << "] succ, cur_idx[" << td->current_idx << "]."; + return 0; + } - bool check_revision() { - return false; + virtual int thrd_initialize_impl() { + // memory pool to be inited in non-serving-threads + if (MempoolWrapper::instance().thread_initialize() != 0) { + LOG(ERROR) << "Failed thread initialize mempool"; + return -1; } -protected: - std::string _model_data_path; + ModelData* md = new (std::nothrow) ModelData; + if (!md || load_data(md, _pd->cores[_pd->current_idx]) != 0) { + LOG(ERROR) << "Failed clone thread data, origin_core[" + << _pd->cores[_pd->current_idx] << "]."; + return -1; + } + + THREAD_SETSPECIFIC(DBReloadableInferEngine::_skey, md); + im::bsf::AutoMutex lock(DBReloadableInferEngine::_mutex); + DBReloadableInferEngine::_reload_vec.push_back(md); + return 0; + } -private: - std::string _reload_tag_file; - std::string _reload_mode_tag; - last_check_status _last_status; - uint32_t _infer_thread_num; - uint32_t _infer_batch_size; - bool _infer_batch_align; - uint64_t _version; + protected: + ModelData* + _pd; // 进程级EngineCore,多个线程级EngineCore共用该对象的模型数据 }; -template -struct ModelData { - ModelData() : current_idx(1) { - cores[0] = NULL; - cores[1] = NULL; - } +template +class FluidInferEngine : public DBReloadableInferEngine { + public: + FluidInferEngine() {} + ~FluidInferEngine() {} - ~ModelData() { - delete cores[0]; - delete cores[1]; + int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { + FluidFamilyCore* core = + DBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get fluid core in infer_impl()"; + return -1; } - EngineCore* cores[2]; - uint32_t current_idx; -}; + if (!core->Run(in, out)) { + LOG(ERROR) << "Failed run fluid family core"; + return -1; + } + return 0; + } -template -class DBReloadableInferEngine : public ReloadableInferEngine { -public: - virtual ~DBReloadableInferEngine() {} - - int proc_initialize(const configure::EngineDesc& conf, bool version) { - THREAD_KEY_CREATE(&_skey, NULL); - THREAD_MUTEX_INIT(&_mutex, NULL); - return ReloadableInferEngine::proc_initialize(conf, version); - } - - virtual int load(const std::string& model_data_dir) { - if (_reload_vec.empty()) { - return 0; - } - - for (uint32_t ti = 0; ti < _reload_vec.size(); ++ti) { - if (load_data(_reload_vec[ti], model_data_dir) != 0) { - LOG(ERROR) << "Failed reload engine model: " << ti; - return -1; - } - } - - LOG(WARNING) << "Succ load engine, path: " << model_data_dir; - - return 0; - } - - int load_data(ModelData* md, const std::string& data_path) { - uint32_t next_idx = (md->current_idx + 1) % 2; - if (md->cores[next_idx]) { - delete md->cores[next_idx]; - } - - md->cores[next_idx] = new (std::nothrow) EngineCore; - if (!md->cores[next_idx] - || md->cores[next_idx]->create(data_path) != 0) { - LOG(ERROR) << "Failed create model, path: " << data_path; - return -1; - } - md->current_idx = next_idx; - return 0; - } - - virtual int thrd_initialize_impl() { - // memory pool to be inited in non-serving-threads - if (MempoolWrapper::instance().thread_initialize() != 0) { - LOG(ERROR) << "Failed thread initialize mempool"; - return -1; - } - - ModelData* md = new(std::nothrow) ModelData; - if (!md || load_data(md, _model_data_path) != 0) { - LOG(ERROR) << "Failed create thread data from " << _model_data_path; - return -1; - } - - THREAD_SETSPECIFIC(_skey, md); - im::bsf::AutoMutex lock(_mutex); - _reload_vec.push_back(md); - return 0; - } - - int thrd_clear_impl() { - // for non-serving-threads - if (MempoolWrapper::instance().thread_clear() != 0) { - LOG(ERROR) << "Failed thread clear mempool"; - return -1; - } - return 0; - } - - int thrd_finalize_impl() { - return 0; - } - - int proc_finalize_impl() { - THREAD_KEY_DELETE(_skey); - THREAD_MUTEX_DESTROY(&_mutex); - return 0; - } - - EngineCore* get_core() { - ModelData* md = (ModelData*)THREAD_GETSPECIFIC(_skey); - if (!md) { - LOG(ERROR) << "Failed get thread specific data"; - return NULL; - } - return md->cores[md->current_idx]; - } - -protected: - THREAD_KEY_T _skey; - THREAD_MUTEX_T _mutex; - std::vector*> _reload_vec; -private: + int infer_impl2(const BatchTensor& in, BatchTensor& out) { // NOLINT + return infer_impl1(&in, &out); + } }; -// 多个EngineCore共用同一份模型数据 -template -class CloneDBReloadableInferEngine : public DBReloadableInferEngine { -public: - virtual ~CloneDBReloadableInferEngine() {} - - virtual int proc_initialize(const configure::EngineDesc& conf, bool version) { - _pd = new (std::nothrow) ModelData; - if (!_pd) { - LOG(ERROR) << "Failed to allocate for ProcData"; - return -1; - } - return DBReloadableInferEngine::proc_initialize( - conf, version); - } - - virtual int load(const std::string& model_data_dir) { - // 加载进程级模型数据 - if (!_pd || DBReloadableInferEngine::load_data( - _pd, model_data_dir) != 0) { - LOG(ERROR) - << "Failed to create common model from [" - << model_data_dir << "]."; - return -1; - } - LOG(WARNING) - << "Succ load common model[" << _pd->cores[_pd->current_idx] - << "], path[" << model_data_dir << "]."; - - if (DBReloadableInferEngine::_reload_vec.empty()) { - return 0; - } - - for (uint32_t ti = 0; ti < DBReloadableInferEngine::_reload_vec.size(); ++ti) { - if (load_data(DBReloadableInferEngine::_reload_vec[ti], - _pd->cores[_pd->current_idx]) != 0) { - LOG(ERROR) << "Failed reload engine model: " << ti; - return -1; - } - } - - LOG(WARNING) << "Succ load clone model, path[" << model_data_dir << "]"; - - return 0; - } - - // 加载线程级对象,多个线程级对象共用pd_core的模型数据 - int load_data( - ModelData* td, - EngineCore* pd_core) { - uint32_t next_idx = (td->current_idx + 1) % 2; - if (td->cores[next_idx]) { - delete td->cores[next_idx]; - } - - td->cores[next_idx] = new (std::nothrow) EngineCore; - if (!td->cores[next_idx] - || td->cores[next_idx]->clone(pd_core->get()) != 0) { - LOG(ERROR) << "Failed clone model from pd_core[ " << pd_core - << "], idx[" << next_idx << "]"; - return -1; - } - td->current_idx = next_idx; - LOG(WARNING) - << "td_core[" << td->cores[td->current_idx] - << "] clone model from pd_core[" - << pd_core << "] succ, cur_idx[" << td->current_idx << "]."; - return 0; - } - - virtual int thrd_initialize_impl() { - // memory pool to be inited in non-serving-threads - if (MempoolWrapper::instance().thread_initialize() != 0) { - LOG(ERROR) << "Failed thread initialize mempool"; - return -1; - } - - ModelData* md = new(std::nothrow) ModelData; - if (!md || load_data(md, _pd->cores[_pd->current_idx]) != 0) { - LOG(ERROR) << "Failed clone thread data, origin_core[" - << _pd->cores[_pd->current_idx] << "]."; - return -1; - } - - THREAD_SETSPECIFIC(DBReloadableInferEngine::_skey, md); - im::bsf::AutoMutex lock(DBReloadableInferEngine::_mutex); - DBReloadableInferEngine::_reload_vec.push_back(md); - return 0; - } - -protected: - ModelData* _pd; // 进程级EngineCore,多个线程级EngineCore共用该对象的模型数据 -}; +template +class TensorrtInferEngine : public DBReloadableInferEngine { + public: + TensorrtInferEngine() {} + ~TensorrtInferEngine() {} -template -class FluidInferEngine : public DBReloadableInferEngine { -public: - FluidInferEngine() {} - ~FluidInferEngine() {} - - int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { - FluidFamilyCore* core - = DBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get fluid core in infer_impl()"; - return -1; - } - - if (!core->Run(in, out)) { - LOG(ERROR) << "Failed run fluid family core"; - return -1; - } - return 0; - } - - int infer_impl2(const BatchTensor& in, BatchTensor& out) { - return infer_impl1(&in, &out); + int infer_impl1(const void* in, void* out, uint32_t batch_size) { + TensorrtFamilyCore* core = + DBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get fluid core in infer_impl()"; + return -1; } -}; -template -class TensorrtInferEngine : public DBReloadableInferEngine { -public: - TensorrtInferEngine() {} - ~TensorrtInferEngine() {} - - int infer_impl1(const void* in, void* out, uint32_t batch_size) { - TensorrtFamilyCore* core - = DBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get fluid core in infer_impl()"; - return -1; - } - - if (!core->Run(in, out, batch_size)) { - LOG(ERROR) << "Failed run fluid family core"; - return -1; - } - return 0; - } - - int infer_impl2(const BatchTensor& in, BatchTensor& out) { - LOG(ERROR) << "Tensortrt donot supports infer_impl2 yet!"; - return -1; + if (!core->Run(in, out, batch_size)) { + LOG(ERROR) << "Failed run fluid family core"; + return -1; } + return 0; + } + + int infer_impl2(const BatchTensor& in, BatchTensor& out) { // NOLINT + LOG(ERROR) << "Tensortrt donot supports infer_impl2 yet!"; + return -1; + } }; -template -class AbacusInferEngine : public CloneDBReloadableInferEngine { -public: - AbacusInferEngine() {} - ~AbacusInferEngine() {} +template +class AbacusInferEngine + : public CloneDBReloadableInferEngine { + public: + AbacusInferEngine() {} + ~AbacusInferEngine() {} + + int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { + LOG(ERROR) << "Abacus dnn engine must use predict interface"; + return -1; + } + + int infer_impl2(const BatchTensor& in, BatchTensor& out) { // NOLINT + LOG(ERROR) << "Abacus dnn engine must use predict interface"; + return -1; + } + + // Abacus special interface + int predict(uint32_t ins_num) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in predict()"; + return -1; + } + + return core->predict(ins_num); + } + int set_use_fpga(bool use_fpga) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in predict()"; + return -1; + } + + return core->set_use_fpga(use_fpga); + } + int debug() { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in debug()"; + return -1; + } + return core->debug(); + } + + int set_search_id(uint64_t sid) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in set_serach_id()"; + return -1; + } + return core->set_search_id(sid); + } + + int set_hidden_layer_dim(uint32_t dim) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in set_layer_dim()"; + return -1; + } + return core->set_hidden_layer_dim(dim); + } + + int get_input(uint32_t ins_idx, uint32_t* fea_num, void* in) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in get_input()"; + return -1; + } + return core->get_input(ins_idx, fea_num, in); + } + + int get_layer_value(const std::string& name, + uint32_t ins_num, + uint32_t fea_dim, + void* out) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in get_layer_value()"; + return -1; + } + return core->get_layer_value(name, ins_num, fea_dim, out); + } + + void set_position_idx(void* input, uint64_t fea, uint32_t ins_idx) { + AbacusFamilyCore* core = + CloneDBReloadableInferEngine::get_core(); + if (!core || !core->get()) { + LOG(ERROR) << "Failed get abacus core in set_position_idx()"; + return; + } + core->set_position_idx(input, fea, ins_idx); + return; + } +}; + +template +class PaddleV2InferEngine + : public CloneDBReloadableInferEngine { + public: + PaddleV2InferEngine() {} + ~PaddleV2InferEngine() {} + + int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { + LOG(ERROR) << "Paddle V2 engine must use predict interface"; + return -1; + } + + int infer_impl2(const BatchTensor& in, BatchTensor& out) { // NOLINT + LOG(ERROR) << "Paddle V2 engine must use predict interface"; + return -1; + } +}; - int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { - LOG(ERROR) << "Abacus dnn engine must use predict interface"; +typedef FactoryPool StaticInferFactory; + +class VersionedInferEngine : public InferEngine { + public: + VersionedInferEngine() { _versions.clear(); } + ~VersionedInferEngine() {} + + int proc_initialize(const configure::EngineDesc& conf) { + if (proc_initialize(conf, false) != 0) { + LOG(ERROR) << "Failed proc intialize engine: " << conf.name().c_str(); + return -1; + } + + LOG(WARNING) << "Succ proc initialize engine: " << conf.name().c_str(); + return 0; + } + + int proc_initialize(const configure::EngineDesc& conf, bool version) { + std::string engine_type = conf.type(); + InferEngine* engine = + StaticInferFactory::instance().generate_object(engine_type); + if (!engine) { + LOG(ERROR) << "Failed generate engine with type:" << engine_type; + return -1; + } + + if (engine->proc_initialize(conf, version) != 0) { + LOG(ERROR) << "Failed initialize engine, type:" << engine_type; + return -1; + } + + auto r = _versions.insert(std::make_pair(engine->version(), engine)); + if (!r.second) { + LOG(ERROR) << "Failed insert item: " << engine->version() + << ", type: " << engine_type; + return -1; + } + LOG(WARNING) << "Succ proc initialize version engine: " + << engine->version(); + return 0; + } + + int proc_finalize() { + for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { + if (iter->second->proc_finalize() != 0) { + LOG(ERROR) << "Failed proc finalize version engine: " << iter->first; + } + LOG(WARNING) << "Succ proc finalize version engine: " << iter->first; + } + return 0; + } + + int thrd_initialize() { + for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { + if (iter->second->thrd_initialize() != 0) { + LOG(ERROR) << "Failed thrd initialize version engine: " << iter->first; return -1; + } + LOG(WARNING) << "Succ thrd initialize version engine: " << iter->first; } + return 0; + } - int infer_impl2(const BatchTensor& in, BatchTensor& out) { - LOG(ERROR) << "Abacus dnn engine must use predict interface"; + int thrd_clear() { + for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { + if (iter->second->thrd_clear() != 0) { + LOG(ERROR) << "Failed thrd clear version engine: " << iter->first; return -1; + } + LOG(INFO) << "Succ thrd clear version engine: " << iter->first; } + return 0; + } - // Abacus special interface - int predict(uint32_t ins_num) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in predict()"; - return -1; - } - - return core->predict(ins_num); - } - int set_use_fpga(bool use_fpga) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in predict()"; - return -1; - } - - return core->set_use_fpga(use_fpga); - } - int debug() { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in debug()"; - return -1; - } - return core->debug(); - } - - int set_search_id(uint64_t sid) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in set_serach_id()"; - return -1; - } - return core->set_search_id(sid); - } - - int set_hidden_layer_dim(uint32_t dim) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in set_layer_dim()"; - return -1; - } - return core->set_hidden_layer_dim(dim); - } - - int get_input( - uint32_t ins_idx, uint32_t* fea_num, void* in) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in get_input()"; - return -1; - } - return core->get_input(ins_idx, fea_num, in); - } - - int get_layer_value(const std::string& name, - uint32_t ins_num, uint32_t fea_dim, void* out) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in get_layer_value()"; - return -1; - } - return core->get_layer_value(name, ins_num, fea_dim, out); - } - - void set_position_idx(void* input, uint64_t fea, uint32_t ins_idx) { - AbacusFamilyCore* core - = CloneDBReloadableInferEngine::get_core(); - if (!core || !core->get()) { - LOG(ERROR) << "Failed get abacus core in set_position_idx()"; - return; - } - core->set_position_idx(input, fea, ins_idx); - return; + int thrd_finalize() { + for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { + if (iter->second->thrd_finalize() != 0) { + LOG(ERROR) << "Failed thrd finalize version engine: " << iter->first; + return -1; + } + LOG(WARNING) << "Succ thrd finalize version engine: " << iter->first; } + return 0; + } + + int reload() { + for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { + if (iter->second->reload() != 0) { + LOG(ERROR) << "Failed reload version engine: " << iter->first; + return -1; + } + LOG(WARNING) << "Succ reload version engine: " << iter->first; + } + return 0; + } + + uint64_t version() const { + InferEngine* engine = default_engine(); + if (engine) { + return engine->version(); + } else { + return uint64_t(-1); + } + } + + // inference interface + InferEngine* default_engine() const { + if (_versions.size() != 1) { + LOG(ERROR) << "Ambiguous default engine version:" << _versions.size(); + return NULL; + } + + return _versions.begin()->second; + } + + int infer(const void* in, void* out, uint32_t batch_size) { + InferEngine* engine = default_engine(); + if (!engine) { + LOG(WARNING) << "fail to get default engine"; + return -1; + } + return engine->infer(in, out, batch_size); + } + + template + T* get_core() { + InferEngine* engine = default_engine(); + if (!engine) { + LOG(WARNING) << "fail to get core"; + return NULL; + } + auto db_engine = dynamic_cast*>(engine); + if (db_engine) { + return db_engine->get_core(); + } + LOG(WARNING) << "fail to get core"; + return NULL; + } + + // versioned inference interface + int infer(const void* in, void* out, uint32_t batch_size, uint64_t version) { + auto iter = _versions.find(version); + if (iter == _versions.end()) { + LOG(ERROR) << "Not found version engine: " << version; + return -1; + } + + return iter->second->infer(in, out, batch_size); + } + + template + T* get_core(uint64_t version) { + auto iter = _versions.find(version); + if (iter == _versions.end()) { + LOG(ERROR) << "Not found version engine: " << version; + return NULL; + } + + auto db_engine = dynamic_cast*>(iter->second); + if (db_engine) { + return db_engine->get_core(); + } + LOG(WARNING) << "fail to get core for " << version; + return NULL; + } + + // -- + int proc_initialize_impl(const configure::EngineDesc& conf, bool) { + return -1; + } + int thrd_initialize_impl() { return -1; } + int thrd_finalize_impl() { return -1; } + int thrd_clear_impl() { return -1; } + int proc_finalize_impl() { return -1; } + int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { + return -1; + } + int infer_impl2(const BatchTensor& in, BatchTensor& out) { // NOLINT + return -1; + } // NOLINT + + private: + boost::unordered_map _versions; }; -template -class PaddleV2InferEngine : public CloneDBReloadableInferEngine { -public: - PaddleV2InferEngine() {} - ~PaddleV2InferEngine() {} - - int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { - LOG(ERROR) << "Paddle V2 engine must use predict interface"; +class InferManager { + public: + static InferManager& instance() { + static InferManager ins; + return ins; + } + + int proc_initialize(const char* path, const char* file) { + ModelToolkitConf model_toolkit_conf; + if (configure::read_proto_conf(path, file, &model_toolkit_conf) != 0) { + LOG(ERROR) << "failed load infer config, path: " << path << "/" << file; + return -1; + } + + size_t engine_num = model_toolkit_conf.engines_size(); + for (size_t ei = 0; ei < engine_num; ++ei) { + std::string engine_name = model_toolkit_conf.engines(ei).name(); + VersionedInferEngine* engine = new (std::nothrow) VersionedInferEngine(); + if (!engine) { + LOG(ERROR) << "Failed generate versioned engine: " << engine_name; + return -1; + } + + if (engine->proc_initialize(model_toolkit_conf.engines(ei)) != 0) { + LOG(ERROR) << "Failed initialize version engine, name:" << engine_name; return -1; + } + + auto r = _map.insert(std::make_pair(engine_name, engine)); + if (!r.second) { + LOG(ERROR) << "Failed insert item: " << engine_name; + return -1; + } + LOG(WARNING) << "Succ proc initialize engine: " << engine_name; } - int infer_impl2(const BatchTensor& in, BatchTensor& out) { - LOG(ERROR) << "Paddle V2 engine must use predict interface"; + return 0; + } + + int thrd_initialize() { + for (auto it = _map.begin(); it != _map.end(); ++it) { + if (it->second->thrd_initialize() != 0) { + LOG(ERROR) << "Failed thrd initialize engine, name: " << it->first; return -1; + } + LOG(WARNING) << "Succ thrd initialize engine, name: " << it->first; } -}; + return 0; + } -typedef FactoryPool StaticInferFactory; + int thrd_clear() { + for (auto it = _map.begin(); it != _map.end(); ++it) { + if (it->second->thrd_clear() != 0) { + LOG(ERROR) << "Failed thrd clear engine, name: " << it->first; + return -1; + } + } + return 0; + } -class VersionedInferEngine : public InferEngine { -public: - VersionedInferEngine() { - _versions.clear(); - } - ~VersionedInferEngine() {} - - int proc_initialize(const configure::EngineDesc& conf) { - if (proc_initialize(conf, false) != 0) { - LOG(ERROR) << "Failed proc intialize engine: " - << conf.name().c_str(); - return -1; - } - - LOG(WARNING) - << "Succ proc initialize engine: " << conf.name().c_str(); - return 0; - } - - int proc_initialize(const configure::EngineDesc& conf, bool version) { - std::string engine_type = conf.type(); - InferEngine* engine - = StaticInferFactory::instance().generate_object( - engine_type); - if (!engine) { - LOG(ERROR) << "Failed generate engine with type:" - << engine_type; - return -1; - } - - if (engine->proc_initialize(conf, version) != 0) { - LOG(ERROR) << "Failed initialize engine, type:" - << engine_type; - return -1; - } - - auto r = _versions.insert(std::make_pair(engine->version(), engine)); - if (!r.second) { - LOG(ERROR) << "Failed insert item: " << engine->version() - << ", type: " << engine_type; - return -1; - } - LOG(WARNING) - << "Succ proc initialize version engine: " << engine->version(); - return 0; - } - - int proc_finalize() { - for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { - if (iter->second->proc_finalize() != 0) { - LOG(ERROR) << "Failed proc finalize version engine: " << - iter->first; - } - LOG(WARNING) - << "Succ proc finalize version engine: " << iter->first; - } - return 0; - } - - int thrd_initialize() { - for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { - if (iter->second->thrd_initialize() != 0) { - LOG(ERROR) << "Failed thrd initialize version engine: " << - iter->first; - return -1; - } - LOG(WARNING) - << "Succ thrd initialize version engine: " << iter->first; - } - return 0; - } - - int thrd_clear() { - for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { - if (iter->second->thrd_clear() != 0) { - LOG(ERROR) << "Failed thrd clear version engine: " << - iter->first; - return -1; - } - LOG(INFO) << "Succ thrd clear version engine: " << iter->first; - } - return 0; - } - - int thrd_finalize() { - for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { - if (iter->second->thrd_finalize() != 0) { - LOG(ERROR) << "Failed thrd finalize version engine: " << - iter->first; - return -1; - } - LOG(WARNING) << "Succ thrd finalize version engine: " << iter->first; - } - return 0; - } - - int reload() { - for (auto iter = _versions.begin(); iter != _versions.end(); ++iter) { - if (iter->second->reload() != 0) { - LOG(ERROR) << "Failed reload version engine: " << - iter->first; - return -1; - } - LOG(WARNING) << "Succ reload version engine: " << iter->first; - } - return 0; - } - - uint64_t version() const { - InferEngine* engine = default_engine(); - if (engine) { - return engine->version(); - } else { - return uint64_t(-1); - } - } - - // inference interface - InferEngine* default_engine() const { - if (_versions.size() != 1) { - LOG(ERROR) << "Ambiguous default engine version:" - << _versions.size(); - return NULL; - } - - return _versions.begin()->second; - } - - int infer(const void* in, void* out, uint32_t batch_size) { - InferEngine* engine = default_engine(); - if (!engine) { - LOG(WARNING) << "fail to get default engine"; - return -1; - } - return engine->infer(in, out, batch_size); - } - - template - T* get_core() { - InferEngine* engine = default_engine(); - if (!engine) { - LOG(WARNING) << "fail to get core"; - return NULL; - } - auto db_engine = dynamic_cast*>(engine); - if (db_engine) { - return db_engine->get_core(); - } - LOG(WARNING) << "fail to get core"; - return NULL; - } - - // versioned inference interface - int infer( - const void* in, void* out, uint32_t batch_size, uint64_t version) { - auto iter = _versions.find(version); - if (iter == _versions.end()) { - LOG(ERROR) << "Not found version engine: " << version; - return -1; - } - - return iter->second->infer(in, out, batch_size); - } - - template - T* get_core(uint64_t version) { - auto iter = _versions.find(version); - if (iter == _versions.end()) { - LOG(ERROR) << "Not found version engine: " << version; - return NULL; - } - - auto db_engine = dynamic_cast*>(iter->second); - if (db_engine) { - return db_engine->get_core(); - } - LOG(WARNING) << "fail to get core for " << version; - return NULL; - } - - // -- - int proc_initialize_impl(const configure::EngineDesc& conf, bool) { return -1; } - int thrd_initialize_impl() { return -1; } - int thrd_finalize_impl() { return -1; } - int thrd_clear_impl() { return -1; } - int proc_finalize_impl() { return -1; } - int infer_impl1(const void* in, void* out, uint32_t batch_size = -1) { return -1; } - int infer_impl2(const BatchTensor& in, BatchTensor& out) { return -1; } - -private: - boost::unordered_map _versions; -}; + int reload() { + for (auto it = _map.begin(); it != _map.end(); ++it) { + if (it->second->reload() != 0) { + LOG(ERROR) << "Failed reload engine, name: " << it->first; + return -1; + } + } + return 0; + } -class InferManager { -public: - static InferManager& instance() { - static InferManager ins; - return ins; - } - - int proc_initialize(const char* path, const char* file) { - ModelToolkitConf model_toolkit_conf; - if (configure::read_proto_conf(path, file, &model_toolkit_conf) != 0) { - LOG(ERROR) << "failed load infer config, path: " - << path << "/" << file; - return -1; - } - - size_t engine_num = model_toolkit_conf.engines_size(); - for (size_t ei = 0; ei < engine_num; ++ei) { - std::string engine_name = model_toolkit_conf.engines(ei).name(); - VersionedInferEngine* engine = new (std::nothrow) VersionedInferEngine(); - if (!engine) { - LOG(ERROR) << "Failed generate versioned engine: " << engine_name; - return -1; - } - - if (engine->proc_initialize(model_toolkit_conf.engines(ei)) != 0) { - LOG(ERROR) << "Failed initialize version engine, name:" - << engine_name; - return -1; - } - - auto r = _map.insert(std::make_pair(engine_name, engine)); - if (!r.second) { - LOG(ERROR) << "Failed insert item: " << engine_name; - return -1; - } - LOG(WARNING) << "Succ proc initialize engine: " << engine_name; - } - - return 0; - } - - int thrd_initialize() { - for (auto it = _map.begin(); it != _map.end(); ++it) { - if (it->second->thrd_initialize() != 0) { - LOG(ERROR) << "Failed thrd initialize engine, name: " - << it->first; - return -1; - } - LOG(WARNING) << "Succ thrd initialize engine, name: " - << it->first; - } - return 0; - } - - int thrd_clear() { - for (auto it = _map.begin(); it != _map.end(); ++it) { - if (it->second->thrd_clear() != 0) { - LOG(ERROR) << "Failed thrd clear engine, name: " - << it->first; - return -1; - } - } - return 0; - } - - int reload() { - for (auto it = _map.begin(); it != _map.end(); ++it) { - if (it->second->reload() != 0) { - LOG(ERROR) << "Failed reload engine, name: " - << it->first; - return -1; - } - } - return 0; - } - - int thrd_finalize() { - for (auto it = _map.begin(); it != _map.end(); ++it) { - if (it->second->thrd_finalize() != 0) { - LOG(ERROR) << "Failed thrd finalize engine, name: " - << it->first; - return -1; - } - LOG(WARNING) << "Succ thrd finalize engine, name: " - << it->first; - } - return 0; - } - - int proc_finalize() { - for (auto it = _map.begin(); it != _map.end(); ++it) { - if (it->second->proc_finalize() != 0) { - LOG(ERROR) << "Failed proc finalize engine, name: " - << it->first; - return -1; - } - LOG(WARNING) << "Succ proc finalize engine, name: " - << it->first; - } - return 0; - } - - // Inference interface - int infer(const char* model_name, const void* in, void* out, uint32_t batch_size = -1) { - auto it = _map.find(model_name); - if (it == _map.end()) { - LOG(WARNING) << "Cannot find engine in map, model name:" - << model_name; - return -1; - } - return it->second->infer(in, out, batch_size); - } - - template - T* get_core(const char* model_name) { - auto it = _map.find(model_name); - if (it == _map.end()) { - LOG(WARNING) << "Cannot find engine in map, model name:" - << model_name; - return NULL; - } - auto infer_engine = dynamic_cast*>( - it->second->default_engine()); - if (infer_engine) { - return infer_engine->get_core(); - } - LOG(WARNING) << "fail to get core for " << model_name; - return NULL; - } - - // Versioned inference interface - int infer(const char* model_name, const void* in, void* out, - uint32_t batch_size, uint64_t version) { - auto it = _map.find(model_name); - if (it == _map.end()) { - LOG(WARNING) << "Cannot find engine in map, model name:" - << model_name; - return -1; - } - return it->second->infer(in, out, batch_size, version); - } - - template - T* get_core(const char* model_name, uint64_t version) { - auto it = _map.find(model_name); - if (it == _map.end()) { - LOG(WARNING) << "Cannot find engine in map, model name:" - << model_name; - return NULL; - } - return it->second->get_core(version); - } - - int query_version(const std::string& model, uint64_t& version) { - auto it = _map.find(model); - if (it == _map.end()) { - LOG(WARNING) << "Cannot find engine in map, model name:" - << model; - return -1; - } - auto infer_engine = it->second->default_engine(); - if (!infer_engine) { - LOG(WARNING) << "Cannot get default engine for model:" - << model; - return -1; - } - version = infer_engine->version(); - LOG(INFO) << "Succ get version: " << version << " for model: " - << model; - return 0; - } - -private: - boost::unordered_map _map; -}; + int thrd_finalize() { + for (auto it = _map.begin(); it != _map.end(); ++it) { + if (it->second->thrd_finalize() != 0) { + LOG(ERROR) << "Failed thrd finalize engine, name: " << it->first; + return -1; + } + LOG(WARNING) << "Succ thrd finalize engine, name: " << it->first; + } + return 0; + } -} // predictor -} // paddle_serving -} // baidu + int proc_finalize() { + for (auto it = _map.begin(); it != _map.end(); ++it) { + if (it->second->proc_finalize() != 0) { + LOG(ERROR) << "Failed proc finalize engine, name: " << it->first; + return -1; + } + LOG(WARNING) << "Succ proc finalize engine, name: " << it->first; + } + return 0; + } + + // Inference interface + int infer(const char* model_name, + const void* in, + void* out, + uint32_t batch_size = -1) { + auto it = _map.find(model_name); + if (it == _map.end()) { + LOG(WARNING) << "Cannot find engine in map, model name:" << model_name; + return -1; + } + return it->second->infer(in, out, batch_size); + } + + template + T* get_core(const char* model_name) { + auto it = _map.find(model_name); + if (it == _map.end()) { + LOG(WARNING) << "Cannot find engine in map, model name:" << model_name; + return NULL; + } + auto infer_engine = + dynamic_cast*>(it->second->default_engine()); + if (infer_engine) { + return infer_engine->get_core(); + } + LOG(WARNING) << "fail to get core for " << model_name; + return NULL; + } + + // Versioned inference interface + int infer(const char* model_name, + const void* in, + void* out, + uint32_t batch_size, + uint64_t version) { + auto it = _map.find(model_name); + if (it == _map.end()) { + LOG(WARNING) << "Cannot find engine in map, model name:" << model_name; + return -1; + } + return it->second->infer(in, out, batch_size, version); + } + + template + T* get_core(const char* model_name, uint64_t version) { + auto it = _map.find(model_name); + if (it == _map.end()) { + LOG(WARNING) << "Cannot find engine in map, model name:" << model_name; + return NULL; + } + return it->second->get_core(version); + } + + int query_version(const std::string& model, uint64_t& version) { // NOLINT + auto it = _map.find(model); + if (it == _map.end()) { + LOG(WARNING) << "Cannot find engine in map, model name:" << model; + return -1; + } + auto infer_engine = it->second->default_engine(); + if (!infer_engine) { + LOG(WARNING) << "Cannot get default engine for model:" << model; + return -1; + } + version = infer_engine->version(); + LOG(INFO) << "Succ get version: " << version << " for model: " << model; + return 0; + } + + private: + boost::unordered_map _map; +}; -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_INFER_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/infer_data.h b/predictor/framework/infer_data.h index cd26982af72fd9cda896c36634275a691fce79e9..be8857c0abd39b5f057b524fa0b748ae78dba7d6 100644 --- a/predictor/framework/infer_data.h +++ b/predictor/framework/infer_data.h @@ -1,179 +1,165 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_INFER_DATA_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_INFER_DATA_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. + +#pragma once +#include +#include #include "common/inner_common.h" namespace baidu { namespace paddle_serving { namespace predictor { -enum DataType { - FLOAT32, - INT64 -}; +enum DataType { FLOAT32, INT64 }; class DataBuf { -public: - DataBuf() : _data(NULL), _size(0), _owned(true) {} + public: + DataBuf() : _data(NULL), _size(0), _owned(true) {} - DataBuf(size_t size) - : _data(new char[size]), _size(size), _owned(true) {} + explicit DataBuf(size_t size) + : _data(new char[size]), _size(size), _owned(true) {} - DataBuf(void* data, size_t size) - : _data(data), _size(size), _owned(false) {} + DataBuf(void* data, size_t size) : _data(data), _size(size), _owned(false) {} - DataBuf(void* data, size_t size, bool owned) - : _data(data), _size(size), _owned(owned) {} + DataBuf(void* data, size_t size, bool owned) + : _data(data), _size(size), _owned(owned) {} - void* data() const { - return _data; - } + void* data() const { return _data; } - size_t size() const { - return _size; - } + size_t size() const { return _size; } - void free() { - _size = 0; - if (_owned) { - delete[] (char*)_data; - } + void free() { + _size = 0; + if (_owned) { + delete[](reinterpret_cast(_data)); } + } - ~DataBuf() { - free(); - } + ~DataBuf() { free(); } -private: - void* _data; - size_t _size; - bool _owned; + private: + void* _data; + size_t _size; + bool _owned; }; struct Tensor { - Tensor() { - shape.clear(); - for (int li = 0; li < lod.size(); ++li) { - lod[li].clear(); - } - lod.clear(); + Tensor() { + shape.clear(); + for (int li = 0; li < lod.size(); ++li) { + lod[li].clear(); + } + lod.clear(); + } + + Tensor(const Tensor& tensor) { + name = tensor.name; + data = tensor.data; + type = tensor.type; + shape.assign(tensor.shape.begin(), tensor.shape.end()); + for (int li = 0; li < tensor.lod.size(); ++li) { + std::vector l; + l.assign(tensor.lod[li].begin(), tensor.lod[li].end()); + lod.push_back(l); + } + } + + ~Tensor() { shape.clear(); } + + size_t ele_byte() const { + if (type == INT64) { + return sizeof(int64_t); + } else { + return sizeof(float); } + } - Tensor(const Tensor& tensor) { - name = tensor.name; - data = tensor.data; - type = tensor.type; - shape.assign(tensor.shape.begin(), tensor.shape.end()); - for (int li = 0; li < tensor.lod.size(); ++li) { - std::vector l; - l.assign(tensor.lod[li].begin(), tensor.lod[li].end()); - lod.push_back(l); - } + bool valid() const { + if (shape.empty()) { + if (data.data() || data.size()) { + LOG(ERROR) << "data should be empty"; + return false; + } + return true; } - ~Tensor() { - shape.clear(); + if (!data.data() || !data.size()) { + LOG(ERROR) << "data cannot empty"; + return false; } - size_t ele_byte() const { - if (type == INT64) { - return sizeof(int64_t); - } else { - return sizeof(float); - } + size_t byte_size = 1; + for (size_t si = 0; si < shape.size(); ++si) { + byte_size *= shape[si]; } - bool valid() const { - if (shape.empty()) { - if (data.data() || data.size()) { - LOG(ERROR) << "data should be empty"; - return false; - } - return true; - } - - if (!data.data() || !data.size()) { - LOG(ERROR) << "data cannot empty"; - return false; - } - - size_t byte_size = 1; - for (size_t si = 0; si < shape.size(); ++si) { - byte_size *= shape[si]; - } - - if (byte_size * ele_byte() != data.size()) { - LOG(ERROR) << "wrong data size: " << byte_size * ele_byte() << " vs. " << data.size(); - return false; - } - - return true; + if (byte_size * ele_byte() != data.size()) { + LOG(ERROR) << "wrong data size: " << byte_size * ele_byte() << " vs. " + << data.size(); + return false; } - size_t shape0() { - if (shape.empty()) { - return 0; - } - return shape[0]; + return true; + } + + size_t shape0() { + if (shape.empty()) { + return 0; } + return shape[0]; + } - std::string name; - std::vector shape; - DataBuf data; - DataType type; - std::vector > lod; + std::string name; + std::vector shape; + DataBuf data; + DataType type; + std::vector> lod; }; class BatchTensor { -public: - BatchTensor() {} - ~BatchTensor() { - _features.clear(); - } + public: + BatchTensor() {} + ~BatchTensor() { _features.clear(); } - BatchTensor(const BatchTensor& tv) { - _features.assign( - tv.features().begin(), tv.features().end()); - } + BatchTensor(const BatchTensor& tv) { + _features.assign(tv.features().begin(), tv.features().end()); + } - Tensor& operator[](int index) { - return _features[index]; - } + Tensor& operator[](int index) { return _features[index]; } - const Tensor& operator[](int index) const { - return _features[index]; - } + const Tensor& operator[](int index) const { return _features[index]; } - void push_back(const Tensor& tensor) { - _features.push_back(tensor); - } + void push_back(const Tensor& tensor) { _features.push_back(tensor); } - size_t count() const { - return _features.size(); - } + size_t count() const { return _features.size(); } - size_t size() const { - // shape0 indicates batch_size - if (count() <= 0 || _features[0].shape.size() <= 0) { - return 0; - } - return _features[0].shape[0]; + size_t size() const { + // shape0 indicates batch_size + if (count() <= 0 || _features[0].shape.size() <= 0) { + return 0; } + return _features[0].shape[0]; + } - const std::vector& features() const { - return _features; - } + const std::vector& features() const { return _features; } - void clear() { - _features.clear(); - } + void clear() { _features.clear(); } -private: - std::vector _features; + private: + std::vector _features; }; -} // predictor -} // paddle_serving -} // baidu - -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_INFER_DATA_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/manager.h b/predictor/framework/manager.h index e280a01a45b44347bf057379329772e3545b269a..6e14fbdda2c5538dd3271e37430b11ccc4c321b9 100644 --- a/predictor/framework/manager.h +++ b/predictor/framework/manager.h @@ -1,10 +1,24 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_MANAGER_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_MANAGER_H - -#include "common/inner_common.h" -#include "framework/workflow.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. + +#pragma once +#include +#include #include "common/constant.h" +#include "common/inner_common.h" #include "framework/service.h" +#include "framework/workflow.h" namespace baidu { namespace paddle_serving { @@ -14,241 +28,218 @@ using configure::WorkflowConf; using configure::InferServiceConf; class Workflow; -//class InferService; -//class ParallelInferService; +// class InferService; +// class ParallelInferService; -template +template I* create_item_impl() { - return new (std::nothrow) I(); + return new (std::nothrow) I(); } -template<> +template <> inline InferService* create_item_impl() { - if (FLAGS_use_parallel_infer_service) { - return new (std::nothrow) ParallelInferService(); - } else { - return new (std::nothrow) InferService(); - } + if (FLAGS_use_parallel_infer_service) { + return new (std::nothrow) ParallelInferService(); + } else { + return new (std::nothrow) InferService(); + } } class WorkflowManager { -public: - static WorkflowManager& instance() { - static WorkflowManager mgr; - return mgr; + public: + static WorkflowManager& instance() { + static WorkflowManager mgr; + return mgr; + } + + int initialize(const std::string path, const std::string file) { + WorkflowConf workflow_conf; + if (configure::read_proto_conf(path, file, &workflow_conf) != 0) { + LOG(ERROR) << "Failed load manager<" << Workflow::tag() + << "> configure from " << path << "/" << file; + return -1; } - int initialize(const std::string path, const std::string file) { - WorkflowConf workflow_conf; - if (configure::read_proto_conf(path, file, &workflow_conf) != 0) { - LOG(ERROR) << "Failed load manager<" << Workflow::tag() << "> configure from " << path << "/" << file; - return -1; + try { + uint32_t item_size = workflow_conf.workflows_size(); + for (uint32_t ii = 0; ii < item_size; ii++) { + std::string name = workflow_conf.workflows(ii).name(); + Workflow* item = new (std::nothrow) Workflow(); + if (item == NULL) { + LOG(ERROR) << "Failed create " << Workflow::tag() << " for: " << name; + return -1; } - - try { - - uint32_t item_size = workflow_conf.workflows_size(); - for (uint32_t ii = 0; ii < item_size; ii++) { - std::string name = workflow_conf.workflows(ii).name(); - Workflow* item = new (std::nothrow) Workflow(); - if (item == NULL) { - LOG(ERROR) << "Failed create " << Workflow::tag() << " for: " << name; - return -1; - } - if (item->init(workflow_conf.workflows(ii)) != 0) { - LOG(ERROR) - << "Failed init item: " << name << " at:" - << ii << "!"; - return -1; - } - - std::pair< - typename boost::unordered_map::iterator, bool> - r = _item_map.insert(std::make_pair(name, item)); - if (!r.second) { - LOG(ERROR) - << "Failed insert item:" << name << " at:" - << ii << "!"; - return -1; - } - - LOG(INFO) - << "Succ init item:" << name << " from conf:" - << path << "/" << file << ", at:" << ii << "!"; - } - - } catch (...) { - LOG(ERROR) - << "Config[" << path << "/" << file << "] format " - << "invalid, load failed"; - return -1; + if (item->init(workflow_conf.workflows(ii)) != 0) { + LOG(ERROR) << "Failed init item: " << name << " at:" << ii << "!"; + return -1; } - return 0; - } - Workflow* create_item() { - return create_item_impl(); - } - - Workflow* item(const std::string& name) { - typename boost::unordered_map::iterator it; - it = _item_map.find(name); - if (it == _item_map.end()) { - LOG(WARNING) << "Not found item: " << name << "!"; - return NULL; + std::pair< + typename boost::unordered_map::iterator, + bool> + r = _item_map.insert(std::make_pair(name, item)); + if (!r.second) { + LOG(ERROR) << "Failed insert item:" << name << " at:" << ii << "!"; + return -1; } - return it->second; + LOG(INFO) << "Succ init item:" << name << " from conf:" << path << "/" + << file << ", at:" << ii << "!"; + } + } catch (...) { + LOG(ERROR) << "Config[" << path << "/" << file << "] format " + << "invalid, load failed"; + return -1; } + return 0; + } - Workflow& operator[](const std::string& name) { - Workflow* i = item(name); - if (i == NULL) { - std::string err = "Not found item in manager for:"; - err += name; - throw std::overflow_error(err); - } - return *i; + Workflow* create_item() { return create_item_impl(); } + + Workflow* item(const std::string& name) { + typename boost::unordered_map::iterator it; + it = _item_map.find(name); + if (it == _item_map.end()) { + LOG(WARNING) << "Not found item: " << name << "!"; + return NULL; } - int reload() { - int ret = 0; - typename boost::unordered_map::iterator it - = _item_map.begin(); - for (; it != _item_map.end(); ++it) { - if (it->second->reload() != 0) { - LOG(WARNING) << "failed reload item: " << it->first << "!"; - ret = -1; - } - } + return it->second; + } - LOG(INFO) << "Finish reload " - << _item_map.size() - << " " << Workflow::tag() << "(s)"; - return ret; + Workflow& operator[](const std::string& name) { + Workflow* i = item(name); + if (i == NULL) { + std::string err = "Not found item in manager for:"; + err += name; + throw std::overflow_error(err); } - - int finalize() { - return 0; + return *i; + } + + int reload() { + int ret = 0; + typename boost::unordered_map::iterator it = + _item_map.begin(); + for (; it != _item_map.end(); ++it) { + if (it->second->reload() != 0) { + LOG(WARNING) << "failed reload item: " << it->first << "!"; + ret = -1; + } } -private: - WorkflowManager() {} + LOG(INFO) << "Finish reload " << _item_map.size() << " " << Workflow::tag() + << "(s)"; + return ret; + } -private: - boost::unordered_map _item_map; + int finalize() { return 0; } + + private: + WorkflowManager() {} + + private: + boost::unordered_map _item_map; }; class InferServiceManager { -public: - static InferServiceManager& instance() { - static InferServiceManager mgr; - return mgr; + public: + static InferServiceManager& instance() { + static InferServiceManager mgr; + return mgr; + } + + int initialize(const std::string path, const std::string file) { + InferServiceConf infer_service_conf; + if (configure::read_proto_conf(path, file, &infer_service_conf) != 0) { + LOG(ERROR) << "Failed load manager<" << InferService::tag() + << "> configure!"; + return -1; } - int initialize(const std::string path, const std::string file) { - InferServiceConf infer_service_conf; - if (configure::read_proto_conf(path, file, &infer_service_conf) != 0) { - LOG(ERROR) << "Failed load manager<" << InferService::tag() << "> configure!"; - return -1; + try { + uint32_t item_size = infer_service_conf.services_size(); + for (uint32_t ii = 0; ii < item_size; ii++) { + std::string name = infer_service_conf.services(ii).name(); + InferService* item = new (std::nothrow) InferService(); + if (item == NULL) { + LOG(ERROR) << "Failed create " << InferService::tag() + << " for: " << name; + return -1; } - - try { - - uint32_t item_size = infer_service_conf.services_size(); - for (uint32_t ii = 0; ii < item_size; ii++) { - std::string name = infer_service_conf.services(ii).name(); - InferService* item = new (std::nothrow) InferService(); - if (item == NULL) { - LOG(ERROR) << "Failed create " << InferService::tag() << " for: " << name; - return -1; - } - if (item->init(infer_service_conf.services(ii)) != 0) { - LOG(ERROR) - << "Failed init item: " << name << " at:" - << ii << "!"; - return -1; - } - - std::pair< - typename boost::unordered_map::iterator, bool> - r = _item_map.insert(std::make_pair(name, item)); - if (!r.second) { - LOG(ERROR) - << "Failed insert item:" << name << " at:" - << ii << "!"; - return -1; - } - - LOG(INFO) - << "Succ init item:" << name << " from conf:" - << path << "/" << file << ", at:" << ii << "!"; - } - - } catch (...) { - LOG(ERROR) - << "Config[" << path << "/" << file << "] format " - << "invalid, load failed"; - return -1; + if (item->init(infer_service_conf.services(ii)) != 0) { + LOG(ERROR) << "Failed init item: " << name << " at:" << ii << "!"; + return -1; } - return 0; - } - InferService* create_item() { - return create_item_impl(); - } - - InferService* item(const std::string& name) { - typename boost::unordered_map::iterator it; - it = _item_map.find(name); - if (it == _item_map.end()) { - LOG(WARNING) << "Not found item: " << name << "!"; - return NULL; + std::pair< + typename boost::unordered_map::iterator, + bool> + r = _item_map.insert(std::make_pair(name, item)); + if (!r.second) { + LOG(ERROR) << "Failed insert item:" << name << " at:" << ii << "!"; + return -1; } - return it->second; + LOG(INFO) << "Succ init item:" << name << " from conf:" << path << "/" + << file << ", at:" << ii << "!"; + } + } catch (...) { + LOG(ERROR) << "Config[" << path << "/" << file << "] format " + << "invalid, load failed"; + return -1; } + return 0; + } - InferService& operator[](const std::string& name) { - InferService* i = item(name); - if (i == NULL) { - std::string err = "Not found item in manager for:"; - err += name; - throw std::overflow_error(err); - } - return *i; + InferService* create_item() { return create_item_impl(); } + + InferService* item(const std::string& name) { + typename boost::unordered_map::iterator it; + it = _item_map.find(name); + if (it == _item_map.end()) { + LOG(WARNING) << "Not found item: " << name << "!"; + return NULL; } - int reload() { - int ret = 0; - typename boost::unordered_map::iterator it - = _item_map.begin(); - for (; it != _item_map.end(); ++it) { - if (it->second->reload() != 0) { - LOG(WARNING) << "failed reload item: " << it->first << "!"; - ret = -1; - } - } + return it->second; + } - LOG(INFO) << "Finish reload " - << _item_map.size() - << " " << InferService::tag() << "(s)"; - return ret; + InferService& operator[](const std::string& name) { + InferService* i = item(name); + if (i == NULL) { + std::string err = "Not found item in manager for:"; + err += name; + throw std::overflow_error(err); } - - int finalize() { - return 0; + return *i; + } + + int reload() { + int ret = 0; + typename boost::unordered_map::iterator it = + _item_map.begin(); + for (; it != _item_map.end(); ++it) { + if (it->second->reload() != 0) { + LOG(WARNING) << "failed reload item: " << it->first << "!"; + ret = -1; + } } -private: - InferServiceManager() {} + LOG(INFO) << "Finish reload " << _item_map.size() << " " + << InferService::tag() << "(s)"; + return ret; + } -private: - boost::unordered_map _item_map; -}; + int finalize() { return 0; } + + private: + InferServiceManager() {} -} // predictor -} // paddle_serving -} // baidu + private: + boost::unordered_map _item_map; +}; -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/memory.cpp b/predictor/framework/memory.cpp index e30d3b5667fb19b9e54699ae29f023ecdf433afe..e0a69df269ac5b2bfe547d66745cf10b4e388fd4 100644 --- a/predictor/framework/memory.cpp +++ b/predictor/framework/memory.cpp @@ -1,63 +1,75 @@ -#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 "common/inner_common.h" namespace baidu { namespace paddle_serving { namespace predictor { int MempoolWrapper::initialize() { - if (THREAD_KEY_CREATE(&_bspec_key, NULL) != 0) { - LOG(ERROR) << "unable to create thread_key of thrd_data"; - return -1; - } - if (THREAD_SETSPECIFIC(_bspec_key, NULL) != 0) { - LOG(ERROR) << "failed initialize bsepecific key to null"; - return -1; - } - - return 0; + if (THREAD_KEY_CREATE(&_bspec_key, NULL) != 0) { + LOG(ERROR) << "unable to create thread_key of thrd_data"; + return -1; + } + if (THREAD_SETSPECIFIC(_bspec_key, NULL) != 0) { + LOG(ERROR) << "failed initialize bsepecific key to null"; + return -1; + } + + return 0; } int MempoolWrapper::thread_initialize() { - _region.init(); - im::Mempool* p_mempool = new (std::nothrow) im::Mempool(&_region); - if (p_mempool == NULL) { - LOG(ERROR) << "Failed create thread mempool"; - return -1; - } - - if (THREAD_SETSPECIFIC(_bspec_key, p_mempool) != 0) { - LOG(ERROR) << "unable to set the thrd_data"; - delete p_mempool; - return -1; - } - - LOG(WARNING) << "Succ thread initialize mempool wrapper"; - return 0; + _region.init(); + im::Mempool* p_mempool = new (std::nothrow) im::Mempool(&_region); + if (p_mempool == NULL) { + LOG(ERROR) << "Failed create thread mempool"; + return -1; + } + + if (THREAD_SETSPECIFIC(_bspec_key, p_mempool) != 0) { + LOG(ERROR) << "unable to set the thrd_data"; + delete p_mempool; + return -1; + } + + LOG(WARNING) << "Succ thread initialize mempool wrapper"; + return 0; } int MempoolWrapper::thread_clear() { - im::Mempool* p_mempool = (im::Mempool*) THREAD_GETSPECIFIC( - _bspec_key); - if (p_mempool) { - p_mempool->release_block(); - _region.reset(); - } - - return 0; + im::Mempool* p_mempool = (im::Mempool*)THREAD_GETSPECIFIC(_bspec_key); + if (p_mempool) { + p_mempool->release_block(); + _region.reset(); + } + + return 0; } void* MempoolWrapper::malloc(size_t size) { - im::Mempool* p_mempool = (im::Mempool*) THREAD_GETSPECIFIC( - _bspec_key); - if (!p_mempool) { - LOG(WARNING) << "Cannot malloc memory:" << size - << ", since mempool is not thread initialized"; - return NULL; - } - return p_mempool->malloc(size); + im::Mempool* p_mempool = (im::Mempool*)THREAD_GETSPECIFIC(_bspec_key); + if (!p_mempool) { + LOG(WARNING) << "Cannot malloc memory:" << size + << ", since mempool is not thread initialized"; + return NULL; + } + return p_mempool->malloc(size); } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/memory.h b/predictor/framework/memory.h index cc7e40b4ec708f9d69522f7d69dae354ac4243ba..e2afc6242a97e94486d619595a88f25127be7d31 100644 --- a/predictor/framework/memory.h +++ b/predictor/framework/memory.h @@ -1,5 +1,18 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_MEMORY_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_MEMORY_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. + +#pragma once #include "common/inner_common.h" #include "mempool/mempool.h" @@ -9,29 +22,27 @@ namespace paddle_serving { namespace predictor { class MempoolWrapper { -public: - MempoolWrapper() {} + public: + MempoolWrapper() {} - static MempoolWrapper& instance() { - static MempoolWrapper mempool; - return mempool; - } + static MempoolWrapper& instance() { + static MempoolWrapper mempool; + return mempool; + } - int initialize(); + int initialize(); - int thread_initialize(); + int thread_initialize(); - int thread_clear(); + int thread_clear(); - void* malloc(size_t size); + void* malloc(size_t size); -private: - im::fugue::memory::Region _region; - THREAD_KEY_T _bspec_key; + private: + im::fugue::memory::Region _region; + THREAD_KEY_T _bspec_key; }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/merger.h b/predictor/framework/merger.h index 76dc3e18b07cf2d68875707220590074433e4ba4..25568dc5b4abcf63576fbe2ed911c7770fab0e2d 100644 --- a/predictor/framework/merger.h +++ b/predictor/framework/merger.h @@ -1,5 +1,20 @@ -#pragma once +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once +#include +#include #include "common/inner_common.h" namespace baidu { @@ -7,89 +22,86 @@ namespace paddle_serving { namespace predictor { class IMerger { -public: - virtual bool merge(const google::protobuf::Message*, google::protobuf::Message*) = 0; + public: + virtual bool merge(const google::protobuf::Message*, + google::protobuf::Message*) = 0; }; class DefaultMerger : public IMerger { -public: - bool merge( - const google::protobuf::Message* s, google::protobuf::Message* d) { - if (!s || !d) { - return false; - } - - d->MergeFrom(*s); - return true; + public: + bool merge(const google::protobuf::Message* s, google::protobuf::Message* d) { + if (!s || !d) { + return false; } + + d->MergeFrom(*s); + return true; + } }; -template +template class Singleton { -public: - static T* instance() { - static T ins; - return &ins; - } + public: + static T* instance() { + static T ins; + return &ins; + } }; class MergerManager { -public: - typedef IMerger MergerT; + public: + typedef IMerger MergerT; - static MergerManager& instance() { - static MergerManager ins; - return ins; - } + static MergerManager& instance() { + static MergerManager ins; + return ins; + } - bool set(std::string name, MergerT* merger) { - if (_mergers.find(name) != _mergers.end()) { - LOG(ERROR) << "Duplicated merger: " << name; - return false; - } - _mergers[name] = merger; - return true; + bool set(std::string name, MergerT* merger) { + if (_mergers.find(name) != _mergers.end()) { + LOG(ERROR) << "Duplicated merger: " << name; + return false; } + _mergers[name] = merger; + return true; + } - bool get(const std::string& name, MergerT*& merger) { - std::map::iterator iter = - _mergers.find(name); - if (iter == _mergers.end()) { - return false; - } - merger = iter->second; - return true; + bool get(const std::string& name, MergerT*& merger) { // NOLINT + std::map::iterator iter = _mergers.find(name); + if (iter == _mergers.end()) { + return false; } + merger = iter->second; + return true; + } -private: - MergerManager() { - set("default", Singleton::instance()); - } - -private: - std::map _mergers; + private: + MergerManager() { set("default", Singleton::instance()); } + + private: + std::map _mergers; }; -#define DECLARE_MERGER(M) \ - static bool regist_self() {\ - if (!baidu::paddle_serving::predictor::MergerManager::instance().set(\ - #M, baidu::paddle_serving::predictor::Singleton::instance())) {\ - LOG(ERROR) << "Failed regist merger: " << #M;\ - return false;\ - }\ - LOG(INFO) << "Succ regist merger: " << #M;\ - return true;\ - } +#define DECLARE_MERGER(M) \ + static bool regist_self() { \ + if (!baidu::paddle_serving::predictor::MergerManager::instance().set( \ + #M, baidu::paddle_serving::predictor::Singleton::instance())) { \ + LOG(ERROR) << "Failed regist merger: " << #M; \ + return false; \ + } \ + LOG(INFO) << "Succ regist merger: " << #M; \ + return true; \ + } #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_MERGER(M)\ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void)\ -{\ - M::regist_self();\ -} +#define DEFINE_MERGER(M) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + M::regist_self(); \ + } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/op_repository.cpp b/predictor/framework/op_repository.cpp index 2bceff15f492048ce629fabfccac5c0c50a6049b..8a430e64bd72f29c4d5132dbe238df19f35d0408 100644 --- a/predictor/framework/op_repository.cpp +++ b/predictor/framework/op_repository.cpp @@ -1,4 +1,19 @@ +// 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/op_repository.h" +#include #include "op/op.h" namespace baidu { @@ -6,44 +21,44 @@ namespace paddle_serving { namespace predictor { Op* OpRepository::get_op(std::string op_type) { - ManagerMap::iterator iter = _repository.find(op_type); - Op* op = NULL; - if (iter != _repository.end()) { - op = (iter->second)->get_op(); - } else { - LOG(ERROR) << "Try to create unknown op[" << op_type << "]"; - } - return op; + ManagerMap::iterator iter = _repository.find(op_type); + Op* op = NULL; + if (iter != _repository.end()) { + op = (iter->second)->get_op(); + } else { + LOG(ERROR) << "Try to create unknown op[" << op_type << "]"; + } + return op; } void OpRepository::return_op(Op* op) { - if (op == NULL) { - LOG(ERROR) << "Try to return NULL op"; - return; - } - ManagerMap::iterator iter = _repository.find(op->type()); - if (iter != _repository.end()) { - iter->second->return_op(op); - } else { - LOG(ERROR) << "Try to return unknown op[" << op << "], op_type[" - << op->type() << "]."; - } + if (op == NULL) { + LOG(ERROR) << "Try to return NULL op"; + return; + } + ManagerMap::iterator iter = _repository.find(op->type()); + if (iter != _repository.end()) { + iter->second->return_op(op); + } else { + LOG(ERROR) << "Try to return unknown op[" << op << "], op_type[" + << op->type() << "]."; + } } void OpRepository::return_op(const std::string& op_type, Op* op) { - if (op == NULL) { - LOG(ERROR) << "Try to return NULL op"; - return; - } - ManagerMap::iterator iter = _repository.find(op_type); - if (iter != _repository.end()) { - iter->second->return_op(op); - } else { - LOG(ERROR) << "Try to return unknown op[" << op << "], op_type[" - << op_type << "]."; - } + if (op == NULL) { + LOG(ERROR) << "Try to return NULL op"; + return; + } + ManagerMap::iterator iter = _repository.find(op_type); + if (iter != _repository.end()) { + iter->second->return_op(op); + } else { + LOG(ERROR) << "Try to return unknown op[" << op << "], op_type[" << op_type + << "]."; + } } -} // namespace predictor -} // namespace paddle_serving -} // namespace baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/op_repository.h b/predictor/framework/op_repository.h index 4ecf2806c803fe7f9dbcc7f1882b81a64ba9eaf2..4f789e48d48708ce844f449a9914a216d703ae21 100644 --- a/predictor/framework/op_repository.h +++ b/predictor/framework/op_repository.h @@ -1,70 +1,80 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_OP_REPOSITORY_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_OP_REPOSITORY_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. + +#pragma once +#include #include "common/inner_common.h" namespace baidu { namespace paddle_serving { namespace predictor { -#define REGISTER_OP(op) \ - ::baidu::paddle_serving::predictor::OpRepository::instance().regist_op(#op) +#define REGISTER_OP(op) \ + ::baidu::paddle_serving::predictor::OpRepository::instance().regist_op( \ + #op) class Op; class Factory { -public: - virtual Op* get_op() = 0; - virtual void return_op(Op* op) = 0; + public: + virtual Op* get_op() = 0; + virtual void return_op(Op* op) = 0; }; -template +template class OpFactory : public Factory { -public: - Op* get_op() { - return butil::get_object(); - } - - void return_op(Op* op) { - butil::return_object(dynamic_cast(op)); - } - - static OpFactory& instance() { - static OpFactory ins; - return ins; - } + public: + Op* get_op() { return butil::get_object(); } + + void return_op(Op* op) { + butil::return_object(dynamic_cast(op)); + } + + static OpFactory& instance() { + static OpFactory ins; + return ins; + } }; class OpRepository { -public: - typedef boost::unordered_map ManagerMap; + public: + typedef boost::unordered_map ManagerMap; - OpRepository() {} - ~OpRepository() {} + OpRepository() {} + ~OpRepository() {} - static OpRepository& instance() { - static OpRepository repo; - return repo; - } + static OpRepository& instance() { + static OpRepository repo; + return repo; + } - template - void regist_op(std::string op_type) { - _repository[op_type] = &OpFactory::instance(); - LOG(INFO) << "Succ regist op: " << op_type << "!"; - } + template + void regist_op(std::string op_type) { + _repository[op_type] = &OpFactory::instance(); + LOG(INFO) << "Succ regist op: " << op_type << "!"; + } - Op* get_op(std::string op_type); + Op* get_op(std::string op_type); - void return_op(Op* op); + void return_op(Op* op); - void return_op(const std::string& op_type, Op* op); + void return_op(const std::string& op_type, Op* op); -private: - ManagerMap _repository; + private: + ManagerMap _repository; }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/predictor_metric.cpp b/predictor/framework/predictor_metric.cpp index 3597e4597e6eaa34ef088da6986bffa1e83baa0e..d9fa271cee25953ddfe7c588056c541033019131 100644 --- a/predictor/framework/predictor_metric.cpp +++ b/predictor/framework/predictor_metric.cpp @@ -1,4 +1,18 @@ -#include "predictor_metric.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 "predictor/framework/predictor_metric.h" #include "butil/memory/singleton.h" namespace baidu { @@ -6,9 +20,9 @@ namespace paddle_serving { namespace predictor { PredictorMetric* PredictorMetric::GetInstance() { - return Singleton::get(); + return Singleton::get(); } -} // namespace predictor -} // namespace paddle_serving -} // namespace baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/predictor_metric.h b/predictor/framework/predictor_metric.h index ca684504e92e35d91a9cb2a9d539a52bccd11c30..201cf64ee0349331dd432150ca3530aacc8a8cd0 100644 --- a/predictor/framework/predictor_metric.h +++ b/predictor/framework/predictor_metric.h @@ -1,290 +1,304 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_FRAMEWORK_PREDICTOR_METRIC_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_FRAMEWORK_PREDICTOR_METRIC_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 // bvar -#include // BAIDU_SCOPED_LOCK -#include // FlatMap -#include // DefaultSingletonTraits +#pragma once +#include // FlatMap +#include // DefaultSingletonTraits +#include // BAIDU_SCOPED_LOCK +#include // bvar +#include namespace baidu { namespace paddle_serving { namespace predictor { -static const std::string WORKFLOW_METRIC_PREFIX = "workflow_"; -static const std::string STAGE_METRIC_PREFIX = "stage_"; -static const std::string OP_METRIC_PREFIX = "op_"; -static const std::string NAME_DELIMITER = "_"; +static const char* WORKFLOW_METRIC_PREFIX = "workflow_"; +static const char* STAGE_METRIC_PREFIX = "stage_"; +static const char* OP_METRIC_PREFIX = "op_"; +static const char* NAME_DELIMITER = "_"; -typedef ::bvar::Window<::bvar::Adder > AdderWindow; +typedef ::bvar::Window<::bvar::Adder> AdderWindow; typedef ::bvar::Window<::bvar::IntRecorder> RecorderWindow; class AdderWindowMetric { -public: - AdderWindowMetric() : - sum_window(&sum, ::bvar::FLAGS_bvar_dump_interval) { - } + public: + AdderWindowMetric() : sum_window(&sum, ::bvar::FLAGS_bvar_dump_interval) {} - AdderWindowMetric(const std::string& name) : - sum_window(name + "_sum_window", &sum, ::bvar::FLAGS_bvar_dump_interval) { - } + explicit AdderWindowMetric(const std::string& name) + : sum_window( + name + "_sum_window", &sum, ::bvar::FLAGS_bvar_dump_interval) {} - inline AdderWindowMetric& operator<<(int count) { - sum << count; - return *this; - } + inline AdderWindowMetric& operator<<(int count) { + sum << count; + return *this; + } -public: - ::bvar::Adder sum; - AdderWindow sum_window; + public: + ::bvar::Adder sum; + AdderWindow sum_window; }; static float g_get_rate(void* arg); class RateBaseMetric { -public: - RateBaseMetric(const std::string& name) : - rate_value(name + "_rate", g_get_rate, this) { - } - - void update_lhs(int count) { lhs.sum << count; } - - void update_rhs(int count) { rhs.sum << count; } - -public: - ::bvar::PassiveStatus rate_value; - AdderWindowMetric lhs; - AdderWindowMetric rhs; + public: + explicit RateBaseMetric(const std::string& name) + : rate_value(name + "_rate", g_get_rate, this) {} + + void update_lhs(int count) { lhs.sum << count; } + + void update_rhs(int count) { rhs.sum << count; } + + public: + ::bvar::PassiveStatus rate_value; + AdderWindowMetric lhs; + AdderWindowMetric rhs; }; static float g_get_rate(void* arg) { - RateBaseMetric* rate_metric = static_cast(arg); - if (rate_metric->rhs.sum_window.get_value() <= 0) { - return 0; - } - return rate_metric->lhs.sum_window.get_value() * 100 - / (float) rate_metric->rhs.sum_window.get_value(); + RateBaseMetric* rate_metric = static_cast(arg); + if (rate_metric->rhs.sum_window.get_value() <= 0) { + return 0; + } + return rate_metric->lhs.sum_window.get_value() * 100 / + static_cast(rate_metric->rhs.sum_window.get_value()); } -// 计算平均值时取整 +// 计算平均值时取整 class AvgWindowMetric { -public: - AvgWindowMetric() : - avg_window(&avg, ::bvar::FLAGS_bvar_dump_interval) { - } + public: + AvgWindowMetric() : avg_window(&avg, ::bvar::FLAGS_bvar_dump_interval) {} - AvgWindowMetric(const std::string& name) : - avg_window(name + "_avg_window", &avg, ::bvar::FLAGS_bvar_dump_interval) { - } + explicit AvgWindowMetric(const std::string& name) + : avg_window( + name + "_avg_window", &avg, ::bvar::FLAGS_bvar_dump_interval) {} - inline AvgWindowMetric& operator<<(int64_t value) { - avg << value; - return *this; - } + inline AvgWindowMetric& operator<<(int64_t value) { + avg << value; + return *this; + } -public: - ::bvar::IntRecorder avg; - RecorderWindow avg_window; + public: + ::bvar::IntRecorder avg; + RecorderWindow avg_window; }; -// 计算平均值时不取整 +// 计算平均值时不取整 static double g_get_double_avg(void* arg); class AvgDoubleWindowMetric { -public: - AvgDoubleWindowMetric(const std::string& name) : - avg_value(name + "_avg_double_window", g_get_double_avg, this) { - } + public: + explicit AvgDoubleWindowMetric(const std::string& name) + : avg_value(name + "_avg_double_window", g_get_double_avg, this) {} - inline AvgDoubleWindowMetric& operator<<(int64_t value) { - recorder << value; - return *this; - } + inline AvgDoubleWindowMetric& operator<<(int64_t value) { + recorder << value; + return *this; + } -public: - ::bvar::PassiveStatus avg_value; - AvgWindowMetric recorder; + public: + ::bvar::PassiveStatus avg_value; + AvgWindowMetric recorder; }; static double g_get_double_avg(void* arg) { - AvgDoubleWindowMetric* avg_metric = static_cast(arg); - return avg_metric->recorder.avg_window.get_value().get_average_double(); + AvgDoubleWindowMetric* avg_metric = static_cast(arg); + return avg_metric->recorder.avg_window.get_value().get_average_double(); } class PredictorMetric { -public: - static PredictorMetric* GetInstance(); - - ~PredictorMetric() { - for (::butil::FlatMap::iterator iter - = latency_recorder_map.begin(); - iter != latency_recorder_map.end(); - ++iter) { - delete iter->second; - } - for (::butil::FlatMap::iterator iter - = adder_window_map.begin(); - iter != adder_window_map.end(); - ++iter) { - delete iter->second; - } - for (::butil::FlatMap::iterator iter - = avg_window_map.begin(); - iter != avg_window_map.end(); - ++iter) { - delete iter->second; - } - for (::butil::FlatMap::iterator iter - = avg_double_window_map.begin(); - iter != avg_double_window_map.end(); - ++iter) { - delete iter->second; - } - for (::butil::FlatMap::iterator iter - = rate_map.begin(); - iter != rate_map.end(); - ++iter) { - delete iter->second; - } - } + public: + static PredictorMetric* GetInstance(); - void regist_latency_metric(const std::string& metric_name) { - { - BAIDU_SCOPED_LOCK(_mutex); - LOG(INFO) << "try to regist latency metric[" << metric_name << "]."; - if (latency_recorder_map.seek(metric_name) == NULL) { - bvar::LatencyRecorder* metric = new (std::nothrow) bvar::LatencyRecorder(metric_name); - latency_recorder_map.insert(metric_name, metric); - LOG(INFO) << "succ to regist latency metric[" << metric_name << "]."; - } - } + ~PredictorMetric() { + for (::butil::FlatMap::iterator iter = + latency_recorder_map.begin(); + iter != latency_recorder_map.end(); + ++iter) { + delete iter->second; } + for (::butil::FlatMap::iterator iter = + adder_window_map.begin(); + iter != adder_window_map.end(); + ++iter) { + delete iter->second; + } + for (::butil::FlatMap::iterator iter = + avg_window_map.begin(); + iter != avg_window_map.end(); + ++iter) { + delete iter->second; + } + for (::butil::FlatMap::iterator iter = + avg_double_window_map.begin(); + iter != avg_double_window_map.end(); + ++iter) { + delete iter->second; + } + for (::butil::FlatMap::iterator iter = + rate_map.begin(); + iter != rate_map.end(); + ++iter) { + delete iter->second; + } + } - void regist_adder_window_metric(const std::string& metric_name) { - { - BAIDU_SCOPED_LOCK(_mutex); - LOG(INFO) << "try to regist adder window metric[" << metric_name << "]."; - if (adder_window_map.seek(metric_name) == NULL) { - AdderWindowMetric* metric = new (std::nothrow) AdderWindowMetric(metric_name); - adder_window_map.insert(metric_name, metric); - LOG(INFO) << "succ to regist adder window metric[" << metric_name << "]."; - } - } + void regist_latency_metric(const std::string& metric_name) { + { + BAIDU_SCOPED_LOCK(_mutex); + LOG(INFO) << "try to regist latency metric[" << metric_name << "]."; + if (latency_recorder_map.seek(metric_name) == NULL) { + bvar::LatencyRecorder* metric = + new (std::nothrow) bvar::LatencyRecorder(metric_name); + latency_recorder_map.insert(metric_name, metric); + LOG(INFO) << "succ to regist latency metric[" << metric_name << "]."; + } } + } - void regist_avg_window_metric(const std::string& metric_name) { - { - BAIDU_SCOPED_LOCK(_mutex); - LOG(INFO) << "try to regist avg window metric[" << metric_name << "]."; - if (avg_window_map.seek(metric_name) == NULL) { - AvgWindowMetric* metric = new (std::nothrow) AvgWindowMetric(metric_name); - avg_window_map.insert(metric_name, metric); - LOG(INFO) << "succ to regist avg window metric[" << metric_name << "]."; - } - } + void regist_adder_window_metric(const std::string& metric_name) { + { + BAIDU_SCOPED_LOCK(_mutex); + LOG(INFO) << "try to regist adder window metric[" << metric_name << "]."; + if (adder_window_map.seek(metric_name) == NULL) { + AdderWindowMetric* metric = + new (std::nothrow) AdderWindowMetric(metric_name); + adder_window_map.insert(metric_name, metric); + LOG(INFO) << "succ to regist adder window metric[" << metric_name + << "]."; + } } + } - void regist_avg_double_window_metric(const std::string& metric_name) { - { - BAIDU_SCOPED_LOCK(_mutex); - LOG(INFO) << "try to regist avg double window metric[" << metric_name << "]."; - if (avg_double_window_map.seek(metric_name) == NULL) { - AvgDoubleWindowMetric* metric = new (std::nothrow) AvgDoubleWindowMetric(metric_name); - avg_double_window_map.insert(metric_name, metric); - LOG(INFO) << "succ to regist avg double window metric[" << metric_name << "]."; - } - } + void regist_avg_window_metric(const std::string& metric_name) { + { + BAIDU_SCOPED_LOCK(_mutex); + LOG(INFO) << "try to regist avg window metric[" << metric_name << "]."; + if (avg_window_map.seek(metric_name) == NULL) { + AvgWindowMetric* metric = + new (std::nothrow) AvgWindowMetric(metric_name); + avg_window_map.insert(metric_name, metric); + LOG(INFO) << "succ to regist avg window metric[" << metric_name << "]."; + } } + } - void regist_rate_metric(const std::string& metric_name) { - { - BAIDU_SCOPED_LOCK(_mutex); - LOG(INFO) << "try to regist rate metric[" << metric_name << "]."; - if (rate_map.seek(metric_name) == NULL) { - RateBaseMetric* metric = new (std::nothrow) RateBaseMetric(metric_name); - rate_map.insert(metric_name, metric); - LOG(INFO) << "succ to regist rate metric[" << metric_name << "]."; - } - } + void regist_avg_double_window_metric(const std::string& metric_name) { + { + BAIDU_SCOPED_LOCK(_mutex); + LOG(INFO) << "try to regist avg double window metric[" << metric_name + << "]."; + if (avg_double_window_map.seek(metric_name) == NULL) { + AvgDoubleWindowMetric* metric = + new (std::nothrow) AvgDoubleWindowMetric(metric_name); + avg_double_window_map.insert(metric_name, metric); + LOG(INFO) << "succ to regist avg double window metric[" << metric_name + << "]."; + } } + } - inline void update_latency_metric(const std::string& metric_name, int64_t latency) { - bvar::LatencyRecorder** metric = latency_recorder_map.seek(metric_name); - if (metric != NULL) { - **metric << latency; - } else { - LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; - } + void regist_rate_metric(const std::string& metric_name) { + { + BAIDU_SCOPED_LOCK(_mutex); + LOG(INFO) << "try to regist rate metric[" << metric_name << "]."; + if (rate_map.seek(metric_name) == NULL) { + RateBaseMetric* metric = new (std::nothrow) RateBaseMetric(metric_name); + rate_map.insert(metric_name, metric); + LOG(INFO) << "succ to regist rate metric[" << metric_name << "]."; + } } - - inline void update_adder_window_metric(const std::string& metric_name, int count) { - AdderWindowMetric** metric = adder_window_map.seek(metric_name); - if (metric != NULL) { - **metric << count; - } else { - LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; - } + } + + inline void update_latency_metric(const std::string& metric_name, + int64_t latency) { + bvar::LatencyRecorder** metric = latency_recorder_map.seek(metric_name); + if (metric != NULL) { + **metric << latency; + } else { + LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; } - - inline void update_avg_window_metric(const std::string& metric_name, int64_t value) { - AvgWindowMetric** metric = avg_window_map.seek(metric_name); - if (metric != NULL) { - **metric << value; - } else { - LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; - } + } + + inline void update_adder_window_metric(const std::string& metric_name, + int count) { + AdderWindowMetric** metric = adder_window_map.seek(metric_name); + if (metric != NULL) { + **metric << count; + } else { + LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; } + } - inline void update_avg_double_window_metric(const std::string& metric_name, int64_t value) { - AvgDoubleWindowMetric** metric = avg_double_window_map.seek(metric_name); - if (metric != NULL) { - **metric << value; - } else { - LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; - } + inline void update_avg_window_metric(const std::string& metric_name, + int64_t value) { + AvgWindowMetric** metric = avg_window_map.seek(metric_name); + if (metric != NULL) { + **metric << value; + } else { + LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; } + } - inline void update_rate_metric_lhs(const std::string& name, int count) { - RateBaseMetric** metric = rate_map.seek(name); - if (metric != NULL) { - (*metric)->update_lhs(count); - } else { - LOG(ERROR) << "impossible, check if you regist[" << name << "]."; - } + inline void update_avg_double_window_metric(const std::string& metric_name, + int64_t value) { + AvgDoubleWindowMetric** metric = avg_double_window_map.seek(metric_name); + if (metric != NULL) { + **metric << value; + } else { + LOG(ERROR) << "impossible, check if you regist[" << metric_name << "]."; } - - inline void update_rate_metric_rhs(const std::string& name, int count) { - RateBaseMetric** metric = rate_map.seek(name); - if (metric != NULL) { - (*metric)->update_rhs(count); - } else { - LOG(ERROR) << "impossible, check if you regist[" << name << "]."; - } + } + + inline void update_rate_metric_lhs(const std::string& name, int count) { + RateBaseMetric** metric = rate_map.seek(name); + if (metric != NULL) { + (*metric)->update_lhs(count); + } else { + LOG(ERROR) << "impossible, check if you regist[" << name << "]."; } - -private: - PredictorMetric() : - bucket_count(300) { - latency_recorder_map.init(bucket_count); - adder_window_map.init(bucket_count); - avg_window_map.init(bucket_count); - avg_double_window_map.init(bucket_count); - rate_map.init(bucket_count); + } + + inline void update_rate_metric_rhs(const std::string& name, int count) { + RateBaseMetric** metric = rate_map.seek(name); + if (metric != NULL) { + (*metric)->update_rhs(count); + } else { + LOG(ERROR) << "impossible, check if you regist[" << name << "]."; } - -private: - const size_t bucket_count; - ::butil::FlatMap latency_recorder_map; - ::butil::FlatMap adder_window_map; - ::butil::FlatMap avg_window_map; - ::butil::FlatMap avg_double_window_map; - ::butil::FlatMap rate_map; - - friend struct DefaultSingletonTraits; - mutable butil::Mutex _mutex; - DISALLOW_COPY_AND_ASSIGN(PredictorMetric); -}; + } -} // namespace predictor -} // namespace paddle_serving -} // namespace baidu + private: + PredictorMetric() : bucket_count(300) { + latency_recorder_map.init(bucket_count); + adder_window_map.init(bucket_count); + avg_window_map.init(bucket_count); + avg_double_window_map.init(bucket_count); + rate_map.init(bucket_count); + } -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_FRAMEWORK_PREDICTOR_METRIC_H + private: + const size_t bucket_count; + ::butil::FlatMap latency_recorder_map; + ::butil::FlatMap adder_window_map; + ::butil::FlatMap avg_window_map; + ::butil::FlatMap avg_double_window_map; + ::butil::FlatMap rate_map; + + friend struct DefaultSingletonTraits; + mutable butil::Mutex _mutex; + DISALLOW_COPY_AND_ASSIGN(PredictorMetric); +}; +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/resource.cpp b/predictor/framework/resource.cpp index cb35b0cf456cc7e9017d5ef816e77f425e0117ee..414e48dd2032ea8e647ddab3e7b6b4d8d8b819cb 100644 --- a/predictor/framework/resource.cpp +++ b/predictor/framework/resource.cpp @@ -1,5 +1,20 @@ -#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/resource.h" +#include +#include "common/inner_common.h" #include "framework/infer.h" namespace baidu { @@ -12,166 +27,170 @@ using configure::ResourceConf; static void dynamic_resource_deleter(void* d) { #if 1 - LOG(INFO) << "dynamic_resource_delete on " << bthread_self(); + LOG(INFO) << "dynamic_resource_delete on " << bthread_self(); #endif - delete static_cast(d); + delete static_cast(d); } DynamicResource::DynamicResource() {} DynamicResource::~DynamicResource() {} -int DynamicResource::initialize() { - return 0; -} +int DynamicResource::initialize() { return 0; } -int DynamicResource::clear() { - return 0; -} +int DynamicResource::clear() { return 0; } int Resource::initialize(const std::string& path, const std::string& file) { - ResourceConf resource_conf; - if (configure::read_proto_conf(path, file, &resource_conf) != 0) { - LOG(ERROR) << "Failed initialize resource from: " - << path << "/" << file; - return -1; - } - - // mempool - if (MempoolWrapper::instance().initialize() != 0) { - LOG(ERROR) << "Failed proc initialized mempool wrapper"; - return -1; + ResourceConf resource_conf; + if (configure::read_proto_conf(path, file, &resource_conf) != 0) { + LOG(ERROR) << "Failed initialize resource from: " << path << "/" << file; + return -1; + } + + // mempool + if (MempoolWrapper::instance().initialize() != 0) { + LOG(ERROR) << "Failed proc initialized mempool wrapper"; + return -1; + } + LOG(WARNING) << "Successfully proc initialized mempool wrapper"; + + if (FLAGS_enable_model_toolkit) { + int err = 0; + std::string model_toolkit_path = resource_conf.model_toolkit_path(); + if (err != 0) { + LOG(ERROR) << "read model_toolkit_path failed, path[" << path + << "], file[" << file << "]"; + return -1; } - LOG(WARNING) << "Successfully proc initialized mempool wrapper"; - - if (FLAGS_enable_model_toolkit) { - int err = 0; - std::string model_toolkit_path = resource_conf.model_toolkit_path(); - if (err != 0) { - LOG(ERROR) << "read model_toolkit_path failed, path[" - << path << "], file[" << file << "]"; - return -1; - } - std::string model_toolkit_file = resource_conf.model_toolkit_file(); - if (err != 0) { - LOG(ERROR) << "read model_toolkit_file failed, path[" - << path << "], file[" << file << "]"; - return -1; - } - if (InferManager::instance().proc_initialize( - model_toolkit_path.c_str(), model_toolkit_file.c_str()) != 0) { - LOG(ERROR) << "failed proc initialize modeltoolkit, config: " - << model_toolkit_path << "/" << model_toolkit_file; - return -1; - } + std::string model_toolkit_file = resource_conf.model_toolkit_file(); + if (err != 0) { + LOG(ERROR) << "read model_toolkit_file failed, path[" << path + << "], file[" << file << "]"; + return -1; } - - if (THREAD_KEY_CREATE(&_tls_bspec_key, dynamic_resource_deleter) != 0) { - LOG(ERROR) << "unable to create tls_bthread_key of thrd_data"; - return -1; + if (InferManager::instance().proc_initialize( + model_toolkit_path.c_str(), model_toolkit_file.c_str()) != 0) { + LOG(ERROR) << "failed proc initialize modeltoolkit, config: " + << model_toolkit_path << "/" << model_toolkit_file; + return -1; } - THREAD_SETSPECIFIC(_tls_bspec_key, NULL); - return 0; + } + + if (THREAD_KEY_CREATE(&_tls_bspec_key, dynamic_resource_deleter) != 0) { + LOG(ERROR) << "unable to create tls_bthread_key of thrd_data"; + return -1; + } + THREAD_SETSPECIFIC(_tls_bspec_key, NULL); + return 0; } int Resource::thread_initialize() { - // mempool - if (MempoolWrapper::instance().thread_initialize() != 0) { - LOG(ERROR) << "Failed thread initialized mempool wrapper"; - return -1; + // mempool + if (MempoolWrapper::instance().thread_initialize() != 0) { + LOG(ERROR) << "Failed thread initialized mempool wrapper"; + return -1; + } + LOG(WARNING) << "Successfully thread initialized mempool wrapper"; + + // infer manager + if (FLAGS_enable_model_toolkit && + InferManager::instance().thrd_initialize() != 0) { + LOG(ERROR) << "Failed thrd initialized infer manager"; + return -1; + } + + DynamicResource* p_dynamic_resource = + reinterpret_cast(THREAD_GETSPECIFIC(_tls_bspec_key)); + if (p_dynamic_resource == NULL) { + p_dynamic_resource = new (std::nothrow) DynamicResource; + if (p_dynamic_resource == NULL) { + LOG(ERROR) << "failed to create tls DynamicResource"; + return -1; } - LOG(WARNING) << "Successfully thread initialized mempool wrapper"; - - // infer manager - if (FLAGS_enable_model_toolkit && InferManager::instance().thrd_initialize() != 0) { - LOG(ERROR) << "Failed thrd initialized infer manager"; - return -1; + if (p_dynamic_resource->initialize() != 0) { + LOG(ERROR) << "DynamicResource initialize failed."; + delete p_dynamic_resource; + p_dynamic_resource = NULL; + return -1; } - DynamicResource* p_dynamic_resource = (DynamicResource*) THREAD_GETSPECIFIC(_tls_bspec_key); - if (p_dynamic_resource == NULL) { - p_dynamic_resource = new (std::nothrow) DynamicResource; - if (p_dynamic_resource == NULL) { - LOG(ERROR) << "failed to create tls DynamicResource"; - return -1; - } - if (p_dynamic_resource->initialize() != 0) { - LOG(ERROR) << "DynamicResource initialize failed."; - delete p_dynamic_resource; - p_dynamic_resource = NULL; - return -1; - } - - if (THREAD_SETSPECIFIC(_tls_bspec_key, p_dynamic_resource) != 0) { - LOG(ERROR) << "unable to set tls DynamicResource"; - delete p_dynamic_resource; - p_dynamic_resource = NULL; - return -1; - } - + if (THREAD_SETSPECIFIC(_tls_bspec_key, p_dynamic_resource) != 0) { + LOG(ERROR) << "unable to set tls DynamicResource"; + delete p_dynamic_resource; + p_dynamic_resource = NULL; + return -1; } + } #if 0 LOG(INFO) << "Successfully thread initialized dynamic resource"; #else - LOG(INFO) << bthread_self() << ": Successfully thread initialized dynamic resource " << p_dynamic_resource; + LOG(INFO) << bthread_self() + << ": Successfully thread initialized dynamic resource " + << p_dynamic_resource; #endif - return 0; + return 0; } int Resource::thread_clear() { - // mempool - if (MempoolWrapper::instance().thread_clear() != 0) { - LOG(ERROR) << "Failed thread clear mempool wrapper"; - return -1; - } - - // infer manager - if (FLAGS_enable_model_toolkit && InferManager::instance().thrd_clear() != 0) { - LOG(ERROR) << "Failed thrd clear infer manager"; - return -1; - } - - DynamicResource* p_dynamic_resource = (DynamicResource*) THREAD_GETSPECIFIC(_tls_bspec_key); - if (p_dynamic_resource == NULL) { + // mempool + if (MempoolWrapper::instance().thread_clear() != 0) { + LOG(ERROR) << "Failed thread clear mempool wrapper"; + return -1; + } + + // infer manager + if (FLAGS_enable_model_toolkit && + InferManager::instance().thrd_clear() != 0) { + LOG(ERROR) << "Failed thrd clear infer manager"; + return -1; + } + + DynamicResource* p_dynamic_resource = + reinterpret_cast(THREAD_GETSPECIFIC(_tls_bspec_key)); + if (p_dynamic_resource == NULL) { #if 0 - LOG(ERROR) << "tls dynamic resource shouldn't be null after thread_initialize"; + LOG(ERROR) << "tls dynamic resource shouldn't be null after " + << "thread_initialize"; #else - LOG(ERROR) << bthread_self() << ": tls dynamic resource shouldn't be null after thread_initialize"; + LOG(ERROR) + << bthread_self() + << ": tls dynamic resource shouldn't be null after thread_initialize"; #endif - return -1; - } - if (p_dynamic_resource->clear() != 0) { - LOG(ERROR) << "Failed to invoke dynamic resource clear"; - return -1; - } - - LOG(INFO) << bthread_self() << "Resource::thread_clear success"; - // ... - return 0; + return -1; + } + if (p_dynamic_resource->clear() != 0) { + LOG(ERROR) << "Failed to invoke dynamic resource clear"; + return -1; + } + + LOG(INFO) << bthread_self() << "Resource::thread_clear success"; + // ... + return 0; } int Resource::reload() { - if (FLAGS_enable_model_toolkit && InferManager::instance().reload() != 0) { - LOG(ERROR) << "Failed reload infer manager"; - return -1; - } - - // other resource reload here... - return 0; + if (FLAGS_enable_model_toolkit && InferManager::instance().reload() != 0) { + LOG(ERROR) << "Failed reload infer manager"; + return -1; + } + + // other resource reload here... + return 0; } int Resource::finalize() { - if (FLAGS_enable_model_toolkit && InferManager::instance().proc_finalize() != 0) { - LOG(ERROR) << "Failed proc finalize infer manager"; - return -1; - } + if (FLAGS_enable_model_toolkit && + InferManager::instance().proc_finalize() != 0) { + LOG(ERROR) << "Failed proc finalize infer manager"; + return -1; + } - THREAD_KEY_DELETE(_tls_bspec_key); + THREAD_KEY_DELETE(_tls_bspec_key); - return 0; + return 0; } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/resource.h b/predictor/framework/resource.h index 8db2464841ecc966a395a8d2cd1eee098c9a4845..9c741e4432c8eb2c87d1b9e3f124bc44bed444c1 100644 --- a/predictor/framework/resource.h +++ b/predictor/framework/resource.h @@ -1,6 +1,19 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_RESOURCE_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_RESOURCE_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. + +#pragma once +#include #include "common/inner_common.h" #include "framework/memory.h" @@ -10,52 +23,47 @@ namespace predictor { class BaseRdDict; struct DynamicResource { - DynamicResource(); - - ~DynamicResource(); - - int initialize(); - - int clear(); + DynamicResource(); + + ~DynamicResource(); + + int initialize(); + + int clear(); }; class Resource { -public: - - Resource() {} + public: + Resource() {} - ~Resource() { finalize(); } + ~Resource() { finalize(); } - static Resource& instance() { - static Resource ins; - return ins; - } + static Resource& instance() { + static Resource ins; + return ins; + } - int initialize(const std::string& path, const std::string& file); + int initialize(const std::string& path, const std::string& file); - int thread_initialize(); + int thread_initialize(); - int thread_clear(); + int thread_clear(); - int reload(); + int reload(); - int finalize(); + int finalize(); - DynamicResource* get_dynamic_resource() { - return (DynamicResource*) THREAD_GETSPECIFIC(_tls_bspec_key); - } + DynamicResource* get_dynamic_resource() { + return reinterpret_cast( + THREAD_GETSPECIFIC(_tls_bspec_key)); + } -private: - int thread_finalize() { - return 0; - } + private: + int thread_finalize() { return 0; } - THREAD_KEY_T _tls_bspec_key; - + THREAD_KEY_T _tls_bspec_key; }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/server.cpp b/predictor/framework/server.cpp index d62101918b0bee39eed88d0dbc6b2c18de941a94..23bda575ade3d30c206412cde83c259ce0a34854 100644 --- a/predictor/framework/server.cpp +++ b/predictor/framework/server.cpp @@ -1,11 +1,27 @@ -#include // NovaServiceAdaptor -#include // PublicPbrpcServiceAdaptor -#include // NsheadMcpackAdaptor -#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/server.h" -#include "framework/service_manager.h" -#include "framework/resource.h" +#include // NovaServiceAdaptor +#include // NsheadMcpackAdaptor +#include // PublicPbrpcServiceAdaptor +#include +#include +#include "common/inner_common.h" #include "framework/manager.h" +#include "framework/resource.h" +#include "framework/service_manager.h" namespace baidu { namespace paddle_serving { @@ -14,39 +30,37 @@ namespace predictor { volatile bool ServerManager::_s_reload_starting = true; bool ServerManager::_compare_string_piece_without_case( - const butil::StringPiece& s1, const char* s2) { - if (strlen(s2) != s1.size()) { - return false; - } - return strncasecmp(s1.data(), s2, s1.size()) == 0; + const butil::StringPiece& s1, const char* s2) { + if (strlen(s2) != s1.size()) { + return false; + } + return strncasecmp(s1.data(), s2, s1.size()) == 0; } ServerManager::ServerManager() { - _format_services.clear(); - _options.idle_timeout_sec = FLAGS_idle_timeout_s; - _options.max_concurrency = FLAGS_max_concurrency; - _options.num_threads = FLAGS_num_threads; + _format_services.clear(); + _options.idle_timeout_sec = FLAGS_idle_timeout_s; + _options.max_concurrency = FLAGS_max_concurrency; + _options.num_threads = FLAGS_num_threads; } int ServerManager::add_service_by_format(const std::string& format) { - Service* service = - FormatServiceManager::instance().get_service(format); + Service* service = FormatServiceManager::instance().get_service(format); if (service == NULL) { LOG(ERROR) << "Not found service by format:" << format << "!"; return -1; } if (_format_services.find(format) != _format_services.end()) { - LOG(ERROR) << "Cannot insert duplicated service by format:" - << format << "!"; + LOG(ERROR) << "Cannot insert duplicated service by format:" << format + << "!"; return -1; } - std::pair::iterator, bool> it - = _format_services.insert(std::make_pair(format, service)); + std::pair::iterator, bool> it = + _format_services.insert(std::make_pair(format, service)); if (!it.second) { - LOG(ERROR) << "Failed insert service by format:" - << format << "!"; + LOG(ERROR) << "Failed insert service by format:" << format << "!"; return -1; } @@ -60,18 +74,15 @@ int ServerManager::start_and_wait() { } boost::unordered_map::iterator it; - for (it = _format_services.begin(); it != _format_services.end(); - it++) { - if (_server.AddService(it->second, brpc::SERVER_DOESNT_OWN_SERVICE) - != 0) { - LOG(ERROR) << "Failed to add service of format:" - << it->first << "!"; + for (it = _format_services.begin(); it != _format_services.end(); it++) { + if (_server.AddService(it->second, brpc::SERVER_DOESNT_OWN_SERVICE) != 0) { + LOG(ERROR) << "Failed to add service of format:" << it->first << "!"; return -1; } } if (_server.Start(FLAGS_port, &_options) != 0) { - LOG(ERROR) << "Failed to start Paddle Inference Server" ; + LOG(ERROR) << "Failed to start Paddle Inference Server"; return -1; } _server.RunUntilAskedToQuit(); @@ -85,61 +96,63 @@ int ServerManager::start_and_wait() { } void ServerManager::_set_server_option_by_protocol( - const ::butil::StringPiece& protocol_type) { - std::string enabled_protocols = FLAGS_enable_protocol_list; - if (_compare_string_piece_without_case(protocol_type, "nova_pbrpc")) { - _options.nshead_service = new ::brpc::policy::NovaServiceAdaptor;; - } else if (_compare_string_piece_without_case(protocol_type, "public_pbrpc")) { - _options.nshead_service = new ::brpc::policy::PublicPbrpcServiceAdaptor; - } else if (_compare_string_piece_without_case(protocol_type, "nshead_mcpack")) { - _options.nshead_service = new ::brpc::policy::NsheadMcpackAdaptor; - } else { - LOG(ERROR) << "fail to set nshead protocol, protocol_type[" << protocol_type << "]."; - return; - } - _options.enabled_protocols = enabled_protocols; - LOG(INFO) << "success to set nshead protocol, protocol_type[" << protocol_type << "]."; + const ::butil::StringPiece& protocol_type) { + std::string enabled_protocols = FLAGS_enable_protocol_list; + if (_compare_string_piece_without_case(protocol_type, "nova_pbrpc")) { + _options.nshead_service = new ::brpc::policy::NovaServiceAdaptor; + } else if (_compare_string_piece_without_case(protocol_type, + "public_pbrpc")) { + _options.nshead_service = new ::brpc::policy::PublicPbrpcServiceAdaptor; + } else if (_compare_string_piece_without_case(protocol_type, + "nshead_mcpack")) { + _options.nshead_service = new ::brpc::policy::NsheadMcpackAdaptor; + } else { + LOG(ERROR) << "fail to set nshead protocol, protocol_type[" << protocol_type + << "]."; + return; + } + _options.enabled_protocols = enabled_protocols; + LOG(INFO) << "success to set nshead protocol, protocol_type[" << protocol_type + << "]."; } int ServerManager::_start_reloader() { - int ret = THREAD_CREATE( - &_reload_thread, NULL, - ServerManager::_reload_worker, - NULL); - - if (ret != 0) { - LOG(ERROR) << "Failed start reload thread, ret:" << ret; - return -1; - } + int ret = + THREAD_CREATE(&_reload_thread, NULL, ServerManager::_reload_worker, NULL); - return 0; + if (ret != 0) { + LOG(ERROR) << "Failed start reload thread, ret:" << ret; + return -1; + } + + return 0; } int ServerManager::_wait_reloader() { - THREAD_JOIN(_reload_thread, NULL); - return 0; + THREAD_JOIN(_reload_thread, NULL); + return 0; } void* ServerManager::_reload_worker(void* args) { - LOG(INFO) << "Entrence reload worker, " - << "interval_s: " << FLAGS_reload_interval_s; - while (ServerManager::reload_starting()) { - LOG(INFO) << "Begin reload framework..."; - if (Resource::instance().reload() != 0) { - LOG(ERROR) << "Failed reload resource!"; - } - - if (WorkflowManager::instance().reload() != 0) { - LOG(ERROR) << "Failed reload workflows"; - } - - usleep(FLAGS_reload_interval_s * 1000000); + LOG(INFO) << "Entrence reload worker, " + << "interval_s: " << FLAGS_reload_interval_s; + while (ServerManager::reload_starting()) { + LOG(INFO) << "Begin reload framework..."; + if (Resource::instance().reload() != 0) { + LOG(ERROR) << "Failed reload resource!"; + } + + if (WorkflowManager::instance().reload() != 0) { + LOG(ERROR) << "Failed reload workflows"; } - LOG(INFO) << "Exit reload worker!"; - return NULL; + usleep(FLAGS_reload_interval_s * 1000000); + } + + LOG(INFO) << "Exit reload worker!"; + return NULL; } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/server.h b/predictor/framework/server.h index 7826f86792ecb6baaf99436ef111d013ce04301c..0158e7e3e074c6c5a82ec4d7c67fd8da91ae83a1 100644 --- a/predictor/framework/server.h +++ b/predictor/framework/server.h @@ -1,6 +1,19 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_SERVER_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_SERVER_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. + +#pragma once +#include #include "common/inner_common.h" namespace baidu { @@ -8,48 +21,43 @@ namespace paddle_serving { namespace predictor { class ServerManager { -public: - typedef google::protobuf::Service Service; - ServerManager(); + public: + typedef google::protobuf::Service Service; + ServerManager(); - static ServerManager& instance() { - static ServerManager server; - return server; - } + static ServerManager& instance() { + static ServerManager server; + return server; + } - static bool reload_starting() { - return _s_reload_starting; - } + static bool reload_starting() { return _s_reload_starting; } - static void stop_reloader() { - _s_reload_starting = false; - } + static void stop_reloader() { _s_reload_starting = false; } - int add_service_by_format(const std::string& format); + int add_service_by_format(const std::string& format); - int start_and_wait(); + int start_and_wait(); -private: - int _start_reloader(); - - int _wait_reloader(); + private: + int _start_reloader(); - static void* _reload_worker(void* args); - - bool _compare_string_piece_without_case( - const butil::StringPiece& s1, const char* s2); + int _wait_reloader(); - void _set_server_option_by_protocol(const ::butil::StringPiece& protocol_type); + static void* _reload_worker(void* args); - brpc::ServerOptions _options; - brpc::Server _server; - boost::unordered_map _format_services; - THREAD_T _reload_thread; - static volatile bool _s_reload_starting; -}; + bool _compare_string_piece_without_case(const butil::StringPiece& s1, + const char* s2); -} // predictor -} // paddle_serving -} // baidu + void _set_server_option_by_protocol( + const ::butil::StringPiece& protocol_type); + + brpc::ServerOptions _options; + brpc::Server _server; + boost::unordered_map _format_services; + THREAD_T _reload_thread; + static volatile bool _s_reload_starting; +}; -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/service.cpp b/predictor/framework/service.cpp index c00755a69646f538d76f3432c17909eac9b60274..a9a2078de100542442471425143690953c3329b2 100644 --- a/predictor/framework/service.cpp +++ b/predictor/framework/service.cpp @@ -1,273 +1,274 @@ +// 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/service.h" +#include // butil::Timer +#include +#include +#include +#include "common/constant.h" #include "common/inner_common.h" #include "framework/channel.h" -#include "common/constant.h" -#include "framework/service.h" -#include // butil::Timer -#include "framework/server.h" #include "framework/dag_view.h" #include "framework/manager.h" +#include "framework/predictor_metric.h" // PredictorMetric #include "framework/resource.h" -#include "framework/predictor_metric.h" // PredictorMetric +#include "framework/server.h" namespace baidu { namespace paddle_serving { namespace predictor { int InferService::init(const configure::InferService& conf) { - _infer_service_format = conf.name(); + _infer_service_format = conf.name(); - std::string merger = conf.merger(); - if (merger == "") { - merger = "default"; - } - if (!MergerManager::instance().get(merger, _merger)) { - LOG(ERROR) << "Failed get merger: " << merger; - return ERR_INTERNAL_FAILURE; - } else { - LOG(WARNING) << "Succ get merger: " << merger << - " for service: " << _infer_service_format; - } + std::string merger = conf.merger(); + if (merger == "") { + merger = "default"; + } + if (!MergerManager::instance().get(merger, _merger)) { + LOG(ERROR) << "Failed get merger: " << merger; + return ERR_INTERNAL_FAILURE; + } else { + LOG(WARNING) << "Succ get merger: " << merger + << " for service: " << _infer_service_format; + } - ServerManager& svr_mgr = ServerManager::instance(); - if (svr_mgr.add_service_by_format(_infer_service_format) != 0) { - LOG(ERROR) - << "Not found service by format name:" - << _infer_service_format << "!"; - return ERR_INTERNAL_FAILURE; - } - - _enable_map_request_to_workflow = conf.enable_map_request_to_workflow(); - LOG(INFO) << "service[" << _infer_service_format + ServerManager& svr_mgr = ServerManager::instance(); + if (svr_mgr.add_service_by_format(_infer_service_format) != 0) { + LOG(ERROR) << "Not found service by format name:" << _infer_service_format + << "!"; + return ERR_INTERNAL_FAILURE; + } + + _enable_map_request_to_workflow = conf.enable_map_request_to_workflow(); + LOG(INFO) << "service[" << _infer_service_format << "], enable_map_request_to_workflow[" << _enable_map_request_to_workflow << "]."; - if (_enable_map_request_to_workflow) { - if (_request_to_workflow_map.init( - MAX_WORKFLOW_NUM_IN_ONE_SERVICE/*load_factor=80*/) != 0) { - LOG(ERROR) - << "init request to workflow map failed, bucket_count[" - << MAX_WORKFLOW_NUM_IN_ONE_SERVICE << "]."; - return ERR_INTERNAL_FAILURE; - } - int err = 0; - _request_field_key = conf.request_field_key().c_str(); - if (_request_field_key == "") { - LOG(ERROR) - << "read request_field_key failed, request_field_key[" - << _request_field_key << "]."; - return ERR_INTERNAL_FAILURE; - } - - LOG(INFO) - << "service[" << _infer_service_format - << "], request_field_key[" - << _request_field_key << "]."; - uint32_t value_mapped_workflows_size = conf.value_mapped_workflows_size(); - for (uint32_t fi = 0; fi < value_mapped_workflows_size; fi++) { - std::vector tokens; - std::vector workflows; - std::string list = conf.value_mapped_workflows(fi).workflow(); - boost::split(tokens, list, boost::is_any_of(",")); - uint32_t tsize = tokens.size(); - for (uint32_t ti = 0; ti < tsize; ++ti) { - boost::trim_if(tokens[ti], boost::is_any_of(" ")); - Workflow* workflow = - WorkflowManager::instance().item(tokens[ti]); - if (workflow == NULL) { - LOG(ERROR) - << "Failed get workflow by name:" - << tokens[ti] << ", ti: " << ti; - return ERR_INTERNAL_FAILURE; - } - workflow->regist_metric(full_name()); - workflows.push_back(workflow); - } + if (_enable_map_request_to_workflow) { + if (_request_to_workflow_map.init( + MAX_WORKFLOW_NUM_IN_ONE_SERVICE /*load_factor=80*/) != 0) { + LOG(ERROR) << "init request to workflow map failed, bucket_count[" + << MAX_WORKFLOW_NUM_IN_ONE_SERVICE << "]."; + return ERR_INTERNAL_FAILURE; + } + int err = 0; + _request_field_key = conf.request_field_key().c_str(); + if (_request_field_key == "") { + LOG(ERROR) << "read request_field_key failed, request_field_key[" + << _request_field_key << "]."; + return ERR_INTERNAL_FAILURE; + } - const std::string& request_field_value = conf.value_mapped_workflows(fi).request_field_value(); - if (_request_to_workflow_map.insert(request_field_value, workflows) == NULL) { - LOG(ERROR) - << "insert [" << request_field_value << "," - << list << "] to _request_to_workflow_map failed."; - return ERR_INTERNAL_FAILURE; - } - LOG(INFO) << "workflow[" << list - << "], request_field_value[" << request_field_value << "]."; + LOG(INFO) << "service[" << _infer_service_format << "], request_field_key[" + << _request_field_key << "]."; + uint32_t value_mapped_workflows_size = conf.value_mapped_workflows_size(); + for (uint32_t fi = 0; fi < value_mapped_workflows_size; fi++) { + std::vector tokens; + std::vector workflows; + std::string list = conf.value_mapped_workflows(fi).workflow(); + boost::split(tokens, list, boost::is_any_of(",")); + uint32_t tsize = tokens.size(); + for (uint32_t ti = 0; ti < tsize; ++ti) { + boost::trim_if(tokens[ti], boost::is_any_of(" ")); + Workflow* workflow = WorkflowManager::instance().item(tokens[ti]); + if (workflow == NULL) { + LOG(ERROR) << "Failed get workflow by name:" << tokens[ti] + << ", ti: " << ti; + return ERR_INTERNAL_FAILURE; } - } else { - uint32_t flow_size = conf.workflows_size(); - for (uint32_t fi = 0; fi < flow_size; fi++) { - const std::string& workflow_name = conf.workflows(fi); - Workflow* workflow = - WorkflowManager::instance().item(workflow_name); - if (workflow == NULL) { - LOG(ERROR) - << "Failed get workflow by name:" - << workflow_name; - return ERR_INTERNAL_FAILURE; - } - workflow->regist_metric(full_name()); - _flows.push_back(workflow); - } - } + workflow->regist_metric(full_name()); + workflows.push_back(workflow); + } - LOG(INFO) - << "Succ load infer_service: " - << _infer_service_format << "!"; + const std::string& request_field_value = + conf.value_mapped_workflows(fi).request_field_value(); + if (_request_to_workflow_map.insert(request_field_value, workflows) == + NULL) { + LOG(ERROR) << "insert [" << request_field_value << "," << list + << "] to _request_to_workflow_map failed."; + return ERR_INTERNAL_FAILURE; + } + LOG(INFO) << "workflow[" << list << "], request_field_value[" + << request_field_value << "]."; + } + } else { + uint32_t flow_size = conf.workflows_size(); + for (uint32_t fi = 0; fi < flow_size; fi++) { + const std::string& workflow_name = conf.workflows(fi); + Workflow* workflow = WorkflowManager::instance().item(workflow_name); + if (workflow == NULL) { + LOG(ERROR) << "Failed get workflow by name:" << workflow_name; + return ERR_INTERNAL_FAILURE; + } + workflow->regist_metric(full_name()); + _flows.push_back(workflow); + } + } - return ERR_OK; -} + LOG(INFO) << "Succ load infer_service: " << _infer_service_format << "!"; -int InferService::reload() { - return ERR_OK; + return ERR_OK; } -const std::string& InferService::name() const { - return _infer_service_format; -} +int InferService::reload() { return ERR_OK; } -// ִÿworkflow -int InferService::inference( - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os) { +const std::string& InferService::name() const { return _infer_service_format; } - TRACEPRINTF("start to inference"); - // when funtion call begins, framework will reset - // thread local variables&resources automatically. - if (Resource::instance().thread_clear() != 0) { - LOG(ERROR) << "Failed thread clear whole resource"; - return ERR_INTERNAL_FAILURE; - } +// ´®ÐÐÖ´ÐÐÿ¸öworkflow +int InferService::inference(const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os) { + TRACEPRINTF("start to inference"); + // when funtion call begins, framework will reset + // thread local variables&resources automatically. + if (Resource::instance().thread_clear() != 0) { + LOG(ERROR) << "Failed thread clear whole resource"; + return ERR_INTERNAL_FAILURE; + } - TRACEPRINTF("finish to thread clear"); + TRACEPRINTF("finish to thread clear"); - if (_enable_map_request_to_workflow) { - std::vector* workflows = _map_request_to_workflow(request); - if (!workflows || workflows->size() == 0) { - LOG(ERROR) << "Failed to map request to workflow"; - return ERR_INTERNAL_FAILURE; - } - size_t fsize = workflows->size(); - for (size_t fi = 0; fi < fsize; ++fi) { - Workflow* workflow = (*workflows)[fi]; - if (workflow == NULL) { - LOG(ERROR) << "Failed to get valid workflow at: " << fi; - return ERR_INTERNAL_FAILURE; - } - TRACEPRINTF("start to execute workflow[%s]", workflow->name().c_str()); - int errcode = _execute_workflow(workflow, request, response, debug_os); - TRACEPRINTF("finish to execute workflow[%s]", workflow->name().c_str()); - if (errcode < 0) { - LOG(ERROR) << "Failed execute workflow[" << workflow->name() - << "] in:" << name(); - return errcode; - } - } - } else { - TRACEPRINTF("start to execute one workflow"); - size_t fsize = _flows.size(); - for (size_t fi = 0; fi < fsize; ++fi) { - TRACEPRINTF("start to execute one workflow-%lu", fi); - int errcode = execute_one_workflow(fi, request, response, debug_os); - TRACEPRINTF("finish to execute one workflow-%lu", fi); - if (errcode < 0) { - LOG(ERROR) << "Failed execute 0-th workflow in:" << name(); - return errcode; - } - } + if (_enable_map_request_to_workflow) { + std::vector* workflows = _map_request_to_workflow(request); + if (!workflows || workflows->size() == 0) { + LOG(ERROR) << "Failed to map request to workflow"; + return ERR_INTERNAL_FAILURE; } - return ERR_OK; + size_t fsize = workflows->size(); + for (size_t fi = 0; fi < fsize; ++fi) { + Workflow* workflow = (*workflows)[fi]; + if (workflow == NULL) { + LOG(ERROR) << "Failed to get valid workflow at: " << fi; + return ERR_INTERNAL_FAILURE; + } + TRACEPRINTF("start to execute workflow[%s]", workflow->name().c_str()); + int errcode = _execute_workflow(workflow, request, response, debug_os); + TRACEPRINTF("finish to execute workflow[%s]", workflow->name().c_str()); + if (errcode < 0) { + LOG(ERROR) << "Failed execute workflow[" << workflow->name() + << "] in:" << name(); + return errcode; + } + } + } else { + TRACEPRINTF("start to execute one workflow"); + size_t fsize = _flows.size(); + for (size_t fi = 0; fi < fsize; ++fi) { + TRACEPRINTF("start to execute one workflow-%lu", fi); + int errcode = execute_one_workflow(fi, request, response, debug_os); + TRACEPRINTF("finish to execute one workflow-%lu", fi); + if (errcode < 0) { + LOG(ERROR) << "Failed execute 0-th workflow in:" << name(); + return errcode; + } + } + } + return ERR_OK; } -int InferService::debug( - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os) { - return inference(request, response, debug_os); +int InferService::debug(const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os) { + return inference(request, response, debug_os); } -int InferService::execute_one_workflow( - uint32_t index, - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os) { - if (index >= _flows.size()) { - LOG(ERROR) << "Faield execute workflow, index: " - << index << " >= max:" << _flows.size(); - return ERR_OVERFLOW_FAILURE; - } - Workflow* workflow = _flows[index]; - return _execute_workflow(workflow, request, response, debug_os); +int InferService::execute_one_workflow(uint32_t index, + const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os) { + if (index >= _flows.size()) { + LOG(ERROR) << "Faield execute workflow, index: " << index + << " >= max:" << _flows.size(); + return ERR_OVERFLOW_FAILURE; + } + Workflow* workflow = _flows[index]; + return _execute_workflow(workflow, request, response, debug_os); } -int InferService::_execute_workflow( - Workflow* workflow, - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os) { - butil::Timer workflow_time(butil::Timer::STARTED); - // create and submit beginer channel - BuiltinChannel req_channel; - req_channel.init(0, START_OP_NAME); - req_channel = request; +int InferService::_execute_workflow(Workflow* workflow, + const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os) { + butil::Timer workflow_time(butil::Timer::STARTED); + // create and submit beginer channel + BuiltinChannel req_channel; + req_channel.init(0, START_OP_NAME); + req_channel = request; - DagView* dv = workflow->fetch_dag_view(full_name()); - dv->set_request_channel(req_channel); + DagView* dv = workflow->fetch_dag_view(full_name()); + dv->set_request_channel(req_channel); - // call actual inference interface - int errcode = dv->execute(debug_os); - if (errcode < 0) { - LOG(ERROR) << "Failed execute dag for workflow:" - << workflow->name(); - return errcode; - } + // call actual inference interface + int errcode = dv->execute(debug_os); + if (errcode < 0) { + LOG(ERROR) << "Failed execute dag for workflow:" << workflow->name(); + return errcode; + } - TRACEPRINTF("finish to dv execute"); - // create ender channel and copy - const Channel* res_channel = dv->get_response_channel(); - if (!_merger || !_merger->merge(res_channel->message(), response)) { - LOG(ERROR) << "Failed merge channel res to response"; - return ERR_INTERNAL_FAILURE; - } - TRACEPRINTF("finish to copy from"); + TRACEPRINTF("finish to dv execute"); + // create ender channel and copy + const Channel* res_channel = dv->get_response_channel(); + if (!_merger || !_merger->merge(res_channel->message(), response)) { + LOG(ERROR) << "Failed merge channel res to response"; + return ERR_INTERNAL_FAILURE; + } + TRACEPRINTF("finish to copy from"); - workflow_time.stop(); - PredictorMetric::GetInstance()->update_latency_metric( - WORKFLOW_METRIC_PREFIX + dv->full_name(), workflow_time.u_elapsed()); - - // return tls data to object pool - workflow->return_dag_view(dv); - TRACEPRINTF("finish to return dag view"); - return ERR_OK; + workflow_time.stop(); + PredictorMetric::GetInstance()->update_latency_metric( + WORKFLOW_METRIC_PREFIX + dv->full_name(), workflow_time.u_elapsed()); + + // return tls data to object pool + workflow->return_dag_view(dv); + TRACEPRINTF("finish to return dag view"); + return ERR_OK; } std::vector* InferService::_map_request_to_workflow( - const google::protobuf::Message* request) { - const google::protobuf::Descriptor* desc = request->GetDescriptor(); - const google::protobuf::FieldDescriptor* field = desc->FindFieldByName(_request_field_key); - if (field == NULL) { - LOG(ERROR) << "No field[" << _request_field_key << "] in [" << desc->full_name() << "]."; - return NULL; - } - if (field->is_repeated()) { - LOG(ERROR) << "field[" << desc->full_name() << "." - << _request_field_key << "] is repeated."; - return NULL; - } - if (field->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_STRING) { - LOG(ERROR) << "field[" << desc->full_name() << "." - << _request_field_key << "] should be string"; - return NULL; - } - const std::string& field_value = request->GetReflection()->GetString(*request, field); - std::vector* p_workflow = _request_to_workflow_map.seek(field_value); - if (p_workflow == NULL) { - LOG(ERROR) << "cannot find key[" << field_value << "] in _request_to_workflow_map"; - return NULL; - } - return p_workflow; + const google::protobuf::Message* request) { + const google::protobuf::Descriptor* desc = request->GetDescriptor(); + const google::protobuf::FieldDescriptor* field = + desc->FindFieldByName(_request_field_key); + if (field == NULL) { + LOG(ERROR) << "No field[" << _request_field_key << "] in [" + << desc->full_name() << "]."; + return NULL; + } + if (field->is_repeated()) { + LOG(ERROR) << "field[" << desc->full_name() << "." << _request_field_key + << "] is repeated."; + return NULL; + } + if (field->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_STRING) { + LOG(ERROR) << "field[" << desc->full_name() << "." << _request_field_key + << "] should be string"; + return NULL; + } + const std::string& field_value = + request->GetReflection()->GetString(*request, field); + std::vector* p_workflow = + _request_to_workflow_map.seek(field_value); + if (p_workflow == NULL) { + LOG(ERROR) << "cannot find key[" << field_value + << "] in _request_to_workflow_map"; + return NULL; + } + return p_workflow; } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/service.h b/predictor/framework/service.h index b187c5c0dd753bd93c70fe3663def123061724f8..0d913acd045de900753273954dde69f9c144dd1f 100644 --- a/predictor/framework/service.h +++ b/predictor/framework/service.h @@ -1,91 +1,98 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_SERVICE_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_SERVICE_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. + +#pragma once +#include +#include +#include #include "common/inner_common.h" -#include "framework/workflow.h" #include "framework/merger.h" +#include "framework/workflow.h" namespace baidu { namespace paddle_serving { namespace predictor { class InferService { -public: - typedef OpChannel BuiltinChannel; + public: + typedef OpChannel BuiltinChannel; - static const char* tag() { - return "service"; - } + static const char* tag() { return "service"; } - InferService() : - _last_change_timestamp(0), - _enable_map_request_to_workflow(false), - _request_field_key(""), - _merger(NULL) { - _flows.clear(); - _request_to_workflow_map.clear(); - } + InferService() + : _last_change_timestamp(0), + _enable_map_request_to_workflow(false), + _request_field_key(""), + _merger(NULL) { + _flows.clear(); + _request_to_workflow_map.clear(); + } - int init(const configure::InferService& conf); + int init(const configure::InferService& conf); - int deinit() { return 0; } + int deinit() { return 0; } - int reload(); + int reload(); - const std::string& name() const; - - const std::string& full_name() const { - return _infer_service_format; - } + const std::string& name() const; - // ִÿworkflow - virtual int inference( - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os = NULL); + const std::string& full_name() const { return _infer_service_format; } - int debug( - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os); + // Execute each workflow serially + virtual int inference(const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os = NULL); - int execute_one_workflow( - uint32_t index, - const google::protobuf::Message* request, + int debug(const google::protobuf::Message* request, google::protobuf::Message* response, butil::IOBufBuilder* debug_os); -private: - int _execute_workflow( - Workflow* workflow, - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os); - - std::vector* _map_request_to_workflow(const google::protobuf::Message* request); -private: - std::vector _flows; - std::string _infer_service_format; - uint64_t _last_change_timestamp; - bool _enable_map_request_to_workflow; - std::string _request_field_key; - ::butil::FlatMap > _request_to_workflow_map; - IMerger* _merger; + int execute_one_workflow(uint32_t index, + const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os); + + private: + int _execute_workflow(Workflow* workflow, + const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os); + + std::vector* _map_request_to_workflow( + const google::protobuf::Message* request); + + private: + std::vector _flows; + std::string _infer_service_format; + uint64_t _last_change_timestamp; + bool _enable_map_request_to_workflow; + std::string _request_field_key; + ::butil::FlatMap> + _request_to_workflow_map; + IMerger* _merger; }; class ParallelInferService : public InferService { -public: - // ִÿworkflow - int inference( - const google::protobuf::Message* request, - google::protobuf::Message* response, - butil::IOBufBuilder* debug_os) { - return 0; - } + public: + // Execute workflows in parallel + int inference(const google::protobuf::Message* request, + google::protobuf::Message* response, + butil::IOBufBuilder* debug_os) { + return 0; + } }; -} // predictor -} // paddle_serving -} // baidu - -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_INFERSERVICE_H +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/service_manager.h b/predictor/framework/service_manager.h index bb1d200863190a8261435563791566bd7c46bd65..d6f05ac5cabc2744a07b6e2196ed1b7c21ac16e0 100644 --- a/predictor/framework/service_manager.h +++ b/predictor/framework/service_manager.h @@ -1,82 +1,85 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_FORMAT_MANAGER_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_FORMAT_MANAGER_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. +#pragma once +#include +#include #include "common/inner_common.h" namespace baidu { namespace paddle_serving { namespace predictor { -#define REGIST_FORMAT_SERVICE(svr_name, svr) \ -do { \ - int ret = ::baidu::paddle_serving::predictor::FormatServiceManager::instance().regist_service(\ - svr_name, svr); \ - if (ret != 0) { \ - LOG(ERROR) \ - << "Failed regist service[" \ - << svr_name << "]" << "[" \ - << typeid(svr).name() << "]" \ - << "!"; \ - } else { \ - LOG(INFO) \ - << "Success regist service[" \ - << svr_name << "][" \ - << typeid(svr).name() << "]" \ - << "!"; \ - } \ -} while (0) +#define REGIST_FORMAT_SERVICE(svr_name, svr) \ + do { \ + int ret = \ + ::baidu::paddle_serving::predictor::FormatServiceManager::instance() \ + .regist_service(svr_name, svr); \ + if (ret != 0) { \ + LOG(ERROR) << "Failed regist service[" << svr_name << "]" \ + << "[" << typeid(svr).name() << "]" \ + << "!"; \ + } else { \ + LOG(INFO) << "Success regist service[" << svr_name << "][" \ + << typeid(svr).name() << "]" \ + << "!"; \ + } \ + } while (0) class FormatServiceManager { -public: - typedef google::protobuf::Service Service; + public: + typedef google::protobuf::Service Service; - int regist_service(const std::string& svr_name, Service* svr) { - if (_service_map.find(svr_name) != _service_map.end()) { - LOG(ERROR) - << "Service[" << svr_name << "][" - << typeid(svr).name() << "]" - << " already exist!"; - return -1; - } - - std::pair::iterator, bool> ret; - ret = _service_map.insert(std::make_pair(svr_name, svr)); - if (ret.second == false) { - LOG(ERROR) - << "Service[" << svr_name << "][" - << typeid(svr).name() << "]" - << " insert failed!"; - return -1; - } - - LOG(INFO) - << "Service[" << svr_name << "] insert successfully!"; - return 0; + int regist_service(const std::string& svr_name, Service* svr) { + if (_service_map.find(svr_name) != _service_map.end()) { + LOG(ERROR) << "Service[" << svr_name << "][" << typeid(svr).name() << "]" + << " already exist!"; + return -1; } - Service* get_service(const std::string& svr_name) { - boost::unordered_map::iterator res; - if ((res = _service_map.find(svr_name)) == _service_map.end()) { - LOG(WARNING) - << "Service[" << svr_name << "] " - << "not found in service manager" - << "!"; - return NULL; - } - return (*res).second; + std::pair::iterator, bool> ret; + ret = _service_map.insert(std::make_pair(svr_name, svr)); + if (ret.second == false) { + LOG(ERROR) << "Service[" << svr_name << "][" << typeid(svr).name() << "]" + << " insert failed!"; + return -1; } - static FormatServiceManager& instance() { - static FormatServiceManager service_; - return service_; + LOG(INFO) << "Service[" << svr_name << "] insert successfully!"; + return 0; + } + + Service* get_service(const std::string& svr_name) { + boost::unordered_map::iterator res; + if ((res = _service_map.find(svr_name)) == _service_map.end()) { + LOG(WARNING) << "Service[" << svr_name << "] " + << "not found in service manager" + << "!"; + return NULL; } + return (*res).second; + } -private: - boost::unordered_map _service_map; -}; + static FormatServiceManager& instance() { + static FormatServiceManager service_; + return service_; + } -} // predictor -} // paddle_serving -} // baidu + private: + boost::unordered_map _service_map; +}; -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/workflow.cpp b/predictor/framework/workflow.cpp index 53f4a22181c97afb196798b0e78889e7b5e70ebf..ac5f23371cc2b8fd910423d45f40c0ece2b59a68 100644 --- a/predictor/framework/workflow.cpp +++ b/predictor/framework/workflow.cpp @@ -1,67 +1,79 @@ -#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/workflow.h" -#include "framework/predictor_metric.h" // PredictorMetric +#include +#include "common/inner_common.h" +#include "framework/predictor_metric.h" // PredictorMetric namespace baidu { namespace paddle_serving { namespace predictor { int Workflow::init(const configure::Workflow& conf) { - const std::string& name = conf.name(); - _type = conf.workflow_type(); - _name = name; - if (_dag.init(conf, name) != 0) { - LOG(ERROR) << "Failed initialize dag: " << _name; - return -1; - } - return 0; + const std::string& name = conf.name(); + _type = conf.workflow_type(); + _name = name; + if (_dag.init(conf, name) != 0) { + LOG(ERROR) << "Failed initialize dag: " << _name; + return -1; + } + return 0; } DagView* Workflow::fetch_dag_view(const std::string& service_name) { - DagView* view = NULL; - if (_type == "Sequence") { - view = butil::get_object(); - } else if (_type == "Parallel") { - view = butil::get_object(); - } else { - LOG(ERROR) - << "Unknown dag type:" << _type << "!"; - return NULL; - } - if (view == NULL) { - LOG(ERROR) << "create dag view from pool failed!"; - return NULL; - } - view->init(&_dag, service_name); - return view; + DagView* view = NULL; + if (_type == "Sequence") { + view = butil::get_object(); + } else if (_type == "Parallel") { + view = butil::get_object(); + } else { + LOG(ERROR) << "Unknown dag type:" << _type << "!"; + return NULL; + } + if (view == NULL) { + LOG(ERROR) << "create dag view from pool failed!"; + return NULL; + } + view->init(&_dag, service_name); + return view; } void Workflow::return_dag_view(DagView* view) { - view->deinit(); - if (_type == "Sequence") { - butil::return_object(view); - } else if (_type == "Parallel") { - butil::return_object( - dynamic_cast(view)); - } else { - LOG(ERROR) - << "Unknown dag type:" << _type << "!"; - return ; - } + view->deinit(); + if (_type == "Sequence") { + butil::return_object(view); + } else if (_type == "Parallel") { + butil::return_object(dynamic_cast(view)); + } else { + LOG(ERROR) << "Unknown dag type:" << _type << "!"; + return; + } } int Workflow::reload() { - // reload op's config here... + // reload op's config here... - return 0; + return 0; } void Workflow::regist_metric(const std::string& service_name) { - PredictorMetric::GetInstance()->regist_latency_metric( - WORKFLOW_METRIC_PREFIX + service_name + NAME_DELIMITER + full_name()); - _dag.regist_metric(service_name); + PredictorMetric::GetInstance()->regist_latency_metric( + WORKFLOW_METRIC_PREFIX + service_name + NAME_DELIMITER + full_name()); + _dag.regist_metric(service_name); } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/framework/workflow.h b/predictor/framework/workflow.h index 552e004e61c099e9481fdfa019dc7de9d03c35af..a89af74d4a2177766e77c2d35dc0d57492c91372 100644 --- a/predictor/framework/workflow.h +++ b/predictor/framework/workflow.h @@ -1,6 +1,19 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_WORKFLOW_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_WORKFLOW_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. + +#pragma once +#include #include "common/inner_common.h" #include "framework/dag.h" #include "framework/dag_view.h" @@ -9,48 +22,40 @@ namespace baidu { namespace paddle_serving { namespace predictor { -template +template class Manager; class Workflow { -public: - Workflow() {} - - static const char* tag() { - return "workflow"; - } - - // Each workflow object corresponds to an independent - // configure file, so you can share the object between - // different apps. - int init(const configure::Workflow& conf); - - DagView* fetch_dag_view(const std::string& service_name); - - int deinit() { return 0; } - - void return_dag_view(DagView* view); - - int reload(); - - const std::string& name() { - return _name; - } - - const std::string& full_name() { - return _name; - } - - void regist_metric(const std::string& service_name); - -private: - Dag _dag; - std::string _type; - std::string _name; -}; + public: + Workflow() {} + + static const char* tag() { return "workflow"; } + + // Each workflow object corresponds to an independent + // configure file, so you can share the object between + // different apps. + int init(const configure::Workflow& conf); + + DagView* fetch_dag_view(const std::string& service_name); + + int deinit() { return 0; } -} // predictor -} // paddle_serving -} // baidu + void return_dag_view(DagView* view); + + int reload(); + + const std::string& name() { return _name; } + + const std::string& full_name() { return _name; } + + void regist_metric(const std::string& service_name); + + private: + Dag _dag; + std::string _type; + std::string _name; +}; -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/mempool/mempool.cpp b/predictor/mempool/mempool.cpp index 11b2f3dd661fd36c6ccef3ae1bdc6a0a71c2bfb7..65e77285304484ea2f527f1513c2a99c33007806 100644 --- a/predictor/mempool/mempool.cpp +++ b/predictor/mempool/mempool.cpp @@ -1,3 +1,17 @@ +// 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 "mempool/mempool.h" namespace im { @@ -9,73 +23,68 @@ namespace fugue { namespace memory { void Region::init() { - _big_mem_capacity = 32 * 1024 * 1024; - _big_mem_start = new char[_big_mem_capacity]; + _big_mem_capacity = 32 * 1024 * 1024; + _big_mem_start = new char[_big_mem_capacity]; } void Region::reset() { - // release memory allocate from GlobalMempool - _free_blocks.unsafe_foreach(); - _free_blocks.reset(); - - // release memory from malloc - BigNode* head = _big_nodes.release(); - while (head) { - BigNode* next = head->next; - ::free(head); - head = next; - } - _mlc_mem_size.store(0, butil::memory_order_relaxed); - _mlc_mem_count.store(0, butil::memory_order_relaxed); - - // clear the large buffer - _big_mem_size.store(0, butil::memory_order_relaxed); - _big_mem_count.store(0, butil::memory_order_relaxed); - + // release memory allocate from GlobalMempool + _free_blocks.unsafe_foreach(); + _free_blocks.reset(); + + // release memory from malloc + BigNode* head = _big_nodes.release(); + while (head) { + BigNode* next = head->next; + ::free(head); + head = next; + } + _mlc_mem_size.store(0, butil::memory_order_relaxed); + _mlc_mem_count.store(0, butil::memory_order_relaxed); + + // clear the large buffer + _big_mem_size.store(0, butil::memory_order_relaxed); + _big_mem_count.store(0, butil::memory_order_relaxed); } BlockReference* Region::get() { - BlockReference* ref = _free_blocks.get(); - if (ref->block == NULL) { - ref->offset = 0; - ref->block = GlobalBlockFreeList::instance()->get(); - } - return ref; + BlockReference* ref = _free_blocks.get(); + if (ref->block == NULL) { + ref->offset = 0; + ref->block = GlobalBlockFreeList::instance()->get(); + } + return ref; } -void Region::put(BlockReference* block) { - _free_blocks.put(block); -} +void Region::put(BlockReference* block) { _free_blocks.put(block); } void* Region::malloc(size_t size) { - if (size < MLC_MEM_THRESHOLD) { - uint32_t offset = _big_mem_size.fetch_add(size, butil::memory_order_relaxed); - if (offset + size < _big_mem_capacity) { - _big_mem_count.fetch_add(1, butil::memory_order_relaxed); - return _big_mem_start + offset; - } + if (size < MLC_MEM_THRESHOLD) { + uint32_t offset = + _big_mem_size.fetch_add(size, butil::memory_order_relaxed); + if (offset + size < _big_mem_capacity) { + _big_mem_count.fetch_add(1, butil::memory_order_relaxed); + return _big_mem_start + offset; } + } - _mlc_mem_size.fetch_add(size, butil::memory_order_relaxed); - _mlc_mem_count.fetch_add(1, butil::memory_order_relaxed); - BigNode* node = (BigNode*)::malloc(sizeof(BigNode) + size); - _big_nodes.push(node); - return node->data; + _mlc_mem_size.fetch_add(size, butil::memory_order_relaxed); + _mlc_mem_count.fetch_add(1, butil::memory_order_relaxed); + BigNode* node = reinterpret_cast(::malloc(sizeof(BigNode) + size)); + _big_nodes.push(node); + return node->data; } Region::Region() { - _big_mem_size.store(0, butil::memory_order_relaxed); - _big_mem_count.store(0, butil::memory_order_relaxed); + _big_mem_size.store(0, butil::memory_order_relaxed); + _big_mem_count.store(0, butil::memory_order_relaxed); - _big_mem_start = NULL; - _big_mem_capacity = 0; - - _mlc_mem_size.store(0, butil::memory_order_relaxed); - _mlc_mem_count.store(0, butil::memory_order_relaxed); -} - -} - -} + _big_mem_start = NULL; + _big_mem_capacity = 0; + _mlc_mem_size.store(0, butil::memory_order_relaxed); + _mlc_mem_count.store(0, butil::memory_order_relaxed); } +} // namespace memory +} // namespace fugue +} // namespace im diff --git a/predictor/mempool/mempool.h b/predictor/mempool/mempool.h index 45422f2f7359308912f183ff01925692873460ee..cc68755954739fcd64c6454a2efc2fd465699ecd 100644 --- a/predictor/mempool/mempool.h +++ b/predictor/mempool/mempool.h @@ -1,13 +1,26 @@ -#ifndef APP_ECOM_IM_MEMPOOL_SRC_MEMPOOL_H -#define APP_ECOM_IM_MEMPOOL_SRC_MEMPOOL_H - -#include -#include -#include -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once #include #include +#include +#include #include +#include +#include +#include namespace im { namespace fugue { @@ -16,470 +29,441 @@ namespace lockfree { template class PushOnlyStack { -public: - PushOnlyStack() { - _head.store(NULL, butil::memory_order_relaxed); - } + public: + PushOnlyStack() { _head.store(NULL, butil::memory_order_relaxed); } - void push(T* node) { - T* head = _head.load(butil::memory_order_relaxed); - node->next = head; - while (!_head.compare_exchange_weak( - head, node, butil::memory_order_relaxed)) { - node->next = head; - } + void push(T* node) { + T* head = _head.load(butil::memory_order_relaxed); + node->next = head; + while ( + !_head.compare_exchange_weak(head, node, butil::memory_order_relaxed)) { + node->next = head; } + } - T* release() { - return _head.exchange(NULL, butil::memory_order_relaxed); - } + T* release() { return _head.exchange(NULL, butil::memory_order_relaxed); } -private: - butil::atomic _head; + private: + butil::atomic _head; }; template struct FreeListNode { - uint64_t id; - uint64_t next; - T data; + uint64_t id; + uint64_t next; + T data; }; template class FreeList { -public: - typedef FreeListNode Node; - static const uint64_t EMPTY = 0xFFFFFFFFFFFFFFFF; - - T* get() { - uint64_t head = _head.load(butil::memory_order_acquire); - if (head == EMPTY) { - return new_node(); - } + public: + typedef FreeListNode Node; + static const uint64_t EMPTY = 0xFFFFFFFFFFFFFFFF; - Node* node = address(head); - while (!_head.compare_exchange_weak( - head, node->next, butil::memory_order_acquire)) { - if (head == EMPTY) { - return new_node(); - } - node = address(head); - } - return &node->data; + T* get() { + uint64_t head = _head.load(butil::memory_order_acquire); + if (head == EMPTY) { + return new_node(); } - void put(T* value) { - Node* node = container_of(value, Node, data); + Node* node = address(head); + while (!_head.compare_exchange_weak( + head, node->next, butil::memory_order_acquire)) { + if (head == EMPTY) { + return new_node(); + } + node = address(head); + } + return &node->data; + } - uint64_t head = _head.load(butil::memory_order_acquire); - // add version - node->id += (1UL << 32); - node->next = head; + void put(T* value) { + Node* node = container_of(value, Node, data); - // NOTE: we MUST use a temp var *head* to call compare_exchange_weak - // because Boost.Atomic will update the *expected* even success - // std::atomic do not have this limitation - while (!_head.compare_exchange_weak( - head, node->id, butil::memory_order_release)) { - node->next = head; - } - } + uint64_t head = _head.load(butil::memory_order_acquire); + // add version + node->id += (1UL << 32); + node->next = head; - template - void unsafe_foreach() { - uint32_t used_blk_cnt = _slot_index.load(butil::memory_order_relaxed); - for (uint32_t i = 0; i < used_blk_cnt; ++i) { - F()(&_node[i]->data); - } + // NOTE: we MUST use a temp var *head* to call compare_exchange_weak + // because Boost.Atomic will update the *expected* even success + // std::atomic do not have this limitation + while (!_head.compare_exchange_weak( + head, node->id, butil::memory_order_release)) { + node->next = head; } + } - uint32_t real_used_size() const { - uint32_t used_blk_cnt = _slot_index.load(butil::memory_order_relaxed); - uint64_t used_bytes = 0; - for (uint32_t i = 0; i < used_blk_cnt; ++i) { - used_bytes += _node[i]->data.offset; - } - return used_bytes >> 10; + template + void unsafe_foreach() { + uint32_t used_blk_cnt = _slot_index.load(butil::memory_order_relaxed); + for (uint32_t i = 0; i < used_blk_cnt; ++i) { + F()(&_node[i]->data); } + } - uint32_t allocate_blocks() const { - return _slot_index.load(butil::memory_order_relaxed); + uint32_t real_used_size() const { + uint32_t used_blk_cnt = _slot_index.load(butil::memory_order_relaxed); + uint64_t used_bytes = 0; + for (uint32_t i = 0; i < used_blk_cnt; ++i) { + used_bytes += _node[i]->data.offset; } + return used_bytes >> 10; + } - uint32_t free_blocks() const { - uint64_t head = _head.load(butil::memory_order_relaxed); - uint32_t size = 0; - while (head != FreeList::EMPTY) { - const Node* head_ptr = address(head); - head = head_ptr->next; - ++size; - } - return size; - } + uint32_t allocate_blocks() const { + return _slot_index.load(butil::memory_order_relaxed); + } - void reset() { - _head.store(FreeList::EMPTY, butil::memory_order_relaxed); - _slot_index.store(0, butil::memory_order_relaxed); + uint32_t free_blocks() const { + uint64_t head = _head.load(butil::memory_order_relaxed); + uint32_t size = 0; + while (head != FreeList::EMPTY) { + const Node* head_ptr = address(head); + head = head_ptr->next; + ++size; } + return size; + } - FreeList() { - for (int i = 0; i < CAP; ++i) { - _node[i] = NULL; - } - reset(); - } + void reset() { + _head.store(FreeList::EMPTY, butil::memory_order_relaxed); + _slot_index.store(0, butil::memory_order_relaxed); + } -private: - uint32_t slot(uint64_t id) const { - return static_cast(id); + FreeList() { + for (int i = 0; i < CAP; ++i) { + _node[i] = NULL; } + reset(); + } - T* new_node() { - uint32_t index = _slot_index.fetch_add(1, butil::memory_order_relaxed); - if (index >= CAP) { - return NULL; - } + private: + uint32_t slot(uint64_t id) const { return static_cast(id); } - if (_node[index] != NULL) { - return &(_node[index]->data); - } + T* new_node() { + uint32_t index = _slot_index.fetch_add(1, butil::memory_order_relaxed); + if (index >= CAP) { + return NULL; + } - Node* node = (Node*)malloc(sizeof(Node)); - new (node) Node; + if (_node[index] != NULL) { + return &(_node[index]->data); + } - node->id = index; - _node[index] = node; + Node* node = reinterpret_cast(malloc(sizeof(Node))); + new (node) Node; - return &node->data; - } + node->id = index; + _node[index] = node; - Node* address(uint64_t id) { - return _node[slot(id)]; - } + return &node->data; + } - const Node* address(uint64_t id) const { - return _node[slot(id)]; - } + Node* address(uint64_t id) { return _node[slot(id)]; } - butil::atomic _head; - butil::atomic _slot_index; - Node* _node[CAP]; -}; + const Node* address(uint64_t id) const { return _node[slot(id)]; } -} + butil::atomic _head; + butil::atomic _slot_index; + Node* _node[CAP]; +}; +} // namespace lockfree namespace memory { struct Block { - static const int BLOCK_SIZE = 2 * 1024 * 1024; - char data[BLOCK_SIZE]; + static const int BLOCK_SIZE = 2 * 1024 * 1024; + char data[BLOCK_SIZE]; }; class GlobalBlockFreeList { -public: - static const int MAX_BLOCK_COUNT = 32 * 1024; - typedef lockfree::FreeList type; - static type* instance() { - static type singleton; - return &singleton; - } + public: + static const int MAX_BLOCK_COUNT = 32 * 1024; + typedef lockfree::FreeList type; + static type* instance() { + static type singleton; + return &singleton; + } }; struct BlockReference { - BlockReference() : offset(0), block(NULL) { - // do nothing - } + BlockReference() : offset(0), block(NULL) { + // do nothing + } - void reset() { - offset = 0; - block = NULL; - } + void reset() { + offset = 0; + block = NULL; + } - uint32_t offset; - Block* block; + uint32_t offset; + Block* block; }; class Region { -public: - struct GlobalPut { - void operator()(BlockReference* block_ref) { - if (block_ref->block != NULL) { - GlobalBlockFreeList::instance()->put(block_ref->block); - } - block_ref->reset(); - } - }; + public: + struct GlobalPut { + void operator()(BlockReference* block_ref) { + if (block_ref->block != NULL) { + GlobalBlockFreeList::instance()->put(block_ref->block); + } + block_ref->reset(); + } + }; - struct BigNode { - BigNode* next; - char data[0]; - }; + struct BigNode { + BigNode* next; + char data[0]; + }; - ~Region() { - reset(); - delete [] _big_mem_start; - _big_mem_start = NULL; - } + ~Region() { + reset(); + delete[] _big_mem_start; + _big_mem_start = NULL; + } - char const* debug_str() const { - uint32_t alloc_blocks = _free_blocks.allocate_blocks(); - uint32_t free_blocks = _free_blocks.free_blocks(); - uint32_t used_mem_mb = _free_blocks.real_used_size(); - uint32_t big_buf_size = _big_mem_size.load(butil::memory_order_relaxed); - uint32_t big_buf_count = _big_mem_count.load(butil::memory_order_relaxed); - uint32_t mlc_mem_size = _mlc_mem_size.load(butil::memory_order_relaxed); - uint32_t mlc_mem_count = _mlc_mem_count.load(butil::memory_order_relaxed); - - std::ostringstream oss; - oss << "[alloc_blks:" << alloc_blocks << ",free_blks:" << free_blocks - << ",used_mem_kb:" << used_mem_mb << ",big_mem_kb:" << (big_buf_size >> 10) - << ",big_buf_cnt:" << big_buf_count << ",mlc_mem_kb:" << (mlc_mem_size >> 10) - << ",mlc_cnt:" << mlc_mem_count << "]"; - - return oss.str().c_str(); - } + char const* debug_str() const { + uint32_t alloc_blocks = _free_blocks.allocate_blocks(); + uint32_t free_blocks = _free_blocks.free_blocks(); + uint32_t used_mem_mb = _free_blocks.real_used_size(); + uint32_t big_buf_size = _big_mem_size.load(butil::memory_order_relaxed); + uint32_t big_buf_count = _big_mem_count.load(butil::memory_order_relaxed); + uint32_t mlc_mem_size = _mlc_mem_size.load(butil::memory_order_relaxed); + uint32_t mlc_mem_count = _mlc_mem_count.load(butil::memory_order_relaxed); - Region(); + std::ostringstream oss; + oss << "[alloc_blks:" << alloc_blocks << ",free_blks:" << free_blocks + << ",used_mem_kb:" << used_mem_mb + << ",big_mem_kb:" << (big_buf_size >> 10) + << ",big_buf_cnt:" << big_buf_count + << ",mlc_mem_kb:" << (mlc_mem_size >> 10) + << ",mlc_cnt:" << mlc_mem_count << "]"; - void init(); + return oss.str().c_str(); + } - void reset(); + Region(); - BlockReference* get(); + void init(); - void* malloc(size_t size); + void reset(); - void put(BlockReference* block); + BlockReference* get(); - static const int MAX_BLOCK_COUNT = 1024; - static const int BIG_MEM_THRESHOLD = 256 * 1024; - static const int MLC_MEM_THRESHOLD = 4 * 1024 * 1024; - static const int COUNTER_SIZE = MLC_MEM_THRESHOLD / BIG_MEM_THRESHOLD + 1; + void* malloc(size_t size); -private: - lockfree::FreeList _free_blocks; - lockfree::PushOnlyStack _big_nodes; + void put(BlockReference* block); - butil::atomic _big_mem_size; - butil::atomic _big_mem_count; + static const int MAX_BLOCK_COUNT = 1024; + static const int BIG_MEM_THRESHOLD = 256 * 1024; + static const int MLC_MEM_THRESHOLD = 4 * 1024 * 1024; + static const int COUNTER_SIZE = MLC_MEM_THRESHOLD / BIG_MEM_THRESHOLD + 1; - char* _big_mem_start; - uint32_t _big_mem_capacity; + private: + lockfree::FreeList _free_blocks; + lockfree::PushOnlyStack _big_nodes; - butil::atomic _mlc_mem_size; - butil::atomic _mlc_mem_count; -}; + butil::atomic _big_mem_size; + butil::atomic _big_mem_count; -} + char* _big_mem_start; + uint32_t _big_mem_capacity; -} + butil::atomic _mlc_mem_size; + butil::atomic _mlc_mem_count; +}; +} // namespace memory +} // namespace fugue class Mempool { -public: - void* malloc(size_t size) { - size = _align(size); - if (size <= _free_size) { - void* p = _free_cursor; - _free_size -= size; - _free_cursor += size; - return p; - } - - return malloc_from_region(size); + public: + void* malloc(size_t size) { + size = _align(size); + if (size <= _free_size) { + void* p = _free_cursor; + _free_size -= size; + _free_cursor += size; + return p; } - void free(void* p, size_t size) { - if (size >= fugue::memory::Region::BIG_MEM_THRESHOLD) { - return; - } + return malloc_from_region(size); + } - if (_free_cursor - size == static_cast(p)) { - size_t down_aligned = _down_align(size); - _free_cursor -= down_aligned; - _free_size += down_aligned; - } + void free(void* p, size_t size) { + if (size >= fugue::memory::Region::BIG_MEM_THRESHOLD) { + return; } - void* realloc(void* old_data, size_t old_size, size_t new_size) { - if (old_size >= new_size) { - return old_data; - } - - size_t required = new_size - old_size; - if (_free_cursor == static_cast(old_data) + old_size) { - if (_free_size >= required) { - _free_cursor += required; - _free_size -= required; - return old_data; - } else { - _free_cursor = static_cast(old_data); - _free_size += old_size; - } - } + if (_free_cursor - size == static_cast(p)) { + size_t down_aligned = _down_align(size); + _free_cursor -= down_aligned; + _free_size += down_aligned; + } + } - void* p = this->malloc_from_region(new_size); - if (p != NULL) { - memcpy(p, old_data, old_size); - return p; - } + void* realloc(void* old_data, size_t old_size, size_t new_size) { + if (old_size >= new_size) { + return old_data; + } - return NULL; + size_t required = new_size - old_size; + if (_free_cursor == static_cast(old_data) + old_size) { + if (_free_size >= required) { + _free_cursor += required; + _free_size -= required; + return old_data; + } else { + _free_cursor = static_cast(old_data); + _free_size += old_size; + } } - Mempool(fugue::memory::Region* blocks) : _free_size(0) - , _free_cursor(NULL) - , _blocks(blocks) { - _block = NULL; + void* p = this->malloc_from_region(new_size); + if (p != NULL) { + memcpy(p, old_data, old_size); + return p; } - ~Mempool() { - release_block(); + return NULL; + } + + explicit Mempool(fugue::memory::Region* blocks) + : _free_size(0), _free_cursor(NULL), _blocks(blocks) { + _block = NULL; + } + + ~Mempool() { release_block(); } + + void release_block() { + if (_block) { + _block->offset = fugue::memory::Block::BLOCK_SIZE - _free_size; + _blocks->put(_block); } - void release_block() { - if (_block) { - _block->offset = fugue::memory::Block::BLOCK_SIZE - _free_size; - _blocks->put(_block); - } + _free_size = 0; + _free_cursor = NULL; + _block = NULL; + } - _free_size = 0; - _free_cursor = NULL; - _block = NULL; + private: + void* malloc_from_region(size_t size) { + if (size >= fugue::memory::Region::BIG_MEM_THRESHOLD) { + return _blocks->malloc(size); } -private: - void* malloc_from_region(size_t size) { - if (size >= fugue::memory::Region::BIG_MEM_THRESHOLD) { - return _blocks->malloc(size); - } + while (true) { + fugue::memory::BlockReference* block = _blocks->get(); + if (block == NULL) { + return NULL; + } - while (true) { - fugue::memory::BlockReference* block = _blocks->get(); - if (block == NULL) { - return NULL; - } - - uint32_t free_size = fugue::memory::Block::BLOCK_SIZE - block->offset; - if (size <= free_size) { - if (_block) { - _block->offset = fugue::memory::Block::BLOCK_SIZE - _free_size; - } - - char* p = block->block->data + block->offset; - _free_size = free_size - size; - _free_cursor = p + size; - _block = block; - return p; - } + uint32_t free_size = fugue::memory::Block::BLOCK_SIZE - block->offset; + if (size <= free_size) { + if (_block) { + _block->offset = fugue::memory::Block::BLOCK_SIZE - _free_size; } - return _blocks->malloc(size); + + char* p = block->block->data + block->offset; + _free_size = free_size - size; + _free_cursor = p + size; + _block = block; + return p; + } } + return _blocks->malloc(size); + } - static const int ALIGN_SIZE = sizeof(void*); + static const int ALIGN_SIZE = sizeof(void*); - inline size_t _align(size_t size) const { - return (size + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1); - } + inline size_t _align(size_t size) const { + return (size + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1); + } - inline size_t _down_align(size_t size) const { - return size & ~(ALIGN_SIZE - 1); - } + inline size_t _down_align(size_t size) const { + return size & ~(ALIGN_SIZE - 1); + } - size_t _free_size; - char* _free_cursor; + size_t _free_size; + char* _free_cursor; - fugue::memory::Region* _blocks; - fugue::memory::BlockReference* _block; + fugue::memory::Region* _blocks; + fugue::memory::BlockReference* _block; }; extern __thread Mempool* g_mempool; class mempool { -public: - virtual void * malloc (size_t size) = 0; - virtual void free (void *p, size_t size) = 0; - inline virtual ~mempool(){} + public: + virtual void* malloc(size_t size) = 0; + virtual void free(void* p, size_t size) = 0; + inline virtual ~mempool() {} }; class GlobalMempool : public mempool { -public: - GlobalMempool() { - // do nothing; - } + public: + GlobalMempool() { + // do nothing; + } - virtual ~GlobalMempool() { - // do nothing; - } + virtual ~GlobalMempool() { + // do nothing; + } - static GlobalMempool* instance() { - static GlobalMempool singleton; - return &singleton; - } + static GlobalMempool* instance() { + static GlobalMempool singleton; + return &singleton; + } - void reset(Mempool* mempool) { - g_mempool = mempool; - } + void reset(Mempool* mempool) { g_mempool = mempool; } - void* malloc(size_t size) { - return g_mempool->malloc(size); - } + void* malloc(size_t size) { return g_mempool->malloc(size); } - void* realloc(void* old_data, size_t old_size, size_t new_size) { - return g_mempool->realloc(old_data, old_size, new_size); - } + void* realloc(void* old_data, size_t old_size, size_t new_size) { + return g_mempool->realloc(old_data, old_size, new_size); + } - void free(void* p, size_t s) { - g_mempool->free(p, s); - } + void free(void* p, size_t s) { g_mempool->free(p, s); } - void clear() { - g_mempool->release_block(); - } - - Mempool* get() { - return g_mempool; - } + void clear() { g_mempool->release_block(); } + Mempool* get() { return g_mempool; } }; class MempoolGuard { -public: - MempoolGuard(fugue::memory::Region* region) : _mempool(region) { - acquire(); - } - - void acquire() { - _saved_mempool = g_mempool; - g_mempool = &_mempool; - } - - void release() { - _mempool.release_block(); - g_mempool = _saved_mempool; - } - - ~MempoolGuard() { - release(); - } - -private: - Mempool _mempool; - Mempool* _saved_mempool; + public: + explicit MempoolGuard(fugue::memory::Region* region) : _mempool(region) { + acquire(); + } + + void acquire() { + _saved_mempool = g_mempool; + g_mempool = &_mempool; + } + + void release() { + _mempool.release_block(); + g_mempool = _saved_mempool; + } + + ~MempoolGuard() { release(); } + + private: + Mempool _mempool; + Mempool* _saved_mempool; }; inline std::string print_trace() { - const static int BT_BUF_SIZE = 400; - std::stringstream debug_stream; + static const int BT_BUF_SIZE = 400; + std::stringstream debug_stream; - void* buffer[BT_BUF_SIZE]; - int nptrs = backtrace(buffer, BT_BUF_SIZE); - char** strings = backtrace_symbols(buffer, nptrs); + void* buffer[BT_BUF_SIZE]; + int nptrs = backtrace(buffer, BT_BUF_SIZE); + char** strings = backtrace_symbols(buffer, nptrs); - for (int j = 0; j < nptrs; j++) { - debug_stream << strings[j] << "\t"; - } - - return debug_stream.str(); -} + for (int j = 0; j < nptrs; j++) { + debug_stream << strings[j] << "\t"; + } + return debug_stream.str(); } -#endif +} // namespace im diff --git a/predictor/op/op.cpp b/predictor/op/op.cpp index 274c840951745c863cb916884c3df309886bb733..5a2904cf81de8fd787219413f83fd44ad1c44687 100644 --- a/predictor/op/op.cpp +++ b/predictor/op/op.cpp @@ -1,7 +1,22 @@ +// 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 "op/op.h" -#include // butil::Timer -#include "common/utils.h" +#include // butil::Timer +#include #include "common/constant.h" +#include "common/utils.h" #include "framework/channel.h" #include "framework/dag.h" @@ -9,297 +24,278 @@ namespace baidu { namespace paddle_serving { namespace predictor { -int Op::init(Bus* bus, Dag* dag, uint32_t id, const std::string& name, - const std::string& type, void* conf) { - _bus = bus; - _dag = dag; - _id = id; - _name = name; - _type = type; - set_config(conf); - - _timer = butil::get_object(); - if (!_timer) { - LOG(ERROR) << "Invalid timerflow in op:" - << this->name(); - return -1; - } - - _timer->init(); - _has_calc = false; - _has_init = true; - - Channel* channel = mutable_channel(); - if (channel == NULL) { - LOG(ERROR) - << "Failed mutable channel in op: " - << this->id() << ", " << this->name() << "!"; - return -1; - } - - return custom_init(); +int Op::init(Bus* bus, + Dag* dag, + uint32_t id, + const std::string& name, + const std::string& type, + void* conf) { + _bus = bus; + _dag = dag; + _id = id; + _name = name; + _type = type; + set_config(conf); + + _timer = butil::get_object(); + if (!_timer) { + LOG(ERROR) << "Invalid timerflow in op:" << this->name(); + return -1; + } + + _timer->init(); + _has_calc = false; + _has_init = true; + + Channel* channel = mutable_channel(); + if (channel == NULL) { + LOG(ERROR) << "Failed mutable channel in op: " << this->id() << ", " + << this->name() << "!"; + return -1; + } + + return custom_init(); } int Op::deinit() { - if (_timer) { - butil::return_object(_timer); - } + if (_timer) { + butil::return_object(_timer); + } - _bus = NULL; - _dag = NULL; - _timer = NULL; + _bus = NULL; + _dag = NULL; + _timer = NULL; - if (release_channel() != 0) { - LOG(ERROR) << "Failed release channel in op:" - << this->id() << ", " << this->name() << "!"; - return -1; - } + if (release_channel() != 0) { + LOG(ERROR) << "Failed release channel in op:" << this->id() << ", " + << this->name() << "!"; + return -1; + } - return custom_deinit(); + return custom_deinit(); } int Op::check_time(const char* tag) { - if (!_timer) { - LOG(ERROR) << "Invalid timer in op"; - return -1; - } + if (!_timer) { + LOG(ERROR) << "Invalid timer in op"; + return -1; + } - if (!_timer->check(tag)) { - LOG(ERROR) << "Failed check timer:" << tag; - return -1; - } + if (!_timer->check(tag)) { + LOG(ERROR) << "Failed check timer:" << tag; + return -1; + } - return 0; + return 0; } int Op::process(bool debug) { - butil::Timer op_time(butil::Timer::STARTED); - if (debug && _timer) { - _timer->start(); - } - if (!_has_init) { - LOG(ERROR) - << "Make sure op has been init before inference"; - return ERR_INTERNAL_FAILURE; - } - - if (_has_calc) { - LOG(INFO) - << "Op: " << _name << " already processed before"; - return ERR_OK; - } - - // 1. dependency inference - /* - DagNode* node = _dag->node_by_name(this->name()); - if (node == NULL) { - LOG(ERROR) << "Failed get node of op:" << this->name(); - return -1; - } - boost::unordered_map& depends = - node->depends; - boost::unordered_map::iterator it; - for (it = depends.begin(); it != depends.end(); it++) { - Op* depend_op = view->find(it->first); - if (depend_op->process() != 0) { - LOG(WARNING) << "Op: " << _name << " processed failed!"; - return -1; - } - }*/ - if (debug && _timer) { - _timer->check("depend"); - } - - // 2. current inference - if (inference() != 0) { - return ERR_OP_INFER_FAILURE; - } - if (debug && _timer) { - _timer->check("infer"); - } - - // 3. share output to bus - Channel* channel = mutable_channel(); - channel->share_to_bus(_bus); - - // 4. mark has calculated - _has_calc = true; - - if (debug && _timer) { - _timer->check("share"); - _timer->end(); - } - - op_time.stop(); - PredictorMetric::GetInstance()->update_latency_metric( - OP_METRIC_PREFIX + full_name(), op_time.u_elapsed()); - LOG(INFO) << " " << name() << "_time=[" << op_time.u_elapsed() << "]"; + butil::Timer op_time(butil::Timer::STARTED); + if (debug && _timer) { + _timer->start(); + } + if (!_has_init) { + LOG(ERROR) << "Make sure op has been init before inference"; + return ERR_INTERNAL_FAILURE; + } + + if (_has_calc) { + LOG(INFO) << "Op: " << _name << " already processed before"; return ERR_OK; + } + + // 1. dependency inference + /* + DagNode* node = _dag->node_by_name(this->name()); + if (node == NULL) { + LOG(ERROR) << "Failed get node of op:" << this->name(); + return -1; + } + boost::unordered_map& depends = + node->depends; + boost::unordered_map::iterator it; + for (it = depends.begin(); it != depends.end(); it++) { + Op* depend_op = view->find(it->first); + if (depend_op->process() != 0) { + LOG(WARNING) << "Op: " << _name << " processed failed!"; + return -1; + } + }*/ + if (debug && _timer) { + _timer->check("depend"); + } + + // 2. current inference + if (inference() != 0) { + return ERR_OP_INFER_FAILURE; + } + if (debug && _timer) { + _timer->check("infer"); + } + + // 3. share output to bus + Channel* channel = mutable_channel(); + channel->share_to_bus(_bus); + + // 4. mark has calculated + _has_calc = true; + + if (debug && _timer) { + _timer->check("share"); + _timer->end(); + } + + op_time.stop(); + PredictorMetric::GetInstance()->update_latency_metric( + OP_METRIC_PREFIX + full_name(), op_time.u_elapsed()); + LOG(INFO) << " " << name() << "_time=[" << op_time.u_elapsed() << "]"; + return ERR_OK; } std::string Op::time_info() { - if (_timer) { - return _timer->info(); - } else { - return "Invalid Timer!"; - } + if (_timer) { + return _timer->info(); + } else { + return "Invalid Timer!"; + } } bool Op::is_mutable(const std::string& op) { - if (op == START_OP_NAME) { - return false; - } - DagNode* node = const_cast(_dag->node_by_name(_name)); - if (node->depends.find(op) == node->depends.end()) { - LOG(WARNING) - << "op: " << _name << " doesnot depend on" - << "op: " << op << "!"; - return false; - } - - if (node->depends[op] != RW) { - LOG(WARNING) - << "op: " << _name << " has no RW access" - << "ot op: " << op << ", mode: " << node->depends[op] - << ", please use get_argment() instead."; - return false; - } - - return true; + if (op == START_OP_NAME) { + return false; + } + DagNode* node = const_cast(_dag->node_by_name(_name)); + if (node->depends.find(op) == node->depends.end()) { + LOG(WARNING) << "op: " << _name << " doesnot depend on" + << "op: " << op << "!"; + return false; + } + + if (node->depends[op] != RW) { + LOG(WARNING) << "op: " << _name << " has no RW access" + << "ot op: " << op << ", mode: " << node->depends[op] + << ", please use get_argment() instead."; + return false; + } + + return true; } bool Op::is_mutable(const std::string& op) const { - if (op == START_OP_NAME) { - return false; - } - DagNode* node = const_cast( - _dag->node_by_name(_name)); - if (node->depends.find(op) == node->depends.end()) { - LOG(WARNING) - << "op: " << _name << " doesnot depend on" - << "op: " << op << "!"; - return false; - } - - if (node->depends[op] != RW) { - LOG(WARNING) - << "op: " << _name << " has no RW access" - << "ot op: " << op << ", mode: " << node->depends[op] - << ", please use get_argment() instead."; - return false; - } - - return true; + if (op == START_OP_NAME) { + return false; + } + DagNode* node = const_cast(_dag->node_by_name(_name)); + if (node->depends.find(op) == node->depends.end()) { + LOG(WARNING) << "op: " << _name << " doesnot depend on" + << "op: " << op << "!"; + return false; + } + + if (node->depends[op] != RW) { + LOG(WARNING) << "op: " << _name << " has no RW access" + << "ot op: " << op << ", mode: " << node->depends[op] + << ", please use get_argment() instead."; + return false; + } + + return true; } bool Op::is_readable(const std::string& op) { - if (op == START_OP_NAME) { - return true; - } - DagNode* node = const_cast(_dag->node_by_name(_name)); - if (node->depends.find(op) == node->depends.end()) { - LOG(WARNING) - << "op: " << _name << " doesnot depend on" - << "op: " << op << "!"; - return false; - } - - if (node->depends[op] != RW && node->depends[op] != RO) { - LOG(WARNING) - << "op: " << _name << " has no RO access" - << "ot op: " << op << ", mode: " << node->depends[op] - << ", please check your configuration."; - return false; - } - + if (op == START_OP_NAME) { return true; + } + DagNode* node = const_cast(_dag->node_by_name(_name)); + if (node->depends.find(op) == node->depends.end()) { + LOG(WARNING) << "op: " << _name << " doesnot depend on" + << "op: " << op << "!"; + return false; + } + + if (node->depends[op] != RW && node->depends[op] != RO) { + LOG(WARNING) << "op: " << _name << " has no RO access" + << "ot op: " << op << ", mode: " << node->depends[op] + << ", please check your configuration."; + return false; + } + + return true; } bool Op::is_readable(const std::string& op) const { - if (op == START_OP_NAME) { - return true; - } - DagNode* node = const_cast(_dag->node_by_name(_name)); - if (node->depends.find(op) == node->depends.end()) { - LOG(WARNING) - << "op: " << _name << " doesnot depend on " - << "op: " << op << "!"; - return false; - } - - if (node->depends[op] != RW && node->depends[op] != RO) { - LOG(WARNING) - << "op: " << _name << " has no RO access" - << "ot op: " << op << ", mode: " << node->depends[op] - << ", please check your configuration."; - return false; - } - + if (op == START_OP_NAME) { return true; + } + DagNode* node = const_cast(_dag->node_by_name(_name)); + if (node->depends.find(op) == node->depends.end()) { + LOG(WARNING) << "op: " << _name << " doesnot depend on " + << "op: " << op << "!"; + return false; + } + + if (node->depends[op] != RW && node->depends[op] != RO) { + LOG(WARNING) << "op: " << _name << " has no RO access" + << "ot op: " << op << ", mode: " << node->depends[op] + << ", please check your configuration."; + return false; + } + + return true; } -// OpChannel +// Get the Channel object of dependent OP Channel* Op::mutable_depend_channel(const std::string& op) { - if (!is_mutable(op)) { - LOG(WARNING) - << "Op: " << _name << " cannot mutable op: " - << op << "!"; - return NULL; - } - - // busлȡopchannel - return _bus->channel_by_name(op); + if (!is_mutable(op)) { + LOG(WARNING) << "Op: " << _name << " cannot mutable op: " << op << "!"; + return NULL; + } + + // Get the Channel object of dependent OP from bus + return _bus->channel_by_name(op); } -// OpChannel +// Get the Channel object of dependent OP const Channel* Op::get_depend_channel(const std::string& op) const { - // dagлȡopmode - if (!is_readable(op)) { - LOG(WARNING) - << "op: " << _name << " doesnot depend on op: " - << op << "!"; - return NULL; - } - - // busлȡopchannel - return _bus->channel_by_name(op); + // Get the `mode` attribute of dependent OP from dag + if (!is_readable(op)) { + LOG(WARNING) << "op: " << _name << " doesnot depend on op: " << op << "!"; + return NULL; + } + + // Get the Channel object of dependent OP from bus + return _bus->channel_by_name(op); } google::protobuf::Message* Op::mutable_message() { - return mutable_channel()->message(); + return mutable_channel()->message(); } const google::protobuf::Message* Op::get_message() const { - return get_channel()->message(); + return get_channel()->message(); } bool Op::has_calc() { return _has_calc; } -const char* Op::name() const { - return _name.c_str(); -} +const char* Op::name() const { return _name.c_str(); } -const std::string& Op::type() const { - return _type; -} +const std::string& Op::type() const { return _type; } -uint32_t Op::id() const { - return _id; -} +uint32_t Op::id() const { return _id; } const std::string Op::debug_string() { - const Channel* channel = get_channel(); - if (!channel) { - LOG(ERROR) << "Invalid channel!"; - return "Invalid channel in OP"; - } - return channel->debug_string(); + const Channel* channel = get_channel(); + if (!channel) { + LOG(ERROR) << "Invalid channel!"; + return "Invalid channel in OP"; + } + return channel->debug_string(); } const google::protobuf::Message* Op::get_request_message() { - return _bus->channel_by_name(START_OP_NAME)->message(); + return _bus->channel_by_name(START_OP_NAME)->message(); } -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/op/op.h b/predictor/op/op.h index bf922a0a67c5ce51ef2c1fc3f1508709319ba490..9e82ce3e5312507803527e34542e176a9c8c5f10 100644 --- a/predictor/op/op.h +++ b/predictor/op/op.h @@ -1,11 +1,24 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_OP_H - -#include // bvar::LatencyRecorder +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include // bvar::LatencyRecorder +#include #include "common/inner_common.h" #include "framework/channel.h" #include "framework/op_repository.h" -#include "framework/predictor_metric.h" // PredictorMetric +#include "framework/predictor_metric.h" // PredictorMetric namespace baidu { namespace paddle_serving { @@ -14,247 +27,234 @@ namespace predictor { class Dag; class Op { -public: - Op() : _bus(NULL), - _dag(NULL), - _has_calc(false), - _has_init(false), + public: + Op() + : _bus(NULL), + _dag(NULL), + _has_calc(false), + _has_init(false), _timer(NULL) {} - virtual ~Op() {} + virtual ~Op() {} - // ------OPChannel/Data/Messageݻȡӿ----- + // ------Getters for Channel/Data/Message of dependent OP----- - // OpChannel - Channel* mutable_depend_channel(const std::string& op); + // Get the Channel object of dependent OP + Channel* mutable_depend_channel(const std::string& op); - // OpChannel - const Channel* get_depend_channel(const std::string& op) const; + // Get the Channel object of dependent OP + const Channel* get_depend_channel(const std::string& op) const; - template - T* mutable_depend_argument(const std::string& op) { - Channel* channel = mutable_depend_channel(op); - if (channel == NULL) { - LOG(WARNING) << "cannot mutable channel of " << op - << " in " << _name; - return NULL; - } + template + T* mutable_depend_argument(const std::string& op) { + Channel* channel = mutable_depend_channel(op); + if (channel == NULL) { + LOG(WARNING) << "cannot mutable channel of " << op << " in " << _name; + return NULL; + } - OpChannel* op_channel = - dynamic_cast*>(channel); - if (!op_channel) { - LOG(ERROR) << "Cannot dynamic cast channel of op:" - << this->name() << " to type: " << typeid(T).name(); - return NULL; - } + OpChannel* op_channel = dynamic_cast*>(channel); + if (!op_channel) { + LOG(ERROR) << "Cannot dynamic cast channel of op:" << this->name() + << " to type: " << typeid(T).name(); + return NULL; + } - return op_channel->data(); + return op_channel->data(); + } + + template + const T* get_depend_argument(const std::string& op) const { + const Channel* channel = get_depend_channel(op); + if (channel == NULL) { + LOG(WARNING) << "cannot get read-only channel of " << op << " in " + << _name; + return NULL; } - template - const T* get_depend_argument(const std::string& op) const { - const Channel* channel = get_depend_channel(op); - if (channel == NULL) { - LOG(WARNING) << "cannot get read-only channel of " << op - << " in " << _name; - return NULL; - } - - const OpChannel* op_channel = - dynamic_cast*>(channel); - if (!op_channel) { - LOG(ERROR) << "Cannot dynamic cast channel of op:" - << this->name() << " to type: " << typeid(T).name(); - return NULL; - } - - return op_channel->data(); + const OpChannel* op_channel = dynamic_cast*>(channel); + if (!op_channel) { + LOG(ERROR) << "Cannot dynamic cast channel of op:" << this->name() + << " to type: " << typeid(T).name(); + return NULL; } - // -----ԵǰOPChannel/Data/Messageݻȡӿ---- + return op_channel->data(); + } - // øOPProtobuf messageָ - google::protobuf::Message* mutable_message(); + // -----Getters for Channel/Data/Message of current OP---- - // øOPProtobuf messageָ - const google::protobuf::Message* get_message() const; + // Get pointer to the progobuf message of current OP + google::protobuf::Message* mutable_message(); - // øOPģݶ - template - T* mutable_data() { - Channel* channel = mutable_channel(); - return (dynamic_cast*>(channel))->data(); - } + // Get pointer to the protobuf message of current OP + const google::protobuf::Message* get_message() const; - // øOPģݶ - template - const T* get_data() const { - const Channel* channel = get_channel(); - return (dynamic_cast*>(channel))->data(); - } + // Get the template class data object of current OP + template + T* mutable_data() { + Channel* channel = mutable_channel(); + return (dynamic_cast*>(channel))->data(); + } - // ---------------- Ա ---------------- + // Get the template class data object of current OP + template + const T* get_data() const { + const Channel* channel = get_channel(); + return (dynamic_cast*>(channel))->data(); + } - int init(Bus* bus, Dag* dag, uint32_t id, const std::string& name, - const std::string& type, void* conf); + // ---------------- Other base class members ---------------- - int deinit(); + int init(Bus* bus, + Dag* dag, + uint32_t id, + const std::string& name, + const std::string& type, + void* conf); - int check_time(const char* tag); + int deinit(); - int process(bool debug); + int check_time(const char* tag); - std::string time_info(); + int process(bool debug); - // - const google::protobuf::Message* get_request_message(); + std::string time_info(); - bool has_calc(); + // Get the input object + const google::protobuf::Message* get_request_message(); - const char* name() const; + bool has_calc(); - const std::string& full_name() const { - return _full_name; - } - - void set_full_name(const std::string full_name) { - _full_name = full_name; - } - - const std::string& type() const; + const char* name() const; + + const std::string& full_name() const { return _full_name; } + + void set_full_name(const std::string full_name) { _full_name = full_name; } - uint32_t id() const; + const std::string& type() const; - // --------------- Default implements ---------------- + uint32_t id() const; - virtual int custom_init() { return 0; } + // --------------- Default implements ---------------- - virtual int custom_deinit() { return 0; } + virtual int custom_init() { return 0; } - virtual const std::string debug_string(); + virtual int custom_deinit() { return 0; } - // ------------------ OP Interface ------------------- + virtual const std::string debug_string(); - // õǰOpChannel - virtual Channel* mutable_channel() = 0; + // ------------------ OP Interface ------------------- - // õǰOpChannel - virtual const Channel* get_channel() const = 0; + // Get the derived Channel object of current OP + virtual Channel* mutable_channel() = 0; - // ͷŵǰOpChannel - virtual int release_channel() = 0; + // Get the derived Channel object of current OP + virtual const Channel* get_channel() const = 0; - // ǰOpԶinferenceӿ - virtual int inference() = 0; + // Release the derived Channel object of current OP + virtual int release_channel() = 0; - // ------------------ Conf Interface ------------------- - virtual void* create_config(const configure::DAGNode& conf) { return NULL; } - - virtual void delete_config(void* conf) { } + // Inference interface + virtual int inference() = 0; - virtual void set_config(void* conf) { return; } + // ------------------ Conf Interface ------------------- + virtual void* create_config(const configure::DAGNode& conf) { return NULL; } - // ------------------ Metric Interface ------------------- - virtual void regist_metric() { return; } - -private: - bool is_mutable(const std::string& op); + virtual void delete_config(void* conf) {} - bool is_mutable(const std::string& op) const; + virtual void set_config(void* conf) { return; } - bool is_readable(const std::string& op); + // ------------------ Metric Interface ------------------- + virtual void regist_metric() { return; } - bool is_readable(const std::string& op) const; + private: + bool is_mutable(const std::string& op); -private: - Bus* _bus; - Dag* _dag; - uint32_t _id; - std::string _name; - std::string _full_name; // service_workflow_stageindex_opname - std::string _type; - bool _has_calc; - bool _has_init; - TimerFlow* _timer; + bool is_mutable(const std::string& op) const; + + bool is_readable(const std::string& op); + + bool is_readable(const std::string& op) const; + + private: + Bus* _bus; + Dag* _dag; + uint32_t _id; + std::string _name; + std::string _full_name; // service_workflow_stageindex_opname + std::string _type; + bool _has_calc; + bool _has_init; + TimerFlow* _timer; }; -template +template class OpWithChannel : public Op { -public: - typedef T DataType; - typedef OpChannel ChannelType; - - OpWithChannel() : _channel(NULL) {} - - virtual ~OpWithChannel() {} - - // ---------- Implements ---------- - - Channel* mutable_channel() { - if (_channel != NULL) { - return _channel; - } - - _channel = butil::get_object(); - if (!_channel) { - LOG(ERROR) - << "Failed mutable channel of type:" - << typeid(T).name(); - return NULL; - } - _channel->init(this->id(), this->name()); - return _channel; + public: + typedef T DataType; + typedef OpChannel ChannelType; + + OpWithChannel() : _channel(NULL) {} + + virtual ~OpWithChannel() {} + + // ---------- Implements ---------- + + Channel* mutable_channel() { + if (_channel != NULL) { + return _channel; } - const Channel* get_channel() const { - return _channel; + _channel = butil::get_object(); + if (!_channel) { + LOG(ERROR) << "Failed mutable channel of type:" << typeid(T).name(); + return NULL; } + _channel->init(this->id(), this->name()); + return _channel; + } - int release_channel() { - if (_channel) { - _channel->deinit(); - butil::return_object(_channel); - } + const Channel* get_channel() const { return _channel; } - _channel = NULL; - return 0; + int release_channel() { + if (_channel) { + _channel->deinit(); + butil::return_object(_channel); } - // ------------- Interface ------------- + _channel = NULL; + return 0; + } + + // ------------- Interface ------------- - // OpԶinferenceӿ - virtual int inference() = 0; + // Inference interface + virtual int inference() = 0; -private: - ChannelType* _channel; + private: + ChannelType* _channel; }; -template +template class OpWithChannelAndConf : public OpWithChannel { -public: - void set_config(void* conf) { - _conf = static_cast(conf); - } + public: + void set_config(void* conf) { _conf = static_cast(conf); } - C* get_self_config() { return _conf; } + C* get_self_config() { return _conf; } - virtual void delete_config(void* conf) { delete static_cast(conf); } + virtual void delete_config(void* conf) { delete static_cast(conf); } -private: - C* _conf; + private: + C* _conf; }; -#define DECLARE_OP(OP_TYPE) \ - OP_TYPE() { \ - REGISTER_OP(OP_TYPE); \ - } \ - static OP_TYPE _s_##OP_TYPE \ - -#define DEFINE_OP(OP_TYPE) \ - OP_TYPE OP_TYPE::_s_##OP_TYPE \ +#define DECLARE_OP(OP_TYPE) \ + OP_TYPE() { REGISTER_OP(OP_TYPE); } \ + static OP_TYPE _s_##OP_TYPE -} // predictor -} // paddle_serving -} // baidu +#define DEFINE_OP(OP_TYPE) OP_TYPE OP_TYPE::_s_##OP_TYPE -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/op/op_struct_demo.h b/predictor/op/op_struct_demo.h index 660c16c194bcf66b6ccb419d0cc100909d2bea64..7733803ec8162e55a004249098b29bdb62275ad3 100644 --- a/predictor/op/op_struct_demo.h +++ b/predictor/op/op_struct_demo.h @@ -1,36 +1,46 @@ -#ifndef BAIDU_PADDLE_SEVING_PREDICTOR_OP_STRUCT_DEMO_H -#define BAIDU_PADDLE_SEVING_PREDICTOR_OP_STRUCT_DEMO_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. + +#pragma once +#include #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { namespace predictor { struct DemoData { - boost::unordered_map name_id; - int data; + boost::unordered_map name_id; + int data; }; class StructOp : public OpWithChannel { -public: + public: + DECLARE_OP(StructOp); - DECLARE_OP(StructOp); + int inference() { + DemoData* data = mutable_data(); + data.data = 1; - int inference() { - DemoData* data = mutable_data(); - data.data = 1; - - return 0; - } + return 0; + } }; DEFINE_OP(StructOp); -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/plugin/stl_util-inl.h b/predictor/plugin/stl_util-inl.h index a2e671bb746126395e32ed5f90f3105012fe72ec..fba170ad65bf4d467913208022bdd95f5ff9b85d 100644 --- a/predictor/plugin/stl_util-inl.h +++ b/predictor/plugin/stl_util-inl.h @@ -1,3 +1,17 @@ +// 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. + // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ @@ -30,10 +44,9 @@ // from google3/util/gtl/stl_util-inl.h -#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ -#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ - +#pragma once #include +#include namespace google { namespace protobuf { @@ -49,8 +62,7 @@ namespace protobuf { // advanced, which could result in the hash function trying to deference a // stale pointer. template -void STLDeleteContainerPointers(ForwardIterator begin, - ForwardIterator end) { +void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) { while (begin != end) { ForwardIterator temp = begin; ++begin; @@ -96,7 +108,7 @@ inline char* string_as_array(string* str) { // ElementDeleter (defined below), which ensures that your container's elements // are deleted when the ElementDeleter goes out of scope. template -void STLDeleteElements(T *container) { +void STLDeleteElements(T* container) { if (!container) return; STLDeleteContainerPointers(container->begin(), container->end()); container->clear(); @@ -107,7 +119,7 @@ void STLDeleteElements(T *container) { // in the case it's given a NULL pointer. template -void STLDeleteValues(T *v) { +void STLDeleteValues(T* v) { if (!v) return; for (typename T::iterator i = v->begin(); i != v->end(); ++i) { delete i->second; @@ -117,5 +129,3 @@ void STLDeleteValues(T *v) { } // namespace protobuf } // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ diff --git a/predictor/plugin/strutil.h b/predictor/plugin/strutil.h index 4a79c2240cab438b6645a38c67b4594eaa39a4fe..4a2e53c2a70e3a58dfe2f627d98530f3da4960b1 100644 --- a/predictor/plugin/strutil.h +++ b/predictor/plugin/strutil.h @@ -1,3 +1,17 @@ +// 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. + // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ @@ -30,18 +44,17 @@ // from google3/strings/strutil.h -#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ -#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ - +#pragma once +#include #include +#include #include -#include namespace google { namespace protobuf { #ifdef _MSC_VER -#define strtoll _strtoi64 +#define strtoll _strtoi64 #define strtoull _strtoui64 #elif defined(__DECCXX) && defined(__osf__) // HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit. @@ -60,14 +73,11 @@ namespace protobuf { // ---------------------------------------------------------------------- inline bool ascii_isalnum(char c) { - return ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'); } -inline bool ascii_isdigit(char c) { - return ('0' <= c && c <= '9'); -} +inline bool ascii_isdigit(char c) { return ('0' <= c && c <= '9'); } // ---------------------------------------------------------------------- // HasPrefixString() @@ -77,8 +87,7 @@ inline bool ascii_isdigit(char c) { // prefix string if the prefix matches, otherwise the original // string. // ---------------------------------------------------------------------- -inline bool HasPrefixString(const string& str, - const string& prefix) { +inline bool HasPrefixString(const string& str, const string& prefix) { return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0; } @@ -99,8 +108,7 @@ inline string StripPrefixString(const string& str, const string& prefix) { // suffix string if the suffix matches, otherwise the original // string. // ---------------------------------------------------------------------- -inline bool HasSuffixString(const string& str, - const string& suffix) { +inline bool HasSuffixString(const string& str, const string& suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } @@ -120,7 +128,8 @@ inline string StripSuffixString(const string& str, const string& suffix) { // Good for keeping html characters or protocol characters (\t) out // of places where they might cause a problem. // ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove, +LIBPROTOBUF_EXPORT void StripString(string* s, + const char* remove, char replacewith); // ---------------------------------------------------------------------- @@ -132,7 +141,7 @@ LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove, // strings. // ---------------------------------------------------------------------- -inline void LowerString(string * s) { +inline void LowerString(string* s) { string::iterator end = s->end(); for (string::iterator i = s->begin(); i != end; ++i) { // tolower() changes based on locale. We don't want this! @@ -140,7 +149,7 @@ inline void LowerString(string * s) { } } -inline void UpperString(string * s) { +inline void UpperString(string* s) { string::iterator end = s->end(); for (string::iterator i = s->begin(); i != end; ++i) { // toupper() changes based on locale. We don't want this! @@ -156,8 +165,10 @@ inline void UpperString(string * s) { // happened or not. // ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all); +LIBPROTOBUF_EXPORT string StringReplace(const string& s, + const string& oldsub, + const string& newsub, + bool replace_all); // ---------------------------------------------------------------------- // SplitStringUsing() @@ -165,7 +176,8 @@ LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, // to 'result'. If there are consecutive delimiters, this function skips // over all of them. // ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, +LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, + const char* delim, vector* res); // ---------------------------------------------------------------------- @@ -177,10 +189,10 @@ LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, // target string is cleared and overwritten. // ---------------------------------------------------------------------- LIBPROTOBUF_EXPORT void JoinStrings(const vector& components, - const char* delim, string* result); + const char* delim, + string* result); -inline string JoinStrings(const vector& components, - const char* delim) { +inline string JoinStrings(const vector& components, const char* delim) { string result; JoinStrings(components, delim, &result); return result; @@ -218,8 +230,9 @@ inline string JoinStrings(const vector& components, // ---------------------------------------------------------------------- LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); -LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, - vector *errors); +LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, + char* dest, + vector* errors); // ---------------------------------------------------------------------- // UnescapeCEscapeString() @@ -237,8 +250,9 @@ LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, // ---------------------------------------------------------------------- LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); -LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, - vector *errors); +LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, + string* dest, + vector* errors); LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); // ---------------------------------------------------------------------- @@ -251,8 +265,10 @@ LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); // // Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. // ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len, - char* dest, int dest_len); +LIBPROTOBUF_EXPORT int CEscapeString(const char* src, + int src_len, + char* dest, + int dest_len); // ---------------------------------------------------------------------- // CEscape() @@ -281,20 +297,22 @@ LIBPROTOBUF_EXPORT string CHexEscape(const string& src); // platforms, so using these is safer, from the point of view of // overflow behavior, than using the standard libc functions. // ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr, +LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char* nptr, + char** endptr, int base); -LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr, +LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char* nptr, + char** endptr, int base); -inline int32 strto32(const char *nptr, char **endptr, int base) { - if (sizeof(int32) == sizeof(long)) +inline int32 strto32(const char* nptr, char** endptr, int base) { + if (sizeof(int32) == sizeof(long)) // NOLINT return strtol(nptr, endptr, base); else return strto32_adaptor(nptr, endptr, base); } -inline uint32 strtou32(const char *nptr, char **endptr, int base) { - if (sizeof(uint32) == sizeof(unsigned long)) +inline uint32 strtou32(const char* nptr, char** endptr, int base) { + if (sizeof(uint32) == sizeof(unsigned long)) // NOLINT return strtoul(nptr, endptr, base); else return strtou32_adaptor(nptr, endptr, base); @@ -302,14 +320,14 @@ inline uint32 strtou32(const char *nptr, char **endptr, int base) { // For now, long long is 64-bit on all the platforms we care about, so these // functions can simply pass the call to strto[u]ll. -inline int64 strto64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long), +inline int64 strto64(const char* nptr, char** endptr, int base) { + GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long), // NOLINT sizeof_int64_is_not_sizeof_long_long); return strtoll(nptr, endptr, base); } -inline uint64 strtou64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), +inline uint64 strtou64(const char* nptr, char** endptr, int base) { + GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), // NOLINT sizeof_uint64_is_not_sizeof_long_long); return strtoull(nptr, endptr, base); } @@ -350,20 +368,20 @@ LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer); // at least 22 bytes long inline char* FastIntToBuffer(int i, char* buffer) { - return (sizeof(i) == 4 ? - FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); + return (sizeof(i) == 4 ? FastInt32ToBuffer(i, buffer) + : FastInt64ToBuffer(i, buffer)); } inline char* FastUIntToBuffer(unsigned int i, char* buffer) { - return (sizeof(i) == 4 ? - FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); + return (sizeof(i) == 4 ? FastUInt32ToBuffer(i, buffer) + : FastUInt64ToBuffer(i, buffer)); } -inline char* FastLongToBuffer(long i, char* buffer) { - return (sizeof(i) == 4 ? - FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); +inline char* FastLongToBuffer(long i, char* buffer) { // NOLINT + return (sizeof(i) == 4 ? FastInt32ToBuffer(i, buffer) + : FastInt64ToBuffer(i, buffer)); } -inline char* FastULongToBuffer(unsigned long i, char* buffer) { - return (sizeof(i) == 4 ? - FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); +inline char* FastULongToBuffer(unsigned long i, char* buffer) { // NOLINT + return (sizeof(i) == 4 ? FastUInt32ToBuffer(i, buffer) + : FastUInt64ToBuffer(i, buffer)); } // ---------------------------------------------------------------------- @@ -405,10 +423,10 @@ inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { // ---------------------------------------------------------------------- LIBPROTOBUF_EXPORT string SimpleItoa(int i); LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i); -LIBPROTOBUF_EXPORT string SimpleItoa(long i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i); -LIBPROTOBUF_EXPORT string SimpleItoa(long long i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i); +LIBPROTOBUF_EXPORT string SimpleItoa(long i); // NOLINT +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i); // NOLINT +LIBPROTOBUF_EXPORT string SimpleItoa(long long i); // NOLINT +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i); // NOLINT // ---------------------------------------------------------------------- // SimpleDtoa() @@ -451,7 +469,3 @@ LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr); } // namespace protobuf } // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ - - diff --git a/predictor/plugin/substitute.cc b/predictor/plugin/substitute.cc index 240a49d5bcfc1cc4f9ee3202b52a6bc4b30ba815..7c432e52fb325a0b8f9f4381af6f805bcb91f991 100644 --- a/predictor/plugin/substitute.cc +++ b/predictor/plugin/substitute.cc @@ -1,3 +1,17 @@ +// 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. + // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ @@ -30,11 +44,11 @@ // Author: kenton@google.com (Kenton Varda) -//#include +// #include #include "plugin/strutil.h" -#include "plugin/substitute.h" #include "plugin/stl_util-inl.h" +#include "plugin/substitute.h" namespace google { namespace protobuf { @@ -52,53 +66,79 @@ static int CountSubstituteArgs(const SubstituteArg* const* args_array) { return count; } -string Substitute( - const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { +string Substitute(const char* format, + const SubstituteArg& arg0, + const SubstituteArg& arg1, + const SubstituteArg& arg2, + const SubstituteArg& arg3, + const SubstituteArg& arg4, + const SubstituteArg& arg5, + const SubstituteArg& arg6, + const SubstituteArg& arg7, + const SubstituteArg& arg8, + const SubstituteArg& arg9) { string result; - SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8, arg9); + SubstituteAndAppend(&result, + format, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9); return result; } -void SubstituteAndAppend( - string* output, const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - const SubstituteArg* const args_array[] = { - &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL - }; +void SubstituteAndAppend(string* output, + const char* format, + const SubstituteArg& arg0, + const SubstituteArg& arg1, + const SubstituteArg& arg2, + const SubstituteArg& arg3, + const SubstituteArg& arg4, + const SubstituteArg& arg5, + const SubstituteArg& arg6, + const SubstituteArg& arg7, + const SubstituteArg& arg8, + const SubstituteArg& arg9) { + const SubstituteArg* const args_array[] = {&arg0, + &arg1, + &arg2, + &arg3, + &arg4, + &arg5, + &arg6, + &arg7, + &arg8, + &arg9, + NULL}; // Determine total size needed. int size = 0; for (int i = 0; format[i] != '\0'; i++) { if (format[i] == '$') { - if (ascii_isdigit(format[i+1])) { - int index = format[i+1] - '0'; + if (ascii_isdigit(format[i + 1])) { + int index = format[i + 1] - '0'; if (args_array[index]->size() == -1) { GOOGLE_LOG(DFATAL) - << "strings::Substitute format string invalid: asked for \"$" - << index << "\", but only " << CountSubstituteArgs(args_array) - << " args were given. Full format string was: \"" - << CEscape(format) << "\"."; + << "strings::Substitute format string invalid: asked for \"$" + << index << "\", but only " << CountSubstituteArgs(args_array) + << " args were given. Full format string was: \"" + << CEscape(format) << "\"."; return; } size += args_array[index]->size(); ++i; // Skip next char. - } else if (format[i+1] == '$') { + } else if (format[i + 1] == '$') { ++size; ++i; // Skip next char. } else { - GOOGLE_LOG(DFATAL) - << "Invalid strings::Substitute() format string: \"" - << CEscape(format) << "\"."; + GOOGLE_LOG(DFATAL) << "Invalid strings::Substitute() format string: \"" + << CEscape(format) << "\"."; return; } } else { @@ -114,12 +154,12 @@ void SubstituteAndAppend( char* target = string_as_array(output) + original_size; for (int i = 0; format[i] != '\0'; i++) { if (format[i] == '$') { - if (ascii_isdigit(format[i+1])) { - const SubstituteArg* src = args_array[format[i+1] - '0']; + if (ascii_isdigit(format[i + 1])) { + const SubstituteArg* src = args_array[format[i + 1] - '0']; memcpy(target, src->data(), src->size()); target += src->size(); ++i; // Skip next char. - } else if (format[i+1] == '$') { + } else if (format[i + 1] == '$') { *target++ = '$'; ++i; // Skip next char. } diff --git a/predictor/plugin/substitute.h b/predictor/plugin/substitute.h index d7defccae5f45443d4aaa7ee577ef27c0907a9f5..c21cf3818a691bf5b725a9c151c8dd70ec51b328 100644 --- a/predictor/plugin/substitute.h +++ b/predictor/plugin/substitute.h @@ -1,3 +1,17 @@ +// 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. + // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ @@ -31,15 +45,13 @@ // Author: kenton@google.com (Kenton Varda) // from google3/strings/substitute.h -#include #include +#include // hmmm... -//#include +// #include #include "plugin/strutil.h" -#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ -#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ - +#pragma once namespace google { namespace protobuf { namespace strings { @@ -88,14 +100,13 @@ namespace internal { // Implementation details. class SubstituteArg { public: - inline SubstituteArg(const char* value) - : text_(value), size_(strlen(text_)) {} - inline SubstituteArg(const string& value) - : text_(value.data()), size_(value.size()) {} + explicit inline SubstituteArg(const char* value) + : text_(value), size_(strlen(text_)) {} + explicit inline SubstituteArg(const string& value) + : text_(value.data()), size_(value.size()) {} // Indicates that no argument was given. - inline explicit SubstituteArg() - : text_(NULL), size_(-1) {} + inline SubstituteArg() : text_(NULL), size_(-1) {} // Primitives // We don't overload for signed and unsigned char because if people are @@ -103,30 +114,37 @@ class SubstituteArg { // probably actually using them as 8-bit integers and would probably // prefer an integer representation. But, we don't really know. So, we // make the caller decide what to do. - inline SubstituteArg(char value) - : text_(scratch_), size_(1) { scratch_[0] = value; } - inline SubstituteArg(short value) - : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned short value) - : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(int value) - : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned int value) - : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(long value) - : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned long value) - : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(long long value) - : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned long long value) - : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(float value) - : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(double value) - : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(bool value) - : text_(value ? "true" : "false"), size_(strlen(text_)) {} + explicit inline SubstituteArg(char value) : text_(scratch_), size_(1) { + scratch_[0] = value; + } + explicit inline SubstituteArg(short value) // NOLINT + : text_(FastInt32ToBuffer(value, scratch_)), + size_(strlen(text_)) {} + explicit inline SubstituteArg(unsigned short value) // NOLINT + : text_(FastUInt32ToBuffer(value, scratch_)), + size_(strlen(text_)) {} + explicit inline SubstituteArg(int value) + : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + explicit inline SubstituteArg(unsigned int value) + : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + explicit inline SubstituteArg(long value) // NOLINT + : text_(FastLongToBuffer(value, scratch_)), + size_(strlen(text_)) {} + explicit inline SubstituteArg(unsigned long value) // NOLINT + : text_(FastULongToBuffer(value, scratch_)), + size_(strlen(text_)) {} + explicit inline SubstituteArg(long long value) // NOLINT + : text_(FastInt64ToBuffer(value, scratch_)), + size_(strlen(text_)) {} + explicit inline SubstituteArg(unsigned long long value) // NOLINT + : text_(FastUInt64ToBuffer(value, scratch_)), + size_(strlen(text_)) {} + explicit inline SubstituteArg(float value) + : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} + explicit inline SubstituteArg(double value) + : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} + explicit inline SubstituteArg(bool value) + : text_(value ? "true" : "false"), size_(strlen(text_)) {} inline const char* data() const { return text_; } inline int size() const { return size_; } @@ -139,34 +157,33 @@ class SubstituteArg { } // namespace internal -LIBPROTOBUF_EXPORT string Substitute( - const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); +LIBPROTOBUF_EXPORT string +Substitute(const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); LIBPROTOBUF_EXPORT void SubstituteAndAppend( - string* output, const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); + string* output, + const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); } // namespace strings } // namespace protobuf } // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ diff --git a/predictor/proto/builtin_format.proto b/predictor/proto/builtin_format.proto index 7683ec674e6406f55553089800213518a1259562..6666f6479393a4912ed23d02c24585a3caf6e1b0 100644 --- a/predictor/proto/builtin_format.proto +++ b/predictor/proto/builtin_format.proto @@ -1,15 +1,25 @@ -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"; import "pds_option.proto"; package baidu.paddle_serving.predictor.format; // dense format -message DenseInstance { - repeated float features = 1; -}; +message DenseInstance { repeated float features = 1; }; -message DensePrediction { - repeated float categories = 1; -}; +message DensePrediction { repeated float categories = 1; }; // sparse format message SparseInstance { @@ -18,9 +28,7 @@ message SparseInstance { repeated float values = 3; }; -message SparsePrediction { - repeated float categories = 1; -}; +message SparsePrediction { repeated float categories = 1; }; // int64-tensor format message Int64TensorInstance { @@ -39,9 +47,7 @@ message XImageReqInstance { required uint32 image_length = 2; }; -message XImageResInstance { - required string response_json = 1; -}; +message XImageResInstance { required string response_json = 1; }; // x-record format message XRecordInstance { diff --git a/predictor/proto/msg_data.proto b/predictor/proto/msg_data.proto index a0f665598cef405062f9da0e72734e4d30481673..41e262c80e10fa36c6c1c0f552e496c58590918c 100644 --- a/predictor/proto/msg_data.proto +++ b/predictor/proto/msg_data.proto @@ -1,7 +1,21 @@ -//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 pds.ut; message OpMessageData { - optional int32 a = 1 [default=33]; - optional float b = 2 [default=4.4]; + optional int32 a = 1 [ default = 33 ]; + optional float b = 2 [ default = 4.4 ]; }; diff --git a/predictor/proto/pds_option.proto b/predictor/proto/pds_option.proto index e6055c79e483f7f09c6067af42499fc475ac6048..c45c41ea8c5cd0f8378015c1abe575664ab61386 100644 --- a/predictor/proto/pds_option.proto +++ b/predictor/proto/pds_option.proto @@ -1,9 +1,23 @@ -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"; import "google/protobuf/descriptor.proto"; package pds; extend google.protobuf.FieldOptions { - optional bool pack_on = 70000 [default=false]; + optional bool pack_on = 70000 [ default = false ]; }; extend google.protobuf.ServiceOptions { @@ -11,6 +25,6 @@ extend google.protobuf.ServiceOptions { }; message PaddleServiceOption { - optional bool generate_impl = 1 [default = false]; - optional bool generate_stub = 2 [default = false]; + optional bool generate_impl = 1 [ default = false ]; + optional bool generate_stub = 2 [ default = false ]; }; diff --git a/predictor/proto/xrecord_format.proto b/predictor/proto/xrecord_format.proto index ef978e160d3e94af3d6ba961907f921b1ad04f95..445d14dbd25cd60702880bd0d20cb3a3e33605b7 100644 --- a/predictor/proto/xrecord_format.proto +++ b/predictor/proto/xrecord_format.proto @@ -1,50 +1,64 @@ -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 aialgs.data; message Float32Tensor { - repeated float values = 1; - repeated uint64 keys = 2; - repeated uint64 shape = 3; + repeated float values = 1; + repeated uint64 keys = 2; + repeated uint64 shape = 3; }; message Float64Tensor { - repeated double values = 1; - repeated uint64 keys = 2; - repeated uint64 shape = 3; + repeated double values = 1; + repeated uint64 keys = 2; + repeated uint64 shape = 3; }; message Int32Tensor { - repeated int32 values = 1; - repeated uint64 keys = 2; - repeated uint64 shape = 3; + repeated int32 values = 1; + repeated uint64 keys = 2; + repeated uint64 shape = 3; }; message Bytes { - repeated bytes value = 1; - optional string content_type = 2; + repeated bytes value = 1; + optional string content_type = 2; }; message Value { - optional Float32Tensor float32_tensor = 2; - optional Float64Tensor float64_tensor = 3; - optional Int32Tensor int32_tensor = 7; - optional Bytes bytes = 9; + optional Float32Tensor float32_tensor = 2; + optional Float64Tensor float64_tensor = 3; + optional Int32Tensor int32_tensor = 7; + optional Bytes bytes = 9; }; message Record { - message FeaturesEntry { - optional string key = 1; - optional Value value = 2; - }; - - message LabelEntry { - optional string key = 1; - optional Value value = 2; - }; - - repeated FeaturesEntry features = 1; - repeated LabelEntry label = 2; - optional string uid = 3; - optional string metadata = 4; - optional string configuration = 5; + message FeaturesEntry { + optional string key = 1; + optional Value value = 2; + }; + + message LabelEntry { + optional string key = 1; + optional Value value = 2; + }; + + repeated FeaturesEntry features = 1; + repeated LabelEntry label = 2; + optional string uid = 3; + optional string metadata = 4; + optional string configuration = 5; }; diff --git a/predictor/src/pdcodegen.cpp b/predictor/src/pdcodegen.cpp index 1a3a7047b1ff00549aec262861c14a1ed20cfca3..f4e4f30baafcb5cff6473bf3d730b5dd45606d6c 100644 --- a/predictor/src/pdcodegen.cpp +++ b/predictor/src/pdcodegen.cpp @@ -1,14 +1,28 @@ -#include -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include -#include -#include -#include -#include -#include +#include "boost/algorithm/string.hpp" +#include "boost/scoped_ptr.hpp" +#include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/compiler/plugin.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/io/zero_copy_stream.h" #include "plugin/strutil.h" #include "plugin/substitute.h" -#include "pds_option.pb.h" +#include "predictor/pds_option.pb.h" using std::string; using google::protobuf::Descriptor; using google::protobuf::FileDescriptor; @@ -22,715 +36,780 @@ using google::protobuf::StripSuffixString; namespace google { namespace protobuf { string dots_to_colons(const string& name) { - return StringReplace(name, ".", "::", true); + return StringReplace(name, ".", "::", true); } string full_class_name(const Descriptor* descriptor) { - // Find "outer", the descriptor of the top-level message in which - // "descriptor" is embedded. - const Descriptor* outer = descriptor; - while (outer->containing_type() != NULL) { - outer = outer->containing_type(); - } - return outer->full_name(); -} -} + // Find "outer", the descriptor of the top-level message in which + // "descriptor" is embedded. + const Descriptor* outer = descriptor; + while (outer->containing_type() != NULL) { + outer = outer->containing_type(); + } + return outer->full_name(); } +} // namespace protobuf +} // namespace google string strip_proto(const string& filename) { - if (HasSuffixString(filename, ".protolevel")) { - return StripSuffixString(filename, ".protolevel"); - } else { - return StripSuffixString(filename, ".proto"); - } + if (HasSuffixString(filename, ".protolevel")) { + return StripSuffixString(filename, ".protolevel"); + } else { + return StripSuffixString(filename, ".proto"); + } } -void string_format(std::string& source) { - size_t len = source.length(); - std::string sep = "_"; - for (int i = 0; i < len; i++) { - if (source[i] >= 'A' && source[i] <= 'Z') { - source[i] += 32; - if (i == 0) { - continue; - } - source.insert(i, sep); - i++; - len++; - } +void string_format(std::string& source) { // NOLINT + size_t len = source.length(); + std::string sep = "_"; + for (int i = 0; i < len; i++) { + if (source[i] >= 'A' && source[i] <= 'Z') { + source[i] += 32; + if (i == 0) { + continue; + } + source.insert(i, sep); + i++; + len++; } + } } bool valid_service_method(const std::vector& methods) { - if (methods.size() != 2) { - return false; - } - if (methods[0]->name() == "inference" && methods[1]->name() == "debug") { - return true; - } - if (methods[1]->name() == "inference" && methods[0]->name() == "debug") { - return true; - } + if (methods.size() != 2) { return false; + } + if (methods[0]->name() == "inference" && methods[1]->name() == "debug") { + return true; + } + if (methods[1]->name() == "inference" && methods[0]->name() == "debug") { + return true; + } + return false; } class PdsCodeGenerator : public CodeGenerator { -public: - virtual bool Generate( - const FileDescriptor* file, - const string& parameter, - GeneratorContext* context, - std::string* error) const { - const string header = strip_proto(file->name()) + ".pb.h"; - const string body = strip_proto(file->name()) + ".pb.cc"; - bool include_inserted = false; - for (int i = 0; i < file->service_count(); ++i) { - const ServiceDescriptor* descriptor = file->service(i); - if (!descriptor) { - *error = "get descriptor failed"; - return false; - } - pds::PaddleServiceOption options - = descriptor->options().GetExtension(pds::options); - bool generate_impl = options.generate_impl(); - bool generate_stub = options.generate_stub(); - if (!generate_impl && !generate_stub) { - return true; - } - if (!include_inserted) { - boost::scoped_ptr output( - context->OpenForInsert(header, "includes")); - google::protobuf::io::Printer printer(output.get(), '$'); - if (generate_impl) { - printer.Print("#include \"common/inner_common.h\"\n"); - printer.Print("#include \"framework/service.h\"\n"); - printer.Print("#include \"framework/manager.h\"\n"); - printer.Print("#include \"framework/service_manager.h\"\n"); - } - if (generate_stub) { - printer.Print("#include \n"); - printer.Print("#include \"factory.h\"\n"); - printer.Print("#include \"stub.h\"\n"); - printer.Print("#include \"stub_impl.h\"\n"); - } - include_inserted = true; - } - const std::string& class_name = descriptor->name(); - const std::string& service_name = descriptor->name(); - // xxx.ph.h - { - if (generate_impl) { - // service scope - // namespace scope - boost::scoped_ptr - output(context->OpenForInsert(header, "namespace_scope")); - google::protobuf::io::Printer printer(output.get(), '$'); - if (!generate_paddle_serving_head(&printer, descriptor, error, - service_name, class_name)) { - return false; - } - } - if (generate_stub) { - // service class scope - - // namespace scope - { - boost::scoped_ptr - output(context->OpenForInsert(header, "namespace_scope")); - google::protobuf::io::Printer printer(output.get(), '$'); - if (!generate_paddle_serving_stub_head(&printer, descriptor, error, - service_name, class_name)) { - return false; - } - } - } - - } - // xxx.pb.cc - { - if (generate_impl) { - // service scope - // namespace scope - boost::scoped_ptr - output(context->OpenForInsert(body, "namespace_scope")); - google::protobuf::io::Printer printer(output.get(), '$'); - if (!generate_paddle_serving_body(&printer, descriptor, error, - service_name, class_name)) { - return false; - } - } - if (generate_stub) { - // service class scope - { - } - // namespace scope - { - boost::scoped_ptr - output(context->OpenForInsert(body, "namespace_scope")); - google::protobuf::io::Printer printer(output.get(), '$'); - if (!generate_paddle_serving_stub_body(&printer, descriptor, error, - service_name, class_name)) { - return false; - } - } - } - } - } + public: + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + std::string* error) const { + const string header = strip_proto(file->name()) + ".pb.h"; + const string body = strip_proto(file->name()) + ".pb.cc"; + bool include_inserted = false; + for (int i = 0; i < file->service_count(); ++i) { + const ServiceDescriptor* descriptor = file->service(i); + if (!descriptor) { + *error = "get descriptor failed"; + return false; + } + pds::PaddleServiceOption options = + descriptor->options().GetExtension(pds::options); + bool generate_impl = options.generate_impl(); + bool generate_stub = options.generate_stub(); + if (!generate_impl && !generate_stub) { return true; - } -private: - bool generate_paddle_serving_head( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { - std::vector methods; - for (int i = 0; i < descriptor->method_count(); ++i) { - methods.push_back(descriptor->method(i)); + } + if (!include_inserted) { + boost::scoped_ptr output( + context->OpenForInsert(header, "includes")); + google::protobuf::io::Printer printer(output.get(), '$'); + if (generate_impl) { + printer.Print("#include \"common/inner_common.h\"\n"); + printer.Print("#include \"framework/service.h\"\n"); + printer.Print("#include \"framework/manager.h\"\n"); + printer.Print("#include \"framework/service_manager.h\"\n"); } - if (!valid_service_method(methods)) { - *error = "Service can only contains two methods: inferend, debug"; - return false; + if (generate_stub) { + printer.Print("#include \n"); + printer.Print("#include \"factory.h\"\n"); + printer.Print("#include \"stub.h\"\n"); + printer.Print("#include \"stub_impl.h\"\n"); } - std::string variable_name = class_name; - string_format(variable_name); - printer->Print( - "class $name$Impl : public $name$ {\n" - "public:\n" - " virtual ~$name$Impl() {}\n" - " static $name$Impl& instance() {\n" - " return _s_$variable_name$_impl;\n" - " }\n\n" - " $name$Impl(const std::string& service_name) {\n" - " REGIST_FORMAT_SERVICE(\n" - " service_name, &$name$Impl::instance());\n" - " }\n\n", - "name", class_name, "variable_name", variable_name); - for (int i = 0; i < methods.size(); i++) { - const MethodDescriptor* m = methods[i]; - printer->Print( - " virtual void $name$(google::protobuf::RpcController* cntl_base,\n" - " const $input_name$* request,\n" - " $output_name$* response,\n" - " google::protobuf::Closure* done);\n\n", - "name", m->name(), - "input_name", google::protobuf::dots_to_colons(m->input_type()->full_name()), - "output_name", google::protobuf::dots_to_colons(m->output_type()->full_name())); + include_inserted = true; + } + const std::string& class_name = descriptor->name(); + const std::string& service_name = descriptor->name(); + // xxx.ph.h + { + if (generate_impl) { + // service scope + // namespace scope + boost::scoped_ptr output( + context->OpenForInsert(header, "namespace_scope")); + google::protobuf::io::Printer printer(output.get(), '$'); + if (!generate_paddle_serving_head( + &printer, descriptor, error, service_name, class_name)) { + return false; + } } - printer->Print( - " static $name$Impl _s_$variable_name$_impl;\n" - "};", "name", class_name, "variable_name", variable_name); - return true; - } - bool generate_paddle_serving_body( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { - std::vector methods; - for (int i = 0; i < descriptor->method_count(); ++i) { - methods.push_back(descriptor->method(i)); + if (generate_stub) { + // service class scope + + // namespace scope + { + boost::scoped_ptr + output(context->OpenForInsert(header, "namespace_scope")); + google::protobuf::io::Printer printer(output.get(), '$'); + if (!generate_paddle_serving_stub_head( + &printer, descriptor, error, service_name, class_name)) { + return false; + } + } } - if (!valid_service_method(methods)) { - *error = "Service can only contains two methods: inferend, debug"; - return false; + } + // xxx.pb.cc + { + if (generate_impl) { + // service scope + // namespace scope + boost::scoped_ptr output( + context->OpenForInsert(body, "namespace_scope")); + google::protobuf::io::Printer printer(output.get(), '$'); + if (!generate_paddle_serving_body( + &printer, descriptor, error, service_name, class_name)) { + return false; + } } - std::string variable_name = class_name; - string_format(variable_name); - for (int i = 0; i < methods.size(); i++) { - const MethodDescriptor* m = methods[i]; - printer->Print( - "void $name$Impl::$method$(\n", - "name", class_name, "method", m->name()); - printer->Print( - " google::protobuf::RpcController* cntl_base,\n" - " const $input_name$* request,\n" - " $output_name$* response,\n" - " google::protobuf::Closure* done) {\n" - " struct timeval tv;\n" - " gettimeofday(&tv, NULL);" - " long start = tv.tv_sec * 1000000 + tv.tv_usec;", - "input_name", google::protobuf::dots_to_colons(m->input_type()->full_name()), - "output_name", google::protobuf::dots_to_colons(m->output_type()->full_name())); - if (m->name() == "inference") { - printer->Print( - " brpc::ClosureGuard done_guard(done);\n" - " brpc::Controller* cntl = \n" - " static_cast(cntl_base);\n" - " ::baidu::paddle_serving::predictor::InferService* svr = \n" - " ::baidu::paddle_serving::predictor::InferServiceManager::instance().item(\"$service$\");\n" - " if (svr == NULL) {\n" - " LOG(ERROR) << \"Not found service: $service$\";\n" - " cntl->SetFailed(404, \"Not found service: $service$\");\n" - " return ;\n" - " }\n" - " LOG(INFO) << \" remote_side=\[\" << cntl->remote_side() << \"\]\";\n" - " LOG(INFO) << \" local_side=\[\" << cntl->local_side() << \"\]\";\n" - " LOG(INFO) << \" service_name=\[\" << \"$name$\" << \"\]\";\n" - " LOG(INFO) << \" log_id=\[\" << cntl->log_id() << \"\]\";\n" - " int err_code = svr->inference(request, response);\n" - " if (err_code != 0) {\n" - " LOG(WARNING)\n" - " << \"Failed call inferservice[$name$], name[$service$]\"\n" - " << \", error_code: \" << err_code;\n" - " cntl->SetFailed(err_code, \"InferService inference failed!\");\n" - " }\n" - " gettimeofday(&tv, NULL);\n" - " long end = tv.tv_sec * 1000000 + tv.tv_usec;\n" - " // flush notice log\n" - " LOG(INFO) << \" tc=\[\" << (end - start) << \"\]\";\n", - "name", class_name, "service", service_name); - } - if (m->name() == "debug") { - printer->Print( - " brpc::ClosureGuard done_guard(done);\n" - " brpc::Controller* cntl = \n" - " static_cast(cntl_base);\n" - " ::baidu::paddle_serving::predictor::InferService* svr = \n" - " ::baidu::paddle_serving::predictor::InferServiceManager::instance().item(\"$service$\");\n" - " if (svr == NULL) {\n" - " LOG(ERROR) << \"Not found service: $service$\";\n" - " cntl->SetFailed(404, \"Not found service: $service$\");\n" - " return ;\n" - " }\n" - " LOG(INFO) << \" remote_side=\[\" << cntl->remote_side() << \"\]\";\n" - " LOG(INFO) << \" local_side=\[\" << cntl->local_side() << \"\]\";\n" - " LOG(INFO) << \" service_name=\[\" << \"$name$\" << \"\]\";\n" - " LOG(INFO) << \" log_id=\[\" << cntl->log_id() << \"\]\";\n" - " butil::IOBufBuilder debug_os;\n" - " int err_code = svr->inference(request, response, &debug_os);\n" - " if (err_code != 0) {\n" - " LOG(WARNING)\n" - " << \"Failed call inferservice[$name$], name[$service$]\"\n" - " << \", error_code: \" << err_code;\n" - " cntl->SetFailed(err_code, \"InferService inference failed!\");\n" - " }\n" - " debug_os.move_to(cntl->response_attachment());\n" - " gettimeofday(&tv, NULL);\n" - " long end = tv.tv_sec * 1000000 + tv.tv_usec;\n" - " // flush notice log\n" - " LOG(INFO) << \" tc=\[\" << (end - start) << \"\]\";\n" - " LOG(INFO)\n" - " << \"TC=[\" << (end - start) << \"] Received debug request[log_id=\" << cntl->log_id()\n" - " << \"] from \" << cntl->remote_side()\n" - " << \" to \" << cntl->local_side();\n", - "name", class_name, "service", service_name); + if (generate_stub) { + // service class scope + {} // namespace scope + { + boost::scoped_ptr + output(context->OpenForInsert(body, "namespace_scope")); + google::protobuf::io::Printer printer(output.get(), '$'); + if (!generate_paddle_serving_stub_body( + &printer, descriptor, error, service_name, class_name)) { + return false; } - printer->Print("}\n"); + } } - printer->Print( - "$name$Impl $name$Impl::_s_$variable_name$_impl(\"$service$\");\n", - "name", class_name, - "variable_name", variable_name, - "service", service_name); - return true; + } + } + return true; + } + + private: + bool generate_paddle_serving_head(google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + std::vector methods; + for (int i = 0; i < descriptor->method_count(); ++i) { + methods.push_back(descriptor->method(i)); + } + if (!valid_service_method(methods)) { + *error = "Service can only contains two methods: inferend, debug"; + return false; } - bool generate_paddle_serving_stub_head( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { + std::string variable_name = class_name; + string_format(variable_name); + printer->Print( + "class $name$Impl : public $name$ {\n" + "public:\n" + " virtual ~$name$Impl() {}\n" + " static $name$Impl& instance() {\n" + " return _s_$variable_name$_impl;\n" + " }\n\n" + " $name$Impl(const std::string& service_name) {\n" + " REGIST_FORMAT_SERVICE(\n" + " service_name, &$name$Impl::instance());\n" + " }\n\n", + "name", + class_name, + "variable_name", + variable_name); + for (int i = 0; i < methods.size(); i++) { + const MethodDescriptor* m = methods[i]; + printer->Print( + " virtual void $name$(google::protobuf::RpcController* cntl_base,\n" + " const $input_name$* request,\n" + " $output_name$* response,\n" + " google::protobuf::Closure* done);\n\n", + "name", + m->name(), + "input_name", + google::protobuf::dots_to_colons(m->input_type()->full_name()), + "output_name", + google::protobuf::dots_to_colons(m->output_type()->full_name())); + } + printer->Print( + " static $name$Impl _s_$variable_name$_impl;\n" + "};", + "name", + class_name, + "variable_name", + variable_name); + return true; + } + bool generate_paddle_serving_body(google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + std::vector methods; + for (int i = 0; i < descriptor->method_count(); ++i) { + methods.push_back(descriptor->method(i)); + } + if (!valid_service_method(methods)) { + *error = "Service can only contains two methods: inferend, debug"; + return false; + } + std::string variable_name = class_name; + string_format(variable_name); + for (int i = 0; i < methods.size(); i++) { + const MethodDescriptor* m = methods[i]; + printer->Print("void $name$Impl::$method$(\n", + "name", + class_name, + "method", + m->name()); + printer->Print( + " google::protobuf::RpcController* cntl_base,\n" + " const $input_name$* request,\n" + " $output_name$* response,\n" + " google::protobuf::Closure* done) {\n" + " struct timeval tv;\n" + " gettimeofday(&tv, NULL);" + " long start = tv.tv_sec * 1000000 + tv.tv_usec;", + "input_name", + google::protobuf::dots_to_colons(m->input_type()->full_name()), + "output_name", + google::protobuf::dots_to_colons(m->output_type()->full_name())); + if (m->name() == "inference") { printer->Print( - "class $name$_StubCallMapper : public brpc::CallMapper {\n" - "private:\n" - " uint32_t _package_size;\n" - " baidu::paddle_serving::sdk_cpp::Stub* _stub_handler;\n" - "public:\n", "name", class_name); - printer->Indent(); + " brpc::ClosureGuard done_guard(done);\n" + " brpc::Controller* cntl = \n" + " static_cast(cntl_base);\n" + " ::baidu::paddle_serving::predictor::InferService* svr = \n" + " " + "::baidu::paddle_serving::predictor::InferServiceManager::instance(" + ").item(\"$service$\");\n" + " if (svr == NULL) {\n" + " LOG(ERROR) << \"Not found service: $service$\";\n" + " cntl->SetFailed(404, \"Not found service: $service$\");\n" + " return ;\n" + " }\n" + " LOG(INFO) << \" remote_side=\[\" << cntl->remote_side() << " // NOLINT + "\"\]\";\n" + " LOG(INFO) << \" local_side=\[\" << cntl->local_side() << " // NOLINT + "\"\]\";\n" + " LOG(INFO) << \" service_name=\[\" << \"$name$\" << \"\]\";\n" // NOLINT + " LOG(INFO) << \" log_id=\[\" << cntl->log_id() << \"\]\";\n" // NOLINT + " int err_code = svr->inference(request, response);\n" + " if (err_code != 0) {\n" + " LOG(WARNING)\n" + " << \"Failed call inferservice[$name$], name[$service$]\"\n" + " << \", error_code: \" << err_code;\n" + " cntl->SetFailed(err_code, \"InferService inference " + "failed!\");\n" + " }\n" + " gettimeofday(&tv, NULL);\n" + " long end = tv.tv_sec * 1000000 + tv.tv_usec;\n" + " // flush notice log\n" + " LOG(INFO) << \" tc=\[\" << (end - start) << \"\]\";\n", // NOLINT + "name", + class_name, + "service", + service_name); + } + if (m->name() == "debug") { printer->Print( - "$name$_StubCallMapper(uint32_t package_size, baidu::paddle_serving::sdk_cpp::Stub* stub) {\n" - " _package_size = package_size;\n" - " _stub_handler = stub;\n" - "}\n", "name", class_name); + " brpc::ClosureGuard done_guard(done);\n" + " brpc::Controller* cntl = \n" + " static_cast(cntl_base);\n" + " ::baidu::paddle_serving::predictor::InferService* svr = \n" + " " + "::baidu::paddle_serving::predictor::InferServiceManager::instance(" + ").item(\"$service$\");\n" + " if (svr == NULL) {\n" + " LOG(ERROR) << \"Not found service: $service$\";\n" + " cntl->SetFailed(404, \"Not found service: $service$\");\n" + " return ;\n" + " }\n" + " LOG(INFO) << \" remote_side=\[\" << cntl->remote_side() << " // NOLINT + "\"\]\";\n" + " LOG(INFO) << \" local_side=\[\" << cntl->local_side() << " // NOLINT + "\"\]\";\n" + " LOG(INFO) << \" service_name=\[\" << \"$name$\" << \"\]\";\n" // NOLINT + " LOG(INFO) << \" log_id=\[\" << cntl->log_id() << \"\]\";\n" // NOLINT + " butil::IOBufBuilder debug_os;\n" + " int err_code = svr->inference(request, response, &debug_os);\n" + " if (err_code != 0) {\n" + " LOG(WARNING)\n" + " << \"Failed call inferservice[$name$], name[$service$]\"\n" + " << \", error_code: \" << err_code;\n" + " cntl->SetFailed(err_code, \"InferService inference " + "failed!\");\n" + " }\n" + " debug_os.move_to(cntl->response_attachment());\n" + " gettimeofday(&tv, NULL);\n" + " long end = tv.tv_sec * 1000000 + tv.tv_usec;\n" + " // flush notice log\n" + " LOG(INFO) << \" tc=\[\" << (end - start) << \"\]\";\n" // NOLINT + " LOG(INFO)\n" + " << \"TC=[\" << (end - start) << \"] Received debug " + "request[log_id=\" << cntl->log_id()\n" + " << \"] from \" << cntl->remote_side()\n" + " << \" to \" << cntl->local_side();\n", + "name", + class_name, + "service", + service_name); + } + printer->Print("}\n"); + } + printer->Print( + "$name$Impl $name$Impl::_s_$variable_name$_impl(\"$service$\");\n", + "name", + class_name, + "variable_name", + variable_name, + "service", + service_name); + return true; + } + bool generate_paddle_serving_stub_head(google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + printer->Print( + "class $name$_StubCallMapper : public brpc::CallMapper {\n" + "private:\n" + " uint32_t _package_size;\n" + " baidu::paddle_serving::sdk_cpp::Stub* _stub_handler;\n" + "public:\n", + "name", + class_name); + printer->Indent(); + printer->Print( + "$name$_StubCallMapper(uint32_t package_size, " + "baidu::paddle_serving::sdk_cpp::Stub* stub) {\n" + " _package_size = package_size;\n" + " _stub_handler = stub;\n" + "}\n", + "name", + class_name); - printer->Print( - "brpc::SubCall default_map(\n" - " int channel_index,\n" - " const google::protobuf::MethodDescriptor* method,\n" - " const google::protobuf::Message* request,\n" - " google::protobuf::Message* response) {\n" - " baidu::paddle_serving::sdk_cpp::TracePackScope scope(\"default_map\", channel_index);", - "name", class_name); - printer->Indent(); + printer->Print( + "brpc::SubCall default_map(\n" + " int channel_index,\n" + " const google::protobuf::MethodDescriptor* method,\n" + " const google::protobuf::Message* request,\n" + " google::protobuf::Message* response) {\n" + " baidu::paddle_serving::sdk_cpp::TracePackScope " + "scope(\"default_map\", channel_index);", + "name", + class_name); + printer->Indent(); - if (!generate_paddle_serving_stub_default_map(printer, descriptor, error, - service_name, class_name)) { - return false; - } + if (!generate_paddle_serving_stub_default_map( + printer, descriptor, error, service_name, class_name)) { + return false; + } - printer->Outdent(); - printer->Print( - "}\n"); + printer->Outdent(); + printer->Print("}\n"); - printer->Print( - "brpc::SubCall sub_package_map(\n" - " int channel_index,\n" - " const google::protobuf::MethodDescriptor* method,\n" - " const google::protobuf::Message* request,\n" - " google::protobuf::Message* response) {\n" - " baidu::paddle_serving::sdk_cpp::TracePackScope scope(\"sub_map\", channel_index);", - "name", class_name); - printer->Indent(); + printer->Print( + "brpc::SubCall sub_package_map(\n" + " int channel_index,\n" + " const google::protobuf::MethodDescriptor* method,\n" + " const google::protobuf::Message* request,\n" + " google::protobuf::Message* response) {\n" + " baidu::paddle_serving::sdk_cpp::TracePackScope scope(\"sub_map\", " + "channel_index);", + "name", + class_name); + printer->Indent(); - std::vector in_shared_fields; - std::vector in_item_fields; - const MethodDescriptor* md = descriptor->FindMethodByName("inference"); - if (!md) { - *error = "not found inference method!"; - return false; - } - for (int i = 0; i < md->input_type()->field_count(); ++i) { - const FieldDescriptor* fd = md->input_type()->field(i); - if (!fd) { - *error = "invalid fd at: " + i; - return false; - } - bool pack_on = fd->options().GetExtension(pds::pack_on); - if (pack_on && !fd->is_repeated()) { - *error = "Pack fields must be repeated, field: " + fd->name(); - return false; - } - if (pack_on) { - in_item_fields.push_back(fd); - } else { - in_shared_fields.push_back(fd); - } - } + std::vector in_shared_fields; + std::vector in_item_fields; + const MethodDescriptor* md = descriptor->FindMethodByName("inference"); + if (!md) { + *error = "not found inference method!"; + return false; + } + for (int i = 0; i < md->input_type()->field_count(); ++i) { + const FieldDescriptor* fd = md->input_type()->field(i); + if (!fd) { + *error = "invalid fd at: " + i; + return false; + } + bool pack_on = fd->options().GetExtension(pds::pack_on); + if (pack_on && !fd->is_repeated()) { + *error = "Pack fields must be repeated, field: " + fd->name(); + return false; + } + if (pack_on) { + in_item_fields.push_back(fd); + } else { + in_shared_fields.push_back(fd); + } + } - if (!generate_paddle_serving_stub_package_map(printer, descriptor, error, - service_name, class_name, in_shared_fields, in_item_fields)) { - return false; - } - printer->Outdent(); - printer->Print( - "}\n"); + if (!generate_paddle_serving_stub_package_map(printer, + descriptor, + error, + service_name, + class_name, + in_shared_fields, + in_item_fields)) { + return false; + } + printer->Outdent(); + printer->Print("}\n"); - printer->Print( - "brpc::SubCall Map(\n" - " int channel_index,\n" - " const google::protobuf::MethodDescriptor* method,\n" - " const google::protobuf::Message* request,\n" - " google::protobuf::Message* response) {\n", - "name", class_name); - printer->Indent(); + printer->Print( + "brpc::SubCall Map(\n" + " int channel_index,\n" + " const google::protobuf::MethodDescriptor* method,\n" + " const google::protobuf::Message* request,\n" + " google::protobuf::Message* response) {\n", + "name", + class_name); + printer->Indent(); - if (in_item_fields.size() <= 0) { - printer->Print( - "// No packed items found in proto file, use default map method\n" - "return default_map(channel_index, method, request, response);\n"); - } else { - printer->Print( - "butil::Timer tt(butil::Timer::STARTED);\n" - "brpc::SubCall ret;\n" - "if (_package_size == 0) {\n" - " ret = default_map(channel_index, method, request, response);\n" - "} else {\n" - " ret = sub_package_map(channel_index, method, request, response);\n" - "}\n" - "tt.stop();\n" - "if (ret.flags != brpc::SKIP_SUB_CHANNEL && ret.method != NULL) {\n" - " _stub_handler->update_latency(tt.u_elapsed(), \"pack_map\");\n" - "}\n" - "return ret;\n"); - } - - printer->Outdent(); - printer->Print("}\n"); + if (in_item_fields.size() <= 0) { + printer->Print( + "// No packed items found in proto file, use default map method\n" + "return default_map(channel_index, method, request, response);\n"); + } else { + printer->Print( + "butil::Timer tt(butil::Timer::STARTED);\n" + "brpc::SubCall ret;\n" + "if (_package_size == 0) {\n" + " ret = default_map(channel_index, method, request, response);\n" + "} else {\n" + " ret = sub_package_map(channel_index, method, request, " + "response);\n" + "}\n" + "tt.stop();\n" + "if (ret.flags != brpc::SKIP_SUB_CHANNEL && ret.method != NULL) {\n" + " _stub_handler->update_latency(tt.u_elapsed(), \"pack_map\");\n" + "}\n" + "return ret;\n"); + } - printer->Outdent(); - printer->Print("};\n"); - - //////////////////////////////////////////////////////////////// - printer->Print( - "class $name$_StubResponseMerger : public brpc::ResponseMerger {\n" - "private:\n" - " uint32_t _package_size;\n" - " baidu::paddle_serving::sdk_cpp::Stub* _stub_handler;\n" - "public:\n", "name", class_name); - printer->Indent(); - printer->Print( - "$name$_StubResponseMerger(uint32_t package_size, baidu::paddle_serving::sdk_cpp::Stub* stub) {\n" - " _package_size = package_size;\n" - " _stub_handler = stub;\n" - "}\n", "name", class_name); - - printer->Print( - "brpc::ResponseMerger::Result default_merge(\n" - " google::protobuf::Message* response,\n" - " const google::protobuf::Message* sub_response) {\n" - " baidu::paddle_serving::sdk_cpp::TracePackScope scope(\"default_merge\");", - "name", class_name); - printer->Indent(); - if (!generate_paddle_serving_stub_default_merger(printer, descriptor, error, - service_name, class_name)) { - return false; - } - printer->Outdent(); - printer->Print( - "}\n"); + printer->Outdent(); + printer->Print("}\n"); - printer->Print( - "brpc::ResponseMerger::Result sub_package_merge(\n" - " google::protobuf::Message* response,\n" - " const google::protobuf::Message* sub_response) {\n" - " baidu::paddle_serving::sdk_cpp::TracePackScope scope(\"sub_merge\");", - "name", class_name); - printer->Indent(); - if (!generate_paddle_serving_stub_package_merger(printer, descriptor, error, - service_name, class_name)) { - return false; - } - printer->Outdent(); - printer->Print( - "}\n"); + printer->Outdent(); + printer->Print("};\n"); - printer->Print( - "brpc::ResponseMerger::Result Merge(\n" - " google::protobuf::Message* response,\n" - " const google::protobuf::Message* sub_response) {\n", - "name", class_name); - printer->Indent(); - printer->Print( - "butil::Timer tt(butil::Timer::STARTED);\n" - "brpc::ResponseMerger::Result ret;" - "if (_package_size <= 0) {\n" - " ret = default_merge(response, sub_response);\n" - "} else {\n" - " ret = sub_package_merge(response, sub_response);\n" - "}\n" - "tt.stop();\n" - "if (ret != brpc::ResponseMerger::FAIL) {\n" - " _stub_handler->update_latency(tt.u_elapsed(), \"pack_merge\");\n" - "}\n" - "return ret;\n"); - printer->Outdent(); - printer->Print("}\n"); + //////////////////////////////////////////////////////////////// + printer->Print( + "class $name$_StubResponseMerger : public brpc::ResponseMerger {\n" + "private:\n" + " uint32_t _package_size;\n" + " baidu::paddle_serving::sdk_cpp::Stub* _stub_handler;\n" + "public:\n", + "name", + class_name); + printer->Indent(); + printer->Print( + "$name$_StubResponseMerger(uint32_t package_size, " + "baidu::paddle_serving::sdk_cpp::Stub* stub) {\n" + " _package_size = package_size;\n" + " _stub_handler = stub;\n" + "}\n", + "name", + class_name); - printer->Outdent(); - printer->Print("};\n"); - return true; - } - bool generate_paddle_serving_stub_default_map( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { - printer->Print( - "if (channel_index > 0) { \n" - " return brpc::SubCall::Skip();\n" - "}\n"); - printer->Print( - "google::protobuf::Message* cur_res = _stub_handler->fetch_response();\n" - "if (cur_res == NULL) {\n" - " LOG(INFO) << \"Failed fetch response from stub handler, new it\";\n" - " cur_res = response->New();\n" - " if (cur_res == NULL) {\n" - " LOG(ERROR) << \"Failed new response item!\";\n" - " _stub_handler->update_average(1, \"pack_fail\");\n" - " return brpc::SubCall::Bad();\n" - " }\n" - " return brpc::SubCall(method, request, cur_res, brpc::DELETE_RESPONSE);\n" - "}\n"); - "LOG(INFO) \n" - " << \"[default] Succ map, channel_index: \" << channel_index;\n"; - printer->Print( - "return brpc::SubCall(method, request, cur_res, 0);\n" - ); - return true; - } - bool generate_paddle_serving_stub_default_merger( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { - printer->Print( - "try {\n" - " response->MergeFrom(*sub_response);\n" - " return brpc::ResponseMerger::MERGED;\n" - "} catch (const std::exception& e) {\n" - " LOG(ERROR) << \"Merge failed.\";\n" - " _stub_handler->update_average(1, \"pack_fail\");\n" - " return brpc::ResponseMerger::FAIL;\n" - "}\n"); - return true; + printer->Print( + "brpc::ResponseMerger::Result default_merge(\n" + " google::protobuf::Message* response,\n" + " const google::protobuf::Message* sub_response) {\n" + " baidu::paddle_serving::sdk_cpp::TracePackScope " + "scope(\"default_merge\");", + "name", + class_name); + printer->Indent(); + if (!generate_paddle_serving_stub_default_merger( + printer, descriptor, error, service_name, class_name)) { + return false; } - bool generate_paddle_serving_stub_package_map( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name, - std::vector& in_shared_fields, - std::vector& in_item_fields) const { - const MethodDescriptor* md = descriptor->FindMethodByName("inference"); - if (!md) { - *error = "not found inference method!"; - return false; - } + printer->Outdent(); + printer->Print("}\n"); - printer->Print( - "const $req_type$* req \n" - " = dynamic_cast(request);\n" - "$req_type$* sub_req = NULL;", - "req_type", google::protobuf::dots_to_colons( - md->input_type()->full_name())); + printer->Print( + "brpc::ResponseMerger::Result sub_package_merge(\n" + " google::protobuf::Message* response,\n" + " const google::protobuf::Message* sub_response) {\n" + " baidu::paddle_serving::sdk_cpp::TracePackScope " + "scope(\"sub_merge\");", + "name", + class_name); + printer->Indent(); + if (!generate_paddle_serving_stub_package_merger( + printer, descriptor, error, service_name, class_name)) { + return false; + } + printer->Outdent(); + printer->Print("}\n"); - + printer->Print( + "brpc::ResponseMerger::Result Merge(\n" + " google::protobuf::Message* response,\n" + " const google::protobuf::Message* sub_response) {\n", + "name", + class_name); + printer->Indent(); + printer->Print( + "butil::Timer tt(butil::Timer::STARTED);\n" + "brpc::ResponseMerger::Result ret;" + "if (_package_size <= 0) {\n" + " ret = default_merge(response, sub_response);\n" + "} else {\n" + " ret = sub_package_merge(response, sub_response);\n" + "}\n" + "tt.stop();\n" + "if (ret != brpc::ResponseMerger::FAIL) {\n" + " _stub_handler->update_latency(tt.u_elapsed(), \"pack_merge\");\n" + "}\n" + "return ret;\n"); + printer->Outdent(); + printer->Print("}\n"); - // 1. pack fields 逐字段计算index范围,并从req copy值sub_req - printer->Print("\n// 1. 样本字段(必须为repeated类型)按指定下标复制\n"); - for (uint32_t ii = 0; ii < in_item_fields.size(); ii++) { - const FieldDescriptor* fd = in_item_fields[ii]; - std::string field_name = fd->name(); - printer->Print("\n/////$field_name$\n", "field_name", field_name); - if (ii == 0) { - printer->Print( - "uint32_t total_size = req->$field_name$_size();\n" - "if (channel_index == 0) {\n" - " _stub_handler->update_average(total_size, \"item_size\");\n" - "}\n", "field_name", field_name); + printer->Outdent(); + printer->Print("};\n"); + return true; + } + bool generate_paddle_serving_stub_default_map( + google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + printer->Print( + "if (channel_index > 0) { \n" + " return brpc::SubCall::Skip();\n" + "}\n"); + printer->Print( + "google::protobuf::Message* cur_res = " + "_stub_handler->fetch_response();\n" + "if (cur_res == NULL) {\n" + " LOG(INFO) << \"Failed fetch response from stub handler, new it\";\n" + " cur_res = response->New();\n" + " if (cur_res == NULL) {\n" + " LOG(ERROR) << \"Failed new response item!\";\n" + " _stub_handler->update_average(1, \"pack_fail\");\n" + " return brpc::SubCall::Bad();\n" + " }\n" + " return brpc::SubCall(method, request, cur_res, " + "brpc::DELETE_RESPONSE);\n" + "}\n"); + "LOG(INFO) \n" + " << \"[default] Succ map, channel_index: \" << channel_index;\n"; + printer->Print("return brpc::SubCall(method, request, cur_res, 0);\n"); + return true; + } + bool generate_paddle_serving_stub_default_merger( + google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + printer->Print( + "try {\n" + " response->MergeFrom(*sub_response);\n" + " return brpc::ResponseMerger::MERGED;\n" + "} catch (const std::exception& e) {\n" + " LOG(ERROR) << \"Merge failed.\";\n" + " _stub_handler->update_average(1, \"pack_fail\");\n" + " return brpc::ResponseMerger::FAIL;\n" + "}\n"); + return true; + } + bool generate_paddle_serving_stub_package_map( + google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name, + std::vector& in_shared_fields, // NOLINT + std::vector& in_item_fields) const { // NOLINT + const MethodDescriptor* md = descriptor->FindMethodByName("inference"); + if (!md) { + *error = "not found inference method!"; + return false; + } - printer->Print( - "int start = _package_size * channel_index;\n" - "if (start >= total_size) {\n" - " return brpc::SubCall::Skip();\n" - "}\n" - "int end = _package_size * (channel_index + 1);\n" - "if (end > total_size) {\n" - " end = total_size;\n" - "}\n"); + printer->Print( + "const $req_type$* req \n" + " = dynamic_cast(request);\n" + "$req_type$* sub_req = NULL;", + "req_type", + google::protobuf::dots_to_colons(md->input_type()->full_name())); - printer->Print( - "sub_req = dynamic_cast<$req_type$*>(_stub_handler->fetch_request());\n" - "if (sub_req == NULL) {\n" - " LOG(ERROR) << \"failed fetch sub_req from stub.\";\n" - " _stub_handler->update_average(1, \"pack_fail\");\n" - " return brpc::SubCall::Bad();\n" - "}\n", - "name", class_name, "req_type", google::protobuf::dots_to_colons( - md->input_type()->full_name())); + // 1. pack fields 逐字段计算index范围,并从req copy值sub_req + printer->Print("\n// 1. 样本字段(必须为repeated类型)按指定下标复制\n"); + for (uint32_t ii = 0; ii < in_item_fields.size(); ii++) { + const FieldDescriptor* fd = in_item_fields[ii]; + std::string field_name = fd->name(); + printer->Print("\n/////$field_name$\n", "field_name", field_name); + if (ii == 0) { + printer->Print( + "uint32_t total_size = req->$field_name$_size();\n" + "if (channel_index == 0) {\n" + " _stub_handler->update_average(total_size, \"item_size\");\n" + "}\n", + "field_name", + field_name); - } else { - printer->Print( - "if (req->$field_name$_size() != total_size) {\n" - " LOG(ERROR) << \"pack field size not consistency: \"\n" - " << total_size << \"!=\" << req->$field_name$_size()\n" - " << \", field: $field_name$.\";\n" - " _stub_handler->update_average(1, \"pack_fail\");\n" - " return brpc::SubCall::Bad();\n" - "}\n", "field_name", field_name); - } + printer->Print( + "int start = _package_size * channel_index;\n" + "if (start >= total_size) {\n" + " return brpc::SubCall::Skip();\n" + "}\n" + "int end = _package_size * (channel_index + 1);\n" + "if (end > total_size) {\n" + " end = total_size;\n" + "}\n"); - printer->Print("for (uint32_t i = start; i < end; ++i) {\n"); - printer->Indent(); - if (fd->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - "sub_req->add_$field_name$()->CopyFrom(req->$field_name$(i));\n", - "field_name", field_name); - } else { - printer->Print( - "sub_req->add_$field_name$(req->$field_name$(i));\n", - "field_name", field_name); - } - printer->Outdent(); - printer->Print("}\n"); - } + printer->Print( + "sub_req = " + "dynamic_cast<$req_type$*>(_stub_handler->fetch_request());\n" + "if (sub_req == NULL) {\n" + " LOG(ERROR) << \"failed fetch sub_req from stub.\";\n" + " _stub_handler->update_average(1, \"pack_fail\");\n" + " return brpc::SubCall::Bad();\n" + "}\n", + "name", + class_name, + "req_type", + google::protobuf::dots_to_colons(md->input_type()->full_name())); - // 2. shared fields逐字段从req copy至sub_req - printer->Print("\n// 2. 共享字段,从req逐个复制到sub_req\n"); - if (in_item_fields.size() == 0) { - printer->Print( - "if (sub_req == NULL) { // no packed items\n" - " sub_req = dynamic_cast<$req_type$*>(_stub_handler->fetch_request());\n" - " if (!sub_req) {\n" - " LOG(ERROR) << \"failed fetch sub_req from stub handler.\";\n" - " _stub_handler->update_average(1, \"pack_fail\");\n" - " return brpc::SubCall::Bad();\n" - " }\n" - "}\n", "req_type", google::protobuf::dots_to_colons( - md->input_type()->full_name())); - } - for (uint32_t si = 0; si < in_shared_fields.size(); si++) { - const FieldDescriptor* fd = in_shared_fields[si]; - std::string field_name = fd->name(); - printer->Print("\n/////$field_name$\n", "field_name", field_name); - if (fd->is_optional()) { - printer->Print( - "if (req->has_$field_name$()) {\n", "field_name", field_name); - printer->Indent(); - } - if (fd->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE || fd->is_repeated()) { - printer->Print( - "sub_req->mutable_$field_name$()->CopyFrom(req->$field_name$());\n", - "field_name", field_name); - } else { - printer->Print( - "sub_req->set_$field_name$(req->$field_name$());\n", - "field_name", field_name); - } - if (fd->is_optional()) { - printer->Outdent(); - printer->Print("}\n"); - } - } - + } else { printer->Print( - "LOG(INFO)\n" - " << \"[pack] Succ map req at: \"\n" - " << channel_index;\n"); + "if (req->$field_name$_size() != total_size) {\n" + " LOG(ERROR) << \"pack field size not consistency: \"\n" + " << total_size << \"!=\" << " + "req->$field_name$_size()\n" + " << \", field: $field_name$.\";\n" + " _stub_handler->update_average(1, \"pack_fail\");\n" + " return brpc::SubCall::Bad();\n" + "}\n", + "field_name", + field_name); + } + + printer->Print("for (uint32_t i = start; i < end; ++i) {\n"); + printer->Indent(); + if (fd->cpp_type() == + google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) { printer->Print( - "google::protobuf::Message* sub_res = _stub_handler->fetch_response();\n" - "if (sub_res == NULL) {\n" - " LOG(ERROR) << \"failed create sub_res from res.\";\n" - " _stub_handler->update_average(1, \"pack_fail\");\n" - " return brpc::SubCall::Bad();\n" - "}\n" - "return brpc::SubCall(method, sub_req, sub_res, 0);\n"); - return true; + "sub_req->add_$field_name$()->CopyFrom(req->$field_name$(i));\n", + "field_name", + field_name); + } else { + printer->Print("sub_req->add_$field_name$(req->$field_name$(i));\n", + "field_name", + field_name); + } + printer->Outdent(); + printer->Print("}\n"); } - bool generate_paddle_serving_stub_package_merger( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { - return generate_paddle_serving_stub_default_merger( - printer, descriptor, error, service_name, class_name); + + // 2. shared fields逐字段从req copy至sub_req + printer->Print("\n// 2. 共享字段,从req逐个复制到sub_req\n"); + if (in_item_fields.size() == 0) { + printer->Print( + "if (sub_req == NULL) { // no packed items\n" + " sub_req = " + "dynamic_cast<$req_type$*>(_stub_handler->fetch_request());\n" + " if (!sub_req) {\n" + " LOG(ERROR) << \"failed fetch sub_req from stub handler.\";\n" + " _stub_handler->update_average(1, \"pack_fail\");\n" + " return brpc::SubCall::Bad();\n" + " }\n" + "}\n", + "req_type", + google::protobuf::dots_to_colons(md->input_type()->full_name())); + } + for (uint32_t si = 0; si < in_shared_fields.size(); si++) { + const FieldDescriptor* fd = in_shared_fields[si]; + std::string field_name = fd->name(); + printer->Print("\n/////$field_name$\n", "field_name", field_name); + if (fd->is_optional()) { + printer->Print( + "if (req->has_$field_name$()) {\n", "field_name", field_name); + printer->Indent(); + } + if (fd->cpp_type() == + google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE || + fd->is_repeated()) { + printer->Print( + "sub_req->mutable_$field_name$()->CopyFrom(req->$field_name$());\n", + "field_name", + field_name); + } else { + printer->Print("sub_req->set_$field_name$(req->$field_name$());\n", + "field_name", + field_name); + } + if (fd->is_optional()) { + printer->Outdent(); + printer->Print("}\n"); + } } - bool generate_paddle_serving_stub_body( - google::protobuf::io::Printer* printer, - const ServiceDescriptor* descriptor, - string *error, - const std::string& service_name, - const std::string& class_name) const { - std::vector methods; - for (int i = 0; i < descriptor->method_count(); ++i) { - methods.push_back(descriptor->method(i)); - } - if (!valid_service_method(methods)) { - *error = "Service can only contains two methods: inferend, debug"; - return false; - } - const MethodDescriptor* md = methods[0]; - std::map variables; - variables["name"] = class_name; - variables["req_type"] = google::protobuf::dots_to_colons(md->input_type()->full_name()); - variables["res_type"] = google::protobuf::dots_to_colons(md->output_type()->full_name()); - variables["fullname"] = descriptor->full_name(); - printer->Print(variables, - "REGIST_STUB_OBJECT_WITH_TAG(\n" - " $name$_Stub,\n" - " $name$_StubCallMapper,\n" - " $name$_StubResponseMerger,\n" - " $req_type$,\n" - " $res_type$,\n" - " \"$fullname$\");\n"); - variables.clear(); - return true; + printer->Print( + "LOG(INFO)\n" + " << \"[pack] Succ map req at: \"\n" + " << channel_index;\n"); + printer->Print( + "google::protobuf::Message* sub_res = " + "_stub_handler->fetch_response();\n" + "if (sub_res == NULL) {\n" + " LOG(ERROR) << \"failed create sub_res from res.\";\n" + " _stub_handler->update_average(1, \"pack_fail\");\n" + " return brpc::SubCall::Bad();\n" + "}\n" + "return brpc::SubCall(method, sub_req, sub_res, 0);\n"); + return true; + } + bool generate_paddle_serving_stub_package_merger( + google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + return generate_paddle_serving_stub_default_merger( + printer, descriptor, error, service_name, class_name); + } + bool generate_paddle_serving_stub_body(google::protobuf::io::Printer* printer, + const ServiceDescriptor* descriptor, + string* error, + const std::string& service_name, + const std::string& class_name) const { + std::vector methods; + for (int i = 0; i < descriptor->method_count(); ++i) { + methods.push_back(descriptor->method(i)); } + if (!valid_service_method(methods)) { + *error = "Service can only contains two methods: inferend, debug"; + return false; + } + + const MethodDescriptor* md = methods[0]; + std::map variables; + variables["name"] = class_name; + variables["req_type"] = + google::protobuf::dots_to_colons(md->input_type()->full_name()); + variables["res_type"] = + google::protobuf::dots_to_colons(md->output_type()->full_name()); + variables["fullname"] = descriptor->full_name(); + printer->Print(variables, + "REGIST_STUB_OBJECT_WITH_TAG(\n" + " $name$_Stub,\n" + " $name$_StubCallMapper,\n" + " $name$_StubResponseMerger,\n" + " $req_type$,\n" + " $res_type$,\n" + " \"$fullname$\");\n"); + variables.clear(); + return true; + } }; int main(int argc, char** argv) { - PdsCodeGenerator generator; - return google::protobuf::compiler::PluginMain(argc, argv, &generator); -}; + PdsCodeGenerator generator; + return google::protobuf::compiler::PluginMain(argc, argv, &generator); +} diff --git a/predictor/src/pdserving.cpp b/predictor/src/pdserving.cpp index 36e2adeed4061c1dddb330e9e5b8dbaf273e1ad1..8d844ecd5b56796fd961cd7e0090ffbd8678b7a5 100644 --- a/predictor/src/pdserving.cpp +++ b/predictor/src/pdserving.cpp @@ -1,18 +1,32 @@ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include -#include +#include // bthread_set_worker_startfn #include -#include // bthread_set_worker_startfn +#include +#include "butil/logging.h" +#include "common/constant.h" #include "common/inner_common.h" -#include "framework/workflow.h" -#include "framework/service.h" #include "framework/manager.h" -#include "framework/server.h" -#include "butil/logging.h" #include "framework/resource.h" -#include "common/constant.h" +#include "framework/server.h" +#include "framework/service.h" +#include "framework/workflow.h" using baidu::paddle_serving::predictor::ServerManager; using baidu::paddle_serving::predictor::WorkflowManager; @@ -34,134 +48,135 @@ using baidu::paddle_serving::configure::read_proto_conf; void print_revision(std::ostream& os, void*) { #if defined(PDSERVING_VERSION) - os << PDSERVING_VERSION; + os << PDSERVING_VERSION; #else - os << "undefined"; + os << "undefined"; #endif #if defined(PDSERVING_BUILDTIME) - os << ", BuildAt: " << PDSERVING_BUILDTIME; + os << ", BuildAt: " << PDSERVING_BUILDTIME; #endif } static bvar::PassiveStatus s_predictor_revision( - "predictor_revision", print_revision, NULL); + "predictor_revision", print_revision, NULL); DEFINE_bool(V, false, "print version, bool"); DEFINE_bool(g, false, "user defined gflag path"); DECLARE_string(flagfile); -void pthread_worker_start_fn() { - Resource::instance().thread_initialize(); -} +void pthread_worker_start_fn() { Resource::instance().thread_initialize(); } static void g_change_server_port() { - InferServiceConf conf; - if (read_proto_conf(FLAGS_inferservice_path.c_str(), FLAGS_inferservice_file.c_str(), &conf) != 0) { - LOG(WARNING) << "failed to load configure[" << FLAGS_inferservice_path - << "," << FLAGS_inferservice_file << "]."; - return; - } - uint32_t port = conf.port(); - if (port != 0) { - FLAGS_port = port; - LOG(INFO) << "use configure[" << FLAGS_inferservice_path << "/" - << FLAGS_inferservice_file << "] port[" << port << "] instead of flags"; - } + InferServiceConf conf; + if (read_proto_conf(FLAGS_inferservice_path.c_str(), + FLAGS_inferservice_file.c_str(), + &conf) != 0) { + LOG(WARNING) << "failed to load configure[" << FLAGS_inferservice_path + << "," << FLAGS_inferservice_file << "]."; return; + } + uint32_t port = conf.port(); + if (port != 0) { + FLAGS_port = port; + LOG(INFO) << "use configure[" << FLAGS_inferservice_path << "/" + << FLAGS_inferservice_file << "] port[" << port + << "] instead of flags"; + } + return; } #ifdef UNIT_TEST int ut_main(int argc, char** argv) { -#else +#else int main(int argc, char** argv) { #endif - google::ParseCommandLineFlags(&argc, &argv, true); - - if (FLAGS_V) { - print_revision(std::cout, NULL); - std::cout << std::flush; - return 0; - } + google::ParseCommandLineFlags(&argc, &argv, true); - if (!FLAGS_g) { - google::SetCommandLineOption("flagfile", "conf/gflags.conf"); - } - - google::ParseCommandLineFlags(&argc, &argv, true); - - g_change_server_port(); - - // initialize logger instance - FLAGS_log_dir = "./log"; - - struct stat st_buf; - int ret = 0; - if ((ret = stat("./log", &st_buf)) != 0) { - mkdir("./log", 0777); - ret = stat("./log", &st_buf); - if (ret != 0) { - LOG(WARNING) << "Log path ./log not exist, and create fail"; - return -1; - } - } - google::InitGoogleLogging(strdup(argv[0])); - - LOG(INFO) << "Succ initialize logger"; - - // initialize resource manager - if (Resource::instance().initialize( - FLAGS_resource_path, FLAGS_resource_file) != 0) { - LOG(ERROR) << "Failed initialize resource, conf:" - << FLAGS_resource_path << "/" << FLAGS_resource_file; - return -1; - } - LOG(INFO) << "Succ initialize resource"; - - // initialize workflow manager - if (WorkflowManager::instance().initialize( - FLAGS_workflow_path, FLAGS_workflow_file) != 0) { - LOG(ERROR) << "Failed initialize workflow manager, conf:" - << FLAGS_workflow_path << "/" << FLAGS_workflow_file; - return -1; - } - LOG(INFO) << "Succ initialize workflow"; - - // initialize service manager - if (InferServiceManager::instance().initialize( - FLAGS_inferservice_path, FLAGS_inferservice_file) != 0) { - LOG(ERROR) - << "Failed initialize infer service manager, conf:" - << FLAGS_inferservice_path << "/" << FLAGS_inferservice_file; - return -1; - } - LOG(INFO) << "Succ initialize inferservice"; + if (FLAGS_V) { + print_revision(std::cout, NULL); + std::cout << std::flush; + return 0; + } - int errcode = bthread_set_worker_startfn(pthread_worker_start_fn); - if (errcode != 0) { - LOG(ERROR) << "Failed call pthread worker start function, error_code[" << errcode << "]"; - return -1; - } - LOG(INFO) << "Succ call pthread worker start function"; + if (!FLAGS_g) { + google::SetCommandLineOption("flagfile", "conf/gflags.conf"); + } - if (ServerManager::instance().start_and_wait() != 0) { - LOG(ERROR) << "Failed start server and wait!"; - return -1; - } - LOG(INFO) << "Succ start service manager"; + google::ParseCommandLineFlags(&argc, &argv, true); - if (InferServiceManager::instance().finalize() != 0) { - LOG(ERROR) << "Failed finalize infer service manager."; - } + g_change_server_port(); - if (WorkflowManager::instance().finalize() != 0) { - LOG(ERROR) << "Failed finalize workflow manager"; - } + // initialize logger instance + FLAGS_log_dir = "./log"; - if (Resource::instance().finalize() != 0) { - LOG(ERROR) << "Failed finalize resource manager"; + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; } - - google::ShutdownGoogleLogging(); - LOG(INFO) << "Paddle Inference Server exit successfully!"; - return 0; + } + google::InitGoogleLogging(strdup(argv[0])); + + LOG(INFO) << "Succ initialize logger"; + + // initialize resource manager + if (Resource::instance().initialize(FLAGS_resource_path, + FLAGS_resource_file) != 0) { + LOG(ERROR) << "Failed initialize resource, conf:" << FLAGS_resource_path + << "/" << FLAGS_resource_file; + return -1; + } + LOG(INFO) << "Succ initialize resource"; + + // initialize workflow manager + if (WorkflowManager::instance().initialize(FLAGS_workflow_path, + FLAGS_workflow_file) != 0) { + LOG(ERROR) << "Failed initialize workflow manager, conf:" + << FLAGS_workflow_path << "/" << FLAGS_workflow_file; + return -1; + } + LOG(INFO) << "Succ initialize workflow"; + + // initialize service manager + if (InferServiceManager::instance().initialize( + FLAGS_inferservice_path, FLAGS_inferservice_file) != 0) { + LOG(ERROR) << "Failed initialize infer service manager, conf:" + << FLAGS_inferservice_path << "/" << FLAGS_inferservice_file; + return -1; + } + LOG(INFO) << "Succ initialize inferservice"; + + int errcode = bthread_set_worker_startfn(pthread_worker_start_fn); + if (errcode != 0) { + LOG(ERROR) << "Failed call pthread worker start function, error_code[" + << errcode << "]"; + return -1; + } + LOG(INFO) << "Succ call pthread worker start function"; + + if (ServerManager::instance().start_and_wait() != 0) { + LOG(ERROR) << "Failed start server and wait!"; + return -1; + } + LOG(INFO) << "Succ start service manager"; + + if (InferServiceManager::instance().finalize() != 0) { + LOG(ERROR) << "Failed finalize infer service manager."; + } + + if (WorkflowManager::instance().finalize() != 0) { + LOG(ERROR) << "Failed finalize workflow manager"; + } + + if (Resource::instance().finalize() != 0) { + LOG(ERROR) << "Failed finalize resource manager"; + } + + google::ShutdownGoogleLogging(); + LOG(INFO) << "Paddle Inference Server exit successfully!"; + return 0; } diff --git a/predictor/unittest/test_bsf.cpp b/predictor/unittest/test_bsf.cpp index eeb4de0964ff602f486f9e6ece1b9fcabc878ec7..6de12b4640f45d5228831079544b1866d94aa2b3 100644 --- a/predictor/unittest/test_bsf.cpp +++ b/predictor/unittest/test_bsf.cpp @@ -1,18 +1,19 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file test_bsf.cpp - * @author root(com@baidu.com) - * @date 2018/09/20 13:54:52 - * @brief - * - **/ +// 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 "test_bsf.h" +#include "predictor/unittest/test_bsf.h" +#include namespace baidu { namespace paddle_serving { @@ -21,73 +22,81 @@ namespace unittest { butil::atomic global_id; void TestItem::auto_gen() { - id = global_id.fetch_add(1); - char buf[128]; - snprintf(buf, sizeof(buf), "test-%d", id); - text = buf; - printf("id:%d,text:%s\n", id, text.c_str()); + id = global_id.fetch_add(1); + char buf[128]; + snprintf(buf, sizeof(buf), "test-%d", id); + text = buf; + printf("id:%d,text:%s\n", id, text.c_str()); } -void work(const std::vector& in, std::vector& out) { - for (size_t i = 0; i < in.size(); ++i) { - out[i] = in[i]; - usleep(50); - } +void work(const std::vector& in, + std::vector& out) { // NOLINT + for (size_t i = 0; i < in.size(); ++i) { + out[i] = in[i]; + usleep(50); + } } TEST_F(TestBsf, test_single_thread) { - // initialize TaskExecutor - global_id.store(0, butil::memory_order_relaxed); - im::bsf::TaskExecutor >::instance()->set_thread_callback_fn( - boost::bind(&work, _1, _2)); - EXPECT_EQ((im::bsf::TaskExecutor >::instance()->start(1)), 0); - - std::vector in; - std::vector out; + // initialize TaskExecutor + global_id.store(0, butil::memory_order_relaxed); + im::bsf::TaskExecutor>::instance() + ->set_thread_callback_fn(boost::bind(&work, _1, _2)); + EXPECT_EQ( + (im::bsf::TaskExecutor>::instance() + ->start(1)), + 0); - TestItem::create(in, out, 5); + std::vector in; + std::vector out; - im::bsf::TaskManager task_manager; - task_manager.schedule(in, out); - printf("wait for bsf finish...\n"); - task_manager.wait(); - printf("bsf executed finished\n"); - ASSERT_EQ(out.size(), 5); - for (size_t i = 0; i < out.size(); i++) { - char temp[128]; - snprintf(temp, sizeof(temp), "test-%d", i); - EXPECT_EQ(i, in[i].id); - EXPECT_EQ(i, out[i].id); - EXPECT_STREQ(temp, in[i].text.c_str()); - EXPECT_STREQ(temp, out[i].text.c_str()); - } + TestItem::create(in, out, 5); - im::bsf::TaskExecutor >::instance()->stop(); + im::bsf::TaskManager task_manager; + task_manager.schedule(in, out); + printf("wait for bsf finish...\n"); + task_manager.wait(); + printf("bsf executed finished\n"); + ASSERT_EQ(out.size(), 5); + for (size_t i = 0; i < out.size(); i++) { + char temp[128]; + snprintf(temp, sizeof(temp), "test-%d", i); + EXPECT_EQ(i, in[i].id); + EXPECT_EQ(i, out[i].id); + EXPECT_STREQ(temp, in[i].text.c_str()); + EXPECT_STREQ(temp, out[i].text.c_str()); + } + + im::bsf::TaskExecutor>::instance()->stop(); } TEST_F(TestBsf, test_multi_thread) { - // initialize TaskExecutor - global_id.store(0, butil::memory_order_relaxed); - im::bsf::TaskExecutor >::instance()->set_thread_callback_fn( - boost::bind(&work, _1, _2)); - im::bsf::TaskExecutor >::instance()->set_batch_size(100); - EXPECT_EQ((im::bsf::TaskExecutor >::instance()->start(3)), 0); - - size_t psize = 5; - pthread_t pid[psize]; - for (size_t i = 0; i < psize; ++i) { - pthread_create(&pid[i], NULL, &TestBsf::task_trigger, NULL); - } + // initialize TaskExecutor + global_id.store(0, butil::memory_order_relaxed); + im::bsf::TaskExecutor>::instance() + ->set_thread_callback_fn(boost::bind(&work, _1, _2)); + im::bsf::TaskExecutor>::instance() + ->set_batch_size(100); + EXPECT_EQ( + (im::bsf::TaskExecutor>::instance() + ->start(3)), + 0); - for (size_t i = 0; i < psize; ++i) { - pthread_join(pid[i], NULL); - } + const size_t psize = 5; + std::unique_ptr pid; + pid.reset(new pthread_t[psize]); + for (size_t i = 0; i < psize; ++i) { + pthread_create(&pid[i], NULL, &TestBsf::task_trigger, NULL); + } - im::bsf::TaskExecutor >::instance()->stop(); -} + for (size_t i = 0; i < psize; ++i) { + pthread_join(pid[i], NULL); + } + im::bsf::TaskExecutor>::instance()->stop(); } -} -} +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/predictor/unittest/test_bsf.h b/predictor/unittest/test_bsf.h index f2334227a8931215a09ed3b23fedede24017ab29..0101d65f7a2483fabe68cd2db6748ba6336442e0 100644 --- a/predictor/unittest/test_bsf.h +++ b/predictor/unittest/test_bsf.h @@ -1,21 +1,21 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file test_bsf.h - * @author root(com@baidu.com) - * @date 2018/09/20 13:53:01 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TEST_BSF_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_TEST_BSF_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. + +#pragma once #include +#include +#include #include "common/inner_common.h" #include "framework/bsf.h" @@ -23,74 +23,70 @@ namespace baidu { namespace paddle_serving { namespace unittest { -#ifndef DEFINE_UP_DOWN -#define DEFINE_UP_DOWN \ - void SetUp() {} \ - void TearDown() {} +#ifndef DEFINE_UP_DOWN +#define DEFINE_UP_DOWN \ + void SetUp() {} \ + void TearDown() {} struct TestItem { - - void auto_gen(); - - bool operator==(const TestItem& other) { - return text == other.text && id == other.id; - } - - static void create(std::vector& in, std::vector& out, size_t size) { - in.clear(); - out.clear(); - for (size_t i = 0; i < size; i++) { - TestItem item; - item.auto_gen(); - in.push_back(item); - item.id += 1000000; - out.push_back(item); - } + void auto_gen(); + + bool operator==(const TestItem& other) { + return text == other.text && id == other.id; + } + + static void create(std::vector& in, // NOLINT + std::vector& out, // NOLINT + size_t size) { + in.clear(); + out.clear(); + for (size_t i = 0; i < size; i++) { + TestItem item; + item.auto_gen(); + in.push_back(item); + item.id += 1000000; + out.push_back(item); } + } - std::string text; - size_t id; + std::string text; + size_t id; }; class TestBsf : public ::testing::Test { -public: - TestBsf() {} - virtual ~TestBsf() {} - - static void* task_trigger(void* arg) { - for (size_t i = 0; i < 100; i++) { - std::vector in; - std::vector out; - - size_t count = rand() % 10 + 1; - TestItem::create(in, out, count); - - im::bsf::TaskManager task_manager; - task_manager.schedule(in, out); - printf("wait for bsf finish..., count:%d, first:%d\n", count, in[0].id); - task_manager.wait(); - printf("bsf executed finished, count:%d, first:%d\n", count, in[0].id); - EXPECT_EQ(out.size(), count); - for (size_t i = 0; i < out.size(); i++) { - EXPECT_EQ(in[i].id, out[i].id); - char temp[128]; - snprintf(temp, sizeof(temp), "test-%d", in[i].id); - EXPECT_STREQ(temp, in[i].text.c_str()); - EXPECT_STREQ(temp, out[i].text.c_str()); - } - } + public: + TestBsf() {} + virtual ~TestBsf() {} + + static void* task_trigger(void* arg) { + for (size_t i = 0; i < 100; i++) { + std::vector in; + std::vector out; + + size_t count = rand_r() % 10 + 1; + TestItem::create(in, out, count); + + im::bsf::TaskManager task_manager; + task_manager.schedule(in, out); + printf("wait for bsf finish..., count:%d, first:%d\n", count, in[0].id); + task_manager.wait(); + printf("bsf executed finished, count:%d, first:%d\n", count, in[0].id); + EXPECT_EQ(out.size(), count); + for (size_t i = 0; i < out.size(); i++) { + EXPECT_EQ(in[i].id, out[i].id); + char temp[128]; + snprintf(temp, sizeof(temp), "test-%d", in[i].id); + EXPECT_STREQ(temp, in[i].text.c_str()); + EXPECT_STREQ(temp, out[i].text.c_str()); + } } + } - DEFINE_UP_DOWN + DEFINE_UP_DOWN }; #undef DEFINE_UP_DOWN #endif - -} -} -} - -#endif //BAIDU_PADDLE_SERVING_PREDICTOR_TEST_FTL_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_main.cpp b/predictor/unittest/test_main.cpp index 38f86eed2e2d9d648c07373d370e7b707c503851..053cdfa942a6e21e952bb310ab755305306aed74 100644 --- a/predictor/unittest/test_main.cpp +++ b/predictor/unittest/test_main.cpp @@ -1,8 +1,22 @@ -#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 +#include "common/inner_common.h" int main(int argc, char** argv) { - LOG(INFO) << "Start running all ut cases..."; - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + LOG(INFO) << "Start running all ut cases..."; + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/predictor/unittest/test_manager.cpp b/predictor/unittest/test_manager.cpp index 0d6cbac59d827cf623ffac8beebbc79798ea4ceb..17587114c166fb3f4fe631a7f4ae452e461e5114 100644 --- a/predictor/unittest/test_manager.cpp +++ b/predictor/unittest/test_manager.cpp @@ -1,7 +1,21 @@ -#include "test_tool.h" -#include "test_manager.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 "predictor/unittest/test_manager.h" #include "framework/manager.h" #include "framework/service.h" +#include "predictor/unittest/test_tool.h" namespace baidu { namespace paddle_serving { @@ -14,91 +28,86 @@ using baidu::paddle_serving::predictor::FLAGS_use_parallel_infer_service; using baidu::paddle_serving::predictor::InferServiceManager; struct ManagerItem { - int a; - float b; + int a; + float b; - int init(const comcfg::ConfigUnit& c) { - return 0; - } + int init(const comcfg::ConfigUnit& c) { return 0; } - static const char* tag() { - return "Item"; - } + static const char* tag() { return "Item"; } }; TEST_F(TestManager, test_manager_instance) { - ManagerItem* item = Manager::instance().create_item(); - EXPECT_FALSE(item == NULL); - item->a = 1; - item->b = 2.0; + ManagerItem* item = Manager::instance().create_item(); + EXPECT_FALSE(item == NULL); + item->a = 1; + item->b = 2.0; } TEST_F(TestManager, test_infer_service_create) { - InferService seq; - ParallelInferService par; + InferService seq; + ParallelInferService par; - FLAGS_use_parallel_infer_service = false; - EXPECT_EQ(typeid(seq), + FLAGS_use_parallel_infer_service = false; + EXPECT_EQ(typeid(seq), typeid(*InferServiceManager::instance().create_item())); - FLAGS_use_parallel_infer_service = true; - EXPECT_EQ(typeid(par), + FLAGS_use_parallel_infer_service = true; + EXPECT_EQ(typeid(par), typeid(*InferServiceManager::instance().create_item())); } TEST_F(TestManager, test_conf_success) { - const char* conf_content = - "[@Item]\n\ - name: item1\n\ - a:b\n\ - [@Item]\n\ - name: item2\n\ - c:d"; - - AutoTempFile file(conf_content); - - typedef Manager mgr; - EXPECT_EQ(mgr::instance().initialize("./", file.name()), 0); - - ManagerItem* item11 = mgr::instance().item("item1"); - ManagerItem* item12 = &mgr::instance()["item1"]; - EXPECT_EQ(item11, item12); - - ManagerItem* item21 = mgr::instance().item("item2"); - ManagerItem* item22 = &mgr::instance()["item2"]; - EXPECT_EQ(item21, item22); + const char* conf_content = + "[@Item]\n" + "name: item1\n" + "a:b\n" + "[@Item]\n" + "name: item2\n" + "c:d"; + + AutoTempFile file(conf_content); + + typedef Manager mgr; + EXPECT_EQ(mgr::instance().initialize("./", file.name()), 0); + + ManagerItem* item11 = mgr::instance().item("item1"); + ManagerItem* item12 = &mgr::instance()["item1"]; + EXPECT_EQ(item11, item12); + + ManagerItem* item21 = mgr::instance().item("item2"); + ManagerItem* item22 = &mgr::instance()["item2"]; + EXPECT_EQ(item21, item22); } TEST_F(TestManager, test_conf_success_item_not_found) { - const char* conf_content = - "[@Item1]\n\ - name: item1\n\ - a:b\n\ - [@Item2]\n\ - name: item2\n\ - c:d"; - - AutoTempFile file(conf_content); - - typedef Manager mgr; - EXPECT_EQ(mgr::instance().initialize("./", file.name()), 0); + const char* conf_content = + "[@Item1]\n" + "name: item1\n" + "a:b\n" + "[@Item2]\n" + "name: item2\n" + "c:d"; + + AutoTempFile file(conf_content); + + typedef Manager mgr; + EXPECT_EQ(mgr::instance().initialize("./", file.name()), 0); } TEST_F(TestManager, test_conf_failed_name_not_found) { - const char* conf_content = - "[@Item]\n\ - name2: item1\n\ - a:b\n\ - [@Item]\n\ - name: item2\n\ - c:d"; - - AutoTempFile file(conf_content); - - typedef Manager mgr; - EXPECT_EQ(mgr::instance().initialize("./", file.name()), -1); -} - -} -} + const char* conf_content = + "[@Item]\n" + "name2: item1\n" + "a:b\n" + "[@Item]\n" + "name: item2\n" + "c:d"; + + AutoTempFile file(conf_content); + + typedef Manager mgr; + EXPECT_EQ(mgr::instance().initialize("./", file.name()), -1); } +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_manager.h b/predictor/unittest/test_manager.h index 90deafb242a3ad2aed8644f2c716642e862ebb2f..a612e2320a13b4157c1a13db8fac13d52e37edc6 100644 --- a/predictor/unittest/test_manager.h +++ b/predictor/unittest/test_manager.h @@ -1,30 +1,39 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TEST_MANAGER_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_TEST_MANAGER_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. + +#pragma once #include namespace baidu { namespace paddle_serving { namespace unittest { -#ifndef DEFINE_UP_DOWN -#define DEFINE_UP_DOWN \ - void SetUp() {} \ - void TearDown() {} \ +#ifndef DEFINE_UP_DOWN +#define DEFINE_UP_DOWN \ + void SetUp() {} \ + void TearDown() {} class TestManager : public ::testing::Test { -public: - TestManager() {} - virtual ~TestManager() {} + public: + TestManager() {} + virtual ~TestManager() {} - DEFINE_UP_DOWN + DEFINE_UP_DOWN }; #undef DEFINE_UP_DOWN #endif - -} -} -} - -#endif +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_message_op.cpp b/predictor/unittest/test_message_op.cpp index 9c04babbc527a406eeb0e02a79a57e7cd631ab06..e50ede2922d41a107947812937401e702dc328e5 100644 --- a/predictor/unittest/test_message_op.cpp +++ b/predictor/unittest/test_message_op.cpp @@ -1,8 +1,23 @@ -#include "test_tool.h" -#include "test_message_op.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 "predictor/unittest/test_message_op.h" +#include +#include "framework/dag.h" #include "framework/manager.h" #include "framework/service.h" -#include "framework/dag.h" +#include "predictor/unittest/test_tool.h" namespace baidu { namespace paddle_serving { @@ -19,39 +34,38 @@ using baidu::paddle_serving::predictor::Channel; using pds::ut::OpMessageData; TEST_F(TestMSGOP, test_init) { - Bus* bus = new Bus(); - ASSERT_NE(bus, NULL); - Dag* dag = NULL; - - MsgOP op; - std::string op_name = "TestMSGOp"; - std::string op_type = "TestMSGOp"; - EXPECT_EQ(0, op.init(bus, dag, (uint32_t)9999, op_name, op_type, NULL)); - EXPECT_FALSE(op.has_calc()); - EXPECT_EQ(9999, op.id()); - EXPECT_STREQ("TestMSGOp", op.name()); - EXPECT_STREQ("", op.debug_string().c_str()); - EXPECT_NE(op._timer, NULL); - EXPECT_EQ(bus, op._bus); - - OpMessageData* ab = op.mutable_data(); - EXPECT_EQ(33, ab->a()); - EXPECT_FLOAT_EQ(4.4, ab->b()); - - Channel* chn = op.mutable_channel(); - EXPECT_EQ(chn->id(), 9999); - EXPECT_STREQ(chn->op().c_str(), "TestMSGOp"); - - EXPECT_EQ(ab, chn->param()); - - EXPECT_EQ(0, bus->size()); - Channel* chn2 = bus->channel_by_name("TestOp"); - EXPECT_EQ(NULL, chn2); - - // Message OP can obtain data via message() - EXPECT_EQ(ab, chn->message()); -} + Bus* bus = new Bus(); + ASSERT_NE(bus, NULL); + Dag* dag = NULL; + MsgOP op; + std::string op_name = "TestMSGOp"; + std::string op_type = "TestMSGOp"; + EXPECT_EQ(0, op.init(bus, dag, (uint32_t)9999, op_name, op_type, NULL)); + EXPECT_FALSE(op.has_calc()); + EXPECT_EQ(9999, op.id()); + EXPECT_STREQ("TestMSGOp", op.name()); + EXPECT_STREQ("", op.debug_string().c_str()); + EXPECT_NE(op._timer, NULL); + EXPECT_EQ(bus, op._bus); + + OpMessageData* ab = op.mutable_data(); + EXPECT_EQ(33, ab->a()); + EXPECT_FLOAT_EQ(4.4, ab->b()); + + Channel* chn = op.mutable_channel(); + EXPECT_EQ(chn->id(), 9999); + EXPECT_STREQ(chn->op().c_str(), "TestMSGOp"); + + EXPECT_EQ(ab, chn->param()); + + EXPECT_EQ(0, bus->size()); + Channel* chn2 = bus->channel_by_name("TestOp"); + EXPECT_EQ(NULL, chn2); + + // Message OP can obtain data via message() + EXPECT_EQ(ab, chn->message()); } -} -} +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_message_op.h b/predictor/unittest/test_message_op.h index f4c0434278c85cf89189b584f23c3d9dfe84acda..398ba3f396f6d4425cf911f05daf82fe712ed9fe 100644 --- a/predictor/unittest/test_message_op.h +++ b/predictor/unittest/test_message_op.h @@ -1,45 +1,53 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TEST_MESSAGE_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_TEST_MESSAGE_OP_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. + +#pragma once #include -#include "op/op.h" -#include "msg_data.pb.h" #include "framework/channel.h" +#include "op/op.h" +#include "predictor/msg_data.pb.h" namespace baidu { namespace paddle_serving { namespace unittest { class MsgOP : public baidu::paddle_serving::predictor::OpWithChannel< - pds::ut::OpMessageData> { -public: - - int inference() { - pds::ut::OpMessageData* msg = mutable_data(); - msg->set_a(11); - msg->set_b(22.2); - return 0; - } + pds::ut::OpMessageData> { + public: + int inference() { + pds::ut::OpMessageData* msg = mutable_data(); + msg->set_a(11); + msg->set_b(22.2); + return 0; + } }; -#ifndef DEFINE_UP_DOWN -#define DEFINE_UP_DOWN \ - void SetUp() {} \ - void TearDown() {} \ +#ifndef DEFINE_UP_DOWN +#define DEFINE_UP_DOWN \ + void SetUp() {} \ + void TearDown() {} class TestMSGOP : public ::testing::Test { -public: - TestMSGOP() {} - virtual ~TestMSGOP() {} + public: + TestMSGOP() {} + virtual ~TestMSGOP() {} - DEFINE_UP_DOWN + DEFINE_UP_DOWN }; #undef DEFINE_UP_DOWN #endif - -} -} -} - -#endif +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_op.cpp b/predictor/unittest/test_op.cpp index 22fcff56a1eb2ced7a3059ca4960603d2444c122..5d9f5abeec51f96340ea22559ff7e263db7e6412 100644 --- a/predictor/unittest/test_op.cpp +++ b/predictor/unittest/test_op.cpp @@ -1,12 +1,28 @@ +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include -#include "framework/manager.h" -#include "framework/service.h" +#include +#include #include "framework/dag.h" #include "framework/dag_view.h" +#include "framework/manager.h" +#include "framework/service.h" -#include "test_tool.h" -#include "test_op.h" -#include "test_message_op.h" +#include "predictor/unittest/test_message_op.h" +#include "predictor/unittest/test_op.h" +#include "predictor/unittest/test_tool.h" namespace baidu { namespace paddle_serving { @@ -27,259 +43,255 @@ using baidu::paddle_serving::predictor::ViewNode; using pds::ut::OpMessageData; TEST_F(TestOP, test_init) { - Bus* bus = new Bus(); - ASSERT_NE(bus, NULL); - Dag* dag = NULL; - - ABOP op; - std::string op_name = "TestOp"; - std::string op_type = "TestOp"; - EXPECT_EQ(0, op.init(bus, dag, (uint32_t)999, op_name, op_type, NULL)); - EXPECT_FALSE(op.has_calc()); - EXPECT_EQ(999, op.id()); - EXPECT_STREQ("TestOp", op.name()); - EXPECT_STREQ("{\"a\": 3, \"b\": 4}", op.debug_string().c_str()); - EXPECT_NE(op._timer, NULL); - EXPECT_EQ(bus, op._bus); - - AB* ab = op.mutable_data(); - EXPECT_EQ(3, ab->a); - EXPECT_FLOAT_EQ(4.0, ab->b); - - Channel* chn = op.mutable_channel(); - EXPECT_EQ(chn->id(), 999); - EXPECT_STREQ(chn->op().c_str(), "TestOp"); - - EXPECT_EQ(ab, chn->param()); - EXPECT_EQ(NULL, chn->message()); - - EXPECT_EQ(0, bus->size()); - Channel* chn2 = bus->channel_by_name("TestOp"); - EXPECT_EQ(NULL, chn2); + Bus* bus = new Bus(); + ASSERT_NE(bus, NULL); + Dag* dag = NULL; + + ABOP op; + std::string op_name = "TestOp"; + std::string op_type = "TestOp"; + EXPECT_EQ(0, op.init(bus, dag, (uint32_t)999, op_name, op_type, NULL)); + EXPECT_FALSE(op.has_calc()); + EXPECT_EQ(999, op.id()); + EXPECT_STREQ("TestOp", op.name()); + EXPECT_STREQ("{\"a\": 3, \"b\": 4}", op.debug_string().c_str()); + EXPECT_NE(op._timer, NULL); + EXPECT_EQ(bus, op._bus); + + AB* ab = op.mutable_data(); + EXPECT_EQ(3, ab->a); + EXPECT_FLOAT_EQ(4.0, ab->b); + + Channel* chn = op.mutable_channel(); + EXPECT_EQ(chn->id(), 999); + EXPECT_STREQ(chn->op().c_str(), "TestOp"); + + EXPECT_EQ(ab, chn->param()); + EXPECT_EQ(NULL, chn->message()); + + EXPECT_EQ(0, bus->size()); + Channel* chn2 = bus->channel_by_name("TestOp"); + EXPECT_EQ(NULL, chn2); } TEST_F(TestOP, test_depend_argment) { - Bus bus; - Dag dag; - - AutoTempFile file( - "[@Node]\n\ - name: node1\n\ - type: ABOP\n\ - [@Node]\n\ - name: node2\n\ - type: ABOP\n\ - [.@Depend]\n\ - name: node1\n\ - mode: RO\n\ - [@Node]\n\ - name: node3\n\ - type: ABOP\n\ - [.@Depend]\n\ - name: node1\n\ - mode: RO\n\ - [@Node]\n\ - name: node4\n\ - type: ABOP\n\ - [.@Depend]\n\ - name: node2\n\ - mode: RW\n\ - [.@Depend]\n\ - name: node3\n\ - mode: RO"); - - std::string dag_name = "DagTest"; - EXPECT_EQ(0, dag.init("./", file.name(), dag_name)); - - ABOP op; - std::string op_name = "node4"; - std::string op_type = "ABOP"; - EXPECT_EQ(0, op.init(&bus, &dag, (uint32_t)888, op_name, op_type, NULL)); - - EXPECT_FALSE(op.is_readable("node1")); - EXPECT_FALSE(op.is_mutable("node1")); - EXPECT_TRUE(op.is_readable("node2")); - EXPECT_TRUE(op.is_mutable("node2")); - EXPECT_TRUE(op.is_readable("node3")); - EXPECT_FALSE(op.is_mutable("node3")); - - // process() is not called, channel has not been - // committed to bus yet! - EXPECT_TRUE(NULL == op.get_depend_channel("node1")); - EXPECT_TRUE(NULL == op.get_depend_channel("node2")); - EXPECT_TRUE(NULL == op.get_depend_channel("node3")); - EXPECT_TRUE(NULL == op.mutable_depend_channel("node1")); - EXPECT_TRUE(NULL == op.mutable_depend_channel("node2")); - EXPECT_TRUE(NULL == op.mutable_depend_channel("node3")); + Bus bus; + Dag dag; + + AutoTempFile file( + "[@Node]\n" + "name: node1\n" + "type: ABOP\n" + "[@Node]\n" + "name: node2\n" + "type: ABOP\n" + "[.@Depend]\n" + "name: node1\n" + "mode: RO\n" + "[@Node]\n" + "name: node3\n" + "type: ABOP\n" + "[.@Depend]\n" + "name: node1\n" + "mode: RO\n" + "[@Node]\n" + "name: node4\n" + "type: ABOP\n" + "[.@Depend]\n" + "name: node2\n" + "mode: RW\n" + "[.@Depend]\n" + "name: node3\n" + "mode: RO"); + + std::string dag_name = "DagTest"; + EXPECT_EQ(0, dag.init("./", file.name(), dag_name)); + + ABOP op; + std::string op_name = "node4"; + std::string op_type = "ABOP"; + EXPECT_EQ(0, op.init(&bus, &dag, (uint32_t)888, op_name, op_type, NULL)); + + EXPECT_FALSE(op.is_readable("node1")); + EXPECT_FALSE(op.is_mutable("node1")); + EXPECT_TRUE(op.is_readable("node2")); + EXPECT_TRUE(op.is_mutable("node2")); + EXPECT_TRUE(op.is_readable("node3")); + EXPECT_FALSE(op.is_mutable("node3")); + + // process() is not called, channel has not been + // committed to bus yet! + EXPECT_TRUE(NULL == op.get_depend_channel("node1")); + EXPECT_TRUE(NULL == op.get_depend_channel("node2")); + EXPECT_TRUE(NULL == op.get_depend_channel("node3")); + EXPECT_TRUE(NULL == op.mutable_depend_channel("node1")); + EXPECT_TRUE(NULL == op.mutable_depend_channel("node2")); + EXPECT_TRUE(NULL == op.mutable_depend_channel("node3")); } TEST_F(TestOP, test_inference) { - Bus bus; - Dag dag; - - AutoTempFile file( - "[@Node]\n\ - name: node1\n\ - type: ABOP\n\ - [@Node]\n\ - name: node2\n\ - type: ABOP\n\ - [.@Depend]\n\ - name: node1\n\ - mode: RO\n\ - [@Node]\n\ - name: node3\n\ - type: ABOP\n\ - [.@Depend]\n\ - name: node1\n\ - mode: RO\n\ - [@Node]\n\ - name: node4\n\ - type: ABOP\n\ - [.@Depend]\n\ - name: node2\n\ - mode: RW\n\ - [.@Depend]\n\ - name: node3\n\ - mode: RO"); - - std::string dag_name = "DagTest"; - EXPECT_EQ(0, dag.init("./", file.name(), dag_name)); - - ABOP op1; - std::string op1_name = "node1"; - std::string op_type = "ABOP"; - EXPECT_EQ(0, op1.init(&bus, &dag, (uint32_t)888, op1_name, op_type, NULL)); - - ABOP op2; - std::string op2_name = "node2"; - EXPECT_EQ(0, op2.init(&bus, &dag, (uint32_t)888, op2_name, op_type, NULL)); - - MsgOP op3; - std::string op3_name = "node3"; - EXPECT_EQ(0, op3.init(&bus, &dag, (uint32_t)888, op3_name, op_type, NULL)); - - ABOP op4; - std::string op4_name = "node4"; - EXPECT_EQ(0, op4.init(&bus, &dag, (uint32_t)888, op4_name, op_type, NULL)); - - EXPECT_TRUE(op2.is_readable("node1")); - EXPECT_FALSE(op2.is_mutable("node1")); - - EXPECT_FALSE(op2.is_readable("node3")); - EXPECT_FALSE(op2.is_mutable("node3")); - - EXPECT_FALSE(op2.is_readable("node4")); - EXPECT_FALSE(op2.is_mutable("node4")); - - EXPECT_TRUE(op3.is_readable("node1")); - EXPECT_FALSE(op3.is_mutable("node1")); - - EXPECT_FALSE(op3.is_readable("node2")); - EXPECT_FALSE(op3.is_mutable("node2")); - - EXPECT_FALSE(op3.is_readable("node4")); - EXPECT_FALSE(op3.is_mutable("node4")); - - EXPECT_FALSE(op4.is_readable("node1")); - EXPECT_FALSE(op4.is_mutable("node1")); - - EXPECT_TRUE(op4.is_readable("node2")); - EXPECT_TRUE(op4.is_mutable("node2")); - - EXPECT_TRUE(op4.is_readable("node3")); - EXPECT_FALSE(op4.is_mutable("node3")); - - EXPECT_EQ(0, op1.process(false)); - EXPECT_EQ(0, op2.process(false)); - EXPECT_EQ(0, op3.process(false)); - EXPECT_EQ(0, op4.process(true)); - - EXPECT_TRUE(NULL == op4.get_depend_channel("node1")); - EXPECT_FALSE(NULL == op4.get_depend_channel("node2")); - EXPECT_FALSE(NULL == op4.get_depend_channel("node3")); - EXPECT_TRUE(NULL == op4.mutable_depend_channel("node1")); - EXPECT_FALSE(NULL == op4.mutable_depend_channel("node2")); - EXPECT_TRUE(NULL == op4.mutable_depend_channel("node3")); - - const AB* dop1 - = op4.get_depend_argument("node1"); - - const AB* dop21 - = op4.get_depend_argument("node2"); - const google::protobuf::Message* dop22 - = op4.get_depend_channel("node2")->message(); - const google::protobuf::Message* dop23 - = op4.get_depend_argument("node2"); - - const OpMessageData* dop31 - = op4.get_depend_argument("node3"); - const google::protobuf::Message* dop32 - = op4.get_depend_channel("node3")->message(); - const google::protobuf::Message* dop33 - = op4.get_depend_argument("node3"); - - EXPECT_EQ(NULL, dop1); - - EXPECT_NE(NULL, dop21); - EXPECT_EQ(NULL, dop22); - EXPECT_EQ(NULL, dop23); - - EXPECT_NE(NULL, dop31); - EXPECT_NE(NULL, dop32); - EXPECT_EQ(NULL, dop33); - EXPECT_EQ(dop31, dop32); - - const OpMessageData* dop322 = dynamic_cast(dop32); - - EXPECT_EQ(1, dop21->a); - EXPECT_FLOAT_EQ(2.2, dop21->b); + Bus bus; + Dag dag; + + AutoTempFile file( + "[@Node]\n" + "name: node1\n" + "type: ABOP\n" + "[@Node]\n" + "name: node2\n" + "type: ABOP\n" + "[.@Depend]\n" + "name: node1\n" + "mode: RO\n" + "[@Node]\n" + "name: node3\n" + "type: ABOP\n" + "[.@Depend]\n" + "name: node1\n" + "mode: RO\n" + "[@Node]\n" + "name: node4\n" + "type: ABOP\n" + "[.@Depend]\n" + "name: node2\n" + "mode: RW\n" + "[.@Depend]\n" + "name: node3\n" + "mode: RO"); + + std::string dag_name = "DagTest"; + EXPECT_EQ(0, dag.init("./", file.name(), dag_name)); + + ABOP op1; + std::string op1_name = "node1"; + std::string op_type = "ABOP"; + EXPECT_EQ(0, op1.init(&bus, &dag, (uint32_t)888, op1_name, op_type, NULL)); + + ABOP op2; + std::string op2_name = "node2"; + EXPECT_EQ(0, op2.init(&bus, &dag, (uint32_t)888, op2_name, op_type, NULL)); + + MsgOP op3; + std::string op3_name = "node3"; + EXPECT_EQ(0, op3.init(&bus, &dag, (uint32_t)888, op3_name, op_type, NULL)); + + ABOP op4; + std::string op4_name = "node4"; + EXPECT_EQ(0, op4.init(&bus, &dag, (uint32_t)888, op4_name, op_type, NULL)); + + EXPECT_TRUE(op2.is_readable("node1")); + EXPECT_FALSE(op2.is_mutable("node1")); + + EXPECT_FALSE(op2.is_readable("node3")); + EXPECT_FALSE(op2.is_mutable("node3")); + + EXPECT_FALSE(op2.is_readable("node4")); + EXPECT_FALSE(op2.is_mutable("node4")); + + EXPECT_TRUE(op3.is_readable("node1")); + EXPECT_FALSE(op3.is_mutable("node1")); + + EXPECT_FALSE(op3.is_readable("node2")); + EXPECT_FALSE(op3.is_mutable("node2")); + + EXPECT_FALSE(op3.is_readable("node4")); + EXPECT_FALSE(op3.is_mutable("node4")); + + EXPECT_FALSE(op4.is_readable("node1")); + EXPECT_FALSE(op4.is_mutable("node1")); + + EXPECT_TRUE(op4.is_readable("node2")); + EXPECT_TRUE(op4.is_mutable("node2")); + + EXPECT_TRUE(op4.is_readable("node3")); + EXPECT_FALSE(op4.is_mutable("node3")); + + EXPECT_EQ(0, op1.process(false)); + EXPECT_EQ(0, op2.process(false)); + EXPECT_EQ(0, op3.process(false)); + EXPECT_EQ(0, op4.process(true)); + + EXPECT_TRUE(NULL == op4.get_depend_channel("node1")); + EXPECT_FALSE(NULL == op4.get_depend_channel("node2")); + EXPECT_FALSE(NULL == op4.get_depend_channel("node3")); + EXPECT_TRUE(NULL == op4.mutable_depend_channel("node1")); + EXPECT_FALSE(NULL == op4.mutable_depend_channel("node2")); + EXPECT_TRUE(NULL == op4.mutable_depend_channel("node3")); + + const AB* dop1 = op4.get_depend_argument("node1"); + + const AB* dop21 = op4.get_depend_argument("node2"); + const google::protobuf::Message* dop22 = + op4.get_depend_channel("node2")->message(); + const google::protobuf::Message* dop23 = + op4.get_depend_argument("node2"); + + const OpMessageData* dop31 = op4.get_depend_argument("node3"); + const google::protobuf::Message* dop32 = + op4.get_depend_channel("node3")->message(); + const google::protobuf::Message* dop33 = + op4.get_depend_argument("node3"); + + EXPECT_EQ(NULL, dop1); + + EXPECT_NE(NULL, dop21); + EXPECT_EQ(NULL, dop22); + EXPECT_EQ(NULL, dop23); + + EXPECT_NE(NULL, dop31); + EXPECT_NE(NULL, dop32); + EXPECT_EQ(NULL, dop33); + EXPECT_EQ(dop31, dop32); + + const OpMessageData* dop322 = dynamic_cast(dop32); + + EXPECT_EQ(1, dop21->a); + EXPECT_FLOAT_EQ(2.2, dop21->b); - EXPECT_EQ(11, dop31->a()); - EXPECT_FLOAT_EQ(22.2, dop31->b()); + EXPECT_EQ(11, dop31->a()); + EXPECT_FLOAT_EQ(22.2, dop31->b()); - EXPECT_EQ(11, dop322->a()); - EXPECT_FLOAT_EQ(22.2, dop322->b()); + EXPECT_EQ(11, dop322->a()); + EXPECT_FLOAT_EQ(22.2, dop322->b()); } TEST_F(TestOP, test_op_with_channel_and_conf) { - Dag dag; - std::string op_name = "test_op"; - std::string name_in_conf = "test_name_in_conf"; - butil::TempFile dag_conf; - dag_conf.save_format( - "[@Node]\n" - "name: %s\n" - "type: OpWithConf\n" - "name_in_conf: %s\n", op_name.c_str(), name_in_conf.c_str()); - - std::string dag_name = "DagTest"; - ASSERT_EQ(0, dag.init("./", dag_conf.fname(), dag_name)); - - DagView view; - view.init(&dag, "service_name"); - ASSERT_EQ(0, view.execute(NULL)); - - const std::vector& view_stage_vec = view._view; - uint32_t stage_size = view_stage_vec.size(); - for (uint32_t si = 0; si < stage_size; si++) { - ViewStage* vstage = view_stage_vec[si]; - uint32_t node_size = vstage->nodes.size(); - for (uint32_t ni = 0; ni < node_size; ni++) { - ViewNode* vnode = vstage->nodes[ni]; - OpWithConf* op = dynamic_cast(vnode->op); - ASSERT_NE(NULL, op); - EXPECT_STREQ(op->name(), op_name.c_str()); - EXPECT_STREQ( - op->get_self_config()->name_in_conf.c_str(), - name_in_conf.c_str()); - EXPECT_STREQ( - op->mutable_data()->name_for_output.c_str(), - name_in_conf.c_str()); - } + Dag dag; + std::string op_name = "test_op"; + std::string name_in_conf = "test_name_in_conf"; + butil::TempFile dag_conf; + dag_conf.save_format( + "[@Node]\n" + "name: %s\n" + "type: OpWithConf\n" + "name_in_conf: %s\n", + op_name.c_str(), + name_in_conf.c_str()); + + std::string dag_name = "DagTest"; + ASSERT_EQ(0, dag.init("./", dag_conf.fname(), dag_name)); + + DagView view; + view.init(&dag, "service_name"); + ASSERT_EQ(0, view.execute(NULL)); + + const std::vector& view_stage_vec = view._view; + uint32_t stage_size = view_stage_vec.size(); + for (uint32_t si = 0; si < stage_size; si++) { + ViewStage* vstage = view_stage_vec[si]; + uint32_t node_size = vstage->nodes.size(); + for (uint32_t ni = 0; ni < node_size; ni++) { + ViewNode* vnode = vstage->nodes[ni]; + OpWithConf* op = dynamic_cast(vnode->op); + ASSERT_NE(NULL, op); + EXPECT_STREQ(op->name(), op_name.c_str()); + EXPECT_STREQ(op->get_self_config()->name_in_conf.c_str(), + name_in_conf.c_str()); + EXPECT_STREQ(op->mutable_data()->name_for_output.c_str(), + name_in_conf.c_str()); } + } } - -} -} -} +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_op.h b/predictor/unittest/test_op.h index b18cf108e18f575fbb58f9d5ae6acf55e32aaee4..174f2f84b8601b83ced50fb634df677410d522c2 100644 --- a/predictor/unittest/test_op.h +++ b/predictor/unittest/test_op.h @@ -1,102 +1,113 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TEST_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_TEST_OP_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. + +#pragma once #include -#include "op/op.h" +#include #include "framework/channel.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { namespace unittest { struct AB { - int a; - float b; - - int Clear() { - a = 3; - b = 4.0; - return 0; - } - - std::string ShortDebugString() const { - std::ostringstream oss; - oss << "{\"a\": "; - oss << a; - oss << ", \"b\": "; - oss << b; - oss << "}"; - return oss.str(); - } + int a; + float b; + + int Clear() { + a = 3; + b = 4.0; + return 0; + } + + std::string ShortDebugString() const { + std::ostringstream oss; + oss << "{\"a\": "; + oss << a; + oss << ", \"b\": "; + oss << b; + oss << "}"; + return oss.str(); + } }; class ABOP : public baidu::paddle_serving::predictor::OpWithChannel { -public: - int inference() { - AB* ab = mutable_data(); - ab->a = 1; - ab->b = 2.2; - return 0; - } - DECLARE_OP(ABOP); + public: + int inference() { + AB* ab = mutable_data(); + ab->a = 1; + ab->b = 2.2; + return 0; + } + DECLARE_OP(ABOP); }; DEFINE_OP(ABOP); struct OpConf { - std::string name_in_conf; + std::string name_in_conf; }; struct OpOutput { - std::string name_for_output; - void Clear() { name_for_output.clear(); } - std::string ShortDebugString() const { return name_for_output; } + std::string name_for_output; + void Clear() { name_for_output.clear(); } + std::string ShortDebugString() const { return name_for_output; } }; -class OpWithConf : public baidu::paddle_serving::predictor::OpWithChannelAndConf< - OpOutput, OpConf> { -public: - DECLARE_OP(OpWithConf); - void* create_config(const comcfg::ConfigUnit& conf) { - OpConf* op_conf = new (std::nothrow) OpConf(); - int err = 0; - op_conf->name_in_conf = conf["name_in_conf"].to_cstr(&err); - if (err != 0) { - return NULL; - } - return op_conf; +class OpWithConf + : public baidu::paddle_serving::predictor::OpWithChannelAndConf { + public: + DECLARE_OP(OpWithConf); + void* create_config(const comcfg::ConfigUnit& conf) { + OpConf* op_conf = new (std::nothrow) OpConf(); + int err = 0; + op_conf->name_in_conf = conf["name_in_conf"].to_cstr(&err); + if (err != 0) { + return NULL; } + return op_conf; + } - void delete_config(void* conf) { delete static_cast(conf); } + void delete_config(void* conf) { delete static_cast(conf); } - int inference() { - OpConf* op_conf = get_self_config(); - OpOutput* op_output = mutable_data(); - op_output->name_for_output = op_conf->name_in_conf; - return 0; - } + int inference() { + OpConf* op_conf = get_self_config(); + OpOutput* op_output = mutable_data(); + op_output->name_for_output = op_conf->name_in_conf; + return 0; + } }; DEFINE_OP(OpWithConf); -#ifndef DEFINE_UP_DOWN -#define DEFINE_UP_DOWN \ - void SetUp() {} \ - void TearDown() {} \ +#ifndef DEFINE_UP_DOWN +#define DEFINE_UP_DOWN \ + void SetUp() {} \ + void TearDown() {} class TestOP : public ::testing::Test { -public: - TestOP() {} - virtual ~TestOP() {} + public: + TestOP() {} + virtual ~TestOP() {} - DEFINE_UP_DOWN + DEFINE_UP_DOWN }; #undef DEFINE_UP_DOWN #endif - -} -} -} - -#endif +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_server_manager.cpp b/predictor/unittest/test_server_manager.cpp index e9e6f69fca422156b77c1119bcda4499ce3e2aab..e610e4a7ac9ccc0d3425fa4f2ec3c4aa7e8d7097 100644 --- a/predictor/unittest/test_server_manager.cpp +++ b/predictor/unittest/test_server_manager.cpp @@ -1,6 +1,21 @@ -#include "test_server_manager.h" // TestServerManager -#include // FLAGS -#include "framework/server.h" // ServerManager +// 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 "predictor/unittest/test_server_manager.h" // TestServerManager +#include // FLAGS +#include +#include "framework/server.h" // ServerManager namespace baidu { namespace paddle_serving { @@ -11,49 +26,49 @@ using baidu::paddle_serving::predictor::FLAGS_enable_nshead_protocol; using baidu::paddle_serving::predictor::FLAGS_nshead_protocol; TEST_F(TestServerManager, test_nshead_protocol) { - ASSERT_EQ(FLAGS_enable_nshead_protocol, false); - ServerManager server_manager1; - EXPECT_EQ(server_manager1._options.nshead_service, NULL); - - google::SetCommandLineOption("enable_nshead_protocol", "true"); - ASSERT_EQ(FLAGS_enable_nshead_protocol, true); - ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), "itp"); - ServerManager server_manager2; - EXPECT_NE(server_manager2._options.nshead_service, NULL); - - std::string protocol = "nova_pbrpc"; - google::SetCommandLineOption("enable_nshead_protocol", "true"); - google::SetCommandLineOption("nshead_protocol", protocol.c_str()); - ASSERT_EQ(FLAGS_enable_nshead_protocol, true); - ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); - ServerManager server_manager3; - EXPECT_NE(server_manager3._options.nshead_service, NULL); - - protocol = "public_pbrpc"; - google::SetCommandLineOption("enable_nshead_protocol", "true"); - google::SetCommandLineOption("nshead_protocol", protocol.c_str()); - ASSERT_EQ(FLAGS_enable_nshead_protocol, true); - ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); - ServerManager server_manager4; - EXPECT_NE(server_manager4._options.nshead_service, NULL); - - protocol = "nshead_mcpack"; - google::SetCommandLineOption("enable_nshead_protocol", "true"); - google::SetCommandLineOption("nshead_protocol", protocol.c_str()); - ASSERT_EQ(FLAGS_enable_nshead_protocol, true); - ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); - ServerManager server_manager5; - EXPECT_NE(server_manager5._options.nshead_service, NULL); - - protocol = "nshead_wrong_protocol"; - google::SetCommandLineOption("enable_nshead_protocol", "true"); - google::SetCommandLineOption("nshead_protocol", protocol.c_str()); - ASSERT_EQ(FLAGS_enable_nshead_protocol, true); - ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); - ServerManager server_manager6; - EXPECT_EQ(server_manager6._options.nshead_service, NULL); + ASSERT_EQ(FLAGS_enable_nshead_protocol, false); + ServerManager server_manager1; + EXPECT_EQ(server_manager1._options.nshead_service, NULL); + + google::SetCommandLineOption("enable_nshead_protocol", "true"); + ASSERT_EQ(FLAGS_enable_nshead_protocol, true); + ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), "itp"); + ServerManager server_manager2; + EXPECT_NE(server_manager2._options.nshead_service, NULL); + + std::string protocol = "nova_pbrpc"; + google::SetCommandLineOption("enable_nshead_protocol", "true"); + google::SetCommandLineOption("nshead_protocol", protocol.c_str()); + ASSERT_EQ(FLAGS_enable_nshead_protocol, true); + ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); + ServerManager server_manager3; + EXPECT_NE(server_manager3._options.nshead_service, NULL); + + protocol = "public_pbrpc"; + google::SetCommandLineOption("enable_nshead_protocol", "true"); + google::SetCommandLineOption("nshead_protocol", protocol.c_str()); + ASSERT_EQ(FLAGS_enable_nshead_protocol, true); + ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); + ServerManager server_manager4; + EXPECT_NE(server_manager4._options.nshead_service, NULL); + + protocol = "nshead_mcpack"; + google::SetCommandLineOption("enable_nshead_protocol", "true"); + google::SetCommandLineOption("nshead_protocol", protocol.c_str()); + ASSERT_EQ(FLAGS_enable_nshead_protocol, true); + ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); + ServerManager server_manager5; + EXPECT_NE(server_manager5._options.nshead_service, NULL); + + protocol = "nshead_wrong_protocol"; + google::SetCommandLineOption("enable_nshead_protocol", "true"); + google::SetCommandLineOption("nshead_protocol", protocol.c_str()); + ASSERT_EQ(FLAGS_enable_nshead_protocol, true); + ASSERT_STREQ(FLAGS_nshead_protocol.c_str(), protocol.c_str()); + ServerManager server_manager6; + EXPECT_EQ(server_manager6._options.nshead_service, NULL); } -} // namespace unittest -} // namespace paddle_serving -} // namespace baidu +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_server_manager.h b/predictor/unittest/test_server_manager.h index 5428b8de79148aee2257133a6206b63822a15326..23837a2ebb69ac92b18328c77d0a1a379459c34d 100644 --- a/predictor/unittest/test_server_manager.h +++ b/predictor/unittest/test_server_manager.h @@ -1,6 +1,18 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TEST_SERVER_MANAGER_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_TEST_SERVER_MANAGER_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. +#pragma once #include namespace baidu { @@ -8,13 +20,11 @@ namespace paddle_serving { namespace unittest { class TestServerManager : public ::testing::Test { -public: - void SetUp() { } - void TearDown() { } + public: + void SetUp() {} + void TearDown() {} }; -} // namespace unittest -} // namespace paddle_serving -} // namespace baidu - -#endif // BAIDU_PADDLE_SERVING_PREDICTOR_TEST_SERVER_MANAGER_H +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/predictor/unittest/test_tool.h b/predictor/unittest/test_tool.h index d2169fc07e73663068e79b61c3cda3bd681aa08d..ce42e7294f4747b36bbc2d04eca9e100052f24c1 100644 --- a/predictor/unittest/test_tool.h +++ b/predictor/unittest/test_tool.h @@ -1,65 +1,73 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_TEST_TOOL_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_TEST_TOOL_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 -#include -#include +#pragma once #include -#include -#include #include +#include +#include +#include +#include +#include +#include namespace baidu { namespace paddle_serving { namespace unittest { class AutoTempFile { -public: - AutoTempFile(const char* content) { - _need_del = false; - _name = generate_temp_name(); - FILE* fd = fopen(_name.c_str(), "w"); - if (!fd) { - return ; - } - fprintf(fd, "%s", content); - fclose(fd); - _need_del = true; + public: + explicit AutoTempFile(const char* content) { + _need_del = false; + _name = generate_temp_name(); + FILE* fd = fopen(_name.c_str(), "w"); + if (!fd) { + return; } + fprintf(fd, "%s", content); + fclose(fd); + _need_del = true; + } - ~AutoTempFile() { - if (_need_del) { - remove(_name.c_str()); - } + ~AutoTempFile() { + if (_need_del) { + remove(_name.c_str()); } + } - const char* name() { - return _name.c_str(); - } + const char* name() { return _name.c_str(); } -private: - std::string generate_temp_name() { - timeval tv; - srand(time(0)); - gettimeofday(&tv, NULL); - std::ostringstream oss; - oss << "uttest_temp_"; - oss << tv.tv_sec * 1000 + tv.tv_usec / 1000; - oss << "_"; - oss << (int)getpid(); - oss << "_"; - oss << rand(); - oss << ".conf"; - return oss.str(); - } + private: + std::string generate_temp_name() { + timeval tv; + srand(time(0)); + gettimeofday(&tv, NULL); + std::ostringstream oss; + oss << "uttest_temp_"; + oss << tv.tv_sec * 1000 + tv.tv_usec / 1000; + oss << "_"; + oss << static_cast(getpid()); + oss << "_"; + oss << rand_r(); + oss << ".conf"; + return oss.str(); + } -private: - std::string _name; - bool _need_del; + private: + std::string _name; + bool _need_del; }; - -} -} -} - -#endif +} // namespace unittest +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/CMakeLists.txt b/sdk-cpp/CMakeLists.txt index 52f30473824127b69b02ef2dff5f7b8837c8baab..b87ea37e498bf6de66d01d522cd90b0d783b660e 100644 --- a/sdk-cpp/CMakeLists.txt +++ b/sdk-cpp/CMakeLists.txt @@ -96,4 +96,3 @@ install(TARGETS int64tensor_format ${PADDLE_SERVING_INSTALL_DIR}/demo/client/int64tensor_format/bin) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/conf DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/demo/client/int64tensor_format/) - diff --git a/sdk-cpp/demo/dense_format.cpp b/sdk-cpp/demo/dense_format.cpp index f97f78e4bbf9ab1143b2d6958ec45c3a6b37b058..beb13877fffa1cc48c73a8b831ffda302987314a 100644 --- a/sdk-cpp/demo/dense_format.cpp +++ b/sdk-cpp/demo/dense_format.cpp @@ -1,25 +1,26 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file demo.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 20:12:44 - * @brief - * - **/ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include -#include "common.h" #include -#include "predictor_sdk.h" -#include "dense_service.pb.h" -#include "builtin_format.pb.h" +#include "sdk-cpp/builtin_format.pb.h" +#include "sdk-cpp/dense_service.pb.h" +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/predictor_sdk.h" using baidu::paddle_serving::sdk_cpp::Predictor; using baidu::paddle_serving::sdk_cpp::PredictorApi; @@ -28,115 +29,110 @@ using baidu::paddle_serving::predictor::dense_service::Response; using baidu::paddle_serving::predictor::format::DensePrediction; using baidu::paddle_serving::predictor::format::DenseInstance; -int create_req(Request& req) { - DenseInstance *ins = req.mutable_instances()->Add(); - ins->add_features(1.5); - ins->add_features(16.0); - ins->add_features(14.0); - - ins = req.mutable_instances()->Add(); - ins->add_features(1.0); - ins->add_features(2.0); - ins->add_features(3.0); - return 0; +int create_req(Request& req) { // NOLINT + DenseInstance* ins = req.mutable_instances()->Add(); + ins->add_features(1.5); + ins->add_features(16.0); + ins->add_features(14.0); + + ins = req.mutable_instances()->Add(); + ins->add_features(1.0); + ins->add_features(2.0); + ins->add_features(3.0); + return 0; } -void print_res( - const Request& req, - const Response& res, - std::string route_tag, - uint64_t elapse_ms) { - - for (uint32_t i = 0; i < res.predictions_size(); ++i) { - const DensePrediction &prediction = res.predictions(i); - std::ostringstream oss; - for (uint32_t j = 0; j < prediction.categories_size(); ++j) { - oss << prediction.categories(j) << " "; - } - LOG(INFO) << "Receive result " << oss.str(); +void print_res(const Request& req, + const Response& res, + std::string route_tag, + uint64_t elapse_ms) { + for (uint32_t i = 0; i < res.predictions_size(); ++i) { + const DensePrediction& prediction = res.predictions(i); + std::ostringstream oss; + for (uint32_t j = 0; j < prediction.categories_size(); ++j) { + oss << prediction.categories(j) << " "; } + LOG(INFO) << "Receive result " << oss.str(); + } - LOG(INFO) - << "Succ call predictor[dense_format], the tag is: " - << route_tag << ", elapse_ms: " << elapse_ms; + LOG(INFO) << "Succ call predictor[dense_format], the tag is: " << route_tag + << ", elapse_ms: " << elapse_ms; } int main(int argc, char** argv) { - PredictorApi api; - - // initialize logger instance - struct stat st_buf; - int ret = 0; - if ((ret = stat("./log", &st_buf)) != 0) { - mkdir("./log", 0777); - ret = stat("./log", &st_buf); - if (ret != 0) { - LOG(WARNING) << "Log path ./log not exist, and create fail"; - return -1; - } - } - FLAGS_log_dir = "./log"; - google::InitGoogleLogging(strdup(argv[0])); - - if (api.create("./conf", "predictors.prototxt") != 0) { - LOG(ERROR) << "Failed create predictors api!"; - return -1; + PredictorApi api; + + // initialize logger instance + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; } + } + FLAGS_log_dir = "./log"; + google::InitGoogleLogging(strdup(argv[0])); - Request req; - Response res; + if (api.create("./conf", "predictors.prototxt") != 0) { + LOG(ERROR) << "Failed create predictors api!"; + return -1; + } - api.thrd_initialize(); + Request req; + Response res; - while (true) { - timeval start; - gettimeofday(&start, NULL); + api.thrd_initialize(); - api.thrd_clear(); + while (true) { + timeval start; + gettimeofday(&start, NULL); - Predictor* predictor = api.fetch_predictor("dense_service"); - if (!predictor) { - LOG(ERROR) << "Failed fetch predictor: echo_service"; - return -1; - } + api.thrd_clear(); - req.Clear(); - res.Clear(); + Predictor* predictor = api.fetch_predictor("dense_service"); + if (!predictor) { + LOG(ERROR) << "Failed fetch predictor: echo_service"; + return -1; + } + + req.Clear(); + res.Clear(); - if (create_req(req) != 0) { - return -1; - } + if (create_req(req) != 0) { + return -1; + } - butil::IOBufBuilder debug_os; - if (predictor->debug(&req, &res, &debug_os) != 0) { - LOG(ERROR) << "failed call predictor with req:" - << req.ShortDebugString(); - return -1; - } + butil::IOBufBuilder debug_os; + if (predictor->debug(&req, &res, &debug_os) != 0) { + LOG(ERROR) << "failed call predictor with req:" << req.ShortDebugString(); + return -1; + } - butil::IOBuf debug_buf; - debug_os.move_to(debug_buf); - LOG(INFO) << "Debug string: " << debug_buf; + butil::IOBuf debug_buf; + debug_os.move_to(debug_buf); + LOG(INFO) << "Debug string: " << debug_buf; - timeval end; - gettimeofday(&end, NULL); + timeval end; + gettimeofday(&end, NULL); - uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - - (start.tv_sec * 1000 + start.tv_usec / 1000); - - print_res(req, res, predictor->tag(), elapse_ms); - res.Clear(); + uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - + (start.tv_sec * 1000 + start.tv_usec / 1000); - usleep(50); + print_res(req, res, predictor->tag(), elapse_ms); + res.Clear(); - } // while (true) + usleep(50); + } // while (true) - api.thrd_finalize(); - api.destroy(); + api.thrd_finalize(); + api.destroy(); - google::ShutdownGoogleLogging(); + google::ShutdownGoogleLogging(); - return 0; + return 0; } /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/demo/echo.cpp b/sdk-cpp/demo/echo.cpp index f9b06eeceafc57706cb28c54e8e3fac3ed99a68a..ca68d2cbafd177864bb3e97164bb57959adf7430 100644 --- a/sdk-cpp/demo/echo.cpp +++ b/sdk-cpp/demo/echo.cpp @@ -1,124 +1,121 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file demo.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 20:12:44 - * @brief - * - **/ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include -#include "common.h" #include -#include "predictor_sdk.h" -#include "echo_service.pb.h" -#include "builtin_format.pb.h" +#include "sdk-cpp/builtin_format.pb.h" +#include "sdk-cpp/echo_service.pb.h" +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/predictor_sdk.h" using baidu::paddle_serving::sdk_cpp::Predictor; using baidu::paddle_serving::sdk_cpp::PredictorApi; using baidu::paddle_serving::predictor::echo_service::RequestAndResponse; -int create_req(RequestAndResponse& req) { - req.set_a(1); - req.set_b(0.1); - return 0; +int create_req(RequestAndResponse& req) { // NOLINT + req.set_a(1); + req.set_b(0.1); + return 0; } -void print_res( - const RequestAndResponse& req, - const RequestAndResponse& res, - std::string route_tag, - uint64_t elapse_ms) { - LOG(INFO) << "Reqeive result: a = " << res.a() << ", b = " << res.b(); +void print_res(const RequestAndResponse& req, + const RequestAndResponse& res, + std::string route_tag, + uint64_t elapse_ms) { + LOG(INFO) << "Reqeive result: a = " << res.a() << ", b = " << res.b(); - LOG(INFO) - << "Succ call predictor[echo_service], the tag is: " - << route_tag << ", elapse_ms: " << elapse_ms; + LOG(INFO) << "Succ call predictor[echo_service], the tag is: " << route_tag + << ", elapse_ms: " << elapse_ms; } int main(int argc, char** argv) { - PredictorApi api; - - // initialize logger instance - struct stat st_buf; - int ret = 0; - if ((ret = stat("./log", &st_buf)) != 0) { - mkdir("./log", 0777); - ret = stat("./log", &st_buf); - if (ret != 0) { - LOG(WARNING) << "Log path ./log not exist, and create fail"; - return -1; - } - } - FLAGS_log_dir = "./log"; - google::InitGoogleLogging(strdup(argv[0])); - - if (api.create("./conf", "predictors.prototxt") != 0) { - LOG(ERROR) << "Failed create predictors api!"; - return -1; + PredictorApi api; + + // initialize logger instance + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; } + } + FLAGS_log_dir = "./log"; + google::InitGoogleLogging(strdup(argv[0])); - RequestAndResponse req; - RequestAndResponse res; + if (api.create("./conf", "predictors.prototxt") != 0) { + LOG(ERROR) << "Failed create predictors api!"; + return -1; + } - api.thrd_initialize(); + RequestAndResponse req; + RequestAndResponse res; - while (true) { - timeval start; - gettimeofday(&start, NULL); + api.thrd_initialize(); - api.thrd_clear(); + while (true) { + timeval start; + gettimeofday(&start, NULL); - Predictor* predictor = api.fetch_predictor("echo_service"); - if (!predictor) { - LOG(ERROR) << "Failed fetch predictor: echo_service"; - return -1; - } + api.thrd_clear(); - req.Clear(); - res.Clear(); + Predictor* predictor = api.fetch_predictor("echo_service"); + if (!predictor) { + LOG(ERROR) << "Failed fetch predictor: echo_service"; + return -1; + } + + req.Clear(); + res.Clear(); - if (create_req(req) != 0) { - return -1; - } + if (create_req(req) != 0) { + return -1; + } - butil::IOBufBuilder debug_os; - if (predictor->debug(&req, &res, &debug_os) != 0) { - LOG(ERROR) << "failed call predictor with req:" - << req.ShortDebugString(); - return -1; - } + butil::IOBufBuilder debug_os; + if (predictor->debug(&req, &res, &debug_os) != 0) { + LOG(ERROR) << "failed call predictor with req:" << req.ShortDebugString(); + return -1; + } - butil::IOBuf debug_buf; - debug_os.move_to(debug_buf); - LOG(INFO) << "Debug string: " << debug_buf; + butil::IOBuf debug_buf; + debug_os.move_to(debug_buf); + LOG(INFO) << "Debug string: " << debug_buf; - timeval end; - gettimeofday(&end, NULL); + timeval end; + gettimeofday(&end, NULL); - uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - - (start.tv_sec * 1000 + start.tv_usec / 1000); - - print_res(req, res, predictor->tag(), elapse_ms); - res.Clear(); + uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - + (start.tv_sec * 1000 + start.tv_usec / 1000); - usleep(50); + print_res(req, res, predictor->tag(), elapse_ms); + res.Clear(); - } // while (true) + usleep(50); + } // while (true) - api.thrd_finalize(); - api.destroy(); + api.thrd_finalize(); + api.destroy(); - google::ShutdownGoogleLogging(); + google::ShutdownGoogleLogging(); - return 0; + return 0; } /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/demo/int64tensor_format.cpp b/sdk-cpp/demo/int64tensor_format.cpp index 941111ada154891479f2264721191fe350cc1e84..97160d82969d5932cc89416c8aecdbad117705de 100644 --- a/sdk-cpp/demo/int64tensor_format.cpp +++ b/sdk-cpp/demo/int64tensor_format.cpp @@ -1,25 +1,26 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file demo.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 20:12:44 - * @brief - * - **/ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include -#include "common.h" #include -#include "predictor_sdk.h" -#include "int64tensor_service.pb.h" -#include "builtin_format.pb.h" +#include "sdk-cpp/builtin_format.pb.h" +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/predictor_sdk.h" +#include "sdk-cpp/int64tensor_service.pb.h" using baidu::paddle_serving::sdk_cpp::Predictor; using baidu::paddle_serving::sdk_cpp::PredictorApi; @@ -28,127 +29,122 @@ using baidu::paddle_serving::predictor::int64tensor_service::Response; using baidu::paddle_serving::predictor::format::Float32TensorPredictor; using baidu::paddle_serving::predictor::format::Int64TensorInstance; -int create_req(Request& req) { - Int64TensorInstance *ins = req.mutable_instances()->Add(); - ins->add_data(1); - ins->add_data(2); - ins->add_data(3); - ins->add_data(4); - ins->add_shape(2); - ins->add_shape(2); - - ins = req.mutable_instances()->Add(); - ins->add_data(5); - ins->add_data(6); - ins->add_data(7); - ins->add_data(8); - ins->add_data(9); - ins->add_shape(5); - ins->add_shape(1); - return 0; +int create_req(Request& req) { // NOLINT + Int64TensorInstance* ins = req.mutable_instances()->Add(); + ins->add_data(1); + ins->add_data(2); + ins->add_data(3); + ins->add_data(4); + ins->add_shape(2); + ins->add_shape(2); + + ins = req.mutable_instances()->Add(); + ins->add_data(5); + ins->add_data(6); + ins->add_data(7); + ins->add_data(8); + ins->add_data(9); + ins->add_shape(5); + ins->add_shape(1); + return 0; } -void print_res( - const Request& req, - const Response& res, - std::string route_tag, - uint64_t elapse_ms) { - - for (uint32_t i = 0; i < res.predictions_size(); ++i) { - const Float32TensorPredictor &prediction = res.predictions(i); - std::ostringstream oss1; - for (uint32_t j = 0; j < prediction.data_size(); ++j) { - oss1 << prediction.data(j) << " "; - } - - std::ostringstream oss2; - for (uint32_t j = 0; j < prediction.shape_size(); ++j) { - oss2 << prediction.shape(j) << " "; - } - LOG(INFO) << "Receive result " << oss1.str() << ", shape " << oss2.str(); +void print_res(const Request& req, + const Response& res, + std::string route_tag, + uint64_t elapse_ms) { + for (uint32_t i = 0; i < res.predictions_size(); ++i) { + const Float32TensorPredictor& prediction = res.predictions(i); + std::ostringstream oss1; + for (uint32_t j = 0; j < prediction.data_size(); ++j) { + oss1 << prediction.data(j) << " "; + } + + std::ostringstream oss2; + for (uint32_t j = 0; j < prediction.shape_size(); ++j) { + oss2 << prediction.shape(j) << " "; } + LOG(INFO) << "Receive result " << oss1.str() << ", shape " << oss2.str(); + } - LOG(INFO) - << "Succ call predictor[int64tensor_format], the tag is: " - << route_tag << ", elapse_ms: " << elapse_ms; + LOG(INFO) << "Succ call predictor[int64tensor_format], the tag is: " + << route_tag << ", elapse_ms: " << elapse_ms; } int main(int argc, char** argv) { - PredictorApi api; - - // initialize logger instance - struct stat st_buf; - int ret = 0; - if ((ret = stat("./log", &st_buf)) != 0) { - mkdir("./log", 0777); - ret = stat("./log", &st_buf); - if (ret != 0) { - LOG(WARNING) << "Log path ./log not exist, and create fail"; - return -1; - } - } - FLAGS_log_dir = "./log"; - google::InitGoogleLogging(strdup(argv[0])); - - if (api.create("./conf", "predictors.prototxt") != 0) { - LOG(ERROR) << "Failed create predictors api!"; - return -1; + PredictorApi api; + + // initialize logger instance + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; } + } + FLAGS_log_dir = "./log"; + google::InitGoogleLogging(strdup(argv[0])); - Request req; - Response res; + if (api.create("./conf", "predictors.prototxt") != 0) { + LOG(ERROR) << "Failed create predictors api!"; + return -1; + } - api.thrd_initialize(); + Request req; + Response res; - while (true) { - timeval start; - gettimeofday(&start, NULL); + api.thrd_initialize(); - api.thrd_clear(); + while (true) { + timeval start; + gettimeofday(&start, NULL); - Predictor* predictor = api.fetch_predictor("int64tensor_service"); - if (!predictor) { - LOG(ERROR) << "Failed fetch predictor: int64tensor_service"; - return -1; - } + api.thrd_clear(); - req.Clear(); - res.Clear(); + Predictor* predictor = api.fetch_predictor("int64tensor_service"); + if (!predictor) { + LOG(ERROR) << "Failed fetch predictor: int64tensor_service"; + return -1; + } - if (create_req(req) != 0) { - return -1; - } + req.Clear(); + res.Clear(); - butil::IOBufBuilder debug_os; - if (predictor->debug(&req, &res, &debug_os) != 0) { - LOG(ERROR) << "failed call predictor with req:" - << req.ShortDebugString(); - return -1; - } + if (create_req(req) != 0) { + return -1; + } + + butil::IOBufBuilder debug_os; + if (predictor->debug(&req, &res, &debug_os) != 0) { + LOG(ERROR) << "failed call predictor with req:" << req.ShortDebugString(); + return -1; + } - butil::IOBuf debug_buf; - debug_os.move_to(debug_buf); - LOG(INFO) << "Debug string: " << debug_buf; + butil::IOBuf debug_buf; + debug_os.move_to(debug_buf); + LOG(INFO) << "Debug string: " << debug_buf; - timeval end; - gettimeofday(&end, NULL); + timeval end; + gettimeofday(&end, NULL); - uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - - (start.tv_sec * 1000 + start.tv_usec / 1000); - - print_res(req, res, predictor->tag(), elapse_ms); - res.Clear(); + uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - + (start.tv_sec * 1000 + start.tv_usec / 1000); - usleep(50); + print_res(req, res, predictor->tag(), elapse_ms); + res.Clear(); - } // while (true) + usleep(50); + } // while (true) - api.thrd_finalize(); - api.destroy(); + api.thrd_finalize(); + api.destroy(); - google::ShutdownGoogleLogging(); + google::ShutdownGoogleLogging(); - return 0; + return 0; } /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/demo/sparse_format.cpp b/sdk-cpp/demo/sparse_format.cpp index ec611b5c714181bfa778a53b380629b01b280ba6..c428881dc909237754a66f5c116fa2b4e266afeb 100644 --- a/sdk-cpp/demo/sparse_format.cpp +++ b/sdk-cpp/demo/sparse_format.cpp @@ -1,25 +1,26 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file demo.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 20:12:44 - * @brief - * - **/ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include -#include "common.h" #include -#include "predictor_sdk.h" -#include "sparse_service.pb.h" -#include "builtin_format.pb.h" +#include "sdk-cpp/builtin_format.pb.h" +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/predictor_sdk.h" +#include "sdk-cpp/sparse_service.pb.h" using baidu::paddle_serving::sdk_cpp::Predictor; using baidu::paddle_serving::sdk_cpp::PredictorApi; @@ -28,125 +29,120 @@ using baidu::paddle_serving::predictor::sparse_service::Response; using baidu::paddle_serving::predictor::format::SparsePrediction; using baidu::paddle_serving::predictor::format::SparseInstance; -int create_req(Request& req) { - SparseInstance *ins = req.mutable_instances()->Add(); - ins->add_keys(26); - ins->add_keys(182); - ins->add_keys(232); - ins->add_shape(2000); - ins->add_values(1); - ins->add_values(1); - ins->add_values(1); - - ins = req.mutable_instances()->Add(); - ins->add_keys(0); - ins->add_keys(182); - ins->add_keys(232); - ins->add_keys(299); - ins->add_shape(2000); - ins->add_values(13); - ins->add_values(1); - ins->add_values(1); - ins->add_values(1); - return 0; +int create_req(Request& req) { // NOLINT + SparseInstance* ins = req.mutable_instances()->Add(); + ins->add_keys(26); + ins->add_keys(182); + ins->add_keys(232); + ins->add_shape(2000); + ins->add_values(1); + ins->add_values(1); + ins->add_values(1); + + ins = req.mutable_instances()->Add(); + ins->add_keys(0); + ins->add_keys(182); + ins->add_keys(232); + ins->add_keys(299); + ins->add_shape(2000); + ins->add_values(13); + ins->add_values(1); + ins->add_values(1); + ins->add_values(1); + return 0; } -void print_res( - const Request& req, - const Response& res, - std::string route_tag, - uint64_t elapse_ms) { - - for (uint32_t i = 0; i < res.predictions_size(); ++i) { - const SparsePrediction &prediction = res.predictions(i); - std::ostringstream oss; - for (uint32_t j = 0; j < prediction.categories_size(); ++j) { - oss << prediction.categories(j) << " "; - } - LOG(INFO) << "Receive result " << oss.str(); +void print_res(const Request& req, + const Response& res, + std::string route_tag, + uint64_t elapse_ms) { + for (uint32_t i = 0; i < res.predictions_size(); ++i) { + const SparsePrediction& prediction = res.predictions(i); + std::ostringstream oss; + for (uint32_t j = 0; j < prediction.categories_size(); ++j) { + oss << prediction.categories(j) << " "; } + LOG(INFO) << "Receive result " << oss.str(); + } - LOG(INFO) - << "Succ call predictor[sparse_format], the tag is: " - << route_tag << ", elapse_ms: " << elapse_ms; + LOG(INFO) << "Succ call predictor[sparse_format], the tag is: " << route_tag + << ", elapse_ms: " << elapse_ms; } int main(int argc, char** argv) { - PredictorApi api; - - // initialize logger instance - struct stat st_buf; - int ret = 0; - if ((ret = stat("./log", &st_buf)) != 0) { - mkdir("./log", 0777); - ret = stat("./log", &st_buf); - if (ret != 0) { - LOG(WARNING) << "Log path ./log not exist, and create fail"; - return -1; - } - } - FLAGS_log_dir = "./log"; - google::InitGoogleLogging(strdup(argv[0])); - - if (api.create("./conf", "predictors.prototxt") != 0) { - LOG(ERROR) << "Failed create predictors api!"; - return -1; + PredictorApi api; + + // initialize logger instance + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; } + } + FLAGS_log_dir = "./log"; + google::InitGoogleLogging(strdup(argv[0])); - Request req; - Response res; + if (api.create("./conf", "predictors.prototxt") != 0) { + LOG(ERROR) << "Failed create predictors api!"; + return -1; + } - api.thrd_initialize(); + Request req; + Response res; - while (true) { - timeval start; - gettimeofday(&start, NULL); + api.thrd_initialize(); - api.thrd_clear(); + while (true) { + timeval start; + gettimeofday(&start, NULL); - Predictor* predictor = api.fetch_predictor("sparse_service"); - if (!predictor) { - LOG(ERROR) << "Failed fetch predictor: sparse_service"; - return -1; - } + api.thrd_clear(); - req.Clear(); - res.Clear(); + Predictor* predictor = api.fetch_predictor("sparse_service"); + if (!predictor) { + LOG(ERROR) << "Failed fetch predictor: sparse_service"; + return -1; + } + + req.Clear(); + res.Clear(); - if (create_req(req) != 0) { - return -1; - } + if (create_req(req) != 0) { + return -1; + } - butil::IOBufBuilder debug_os; - if (predictor->debug(&req, &res, &debug_os) != 0) { - LOG(ERROR) << "failed call predictor with req:" - << req.ShortDebugString(); - return -1; - } + butil::IOBufBuilder debug_os; + if (predictor->debug(&req, &res, &debug_os) != 0) { + LOG(ERROR) << "failed call predictor with req:" << req.ShortDebugString(); + return -1; + } - butil::IOBuf debug_buf; - debug_os.move_to(debug_buf); - LOG(INFO) << "Debug string: " << debug_buf; + butil::IOBuf debug_buf; + debug_os.move_to(debug_buf); + LOG(INFO) << "Debug string: " << debug_buf; - timeval end; - gettimeofday(&end, NULL); + timeval end; + gettimeofday(&end, NULL); - uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - - (start.tv_sec * 1000 + start.tv_usec / 1000); - - print_res(req, res, predictor->tag(), elapse_ms); - res.Clear(); + uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - + (start.tv_sec * 1000 + start.tv_usec / 1000); - usleep(50); + print_res(req, res, predictor->tag(), elapse_ms); + res.Clear(); - } // while (true) + usleep(50); + } // while (true) - api.thrd_finalize(); - api.destroy(); + api.thrd_finalize(); + api.destroy(); - google::ShutdownGoogleLogging(); + google::ShutdownGoogleLogging(); - return 0; + return 0; } /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/demo/ximage.cpp b/sdk-cpp/demo/ximage.cpp index 223ef7e02304344663e67163efd1821752457104..72d3407c6e039000a9e97c8bbcd60df80af07477 100644 --- a/sdk-cpp/demo/ximage.cpp +++ b/sdk-cpp/demo/ximage.cpp @@ -1,25 +1,26 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file demo.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 20:12:44 - * @brief - * - **/ -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include +#include #include -#include "common.h" #include -#include "predictor_sdk.h" -#include "image_class.pb.h" -#include "builtin_format.pb.h" +#include "sdk-cpp/builtin_format.pb.h" +#include "sdk-cpp/image_class.pb.h" +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/predictor_sdk.h" using baidu::paddle_serving::sdk_cpp::Predictor; using baidu::paddle_serving::sdk_cpp::PredictorApi; @@ -28,124 +29,120 @@ using baidu::paddle_serving::predictor::format::DensePrediction; using baidu::paddle_serving::predictor::image_classification::Request; using baidu::paddle_serving::predictor::image_classification::Response; -int create_req(Request& req) { - static const char* TEST_IMAGE_PATH = "./data/images/what.jpg"; - - FILE* fp = fopen(TEST_IMAGE_PATH, "rb"); - if (!fp) { - LOG(ERROR) << "Failed open image: " << TEST_IMAGE_PATH; - return -1; - } - - fseek(fp, 0L, SEEK_END); - size_t isize = ftell(fp); - char* ibuf = new(std::nothrow) char[isize]; - if (!ibuf) { - LOG(ERROR) << "Failed malloc image buffer"; - fclose(fp); - return -1; - } - - fseek(fp, 0, SEEK_SET); - fread(ibuf, sizeof(ibuf[0]), isize, fp); - XImageReqInstance* ins = req.add_instances(); - if (!ins) { - LOG(ERROR) << "Failed create req instance"; - delete[] ibuf; - fclose(fp); - return -1; - } +int create_req(Request& req) { // NOLINT + static const char* TEST_IMAGE_PATH = "./data/images/what.jpg"; - ins->set_image_binary(ibuf, isize); - ins->set_image_length(isize); + FILE* fp = fopen(TEST_IMAGE_PATH, "rb"); + if (!fp) { + LOG(ERROR) << "Failed open image: " << TEST_IMAGE_PATH; + return -1; + } + fseek(fp, 0L, SEEK_END); + size_t isize = ftell(fp); + char* ibuf = new (std::nothrow) char[isize]; + if (!ibuf) { + LOG(ERROR) << "Failed malloc image buffer"; + fclose(fp); + return -1; + } + + fseek(fp, 0, SEEK_SET); + fread(ibuf, sizeof(ibuf[0]), isize, fp); + XImageReqInstance* ins = req.add_instances(); + if (!ins) { + LOG(ERROR) << "Failed create req instance"; delete[] ibuf; fclose(fp); + return -1; + } - return 0; -} + ins->set_image_binary(ibuf, isize); + ins->set_image_length(isize); -void print_res( - const Request& req, - const Response& res, - std::string route_tag, - uint64_t elapse_ms) { + delete[] ibuf; + fclose(fp); - static const char* GT_TEXT_PATH - = "./data/images/groundtruth.txt"; - std::vector gt_labels; + return 0; +} - std::ifstream file(GT_TEXT_PATH); - std::string temp_str; - while (std::getline(file, temp_str)) { - gt_labels.push_back(temp_str); +void print_res(const Request& req, + const Response& res, + std::string route_tag, + uint64_t elapse_ms) { + static const char* GT_TEXT_PATH = "./data/images/groundtruth.txt"; + std::vector gt_labels; + + std::ifstream file(GT_TEXT_PATH); + std::string temp_str; + while (std::getline(file, temp_str)) { + gt_labels.push_back(temp_str); + } + + DensePrediction json_msg; + uint32_t sample_size = res.predictions_size(); + std::string err_string; + for (uint32_t si = 0; si < sample_size; ++si) { + std::string json = res.predictions(si).response_json(); + butil::IOBuf buf; + buf.append(json); + butil::IOBufAsZeroCopyInputStream wrapper(buf); + if (!json2pb::JsonToProtoMessage(&wrapper, &json_msg, &err_string)) { + LOG(ERROR) << "Failed parse json from str:" << json; + return; } - DensePrediction json_msg; - uint32_t sample_size = res.predictions_size(); - std::string err_string; - for (uint32_t si = 0; si < sample_size; ++si) { - std::string json = res.predictions(si).response_json(); - butil::IOBuf buf; - buf.append(json); - butil::IOBufAsZeroCopyInputStream wrapper(buf); - if (!json2pb::JsonToProtoMessage(&wrapper, &json_msg, &err_string)) { - LOG(ERROR) << "Failed parse json from str:" << json; - return ; - } - - uint32_t csize = json_msg.categories_size(); - if (csize <= 0) { - LOG(ERROR) << "sample-" << si << "has no" - << "categories props"; - continue; - } - float max_prop = json_msg.categories(0); - uint32_t max_idx = 0; - for (uint32_t ci = 1; ci < csize; ++ci) { - if (json_msg.categories(ci) > max_prop) { - max_prop = json_msg.categories(ci); - max_idx = ci; - } - } - - LOG(INFO) << "sample-" << si << "'s classify result: " - << gt_labels[max_idx] << ", prop: " << max_prop; + uint32_t csize = json_msg.categories_size(); + if (csize <= 0) { + LOG(ERROR) << "sample-" << si << "has no" + << "categories props"; + continue; + } + float max_prop = json_msg.categories(0); + uint32_t max_idx = 0; + for (uint32_t ci = 1; ci < csize; ++ci) { + if (json_msg.categories(ci) > max_prop) { + max_prop = json_msg.categories(ci); + max_idx = ci; + } } - LOG(INFO) - << "Succ call predictor[ximage], the tag is: " - << route_tag << ", elapse_ms: " << elapse_ms; + LOG(INFO) << "sample-" << si << "'s classify result: " << gt_labels[max_idx] + << ", prop: " << max_prop; + } + + LOG(INFO) << "Succ call predictor[ximage], the tag is: " << route_tag + << ", elapse_ms: " << elapse_ms; } int main(int argc, char** argv) { - PredictorApi api; - - // initialize logger instance - struct stat st_buf; - int ret = 0; - if ((ret = stat("./log", &st_buf)) != 0) { - mkdir("./log", 0777); - ret = stat("./log", &st_buf); - if (ret != 0) { - LOG(WARNING) << "Log path ./log not exist, and create fail"; - return -1; - } + PredictorApi api; + + // initialize logger instance + struct stat st_buf; + int ret = 0; + if ((ret = stat("./log", &st_buf)) != 0) { + mkdir("./log", 0777); + ret = stat("./log", &st_buf); + if (ret != 0) { + LOG(WARNING) << "Log path ./log not exist, and create fail"; + return -1; } - FLAGS_log_dir = "./log"; - google::InitGoogleLogging(strdup(argv[0])); + } + FLAGS_log_dir = "./log"; + google::InitGoogleLogging(strdup(argv[0])); - if (api.create("./conf", "predictors.prototxt") != 0) { - LOG(ERROR) << "Failed create predictors api!"; - return -1; - } + if (api.create("./conf", "predictors.prototxt") != 0) { + LOG(ERROR) << "Failed create predictors api!"; + return -1; + } - Request req; - Response res; + Request req; + Response res; - api.thrd_initialize(); + api.thrd_initialize(); - while (true) { + while (true) { timeval start; gettimeofday(&start, NULL); @@ -153,22 +150,21 @@ int main(int argc, char** argv) { Predictor* predictor = api.fetch_predictor("ximage"); if (!predictor) { - LOG(ERROR) << "Failed fetch predictor: wasq"; - return -1; + LOG(ERROR) << "Failed fetch predictor: wasq"; + return -1; } req.Clear(); res.Clear(); if (create_req(req) != 0) { - return -1; + return -1; } butil::IOBufBuilder debug_os; if (predictor->debug(&req, &res, &debug_os) != 0) { - LOG(ERROR) << "failed call predictor with req:" - << req.ShortDebugString(); - return -1; + LOG(ERROR) << "failed call predictor with req:" << req.ShortDebugString(); + return -1; } butil::IOBuf debug_buf; @@ -178,20 +174,19 @@ int main(int argc, char** argv) { timeval end; gettimeofday(&end, NULL); - uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - - (start.tv_sec * 1000 + start.tv_usec / 1000); - + uint64_t elapse_ms = (end.tv_sec * 1000 + end.tv_usec / 1000) - + (start.tv_sec * 1000 + start.tv_usec / 1000); + print_res(req, res, predictor->tag(), elapse_ms); res.Clear(); usleep(50); + } // while (true) - } // while (true) - - api.thrd_finalize(); - api.destroy(); + api.thrd_finalize(); + api.destroy(); - return 0; + return 0; } /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/include/abtest.h b/sdk-cpp/include/abtest.h index 2011167fe0779db4f32c6e9839299ce79f29b874..b30b5442afd845fdc5317300f26c1c382b468517 100644 --- a/sdk-cpp/include/abtest.h +++ b/sdk-cpp/include/abtest.h @@ -1,24 +1,24 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file abtest.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/06 17:11:38 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_ABTEST_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_ABTEST_H - -#include "stub.h" -#include "common.h" -#include "factory.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. + +#pragma once #include +#include +#include +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/factory.h" +#include "sdk-cpp/include/stub.h" namespace baidu { namespace paddle_serving { @@ -27,53 +27,43 @@ namespace sdk_cpp { class Stub; class Variant; -static const std::string WEIGHT_SEPERATOR = "|"; +static const char* WEIGHT_SEPERATOR = "|"; class EndpointRouterBase { -public: - typedef std::vector VariantList; + public: + typedef std::vector VariantList; - virtual ~EndpointRouterBase() {} + virtual ~EndpointRouterBase() {} - virtual int initialize( - const google::protobuf::Message& conf) = 0; + virtual int initialize(const google::protobuf::Message& conf) = 0; - virtual Variant* route(const VariantList&) = 0; + virtual Variant* route(const VariantList&) = 0; - virtual Variant* route( - const VariantList&, - const void*) = 0; + virtual Variant* route(const VariantList&, const void*) = 0; }; class WeightedRandomRender : public EndpointRouterBase { -public: - static int register_self() { - INLINE_REGIST_OBJECT(WeightedRandomRender, EndpointRouterBase, -1); - return 0; - } + public: + static int register_self() { + INLINE_REGIST_OBJECT(WeightedRandomRender, EndpointRouterBase, -1); + return 0; + } - WeightedRandomRender() : _normalized_sum(0) {} + WeightedRandomRender() : _normalized_sum(0) {} - ~WeightedRandomRender() {} + ~WeightedRandomRender() {} - int initialize( - const google::protobuf::Message& conf); + int initialize(const google::protobuf::Message& conf); - Variant* route(const VariantList&); + Variant* route(const VariantList&); - Variant* route( - const VariantList&, - const void*); + Variant* route(const VariantList&, const void*); -private: - std::vector _variant_weight_list; - uint32_t _normalized_sum; + private: + std::vector _variant_weight_list; + uint32_t _normalized_sum; }; -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_ABTEST_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/common.h b/sdk-cpp/include/common.h index 9ca75a876612e41a3cf08f300135631e50be6d50..8e7138a234cc8a87a468df523278aa128cfc7a15 100644 --- a/sdk-cpp/include/common.h +++ b/sdk-cpp/include/common.h @@ -1,51 +1,43 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file common.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 20:24:19 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_CPP_SDK_COMMON_H -#define BAIDU_PADDLE_SERVING_CPP_SDK_COMMON_H - -#include -#include -#include -#include +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include +#include #include +#include +#include #include -#include +#include +#include #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sdk_configure.pb.h" -#include "configure_parser.h" +#include "boost/unordered_map.hpp" +#include "gflags/gflags.h" +#include "google/protobuf/message.h" -#include "utils.h" +#include "brpc/channel.h" +#include "brpc/parallel_channel.h" +#include "brpc/traceprintf.h" +#include "bthread/bthread.h" +#include "butil/logging.h" +#include "butil/object_pool.h" +#include "butil/time.h" +#include "bvar/bvar.h" +#include "json2pb/json_to_pb.h" -#endif //BAIDU_PADDLE_SERVING_CPP_SDK_COMMON_H +#include "configure/include/configure_parser.h" +#include "configure/sdk_configure.pb.h" -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +#include "sdk-cpp/include/utils.h" diff --git a/sdk-cpp/include/config_manager.h b/sdk-cpp/include/config_manager.h index 5696092b6068b6ccb7242f11e8921adf1160b6a4..10dab498682159908001653aa661ed95fa82dd29 100644 --- a/sdk-cpp/include/config_manager.h +++ b/sdk-cpp/include/config_manager.h @@ -1,95 +1,78 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file config_manager.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 15:28:43 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_CONFIG_MANAGER_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_CONFIG_MANAGER_H - -#include "common.h" -#include "endpoint_config.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. + +#pragma once +#include +#include +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/endpoint_config.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { class EndpointConfigManager { -public: - static EndpointConfigManager& instance() { - static EndpointConfigManager singleton; - return singleton; - } + public: + static EndpointConfigManager& instance() { + static EndpointConfigManager singleton; + return singleton; + } + + EndpointConfigManager() + : _last_update_timestamp(0), _current_endpointmap_id(1) {} - EndpointConfigManager() - : _last_update_timestamp(0), - _current_endpointmap_id(1) {} + int create(const char* path, const char* file); - int create(const char* path, const char* file); + int load(); - int load(); + bool need_reload() { return false; } - bool need_reload() { - return false; + int reload() { + if (!need_reload()) { + LOG(INFO) << "Noneed reload endpoin config"; + return 0; } - int reload() { - if (!need_reload()) { - LOG(INFO) << "Noneed reload endpoin config"; - return 0; - } + return load(); + } - return load(); - } + const std::map& config() { return _ep_map; } - const std::map& config() { - return _ep_map; - } + const std::map& config() const { return _ep_map; } - const std::map& config() const { - return _ep_map; - } + private: + int init_one_variant(const configure::VariantConf& conf, + VariantInfo& var); // NOLINT -private: - int init_one_variant( - const configure::VariantConf& conf, - VariantInfo& var); - - int init_one_endpoint( - const configure::Predictor& conf, - EndpointInfo& ep, - const VariantInfo& default_var); - - int merge_variant( - const VariantInfo& default_var, - const configure::VariantConf& conf, - VariantInfo& merged_var); - - int parse_tag_values( - SplitParameters& split); - -private: - std::map _ep_map; - std::string _endpoint_config_path; - std::string _endpoint_config_file; - uint32_t _last_update_timestamp; - uint32_t _current_endpointmap_id; -}; + int init_one_endpoint(const configure::Predictor& conf, + EndpointInfo& ep, // NOLINT + const VariantInfo& default_var); -} // sdk_cpp -} // paddle_serving -} // baidu + int merge_variant(const VariantInfo& default_var, + const configure::VariantConf& conf, + VariantInfo& merged_var); // NOLINT -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_CONFIG_MANAGER_H + int parse_tag_values(SplitParameters& split); // NOLINT + + private: + std::map _ep_map; + std::string _endpoint_config_path; + std::string _endpoint_config_file; + uint32_t _last_update_timestamp; + uint32_t _current_endpointmap_id; +}; -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/endpoint.h b/sdk-cpp/include/endpoint.h index 6a3c98899c744e494e8295dd3025486adc1640d3..d28b1d56b73b1f0f139ed3574c6cbcc7af6cd98c 100644 --- a/sdk-cpp/include/endpoint.h +++ b/sdk-cpp/include/endpoint.h @@ -1,74 +1,66 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/resource.h - * @author wanlijin(wanlijin01@baidu.com) - * @date 2018/07/06 17:06:25 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_ENDPOINT_H -#define BAIDU_PADDLE_SERVING_SDK_ENDPOINT_H - -#include "common.h" -#include "endpoint_config.h" -#include "stub.h" -#include "variant.h" -#include "predictor.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. + +#pragma once + +#include +#include +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/endpoint_config.h" +#include "sdk-cpp/include/predictor.h" +#include "sdk-cpp/include/stub.h" +#include "sdk-cpp/include/variant.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { class Endpoint { -friend class EndpointRouterBase; -public: + friend class EndpointRouterBase; - virtual ~Endpoint() {} + public: + virtual ~Endpoint() {} - Endpoint() { - _variant_list.clear(); - } + Endpoint() { _variant_list.clear(); } - int initialize(const EndpointInfo& ep_info); + int initialize(const EndpointInfo& ep_info); - int thrd_initialize(); + int thrd_initialize(); - int thrd_clear(); + int thrd_clear(); - int thrd_finalize(); + int thrd_finalize(); - Predictor* get_predictor(const void* params); + Predictor* get_predictor(const void* params); - Predictor* get_predictor(); + Predictor* get_predictor(); - int ret_predictor(Predictor* predictor); + int ret_predictor(Predictor* predictor); - const std::string& endpoint_name() const { - return _endpoint_name; - } + const std::string& endpoint_name() const { return _endpoint_name; } -private: - int initialize_variant( - const VariantInfo& var_info, - const std::string& service, - const std::string& ep_name, - std::vector& stubs); + private: + int initialize_variant(const VariantInfo& var_info, + const std::string& service, + const std::string& ep_name, + std::vector& stubs); // NOLINT -private: - std::string _endpoint_name; - std::vector _variant_list; + private: + std::string _endpoint_name; + std::vector _variant_list; }; -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPPRESOURCE_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/endpoint_config.h b/sdk-cpp/include/endpoint_config.h index fc98b3decc93f59bc892dca59270db3528ebd2ce..0fdabdb4985aca34606ca9d02dd1dfae230ab657 100644 --- a/sdk-cpp/include/endpoint_config.h +++ b/sdk-cpp/include/endpoint_config.h @@ -1,116 +1,111 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file endpoint_config.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/12 15:17:56 - * @brief - * - **/ - -#include "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. + +#pragma once #include - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_ENDPOINT_CONFIG_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_ENDPOINT_CONFIG_H +#include +#include +#include "sdk-cpp/include/common.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { #define PARSE_CONF_ITEM(conf, item, name, fail) \ - do { \ - if (conf.has_##name()) { \ - item.set(conf.name()); \ - } \ - else { \ - LOG(ERROR) << "Not found key in configue: " << #name;\ - } \ - } while (0) - -#define ASSIGN_CONF_ITEM(dest, src, fail) \ - do { \ - if (!src.init) { \ - LOG(ERROR) << "Cannot assign an unintialized item: " \ - << #src << " to dest: " << #dest; \ - return fail; \ - } \ - dest = src.value; \ - } while (0) - -template struct type_traits { - static type_traits tag; + do { \ + if (conf.has_##name()) { \ + item.set(conf.name()); \ + } else { \ + LOG(ERROR) << "Not found key in configue: " << #name; \ + } \ + } while (0) + +#define ASSIGN_CONF_ITEM(dest, src, fail) \ + do { \ + if (!src.init) { \ + LOG(ERROR) << "Cannot assign an unintialized item: " << #src \ + << " to dest: " << #dest; \ + return fail; \ + } \ + dest = src.value; \ + } while (0) + +template +struct type_traits { + static type_traits tag; }; -template +template type_traits type_traits::tag; -template struct ConfigItem { - T value; - bool init; - ConfigItem() : init(false) {} - void set(const T& unit) { - value = unit; - init = true; - } +template +struct ConfigItem { + T value; + bool init; + ConfigItem() : init(false) {} + void set(const T& unit) { + value = unit; + init = true; + } }; struct Connection { - ConfigItem tmo_conn; - ConfigItem tmo_rpc; - ConfigItem tmo_hedge; - ConfigItem cnt_retry_conn; - ConfigItem cnt_retry_hedge; - ConfigItem cnt_maxconn_per_host; - ConfigItem type_conn; + ConfigItem tmo_conn; + ConfigItem tmo_rpc; + ConfigItem tmo_hedge; + ConfigItem cnt_retry_conn; + ConfigItem cnt_retry_hedge; + ConfigItem cnt_maxconn_per_host; + ConfigItem type_conn; }; struct NamingInfo { - ConfigItem cluster_naming; - ConfigItem load_balancer; - ConfigItem cluster_filter; + ConfigItem cluster_naming; + ConfigItem load_balancer; + ConfigItem cluster_filter; }; struct RpcParameters { - ConfigItem protocol; - ConfigItem compress_type; - ConfigItem package_size; - ConfigItem route_tag; - ConfigItem max_channel; + ConfigItem protocol; + ConfigItem compress_type; + ConfigItem package_size; + ConfigItem route_tag; + ConfigItem max_channel; }; struct SplitParameters { - ConfigItem split_tag; - ConfigItem tag_cands_str; - std::vector tag_values; + ConfigItem split_tag; + ConfigItem tag_cands_str; + std::vector tag_values; }; struct VariantInfo { - VariantInfo() {} - Connection connection; - NamingInfo naminginfo; - RpcParameters parameters; - SplitParameters splitinfo; + VariantInfo() {} + Connection connection; + NamingInfo naminginfo; + RpcParameters parameters; + SplitParameters splitinfo; }; struct EndpointInfo { - EndpointInfo() : ab_test(NULL) {} - std::string endpoint_name; - std::string stub_service; - std::vector vars; - void* ab_test; + EndpointInfo() : ab_test(NULL) {} + std::string endpoint_name; + std::string stub_service; + std::vector vars; + void* ab_test; }; -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_ENDPOINT_CONFIG_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/factory.h b/sdk-cpp/include/factory.h index f43d4bc640ebc79586d237c27dcb6808b7f43715..e49525be5772787c10ce8abf76f7573ddf6f7a7d 100644 --- a/sdk-cpp/include/factory.h +++ b/sdk-cpp/include/factory.h @@ -1,193 +1,187 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/factory.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/10 22:09:57 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_FACTORY_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_FACTORY_H - -#include "common.h" -#include "stub_impl.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. + +#pragma once +#include +#include +#include #include "glog/raw_logging.h" +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/stub_impl.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { -#define INLINE_REGIST_OBJECT(D, B, E) \ -do { \ - Factory* factory = \ - new (std::nothrow) Factory(); \ - if (factory == NULL \ - || FactoryPool::instance().register_factory(\ - #D, factory) != 0) { \ - RAW_LOG_ERROR("Failed regist factory: %s->%s in macro!", #D, #B); \ - return E; \ - } \ -} while (0) - -#define DECLARE_FACTORY_OBJECT(D, B) \ - static int regist(const std::string& tag) { \ - Factory* factory = \ - new (std::nothrow) Factory();\ - if (factory == NULL \ - || FactoryPool::instance().register_factory(\ - tag, factory) != 0) { \ - RAW_LOG_ERROR("Failed regist factory: %s in macro!", #D);\ - return -1; \ - } \ - return 0; \ - } +#define INLINE_REGIST_OBJECT(D, B, E) \ + do { \ + Factory* factory = new (std::nothrow) Factory(); \ + if (factory == NULL || \ + FactoryPool::instance().register_factory(#D, factory) != 0) { \ + RAW_LOG_ERROR("Failed regist factory: %s->%s in macro!", #D, #B); \ + return E; \ + } \ + } while (0) + +#define DECLARE_FACTORY_OBJECT(D, B) \ + static int regist(const std::string& tag) { \ + Factory* factory = new (std::nothrow) Factory(); \ + if (factory == NULL || \ + FactoryPool::instance().register_factory(tag, factory) != 0) { \ + RAW_LOG_ERROR("Failed regist factory: %s in macro!", #D); \ + return -1; \ + } \ + return 0; \ + } #define PDS_STR_CAT(a, b) PDS_STR_CAT_I(a, b) -#define PDS_STR_CAT_I(a, b) a ## b - -#define DEFINE_FACTORY_OBJECT(D) \ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - D::regist(#D); \ -} - -#define REGIST_FACTORY_OBJECT_IMPL(D, B) \ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - ::baidu::paddle_serving::sdk_cpp::Factory* factory =\ - new (::std::nothrow) ::baidu::paddle_serving::sdk_cpp::Factory();\ - if (factory == NULL \ - || ::baidu::paddle_serving::sdk_cpp::FactoryPool::instance().register_factory(\ - #D, factory) != 0) { \ - RAW_LOG_ERROR("Failed regist factory: %s->%s in macro!", #D, #B); \ - return ; \ - } \ - return ; \ -} - -#define REGIST_FACTORY_OBJECT_IMPL_WITH_TAG(D, B, T)\ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - ::baidu::paddle_serving::sdk_cpp::Factory* factory =\ - new (::std::nothrow) ::baidu::paddle_serving::sdk_cpp::Factory();\ - if (factory == NULL \ - || ::baidu::paddle_serving::sdk_cpp::FactoryPool::instance().register_factory(\ - T, factory) != 0) { \ - RAW_LOG_ERROR("Failed regist factory: %s->%s, tag %s in macro!", #D, #B, T); \ - return ; \ - } \ - return ; \ -} - -#define REGIST_ABTEST_OBJECT(D) \ - REGIST_FACTORY_OBJECT_IMPL( \ - D, \ - ::baidu::paddle_serving::sdk_cpp::ABTestRouterBase) - -#define REGIST_ABTEST_OBJECT_WITH_TAG(D, T) \ - REGIST_FACTORY_OBJECT_IMPL_WITH_TAG( \ - D, \ - ::baidu::paddle_serving::sdk_cpp::ABTestRouterBase,\ - T) - -#define REGIST_STUB_OBJECT_WITH_TAG(D, C, R, I, O, T) \ -__attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, __LINE__)(void) \ -{ \ - RAW_LOG_INFO("REGIST_STUB_OBJECT_WITH_TAG"); \ - ::baidu::paddle_serving::sdk_cpp::Factory< \ - ::baidu::paddle_serving::sdk_cpp::StubImpl,\ - ::baidu::paddle_serving::sdk_cpp::Stub>* factory = \ - new (::std::nothrow) ::baidu::paddle_serving::sdk_cpp::Factory< \ - ::baidu::paddle_serving::sdk_cpp::StubImpl,\ - ::baidu::paddle_serving::sdk_cpp::Stub>(); \ - if (factory == NULL \ - || ::baidu::paddle_serving::sdk_cpp::FactoryPool< \ - ::baidu::paddle_serving::sdk_cpp::Stub>::instance().register_factory(\ - T, factory) != 0) { \ - RAW_LOG_ERROR("Failed regist factory: %s->Stub, tag: %s in macro!", #D, T); \ - return ; \ - } \ - return ; \ -} +#define PDS_STR_CAT_I(a, b) a##b + +#define DEFINE_FACTORY_OBJECT(D) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + D::regist(#D); \ + } + +#define REGIST_FACTORY_OBJECT_IMPL(D, B) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + ::baidu::paddle_serving::sdk_cpp::Factory* factory = \ + new (::std::nothrow)::baidu::paddle_serving::sdk_cpp::Factory(); \ + if (factory == NULL || \ + ::baidu::paddle_serving::sdk_cpp::FactoryPool::instance() \ + .register_factory(#D, factory) != 0) { \ + RAW_LOG_ERROR("Failed regist factory: %s->%s in macro!", #D, #B); \ + return; \ + } \ + return; \ + } + +#define REGIST_FACTORY_OBJECT_IMPL_WITH_TAG(D, B, T) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + ::baidu::paddle_serving::sdk_cpp::Factory* factory = \ + new (::std::nothrow)::baidu::paddle_serving::sdk_cpp::Factory(); \ + if (factory == NULL || \ + ::baidu::paddle_serving::sdk_cpp::FactoryPool::instance() \ + .register_factory(T, factory) != 0) { \ + RAW_LOG_ERROR( \ + "Failed regist factory: %s->%s, tag %s in macro!", #D, #B, T); \ + return; \ + } \ + return; \ + } + +#define REGIST_ABTEST_OBJECT(D) \ + REGIST_FACTORY_OBJECT_IMPL( \ + D, ::baidu::paddle_serving::sdk_cpp::ABTestRouterBase) + +#define REGIST_ABTEST_OBJECT_WITH_TAG(D, T) \ + REGIST_FACTORY_OBJECT_IMPL_WITH_TAG( \ + D, ::baidu::paddle_serving::sdk_cpp::ABTestRouterBase, T) + +#define REGIST_STUB_OBJECT_WITH_TAG(D, C, R, I, O, T) \ + __attribute__((constructor)) static void PDS_STR_CAT(GlobalRegistObject, \ + __LINE__)(void) { \ + RAW_LOG_INFO("REGIST_STUB_OBJECT_WITH_TAG"); \ + ::baidu::paddle_serving::sdk_cpp::Factory< \ + ::baidu::paddle_serving::sdk_cpp::StubImpl, \ + ::baidu::paddle_serving::sdk_cpp::Stub>* factory = \ + new (::std::nothrow)::baidu::paddle_serving::sdk_cpp::Factory< \ + ::baidu::paddle_serving::sdk_cpp::StubImpl, \ + ::baidu::paddle_serving::sdk_cpp::Stub>(); \ + if (factory == NULL || \ + ::baidu::paddle_serving::sdk_cpp::FactoryPool< \ + ::baidu::paddle_serving::sdk_cpp::Stub>::instance() \ + .register_factory(T, factory) != 0) { \ + RAW_LOG_ERROR( \ + "Failed regist factory: %s->Stub, tag: %s in macro!", #D, T); \ + return; \ + } \ + return; \ + } class Stub; class EndpointRouterBase; class VariantRouterBase; -template +template class FactoryBase { -public: - virtual B* gen() = 0; - virtual void del(B* obj) = 0; + public: + virtual B* gen() = 0; + virtual void del(B* obj) = 0; }; -template +template class Factory : public FactoryBase { -public: - B* gen() { - return new(std::nothrow) D(); - } + public: + B* gen() { return new (std::nothrow) D(); } - void del(B* obj) { - delete dynamic_cast(obj); - } + void del(B* obj) { delete dynamic_cast(obj); } }; -template +template class FactoryPool { -public: - static FactoryPool& instance() { - static FactoryPool singleton; - return singleton; + public: + static FactoryPool& instance() { + static FactoryPool singleton; + return singleton; + } + + int register_factory(const std::string& tag, FactoryBase* factory) { + typename std::map*>::iterator it = + _pool.find(tag); + if (it != _pool.end()) { + RAW_LOG_ERROR("Insert duplicate with tag: %s", tag.c_str()); + return -1; } - int register_factory(const std::string& tag, - FactoryBase* factory) { - typename std::map*>::iterator it - = _pool.find(tag); - if (it != _pool.end()) { - RAW_LOG_ERROR("Insert duplicate with tag: %s", tag.c_str()); - return -1; - } - - std::pair< - typename std::map*>::iterator, - bool> r = _pool.insert(std::make_pair(tag, factory)); - if (!r.second) { - RAW_LOG_ERROR("Failed insert new factory with: %s", tag.c_str()); - return -1; - } - - RAW_LOG_INFO("Succ insert one factory, tag: %s, base type %s", tag.c_str(), typeid(B).name()); - - return 0; + std::pair*>::iterator, bool> + r = _pool.insert(std::make_pair(tag, factory)); + if (!r.second) { + RAW_LOG_ERROR("Failed insert new factory with: %s", tag.c_str()); + return -1; } - B* generate_object(const std::string& tag) { - typename std::map*>::iterator it - = _pool.find(tag); - if (it == _pool.end() || it->second == NULL) { - RAW_LOG_ERROR("Not found factory pool, tag: %s, pool size: %u", tag.c_str(), _pool.size()); - return NULL; - } - - return it->second->gen(); + RAW_LOG_INFO("Succ insert one factory, tag: %s, base type %s", + tag.c_str(), + typeid(B).name()); + + return 0; + } + + B* generate_object(const std::string& tag) { + typename std::map*>::iterator it = + _pool.find(tag); + if (it == _pool.end() || it->second == NULL) { + RAW_LOG_ERROR("Not found factory pool, tag: %s, pool size: %u", + tag.c_str(), + _pool.size()); + return NULL; } - template - void return_object(B* object) { - Factory factory; - factory->del(object); - } + return it->second->gen(); + } + + template + void return_object(B* object) { + Factory factory; + factory->del(object); + } -private: - std::map*> _pool; + private: + std::map*> _pool; }; typedef FactoryPool StubFactory; @@ -196,10 +190,6 @@ typedef FactoryPool ResponseMergerFactory; typedef FactoryPool EndpointRouterFactory; typedef FactoryPool VariantRouterFactory; -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_FACTORY_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/predictor.h b/sdk-cpp/include/predictor.h index 34672694432e33cc4c604a8208f065e2c393760f..82e3f6bc0259218cfd00a8e453b73dfc493ce8ac 100644 --- a/sdk-cpp/include/predictor.h +++ b/sdk-cpp/include/predictor.h @@ -1,234 +1,217 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/predictor.h - * @author wanlijin01(com@baidu.com) - * @date 2018/07/05 16:53:43 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_H - -#include "stub.h" -#include "common.h" -#include "endpoint_config.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. + +#pragma once +#include +#include +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/endpoint_config.h" +#include "sdk-cpp/include/stub.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { -#define GET_OBJECT_FROM_POOL(param, T, err) \ - do { \ - param = butil::get_object(); \ - if (!param) { \ - LOG(ERROR) << "Failed get object from pool" \ - << ", arg:" << #param << "type: " \ - << #T; \ - return err; \ - } \ - } while (0) - -static const brpc::CompressType compress_types[] = { - brpc::COMPRESS_TYPE_NONE, - brpc::COMPRESS_TYPE_SNAPPY, - brpc::COMPRESS_TYPE_GZIP, - brpc::COMPRESS_TYPE_ZLIB, - brpc::COMPRESS_TYPE_LZ4}; - -typedef void (*DoneType) (google::protobuf::Message* res, - brpc::Controller* controller); - -template +#define GET_OBJECT_FROM_POOL(param, T, err) \ + do { \ + param = butil::get_object(); \ + if (!param) { \ + LOG(ERROR) << "Failed get object from pool" \ + << ", arg:" << #param << "type: " << #T; \ + return err; \ + } \ + } while (0) + +static const brpc::CompressType compress_types[] = {brpc::COMPRESS_TYPE_NONE, + brpc::COMPRESS_TYPE_SNAPPY, + brpc::COMPRESS_TYPE_GZIP, + brpc::COMPRESS_TYPE_ZLIB, + brpc::COMPRESS_TYPE_LZ4}; + +typedef void (*DoneType)(google::protobuf::Message* res, + brpc::Controller* controller); + +template class FunctionClosure : public ::google::protobuf::Closure { -public: - typedef void (*FunctionType)(Arg1* arg1, Arg2* arg2); + public: + typedef void (*FunctionType)(Arg1* arg1, Arg2* arg2); - FunctionClosure() {} + FunctionClosure() {} - ~FunctionClosure() {} + ~FunctionClosure() {} - int init(FunctionType function, bool self_deleting, - bool arg1_deleting, bool arg2_deleting, - Arg1* arg1 = NULL, Arg2* arg2 = NULL); + int init(FunctionType function, + bool self_deleting, + bool arg1_deleting, + bool arg2_deleting, + Arg1* arg1 = NULL, + Arg2* arg2 = NULL); - void Run(); + void Run(); -private: - FunctionType _function; - Arg1* _arg1; - Arg2* _arg2; - bool _self_deleting; - bool _arg1_deleting; - bool _arg2_deleting; + private: + FunctionType _function; + Arg1* _arg1; + Arg2* _arg2; + bool _self_deleting; + bool _arg1_deleting; + bool _arg2_deleting; }; class InterfaceAdaptor { -public: - typedef google::protobuf::Message RequestMessage; - typedef google::protobuf::Message ResponseMessage; - - virtual int partition(RequestMessage& request, std::vector& out) = 0; - virtual int merge(std::vector& response, ResponseMessage& out) = 0; + public: + typedef google::protobuf::Message RequestMessage; + typedef google::protobuf::Message ResponseMessage; + + virtual int partition(RequestMessage& request, // NOLINT + std::vector& out) = 0; // NOLINT + virtual int merge(std::vector& response, // NOLINT + ResponseMessage& out) = 0; // NOLINT }; class EchoAdaptor : public InterfaceAdaptor { -public: - typedef google::protobuf::Message RequestMessage; - typedef google::protobuf::Message ResponseMessage; - - int partition(RequestMessage& request, std::vector& out) { - return 0; - } - - int merge(std::vector& response, ResponseMessage*& out) { - return 0; - } + public: + typedef google::protobuf::Message RequestMessage; + typedef google::protobuf::Message ResponseMessage; + + int partition(RequestMessage& request, // NOLINT + std::vector& out) { // NOLINT + return 0; + } + + int merge(std::vector& response, // NOLINT + ResponseMessage*& out) { // NOLINT + return 0; + } }; class Predictor { -public: - // synchronize interface - virtual int inference( - google::protobuf::Message* req, - google::protobuf::Message* res) = 0; - - // asynchronize interface - virtual int inference( - google::protobuf::Message* req, - google::protobuf::Message* res, - DoneType done, - brpc::CallId* cid = NULL) = 0; + public: + // synchronize interface + virtual int inference(google::protobuf::Message* req, + google::protobuf::Message* res) = 0; - // synchronize interface - virtual int debug( - google::protobuf::Message* req, - google::protobuf::Message* res, - butil::IOBufBuilder* debug_os) = 0; + // asynchronize interface + virtual int inference(google::protobuf::Message* req, + google::protobuf::Message* res, + DoneType done, + brpc::CallId* cid = NULL) = 0; + + // synchronize interface + virtual int debug(google::protobuf::Message* req, + google::protobuf::Message* res, + butil::IOBufBuilder* debug_os) = 0; - // un-blocked interface - virtual int send_inference( - google::protobuf::Message* req, - google::protobuf::Message* res) = 0; - virtual int recv_inference() = 0; - virtual void cancel_inference() = 0; + // un-blocked interface + virtual int send_inference(google::protobuf::Message* req, + google::protobuf::Message* res) = 0; + virtual int recv_inference() = 0; + virtual void cancel_inference() = 0; - virtual const char* tag() = 0; + virtual const char* tag() = 0; - virtual const google::protobuf::Service* service() = 0; + virtual const google::protobuf::Service* service() = 0; - virtual const brpc::Controller* controller() = 0; + virtual const brpc::Controller* controller() = 0; - virtual const google::protobuf::RpcChannel* channel() = 0; + virtual const google::protobuf::RpcChannel* channel() = 0; - virtual const Stub* stub() = 0; + virtual const Stub* stub() = 0; - virtual bool is_inited() = 0; + virtual bool is_inited() = 0; }; -template +template class PredictorImpl : public Predictor { -public: - - typedef google::protobuf::MethodDescriptor MethodDescriptor; - - PredictorImpl() : _service(NULL), _stub(NULL), _infer(NULL), - _debug(NULL), _channel(NULL), _inited(false) { - // _inferid = 0; - } + public: + typedef google::protobuf::MethodDescriptor MethodDescriptor; + + PredictorImpl() + : _service(NULL), + _stub(NULL), + _infer(NULL), + _debug(NULL), + _channel(NULL), + _inited(false) { + // _inferid = 0; + } + + ~PredictorImpl() {} + + int init(google::protobuf::RpcChannel* chnl, + T* service, + const MethodDescriptor* infer, + const MethodDescriptor* debug, + const RpcParameters& options, + Stub* stub, + const std::string& tag); + + int reset(const RpcParameters& options, brpc::Controller& cntl); // NOLINT + + int deinit(); + + bool is_inited() { return _inited; } + + // 同步接口 + int inference(google::protobuf::Message* req, google::protobuf::Message* res); + + // 异步接口 + int inference(google::protobuf::Message* req, + google::protobuf::Message* res, + DoneType done, + brpc::CallId* cid = NULL); + + // Debug同步接口 + int debug(google::protobuf::Message* req, + google::protobuf::Message* res, + butil::IOBufBuilder* debug_os); - ~PredictorImpl() {} + // 半同步(非阻塞)接口 + int send_inference(google::protobuf::Message* req, + google::protobuf::Message* res); - int init( - google::protobuf::RpcChannel* chnl, - T* service, - const MethodDescriptor* infer, - const MethodDescriptor* debug, - const RpcParameters& options, - Stub* stub, - const std::string& tag); + // 半同步(非阻塞)接口 + int recv_inference(); - int reset( - const RpcParameters& options, - brpc::Controller& cntl); + // 半同步(非阻塞)接口 + void cancel_inference(); - int deinit(); + const char* tag(); - bool is_inited() { - return _inited; - } + const google::protobuf::Service* service() { return _service; } - // 同步接口 - int inference( - google::protobuf::Message* req, - google::protobuf::Message* res); + const brpc::Controller* controller() { return &_cntl; } - // 异步接口 - int inference( - google::protobuf::Message* req, - google::protobuf::Message* res, - DoneType done, - brpc::CallId* cid = NULL); + const google::protobuf::RpcChannel* channel() { return _channel; } - // Debug同步接口 - int debug( - google::protobuf::Message* req, - google::protobuf::Message* res, - butil::IOBufBuilder* debug_os); + const Stub* stub() { return _stub; } - // 半同步(非阻塞)接口 - int send_inference( - google::protobuf::Message* req, - google::protobuf::Message* res); - - // 半同步(非阻塞)接口 - int recv_inference(); - - // 半同步(非阻塞)接口 - void cancel_inference(); - - const char* tag(); - - const google::protobuf::Service* service() { - return _service; - } - - const brpc::Controller* controller() { - return &_cntl; - } - - const google::protobuf::RpcChannel* channel() { - return _channel; - } - - const Stub* stub() { - return _stub; - } - -private: - T* _service; - Stub* _stub; - const MethodDescriptor* _infer; - const MethodDescriptor* _debug; - google::protobuf::RpcChannel* _channel; - brpc::Controller _cntl; - brpc::CallId _inferid; - RpcParameters _options; - std::string _tag; - bool _inited; + private: + T* _service; + Stub* _stub; + const MethodDescriptor* _infer; + const MethodDescriptor* _debug; + google::protobuf::RpcChannel* _channel; + brpc::Controller _cntl; + brpc::CallId _inferid; + RpcParameters _options; + std::string _tag; + bool _inited; }; -} // sdk_cpp -} // paddle_serving -} // baidu +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu #include "predictor.hpp" - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/include/predictor.hpp b/sdk-cpp/include/predictor.hpp index eeed9d518c278bdb31c45d390c5c7493fbcd935c..de34040d2203d0c9792b77fd4b04b5e7dcbacafe 100644 --- a/sdk-cpp/include/predictor.hpp +++ b/sdk-cpp/include/predictor.hpp @@ -1,204 +1,211 @@ -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_HPP -#define BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_HPP - +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include namespace baidu { namespace paddle_serving { namespace sdk_cpp { class MetricScope; class Stub; -template +template class StubImpl; -template -inline ::google::protobuf::Closure* NewClosure( - void (*function)(Arg1*, Arg2*), - Arg1* arg1 = NULL, Arg2* arg2 = NULL) { - - FunctionClosure* closure = butil::get_object< - FunctionClosure >(); - - if (closure) { - if (closure->init(function, true, false, true, - arg1, arg2) != 0) { - LOG(FATAL) << "Failed create closure objects"; - return NULL; - } +template +inline ::google::protobuf::Closure* NewClosure(void (*function)(Arg1*, Arg2*), + Arg1* arg1 = NULL, + Arg2* arg2 = NULL) { + FunctionClosure* closure = + butil::get_object>(); + + if (closure) { + if (closure->init(function, true, false, true, arg1, arg2) != 0) { + LOG(FATAL) << "Failed create closure objects"; + return NULL; } + } - return closure; + return closure; } -template -int FunctionClosure::init( - FunctionType function, bool self_deleting, - bool arg1_deleting, bool arg2_deleting, - Arg1* arg1, Arg2* arg2) { - _function = function; - _self_deleting = self_deleting; - _arg1_deleting = arg1_deleting; - _arg2_deleting = arg2_deleting; - - if (arg2 == NULL) { - GET_OBJECT_FROM_POOL(_arg2, Arg2, -1); - _arg2_deleting = true; - } - - return 0; +template +int FunctionClosure::init(FunctionType function, + bool self_deleting, + bool arg1_deleting, + bool arg2_deleting, + Arg1* arg1, + Arg2* arg2) { + _function = function; + _self_deleting = self_deleting; + _arg1_deleting = arg1_deleting; + _arg2_deleting = arg2_deleting; + + if (arg2 == NULL) { + GET_OBJECT_FROM_POOL(_arg2, Arg2, -1); + _arg2_deleting = true; + } + + return 0; } -template +template void FunctionClosure::Run() { - bool self_delete = _self_deleting; - bool arg1_delete = _arg1_deleting; - bool arg2_delete = _arg2_deleting; + bool self_delete = _self_deleting; + bool arg1_delete = _arg1_deleting; + bool arg2_delete = _arg2_deleting; - _function(_arg1, _arg2); + _function(_arg1, _arg2); - if (self_delete) { - butil::return_object(this); - } + if (self_delete) { + butil::return_object(this); + } - if (arg2_delete) { - butil::return_object(_arg2); - } + if (arg2_delete) { + butil::return_object(_arg2); + } } -template int PredictorImpl::init( - google::protobuf::RpcChannel* chnl, - T* service, - const MethodDescriptor* infer, - const MethodDescriptor* debug, - const RpcParameters& options, - Stub* stub, - const std::string& tag) { - MetricScope metric(stub, "rpc_init"); - butil::Timer tt(butil::Timer::STARTED); - _service = service; - _channel = chnl; - _infer = infer; - _debug = debug; - _options = options; - _stub = stub; - _tag = tag; - reset(_options, _cntl); - _inited = true; - return 0; +template +int PredictorImpl::init(google::protobuf::RpcChannel* chnl, + T* service, + const MethodDescriptor* infer, + const MethodDescriptor* debug, + const RpcParameters& options, + Stub* stub, + const std::string& tag) { + MetricScope metric(stub, "rpc_init"); + butil::Timer tt(butil::Timer::STARTED); + _service = service; + _channel = chnl; + _infer = infer; + _debug = debug; + _options = options; + _stub = stub; + _tag = tag; + reset(_options, _cntl); + _inited = true; + return 0; } -template int PredictorImpl::reset( - const RpcParameters& options, - brpc::Controller& cntl) { - cntl.Reset(); - if (options.compress_type.init) { - cntl.set_request_compress_type( - compress_types[options.compress_type.value]); - } - return 0; +template +int PredictorImpl::reset(const RpcParameters& options, + brpc::Controller& cntl) { // NOLINT + cntl.Reset(); + if (options.compress_type.init) { + cntl.set_request_compress_type(compress_types[options.compress_type.value]); + } + return 0; } -template int PredictorImpl::deinit() { - // do nothing - _inited = false; - return 0; +template +int PredictorImpl::deinit() { + // do nothing + _inited = false; + return 0; } -template int PredictorImpl::inference( - google::protobuf::Message* req, - google::protobuf::Message* res) { - MetricScope metric(_stub, "infer_sync"); - _service->CallMethod(_infer, &_cntl, req, res, NULL); - if (_cntl.Failed()) { - LOG(WARNING) - << "inference call failed, message: " - << _cntl.ErrorText(); - _stub->update_average(1, "failure"); - return -1; - } - return 0; +template +int PredictorImpl::inference(google::protobuf::Message* req, + google::protobuf::Message* res) { + MetricScope metric(_stub, "infer_sync"); + _service->CallMethod(_infer, &_cntl, req, res, NULL); + if (_cntl.Failed()) { + LOG(WARNING) << "inference call failed, message: " << _cntl.ErrorText(); + _stub->update_average(1, "failure"); + return -1; + } + return 0; } -template int PredictorImpl::inference( - google::protobuf::Message* req, - google::protobuf::Message* res, - DoneType done, - brpc::CallId* cid) { - MetricScope metric(_stub, "infer_async"); - // 异步接口不能使用当前predictor的controller成员,而应该 - // 在对象池临时申请一个独立的对象,且直到异步回调执行完 - // 成后才能释放,而该释放行为被NewClosure自动托管,用户 - // 无需关注。 - brpc::Controller* cntl - = butil::get_object(); - if (!cntl || reset(_options, *cntl) != 0) { - LOG(FATAL) << "Failed get controller from object pool," - << "cntl is null: " << (cntl == NULL); - _stub->update_average(1, "failure"); - return -1; - } - - if (cid != NULL) { // you can join this rpc with cid - *cid = cntl->call_id(); - } - - _service->CallMethod(_infer, cntl, req, res, NewClosure( - done, res, cntl)); - return 0; +template +int PredictorImpl::inference(google::protobuf::Message* req, + google::protobuf::Message* res, + DoneType done, + brpc::CallId* cid) { + MetricScope metric(_stub, "infer_async"); + // 异步接口不能使用当前predictor的controller成员,而应该 + // 在对象池临时申请一个独立的对象,且直到异步回调执行完 + // 成后才能释放,而该释放行为被NewClosure自动托管,用户 + // 无需关注。 + brpc::Controller* cntl = butil::get_object(); + if (!cntl || reset(_options, *cntl) != 0) { + LOG(FATAL) << "Failed get controller from object pool," + << "cntl is null: " << (cntl == NULL); + _stub->update_average(1, "failure"); + return -1; + } + + if (cid != NULL) { // you can join this rpc with cid + *cid = cntl->call_id(); + } + + _service->CallMethod(_infer, cntl, req, res, NewClosure(done, res, cntl)); + return 0; } -template int PredictorImpl::debug( - google::protobuf::Message* req, - google::protobuf::Message* res, - butil::IOBufBuilder* debug_os) { - MetricScope metric(_stub, "debug"); - _service->CallMethod(_debug, &_cntl, req, res, NULL); - if (_cntl.Failed()) { - LOG(WARNING) - << "inference call failed, message: " - << _cntl.ErrorText(); - _stub->update_average(1, "failure"); - return -1; - } - - // copy debug info from response attachment - (*debug_os) << _cntl.response_attachment(); - return 0; +template +int PredictorImpl::debug(google::protobuf::Message* req, + google::protobuf::Message* res, + butil::IOBufBuilder* debug_os) { + MetricScope metric(_stub, "debug"); + _service->CallMethod(_debug, &_cntl, req, res, NULL); + if (_cntl.Failed()) { + LOG(WARNING) << "inference call failed, message: " << _cntl.ErrorText(); + _stub->update_average(1, "failure"); + return -1; + } + + // copy debug info from response attachment + (*debug_os) << _cntl.response_attachment(); + return 0; } -template int PredictorImpl::send_inference( - google::protobuf::Message* req, - google::protobuf::Message* res) { - MetricScope metric(_stub, "infer_send"); - _inferid = _cntl.call_id(); - _service->CallMethod( - _infer, &_cntl, req, res, brpc::DoNothing()); - return 0; +template +int PredictorImpl::send_inference(google::protobuf::Message* req, + google::protobuf::Message* res) { + MetricScope metric(_stub, "infer_send"); + _inferid = _cntl.call_id(); + _service->CallMethod(_infer, &_cntl, req, res, brpc::DoNothing()); + return 0; } -template int PredictorImpl::recv_inference() { - // waiting for callback done - MetricScope metric(_stub, "infer_recv"); - brpc::Join(_inferid); - if (_cntl.Failed()) { - LOG(WARNING) << "Failed recv response from rpc" - << ", err: " << _cntl.ErrorText(); - _stub->update_average(1, "failure"); - return -1; - } - return 0; +template +int PredictorImpl::recv_inference() { + // waiting for callback done + MetricScope metric(_stub, "infer_recv"); + brpc::Join(_inferid); + if (_cntl.Failed()) { + LOG(WARNING) << "Failed recv response from rpc" + << ", err: " << _cntl.ErrorText(); + _stub->update_average(1, "failure"); + return -1; + } + return 0; } -template void PredictorImpl::cancel_inference() { - MetricScope metric(_stub, "infer_cancel"); - brpc::StartCancel(_inferid); +template +void PredictorImpl::cancel_inference() { + MetricScope metric(_stub, "infer_cancel"); + brpc::StartCancel(_inferid); } -template const char* PredictorImpl::tag() { - return _tag.c_str(); +template +const char* PredictorImpl::tag() { + return _tag.c_str(); } -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTORR_HPP +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/predictor_sdk.h b/sdk-cpp/include/predictor_sdk.h index ee0ccade55c05e05b7e3ab9c6e93b8d64e6b2114..15e30f1e5e462a7b8f4569e71e0b73ccdf1b5b4b 100644 --- a/sdk-cpp/include/predictor_sdk.h +++ b/sdk-cpp/include/predictor_sdk.h @@ -1,93 +1,86 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/predictor_api.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 17:33:59 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_SDK_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_SDK_H - -#include "stub.h" -#include "predictor.h" -#include "endpoint_config.h" -#include "endpoint.h" -#include "config_manager.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. + +#pragma once +#include +#include +#include "sdk-cpp/include/config_manager.h" +#include "sdk-cpp/include/endpoint.h" +#include "sdk-cpp/include/endpoint_config.h" +#include "sdk-cpp/include/predictor.h" +#include "sdk-cpp/include/stub.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { class PredictorApi { -public: - PredictorApi() {} + public: + PredictorApi() {} - int register_all(); + int register_all(); - int create(const char* path, const char* file); + int create(const char* path, const char* file); - int thrd_initialize(); + int thrd_initialize(); - int thrd_clear(); + int thrd_clear(); - int thrd_finalize(); + int thrd_finalize(); - void destroy(); + void destroy(); - static PredictorApi& instance() { - static PredictorApi api; - return api; - } + static PredictorApi& instance() { + static PredictorApi api; + return api; + } - Predictor* fetch_predictor(std::string ep_name) { - std::map::iterator it - = _endpoints.find(ep_name); - if (it == _endpoints.end() || !it->second) { - LOG(ERROR) << "Failed fetch predictor:" - << ", ep_name: " << ep_name; - return NULL; - } - return it->second->get_predictor(); + Predictor* fetch_predictor(std::string ep_name) { + std::map::iterator it = _endpoints.find(ep_name); + if (it == _endpoints.end() || !it->second) { + LOG(ERROR) << "Failed fetch predictor:" + << ", ep_name: " << ep_name; + return NULL; } - - Predictor* fetch_predictor(std::string ep_name, - const void* params) { - std::map::iterator it - = _endpoints.find(ep_name); - if (it == _endpoints.end() || !it->second) { - LOG(ERROR) << "Failed fetch predictor:" - << ", ep_name: " << ep_name; - return NULL; - } - return it->second->get_predictor(params); + return it->second->get_predictor(); + } + + Predictor* fetch_predictor(std::string ep_name, const void* params) { + std::map::iterator it = _endpoints.find(ep_name); + if (it == _endpoints.end() || !it->second) { + LOG(ERROR) << "Failed fetch predictor:" + << ", ep_name: " << ep_name; + return NULL; } - - int free_predictor(Predictor* predictor) { - const Stub* stub = predictor->stub(); - if (!stub || stub->return_predictor(predictor) != 0) { - LOG(ERROR) << "Failed return predictor via stub"; - return -1; - } - - return 0; + return it->second->get_predictor(params); + } + + int free_predictor(Predictor* predictor) { + const Stub* stub = predictor->stub(); + if (!stub || stub->return_predictor(predictor) != 0) { + LOG(ERROR) << "Failed return predictor via stub"; + return -1; } -private: - EndpointConfigManager _config_manager; - std::map _endpoints; -}; - -} // sdk_cpp -} // paddle_serving -} // baidu + return 0; + } -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_PREDICTOR_SDK_H + private: + EndpointConfigManager _config_manager; + std::map _endpoints; +}; -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/stub.h b/sdk-cpp/include/stub.h index 5289c6edafd184ad92586df5544f96fb41d78e25..7e4ee485030c8daaa646cee52883e918e9f0faa4 100644 --- a/sdk-cpp/include/stub.h +++ b/sdk-cpp/include/stub.h @@ -1,21 +1,20 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/stub.h - * @author wanlijin(wanlijin01@baidu.com) - * @date 2018/12/04 16:42:29 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_STUB_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_STUB_H - -#include "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. + +#pragma once +#include +#include "sdk-cpp/include/common.h" namespace baidu { namespace paddle_serving { @@ -25,46 +24,44 @@ class Predictor; struct VariantInfo; class Stub { -public: - typedef google::protobuf::Message Message; + public: + typedef google::protobuf::Message Message; - virtual ~Stub() {} + virtual ~Stub() {} - virtual int initialize(const VariantInfo& var, const std::string& ep, - const std::string* tag, const std::string* tag_value) = 0; + virtual int initialize(const VariantInfo& var, + const std::string& ep, + const std::string* tag, + const std::string* tag_value) = 0; - // predictor - virtual Predictor* fetch_predictor() = 0; - virtual int return_predictor(Predictor* predictor) = 0; - virtual int return_predictor(Predictor* predictor) const = 0; + // predictor + virtual Predictor* fetch_predictor() = 0; + virtual int return_predictor(Predictor* predictor) = 0; + virtual int return_predictor(Predictor* predictor) const = 0; - // request - virtual Message* fetch_request() = 0; - virtual int return_request(Message* request) = 0; - virtual int return_request(Message* request) const = 0; + // request + virtual Message* fetch_request() = 0; + virtual int return_request(Message* request) = 0; + virtual int return_request(Message* request) const = 0; - // response - virtual Message* fetch_response() = 0; - virtual int return_response(Message* response) = 0; - virtual int return_response(Message* response) const = 0; + // response + virtual Message* fetch_response() = 0; + virtual int return_response(Message* response) = 0; + virtual int return_response(Message* response) const = 0; - virtual const std::string& which_endpoint() const = 0; + virtual const std::string& which_endpoint() const = 0; - // control logic for tls - virtual int thrd_initialize() = 0; + // control logic for tls + virtual int thrd_initialize() = 0; - virtual int thrd_clear() = 0; + virtual int thrd_clear() = 0; - virtual int thrd_finalize() = 0; + virtual int thrd_finalize() = 0; - virtual void update_average(int64_t acc, const char* name) = 0; - virtual void update_latency(int64_t acc, const char* name) = 0; + virtual void update_average(int64_t acc, const char* name) = 0; + virtual void update_latency(int64_t acc, const char* name) = 0; }; -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_STUB_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/stub_impl.h b/sdk-cpp/include/stub_impl.h index c3cccb8491caee57f140fa5f9d92452bb4fda4e5..4681806b98b1735158fe2a8bc4533fc9b794eda3 100644 --- a/sdk-cpp/include/stub_impl.h +++ b/sdk-cpp/include/stub_impl.h @@ -1,337 +1,328 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file include/stub.h - * @author wanlijin(wanlijin01@baidu.com) - * @date 2018/07/04 16:42:29 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_STUB_IMPL_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_STUB_IMPL_H - -#include "common.h" -#include "predictor.h" -#include "stub.h" -#include "endpoint_config.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. + +#pragma once +#include +#include +#include +#include +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/endpoint_config.h" +#include "sdk-cpp/include/predictor.h" +#include "sdk-cpp/include/stub.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { -static const std::string AVG_PREFIX = "avg_"; -static const std::string LTC_PREFIX = "ltc_"; +static const char* AVG_PREFIX = "avg_"; +static const char* LTC_PREFIX = "ltc_"; class Predictor; -template +template class PredictorImpl; static const char* INFERENCE_METHOD_NAME = "inference"; static const char* DEBUG_METHOD_NAME = "debug"; class MetricScope { -public: - MetricScope(Stub* stub, const char* routine) : - _stub(stub), _tt(butil::Timer::STARTED), _routine(routine) { - TRACEPRINTF("enter %s", routine); - } - - ~MetricScope() { - TRACEPRINTF("exit %s", _routine.c_str()); - _tt.stop(); - _stub->update_latency(_tt.u_elapsed(), _routine.c_str()); - } - -private: - Stub* _stub; - butil::Timer _tt; - std::string _routine; + public: + MetricScope(Stub* stub, const char* routine) + : _stub(stub), _tt(butil::Timer::STARTED), _routine(routine) { + TRACEPRINTF("enter %s", routine); + } + + ~MetricScope() { + TRACEPRINTF("exit %s", _routine.c_str()); + _tt.stop(); + _stub->update_latency(_tt.u_elapsed(), _routine.c_str()); + } + + private: + Stub* _stub; + butil::Timer _tt; + std::string _routine; }; class TracePackScope { -public: - TracePackScope(const char* routine) : - _routine(routine), _index(-1) { - TRACEPRINTF("start pack: %s", routine); - } - - TracePackScope(const char* routine, int index) : - _routine(routine), _index(index) { - TRACEPRINTF("start pack: %s, index: %d", routine, index); + public: + explicit TracePackScope(const char* routine) : _routine(routine), _index(-1) { + TRACEPRINTF("start pack: %s", routine); + } + + TracePackScope(const char* routine, int index) + : _routine(routine), _index(index) { + TRACEPRINTF("start pack: %s, index: %d", routine, index); + } + + ~TracePackScope() { + if (_index >= 0) { + TRACEPRINTF("finish pack: %s, index: %d", _routine.c_str(), _index); + } else { + TRACEPRINTF("finish pack: %s", _routine.c_str()); } + } - ~TracePackScope() { - if (_index >= 0) { - TRACEPRINTF("finish pack: %s, index: %d", _routine.c_str(), _index); - } else { - TRACEPRINTF("finish pack: %s", _routine.c_str()); - } - } - -private: - std::string _routine; - int _index; + private: + std::string _routine; + int _index; }; class TagFilter : public brpc::NamingServiceFilter { -public: - class TagHelper { - public: - TagHelper(const std::string& kv_str) { - if (kv_str.compare("") == 0) { - return; - } - - static const char TAG_DELIM = ','; - static const char KV_DELIM = ':'; - - std::string::size_type start_pos = 0; - std::string::size_type end_pos; - - do { - end_pos = kv_str.find(TAG_DELIM, start_pos); - std::string kv_pair_str; - if (end_pos == std::string::npos) { - kv_pair_str = kv_str.substr(start_pos); - } else { - kv_pair_str = kv_str.substr(start_pos, end_pos - start_pos); - start_pos = end_pos + 1; - } - - std::string::size_type kv_delim_pos = kv_pair_str.find(KV_DELIM, 0); - if (kv_delim_pos == std::string::npos) { - LOG(ERROR) << "invalid kv pair: " << kv_pair_str.c_str(); - continue; - } - - std::string key = kv_pair_str.substr(0, kv_delim_pos); - std::string value = kv_pair_str.substr(kv_delim_pos + 1); - _kv_map.insert(std::pair(key, value)); - - } while (end_pos != std::string::npos); + public: + class TagHelper { + public: + explicit TagHelper(const std::string& kv_str) { + if (kv_str.compare("") == 0) { + return; + } + + static const char TAG_DELIM = ','; + static const char KV_DELIM = ':'; + + std::string::size_type start_pos = 0; + std::string::size_type end_pos; + + do { + end_pos = kv_str.find(TAG_DELIM, start_pos); + std::string kv_pair_str; + if (end_pos == std::string::npos) { + kv_pair_str = kv_str.substr(start_pos); + } else { + kv_pair_str = kv_str.substr(start_pos, end_pos - start_pos); + start_pos = end_pos + 1; } - bool container(const std::string& k, const std::string& v) const { - std::map::const_iterator found - = _kv_map.find(k); - if (found == _kv_map.end()) { - // key not found - return false; - } - - if (v.compare(found->second) != 0) { - // value not equals - return false; - } - return true; + std::string::size_type kv_delim_pos = kv_pair_str.find(KV_DELIM, 0); + if (kv_delim_pos == std::string::npos) { + LOG(ERROR) << "invalid kv pair: " << kv_pair_str.c_str(); + continue; } - private: - std::map _kv_map; - }; - - TagFilter(const std::string& key, const std::string& val) { - _key = key; - _value = val; + std::string key = kv_pair_str.substr(0, kv_delim_pos); + std::string value = kv_pair_str.substr(kv_delim_pos + 1); + _kv_map.insert(std::pair(key, value)); + } while (end_pos != std::string::npos); } - bool Accept(const brpc::ServerNode& server) const { - TagHelper helper(server.tag); - return helper.container(_key, _value); + bool container(const std::string& k, const std::string& v) const { + std::map::const_iterator found = + _kv_map.find(k); + if (found == _kv_map.end()) { + // key not found + return false; + } + + if (v.compare(found->second) != 0) { + // value not equals + return false; + } + return true; } -private: - std::string _key; - std::string _value; + private: + std::map _kv_map; + }; + + TagFilter(const std::string& key, const std::string& val) { + _key = key; + _value = val; + } + + bool Accept(const brpc::ServerNode& server) const { + TagHelper helper(server.tag); + return helper.container(_key, _value); + } + + private: + std::string _key; + std::string _value; }; class BvarWrapper { -public: - virtual void update_latency(int64_t acc) = 0; - virtual void update_average(int64_t acc) = 0; + public: + virtual void update_latency(int64_t acc) = 0; + virtual void update_average(int64_t acc) = 0; }; class LatencyWrapper : public BvarWrapper { -public: - LatencyWrapper(const std::string& name) : - _ltc(name + "_ltc") { - } + public: + explicit LatencyWrapper(const std::string& name) : _ltc(name + "_ltc") {} - void update_latency(int64_t acc) { - _ltc << acc; - } + void update_latency(int64_t acc) { _ltc << acc; } - void update_average(int64_t acc) { - LOG(ERROR) << "Cannot update average to a LatencyRecorder"; - } + void update_average(int64_t acc) { + LOG(ERROR) << "Cannot update average to a LatencyRecorder"; + } -private: - bvar::LatencyRecorder _ltc; + private: + bvar::LatencyRecorder _ltc; }; class AverageWrapper : public BvarWrapper { -public: - AverageWrapper(const std::string& name) : - _win(name + "_avg", &_avg, ::bvar::FLAGS_bvar_dump_interval) { - } + public: + explicit AverageWrapper(const std::string& name) + : _win(name + "_avg", &_avg, ::bvar::FLAGS_bvar_dump_interval) {} - void update_latency(int64_t acc) { - LOG(ERROR) << "Cannot update latency to a AverageWrapper"; - } + void update_latency(int64_t acc) { + LOG(ERROR) << "Cannot update latency to a AverageWrapper"; + } - void update_average(int64_t acc) { - _avg << acc; - } + void update_average(int64_t acc) { _avg << acc; } -private: - bvar::IntRecorder _avg; - bvar::Window _win; + private: + bvar::IntRecorder _avg; + bvar::Window _win; }; struct StubTLS { - StubTLS() { - predictor_pools.clear(); - request_pools.clear(); - response_pools.clear(); - } - - std::vector predictor_pools; - std::vector request_pools; - std::vector response_pools; + StubTLS() { + predictor_pools.clear(); + request_pools.clear(); + response_pools.clear(); + } + + std::vector predictor_pools; + std::vector request_pools; + std::vector response_pools; }; -template +template class StubImpl : public Stub { -public: - typedef google::protobuf::Message Message; - - StubImpl() - : _channel(NULL), _pchannel(NULL), _gchannel(NULL), - _service_stub(NULL), _infer(NULL), _debug(NULL) {} - ~StubImpl() {} - - int initialize(const VariantInfo& var, const std::string& ep, - const std::string* tag, const std::string* tag_value); - - Predictor* fetch_predictor(); - int return_predictor(Predictor* predictor); - int return_predictor(Predictor* predictor) const; - - Message* fetch_request(); - int return_request(Message* request); - int return_request(Message* request) const; - - Message* fetch_response(); - int return_response(Message* response); - int return_response(Message* response) const; - - int thrd_initialize(); - int thrd_clear(); - int thrd_finalize(); - - const std::string& which_endpoint() const { - return _endpoint; - } - -private: - google::protobuf::RpcChannel* init_channel( - const VariantInfo& var, - brpc::NamingServiceFilter* filter = NULL); - - brpc::ParallelChannel* init_pchannel( - brpc::Channel* sub_channel, uint32_t channel_count, - uint32_t package_size, const brpc::ChannelOptions& options); - - StubTLS* get_tls() { - return static_cast(bthread_getspecific(_bthread_key)); - } - -private: - brpc::Channel* _channel; - brpc::ParallelChannel* _pchannel; - google::protobuf::RpcChannel* _gchannel; - T* _service_stub; - const google::protobuf::MethodDescriptor* _infer; - const google::protobuf::MethodDescriptor* _debug; - std::string _endpoint; - RpcParameters _options; - std::string _tag; - uint32_t _max_channel; - uint32_t _package_size; - - // tls handlers - bthread_key_t _bthread_key; - - // bvar variables - std::map _ltc_bvars; - std::map _avg_bvars; - mutable butil::Mutex _bvar_mutex; + public: + typedef google::protobuf::Message Message; + + StubImpl() + : _channel(NULL), + _pchannel(NULL), + _gchannel(NULL), + _service_stub(NULL), + _infer(NULL), + _debug(NULL) {} + ~StubImpl() {} + + int initialize(const VariantInfo& var, + const std::string& ep, + const std::string* tag, + const std::string* tag_value); + + Predictor* fetch_predictor(); + int return_predictor(Predictor* predictor); + int return_predictor(Predictor* predictor) const; + + Message* fetch_request(); + int return_request(Message* request); + int return_request(Message* request) const; + + Message* fetch_response(); + int return_response(Message* response); + int return_response(Message* response) const; + + int thrd_initialize(); + int thrd_clear(); + int thrd_finalize(); + + const std::string& which_endpoint() const { return _endpoint; } + + private: + google::protobuf::RpcChannel* init_channel( + const VariantInfo& var, brpc::NamingServiceFilter* filter = NULL); + + brpc::ParallelChannel* init_pchannel(brpc::Channel* sub_channel, + uint32_t channel_count, + uint32_t package_size, + const brpc::ChannelOptions& options); + + StubTLS* get_tls() { + return static_cast(bthread_getspecific(_bthread_key)); + } + + private: + brpc::Channel* _channel; + brpc::ParallelChannel* _pchannel; + google::protobuf::RpcChannel* _gchannel; + T* _service_stub; + const google::protobuf::MethodDescriptor* _infer; + const google::protobuf::MethodDescriptor* _debug; + std::string _endpoint; + RpcParameters _options; + std::string _tag; + uint32_t _max_channel; + uint32_t _package_size; + + // tls handlers + bthread_key_t _bthread_key; + + // bvar variables + std::map _ltc_bvars; + std::map _avg_bvars; + mutable butil::Mutex _bvar_mutex; #ifndef DECLARE_LATENCY -#define DECLARE_LATENCY(item) \ - LatencyWrapper* _ltc_##item; +#define DECLARE_LATENCY(item) LatencyWrapper* _ltc_##item; #endif - DECLARE_LATENCY(infer_sync); // 同步请求 - DECLARE_LATENCY(infer_async); // 异步请求 - DECLARE_LATENCY(infer_send); // 半同步send - DECLARE_LATENCY(infer_recv); // 半同步recv - DECLARE_LATENCY(infer_cancel);// 半同步cancel - DECLARE_LATENCY(debug); // 调试请求 - DECLARE_LATENCY(rpc_init); // rpc reset - DECLARE_LATENCY(thrd_clear); // thrd clear - DECLARE_LATENCY(pack_map); // thrd clear - DECLARE_LATENCY(pack_merge); // thrd clear + DECLARE_LATENCY(infer_sync); // 同步请求 + DECLARE_LATENCY(infer_async); // 异步请求 + DECLARE_LATENCY(infer_send); // 半同步send + DECLARE_LATENCY(infer_recv); // 半同步recv + DECLARE_LATENCY(infer_cancel); // 半同步cancel + DECLARE_LATENCY(debug); // 调试请求 + DECLARE_LATENCY(rpc_init); // rpc reset + DECLARE_LATENCY(thrd_clear); // thrd clear + DECLARE_LATENCY(pack_map); // thrd clear + DECLARE_LATENCY(pack_merge); // thrd clear #undef DECLARE_LATENCY #ifndef DECLARE_AVERAGE -#define DECLARE_AVERAGE(item) \ - AverageWrapper* _avg_##item; +#define DECLARE_AVERAGE(item) AverageWrapper* _avg_##item; #endif - DECLARE_AVERAGE(failure); // 失败请求数 - DECLARE_AVERAGE(item_size); // 单次请求item数 - DECLARE_AVERAGE(pack); // 单次请求分包数 - DECLARE_AVERAGE(pack_fail); // 单次请求分包失败数 + DECLARE_AVERAGE(failure); // 失败请求数 + DECLARE_AVERAGE(item_size); // 单次请求item数 + DECLARE_AVERAGE(pack); // 单次请求分包数 + DECLARE_AVERAGE(pack_fail); // 单次请求分包失败数 #undef DECLARE_AVERAGE -public: - void update_average(int64_t acc, const char* name) { - std::map::iterator iter = - _avg_bvars.find(AVG_PREFIX + name); - if (iter == _avg_bvars.end()) { - LOG(ERROR) << "Not found average record:avg_" << name; - return ; - } - - iter->second->update_average(acc); + public: + void update_average(int64_t acc, const char* name) { + std::map::iterator iter = + _avg_bvars.find(std::string(AVG_PREFIX) + name); + if (iter == _avg_bvars.end()) { + LOG(ERROR) << "Not found average record:avg_" << name; + return; } - void update_latency(int64_t acc, const char* name) { - std::map::iterator iter = - _ltc_bvars.find(LTC_PREFIX + name); - if (iter == _ltc_bvars.end()) { - LOG(ERROR) << "Not found latency record:ltc_" << name; - return ; - } - - iter->second->update_latency(acc); + iter->second->update_average(acc); + } + + void update_latency(int64_t acc, const char* name) { + std::map::iterator iter = + _ltc_bvars.find(std::string(LTC_PREFIX) + name); + if (iter == _ltc_bvars.end()) { + LOG(ERROR) << "Not found latency record:ltc_" << name; + return; } + + iter->second->update_latency(acc); + } }; -} // sdk_cpp -} // paddle_serving -} // baidu +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu #include "stub_impl.hpp" - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_STUB_IMPL_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/include/stub_impl.hpp b/sdk-cpp/include/stub_impl.hpp index c62f2685bc6bafc3cbaa354e28ae56ed5029d26a..068192b7c0b363fd0316520e0f29ea712f3bf095 100644 --- a/sdk-cpp/include/stub_impl.hpp +++ b/sdk-cpp/include/stub_impl.hpp @@ -1,412 +1,418 @@ -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_STUB_IMPL_HPP -#define BAIDU_PADDLE_SERVING_SDK_CPP_STUB_IMPL_HPP - +// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include namespace baidu { namespace paddle_serving { namespace sdk_cpp { -template -int StubImpl::initialize( - const VariantInfo& var, const std::string& ep, - const std::string* tag, const std::string* tag_value) { - if (tag != NULL && tag_value != NULL) { - TagFilter* filter = new (std::nothrow) TagFilter( - *tag, *tag_value); - if (!filter) { - LOG(FATAL) << "Failed create tag filter, key: " << tag - << ", value: " << tag_value; - return -1; - } - - _gchannel = init_channel(var, filter); - LOG(INFO) - << "Create stub with tag: " << *tag - << ", " << *tag_value << ", ep: " << ep; - } else { - _gchannel = init_channel(var, NULL); - LOG(INFO) << "Create stub without tag, ep " << ep; - } - - if (!_gchannel) { - LOG(FATAL) << "Failed init channel via var_info"; - return -1; - } - - _service_stub = new (std::nothrow) T(_gchannel); - if (!_service_stub) { - LOG(FATAL) << "Failed create stub with channel"; - return -1; - } - - _infer = _service_stub->GetDescriptor()->FindMethodByName( - INFERENCE_METHOD_NAME); - if (!_infer) { - LOG(FATAL) << "Failed get inference method, " - << "method name: " << INFERENCE_METHOD_NAME; - return -1; - } - - _debug = _service_stub->GetDescriptor()->FindMethodByName( - DEBUG_METHOD_NAME); - if (!_debug) { - LOG(FATAL) << "Failed get debug method, " - << "method name: " << DEBUG_METHOD_NAME; - return -1; - } - - _endpoint = ep; - - if (bthread_key_create(&_bthread_key, NULL) != 0) { - LOG(FATAL) << "Failed create key for stub tls"; - return -1; +template +int StubImpl::initialize(const VariantInfo& var, + const std::string& ep, + const std::string* tag, + const std::string* tag_value) { + if (tag != NULL && tag_value != NULL) { + TagFilter* filter = new (std::nothrow) TagFilter(*tag, *tag_value); + if (!filter) { + LOG(FATAL) << "Failed create tag filter, key: " << tag + << ", value: " << tag_value; + return -1; } - const std::string& name - = _endpoint + "_" + _service_stub->GetDescriptor()->full_name() + "_" + _tag; - - _ltc_bvars.clear(); - _avg_bvars.clear(); - BAIDU_SCOPED_LOCK(_bvar_mutex); + _gchannel = init_channel(var, filter); + LOG(INFO) << "Create stub with tag: " << *tag << ", " << *tag_value + << ", ep: " << ep; + } else { + _gchannel = init_channel(var, NULL); + LOG(INFO) << "Create stub without tag, ep " << ep; + } + + if (!_gchannel) { + LOG(FATAL) << "Failed init channel via var_info"; + return -1; + } + + _service_stub = new (std::nothrow) T(_gchannel); + if (!_service_stub) { + LOG(FATAL) << "Failed create stub with channel"; + return -1; + } + + _infer = + _service_stub->GetDescriptor()->FindMethodByName(INFERENCE_METHOD_NAME); + if (!_infer) { + LOG(FATAL) << "Failed get inference method, " + << "method name: " << INFERENCE_METHOD_NAME; + return -1; + } + + _debug = _service_stub->GetDescriptor()->FindMethodByName(DEBUG_METHOD_NAME); + if (!_debug) { + LOG(FATAL) << "Failed get debug method, " + << "method name: " << DEBUG_METHOD_NAME; + return -1; + } + + _endpoint = ep; + + if (bthread_key_create(&_bthread_key, NULL) != 0) { + LOG(FATAL) << "Failed create key for stub tls"; + return -1; + } + + const std::string& name = _endpoint + "_" + + _service_stub->GetDescriptor()->full_name() + "_" + + _tag; + + _ltc_bvars.clear(); + _avg_bvars.clear(); + BAIDU_SCOPED_LOCK(_bvar_mutex); #ifndef DEFINE_LATENCY -#define DEFINE_LATENCY(item) \ - do { \ - _ltc_##item = new (std::nothrow) LatencyWrapper(name + "_"#item);\ - if (!_ltc_##item) { \ - LOG(FATAL) << "Failed create latency recorder:" \ - << name + "_"#item; \ - return -1; \ - } \ - _ltc_bvars["ltc_"#item] = _ltc_##item; \ - } while(0) +#define DEFINE_LATENCY(item) \ + do { \ + _ltc_##item = new (std::nothrow) LatencyWrapper(name + "_" #item); \ + if (!_ltc_##item) { \ + LOG(FATAL) << "Failed create latency recorder:" << name + "_" #item; \ + return -1; \ + } \ + _ltc_bvars["ltc_" #item] = _ltc_##item; \ + } while (0) #endif - DEFINE_LATENCY(infer_sync); - DEFINE_LATENCY(infer_async); - DEFINE_LATENCY(infer_send); - DEFINE_LATENCY(infer_recv); - DEFINE_LATENCY(infer_cancel); - DEFINE_LATENCY(debug); - DEFINE_LATENCY(rpc_init); - DEFINE_LATENCY(thrd_clear); - DEFINE_LATENCY(pack_map); - DEFINE_LATENCY(pack_merge); + DEFINE_LATENCY(infer_sync); + DEFINE_LATENCY(infer_async); + DEFINE_LATENCY(infer_send); + DEFINE_LATENCY(infer_recv); + DEFINE_LATENCY(infer_cancel); + DEFINE_LATENCY(debug); + DEFINE_LATENCY(rpc_init); + DEFINE_LATENCY(thrd_clear); + DEFINE_LATENCY(pack_map); + DEFINE_LATENCY(pack_merge); #undef DEFINE_LATENCY #ifndef DEFINE_AVERAGE -#define DEFINE_AVERAGE(item) \ - do { \ - _avg_##item = new(std::nothrow) AverageWrapper(name + "_"#item);\ - if (!_avg_##item) { \ - LOG(FATAL) << "Failed create average recorder:" \ - << name + "_"#item; \ - return -1; \ - } \ - _avg_bvars["avg_"#item] = _avg_##item; \ - } while(0) +#define DEFINE_AVERAGE(item) \ + do { \ + _avg_##item = new (std::nothrow) AverageWrapper(name + "_" #item); \ + if (!_avg_##item) { \ + LOG(FATAL) << "Failed create average recorder:" << name + "_" #item; \ + return -1; \ + } \ + _avg_bvars["avg_" #item] = _avg_##item; \ + } while (0) #endif - DEFINE_AVERAGE(failure); - DEFINE_AVERAGE(pack); - DEFINE_AVERAGE(item_size); - DEFINE_AVERAGE(pack_fail); + DEFINE_AVERAGE(failure); + DEFINE_AVERAGE(pack); + DEFINE_AVERAGE(item_size); + DEFINE_AVERAGE(pack_fail); #undef DEFINE_AVERAGE - return 0; + return 0; } -template +template int StubImpl::thrd_initialize() { - if (bthread_getspecific(_bthread_key) != NULL) { - LOG(WARNING) << "Already thread initialized for stub"; - return 0; - } + if (bthread_getspecific(_bthread_key) != NULL) { + LOG(WARNING) << "Already thread initialized for stub"; + return 0; + } - StubTLS* tls = new (std::nothrow) StubTLS(); - if (!tls || bthread_setspecific(_bthread_key, tls) != 0) { - LOG(FATAL) << "Failed binding tls data to bthread_key"; - return -1; - } + StubTLS* tls = new (std::nothrow) StubTLS(); + if (!tls || bthread_setspecific(_bthread_key, tls) != 0) { + LOG(FATAL) << "Failed binding tls data to bthread_key"; + return -1; + } - LOG(WARNING) << "Succ thread initialize stub impl!"; + LOG(WARNING) << "Succ thread initialize stub impl!"; - return 0; + return 0; } -template +template int StubImpl::thrd_clear() { - MetricScope metric(this, "thrd_clear"); - StubTLS* tls = get_tls(); - if (!tls) { - LOG(FATAL) << "Failed get tls stub object"; - return -1; - } - - // clear predictor - size_t ps = tls->predictor_pools.size(); - for (size_t pi = 0; pi < ps; ++pi) { - Predictor* p = tls->predictor_pools[pi]; - if (p && p->is_inited() && return_predictor(p) != 0) { - LOG(FATAL) << "Failed return predictor: " << pi; - return -1; - } + MetricScope metric(this, "thrd_clear"); + StubTLS* tls = get_tls(); + if (!tls) { + LOG(FATAL) << "Failed get tls stub object"; + return -1; + } + + // clear predictor + size_t ps = tls->predictor_pools.size(); + for (size_t pi = 0; pi < ps; ++pi) { + Predictor* p = tls->predictor_pools[pi]; + if (p && p->is_inited() && return_predictor(p) != 0) { + LOG(FATAL) << "Failed return predictor: " << pi; + return -1; } - tls->predictor_pools.clear(); - - // clear request - size_t is = tls->request_pools.size(); - for (size_t ii = 0; ii < is; ++ii) { - if (return_request(tls->request_pools[ii])!= 0) { - LOG(FATAL) << "Failed return request: " << ii; - return -1; - } + } + tls->predictor_pools.clear(); + + // clear request + size_t is = tls->request_pools.size(); + for (size_t ii = 0; ii < is; ++ii) { + if (return_request(tls->request_pools[ii]) != 0) { + LOG(FATAL) << "Failed return request: " << ii; + return -1; } - tls->request_pools.clear(); - - // clear response - size_t os = tls->response_pools.size(); - for (size_t oi = 0; oi < os; ++oi) { - if (return_response(tls->response_pools[oi])!= 0) { - LOG(FATAL) << "Failed return response: " << oi; - return -1; - } + } + tls->request_pools.clear(); + + // clear response + size_t os = tls->response_pools.size(); + for (size_t oi = 0; oi < os; ++oi) { + if (return_response(tls->response_pools[oi]) != 0) { + LOG(FATAL) << "Failed return response: " << oi; + return -1; } - tls->response_pools.clear(); - return 0; + } + tls->response_pools.clear(); + return 0; } -template +template int StubImpl::thrd_finalize() { - StubTLS* tls = get_tls(); - if (!tls || thrd_clear() != 0) { - LOG(FATAL) << "Failed clreate tls in thrd finalize"; - return -1; - } - - delete tls; - return 0; + StubTLS* tls = get_tls(); + if (!tls || thrd_clear() != 0) { + LOG(FATAL) << "Failed clreate tls in thrd finalize"; + return -1; + } + + delete tls; + return 0; } -template +template Predictor* StubImpl::fetch_predictor() { - StubTLS* tls = get_tls(); - if (!tls) { - LOG(FATAL) << "Failed get tls data when fetching predictor"; - return NULL; - } - - PredictorImpl* predictor = butil::get_object >(); - if (!predictor) { - LOG(FATAL) << "Failed fetch predictor"; - return NULL; - } - - if (predictor->init(_gchannel, _service_stub, _infer, _debug, _options, - this, _tag) != 0) { - LOG(FATAL) << "Failed init fetched predictor"; - return NULL; - } - - tls->predictor_pools.push_back(predictor); - return predictor; + StubTLS* tls = get_tls(); + if (!tls) { + LOG(FATAL) << "Failed get tls data when fetching predictor"; + return NULL; + } + + PredictorImpl* predictor = butil::get_object>(); + if (!predictor) { + LOG(FATAL) << "Failed fetch predictor"; + return NULL; + } + + if (predictor->init( + _gchannel, _service_stub, _infer, _debug, _options, this, _tag) != + 0) { + LOG(FATAL) << "Failed init fetched predictor"; + return NULL; + } + + tls->predictor_pools.push_back(predictor); + return predictor; } -template +template int StubImpl::return_predictor(Predictor* predictor) { - if ((dynamic_cast*>(predictor))->deinit() != 0) { - LOG(FATAL) << "Failed deinit fetched predictor"; - return -1; - } - butil::return_object(dynamic_cast*>(predictor)); - return 0; + if ((dynamic_cast*>(predictor))->deinit() != 0) { + LOG(FATAL) << "Failed deinit fetched predictor"; + return -1; + } + butil::return_object(dynamic_cast*>(predictor)); + return 0; } -template +template int StubImpl::return_predictor(Predictor* predictor) const { - if ((dynamic_cast*>(predictor))->deinit() != 0) { - LOG(FATAL) << "Failed deinit fetched predictor"; - return -1; - } - butil::return_object(dynamic_cast*>(predictor)); - return 0; + if ((dynamic_cast*>(predictor))->deinit() != 0) { + LOG(FATAL) << "Failed deinit fetched predictor"; + return -1; + } + butil::return_object(dynamic_cast*>(predictor)); + return 0; } -template +template google::protobuf::Message* StubImpl::fetch_request() { - StubTLS* tls = get_tls(); - if (!tls) { - LOG(FATAL) << "Failed get tls data when fetching request"; - return NULL; - } - - I* req = butil::get_object(); - if (!req) { - LOG(FATAL) << "Failed get tls request item, type: " << typeid(I).name(); - return NULL; - } - - req->Clear(); - tls->request_pools.push_back(req); - return req; + StubTLS* tls = get_tls(); + if (!tls) { + LOG(FATAL) << "Failed get tls data when fetching request"; + return NULL; + } + + I* req = butil::get_object(); + if (!req) { + LOG(FATAL) << "Failed get tls request item, type: " << typeid(I).name(); + return NULL; + } + + req->Clear(); + tls->request_pools.push_back(req); + return req; } -template +template int StubImpl::return_request( - google::protobuf::Message* request) const { - request->Clear(); - butil::return_object(dynamic_cast(request)); - return 0; + google::protobuf::Message* request) const { + request->Clear(); + butil::return_object(dynamic_cast(request)); + return 0; } -template +template int StubImpl::return_request( - google::protobuf::Message* request) { - request->Clear(); - butil::return_object(dynamic_cast(request)); - return 0; + google::protobuf::Message* request) { + request->Clear(); + butil::return_object(dynamic_cast(request)); + return 0; } -template +template google::protobuf::Message* StubImpl::fetch_response() { - StubTLS* tls = get_tls(); - if (!tls) { - LOG(FATAL) << "Failed get tls data when fetching response"; - return NULL; - } - - O* res = butil::get_object(); - if (!res) { - LOG(FATAL) << "Failed get tls response item, type: " << typeid(O).name(); - return NULL; - } - - res->Clear(); - tls->response_pools.push_back(res); - return res; + StubTLS* tls = get_tls(); + if (!tls) { + LOG(FATAL) << "Failed get tls data when fetching response"; + return NULL; + } + + O* res = butil::get_object(); + if (!res) { + LOG(FATAL) << "Failed get tls response item, type: " << typeid(O).name(); + return NULL; + } + + res->Clear(); + tls->response_pools.push_back(res); + return res; } -template +template int StubImpl::return_response( - google::protobuf::Message* response) const { - response->Clear(); - butil::return_object(dynamic_cast(response)); - return 0; + google::protobuf::Message* response) const { + response->Clear(); + butil::return_object(dynamic_cast(response)); + return 0; } -template +template int StubImpl::return_response( - google::protobuf::Message* response) { - response->Clear(); - butil::return_object(dynamic_cast(response)); - return 0; + google::protobuf::Message* response) { + response->Clear(); + butil::return_object(dynamic_cast(response)); + return 0; } -template +template google::protobuf::RpcChannel* StubImpl::init_channel( - const VariantInfo& var, brpc::NamingServiceFilter* filter) { - brpc::ChannelOptions chn_options; - chn_options.ns_filter = filter; - - // parameters - ASSIGN_CONF_ITEM(chn_options.protocol, var.parameters.protocol, NULL); - ASSIGN_CONF_ITEM(_tag, var.parameters.route_tag, NULL); - ASSIGN_CONF_ITEM(_max_channel, var.parameters.max_channel, NULL); - ASSIGN_CONF_ITEM(_package_size, var.parameters.package_size, NULL); - - if (_max_channel < 1) { - LOG(ERROR) << "Invalid MaxChannelPerRequest: " << _max_channel; - return NULL; - } - - // connection - ASSIGN_CONF_ITEM(chn_options.max_retry, var.connection.cnt_retry_conn, NULL); - ASSIGN_CONF_ITEM(chn_options.connect_timeout_ms, var.connection.tmo_conn, NULL); - ASSIGN_CONF_ITEM(chn_options.timeout_ms, var.connection.tmo_rpc, NULL); - ASSIGN_CONF_ITEM(chn_options.backup_request_ms, var.connection.tmo_hedge, NULL); - - // connection type - std::string conn_type_str; - ASSIGN_CONF_ITEM(conn_type_str, var.connection.type_conn, NULL); - chn_options.connection_type - = brpc::StringToConnectionType(conn_type_str); - - // naminginfo - std::string cluster_naming_info; - std::string cluster_loadbalancer; - ASSIGN_CONF_ITEM(cluster_naming_info, var.naminginfo.cluster_naming, NULL); - ASSIGN_CONF_ITEM(cluster_loadbalancer, var.naminginfo.load_balancer, NULL); - - // brpc single channel - _channel = butil::get_object(); - if (!_channel) { - LOG(FATAL) << "Failed get channel object from butil::pool"; - return NULL; - } - - if (_channel->Init( - cluster_naming_info.c_str(), - cluster_loadbalancer.c_str(), - &chn_options) != 0) { - LOG(ERROR) - << "Failed to initialize channel, path: " - << cluster_naming_info; - return NULL; - } - - // brpc parallel channel - _pchannel = init_pchannel( - _channel, _max_channel, _package_size, chn_options); - if (_pchannel) { - LOG(INFO) << "Succ create parallel channel, count: " - << _max_channel; - return _pchannel; - } + const VariantInfo& var, brpc::NamingServiceFilter* filter) { + brpc::ChannelOptions chn_options; + chn_options.ns_filter = filter; + + // parameters + ASSIGN_CONF_ITEM(chn_options.protocol, var.parameters.protocol, NULL); + ASSIGN_CONF_ITEM(_tag, var.parameters.route_tag, NULL); + ASSIGN_CONF_ITEM(_max_channel, var.parameters.max_channel, NULL); + ASSIGN_CONF_ITEM(_package_size, var.parameters.package_size, NULL); + + if (_max_channel < 1) { + LOG(ERROR) << "Invalid MaxChannelPerRequest: " << _max_channel; + return NULL; + } + + // connection + ASSIGN_CONF_ITEM(chn_options.max_retry, var.connection.cnt_retry_conn, NULL); + ASSIGN_CONF_ITEM( + chn_options.connect_timeout_ms, var.connection.tmo_conn, NULL); + ASSIGN_CONF_ITEM(chn_options.timeout_ms, var.connection.tmo_rpc, NULL); + ASSIGN_CONF_ITEM( + chn_options.backup_request_ms, var.connection.tmo_hedge, NULL); + + // connection type + std::string conn_type_str; + ASSIGN_CONF_ITEM(conn_type_str, var.connection.type_conn, NULL); + chn_options.connection_type = brpc::StringToConnectionType(conn_type_str); + + // naminginfo + std::string cluster_naming_info; + std::string cluster_loadbalancer; + ASSIGN_CONF_ITEM(cluster_naming_info, var.naminginfo.cluster_naming, NULL); + ASSIGN_CONF_ITEM(cluster_loadbalancer, var.naminginfo.load_balancer, NULL); + + // brpc single channel + _channel = butil::get_object(); + if (!_channel) { + LOG(FATAL) << "Failed get channel object from butil::pool"; + return NULL; + } + + if (_channel->Init(cluster_naming_info.c_str(), + cluster_loadbalancer.c_str(), + &chn_options) != 0) { + LOG(ERROR) << "Failed to initialize channel, path: " << cluster_naming_info; + return NULL; + } + + // brpc parallel channel + _pchannel = init_pchannel(_channel, _max_channel, _package_size, chn_options); + if (_pchannel) { + LOG(INFO) << "Succ create parallel channel, count: " << _max_channel; + return _pchannel; + } - return _channel; + return _channel; } -template +template brpc::ParallelChannel* StubImpl::init_pchannel( - brpc::Channel* sub_channel, uint32_t channel_count, - uint32_t package_size, const brpc::ChannelOptions& options) { - if (channel_count <= 1) { // noneed use parallel channel - LOG(INFO) << "channel count <= 1, noneed use pchannel."; - return NULL; + brpc::Channel* sub_channel, + uint32_t channel_count, + uint32_t package_size, + const brpc::ChannelOptions& options) { + if (channel_count <= 1) { // noneed use parallel channel + LOG(INFO) << "channel count <= 1, noneed use pchannel."; + return NULL; + } + + _pchannel = butil::get_object(); + if (!_pchannel) { + LOG(FATAL) << "Failed get pchannel from object pool"; + return NULL; + } + + brpc::ParallelChannelOptions pchan_options; + pchan_options.timeout_ms = options.timeout_ms; + if (_pchannel->Init(&pchan_options) != 0) { + LOG(FATAL) << "Failed init parallel channel with tmo_us: " + << pchan_options.timeout_ms; + return NULL; + } + + for (uint32_t si = 0; si < channel_count; ++si) { + if (_pchannel->AddChannel(sub_channel, + brpc::DOESNT_OWN_CHANNEL, + new C(package_size, this), + new R(package_size, this)) != 0) { + LOG(FATAL) << "Failed add channel at: " << si + << ", package_size:" << package_size; + return NULL; } + } - _pchannel = butil::get_object(); - if (!_pchannel) { - LOG(FATAL) << "Failed get pchannel from object pool"; - return NULL; - } - - brpc::ParallelChannelOptions pchan_options; - pchan_options.timeout_ms = options.timeout_ms; - if (_pchannel->Init(&pchan_options) != 0) { - LOG(FATAL) << "Failed init parallel channel with tmo_us: " - << pchan_options.timeout_ms; - return NULL; - } - - for (uint32_t si = 0; si < channel_count; ++si) { - if (_pchannel->AddChannel( - sub_channel, - brpc::DOESNT_OWN_CHANNEL, - new C(package_size, this), - new R(package_size, this)) != 0) { - LOG(FATAL) << "Failed add channel at: " << si - << ", package_size:" << package_size; - return NULL; - } - } - - return _pchannel; + return _pchannel; } -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_STUB_IMPL_HPP +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/utils.h b/sdk-cpp/include/utils.h index 76c900ee3f3e903c9ff0f53af9104c1b0a8fbe47..75372a7d7b3ed0bb04c53a83cdde7bedc54462e9 100644 --- a/sdk-cpp/include/utils.h +++ b/sdk-cpp/include/utils.h @@ -1,71 +1,60 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file utils.h - * @author root(com@baidu.com) - * @date 2018/07/09 19:43:36 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_SDK_CPP_UTILS_H -#define BAIDU_PADDLE_SERVING_SDK_CPP_UTILS_H - -#include "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. + +#pragma once +#include +#include +#include "sdk-cpp/include/common.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { -inline int str_split( - const std::string& source, - const std::string& delim, - std::vector* vector_spliter) { - - int delim_length = delim.length(); - int total_length = source.length(); - int last = 0; +inline int str_split(const std::string& source, + const std::string& delim, + std::vector* vector_spliter) { + int delim_length = delim.length(); + int total_length = source.length(); + int last = 0; - if (delim_length == 0) { - vector_spliter->push_back(source); - return 0; + if (delim_length == 0) { + vector_spliter->push_back(source); + return 0; + } + + if (delim_length == 1) { + size_t index = source.find_first_of(delim, last); + while (index != std::string::npos) { + vector_spliter->push_back(source.substr(last, index - last)); + last = index + delim_length; + index = source.find_first_of(delim, last); } - - if (delim_length == 1) { - size_t index = source.find_first_of(delim, last); - while (index != std::string::npos) { - vector_spliter->push_back(source.substr(last, - index - last)); - last = index + delim_length; - index = source.find_first_of(delim, last); - } - } else { - size_t index = source.find(delim, last); - while (index != std::string::npos) { - vector_spliter->push_back(source.substr(last, - index - last)); - last = index + delim_length; - index = source.find(delim, last); - } + } else { + size_t index = source.find(delim, last); + while (index != std::string::npos) { + vector_spliter->push_back(source.substr(last, index - last)); + last = index + delim_length; + index = source.find(delim, last); } + } - if (last < total_length) { - vector_spliter->push_back(source.substr(last, - total_length - last)); - } - return 0; + if (last < total_length) { + vector_spliter->push_back(source.substr(last, total_length - last)); + } + return 0; } -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_SDK_CPP_UTILS_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/include/variant.h b/sdk-cpp/include/variant.h index e588b741d1f68067eebff54db4b5f780fea99439..8857e14d7592aea406198c9bfb402e93220cf745 100644 --- a/sdk-cpp/include/variant.h +++ b/sdk-cpp/include/variant.h @@ -1,75 +1,62 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file include/variant.h - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/27 17:37:31 - * @brief - * - **/ - -#ifndef BAIDU_PADDLE_SERVING_CPP_SDK_VARIANT_H -#define BAIDU_PADDLE_SERVING_CPP_SDK_VARIANT_H - -#include "common.h" -#include "endpoint_config.h" -#include "stub.h" -#include "predictor.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. + +#pragma once +#include +#include +#include "sdk-cpp/include/common.h" +#include "sdk-cpp/include/endpoint_config.h" +#include "sdk-cpp/include/predictor.h" +#include "sdk-cpp/include/stub.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { class Variant { -friend class VariantRouterBase; -public: + friend class VariantRouterBase; - virtual ~Variant() {} + public: + virtual ~Variant() {} - Variant() : _default_stub(NULL) { - _stub_map.clear(); - } + Variant() : _default_stub(NULL) { _stub_map.clear(); } - int initialize( - const EndpointInfo& ep_info, - const VariantInfo& var_info); + int initialize(const EndpointInfo& ep_info, const VariantInfo& var_info); - int thrd_initialize(); + int thrd_initialize(); - int thrd_clear(); + int thrd_clear(); - int thrd_finalize(); + int thrd_finalize(); - Predictor* get_predictor( - const void* params); + Predictor* get_predictor(const void* params); - Predictor* get_predictor(); + Predictor* get_predictor(); - int ret_predictor(Predictor* predictor); + int ret_predictor(Predictor* predictor); - const std::string& variant_tag() const { - return _variant_tag; - } + const std::string& variant_tag() const { return _variant_tag; } -private: - std::string _endpoint_name; - std::string _stub_service; + private: + std::string _endpoint_name; + std::string _stub_service; - std::string _variant_tag; - std::map _stub_map; - Stub* _default_stub; + std::string _variant_tag; + std::map _stub_map; + Stub* _default_stub; }; -} // sdk_cpp -} // paddle_serving -} // baidu - -#endif //BAIDU_PADDLE_SERVING_CPP_SDK_VARIANT_H - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/proto/builtin_format.proto b/sdk-cpp/proto/builtin_format.proto index d30504fc18bac26670e16956b7624e243cbb28bf..8f0d1d8f01ffa6f026271a1f3d20b08ae072cc77 100644 --- a/sdk-cpp/proto/builtin_format.proto +++ b/sdk-cpp/proto/builtin_format.proto @@ -1,14 +1,24 @@ -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.predictor.format; // dense format -message DenseInstance { - repeated float features = 1; -}; +message DenseInstance { repeated float features = 1; }; -message DensePrediction { - repeated float categories = 1; -}; +message DensePrediction { repeated float categories = 1; }; // sparse format message SparseInstance { @@ -17,9 +27,7 @@ message SparseInstance { repeated float values = 3; }; -message SparsePrediction { - repeated float categories = 1; -}; +message SparsePrediction { repeated float categories = 1; }; // int64-tensor format message Int64TensorInstance { @@ -38,9 +46,7 @@ message XImageReqInstance { required uint32 image_length = 2; }; -message XImageResInstance { - required string response_json = 1; -}; +message XImageResInstance { required string response_json = 1; }; // x-record format message XRecordInstance { diff --git a/sdk-cpp/proto/default_schema.proto b/sdk-cpp/proto/default_schema.proto index 8c2c518cc12511df840457a4707cfe0c81324a43..9cb5dfc169d9ac083839876220b564419cc78f4d 100644 --- a/sdk-cpp/proto/default_schema.proto +++ b/sdk-cpp/proto/default_schema.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; package baidu.paddle_serving.fluid_engine; @@ -6,52 +20,40 @@ option cc_generic_services = true; // default dense request message DenseTensor { - required string name = 1; - repeated uint32 shape = 2; - required bytes features = 3; + required string name = 1; + repeated uint32 shape = 2; + required bytes features = 3; }; -message DenseInstance { - repeated DenseTensor tensors = 1; -}; +message DenseInstance { repeated DenseTensor tensors = 1; }; -message DenseRequest { - repeated DenseInstance instances = 1; -}; +message DenseRequest { repeated DenseInstance instances = 1; }; // default sparse request message SparseTensor { - required string name = 1; - repeated uint32 keys = 2; - repeated uint32 shape = 3; - required bytes features = 4; + required string name = 1; + repeated uint32 keys = 2; + repeated uint32 shape = 3; + required bytes features = 4; }; -message SparseInstance { - repeated SparseTensor tensors = 1; -}; +message SparseInstance { repeated SparseTensor tensors = 1; }; -message SparseRequest { - repeated SparseInstance instances = 1; -}; +message SparseRequest { repeated SparseInstance instances = 1; }; // default response -message Prediction { - repeated float categories = 1; -}; +message Prediction { repeated float categories = 1; }; -message Response { - repeated Prediction predictions = 1; -}; +message Response { repeated Prediction predictions = 1; }; service DefaultSparseService { - rpc inference(SparseRequest) returns (Response); - rpc debug(SparseRequest) returns (Response); - option (pds.options).generate_stub = true; + rpc inference(SparseRequest) returns (Response); + rpc debug(SparseRequest) returns (Response); + option (pds.options).generate_stub = true; }; service DefaultDenseService { - rpc inference(DenseRequest) returns (Response); - rpc debug(DenseRequest) returns (Response); - option (pds.options).generate_stub = true; + rpc inference(DenseRequest) returns (Response); + rpc debug(DenseRequest) returns (Response); + option (pds.options).generate_stub = true; }; diff --git a/sdk-cpp/proto/dense_service.proto b/sdk-cpp/proto/dense_service.proto index f6fdba334bf927f615f2536b16b0a3c1d0302126..b1cdd784eab459893c87142b94c4939f464d7c74 100644 --- a/sdk-cpp/proto/dense_service.proto +++ b/sdk-cpp/proto/dense_service.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.dense_service; @@ -10,7 +24,8 @@ message Request { }; message Response { - repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = 1; + repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = + 1; }; service BuiltinDenseFormatService { diff --git a/sdk-cpp/proto/echo_service.proto b/sdk-cpp/proto/echo_service.proto index d108c62344a1a4a026374a09040fb1200b5d0e29..3ffd3678c316f15bd75731659d7044f79512c667 100644 --- a/sdk-cpp/proto/echo_service.proto +++ b/sdk-cpp/proto/echo_service.proto @@ -1,16 +1,30 @@ -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"; import "pds_option.proto"; package baidu.paddle_serving.predictor.echo_service; option cc_generic_services = true; message RequestAndResponse { - required int32 a = 1; - required float b = 2; + required int32 a = 1; + required float b = 2; }; service BuiltinTestEchoService { - rpc inference(RequestAndResponse) returns (RequestAndResponse); - rpc debug(RequestAndResponse) returns (RequestAndResponse); - option (pds.options).generate_stub = true; + rpc inference(RequestAndResponse) returns (RequestAndResponse); + rpc debug(RequestAndResponse) returns (RequestAndResponse); + option (pds.options).generate_stub = true; }; diff --git a/sdk-cpp/proto/image_class.proto b/sdk-cpp/proto/image_class.proto index 9e1ca53e968c49441f533980415c0b49559854a7..0245702b00f2311b96377114fa2ddd444d95ea65 100644 --- a/sdk-cpp/proto/image_class.proto +++ b/sdk-cpp/proto/image_class.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.image_classification; @@ -6,20 +20,23 @@ package baidu.paddle_serving.predictor.image_classification; option cc_generic_services = true; message ClassifyResponse { - repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = 1; + repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = + 1; }; message Request { - repeated baidu.paddle_serving.predictor.format.XImageReqInstance instances = 1; + repeated baidu.paddle_serving.predictor.format.XImageReqInstance instances = + 1; }; message Response { - // Each json string is serialized from ClassifyResponse predictions - repeated baidu.paddle_serving.predictor.format.XImageResInstance predictions = 1; + // Each json string is serialized from ClassifyResponse predictions + repeated baidu.paddle_serving.predictor.format.XImageResInstance predictions = + 1; }; service ImageClassifyService { - rpc inference(Request) returns (Response); - rpc debug(Request) returns (Response); - option (pds.options).generate_stub = true; + rpc inference(Request) returns (Response); + rpc debug(Request) returns (Response); + option (pds.options).generate_stub = true; }; diff --git a/sdk-cpp/proto/int64tensor_service.proto b/sdk-cpp/proto/int64tensor_service.proto index baab0cb0a4bf301b46dc7f9aedb850b4a1b50c2b..671ab1fb82522ca2438f3c6959c1d81b3af3be04 100644 --- a/sdk-cpp/proto/int64tensor_service.proto +++ b/sdk-cpp/proto/int64tensor_service.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.int64tensor_service; @@ -6,12 +20,12 @@ package baidu.paddle_serving.predictor.int64tensor_service; option cc_generic_services = true; message Request { - repeated baidu.paddle_serving.predictor.format.Int64TensorInstance - instances = 1; + repeated baidu.paddle_serving.predictor.format.Int64TensorInstance instances = + 1; }; message Response { - repeated baidu.paddle_serving.predictor.format.Float32TensorPredictor + repeated baidu.paddle_serving.predictor.format.Float32TensorPredictor predictions = 1; }; diff --git a/sdk-cpp/proto/pds_option.proto b/sdk-cpp/proto/pds_option.proto index 81b01f819d63ae9e8b917e924293d34fd49667ce..c45c41ea8c5cd0f8378015c1abe575664ab61386 100644 --- a/sdk-cpp/proto/pds_option.proto +++ b/sdk-cpp/proto/pds_option.proto @@ -1,9 +1,23 @@ -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"; import "google/protobuf/descriptor.proto"; package pds; extend google.protobuf.FieldOptions { - optional bool pack_on = 70000 [default=false]; + optional bool pack_on = 70000 [ default = false ]; }; extend google.protobuf.ServiceOptions { @@ -11,6 +25,6 @@ extend google.protobuf.ServiceOptions { }; message PaddleServiceOption { - optional bool generate_impl = 1 [default = false]; - optional bool generate_stub = 2 [default = false]; + optional bool generate_impl = 1 [ default = false ]; + optional bool generate_stub = 2 [ default = false ]; }; diff --git a/sdk-cpp/proto/sparse_service.proto b/sdk-cpp/proto/sparse_service.proto index e44327949ed69d87091471d1aa394c523be5c38d..ff5fa7922da260696f9615a08a6d03c3f7fe3fe1 100644 --- a/sdk-cpp/proto/sparse_service.proto +++ b/sdk-cpp/proto/sparse_service.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.sparse_service; @@ -6,11 +20,12 @@ package baidu.paddle_serving.predictor.sparse_service; option cc_generic_services = true; message Request { - repeated baidu.paddle_serving.predictor.format.SparseInstance instances = 1; + repeated baidu.paddle_serving.predictor.format.SparseInstance instances = 1; }; message Response { - repeated baidu.paddle_serving.predictor.format.SparsePrediction predictions = 1; + repeated baidu.paddle_serving.predictor.format.SparsePrediction predictions = + 1; }; service BuiltinSparseFormatService { diff --git a/sdk-cpp/src/abtest.cpp b/sdk-cpp/src/abtest.cpp index c8dfc702678386a78db07b23aad054941b91c5f9..c205bb694be754953df95cd2429afbeb32e7e9eb 100644 --- a/sdk-cpp/src/abtest.cpp +++ b/sdk-cpp/src/abtest.cpp @@ -1,114 +1,105 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file ../src/abtest.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 17:41:27 - * @brief - * - **/ - -#include "abtest.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 "sdk-cpp/include/abtest.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { +int WeightedRandomRender::initialize(const google::protobuf::Message& conf) { + srand((unsigned)time(NULL)); + try { + const configure::WeightedRandomRenderConf& weighted_random_render_conf = + dynamic_cast(conf); -int WeightedRandomRender::initialize( - const google::protobuf::Message& conf) { - srand((unsigned)time(NULL)); - try { - const configure::WeightedRandomRenderConf &weighted_random_render_conf = - dynamic_cast(conf); - - std::string weights - = weighted_random_render_conf.variant_weight_list(); - - std::vector splits; - if (str_split(weights, WEIGHT_SEPERATOR, &splits) != 0) { - LOG(ERROR) << "Failed split string:" << - weights; - return -1; - } - - uint32_t weight_size = splits.size(); - _normalized_sum = 0; - for (uint32_t wi = 0; wi < weight_size; ++wi) { - char* end_pos = NULL; - uint32_t ratio = strtoul( - splits[wi].c_str(), &end_pos, 10); - if (end_pos == splits[wi].c_str()) { - LOG(ERROR) << "Error ratio(uint32) format:" - << splits[wi] << " at " << wi; - return -1; - } - - _variant_weight_list.push_back(ratio); - _normalized_sum += ratio; - } - - if (_normalized_sum <= 0) { - LOG(ERROR) << "Zero normalized weight sum"; - return -1; - } - - LOG(INFO) << "Succ read weights list: " << weights - << ", count: " << _variant_weight_list.size() - << ", normalized: " << _normalized_sum; - } catch (std::bad_cast& e) { - LOG(ERROR) << "Failed init WeightedRandomRender" - << "from configure, err:" << e.what(); - return -1; - } catch (...) { - LOG(ERROR) << "Failed init WeightedRandomRender" - << "from configure, err message is unkown."; + std::string weights = weighted_random_render_conf.variant_weight_list(); + + std::vector splits; + if (str_split(weights, WEIGHT_SEPERATOR, &splits) != 0) { + LOG(ERROR) << "Failed split string:" << weights; + return -1; + } + + uint32_t weight_size = splits.size(); + _normalized_sum = 0; + for (uint32_t wi = 0; wi < weight_size; ++wi) { + char* end_pos = NULL; + uint32_t ratio = strtoul(splits[wi].c_str(), &end_pos, 10); + if (end_pos == splits[wi].c_str()) { + LOG(ERROR) << "Error ratio(uint32) format:" << splits[wi] << " at " + << wi; return -1; + } + + _variant_weight_list.push_back(ratio); + _normalized_sum += ratio; } - return 0; + if (_normalized_sum <= 0) { + LOG(ERROR) << "Zero normalized weight sum"; + return -1; + } + + LOG(INFO) << "Succ read weights list: " << weights + << ", count: " << _variant_weight_list.size() + << ", normalized: " << _normalized_sum; + } catch (std::bad_cast& e) { + LOG(ERROR) << "Failed init WeightedRandomRender" + << "from configure, err:" << e.what(); + return -1; + } catch (...) { + LOG(ERROR) << "Failed init WeightedRandomRender" + << "from configure, err message is unkown."; + return -1; + } + + return 0; } -Variant* WeightedRandomRender::route( - const VariantList& variants, - const void* params) { - return route(variants); +Variant* WeightedRandomRender::route(const VariantList& variants, + const void* params) { + return route(variants); } -Variant* WeightedRandomRender::route( - const VariantList& variants) { - if (variants.size() != _variant_weight_list.size()) { - LOG(ERROR) << "#(Weights) is not equal #(Stubs)" - << ", size: " << _variant_weight_list.size() - << " vs. " << variants.size(); - return NULL; - } - - uint32_t sample = rand() % _normalized_sum; - uint32_t cand_size = _variant_weight_list.size(); - uint32_t cur_total = 0; - for (uint32_t ci = 0; ci < cand_size; ++ci) { - cur_total += _variant_weight_list[ci]; - if (sample < cur_total) { - LOG(INFO) << "Sample " << sample << " on " << ci +Variant* WeightedRandomRender::route(const VariantList& variants) { + if (variants.size() != _variant_weight_list.size()) { + LOG(ERROR) << "#(Weights) is not equal #(Stubs)" + << ", size: " << _variant_weight_list.size() << " vs. " + << variants.size(); + return NULL; + } + + uint32_t sample = rand() % _normalized_sum; // NOLINT + uint32_t cand_size = _variant_weight_list.size(); + uint32_t cur_total = 0; + for (uint32_t ci = 0; ci < cand_size; ++ci) { + cur_total += _variant_weight_list[ci]; + if (sample < cur_total) { + LOG(INFO) << "Sample " << sample << " on " << ci << ", _normalized: " << _normalized_sum << ", weight: " << _variant_weight_list[ci]; - return variants[ci]; - } + return variants[ci]; } + } - LOG(ERROR) << "Errors accurs in sampling, sample:" - << sample << ", total: " << _normalized_sum; + LOG(ERROR) << "Errors accurs in sampling, sample:" << sample + << ", total: " << _normalized_sum; - return NULL; + return NULL; } -} // sdk_cpp -} // paddle_serving -} // baidu - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/src/config_manager.cpp b/sdk-cpp/src/config_manager.cpp index 50145e8cc7175ed7b253b6de32de53f9230b4126..24d25f33e9cf8ee63ea15ba22a5e4cb59920e9d4 100644 --- a/sdk-cpp/src/config_manager.cpp +++ b/sdk-cpp/src/config_manager.cpp @@ -1,19 +1,20 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file endpoint_config.cpp - * @author wanlijin01(com@baidu.com) - * @date 2018/07/09 15:30:09 - * @brief - * - **/ -#include "abtest.h" -#include "config_manager.h" -#include +// 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 "sdk-cpp/include/config_manager.h" +#include "brpc/server.h" +#include "sdk-cpp/include/abtest.h" namespace baidu { namespace paddle_serving { @@ -22,261 +23,232 @@ namespace sdk_cpp { using configure::SDKConf; int EndpointConfigManager::create(const char* path, const char* file) { - _endpoint_config_path = path; - _endpoint_config_file = file; + _endpoint_config_path = path; + _endpoint_config_file = file; - if (load() != 0) { - LOG(ERROR) << "Failed reload endpoint config"; - return -1; - } + if (load() != 0) { + LOG(ERROR) << "Failed reload endpoint config"; + return -1; + } - return 0; + return 0; } int EndpointConfigManager::load() { - try { - SDKConf sdk_conf; - if (configure::read_proto_conf( - _endpoint_config_path.c_str(), - _endpoint_config_file.c_str(), - &sdk_conf) != 0) { - LOG(ERROR) - << "Failed initialize endpoint list" - << ", config: " << _endpoint_config_path - << "/" << _endpoint_config_file; - return -1; - } - - VariantInfo default_var; - if (init_one_variant(sdk_conf.default_variant_conf(), - default_var) != 0) { - LOG(ERROR) << "Failed read default var conf"; - return -1; - } - - uint32_t ep_size = sdk_conf.predictors_size(); + try { + SDKConf sdk_conf; + if (configure::read_proto_conf(_endpoint_config_path.c_str(), + _endpoint_config_file.c_str(), + &sdk_conf) != 0) { + LOG(ERROR) << "Failed initialize endpoint list" + << ", config: " << _endpoint_config_path << "/" + << _endpoint_config_file; + return -1; + } + + VariantInfo default_var; + if (init_one_variant(sdk_conf.default_variant_conf(), default_var) != 0) { + LOG(ERROR) << "Failed read default var conf"; + return -1; + } + + uint32_t ep_size = sdk_conf.predictors_size(); #if 1 - LOG(INFO) << "ep_size: " << ep_size; + LOG(INFO) << "ep_size: " << ep_size; #endif - for (uint32_t ei = 0; ei < ep_size; ++ei) { - EndpointInfo ep; - if (init_one_endpoint(sdk_conf.predictors(ei), ep, - default_var) != 0) { - LOG(ERROR) << "Failed read endpoint info at: " - << ei; - return -1; - } - - std::map::iterator it; - if (_ep_map.find(ep.endpoint_name) != _ep_map.end()) { - LOG(ERROR) << "Cannot insert duplicated endpoint" - << ", ep name: " << ep.endpoint_name; - } - - std::pair::iterator, bool> r - = _ep_map.insert(std::make_pair(ep.endpoint_name, ep)); - if (!r.second) { - LOG(ERROR) << "Failed insert endpoint, name" - << ep.endpoint_name; - return -1; - } - } - - } catch (std::exception& e) { - LOG(ERROR) << "Failed load configure" << e.what(); + for (uint32_t ei = 0; ei < ep_size; ++ei) { + EndpointInfo ep; + if (init_one_endpoint(sdk_conf.predictors(ei), ep, default_var) != 0) { + LOG(ERROR) << "Failed read endpoint info at: " << ei; return -1; + } + + std::map::iterator it; + if (_ep_map.find(ep.endpoint_name) != _ep_map.end()) { + LOG(ERROR) << "Cannot insert duplicated endpoint" + << ", ep name: " << ep.endpoint_name; + } + + std::pair::iterator, bool> r = + _ep_map.insert(std::make_pair(ep.endpoint_name, ep)); + if (!r.second) { + LOG(ERROR) << "Failed insert endpoint, name" << ep.endpoint_name; + return -1; + } } - LOG(INFO) - << "Success reload endpoint config file, id: " - << _current_endpointmap_id; - return 0; + } catch (std::exception& e) { + LOG(ERROR) << "Failed load configure" << e.what(); + return -1; + } + LOG(INFO) << "Success reload endpoint config file, id: " + << _current_endpointmap_id; + return 0; } -int EndpointConfigManager::init_one_endpoint( - const configure::Predictor& conf, EndpointInfo& ep, - const VariantInfo& dft_var) { +int EndpointConfigManager::init_one_endpoint(const configure::Predictor& conf, + EndpointInfo& ep, + const VariantInfo& dft_var) { #if 1 - LOG(INFO) << "init_one_endpoint " << conf.name().c_str(); + LOG(INFO) << "init_one_endpoint " << conf.name().c_str(); #endif - try { - // name - ep.endpoint_name = conf.name(); - // stub - ep.stub_service = conf.service_name(); - // abtest - ConfigItem ep_router; - PARSE_CONF_ITEM(conf, ep_router, endpoint_router, -1); - if (ep_router.init) { - if (ep_router.value != "WeightedRandomRender") { - LOG(ERROR) << "endpointer_router unrecognized " << ep_router.value; - return -1; - } - - EndpointRouterBase* router - = EndpointRouterFactory::instance().generate_object( - ep_router.value); - - const configure::WeightedRandomRenderConf &router_conf = - conf.weighted_random_render_conf(); - if (!router || router->initialize(router_conf) != 0) { - LOG(ERROR) << "Failed fetch valid ab test strategy" - << ", name:" << ep_router.value; - return -1; - } - ep.ab_test = router; - } - - // varlist - uint32_t var_size = conf.variants_size(); + try { + // name + ep.endpoint_name = conf.name(); + // stub + ep.stub_service = conf.service_name(); + // abtest + ConfigItem ep_router; + PARSE_CONF_ITEM(conf, ep_router, endpoint_router, -1); + if (ep_router.init) { + if (ep_router.value != "WeightedRandomRender") { + LOG(ERROR) << "endpointer_router unrecognized " << ep_router.value; + return -1; + } + + EndpointRouterBase* router = + EndpointRouterFactory::instance().generate_object(ep_router.value); + + const configure::WeightedRandomRenderConf& router_conf = + conf.weighted_random_render_conf(); + if (!router || router->initialize(router_conf) != 0) { + LOG(ERROR) << "Failed fetch valid ab test strategy" + << ", name:" << ep_router.value; + return -1; + } + ep.ab_test = router; + } + + // varlist + uint32_t var_size = conf.variants_size(); #if 1 - LOG(INFO) << "Variant size: " << var_size; + LOG(INFO) << "Variant size: " << var_size; #endif - for (uint32_t vi = 0; vi < var_size; ++vi) { - VariantInfo var; - if (merge_variant(dft_var, conf.variants(vi), - var) != 0) { - LOG(ERROR) << "Failed merge variant info at: " - << vi; - return -1; - } - - ep.vars.push_back(var); - } - - if (ep.vars.size() > 1 && ep.ab_test == NULL) { - LOG(ERROR) << "EndpointRouter must be configured, when" - << " #Variants > 1."; - return -1; - } - - LOG(INFO) - << "Succ load one endpoint, name: " << ep.endpoint_name - << ", count of variants: " << ep.vars.size() << "."; - - } catch (std::exception& e) { - LOG(ERROR) << "Exception acccurs when load endpoint conf" - << ", message: " << e.what(); + for (uint32_t vi = 0; vi < var_size; ++vi) { + VariantInfo var; + if (merge_variant(dft_var, conf.variants(vi), var) != 0) { + LOG(ERROR) << "Failed merge variant info at: " << vi; return -1; + } + + ep.vars.push_back(var); } - return 0; + + if (ep.vars.size() > 1 && ep.ab_test == NULL) { + LOG(ERROR) << "EndpointRouter must be configured, when" + << " #Variants > 1."; + return -1; + } + + LOG(INFO) << "Succ load one endpoint, name: " << ep.endpoint_name + << ", count of variants: " << ep.vars.size() << "."; + } catch (std::exception& e) { + LOG(ERROR) << "Exception acccurs when load endpoint conf" + << ", message: " << e.what(); + return -1; + } + return 0; } -int EndpointConfigManager::init_one_variant( - const configure::VariantConf& conf, VariantInfo& var) { - try { +int EndpointConfigManager::init_one_variant(const configure::VariantConf& conf, + VariantInfo& var) { + try { // Connect const configure::ConnectionConf& conn = conf.connection_conf(); - PARSE_CONF_ITEM(conn, var.connection.tmo_conn, - connect_timeout_ms, -1); - PARSE_CONF_ITEM(conn, var.connection.tmo_rpc, - rpc_timeout_ms, -1); - PARSE_CONF_ITEM(conn, var.connection.tmo_hedge, - hedge_request_timeout_ms, -1); - PARSE_CONF_ITEM(conn, var.connection.cnt_retry_conn, - connect_retry_count, -1); - PARSE_CONF_ITEM(conn, var.connection.cnt_retry_hedge, - hedge_fetch_retry_count, -1); - PARSE_CONF_ITEM(conn, var.connection.cnt_maxconn_per_host, - max_connection_per_host, -1); - PARSE_CONF_ITEM(conn, var.connection.type_conn, - connection_type, -1); + PARSE_CONF_ITEM(conn, var.connection.tmo_conn, connect_timeout_ms, -1); + PARSE_CONF_ITEM(conn, var.connection.tmo_rpc, rpc_timeout_ms, -1); + PARSE_CONF_ITEM( + conn, var.connection.tmo_hedge, hedge_request_timeout_ms, -1); + PARSE_CONF_ITEM( + conn, var.connection.cnt_retry_conn, connect_retry_count, -1); + PARSE_CONF_ITEM( + conn, var.connection.cnt_retry_hedge, hedge_fetch_retry_count, -1); + PARSE_CONF_ITEM( + conn, var.connection.cnt_maxconn_per_host, max_connection_per_host, -1); + PARSE_CONF_ITEM(conn, var.connection.type_conn, connection_type, -1); // Naming const configure::NamingConf& name = conf.naming_conf(); - PARSE_CONF_ITEM(name, var.naminginfo.cluster_naming, - cluster, -1); - PARSE_CONF_ITEM(name, var.naminginfo.load_balancer, - load_balance_strategy, -1); - PARSE_CONF_ITEM(name, var.naminginfo.cluster_filter, - cluster_filter_strategy, -1); + PARSE_CONF_ITEM(name, var.naminginfo.cluster_naming, cluster, -1); + PARSE_CONF_ITEM( + name, var.naminginfo.load_balancer, load_balance_strategy, -1); + PARSE_CONF_ITEM( + name, var.naminginfo.cluster_filter, cluster_filter_strategy, -1); // Rpc const configure::RpcParameter& params = conf.rpc_parameter(); - PARSE_CONF_ITEM(params, var.parameters.protocol, - protocol, -1); + PARSE_CONF_ITEM(params, var.parameters.protocol, protocol, -1); #if 1 LOG(WARNING) << var.parameters.protocol.value.c_str(); #endif - PARSE_CONF_ITEM(params, var.parameters.compress_type, - compress_type, -1); - PARSE_CONF_ITEM(params, var.parameters.package_size, - package_size, -1); - PARSE_CONF_ITEM(params, var.parameters.max_channel, - max_channel_per_request, -1); + PARSE_CONF_ITEM(params, var.parameters.compress_type, compress_type, -1); + PARSE_CONF_ITEM(params, var.parameters.package_size, package_size, -1); + PARSE_CONF_ITEM( + params, var.parameters.max_channel, max_channel_per_request, -1); // Split const configure::SplitConf& splits = conf.split_conf(); - PARSE_CONF_ITEM(splits, var.splitinfo.split_tag, - split_tag_name, -1); - PARSE_CONF_ITEM(splits, var.splitinfo.tag_cands_str, - tag_candidates, -1); + PARSE_CONF_ITEM(splits, var.splitinfo.split_tag, split_tag_name, -1); + PARSE_CONF_ITEM(splits, var.splitinfo.tag_cands_str, tag_candidates, -1); if (parse_tag_values(var.splitinfo) != 0) { - LOG(ERROR) << "Failed parse tag_values:" << - var.splitinfo.tag_cands_str.value; - return -1; + LOG(ERROR) << "Failed parse tag_values:" + << var.splitinfo.tag_cands_str.value; + return -1; } // tag - PARSE_CONF_ITEM(conf, var.parameters.route_tag, - tag, -1); + PARSE_CONF_ITEM(conf, var.parameters.route_tag, tag, -1); + } catch (...) { + LOG(ERROR) << "Failed load variant from configure unit"; + return -1; + } - } catch (...) { - LOG(ERROR) << "Failed load variant from configure unit"; - return -1; - } - - return 0; + return 0; } -int EndpointConfigManager::merge_variant( - const VariantInfo& default_var, - const configure::VariantConf& conf, - VariantInfo& merged_var) { - merged_var = default_var; +int EndpointConfigManager::merge_variant(const VariantInfo& default_var, + const configure::VariantConf& conf, + VariantInfo& merged_var) { + merged_var = default_var; #if 1 - LOG(INFO) << "merge_variant " << conf.tag().c_str(); + LOG(INFO) << "merge_variant " << conf.tag().c_str(); #endif - return init_one_variant(conf, merged_var); + return init_one_variant(conf, merged_var); } -int EndpointConfigManager::parse_tag_values( - SplitParameters& split) { - - split.tag_values.clear(); - if (!split.split_tag.init || !split.tag_cands_str.init) { - LOG(WARNING) << "split info not set, skip..."; - return 0; +int EndpointConfigManager::parse_tag_values(SplitParameters& split) { + split.tag_values.clear(); + if (!split.split_tag.init || !split.tag_cands_str.init) { + LOG(WARNING) << "split info not set, skip..."; + return 0; + } + + static const char SPLIT_DELIM = ','; + const std::string& tag_str = split.tag_cands_str.value; + std::string::size_type start_pos = 0; + std::string::size_type end_pos; + + do { + end_pos = tag_str.find(SPLIT_DELIM, start_pos); + std::string tag_value_str; + if (end_pos == std::string::npos) { + tag_value_str = tag_str.substr(start_pos); + } else { + tag_value_str = tag_str.substr(start_pos, end_pos - start_pos); + start_pos = end_pos + 1; } - static const char SPLIT_DELIM = ','; - const std::string& tag_str = split.tag_cands_str.value; - std::string::size_type start_pos = 0; - std::string::size_type end_pos; - - do { - end_pos = tag_str.find(SPLIT_DELIM, start_pos); - std::string tag_value_str; - if (end_pos == std::string::npos) { - tag_value_str = tag_str.substr(start_pos); - } else { - tag_value_str = tag_str.substr( - start_pos, end_pos - start_pos); - start_pos = end_pos + 1; - } - - split.tag_values.push_back(tag_value_str); - } while (end_pos != std::string::npos); + split.tag_values.push_back(tag_value_str); + } while (end_pos != std::string::npos); - return 0; + return 0; } -} // sdk_cpp -} // paddle_serving -} // baidu +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ diff --git a/sdk-cpp/src/endpoint.cpp b/sdk-cpp/src/endpoint.cpp index 73d18c273502246320aed0a2f1017a3184ffe543..8b2a15aa349080a242966dd9573b1fa8376c79b2 100644 --- a/sdk-cpp/src/endpoint.cpp +++ b/sdk-cpp/src/endpoint.cpp @@ -1,131 +1,125 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file endpoint.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 14:10:44 - * @brief - * - **/ +// 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 "endpoint.h" -#include "factory.h" +#include "sdk-cpp/include/endpoint.h" +#include "sdk-cpp/include/factory.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { int Endpoint::initialize(const EndpointInfo& ep_info) { - _variant_list.clear(); - _endpoint_name = ep_info.endpoint_name; - uint32_t var_size = ep_info.vars.size(); - for (uint32_t vi = 0; vi < var_size; ++vi) { - const VariantInfo& var_info = ep_info.vars[vi]; - Variant* var = new (std::nothrow) Variant; - if (!var || var->initialize(ep_info, var_info) != 0) { - LOG(ERROR) << "Failed initialize variant, tag:" - << var_info.parameters.route_tag.value - << ", endpoint: " << ep_info.endpoint_name - << ", var index: " << vi; - return -1; - } - _variant_list.push_back(var); - LOG(INFO) << "Succ create variant: " << vi << ", endpoint:" - << _endpoint_name; + _variant_list.clear(); + _endpoint_name = ep_info.endpoint_name; + uint32_t var_size = ep_info.vars.size(); + for (uint32_t vi = 0; vi < var_size; ++vi) { + const VariantInfo& var_info = ep_info.vars[vi]; + Variant* var = new (std::nothrow) Variant; + if (!var || var->initialize(ep_info, var_info) != 0) { + LOG(ERROR) << "Failed initialize variant, tag:" + << var_info.parameters.route_tag.value + << ", endpoint: " << ep_info.endpoint_name + << ", var index: " << vi; + return -1; } + _variant_list.push_back(var); + LOG(INFO) << "Succ create variant: " << vi + << ", endpoint:" << _endpoint_name; + } - return 0; + return 0; } int Endpoint::thrd_initialize() { - uint32_t var_size = _variant_list.size(); - for (uint32_t vi = 0; vi < var_size; ++vi) { - Variant* var = _variant_list[vi]; - if (!var || var->thrd_initialize()) { - LOG(ERROR) << "Failed thrd initialize var: " << vi; - return -1; - } + uint32_t var_size = _variant_list.size(); + for (uint32_t vi = 0; vi < var_size; ++vi) { + Variant* var = _variant_list[vi]; + if (!var || var->thrd_initialize()) { + LOG(ERROR) << "Failed thrd initialize var: " << vi; + return -1; } - LOG(WARNING) << "Succ thrd initialize all vars: " << var_size; - return 0; + } + LOG(WARNING) << "Succ thrd initialize all vars: " << var_size; + return 0; } int Endpoint::thrd_clear() { - uint32_t var_size = _variant_list.size(); - for (uint32_t vi = 0; vi < var_size; ++vi) { - Variant* var = _variant_list[vi]; - if (!var || var->thrd_clear()) { - LOG(ERROR) << "Failed thrd clear var: " << vi; - return -1; - } + uint32_t var_size = _variant_list.size(); + for (uint32_t vi = 0; vi < var_size; ++vi) { + Variant* var = _variant_list[vi]; + if (!var || var->thrd_clear()) { + LOG(ERROR) << "Failed thrd clear var: " << vi; + return -1; } - LOG(INFO) << "Succ thrd clear all vars: " << var_size; - return 0; + } + LOG(INFO) << "Succ thrd clear all vars: " << var_size; + return 0; } int Endpoint::thrd_finalize() { - uint32_t var_size = _variant_list.size(); - for (uint32_t vi = 0; vi < var_size; ++vi) { - Variant* var = _variant_list[vi]; - if (!var || var->thrd_finalize()) { - LOG(ERROR) << "Failed thrd finalize var: " << vi; - return -1; - } + uint32_t var_size = _variant_list.size(); + for (uint32_t vi = 0; vi < var_size; ++vi) { + Variant* var = _variant_list[vi]; + if (!var || var->thrd_finalize()) { + LOG(ERROR) << "Failed thrd finalize var: " << vi; + return -1; } - LOG(INFO) << "Succ thrd finalize all vars: " << var_size; - return 0; + } + LOG(INFO) << "Succ thrd finalize all vars: " << var_size; + return 0; } // 带全流量分层实验路由信息 -Predictor* Endpoint::get_predictor( - const void* params) { - Variant* var = NULL; - if (_variant_list.size() == 1) { - var = _variant_list[0]; - } +Predictor* Endpoint::get_predictor(const void* params) { + Variant* var = NULL; + if (_variant_list.size() == 1) { + var = _variant_list[0]; + } - if (!var) { - LOG(ERROR) << "get null var from endpoint."; - return NULL; - } + if (!var) { + LOG(ERROR) << "get null var from endpoint."; + return NULL; + } - return var->get_predictor(params); + return var->get_predictor(params); } Predictor* Endpoint::get_predictor() { #if 1 - LOG(INFO) << "Endpoint::get_predictor"; + LOG(INFO) << "Endpoint::get_predictor"; #endif - if (_variant_list.size() == 1) { - if (_variant_list[0] == NULL) { - LOG(ERROR) << "Not valid variant info"; - return NULL; - } - return _variant_list[0]->get_predictor(); + if (_variant_list.size() == 1) { + if (_variant_list[0] == NULL) { + LOG(ERROR) << "Not valid variant info"; + return NULL; } - - return NULL; + return _variant_list[0]->get_predictor(); + } + + return NULL; } int Endpoint::ret_predictor(Predictor* predictor) { - const Stub* stub = predictor->stub(); - if (!stub || stub->return_predictor( - predictor) != 0) { - LOG(ERROR) << "Failed return predictor to pool"; - return -1; - } + const Stub* stub = predictor->stub(); + if (!stub || stub->return_predictor(predictor) != 0) { + LOG(ERROR) << "Failed return predictor to pool"; + return -1; + } - return 0; + return 0; } -} // sdk_cpp -} // paddle_serving -} // baidu - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/src/predictor_sdk.cpp b/sdk-cpp/src/predictor_sdk.cpp index 2e5d1c5a77d091d1dfaf77072452265ad973d879..214473f64204866febb7d842b53551aa1cfe225d 100644 --- a/sdk-cpp/src/predictor_sdk.cpp +++ b/sdk-cpp/src/predictor_sdk.cpp @@ -1,136 +1,121 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - -/** - * @file src/predictor_api.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/09 17:36:13 - * @brief - * - **/ -#include "abtest.h" -#include "predictor_sdk.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 "sdk-cpp/include/predictor_sdk.h" +#include "sdk-cpp/include/abtest.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { int PredictorApi::register_all() { - if (WeightedRandomRender::register_self() != 0) { - LOG(ERROR) << "Failed register WeightedRandomRender"; - return -1; - } + if (WeightedRandomRender::register_self() != 0) { + LOG(ERROR) << "Failed register WeightedRandomRender"; + return -1; + } - LOG(WARNING) << "Succ register all components!"; + LOG(WARNING) << "Succ register all components!"; - return 0; + return 0; } int PredictorApi::create(const char* path, const char* file) { - if (register_all() != 0) { - LOG(ERROR) << "Failed do register all!"; - return -1; + if (register_all() != 0) { + LOG(ERROR) << "Failed do register all!"; + return -1; + } + + if (_config_manager.create(path, file) != 0) { + LOG(ERROR) << "Failed create config manager from conf:" << path << "/" + << file; + return -1; + } + + const std::map& map = _config_manager.config(); + std::map::const_iterator it; + for (it = map.begin(); it != map.end(); ++it) { + const EndpointInfo& ep_info = it->second; + Endpoint* ep = new (std::nothrow) Endpoint(); + if (ep->initialize(ep_info) != 0) { + LOG(ERROR) << "Failed intialize endpoint:" << ep_info.endpoint_name; + return -1; } - if (_config_manager.create(path, file) != 0) { - LOG(ERROR) << "Failed create config manager from conf:" - << path << "/" << file; - return -1; + if (_endpoints.find(ep_info.endpoint_name) != _endpoints.end()) { + LOG(ERROR) << "Cannot insert duplicated endpoint:" + << ep_info.endpoint_name; + return -1; } - const std::map& map - = _config_manager.config(); - std::map::const_iterator it; - for (it = map.begin(); it != map.end(); ++it) { - const EndpointInfo& ep_info = it->second; - Endpoint* ep = new (std::nothrow) Endpoint(); - if (ep->initialize(ep_info) != 0) { - LOG(ERROR) << "Failed intialize endpoint:" - << ep_info.endpoint_name; - return -1; - } - - if (_endpoints.find( - ep_info.endpoint_name) != _endpoints.end()) { - LOG(ERROR) << "Cannot insert duplicated endpoint:" - << ep_info.endpoint_name; - return -1; - } - - std::pair::iterator, bool> r - = _endpoints.insert(std::make_pair( - ep_info.endpoint_name, ep)); - if (!r.second) { - LOG(ERROR) << "Failed insert endpoint:" - << ep_info.endpoint_name; - return -1; - } - - LOG(INFO) << "Succ create endpoint instance with name: " - << ep_info.endpoint_name; + std::pair::iterator, bool> r = + _endpoints.insert(std::make_pair(ep_info.endpoint_name, ep)); + if (!r.second) { + LOG(ERROR) << "Failed insert endpoint:" << ep_info.endpoint_name; + return -1; } - return 0; + LOG(INFO) << "Succ create endpoint instance with name: " + << ep_info.endpoint_name; + } + + return 0; } int PredictorApi::thrd_initialize() { - std::map::const_iterator it; - for (it = _endpoints.begin(); it != _endpoints.end(); ++it) { - Endpoint* ep = it->second; - if (ep->thrd_initialize() != 0) { - LOG(ERROR) << "Failed thrd initialize endpoint:" - << it->first; - return -1; - } - - LOG(WARNING) << "Succ thrd initialize endpoint:" - << it->first; + std::map::const_iterator it; + for (it = _endpoints.begin(); it != _endpoints.end(); ++it) { + Endpoint* ep = it->second; + if (ep->thrd_initialize() != 0) { + LOG(ERROR) << "Failed thrd initialize endpoint:" << it->first; + return -1; } - return 0; + + LOG(WARNING) << "Succ thrd initialize endpoint:" << it->first; + } + return 0; } int PredictorApi::thrd_clear() { - std::map::const_iterator it; - for (it = _endpoints.begin(); it != _endpoints.end(); ++it) { - Endpoint* ep = it->second; - if (ep->thrd_clear() != 0) { - LOG(ERROR) << "Failed thrd clear endpoint:" - << it->first; - return -1; - } - - LOG(INFO) << "Succ thrd clear endpoint:" - << it->first; + std::map::const_iterator it; + for (it = _endpoints.begin(); it != _endpoints.end(); ++it) { + Endpoint* ep = it->second; + if (ep->thrd_clear() != 0) { + LOG(ERROR) << "Failed thrd clear endpoint:" << it->first; + return -1; } - return 0; + + LOG(INFO) << "Succ thrd clear endpoint:" << it->first; + } + return 0; } int PredictorApi::thrd_finalize() { - std::map::const_iterator it; - for (it = _endpoints.begin(); it != _endpoints.end(); ++it) { - Endpoint* ep = it->second; - if (ep->thrd_finalize() != 0) { - LOG(ERROR) << "Failed thrd finalize endpoint:" - << it->first; - return -1; - } - - LOG(INFO) << "Succ thrd finalize endpoint:" - << it->first; + std::map::const_iterator it; + for (it = _endpoints.begin(); it != _endpoints.end(); ++it) { + Endpoint* ep = it->second; + if (ep->thrd_finalize() != 0) { + LOG(ERROR) << "Failed thrd finalize endpoint:" << it->first; + return -1; } - return 0; -} -void PredictorApi::destroy() { - // TODO - return ; + LOG(INFO) << "Succ thrd finalize endpoint:" << it->first; + } + return 0; } -} // sdk_cpp -} // paddle_serving -} // baidu +void PredictorApi::destroy() { return; } -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/sdk-cpp/src/variant.cpp b/sdk-cpp/src/variant.cpp index 3fc9bf53c39e7931ebbbd6b3e25431b2555ff61e..5657c36b5909f7608293172fc2f6c5847bc3aecf 100644 --- a/sdk-cpp/src/variant.cpp +++ b/sdk-cpp/src/variant.cpp @@ -1,151 +1,142 @@ -/*************************************************************************** - * - * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved - * - **************************************************************************/ - - - -/** - * @file src/variant.cpp - * @author wanlijin01(wanlijin01@baidu.com) - * @date 2018/07/27 17:42:21 - * @brief - * - **/ - -#include "variant.h" -#include "factory.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 "sdk-cpp/include/variant.h" +#include "sdk-cpp/include/factory.h" namespace baidu { namespace paddle_serving { namespace sdk_cpp { int Variant::initialize(const EndpointInfo& ep_info, - const VariantInfo& var_info) { - - _endpoint_name = ep_info.endpoint_name; - _stub_service = ep_info.stub_service; - - _variant_tag = var_info.parameters.route_tag.value; - _stub_map.clear(); - - const SplitParameters& split_info = var_info.splitinfo; - uint32_t tag_size = split_info.tag_values.size(); - for (uint32_t ti = 0; ti < tag_size; ++ti) { // split - Stub* stub = StubFactory::instance().generate_object( - _stub_service); - const std::string& tag_value = split_info.tag_values[ti]; - if (!stub || stub->initialize(var_info, ep_info.endpoint_name, - &split_info.split_tag.value, &tag_value) != 0) { - LOG(ERROR) << "Failed init stub from factory" - << ", stub name: " << ep_info.stub_service - << ", filter tag: " << tag_value; - return -1; - } - - // 判重 - std::map::iterator iter = - _stub_map.find(tag_value); - if (iter != _stub_map.end()) { - LOG(ERROR) << "duplicated tag value: " - << tag_value; - return -1; - } - _stub_map[tag_value] = stub; - } - - if (_stub_map.size() > 0) { - LOG(INFO) << "Initialize variants from VariantInfo" - << ", stubs count: " << _stub_map.size(); - return 0; + const VariantInfo& var_info) { + _endpoint_name = ep_info.endpoint_name; + _stub_service = ep_info.stub_service; + + _variant_tag = var_info.parameters.route_tag.value; + _stub_map.clear(); + + const SplitParameters& split_info = var_info.splitinfo; + uint32_t tag_size = split_info.tag_values.size(); + for (uint32_t ti = 0; ti < tag_size; ++ti) { // split + Stub* stub = StubFactory::instance().generate_object(_stub_service); + const std::string& tag_value = split_info.tag_values[ti]; + if (!stub || + stub->initialize(var_info, + ep_info.endpoint_name, + &split_info.split_tag.value, + &tag_value) != 0) { + LOG(ERROR) << "Failed init stub from factory" + << ", stub name: " << ep_info.stub_service + << ", filter tag: " << tag_value; + return -1; } - Stub* stub = StubFactory::instance().generate_object( - ep_info.stub_service); - if (!stub || stub->initialize( - var_info, _endpoint_name, NULL, NULL) != 0) { - LOG(ERROR) << "Failed init stub from factory" - << ", stub name: " << ep_info.stub_service; - return -1; + // 判重 + std::map::iterator iter = _stub_map.find(tag_value); + if (iter != _stub_map.end()) { + LOG(ERROR) << "duplicated tag value: " << tag_value; + return -1; } + _stub_map[tag_value] = stub; + } - _default_stub = stub; - LOG(INFO) << "Succ create default debug"; + if (_stub_map.size() > 0) { + LOG(INFO) << "Initialize variants from VariantInfo" + << ", stubs count: " << _stub_map.size(); return 0; + } + + Stub* stub = StubFactory::instance().generate_object(ep_info.stub_service); + if (!stub || stub->initialize(var_info, _endpoint_name, NULL, NULL) != 0) { + LOG(ERROR) << "Failed init stub from factory" + << ", stub name: " << ep_info.stub_service; + return -1; + } + + _default_stub = stub; + LOG(INFO) << "Succ create default debug"; + return 0; } int Variant::thrd_initialize() { - if (_stub_map.size() <= 0) { - return _default_stub->thrd_initialize(); - } - - std::map::iterator iter; - for (iter = _stub_map.begin(); iter != _stub_map.end(); ++iter) { - Stub* stub = iter->second; - if (!stub || stub->thrd_initialize() != 0) { - LOG(ERROR) << "Failed thrd initialize stub: " << iter->first; - return -1; - } - LOG(INFO) << "Succ thrd initialize stub:" << iter->first; + if (_stub_map.size() <= 0) { + return _default_stub->thrd_initialize(); + } + + std::map::iterator iter; + for (iter = _stub_map.begin(); iter != _stub_map.end(); ++iter) { + Stub* stub = iter->second; + if (!stub || stub->thrd_initialize() != 0) { + LOG(ERROR) << "Failed thrd initialize stub: " << iter->first; + return -1; } + LOG(INFO) << "Succ thrd initialize stub:" << iter->first; + } - LOG(WARNING) << "Succ thrd initialize all stubs"; - return 0; + LOG(WARNING) << "Succ thrd initialize all stubs"; + return 0; } int Variant::thrd_clear() { - if (_stub_map.size() <= 0) { - return _default_stub->thrd_clear(); + if (_stub_map.size() <= 0) { + return _default_stub->thrd_clear(); + } + + std::map::iterator iter; + for (iter = _stub_map.begin(); iter != _stub_map.end(); ++iter) { + Stub* stub = iter->second; + if (!stub || stub->thrd_clear() != 0) { + LOG(ERROR) << "Failed thrd clear stub: " << iter->first; + return -1; } - - std::map::iterator iter; - for (iter = _stub_map.begin(); iter != _stub_map.end(); ++iter) { - Stub* stub = iter->second; - if (!stub || stub->thrd_clear() != 0) { - LOG(ERROR) << "Failed thrd clear stub: " << iter->first; - return -1; - } - } - return 0; + } + return 0; } int Variant::thrd_finalize() { - if (_stub_map.size() <= 0) { - return _default_stub->thrd_finalize(); + if (_stub_map.size() <= 0) { + return _default_stub->thrd_finalize(); + } + + std::map::iterator iter; + for (iter = _stub_map.begin(); iter != _stub_map.end(); ++iter) { + Stub* stub = iter->second; + if (!stub || stub->thrd_finalize() != 0) { + LOG(ERROR) << "Failed thrd finalize stub: " << iter->first; + return -1; } - - std::map::iterator iter; - for (iter = _stub_map.begin(); iter != _stub_map.end(); ++iter) { - Stub* stub = iter->second; - if (!stub || stub->thrd_finalize() != 0) { - LOG(ERROR) << "Failed thrd finalize stub: " << iter->first; - return -1; - } - } - return 0; + } + return 0; } Predictor* Variant::get_predictor() { - if (_default_stub) { - return _default_stub->fetch_predictor(); - } + if (_default_stub) { + return _default_stub->fetch_predictor(); + } - return NULL; + return NULL; } -Predictor* Variant::get_predictor( - const void* params) { - - if (_default_stub) { - return _default_stub->fetch_predictor(); - } +Predictor* Variant::get_predictor(const void* params) { + if (_default_stub) { + return _default_stub->fetch_predictor(); + } - return NULL; + return NULL; } -} // sdk_cpp -} // paddle_serving -} // baidu - -/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */ +} // namespace sdk_cpp +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/CMakeLists.txt b/serving/CMakeLists.txt index b275e4ecc15ef584b77418fdd05779f958000390..8d2018f81c52da7da41d0915c2a7069a2687ea9e 100644 --- a/serving/CMakeLists.txt +++ b/serving/CMakeLists.txt @@ -20,5 +20,3 @@ install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/conf DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/demo/serving/) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/data DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/demo/serving/) - - diff --git a/serving/op/classify_op.cpp b/serving/op/classify_op.cpp index 8bba708070e9427d4581d089ff2c3a74d560d0ac..aa8c14537594a048aeddeaecddb799aa25ff96ba 100644 --- a/serving/op/classify_op.cpp +++ b/serving/op/classify_op.cpp @@ -1,7 +1,21 @@ -#include "op/reader_op.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 "op/classify_op.h" -#include "framework/memory.h" #include "framework/infer.h" +#include "framework/memory.h" +#include "op/reader_op.h" namespace baidu { namespace paddle_serving { @@ -12,85 +26,84 @@ using baidu::paddle_serving::predictor::image_classification::ClassifyResponse; using baidu::paddle_serving::predictor::InferManager; int ClassifyOp::inference() { - const ReaderOutput* reader_out = - get_depend_argument("image_reader_op"); - if (!reader_out) { - LOG(ERROR) << "Failed mutable depended argument, op:" - << "reader_op"; - return -1; + const ReaderOutput* reader_out = + get_depend_argument("image_reader_op"); + if (!reader_out) { + LOG(ERROR) << "Failed mutable depended argument, op:" + << "reader_op"; + return -1; + } + + const TensorVector* in = &reader_out->tensors; + uint32_t sample_size = in->size(); + + TensorVector* out = butil::get_object(); + if (!out) { + LOG(ERROR) << "Failed get tls output object failed"; + return -1; + } + + if (sample_size <= 0) { + LOG(INFO) << "No samples need to to predicted"; + return 0; + } + + // call paddle fluid model for inferencing + if (InferManager::instance().infer( + IMAGE_CLASSIFICATION_MODEL_NAME, in, out, sample_size)) { + LOG(ERROR) << "Failed do infer in fluid model: " + << IMAGE_CLASSIFICATION_MODEL_NAME; + return -1; + } + + if (out->size() != sample_size) { + LOG(ERROR) << "Output size not eq input size: " << in->size() + << out->size(); + return -1; + } + + // copy output tensor into response + ClassifyResponse* res = mutable_data(); + for (uint32_t si = 0; si < sample_size; si++) { + const paddle::PaddleTensor& out_tensor = (*out)[si]; + DensePrediction* ins = res->add_predictions(); + if (!ins) { + LOG(ERROR) << "Failed append new out tensor"; + return -1; } - const TensorVector* in = &reader_out->tensors; - uint32_t sample_size = in->size(); - - TensorVector* out = butil::get_object(); - if (!out) { - LOG(ERROR) << "Failed get tls output object failed"; - return -1; + uint32_t shape_size = out_tensor.shape.size(); + if (out_tensor.shape.size() != 2 || out_tensor.shape[0] != 1) { + LOG(ERROR) << "Not valid classification out shape" + << ", shape size: " << out_tensor.shape.size(); + return -1; } - if (sample_size <= 0) { - LOG(INFO) << "No samples need to to predicted"; - return 0; + // assign output data + uint32_t data_size = out_tensor.data.length() / sizeof(float); + float* data = reinterpret_cast(out_tensor.data.data()); + for (uint32_t di = 0; di < data_size; ++di) { + ins->add_categories(data[di]); } + } - // call paddle fluid model for inferencing - if (InferManager::instance().infer( - IMAGE_CLASSIFICATION_MODEL_NAME, in, - out, sample_size)) { - LOG(ERROR) << "Failed do infer in fluid model: " - << IMAGE_CLASSIFICATION_MODEL_NAME; - return -1; - } - - if (out->size() != sample_size) { - LOG(ERROR) << "Output size not eq input size: " << in->size() - << out->size(); - return -1; - } - - // copy output tensor into response - ClassifyResponse* res = mutable_data(); - for (uint32_t si = 0; si < sample_size; si++) { - const paddle::PaddleTensor& out_tensor = (*out)[si]; - DensePrediction* ins = res->add_predictions(); - if (!ins) { - LOG(ERROR) << "Failed append new out tensor"; - return -1; - } - - uint32_t shape_size = out_tensor.shape.size(); - if (out_tensor.shape.size() != 2 || out_tensor.shape[0] != 1) { - LOG(ERROR) << "Not valid classification out shape" - << ", shape size: " << out_tensor.shape.size(); - return -1; - } - - // assign output data - uint32_t data_size = out_tensor.data.length() / sizeof(float); - float* data = (float*)out_tensor.data.data(); - for (uint32_t di = 0; di < data_size; ++di) { - ins->add_categories(data[di]); - } - } - - // release out tensor object resource - size_t out_size = out->size(); - for (size_t oi = 0; oi < out_size; ++oi) { - (*out)[oi].shape.clear(); - } - out->clear(); - butil::return_object(out); + // release out tensor object resource + size_t out_size = out->size(); + for (size_t oi = 0; oi < out_size; ++oi) { + (*out)[oi].shape.clear(); + } + out->clear(); + butil::return_object(out); - LOG(INFO) << "Response in image classification:" - << "length:" << res->ByteSize() << "," - << "data:" << res->ShortDebugString(); + LOG(INFO) << "Response in image classification:" + << "length:" << res->ByteSize() << "," + << "data:" << res->ShortDebugString(); - return 0; + return 0; } DEFINE_OP(ClassifyOp); -} // serving -} // paddle_serving -} // baidu +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/classify_op.h b/serving/op/classify_op.h index 6e23988961ff7a9afe66b8334ffb6b50caffc87c..68eb05c7bbb23b63bb58363cce87e9c7e89f497b 100644 --- a/serving/op/classify_op.h +++ b/serving/op/classify_op.h @@ -1,32 +1,40 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_OP_IMAGE_CLASSIFY_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_OP_IMAGE_CLASSIFY_OP_H - -#include "builtin_format.pb.h" -#include "image_class.pb.h" -#include "common/inner_common.h" -#include "op/op.h" -#include "framework/channel.h" -#include "framework/op_repository.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. + +#pragma once +#include +#include "paddle/fluid/inference/paddle_inference_api.h" +#include "serving/image_class.pb.h" namespace baidu { namespace paddle_serving { namespace serving { -static const char* IMAGE_CLASSIFICATION_MODEL_NAME - = "image_classification_resnet"; +static const char* IMAGE_CLASSIFICATION_MODEL_NAME = + "image_classification_resnet"; class ClassifyOp : public baidu::paddle_serving::predictor::OpWithChannel< - baidu::paddle_serving::predictor::image_classification::ClassifyResponse> { -public: - typedef std::vector TensorVector; + baidu::paddle_serving::predictor::image_classification:: + ClassifyResponse> { + public: + typedef std::vector TensorVector; - DECLARE_OP(ClassifyOp); + DECLARE_OP(ClassifyOp); - int inference(); + int inference(); }; -} // serving -} // paddle_serving -} // baidu - -#endif +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/common_echo_op.cpp b/serving/op/common_echo_op.cpp index cf2a89723aed579fd9c35e8051f2faaf1e242648..570088cbf9adfb981bd3f92d08f95d8a9f793e32 100644 --- a/serving/op/common_echo_op.cpp +++ b/serving/op/common_echo_op.cpp @@ -1,3 +1,17 @@ +// 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 "op/common_echo_op.h" namespace baidu { @@ -6,6 +20,6 @@ namespace predictor { DEFINE_OP(CommonEchoOp); -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/common_echo_op.h b/serving/op/common_echo_op.h index 08134ef2b5d5d92429fac4a87426f5438bb493e8..f8da7883fa2327d3f1a1443270a6d2efd57ae0d0 100644 --- a/serving/op/common_echo_op.h +++ b/serving/op/common_echo_op.h @@ -1,40 +1,50 @@ -#ifndef BAIDU_PREDICTOR_PREDICTOR_COMMON_ECHO_OP_H -#define BAIDU_PREDICTOR_PREDICTOR_COMMON_ECHO_OP_H - -#include "echo_service.pb.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. + +#pragma once +#include "serving/echo_service.pb.h" #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { namespace predictor { -class CommonEchoOp : public OpWithChannel< - baidu::paddle_serving::predictor::echo_service::RequestAndResponse> { -public: +class CommonEchoOp + : public OpWithChannel< + baidu::paddle_serving::predictor::echo_service::RequestAndResponse> { + public: + typedef baidu::paddle_serving::predictor::echo_service::RequestAndResponse + RequestAndResponse; - typedef baidu::paddle_serving::predictor::echo_service::RequestAndResponse - RequestAndResponse; - - DECLARE_OP(CommonEchoOp); + DECLARE_OP(CommonEchoOp); - int inference() { - const RequestAndResponse* req = dynamic_cast( - get_request_message()); + int inference() { + const RequestAndResponse* req = + dynamic_cast(get_request_message()); - RequestAndResponse* data = mutable_data(); + RequestAndResponse* data = mutable_data(); - data->CopyFrom(*req); + data->CopyFrom(*req); - return 0; - } + return 0; + } }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/dense_echo_op.cpp b/serving/op/dense_echo_op.cpp index 505d17ea906bc1fa79ebba7bd7aa1df86f33baad..b63682aa6aafe33d1ee7723d3a8a3c02a9a0e149 100644 --- a/serving/op/dense_echo_op.cpp +++ b/serving/op/dense_echo_op.cpp @@ -1,3 +1,17 @@ +// 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 "op/dense_echo_op.h" namespace baidu { @@ -9,23 +23,20 @@ using baidu::paddle_serving::predictor::dense_service::Request; using baidu::paddle_serving::predictor::dense_service::Response; int DenseEchoOp::inference() { - const Request* req = - dynamic_cast(get_request_message()); - Response* res = mutable_data(); - LOG(INFO) << "Receive request in dense service:" - << req->ShortDebugString(); - uint32_t sample_size = req->instances_size(); - for (uint32_t si = 0; si < sample_size; si++) { - DensePrediction* dense_res = - res->mutable_predictions()->Add(); - dense_res->add_categories(100.0 + si * 0.1); - dense_res->add_categories(200.0 + si * 0.1); - } - return 0; + const Request* req = dynamic_cast(get_request_message()); + Response* res = mutable_data(); + LOG(INFO) << "Receive request in dense service:" << req->ShortDebugString(); + uint32_t sample_size = req->instances_size(); + for (uint32_t si = 0; si < sample_size; si++) { + DensePrediction* dense_res = res->mutable_predictions()->Add(); + dense_res->add_categories(100.0 + si * 0.1); + dense_res->add_categories(200.0 + si * 0.1); + } + return 0; } DEFINE_OP(DenseEchoOp); -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/dense_echo_op.h b/serving/op/dense_echo_op.h index addbb90b8731fa6653ad1a7951ce82a9b4d865dd..79f3d26eb8fe511f958254d2b490bfda91fb2937 100644 --- a/serving/op/dense_echo_op.h +++ b/serving/op/dense_echo_op.h @@ -1,28 +1,38 @@ -#ifndef BAIDU_PADDLE_SSERVER_PREDICTOR_OP_DENSE_ECHO_OP_H -#define BAIDU_PADDLE_SSERVER_PREDICTOR_OP_DENSE_ECHO_OP_H - -#include "dense_service.pb.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. + +#pragma once +#include "serving/dense_service.pb.h" #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { namespace predictor { -class DenseEchoOp : public OpWithChannel< - baidu::paddle_serving::predictor::dense_service::Response> { -public: +class DenseEchoOp + : public OpWithChannel< + baidu::paddle_serving::predictor::dense_service::Response> { + public: + DECLARE_OP(DenseEchoOp); - DECLARE_OP(DenseEchoOp); - - int inference(); + int inference(); }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/int64tensor_echo_op.cpp b/serving/op/int64tensor_echo_op.cpp index 5baf3cb079ec7149cea25fd61dbb7d73f9824cf6..b17bb03e186b6c21c46cbfa83e9620e302ccd016 100644 --- a/serving/op/int64tensor_echo_op.cpp +++ b/serving/op/int64tensor_echo_op.cpp @@ -1,3 +1,17 @@ +// 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 "op/int64tensor_echo_op.h" namespace baidu { @@ -9,25 +23,23 @@ using baidu::paddle_serving::predictor::int64tensor_service::Request; using baidu::paddle_serving::predictor::int64tensor_service::Response; int Int64TensorEchoOp::inference() { - const Request* req = - dynamic_cast(get_request_message()); - Response* res = mutable_data(); - LOG(INFO) << "Receive request in dense service:" - << req->ShortDebugString(); - uint32_t sample_size = req->instances_size(); - for (uint32_t si = 0; si < sample_size; si++) { - Float32TensorPredictor* float32_tensor_res = - res->mutable_predictions()->Add(); - float32_tensor_res->add_data(1.0); - float32_tensor_res->add_data(2.0); - float32_tensor_res->add_shape(2); - float32_tensor_res->add_shape(1); - } - return 0; + const Request* req = dynamic_cast(get_request_message()); + Response* res = mutable_data(); + LOG(INFO) << "Receive request in dense service:" << req->ShortDebugString(); + uint32_t sample_size = req->instances_size(); + for (uint32_t si = 0; si < sample_size; si++) { + Float32TensorPredictor* float32_tensor_res = + res->mutable_predictions()->Add(); + float32_tensor_res->add_data(1.0); + float32_tensor_res->add_data(2.0); + float32_tensor_res->add_shape(2); + float32_tensor_res->add_shape(1); + } + return 0; } DEFINE_OP(Int64TensorEchoOp); -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/int64tensor_echo_op.h b/serving/op/int64tensor_echo_op.h index 3df40c5b4da831013600c97c2b71b27f561271f1..4d238c178c4db732eef3e7dcba96a21594f8fb47 100644 --- a/serving/op/int64tensor_echo_op.h +++ b/serving/op/int64tensor_echo_op.h @@ -1,28 +1,38 @@ -#ifndef BAIDU_PADDLE_SSERVER_PREDICTOR_OP_DENSE_ECHO_OP_H -#define BAIDU_PADDLE_SSERVER_PREDICTOR_OP_DENSE_ECHO_OP_H - -#include "int64tensor_service.pb.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. + +#pragma once +#include "serving/int64tensor_service.pb.h" #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { namespace predictor { -class Int64TensorEchoOp : public OpWithChannel< - baidu::paddle_serving::predictor::int64tensor_service::Response> { -public: +class Int64TensorEchoOp + : public OpWithChannel< + baidu::paddle_serving::predictor::int64tensor_service::Response> { + public: + DECLARE_OP(Int64TensorEchoOp); - DECLARE_OP(Int64TensorEchoOp); - - int inference(); + int inference(); }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/reader_op.cpp b/serving/op/reader_op.cpp index cbe69b484bb3ed904235fded8676585dc53090d2..9f62c5143fe8394136519e17a5158c2d9aab1be7 100644 --- a/serving/op/reader_op.cpp +++ b/serving/op/reader_op.cpp @@ -1,4 +1,19 @@ +// 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 "op/reader_op.h" +#include #include "framework/memory.h" namespace baidu { @@ -10,140 +25,134 @@ using baidu::paddle_serving::predictor::format::XImageReqInstance; using baidu::paddle_serving::predictor::image_classification::Request; int ReaderOp::inference() { - const Request* req = - dynamic_cast(get_request_message()); - LOG(INFO) << "Receive request in dense service:" - << req->ShortDebugString(); - - ReaderOutput* res = mutable_data(); - if (!res) { - LOG(ERROR) << "Failed get op tls reader object output"; - return -1; + const Request* req = dynamic_cast(get_request_message()); + LOG(INFO) << "Receive request in dense service:" << req->ShortDebugString(); + + ReaderOutput* res = mutable_data(); + if (!res) { + LOG(ERROR) << "Failed get op tls reader object output"; + return -1; + } + + TensorVector* in = &res->tensors; + uint32_t sample_size = req->instances_size(); + if (sample_size <= 0) { + LOG(WARNING) << "No instances need to inference!"; + return -1; + } + + // TODO(xxx) pmeans/scales/isize/enable_crop should be configurable. + float pmean[3] = {0.485 * 255, 0.456 * 255, 0.406 * 255}; + float scale[3] = {1 / (0.229 * 255), 1 / (0.224 * 255), 1 / (0.225 * 255)}; + size_t iresize[] = {244, 244}; // row, column + bool enable_crop = true; + + cv::Size resize; + resize.height = iresize[0]; + resize.width = iresize[1]; + + for (uint32_t si = 0; si < sample_size; si++) { + // parse image object from x-image + const XImageReqInstance& ins = req->instances(si); + // read dense image from request bytes + const char* binary = ins.image_binary().c_str(); + size_t length = ins.image_length(); + if (length == 0) { + LOG(ERROR) << "Empty image, length is 0"; + return -1; } - TensorVector* in = &res->tensors; - uint32_t sample_size = req->instances_size(); - if (sample_size <= 0) { - LOG(WARNING) << "No instances need to inference!"; - return -1; + _image_vec_tmp.clear(); + _image_vec_tmp.assign(binary, binary + length); + _image_8u_tmp = cv::imdecode(cv::Mat(_image_vec_tmp), + CV_LOAD_IMAGE_COLOR /*1*/); // in B/G/R order. + if (_image_8u_tmp.data == NULL) { + LOG(ERROR) << "Image decode failed!"; + return -1; } - // TODO pmeans/scales/isize/enable_crop should be configurable. - float pmean[3] = {0.485 * 255, 0.456 * 255, 0.406 * 255}; - float scale[3] = { 1 / (0.229 * 255), 1 / (0.224 * 255), \ - 1 / (0.225 * 255)}; - size_t iresize[] = {244, 244}; // row, column - bool enable_crop = true; - - cv::Size resize; - resize.height = iresize[0]; - resize.width = iresize[1]; - - for (uint32_t si = 0; si < sample_size; si++) { - // parse image object from x-image - const XImageReqInstance& ins = req->instances(si); - // read dense image from request bytes - const char* binary = ins.image_binary().c_str(); - size_t length = ins.image_length(); - if (length == 0) { - LOG(ERROR) << "Empty image, length is 0"; - return -1; - } - - _image_vec_tmp.clear(); - _image_vec_tmp.assign(binary, binary + length); - _image_8u_tmp = cv::imdecode(cv::Mat(_image_vec_tmp), - CV_LOAD_IMAGE_COLOR/*1*/); // in B/G/R order. - if (_image_8u_tmp.data == NULL) { - LOG(ERROR) << "Image decode failed!"; - return -1; - } - - // accumulate length - const int HH = _image_8u_tmp.rows; - const int WW = _image_8u_tmp.cols; - const int CC = _image_8u_tmp.channels(); - - // resize/crop - if (_image_8u_tmp.cols != resize.width - || _image_8u_tmp.rows != resize.height) { - int short_egde = std::min( - _image_8u_tmp.cols, _image_8u_tmp.rows); - int yy = int((_image_8u_tmp.rows - short_egde) / 2); - int xx = int((_image_8u_tmp.cols - short_egde) / 2); - _image_8u_tmp = cv::Mat(_image_8u_tmp, - cv::Rect(xx, yy, short_egde, short_egde)); - if (_image_8u_tmp.cols != resize.width - || _image_8u_tmp.rows != resize.height) { - cv::Mat resize_image; - cv::resize(_image_8u_tmp, resize_image, resize); - _image_8u_tmp = resize_image; - } - - LOG(INFO) << "Succ crop one image[CHW=" - << _image_8u_tmp.channels() << ", " - << _image_8u_tmp.cols << ", " - << _image_8u_tmp.rows << "]" - << " from image[CHW=" << CC << ", " - << HH << ", " << WW << "]"; - } + // accumulate length + const int HH = _image_8u_tmp.rows; + const int WW = _image_8u_tmp.cols; + const int CC = _image_8u_tmp.channels(); + + // resize/crop + if (_image_8u_tmp.cols != resize.width || + _image_8u_tmp.rows != resize.height) { + int short_egde = std::min(_image_8u_tmp.cols, _image_8u_tmp.rows); + int yy = static_cast((_image_8u_tmp.rows - short_egde) / 2); + int xx = static_cast((_image_8u_tmp.cols - short_egde) / 2); + _image_8u_tmp = + cv::Mat(_image_8u_tmp, cv::Rect(xx, yy, short_egde, short_egde)); + if (_image_8u_tmp.cols != resize.width || + _image_8u_tmp.rows != resize.height) { + cv::Mat resize_image; + cv::resize(_image_8u_tmp, resize_image, resize); + _image_8u_tmp = resize_image; + } + + LOG(INFO) << "Succ crop one image[CHW=" << _image_8u_tmp.channels() + << ", " << _image_8u_tmp.cols << ", " << _image_8u_tmp.rows + << "]" + << " from image[CHW=" << CC << ", " << HH << ", " << WW << "]"; + } - // BGR->RGB transformer - cv::cvtColor(_image_8u_tmp, _image_8u_rgb, CV_BGR2RGB); - - const int H = _image_8u_rgb.rows; - const int W = _image_8u_rgb.cols; - const int C = _image_8u_rgb.channels(); - size_t dense_capacity = H * W * C; - - paddle::PaddleTensor in_tensor; - in_tensor.name = "tensor"; - in_tensor.dtype = paddle::FLOAT32; - - // shape assignment - in_tensor.shape.push_back(1); // batch_size - - // accoreding to training stage, the instance shape should be - // in order of C-W-H. - in_tensor.shape.push_back(C); - in_tensor.shape.push_back(W); - in_tensor.shape.push_back(H); - - LOG(INFO) << "Succ read one image, C: " << C - << ", W: " << W << ", H: " << H; - - // tls resource assignment - size_t len = dense_capacity * sizeof(float); - float* data = (float*) MempoolWrapper::instance().malloc(len); - if (data == NULL) { - LOG(ERROR) << "Failed create temp float array, " - << "size=" << dense_capacity; - return -1; - } + // BGR->RGB transformer + cv::cvtColor(_image_8u_tmp, _image_8u_rgb, CV_BGR2RGB); + + const int H = _image_8u_rgb.rows; + const int W = _image_8u_rgb.cols; + const int C = _image_8u_rgb.channels(); + size_t dense_capacity = H * W * C; + + paddle::PaddleTensor in_tensor; + in_tensor.name = "tensor"; + in_tensor.dtype = paddle::FLOAT32; + + // shape assignment + in_tensor.shape.push_back(1); // batch_size + + // accoreding to training stage, the instance shape should be + // in order of C-W-H. + in_tensor.shape.push_back(C); + in_tensor.shape.push_back(W); + in_tensor.shape.push_back(H); + + LOG(INFO) << "Succ read one image, C: " << C << ", W: " << W + << ", H: " << H; + + // tls resource assignment + size_t len = dense_capacity * sizeof(float); + float* data = + reinterpret_cast(MempoolWrapper::instance().malloc(len)); + if (data == NULL) { + LOG(ERROR) << "Failed create temp float array, " + << "size=" << dense_capacity; + return -1; + } - for (int h = 0; h < H; h++) { - // p points to a new line - unsigned char* p = _image_8u_rgb.ptr < unsigned char>(h); - for (int w = 0; w < W; w++) { - for (int c = 0; c < C; c++) { - // HWC(row,column,channel) -> CWH - data[W * H * c + W * h + w] = - (p[C * w + c] - pmean[c]) * scale[c]; - } - } + for (int h = 0; h < H; h++) { + // p points to a new line + unsigned char* p = _image_8u_rgb.ptr(h); + for (int w = 0; w < W; w++) { + for (int c = 0; c < C; c++) { + // HWC(row,column,channel) -> CWH + data[W * H * c + W * h + w] = (p[C * w + c] - pmean[c]) * scale[c]; } + } + } - paddle::PaddleBuf pbuf(data, len); - in_tensor.data = pbuf; + paddle::PaddleBuf pbuf(data, len); + in_tensor.data = pbuf; - in->push_back(in_tensor); - } + in->push_back(in_tensor); + } - return 0; + return 0; } DEFINE_OP(ReaderOp); -} // serving -} // paddle_serving -} // baidu +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/reader_op.h b/serving/op/reader_op.h index cb8de8abeaed6978400deabdfa21fee381565c3e..6ec6fd2bfb2f08dcb304ca3f328c3083d40af124 100644 --- a/serving/op/reader_op.h +++ b/serving/op/reader_op.h @@ -1,18 +1,32 @@ -#ifndef BAIDU_PADDLE_SERVING_SERVING_OP_READER_OP_H -#define BAIDU_PADDLE_SERVING_SERVING_OP_READER_OP_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 "builtin_format.pb.h" -#include "image_class.pb.h" +#pragma once +#include +#include #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" +#include "predictor/builtin_format.pb.h" +#include "serving/image_class.pb.h" // opencv #include "opencv/cv.h" -#include "opencv/highgui.h" -#include "opencv/cxcore.h" #include "opencv/cv.hpp" +#include "opencv/cxcore.h" +#include "opencv/highgui.h" #include "paddle/fluid/inference/paddle_inference_api.h" @@ -21,38 +35,34 @@ namespace paddle_serving { namespace serving { struct ReaderOutput { - std::vector tensors; - - void Clear() { - size_t tensor_count = tensors.size(); - for (size_t ti = 0; ti < tensor_count; ++ti) { - tensors[ti].shape.clear(); - } - tensors.clear(); - } + std::vector tensors; - std::string ShortDebugString() const { - return "Not implemented!"; + void Clear() { + size_t tensor_count = tensors.size(); + for (size_t ti = 0; ti < tensor_count; ++ti) { + tensors[ti].shape.clear(); } + tensors.clear(); + } + + std::string ShortDebugString() const { return "Not implemented!"; } }; -class ReaderOp : public baidu::paddle_serving::predictor::OpWithChannel< - ReaderOutput> { -public: - typedef std::vector TensorVector; +class ReaderOp + : public baidu::paddle_serving::predictor::OpWithChannel { + public: + typedef std::vector TensorVector; - DECLARE_OP(ReaderOp); + DECLARE_OP(ReaderOp); - int inference(); + int inference(); -private: - cv::Mat _image_8u_tmp; - cv::Mat _image_8u_rgb; - std::vector _image_vec_tmp; + private: + cv::Mat _image_8u_tmp; + cv::Mat _image_8u_rgb; + std::vector _image_vec_tmp; }; -} // serving -} // paddle_serving -} // baidu - -#endif +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/sparse_echo_op.cpp b/serving/op/sparse_echo_op.cpp index 25200d64432c414ab7e85ca1d2204ffb0c249493..dce79a39446ee58c6b01076675f7a3fe0723ff42 100644 --- a/serving/op/sparse_echo_op.cpp +++ b/serving/op/sparse_echo_op.cpp @@ -1,3 +1,17 @@ +// 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 "op/sparse_echo_op.h" namespace baidu { @@ -5,34 +19,30 @@ namespace paddle_serving { namespace predictor { int SparseEchoOp::inference() { - // Every op can obtain request message by: - // get_request_message() - const Request* req = - dynamic_cast(get_request_message()); - - // Each op can obtain self-writable-data by: - // mutable_data() - Response* res = mutable_data(); - - // You can get the channel/data of depended ops by: - // get/mutable_depend_argment() - // ... - - LOG(INFO) - << "Receive request in sparse service:" - << req->ShortDebugString(); - uint32_t sample_size = req->instances_size(); - for (uint32_t si = 0; si < sample_size; si++) { - SparsePrediction* sparse_res = - res->mutable_predictions()->Add(); - sparse_res->add_categories(100.0 + si * 0.1); - sparse_res->add_categories(200.0 + si * 0.1); - } - return 0; + // Every op can obtain request message by: + // get_request_message() + const Request* req = dynamic_cast(get_request_message()); + + // Each op can obtain self-writable-data by: + // mutable_data() + Response* res = mutable_data(); + + // You can get the channel/data of depended ops by: + // get/mutable_depend_argment() + // ... + + LOG(INFO) << "Receive request in sparse service:" << req->ShortDebugString(); + uint32_t sample_size = req->instances_size(); + for (uint32_t si = 0; si < sample_size; si++) { + SparsePrediction* sparse_res = res->mutable_predictions()->Add(); + sparse_res->add_categories(100.0 + si * 0.1); + sparse_res->add_categories(200.0 + si * 0.1); + } + return 0; } DEFINE_OP(SparseEchoOp); -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/sparse_echo_op.h b/serving/op/sparse_echo_op.h index 82c79fb4e17f3aa1a66e018c76914a9f375b24ca..0b210588ecc1204061528482d0ee2ab48b6698ad 100644 --- a/serving/op/sparse_echo_op.h +++ b/serving/op/sparse_echo_op.h @@ -1,33 +1,43 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_OP_SPARSE_ECHO_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_OP_SPARSE_ECHO_OP_H - -#include "sparse_service.pb.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. + +#pragma once +#include "serving/sparse_service.pb.h" #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" namespace baidu { namespace paddle_serving { namespace predictor { -class SparseEchoOp : public OpWithChannel< - baidu::paddle_serving::predictor::sparse_service::Response> { -public: +class SparseEchoOp + : public OpWithChannel< + baidu::paddle_serving::predictor::sparse_service::Response> { + public: + DECLARE_OP(SparseEchoOp); - DECLARE_OP(SparseEchoOp); + typedef baidu::paddle_serving::predictor::sparse_service::Request Request; + typedef baidu::paddle_serving::predictor::sparse_service::Response Response; + typedef baidu::paddle_serving::predictor::format::SparsePrediction + SparsePrediction; - typedef baidu::paddle_serving::predictor::sparse_service::Request Request; - typedef baidu::paddle_serving::predictor::sparse_service::Response Response; - typedef baidu::paddle_serving::predictor::format::SparsePrediction - SparsePrediction; - - int inference(); + int inference(); }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/write_json_op.cpp b/serving/op/write_json_op.cpp index 5f55e42385f1e44dd79dcfbba19ca04ffd8f7e54..423f5afeca2a1dccd7e1548c6fd45136c18ed74f 100644 --- a/serving/op/write_json_op.cpp +++ b/serving/op/write_json_op.cpp @@ -1,8 +1,23 @@ -#include "json2pb/pb_to_json.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 +#include +#include "json2pb/pb_to_json.h" -#include "op/write_json_op.h" #include "framework/memory.h" +#include "op/write_json_op.h" namespace baidu { namespace paddle_serving { @@ -13,48 +28,47 @@ using baidu::paddle_serving::predictor::image_classification::ClassifyResponse; using baidu::paddle_serving::predictor::image_classification::Response; int WriteJsonOp::inference() { - const ClassifyResponse* classify_out = - get_depend_argument("image_classify_op"); - if (!classify_out) { - LOG(ERROR) << "Failed mutable depended argument, op:" - << "image_classify_op"; - return -1; - } + const ClassifyResponse* classify_out = + get_depend_argument("image_classify_op"); + if (!classify_out) { + LOG(ERROR) << "Failed mutable depended argument, op:" + << "image_classify_op"; + return -1; + } - Response* res = mutable_data(); - if (!res) { - LOG(ERROR) << "Failed mutable output response in op:" - << "WriteJsonOp"; - return -1; - } + Response* res = mutable_data(); + if (!res) { + LOG(ERROR) << "Failed mutable output response in op:" + << "WriteJsonOp"; + return -1; + } - // transfer classify output message into json format - std::string err_string; - uint32_t sample_size = classify_out->predictions_size(); - for (uint32_t si = 0; si < sample_size; si++) { - XImageResInstance* ins = res->add_predictions(); - if (!ins) { - LOG(ERROR) << "Failed add one prediction ins"; - return -1; - } - std::string* text = ins->mutable_response_json(); - if (!json2pb::ProtoMessageToJson(classify_out->predictions(si), - text, &err_string)) { - LOG(ERROR) << "Failed convert message[" - << classify_out->predictions(si).ShortDebugString() - << "], err: " << err_string; - return -1; - } + // transfer classify output message into json format + std::string err_string; + uint32_t sample_size = classify_out->predictions_size(); + for (uint32_t si = 0; si < sample_size; si++) { + XImageResInstance* ins = res->add_predictions(); + if (!ins) { + LOG(ERROR) << "Failed add one prediction ins"; + return -1; + } + std::string* text = ins->mutable_response_json(); + if (!json2pb::ProtoMessageToJson( + classify_out->predictions(si), text, &err_string)) { + LOG(ERROR) << "Failed convert message[" + << classify_out->predictions(si).ShortDebugString() + << "], err: " << err_string; + return -1; } + } - LOG(INFO) << "Succ write json:" - << classify_out->ShortDebugString(); + LOG(INFO) << "Succ write json:" << classify_out->ShortDebugString(); - return 0; + return 0; } DEFINE_OP(WriteJsonOp); -} // predictor -} // paddle_serving -} // baidu +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/write_json_op.h b/serving/op/write_json_op.h index a65c2950dd938dfb93b5e43330ce14d177aeeb8e..6fbb2358593843563dcde19c3ee3cb9fd0987a52 100644 --- a/serving/op/write_json_op.h +++ b/serving/op/write_json_op.h @@ -1,28 +1,37 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_OP_WRITE_JSON_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_OP_WRITE_JSON_OP_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 "builtin_format.pb.h" -#include "image_class.pb.h" +#pragma once #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" +#include "serving/image_class.pb.h" namespace baidu { namespace paddle_serving { namespace predictor { -class WriteJsonOp : public OpWithChannel< - baidu::paddle_serving::predictor::image_classification::Response> { -public: +class WriteJsonOp + : public OpWithChannel< + baidu::paddle_serving::predictor::image_classification::Response> { + public: + DECLARE_OP(WriteJsonOp); - DECLARE_OP(WriteJsonOp); - - int inference(); + int inference(); }; -} // predictor -} // paddle_serving -} // baidu - -#endif +} // namespace predictor +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/write_op.cpp b/serving/op/write_op.cpp index a3cda27c09e0d48e016465c193b83b98d07f0447..7200070c208a90b714f8ef525aa8cee72ac12836 100644 --- a/serving/op/write_op.cpp +++ b/serving/op/write_op.cpp @@ -1,8 +1,23 @@ -#include "json2pb/pb_to_json.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 +#include +#include "json2pb/pb_to_json.h" -#include "op/write_op.h" #include "framework/memory.h" +#include "op/write_op.h" namespace baidu { namespace paddle_serving { @@ -13,48 +28,47 @@ using baidu::paddle_serving::predictor::image_classification::ClassifyResponse; using baidu::paddle_serving::predictor::image_classification::Response; int WriteOp::inference() { - const ClassifyResponse* classify_out = - get_depend_argument("image_classify_op"); - if (!classify_out) { - LOG(ERROR) << "Failed mutable depended argument, op:" - << "image_classify_op"; - return -1; - } + const ClassifyResponse* classify_out = + get_depend_argument("image_classify_op"); + if (!classify_out) { + LOG(ERROR) << "Failed mutable depended argument, op:" + << "image_classify_op"; + return -1; + } - Response* res = mutable_data(); - if (!res) { - LOG(ERROR) << "Failed mutable output response in op:" - << "WriteOp"; - return -1; - } + Response* res = mutable_data(); + if (!res) { + LOG(ERROR) << "Failed mutable output response in op:" + << "WriteOp"; + return -1; + } - // transfer classify output message into json format - std::string err_string; - uint32_t sample_size = classify_out->predictions_size(); - for (uint32_t si = 0; si < sample_size; si++) { - XImageResInstance* ins = res->add_predictions(); - if (!ins) { - LOG(ERROR) << "Failed add one prediction ins"; - return -1; - } - std::string* text = ins->mutable_response_json(); - if (!json2pb::ProtoMessageToJson(classify_out->predictions(si), - text, &err_string)) { - LOG(ERROR) << "Failed convert message[" - << classify_out->predictions(si).ShortDebugString() - << "], err: " << err_string; - return -1; - } + // transfer classify output message into json format + std::string err_string; + uint32_t sample_size = classify_out->predictions_size(); + for (uint32_t si = 0; si < sample_size; si++) { + XImageResInstance* ins = res->add_predictions(); + if (!ins) { + LOG(ERROR) << "Failed add one prediction ins"; + return -1; + } + std::string* text = ins->mutable_response_json(); + if (!json2pb::ProtoMessageToJson( + classify_out->predictions(si), text, &err_string)) { + LOG(ERROR) << "Failed convert message[" + << classify_out->predictions(si).ShortDebugString() + << "], err: " << err_string; + return -1; } + } - LOG(INFO) << "Succ write json:" - << classify_out->ShortDebugString(); + LOG(INFO) << "Succ write json:" << classify_out->ShortDebugString(); - return 0; + return 0; } DEFINE_OP(WriteOp); -} // predictor -} // paddle_serving -} // baidu +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/op/write_op.h b/serving/op/write_op.h index af2f04c5772ec46f3472a2419742e904d0f7dbb1..f46a29b72ccaaaf8958ae5a48702c47ad7161fae 100644 --- a/serving/op/write_op.h +++ b/serving/op/write_op.h @@ -1,28 +1,38 @@ -#ifndef BAIDU_PADDLE_SERVING_PREDICTOR_OP_WRITE_OP_H -#define BAIDU_PADDLE_SERVING_PREDICTOR_OP_WRITE_OP_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 "builtin_format.pb.h" -#include "image_class.pb.h" +#pragma once #include "common/inner_common.h" -#include "op/op.h" #include "framework/channel.h" #include "framework/op_repository.h" +#include "op/op.h" +#include "predictor/builtin_format.pb.h" +#include "serving/image_class.pb.h" namespace baidu { namespace paddle_serving { namespace serving { -class WriteOp : public baidu::paddle_serving::predictor::OpWithChannel< - baidu::paddle_serving::predictor::image_classification::Response> { -public: +class WriteOp + : public baidu::paddle_serving::predictor::OpWithChannel< + baidu::paddle_serving::predictor::image_classification::Response> { + public: + DECLARE_OP(WriteOp); - DECLARE_OP(WriteOp); - - int inference(); + int inference(); }; -} // serving -} // paddle_serving -} // baidu - -#endif +} // namespace serving +} // namespace paddle_serving +} // namespace baidu diff --git a/serving/proto/builtin_format.proto b/serving/proto/builtin_format.proto index 7683ec674e6406f55553089800213518a1259562..6666f6479393a4912ed23d02c24585a3caf6e1b0 100644 --- a/serving/proto/builtin_format.proto +++ b/serving/proto/builtin_format.proto @@ -1,15 +1,25 @@ -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"; import "pds_option.proto"; package baidu.paddle_serving.predictor.format; // dense format -message DenseInstance { - repeated float features = 1; -}; +message DenseInstance { repeated float features = 1; }; -message DensePrediction { - repeated float categories = 1; -}; +message DensePrediction { repeated float categories = 1; }; // sparse format message SparseInstance { @@ -18,9 +28,7 @@ message SparseInstance { repeated float values = 3; }; -message SparsePrediction { - repeated float categories = 1; -}; +message SparsePrediction { repeated float categories = 1; }; // int64-tensor format message Int64TensorInstance { @@ -39,9 +47,7 @@ message XImageReqInstance { required uint32 image_length = 2; }; -message XImageResInstance { - required string response_json = 1; -}; +message XImageResInstance { required string response_json = 1; }; // x-record format message XRecordInstance { diff --git a/serving/proto/dense_service.proto b/serving/proto/dense_service.proto index 5e031f1fb2d151129f028be0c9ecb1b187d179dd..617a79330dd65abbe14b46ecead591c53b2701c7 100644 --- a/serving/proto/dense_service.proto +++ b/serving/proto/dense_service.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.dense_service; @@ -10,7 +24,8 @@ message Request { }; message Response { - repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = 1; + repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = + 1; }; service BuiltinDenseFormatService { diff --git a/serving/proto/echo_service.proto b/serving/proto/echo_service.proto index 3956f42d014c17e4570baeb69309c38d1b5de53b..a91beced2a65c0153d123f2044b1b689d998c6e0 100644 --- a/serving/proto/echo_service.proto +++ b/serving/proto/echo_service.proto @@ -1,16 +1,30 @@ -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"; import "pds_option.proto"; package baidu.paddle_serving.predictor.echo_service; option cc_generic_services = true; message RequestAndResponse { - required int32 a = 1; - required float b = 2; + required int32 a = 1; + required float b = 2; }; service BuiltinTestEchoService { - rpc inference(RequestAndResponse) returns (RequestAndResponse); - rpc debug(RequestAndResponse) returns (RequestAndResponse); - option (pds.options).generate_impl = true; + rpc inference(RequestAndResponse) returns (RequestAndResponse); + rpc debug(RequestAndResponse) returns (RequestAndResponse); + option (pds.options).generate_impl = true; }; diff --git a/serving/proto/image_class.proto b/serving/proto/image_class.proto index 6d4216e75c3690a5ab748626e744a0249561510f..94e3863e04166594f664bfd614d36c7bcd67a137 100644 --- a/serving/proto/image_class.proto +++ b/serving/proto/image_class.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.image_classification; @@ -6,20 +20,23 @@ package baidu.paddle_serving.predictor.image_classification; option cc_generic_services = true; message ClassifyResponse { - repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = 1; + repeated baidu.paddle_serving.predictor.format.DensePrediction predictions = + 1; }; message Request { - repeated baidu.paddle_serving.predictor.format.XImageReqInstance instances = 1; + repeated baidu.paddle_serving.predictor.format.XImageReqInstance instances = + 1; }; message Response { - // Each json string is serialized from ClassifyResponse predictions - repeated baidu.paddle_serving.predictor.format.XImageResInstance predictions = 1; + // Each json string is serialized from ClassifyResponse predictions + repeated baidu.paddle_serving.predictor.format.XImageResInstance predictions = + 1; }; service ImageClassifyService { - rpc inference(Request) returns (Response); - rpc debug(Request) returns (Response); - option (pds.options).generate_impl = true; + rpc inference(Request) returns (Response); + rpc debug(Request) returns (Response); + option (pds.options).generate_impl = true; }; diff --git a/serving/proto/int64tensor_service.proto b/serving/proto/int64tensor_service.proto index e860f552f2c39605739e7d05fc6cac3fc2c0b8c9..1626ecaa4fba307a3410159f0fe212c7d7a2666b 100644 --- a/serving/proto/int64tensor_service.proto +++ b/serving/proto/int64tensor_service.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.int64tensor_service; @@ -6,12 +20,12 @@ package baidu.paddle_serving.predictor.int64tensor_service; option cc_generic_services = true; message Request { - repeated baidu.paddle_serving.predictor.format.Int64TensorInstance - instances = 1; + repeated baidu.paddle_serving.predictor.format.Int64TensorInstance instances = + 1; }; message Response { - repeated baidu.paddle_serving.predictor.format.Float32TensorPredictor + repeated baidu.paddle_serving.predictor.format.Float32TensorPredictor predictions = 1; }; diff --git a/serving/proto/native_tensor.proto b/serving/proto/native_tensor.proto index 043357d58a727ae7f91e1678b89e6bce666c152e..d8082086eea0513b2873116702d3b2ff762e6a9d 100644 --- a/serving/proto/native_tensor.proto +++ b/serving/proto/native_tensor.proto @@ -1,67 +1,73 @@ -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"; import "pds_option.proto"; package baidu.paddle_serving.predictor.native_tensor; option cc_generic_services = true; enum TensorType { - FLOAT = 0; - DOUBLE = 1; - INT32 = 2; - INT64 = 3; - UINT32 = 4; - UINT64 = 5; + FLOAT = 0; + DOUBLE = 1; + INT32 = 2; + INT64 = 3; + UINT32 = 4; + UINT64 = 5; }; message DenseTensor { - optional string name = 1; - repeated uint32 shape = 2; - required TensorType type = 3; - repeated float float_data = 4; - repeated double double_data = 5; - repeated int32 int32_data = 6; - repeated int64 int64_data = 7; - repeated uint32 uint32_data = 8; - repeated uint64 uint64_data = 9; + optional string name = 1; + repeated uint32 shape = 2; + required TensorType type = 3; + repeated float float_data = 4; + repeated double double_data = 5; + repeated int32 int32_data = 6; + repeated int64 int64_data = 7; + repeated uint32 uint32_data = 8; + repeated uint64 uint64_data = 9; }; -message DenseRequest { - repeated DenseTensor tensors = 1; -}; +message DenseRequest { repeated DenseTensor tensors = 1; }; -message DenseResponse { - repeated DenseTensor tensors = 1; -}; +message DenseResponse { repeated DenseTensor tensors = 1; }; service BuiltinDenseFormatService { - rpc inference(DenseRequest) returns (DenseResponse); - rpc debug(DenseRequest) returns (DenseResponse); - option (pds.options).generate_impl = true; + rpc inference(DenseRequest) returns (DenseResponse); + rpc debug(DenseRequest) returns (DenseResponse); + option (pds.options).generate_impl = true; }; message SparseTensor { - required string name = 1; - repeated uint32 keys = 2; - repeated uint32 shape = 3; - required TensorType type = 4; - repeated float float_data = 5; - repeated double double_data = 6; - repeated int32 int32_data = 7; - repeated int64 int64_data = 8; - repeated uint32 uint32_data = 9; - repeated uint64 uint64_data = 10; + required string name = 1; + repeated uint32 keys = 2; + repeated uint32 shape = 3; + required TensorType type = 4; + repeated float float_data = 5; + repeated double double_data = 6; + repeated int32 int32_data = 7; + repeated int64 int64_data = 8; + repeated uint32 uint32_data = 9; + repeated uint64 uint64_data = 10; }; -message SparseRequest { - repeated SparseTensor tensors = 1; -}; +message SparseRequest { repeated SparseTensor tensors = 1; }; -message SparseResponse { - repeated SparseTensor tensors = 1; -}; +message SparseResponse { repeated SparseTensor tensors = 1; }; service BuiltinSparseFormatService { - rpc inference(SparseRequest) returns (SparseResponse); - rpc debug(SparseRequest) returns (SparseResponse); - option (pds.options).generate_impl = true; + rpc inference(SparseRequest) returns (SparseResponse); + rpc debug(SparseRequest) returns (SparseResponse); + option (pds.options).generate_impl = true; }; diff --git a/serving/proto/pds_option.proto b/serving/proto/pds_option.proto index e6055c79e483f7f09c6067af42499fc475ac6048..c45c41ea8c5cd0f8378015c1abe575664ab61386 100644 --- a/serving/proto/pds_option.proto +++ b/serving/proto/pds_option.proto @@ -1,9 +1,23 @@ -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"; import "google/protobuf/descriptor.proto"; package pds; extend google.protobuf.FieldOptions { - optional bool pack_on = 70000 [default=false]; + optional bool pack_on = 70000 [ default = false ]; }; extend google.protobuf.ServiceOptions { @@ -11,6 +25,6 @@ extend google.protobuf.ServiceOptions { }; message PaddleServiceOption { - optional bool generate_impl = 1 [default = false]; - optional bool generate_stub = 2 [default = false]; + optional bool generate_impl = 1 [ default = false ]; + optional bool generate_stub = 2 [ default = false ]; }; diff --git a/serving/proto/sparse_service.proto b/serving/proto/sparse_service.proto index a631493c61de32f87da7650d8558bf6addde3379..288eb1137c50d12b8b2689eef9914f45632cb1f9 100644 --- a/serving/proto/sparse_service.proto +++ b/serving/proto/sparse_service.proto @@ -1,4 +1,18 @@ -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"; import "pds_option.proto"; import "builtin_format.proto"; package baidu.paddle_serving.predictor.sparse_service; @@ -6,11 +20,12 @@ package baidu.paddle_serving.predictor.sparse_service; option cc_generic_services = true; message Request { - repeated baidu.paddle_serving.predictor.format.SparseInstance instances = 1; + repeated baidu.paddle_serving.predictor.format.SparseInstance instances = 1; }; message Response { - repeated baidu.paddle_serving.predictor.format.SparsePrediction predictions = 1; + repeated baidu.paddle_serving.predictor.format.SparsePrediction predictions = + 1; }; service BuiltinSparseFormatService {