123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #include "IterationCompiler.h"
- #include "NaiveIRGenerator.h"
- #include "Mandel.h"
- #ifdef WITH_ASMJIT
- #include "ExecData.h"
- #endif // WITH_ASMJIT
- #include "OpenClInternal.h"
- #include "OpenClCode.h"
- #include <cmath>
- #include <omp.h>
- #include <any>
- #include <string>
- using namespace std::string_literals;
- namespace mnd
- {
- struct OpenClDDVisitor
- {
- int varnameCounter = 0;
- std::stringstream code;
- std::string floatTypeName;
- OpenClDDVisitor(int startVarname, const std::string& floatTypeName) :
- varnameCounter{ startVarname },
- floatTypeName{ floatTypeName }
- {
- }
- std::string createVarname(void)
- {
- return "tmp"s + std::to_string(varnameCounter++);
- }
- std::string visitNode(ir::Node& node)
- {
- auto& nodeData = std::visit([] (auto& n) -> std::any& { return n.nodeData; }, node);
- if (std::string* var = std::any_cast<std::string>(&nodeData)) {
- return *var;
- }
- else {
- std::string value = std::visit(*this, node);
- if (!std::get_if<ir::Variable>(&node) && !std::get_if<ir::Constant>(&node)) {
- std::string varname = createVarname();
- code << floatTypeName << " " << varname << " = " << value << ";" << std::endl;
- nodeData = varname;
- return varname;
- }
- return value;
- }
- }
- std::string operator()(const ir::Constant& c) {
- return std::to_string(mnd::convert<double>(c.value)) + ((floatTypeName == "float") ? "f" : "");
- }
- std::string operator()(const ir::Variable& v) {
- return v.name;
- }
- std::string operator()(const ir::Negation& n) {
- return "-("s + visitNode(*n.value) + ")";
- }
- std::string operator()(const ir::Addition& a) {
- return "("s + visitNode(*a.left) + ") + (" + visitNode(*a.right) + ")";
- }
- std::string operator()(const ir::Subtraction& a) {
- return "("s + visitNode(*a.left) + ") - (" + visitNode(*a.right) + ")";
- }
- std::string operator()(const ir::Multiplication& a) {
- return "("s + visitNode(*a.left) + ") * (" + visitNode(*a.right) + ")";
- }
- std::string operator()(const ir::Division& a) {
- return "("s + visitNode(*a.left) + ") / (" + visitNode(*a.right) + ")";
- }
- std::string operator()(const ir::Atan2& a) {
- return "atan2("s + visitNode(*a.left) + ", " + visitNode(*a.right) + ")";
- }
- std::string operator()(const ir::Pow& a) {
- return "pow("s + visitNode(*a.left) + ", " + visitNode(*a.right) + ")";
- }
- std::string operator()(const ir::Cos& a) {
- return "cos("s + visitNode(*a.value) + ")";
- }
- std::string operator()(const ir::Sin& a) {
- return "sin("s + visitNode(*a.value) + ")";
- }
- std::string operator()(const ir::Exp& a) {
- return "exp("s + visitNode(*a.value) + ")";
- }
- std::string operator()(const ir::Ln& a) {
- return "log("s + visitNode(*a.value) + ")";
- }
- };
- std::string compileToOpenClDoubleDouble(const ir::Formula& formula)
- {
- OpenClDDVisitor z0Visitor{ 0, "double2" };
- std::string startA = z0Visitor.visitNode(*formula.startA);
- std::string startB = z0Visitor.visitNode(*formula.startB);
- OpenClDDVisitor ocv{ z0Visitor.varnameCounter, "double2" };
- std::string newA = ocv.visitNode(*formula.newA);
- std::string newB = ocv.visitNode(*formula.newB);
- std::string prelude =
- "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
- "__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"
- " int index = get_global_id(0);\n"
- " int ix = index % width;\n"
- " int iy = index / width;\n"
- " double c_re = ix * pixelScaleX + xl;\n"
- " double c_im = iy * pixelScaleY + yt;\n";
- prelude += z0Visitor.code.str() +
- " double z_re = " + startA + ";\n" +
- " double z_im = " + startB + ";\n" +
- "\n"
- " int n = 0;\n"
- " while (n < max - 1) {\n";
- std::string after =
- " if (z_re * z_re + z_im * z_im > 16) break;\n"
- " n++;\n"
- " }\n"
- " if (n >= max - 1) {\n"
- " A[index] = max;\n"
- " }\n"
- " else {\n"
- " A[index] = ((float)n);\n"
- " }\n"
- "}\n";
- std::string code = prelude + ocv.code.str();
- code += "z_re = " + newA + ";\n";
- code += "z_im = " + newB + ";\n";
- code += after;
- //code = mnd::getFloat_cl();
- printf("cld: %s\n", code.c_str()); fflush(stdout);
- return code;
- }
- #ifdef WITH_OPENCL
- std::unique_ptr<MandelGenerator> compileClDoubleDouble(const ir::Formula& formula, MandelDevice& md)
- {
- return nullptr;
- //return std::make_unique<CompiledClGeneratorDouble>(md, compileToOpenClDouble(formula));
- }
- #endif
- }
|