Nicolas Winkler 5 lat temu
rodzic
commit
0e669afdd0

+ 23 - 10
CMakeLists.txt

@@ -37,7 +37,7 @@ target_include_directories(Almond PUBLIC ${FFMPEG_INCLUDE_DIRS})
 target_link_libraries(Almond PUBLIC mandel asmjit qd)
 target_link_libraries(Almond PUBLIC Qt5::Core Qt5::Widgets Qt5::OpenGL Qt5::Xml)
 target_link_libraries(Almond PUBLIC ${FFMPEG_LIBRARIES})
-target_link_libraries(Almond PUBLIC OpenGL::OpenGL)
+target_link_libraries(Almond PUBLIC OpenGL::GL)
 
 if(Boost_FOUND)
     target_compile_definitions(Almond PUBLIC WITH_BOOST)
@@ -50,15 +50,28 @@ if(OpenMP_CXX_FOUND)
     target_link_libraries(Almond PUBLIC OpenMP::OpenMP_CXX)
 endif()
 
-install(TARGETS Almond RUNTIME DESTINATION "bin")
-set(CPACK_GENERATOR "DEB")
-set(CPACK_SOURCE_GENERATOR "DEB")
-set(CPACK_COMPONENTS_ALL Almond)
-set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nicolas Winkler")
-set(CPACK_DEBIAN_PACKAGE_DEPENDS "qt5-default,libavformat58,libavdevice58,libavfilter7,libavutil56,libswscale5,libgl1,ocl-icd-libopencl1")
-set(CPACK_SET_DESTDIR True)
-set(CPACK_INSTALL_PREFIX "/usr")
 
-include(CPack)
+set(CPACK_PACKAGE_NAME "Almond")
+set(CPACK_PACKAGE_VERSION "1.0.0")
+IF (WIN32)
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyPackage Installation Example")
+    include(CPack)
+    include(CPackIFW)
+    cpack_add_component(Almond
+        DISPLAY_NAME "Almond"
+        DESCRIPTION "Almond Application")
+    cpack_ifw_configure_component(Almond)
+
+ELSEIF (UNIX AND NOT APPLE)
+    install(TARGETS Almond RUNTIME DESTINATION "bin")
+    set(CPACK_GENERATOR "DEB")
+    set(CPACK_SOURCE_GENERATOR "DEB")
+    set(CPACK_COMPONENTS_ALL Almond)
+    set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nicolas Winkler")
+    set(CPACK_DEBIAN_PACKAGE_DEPENDS "qt5-default,libavformat58,libavdevice58,libavfilter7,libavutil56,libswscale5,libgl1,ocl-icd-libopencl1")
+    set(CPACK_SET_DESTDIR True)
+    set(CPACK_INSTALL_PREFIX "/usr")
+    include(CPack)
+ENDIF()
 
 

+ 3 - 2
libmandel/include/NaiveIRGenerator.h

@@ -1,6 +1,8 @@
 #ifndef MANDEL_NAIVEIRGENERATOR_H
 #define MANDEL_NAIVEIRGENERATOR_H
 
+#include "IterationIR.h"
+#include "Generators.h"
 
 namespace mnd
 {
@@ -14,11 +16,10 @@ class mnd::NaiveIRGenerator : public mnd::MandelGenerator
 {
     const ir::Formula& form;
 public:
-    NaiveIRGenerator(const ir::Formula& irf, mnd::Precision prec);
+    NaiveIRGenerator(const ir::Formula& irf, mnd::Precision prec = mnd::getType<T>());
     NaiveIRGenerator(NaiveIRGenerator&&) = default;
 
     virtual void generate(const MandelInfo& info, float* data);
-    double calc(ir::Node* expr, double a, double b, double x, double y);
 };
 
 

+ 4 - 0
libmandel/src/IterationCompiler.cpp

@@ -1,4 +1,5 @@
 #include "IterationCompiler.h"
+#include "NaiveIRGenerator.h"
 
 #include "ExecData.h"
 #include "Mandel.h"
@@ -783,6 +784,9 @@ namespace mnd
             printf("asm avxvec: %s\n", dgavx->dump().c_str()); fflush(stdout);
             vec.push_back(std::move(dgavx));
         }
+
+        //vec.push_back(std::make_unique<NaiveIRGenerator<mnd::DoubleDouble>>(irf));
+        //vec.push_back(std::make_unique<NaiveIRGenerator<mnd::QuadDouble>>(irf));
         
         //auto dg = std::make_unique<NaiveIRGenerator>(*irf, mnd::getPrecision<double>());
 

+ 0 - 9
libmandel/src/IterationGenerator.cpp

@@ -12,15 +12,6 @@ using mnd::NaiveGenerator;
 using mnd::IterationFormula;
 
 
-namespace mnd
-{
-    template class NaiveIRGenerator<float>;
-    template class NaiveIRGenerator<double>;
-    template class NaiveIRGenerator<mnd::DoubleDouble>;
-    template class NaiveIRGenerator<mnd::QuadDouble>;
-}
-
-
 IterationGenerator::IterationGenerator(IterationFormula z0, IterationFormula zi,
             mnd::Precision prec, mnd::CpuExtension ex) :
     mnd::MandelGenerator{ prec, ex },

+ 127 - 99
libmandel/src/NaiveIRGenerator.cpp

@@ -1,9 +1,19 @@
 #include "NaiveIRGenerator.h"
+#include <omp.h>
 
-#include "IterationIR.h"
 
 using mnd::NaiveIRGenerator;
 
+
+namespace mnd
+{
+    template class NaiveIRGenerator<float>;
+    template class NaiveIRGenerator<double>;
+    template class NaiveIRGenerator<mnd::DoubleDouble>;
+    template class NaiveIRGenerator<mnd::QuadDouble>;
+}
+
+
 template<typename T>
 NaiveIRGenerator<T>::NaiveIRGenerator(const mnd::ir::Formula& irf,
     mnd::Precision prec) :
@@ -13,38 +23,146 @@ NaiveIRGenerator<T>::NaiveIRGenerator(const mnd::ir::Formula& irf,
 }
 
 
-template<typename U>
-void NaiveIRGenerator<U>::generate(const mnd::MandelInfo& info, float* data)
+template<typename T>
+struct EvalRes
+{
+    size_t incVal;
+    T result;
+};
+
+
+using namespace mnd;
+template<typename T>
+struct TVisitor
+{
+    T a, b, x, y;
+    size_t incrementValue;
+
+    T visitNode(ir::Node* n) {
+        EvalRes<T>* nodeData = getNodeData(n);
+        if (nodeData) {
+            if (nodeData->incVal == incrementValue)
+                return nodeData->result;
+        }
+        T res = std::visit(*this, *n);
+        if (nodeData) {
+            nodeData->incVal = incrementValue;
+            nodeData->result = res;
+        }
+        return res;
+    }
+
+    EvalRes<T>* getNodeData(ir::Node* n) {
+        assert(n != nullptr);
+        std::any& x = std::visit([](auto& n) {
+            return n.nodeData;
+        }, *n);
+        if (auto* v = std::any_cast<EvalRes<T>>(&x))
+            return v;
+        else
+            return nullptr;
+    }
+
+    T operator()(const ir::Constant& c) {
+        return mnd::convert<double>(c.value);
+    }
+
+    T operator()(const ir::Variable& v) {
+        if (v.name == "z_re")
+            return a;
+        else if (v.name == "z_im")
+            return b;
+        else if (v.name == "c_re")
+            return x;
+        else if (v.name == "c_im")
+            return y;
+        else
+            return 0.0;
+    }
+
+    T operator()(const ir::Negation& n) {
+        return -visitNode(n.value);
+    }
+
+    T operator()(const ir::Addition& n) {
+        return visitNode(n.left) + visitNode(n.right);
+    }
+
+    T operator()(const ir::Subtraction& n) {
+        return visitNode(n.left) - visitNode(n.right);
+    }
+
+    T operator()(const ir::Multiplication& n) {
+        return visitNode(n.left) * visitNode(n.right);
+    }
+
+    T operator()(const ir::Division& n) {
+        return visitNode(n.left) / visitNode(n.right);
+    }
+
+    T operator()(const ir::Atan2& n) {
+        return ::atan2(visitNode(n.left), visitNode(n.right));
+    }
+
+    T operator()(const ir::Pow& n) {
+        return ::pow(visitNode(n.left), visitNode(n.right));
+    }
+
+    T operator()(const ir::Cos& n) {
+        return ::cos(visitNode(n.value));
+    }
+
+    T operator()(const ir::Sin& n) {
+        return ::sin(visitNode(n.value));
+    }
+
+    T operator()(const ir::Exp& n) {
+        return ::exp(visitNode(n.value));
+    }
+
+    T operator()(const ir::Ln& n) {
+        return ::log(visitNode(n.value));
+    }
+};
+
+
+template<typename T>
+void NaiveIRGenerator<T>::generate(const mnd::MandelInfo& info, float* data)
 {
     const MandelViewport& view = info.view;
 
     const bool parallel = true;
-    using T = double;
     T viewx = mnd::convert<T>(view.x);
     T viewy = mnd::convert<T>(view.y);
     T wpp = mnd::convert<T>(view.width / info.bWidth);
     T hpp = mnd::convert<T>(view.height / info.bHeight);
 
+#if defined(_OPENMP)
     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)
+#endif
     for (long j = 0; j < info.bHeight; j++) {
         T y = viewy + T(double(j)) * hpp;
         long i = 0;
         for (i; i < info.bWidth; i++) {
             T x = viewx + T(double(i)) * wpp;
 
-            T a = calc(form.startA, x, y, 0, 0);
-            T b = calc(form.startB, x, y, 0, 0);
+            TVisitor<T> beforeVisitor{ 0, 0, x, y, 0 };
+
+            T a = beforeVisitor.visitNode(form.startA);
+            T b = beforeVisitor.visitNode(form.startB);
 
+            TVisitor<T> visitor{ a, b, x, y, 0 };
             int k = 0;
             for (k = 0; k < info.maxIter; k++) {
-                double newA = calc(form.newA, a, b, x, y);
-                double newB = calc(form.newB, a, b, x, y);
+                T newA = visitor.visitNode(form.newA);
+                T newB = visitor.visitNode(form.newB);
                 a = newA;
                 b = newB;
                 if (a * a + b * b >= 16.0)
                     break;
+                visitor.incrementValue++;
             }
             data[i + j * info.bWidth] = float(k);
         }
@@ -52,93 +170,3 @@ void NaiveIRGenerator<U>::generate(const mnd::MandelInfo& info, float* data)
 }
 
 
-template<typename T>
-struct EvalNode
-{
-
-};
-
-
-template<typename T>
-double NaiveIRGenerator<T>::calc(mnd::ir::Node* expr, double a, double b, double x, double y)
-{
-    struct DoubleVisitor
-    {
-        double a, b, x, y;
-        double visitNode(ir::Node* n) {
-            auto& nodeData = getNodeData(n);
-            //if (std::get_a)
-            return std::visit(*this, *n);
-        }
-
-        const std::any& getNodeData(ir::Node* n) {
-            return std::visit([](auto& n) {
-                return n.nodeData;
-            }, *n);
-        }
-
-        double operator()(const ir::Constant& c) {
-            return mnd::convert<double>(c.value);
-        }
-
-        double operator()(const ir::Variable& v) {
-            if (v.name == "z_re")
-                return a;
-            else if (v.name == "z_im")
-                return b;
-            else if (v.name == "c_re")
-                return x;
-            else if (v.name == "c_im")
-                return y;
-            else
-                return 0.0;
-        }
-
-        double operator()(const ir::Negation& n) {
-            return -visitNode(n.value);
-        }
-
-        double operator()(const ir::Addition& n) {
-            return visitNode(n.left) + visitNode(n.right);
-        }
-
-        double operator()(const ir::Subtraction& n) {
-            return visitNode(n.left) - visitNode(n.right);
-        }
-
-        double operator()(const ir::Multiplication& n) {
-            return visitNode(n.left) * visitNode(n.right);
-        }
-
-        double operator()(const ir::Division& n) {
-            return visitNode(n.left) / visitNode(n.right);
-        }
-
-        double operator()(const ir::Atan2& n) {
-            return ::atan2(visitNode(n.left), visitNode(n.right));
-        }
-
-        double operator()(const ir::Pow& n) {
-            return ::pow(visitNode(n.left), visitNode(n.right));
-        }
-
-        double operator()(const ir::Cos& n) {
-            return ::cos(visitNode(n.value));
-        }
-
-        double operator()(const ir::Sin& n) {
-            return ::sin(visitNode(n.value));
-        }
-
-        double operator()(const ir::Exp& n) {
-            return ::exp(visitNode(n.value));
-        }
-
-        double operator()(const ir::Ln& n) {
-            return ::log(visitNode(n.value));
-        }
-    };
-
-    DoubleVisitor dv{ a, b, x, y };
-    return dv.visitNode(expr);
-}