/// <summary>
        /// Creates a <see cref="SimpleMemory"/> instance that stores the image.
        /// </summary>
        /// <param name="image">The image to process.</param>
        /// <param name="contrastValue">The contrast difference value.</param>
        /// <returns>The instance of the created <see cref="SimpleMemory"/>.</returns>
        private SimpleMemory CreateSimpleMemory(Bitmap image, int contrastValue)
        {
            var pixelCount = image.Width * image.Height;
            var cellCount  =
                pixelCount +
                (pixelCount % MaxDegreeOfParallelism != 0 ? MaxDegreeOfParallelism : 0) +
                3;
            var memory = new SimpleMemory(cellCount);

            memory.WriteUInt32(ChangeContrast_ImageWidthIndex, (uint)image.Width);
            memory.WriteUInt32(ChangeContrast_ImageHeightIndex, (uint)image.Height);
            memory.WriteInt32(ChangeContrast_ContrastValueIndex, contrastValue);

            for (int x = 0; x < image.Height; x++)
            {
                for (int y = 0; y < image.Width; y++)
                {
                    var pixel = image.GetPixel(y, x);

                    // This leaves 1 byte unused in each memory cell, but that would make the whole logic a lot more
                    // complicated, so good enough for a sample; if we'd want to optimize memory usage, that would be
                    // needed.
                    memory.Write4Bytes(
                        x * image.Width + y + ChangeContrast_ImageStartIndex,
                        new[] { pixel.R, pixel.G, pixel.B });
                }
            }

            return(memory);
        }
Пример #2
0
        /// <summary>
        /// This copies random seed from the host to the FPGA.
        /// </summary>
        public static SimpleMemory PushRandomSeed(this PrngTestInterface kernels, ulong seed)
        {
            SimpleMemory sm = new SimpleMemory(3);

            sm.WriteUInt32(0, (uint)seed); //LE: 0 is low byte, 1 is high byte
            sm.WriteUInt32(1, (uint)(seed >> 32));
            return(sm);
        }
Пример #3
0
        public virtual void CalculateFactorial(SimpleMemory memory)
        {
            memory.WriteUInt32(CalculateFactorial_InvocationCounterUInt32Index, 1);

            var number = (short)memory.ReadInt32(CalculateFactorial_InputShortIndex);

            memory.WriteUInt32(CalculateFactorial_OutputUInt32Index, RecursivelyCalculateFactorial(memory, number));
        }
Пример #4
0
        /// <summary>
        /// This function adds two numbers on the FPGA using <see cref="KpzKernelsInterface.TestAdd(SimpleMemory)"/>.
        /// </summary>
        public static uint TestAddWrapper(this KpzKernelsInterface kernels, uint a, uint b)
        {
            var sm = new SimpleMemory(3);

            sm.WriteUInt32(0, a);
            sm.WriteUInt32(1, b);
            kernels.TestAdd(sm);
            return(sm.ReadUInt32(2));
        }
Пример #5
0
        public virtual void MWC64X(SimpleMemory memory)
        {
            uint  stateHighWord = memory.ReadUInt32(1);
            uint  stateLowWord  = memory.ReadUInt32(0);;
            ulong randomState   = stateLowWord * 0xFFFEB81BUL + stateHighWord;
            uint  randomWord    = stateLowWord ^ stateHighWord;

            memory.WriteUInt32(0, (uint)randomState); //LE: 1 is high byte, 0 is low byte
            memory.WriteUInt32(1, (uint)(randomState >> 32));
            memory.WriteUInt32(2, randomWord);
        }
Пример #6
0
        public virtual void MWC64X(SimpleMemory memory)
        {
            uint stateHighWord = memory.ReadUInt32(1);
            uint stateLowWord  = memory.ReadUInt32(0);;
            // Creating the value 0xFFFEB81BUL. This literal can't be directly used due to an ILSpy bug, see:
            // https://github.com/icsharpcode/ILSpy/issues/807
            uint  constantHighShort = 0xFFFE;
            uint  constantLowShort  = 0xB81B;
            uint  constantWord      = (0 << 32) | (constantHighShort << 16) | constantLowShort;
            ulong randomState       = (ulong)stateLowWord * (ulong)constantWord + (ulong)stateHighWord;
            uint  randomWord        = stateLowWord ^ stateHighWord;

            memory.WriteUInt32(0, (uint)randomState); //LE: 1 is high byte, 0 is low byte
            memory.WriteUInt32(1, (uint)(randomState >> 32));
            memory.WriteUInt32(2, randomWord);
        }
Пример #7
0
 public static uint Run(this ParallelAlgorithm algorithm, uint input)
 {
     var memory = new SimpleMemory(1);
     memory.WriteUInt32(ParallelAlgorithm.Run_InputUInt32Index, input);
     algorithm.Run(memory);
     return memory.ReadUInt32(ParallelAlgorithm.Run_OutputUInt32Index);
 }
Пример #8
0
        public static uint Run(this ObjectOrientedShowcase algorithm, uint input)
        {
            var memory = new SimpleMemory(1);

            memory.WriteUInt32(ObjectOrientedShowcase.Run_InputUInt32Index, input);
            algorithm.Run(memory);
            return(memory.ReadUInt32(ObjectOrientedShowcase.Run_OutputUInt32Index));
        }
Пример #9
0
        public static bool IsPrimeNumber(this PrimeCalculator primeCalculator, uint number)
        {
            var memory = new SimpleMemory(1);

            memory.WriteUInt32(PrimeCalculator.IsPrimeNumber_InputUInt32Index, number);
            primeCalculator.IsPrimeNumber(memory);
            return(memory.ReadBoolean(PrimeCalculator.IsPrimeNumber_OutputBooleanIndex));
        }
Пример #10
0
        public uint Run(uint input)
        {
            var memory = new SimpleMemory(1);

            memory.WriteUInt32(Run_InputUInt32Index, input);
            Run(memory);
            return(memory.ReadUInt32(Run_OutputUInt32Index));
        }
        public double EstimatePi(uint iterationsCount)
        {
            if (iterationsCount % MaxDegreeOfParallelism != 0)
            {
                throw new Exception($"The number of iterations must be divisible by {MaxDegreeOfParallelism}.");
            }

            var memory = new SimpleMemory(2);

            memory.WriteUInt32(EstimatePi_IteractionsCountUInt32Index, iterationsCount);
            memory.WriteUInt32(EstimatePi_RandomSeedUInt32Index, (uint)_random.Next(0, int.MaxValue));

            EstimatePi(memory);

            // This single calculation takes up too much space on the FPGA, since it needs fix point arithmetic, but
            // it doesn't take much time. So doing it on the host instead.
            return((double)memory.ReadInt32(EstimatePi_InCircleCountSumUInt32Index) / iterationsCount * 4);
        }
Пример #12
0
        /// <summary>
        /// Makes the changes according to the matrix on the image.
        /// </summary>
        /// <param name="memory">The <see cref="SimpleMemory"/> object representing the accessible memory space.</param>
        public virtual void FilterImage(SimpleMemory memory)
        {
            ushort imageWidth  = (ushort)memory.ReadUInt32(FilterImage_ImageWidthIndex);
            ushort imageHeight = (ushort)memory.ReadUInt32(FilterImage_ImageHeightIndex);

            int factor            = memory.ReadInt32(FilterImage_FactorIndex);
            int offset            = memory.ReadInt32(FilterImage_OffsetIndex);
            int topLeftValue      = memory.ReadInt32(FilterImage_TopLeftIndex);
            int topMiddleValue    = memory.ReadInt32(FilterImage_TopMiddleIndex);
            int topRightValue     = memory.ReadInt32(FilterImage_TopRightIndex);
            int middleLeftValue   = memory.ReadInt32(FilterImage_MiddleLeftIndex);
            int pixelValue        = memory.ReadInt32(FilterImage_PixelIndex);
            int middleRightValue  = memory.ReadInt32(FilterImage_MiddleRightIndex);
            int bottomLeftValue   = memory.ReadInt32(FilterImage_BottomLeftIndex);
            int bottomMiddleValue = memory.ReadInt32(FilterImage_BottomMiddleIndex);
            int bottomRightValue  = memory.ReadInt32(FilterImage_BottomRightIndex);

            ushort topLeft      = 0;
            ushort topMiddle    = 0;
            ushort topRight     = 0;
            ushort middleLeft   = 0;
            ushort pixel        = 0;
            ushort middleRight  = 0;
            ushort bottomLeft   = 0;
            ushort bottomMiddle = 0;
            ushort bottomRight  = 0;

            int    pixelCountHelper = imageHeight * imageWidth * 3;
            ushort imageWidthHelper = (ushort)(imageWidth * 3);

            for (int x = 1; x < imageHeight - 1; x++)
            {
                for (int y = 3; y < imageWidthHelper - 3; y++)
                {
                    topLeft      = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper - imageWidthHelper - 3 + FilterImage_ImageStartIndex);
                    topMiddle    = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper - imageWidthHelper + FilterImage_ImageStartIndex);
                    topRight     = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper - imageWidthHelper + 3 + FilterImage_ImageStartIndex);
                    middleLeft   = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper - 3 + FilterImage_ImageStartIndex);
                    pixel        = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper + FilterImage_ImageStartIndex);
                    middleRight  = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper + 3 + FilterImage_ImageStartIndex);
                    bottomLeft   = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper + imageWidthHelper - 3 + FilterImage_ImageStartIndex);
                    bottomMiddle = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper + imageWidthHelper + FilterImage_ImageStartIndex);
                    bottomRight  = (ushort)memory.ReadUInt32(x * imageWidthHelper + y + pixelCountHelper + imageWidthHelper + 3 + FilterImage_ImageStartIndex);

                    memory.WriteUInt32(x * imageWidthHelper + y + FilterImage_ImageStartIndex, CalculatePixelValue(
                                           topLeft, topMiddle, topRight,
                                           middleLeft, pixel, middleRight,
                                           bottomLeft, bottomMiddle, bottomRight,
                                           topLeftValue, topMiddleValue, topRightValue,
                                           middleLeftValue, pixelValue, middleRightValue,
                                           bottomLeftValue, bottomMiddleValue, bottomRightValue,
                                           factor, offset));
                }
            }
        }
Пример #13
0
 /// <summary>Push table into FPGA.</summary>
 public static void CopyFromGridToSimpleMemory(KpzNode[,] gridSrc, SimpleMemory memoryDst)
 {
     for (int x = 0; x < KpzKernels.GridHeight; x++)
     {
         for (int y = 0; y < KpzKernels.GridWidth; y++)
         {
             KpzNode node = gridSrc[x, y];
             memoryDst.WriteUInt32(KpzKernels.MemIndexGrid + y * KpzKernels.GridWidth + x, node.SerializeToUInt32());
         }
     }
 }
Пример #14
0
 /// <summary>
 /// Copies the grid data from BRAM/LUT RAM to DDR.
 /// </summary>
 public void CopyToSimpleMemoryFromRawGrid(SimpleMemory memory)
 {
     for (int y = 0; y < GridHeight; y++)
     {
         for (int x = 0; x < GridWidth; x++)
         {
             int index = y * GridWidth + x;
             memory.WriteUInt32(MemIndexGrid + index, _gridRaw[index]);
         }
     }
 }
Пример #15
0
 /// <summary>Push table into FPGA.</summary>
 public static void CopyFromGridToSimpleMemory(KpzNode[,] gridSrc, SimpleMemory memoryDst)
 {
     for (int x = 0; x < KpzKernelsParallelizedInterface.GridSize; x++)
     {
         for (int y = 0; y < KpzKernelsParallelizedInterface.GridSize; y++)
         {
             KpzNode node = gridSrc[x, y];
             memoryDst.WriteUInt32(KpzKernelsParallelizedInterface.MemIndexGrid + y * KpzKernelsParallelizedInterface.GridSize + x, node.SerializeToUInt32());
         }
     }
 }
Пример #16
0
        private static async Task <bool> RunIsPrimeNumber(uint number, Func <SimpleMemory, Task> methodRunner)
        {
            // One memory cell is enough for data exchange.
            var memory = new SimpleMemory(1);

            memory.WriteUInt32(PrimeCalculator.IsPrimeNumber_InputUInt32Index, number);

            await methodRunner(memory);

            return(memory.ReadBoolean(PrimeCalculator.IsPrimeNumber_OutputBooleanIndex));
        }
        public virtual void EstimatePi(SimpleMemory memory)
        {
            var iterationsCount   = memory.ReadUInt32(EstimatePi_IteractionsCountUInt32Index);
            var randomSeed        = (ushort)memory.ReadUInt32(EstimatePi_RandomSeedUInt32Index);
            var iterationsPerTask = iterationsCount / MaxDegreeOfParallelism;
            var tasks             = new Task <uint> [MaxDegreeOfParallelism];

            for (uint i = 0; i < MaxDegreeOfParallelism; i++)
            {
                tasks[i] = Task.Factory.StartNew(
                    indexObject =>
                {
                    var index = (uint)indexObject;
                    // A 16b PRNG is enough for this task and the xorshift one has suitable quality.
                    var random = new RandomXorshiftLfsr16 {
                        State = (ushort)(randomSeed + index)
                    };

                    uint inCircleCount = 0;

                    for (var j = 0; j < iterationsPerTask; j++)
                    {
                        uint a = random.NextUInt16();
                        uint b = random.NextUInt16();

                        // A bit of further parallelization can be exploited with SIMD to shave off some execution
                        // time. However, this needs so much resources on the hardware that the degree of
                        // parallelism needs to be lowered substantially (below 60).
                        //var randomNumbers = new uint[] { random.NextUInt16(), random.NextUInt16() };
                        //var products = Common.Numerics.SimdOperations.MultiplyVectors(randomNumbers, randomNumbers, 2);

                        if ((ulong)(a * a) + b * b <= ((uint)ushort.MaxValue * ushort.MaxValue))
                        //if ((ulong)products[0] + products[1] <= ((uint)ushort.MaxValue * ushort.MaxValue))
                        {
                            inCircleCount++;
                        }
                    }

                    return(inCircleCount);
                },
                    i);
            }

            Task.WhenAll(tasks).Wait();

            uint inCircleCountSum = 0;

            for (int i = 0; i < MaxDegreeOfParallelism; i++)
            {
                inCircleCountSum += tasks[i].Result;
            }

            memory.WriteUInt32(EstimatePi_InCircleCountSumUInt32Index, inCircleCountSum);
        }
Пример #18
0
        private uint RecursivelyCalculateFactorial(SimpleMemory memory, short number)
        {
            memory.WriteUInt32(
                CalculateFactorial_InvocationCounterUInt32Index,
                memory.ReadUInt32(CalculateFactorial_InvocationCounterUInt32Index) + 1);

            if (number == 0)
            {
                return(1);
            }
            return((uint)(number * RecursivelyCalculateFactorial(memory, (short)(number - 1))));
        }
Пример #19
0
        // The return value should be a type with a bigger range than the input. Although we can use 64b numbers
        // internally we can't write the to memory yet so the input needs to be a short.
        private uint RecursivelyCalculateFibonacchiSeries(SimpleMemory memory, short number)
        {
            memory.WriteUInt32(
                CalculateFibonacchiSeries_InvocationCounterUInt32Index,
                memory.ReadUInt32(CalculateFibonacchiSeries_InvocationCounterUInt32Index) + 1);

            if (number == 0 || number == 1)
            {
                return((uint)number);
            }
            return(RecursivelyCalculateFibonacchiSeries(memory, (short)(number - 2)) + RecursivelyCalculateFibonacchiSeries(memory, (short)(number - 1)));
        }
Пример #20
0
        /// <summary>
        /// This function is for testing how Hastlayer works by running a random generator, writing the results into
        /// SimpleMemory.
        /// </summary>
        public void TestPrng(SimpleMemory memory)
        {
            var kernels = new KpzKernels();

            kernels.InitializeParametersFromMemory(memory);
            var numberOfStepsInIteration = KpzKernels.GridWidth * KpzKernels.GridHeight;

            for (int i = 0; i < numberOfStepsInIteration; i++)
            {
                memory.WriteUInt32(i, kernels.Random1.NextUInt32());
            }
        }
Пример #21
0
        /// <summary>
        /// Creates a <see cref="SimpleMemory"/> object filled with the input values.
        /// </summary>
        /// <param name="inputOne">The first string to compare.</param>
        /// <param name="inputTwo">The second string to compare.</param>
        /// <returns>Returns a <see cref="SimpleMemory"/> object containing the input values.</returns>
        private SimpleMemory CreateSimpleMemory(string inputOne, string inputTwo)
        {
            var cellCount = 2 + inputOne.Length + inputTwo.Length + (inputOne.Length * inputTwo.Length) * 2 + Math.Max(inputOne.Length, inputTwo.Length);

            var simpleMemory = new SimpleMemory(cellCount);

            simpleMemory.WriteUInt32(GetLCS_InputOneLengthIndex, (uint)inputOne.Length);
            simpleMemory.WriteUInt32(GetLCS_InputTwoLengthIndex, (uint)inputTwo.Length);

            for (int i = 0; i < inputOne.Length; i++)
            {
                simpleMemory.WriteUInt32(GetLCS_InputOneStartIndex + i, Encoding.UTF8.GetBytes(inputOne[i].ToString())[0]);
            }

            for (int i = 0; i < inputTwo.Length; i++)
            {
                simpleMemory.WriteUInt32(GetLCS_InputOneStartIndex + i + inputOne.Length, Encoding.UTF8.GetBytes(inputTwo[i].ToString())[0]);
            }

            return(simpleMemory);
        }
Пример #22
0
        /// <summary>
        /// Creates a <see cref="SimpleMemory"/> object filled with the input values.
        /// </summary>
        /// <param name="iterationsCount">The number of iterations the algorithm uses for calculations.</param>
        /// <returns>Returns a <see cref="SimpleMemory"/> object containing the input values.</returns>
        private static SimpleMemory CreateSimpleMemory(int iterationsCount)
        {
            var simpleMemory = new SimpleMemory(10 + iterationsCount * 3);

            simpleMemory.WriteInt32(MonteCarloAlgorithm.MonteCarloAlgorithm_IterationsCountIndex, iterationsCount);

            for (int i = 0; i < iterationsCount * 3; i++)
            {
                simpleMemory.WriteUInt32(MonteCarloAlgorithm.MonteCarloAlgorithm_RandomNumbersStartIndex + i, (uint)(_random.Next(101)));
            }

            return(simpleMemory);
        }
Пример #23
0
        public static bool[] ArePrimeNumbers(this PrimeCalculator primeCalculator, uint[] numbers)
        {
            var memory = new SimpleMemory(numbers.Length + 1);

            memory.WriteUInt32(PrimeCalculator.ArePrimeNumbers_InputUInt32CountIndex, (uint)numbers.Length);

            for (int i = 0; i < numbers.Length; i++)
            {
                memory.WriteUInt32(PrimeCalculator.ArePrimeNumbers_InputUInt32sStartIndex + i, numbers[i]);
            }

            primeCalculator.ArePrimeNumbers(memory);


            var output = new bool[numbers.Length];

            for (int i = 0; i < numbers.Length; i++)
            {
                output[i] = memory.ReadBoolean(PrimeCalculator.ArePrimeNumbers_OutputUInt32sStartIndex + i);
            }
            return(output);
        }
Пример #24
0
        private static bool[] RunArePrimeNumbersMethod(uint[] numbers, Action <SimpleMemory> methodRunner)
        {
            // We need to allocate more memory cells, enough for all the inputs and outputs.
            var memory = new SimpleMemory(numbers.Length + 1);

            memory.WriteUInt32(PrimeCalculator.ArePrimeNumbers_InputUInt32CountIndex, (uint)numbers.Length);
            for (int i = 0; i < numbers.Length; i++)
            {
                memory.WriteUInt32(PrimeCalculator.ArePrimeNumbers_InputUInt32sStartIndex + i, numbers[i]);
            }


            methodRunner(memory);


            var output = new bool[numbers.Length];

            for (int i = 0; i < numbers.Length; i++)
            {
                output[i] = memory.ReadBoolean(PrimeCalculator.ArePrimeNumbers_OutputBooleansStartIndex + i);
            }
            return(output);
        }
Пример #25
0
        public virtual void Run(SimpleMemory memory)
        {
            var inputNumber = memory.ReadUInt32(Run_InputUInt32Index);

            // Or:
            inputNumber = new MemoryContainer(memory).GetInput();

            // Arrays can be initialized as usual, as well as objects.
            var numberContainers1 = new[]
            {
                new NumberContainer {
                    Number = inputNumber
                },
                new NumberContainer {
                    Number = inputNumber + 4
                },
                new NumberContainer {
                    Number = 24
                },
                new NumberContainer(9)
            };

            // Array elements can be accessed and modified as usual.
            numberContainers1[0].NumberPlusFive = inputNumber + 10;
            numberContainers1[1].IncreaseNumber(5);


            // Note that array dimensions need to be defined compile-time. They needn't bee constants directly used
            // when instantiating the array but the size argument needs to be resolvable compile-time (so if it's a
            // variable then its value should be computable from all other values at compile-time).
            var numberContainers2 = new NumberContainer[1];
            var numberContainer   = new NumberContainer();

            numberContainer.Number = 5;
            numberContainer.Number = numberContainer.NumberPlusFive;
            if (!numberContainer.WasIncreased)
            {
                numberContainer.IncreaseNumber(5);
            }
            numberContainers2[0] = numberContainer;

            for (int i = 0; i < numberContainers1.Length; i++)
            {
                numberContainers1[i].IncreaseNumber(numberContainers2[0].Number);
            }

            // You can also pass arrays and other objects around to other methods.
            memory.WriteUInt32(Run_OutputUInt32Index, SumNumberCointainers(numberContainers1));
        }
Пример #26
0
 /// <summary>
 /// This function pushes parameters and PRNG seed to the FPGA.
 /// </summary>
 /// <param name="memoryDst"></param>
 /// <param name="testMode"></param>
 /// <param name="randomSeed1"></param>
 /// <param name="randomSeed2"></param>
 /// <param name="numberOfIterations"></param>
 public static void CopyParametersToMemory(SimpleMemory memoryDst, bool testMode, ulong randomSeed1,
                                           ulong randomSeed2, uint numberOfIterations)
 {
     memoryDst.WriteUInt32(KpzKernels.MemIndexRandomStates, (uint)(randomSeed1 & 0xFFFFFFFFUL));
     memoryDst.WriteUInt32(KpzKernels.MemIndexRandomStates + 1, (uint)((randomSeed1 >> 32) & 0xFFFFFFFFUL));
     memoryDst.WriteUInt32(KpzKernels.MemIndexRandomStates + 2, (uint)(randomSeed2 & 0xFFFFFFFFUL));
     memoryDst.WriteUInt32(KpzKernels.MemIndexRandomStates + 3, (uint)((randomSeed2 >> 32) & 0xFFFFFFFFUL));
     memoryDst.WriteUInt32(KpzKernels.MemIndexStepMode, (testMode) ? 1U : 0U);
     memoryDst.WriteUInt32(KpzKernels.MemIndexNumberOfIterations, numberOfIterations);
 }
Пример #27
0
        public virtual void Run(SimpleMemory memory)
        {
            var input = memory.ReadUInt32(Run_InputUInt32Index);
            var tasks = new Task <uint> [MaxDegreeOfParallelism];

            // Hastlayer will figure out how many Tasks you want to start if you kick them off in a loop like this.
            // If this is more involved then you'll need to tell Hastlayer the level of parallelism, see the comment in
            // ParallelAlgorithmSampleRunner.
            for (uint i = 0; i < MaxDegreeOfParallelism; i++)
            {
                tasks[i] = Task.Factory.StartNew(
                    indexObject =>
                {
                    var index   = (uint)indexObject;
                    uint result = input + index * 2;

                    var even = true;
                    for (int j = 2; j < 9999999; j++)
                    {
                        if (even)
                        {
                            result += index;
                        }
                        else
                        {
                            result -= index;
                        }

                        even = !even;
                    }

                    return(result);
                },
                    i);
            }

            // Task.WhenAny() can be used too.
            Task.WhenAll(tasks).Wait();

            uint output = 0;

            for (int i = 0; i < MaxDegreeOfParallelism; i++)
            {
                output += tasks[i].Result;
            }

            memory.WriteUInt32(Run_OutputUInt32Index, output);
        }
Пример #28
0
        /// <summary>
        /// Creates a <see cref="SimpleMemory"/> instance that stores the image.
        /// </summary>
        /// <param name="image">The image to process.</param>
        /// <param name="topLeft">Top left value.</param>
        /// <param name="topMiddle">Top middle value.</param>
        /// <param name="topRight">Top right value.</param>
        /// <param name="middleLeft">Middle left value.</param>
        /// <param name="pixel">The current pixel value.</param>
        /// <param name="middleRight">Middle right value.</param>
        /// <param name="bottomLeft">Bottom left value.</param>
        /// <param name="bottomMiddle">Bottom middle value.</param>
        /// <param name="bottomRight">Bottom right value.</param>
        /// <param name="factor">The value to divide the summed matrix values with.</param>
        /// <param name="offset">Offset value added to the result.</param>
        /// <returns>The instance of the created <see cref="SimpleMemory"/>.</returns>
        private SimpleMemory CreateSimpleMemory(
            Bitmap image,
            int topLeft, int topMiddle, int topRight,
            int middleLeft, int pixel, int middleRight,
            int bottomLeft, int bottomMiddle, int bottomRight,
            int factor = 1, int offset = 0)
        {
            var memory = new SimpleMemory(image.Width * image.Height * 6 + 13);

            memory.WriteUInt32(FilterImage_ImageWidthIndex, (uint)image.Width);
            memory.WriteUInt32(FilterImage_ImageHeightIndex, (uint)image.Height);
            memory.WriteInt32(FilterImage_TopLeftIndex, topLeft);
            memory.WriteInt32(FilterImage_TopMiddleIndex, topMiddle);
            memory.WriteInt32(FilterImage_TopRightIndex, topRight);
            memory.WriteInt32(FilterImage_MiddleLeftIndex, middleLeft);
            memory.WriteInt32(FilterImage_PixelIndex, pixel);
            memory.WriteInt32(FilterImage_MiddleRightIndex, middleRight);
            memory.WriteInt32(FilterImage_BottomLeftIndex, bottomLeft);
            memory.WriteInt32(FilterImage_BottomMiddleIndex, bottomMiddle);
            memory.WriteInt32(FilterImage_BottomRightIndex, bottomRight);
            memory.WriteInt32(FilterImage_FactorIndex, factor);
            memory.WriteInt32(FilterImage_OffsetIndex, offset);

            int size = image.Width * image.Height;

            for (int x = 0; x < image.Height; x++)
            {
                for (int y = 0; y < image.Width; y++)
                {
                    var pixelValue = image.GetPixel(y, x);

                    memory.WriteUInt32((x * image.Width + y) * 3 + FilterImage_ImageStartIndex, pixelValue.R);
                    memory.WriteUInt32((x * image.Width + y) * 3 + 1 + FilterImage_ImageStartIndex, pixelValue.G);
                    memory.WriteUInt32((x * image.Width + y) * 3 + 2 + FilterImage_ImageStartIndex, pixelValue.B);

                    memory.WriteUInt32((x * image.Width + y) * 3 + (size * 3) + FilterImage_ImageStartIndex, pixelValue.R);
                    memory.WriteUInt32((x * image.Width + y) * 3 + 1 + (size * 3) + FilterImage_ImageStartIndex, pixelValue.G);
                    memory.WriteUInt32((x * image.Width + y) * 3 + 2 + (size * 3) + FilterImage_ImageStartIndex, pixelValue.B);
                }
            }

            return(memory);
        }
Пример #29
0
        public virtual void Run(SimpleMemory memory)
        {
            var input = memory.ReadUInt32(Run_InputUInt32Index);
            var tasks = new Task <uint> [MaxDegreeOfParallelism];

            for (uint i = 0; i < MaxDegreeOfParallelism; i++)
            {
                tasks[i] = Task.Factory.StartNew(
                    indexObject =>
                {
                    var index   = (uint)indexObject;
                    uint result = input + index * 2;

                    var even = true;
                    for (int j = 2; j < 9999999; j++)
                    {
                        if (even)
                        {
                            result += index;
                        }
                        else
                        {
                            result -= index;
                        }

                        even = !even;
                    }

                    return(result);
                },
                    i);
            }

            // Task.WhenAny() can be used too.
            Task.WhenAll(tasks).Wait();

            uint output = 0;

            for (int i = 0; i < MaxDegreeOfParallelism; i++)
            {
                output += tasks[i].Result;
            }

            memory.WriteUInt32(Run_OutputUInt32Index, output);
        }
Пример #30
0
        public virtual void CalculateTorusSectionValues(SimpleMemory memory)
        {
            int w, x, y, s, z, dw, dx, dy, dz, sw, swx, swy, swz, varw, varx, vary, varz, ss, volume;

            w = x = y = s = z = dw = dx = dy = dz = sw = swx = swy = swz = varw = varx = vary = varz = 0;

            // Rounded constant value instead of "0.2 * (Math.Exp(5.0) - Math.Exp(-5.0))".
            // This is the interval of s to be random sampled.
            ss     = 29;
            volume = 3 * 7 * ss; // Volume of the sampled region in x,y,s space.

            int iterationsCount = memory.ReadInt32(MonteCarloAlgorithm_IterationsCountIndex);

            int sumsw    = 0;
            int sumswx   = 0;
            int sumswy   = 0;
            int sumswz   = 0;
            int sumvarw  = 0;
            int sumvarwx = 0;
            int sumvarwy = 0;
            int sumvarwz = 0;

            uint randomX = 0;
            uint randomY = 0;
            uint randomZ = 0;

            for (int i = 1; i <= iterationsCount; i++)
            {
                randomX = memory.ReadUInt32(MonteCarloAlgorithm_RandomNumbersStartIndex + i);
                randomY = memory.ReadUInt32(MonteCarloAlgorithm_RandomNumbersStartIndex + i + 1);
                randomZ = memory.ReadUInt32(MonteCarloAlgorithm_RandomNumbersStartIndex + i + 2);

                // Pick points randomly from the sampled region.
                x = checked ((int)(Multiplier + randomX * 3 * Multiplier / 100));

                // The constant can't be specified properly inline as (since it can't be specified as a short, see:
                // http://stackoverflow.com/questions/8670511/how-to-specify-a-short-int-constant-without-casting)
                // it would cause an underflow and be casted to an ulong.
                short minusThree = -3;
                y = checked ((int)(minusThree * Multiplier + randomY * 7 * Multiplier / 100));
                short thirteen = 13;
                s = checked ((int)(thirteen + ss * (short)randomZ * Multiplier / 100));
                short two = 2;
                z = checked ((int)(two * Multiplier * Log(5 * s / Multiplier) / 10));

                int b = checked ((int)(Sqrt((x * x) + (y * y)) - 3 * Multiplier));
                int a = checked ((int)(((z * z) + (b * b)) / Multiplier));

                // Check if the selected points are inside the torus.
                // If they are inside, add to the various cumulants.
                if (a < Multiplier)
                {
                    sw    = checked (sw + Multiplier);
                    swx   = checked (swx + x);
                    swy   = checked (swy + y);
                    swz   = checked (swz + z);
                    varw  = Multiplier;
                    varx += (x * x) / Multiplier;
                    vary += (y * y) / Multiplier;
                    varz += (z * z) / Multiplier;
                }

                // Divide the values with the multiplier to return to the original numbers in every 1000th iteration.
                // This way we can avoid overflows at the final computations, but we still get more precise values.
                if (i % 1000 == 0 || i == iterationsCount)
                {
                    sumsw     = checked (sumsw + sw / Multiplier);
                    sumswx    = checked (sumswx + swx / Multiplier);
                    sumswy    = checked (sumswy + swy / Multiplier);
                    sumswz    = checked (sumswz + swz / Multiplier);
                    sumvarw   = Multiplier;
                    sumvarwx += varx / Multiplier;
                    sumvarwy += vary / Multiplier;
                    sumvarwz += varz / Multiplier;

                    sw = swx = swy = swz = varw = varx = vary = varz = 0;
                }
            }

            // Values of the integrals.
            memory.WriteUInt32(MonteCarloAlgorithm_WIndex, checked ((uint)((uint)volume * (uint)sumsw / iterationsCount)));
            memory.WriteUInt32(MonteCarloAlgorithm_XIndex, checked ((uint)((uint)volume * (uint)sumswx / iterationsCount)));
            memory.WriteUInt32(MonteCarloAlgorithm_YIndex, checked ((uint)((uint)volume * (uint)sumswy / iterationsCount)));
            memory.WriteUInt32(MonteCarloAlgorithm_ZIndex, checked ((uint)((uint)volume * (uint)sumswz / iterationsCount)));

            // Values of the error estimates.
            memory.WriteUInt32(MonteCarloAlgorithm_DWIndex,
                               checked ((uint)(volume * Sqrt((int)((sumvarw / iterationsCount - Pow((sumsw / iterationsCount), 2)) / iterationsCount)))));
            memory.WriteUInt32(MonteCarloAlgorithm_DXIndex,
                               checked ((uint)(volume * Sqrt((int)((sumvarwx / iterationsCount - Pow((sumswx / iterationsCount), 2)) / iterationsCount)))));
            memory.WriteUInt32(MonteCarloAlgorithm_DYIndex,
                               checked ((uint)(volume * Sqrt((int)((sumvarwy / iterationsCount - Pow((sumswy / iterationsCount), 2)) / iterationsCount)))));
            memory.WriteUInt32(MonteCarloAlgorithm_DZIndex,
                               checked ((uint)(volume * Sqrt((int)((sumvarwz / iterationsCount - Pow((sumswz / iterationsCount), 2)) / iterationsCount)))));
        }