/// <inheritdoc /> protected override Util.ISigmaDiffDataBuffer <T> _InternalDeepCopy() { T[] copyData = SigmaDiffSharpBackendProvider.Instance.GetBackend <T>(BackendTag).BackendHandle.CreateUninitialisedArray((int)Length); CudaSigmaDiffDataBuffer <T> copy = new CudaSigmaDiffDataBuffer <T>(copyData, 0L, Length, BackendTag, CudaContext, Type); if (_initialisedInContext && !_flagHostModified) { copy.InitialiseCudaBuffer(copyHostToDevice: false); copy._cudaBuffer.AsyncCopyToDevice(_cudaBuffer, CudaFloat32Handler.GetStreamForContext(CudaContext)); copy._flagHostModified = false; copy._flagDeviceModified = true; } else { OnReadAccess(); Buffer.BlockCopy(_data, (int)(Offset * Type.SizeBytes), copyData, 0, (int)(Length * Type.SizeBytes)); copy._flagHostModified = true; } return(copy); }
/// <inheritdoc /> public override Util.ISigmaDiffDataBuffer <T> GetStackedValues(int totalRows, int totalCols, int rowStart, int rowFinish, int colStart, int colFinish) { int colLength = colFinish - colStart + 1; int newSize = (rowFinish - rowStart + 1) * colLength; Backend <T> backendHandle = SigmaDiffSharpBackendProvider.Instance.GetBackend <T>(BackendTag).BackendHandle; CudaSigmaDiffDataBuffer <T> values = (CudaSigmaDiffDataBuffer <T>)backendHandle.CreateDataBuffer(backendHandle.CreateUninitialisedArray(newSize)); if (_initialisedInContext) { SynchroniseFromDeviceToHost(); } for (int m = rowStart; m <= rowFinish; m++) { long sourceIndex = Offset + m * totalCols + colStart; long destinationIndex = (m - rowStart) * colLength; Buffer.BlockCopy(_data, (int)(sourceIndex * Type.SizeBytes), values.Data, (int)(destinationIndex * Type.SizeBytes), colLength * Type.SizeBytes); } if (_initialisedInContext) { values.SynchroniseFromHostToDevice(); } return(values); }
/// <inheritdoc /> public override void Fill(INDArray filler, INDArray arrayToFill, long[] sourceBeginIndices, long[] sourceEndIndices, long[] destinationBeginIndices, long[] destinationEndIndices) { CudaSigmaDiffDataBuffer <float> fillerData = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(filler).Data; CudaSigmaDiffDataBuffer <float> arrayToFillData = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(arrayToFill).Data; int sourceOffset = (int)NDArrayUtils.GetFlatIndex(filler.Shape, filler.Strides, sourceBeginIndices); int sourceLength = (int)NDArrayUtils.GetFlatIndex(filler.Shape, filler.Strides, sourceEndIndices) - sourceOffset + 1; // +1 because end is inclusive int destinationOffset = (int)NDArrayUtils.GetFlatIndex(arrayToFill.Shape, arrayToFill.Strides, destinationBeginIndices); int destinationLength = (int)NDArrayUtils.GetFlatIndex(arrayToFill.Shape, arrayToFill.Strides, destinationEndIndices) - destinationOffset + 1; // same here if (sourceLength < 0) { throw new ArgumentOutOfRangeException($"Source begin indices must be smaller than source end indices, but source length was {sourceLength}."); } if (destinationLength < 0) { throw new ArgumentOutOfRangeException($"Destination begin indices must be smaller than destination end indices, but destination length was {destinationLength}."); } if (sourceLength != destinationLength) { throw new ArgumentException($"Source and destination indices length must batch, but source length was {sourceLength} and destination legnth was {destinationLength}."); } Array.Copy(fillerData.Data, sourceOffset, arrayToFillData.Data, destinationOffset, sourceLength); arrayToFillData.CopyFromHostToDevice(); }
/// <inheritdoc /> public override void Fill(INDArray filler, INDArray arrayToFill) { CudaSigmaDiffDataBuffer <float> fillerData = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(filler).Data; CudaSigmaDiffDataBuffer <float> arrayToFillData = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(arrayToFill).Data; arrayToFillData.SetValues(fillerData.Data, fillerData.Offset, 0, Math.Min(arrayToFill.Length, filler.Length)); arrayToFillData.CopyFromHostToDevice(); }
private void PrepareCudaBuffer(CudaContext cudaContext, T[] data, long offset, long length) { CudaContext = cudaContext; _cudaZero = new SizeT(0); _cudaOffsetBytes = new SizeT(offset * Type.SizeBytes); _cudaLengthBytes = new SizeT(length * Type.SizeBytes); _cudaContextDeviceId = cudaContext.DeviceId; _underlyingCudaBuffer = GetUnderlyingBuffer() as CudaSigmaDiffDataBuffer <T>; }
/// <summary> /// Shallow copy constructor with the same system- and device memory buffers. /// </summary> /// <param name="other"></param> internal CudaSigmaDiffDataBuffer(CudaSigmaDiffDataBuffer <T> other) : base(other, other.BackendTag) { _cudaBuffer = other._cudaBuffer; CudaContext = other.CudaContext; _cudaOffsetBytes = other._cudaOffsetBytes; _cudaLengthBytes = other._cudaLengthBytes; _flagDeviceModified = other._flagDeviceModified; _flagHostModified = other._flagHostModified; }
/// <inheritdoc /> protected override INDArray _RowWiseDirect(INDArray array, CudaFloat32NDArray internalArray, Func <INDArray, INDArray> function) { INDArray result = base._RowWiseDirect(array, internalArray, function); // TODO optimise ofRows operation for CUDA on device // flag host array modified because for some reason the host modification logic isn't triggered from F# SigmaDiff when appling ofRows (using System.Array.Copy) CudaSigmaDiffDataBuffer <float> resultBuffer = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(result).Data; resultBuffer.FlagHostModified(); return(result); }
/// <inheritdoc /> public override void Fill <TOther>(TOther value, INDArray arrayToFill) { CudaSigmaDiffDataBuffer <float> arrayToFillData = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(arrayToFill).Data; float floatValue = (float)System.Convert.ChangeType(value, typeof(float)); for (int i = 0; i < arrayToFillData.Length; i++) { arrayToFillData.Data.SetValue(floatValue, i); } arrayToFillData.CopyFromHostToDevice(); }
/// <inheritdoc /> public override void Fill <T>(T[] filler, INDArray arrayToFill, long[] destinationBeginIndices, long[] destinationEndIndices) { CudaSigmaDiffDataBuffer <float> arrayToFillData = (CudaSigmaDiffDataBuffer <float>)InternaliseArray(arrayToFill).Data; int destinationOffset = (int)NDArrayUtils.GetFlatIndex(arrayToFill.Shape, arrayToFill.Strides, destinationBeginIndices); int destinationLength = (int)NDArrayUtils.GetFlatIndex(arrayToFill.Shape, arrayToFill.Strides, destinationEndIndices) - destinationOffset + 1; // +1 because end is inclusive if (destinationLength < 0) { throw new ArgumentOutOfRangeException($"Destination begin indices must be smaller than destination end indices, but destination length was {destinationLength}."); } Array.Copy(filler, 0, arrayToFillData.Data, destinationOffset, destinationLength); arrayToFillData.CopyFromHostToDevice(); }
/// <inheritdoc /> public override IDataBuffer <T> GetValues(long startIndex, long length) { if (_initialisedInContext && !_flagHostModified) { CudaSigmaDiffDataBuffer <T> vData = new CudaSigmaDiffDataBuffer <T>(_data, startIndex, length, BackendTag, CudaContext); vData.InitialiseCudaBuffer(copyHostToDevice: false); vData._cudaBuffer.AsyncCopyToDevice(_cudaBuffer.DevicePointer, new SizeT(startIndex * sizeof(float)), vData._cudaZero, vData._cudaLengthBytes, CudaFloat32Handler.GetStreamForContext(CudaContext)); vData._flagHostModified = false; vData._flagDeviceModified = false; return(vData); } else { OnReadAccess(); return(new CudaSigmaDiffDataBuffer <T>(this, startIndex, length, BackendTag, CudaContext)); } }