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); }
private void RunSimdOperation(SimpleMemory memory, SimdOperation operation) { var elementCount = memory.ReadInt32(VectorsElementCountInt32Index); int i = 0; while (i < elementCount) { var vector1 = new int[MaxDegreeOfParallelism]; var vector2 = new int[MaxDegreeOfParallelism]; var resultVector = new int[MaxDegreeOfParallelism]; for (int m = 0; m < MaxDegreeOfParallelism; m++) { vector1[m] = memory.ReadInt32(VectorElementsStartInt32Index + i + m); } for (int m = 0; m < MaxDegreeOfParallelism; m++) { vector2[m] = memory.ReadInt32(VectorElementsStartInt32Index + i + m + elementCount); } switch (operation) { case SimdOperation.Add: resultVector = SimdOperations.AddVectors(vector1, vector2, MaxDegreeOfParallelism); break; case SimdOperation.Subtract: resultVector = SimdOperations.SubtractVectors(vector1, vector2, MaxDegreeOfParallelism); break; case SimdOperation.Multiply: resultVector = SimdOperations.MultiplyVectors(vector1, vector2, MaxDegreeOfParallelism); break; case SimdOperation.Divide: resultVector = SimdOperations.DivideVectors(vector1, vector2, MaxDegreeOfParallelism); break; default: break; } for (int m = 0; m < MaxDegreeOfParallelism; m++) { memory.WriteInt32(ResultVectorElementsStartInt32Index + i + m, resultVector[m]); } i += MaxDegreeOfParallelism; } }
public virtual void Run(SimpleMemory memory) { var startIndex = memory.ReadInt32(Run_StartIndexInt32Index); var length = memory.ReadInt32(Run_LengthInt32Index); var endIndex = startIndex + length; for (int i = startIndex; i < endIndex; i++) { // Adding 1 to the input so it's visible whether this actually has run, not just the untouched data was // sent back. memory.WriteInt32(i, memory.ReadInt32(i) + 1); } }
public Fix64 CalculateIntegerSumUpToNumber(int input) { var memory = new SimpleMemory(2); memory.WriteInt32(CalculateLargeIntegerSum_InputInt32Index, input); CalculateIntegerSumUpToNumber(memory); return(Fix64.FromRawInts(new[] { memory.ReadInt32(CalculateLargeIntegerSum_OutputInt32Index), memory.ReadInt32(CalculateLargeIntegerSum_OutputInt32Index + 1) })); }
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)); }
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)); }
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)); }
public int Run(int input) { var memory = new SimpleMemory(1); memory.WriteInt32(Run_InputOutputInt32Index, input); Run(memory); return(memory.ReadInt32(Run_InputOutputInt32Index)); }
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)); }
/// <summary> /// Creates an image from a <see cref="SimpleMemory"/> instance. /// </summary> /// <param name="memory">The <see cref="SimpleMemory"/> instance.</param> /// <param name="image">The original image.</param> /// <returns>Returns the processed image.</returns> private Bitmap CreateImage(SimpleMemory memory, Bitmap image) { var newImage = new Bitmap(image); int r, g, b; for (int x = 0; x < newImage.Height; x++) { for (int y = 0; y < newImage.Width; y++) { r = memory.ReadInt32((x * newImage.Width + y) * 3 + FilterImage_ImageStartIndex); g = memory.ReadInt32((x * newImage.Width + y) * 3 + 1 + FilterImage_ImageStartIndex); b = memory.ReadInt32((x * newImage.Width + y) * 3 + 2 + FilterImage_ImageStartIndex); newImage.SetPixel(y, x, Color.FromArgb(r, g, b)); } } return(newImage); }
public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) { var number = memory.ReadInt32(CalculateLargeIntegerSum_InputInt32Index); var a = new Fix64(1); var b = a; for (var i = 1; i < number; i++) { a += b; } var integers = a.ToIntegers(); memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, integers[0]); memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index + 1, integers[1]); }
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); }
public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) { var numbers = new int[MaxDegreeOfParallelism]; var tasks = new Task <TaskResult> [MaxDegreeOfParallelism]; for (int i = 0; i < MaxDegreeOfParallelism; i++) { var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); tasks[i] = Task.Factory.StartNew( upToNumberObject => { var a = new Fix64(1); var b = a; for (var j = 1; j < (int)upToNumberObject; j++) { a += b; } var integers = a.ToIntegers(); return(new TaskResult { Fix64Low = integers[0], Fix64High = integers[1] }); }, upToNumber); } Task.WhenAll(tasks).Wait(); for (int i = 0; i < MaxDegreeOfParallelism; i++) { var itemOutputStartIndex = ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i * 2; memory.WriteInt32(itemOutputStartIndex, tasks[i].Result.Fix64Low); memory.WriteInt32(itemOutputStartIndex + 1, tasks[i].Result.Fix64High); } }
public virtual void ScheduleIterations(SimpleMemory memory) { int numberOfIterations = memory.ReadInt32(MemIndexNumberOfIterations); const int TasksPerIteration = (GridSize * GridSize) / (LocalGridSize * LocalGridSize); const int SchedulesPerIteration = TasksPerIteration / ParallelTasks; int iterationGroupSize = numberOfIterations * ReschedulesPerTaskIteration; const int PokesInsideTask = LocalGridSize * LocalGridSize / ReschedulesPerTaskIteration; const int LocalGridPartitions = GridSize / LocalGridSize; //Note: TotalNumberOfTasks = TasksPerIteration * NumberOfIterations == // ((GridSize * GridSize) / (LocalGridSize * LocalGridSize)) * NumberOfIterations int parallelTaskRandomIndex = 0; uint randomSeedTemp; var random0 = new RandomMwc64X(); var taskLocals = new KpzKernelsTaskState[ParallelTasks]; for (int TaskLocalsIndex = 0; TaskLocalsIndex < ParallelTasks; TaskLocalsIndex++) { taskLocals[TaskLocalsIndex] = new KpzKernelsTaskState { BramDx = new bool[LocalGridSize * LocalGridSize], BramDy = new bool[LocalGridSize * LocalGridSize], Random1 = new RandomMwc64X { State = memory.ReadUInt32(MemIndexRandomSeed + parallelTaskRandomIndex++) } }; randomSeedTemp = memory.ReadUInt32(MemIndexRandomSeed + parallelTaskRandomIndex++); taskLocals[TaskLocalsIndex].Random1.State |= ((ulong)randomSeedTemp) << 32; taskLocals[TaskLocalsIndex].Random2 = new RandomMwc64X { State = memory.ReadUInt32(MemIndexRandomSeed + parallelTaskRandomIndex++) }; randomSeedTemp = memory.ReadUInt32(MemIndexRandomSeed + parallelTaskRandomIndex++); taskLocals[TaskLocalsIndex].Random2.State |= ((ulong)randomSeedTemp) << 32; } // What is iterationGroupIndex good for? // IterationPerTask needs to be between 0.5 and 1 based on the e-mail of Mate. // If we want 10 iterations, and starting a full series of tasks makes half iteration on the full table, // then we need to start it 20 times (thus IterationGroupSize will be 20). random0.State = memory.ReadUInt32(MemIndexRandomSeed + parallelTaskRandomIndex++); randomSeedTemp = memory.ReadUInt32(MemIndexRandomSeed + parallelTaskRandomIndex++); random0.State |= ((ulong)randomSeedTemp) << 32; for (int iterationGroupIndex = 0; iterationGroupIndex < iterationGroupSize; iterationGroupIndex++) { uint randomValue0 = random0.NextUInt32(); // This assumes that LocalGridSize is 2^N: int randomXOffset = (int)((LocalGridSize - 1) & randomValue0); int randomYOffset = (int)((LocalGridSize - 1) & (randomValue0 >> 16)); for (int scheduleIndex = 0; scheduleIndex < SchedulesPerIteration; scheduleIndex++) { var tasks = new Task <KpzKernelsTaskState> [ParallelTasks]; for (int parallelTaskIndex = 0; parallelTaskIndex < ParallelTasks; parallelTaskIndex++) { // Decide the X and Y starting coordinates based on ScheduleIndex and ParallelTaskIndex // (and the random added value) int localGridIndex = parallelTaskIndex + scheduleIndex * ParallelTasks; // The X and Y coordinate within the small table (local grid): int partitionX = localGridIndex % LocalGridPartitions; int partitionY = localGridIndex / LocalGridPartitions; // The X and Y coordinate within the big table (grid): int baseX = partitionX * LocalGridSize + randomXOffset; int baseY = partitionY * LocalGridSize + randomYOffset; // Copy to local memory for (int copyDstX = 0; copyDstX < LocalGridSize; copyDstX++) { for (int CopyDstY = 0; CopyDstY < LocalGridSize; CopyDstY++) { //Prevent going out of grid memory area (e.g. reading into random seed): int copySrcX = (baseX + copyDstX) % GridSize; int copySrcY = (baseY + CopyDstY) % GridSize; uint value = memory.ReadUInt32(MemIndexGrid + copySrcX + copySrcY * GridSize); taskLocals[parallelTaskIndex].BramDx[copyDstX + CopyDstY * LocalGridSize] = (value & 1) == 1; taskLocals[parallelTaskIndex].BramDy[copyDstX + CopyDstY * LocalGridSize] = (value & 2) == 2; } } tasks[parallelTaskIndex] = Task.Factory.StartNew( rawTaskState => { // Then do TasksPerIteration iterations var taskLocal = (KpzKernelsTaskState)rawTaskState; for (int pokeIndex = 0; pokeIndex < PokesInsideTask; pokeIndex++) { // ==== <Now randomly switch four cells> ==== // Generating two random numbers: uint taskRandomNumber1 = taskLocal.Random1.NextUInt32(); uint taskRandomNumber2 = taskLocal.Random2.NextUInt32(); // The existence of var-1 in code is a good indicator of that it is assumed to be 2^N: int pokeCenterX = (int)(taskRandomNumber1 & (LocalGridSize - 1)); int pokeCenterY = (int)((taskRandomNumber1 >> 16) & (LocalGridSize - 1)); int pokeCenterIndex = pokeCenterX + pokeCenterY * LocalGridSize; uint randomVariable1 = taskRandomNumber2 & ((1 << 16) - 1); uint randomVariable2 = (taskRandomNumber2 >> 16) & ((1 << 16) - 1); // get neighbour indexes: int rightNeighbourIndex; int bottomNeighbourIndex; // We skip if neighbours would fall out of the local grid: if (pokeCenterX >= LocalGridSize - 1 || pokeCenterY >= LocalGridSize - 1) { continue; } int rightNeighbourX = pokeCenterX + 1; int rightNeighbourY = pokeCenterY; int bottomNeighbourX = pokeCenterX; int bottomNeighbourY = pokeCenterY + 1; rightNeighbourIndex = rightNeighbourY * LocalGridSize + rightNeighbourX; bottomNeighbourIndex = bottomNeighbourY * LocalGridSize + bottomNeighbourX; // We check our own {dx,dy} values, and the right neighbour's dx, and bottom neighbour's dx. if ( // If we get the pattern {01, 01} we have a pyramid: ((taskLocal.BramDx[pokeCenterIndex] && !taskLocal.BramDx[rightNeighbourIndex]) && (taskLocal.BramDy[pokeCenterIndex] && !taskLocal.BramDy[bottomNeighbourIndex]) && (false || randomVariable1 < IntegerProbabilityP)) || // If we get the pattern {10, 10} we have a hole: ((!taskLocal.BramDx[pokeCenterIndex] && taskLocal.BramDx[rightNeighbourIndex]) && (!taskLocal.BramDy[pokeCenterIndex] && taskLocal.BramDy[bottomNeighbourIndex]) && (false || randomVariable2 < IntegerProbabilityQ)) ) { // We make a hole into a pyramid, and a pyramid into a hole. taskLocal.BramDx[pokeCenterIndex] = !taskLocal.BramDx[pokeCenterIndex]; taskLocal.BramDy[pokeCenterIndex] = !taskLocal.BramDy[pokeCenterIndex]; taskLocal.BramDx[rightNeighbourIndex] = !taskLocal.BramDx[rightNeighbourIndex]; taskLocal.BramDy[bottomNeighbourIndex] = !taskLocal.BramDy[bottomNeighbourIndex]; } // ==== </Now randomly switch four cells> ==== } return(taskLocal); }, taskLocals[parallelTaskIndex]); } Task.WhenAll(tasks).Wait(); // Copy back to SimpleMemory for (int parallelTaskIndex = 0; parallelTaskIndex < ParallelTasks; parallelTaskIndex++) { // Calculate these things again int localGridIndex = parallelTaskIndex + scheduleIndex * ParallelTasks; // The X and Y coordinate within the small table (local grid): int partitionX = localGridIndex % LocalGridPartitions; int partitionY = localGridIndex / LocalGridPartitions; // The X and Y coordinate within the big table (grid): int baseX = partitionX * LocalGridSize + randomXOffset; int baseY = partitionY * LocalGridSize + randomYOffset; //Console.WriteLine("CopyBack | Task={0}, To: {1},{2}", ParallelTaskIndex, BaseX, BaseY); for (int copySrcX = 0; copySrcX < LocalGridSize; copySrcX++) { for (int copySrcY = 0; copySrcY < LocalGridSize; copySrcY++) { int copyDstX = (baseX + copySrcX) % GridSize; int copyDstY = (baseY + copySrcY) % GridSize; uint value = (tasks[parallelTaskIndex].Result.BramDx[copySrcX + copySrcY * LocalGridSize] ? 1U : 0U) | (tasks[parallelTaskIndex].Result.BramDy[copySrcX + copySrcY * LocalGridSize] ? 2U : 0U); //Note: use (tasks[parallelTaskIndex].Result), because // (TaskLocals[ParallelTaskIndex]) won't work. memory.WriteUInt32(MemIndexGrid + copyDstX + copyDstY * GridSize, value); } } // Take PRNG current state from Result to feed it to input next time taskLocals[parallelTaskIndex].Random1.State = tasks[parallelTaskIndex].Result.Random1.State; taskLocals[parallelTaskIndex].Random2.State = tasks[parallelTaskIndex].Result.Random2.State; } } } }
/// <summary> /// Changes the contrast of an image. /// </summary> /// <param name="memory">The <see cref="SimpleMemory"/> object representing the accessible memory space.</param> public virtual void ChangeContrast(SimpleMemory memory) { var imageWidth = (ushort)memory.ReadUInt32(ChangeContrast_ImageWidthIndex); var imageHeight = (ushort)memory.ReadUInt32(ChangeContrast_ImageHeightIndex); int contrastValue = memory.ReadInt32(ChangeContrast_ContrastValueIndex); if (contrastValue > 100) { contrastValue = 100; } else if (contrastValue < -100) { contrastValue = -100; } contrastValue = (100 + contrastValue * Multiplier) / 100; var tasks = new Task <PixelProcessingTaskOutput> [MaxDegreeOfParallelism]; // Since we only need to compute the loop condition's right side once, not on each loop execution, it's an // optimization to put it in a separate variable. This way it's indeed computed only once. var pixelCount = imageHeight * imageWidth; var stepCount = pixelCount / MaxDegreeOfParallelism; if (pixelCount % MaxDegreeOfParallelism != 0) { // This will take care of the rest of the pixels. This is wasteful as on the last step not all Tasks // will work on something but it's a way to keep the number of Tasks constant. stepCount += 1; } for (int i = 0; i < stepCount; i++) { for (int t = 0; t < MaxDegreeOfParallelism; t++) { var pixelBytes = memory.Read4Bytes(i * MaxDegreeOfParallelism + t + ChangeContrast_ImageStartIndex); // Using an input class to also pass contrastValue because it's currently not supported to access // variables from the parent scope from inside Tasks (you need to explicitly pass in all inputs). // Using an output class to pass the pixel values back because returning an array from Tasks is not // supported at the time either. tasks[t] = Task.Factory.StartNew( inputObject => { var input = (PixelProcessingTaskInput)inputObject; return(new PixelProcessingTaskOutput { R = ChangePixelValue(input.PixelBytes[0], input.ContrastValue), G = ChangePixelValue(input.PixelBytes[1], input.ContrastValue), B = ChangePixelValue(input.PixelBytes[2], input.ContrastValue) }); }, new PixelProcessingTaskInput { PixelBytes = pixelBytes, ContrastValue = contrastValue }); } Task.WhenAll(tasks).Wait(); for (int t = 0; t < MaxDegreeOfParallelism; t++) { // It's no problem that we write just 3 bytes to a 4-byte slot. memory.Write4Bytes( i * MaxDegreeOfParallelism + t + ChangeContrast_ImageStartIndex, new[] { tasks[t].Result.R, tasks[t].Result.G, tasks[t].Result.B }); } } }
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))))); }
public virtual void Run(SimpleMemory memory) { // Adding 1 to the input so it's visible whether this actually has run, not just the untouched data was // sent back. memory.WriteInt32(Run_InputOutputInt32Index, memory.ReadInt32(Run_InputOutputInt32Index) + 1); }
/// <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)); } } }