function concat_(tensors, axis) {
	  if (axis === void 0) {
	    axis = 0;
	  }

	  assert(tensors.length >= 1, function () {
	    return 'Pass at least one tensor to concat';
	  });
	  var $tensors = convertToTensorArray(tensors, 'tensors', 'concat', 'string_or_numeric');

	  if ($tensors[0].dtype === 'complex64') {
	    $tensors.forEach(function (tensor) {
	      if (tensor.dtype !== 'complex64') {
	        throw new Error("Cannot concatenate complex64 tensors with a tensor\n          with dtype " + tensor.dtype + ". ");
	      }
	    });
	  }

	  if ($tensors.length === 1) {
	    return clone($tensors[0]);
	  }

	  var inputs = $tensors;
	  var attr = {
	    axis: axis
	  };
	  return ENGINE.runKernel(Concat, inputs, attr);
	}
Concatenates a list of `tf.Tensor`s along a given axis.

The tensors ranks and types must match, and their sizes must match in all
dimensions except `axis`.

Also available are stricter rank-specific methods that assert that
`tensors` are of the given rank:
  - `tf.concat1d`
  - `tf.concat2d`
  - `tf.concat3d`
  - `tf.concat4d`

Except `tf.concat1d` (which does not have axis param), all methods have
same signature as this method.

```js
const a = tf.tensor1d([1, 2]);
const b = tf.tensor1d([3, 4]);
a.concat(b).print();  // or a.concat(b)
```

```js
const a = tf.tensor1d([1, 2]);
const b = tf.tensor1d([3, 4]);
const c = tf.tensor1d([5, 6]);
tf.concat([a, b, c]).print();
```

```js
const a = tf.tensor2d([[1, 2], [10, 20]]);
const b = tf.tensor2d([[3, 4], [30, 40]]);
const axis = 1;
tf.concat([a, b], axis).print();
```
@param tensors A list of tensors to concatenate.
@param axis The axis to concate along. Defaults to 0 (the first dim).

@doc {heading: 'Tensors', subheading: 'Slicing and Joining'}