Skip to content

Commit f173eaf

Browse files
author
Wei Chen
committed
[Relay][Op][TF] Complete tensor array unstack with all ranks support
1 parent d2fc025 commit f173eaf

3 files changed

Lines changed: 148 additions & 3 deletions

File tree

python/tvm/relay/frontend/tensorflow.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from .common import infer_shape as _infer_shape
4141
from .common import infer_channels as _infer_channels
4242
from .common import infer_value as _infer_value
43+
from .common import infer_value_simulated as _infer_value_simulated
4344

4445
__all__ = ['from_tensorflow']
4546

@@ -1070,9 +1071,13 @@ def _impl(inputs, attr, params):
10701071
def _range():
10711072
def _impl(inputs, attr, params):
10721073
start = _get_param(params, inputs[0])[0]
1073-
limit = _get_param(params, inputs[1])[0] \
1074-
if hasattr(inputs[1], "name_hint") or isinstance(inputs[1], _expr.Constant) \
1075-
else params.pop('Rank').asnumpy()[0]
1074+
if hasattr(inputs[1], "name_hint") or isinstance(inputs[1], _expr.Constant):
1075+
limit = _get_param(params, inputs[1])[0]
1076+
else:
1077+
if any(['Rank' in param for param in params]):
1078+
limit = params.pop('Rank').asnumpy()[0]
1079+
else:
1080+
limit = _infer_value_simulated(inputs[1], params).asnumpy()[0]
10761081
delta = _get_param(params, inputs[2])[0]
10771082
dtype = attr['dtype'].name if 'dtype' in attr else "int32"
10781083
return AttrCvt(

python/tvm/relay/prelude.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,122 @@ def define_tensor_array_unstack_tensor2(self):
336336
Function([tensor2], helper_var(const(0), ndim, tensor2),
337337
self.prelude.l(self.get_var('tensor_t')()), [])
338338

339+
def define_tensor_array_unstack_tensor3(self):
340+
"""Defines a function to unstack the values of a tensor_t with rank 3 in a tensor array.
341+
342+
tensor_array_unstack_tensor3(t) : tensor_t -> list[tensor_t]
343+
"""
344+
helper_name = self.get_name("tensor_array_unstack_tensor3_helper")
345+
helper_var = GlobalVar(helper_name)
346+
setattr(self.prelude, helper_name, helper_var)
347+
tensor = Var("t", TensorType([Any(), Any(), Any()], self.dtype))
348+
up = Var("up", scalar_type('int32'))
349+
i = Var("i", scalar_type('int32'))
350+
351+
helper_body = If(equal(i, up),
352+
self.prelude.nil(),
353+
self.prelude.cons(self.get_var('tensor2')(op.take(tensor, i, axis=0)),
354+
helper_var(add(i, const(1)), up, tensor)))
355+
self.prelude.mod[helper_var] =\
356+
Function([i, up, tensor], helper_body, self.prelude.l(self.get_var('tensor_t')()), [])
357+
358+
tensor_array_unstack_tensor3_name = self.get_name("tensor_array_unstack_tensor3")
359+
tensor_array_unstack_tensor3_var = GlobalVar(tensor_array_unstack_tensor3_name)
360+
setattr(self.prelude, tensor_array_unstack_tensor3_name, tensor_array_unstack_tensor3_var)
361+
tensor3 = Var("tensor", TensorType([Any(), Any(), Any()], self.dtype))
362+
shape = op.shape_of(tensor3)
363+
ndim = op.take(shape, const(0))
364+
self.prelude.mod[tensor_array_unstack_tensor3_var] =\
365+
Function([tensor3], helper_var(const(0), ndim, tensor3),
366+
self.prelude.l(self.get_var('tensor_t')()), [])
367+
368+
def define_tensor_array_unstack_tensor4(self):
369+
"""Defines a function to unstack the values of a tensor_t with rank 4 in a tensor array.
370+
371+
tensor_array_unstack_tensor4(t) : tensor_t -> list[tensor_t]
372+
"""
373+
helper_name = self.get_name("tensor_array_unstack_tensor4_helper")
374+
helper_var = GlobalVar(helper_name)
375+
setattr(self.prelude, helper_name, helper_var)
376+
tensor = Var("t", TensorType([Any(), Any(), Any(), Any()], self.dtype))
377+
up = Var("up", scalar_type('int32'))
378+
i = Var("i", scalar_type('int32'))
379+
380+
helper_body = If(equal(i, up),
381+
self.prelude.nil(),
382+
self.prelude.cons(self.get_var('tensor3')(op.take(tensor, i, axis=0)),
383+
helper_var(add(i, const(1)), up, tensor)))
384+
self.prelude.mod[helper_var] =\
385+
Function([i, up, tensor], helper_body, self.prelude.l(self.get_var('tensor_t')()), [])
386+
387+
tensor_array_unstack_tensor4_name = self.get_name("tensor_array_unstack_tensor4")
388+
tensor_array_unstack_tensor4_var = GlobalVar(tensor_array_unstack_tensor4_name)
389+
setattr(self.prelude, tensor_array_unstack_tensor4_name, tensor_array_unstack_tensor4_var)
390+
tensor4 = Var("tensor", TensorType([Any(), Any(), Any(), Any()], self.dtype))
391+
shape = op.shape_of(tensor4)
392+
ndim = op.take(shape, const(0))
393+
self.prelude.mod[tensor_array_unstack_tensor4_var] =\
394+
Function([tensor4], helper_var(const(0), ndim, tensor4),
395+
self.prelude.l(self.get_var('tensor_t')()), [])
396+
397+
def define_tensor_array_unstack_tensor5(self):
398+
"""Defines a function to unstack the values of a tensor_t with rank 5 in a tensor array.
399+
400+
tensor_array_unstack_tensor5(t) : tensor_t -> list[tensor_t]
401+
"""
402+
helper_name = self.get_name("tensor_array_unstack_tensor5_helper")
403+
helper_var = GlobalVar(helper_name)
404+
setattr(self.prelude, helper_name, helper_var)
405+
tensor = Var("t", TensorType([Any(), Any(), Any(), Any(), Any()], self.dtype))
406+
up = Var("up", scalar_type('int32'))
407+
i = Var("i", scalar_type('int32'))
408+
409+
helper_body = If(equal(i, up),
410+
self.prelude.nil(),
411+
self.prelude.cons(self.get_var('tensor4')(op.take(tensor, i, axis=0)),
412+
helper_var(add(i, const(1)), up, tensor)))
413+
self.prelude.mod[helper_var] =\
414+
Function([i, up, tensor], helper_body, self.prelude.l(self.get_var('tensor_t')()), [])
415+
416+
tensor_array_unstack_tensor5_name = self.get_name("tensor_array_unstack_tensor5")
417+
tensor_array_unstack_tensor5_var = GlobalVar(tensor_array_unstack_tensor5_name)
418+
setattr(self.prelude, tensor_array_unstack_tensor5_name, tensor_array_unstack_tensor5_var)
419+
tensor5 = Var("tensor", TensorType([Any(), Any(), Any(), Any(), Any()], self.dtype))
420+
shape = op.shape_of(tensor5)
421+
ndim = op.take(shape, const(0))
422+
self.prelude.mod[tensor_array_unstack_tensor5_var] =\
423+
Function([tensor5], helper_var(const(0), ndim, tensor5),
424+
self.prelude.l(self.get_var('tensor_t')()), [])
425+
426+
def define_tensor_array_unstack_tensor6(self):
427+
"""Defines a function to unstack the values of a tensor_t with rank 6 in a tensor array.
428+
429+
tensor_array_unstack_tensor6(t) : tensor_t -> list[tensor_t]
430+
"""
431+
helper_name = self.get_name("tensor_array_unstack_tensor6_helper")
432+
helper_var = GlobalVar(helper_name)
433+
setattr(self.prelude, helper_name, helper_var)
434+
tensor = Var("t", TensorType([Any(), Any(), Any(), Any(), Any(), Any()], self.dtype))
435+
up = Var("up", scalar_type('int32'))
436+
i = Var("i", scalar_type('int32'))
437+
438+
helper_body = If(equal(i, up),
439+
self.prelude.nil(),
440+
self.prelude.cons(self.get_var('tensor5')(op.take(tensor, i, axis=0)),
441+
helper_var(add(i, const(1)), up, tensor)))
442+
self.prelude.mod[helper_var] =\
443+
Function([i, up, tensor], helper_body, self.prelude.l(self.get_var('tensor_t')()), [])
444+
445+
tensor_array_unstack_tensor6_name = self.get_name("tensor_array_unstack_tensor6")
446+
tensor_array_unstack_tensor6_var = GlobalVar(tensor_array_unstack_tensor6_name)
447+
setattr(self.prelude, tensor_array_unstack_tensor6_name, tensor_array_unstack_tensor6_var)
448+
tensor6 = Var("tensor", TensorType([Any(), Any(), Any(), Any(), Any(), Any()], self.dtype))
449+
shape = op.shape_of(tensor6)
450+
ndim = op.take(shape, const(0))
451+
self.prelude.mod[tensor_array_unstack_tensor6_var] =\
452+
Function([tensor6], helper_var(const(0), ndim, tensor6),
453+
self.prelude.l(self.get_var('tensor_t')()), [])
454+
339455
def define_tensor_array_scatter(self):
340456
"""Defines a function to scatter the values of a tensor_t in indices of a tensor array.
341457
tensor_array_scatter(ta, indices, value) :
@@ -516,6 +632,10 @@ def register(self):
516632
self.define_tensor_array_write()
517633
self.define_tensor_array_unstack_tensor1()
518634
self.define_tensor_array_unstack_tensor2()
635+
self.define_tensor_array_unstack_tensor3()
636+
self.define_tensor_array_unstack_tensor4()
637+
self.define_tensor_array_unstack_tensor5()
638+
self.define_tensor_array_unstack_tensor6()
519639
self.define_tensor_array_scatter()
520640
self.define_tensor_array_split()
521641
self.define_tensor_array_concat()

tests/python/frontend/tensorflow/test_forward.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,26 @@ def run(dtype_str):
750750
for dtype in tf_dtypes.keys():
751751
run(dtype)
752752

753+
def test_tensor_array_unstack():
754+
def run(dtype_str, input_shape):
755+
with tf.Graph().as_default():
756+
dtype = tf_dtypes[dtype_str]
757+
t = tf.constant(np.random.choice([0, 1, 2, 3],
758+
size=input_shape).astype(dtype.name))
759+
ta1 = tf.TensorArray(dtype=dtype, infer_shape=False, size=input_shape[0])
760+
ta2 = ta1.unstack(t)
761+
out0 = ta2.size()
762+
out1 = ta2.read(0)
763+
compare_tf_with_tvm([], [], 'TensorArraySizeV3:0', mode='debug')
764+
compare_tf_with_tvm([], [], 'TensorArrayReadV3:0', mode='debug')
765+
for dtype in tf_dtypes.keys():
766+
run(dtype, (5,))
767+
run(dtype, (5, 5))
768+
run(dtype, (5, 5, 5))
769+
run(dtype, (5, 5, 5, 5))
770+
run(dtype, (5, 5, 5, 5, 5))
771+
run(dtype, (5, 5, 5, 5, 5, 5))
772+
753773
#######################################################################
754774
# ConcatV2
755775
# --------

0 commit comments

Comments
 (0)