Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
2742195759 committed Nov 16, 2021
1 parent 553295a commit 1602b10
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 93 deletions.
96 changes: 3 additions & 93 deletions paddle/fluid/framework/new_executor/interpretercore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,108 +77,18 @@ paddle::framework::FetchList InterpreterCore::Run(
return *(fetch_var->GetMutable<framework::FetchList>());
}

void update_var_min_rw_op(const std::map<int, std::set<int>>& op2dependences,
std::map<int, std::list<int>>& var2min_rw_op,
int cur_op, int rw_var) {
// rw_var is inputs or outputs of cur_op
// this function update the var2min_rw_op set .
if (var2min_rw_op.find(rw_var) == var2min_rw_op.end())
var2min_rw_op[rw_var] = std::list<int>();
for (auto dep_op : op2dependences.at(cur_op)) {
var2min_rw_op[rw_var].remove(dep_op);
}
var2min_rw_op[rw_var].push_back(cur_op);
}

std::map<int, std::list<int>> get_downstream_map(
const std::map<int, std::set<int>>& op2dependences) {
// op2dependences is op -> it's dependences. we want to get op -> [ops] map,
// where ops is the next instruction of op.
std::map<int, std::list<int>> result;
for (auto& item : op2dependences) {
int op = item.first;
for (auto dep_op : item.second) {
if (result.find(dep_op) == result.end())
result[dep_op] = std::list<int>();
result[dep_op].push_back(op);
}
}
return std::move(result);
}

void InterpreterCore::BuildOperatorDependences() {
// set the dependecy_count_ and Call Schedule
// refer to http://agroup.baidu.com/share/md/92946214aa4c4785a2cc4c1f361a023c
// for pesudo code
// analysis the dependences between ops, set the dependecy_count_ and Call
// Schedule
auto op_nums = vec_instruction_.size();
auto var2min_rw_op = std::map<
int, std::list<int>>(); // # map from variable id to read / write op id.
auto var2recent_write_op =
std::map<int, int>(); // # map from variable to recent write op.
auto op2dependences =
std::map<int, std::set<int>>(); //# map from op to the dependence list,
// op must run after the dependence.
std::set<int> remove_duplicate;

// reserve
for (size_t op = 0; op < vec_instruction_.size(); ++op) {
op2dependences[op] = std::set<int>();
}
dependecy_count_.resize(op_nums);

for (size_t op = 0; op < vec_instruction_.size(); ++op) {
remove_duplicate.clear();
// step1: update the op2dependences structure
for (auto& item :
vec_instruction_[op].Inputs()) { // for all inputs(read only)
for (auto var : item.second) {
if (var2recent_write_op.count(var))
op2dependences[op].insert(var2recent_write_op[var]);
}
}

for (auto& item : vec_instruction_[op].Outputs()) { // for all write vars
for (auto var : item.second) {
if (var2min_rw_op.count(var)) {
for (auto dep_op : var2min_rw_op[var]) {
op2dependences[op].insert(dep_op);
}
}
}
}

// step2: update 2 var2xxxx data structure
for (auto& item :
vec_instruction_[op].Inputs()) { // for all inputs(read only)
for (auto var : item.second) {
update_var_min_rw_op(op2dependences, var2min_rw_op, op, var);
remove_duplicate.insert(var);
}
}

for (auto& item : vec_instruction_[op].Outputs()) { // for all write vars
for (auto var : item.second) {
var2recent_write_op[var] = op;
if (remove_duplicate.count(var) ==
0) { // var in input list and in output list, so remove it.
update_var_min_rw_op(op2dependences, var2min_rw_op, op, var);
}
}
}
}

auto op2downstream = get_downstream_map(op2dependences);

VLOG(5) << "the size of vec_instruction_ : " << vec_instruction_.size();

auto op2downstream = interpreter::build_op_downstream_map(vec_instruction_);
for (size_t op = 0; op < vec_instruction_.size(); ++op) {
VLOG(5) << "the op2downstream : " << op;
auto op_list = op2downstream[op];
std::vector<size_t> downsteam_vector(op_list.begin(), op_list.end());
stream_analyzer_.Schedule(downsteam_vector, &vec_instruction_, op);

for (auto inst_id : op_list) {
VLOG(5) << "\t " << inst_id;
dependecy_count_[inst_id]++;
}
}
Expand Down
91 changes: 91 additions & 0 deletions paddle/fluid/framework/new_executor/interpretercore_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,97 @@ std::vector<size_t> merge_vector(const std::vector<size_t>& first,
return out;
}

void update_var_min_rw_op(const std::map<int, std::set<int>>& op2dependences,
std::map<int, std::list<int>>& var2min_rw_op,
int cur_op, int rw_var) {
// rw_var is inputs or outputs of cur_op
// this function update the var2min_rw_op set .
if (var2min_rw_op.find(rw_var) == var2min_rw_op.end())
var2min_rw_op[rw_var] = std::list<int>();
for (auto dep_op : op2dependences.at(cur_op)) {
var2min_rw_op[rw_var].remove(dep_op);
}
var2min_rw_op[rw_var].push_back(cur_op);
}

std::map<int, std::list<int>> get_downstream_map(
const std::map<int, std::set<int>>& op2dependences) {
// op2dependences is op -> it's dependences. we want to get op -> [ops] map,
// where ops is the next instruction of op.
std::map<int, std::list<int>> result;
for (auto& item : op2dependences) {
int op = item.first;
for (auto dep_op : item.second) {
if (result.find(dep_op) == result.end())
result[dep_op] = std::list<int>();
result[dep_op].push_back(op);
}
}
return std::move(result);
}

std::map<int, std::list<int>> build_op_downstream_map(
const std::vector<Instruction>& vec_instruction) {
auto var2min_rw_op = std::map<
int, std::list<int>>(); // # map from variable id to read / write op id.
auto var2recent_write_op =
std::map<int, int>(); // # map from variable to recent write op.
auto op2dependences =
std::map<int, std::set<int>>(); //# map from op to the dependence list,
// op must run after the dependence.
std::set<int>
remove_duplicate; // remove the duplicate between inputs and outputs

// reserve
for (size_t op_idx = 0; op_idx < vec_instruction.size(); ++op_idx) {
op2dependences[op_idx] = std::set<int>();
}

for (size_t op_idx = 0; op_idx < vec_instruction.size(); ++op_idx) {
remove_duplicate.clear();
// step1: update the op2dependences structure
for (auto& item :
vec_instruction[op_idx].Inputs()) { // for all inputs(read only)
for (auto var : item.second) {
if (var2recent_write_op.count(var))
op2dependences[op_idx].insert(var2recent_write_op[var]);
}
}

for (auto& item :
vec_instruction[op_idx].Outputs()) { // for all write vars
for (auto var : item.second) {
if (var2min_rw_op.count(var)) {
for (auto dep_op : var2min_rw_op[var]) {
op2dependences[op_idx].insert(dep_op);
}
}
}
}

// step2: update 2 var2xxxx data structure
for (auto& item :
vec_instruction[op_idx].Inputs()) { // for all inputs(read only)
for (auto var : item.second) {
update_var_min_rw_op(op2dependences, var2min_rw_op, op_idx, var);
remove_duplicate.insert(var);
}
}

for (auto& item :
vec_instruction[op_idx].Outputs()) { // for all write vars
for (auto var : item.second) {
var2recent_write_op[var] = op_idx;
if (remove_duplicate.count(var) ==
0) { // var in input list and in output list, so remove it.
update_var_min_rw_op(op2dependences, var2min_rw_op, op_idx, var);
}
}
}
}
return std::move(get_downstream_map(op2dependences));
}

} // namespace interpreter
} // namespace framework
} // namespace paddle
3 changes: 3 additions & 0 deletions paddle/fluid/framework/new_executor/interpretercore_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ void build_op_func_list(const platform::Place& place,
std::vector<OpFuncNode>* vec_func_list,
VariableScope* var_scope);

std::map<int, std::list<int>> build_op_downstream_map(
const std::vector<Instruction>& vec_instruction);

void add_fetch(const std::vector<std::string>& fetch_names,
framework::BlockDesc* block);

Expand Down

1 comment on commit 1602b10

@paddle-bot-old
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulation! Your pull request passed all required CI. You could ask reviewer(s) to approve and merge. 🎉

Please sign in to comment.