public void RunLclVarScenario_LoadAligned() { var firstOp = Avx.LoadAlignedVector256((Double *)(_dataTable.inArrayPtr)); var result = Avx.ConvertToVector128Single(firstOp); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(firstOp, _dataTable.outArrayPtr); }
public void RunLclVarScenario_UnsafeRead() { var firstOp = Unsafe.Read <Vector256 <Double> >(_dataTable.inArrayPtr); var result = Avx.ConvertToVector128Single(firstOp); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(firstOp, _dataTable.outArrayPtr); }
public void RunLclFldScenario() { var test = new SimpleUnaryOpTest__ConvertToVector128SingleDouble(); var result = Avx.ConvertToVector128Single(test._fld); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld, _dataTable.outArrayPtr); }
public void RunClsVarScenario() { var result = Avx.ConvertToVector128Single( _clsVar ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_clsVar, _dataTable.outArrayPtr); }
public void RunBasicScenario_LoadAligned() { var result = Avx.ConvertToVector128Single( Avx.LoadAlignedVector256((Double *)(_dataTable.inArrayPtr)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); }
public void RunBasicScenario_UnsafeRead() { var result = Avx.ConvertToVector128Single( Unsafe.Read <Vector256 <Double> >(_dataTable.inArrayPtr) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); }
public unsafe static Vector128 <float> Log2(Vector128 <float> value) { // split value into exponent and mantissa parts Vector128 <float> one = AvxExtensions.BroadcastScalarToVector128(MathV.One); Vector128 <int> integerValue = value.AsInt32(); Vector128 <float> exponent = Avx.ConvertToVector128Single(Avx.Subtract(Avx.ShiftRightLogical(Avx.And(integerValue, MathV.FloatExponentMask128), MathV.FloatMantissaBits), MathV.FloatMantissaZero128)); Vector128 <float> mantissa = Avx.Or(Avx.And(integerValue, MathV.FloatMantissaMask128).AsSingle(), one); // evaluate mantissa polynomial Vector128 <float> beta1 = AvxExtensions.BroadcastScalarToVector128(MathV.Log2Beta1); Vector128 <float> beta2 = AvxExtensions.BroadcastScalarToVector128(MathV.Log2Beta2); Vector128 <float> beta3 = AvxExtensions.BroadcastScalarToVector128(MathV.Log2Beta3); Vector128 <float> beta4 = AvxExtensions.BroadcastScalarToVector128(MathV.Log2Beta4); Vector128 <float> beta5 = AvxExtensions.BroadcastScalarToVector128(MathV.Log2Beta5); Vector128 <float> x = Avx.Subtract(mantissa, one); Vector128 <float> polynomial = Avx.Multiply(beta1, x); Vector128 <float> x2 = Avx.Multiply(x, x); polynomial = Avx.Add(polynomial, Avx.Multiply(beta2, x2)); Vector128 <float> x3 = Avx.Multiply(x2, x); polynomial = Avx.Add(polynomial, Avx.Multiply(beta3, x3)); Vector128 <float> x4 = Avx.Multiply(x3, x); polynomial = Avx.Add(polynomial, Avx.Multiply(beta4, x4)); Vector128 <float> x5 = Avx.Multiply(x4, x); polynomial = Avx.Add(polynomial, Avx.Multiply(beta5, x5)); // form logarithm return(Avx.Add(exponent, polynomial)); }
public unsafe static Vector <float> BitmapToVectorF(Bitmap bitmap, BitmapChannel channel = BitmapChannel.Gray) { int width = bitmap.Width; int height = bitmap.Height; int pixelCount = width * height; bool needDispose = false; bool isGray = false; var rect = new Rectangle(0, 0, width, height); int depth = Bitmap.GetPixelFormatSize(bitmap.PixelFormat); switch (bitmap.PixelFormat) { case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppRgb: break; default: bitmap = channel == BitmapChannel.Gray ? MakeGrayscale(bitmap) : MakeColor(bitmap); needDispose = true; break; } if (!needDispose && channel == BitmapChannel.Gray) { bitmap = MakeGrayscale(bitmap); needDispose = true; isGray = true; } var result = new float[pixelCount]; var bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat); try { unsafe { byte *scan0 = (byte *)bitmapData.Scan0.ToPointer(); var ptr = bitmapData.Scan0; int startIndex; switch (depth) { case 8: // For 8 bpp get color value (Red, Green and Blue values are the same) if (channel == BitmapChannel.Alpha) { break; } for (int y = 0; y < bitmapData.Height; y++) { var rowB = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } for (int x = 0; x < bitmapData.Width; x++) { result[startIndex + x] = rowB[x]; } } PointwiseDivideInPlaceF(result, 256.0f); break; case 16: // For 16 bpp - gray with 65536 shades if (channel == BitmapChannel.Alpha) { break; } for (int y = 0; y < bitmapData.Height; y++) { var rowS = (short *)bitmapData.Scan0 + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } for (int x = 0; x < bitmapData.Width; x++) { result[startIndex + x] = rowS[x]; } } PointwiseDivideInPlaceF(result, 65536.0f); break; case 24: // For 24 bpp get Red, Green and Blue case 32: // For 32 bpp get Red, Green, Blue and Alpha if (channel == BitmapChannel.Alpha && depth == 24) { break; } int step = depth / 8; if (channel == BitmapChannel.Gray) { if (isGray && UseGrayConverter) { for (int y = 0; y < bitmapData.Height; y++) { var row3B = (byte *)bitmapData.Scan0.ToPointer() + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { result[startIndex + i] = row3B[x]; //In gray image (made with method MakeGray()) R = G = B. } } PointwiseDivideInPlaceF(result, 256.0f); } else if (UseAvx) { var vectorGrayCoeffAvx = Vector128.Create(0.11f, 0.59f, 0.3f, 0f); for (int y = 0; y < bitmapData.Height; y++) { var row3B = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { var vectorB = Vector128.Create((int)row3B[x], (int)row3B[x + 1], (int)row3B[x + 2], (int)0); var vectorF = Avx.ConvertToVector128Single(vectorB); var vectorGray = Avx.Multiply(vectorF, vectorGrayCoeffAvx); float fGray = vectorGray.GetElement(0) + vectorGray.GetElement(1) + vectorGray.GetElement(2); result[startIndex + i] = fGray; } } PointwiseDivideInPlaceF(result, 256.0f); } else if (UseSIMD) { var vectorGrayCoeff = new Numerics.Vector4(0.11f, 0.59f, 0.3f, 0f); for (int y = 0; y < bitmapData.Height; y++) { var row3B = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { var vectorF = new Numerics.Vector4(row3B[x], row3B[x + 1], row3B[x + 2], 0); var fGray = Numerics.Vector4.Dot(vectorF, vectorGrayCoeff); result[startIndex + i] = fGray; } } PointwiseDivideInPlaceF(result, 256.0f); } else { for (int y = 0; y < bitmapData.Height; y++) { var row3B = (byte *)bitmapData.Scan0.ToPointer() + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { float gray = 0.11f * row3B[x] + 0.59f * row3B[x + 1] + 0.11f * row3B[x + 2]; result[startIndex + i] = gray; } } PointwiseDivideInPlaceF(result, 256.0f); } } else { for (int y = 0; y < bitmapData.Height; y++) { var row3B = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride); startIndex = y * bitmapData.Width; if (bitmapData.Stride < 0) { startIndex = (pixelCount - bitmapData.Width) - startIndex; } switch (channel) { case BitmapChannel.Red: for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { result[startIndex + i] = row3B[x + 2]; } break; case BitmapChannel.Green: for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { result[startIndex + i] = row3B[x + 1]; } break; case BitmapChannel.Blue: for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { result[startIndex + i] = row3B[x]; } break; case BitmapChannel.Alpha: if (depth == 32) { for (int i = 0, x = 0; i < bitmapData.Width; i++, x += step) { result[startIndex + i] = row3B[x + 3]; } } else { //Do nothing, 24bit images have no alpha channel } break; } } PointwiseDivideInPlaceF(result, 256.0f); } break; } } } finally { bitmap.UnlockBits(bitmapData); if (needDispose) { bitmap.Dispose(); } } return(Vector <float> .Build.Dense(result)); }
public static void IsTrue(Vector128 <int> comparison) { AssertV.IsTrue(Avx.ConvertToVector128Single(comparison)); }
public unsafe void Process(MutableByteImage currentPicture, MutableByteImage nextPicture) { float MaxFactor = 1; float[] attackAr = new float[] { Attack, Attack, Attack, Attack }; float[] decayAr = new float[] { Decay, Decay, Decay, Decay }; int length = nextPicture.Data.Length; float *MaxFactorPtr = &MaxFactor; fixed(float *AttackPtr = attackAr) fixed(float *DecayPtr = decayAr) fixed(byte *currentPicPtr = currentPicture.Data) fixed(byte *nextPicPtr = nextPicture.Data) { byte *currentPxPtr = currentPicPtr; byte *nextPxPtr = nextPicPtr; int remainingLength = length % 4; for (int i = 0; i < length; i += 4) { var currentColor = *nextPxPtr; var workingDataColor = *currentPxPtr; var currentColorPtr = nextPxPtr; var workingDataColorPtr = currentPxPtr; var cmpResult = Avx.ConvertToVector128Single( Sse2.CompareGreaterThan( Sse41.ConvertToVector128Int32(currentColorPtr), Sse41.ConvertToVector128Int32(workingDataColorPtr) )); var pixelFactor = Avx.Add( Avx.And(cmpResult, Avx.BroadcastScalarToVector128(AttackPtr)), Avx.AndNot(cmpResult, Avx.BroadcastScalarToVector128(DecayPtr)) ); var result = Avx.Add( Avx.Multiply( Avx.Subtract( Avx.BroadcastScalarToVector128(MaxFactorPtr), pixelFactor), Sse41.ConvertToVector128Single( Sse41.ConvertToVector128Int32(workingDataColorPtr)) ), Avx.Multiply( pixelFactor, Sse41.ConvertToVector128Single( Sse41.ConvertToVector128Int32(currentColorPtr)))); // TODO improve Store *currentPxPtr = (byte)Avx.Extract(result, 0); currentPxPtr++; *currentPxPtr = (byte)Avx.Extract(result, 1); currentPxPtr++; *currentPxPtr = (byte)Avx.Extract(result, 2); currentPxPtr++; *currentPxPtr = (byte)Avx.Extract(result, 3); currentPxPtr++; nextPxPtr += 4; } for (int i = 0; i < remainingLength; i++) { var currentColor = *nextPxPtr; var workingDataColor = *currentPxPtr; var newPixelFactor = workingDataColor < currentColor ? Attack : Decay; var newPixelValue = (byte)((currentColor * newPixelFactor) + (workingDataColor * (1 - newPixelFactor))); *currentPxPtr = newPixelValue; currentPxPtr++; nextPxPtr++; } } }