mandel.cpp 4.7 KB

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