Rewrite graph to add `.flat_map(lambda x: tf.data.Dataset.from_tensor_slices(x). batch(minibatch_size, drop_remainder=False))` after the batch node. This ensures that the sum of the minibatch sizes in a step adds up to the global batch size. However, since this adds additional data copies (both from_tensor_slices and batch), we only use this approach when necessary, i.e. when we need to drop remai
| 511 | // global batch, or when the global batch size does not divide num_replicas |
| 512 | // evenly. |
| 513 | Status AppendFlatMap(const NodeDef& batch_node, int64 num_replicas, |
| 514 | FunctionLibraryDefinition* flib, MutableGraphView* graph) { |
| 515 | // `.flat_map(lambda x: tf.data.Dataset.from_tensor_slices(x). |
| 516 | // batch(minibatch_size, drop_remainder=False))` |
| 517 | FunctionDef flat_map_fn; |
| 518 | FunctionDefLibrary lib = flib->ToProto(); |
| 519 | graph_utils::SetUniqueGraphFunctionName("rebatch/flat_map_fn", &lib, |
| 520 | &flat_map_fn); |
| 521 | DataTypeVector dtypes; |
| 522 | TF_RETURN_IF_ERROR( |
| 523 | graph_utils::GetDatasetOutputTypesAttr(batch_node, &dtypes)); |
| 524 | TF_RETURN_IF_ERROR( |
| 525 | CreateFlatMapFnWithBatch(dtypes, num_replicas, &flat_map_fn)); |
| 526 | |
| 527 | NodeDef* flat_map_node; |
| 528 | |
| 529 | AttrValue output_shapes = batch_node.attr().at(kOutputShapesAttr); |
| 530 | for (auto& shape : *output_shapes.mutable_list()->mutable_shape()) { |
| 531 | if (!shape.unknown_rank() && shape.dim(0).size() != -1) { |
| 532 | // Because the flat map function uses drop_remainder = False, |
| 533 | // the shape might be unknown |
| 534 | auto old_dim = shape.dim(0).size(); |
| 535 | auto new_dim = old_dim % num_replicas == 0 ? old_dim / num_replicas : -1; |
| 536 | shape.mutable_dim(0)->set_size(new_dim); |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | TF_RETURN_IF_ERROR(AddFlatMapNode(strings::StrCat(batch_node.name(), ":0"), |
| 541 | {}, {}, flat_map_fn, output_shapes, dtypes, |
| 542 | flib, graph, &flat_map_node)); |
| 543 | |
| 544 | TF_RETURN_IF_ERROR( |
| 545 | graph->UpdateFanouts(batch_node.name(), flat_map_node->name())); |
| 546 | |
| 547 | return Status::OK(); |
| 548 | } |
| 549 | |
| 550 | // There are several things we do here, depending on the values of |
| 551 | // batch_size and drop_remainder. |
no test coverage detected