| 1227 | } |
| 1228 | |
| 1229 | Status FunctionLibraryDefinition::AddLibrary( |
| 1230 | const FunctionLibraryDefinition& other) { |
| 1231 | // Clone `other` to ensure thread-safety (grabbing `other`'s lock for |
| 1232 | // the duration of the function could lead to deadlock). |
| 1233 | FunctionLibraryDefinition clone(other); |
| 1234 | mutex_lock l(mu_); |
| 1235 | mutex_lock l2(clone.mu_); |
| 1236 | // Remember the funcs and grads that we added successfully so that |
| 1237 | // we can roll them back on error. |
| 1238 | std::vector<string> funcs; |
| 1239 | std::vector<string> funcs_with_grads; |
| 1240 | Status s; |
| 1241 | bool added; |
| 1242 | for (auto iter : clone.function_defs_) { |
| 1243 | s = AddHelper(iter.second, &added); |
| 1244 | if (!s.ok()) { |
| 1245 | Remove(funcs, funcs_with_grads); |
| 1246 | return s; |
| 1247 | } |
| 1248 | if (added) { |
| 1249 | funcs.push_back(iter.second->fdef.signature().name()); |
| 1250 | } |
| 1251 | } |
| 1252 | for (auto iter : clone.func_grad_) { |
| 1253 | GradientDef grad; |
| 1254 | grad.set_function_name(iter.first); |
| 1255 | grad.set_gradient_func(iter.second); |
| 1256 | s = AddGradientDefHelper(grad, &added); |
| 1257 | if (!s.ok()) { |
| 1258 | Remove(funcs, funcs_with_grads); |
| 1259 | return s; |
| 1260 | } |
| 1261 | if (added) { |
| 1262 | funcs_with_grads.push_back(grad.function_name()); |
| 1263 | } |
| 1264 | } |
| 1265 | return Status::OK(); |
| 1266 | } |
| 1267 | |
| 1268 | Status FunctionLibraryDefinition::AddLibrary( |
| 1269 | const FunctionDefLibrary& lib_def) { |