Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion python/tvm/relax/frontend/torch/base_fx_graph_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2112,7 +2112,26 @@ def _broadcast_to(self, node: fx.Node) -> relax.Var:
def _cat(self, node: fx.Node) -> relax.Var:
args = self.retrieve_args(node)
axis = args[1] if len(node.args) > 1 else node.kwargs.get("dim", 0)
return self.block_builder.emit(relax.op.concat(args[0], axis=axis))
tensors = args[0]

filtered = []
for t in tensors:
shape = self.shape_of(t)
if shape is not None and len(shape) == 1:
dim0 = self._static_dim(shape[0])
if dim0 == 0:
continue
filtered.append(t)

if not filtered:
# Passes args[0] to relax.op.concat
filtered = tensors

if len(filtered) == 1:
# Returns the only tensor that is not a 1D empty tensor
return filtered[0]

return self.block_builder.emit(relax.op.concat(filtered, axis=axis))

def _chunk(self, node: fx.Node) -> relax.Var:
x = self.env[node.args[0]]
Expand Down
19 changes: 19 additions & 0 deletions tests/python/relax/test_frontend_from_exported_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -4987,6 +4987,10 @@ class Cat1(Module):
def forward(self, x, y):
return torch.cat((x, y), dim=1)

class Cat2(Module):
def forward(self, x, y):
return torch.cat((x, y), dim=0)

@I.ir_module
class Expected1:
@R.function
Expand All @@ -5013,9 +5017,24 @@ def main(
R.output(gv)
return gv

# Expected IR: Concatenate a 1D empty tensor with any tensor
@I.ir_module
class Expected3:
@R.function
def main(
inp_0: R.Tensor((0,), dtype="float32"),
inp_1: R.Tensor((2, 3), dtype="float32"),
) -> R.Tuple(R.Tensor((2, 3), dtype="float32")):
with R.dataflow():
gv: R.Tuple(R.Tensor((2, 3), dtype="float32")) = (inp_1,)
R.output(gv)
return gv

example_args = (torch.randn(2, 3, dtype=torch.float32), torch.randn(2, 3, dtype=torch.float32))
example_args_empty = (torch.tensor([], dtype=torch.float32), torch.randn(2, 3, dtype=torch.float32))
verify_model(Cat0(), example_args, {}, Expected1)
verify_model(Cat1(), example_args, {}, Expected2)
verify_model(Cat2(), example_args_empty, {}, Expected3)


def test_cumsum():
Expand Down
14 changes: 14 additions & 0 deletions tests/python/relax/test_frontend_from_fx.py
Original file line number Diff line number Diff line change
Expand Up @@ -5110,10 +5110,24 @@ def main(
R.output(gv)
return gv

# Expected IR: Concatenate a 1D empty tensor with any tensor
@I.ir_module
class Expected3:
@R.function
def main(
inp_0: R.Tensor((0,), dtype="float32"),
inp_1: R.Tensor((2, 3), dtype="float32"),
) -> R.Tensor((2, 3), dtype="float32"):
with R.dataflow():
gv: R.Tensor((2, 3), dtype="float32") = inp_1
R.output(gv)
return gv

verify_model(Cat0(), [([2, 3], "float32"), ([2, 3], "float32")], {}, Expected1)
verify_model(Cat1(), [([2, 3], "float32"), ([2, 3], "float32")], {}, Expected2)
verify_model(Cat2(), [([2, 3], "float32"), ([2, 3], "float32")], {}, Expected2)
verify_model(Cat3(), [([2, 3], "float32"), ([2, 3], "float32")], {}, Expected1)
verify_model(Cat3(), [([0], "float32"), ([2, 3], "float32")], {}, Expected3)


def test_max():
Expand Down