Prechádzať zdrojové kódy

improving compilation 2

Nicolas Winkler 5 rokov pred
rodič
commit
1e4e6eca63

+ 23 - 9
choosegenerators.cpp

@@ -304,24 +304,38 @@ void ChooseGenerators::on_compile_clicked()
 {
     QString formula = this->ui->formula->text();
     QString z0formula = this->ui->initialFormula->text();
-    mnd::IterationFormula itf{ mnd::parse(formula.toStdString()) };
+    mnd::IterationFormula zi{ mnd::parse(formula.toStdString()) };
     mnd::IterationFormula z0{ mnd::parse(z0formula.toStdString()) };
-    itf.optimize();
-    z0.optimize();
+    //zi.optimize();
+    //z0.optimize();
 
+    //const mnd::MandelDevice& dev = mndCtxt.getDevices()[0];
+    //auto cls = mnd::compileOpenCl(dev, z0, itf);
+    std::vector<std::unique_ptr<mnd::MandelGenerator>> cpuGenerators;
+    try {
+        std::cout << mnd::toString(*z0.expr) << std::endl;
+        std::cout << mnd::toString(*zi.expr) << std::endl;
+        cpuGenerators = compileCpu(mndCtxt, z0, zi);
+    }
+    catch(const mnd::ParseError& pe) {
+        printf("Parse error: %s\n", pe.what());
+        return;
+    }
+    /*catch(const char* e) {
+        printf("error: %s\n", e);
+        return;
+    }*/
+    chosenGenerator = std::move(cpuGenerators[0]);
 
-    const mnd::MandelDevice& dev = mndCtxt.getDevices()[0];
-    auto cls = mnd::compileOpenCl(dev, z0, itf);
-    chosenGenerator = compileCpu(mndCtxt, z0, itf);
-
+    return;
 
-    std::string expr = mnd::toString(*itf.expr);
+    std::string expr = mnd::toString(*zi.expr);
     printf("zi := %s\n", expr.c_str()); fflush(stdout);
     expr = mnd::toString(*z0.expr);
     printf("z0 := %s\n", expr.c_str()); fflush(stdout);
     //chosenGenerator = std::make_unique<mnd::NaiveGenerator>(std::move(itf), std::move(z0), mnd::getPrecision<double>());
     //return;
-    mnd::ir::Formula irform = mnd::expand(itf, z0);
+    mnd::ir::Formula irform = mnd::expand(z0, zi);
     printf("%s\n", irform.toString().c_str()); fflush(stdout);
     irform.constantPropagation();
     printf("%s\n", irform.toString().c_str()); fflush(stdout);

+ 3 - 3
libmandel/include/IterationCompiler.h

@@ -20,13 +20,13 @@ namespace mnd
 
     //mnd::ExecData compile(mnd::MandelContext& mndCtxt);
 
-    std::unique_ptr<mnd::MandelGenerator> compileCpu(mnd::MandelContext& mndCtxt,
+    std::vector<std::unique_ptr<mnd::MandelGenerator>> compileCpu(mnd::MandelContext& mndCtxt,
         const IterationFormula& z0,
-        const IterationFormula& z);
+        const IterationFormula& zi);
 
     std::vector<std::pair<mnd::GeneratorType, std::unique_ptr<mnd::MandelGenerator>>> compileOpenCl(const mnd::MandelDevice& dev,
         const IterationFormula& z0,
-        const IterationFormula& z);
+        const IterationFormula& zi);
 }
 //void squareTest();
 

+ 2 - 2
libmandel/include/IterationFormula.h

@@ -49,8 +49,8 @@ struct mnd::IterationFormula
 {
     std::vector<std::string> variables;
     std::unique_ptr<Expression> expr;
-    IterationFormula(std::unique_ptr<Expression> expr, const std::vector<std::string>& variables = { "c", "z" });
-    IterationFormula(Expression expr, const std::vector<std::string>& variables = { "c", "z" });
+    IterationFormula(std::unique_ptr<Expression> expr, const std::vector<std::string>& variables = { "c", "z", "i" });
+    IterationFormula(Expression expr, const std::vector<std::string>& variables = { "c", "z", "i" });
 
     std::optional<std::string> findUnknownVariables(const Expression& expr);
     void optimize(void);

+ 2 - 0
libmandel/include/IterationGenerator.h

@@ -36,6 +36,7 @@ class mnd::NaiveGenerator : public mnd::IterationGenerator
 {
 public:
     NaiveGenerator(IterationFormula z0, IterationFormula zi, const mnd::Real& prec);
+    NaiveGenerator(NaiveGenerator&&) = default;
 
     virtual void generate(const MandelInfo& info, float* data);
 private:
@@ -64,6 +65,7 @@ class mnd::CompiledClGenerator : public mnd::ClGeneratorFloat
 {
 public:
     CompiledClGenerator(const MandelDevice& device, const std::string& code);
+    CompiledClGenerator(CompiledClGenerator&&) = default;
     //virtual ~CompiledGenerator(void);
     //virtual void generate(const MandelInfo& info, float* data);
     virtual std::string getKernelCode(bool smooth) const override;

+ 2 - 1
libmandel/include/IterationIR.h

@@ -64,10 +64,11 @@ namespace mnd
             std::string toString(void) const;
 
             void constantPropagation(void);
+            void optimize(void);
         };
     }
 
-    ir::Formula expand(const mnd::IterationFormula& fmla, const mnd::IterationFormula& z0);
+    ir::Formula expand(const mnd::IterationFormula& z0, const mnd::IterationFormula& zi);
 }
 
 

+ 12 - 8
libmandel/src/IterationCompiler.cpp

@@ -13,7 +13,6 @@
 using namespace std::string_literals;
 namespace mnd
 {
-
     struct CompileVisitor
     {
         using Reg = asmjit::x86::Xmm;
@@ -65,7 +64,7 @@ namespace mnd
                 return y;
             }
             else
-                throw "unknown variable";
+                throw mnd::ParseError(std::string("unknown variable: ") + v.name);
         }
 
         Reg operator()(const ir::Negation& n) {
@@ -404,16 +403,21 @@ namespace mnd
     }
 #endif
 
-    std::unique_ptr<mnd::MandelGenerator> compileCpu(mnd::MandelContext& mndCtxt,
+    std::vector<std::unique_ptr<mnd::MandelGenerator>> compileCpu(mnd::MandelContext& mndCtxt,
         const IterationFormula& z0,
         const IterationFormula& zi)
     {
-        auto ng = std::make_unique<NaiveGenerator>(z0.clone(), zi.clone(), mnd::getPrecision<double>());
-        
-        //ir::Formula irf = mnd::expand(zi, z0);
-        //auto dg = std::make_unique<CompiledGenerator>(compile(irf));
+        //std::unique_ptr<mnd::MandelGenerator> ng = std::make_unique<NaiveGenerator>(z0.clone(), zi.clone(), mnd::getPrecision<double>());
+
+        ir::Formula irf = mnd::expand(z0, zi);
+        irf.optimize();
+        printf("ir: %s\n", irf.toString().c_str()); fflush(stdout);
+        auto dg = std::make_unique<CompiledGenerator>(compile(irf));
 
-        return ng;
+        std::vector<std::unique_ptr<mnd::MandelGenerator>> vec;
+        //vec.push_back(std::move(ng));
+        vec.push_back(std::move(dg));
+        return vec;
     }
 
     std::vector<std::pair<mnd::GeneratorType, std::unique_ptr<mnd::MandelGenerator>>> compileOpenCl(const mnd::MandelDevice& dev,

+ 1 - 3
libmandel/src/IterationFormula.cpp

@@ -193,14 +193,12 @@ bool mnd::IterationFormula::containsVariable(const std::string& name) const
 
 mnd::IterationFormula mnd::IterationFormula::clone(void) const
 {
-
-
     std::function<std::unique_ptr<mnd::Expression>(const mnd::Expression&)> cloner;
     cloner = [&cloner](const mnd::Expression& e) {
         return std::make_unique<mnd::Expression>(std::visit([&cloner](const auto& x) -> mnd::Expression {
             using T = std::decay_t<decltype(x)>;
             if constexpr (std::is_same<T, mnd::Constant>::value) {
-                return mnd::Constant{ 0, 0 };
+                return x;
             }
             else if constexpr (std::is_same<T, mnd::Variable>::value) {
                 return mnd::Variable{ x.name };

+ 2 - 5
libmandel/src/IterationGenerator.cpp

@@ -41,12 +41,9 @@ void NaiveGenerator::generate(const mnd::MandelInfo& info, float* data)
     T wpp = mnd::convert<T>(view.width / info.bWidth);
     T hpp = mnd::convert<T>(view.height / info.bHeight);
 
-    T juliaX = mnd::convert<T>(info.juliaX);
-    T juliaY = mnd::convert<T>(info.juliaY);
-
     if constexpr (parallel)
         omp_set_num_threads(omp_get_num_procs());
-#pragma omp parallel for schedule(static, 1) if (parallel)
+//#pragma omp parallel for schedule(static, 1) if (parallel)
     for (long j = 0; j < info.bHeight; j++) {
         T y = viewy + T(double(j)) * hpp;
         long i = 0;
@@ -175,7 +172,7 @@ void CompiledGenerator::generate(const mnd::MandelInfo& info, float* data)
     using IterFunc = int (*)(double, double, int);
 
     omp_set_num_threads(omp_get_num_procs());
-#pragma omp parallel for schedule(static, 1)
+//#pragma omp parallel for schedule(static, 1)
     for (int i = 0; i < info.bHeight; i++) {
         double y = mnd::convert<double>(info.view.y + info.view.height * i / info.bHeight);
         for (int j = 0; j < info.bWidth; j++) {

+ 19 - 12
libmandel/src/IterationIR.cpp

@@ -40,14 +40,14 @@ namespace mnd
         NodePair operator() (const Variable& v)
         {
             //printf("var %s\n", v.name.c_str()); fflush(stdout);
-            if (iterationFormula.containsVariable(v.name)) {
+            if (v.name == "i") {
+                return { zero, one };
+            }
+            else if (iterationFormula.containsVariable(v.name)) {
                 Node* a = arena.allocate(ir::Variable{ v.name + "_re" });
                 Node* b = arena.allocate(ir::Variable{ v.name + "_im" });
                 return { a, b };
             }
-            else if (v.name == "i") {
-                return { zero, one };
-            }
             else
                 throw "unknown variable";
         }
@@ -220,16 +220,15 @@ namespace mnd
         }
     };
 
-    ir::Formula expand(const mnd::IterationFormula& fmla, const mnd::IterationFormula& z0)
+    ir::Formula expand(const mnd::IterationFormula& z0, const mnd::IterationFormula& zi)
     {
         ir::Formula formula;
-        ConvertVisitor cv{ formula.nodeArena, fmla };
-        std::tie(formula.startA, formula.startB) = std::visit(cv, *z0.expr);
-        std::tie(formula.newA, formula.newB) = std::visit(cv, *fmla.expr);
+        ConvertVisitor cv0{ formula.nodeArena, z0 };
+        ConvertVisitor cvi{ formula.nodeArena, zi };
+        std::tie(formula.startA, formula.startB) = std::visit(cv0, *z0.expr);
+        std::tie(formula.newA, formula.newB) = std::visit(cvi, *zi.expr);
         return formula;
-    }
-
-    
+    }    
 }
 
 
@@ -291,7 +290,9 @@ std::string mnd::ir::Formula::toString(void) const
     };
 
     return std::string("a = ") + std::visit(ToStringVisitor{}, *this->newA) + 
-        "\nb = " + std::visit(ToStringVisitor{}, *this->newB);
+        "\nb = " + std::visit(ToStringVisitor{}, *this->newB) +
+        "\nx = " + std::visit(ToStringVisitor{}, *this->startA) +
+        "\ny = " + std::visit(ToStringVisitor{}, *this->startB);
 }
 
 struct ConstantPropagator
@@ -502,4 +503,10 @@ void mnd::ir::Formula::constantPropagation(void)
 }
 
 
+void mnd::ir::Formula::optimize(void)
+{
+    constantPropagation();
+}
+
+