From 962061f0a30da33a22999654ee872faa766a7f76 Mon Sep 17 00:00:00 2001 From: dzhwinter Date: Mon, 15 Oct 2018 19:08:10 +0800 Subject: [PATCH] windows fix --- cmake/cudnn.cmake | 2 +- cmake/generic.cmake | 2 +- paddle/fluid/framework/executor.cc | 19 +- paddle/fluid/inference/api/api_impl.cc | 15 +- .../inference/api/demo_ci/inference_icnet.cc | 379 +++++++++--------- .../inference/api/demo_ci/naive_model_test.cc | 97 +++++ .../api/demo_ci/simple_on_word2vec.cc | 1 + 7 files changed, 324 insertions(+), 191 deletions(-) create mode 100644 paddle/fluid/inference/api/demo_ci/naive_model_test.cc diff --git a/cmake/cudnn.cmake b/cmake/cudnn.cmake index 6c72f4ea583..813611b032f 100644 --- a/cmake/cudnn.cmake +++ b/cmake/cudnn.cmake @@ -82,7 +82,7 @@ if(CUDNN_FOUND) if(NOT CUDNN_MAJOR_VERSION) set(CUDNN_VERSION "???") - else() + else() math(EXPR CUDNN_VERSION "${CUDNN_MAJOR_VERSION} * 1000 + ${CUDNN_MINOR_VERSION} * 100 + ${CUDNN_PATCHLEVEL_VERSION}") diff --git a/cmake/generic.cmake b/cmake/generic.cmake index 0bb01a61b91..1080365f0c4 100644 --- a/cmake/generic.cmake +++ b/cmake/generic.cmake @@ -243,7 +243,7 @@ function(cc_library TARGET_NAME) # add libxxx.lib prefix in windows set(${TARGET_NAME}_LIB_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}${TARGET_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE STRING "output library name for target ${TARGET_NAME}") endif(WIN32) - message("flags" ${CMAKE_CXX_FLAGS}) + if(cc_library_SRCS) if(cc_library_SHARED OR cc_library_shared) # build *.so add_library(${TARGET_NAME} SHARED ${cc_library_SRCS}) diff --git a/paddle/fluid/framework/executor.cc b/paddle/fluid/framework/executor.cc index dad170ed78c..1101707f804 100644 --- a/paddle/fluid/framework/executor.cc +++ b/paddle/fluid/framework/executor.cc @@ -293,26 +293,41 @@ void Executor::Run(const ProgramDesc& program, Scope* scope, std::unique_ptr Executor::Prepare( const ProgramDesc& program, int block_id) { + VLOG(3) << "before create prepare" << block_id << " " << program.Size(); std::unique_ptr ctx( new ExecutorPrepareContext(program, block_id)); - PADDLE_ENFORCE_LT(static_cast(block_id), program.Size()); + VLOG(3) << "after create prepare"; + // PADDLE_ENFORCE_LT(static_cast(block_id), program.Size()); + VLOG(3) << "before create op_desc"; auto& block = program.Block(block_id); + VLOG(3) << "create before" << ctx->ops_.size() << " " << block.AllOps().size(); + int counter = 0; for (auto& op_desc : block.AllOps()) { ctx->ops_.push_back(OpRegistry::CreateOp(*op_desc)); + VLOG(3) << "create op " << "index " << ++counter << " type " << op_desc->Type(); } + VLOG(3) << "create finished" << ctx->ops_.size() << " " << block.AllOps().size(); return ctx; } std::vector> Executor::Prepare( const ProgramDesc& program, const std::vector& block_ids) { + VLOG(3) << "inside prepare"; std::vector> result; + VLOG(3) << "before go through block_ids"; for (auto& bid : block_ids) { + VLOG(3) << "block id" << bid; auto* ctx = new ExecutorPrepareContext(program, bid); - PADDLE_ENFORCE_LT(static_cast(bid), program.Size()); + //PADDLE_ENFORCE_LT(static_cast(bid), program.Size()); auto& block = program.Block(bid); + int counter = 0; + VLOG(3) << "create before" << ctx->ops_.size() << " " << block.AllOps().size(); for (auto& op_desc : block.AllOps()) { + ctx->ops_.push_back(OpRegistry::CreateOp(*op_desc)); + VLOG(3) << "create op " << "index " << ++counter << " type " << op_desc->Type(); } + VLOG(3) << "create finished" << ctx->ops_.size() << " " << block.AllOps().size(); result.push_back(std::shared_ptr(ctx)); } return result; diff --git a/paddle/fluid/inference/api/api_impl.cc b/paddle/fluid/inference/api/api_impl.cc index 2dae4338810..0ed9bab2464 100644 --- a/paddle/fluid/inference/api/api_impl.cc +++ b/paddle/fluid/inference/api/api_impl.cc @@ -88,12 +88,16 @@ bool NativePaddlePredictor::Init( VLOG(3) << config_.model_dir; inference_program_ = paddle::inference::Load(executor_.get(), scope_.get(), config_.model_dir); - VLOG(3) << "load model Finish"; + VLOG(3) << "load model finish"; } else if (!config_.prog_file.empty() && !config_.param_file.empty()) { // All parameters are saved in a single file. // The file names should be consistent with that used // in Python API `fluid.io.save_inference_model`. - VLOG(3) << "load program"; + VLOG(3) << "load program before"; + auto exe = executor_.get(); + VLOG(3) << "executor_"; + auto sc = scope_.get(); + VLOG(3) << "scope_"; inference_program_ = paddle::inference::Load( executor_.get(), scope_.get(), config_.prog_file, config_.param_file); VLOG(3) << "load program finish"; @@ -101,13 +105,18 @@ bool NativePaddlePredictor::Init( LOG(ERROR) << "fail to load inference model."; return false; } - VLOG(3) << "prepare"; + VLOG(3) << "pointer" << inference_program_.get(); + + VLOG(3) << "prepare before"; ctx_ = executor_->Prepare(*inference_program_, 0); + VLOG(3) << "prepare finished"; executor_->CreateVariables(*inference_program_, sub_scope_ ? sub_scope_ : scope_.get(), 0); + VLOG(3) << "create variables"; // Get the feed_target_names and fetch_target_names PrepareFeedFetch(); + VLOG(3) << "feed fetch"; return true; } diff --git a/paddle/fluid/inference/api/demo_ci/inference_icnet.cc b/paddle/fluid/inference/api/demo_ci/inference_icnet.cc index e6040fb333f..f7c199d0d10 100644 --- a/paddle/fluid/inference/api/demo_ci/inference_icnet.cc +++ b/paddle/fluid/inference/api/demo_ci/inference_icnet.cc @@ -29,17 +29,18 @@ limitations under the License. */ #include "paddle/fluid/inference/paddle_inference_api.h" std::string MODELDIR = ""; /* "Directory of the inference model." */ // NOLINT -std::string REFER = ""; /*"path to reference result for comparison."*/ //NOTLINT +std::string REFER = ""; +/*"path to reference result for comparison."*/ //NOTLINT /*path of data; each line is a record, format: \t Please check the demo data of data.txt for details. */ std::string DATA = ""; -bool USE_GPU = false; /*"Whether use gpu."*/ +bool USE_GPU = true; /*"Whether use gpu."*/ - -auto message_err = []() { +auto message_err = []() +{ std::cout << "Copyright (c) 2018 PaddlePaddle Authors." << std::endl; std::cout << "Demo Case for windows inference. " << "\n" @@ -49,187 +50,197 @@ auto message_err = []() { std::cout << std::endl; }; - -namespace paddle { -namespace demo { - -void split(const std::string& str, char sep, - std::vector* pieces) { - pieces->clear(); - if (str.empty()) { - return; - } - size_t pos = 0; - size_t next = str.find(sep, pos); - while (next != std::string::npos) { - pieces->push_back(str.substr(pos, next - pos)); - pos = next + 1; - next = str.find(sep, pos); - } - if (!str.substr(pos).empty()) { - pieces->push_back(str.substr(pos)); - } -} - -/* - * Get a summary of a PaddleTensor content. - */ -std::string SummaryTensor(const PaddleTensor& tensor) { - std::stringstream ss; - int num_elems = tensor.data.length() / PaddleDtypeSize(tensor.dtype); - - ss << "data[:10]\t"; - switch (tensor.dtype) { - case PaddleDType::INT64: { - for (int i = 0; i < std::min(num_elems, 10); i++) { - ss << static_cast(tensor.data.data())[i] << " "; - } - break; - } - case PaddleDType::FLOAT32: - for (int i = 0; i < std::min(num_elems, 10); i++) { - ss << static_cast(tensor.data.data())[i] << " "; - } - break; - } - return ss.str(); -} - -std::string ToString(const NativeConfig& config) { - std::stringstream ss; - ss << "Use GPU : " << (config.use_gpu ? "True" : "False") << "\n" - << "Device : " << config.device << "\n" - << "fraction_of_gpu_memory : " << config.fraction_of_gpu_memory << "\n" - << "specify_input_name : " - << (config.specify_input_name ? "True" : "False") << "\n" - << "Program File : " << config.prog_file << "\n" - << "Param File : " << config.param_file; - return ss.str(); -} - -struct Record { - std::vector data; - std::vector shape; -}; - - -Record ProcessALine(const std::string& line) { - std::cout << "process a line" << std::endl;; - std::vector columns; - split(line, '\t', &columns); - assert(columns.size() == 2UL, - "data format error, should be \t"); - - Record record; - std::vector data_strs; - split(columns[0], ' ', &data_strs); - for (auto& d : data_strs) { - record.data.push_back(std::stof(d)); - } - - std::vector shape_strs; - split(columns[1], ' ', &shape_strs); - for (auto& s : shape_strs) { - record.shape.push_back(std::stoi(s)); - } - std::cout << "data size " << record.data.size() << std::endl; - std::cout << "data shape size " << record.shape.size() << std::endl; - return record; -} - -void CheckOutput(const std::string& referfile, const PaddleTensor& output) { - std::string line; - std::ifstream file(referfile); - std::getline(file, line); - auto refer = ProcessALine(line); - file.close(); - - size_t numel = output.data.length() / PaddleDtypeSize(output.dtype); - std::cout << "predictor output numel " << numel << std::endl; - std::cout << "reference output numel " << refer.data.size() << std::endl; - assert(numel == refer.data.size()); - switch (output.dtype) { - case PaddleDType::INT64: { - for (size_t i = 0; i < numel; ++i) { - assert(static_cast(output.data.data())[i] == - refer.data[i]); - } - break; - } - case PaddleDType::FLOAT32: - for (size_t i = 0; i < numel; ++i) { - assert( - fabs(static_cast(output.data.data())[i] - refer.data[i]) <= - 1e-5); - } - break; - } -} - -/* - * Use the native fluid engine to inference the demo. - */ -void Main(bool use_gpu) { - NativeConfig config; - config.param_file = MODELDIR + "/__params__"; - config.prog_file = MODELDIR + "/__model__"; - config.use_gpu = USE_GPU; - config.device = 0; - if (USE_GPU) { - config.fraction_of_gpu_memory = 0.1f; // set by yourself - } - std::cout << ToString(config) << std::endl; - std::cout << "init predictor" << std::endl; - auto predictor = - CreatePaddlePredictor(config); - - std::cout << "begin to process data" << std::endl; - // Just a single batch of data. - std::string line; - std::cout << "data : " << std::endl; - std::ifstream file(DATA); - if(!file.is_open()) { - std::cout << "failed open data" << DATA << std::endl; - exit(0); - } - std::getline(file, line); - auto record = ProcessALine(line); - file.close(); - - // Inference. - PaddleTensor input; - input.shape = record.shape; - input.data = - PaddleBuf(record.data.data(), record.data.size() * sizeof(float)); - input.dtype = PaddleDType::FLOAT32; - - std::cout << "run executor" << std::endl; - std::vector output; - predictor->Run({input}, &output); - - std::cout << "output.size " << output.size() << std::endl; - auto& tensor = output.front(); - std::cout << "output: " << SummaryTensor(tensor) << std::endl; - - // compare with reference result - std::cout << "refer result : " << REFER << std::endl; - CheckOutput(REFER, tensor); +namespace paddle +{ + namespace demo + { + void split(const std::string& str, char sep, + std::vector* pieces) + { + pieces->clear(); + if (str.empty()) + { + return; + } + size_t pos = 0; + size_t next = str.find(sep, pos); + while (next != std::string::npos) + { + pieces->push_back(str.substr(pos, next - pos)); + pos = next + 1; + next = str.find(sep, pos); + } + if (!str.substr(pos).empty()) + { + pieces->push_back(str.substr(pos)); + } + } + + /* + * Get a summary of a PaddleTensor content. + */ + std::string SummaryTensor(const PaddleTensor& tensor) + { + std::stringstream ss; + int num_elems = tensor.data.length() / PaddleDtypeSize(tensor.dtype); + + ss << "data[:10]\t"; + switch (tensor.dtype) + { + case PaddleDType::INT64: + for (int i = 0; i < std::min(num_elems, 10); i++) + { + ss << static_cast(tensor.data.data())[i] << " "; + } + break; + case PaddleDType::FLOAT32: + for (int i = 0; i < std::min(num_elems, 10); i++) + { + ss << static_cast(tensor.data.data())[i] << " "; + } + break; + } + return ss.str(); + } + + std::string ToString(const NativeConfig& config) + { + std::stringstream ss; + ss << "Use GPU : " << (config.use_gpu ? "True" : "False") << "\n" + << "Device : " << config.device << "\n" + << "fraction_of_gpu_memory : " << config.fraction_of_gpu_memory << "\n" + << "specify_input_name : " + << (config.specify_input_name ? "True" : "False") << "\n" + << "Program File : " << config.prog_file << "\n" + << "Param File : " << config.param_file; + return ss.str(); + } + + struct Record + { + std::vector data; + std::vector shape; + }; + + Record ProcessALine(const std::string& line) + { + std::cout << "process a line" << std::endl; + std::vector columns; + split(line, '\t', &columns); + assert(columns.size() == 2UL, "data format error, should be \t"); + + Record record; + std::vector data_strs; + split(columns[0], ' ', &data_strs); + //将数据字符串转换为整型数据并放到record.data中 + for (auto& d : data_strs) + { + record.data.push_back(std::stof(d)); + } + + std::vector shape_strs; + split(columns[1], ' ', &shape_strs); + for (auto& s : shape_strs) + { + record.shape.push_back(std::stoi(s)); + } + std::cout << "data size " << record.data.size() << std::endl; + std::cout << "data shape size " << record.shape.size() << std::endl; + return record; + } + + void CheckOutput(const std::string& referfile, const PaddleTensor& output) + { + std::string line; + std::ifstream file(referfile); + std::getline(file, line); + auto refer = ProcessALine(line); + file.close(); + + size_t numel = output.data.length() / PaddleDtypeSize(output.dtype); + std::cout << "predictor output numel " << numel << std::endl; + std::cout << "reference output numel " << refer.data.size() << std::endl; + assert(numel == refer.data.size()); + switch (output.dtype) + { + case PaddleDType::INT64: + for (size_t i = 0; i < numel; ++i) + { + assert(static_cast(output.data.data())[i] == refer.data[i]); + } + break; + case PaddleDType::FLOAT32: + for (size_t i = 0; i < numel; ++i) + { + assert(fabs(static_cast(output.data.data())[i] - refer.data[i]) <= 1e-5); + } + break; + } + } + + /* + * Use the native fluid engine to inference the demo. + */ + void Main(bool use_gpu) + { + NativeConfig config; + config.model_dir = MODELDIR; + //config.param_file = MODELDIR + "/__params__"; + //config.prog_file = MODELDIR + "/__model__"; + config.use_gpu = USE_GPU; + config.device = 0; + if (USE_GPU) + { + config.fraction_of_gpu_memory = 0.1f; // set by yourself + } + std::cout << ToString(config) << std::endl; + std::cout << "init predictor" << std::endl; + auto predictor = CreatePaddlePredictor(config); + + std::cout << "begin to process data" << std::endl; + // Just a single batch of data. + std::string line; + std::cout << "data : " << std::endl; + std::ifstream file(DATA); + if (!file.is_open()) + { + std::cout << "failed open data" << DATA << std::endl; + exit(0); + } + std::getline(file, line); + auto record = ProcessALine(line); + file.close(); + + // Inference. + PaddleTensor input; + input.shape = record.shape; + input.data = + PaddleBuf(record.data.data(), record.data.size() * sizeof(float)); + input.dtype = PaddleDType::FLOAT32; + + std::cout << "run executor" << std::endl; + std::vector output; + predictor->Run({ input }, &output); + + std::cout << "output.size " << output.size() << std::endl; + auto& tensor = output.front(); + std::cout << "output: " << SummaryTensor(tensor) << std::endl; + + // compare with reference result + std::cout << "refer result : " << REFER << std::endl; + CheckOutput(REFER, tensor); + } + } } +int main(int argc, char** argv) +{ + MODELDIR = "./LB_icnet_model"; + //DATA = "./icnet_image.txt"; + DATA = "./1.png.txt"; + REFER = "./icnet_label.txt"; + paddle::demo::Main(USE_GPU); -} // namespace demo -} // namespace paddle - -int main(int argc, char** argv) { - // ParseArgs(); - MODELDIR = "./mobilenet/model"; - DATA = "./mobilenet/data.txt"; - REFER = "./mobilenet/result.txt"; - USE_GPU = true; - paddle::demo::Main(false /* USE_GPU*/); - if (USE_GPU) { - paddle::demo::Main(true /*USE_GPU*/); - } - system("pause"); - return 0; + system("pause"); + return 0; } diff --git a/paddle/fluid/inference/api/demo_ci/naive_model_test.cc b/paddle/fluid/inference/api/demo_ci/naive_model_test.cc new file mode 100644 index 00000000000..6e6e1aa7b40 --- /dev/null +++ b/paddle/fluid/inference/api/demo_ci/naive_model_test.cc @@ -0,0 +1,97 @@ +// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include "paddle/fluid/inference/api/paddle_inference_api.h" + +namespace paddle { + +std::string DIRNAME = "./LB_icnet_model"; +//std::string DIRNAME = "./infer_models"; +NativeConfig GetConfig() { + NativeConfig config; + config.prog_file=DIRNAME + "/__model__"; + config.param_file=DIRNAME + "/__params__"; + config.fraction_of_gpu_memory = 0.8; + config.use_gpu = true; + config.device = 0; + return config; +} + +using Time = decltype(std::chrono::high_resolution_clock::now()); +Time time() { return std::chrono::high_resolution_clock::now(); }; +double time_diff(Time t1, Time t2) { + typedef std::chrono::microseconds ms; + auto diff = t2 - t1; + ms counter = std::chrono::duration_cast(diff); + return counter.count() / 1000.0; +} + +void test_naive(int batch_size){ + NativeConfig config = GetConfig(); + // config.model_dir = model_path; + auto predictor = CreatePaddlePredictor(config); + int height = 449; + int width = 581; + //int height = 3; + //int width = 3; + int num_sum = height * width * 3 * batch_size; + + std::vector data; + + for(int i = 0; i < num_sum; i++) { + data.push_back(0.0); + } + + PaddleTensor tensor; + tensor.shape = std::vector({batch_size, 3, height, width}); + tensor.data.Resize(sizeof(float) * batch_size * 3 * height * width); + std::copy(data.begin(), data.end(), static_cast(tensor.data.data())); + tensor.dtype = PaddleDType::FLOAT32; + std::vector paddle_tensor_feeds(1, tensor); + PaddleTensor tensor_out; + + std::vector outputs(1, tensor_out); + + predictor->Run(paddle_tensor_feeds, &outputs, batch_size); + std::cout << "start predict123:" << std::endl; + auto time1 = time(); + + for(size_t i = 0; i < 2; i++) { + predictor->Run(paddle_tensor_feeds, &outputs, batch_size); + std::cout << "pass " << i; + } + + auto time2 = time(); + std::ofstream ofresult("naive_test_result.txt", std::ios::app); + + std::cout <<"batch: " << batch_size << " predict cost: " << time_diff(time1, time2) / 100.0 << "ms" << std::endl; + std::cout << outputs.size() << std::endl; + /* + int64_t * data_o = static_cast(outputs[0].data.data()); + for (size_t j = 0; j < outputs[0].data.length() / sizeof(int64_t); ++j) { + ofresult << std::to_string(data_o[j]) << " "; + } + ofresult << std::endl; + ofresult.close(); + */ +} +} // namespace paddle + +int main(int argc, char** argv) { + paddle::test_naive(1 << 0); + return 0; +} \ No newline at end of file diff --git a/paddle/fluid/inference/api/demo_ci/simple_on_word2vec.cc b/paddle/fluid/inference/api/demo_ci/simple_on_word2vec.cc index 360f924810a..0f624e459b0 100644 --- a/paddle/fluid/inference/api/demo_ci/simple_on_word2vec.cc +++ b/paddle/fluid/inference/api/demo_ci/simple_on_word2vec.cc @@ -133,6 +133,7 @@ void MainThreads(int num_threads, bool use_gpu) { } // namespace paddle int main(int argc, char** argv) { + FLAGS_dirname = "./word2vec.inference.model"; google::ParseCommandLineFlags(&argc, &argv, true); paddle::demo::Main(false /* use_gpu*/); paddle::demo::MainThreads(1, false /* use_gpu*/); -- GitLab