Bladeren bron

Merge branch 'master' of http://192.168.1.47/nicolas/Almond

Nicolas Winkler 5 jaren geleden
bovenliggende
commit
d39d0d70dc

+ 41 - 39
benchmarkdialog.cpp

@@ -9,44 +9,44 @@ mnd::MandelViewport Benchmarker::benchViewport(void)
 }
 
 const std::vector<mnd::MandelInfo> Benchmarker::benches {
-    mnd::MandelInfo{ benchViewport(), 50, 50, 250 },
-    mnd::MandelInfo{ benchViewport(), 50, 50, 500 },
-    mnd::MandelInfo{ benchViewport(), 50, 100, 500 },
-    mnd::MandelInfo{ benchViewport(), 100, 100, 500 },
-    mnd::MandelInfo{ benchViewport(), 100, 100, 1000 },
-    mnd::MandelInfo{ benchViewport(), 100, 200, 1000 },
-    mnd::MandelInfo{ benchViewport(), 200, 200, 1000 },
-    mnd::MandelInfo{ benchViewport(), 200, 200, 2000 },
-    mnd::MandelInfo{ benchViewport(), 200, 400, 2000 },
-    mnd::MandelInfo{ benchViewport(), 400, 400, 2000 },
-    mnd::MandelInfo{ benchViewport(), 400, 400, 4000 },
-    mnd::MandelInfo{ benchViewport(), 400, 800, 4000 },
-    mnd::MandelInfo{ benchViewport(), 800, 800, 4000 },
-    mnd::MandelInfo{ benchViewport(), 800, 800, 8000 },
-    mnd::MandelInfo{ benchViewport(), 800, 800, 16000 },
-    mnd::MandelInfo{ benchViewport(), 800, 1600, 16000 },
-    mnd::MandelInfo{ benchViewport(), 1600, 1600, 16000 },
-    mnd::MandelInfo{ benchViewport(), 1600, 1600, 32000 },
-    mnd::MandelInfo{ benchViewport(), 1600, 1600, 64000 },
-    mnd::MandelInfo{ benchViewport(), 1600, 3200, 64000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 3200, 64000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 3200, 128000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 3200, 256000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 3200, 512000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 3200, 1024000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 3200, 2048000 },
-    mnd::MandelInfo{ benchViewport(), 3200, 6400, 2048000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 2048000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 4096000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 8192000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 16384000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 32768000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 65536000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 131072000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 262144000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 524288000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 1048576000 },
-    mnd::MandelInfo{ benchViewport(), 6400, 6400, 2097152000 },
+    mnd::MandelInfo{ benchViewport(), 50, 50, 250, false },
+    mnd::MandelInfo{ benchViewport(), 50, 50, 500, false },
+    mnd::MandelInfo{ benchViewport(), 50, 100, 500, false },
+    mnd::MandelInfo{ benchViewport(), 100, 100, 500, false },
+    mnd::MandelInfo{ benchViewport(), 100, 100, 1000, false },
+    mnd::MandelInfo{ benchViewport(), 100, 200, 1000, false },
+    mnd::MandelInfo{ benchViewport(), 200, 200, 1000, false },
+    mnd::MandelInfo{ benchViewport(), 200, 200, 2000, false },
+    mnd::MandelInfo{ benchViewport(), 200, 400, 2000, false },
+    mnd::MandelInfo{ benchViewport(), 400, 400, 2000, false },
+    mnd::MandelInfo{ benchViewport(), 400, 400, 4000, false },
+    mnd::MandelInfo{ benchViewport(), 400, 800, 4000, false },
+    mnd::MandelInfo{ benchViewport(), 800, 800, 4000, false },
+    mnd::MandelInfo{ benchViewport(), 800, 800, 8000, false },
+    mnd::MandelInfo{ benchViewport(), 800, 800, 16000, false },
+    mnd::MandelInfo{ benchViewport(), 800, 1600, 16000, false },
+    mnd::MandelInfo{ benchViewport(), 1600, 1600, 16000, false },
+    mnd::MandelInfo{ benchViewport(), 1600, 1600, 32000, false },
+    mnd::MandelInfo{ benchViewport(), 1600, 1600, 64000, false },
+    mnd::MandelInfo{ benchViewport(), 1600, 3200, 64000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 3200, 64000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 3200, 128000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 3200, 256000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 3200, 512000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 3200, 1024000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 3200, 2048000, false },
+    mnd::MandelInfo{ benchViewport(), 3200, 6400, 2048000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 2048000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 4096000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 8192000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 16384000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 32768000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 65536000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 131072000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 262144000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 524288000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 1048576000, false },
+    mnd::MandelInfo{ benchViewport(), 6400, 6400, 2097152000, false },
 };
 
 
@@ -98,6 +98,7 @@ double Benchmarker::benchmarkResult(mnd::Generator& mg) const
 
 void Benchmarker::start(void)
 {
+    /*
     mnd::Generator& cpuf = mndContext.getCpuGeneratorFloat();
     mnd::Generator& cpud = mndContext.getCpuGeneratorDouble();
     mnd::Generator* cpudd = mndContext.getCpuGeneratorDD();
@@ -186,6 +187,7 @@ void Benchmarker::start(void)
         }
     }
     emit update(br);
+    */
     emit finished();
 }
 
@@ -196,7 +198,7 @@ BenchmarkDialog::BenchmarkDialog(mnd::MandelContext& mndContext, QWidget *parent
     benchmarker{ mndContext }
 {
     ui.setupUi(this);
-    printf("bench!\n"); fflush(stdout);
+    //printf("bench!\n"); fflush(stdout);
 
     auto& devices = mndContext.getDevices();
     size_t nDevices = devices.size() + 1;

+ 4 - 5
libmandel/include/ClGenerators.h

@@ -33,7 +33,6 @@ public:
     virtual ~ClGenerator(void);
 
     virtual void generate(const MandelInfo& info, float* data);
-
 protected:
     virtual std::string getKernelCode(bool smooth) const = 0;
 };
@@ -42,7 +41,7 @@ protected:
 class mnd::ClGeneratorFloat : public ClGenerator
 {
 public:
-    ClGeneratorFloat(cl::Device device, bool smooth);
+    ClGeneratorFloat(cl::Device device);
     virtual ~ClGeneratorFloat(void) = default;
 
 protected:
@@ -53,7 +52,7 @@ protected:
 class mnd::ClGeneratorDouble : public ClGenerator
 {
 public:
-    ClGeneratorDouble(cl::Device device, bool smooth);
+    ClGeneratorDouble(cl::Device device);
     virtual ~ClGeneratorDouble(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data);
@@ -66,7 +65,7 @@ class mnd::ClGeneratorDoubleDouble : public ClGenerator
 {
     bool smooth;
 public:
-    ClGeneratorDoubleDouble(cl::Device device, bool smooth);
+    ClGeneratorDoubleDouble(cl::Device device);
     virtual ~ClGeneratorDoubleDouble(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data);
@@ -77,7 +76,7 @@ protected:
 class mnd::ClGenerator128 : public ClGenerator
 {
 public:
-    ClGenerator128(cl::Device device, bool smooth);
+    ClGenerator128(cl::Device device);
     virtual ~ClGenerator128(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data);

+ 16 - 16
libmandel/include/CpuGenerators.h

@@ -13,7 +13,7 @@ namespace mnd
         ARM_NEON,
     };
 
-    template<typename T, mnd::CpuExtension ex = mnd::NONE, bool parallel = true, bool smooth = true>
+    template<typename T, mnd::CpuExtension ex = mnd::NONE, bool parallel = true>
     class CpuGenerator;
 
 
@@ -39,7 +39,7 @@ namespace mnd
 }
 
 
-template<typename T, mnd::CpuExtension ex, bool parallel, bool smooth>
+template<typename T, mnd::CpuExtension ex, bool parallel>
 class mnd::CpuGenerator : public Generator
 {
 public:
@@ -47,8 +47,8 @@ public:
 };
 
 
-template<typename T, bool parallel, bool smooth>
-class mnd::CpuGenerator<T, mnd::NONE, parallel, smooth> : public Generator
+template<typename T, bool parallel>
+class mnd::CpuGenerator<T, mnd::NONE, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);
@@ -56,46 +56,46 @@ public:
 
 
 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) 
-template<bool parallel, bool smooth>
-class mnd::CpuGenerator<float, mnd::X86_SSE2, parallel, smooth> : public Generator
+template<bool parallel>
+class mnd::CpuGenerator<float, mnd::X86_SSE2, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);
 };
 
-template<bool parallel, bool smooth>
-class mnd::CpuGenerator<double, mnd::X86_SSE2, parallel, smooth> : public Generator
+template<bool parallel>
+class mnd::CpuGenerator<double, mnd::X86_SSE2, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);
 };
 
 
-template<bool parallel, bool smooth>
-class mnd::CpuGenerator<float, mnd::X86_AVX, parallel, smooth> : public Generator
+template<bool parallel>
+class mnd::CpuGenerator<float, mnd::X86_AVX, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);
 };
 
-template<bool parallel, bool smooth>
-class mnd::CpuGenerator<double, mnd::X86_AVX, parallel, smooth> : public Generator
+template<bool parallel>
+class mnd::CpuGenerator<double, mnd::X86_AVX, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);
 };
 
 #elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) 
-template<typename T, bool parallel, bool smooth>
-class mnd::CpuGenerator<T, mnd::ARM_NEON, parallel, smooth> : public Generator
+template<typename T, bool parallel>
+class mnd::CpuGenerator<T, mnd::ARM_NEON, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);
 };
 #endif
 
-template<bool parallel, bool smooth>
-class mnd::CpuGenerator<Fixed128, mnd::NONE, parallel, smooth> : public Generator
+template<bool parallel>
+class mnd::CpuGenerator<Fixed128, mnd::NONE, parallel> : public Generator
 {
 public:
     virtual void generate(const MandelInfo& info, float* data);

+ 14 - 0
libmandel/include/Generators.h

@@ -14,6 +14,19 @@ namespace mnd
     class Generator;
 
     class AdaptiveGenerator;
+
+    enum class Precision : int
+    {
+        FLOAT,
+        DOUBLE,
+        DOUBLE_DOUBLE,
+        FLOAT128,
+        QUAD_DOUBLE,
+        FLOAT256,
+        INFINITE
+    };
+
+    Real getPrecision(Precision p);
 }
 
 
@@ -43,6 +56,7 @@ public:
     virtual ~AdaptiveGenerator(void) = default;
 
     void addGenerator(const Real& precision, Generator& generator);
+    void addGenerator(Precision p, Generator& generator);
 
     virtual void generate(const MandelInfo& info, float* data);
 };

+ 27 - 37
libmandel/include/Mandel.h

@@ -2,6 +2,7 @@
 #define MANDEL_MANDEL_H
 
 #include <vector>
+#include <map>
 #include <string>
 #include <memory>
 
@@ -14,6 +15,7 @@
 
 namespace mnd
 {
+    enum class GeneratorType;
     class MandelContext;
     class MandelDevice;
 
@@ -21,6 +23,25 @@ namespace mnd
 }
 
 
+enum class mnd::GeneratorType
+{
+    FLOAT,
+    FLOAT_SSE2,
+    FLOAT_AVX,
+    FLOAT_AVX512,
+    FLOAT_NEON,
+    DOUBLE,
+    DOUBLE_SSE2,
+    DOUBLE_AVX,
+    DOUBLE_AVX512,
+    DOUBLE_NEON,
+    DOUBLE_DOUBLE,
+    QUAD_DOUBLE,
+    FLOAT128,
+    FLOAT256
+};
+
+
 class mnd::MandelDevice
 {
 private:
@@ -29,27 +50,15 @@ private:
     std::string vendor;
     std::string name;
 
-    std::unique_ptr<Generator> floatGenerator;
-    std::unique_ptr<Generator> doubleGenerator;
-    std::unique_ptr<Generator> doubleDoubleGenerator;
-    //std::unique_ptr<Generator> quadGenerator;
-    //std::unique_ptr<Generator> generator128;
-
-    std::unique_ptr<Generator> floatGeneratorSmooth;
-    std::unique_ptr<Generator> doubleGeneratorSmooth;
-    std::unique_ptr<Generator> doubleDoubleGeneratorSmooth;
-    //std::unique_ptr<Generator> quadGeneratorSmooth;
-    //std::unique_ptr<Generator> generator128Smooth;
+    std::map<GeneratorType, std::unique_ptr<Generator>> generators;
 
     MandelDevice(void);
 public:
 
     inline const std::string& getVendor(void) const { return vendor; }
-    const std::string& getName(void) const;
+    inline const std::string& getName(void) const { return name; }
 
-    Generator* getGeneratorFloat(bool smooth = true) const;
-    Generator* getGeneratorDouble(bool smooth = true) const;
-    Generator* getGeneratorDoubleDouble(bool smooth = true) const;
+    Generator* getGenerator(GeneratorType type) const;
     //Generator* getGeneratorQuad(bool smooth = true) const;
     //Generator* getGenerator128(bool smooth = true) const;
 };
@@ -62,41 +71,22 @@ private:
 
     CpuInfo cpuInfo;
 
-    std::unique_ptr<Generator> cpuGeneratorFloat;
-    std::unique_ptr<Generator> cpuGeneratorDouble;
-    std::unique_ptr<Generator> cpuGeneratorQuad;
-    std::unique_ptr<Generator> cpuGeneratorOct;
-    std::unique_ptr<Generator> cpuGenerator128;
-    std::unique_ptr<Generator> cpuGeneratorDD;
-    std::unique_ptr<Generator> cpuGeneratorQD;
-
-    std::unique_ptr<Generator> cpuGeneratorFloatSmooth;
-    std::unique_ptr<Generator> cpuGeneratorDoubleSmooth;
-    std::unique_ptr<Generator> cpuGeneratorQuadSmooth;
-    std::unique_ptr<Generator> cpuGenerator128Smooth;
-    std::unique_ptr<Generator> cpuGeneratorDDSmooth;
-    std::unique_ptr<Generator> cpuGeneratorQDSmooth;
+    std::map<GeneratorType, std::unique_ptr<Generator>> cpuGenerators;
 
     std::unique_ptr<AdaptiveGenerator> adaptiveGenerator;
-    std::unique_ptr<AdaptiveGenerator> adaptiveGeneratorSmooth;
 
     std::vector<MandelDevice> devices;
 
     MandelContext(void);
 
+    std::unique_ptr<AdaptiveGenerator> createAdaptiveGenerator(void);
     std::vector<MandelDevice> createDevices(void);
 public:
 
     Generator& getDefaultGenerator(bool smooth = true);
     const std::vector<MandelDevice>& getDevices(void);
 
-    Generator& getCpuGeneratorFloat(void);
-    Generator& getCpuGeneratorDouble(void);
-    Generator* getCpuGeneratorQuad(void);
-    Generator* getCpuGeneratorOct(void);
-    Generator* getCpuGenerator128(void);
-    Generator* getCpuGeneratorDD(void);
-    Generator* getCpuGeneratorQD(void);
+    Generator* getCpuGenerator(mnd::GeneratorType type);
 
     const CpuInfo& getCpuInfo(void) const { return cpuInfo; }
 };

+ 3 - 0
libmandel/include/MandelUtil.h

@@ -69,6 +69,9 @@ struct mnd::MandelInfo
     
     /// maximum iterations
     long maxIter;
+
+    /// smooth coloring
+    bool smooth;
 };
 
 #endif // MANDEL_MANDELUTIL_H

+ 6 - 0
libmandel/include/Types.h

@@ -125,6 +125,12 @@ namespace mnd
 #endif
 
     std::string toString(const Real& num);
+
+
+/*
+    template<typename T>
+    constexpr mnd::Real precision(void);
+*/
 }
 
 

+ 9 - 10
libmandel/src/ClGenerators.cpp

@@ -111,7 +111,7 @@ void ClGenerator::generate(const mnd::MandelInfo& info, float* data)
 }
 
 
-ClGeneratorFloat::ClGeneratorFloat(cl::Device device, bool smooth) :
+ClGeneratorFloat::ClGeneratorFloat(cl::Device device) :
     ClGenerator{ device }
 {
     /*Platform p = getPlatform();
@@ -119,7 +119,7 @@ ClGeneratorFloat::ClGeneratorFloat(cl::Device device, bool smooth) :
     context = Context{ device };
     Program::Sources sources;
 
-    std::string kcode = this->getKernelCode(smooth);
+    std::string kcode = this->getKernelCode(false);
 
     sources.push_back({ kcode.c_str(), kcode.length() });
 
@@ -199,13 +199,13 @@ std::string ClGeneratorFloat::getKernelCode(bool smooth) const
 }
 
 
-ClGeneratorDouble::ClGeneratorDouble(cl::Device device, bool smooth) :
+ClGeneratorDouble::ClGeneratorDouble(cl::Device device) :
     ClGenerator{ device }
 {
     context = Context{ device };
     Program::Sources sources;
 
-    std::string kcode = this->getKernelCode(smooth);
+    std::string kcode = this->getKernelCode(false);
 
     sources.push_back({ kcode.c_str(), kcode.length() });
 
@@ -307,9 +307,8 @@ std::string ClGeneratorDouble::getKernelCode(bool smooth) const
 }
 
 
-ClGeneratorDoubleDouble::ClGeneratorDoubleDouble(cl::Device device, bool smooth) :
-    ClGenerator{ device },
-    smooth{ smooth }
+ClGeneratorDoubleDouble::ClGeneratorDoubleDouble(cl::Device device) :
+    ClGenerator{ device }
 {
     context = Context{ device };
     Program::Sources sources;
@@ -351,7 +350,7 @@ void ClGeneratorDoubleDouble::generate(const mnd::MandelInfo& info, float* data)
     iterate.setArg(8, psy.x[0]);
     iterate.setArg(9, psy.x[1]);
     iterate.setArg(10, int(info.maxIter));
-    iterate.setArg(11, int(smooth ? 1 : 0));
+    iterate.setArg(11, int(info.smooth ? 1 : 0));
 
     cl_int result = queue.enqueueNDRangeKernel(iterate, 0, NDRange(info.bWidth * info.bHeight));
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
@@ -364,13 +363,13 @@ std::string ClGeneratorDoubleDouble::getKernelCode(bool smooth) const
 }
 
 
-ClGenerator128::ClGenerator128(cl::Device device, bool smooth) :
+ClGenerator128::ClGenerator128(cl::Device device) :
     ClGenerator{ device }
 {
     context = Context{ device };
     Program::Sources sources;
 
-    std::string kcode = this->getKernelCode(smooth);
+    std::string kcode = this->getKernelCode(false);
 
     sources.push_back({ kcode.c_str(), kcode.length() });
 

+ 24 - 36
libmandel/src/CpuGenerators.cpp

@@ -14,52 +14,40 @@ using mnd::CpuGenerator;
 
 namespace mnd
 {
-    template class CpuGenerator<float, mnd::NONE, false, false>;
-    template class CpuGenerator<float, mnd::NONE, false, true>;
-    template class CpuGenerator<float, mnd::NONE, true, false>;
-    template class CpuGenerator<float, mnd::NONE, true, true>;
+    template class CpuGenerator<float, mnd::NONE, false>;
+    template class CpuGenerator<float, mnd::NONE, true>;
 
-    template class CpuGenerator<double, mnd::NONE, false, false>;
-    template class CpuGenerator<double, mnd::NONE, false, true>;
-    template class CpuGenerator<double, mnd::NONE, true, false>;
-    template class CpuGenerator<double, mnd::NONE, true, true>;
+    template class CpuGenerator<double, mnd::NONE, false>;
+    template class CpuGenerator<double, mnd::NONE, true>;
 
     
-    //template class CpuGenerator<Fixed128, mnd::NONE, false, false>;
+    //template class CpuGenerator<Fixed128, mnd::NONE, false>;
     //template class CpuGenerator<Fixed128, mnd::NONE, false, true>;
-    //template class CpuGenerator<Fixed128, mnd::NONE, true, false>;
+    //template class CpuGenerator<Fixed128, mnd::NONE, true>;
     //template class CpuGenerator<Fixed128, mnd::NONE, true, true>;
     
 
 #ifdef WITH_BOOST
 #include <boost/multiprecision/cpp_bin_float.hpp>
-    template class CpuGenerator<mnd::Float128, mnd::NONE, false, false>;
-    template class CpuGenerator<mnd::Float128, mnd::NONE, false, true>;
-    template class CpuGenerator<mnd::Float128, mnd::NONE, true, false>;
-    template class CpuGenerator<mnd::Float128, mnd::NONE, true, true>;
-
-    template class CpuGenerator<mnd::Float256, mnd::NONE, false, false>;
-    template class CpuGenerator<mnd::Float256, mnd::NONE, false, true>;
-    template class CpuGenerator<mnd::Float256, mnd::NONE, true, false>;
-    template class CpuGenerator<mnd::Float256, mnd::NONE, true, true>;
+    template class CpuGenerator<mnd::Float128, mnd::NONE, false>;
+    template class CpuGenerator<mnd::Float128, mnd::NONE, true>;
+
+    template class CpuGenerator<mnd::Float256, mnd::NONE, false>;
+    template class CpuGenerator<mnd::Float256, mnd::NONE, true>;
 #endif
 
 #ifdef WITH_QD
-    template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, false, false>;
-    template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, false, true>;
-    template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, true, false>;
-    template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, true, true>;
-
-    template class CpuGenerator<mnd::QuadDouble, mnd::NONE, false, false>;
-    template class CpuGenerator<mnd::QuadDouble, mnd::NONE, false, true>;
-    template class CpuGenerator<mnd::QuadDouble, mnd::NONE, true, false>;
-    template class CpuGenerator<mnd::QuadDouble, mnd::NONE, true, true>;
+    template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, false>;
+    template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, true>;
+
+    template class CpuGenerator<mnd::QuadDouble, mnd::NONE, false>;
+    template class CpuGenerator<mnd::QuadDouble, mnd::NONE, true>;
 #endif
 }
 
 
-template<typename T, bool parallel, bool smooth>
-void CpuGenerator<T, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<typename T, bool parallel>
+void CpuGenerator<T, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     const MandelViewport& view = info.view;
 
@@ -91,7 +79,7 @@ void CpuGenerator<T, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInf
                     break;
                 }
             }
-            if constexpr (smooth) {
+            if (info.smooth) {
                 if (k >= info.maxIter)
                     data[i + j * info.bWidth] = info.maxIter;
                 else
@@ -105,8 +93,8 @@ void CpuGenerator<T, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInf
 
 /*
 #if defined(WITH_BOOST) || 1
-template<bool parallel, bool smooth>
-void CpuGenerator<Fixed128, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<bool parallel>
+void CpuGenerator<Fixed128, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     using T = Fixed128;
     const MandelViewport& view = info.view;
@@ -158,8 +146,8 @@ void CpuGenerator<Fixed128, mnd::NONE, parallel, smooth>::generate(const mnd::Ma
 */
 
 #ifdef WITH_MPFR
-template<unsigned int bits, bool parallel, bool smooth>
-void CpuGenerator<mnd::MpfrFloat<bits>, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<unsigned int bits, bool parallel>
+void CpuGenerator<mnd::MpfrFloat<bits>, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     const MandelViewport& view = info.view;
     using T = mnd::MpfrFloat<bits>;
@@ -187,7 +175,7 @@ void CpuGenerator<mnd::MpfrFloat<bits>, mnd::NONE, parallel, smooth>::generate(c
                     break;
                 }
             }
-            if constexpr (smooth) {
+            if (info.smooth) {
                 if (k >= info.maxIter)
                     data[i + j * info.bWidth] = info.maxIter;
                 else

+ 12 - 16
libmandel/src/CpuGeneratorsAVX.cpp

@@ -10,19 +10,15 @@ using mnd::CpuGenerator;
 
 namespace mnd
 {
-    template class CpuGenerator<float, mnd::X86_AVX, false, false>;
-    template class CpuGenerator<float, mnd::X86_AVX, false, true>;
-    template class CpuGenerator<float, mnd::X86_AVX, true, false>;
-    template class CpuGenerator<float, mnd::X86_AVX, true, true>;
-
-    template class CpuGenerator<double, mnd::X86_AVX, false, false>;
-    template class CpuGenerator<double, mnd::X86_AVX, false, true>;
-    template class CpuGenerator<double, mnd::X86_AVX, true, false>;
-    template class CpuGenerator<double, mnd::X86_AVX, true, true>;
+    template class CpuGenerator<float, mnd::X86_AVX, false>;
+    template class CpuGenerator<float, mnd::X86_AVX, true>;
+
+    template class CpuGenerator<double, mnd::X86_AVX, false>;
+    template class CpuGenerator<double, mnd::X86_AVX, true>;
 }
 
-template<bool parallel, bool smooth>
-void CpuGenerator<float, mnd::X86_AVX, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<bool parallel>
+void CpuGenerator<float, mnd::X86_AVX, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     using T = float;
     const MandelViewport& view = info.view;
@@ -63,7 +59,7 @@ void CpuGenerator<float, mnd::X86_AVX, parallel, smooth>::generate(const mnd::Ma
                 a = _mm256_add_ps(_mm256_sub_ps(aa, bb), xs);
                 b = _mm256_add_ps(abab, ys);
                 __m256 cmp = _mm256_cmp_ps(_mm256_add_ps(aa, bb), threshold, _CMP_LE_OQ);
-                if constexpr (smooth) {
+                if (info.smooth) {
                     resultsa = _mm256_or_ps(_mm256_andnot_ps(cmp, resultsa), _mm256_and_ps(cmp, a));
                     resultsb = _mm256_or_ps(_mm256_andnot_ps(cmp, resultsb), _mm256_and_ps(cmp, b));
                 }
@@ -88,7 +84,7 @@ void CpuGenerator<float, mnd::X86_AVX, parallel, smooth>::generate(const mnd::Ma
 
             _mm256_store_ps(ftRes, counter);
             for (int k = 0; k < 8 && i + k < info.bWidth; k++) {
-                if constexpr (smooth) {
+                if (info.smooth) {
                     data[i + k + j * info.bWidth] = ftRes[k] <= 0 ? info.maxIter :
                         ftRes[k] >= info.maxIter ? info.maxIter :
                         ((float)ftRes[k]) + 1 - ::log(::log(resa[k] * resa[k] + resb[k] * resb[k]) / 2) / ::log(2.0f);
@@ -102,15 +98,15 @@ void CpuGenerator<float, mnd::X86_AVX, parallel, smooth>::generate(const mnd::Ma
 }
 
 
-template<bool parallel, bool smooth>
-void CpuGenerator<double, mnd::X86_AVX, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<bool parallel>
+void CpuGenerator<double, mnd::X86_AVX, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     using T = double;
     const MandelViewport& view = info.view;
 
     if constexpr(parallel)
         omp_set_num_threads(2 * omp_get_num_procs());
-#pragma omp parallel for if (smooth)
+#pragma omp parallel for schedule(static, 1) if (parallel)
     for (long j = 0; j < info.bHeight; j++) {
         T y = T(view.y + T(j) * view.height / info.bHeight);
         long i = 0;

+ 9 - 13
libmandel/src/CpuGeneratorsSSE2.cpp

@@ -9,19 +9,15 @@ using mnd::CpuGenerator;
 
 namespace mnd
 {
-    template class CpuGenerator<float, mnd::X86_SSE2, false, false>;
-    template class CpuGenerator<float, mnd::X86_SSE2, false, true>;
-    template class CpuGenerator<float, mnd::X86_SSE2, true, false>;
-    template class CpuGenerator<float, mnd::X86_SSE2, true, true>;
-
-    template class CpuGenerator<double, mnd::X86_SSE2, false, false>;
-    template class CpuGenerator<double, mnd::X86_SSE2, false, true>;
-    template class CpuGenerator<double, mnd::X86_SSE2, true, false>;
-    template class CpuGenerator<double, mnd::X86_SSE2, true, true>;
+    template class CpuGenerator<float, mnd::X86_SSE2, false>;
+    template class CpuGenerator<float, mnd::X86_SSE2, true>;
+
+    template class CpuGenerator<double, mnd::X86_SSE2, false>;
+    template class CpuGenerator<double, mnd::X86_SSE2, true>;
 }
 
-template<bool parallel, bool smooth>
-void CpuGenerator<float, mnd::X86_SSE2, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<bool parallel>
+void CpuGenerator<float, mnd::X86_SSE2, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     using T = float;
     const MandelViewport& view = info.view;
@@ -81,8 +77,8 @@ void CpuGenerator<float, mnd::X86_SSE2, parallel, smooth>::generate(const mnd::M
 }
 
 
-template<bool parallel, bool smooth>
-void CpuGenerator<double, mnd::X86_SSE2, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
+template<bool parallel>
+void CpuGenerator<double, mnd::X86_SSE2, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
     using T = double;
     const MandelViewport& view = info.view;

+ 25 - 0
libmandel/src/Generators.cpp

@@ -31,6 +31,12 @@ void AdaptiveGenerator::addGenerator(const mnd::Real& precision, mnd::Generator&
 }
 
 
+void AdaptiveGenerator::addGenerator(Precision p, Generator& generator)
+{
+    generators.insert({ getPrecision(p), &generator });
+}
+
+
 void AdaptiveGenerator::generate(const mnd::MandelInfo& info, float* data)
 {
     Real pixelW = info.view.width / info.bWidth;
@@ -69,4 +75,23 @@ void AdaptiveGenerator::generate(const mnd::MandelInfo& info, float* data)
     }*/
 }
 
+namespace mnd
+{
+    Real getPrecision(Precision p)
+    {
+        static const std::map<Precision, Real> precs {
+            { Precision::FLOAT, 1.0e-7 },
+            { Precision::DOUBLE, 1.0e-15 },
+            { Precision::DOUBLE_DOUBLE, Real("1.0e-29") },
+            { Precision::QUAD_DOUBLE, Real("1.0e-56") },
+            { Precision::FLOAT256, Real("1.0e-58") },
+            { Precision::INFINITE, Real(0.0) },
+        };
+
+        return precs.at(p);
+    }
+}
+
+
+
 

+ 80 - 179
libmandel/src/Mandel.cpp

@@ -18,168 +18,113 @@ MandelContext mnd::initializeContext(void)
 }
 
 
-MandelDevice::MandelDevice(void) :
-    floatGenerator{ nullptr },
-    doubleGenerator{ nullptr },
-    floatGeneratorSmooth{ nullptr },
-    doubleGeneratorSmooth{ nullptr }
-
-{
-}
-
-
-mnd::Generator* MandelDevice::getGeneratorFloat(bool smooth) const
-{
-    if (smooth)
-        return floatGeneratorSmooth.get();
-    else
-        return floatGenerator.get();
-}
-
-
-mnd::Generator* MandelDevice::getGeneratorDouble(bool smooth) const
+MandelDevice::MandelDevice(void)
 {
-    if (smooth)
-        return doubleGeneratorSmooth.get();
-    else
-        return doubleGenerator.get();
 }
 
 
-mnd::Generator* MandelDevice::getGeneratorDoubleDouble(bool smooth) const
+mnd::Generator* MandelDevice::getGenerator(mnd::GeneratorType type) const
 {
-    if (smooth)
-        return doubleDoubleGeneratorSmooth.get();
+    auto it = generators.find(type);
+    if (it != generators.end())
+        return it->second.get();
     else
-        return doubleDoubleGenerator.get();
+        return nullptr;
 }
 
 
-/*
-mnd::Generator* MandelDevice::getGeneratorQuad(bool smooth) const
-{
-    if (smooth)
-        return quadGeneratorSmooth.get();
-    else
-        return quadGenerator.get();
-}*/
-
-
-/*
-mnd::Generator* MandelDevice::getGenerator128(bool smooth) const
-{
-    if (smooth)
-        return generator128Smooth.get();
-    else
-        return generator128.get();
-}
-*/
-
-MandelContext::MandelContext(void) :
-    cpuGeneratorQuad{ nullptr },
-    cpuGeneratorQuadSmooth{ nullptr }
+MandelContext::MandelContext(void)
 {
 
 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) 
     if (cpuInfo.hasAvx()) {
-        cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::X86_AVX, true, false>>();
-        cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::X86_AVX, true, false>>();
-        cpuGeneratorFloatSmooth = std::make_unique<CpuGenerator<float, mnd::X86_AVX, true, true>>();
-        //cpuGeneratorDoubleSmooth = std::make_unique<CpuGenerator<double, mnd::X86_AVX, true, true>>();
-        cpuGeneratorDoubleSmooth = std::make_unique<CpuGenerator<double, mnd::NONE, true, true>>();
+        auto fl = std::make_unique<CpuGenerator<float, mnd::X86_AVX, true>>();
+        auto db = std::make_unique<CpuGenerator<double, mnd::X86_AVX, true>>();
+        cpuGenerators.insert({ GeneratorType::FLOAT_AVX, std::move(fl) });
+        cpuGenerators.insert({ GeneratorType::DOUBLE_AVX512, std::move(db) });
     }
     else if (cpuInfo.hasSse2()) {
-        cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::X86_SSE2, true, false>>();
-        cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::X86_SSE2, true, false>>();
-        cpuGeneratorFloatSmooth = std::make_unique<CpuGenerator<float, mnd::X86_SSE2, true, true>>();
-        cpuGeneratorDoubleSmooth = std::make_unique<CpuGenerator<double, mnd::X86_SSE2, true, true>>();
+        auto fl = std::make_unique<CpuGenerator<float, mnd::X86_SSE2, true>>();
+        auto db = std::make_unique<CpuGenerator<double, mnd::X86_SSE2, true>>();
+        cpuGenerators.insert({ GeneratorType::FLOAT_SSE2, std::move(fl) });
+        cpuGenerators.insert({ GeneratorType::DOUBLE_SSE2, std::move(db) });
     }
     else
 #elif defined(__aarch64__)
     if (true) {
-        cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::ARM_NEON, true, false>>();
-        cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::ARM_NEON, true, false>>();
-        cpuGeneratorFloatSmooth = std::make_unique<CpuGenerator<float, mnd::ARM_NEON>>();
-        cpuGeneratorDoubleSmooth = std::make_unique<CpuGenerator<double, mnd::ARM_NEON>>();
+        auto fl = std::make_unique<CpuGenerator<float, mnd::ARM_NEON, true>>();
+        auto db = std::make_unique<CpuGenerator<double, mnd::ARM_NEON, true>>();
+        cpuGenerators.insert({ GeneratorType::FLOAT_NEON, std::move(fl) });
+        cpuGenerators.insert({ GeneratorType::DOUBLE_NEON, std::move(db) });
     }
     else
 #endif
     {
-        cpuGeneratorFloat = std::make_unique<CpuGenerator<float, mnd::NONE, true, false>>();
-        cpuGeneratorDouble = std::make_unique<CpuGenerator<double, mnd::NONE, true, false>>();
-        cpuGeneratorFloatSmooth = std::make_unique<CpuGenerator<float, mnd::NONE, true, true>>();
-        cpuGeneratorDoubleSmooth = std::make_unique<CpuGenerator<double, mnd::NONE, true, true>>();
+        auto fl = std::make_unique<CpuGenerator<float, mnd::NONE, true>>();
+        auto db = std::make_unique<CpuGenerator<double, mnd::NONE, true>>();
+        cpuGenerators.insert({ GeneratorType::FLOAT, std::move(fl) });
+        cpuGenerators.insert({ GeneratorType::DOUBLE, std::move(db) });
     }
 
-    //cpuGenerator128Smooth = std::make_unique<CpuGenerator<Fixed128>>();
-    //cpuGeneratorFixedp = std::make_unique<CpuGenerator<fixed<1, 3>>>();
-
 #ifdef WITH_BOOST
-    cpuGeneratorQuad = std::make_unique<CpuGenerator<Float128, mnd::NONE, true, false>>();
-    cpuGeneratorQuadSmooth = std::make_unique<CpuGenerator<Float128, mnd::NONE, true, true>>();
-    cpuGeneratorOct = std::make_unique<CpuGenerator<Float256, mnd::NONE, true, false>>();
-    //cpuGenerator128 = std::make_unique<CpuGenerator<Fixed128, mnd::NONE, true, false>>();
-    //cpuGenerator128Smooth = std::make_unique<CpuGenerator<Fixed128, mnd::NONE, true, true>>();
+    auto quad = std::make_unique<CpuGenerator<Float128, mnd::NONE, true>>();
+    auto oct = std::make_unique<CpuGenerator<Float256, mnd::NONE, true>>();
+    cpuGenerators.insert({ GeneratorType::FLOAT128, std::move(quad) });
+    cpuGenerators.insert({ GeneratorType::FLOAT256, std::move(oct) });
 #endif // WITH_BOOST
 
 #ifdef WITH_QD
-    cpuGeneratorDD = std::make_unique<CpuGenerator<DoubleDouble, mnd::NONE, true, false>>();
-    cpuGeneratorDDSmooth = std::make_unique<CpuGenerator<DoubleDouble, mnd::NONE, true, true>>();
-    cpuGeneratorQD = std::make_unique<CpuGenerator<QuadDouble, mnd::NONE, true, false>>();
-    cpuGeneratorQDSmooth = std::make_unique<CpuGenerator<QuadDouble, mnd::NONE, true, true>>();
-#endif
+    auto dd = std::make_unique<CpuGenerator<DoubleDouble, mnd::NONE, true>>();
+    auto qd = std::make_unique<CpuGenerator<QuadDouble, mnd::NONE, true>>();
+    cpuGenerators.insert({ GeneratorType::DOUBLE_DOUBLE, std::move(dd) });
+    cpuGenerators.insert({ GeneratorType::DOUBLE_DOUBLE, std::move(qd) });
+#endif // WITH_QD
 
     devices = createDevices();
 
+    adaptiveGenerator = createAdaptiveGenerator();
+}
 
-    adaptiveGenerator = std::make_unique<AdaptiveGenerator>();
-    adaptiveGeneratorSmooth = std::make_unique<AdaptiveGenerator>();
 
-    {
-        auto& device1 = devices[0];
-        Generator* floatGenerator = device1.getGeneratorFloat(false);
-        Generator* doubleGenerator = device1.getGeneratorDouble(false);
-        Generator* doubleDoubleGenerator = device1.getGeneratorDoubleDouble(false);
-        Generator* floatGeneratorSmooth = device1.getGeneratorFloat(true);
-        Generator* doubleGeneratorSmooth = device1.getGeneratorDouble(true);
-        Generator* doubleDoubleGeneratorSmooth = device1.getGeneratorDoubleDouble(true);
-        if (floatGenerator != nullptr)
-            adaptiveGenerator->addGenerator(1.0e-7, *floatGenerator);
-        else
-            adaptiveGenerator->addGenerator(1.0e-7, *cpuGeneratorFloat);
-
-        if (doubleGenerator != nullptr)
-            adaptiveGenerator->addGenerator(0.5e-15, *doubleGenerator);
-        else
-            adaptiveGenerator->addGenerator(0.5e-15, *cpuGeneratorDouble);
-
-        if (floatGeneratorSmooth != nullptr)
-            adaptiveGeneratorSmooth->addGenerator(1.0e-7, *floatGeneratorSmooth);
-        else
-            adaptiveGeneratorSmooth->addGenerator(1.0e-7, *cpuGeneratorFloatSmooth);
-
-        if (doubleGeneratorSmooth != nullptr)
-            adaptiveGeneratorSmooth->addGenerator(0.5e-15, *doubleGeneratorSmooth);
-        else
-            adaptiveGeneratorSmooth->addGenerator(0.5e-15, *cpuGeneratorDoubleSmooth);
-
-        if (doubleDoubleGenerator != nullptr)
-            adaptiveGenerator->addGenerator(Real("1.0e-29"), *doubleDoubleGenerator);
-        if (doubleDoubleGeneratorSmooth != nullptr)
-            adaptiveGeneratorSmooth->addGenerator(Real("1.0e-29"), *doubleDoubleGeneratorSmooth);
+std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(void)
+{
+    auto* floatGen = getCpuGenerator(GeneratorType::FLOAT);
+    auto* doubleGen = getCpuGenerator(GeneratorType::DOUBLE);
+    auto* doubleDoubleGen = getCpuGenerator(GeneratorType::DOUBLE_DOUBLE);
+    auto* quadDoubleGen = getCpuGenerator(GeneratorType::QUAD_DOUBLE);
+    auto* f256Gen = getCpuGenerator(GeneratorType::FLOAT256);
 
+    if (cpuInfo.hasAvx()) {
+        floatGen = getCpuGenerator(GeneratorType::FLOAT_AVX);
+        doubleGen = getCpuGenerator(GeneratorType::DOUBLE_AVX);
+    }
+    else if (cpuInfo.hasSse2()) {
+        floatGen = getCpuGenerator(GeneratorType::FLOAT_SSE2);
+        doubleGen = getCpuGenerator(GeneratorType::DOUBLE_SSE2);
     }
 
-#ifdef WITH_QD
-        adaptiveGenerator->addGenerator(Real("1.0e-29"), *cpuGeneratorDD);
-        adaptiveGeneratorSmooth->addGenerator(Real("1.0e-29"), *cpuGeneratorDDSmooth);
-        adaptiveGenerator->addGenerator(Real("1.0e-57"), *cpuGeneratorQD);
-        adaptiveGeneratorSmooth->addGenerator(Real("1.0e-57"), *cpuGeneratorQDSmooth);
-#endif
-#ifdef WITH_BOOST
-        //adaptiveGenerator->addGenerator(1.0e-28, *cpuGeneratorQuad);
-        //adaptiveGeneratorSmooth->addGenerator(1.0e-28, *cpuGeneratorQuadSmooth);
-#endif
+    if (!devices.empty()) {
+        auto& device = devices[0];
+        auto* fGen = device.getGenerator(GeneratorType::FLOAT);
+        auto* dGen = device.getGenerator(GeneratorType::DOUBLE);
+        auto* ddGen = device.getGenerator(GeneratorType::DOUBLE_DOUBLE);
+
+        if (fGen)
+            floatGen = fGen;
+        if (dGen)
+            doubleGen = dGen;
+        if (ddGen)
+            doubleDoubleGen = ddGen;
+    }
+
+    auto ag = std::make_unique<AdaptiveGenerator>();
+    ag->addGenerator(Precision::FLOAT, *floatGen);
+    ag->addGenerator(Precision::DOUBLE, *doubleGen);
+    ag->addGenerator(Precision::DOUBLE_DOUBLE, *doubleDoubleGen);
+    ag->addGenerator(Precision::QUAD_DOUBLE, *quadDoubleGen);
+    ag->addGenerator(Precision::FLOAT256, *f256Gen);
+
+    return ag;
 }
 
 
@@ -217,8 +162,7 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
             md.name = device.getInfo<CL_DEVICE_NAME>();
             md.vendor = device.getInfo<CL_DEVICE_VENDOR>();
             try {
-                md.floatGenerator = std::make_unique<ClGeneratorFloat>(device, false);
-                md.floatGeneratorSmooth = std::make_unique<ClGeneratorFloat>(device, true);
+                md.generators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(device) });
             }
             catch (const std::string& err) {
                 printf("err: %s", err.c_str());
@@ -226,10 +170,8 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
 
             if (supportsDouble) {
                 try {
-                    md.doubleGenerator = std::make_unique<ClGeneratorDouble>(device, false);
-                    md.doubleGeneratorSmooth = std::make_unique<ClGeneratorDouble>(device, true);
-                    md.doubleDoubleGenerator = std::make_unique<ClGeneratorDoubleDouble>(device, false);
-                    md.doubleDoubleGeneratorSmooth = std::make_unique<ClGeneratorDoubleDouble>(device, true);
+                    md.generators.insert({ GeneratorType::DOUBLE, std::make_unique<ClGeneratorDouble>(device) });
+                    md.generators.insert({ GeneratorType::DOUBLE_DOUBLE, std::make_unique<ClGeneratorDoubleDouble>(device) });
                 }
                 catch (const std::string& err) {
                     printf("err: %s", err.c_str());
@@ -253,18 +195,9 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
 }
 
 
-const std::string& MandelDevice::getName(void) const
-{
-    return name;
-}
-
-
 Generator& MandelContext::getDefaultGenerator(bool smooth)
 {
-    if (smooth)
-        return *adaptiveGeneratorSmooth;
-    else
-        return *adaptiveGenerator;
+    return *adaptiveGenerator;
 }
 
 
@@ -274,43 +207,11 @@ const std::vector<MandelDevice>& MandelContext::getDevices(void)
 }
 
 
-Generator& MandelContext::getCpuGeneratorFloat(void)
-{
-    return *cpuGeneratorFloat;
-}
-
-
-Generator& MandelContext::getCpuGeneratorDouble(void)
-{
-    return *cpuGeneratorDouble;
-}
-
-
-Generator* MandelContext::getCpuGeneratorQuad(void)
-{
-    return cpuGeneratorQuad.get();
-}
-
-
-Generator* MandelContext::getCpuGeneratorOct(void)
-{
-    return cpuGeneratorOct.get();
-}
-
-
-Generator* MandelContext::getCpuGenerator128(void)
-{
-    return cpuGenerator128.get();
-}
-
-
-Generator* MandelContext::getCpuGeneratorDD(void)
-{
-    return cpuGeneratorDD.get();
-}
-
-
-Generator* MandelContext::getCpuGeneratorQD(void)
+Generator* MandelContext::getCpuGenerator(mnd::GeneratorType type)
 {
-    return cpuGeneratorQD.get();
+    auto it = cpuGenerators.find(type);
+    if (it != cpuGenerators.end())
+        return it->second.get();
+    else
+        return nullptr;
 }

+ 42 - 0
libmandel/src/Types.cpp

@@ -17,5 +17,47 @@ namespace mnd
         return ss.str();
     }
 #endif // WITH_BOOST
+
+
+/*
+    template<>
+    constexpr Real precision<float>(void)
+    {
+        return 1.0e-7;
+    }
+
+    template<>
+    constexpr Real precision<double>(void)
+    {
+        return 1.0e-15;
+    }
+
+#ifdef WITH_QD
+    template<>
+    constexpr Real precision<DoubleDouble>(void)
+    {
+        return Real("1.0e-29");
+    }
+
+    template<>
+    constexpr Real precision<QuadDouble>(void)
+    {
+        return Real("1.0e-57");
+    }
+#endif // WITH_QD
+#ifdef WITH_BOOST
+    template<>
+    constexpr Real precision<Float128>(void)
+    {
+        return Real("1.0e-29");
+    }
+
+    template<>
+    constexpr Real precision<Float256>(void)
+    {
+        return Real("1.0e-60");
+    }
+#endif // WITH_BOOST
+*/
 }