Skip to content

Commit 265929c

Browse files
committed
CumConcatLayer more (finished?)
1 parent 8bb54a0 commit 265929c

1 file changed

Lines changed: 26 additions & 14 deletions

File tree

returnn/tf/layers/rec.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8542,8 +8542,10 @@ def __init__(self, new_dim, **kwargs):
85428542
:param DimensionTag new_dim:
85438543
"""
85448544
super(CumConcatLayer, self).__init__(**kwargs)
8545-
assert self.network.is_inside_rec_layer()
8545+
rec_layer = self.network.get_rec_parent_layer(inside_loop=False)
8546+
assert rec_layer, "%r must be used inside a RecLayer" % self
85468547
out_axis = self.output.get_axis_from_description(new_dim)
8548+
new_dim_ = self.output.dim_tags[out_axis]
85478549

85488550
if self.network.is_inside_rec_layer(inside_loop=True):
85498551
current_data = self.input_data.copy_compatible_to(self.output, unbroadcast=False)
@@ -8553,21 +8555,31 @@ def __init__(self, new_dim, **kwargs):
85538555
self.rec_vars_outputs["state"] = concat_frames
85548556
self.output.placeholder = concat_frames
85558557

8556-
dyn_size = tf.broadcast_to(self.network.get_rec_step_index() + 1, [data.get_batch_dim()])
8558+
if not new_dim_.dyn_size_ext:
8559+
# Unbroadcasting to [B] is not needed because any layers operating on this
8560+
# should be able to handle extended dyn sizes.
8561+
# Clipping it to the max length for sequences in the loop which are already ended
8562+
# (i.e. considering the end flag)
8563+
# is also not needed because any calculations after the end are irrelevant.
8564+
dyn_size = self.network.get_rec_step_index() + 1 # scalar
8565+
new_dim_.dyn_size_ext = Data(
8566+
name="%s:cum-concat:size-inside" % self.name,
8567+
dim_tags=[], # scalar
8568+
placeholder=dyn_size)
85578569

85588570
else:
8559-
# If not inside a rec loop, this layer is a no-op
8560-
self.output.placeholder = None # TODO
8561-
data.size_placeholder = self.input_data.size_placeholder.copy()
8562-
dyn_size = tf.identity(data.get_dynamic_size(out_axis))
8563-
8564-
# We already set the size_placeholder to a dummy rec-history before, now do it properly
8565-
from returnn.tf.util.basic import DimensionTag
8566-
tag = DimensionTag(
8567-
description="rec-history:%s" % self.get_absolute_name(),
8568-
kind=DimensionTag.Types.Time)
8569-
data.size_placeholder[data.get_batch_axis_excluding_batch(out_axis)] = dyn_size
8570-
tag.set_tag_on_size_tensor(dyn_size)
8571+
# If not inside a rec loop, this layer is a no-op on the tensor.
8572+
self.output.placeholder = self.input_data.placeholder
8573+
8574+
# However, we used new dim tags, which were already prepared.
8575+
# We now must fill in the extended dynamic size information.
8576+
if not new_dim_.dyn_size_ext:
8577+
# This must match the logic above for inside the loop.
8578+
dyn_size = tf.range(tf.math.reduce_max(rec_layer.time_dim_tag.dyn_size)) + 1 # [T]
8579+
new_dim_.dyn_size_ext = Data(
8580+
name="%s:cum-concat:size-outside" % self.name,
8581+
dim_tags=[rec_layer.time_dim_tag],
8582+
placeholder=dyn_size)
85718583

85728584
@classmethod
85738585
def get_out_data_from_opts(cls, name, network, sources, new_dim, **kwargs):

0 commit comments

Comments
 (0)