/// <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; } }
public virtual void IsPrimeNumber(SimpleMemory memory) { var number = memory.ReadUInt32(IsPrimeNumber_InputUInt32Index); var isPrime = IsPrimeNumberInternal(number); memory.WriteBoolean(IsPrimeNumber_OutputBooleanIndex, isPrime); }
/// <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)); }
public virtual void ArePrimeNumbers(SimpleMemory memory) { // We need this information explicitly as we can't store arrays directly in memory. uint numberCount = memory.ReadUInt32(ArePrimeNumbers_InputUInt32CountIndex); for (int i = 0; i < numberCount; i++) { uint number = memory.ReadUInt32(ArePrimeNumbers_InputUInt32sStartIndex + i); memory.WriteBoolean(ArePrimeNumbers_OutputBooleansStartIndex + i, IsPrimeNumberInternal(number)); } }
public virtual void ArePrimeNumbers(SimpleMemory memory) { uint numberCount = memory.ReadUInt32(ArePrimeNumbers_InputUInt32CountIndex); for (int i = 0; i < numberCount; i++) { uint number = memory.ReadUInt32(ArePrimeNumbers_InputUInt32sStartIndex + i); var isPrime = IsPrimeNumberInternal(number); memory.WriteBoolean(ArePrimeNumbers_OutputUInt32sStartIndex + i, isPrime); } }
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); tasks[m] = Task.Factory.StartNew( numberObject => { // This is a copy of the body of IsPrimeNumberInternal(). We could also call that method // from this lambda but it's more efficient to just do it directly, not adding indirection. var number = (uint)numberObject; uint factor = number / 2; for (uint x = 2; x <= factor; x++) { if ((number % x) == 0) { return(false); } } return(true); }, 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; } }