message: Enable concat to work with symbolic tensors
diff: @@ -1122,7 +1122,7 @@ class Concatenate(tile.Operation):
  offsets = [0]
  for i in range(len(tensors)):
  - offsets.append(offsets[i] + tensors[i].shape.dims[axis])
  + offsets.append("+".join("A{}".format(j) for j in range(i+1)))
  out_dims = tuple(
  tensors[0].shape.dims[i] if i != axis else offsets[len(tensors)] for i in range(rank))
  @@ -1150,8 +1150,6 @@ class Concatenate(tile.Operation):
  body_str = ''
  line_subs = {'beg': indices_begin, 'end': indices_end, 'odims': output_dims_str}
  for i in range(len(tensors)):
  - # TODO: If offsets[i] is symbolic, add it to the function
  - # inputs and use it symbolically.
  line_subs['off'] = '+{}'.format(offsets[i])
  line_subs['i'] = i
  curr_line = ' T{i}[{beg}{off}{end}: {odims}] = =(I{i}[{beg}{end}]);\n'.format(
  @@ -1163,9 +1161,9 @@ class Concatenate(tile.Operation):
  # Example 'code' (concatenating (4,3,2), (4,5,2), (4,1,2)):
  # function (I0[N0, A0, N2], I1[N0, A1, N2], I2[N0, A2, N2]) -> (O) {
  - # T0[n0, a, n2: N0, 9, N2] = =(I0[n0, a, n2]);
  - # T1[n0, a+3, n2: N0, 9, N2] = =(I1[n0, a, n2]);
  - # T2[n0, a+8, n2: N0, 9, N2] = =(I2[n0, a, n2]);
  + # T0[n0, a, n2: N0, A0+A1+A2, N2] = =(I0[n0, a, n2]);
  + # T1[n0, a+A0, n2: N0, A0+A1+A2, N2] = =(I1[n0, a, n2]);
  + # T2[n0, a+A0+A1, n2: N0, A0+A1+A2, N2] = =(I2[n0, a, n2]);
  # O = T0 + T1 + T2;
  # }
  code = ('function ({inputs}) -> (O) {{\n{body}\n}}').format(
  