1
0
Prechádzať zdrojové kódy

Added Triple Doubles for cpu and gpu #4 avx not yet

Nicolas Winkler 4 rokov pred
rodič
commit
d1257a8481

+ 14 - 0
libmandel/include/ClGenerators.h

@@ -25,6 +25,7 @@ namespace mnd
     class ClGeneratorDoubleFloat;
     class ClGeneratorDouble;
     class ClGeneratorDoubleDouble;
+    class ClGeneratorTripleDouble;
     class ClGeneratorQuadDouble;
     class ClGenerator128;
     class ClGenerator64;
@@ -98,6 +99,19 @@ protected:
 };
 
 
+class mnd::ClGeneratorTripleDouble : public ClGenerator
+{
+    bool smooth;
+public:
+    ClGeneratorTripleDouble(mnd::MandelDevice& device);
+    virtual ~ClGeneratorTripleDouble(void) = default;
+
+    virtual void generate(const MandelInfo& info, float* data) override;
+protected:
+    virtual std::string getKernelCode(bool smooth) const;
+};
+
+
 class mnd::ClGeneratorQuadDouble : public ClGenerator
 {
     bool smooth;

+ 1 - 0
libmandel/include/OpenClCode.h

@@ -9,6 +9,7 @@ namespace mnd
     std::string getDouble_cl();
     std::string getDoubleFloat_cl();
     std::string getDoubleDouble_cl();
+    std::string getTripleDouble_cl();
     std::string getQuadDouble_cl();
     std::string getFixed64_cl();
     std::string getFixed128_cl();

+ 58 - 0
libmandel/src/ClGenerators.cpp

@@ -17,6 +17,7 @@ using mnd::ClGeneratorFloat;
 using mnd::ClGeneratorDoubleFloat;
 using mnd::ClGeneratorDouble;
 using mnd::ClGeneratorDoubleDouble;
+using mnd::ClGeneratorTripleDouble;
 using mnd::ClGeneratorQuadDouble;
 using mnd::ClGenerator128;
 using mnd::ClGenerator64;
@@ -382,6 +383,63 @@ std::string ClGeneratorDoubleDouble::getKernelCode(bool smooth) const
 }
 
 
+ClGeneratorTripleDouble::ClGeneratorTripleDouble(mnd::MandelDevice& device) :
+    ClGenerator{ device, getTripleDouble_cl(), mnd::Precision::TRIPLE_DOUBLE }
+{
+    kernel = Kernel(program, "iterate");
+}
+
+
+void ClGeneratorTripleDouble::generate(const mnd::MandelInfo& info, float* data)
+{
+    ::size_t bufferSize = info.bWidth * info.bHeight * sizeof(float);
+
+    Buffer buffer_A(context, CL_MEM_WRITE_ONLY, bufferSize);
+
+    mnd::TripleDouble x = mnd::convert<mnd::TripleDouble>(info.view.x);
+    mnd::TripleDouble y = mnd::convert<mnd::TripleDouble>(info.view.y);
+
+    mnd::TripleDouble psx = mnd::convert<mnd::TripleDouble>(info.view.width / info.bWidth);
+    mnd::TripleDouble psy = mnd::convert<mnd::TripleDouble>(info.view.height / info.bHeight);
+
+    mnd::TripleDouble juliaX = mnd::convert<mnd::TripleDouble>(info.juliaX);
+    mnd::TripleDouble juliaY = mnd::convert<mnd::TripleDouble>(info.juliaY);
+
+    kernel.setArg(0, buffer_A);
+    kernel.setArg(1, int(info.bWidth));
+    kernel.setArg(2, x.x[0]);
+    kernel.setArg(3, x.x[1]);
+    kernel.setArg(4, x.x[2]);
+    kernel.setArg(5, y.x[0]);
+    kernel.setArg(6, y.x[1]);
+    kernel.setArg(7, y.x[2]);
+    kernel.setArg(8, psx.x[0]);
+    kernel.setArg(9, psx.x[1]);
+    kernel.setArg(10, psx.x[2]);
+    kernel.setArg(11, psy.x[0]);
+    kernel.setArg(12, psy.x[1]);
+    kernel.setArg(13, psy.x[2]);
+    kernel.setArg(14, int(info.maxIter));
+    kernel.setArg(15, int(info.smooth ? 1 : 0));
+    kernel.setArg(16, info.julia ? 1 : 0);
+    kernel.setArg(17, juliaX.x[0]);
+    kernel.setArg(18, juliaX.x[1]);
+    kernel.setArg(19, juliaX.x[2]);
+    kernel.setArg(20, juliaY.x[0]);
+    kernel.setArg(21, juliaY.x[1]);
+    kernel.setArg(22, juliaY.x[2]);
+
+    cl_int result = queue.enqueueNDRangeKernel(kernel, 0, NDRange(info.bWidth * info.bHeight));
+    queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
+}
+
+
+std::string ClGeneratorTripleDouble::getKernelCode(bool smooth) const
+{
+    return getTripleDouble_cl();
+}
+
+
 ClGeneratorQuadDouble::ClGeneratorQuadDouble(mnd::MandelDevice& device) :
     ClGenerator{ device, getQuadDouble_cl(), mnd::Precision::QUAD_DOUBLE }
 {

+ 2 - 2
libmandel/src/Generators.cpp

@@ -174,7 +174,7 @@ namespace mnd
             { Precision::DOUBLE_FLOAT, Real("4.0e-15") },
             { Precision::DOUBLE, getPrecision<double>() },
             { Precision::DOUBLE_DOUBLE, Real("1.0e-29") },
-            { Precision::TRIPLE_DOUBLE, Real("1.0e-45") },
+            { Precision::TRIPLE_DOUBLE, Real("1.0e-47") },
             { Precision::QUAD_DOUBLE, Real("1.0e-56") },
             { Precision::FIXED64, Real("3.5e-15") },
             { Precision::FIXED128, Real("1.317e-29") },
@@ -247,7 +247,7 @@ namespace mnd
     }
     template<>
     Real getPrecision<TripleDouble>() {
-        return Real("1.0e-46");
+        return Real("1.0e-47");
     }
     template<>
     Real getPrecision<QuadDouble>() {

+ 6 - 0
libmandel/src/Mandel.cpp

@@ -210,6 +210,7 @@ std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(v
     auto* floatGen = getCpuGenerator(GeneratorType::FLOAT);
     auto* doubleGen = getCpuGenerator(GeneratorType::DOUBLE);
     auto* doubleDoubleGen = getCpuGenerator(GeneratorType::DOUBLE_DOUBLE);
+    auto* tripleDoubleGen = getCpuGenerator(GeneratorType::TRIPLE_DOUBLE);
     auto* quadDoubleGen = getCpuGenerator(GeneratorType::QUAD_DOUBLE);
     auto* f256Gen = getCpuGenerator(GeneratorType::FLOAT256);
     auto* fix512 = getCpuGenerator(GeneratorType::FIXED512);
@@ -244,6 +245,7 @@ std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(v
         auto* fGen = device->getGenerator(GeneratorType::FLOAT);
         auto* dGen = device->getGenerator(GeneratorType::DOUBLE);
         auto* ddGen = device->getGenerator(GeneratorType::DOUBLE_DOUBLE);
+        auto* tdGen = device->getGenerator(GeneratorType::TRIPLE_DOUBLE);
         auto* qdGen = device->getGenerator(GeneratorType::QUAD_DOUBLE);
 
         if (fGen)
@@ -252,6 +254,8 @@ std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(v
             doubleGen = dGen;
         if (ddGen)
             doubleDoubleGen = ddGen;
+        if (tdGen)
+            tripleDoubleGen = tdGen;
         if (qdGen)
             quadDoubleGen = qdGen;
     }
@@ -260,6 +264,7 @@ std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(v
     ag->addGenerator(getPrecision<float>(), *floatGen);
     ag->addGenerator(getPrecision<double>(), *doubleGen);
     ag->addGenerator(getPrecision<DoubleDouble>(), *doubleDoubleGen);
+    ag->addGenerator(getPrecision<TripleDouble>(), *tripleDoubleGen);
     ag->addGenerator(getPrecision<QuadDouble>(), *quadDoubleGen);
     ag->addGenerator(getPrecision<Float256>(), *f256Gen);
     ag->addGenerator(Precision::INF_PREC, *fix512);
@@ -330,6 +335,7 @@ std::vector<std::unique_ptr<MandelDevice>> MandelContext::createDevices(void)
                 try {
                     md.mandelGenerators.insert({ GeneratorType::DOUBLE, std::make_unique<ClGeneratorDouble>(md) });
                     md.mandelGenerators.insert({ GeneratorType::DOUBLE_DOUBLE, std::make_unique<ClGeneratorDoubleDouble>(md) });
+                    md.mandelGenerators.insert({ GeneratorType::TRIPLE_DOUBLE, std::make_unique<ClGeneratorTripleDouble>(md) });
                     md.mandelGenerators.insert({ GeneratorType::QUAD_DOUBLE, std::make_unique<ClGeneratorQuadDouble>(md) });
                 }
                 catch (const std::string& err) {

+ 5 - 0
libmandel/src/OpenClCode.cpp

@@ -4,6 +4,7 @@
 #include "opencl/double.h"
 #include "opencl/doublefloat.h"
 #include "opencl/doubledouble.h"
+#include "opencl/tripledouble.h"
 #include "opencl/quaddouble.h"
 
 #include "opencl/fixed64.h"
@@ -28,6 +29,10 @@ namespace mnd
         return std::string{ (char*) doubledouble_cl, doubledouble_cl_len };
     }
 
+    std::string getTripleDouble_cl() {
+        return std::string{ (char*) tripledouble_cl, tripledouble_cl_len };
+    }
+
     std::string getQuadDouble_cl() {
         return std::string{ (char*) quaddouble_cl, quaddouble_cl_len };
     }