GPU errors won't go silently, so that we can analyze and fix them.

This commit is contained in:
Marek Lemańczyk committed 2025-10-07 21:57:27 +02:00
1 parent 31e95e5a8b
commit 48127845b5
1 file changed
+444 -434
+444 -434
View File
@@ -7,6 +7,7 @@ using System.Numerics;
using PerfectNumbers.Core; using PerfectNumbers.Core;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using ILGPU.Runtime.OpenCL;
namespace PerfectNumbers.Core.Gpu; namespace PerfectNumbers.Core.Gpu;
internal enum GpuPow2ModStatus internal enum GpuPow2ModStatus
@@ -408,393 +409,393 @@ internal static partial class PrimeOrderGpuHeuristics
{ {
switch (index) switch (index)
{ {
case 0: case 0:
Element0 = value; Element0 = value;
return; return;
case 1: case 1:
Element1 = value; Element1 = value;
return; return;
case 2: case 2:
Element2 = value; Element2 = value;
return; return;
case 3: case 3:
Element3 = value; Element3 = value;
return; return;
case 4: case 4:
Element4 = value; Element4 = value;
return; return;
case 5: case 5:
Element5 = value; Element5 = value;
return; return;
case 6: case 6:
Element6 = value; Element6 = value;
return; return;
case 7: case 7:
Element7 = value; Element7 = value;
return; return;
case 8: case 8:
Element8 = value; Element8 = value;
return; return;
case 9: case 9:
Element9 = value; Element9 = value;
return; return;
case 10: case 10:
Element10 = value; Element10 = value;
return; return;
case 11: case 11:
Element11 = value; Element11 = value;
return; return;
case 12: case 12:
Element12 = value; Element12 = value;
return; return;
case 13: case 13:
Element13 = value; Element13 = value;
return; return;
case 14: case 14:
Element14 = value; Element14 = value;
return; return;
case 15: case 15:
Element15 = value; Element15 = value;
return; return;
case 16: case 16:
Element16 = value; Element16 = value;
return; return;
case 17: case 17:
Element17 = value; Element17 = value;
return; return;
case 18: case 18:
Element18 = value; Element18 = value;
return; return;
case 19: case 19:
Element19 = value; Element19 = value;
return; return;
case 20: case 20:
Element20 = value; Element20 = value;
return; return;
case 21: case 21:
Element21 = value; Element21 = value;
return; return;
case 22: case 22:
Element22 = value; Element22 = value;
return; return;
case 23: case 23:
Element23 = value; Element23 = value;
return; return;
case 24: case 24:
Element24 = value; Element24 = value;
return; return;
case 25: case 25:
Element25 = value; Element25 = value;
return; return;
case 26: case 26:
Element26 = value; Element26 = value;
return; return;
case 27: case 27:
Element27 = value; Element27 = value;
return; return;
case 28: case 28:
Element28 = value; Element28 = value;
return; return;
case 29: case 29:
Element29 = value; Element29 = value;
return; return;
case 30: case 30:
Element30 = value; Element30 = value;
return; return;
case 31: case 31:
Element31 = value; Element31 = value;
return; return;
case 32: case 32:
Element32 = value; Element32 = value;
return; return;
case 33: case 33:
Element33 = value; Element33 = value;
return; return;
case 34: case 34:
Element34 = value; Element34 = value;
return; return;
case 35: case 35:
Element35 = value; Element35 = value;
return; return;
case 36: case 36:
Element36 = value; Element36 = value;
return; return;
case 37: case 37:
Element37 = value; Element37 = value;
return; return;
case 38: case 38:
Element38 = value; Element38 = value;
return; return;
case 39: case 39:
Element39 = value; Element39 = value;
return; return;
case 40: case 40:
Element40 = value; Element40 = value;
return; return;
case 41: case 41:
Element41 = value; Element41 = value;
return; return;
case 42: case 42:
Element42 = value; Element42 = value;
return; return;
case 43: case 43:
Element43 = value; Element43 = value;
return; return;
case 44: case 44:
Element44 = value; Element44 = value;
return; return;
case 45: case 45:
Element45 = value; Element45 = value;
return; return;
case 46: case 46:
Element46 = value; Element46 = value;
return; return;
case 47: case 47:
Element47 = value; Element47 = value;
return; return;
case 48: case 48:
Element48 = value; Element48 = value;
return; return;
case 49: case 49:
Element49 = value; Element49 = value;
return; return;
case 50: case 50:
Element50 = value; Element50 = value;
return; return;
case 51: case 51:
Element51 = value; Element51 = value;
return; return;
case 52: case 52:
Element52 = value; Element52 = value;
return; return;
case 53: case 53:
Element53 = value; Element53 = value;
return; return;
case 54: case 54:
Element54 = value; Element54 = value;
return; return;
case 55: case 55:
Element55 = value; Element55 = value;
return; return;
case 56: case 56:
Element56 = value; Element56 = value;
return; return;
case 57: case 57:
Element57 = value; Element57 = value;
return; return;
case 58: case 58:
Element58 = value; Element58 = value;
return; return;
case 59: case 59:
Element59 = value; Element59 = value;
return; return;
case 60: case 60:
Element60 = value; Element60 = value;
return; return;
case 61: case 61:
Element61 = value; Element61 = value;
return; return;
case 62: case 62:
Element62 = value; Element62 = value;
return; return;
case 63: case 63:
Element63 = value; Element63 = value;
return; return;
case 64: case 64:
Element64 = value; Element64 = value;
return; return;
case 65: case 65:
Element65 = value; Element65 = value;
return; return;
case 66: case 66:
Element66 = value; Element66 = value;
return; return;
case 67: case 67:
Element67 = value; Element67 = value;
return; return;
case 68: case 68:
Element68 = value; Element68 = value;
return; return;
case 69: case 69:
Element69 = value; Element69 = value;
return; return;
case 70: case 70:
Element70 = value; Element70 = value;
return; return;
case 71: case 71:
Element71 = value; Element71 = value;
return; return;
case 72: case 72:
Element72 = value; Element72 = value;
return; return;
case 73: case 73:
Element73 = value; Element73 = value;
return; return;
case 74: case 74:
Element74 = value; Element74 = value;
return; return;
case 75: case 75:
Element75 = value; Element75 = value;
return; return;
case 76: case 76:
Element76 = value; Element76 = value;
return; return;
case 77: case 77:
Element77 = value; Element77 = value;
return; return;
case 78: case 78:
Element78 = value; Element78 = value;
return; return;
case 79: case 79:
Element79 = value; Element79 = value;
return; return;
case 80: case 80:
Element80 = value; Element80 = value;
return; return;
case 81: case 81:
Element81 = value; Element81 = value;
return; return;
case 82: case 82:
Element82 = value; Element82 = value;
return; return;
case 83: case 83:
Element83 = value; Element83 = value;
return; return;
case 84: case 84:
Element84 = value; Element84 = value;
return; return;
case 85: case 85:
Element85 = value; Element85 = value;
return; return;
case 86: case 86:
Element86 = value; Element86 = value;
return; return;
case 87: case 87:
Element87 = value; Element87 = value;
return; return;
case 88: case 88:
Element88 = value; Element88 = value;
return; return;
case 89: case 89:
Element89 = value; Element89 = value;
return; return;
case 90: case 90:
Element90 = value; Element90 = value;
return; return;
case 91: case 91:
Element91 = value; Element91 = value;
return; return;
case 92: case 92:
Element92 = value; Element92 = value;
return; return;
case 93: case 93:
Element93 = value; Element93 = value;
return; return;
case 94: case 94:
Element94 = value; Element94 = value;
return; return;
case 95: case 95:
Element95 = value; Element95 = value;
return; return;
case 96: case 96:
Element96 = value; Element96 = value;
return; return;
case 97: case 97:
Element97 = value; Element97 = value;
return; return;
case 98: case 98:
Element98 = value; Element98 = value;
return; return;
case 99: case 99:
Element99 = value; Element99 = value;
return; return;
case 100: case 100:
Element100 = value; Element100 = value;
return; return;
case 101: case 101:
Element101 = value; Element101 = value;
return; return;
case 102: case 102:
Element102 = value; Element102 = value;
return; return;
case 103: case 103:
Element103 = value; Element103 = value;
return; return;
case 104: case 104:
Element104 = value; Element104 = value;
return; return;
case 105: case 105:
Element105 = value; Element105 = value;
return; return;
case 106: case 106:
Element106 = value; Element106 = value;
return; return;
case 107: case 107:
Element107 = value; Element107 = value;
return; return;
case 108: case 108:
Element108 = value; Element108 = value;
return; return;
case 109: case 109:
Element109 = value; Element109 = value;
return; return;
case 110: case 110:
Element110 = value; Element110 = value;
return; return;
case 111: case 111:
Element111 = value; Element111 = value;
return; return;
case 112: case 112:
Element112 = value; Element112 = value;
return; return;
case 113: case 113:
Element113 = value; Element113 = value;
return; return;
case 114: case 114:
Element114 = value; Element114 = value;
return; return;
case 115: case 115:
Element115 = value; Element115 = value;
return; return;
case 116: case 116:
Element116 = value; Element116 = value;
return; return;
case 117: case 117:
Element117 = value; Element117 = value;
return; return;
case 118: case 118:
Element118 = value; Element118 = value;
return; return;
case 119: case 119:
Element119 = value; Element119 = value;
return; return;
case 120: case 120:
Element120 = value; Element120 = value;
return; return;
case 121: case 121:
Element121 = value; Element121 = value;
return; return;
case 122: case 122:
Element122 = value; Element122 = value;
return; return;
case 123: case 123:
Element123 = value; Element123 = value;
return; return;
case 124: case 124:
Element124 = value; Element124 = value;
return; return;
case 125: case 125:
Element125 = value; Element125 = value;
return; return;
case 126: case 126:
Element126 = value; Element126 = value;
return; return;
case 127: case 127:
Element127 = value; Element127 = value;
return; return;
default: default:
// ILGPU kernels cannot throw exceptions, and callers guarantee the index range. // ILGPU kernels cannot throw exceptions, and callers guarantee the index range.
return; return;
} }
} }
} }
@@ -905,63 +906,72 @@ internal static partial class PrimeOrderGpuHeuristics
try try
{ {
var lease = GpuKernelPool.GetKernel(useGpuOrder: true); var lease = GpuKernelPool.GetKernel(useGpuOrder: true);
try var execution = lease.EnterExecutionScope();
{ Accelerator accelerator = lease.Accelerator;
using var execution = lease.EnterExecutionScope(); AcceleratorStream stream = lease.Stream;
Accelerator accelerator = lease.Accelerator;
AcceleratorStream stream = lease.Stream;
var kernel = GetPartialFactorKernel(accelerator); var kernel = GetPartialFactorKernel(accelerator);
SmallPrimeDeviceCache cache = GetSmallPrimeDeviceCache(accelerator); SmallPrimeDeviceCache cache = GetSmallPrimeDeviceCache(accelerator);
using var factorBuffer = accelerator.Allocate1D<ulong>(primeTargets.Length); var factorBuffer = accelerator.Allocate1D<ulong>(primeTargets.Length);
using var exponentBuffer = accelerator.Allocate1D<int>(exponentTargets.Length); var exponentBuffer = accelerator.Allocate1D<int>(exponentTargets.Length);
using var countBuffer = accelerator.Allocate1D<int>(1); var countBuffer = accelerator.Allocate1D<int>(1);
using var remainingBuffer = accelerator.Allocate1D<ulong>(1); var remainingBuffer = accelerator.Allocate1D<ulong>(1);
using var fullyFactoredBuffer = accelerator.Allocate1D<byte>(1); var fullyFactoredBuffer = accelerator.Allocate1D<byte>(1);
factorBuffer.MemSetToZero(); factorBuffer.MemSetToZero();
exponentBuffer.MemSetToZero(); exponentBuffer.MemSetToZero();
countBuffer.MemSetToZero(); countBuffer.MemSetToZero();
remainingBuffer.MemSetToZero(); remainingBuffer.MemSetToZero();
fullyFactoredBuffer.MemSetToZero(); fullyFactoredBuffer.MemSetToZero();
kernel( kernel(
stream, stream,
1, 1,
cache.Primes!.View, cache.Primes!.View,
cache.Squares!.View, cache.Squares!.View,
cache.Count, cache.Count,
primeTargets.Length, primeTargets.Length,
value, value,
limit, limit,
factorBuffer.View, factorBuffer.View,
exponentBuffer.View, exponentBuffer.View,
countBuffer.View, countBuffer.View,
remainingBuffer.View, remainingBuffer.View,
fullyFactoredBuffer.View); fullyFactoredBuffer.View);
stream.Synchronize(); stream.Synchronize();
countBuffer.View.CopyToCPU(ref factorCount, 1); countBuffer.View.CopyToCPU(ref factorCount, 1);
factorCount = Math.Min(factorCount, primeTargets.Length); factorCount = Math.Min(factorCount, primeTargets.Length);
factorBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(primeTargets), primeTargets.Length); factorBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(primeTargets), primeTargets.Length);
exponentBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(exponentTargets), exponentTargets.Length); exponentBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(exponentTargets), exponentTargets.Length);
remainingBuffer.View.CopyToCPU(ref remaining, 1); remainingBuffer.View.CopyToCPU(ref remaining, 1);
byte fullyFactoredFlag = 0; byte fullyFactoredFlag = 0;
fullyFactoredBuffer.View.CopyToCPU(ref fullyFactoredFlag, 1); fullyFactoredBuffer.View.CopyToCPU(ref fullyFactoredFlag, 1);
fullyFactored = fullyFactoredFlag != 0; fullyFactored = fullyFactoredFlag != 0;
return true; factorBuffer.Dispose();
} exponentBuffer.Dispose();
finally countBuffer.Dispose();
{ remainingBuffer.Dispose();
lease.Dispose(); fullyFactoredBuffer.Dispose();
} execution.Dispose();
lease.Dispose();
return true;
}
catch (CLException ex)
{
Console.WriteLine($"GPU ERROR ({ex.Error}): {ex.Message}");
factorCount = 0;
remaining = value;
fullyFactored = false;
return false;
} }
catch (Exception ex) when (ex is AcceleratorException or InternalCompilerException or NotSupportedException or InvalidOperationException or AggregateException) catch (Exception ex) when (ex is AcceleratorException or InternalCompilerException or NotSupportedException or InvalidOperationException or AggregateException)
{ {
Console.WriteLine($"GPU ERROR: {ex.Message}");
factorCount = 0; factorCount = 0;
remaining = value; remaining = value;
fullyFactored = false; fullyFactored = false;
@@ -1497,7 +1507,7 @@ internal static partial class PrimeOrderGpuHeuristics
continue; continue;
} }
ulong reduced = phi / factor; ulong reduced = phi / factor;
if (reduced.Pow2MontgomeryModWindowed(divisor, keepMontgomery: false) == 1UL) if (reduced.Pow2MontgomeryModWindowed(divisor, keepMontgomery: false) == 1UL)
{ {
return false; return false;