| 1432 | } |
| 1433 | |
| 1434 | Status AddFusedConv2DNode(RemapperContext* ctx, |
| 1435 | const ContractionWithSqueezeAndBiasAdd& matched, |
| 1436 | std::vector<bool>* invalidated_nodes, |
| 1437 | std::vector<bool>* nodes_to_delete) { |
| 1438 | DCHECK(IsDeviceCompatible(*ctx, matched)) << "Unsupported fusion pattern"; |
| 1439 | |
| 1440 | const GraphDef* graph = ctx->graph_view.graph(); |
| 1441 | const NodeDef& contraction = graph->node(matched.contraction); |
| 1442 | DCHECK(IsConv2D(contraction)) << "Only Conv2D supported for now"; |
| 1443 | |
| 1444 | const NodeDef& bias_add = graph->node(matched.bias_add); |
| 1445 | const NodeDef& squeeze = graph->node(matched.squeeze); |
| 1446 | VLOG(2) << "Fuse Conv2D with Squeeze and BiasAdd: " |
| 1447 | << " bias_add=" << bias_add.name() << " squeeze=" << squeeze.name() |
| 1448 | << " conv2d=" << contraction.name(); |
| 1449 | |
| 1450 | // Replace Conv2D node with a fused Conv2D. Matched pattern guarantees that it |
| 1451 | // has single consumer (only the squeeze node). |
| 1452 | NodeDef fused_conv2d; |
| 1453 | fused_conv2d.set_name(contraction.name()); |
| 1454 | fused_conv2d.set_op(kFusedConv2D); |
| 1455 | fused_conv2d.set_device(contraction.device()); |
| 1456 | fused_conv2d.add_input(contraction.input(0)); // 0: input |
| 1457 | fused_conv2d.add_input(contraction.input(1)); // 1: filter |
| 1458 | fused_conv2d.add_input(bias_add.input(1)); // 2: bias |
| 1459 | |
| 1460 | CopyConv2DAttributes(contraction, &fused_conv2d); |
| 1461 | SetFusedOpAttributes(&fused_conv2d, {"BiasAdd"}); |
| 1462 | |
| 1463 | // Replace BiasAdd node with a Squeeze. |
| 1464 | NodeDef remapped_squeeze = squeeze; |
| 1465 | remapped_squeeze.set_name(bias_add.name()); |
| 1466 | remapped_squeeze.set_input(0, contraction.name()); |
| 1467 | |
| 1468 | utils::Mutation* mutation = ctx->graph_view.GetMutationBuilder(); |
| 1469 | Status status; |
| 1470 | mutation->AddNode(std::move(fused_conv2d), &status); |
| 1471 | TF_RETURN_IF_ERROR(status); |
| 1472 | mutation->AddNode(std::move(remapped_squeeze), &status); |
| 1473 | TF_RETURN_IF_ERROR(status); |
| 1474 | TF_RETURN_IF_ERROR(mutation->Apply()); |
| 1475 | |
| 1476 | (*invalidated_nodes)[matched.contraction] = true; |
| 1477 | (*invalidated_nodes)[matched.bias_add] = true; |
| 1478 | (*nodes_to_delete)[matched.squeeze] = true; |
| 1479 | |
| 1480 | return Status::OK(); |
| 1481 | } |
| 1482 | |
| 1483 | Status AddFusedConv2DNode(RemapperContext* ctx, |
| 1484 | const ContractionWithBatchNorm& matched, |
no test coverage detected