// // Copy the data of the Value object into the buffer provided by 'sequences'. // The 'sequences' is a list of sequences with variable length. // The number of items contained in the outer list of 'sequences' is the number of sequences in the Value object. // Each element of the outer list represents a sequence. // Each sequence, represented by List<T>, contains a variable number of samples. // Each sample consits of a fixed number of elements with type of 'T'. The number of elements is determined by the sample shape. // The number of samples = the count of elements in List<T> / the count of elements of the sample // The sampleShape should match the shape of the Value object. // public static void CopyTo <T>(this Value value, NDShape sampelShape, List <List <T> > sequences) { 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."); } throw new Exception("Not implemented yet."); }
// // Copy the data of the Value object into the buffer provided by 'sequences'. // The 'sequences' is a list of sequences with variable length. // The number of items contained in the outer list of 'sequences' is the number of sequences in the Value object. // Each element of the outer list represents a sequence. // Each sequence, represented by List<T>, contains a variable number of samples. // Each sample consits of a fixed number of elements with type of 'T'. The number of elements is determined by the variable shape. // The number of samples = the count of elements in List<T> / the count of elements of the sample // The shape of the variable should match the shape of the Value object. // public static void CopyVariableValueTo <T>(this Value value, Variable sampleVariable, List <List <T> > sequences) { if (typeof(T).Equals(typeof(float))) { if (value.GetDataType() != DataType.Float) { throw new ArgumentException("The value type does not match the list type."); } var seqVec = new FloatVectorVector(); value.CopyVariableValueToFloat(sampleVariable, seqVec); sequences.Clear(); foreach (var seq in seqVec) { var seqList = seq as IEnumerable <T>; if (seqList == null) { throw new TypeAccessException("Cannot convert to the value type."); } sequences.Add(new List <T>(seqList)); } } else if (typeof(T).Equals(typeof(double))) { if (value.GetDataType() != DataType.Double) { throw new ArgumentException("The value type does not match the list type."); } var seqVec = new DoubleVectorVector(); value.CopyVariableValueToDouble(sampleVariable, seqVec); sequences.Clear(); foreach (var seq in seqVec) { var seqList = seq as IEnumerable <T>; if (seqList == null) { throw new TypeAccessException("Cannot convert to the value type."); } sequences.Add(new List <T>(seqList)); } } else { throw new ArgumentException("The value type does not match the list type."); } }
// 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); } }
// 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); } }