IterationCompilerCl.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "IterationCompiler.h"
  2. #include "NaiveIRGenerator.h"
  3. #include "Mandel.h"
  4. #ifdef WITH_ASMJIT
  5. #include "ExecData.h"
  6. #endif // WITH_ASMJIT
  7. #include "OpenClInternal.h"
  8. #include "OpenClCode.h"
  9. #include <cmath>
  10. #include <omp.h>
  11. #include <any>
  12. #include <string>
  13. using namespace std::string_literals;
  14. namespace mnd
  15. {
  16. struct OpenClDDVisitor
  17. {
  18. int varnameCounter = 0;
  19. std::stringstream code;
  20. std::string floatTypeName;
  21. OpenClDDVisitor(int startVarname, const std::string& floatTypeName) :
  22. varnameCounter{ startVarname },
  23. floatTypeName{ floatTypeName }
  24. {
  25. }
  26. std::string createVarname(void)
  27. {
  28. return "tmp"s + std::to_string(varnameCounter++);
  29. }
  30. std::string visitNode(ir::Node& node)
  31. {
  32. auto& nodeData = std::visit([] (auto& n) -> std::any& { return n.nodeData; }, node);
  33. if (std::string* var = std::any_cast<std::string>(&nodeData)) {
  34. return *var;
  35. }
  36. else {
  37. std::string value = std::visit(*this, node);
  38. if (!std::get_if<ir::Variable>(&node) && !std::get_if<ir::Constant>(&node)) {
  39. std::string varname = createVarname();
  40. code << floatTypeName << " " << varname << " = " << value << ";" << std::endl;
  41. nodeData = varname;
  42. return varname;
  43. }
  44. return value;
  45. }
  46. }
  47. std::string operator()(const ir::Constant& c) {
  48. return std::to_string(mnd::convert<double>(c.value)) + ((floatTypeName == "float") ? "f" : "");
  49. }
  50. std::string operator()(const ir::Variable& v) {
  51. return v.name;
  52. }
  53. std::string operator()(const ir::Negation& n) {
  54. return "-("s + visitNode(*n.value) + ")";
  55. }
  56. std::string operator()(const ir::Addition& a) {
  57. return "("s + visitNode(*a.left) + ") + (" + visitNode(*a.right) + ")";
  58. }
  59. std::string operator()(const ir::Subtraction& a) {
  60. return "("s + visitNode(*a.left) + ") - (" + visitNode(*a.right) + ")";
  61. }
  62. std::string operator()(const ir::Multiplication& a) {
  63. return "("s + visitNode(*a.left) + ") * (" + visitNode(*a.right) + ")";
  64. }
  65. std::string operator()(const ir::Division& a) {
  66. return "("s + visitNode(*a.left) + ") / (" + visitNode(*a.right) + ")";
  67. }
  68. std::string operator()(const ir::Atan2& a) {
  69. return "atan2("s + visitNode(*a.left) + ", " + visitNode(*a.right) + ")";
  70. }
  71. std::string operator()(const ir::Pow& a) {
  72. return "pow("s + visitNode(*a.left) + ", " + visitNode(*a.right) + ")";
  73. }
  74. std::string operator()(const ir::Cos& a) {
  75. return "cos("s + visitNode(*a.value) + ")";
  76. }
  77. std::string operator()(const ir::Sin& a) {
  78. return "sin("s + visitNode(*a.value) + ")";
  79. }
  80. std::string operator()(const ir::Exp& a) {
  81. return "exp("s + visitNode(*a.value) + ")";
  82. }
  83. std::string operator()(const ir::Ln& a) {
  84. return "log("s + visitNode(*a.value) + ")";
  85. }
  86. };
  87. std::string compileToOpenClDoubleDouble(const ir::Formula& formula)
  88. {
  89. OpenClDDVisitor z0Visitor{ 0, "double2" };
  90. std::string startA = z0Visitor.visitNode(*formula.startA);
  91. std::string startB = z0Visitor.visitNode(*formula.startB);
  92. OpenClDDVisitor ocv{ z0Visitor.varnameCounter, "double2" };
  93. std::string newA = ocv.visitNode(*formula.newA);
  94. std::string newB = ocv.visitNode(*formula.newB);
  95. std::string prelude =
  96. "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
  97. "__kernel void iterate(__global float* A, const int width, double xl, double yt, double pixelScaleX, double pixelScaleY, int max, int smooth, int julia, double juliaX, double juliaY) {\n"
  98. " int index = get_global_id(0);\n"
  99. " int ix = index % width;\n"
  100. " int iy = index / width;\n"
  101. " double c_re = ix * pixelScaleX + xl;\n"
  102. " double c_im = iy * pixelScaleY + yt;\n";
  103. prelude += z0Visitor.code.str() +
  104. " double z_re = " + startA + ";\n" +
  105. " double z_im = " + startB + ";\n" +
  106. "\n"
  107. " int n = 0;\n"
  108. " while (n < max - 1) {\n";
  109. std::string after =
  110. " if (z_re * z_re + z_im * z_im > 16) break;\n"
  111. " n++;\n"
  112. " }\n"
  113. " if (n >= max - 1) {\n"
  114. " A[index] = max;\n"
  115. " }\n"
  116. " else {\n"
  117. " A[index] = ((float)n);\n"
  118. " }\n"
  119. "}\n";
  120. std::string code = prelude + ocv.code.str();
  121. code += "z_re = " + newA + ";\n";
  122. code += "z_im = " + newB + ";\n";
  123. code += after;
  124. //code = mnd::getFloat_cl();
  125. printf("cld: %s\n", code.c_str()); fflush(stdout);
  126. return code;
  127. }
  128. #ifdef WITH_OPENCL
  129. std::unique_ptr<MandelGenerator> compileClDoubleDouble(const ir::Formula& formula, MandelDevice& md)
  130. {
  131. return nullptr;
  132. //return std::make_unique<CompiledClGeneratorDouble>(md, compileToOpenClDouble(formula));
  133. }
  134. #endif
  135. }