Example #1
0
        public static FloatTensor Concatenate(FloatTensorFactory factory, FloatTensor[] tensors_inp, int axis, FloatTensor result = null)
        {
            FloatTensor first = tensors_inp[0];

            FloatTensor[] tensors = new FloatTensor[tensors_inp.Length - 1];
            for (int i = 0; i < tensors_inp.Length - 1; i++)
            {
                tensors[i] = tensors_inp[i + 1];
            }

            if (first.DataOnGpu)
            {
                throw new NotImplementedException("Can't concatenate GPU tensors yet");
            }

            int num_new_rows = 0;

            List <IntTensor> int_tensors_for_index_add = new List <IntTensor>();

            int[] first_indices = new int[first.Shape[axis]];
            for (int i = 0; i < first.Shape[axis]; i++)
            {
                first_indices[i] = i + num_new_rows;
            }
            int_tensors_for_index_add.Add(
                factory.ctrl.intTensorFactory.Create(_shape: new int[1] {
                first.Shape[axis]
            }, _data: first_indices));

            num_new_rows += first.Shape[axis];

            foreach (FloatTensor tensor in tensors)
            {
                if (tensor.Shape.Length != first.Shape.Length)
                {
                    throw new InvalidOperationException("Tensors do not have the same number of dimensions.");
                }

                for (int i = 0; i < tensor.Shape.Length; i++)
                {
                    if (i != axis)
                    {
                        if (tensor.Shape[i] != first.Shape[i])
                        {
                            throw new InvalidOperationException("Tensors do not have the same shape.");
                        }
                    }
                }

                if (tensor.DataOnGpu != first.DataOnGpu)
                {
                    throw new InvalidOperationException("All tensors must be on the same device...");
                }

                int[] indices = new int[tensor.Shape[axis]];
                for (int i = 0; i < tensor.Shape[axis]; i++)
                {
                    indices[i] = i + num_new_rows;
                }
                int_tensors_for_index_add.Add(
                    factory.ctrl.intTensorFactory.Create(_shape: new int[1] {
                    tensor.Shape[axis]
                }, _data: indices));


                num_new_rows += tensor.Shape[axis];
            }

            Debug.Log("Num new Rows:" + num_new_rows);

            int[] concat_shape = new int[first.Shape.Length];

            for (int i = 0; i < first.Shape.Length; i++)
            {
                if (i == axis)
                {
                    concat_shape[i] = num_new_rows;
                }
                else
                {
                    concat_shape[i] = first.Shape[i];
                }
            }

            result = first.HookGraph(ref result, tensor_inputs: tensors, creation_op: "concatenate_" + axis, inline: false, resultShape: concat_shape, indices: int_tensors_for_index_add.ToArray());

            if (axis != 0)
            {
                result.IndexAdd(int_tensors_for_index_add[0], axis, first, inline: true);

                for (int i = 0; i < tensors.Length; i++)
                {
                    result.IndexAdd(int_tensors_for_index_add[i + 1], axis, tensors[i], inline: true);
                }
            }
            else
            {
                //Debug.Log("Result Size:" + result.Size);
                //Debug.Log("First Size:" + first.Size);

                int result_i = 0;

                for (int i = 0; i < first.Data.Length; i++)
                {
                    result.Data[result_i] = first.Data[i];
                    result_i += 1;
                }

                foreach (FloatTensor tensor in tensors)
                {
                    //Debug.Log("Tensor Size:" + tensor.Size);
                    for (int i = 0; i < tensor.Data.Length; i++)
                    {
                        result.Data[result_i] = tensor.Data[i];
                        result_i += 1;
                    }
                }
            }
            return(result);
        }