Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Don't Review] Add float16 image classification example code and add float16 support to save op #9864

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions paddle/fluid/framework/executor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void CheckTensorNANOrInf(const std::string& name,
}

void Executor::CreateVariables(const ProgramDesc& pdesc, Scope* scope,
int block_id) {
int block_id) const {
auto& global_block = pdesc.Block(block_id);

const Scope* ancestor_scope = scope;
Expand Down Expand Up @@ -131,7 +131,7 @@ void Executor::CreateVariables(const ProgramDesc& pdesc, Scope* scope,
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id,
bool create_local_scope, bool create_vars) {
bool create_local_scope, bool create_vars) const {
platform::RecordBlock b(block_id);
auto ctx = Prepare(pdesc, block_id);
RunPreparedContext(ctx.get(), scope, create_local_scope, create_vars);
Expand Down Expand Up @@ -226,10 +226,10 @@ static bool has_fetch_operators(
}

void Executor::Run(const ProgramDesc& program, Scope* scope,
std::map<std::string, const LoDTensor*>& feed_targets,
std::map<std::string, LoDTensor*>& fetch_targets,
const std::map<std::string, const LoDTensor*>& feed_targets,
const std::map<std::string, LoDTensor*>& fetch_targets,
bool create_vars, const std::string& feed_holder_name,
const std::string& fetch_holder_name) {
const std::string& fetch_holder_name) const {
platform::RecordBlock b(kProgramId);
bool has_feed_ops =
has_feed_operators(program.Block(0), feed_targets, feed_holder_name);
Expand Down Expand Up @@ -321,7 +321,8 @@ std::vector<std::shared_ptr<ExecutorPrepareContext>> Executor::Prepare(
}

void Executor::RunPreparedContext(ExecutorPrepareContext* ctx, Scope* scope,
bool create_local_scope, bool create_vars) {
bool create_local_scope,
bool create_vars) const {
Scope* local_scope = scope;
if (create_vars) {
if (create_local_scope) {
Expand Down Expand Up @@ -361,9 +362,10 @@ void Executor::RunPreparedContext(ExecutorPrepareContext* ctx, Scope* scope,

void Executor::RunPreparedContext(
ExecutorPrepareContext* ctx, Scope* scope,
std::map<std::string, const LoDTensor*>& feed_targets,
std::map<std::string, LoDTensor*>& fetch_targets, bool create_vars,
const std::string& feed_holder_name, const std::string& fetch_holder_name) {
const std::map<std::string, const LoDTensor*>& feed_targets,
const std::map<std::string, LoDTensor*>& fetch_targets, bool create_vars,
const std::string& feed_holder_name,
const std::string& fetch_holder_name) const {
auto& global_block = ctx->prog_.Block(ctx->block_id_);

PADDLE_ENFORCE(
Expand All @@ -378,8 +380,8 @@ void Executor::RunPreparedContext(
if (op->Type() == kFeedOpType) {
std::string feed_target_name = op->Output("Out")[0];
int idx = boost::get<int>(op->GetAttr("col"));
SetFeedVariable(scope, *feed_targets[feed_target_name], feed_holder_name,
idx);
SetFeedVariable(scope, *feed_targets.at(feed_target_name),
feed_holder_name, idx);
}
}

Expand All @@ -390,7 +392,7 @@ void Executor::RunPreparedContext(
if (op->Type() == kFetchOpType) {
std::string fetch_target_name = op->Input("X")[0];
int idx = boost::get<int>(op->GetAttr("col"));
*fetch_targets[fetch_target_name] =
*fetch_targets.at(fetch_target_name) =
GetFetchVariable(*scope, fetch_holder_name, idx);
}
}
Expand Down
27 changes: 14 additions & 13 deletions paddle/fluid/framework/executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,33 +52,34 @@ class Executor {
* Scope
*/
void Run(const ProgramDesc& prog, Scope* scope, int block_id,
bool create_local_scope = true, bool create_vars = true);
bool create_local_scope = true, bool create_vars = true) const;

void Run(const ProgramDesc& program, Scope* scope,
std::map<std::string, const LoDTensor*>& feed_targets,
std::map<std::string, LoDTensor*>& fetch_targets,
const std::map<std::string, const LoDTensor*>& feed_targets,
const std::map<std::string, LoDTensor*>& fetch_targets,
bool create_vars = true,
const std::string& feed_holder_name = "feed",
const std::string& fetch_holder_name = "fetch");
const std::string& fetch_holder_name = "fetch") const;

static std::unique_ptr<ExecutorPrepareContext> Prepare(
const ProgramDesc& program, int block_id);

static std::vector<std::shared_ptr<ExecutorPrepareContext>> Prepare(
const ProgramDesc& program, const std::vector<int>& block_ids);

void CreateVariables(const ProgramDesc& pdesc, Scope* scope, int block_id);
void CreateVariables(const ProgramDesc& pdesc, Scope* scope,
int block_id) const;

void RunPreparedContext(ExecutorPrepareContext* ctx, Scope* scope,
bool create_local_scope = true,
bool create_vars = true);

void RunPreparedContext(ExecutorPrepareContext* ctx, Scope* scope,
std::map<std::string, const LoDTensor*>& feed_targets,
std::map<std::string, LoDTensor*>& fetch_targets,
bool create_vars = true,
const std::string& feed_holder_name = "feed",
const std::string& fetch_holder_name = "fetch");
bool create_vars = true) const;

void RunPreparedContext(
ExecutorPrepareContext* ctx, Scope* scope,
const std::map<std::string, const LoDTensor*>& feed_targets,
const std::map<std::string, LoDTensor*>& fetch_targets,
bool create_vars = true, const std::string& feed_holder_name = "feed",
const std::string& fetch_holder_name = "fetch") const;

private:
const platform::Place place_;
Expand Down
27 changes: 15 additions & 12 deletions paddle/fluid/inference/io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ limitations under the License. */

#include "paddle/fluid/inference/io.h"

#include <algorithm>
#include <fstream>

#include "paddle/fluid/framework/block_desc.h"
#include "paddle/fluid/framework/feed_fetch_type.h"
#include "paddle/fluid/framework/op_registry.h"
Expand All @@ -27,14 +29,14 @@ namespace inference {
// linking the inference shared library.
void Init(bool init_p2p) { framework::InitDevices(init_p2p); }

void ReadBinaryFile(const std::string& filename, std::string& contents) {
void ReadBinaryFile(const std::string& filename, std::string* contents) {
std::ifstream fin(filename, std::ios::in | std::ios::binary);
PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open file %s", filename);
fin.seekg(0, std::ios::end);
contents.clear();
contents.resize(fin.tellg());
contents->clear();
contents->resize(fin.tellg());
fin.seekg(0, std::ios::beg);
fin.read(&contents[0], contents.size());
fin.read(&(contents->at(0)), contents->size());
fin.close();
}

Expand All @@ -47,7 +49,8 @@ bool IsPersistable(const framework::VarDesc* var) {
return false;
}

void LoadPersistables(framework::Executor& executor, framework::Scope& scope,
void LoadPersistables(const framework::Executor& executor,
framework::Scope* scope,
const framework::ProgramDesc& main_program,
const std::string& dirname,
const std::string& param_filename) {
Expand Down Expand Up @@ -92,18 +95,18 @@ void LoadPersistables(framework::Executor& executor, framework::Scope& scope,
op->CheckAttrs();
}

executor.Run(*load_program, &scope, 0, true, true);
executor.Run(*load_program, scope, 0, true, true);

delete load_program;
}

std::unique_ptr<framework::ProgramDesc> Load(framework::Executor& executor,
framework::Scope& scope,
const std::string& dirname) {
std::unique_ptr<framework::ProgramDesc> Load(
const framework::Executor& executor, framework::Scope* scope,
const std::string& dirname) {
std::string model_filename = dirname + "/__model__";
std::string program_desc_str;
VLOG(3) << "loading model from " << model_filename;
ReadBinaryFile(model_filename, program_desc_str);
ReadBinaryFile(model_filename, &program_desc_str);

std::unique_ptr<framework::ProgramDesc> main_program(
new framework::ProgramDesc(program_desc_str));
Expand All @@ -113,11 +116,11 @@ std::unique_ptr<framework::ProgramDesc> Load(framework::Executor& executor,
}

std::unique_ptr<framework::ProgramDesc> Load(
framework::Executor& executor, framework::Scope& scope,
const framework::Executor& executor, framework::Scope* scope,
const std::string& prog_filename, const std::string& param_filename) {
std::string model_filename = prog_filename;
std::string program_desc_str;
ReadBinaryFile(model_filename, program_desc_str);
ReadBinaryFile(model_filename, &program_desc_str);

std::unique_ptr<framework::ProgramDesc> main_program(
new framework::ProgramDesc(program_desc_str));
Expand Down
16 changes: 8 additions & 8 deletions paddle/fluid/inference/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ namespace inference {

void Init(bool init_p2p);

void LoadPersistables(framework::Executor& executor, framework::Scope& scope,
void LoadPersistables(const framework::Executor& executor,
framework::Scope* scope,
const framework::ProgramDesc& main_program,
const std::string& dirname,
const std::string& param_filename);

std::unique_ptr<framework::ProgramDesc> Load(framework::Executor& executor,
framework::Scope& scope,
const std::string& dirname);
std::unique_ptr<framework::ProgramDesc> Load(
const framework::Executor& executor, framework::Scope* scope,
const std::string& dirname);

std::unique_ptr<framework::ProgramDesc> Load(framework::Executor& executor,
framework::Scope& scope,
const std::string& prog_filename,
const std::string& param_filename);
std::unique_ptr<framework::ProgramDesc> Load(
const framework::Executor& executor, framework::Scope* scope,
const std::string& prog_filename, const std::string& param_filename);

} // namespace inference
} // namespace paddle
18 changes: 16 additions & 2 deletions paddle/fluid/inference/tests/book/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@ function(inference_test TARGET_NAME)
else()
list(APPEND arg_list "_")
endif()

set(use_float16 "")
if(${TARGET_NAME} MATCHES "^float16")
if(${TARGET_NAME} MATCHES "image_classification")
set(use_float16 "--use_float16=true")
endif()
set(book_dir "book_float16")
else()
set(book_dir "book")
endif()
set(SOURCE_NAME "")
string(REGEX REPLACE "^float16_" "" SOURCE_NAME "${TARGET_NAME}")

foreach(arg ${arg_list})
string(REGEX REPLACE "^_$" "" arg "${arg}")
cc_test(test_inference_${TARGET_NAME}${arg}
SRCS test_inference_${TARGET_NAME}.cc
SRCS test_inference_${SOURCE_NAME}.cc
DEPS paddle_fluid
ARGS --dirname=${PYTHON_TESTS_DIR}/book/${TARGET_NAME}${arg}.inference.model)
ARGS --dirname=${PYTHON_TESTS_DIR}/${book_dir}/${TARGET_NAME}${arg}.inference.model ${use_float16})
set_tests_properties(test_inference_${TARGET_NAME}${arg}
PROPERTIES DEPENDS test_${TARGET_NAME})
endforeach()
Expand All @@ -27,6 +40,7 @@ endfunction(inference_test)
# This unittest is buggy!
#inference_test(fit_a_line)
inference_test(image_classification ARGS vgg resnet)
inference_test(float16_image_classification ARGS vgg resnet)
inference_test(label_semantic_roles)
inference_test(recognize_digits ARGS mlp conv)
inference_test(recommender_system)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ limitations under the License. */
#include "gflags/gflags.h"
#include "gtest/gtest.h"
#include "paddle/fluid/inference/tests/test_helper.h"
#include "paddle/fluid/platform/float16.h"

DEFINE_string(dirname, "", "Directory of the inference model.");
DEFINE_int32(batch_size, 1, "Batch size of input data");
DEFINE_int32(repeat, 1, "Running the inference program repeat times");
DEFINE_bool(use_float16, false, "Running inference in float16 mode or not");

TEST(inference, image_classification) {
using float16 = paddle::platform::float16;

if (FLAGS_dirname.empty() || FLAGS_batch_size < 1 || FLAGS_repeat < 1) {
LOG(FATAL) << "Usage: ./example --dirname=path/to/your/model "
"--batch_size=1 --repeat=1";
Expand All @@ -35,20 +39,28 @@ TEST(inference, image_classification) {
paddle::framework::LoDTensor input;
// Use normilized image pixels as input data,
// which should be in the range [0.0, 1.0].
SetupTensor<float>(&input, {FLAGS_batch_size, 3, 32, 32},
static_cast<float>(0), static_cast<float>(1));
if (!FLAGS_use_float16) {
SetupTensor<float>(&input, {FLAGS_batch_size, 3, 32, 32},
static_cast<float>(0), static_cast<float>(1));
} else {
SetupTensor<float16>(&input, {FLAGS_batch_size, 3, 32, 32},
static_cast<float16>(0), static_cast<float16>(1));
}
std::vector<paddle::framework::LoDTensor*> cpu_feeds;
cpu_feeds.push_back(&input);

// float16 inference is currently not supported on CPU
paddle::framework::LoDTensor output1;
std::vector<paddle::framework::LoDTensor*> cpu_fetchs1;
cpu_fetchs1.push_back(&output1);
if (!FLAGS_use_float16) {
std::vector<paddle::framework::LoDTensor*> cpu_fetchs1;
cpu_fetchs1.push_back(&output1);

// Run inference on CPU
LOG(INFO) << "--- CPU Runs: ---";
TestInference<paddle::platform::CPUPlace, false, true>(
dirname, cpu_feeds, cpu_fetchs1, FLAGS_repeat);
LOG(INFO) << output1.dims();
// Run inference on CPU
LOG(INFO) << "--- CPU Runs: ---";
TestInference<paddle::platform::CPUPlace, false, true>(
dirname, cpu_feeds, cpu_fetchs1, FLAGS_repeat);
LOG(INFO) << output1.dims();
}

#ifdef PADDLE_WITH_CUDA
paddle::framework::LoDTensor output2;
Expand All @@ -61,6 +73,8 @@ TEST(inference, image_classification) {
dirname, cpu_feeds, cpu_fetchs2, FLAGS_repeat);
LOG(INFO) << output2.dims();

CheckError<float>(output1, output2);
if (!FLAGS_use_float16) {
CheckError<float>(output1, output2);
}
#endif
}
8 changes: 5 additions & 3 deletions paddle/fluid/inference/tests/test_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ void SetupTensor(paddle::framework::LoDTensor* input,

T* input_ptr = input->mutable_data<T>(dims, paddle::platform::CPUPlace());
for (int i = 0; i < input->numel(); ++i) {
input_ptr[i] = static_cast<T>(uniform_dist(rng) * (upper - lower) + lower);
input_ptr[i] =
static_cast<T>(uniform_dist(rng) * static_cast<double>(upper - lower) +
static_cast<double>(lower));
}
}

Expand Down Expand Up @@ -133,12 +135,12 @@ void TestInference(const std::string& dirname,
std::string prog_filename = "__model_combined__";
std::string param_filename = "__params_combined__";
inference_program = paddle::inference::Load(
executor, *scope, dirname + "/" + prog_filename,
executor, scope, dirname + "/" + prog_filename,
dirname + "/" + param_filename);
} else {
// Parameters are saved in separate files sited in the specified
// `dirname`.
inference_program = paddle::inference::Load(executor, *scope, dirname);
inference_program = paddle::inference::Load(executor, scope, dirname);
}
}
// Disable the profiler and print the timing information
Expand Down
2 changes: 1 addition & 1 deletion paddle/fluid/inference/tests/test_multi_thread_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void TestMultiThreadInference(

// 2. Initialize the inference_program and load parameters
std::unique_ptr<paddle::framework::ProgramDesc> inference_program =
paddle::inference::Load(executor, *scope, dirname);
paddle::inference::Load(executor, scope, dirname);

std::vector<std::thread*> threads;
for (int i = 0; i < num_threads; ++i) {
Expand Down
Loading