'tf.concats outputs of layers that run on the same inputs.
Args:
prev_layer: Input tensor.
index:      Position in model_str to start parsing
Returns:
Output tensor of the parallel,  end index in model_str.
Raises:
ValueError: If () are unbalanced or the elements don\'t match.'

def AddParallel(self, prev_layer, index):

    if (self.model_str[index] != '('):
        return (None, None)
    index += 1
    layers = []
    num_dims = 0
    original_factors = self.reduction_factors
    final_factors = None
    while ((index < len(self.model_str)) and (self.model_str[index] != ')')):
        self.reduction_factors = original_factors
        (layer, index) = self.BuildFromString(prev_layer, index)
        if (num_dims == 0):
            num_dims = len(layer.get_shape())
        elif (num_dims != len(layer.get_shape())):
            raise ValueError('All    elements    of    parallel    must    return    same    num    dims')
        layers.append(layer)
        if final_factors:
            if (final_factors != self.reduction_factors):
                raise ValueError('All    elements    of    parallel    must    scale    the    same')
        else:
            final_factors = self.reduction_factors
    if (index == len(self.model_str)):
        raise ValueError(('Missing    )    at    end    of    parallel!' + self.model_str))
    return (tf.concat(axis=(num_dims - 1), values=layers), (index + 1))
