| 832 | } |
| 833 | |
| 834 | bool OpDefEqual(const OpDef& o1, const OpDef& o2) { |
| 835 | // attr order doesn't matter. |
| 836 | // Compare it separately here instead of serializing below. |
| 837 | if (!RepeatedAttrDefEqual(o1.attr(), o2.attr())) return false; |
| 838 | |
| 839 | // `control_output` order doesn't matter. |
| 840 | std::set<string> control_output1(o1.control_output().begin(), |
| 841 | o1.control_output().end()); |
| 842 | std::set<string> control_output2(o2.control_output().begin(), |
| 843 | o2.control_output().end()); |
| 844 | if (control_output1 != control_output2) return false; |
| 845 | |
| 846 | // Clear `attr` and `control_output` fields, serialize, and compare serialized |
| 847 | // strings. |
| 848 | OpDef o1_copy = o1; |
| 849 | OpDef o2_copy = o2; |
| 850 | o1_copy.clear_attr(); |
| 851 | o1_copy.clear_control_output(); |
| 852 | o2_copy.clear_attr(); |
| 853 | o2_copy.clear_control_output(); |
| 854 | |
| 855 | return AreSerializedProtosEqual(o1_copy, o2_copy); |
| 856 | } |
| 857 | |
| 858 | uint64 OpDefHash(const OpDef& o) { |
| 859 | uint64 h = RepeatedAttrDefHash(o.attr()); |