Skip to content

Commit 4613aeb

Browse files
authored
Merge pull request #10272 from kexinzhao/save_fp16
Add float16 support to save op
2 parents 9a8be9d + efba1c7 commit 4613aeb

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

paddle/fluid/operators/save_load_op_test.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ limitations under the License. */
1414

1515
#include "gtest/gtest.h"
1616
#include "paddle/fluid/framework/op_registry.h"
17+
#include "paddle/fluid/platform/float16.h"
1718

1819
USE_NO_KERNEL_OP(save);
1920
USE_NO_KERNEL_OP(load);
@@ -61,3 +62,35 @@ TEST(SaveLoadOp, CPU) {
6162
}
6263
}
6364
}
65+
66+
TEST(SaveLoadFP16Op, CPU) {
67+
paddle::framework::Scope scope;
68+
paddle::platform::CPUPlace place;
69+
70+
auto var = scope.Var("test_var");
71+
auto tensor = var->GetMutable<paddle::framework::LoDTensor>();
72+
tensor->Resize({3, 10});
73+
74+
float* expect = tensor->mutable_data<float>(place);
75+
for (int64_t i = 0; i < tensor->numel(); ++i) {
76+
expect[i] = static_cast<float>(paddle::platform::float16(i));
77+
}
78+
79+
paddle::framework::AttributeMap attrs;
80+
attrs.insert({"file_path", std::string("tensor.save")});
81+
attrs.insert({"save_as_fp16", true});
82+
83+
auto save_op = paddle::framework::OpRegistry::CreateOp(
84+
"save", {{"X", {"test_var"}}}, {}, attrs);
85+
save_op->Run(scope, place);
86+
87+
auto load_var = scope.Var("out_var");
88+
auto target = load_var->GetMutable<paddle::framework::LoDTensor>();
89+
auto load_op = paddle::framework::OpRegistry::CreateOp(
90+
"load", {}, {{"Out", {"out_var"}}}, attrs);
91+
load_op->Run(scope, place);
92+
paddle::platform::float16* actual = target->data<paddle::platform::float16>();
93+
for (int64_t i = 0; i < tensor->numel(); ++i) {
94+
EXPECT_EQ(expect[i], static_cast<float>(actual[i]));
95+
}
96+
}

paddle/fluid/operators/save_op.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License. */
1818
#include <numeric>
1919

2020
#include "paddle/fluid/framework/data_type.h"
21+
#include "paddle/fluid/framework/data_type_transform.h"
2122
#include "paddle/fluid/framework/framework.pb.h"
2223
#include "paddle/fluid/framework/lod_tensor.h"
2324
#include "paddle/fluid/framework/op_registry.h"
@@ -68,6 +69,7 @@ class SaveOp : public framework::OperatorBase {
6869
const platform::Place &place) const override {
6970
auto filename = Attr<std::string>("file_path");
7071
auto overwrite = Attr<bool>("overwrite");
72+
auto save_as_fp16 = Attr<bool>("save_as_fp16");
7173

7274
if (FileExists(filename) && !overwrite) {
7375
PADDLE_THROW("%s is existed, cannot save to it when overwrite=false",
@@ -96,7 +98,18 @@ class SaveOp : public framework::OperatorBase {
9698
platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
9799
auto &dev_ctx = *pool.Get(place);
98100

99-
framework::SerializeToStream(fout, tensor, dev_ctx);
101+
auto in_dtype = framework::ToDataType(tensor.type());
102+
auto out_dtype = save_as_fp16 ? framework::proto::VarType::FP16 : in_dtype;
103+
104+
if (in_dtype != out_dtype) {
105+
auto in_kernel_type = framework::OpKernelType(in_dtype, place);
106+
auto out_kernel_type = framework::OpKernelType(out_dtype, place);
107+
framework::LoDTensor out;
108+
framework::TransDataType(in_kernel_type, out_kernel_type, tensor, &out);
109+
framework::SerializeToStream(fout, out, dev_ctx);
110+
} else {
111+
framework::SerializeToStream(fout, tensor, dev_ctx);
112+
}
100113
}
101114
};
102115

@@ -114,6 +127,12 @@ This operator will serialize and write a tensor variable to file on disk.
114127
"(boolean, default true)"
115128
"Overwrite the output file if exist")
116129
.SetDefault(true);
130+
AddAttr<bool>("save_as_fp16",
131+
"(boolean, default false)"
132+
"If true, the tensor will be converted to float16 data "
133+
"type and then saved. Otherwise, the tensor will be "
134+
"directly saved without data type conversion.")
135+
.SetDefault(false);
117136
AddAttr<std::string>("file_path",
118137
"(string)"
119138
"The \"file_path\" where the variable will be saved.")

0 commit comments

Comments
 (0)