| 164 | } |
| 165 | |
| 166 | void AttrBuilder::FillAttrValueMap(AttrValueMap* m, |
| 167 | bool include_those_in_node_def) const { |
| 168 | for (const auto& p : int_attrs_) { |
| 169 | SetInAttrValueMap(m, p.first, p.second); |
| 170 | } |
| 171 | for (const auto& p : float_attrs_) { |
| 172 | SetInAttrValueMap(m, p.first, p.second); |
| 173 | } |
| 174 | for (const auto& p : bool_attrs_) { |
| 175 | SetInAttrValueMap(m, p.first, p.second); |
| 176 | } |
| 177 | for (const auto& p : type_attrs_) { |
| 178 | SetInAttrValueMap(m, p.first, p.second); |
| 179 | } |
| 180 | if (include_those_in_node_def && node_def_ != nullptr) { |
| 181 | for (AttrValueMap::const_iterator it = node_def_->attr().begin(); |
| 182 | it != node_def_->attr().end(); ++it) { |
| 183 | m->insert(*it); |
| 184 | } |
| 185 | } |
| 186 | // For any attr-value pairs that exist in the op def (from op registry) but |
| 187 | // not `m`, fill them into `m`, so that we can run a TFE_Op without having to |
| 188 | // specify all the default attr values (e.g. for matmul, the `transpose_a` |
| 189 | // attr defaults to false). |
| 190 | const OpDef* op_def = nullptr; |
| 191 | Status s = OpDefForOp(op_name_.c_str(), &op_def); |
| 192 | // This is expected, if this op is a custom function, and is therefore not |
| 193 | // present in the op registry. |
| 194 | if (!s.ok()) return; |
| 195 | |
| 196 | DCHECK(op_def); |
| 197 | for (const auto& attr_def : op_def->attr()) { |
| 198 | if (attr_def.has_default_value() && !m->count(attr_def.name())) { |
| 199 | SetInAttrValueMap(m, attr_def.name(), attr_def.default_value()); |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | const NodeDef& AttrBuilder::BuildNodeDef() { |
| 205 | if (node_def_finalized_) return *node_def_; |