From 0daa634482107dddf7aa526c045ae716a797c8e3 Mon Sep 17 00:00:00 2001 From: wangguibao Date: Thu, 14 Nov 2019 17:20:20 +0800 Subject: [PATCH] Elastic CTR --- CMakeLists.txt | 5 -- cmake/external/pybind11.cmake | 42 ---------- cmake/external/python.cmake | 65 ---------------- elastic-ctr/client/CMakeLists.txt | 22 ++---- elastic-ctr/client/api/pybind.cpp | 61 --------------- .../client/api/python/elasticctr/__init__.py | 24 ------ .../api/python/elasticctr/elastic_ctr_api.py | 77 +++++++++++++++++++ .../api/python/elasticctr/elasticctr.py | 49 ------------ elastic-ctr/client/demo/demo.py | 50 ------------ elastic-ctr/client/demo/elastic_ctr.py | 50 ++++-------- 10 files changed, 98 insertions(+), 347 deletions(-) delete mode 100644 cmake/external/pybind11.cmake delete mode 100644 cmake/external/python.cmake delete mode 100644 elastic-ctr/client/api/pybind.cpp delete mode 100644 elastic-ctr/client/api/python/elasticctr/__init__.py create mode 100644 elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py delete mode 100644 elastic-ctr/client/api/python/elasticctr/elasticctr.py delete mode 100644 elastic-ctr/client/demo/demo.py diff --git a/CMakeLists.txt b/CMakeLists.txt index b736496d..dbccc024 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,11 +76,6 @@ include(external/gtest) include(generic) include(flags) -if(WITH_ELASTIC_CTR) -include(external/python) -include(external/pybind11) -endif() - if (NOT CLIENT_ONLY) include(external/cudnn) include(paddlepaddle) diff --git a/cmake/external/pybind11.cmake b/cmake/external/pybind11.cmake deleted file mode 100644 index a2dbf4cd..00000000 --- a/cmake/external/pybind11.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# 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) diff --git a/cmake/external/python.cmake b/cmake/external/python.cmake deleted file mode 100644 index 7679cd5f..00000000 --- a/cmake/external/python.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# 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}) diff --git a/elastic-ctr/client/CMakeLists.txt b/elastic-ctr/client/CMakeLists.txt index afba0587..c844b975 100644 --- a/elastic-ctr/client/CMakeLists.txt +++ b/elastic-ctr/client/CMakeLists.txt @@ -4,11 +4,9 @@ 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/pybind.cpp) + ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.cpp) add_library(elasticctr SHARED ${elasticctr_srcs}) -add_dependencies(elasticctr pybind) target_link_libraries(elasticctr brpc configure protobuf leveldb -lcrypto -lssl -lz -lrt) @@ -16,19 +14,15 @@ set_target_properties(elasticctr PROPERTIES INTERFACE_LINK_LIBRARIES "") add_executable(elastic_ctr_demo ${CMAKE_CURRENT_LIST_DIR}/demo/demo.cpp) set_target_properties(elastic_ctr_demo PROPERTIES LINK_LIBRARIES "") -target_link_libraries(elastic_ctr_demo elasticctr python -lpthread -lcrypto -lm -lrt +target_link_libraries(elastic_ctr_demo elasticctr -lpthread -lcrypto -lm -lrt -lssl -ldl -lz) -get_filename_component(PYTHON_LIBRARY_REAL_PATH ${PYTHON_LIBRARY} REALPATH) - # install install(TARGETS elasticctr elastic_ctr_demo RUNTIME DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin LIBRARY DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) -install(FILES ${PYTHON_LIBRARY_REAL_PATH} - DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/conf DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION @@ -37,9 +31,6 @@ install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/demo/data/ctr_prediction DESTINATION install(TARGETS elasticctr LIBRARY DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib) -install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink -${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib/libelasticctr.so -${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib/elasticctr.so)") install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/elastic_ctr_api.h DESTINATION @@ -76,11 +67,12 @@ install(DIRECTORY ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/include) # Python client API -install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/__init__.py - ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elasticctr.py +install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elastic_ctr_api.py DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/api/lib) -install(FILES ${CMAKE_CURRENT_LIST_DIR}/demo/demo.py - DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/api/python/elasticctr/elastic_ctr_api.py + DESTINATION + ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) install(FILES ${CMAKE_CURRENT_LIST_DIR}/demo/elastic_ctr.py DESTINATION ${PADDLE_SERVING_INSTALL_DIR}/elastic_ctr/client/bin) diff --git a/elastic-ctr/client/api/pybind.cpp b/elastic-ctr/client/api/pybind.cpp deleted file mode 100644 index b0f71eaf..00000000 --- a/elastic-ctr/client/api/pybind.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ -#include -#include -#include -#include -#include -#include // NOLINT // for call_once -#include -#include -#include -#include -#include -#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_(m, "ReqInstance", py::buffer_protocol()) - .def(py::init<>()); - - py::class_( - 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> results_vec; - self.inference(results_vec); - return results_vec; - }); -} -} // namespace elastic_ctr -} // namespace paddle_serving -} // namespace baidu diff --git a/elastic-ctr/client/api/python/elasticctr/__init__.py b/elastic-ctr/client/api/python/elasticctr/__init__.py deleted file mode 100644 index 1dd9525a..00000000 --- a/elastic-ctr/client/api/python/elasticctr/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -def __bootstrap__(): - """ - Returns: - None - """ - import sys - import os - import platform - from . import elasticctr diff --git a/elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py b/elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py new file mode 100644 index 00000000..5591cfd8 --- /dev/null +++ b/elastic-ctr/client/api/python/elasticctr/elastic_ctr_api.py @@ -0,0 +1,77 @@ +# 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 json +import httplib +import sys +import os + + +class ElasticCTRAPI(object): + def __init__(self, serving_ip, serving_port): + self._instances = [] + self._slots = [] + self._conn = self.conn(serving_ip, serving_port) + + def read_slots_conf(self, slots_conf_file): + if not os.path.exists(slots_conf_file): + print "Path %s not exist" % sltos_conf_file + return -1 + with open(slots_conf_file, "r") as f: + for line in f: + self._slots.append(line.rstrip('\n')) + return 0 + + def conn(self, ip, port): + return httplib.HTTPConnection(ip, port) + + def add_instance(self): + feature_slots = [] + instance = [{"slots": feature_slots}] + self._instances += instance + return instance + + def add_slot(self, instance, slot, feasigns): + if not isinstance(instance, list): + print "add slot: parameter invalid: instance should be list" + return -1 + + if not isinstance(feasigns, list): + print "add slot: value format invalid: feasigns should be list" + return -1 + + kv = [{"slot_name": slot, "feasigns": feasigns}] + instance[0]["slots"] += kv + + def inference(self): + for instance in self._instances: + feature_slots = instance["slots"] + keys = [] + for x in feature_slots: + keys += [x["slot_name"]] + for slot in self._slots: + if not slot in keys: + feature_slots += [{"slot_name": slot, "feasigns": [0]}] + req = {"instances": self._instances} + + request_json = json.dumps(req) + + try: + self._conn.request('POST', "/ElasticCTRPredictionService/inference", + request_json, + {"Content-Type": "application/json"}) + response = self._conn.getresponse() + return response.read() + except httplib.HTTPException as e: + print e.reason diff --git a/elastic-ctr/client/api/python/elasticctr/elasticctr.py b/elastic-ctr/client/api/python/elasticctr/elasticctr.py deleted file mode 100644 index 5e6b44f3..00000000 --- a/elastic-ctr/client/api/python/elasticctr/elasticctr.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -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() diff --git a/elastic-ctr/client/demo/demo.py b/elastic-ctr/client/demo/demo.py deleted file mode 100644 index ca2e8788..00000000 --- a/elastic-ctr/client/demo/demo.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -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() diff --git a/elastic-ctr/client/demo/elastic_ctr.py b/elastic-ctr/client/demo/elastic_ctr.py index 6325599c..dc093033 100644 --- a/elastic-ctr/client/demo/elastic_ctr.py +++ b/elastic-ctr/client/demo/elastic_ctr.py @@ -17,6 +17,8 @@ import httplib import sys import os +from elastic_ctr_api import ElasticCTRAPI + BATCH_SIZE = 3 SERVING_IP = "127.0.0.1" SLOT_CONF_FILE = "./conf/slot.conf" @@ -53,60 +55,36 @@ def data_reader(data_file, samples, labels): samples.append(sample) -def read_slots_conf(slots_conf_file, slots): - if not os.path.exists(slots_conf_file): - print "Path %s not exist" % sltos_conf_file - return -1 - with open(slots_conf_file, "r") as f: - for line in f: - slots.append(line.rstrip('\n')) - print slots - return 0 - - if __name__ == "__main__": """ main """ - if len(sys.argv) != 4: - print "Usage: python elastic_ctr.py SERVING_IP SLOT_CONF_FILE DATA_FILE" + if len(sys.argv) != 5: + print "Usage: python elastic_ctr.py SERVING_IP SERVING_PORT SLOT_CONF_FILE DATA_FILE" sys.exit(-1) samples = [] labels = [] SERVING_IP = sys.argv[1] - SLOT_CONF_FILE = sys.argv[2] + SERVING_PORT = sys.argv[2] + SLOT_CONF_FILE = sys.argv[3] - ret = read_slots_conf(SLOT_CONF_FILE, SLOTS) + api = ElasticCTRAPI(SERVING_IP, SERVING_PORT) + ret = api.read_slots_conf(SLOT_CONF_FILE) if ret != 0: sys.exit(-1) - print SLOTS - - ret = data_reader(sys.argv[3], samples, labels) - conn = httplib.HTTPConnection(SERVING_IP, 8010) + ret = data_reader(sys.argv[4], samples, labels) for i in range(0, len(samples) - BATCH_SIZE, BATCH_SIZE): batch = samples[i:i + BATCH_SIZE] instances = [] for sample in batch: - instance = [] + instance = api.add_instance() kv = [] for k, v in sample.iteritems(): - kv += [{"slot_name": k, "feasigns": v}] - print kv - instance = [{"slots": kv}] - instances += instance - req = {"instances": instances} - - request_json = json.dumps(req) - print request_json - - try: - conn.request('POST', "/ElasticCTRPredictionService/inference", - request_json, {"Content-Type": "application/json"}) - response = conn.getresponse() - print response.read() - except httplib.HTTPException as e: - print e.reason + api.add_slot(instance, k, v) + + ret = api.inference() + print ret sys.exit(0) -- GitLab