/// <summary> /// A simple 1D kernel using a custom atomic implementation /// of Atomic.Add(ArrayView<double>, double) that leverages pre-defined /// compare-exchange functionality for doubles. /// <param name="index">The current thread index.</param> /// <param name="dataView">The view pointing to our memory buffer.</param> /// <param name="value">The value to add.</param> static void AddDoubleAtomicILGPUFunctionsKernel( Index1 index, ArrayView <double> dataView, double value) { // atomic add: dataView[0] += value; Atomic.MakeAtomic( ref dataView[0], value, new AddDoubleOperation(), new CompareExchangeDouble()); }
/// <summary> /// A simple 1D kernel using a custom atomic implementation /// of Atomic.Add(ArrayView<double>, double) /// <param name="index">The current thread index.</param> /// <param name="dataView">The view pointing to our memory buffer.</param> /// <param name="value">The value to add.</param> static void AddDoubleAtomicKernel( Index index, ArrayView <double> dataView, double value) { // atomic add: dataView[0] += value; Atomic.MakeAtomic( dataView.GetVariableView(0), value, new AddDoubleOperation(), new DoubleCompareExchangeOperation()); }
private static void ShrinkKernel(Index2 index, ArrayView2D <float> xImage, ArrayView2D <float> bMap, ArrayView2D <float> aMap, ArrayView <float> lambdaAlpha, ArrayView <Pixel> output) { if (index.X == 0 & index.Y == 0) { output[0].AbsDiff = 0; } if (index.InBounds(xImage.Extent)) { var xOld = xImage[index]; var gradient = bMap[index]; var lipschitz = aMap[index]; var lambda = lambdaAlpha[0]; var alpha = lambdaAlpha[1]; var xNew = GPUProximalOperator(xOld * lipschitz + gradient, lipschitz, lambda, alpha); var xAbsDiff = XMath.Abs(xNew - xOld); var xIndex = index.X; var yIndex = index.Y; var sign = XMath.Sign(xNew - xOld); var pix = new Pixel() { AbsDiff = xAbsDiff, X = xIndex, Y = yIndex, Sign = sign }; Atomic.MakeAtomic(ref output[0], pix, new MaxPixelOperation(), new PixelCompareExchange()); } }
/// <summary> /// A software implementation for atomic adds on 64-bit floats. /// </summary> /// <param name="target">The target address.</param> /// <param name="value">The value to add.</param> private static double AtomicAddF64(ref double target, double value) => Atomic.MakeAtomic( ref target, value, new AddDouble(), new CompareExchangeDouble());
private static float AtomicAddF32(ref float target, float value) => Atomic.MakeAtomic( ref target, value, new AddFloat(), new CompareExchangeFloat());