提交 9cba0622 编写于 作者: L Liu Yiqun

Add inferface to change the feed/fetch_holder_name.

上级 e359b24a
...@@ -17,6 +17,7 @@ limitations under the License. */ ...@@ -17,6 +17,7 @@ limitations under the License. */
#include <deque> #include <deque>
#include <memory> #include <memory>
#include <set> #include <set>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
...@@ -96,6 +97,8 @@ class BlockDesc { ...@@ -96,6 +97,8 @@ class BlockDesc {
*/ */
void RemoveOp(size_t s, size_t e); void RemoveOp(size_t s, size_t e);
void RemoveVar(const std::string &name) { vars_.erase(name); }
std::vector<OpDesc *> AllOps() const; std::vector<OpDesc *> AllOps() const;
size_t OpSize() const { return ops_.size(); } size_t OpSize() const { return ops_.size(); }
......
...@@ -85,9 +85,9 @@ ProgramDesc::ProgramDesc(const std::string &binary_str) { ...@@ -85,9 +85,9 @@ ProgramDesc::ProgramDesc(const std::string &binary_str) {
} }
const std::vector<std::string> ProgramDesc::GetFeedTargetNames() { const std::vector<std::string> ProgramDesc::GetFeedTargetNames() {
BlockDesc *global_block = blocks_[0].get(); auto &global_block = Block(0);
std::vector<std::string> feed_target_names; std::vector<std::string> feed_target_names;
for (auto *op : global_block->AllOps()) { for (auto *op : global_block.AllOps()) {
if (op->Type() == kFeedOpType) { if (op->Type() == kFeedOpType) {
feed_target_names.insert(feed_target_names.begin(), op->Output("Out")[0]); feed_target_names.insert(feed_target_names.begin(), op->Output("Out")[0]);
} }
...@@ -96,9 +96,9 @@ const std::vector<std::string> ProgramDesc::GetFeedTargetNames() { ...@@ -96,9 +96,9 @@ const std::vector<std::string> ProgramDesc::GetFeedTargetNames() {
} }
const std::vector<std::string> ProgramDesc::GetFetchTargetNames() { const std::vector<std::string> ProgramDesc::GetFetchTargetNames() {
BlockDesc *global_block = blocks_[0].get(); auto &global_block = Block(0);
std::vector<std::string> fetch_target_names; std::vector<std::string> fetch_target_names;
for (auto *op : global_block->AllOps()) { for (auto *op : global_block.AllOps()) {
if (op->Type() == kFetchOpType) { if (op->Type() == kFetchOpType) {
fetch_target_names.push_back(op->Input("X")[0]); fetch_target_names.push_back(op->Input("X")[0]);
} }
...@@ -106,5 +106,43 @@ const std::vector<std::string> ProgramDesc::GetFetchTargetNames() { ...@@ -106,5 +106,43 @@ const std::vector<std::string> ProgramDesc::GetFetchTargetNames() {
return fetch_target_names; return fetch_target_names;
} }
void ProgramDesc::SetFeedHolderName(const std::string &feed_holder_name) {
auto *global_block = MutableBlock(0);
int index = 0;
for (auto *op : global_block->AllOps()) {
if (op->Type() == kFeedOpType) {
// Unify the input's name of all feed_ops to feed_holder_name
global_block->RemoveVar(op->Input("X")[0]);
op->SetInput("X", {feed_holder_name});
op->SetAttr("col", {index});
op->CheckAttrs();
index++;
}
}
auto *feed_holder = global_block->Var(feed_holder_name);
feed_holder->SetType(proto::VarType::FEED_MINIBATCH);
feed_holder->SetPersistable(true);
}
void ProgramDesc::SetFetchHolderName(const std::string &fetch_holder_name) {
auto *global_block = MutableBlock(0);
int index = 0;
for (auto *op : global_block->AllOps()) {
if (op->Type() == kFetchOpType) {
// Unify the output's name of all fetch_ops to fetch_holder_name
global_block->RemoveVar(op->Output("Out")[0]);
op->SetOutput("Out", {fetch_holder_name});
op->SetAttr("col", {index});
op->CheckAttrs();
index++;
}
}
auto *fetch_holder = global_block->Var(fetch_holder_name);
fetch_holder->SetType(proto::VarType::FETCH_LIST);
fetch_holder->SetPersistable(true);
}
} // namespace framework } // namespace framework
} // namespace paddle } // namespace paddle
...@@ -15,6 +15,7 @@ limitations under the License. */ ...@@ -15,6 +15,7 @@ limitations under the License. */
#pragma once #pragma once
#include <memory> #include <memory>
#include <string>
#include <vector> #include <vector>
#include "paddle/fluid/framework/block_desc.h" #include "paddle/fluid/framework/block_desc.h"
#include "paddle/fluid/framework/framework.pb.h" #include "paddle/fluid/framework/framework.pb.h"
...@@ -55,6 +56,9 @@ class ProgramDesc { ...@@ -55,6 +56,9 @@ class ProgramDesc {
const std::vector<std::string> GetFeedTargetNames(); const std::vector<std::string> GetFeedTargetNames();
const std::vector<std::string> GetFetchTargetNames(); const std::vector<std::string> GetFetchTargetNames();
void SetFeedHolderName(const std::string &feed_holder_name);
void SetFetchHolderName(const std::string &fetch_holder_name);
private: private:
proto::ProgramDesc desc_; proto::ProgramDesc desc_;
......
...@@ -35,7 +35,7 @@ TEST(inference, image_classification) { ...@@ -35,7 +35,7 @@ TEST(inference, image_classification) {
paddle::framework::LoDTensor input; paddle::framework::LoDTensor input;
// Use normilized image pixels as input data, // Use normilized image pixels as input data,
// which should be in the range [0.0, 1.0]. // which should be in the range [0.0, 1.0].
SetupTensor<float>(input, SetupTensor<float>(&input,
{FLAGS_batch_size, 3, 32, 32}, {FLAGS_batch_size, 3, 32, 32},
static_cast<float>(0), static_cast<float>(0),
static_cast<float>(1)); static_cast<float>(1));
......
...@@ -36,35 +36,35 @@ TEST(inference, label_semantic_roles) { ...@@ -36,35 +36,35 @@ TEST(inference, label_semantic_roles) {
int64_t predicate_dict_len = 3162; int64_t predicate_dict_len = 3162;
int64_t mark_dict_len = 2; int64_t mark_dict_len = 2;
SetupLoDTensor(word, SetupLoDTensor(&word,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
SetupLoDTensor(predicate, SetupLoDTensor(&predicate,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(predicate_dict_len - 1)); static_cast<int64_t>(predicate_dict_len - 1));
SetupLoDTensor(ctx_n2, SetupLoDTensor(&ctx_n2,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
SetupLoDTensor(ctx_n1, SetupLoDTensor(&ctx_n1,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
SetupLoDTensor(ctx_0, SetupLoDTensor(&ctx_0,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
SetupLoDTensor(ctx_p1, SetupLoDTensor(&ctx_p1,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
SetupLoDTensor(ctx_p2, SetupLoDTensor(&ctx_p2,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
SetupLoDTensor(mark, SetupLoDTensor(&mark,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(mark_dict_len - 1)); static_cast<int64_t>(mark_dict_len - 1));
......
...@@ -35,7 +35,7 @@ TEST(inference, recognize_digits) { ...@@ -35,7 +35,7 @@ TEST(inference, recognize_digits) {
paddle::framework::LoDTensor input; paddle::framework::LoDTensor input;
// Use normilized image pixels as input data, // Use normilized image pixels as input data,
// which should be in the range [-1.0, 1.0]. // which should be in the range [-1.0, 1.0].
SetupTensor<float>(input, SetupTensor<float>(&input,
{FLAGS_batch_size, 1, 28, 28}, {FLAGS_batch_size, 1, 28, 28},
static_cast<float>(-1), static_cast<float>(-1),
static_cast<float>(1)); static_cast<float>(1));
......
...@@ -36,25 +36,25 @@ TEST(inference, recommender_system) { ...@@ -36,25 +36,25 @@ TEST(inference, recommender_system) {
// Use the first data from paddle.dataset.movielens.test() as input // Use the first data from paddle.dataset.movielens.test() as input
std::vector<int64_t> user_id_data = {1}; std::vector<int64_t> user_id_data = {1};
SetupTensor<int64_t>(user_id, {batch_size, 1}, user_id_data); SetupTensor<int64_t>(&user_id, {batch_size, 1}, user_id_data);
std::vector<int64_t> gender_id_data = {1}; std::vector<int64_t> gender_id_data = {1};
SetupTensor<int64_t>(gender_id, {batch_size, 1}, gender_id_data); SetupTensor<int64_t>(&gender_id, {batch_size, 1}, gender_id_data);
std::vector<int64_t> age_id_data = {0}; std::vector<int64_t> age_id_data = {0};
SetupTensor<int64_t>(age_id, {batch_size, 1}, age_id_data); SetupTensor<int64_t>(&age_id, {batch_size, 1}, age_id_data);
std::vector<int64_t> job_id_data = {10}; std::vector<int64_t> job_id_data = {10};
SetupTensor<int64_t>(job_id, {batch_size, 1}, job_id_data); SetupTensor<int64_t>(&job_id, {batch_size, 1}, job_id_data);
std::vector<int64_t> movie_id_data = {783}; std::vector<int64_t> movie_id_data = {783};
SetupTensor<int64_t>(movie_id, {batch_size, 1}, movie_id_data); SetupTensor<int64_t>(&movie_id, {batch_size, 1}, movie_id_data);
std::vector<int64_t> category_id_data = {10, 8, 9}; std::vector<int64_t> category_id_data = {10, 8, 9};
SetupLoDTensor<int64_t>(category_id, {3, 1}, {{0, 3}}, category_id_data); SetupLoDTensor<int64_t>(&category_id, {3, 1}, {{0, 3}}, category_id_data);
std::vector<int64_t> movie_title_data = {1069, 4140, 2923, 710, 988}; std::vector<int64_t> movie_title_data = {1069, 4140, 2923, 710, 988};
SetupLoDTensor<int64_t>(movie_title, {5, 1}, {{0, 5}}, movie_title_data); SetupLoDTensor<int64_t>(&movie_title, {5, 1}, {{0, 5}}, movie_title_data);
std::vector<paddle::framework::LoDTensor*> cpu_feeds; std::vector<paddle::framework::LoDTensor*> cpu_feeds;
cpu_feeds.push_back(&user_id); cpu_feeds.push_back(&user_id);
......
...@@ -33,9 +33,9 @@ TEST(inference, rnn_encoder_decoder) { ...@@ -33,9 +33,9 @@ TEST(inference, rnn_encoder_decoder) {
paddle::framework::LoD lod{{0, 4, 10}}; paddle::framework::LoD lod{{0, 4, 10}};
SetupLoDTensor( SetupLoDTensor(
word_data, lod, static_cast<int64_t>(0), static_cast<int64_t>(1)); &word_data, lod, static_cast<int64_t>(0), static_cast<int64_t>(1));
SetupLoDTensor( SetupLoDTensor(
trg_word, lod, static_cast<int64_t>(0), static_cast<int64_t>(1)); &trg_word, lod, static_cast<int64_t>(0), static_cast<int64_t>(1));
std::vector<paddle::framework::LoDTensor*> cpu_feeds; std::vector<paddle::framework::LoDTensor*> cpu_feeds;
cpu_feeds.push_back(&word_data); cpu_feeds.push_back(&word_data);
......
...@@ -33,7 +33,7 @@ TEST(inference, understand_sentiment) { ...@@ -33,7 +33,7 @@ TEST(inference, understand_sentiment) {
paddle::framework::LoD lod{{0, 4, 10}}; paddle::framework::LoD lod{{0, 4, 10}};
int64_t word_dict_len = 5147; int64_t word_dict_len = 5147;
SetupLoDTensor(words, SetupLoDTensor(&words,
lod, lod,
static_cast<int64_t>(0), static_cast<int64_t>(0),
static_cast<int64_t>(word_dict_len - 1)); static_cast<int64_t>(word_dict_len - 1));
......
...@@ -33,10 +33,10 @@ TEST(inference, word2vec) { ...@@ -33,10 +33,10 @@ TEST(inference, word2vec) {
paddle::framework::LoD lod{{0, 1}}; paddle::framework::LoD lod{{0, 1}};
int64_t dict_size = 2073; // The size of dictionary int64_t dict_size = 2073; // The size of dictionary
SetupLoDTensor(first_word, lod, static_cast<int64_t>(0), dict_size - 1); SetupLoDTensor(&first_word, lod, static_cast<int64_t>(0), dict_size - 1);
SetupLoDTensor(second_word, lod, static_cast<int64_t>(0), dict_size - 1); SetupLoDTensor(&second_word, lod, static_cast<int64_t>(0), dict_size - 1);
SetupLoDTensor(third_word, lod, static_cast<int64_t>(0), dict_size - 1); SetupLoDTensor(&third_word, lod, static_cast<int64_t>(0), dict_size - 1);
SetupLoDTensor(fourth_word, lod, static_cast<int64_t>(0), dict_size - 1); SetupLoDTensor(&fourth_word, lod, static_cast<int64_t>(0), dict_size - 1);
std::vector<paddle::framework::LoDTensor*> cpu_feeds; std::vector<paddle::framework::LoDTensor*> cpu_feeds;
cpu_feeds.push_back(&first_word); cpu_feeds.push_back(&first_word);
......
...@@ -12,58 +12,63 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ...@@ -12,58 +12,63 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#pragma once
#include <time.h> #include <time.h>
#include <map>
#include <string>
#include <vector>
#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/inference/io.h" #include "paddle/fluid/inference/io.h"
#include "paddle/fluid/platform/profiler.h" #include "paddle/fluid/platform/profiler.h"
template <typename T> template <typename T>
void SetupTensor(paddle::framework::LoDTensor& input, void SetupTensor(paddle::framework::LoDTensor* input,
paddle::framework::DDim dims, paddle::framework::DDim dims,
T lower, const T lower,
T upper) { const T upper) {
srand(time(0)); T* input_ptr = input->mutable_data<T>(dims, paddle::platform::CPUPlace());
T* input_ptr = input.mutable_data<T>(dims, paddle::platform::CPUPlace()); unsigned int seed = time(NULL);
for (int i = 0; i < input.numel(); ++i) { for (int i = 0; i < input->numel(); ++i) {
input_ptr[i] = input_ptr[i] = (static_cast<T>(rand_r(&seed)) / static_cast<T>(RAND_MAX)) *
(static_cast<T>(rand()) / static_cast<T>(RAND_MAX)) * (upper - lower) + (upper - lower) +
lower; lower;
} }
} }
template <typename T> template <typename T>
void SetupTensor(paddle::framework::LoDTensor& input, void SetupTensor(paddle::framework::LoDTensor* input,
paddle::framework::DDim dims, paddle::framework::DDim dims,
std::vector<T>& data) { const std::vector<T>& data) {
CHECK_EQ(paddle::framework::product(dims), static_cast<int64_t>(data.size())); CHECK_EQ(paddle::framework::product(dims), static_cast<int64_t>(data.size()));
T* input_ptr = input.mutable_data<T>(dims, paddle::platform::CPUPlace()); T* input_ptr = input->mutable_data<T>(dims, paddle::platform::CPUPlace());
memcpy(input_ptr, data.data(), input.numel() * sizeof(T)); memcpy(input_ptr, data.data(), input->numel() * sizeof(T));
} }
template <typename T> template <typename T>
void SetupLoDTensor(paddle::framework::LoDTensor& input, void SetupLoDTensor(paddle::framework::LoDTensor* input,
paddle::framework::LoD& lod, const paddle::framework::LoD& lod,
T lower, const T lower,
T upper) { const T upper) {
input.set_lod(lod); input->set_lod(lod);
int dim = lod[0][lod[0].size() - 1]; int dim = lod[0][lod[0].size() - 1];
SetupTensor<T>(input, {dim, 1}, lower, upper); SetupTensor<T>(input, {dim, 1}, lower, upper);
} }
template <typename T> template <typename T>
void SetupLoDTensor(paddle::framework::LoDTensor& input, void SetupLoDTensor(paddle::framework::LoDTensor* input,
paddle::framework::DDim dims, paddle::framework::DDim dims,
paddle::framework::LoD lod, paddle::framework::LoD lod,
std::vector<T>& data) { const std::vector<T>& data) {
const size_t level = lod.size() - 1; const size_t level = lod.size() - 1;
CHECK_EQ(dims[0], static_cast<int64_t>((lod[level]).back())); CHECK_EQ(dims[0], static_cast<int64_t>((lod[level]).back()));
input.set_lod(lod); input->set_lod(lod);
SetupTensor<T>(input, dims, data); SetupTensor<T>(input, dims, data);
} }
template <typename T> template <typename T>
void CheckError(paddle::framework::LoDTensor& output1, void CheckError(const paddle::framework::LoDTensor& output1,
paddle::framework::LoDTensor& output2) { const paddle::framework::LoDTensor& output2) {
// Check lod information // Check lod information
EXPECT_EQ(output1.lod(), output2.lod()); EXPECT_EQ(output1.lod(), output2.lod());
...@@ -91,7 +96,7 @@ void CheckError(paddle::framework::LoDTensor& output1, ...@@ -91,7 +96,7 @@ void CheckError(paddle::framework::LoDTensor& output1,
template <typename Place> template <typename Place>
void TestInference(const std::string& dirname, void TestInference(const std::string& dirname,
const std::vector<paddle::framework::LoDTensor*>& cpu_feeds, const std::vector<paddle::framework::LoDTensor*>& cpu_feeds,
std::vector<paddle::framework::LoDTensor*>& cpu_fetchs, const std::vector<paddle::framework::LoDTensor*>& cpu_fetchs,
const int repeat = 1, const int repeat = 1,
const bool is_combined = false) { const bool is_combined = false) {
// 1. Define place, executor, scope // 1. Define place, executor, scope
......
...@@ -12,6 +12,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ...@@ -12,6 +12,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#pragma once
#include <thread> #include <thread>
#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/inference/io.h" #include "paddle/fluid/inference/io.h"
...@@ -20,13 +22,23 @@ void ThreadedRunInference( ...@@ -20,13 +22,23 @@ void ThreadedRunInference(
std::unique_ptr<paddle::framework::ProgramDesc>& inference_program, std::unique_ptr<paddle::framework::ProgramDesc>& inference_program,
paddle::framework::Executor& executor, paddle::framework::Executor& executor,
paddle::framework::Scope* scope, paddle::framework::Scope* scope,
const int thread_id,
const std::vector<paddle::framework::LoDTensor*>& cpu_feeds, const std::vector<paddle::framework::LoDTensor*>& cpu_feeds,
std::vector<paddle::framework::LoDTensor*>& cpu_fetchs) { std::vector<paddle::framework::LoDTensor*>& cpu_fetchs) {
auto copy_program = std::unique_ptr<paddle::framework::ProgramDesc>(
new paddle::framework::ProgramDesc(*inference_program));
std::string feed_holder_name = "feed_" + paddle::string::to_string(thread_id);
std::string fetch_holder_name =
"fetch_" + paddle::string::to_string(thread_id);
copy_program->SetFeedHolderName(feed_holder_name);
copy_program->SetFetchHolderName(fetch_holder_name);
// 3. Get the feed_target_names and fetch_target_names // 3. Get the feed_target_names and fetch_target_names
const std::vector<std::string>& feed_target_names = const std::vector<std::string>& feed_target_names =
inference_program->GetFeedTargetNames(); copy_program->GetFeedTargetNames();
const std::vector<std::string>& fetch_target_names = const std::vector<std::string>& fetch_target_names =
inference_program->GetFetchTargetNames(); copy_program->GetFetchTargetNames();
// 4. Prepare inputs: set up maps for feed targets // 4. Prepare inputs: set up maps for feed targets
std::map<std::string, const paddle::framework::LoDTensor*> feed_targets; std::map<std::string, const paddle::framework::LoDTensor*> feed_targets;
...@@ -42,7 +54,12 @@ void ThreadedRunInference( ...@@ -42,7 +54,12 @@ void ThreadedRunInference(
} }
// 6. Run the inference program // 6. Run the inference program
executor.Run(*inference_program, scope, feed_targets, fetch_targets); executor.Run(*copy_program,
scope,
feed_targets,
fetch_targets,
feed_holder_name,
fetch_holder_name);
} }
template <typename Place> template <typename Place>
...@@ -66,6 +83,7 @@ void TestMultiThreadInference( ...@@ -66,6 +83,7 @@ void TestMultiThreadInference(
std::ref(inference_program), std::ref(inference_program),
std::ref(executor), std::ref(executor),
scope, scope,
i,
std::ref(cpu_feeds[i]), std::ref(cpu_feeds[i]),
std::ref(cpu_fetchs[i]))); std::ref(cpu_fetchs[i])));
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册