提交 e847c753 编写于 作者: W wangguibao

Elastic CTR

上级 aac13e10
......@@ -74,6 +74,8 @@ include(external/snappy)
include(external/gtest)
include(generic)
include(flags)
include(external/python)
include(external/pybind11)
if (NOT CLIENT_ONLY)
include(external/cudnn)
......
# Copyright (c) 2016 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(ExternalProject)
set(PYBIND_SOURCE_DIR ${THIRD_PARTY_PATH}/pybind)
include_directories(${PYBIND_SOURCE_DIR}/src/extern_pybind/include)
ExternalProject_Add(
extern_pybind
${EXTERNAL_PROJECT_LOG_ARGS}
GIT_REPOSITORY "https://github.com/pybind/pybind11.git"
GIT_TAG "v2.2.4"
PREFIX ${PYBIND_SOURCE_DIR}
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
if(${CMAKE_VERSION} VERSION_LESS "3.3.0")
set(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/pybind_dummy.c)
file(WRITE ${dummyfile} "const char * dummy_pybind = \"${dummyfile}\";")
add_library(pybind STATIC ${dummyfile})
else()
add_library(pybind INTERFACE)
endif()
add_dependencies(pybind extern_pybind)
# Copyright (c) 2016 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.
FIND_PACKAGE(PythonInterp ${PY_VERSION} REQUIRED)
FIND_PACKAGE(PythonLibs ${PY_VERSION} REQUIRED)
if(WIN32)
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
"from distutils import sysconfig as s;import sys;import struct;
print(sys.prefix);
print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));
"
RESULT_VARIABLE _PYTHON_SUCCESS
OUTPUT_VARIABLE _PYTHON_VALUES
ERROR_VARIABLE _PYTHON_ERROR_VALUE)
if(NOT _PYTHON_SUCCESS MATCHES 0)
set(PYTHONLIBS_FOUND FALSE)
return()
endif()
# Convert the process output into a list
string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
list(GET _PYTHON_VALUES 0 PYTHON_PREFIX)
list(GET _PYTHON_VALUES 1 PYTHON_LIBRARY_SUFFIX)
# Make sure all directory separators are '/'
string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
set(PYTHON_LIBRARY
"${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
# when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the
# original python installation. They may be found relative to PYTHON_INCLUDE_DIR.
if(NOT EXISTS "${PYTHON_LIBRARY}")
get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)
set(PYTHON_LIBRARY
"${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
endif()
# raise an error if the python libs are still not found.
if(NOT EXISTS "${PYTHON_LIBRARY}")
message(FATAL_ERROR "Python libraries not found")
endif()
SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
endif(WIN32)
# Fixme: Maybe find a static library. Get SHARED/STATIC by FIND_PACKAGE.
ADD_LIBRARY(python SHARED IMPORTED GLOBAL)
SET_PROPERTY(TARGET python PROPERTY IMPORTED_LOCATION ${PYTHON_LIBRARIES})
SET(py_env "")
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIR})
......@@ -4,13 +4,17 @@ file(GLOB sdk_cpp_srcs ${CMAKE_SOURCE_DIR}/sdk-cpp/src/*.cpp)
list(APPEND elasticctr_srcs ${elastic_ctr_cpp_srcs})
list(APPEND elasticctr_srcs ${sdk_cpp_srcs})
list(APPEND elasticctr_srcs
${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.cpp)
${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.cpp
${CMAKE_CURRENT_LIST_DIR}/api/pybind.cpp)
add_library(elasticctr SHARED ${elasticctr_srcs})
target_link_libraries(elasticctr brpc configure protobuf leveldb)
add_dependencies(elasticctr pybind)
target_link_libraries(elasticctr brpc configure protobuf leveldb -lcrypto
-lssl -lz)
add_executable(elastic_ctr_demo ${CMAKE_CURRENT_LIST_DIR}/demo/demo.cpp)
target_link_libraries(elastic_ctr_demo elasticctr -lpthread -lcrypto -lm -lrt -lssl -ldl -lz)
target_link_libraries(elastic_ctr_demo elasticctr python -lpthread -lcrypto -lm -lrt
-lssl -ldl -lz)
# install
install(TARGETS elastic_ctr_demo
......
......@@ -93,14 +93,14 @@ void ThreadResource::validate_request(const std::set<std::string> &slot_names) {
}
}
void ElasticCTRPredictorApi::read_slot_conf(const char *path,
const char *slot_conf_file) {
int ElasticCTRPredictorApi::read_slot_conf(const char *path,
const char *slot_conf_file) {
struct stat stat_buf;
char name[VARIABLE_NAME_LEN];
snprintf(name, VARIABLE_NAME_LEN, "%s/%s", path, slot_conf_file);
if (stat(name, &stat_buf) != 0) {
LOG(ERROR) << "Error stating file" << name;
return;
return -1;
}
std::ifstream fs(name);
......@@ -113,13 +113,22 @@ void ElasticCTRPredictorApi::read_slot_conf(const char *path,
LOG(INFO) << "slot: " << x.c_str();
}
#endif
return 0;
}
int ElasticCTRPredictorApi::init(const char *path,
const char *slot_conf_file,
const char *serving_conf_file) {
api_.create(path, serving_conf_file);
read_slot_conf(path, slot_conf_file);
int ret = api_.create(path, serving_conf_file);
if (ret != 0) {
return ret;
}
ret = read_slot_conf(path, slot_conf_file);
if (ret != 0) {
return ret;
}
// Thread-local storage
if (pthread_key_create(&tls_bspec_key_, thread_resource_delete) != 0) {
......@@ -231,7 +240,8 @@ void ElasticCTRPredictorApi::validate_request() {
thread_resource->validate_request(slot_names_);
}
int ElasticCTRPredictorApi::inference() {
int ElasticCTRPredictorApi::inference(
std::vector<std::vector<float>> &results_vec) {
ThreadResource *thread_resource =
reinterpret_cast<ThreadResource *>(pthread_getspecific(tls_bspec_key_));
if (thread_resource == NULL) {
......@@ -257,33 +267,19 @@ int ElasticCTRPredictorApi::inference() {
return ret;
}
return 0;
}
std::vector<Prediction> ElasticCTRPredictorApi::get_results() {
std::vector<Prediction> prediction_vec;
ThreadResource *thread_resource =
reinterpret_cast<ThreadResource *>(pthread_getspecific(tls_bspec_key_));
if (thread_resource == NULL) {
if (thread_resource == NULL) {
LOG(ERROR) << "ERROR: thread local resource is null";
return prediction_vec;
}
}
Response *response = thread_resource->get_response();
for (int i = 0; i < response->predictions_size(); ++i) {
const ResInstance &res_instance = response->predictions(i);
Prediction prediction;
prediction.prob0 = res_instance.prob0();
prediction.prob1 = res_instance.prob1();
prediction_vec.push_back(prediction);
std::vector<float> res;
res.push_back(res_instance.prob0());
res.push_back(res_instance.prob1());
results_vec.push_back(res);
}
return prediction_vec;
return 0;
}
} // namespace elastic_ctr
} // namespace paddle_serving
} // namespace baidu
......@@ -91,11 +91,10 @@ class ElasticCTRPredictorApi {
int add_slot(ReqInstance *instance,
const std::string slot_name,
int64_t value);
int inference();
std::vector<Prediction> get_results();
int inference(std::vector<std::vector<float>> &results_vec); // NOLINT
private:
static void read_slot_conf(const char *path, const char *slot_conf_file);
static int read_slot_conf(const char *path, const char *slot_conf_file);
void validate_request();
private:
......
/* 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 <Python.h>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <memory>
#include <mutex> // NOLINT // for call_once
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "elastic-ctr/client/api/elastic_ctr_api.h"
#include "pybind11/pybind11.h"
#include "pybind11/stl.h"
namespace baidu {
namespace paddle_serving {
namespace elastic_ctr {
namespace py = pybind11;
using baidu::paddle_serving::predictor::elastic_ctr::ReqInstance;
PYBIND11_MODULE(elasticctr, m) {
m.doc() = "C++ core of ElasticCTRPredictorApi";
py::class_<ReqInstance>(m, "ReqInstance", py::buffer_protocol())
.def(py::init<>());
py::class_<ElasticCTRPredictorApi>(
m, "ElasticCTRPredictorApi", py::buffer_protocol())
.def(py::init<>())
.def("init", &ElasticCTRPredictorApi::init)
.def("thrd_initialize", &ElasticCTRPredictorApi::thrd_initialize)
.def("thrd_clear", &ElasticCTRPredictorApi::thrd_clear)
.def("thrd_finalize", &ElasticCTRPredictorApi::thrd_finalize)
.def("destroy", &ElasticCTRPredictorApi::destroy)
.def("add_instance", &ElasticCTRPredictorApi::add_instance)
.def("add_slot", &ElasticCTRPredictorApi::add_slot)
.def("inference",
[](ElasticCTRPredictorApi &self) -> std::vector<std::vector<float>> {
std::vector<std::vector<float>> results_vec;
self.inference(results_vec);
return results_vec;
});
}
} // namespace elastic_ctr
} // namespace paddle_serving
} // namespace baidu
# 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.
def __bootstrap__():
"""
Returns:
None
"""
import sys
import os
import platform
from . import elasticctr
# 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.
import elasticctr
class ElasticCTRPredictorApi(object):
"""
A ElasticCTRPredictorApi Wrapper class
"""
def __init__(self):
self.api = elasticctr.ElasticCTRPredictorApi
print "Init OK"
def init(conf_dir, slot_conf_file, serving_conf_file):
self.api.init(conf_dir, slot_conf_file, serving_conf_file)
def thrd_initialize():
self.api.thrd_initialize()
def thrd_clear():
self.api.thrd_clear()
def destroy():
self.api.destroy()
def add_instance():
return self.api.add_instance()
def add_slot(instance, slot_name, value):
return self.api.add_slot(instance, slot_name, value)
def inference():
self.api.inferene()
def get_results():
return self.api.get_results()
......@@ -158,17 +158,16 @@ int main(int argc, char** argv) {
++index;
}
Response res;
if (api.inference() != 0) {
std::vector<std::vector<float>> results_vec;
if (api.inference(results_vec) != 0) {
LOG(ERROR) << "failed call predictor";
return -1;
}
std::vector<Prediction> ret = api.get_results();
#if 1
for (std::size_t i = 0; i < ret.size(); ++i) {
LOG(INFO) << "sample " << i << ": [" << ret[i].prob0 << ", "
<< ret[i].prob1 << "]";
for (std::size_t i = 0; i < results_vec.size(); ++i) {
LOG(INFO) << "sample " << i << ": [" << results_vec[i].at(0) << ", "
<< results_vec[i].at(1) << "]";
}
#endif
} // end while
......
# 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.
import os
import os.path
import sys
path = os.path.abspath(os.path.curdir) + '/../api'
print path
sys.path.append(path)
import lib
from lib import elasticctr
api = elasticctr.ElasticCTRPredictorApi()
ret = api.init("./conf", "slot.conf", "predictors.prototxt")
if ret != 0:
print "api.init fail"
sys.exit(-1)
api.thrd_initialize()
api.thrd_clear()
instance = api.add_instance()
api.add_slot(instance, "0", 1234)
api.add_slot(instance, "1", 1234)
api.add_slot(instance, "2", 1234)
api.add_slot(instance, "3", 1234)
api.add_slot(instance, "4", 1234)
api.add_slot(instance, "5", 1234)
api.add_slot(instance, "6", 1234)
ret = api.inference()
print ret
api.destroy()
engines {
name: "ctr_prediction"
name: "elastic_ctr_prediction"
type: "FLUID_CPU_ANALYSIS_DIR"
reloadable_meta: "./data/model/paddle/fluid_time_file"
reloadable_type: "timestamp_ne"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册