/* * private Tensor GetRegion(long[] dimensionStarts, long[] dimensionSizes) * { * var result = this.CopyRef(); * for (int i = 0; i < dimensionStarts.Length; ++i) * { * var resultOld = result; * result.Narrow(i, dimensionStarts[i], dimensionSizes[i]); * resultOld.Dispose(); * } * return result; * }*/ /// <summary> /// Copies from. /// </summary> /// <param name="array">The array.</param> /// <exception cref="InvalidOperationException"> /// Tensor must be contiguous to copy from CLR array /// or /// Tensor and array must have the same number of elements /// or /// Tensor and array must have the same element types /// </exception> public void CopyFrom(Array array) { var elementType = DTypeBuilder.FromCLRType(array.GetType().GetElementType()); if (!this.IsContiguous()) { throw new InvalidOperationException("Tensor must be contiguous to copy from CLR array"); } if (this.ElementCount() != array.LongLength) { throw new InvalidOperationException("Tensor and array must have the same number of elements"); } if (this.ElementType != elementType) { throw new InvalidOperationException("Tensor and array must have the same element types"); } var handle = GCHandle.Alloc(array, GCHandleType.Pinned); try { var length = Buffer.ByteLength(array); this.Storage.CopyToStorage(this.StorageOffset, handle.AddrOfPinnedObject(), length); } finally { handle.Free(); } }
/// <summary> /// Froms the array. /// </summary> /// <param name="allocator">The allocator.</param> /// <param name="array">The array.</param> /// <returns>Tensor.</returns> public static NDArray FromArray(IAllocator allocator, Array array) { // From the CLI spec(section 8.9.1): // Array elements shall be laid out within the array object in row - major order // (i.e., the elements associated with the rightmost array dimension shall be laid out contiguously from lowest to highest index). // The actual storage allocated for each array element can include platform - specific padding. // This is already in the order we want - and here we will (potentially incorrectly) assume that there is no // 'platform-specific padding'. This appears to be a reasonable assumption on both CLR and Mono. // Assuming no platform-specific padding allows us to use memcpy instead of iterating and copying each element var elementType = DTypeBuilder.FromCLRType(array.GetType().GetElementType()); var dimSizes = Enumerable.Range(0, array.Rank) .Select(x => (long)array.GetLength(x)) .ToArray(); var result = new NDArray(allocator, elementType, dimSizes); result.CopyFrom(array); return(result); }