Skip to content

Commit e426cda

Browse files
authored
fix inference output with lod (#13557)
1 parent bc1fa4f commit e426cda

File tree

3 files changed

+29
-68
lines changed

3 files changed

+29
-68
lines changed

paddle/fluid/inference/api/api_impl.cc

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ limitations under the License. */
2222

2323
#include "paddle/fluid/framework/feed_fetch_method.h"
2424
#include "paddle/fluid/inference/api/api_impl.h"
25+
#include "paddle/fluid/inference/api/helper.h"
2526
#include "paddle/fluid/inference/api/timer.h"
2627
#include "paddle/fluid/platform/profiler.h"
2728

@@ -215,57 +216,20 @@ bool NativePaddlePredictor::SetFeed(const std::vector<PaddleTensor> &inputs,
215216
template <typename T>
216217
void NativePaddlePredictor::GetFetchOne(const framework::LoDTensor &fetch,
217218
PaddleTensor *output) {
218-
std::vector<int> shape;
219-
auto dims_i = fetch.dims();
220-
auto lod = fetch.lod();
221-
const T *output_ptr = fetch.data<T>();
222-
auto num = fetch.numel();
223-
std::vector<T> data;
224-
if (0 == lod.size()) {
225-
std::copy(output_ptr, output_ptr + num, std::back_inserter(data));
226-
for (int j = 0; j < dims_i.size(); ++j) {
227-
shape.push_back(dims_i[j]);
228-
}
229-
} else {
230-
// for batch detection
231-
// image[0] -> output[0] shape {145, 6}
232-
// image[1] -> output[1] shape {176, 6}
233-
// then,
234-
// the batch output shape {321, 6}
235-
// the lod {{0, 145, 321}}
236-
// so we should append output[0] to {176, 6}
237-
size_t max_dim = 0;
238-
for (size_t j = 1; j < lod[0].size(); j++) {
239-
max_dim = std::max(max_dim, lod[0][j] - lod[0][j - 1]);
240-
}
241-
size_t common_dim = lod[0].back() == 0 ? 0 : num / lod[0].back();
242-
if (max_dim > 0) {
243-
data.resize((lod[0].size() - 1) * max_dim * common_dim, 0);
244-
}
245-
for (size_t j = 1; j < lod[0].size(); j++) {
246-
size_t start = lod[0][j - 1] * common_dim;
247-
size_t end = lod[0][j] * common_dim;
248-
if (end > start) {
249-
std::copy(output_ptr + start, output_ptr + end,
250-
data.begin() + (j - 1) * max_dim * common_dim);
251-
}
252-
}
253-
shape.push_back(lod[0].size() - 1);
254-
shape.push_back(max_dim);
255-
for (int j = 1; j < dims_i.size(); ++j) {
256-
shape.push_back(dims_i[j]);
257-
}
258-
}
259-
260-
output->shape = shape;
261-
auto &buffer = output->data;
262-
if (buffer.empty() || buffer.length() < sizeof(T) * data.size()) {
263-
buffer.Resize(sizeof(T) * data.size());
264-
}
265-
std::memcpy(buffer.data(), data.data(), sizeof(T) * data.size());
266-
// copy LoD
267-
for (const auto &level : fetch.lod()) {
268-
output->lod.emplace_back(level);
219+
// set shape.
220+
auto shape = framework::vectorize(fetch.dims());
221+
output->shape.assign(shape.begin(), shape.end());
222+
// set data.
223+
const T *data = fetch.data<T>();
224+
int num_elems = inference::VecReduceToInt(shape);
225+
output->data.Resize(num_elems * sizeof(T));
226+
// The fetched tensor output by fetch op, should always in CPU memory, so just
227+
// copy.
228+
memcpy(output->data.data(), data, num_elems * sizeof(T));
229+
// set lod
230+
output->lod.clear();
231+
for (auto &level : fetch.lod()) {
232+
output->lod.emplace_back(level.begin(), level.end());
269233
}
270234
}
271235

paddle/fluid/inference/api/helper.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,17 @@ template <>
7474
std::string to_string<std::vector<std::vector<float>>>(
7575
const std::vector<std::vector<std::vector<float>>> &vec);
7676

77+
template <typename T>
78+
int VecReduceToInt(const std::vector<T> &v) {
79+
return std::accumulate(v.begin(), v.end(), 1, [](T a, T b) { return a * b; });
80+
}
81+
7782
template <typename T>
7883
static void TensorAssignData(PaddleTensor *tensor,
7984
const std::vector<std::vector<T>> &data) {
8085
// Assign buffer
81-
int dim = std::accumulate(tensor->shape.begin(), tensor->shape.end(), 1,
82-
[](int a, int b) { return a * b; });
83-
tensor->data.Resize(sizeof(T) * dim);
86+
int num_elems = VecReduceToInt(tensor->shape);
87+
tensor->data.Resize(sizeof(T) * num_elems);
8488
int c = 0;
8589
for (const auto &f : data) {
8690
for (T v : f) {
@@ -89,7 +93,7 @@ static void TensorAssignData(PaddleTensor *tensor,
8993
}
9094
}
9195

92-
std::string DescribeTensor(const PaddleTensor &tensor) {
96+
static std::string DescribeTensor(const PaddleTensor &tensor) {
9397
std::stringstream os;
9498
os << "Tensor [" << tensor.name << "]\n";
9599
os << " - type: ";
@@ -113,17 +117,16 @@ std::string DescribeTensor(const PaddleTensor &tensor) {
113117
os << "\n";
114118
os << " - data: ";
115119

116-
int dim = std::accumulate(tensor.shape.begin(), tensor.shape.end(), 1,
117-
[](int a, int b) { return a * b; });
120+
int dim = VecReduceToInt(tensor.shape);
118121
for (int i = 0; i < dim; i++) {
119122
os << static_cast<float *>(tensor.data.data())[i] << " ";
120123
}
121124
os << '\n';
122125
return os.str();
123126
}
124127

125-
void PrintTime(int batch_size, int repeat, int num_threads, int tid,
126-
double latency, int epoch = 1) {
128+
static void PrintTime(int batch_size, int repeat, int num_threads, int tid,
129+
double latency, int epoch = 1) {
127130
LOG(INFO) << "====== batch_size: " << batch_size << ", repeat: " << repeat
128131
<< ", threads: " << num_threads << ", thread id: " << tid
129132
<< ", latency: " << latency << "ms ======";

paddle/fluid/inference/tests/api/tester_helper.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ void CompareResult(const std::vector<PaddleTensor> &outputs,
4747
for (size_t i = 0; i < outputs.size(); i++) {
4848
auto &out = outputs[i];
4949
auto &ref_out = ref_outputs[i];
50-
size_t size = std::accumulate(out.shape.begin(), out.shape.end(), 1,
51-
[](int a, int b) { return a * b; });
52-
size_t ref_size =
53-
std::accumulate(ref_out.shape.begin(), ref_out.shape.end(), 1,
54-
[](int a, int b) { return a * b; });
50+
size_t size = VecReduceToInt(out.shape);
51+
size_t ref_size = VecReduceToInt(ref_out.shape);
5552
EXPECT_GT(size, 0);
5653
EXPECT_EQ(size, ref_size);
5754
EXPECT_EQ(out.dtype, ref_out.dtype);
@@ -87,10 +84,7 @@ std::unique_ptr<PaddlePredictor> CreateTestPredictor(
8784
}
8885
}
8986

90-
size_t GetSize(const PaddleTensor &out) {
91-
return std::accumulate(out.shape.begin(), out.shape.end(), 1,
92-
[](int a, int b) { return a * b; });
93-
}
87+
size_t GetSize(const PaddleTensor &out) { return VecReduceToInt(out.shape); }
9488

9589
std::unordered_map<std::string, int> GetFuseStatis(AnalysisConfig config,
9690
int *num_ops) {

0 commit comments

Comments
 (0)