[XLA:Tool] Make Hlo parser report the location of the already defined instrucion/computation.
PiperOrigin-RevId: 185213461
This commit is contained in:
parent
7a5d775685
commit
816f59e6ab
@ -220,10 +220,13 @@ class HloParser {
|
|||||||
bool AddComputation(const string& name, HloComputation* computation,
|
bool AddComputation(const string& name, HloComputation* computation,
|
||||||
LocTy name_loc);
|
LocTy name_loc);
|
||||||
|
|
||||||
// The map from the instruction name to the instruction. This does not own the
|
// The map from the instruction/computation name to the
|
||||||
// instructions.
|
// instruction/computation itself and it's location. This does not own the
|
||||||
std::unordered_map<string, HloInstruction*> instruction_pool_;
|
// pointers.
|
||||||
std::unordered_map<string, HloComputation*> computation_pool_;
|
std::unordered_map<string, std::pair<HloInstruction*, LocTy>>
|
||||||
|
instruction_pool_;
|
||||||
|
std::unordered_map<string, std::pair<HloComputation*, LocTy>>
|
||||||
|
computation_pool_;
|
||||||
|
|
||||||
HloLexer lexer_;
|
HloLexer lexer_;
|
||||||
std::unique_ptr<HloModule> module_;
|
std::unique_ptr<HloModule> module_;
|
||||||
@ -340,15 +343,16 @@ bool HloParser::ParseComputation(HloComputation** entry_computation) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HloInstruction* root =
|
std::pair<HloInstruction*, LocTy>* root_node =
|
||||||
tensorflow::gtl::FindPtrOrNull(instruction_pool_, root_name);
|
tensorflow::gtl::FindOrNull(instruction_pool_, root_name);
|
||||||
// This means some instruction was marked as ROOT but we didn't find it in the
|
// This means some instruction was marked as ROOT but we didn't find it in the
|
||||||
// pool, which should not happen.
|
// pool, which should not happen.
|
||||||
if (!root_name.empty() && root == nullptr) {
|
if (!root_name.empty() && root_node == nullptr) {
|
||||||
LOG(FATAL) << "instruction " << root_name
|
LOG(FATAL) << "instruction " << root_name
|
||||||
<< " was marked as ROOT but the parser has not seen it before";
|
<< " was marked as ROOT but the parser has not seen it before";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HloInstruction* root = root_node == nullptr ? nullptr : root_node->first;
|
||||||
// Now root can be either an existing instruction or a nullptr. If it's a
|
// Now root can be either an existing instruction or a nullptr. If it's a
|
||||||
// nullptr, the implementation of Builder will set the last instruction as
|
// nullptr, the implementation of Builder will set the last instruction as
|
||||||
// root instruction.
|
// root instruction.
|
||||||
@ -1229,13 +1233,13 @@ bool HloParser::ParseInstructionNames(
|
|||||||
if (!ParseName(&name)) {
|
if (!ParseName(&name)) {
|
||||||
return Error(loc, "expects a instruction name");
|
return Error(loc, "expects a instruction name");
|
||||||
}
|
}
|
||||||
HloInstruction* instr =
|
std::pair<HloInstruction*, LocTy>* instr =
|
||||||
tensorflow::gtl::FindPtrOrNull(instruction_pool_, name);
|
tensorflow::gtl::FindOrNull(instruction_pool_, name);
|
||||||
if (!instr) {
|
if (!instr) {
|
||||||
return TokenError(
|
return TokenError(
|
||||||
Printf("instruction '%s' is not defined", name.c_str()));
|
Printf("instruction '%s' is not defined", name.c_str()));
|
||||||
}
|
}
|
||||||
instructions->push_back(instr);
|
instructions->push_back(instr->first);
|
||||||
} while (EatIfPresent(TokKind::kComma));
|
} while (EatIfPresent(TokKind::kComma));
|
||||||
|
|
||||||
return ParseToken(TokKind::kRbrace,
|
return ParseToken(TokKind::kRbrace,
|
||||||
@ -1705,12 +1709,12 @@ bool HloParser::ParseOperands(std::vector<HloInstruction*>* operands) {
|
|||||||
if (!ParseName(&name)) {
|
if (!ParseName(&name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HloInstruction* instruction =
|
std::pair<HloInstruction*, LocTy>* instruction =
|
||||||
tensorflow::gtl::FindPtrOrNull(instruction_pool_, name);
|
tensorflow::gtl::FindOrNull(instruction_pool_, name);
|
||||||
if (!instruction) {
|
if (!instruction) {
|
||||||
return Error(loc, StrCat("instruction does not exist: ", name));
|
return Error(loc, StrCat("instruction does not exist: ", name));
|
||||||
}
|
}
|
||||||
operands->push_back(instruction);
|
operands->push_back(instruction->first);
|
||||||
} while (EatIfPresent(TokKind::kComma));
|
} while (EatIfPresent(TokKind::kComma));
|
||||||
}
|
}
|
||||||
return ParseToken(TokKind::kRparen, "expects ')' at the end of operands");
|
return ParseToken(TokKind::kRparen, "expects ')' at the end of operands");
|
||||||
@ -1957,10 +1961,12 @@ bool HloParser::ParseComputationName(HloComputation** value) {
|
|||||||
if (!ParseName(&name)) {
|
if (!ParseName(&name)) {
|
||||||
return Error(loc, "expects computation name");
|
return Error(loc, "expects computation name");
|
||||||
}
|
}
|
||||||
*value = tensorflow::gtl::FindPtrOrNull(computation_pool_, name);
|
std::pair<HloComputation*, LocTy>* computation =
|
||||||
if (*value == nullptr) {
|
tensorflow::gtl::FindOrNull(computation_pool_, name);
|
||||||
|
if (computation == nullptr) {
|
||||||
return Error(loc, StrCat("computation does not exist: ", name));
|
return Error(loc, StrCat("computation does not exist: ", name));
|
||||||
}
|
}
|
||||||
|
*value = computation->first;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2576,18 +2582,22 @@ bool HloParser::EatIfPresent(TokKind kind) {
|
|||||||
|
|
||||||
bool HloParser::AddInstruction(const string& name, HloInstruction* instruction,
|
bool HloParser::AddInstruction(const string& name, HloInstruction* instruction,
|
||||||
LocTy name_loc) {
|
LocTy name_loc) {
|
||||||
auto result = instruction_pool_.insert({name, instruction});
|
auto result = instruction_pool_.insert({name, {instruction, name_loc}});
|
||||||
if (!result.second) {
|
if (!result.second) {
|
||||||
return Error(name_loc, StrCat("instruction already exists: ", name));
|
Error(name_loc, StrCat("instruction already exists: ", name));
|
||||||
|
return Error(/*loc=*/result.first->second.second,
|
||||||
|
"instruction previously defined here");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HloParser::AddComputation(const string& name, HloComputation* computation,
|
bool HloParser::AddComputation(const string& name, HloComputation* computation,
|
||||||
LocTy name_loc) {
|
LocTy name_loc) {
|
||||||
auto result = computation_pool_.insert({name, computation});
|
auto result = computation_pool_.insert({name, {computation, name_loc}});
|
||||||
if (!result.second) {
|
if (!result.second) {
|
||||||
return Error(name_loc, StrCat("computation already exists: ", name));
|
Error(name_loc, StrCat("computation already exists: ", name));
|
||||||
|
return Error(/*loc=*/result.first->second.second,
|
||||||
|
"computation previously defined here");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1275,6 +1275,35 @@ ENTRY consts {
|
|||||||
"one computation should have only one ROOT");
|
"one computation should have only one ROOT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(HloParserTest, InstructionExists) {
|
||||||
|
const string original = R"(HloModule comp_exists
|
||||||
|
c1 {
|
||||||
|
instr = f32[1]{0} constant({12345})
|
||||||
|
}
|
||||||
|
c2 {
|
||||||
|
instr = f32[1]{0} constant({67890})
|
||||||
|
})";
|
||||||
|
|
||||||
|
ExpectHasSubstr(Parse(original).status().error_message(),
|
||||||
|
R"(was parsing 3:3: error: instruction previously defined here
|
||||||
|
instr = f32[1]{0} constant({12345})
|
||||||
|
^)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(HloParserTest, ComputationExists) {
|
||||||
|
const string original = R"(HloModule comp_exists
|
||||||
|
comp {
|
||||||
|
const1 = f32[1]{0} constant({12345})
|
||||||
|
}
|
||||||
|
comp {
|
||||||
|
const2 = f32[1]{0} constant({67890})
|
||||||
|
})";
|
||||||
|
ExpectHasSubstr(Parse(original).status().error_message(),
|
||||||
|
R"(was parsing 2:1: error: computation previously defined here
|
||||||
|
comp {
|
||||||
|
^)");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tools
|
} // namespace tools
|
||||||
} // namespace xla
|
} // namespace xla
|
||||||
|
Loading…
Reference in New Issue
Block a user