예제 #1
0
        public IEnumerable <Fix64> ParallelizedCalculateIntegerSumUpToNumbers(int[] numbers)
        {
            if (numbers.Length != MaxDegreeOfParallelism)
            {
                throw new ArgumentException(
                          "Provide as many numbers as the degree of parallelism of Fix64Calculator is (" +
                          MaxDegreeOfParallelism + ")");
            }

            var memory = new SimpleMemory(2 * MaxDegreeOfParallelism);

            for (int i = 0; i < numbers.Length; i++)
            {
                memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]);
            }

            ParallelizedCalculateIntegerSumUpToNumbers(memory);

            var results = new Fix64[MaxDegreeOfParallelism];

            for (int i = 0; i < MaxDegreeOfParallelism; i++)
            {
                var itemOutputStartIndex = ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i * 2;

                results[i] = Fix64.FromRawInts(new[]
                {
                    memory.ReadInt32(itemOutputStartIndex),
                    memory.ReadInt32(itemOutputStartIndex + 1)
                });
            }

            return(results);
        }
예제 #2
0
        public virtual void IsPrimeNumber(SimpleMemory memory)
        {
            var number  = memory.ReadUInt32(IsPrimeNumber_InputUInt32Index);
            var isPrime = IsPrimeNumberInternal(number);

            memory.WriteBoolean(IsPrimeNumber_OutputBooleanIndex, isPrime);
        }
예제 #3
0
        private int[] RunSimdOperation(int[] vector1, int[] vector2, Action <SimpleMemory> operation)
        {
            SimdOperations.ThrowIfVectorsNotEquallyLong(vector1, vector2);

            var originalElementCount = vector1.Length;

            vector1 = vector1.PadToMultipleOf(MaxDegreeOfParallelism);
            vector2 = vector2.PadToMultipleOf(MaxDegreeOfParallelism);

            var elementCount = vector1.Length;
            var memory       = new SimpleMemory(1 + elementCount * 2);

            memory.WriteInt32(VectorsElementCountInt32Index, elementCount);

            for (int i = 0; i < elementCount; i++)
            {
                memory.WriteInt32(VectorElementsStartInt32Index + i, vector1[i]);
                memory.WriteInt32(VectorElementsStartInt32Index + elementCount + i, vector2[i]);
            }

            operation(memory);

            var result = new int[elementCount];

            for (int i = 0; i < elementCount; i++)
            {
                result[i] = memory.ReadInt32(ResultVectorElementsStartInt32Index + i);
            }

            return(result.CutToLength(originalElementCount));
        }
예제 #4
0
        /// <summary>
        /// Calculates whether the number is prime, in an async way.
        /// </summary>
        /// <remarks>
        /// For efficient parallel execution with multiple connected FPGA boards you can make a non-parallelized hardware
        /// entry point method async like this.
        /// </remarks>
        public virtual Task IsPrimeNumberAsync(SimpleMemory memory)
        {
            IsPrimeNumber(memory);

            // In .NET <4.6 Task.FromResult(true) can be used too.
            return(Task.CompletedTask);
        }
예제 #5
0
 /// <summary>
 /// 初始化
 /// </summary>
 private SimpleMediator()
 {
     //系统实例化
     CampSystem   = new SimpleCamp();
     MemorySystem = new SimpleMemory();
     GameMgr      = new SimpleGameMgr();
 }
예제 #6
0
        private static void Verify(SimpleMemory memory, SimpleMemory referenceMemory)
        {
            var mismatches = new List <HardwareExecutionResultMismatchException.Mismatch>();

            for (int i = 0; i < memory.CellCount && i < referenceMemory.CellCount; i++)
            {
                if (!memory.Read4Bytes(i).SequenceEqual(referenceMemory.Read4Bytes(i)))
                {
                    mismatches.Add(new HardwareExecutionResultMismatchException.Mismatch(
                                       i, memory.Read4Bytes(i), referenceMemory.Read4Bytes(i)));
                }
            }

            if (mismatches.Count > 0)
            {
                Console.WriteLine("MISMATCH:");
                Console.WriteLine(new HardwareExecutionResultMismatchException(mismatches));
            }
            if (memory.CellCount != referenceMemory.CellCount)
            {
                Console.WriteLine("MISMATCH IN LENGTH:{0}Hardware: {1}{0}Software: {2}",
                                  Environment.NewLine, memory.CellCount, referenceMemory.CellCount);
            }
            else if (mismatches.Count == 0)
            {
                Console.WriteLine("Verification passed!");
            }
        }
예제 #7
0
        /// <summary>
        /// Calculates for multiple numbers whether they're primes, in a parallelized way.
        /// </summary>
        /// <remarks>
        /// This demonstrates how you can write parallelized code that Hastlayer will process and turn into hardware-level
        /// parallelization: the Tasks' bodies will be copied in hardware as many times as many Tasks you start; thus,
        /// the actual level of parallelism you get on the hardware corresponds to the number of Tasks, not the number
        /// of CPU cores.
        /// </remarks>
        public virtual void ParallelizedArePrimeNumbers(SimpleMemory memory)
        {
            // We need this information explicitly as we can't store arrays directly in memory.
            uint numberCount = memory.ReadUInt32(ArePrimeNumbers_InputUInt32CountIndex);

            // At the moment Hastlayer only supports a fixed degree of parallelism so we need to pad the input array
            // if necessary, see PrimeCalculatorExtensions.
            var tasks = new Task <bool> [MaxDegreeOfParallelism];
            int i     = 0;

            while (i < numberCount)
            {
                for (int m = 0; m < MaxDegreeOfParallelism; m++)
                {
                    var currentNumber = memory.ReadUInt32(ArePrimeNumbers_InputUInt32sStartIndex + i + m);

                    // Note that you can just call (thread-safe) methods from inside Tasks as usual. In hardware those
                    // invoked methods will be copied together with the Tasks' bodies too.
                    tasks[m] = Task.Factory.StartNew(
                        numberObject => IsPrimeNumberInternal((uint)numberObject),
                        currentNumber);
                }

                // Hastlayer doesn't support async code at the moment since ILSpy doesn't handle the new Roslyn-compiled
                // code. See: https://github.com/icsharpcode/ILSpy/issues/502
                Task.WhenAll(tasks).Wait();

                for (int m = 0; m < MaxDegreeOfParallelism; m++)
                {
                    memory.WriteBoolean(ArePrimeNumbers_OutputBooleansStartIndex + i + m, tasks[m].Result);
                }

                i += MaxDegreeOfParallelism;
            }
        }
        /// <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);
        }
예제 #9
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);
 }
        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);
            numberContainers1[2].IncreaseNumberBy10();

            // Using ref and out.
            uint increaseBy = 10;

            numberContainers1[3].IncreaseNumberByParameterTimes10(ref increaseBy, out uint originalNumber);
예제 #11
0
        public static uint CalculateFactorial(this RecursiveAlgorithms recursiveAlgorithms, short number)
        {
            var memory = new SimpleMemory(2);

            memory.WriteInt32(RecursiveAlgorithms.CalculateFactorial_InputShortIndex, number);
            recursiveAlgorithms.CalculateFactorial(memory);
            return(memory.ReadUInt32(RecursiveAlgorithms.CalculateFactorial_OutputUInt32Index));
        }
예제 #12
0
파일: ZLink.cs 프로젝트: ZYSF/ZLink
 public SimpleMemory GetMemory()
 {
     if (_memory == null)
     {
         _memory = new SimpleMemory(memsz);
     }
     return(_memory);
 }
예제 #13
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));
        }
예제 #14
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));
        }
예제 #15
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);
        }
예제 #16
0
        public int Run(int input)
        {
            var memory = new SimpleMemory(1);

            memory.WriteInt32(Run_InputOutputInt32Index, input);
            Run(memory);
            return(memory.ReadInt32(Run_InputOutputInt32Index));
        }
예제 #17
0
        public uint CalculateFactorial(short number)
        {
            var memory = new SimpleMemory(2);

            memory.WriteInt32(CalculateFactorial_InputShortIndex, number);
            CalculateFactorial(memory);
            return(memory.ReadUInt32(CalculateFactorial_OutputUInt32Index));
        }
예제 #18
0
        public uint Run(uint input)
        {
            var memory = new SimpleMemory(1);

            memory.WriteUInt32(Run_InputUInt32Index, input);
            Run(memory);
            return(memory.ReadUInt32(Run_OutputUInt32Index));
        }
예제 #19
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));
        }
예제 #20
0
        public uint CalculateFibonacchiSeries(short number)
        {
            var memory = new SimpleMemory(2);

            memory.WriteInt32(CalculateFibonacchiSeries_InputShortIndex, number);
            CalculateFibonacchiSeries(memory);
            return(memory.ReadUInt32(CalculateFibonacchiSeries_OutputUInt32Index));
        }
예제 #21
0
        /// <summary>
        /// Calculates whether a number is prime.
        /// </summary>
        /// <remarks>
        /// Note that the entry point of SimpleMemory-using algorithms should be void methods having a single
        /// <see cref="SimpleMemory"/> argument.
        /// </remarks>
        /// <param name="memory">The <see cref="SimpleMemory"/> object representing the accessible memory space.</param>
        public virtual void IsPrimeNumber(SimpleMemory memory)
        {
            // Reading out the input parameter.
            var number = memory.ReadUInt32(IsPrimeNumber_InputUInt32Index);

            // Writing back the output.
            memory.WriteBoolean(IsPrimeNumber_OutputBooleanIndex, IsPrimeNumberInternal(number));
        }
예제 #22
0
        public static int Run(this Loopback loopback, int input)
        {
            var memory = new SimpleMemory(1);

            memory.WriteInt32(Loopback.Run_InputOutputInt32Index, input);
            loopback.Run(memory);
            return(memory.ReadInt32(Loopback.Run_InputOutputInt32Index));
        }
예제 #23
0
        public int Run(int startIndex, int length)
        {
            var memory = new SimpleMemory(startIndex + length < 2 ? 2 : startIndex + length);

            memory.WriteInt32(Run_StartIndexInt32Index, startIndex);
            memory.WriteInt32(Run_LengthInt32Index, length);
            Run(memory);
            return(memory.ReadInt32(Run_StartIndexInt32Index));
        }
예제 #24
0
 /// <summary>
 /// It loads the TestMode, NumberOfIterations parameters and also the PRNG seed from the SimpleMemory at
 /// the beginning.
 /// </summary>
 /// <param name="memory"></param>
 public void InitializeParametersFromMemory(SimpleMemory memory)
 {
     Prng1 = new PrngMWC64X((((ulong)memory.ReadUInt32(MemIndexRandomStates)) << 32) |
                            memory.ReadUInt32(MemIndexRandomStates + 1));
     Prng2 = new PrngMWC64X((((ulong)memory.ReadUInt32(MemIndexRandomStates + 2)) << 32) |
                            memory.ReadUInt32(MemIndexRandomStates + 3));
     TestMode           = (memory.ReadUInt32(MemIndexStepMode) & 1) == 1;
     NumberOfIterations = memory.ReadUInt32(MemIndexNumberOfIterations);
 }
예제 #25
0
        public virtual Task IsPrimeNumberAsync(SimpleMemory memory)
        {
            IsPrimeNumber(memory);

            // For efficient parallel execution with multiple connected FPGA boards you can make a non-parallelized
            // hardware entry point method async with Task.FromResult(). In .NET <4.6 Task.FromResult(true) can be used
            // too.
            return(Task.CompletedTask);
        }
예제 #26
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));
        }
예제 #27
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);
 }
예제 #28
0
 /// <summary>Pull table from the FPGA.</summary>
 public static void CopyFromSimpleMemoryToGrid(KpzNode[,] gridDst, SimpleMemory memorySrc)
 {
     for (int x = 0; x < KpzKernels.GridWidth; x++)
     {
         for (int y = 0; y < KpzKernels.GridHeight; y++)
         {
             gridDst[x, y] = KpzNode.DeserializeFromUInt32(memorySrc.ReadUInt32(KpzKernels.MemIndexGrid + y * KpzKernels.GridWidth + x));
         }
     }
 }
예제 #29
0
        private static void SaveFile(OutputFileType fileType,
                                     PayloadType payloadType,
                                     string fileName,
                                     bool isInput,
                                     SimpleMemory memory)
        {
            var fileNamePrefix = isInput ? "in-" : "out-";
            var direction      = isInput ? "input" : "output";

            switch (fileType)
            {
            case OutputFileType.None: return;

            case OutputFileType.Hexdump:
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = fileNamePrefix + DefaultHexdumpFileName;
                }
                Console.WriteLine("Saving {0} hexdump to '{1}'...", direction, fileName);
                if (fileName == Options.OutputFileNameConsole)
                {
                    WriteHexdump(Console.Out, memory);
                }
                else
                {
                    using (var streamWriter = new StreamWriter(fileName, false, Encoding.UTF8))
                    {
                        WriteHexdump(streamWriter, memory);
                    }
                }
                break;

            case OutputFileType.Binary:
                if (payloadType != PayloadType.BinaryFile)
                {
                    if (string.IsNullOrEmpty(fileName))
                    {
                        fileName = fileNamePrefix + DefaultBinaryFileName;
                    }
                    Console.WriteLine("Saving {0} binary file to '{1}'...", direction, fileName);
                    using (var fileStream = File.OpenWrite(fileName))
                    {
                        var accessor = new SimpleMemoryAccessor(memory);
                        var segment  = accessor.Get().GetUnderlyingArray();
                        fileStream.Write(segment.Array, segment.Offset, memory.ByteCount);
                    }
                }
                break;

            default:
                throw new ArgumentException(string.Format("Unknown {0} file type: {1}", direction, fileType));
            }

            Console.WriteLine("File saved.");
        }
예제 #30
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));
                }
            }
        }