chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
// Copyright (c) 2021 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 "paddle/fluid/framework/ir/cost_model.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/common/errors.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/program_desc.h"
|
||||
#include "paddle/phi/api/profiler/event.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
|
||||
// Register test op
|
||||
class FakeTestOpMaker : public OpProtoAndCheckerMaker {
|
||||
public:
|
||||
void Make() override {
|
||||
AddInput("X", "").AsDuplicable();
|
||||
AddInput("Y", "").AsDuplicable();
|
||||
AddOutput("Out", "").AsDuplicable();
|
||||
AddComment("");
|
||||
}
|
||||
};
|
||||
|
||||
class FakeTestOp : public OperatorBase {
|
||||
public:
|
||||
FakeTestOp(const std::string &type,
|
||||
const VariableNameMap &inputs,
|
||||
const VariableNameMap &outputs,
|
||||
const AttributeMap &attrs)
|
||||
: OperatorBase(type, inputs, outputs, attrs) {}
|
||||
|
||||
private:
|
||||
void RunImpl(const Scope &scope, const phi::Place &place) const override {
|
||||
// Fake RunImpl, for test only
|
||||
Variable *var = scope.FindVar("X");
|
||||
if (var != nullptr) {
|
||||
phi::DenseTensor *tensor = var->GetMutable<phi::DenseTensor>();
|
||||
tensor->mutable_data<float>(place);
|
||||
}
|
||||
int count = 0;
|
||||
while (count <= 1000) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
||||
|
||||
REGISTER_OPERATOR(fake_test_op,
|
||||
paddle::framework::FakeTestOp,
|
||||
paddle::framework::FakeTestOpMaker);
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
|
||||
ProgramDesc CreateTestProgram() {
|
||||
// create a ProgramDesc:
|
||||
// Z = fake_test_op(X, Y)
|
||||
// Out = fake_test_op(Z, W)
|
||||
ProgramDesc program;
|
||||
auto *global_block = program.MutableBlock(0);
|
||||
|
||||
auto *x = global_block->Var("X");
|
||||
x->SetType(proto::VarType::DENSE_TENSOR);
|
||||
x->SetLoDLevel(0);
|
||||
x->SetDataType(proto::VarType::FP32);
|
||||
x->SetShape({1000, 784});
|
||||
|
||||
auto *y = global_block->Var("Y");
|
||||
y->SetType(proto::VarType::DENSE_TENSOR);
|
||||
y->SetLoDLevel(0);
|
||||
y->SetDataType(proto::VarType::FP32);
|
||||
y->SetShape({784, 100});
|
||||
|
||||
auto *op0 = global_block->AppendOp();
|
||||
op0->SetType("fake_test_op");
|
||||
op0->SetInput("X", {x->Name()});
|
||||
op0->SetInput("Y", {y->Name()});
|
||||
|
||||
auto *z = global_block->Var("Z");
|
||||
z->SetType(proto::VarType::DENSE_TENSOR);
|
||||
op0->SetOutput("Out", {z->Name()});
|
||||
|
||||
auto *w = global_block->Var("W");
|
||||
w->SetType(proto::VarType::DENSE_TENSOR);
|
||||
w->SetLoDLevel(0);
|
||||
w->SetDataType(proto::VarType::FP32);
|
||||
w->SetShape({100, 10});
|
||||
|
||||
auto *op1 = global_block->AppendOp();
|
||||
op1->SetType("fake_test_op");
|
||||
op1->SetInput("X", {z->Name()});
|
||||
op1->SetInput("Y", {w->Name()});
|
||||
|
||||
auto *out = global_block->Var("Out");
|
||||
out->SetType(proto::VarType::DENSE_TENSOR);
|
||||
op1->SetOutput("Out", {out->Name()});
|
||||
return program;
|
||||
}
|
||||
|
||||
TEST(CostModelTest, TestProfileMeasure_EmptyProgram) {
|
||||
CostModel cost_model;
|
||||
ProgramDesc empty_program;
|
||||
CostData cost_data =
|
||||
cost_model.ProfileMeasure(empty_program, empty_program, "cpu", {"time"});
|
||||
EXPECT_EQ(cost_data.GetWholeTimeMs(), 0);
|
||||
}
|
||||
|
||||
TEST(CostModelTest, TestProfileMeasure_Program) {
|
||||
CostModel cost_model;
|
||||
ProgramDesc program = CreateTestProgram();
|
||||
ProgramDesc empty_program;
|
||||
CostData cost_data =
|
||||
cost_model.ProfileMeasure(program, empty_program, "cpu", {"time"});
|
||||
double op0_time_ms = cost_data.GetOpTimeMs(0);
|
||||
double op1_time_ms = cost_data.GetOpTimeMs(1);
|
||||
EXPECT_GT(op0_time_ms, 0);
|
||||
EXPECT_GT(op1_time_ms, 0);
|
||||
EXPECT_GT(cost_data.GetWholeTimeMs(), op0_time_ms + op1_time_ms);
|
||||
}
|
||||
|
||||
TEST(CostModelTest, TestProfileMeasure_UnsupportedDevice) {
|
||||
CostModel cost_model;
|
||||
ProgramDesc program = CreateTestProgram();
|
||||
ProgramDesc empty_program;
|
||||
|
||||
EXPECT_THROW(cost_model.ProfileMeasure(
|
||||
program, empty_program, "wrong_device", {"time"}),
|
||||
paddle::platform::EnforceNotMet);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestGetGraphProgram) {
|
||||
CostData cost_data;
|
||||
EXPECT_EQ(cost_data.GetGraph(), nullptr);
|
||||
EXPECT_EQ(cost_data.GetProgram(), nullptr);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestUninitialized) {
|
||||
CostData cost_data;
|
||||
EXPECT_EQ(cost_data.GetWholeMemoryBytes(), CostData::NOT_MEASURED);
|
||||
EXPECT_EQ(cost_data.GetWholeTimeMs(), CostData::NOT_MEASURED);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestEmptyProgram) {
|
||||
CostData cost_data;
|
||||
ProgramDesc empty_program("");
|
||||
EXPECT_EQ(cost_data.SetCostData(empty_program, {}), true);
|
||||
EXPECT_EQ(cost_data.GetWholeMemoryBytes(), 0);
|
||||
EXPECT_EQ(cost_data.GetWholeTimeMs(), 0);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestEmptyTimeEvent) {
|
||||
CostData cost_data;
|
||||
ProgramDesc program = CreateTestProgram();
|
||||
EXPECT_EQ(cost_data.SetCostData(program, {}), false);
|
||||
EXPECT_EQ(cost_data.GetWholeMemoryBytes(), CostData::NOT_MEASURED);
|
||||
EXPECT_EQ(cost_data.GetWholeTimeMs(), CostData::NOT_MEASURED);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestNoOpEvent) {
|
||||
CostData cost_data;
|
||||
ProgramDesc program = CreateTestProgram();
|
||||
std::vector<phi::Event> thread_events;
|
||||
thread_events.push_back(
|
||||
phi::Event(phi::EventType::kPushRange, "not exist name", 0));
|
||||
std::vector<std::vector<phi::Event>> time_events{thread_events};
|
||||
EXPECT_EQ(cost_data.SetCostData(program, time_events), false);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestNoOpPopEvent) {
|
||||
CostData cost_data;
|
||||
ProgramDesc program = CreateTestProgram();
|
||||
std::vector<phi::Event> thread_events;
|
||||
thread_events.push_back(
|
||||
phi::Event(phi::EventType::kPushRange, "fake_test_op", 0));
|
||||
std::vector<std::vector<phi::Event>> time_events{thread_events};
|
||||
EXPECT_EQ(cost_data.SetCostData(program, time_events), false);
|
||||
}
|
||||
|
||||
TEST(CostDataTest, TestNoWholeEvent) {
|
||||
CostData cost_data;
|
||||
ProgramDesc program = CreateTestProgram();
|
||||
std::vector<phi::Event> thread_events;
|
||||
thread_events.push_back(
|
||||
phi::Event(phi::EventType::kPushRange, "fake_test_op", 0));
|
||||
thread_events.push_back(
|
||||
phi::Event(phi::EventType::kPopRange, "fake_test_op", 0));
|
||||
thread_events.push_back(
|
||||
phi::Event(phi::EventType::kPushRange, "fake_test_op", 0));
|
||||
thread_events.push_back(
|
||||
phi::Event(phi::EventType::kPopRange, "fake_test_op", 0));
|
||||
std::vector<std::vector<phi::Event>> time_events{thread_events};
|
||||
EXPECT_EQ(cost_data.SetCostData(program, time_events), false);
|
||||
}
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
||||
Reference in New Issue
Block a user