1
0

mandel.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "Mandel.h"
  2. #include "Fixed.h"
  3. #include "CpuGenerators.h"
  4. #include "ClGenerators.h"
  5. using mnd::MandelDevice;
  6. using mnd::MandelContext;
  7. using mnd::Generator;
  8. using mnd::AdaptiveGenerator;
  9. MandelContext mnd::initializeContext(void)
  10. {
  11. MandelContext context = MandelContext();
  12. return context;
  13. }
  14. MandelDevice::MandelDevice(void) :
  15. floatGenerator{ nullptr },
  16. doubleGenerator{ nullptr }
  17. {
  18. }
  19. mnd::Generator* MandelDevice::getGeneratorFloat(void) const
  20. {
  21. if (floatGenerator)
  22. return floatGenerator.get();
  23. else
  24. return nullptr;
  25. }
  26. mnd::Generator* MandelDevice::getGeneratorDouble(void) const
  27. {
  28. if (doubleGenerator)
  29. return doubleGenerator.get();
  30. else
  31. return nullptr;
  32. }
  33. mnd::Generator* MandelDevice::getGenerator128(void) const
  34. {
  35. if (generator128)
  36. return generator128.get();
  37. else
  38. return nullptr;
  39. }
  40. MandelContext::MandelContext(void)
  41. {
  42. #if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
  43. if (cpuInfo.hasAvx()) {
  44. cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::X86_AVX>>();
  45. cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::X86_AVX>>();
  46. }
  47. else if (cpuInfo.hasSse2()) {
  48. cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::X86_SSE2>>();
  49. cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::X86_SSE2>>();
  50. }
  51. else
  52. #elif defined(__aarch64__)
  53. if (true) {
  54. cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::ARM_NEON>>();
  55. cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::ARM_NEON>>();
  56. }
  57. else
  58. #endif
  59. {
  60. cpuGeneratorFloat = std::make_unique<CpuGenerator<float>>();
  61. cpuGeneratorDouble = std::make_unique<CpuGenerator<double>>();
  62. }
  63. cpuGenerator128 = std::make_unique<CpuGenerator<Fixed128>>();
  64. //cpuGeneratorFixedp = std::make_unique<CpuGenerator<fixed<1, 3>>>();
  65. devices = createDevices();
  66. if (devices.empty() || true) {
  67. adaptiveGenerator = std::make_unique<AdaptiveGenerator>(cpuGeneratorFloat.get(), cpuGeneratorDouble.get());
  68. }
  69. else {
  70. auto& device1 = devices[0];
  71. Generator* floatGenerator = device1.getGeneratorFloat();
  72. Generator* doubleGenerator = device1.getGeneratorDouble();
  73. if (floatGenerator == nullptr)
  74. floatGenerator = cpuGeneratorFloat.get();
  75. if (doubleGenerator == nullptr)
  76. doubleGenerator = cpuGeneratorDouble.get();
  77. adaptiveGenerator = std::make_unique<AdaptiveGenerator>(floatGenerator, doubleGenerator);
  78. }
  79. }
  80. std::vector<MandelDevice> MandelContext::createDevices(void)
  81. {
  82. std::vector<MandelDevice> mandelDevices;
  83. #ifdef WITH_OPENCL
  84. std::vector<cl::Platform> platforms;
  85. cl::Platform::get(&platforms);
  86. //platforms.erase(platforms.begin() + 1);
  87. for (auto& platform : platforms) {
  88. std::string name = platform.getInfo<CL_PLATFORM_NAME>();
  89. std::string profile = platform.getInfo<CL_PLATFORM_PROFILE>();
  90. //std::string ext = platform.getInfo<CL_PLATFORM_EXTENSIONS>();
  91. //printf("Platform extensions: %s\n", ext.c_str());
  92. //printf("Platform: %s, %s\n", name.c_str(), profile.c_str());
  93. std::vector<cl::Device> devices;
  94. platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
  95. for (auto& device : devices) {
  96. //printf("Device: %s\n", device.getInfo<CL_DEVICE_NAME>().c_str());
  97. //printf("preferred float width: %d\n", device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT>());
  98. //printf("vendor: %s\n", device.getInfo<CL_DEVICE_VENDOR>().c_str());
  99. std::string extensions = device.getInfo<CL_DEVICE_EXTENSIONS>();
  100. auto supportsDouble = extensions.find("cl_khr_fp64") != std::string::npos;
  101. //printf("Device extensions: %s\n", ext.c_str());
  102. MandelDevice md;
  103. //printf("clock: %d", device.getInfo<CL_DEVICE_MAX_CLOCK_FREQUENCY>());
  104. md.name = device.getInfo<CL_DEVICE_NAME>();
  105. md.vendor = device.getInfo<CL_DEVICE_VENDOR>();
  106. try {
  107. md.floatGenerator = std::make_unique<ClGeneratorFloat>(device);
  108. }
  109. catch (const std::string& err) {
  110. printf("err: %s", err.c_str());
  111. }
  112. if (supportsDouble) {
  113. try {
  114. md.doubleGenerator = std::make_unique<ClGeneratorDouble>(device);
  115. }
  116. catch (const std::string& err) {
  117. }
  118. }
  119. try {
  120. //md.generator128 = std::make_unique<ClGenerator128>(device);
  121. }
  122. catch (const std::string& err) {
  123. //fprintf(stderr, "error creating 128bit cl generator: %s\n", err.c_str());
  124. }
  125. mandelDevices.push_back(std::move(md));
  126. }
  127. }
  128. #endif // WITH_OPENCL
  129. return mandelDevices;
  130. }
  131. const std::string& MandelDevice::getName(void) const
  132. {
  133. return name;
  134. }
  135. Generator& MandelContext::getDefaultGenerator(void)
  136. {
  137. return *adaptiveGenerator;
  138. }
  139. const std::vector<MandelDevice>& MandelContext::getDevices(void)
  140. {
  141. return devices;
  142. }
  143. Generator& MandelContext::getCpuGeneratorFloat(void)
  144. {
  145. return *cpuGeneratorFloat;
  146. }
  147. Generator& MandelContext::getCpuGeneratorDouble(void)
  148. {
  149. return *cpuGeneratorDouble;
  150. }
  151. Generator& MandelContext::getCpuGenerator128(void)
  152. {
  153. return *cpuGenerator128;
  154. }