| 1038 | } |
| 1039 | |
| 1040 | void SeqModifierForSublinearMemory::sanity_check(const OprNodeArray& opr_seq) { |
| 1041 | OperatorNodeBase* first_bad_opr = nullptr; |
| 1042 | for (auto i : opr_seq) { |
| 1043 | auto iter = m_opr2replace_info.find(i); |
| 1044 | if (iter != m_opr2replace_info.end() && iter->second.recomp && !first_bad_opr) { |
| 1045 | first_bad_opr = i; |
| 1046 | break; |
| 1047 | } |
| 1048 | } |
| 1049 | if (first_bad_opr) { |
| 1050 | VarNodeSet bad_vars[2]; |
| 1051 | std::string err_msg; |
| 1052 | size_t nr_bad_opr = 0; |
| 1053 | auto add_bad_opr = [&](int type, OperatorNodeBase* opr) { |
| 1054 | err_msg += ssprintf( |
| 1055 | " %d#%zu: %s{%s} id=%zu\n", type, nr_bad_opr++, opr->cname(), |
| 1056 | opr->dyn_typeinfo()->name, opr->id()); |
| 1057 | for (auto i : opr->input()) { |
| 1058 | err_msg += ssprintf(" inp var%zu %s\n", i->id(), i->cname()); |
| 1059 | } |
| 1060 | for (auto i : opr->output()) { |
| 1061 | bad_vars[type].insert(i); |
| 1062 | err_msg += ssprintf(" out var%zu %s\n", i->id(), i->cname()); |
| 1063 | } |
| 1064 | }; |
| 1065 | OperatorNodeBase* bad_opr[] = { |
| 1066 | first_bad_opr, m_opr2replace_info.at(first_bad_opr).recomp}; |
| 1067 | |
| 1068 | for (auto i : opr_seq) { |
| 1069 | bool bad[2] = {i == bad_opr[0], i == bad_opr[1]}; |
| 1070 | for (auto j : i->input()) { |
| 1071 | if (bad_vars[0].count(j)) { |
| 1072 | bad[0] = true; |
| 1073 | } |
| 1074 | if (bad_vars[1].count(j)) { |
| 1075 | bad[1] = true; |
| 1076 | } |
| 1077 | } |
| 1078 | if (bad[0]) { |
| 1079 | add_bad_opr(0, i); |
| 1080 | } |
| 1081 | if (bad[1]) { |
| 1082 | add_bad_opr(1, i); |
| 1083 | } |
| 1084 | } |
| 1085 | mgb_throw( |
| 1086 | InternalError, |
| 1087 | "sublinear memory: opreator input already replaced, but the " |
| 1088 | "orignal operator is still used. operator chain: {\n%s}", |
| 1089 | err_msg.c_str()); |
| 1090 | } |
| 1091 | } |
| 1092 | |
| 1093 | const CompNode::UnorderedMap<size_t>& SeqModifierForSublinearMemory:: |
| 1094 | prev_min_bottleneck() { |