FindPrimeNumbers.hlsl 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. /*
  6. bool isPrime(uint N)
  7. {
  8. for(uint j = 2; j < N / 2; ++j)
  9. {
  10. if(i % N == 0) return false;
  11. }
  12. return true;
  13. }
  14. */
  15. #define NUMTHREADS 256
  16. #if WORKGRAPHS
  17. struct FirstNodeInput
  18. {
  19. uint3 m_svDispatchGrid : SV_DispatchGrid;
  20. };
  21. #endif
  22. struct Misc
  23. {
  24. uint m_threadgroupCounter;
  25. uint m_threadgroupCount;
  26. uint m_primeNumberCount;
  27. };
  28. RWStructuredBuffer<uint> g_primeNumbers : register(u0);
  29. RWStructuredBuffer<Misc> g_misc : register(u1);
  30. groupshared uint g_isPrime;
  31. #if WORKGRAPHS
  32. [Shader("node")][NodeLaunch("broadcasting")][NodeIsProgramEntry][NodeMaxDispatchGrid(1, 1, 1)][numthreads(NUMTHREADS, 1, 1)]
  33. #else
  34. [numthreads(NUMTHREADS, 1, 1)]
  35. #endif
  36. void
  37. main(uint svGroupIndex : SV_GROUPINDEX, uint svGroupId : SV_GROUPID
  38. #if WORKGRAPHS
  39. ,
  40. DispatchNodeInputRecord<FirstNodeInput> input
  41. #endif
  42. )
  43. {
  44. if(svGroupIndex == 0)
  45. {
  46. g_isPrime = 1;
  47. }
  48. GroupMemoryBarrierWithGroupSync();
  49. const uint N = svGroupId; // The candidate number to check
  50. if(N >= 2)
  51. {
  52. // Iterations to find if it's prime
  53. const uint iterations = N / 2 - 2;
  54. const uint loopCountPerThread = (iterations + NUMTHREADS - 1) / NUMTHREADS;
  55. for(uint i = 0; i < loopCountPerThread; ++i)
  56. {
  57. const uint j = 2 + loopCountPerThread * i + svGroupIndex;
  58. if(j <= N / 2 && N % j == 0)
  59. {
  60. uint origVal;
  61. InterlockedExchange(g_isPrime, 0, origVal);
  62. break;
  63. }
  64. }
  65. }
  66. else
  67. {
  68. uint origVal;
  69. InterlockedExchange(g_isPrime, 0, origVal);
  70. }
  71. GroupMemoryBarrierWithGroupSync();
  72. if(svGroupIndex == 0 && g_isPrime)
  73. {
  74. uint offset;
  75. InterlockedAdd(g_misc[0].m_primeNumberCount, 1, offset);
  76. g_primeNumbers[offset + 1] = N;
  77. }
  78. GroupMemoryBarrierWithGroupSync();
  79. if(svGroupIndex == 0)
  80. {
  81. uint orig;
  82. InterlockedAdd(g_misc[0].m_threadgroupCounter, 1, orig);
  83. const bool lastThreadgroup = (orig + 1u) == g_misc[0].m_threadgroupCount;
  84. if(lastThreadgroup)
  85. {
  86. g_primeNumbers[0] = g_misc[0].m_primeNumberCount;
  87. g_misc[0].m_primeNumberCount = 0;
  88. g_misc[0].m_threadgroupCounter = 0;
  89. }
  90. }
  91. }