Esempio n. 1
0
        // The value represents a n-dimensional tensor with 2 dynamic axes: sequence and batch
        // It assumes that only the highest 2 axes are dynamic, and all the other axes are static.
        public static void CopyTo <T>(this Value value, Variable variable, List <List <T> > data)
        {
            if ((value.GetDataType() == DataType.Float) && (!typeof(T).Equals(typeof(float))) ||
                (value.GetDataType() == DataType.Double) && (!typeof(T).Equals(typeof(double))))
            {
                throw new ArgumentException("The value type does not match the list type.");
            }

            // Todo: how to check whether the dynamic axes are the highest 2 axes in the shape.
            if (variable.DynamicAxes().Count != 2)
            {
                throw new ArgumentException("The variable should have 2 dynamic axes.");
            }

            var variableShape = variable.Shape;
            var valueShape    = value.Shape;

            if (variableShape != value.Shape.SubShape(0, valueShape.Rank - 2))
            {
                throw new ArgumentException("The variable and value does not have same shape.");
            }

            // Todo: transform sparse to dense
            // Currently only for dense
            if ((value.GetStorageFormat() != StorageFormat.Dense))
            {
                throw new ArgumentException("The value is not in denst format.");
            }

            var outputNDArrayView      = value.Data();
            var outputShape            = outputNDArrayView.Shape();
            var outputShapeRank        = outputShape.Rank;
            var numOfElementsInSample  = variableShape.TotalSize;
            var numOfSamplesInSequence = outputShape.GetDimensionSize(outputShapeRank - 2);
            var numOfSequences         = outputShape.GetDimensionSize(outputShapeRank - 1);

            // Copy the data from the output buffer.
            // Todo: directly access the data in output buffer?
            // Todo: need to map DataBuffer() to C#
            NDArrayView cpuOutputNDArrayView;
            uint        numOfOutputData = outputNDArrayView.Shape().TotalSize;

            // Todo: consider mask.
            Debug.Assert(numOfElementsInSample * numOfSamplesInSequence * numOfSequences == numOfOutputData);
            T[] outputData = new T[numOfOutputData];
            if (value.GetDataType() == DataType.Float)
            {
                cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as float[], numOfOutputData, DeviceDescriptor.CPUDevice);
            }
            else if (value.GetDataType() == DataType.Double)
            {
                cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as double[], numOfOutputData, DeviceDescriptor.CPUDevice);
            }
            else
            {
                throw new ArgumentException("The data type " + value.GetDataType().ToString() + " is not supported. Only float or double is supported by CNTK.");
            }

            cpuOutputNDArrayView.CopyFrom(outputNDArrayView);
            for (int seqIndex = 0, dataIndex = 0; seqIndex < numOfSequences; seqIndex++)
            {
                var seqData = new List <T>();
                // Todo: consider mask
                // Todo: make it more efficient.
                for (int i = 0; i < numOfElementsInSample * numOfSamplesInSequence; i++)
                {
                    seqData.Add(outputData[dataIndex++]);
                }
                data.Add(seqData);
            }
        }
Esempio n. 2
0
        // Copy Value to List<List<T>> for dense input
        // Todo: could this be a extension to Value class??
        public void CopyValueTo <T>(string varName, Value value, List <List <T> > sequences)
        {
            // Todo: deal with GPUDevice.
            if (value.Device != DeviceDescriptor.CPUDevice)
            {
                throw new InvalidOperationException("Currently only CPU device is supported.");
            }

            if ((value.GetDataType() == DataType.Float) && (!typeof(T).Equals(typeof(float))) ||
                (value.GetDataType() == DataType.Double) && (!typeof(T).Equals(typeof(double))))
            {
                throw new InvalidDataException("The value type does not match the list type.");
            }

            // Todo: transform sparse to dense
            // Currently only for dense
            if ((value.GetStorageFormat() != StorageFormat.Dense))
            {
                throw new InvalidDataException("The value is not in denst format.");
            }

            var variable          = getVariableByName(varName);
            var outputNDArrayView = value.Data();
            var outputShape       = outputNDArrayView.Shape();

            var varRank   = variable.Shape.Rank;
            var valueRank = outputNDArrayView.Shape().Rank;

            Debug.Assert(varRank + 2 == valueRank);
            var numOfElementsInSample  = variable.Shape.TotalSize;
            var numOfSamplesInSequence = outputShape.GetDimensionSize(varRank);
            var numOfSequences         = outputShape.GetDimensionSize(varRank + 1);

            //var outputShape = outputVar.Shape().AppendShape(new NDShape(dynamicAxisShape));

            // Copy the data from the output buffer.
            // Todo: directly access the data in output buffer?
            // Todo: need to map DataBuffer() to C#
            NDArrayView cpuOutputNDArrayView;
            uint        numOfOutputData = outputNDArrayView.Shape().TotalSize;

            Debug.Assert(numOfElementsInSample * numOfSamplesInSequence * numOfSequences == numOfOutputData);
            T[] outputData = new T[numOfOutputData];
            if (value.GetDataType() == DataType.Float)
            {
                cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as float[], numOfOutputData, DeviceDescriptor.CPUDevice);
            }
            else if (value.GetDataType() == DataType.Double)
            {
                cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as double[], numOfOutputData, DeviceDescriptor.CPUDevice);
            }
            else
            {
                throw new InvalidDataException("The data type " + value.GetDataType().ToString() + " is not supported. Only float or double is supported by CNTK.");
            }

            cpuOutputNDArrayView.CopyFrom(outputNDArrayView);
            for (int seqIndex = 0, dataIndex = 0; seqIndex < numOfSequences; seqIndex++)
            {
                var seqData = new List <T>();
                // Todo: make it more efficient.
                for (int i = 0; i < numOfElementsInSample * numOfSamplesInSequence; i++)
                {
                    seqData.Add(outputData[dataIndex++]);
                }
                sequences.Add(seqData);
            }
        }