瀏覽代碼

improving compilation

Nicolas Winkler 5 年之前
父節點
當前提交
acfcd4ec4b

+ 9 - 9
libmandel/include/ClGenerators.h

@@ -29,13 +29,13 @@ namespace mnd
 class mnd::ClGenerator : public MandelGenerator
 {
 protected:
-    const MandelDevice& device;
+    MandelDevice& device;
     cl::Context& context;
     cl::Program program;
     cl::CommandQueue queue;
     cl::Kernel kernel;
 public:
-    ClGenerator(const MandelDevice& device, const std::string& source, const mnd::Real& precision);
+    ClGenerator(MandelDevice& device, const std::string& source, const mnd::Real& precision);
     virtual ~ClGenerator(void);
 
     virtual void generate(const MandelInfo& info, float* data) = 0;
@@ -46,7 +46,7 @@ class mnd::ClGeneratorFloat : public ClGenerator
 {
     bool useVec;
 public:
-    ClGeneratorFloat(cl::Device device, const std::string& code);
+    ClGeneratorFloat(MandelDevice& device, const std::string& code);
     virtual ~ClGeneratorFloat(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;
@@ -58,7 +58,7 @@ protected:
 class mnd::ClGeneratorDoubleFloat : public ClGenerator
 {
 public:
-    ClGeneratorDoubleFloat(cl::Device device);
+    ClGeneratorDoubleFloat(MandelDevice& device);
     virtual ~ClGeneratorDoubleFloat(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;
@@ -70,7 +70,7 @@ protected:
 class mnd::ClGeneratorDouble : public ClGenerator
 {
 public:
-    ClGeneratorDouble(cl::Device device);
+    ClGeneratorDouble(mnd::MandelDevice& device);
     virtual ~ClGeneratorDouble(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;
@@ -83,7 +83,7 @@ class mnd::ClGeneratorDoubleDouble : public ClGenerator
 {
     bool smooth;
 public:
-    ClGeneratorDoubleDouble(cl::Device device);
+    ClGeneratorDoubleDouble(mnd::MandelDevice& device);
     virtual ~ClGeneratorDoubleDouble(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;
@@ -96,7 +96,7 @@ class mnd::ClGeneratorQuadDouble : public ClGenerator
 {
     bool smooth;
 public:
-    ClGeneratorQuadDouble(cl::Device device);
+    ClGeneratorQuadDouble(mnd::MandelDevice& device);
     virtual ~ClGeneratorQuadDouble(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;
@@ -108,7 +108,7 @@ protected:
 class mnd::ClGenerator128 : public ClGenerator
 {
 public:
-    ClGenerator128(cl::Device device);
+    ClGenerator128(mnd::MandelDevice& device);
     virtual ~ClGenerator128(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;
@@ -120,7 +120,7 @@ protected:
 class mnd::ClGenerator64 : public ClGenerator
 {
 public:
-    ClGenerator64(cl::Device device);
+    ClGenerator64(mnd::MandelDevice& device);
     virtual ~ClGenerator64(void) = default;
 
     virtual void generate(const MandelInfo& info, float* data) override;

+ 2 - 2
libmandel/include/IterationCompiler.h

@@ -24,7 +24,7 @@ namespace mnd
         const IterationFormula& z0,
         const IterationFormula& zi);
 
-    std::vector<std::unique_ptr<mnd::MandelGenerator>> compileOpenCl(const mnd::MandelDevice& dev,
+    std::vector<std::unique_ptr<mnd::MandelGenerator>> compileOpenCl(mnd::MandelDevice& dev,
         const IterationFormula& z0,
         const IterationFormula& zi);
 }
@@ -35,7 +35,7 @@ namespace mnd
 namespace mnd
 {
     CompiledGenerator compile(const ir::Formula& formula);
-    std::unique_ptr<MandelGenerator> compileCl(const ir::Formula& formula, const MandelDevice& md);
+    std::unique_ptr<MandelGenerator> compileCl(const ir::Formula& formula, MandelDevice& md);
 }
 
 

+ 4 - 3
libmandel/include/IterationGenerator.h

@@ -19,6 +19,7 @@ namespace mnd
     class NaiveIRGenerator;
     class CompiledGenerator;
     class CompiledClGenerator;
+    class CompiledClGeneratorDouble;
 
     // forward declaration
     struct ExecData;
@@ -81,7 +82,7 @@ public:
 class mnd::CompiledClGenerator : public mnd::ClGeneratorFloat
 {
 public:
-    CompiledClGenerator(const MandelDevice& device, const std::string& code);
+    CompiledClGenerator(MandelDevice& device, const std::string& code);
     CompiledClGenerator(CompiledClGenerator&&) = default;
     virtual void generate(const MandelInfo& info, float* data);
 };
@@ -89,8 +90,8 @@ public:
 class mnd::CompiledClGeneratorDouble : public mnd::ClGeneratorDouble
 {
 public:
-    CompiledClGeneratorDouble(const MandelDevice& device, const std::string& code);
-    CompiledClGenerator(CompiledClGenerator&&) = default;
+    CompiledClGeneratorDouble(MandelDevice& device, const std::string& code);
+    CompiledClGeneratorDouble(CompiledClGeneratorDouble&&) = default;
     virtual void generate(const MandelInfo& info, float* data);
 };
 #endif // WITH_OPENCL

+ 1 - 0
libmandel/include/Mandel.h

@@ -83,6 +83,7 @@ public:
     inline const std::string& getName(void) const { return name; }
 
     MandelGenerator* getGenerator(GeneratorType type) const;
+    inline ClDeviceWrapper& getClDevice(void) { return *clDevice; }
     inline const ClDeviceWrapper& getClDevice(void) const { return *clDevice; }
 
     std::vector<GeneratorType> getSupportedTypes(void) const;

+ 14 - 12
libmandel/src/ClGenerators.cpp

@@ -61,21 +61,22 @@ Device getDevice(Platform& platform, int i, bool display = false) {
 }
 
 
-ClGenerator::ClGenerator(const MandelDevice& device, const std::string& source, const mnd::Real& precision) :
+ClGenerator::ClGenerator(MandelDevice& device, const std::string& source, const mnd::Real& precision) :
     MandelGenerator{ precision },
     device{ device },
     context{ device.getClDevice().context }
 {
     Program::Sources sources;
+    const cl::Device& dev = device.getClDevice().device;
 
     sources.push_back({ source.c_str(), source.length() });
 
     program = Program{ context, sources };
-    if (program.build({ device }) != CL_SUCCESS) {
-        throw std::string(program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device));
+    if (program.build({ dev }) != CL_SUCCESS) {
+        throw std::string(program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev));
     }
 
-    queue = CommandQueue(context, device);
+    queue = CommandQueue(context, dev);
 
     /*Platform p = getPlatform();
     device = getDevice(p, 0, true);
@@ -103,10 +104,11 @@ ClGenerator::~ClGenerator(void)
 }
 
 
-ClGeneratorFloat::ClGeneratorFloat(cl::Device device, const std::string& code) :
+ClGeneratorFloat::ClGeneratorFloat(mnd::MandelDevice& device, const std::string& code) :
     ClGenerator{ device, code, mnd::getPrecision<float>() }
 {
-    useVec = device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT>() >= 4;
+    const cl::Device& dev = device.getClDevice().device;
+    useVec = dev.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT>() >= 4;
     kernel = Kernel(program, useVec ? "iterate_vec4" : "iterate");
 }
 
@@ -148,7 +150,7 @@ std::string ClGeneratorFloat::getKernelCode(bool smooth) const
 }
 
 
-ClGeneratorDoubleFloat::ClGeneratorDoubleFloat(cl::Device device) :
+ClGeneratorDoubleFloat::ClGeneratorDoubleFloat(mnd::MandelDevice& device) :
     ClGenerator{ device, this->getKernelCode(false), mnd::getPrecision(mnd::Precision::DOUBLE_FLOAT)  }
 {
     kernel = Kernel(program, "iterate");
@@ -299,7 +301,7 @@ std::string ClGeneratorDoubleFloat::getKernelCode(bool smooth) const
 }
 
 
-ClGeneratorDouble::ClGeneratorDouble(cl::Device device) :
+ClGeneratorDouble::ClGeneratorDouble(mnd::MandelDevice& device) :
     ClGenerator{ device, getDouble_cl(), mnd::getPrecision<double>() }
 {
     kernel = Kernel(program, "iterate");
@@ -367,7 +369,7 @@ std::string ClGeneratorDouble::getKernelCode(bool smooth) const
 }
 
 
-ClGeneratorDoubleDouble::ClGeneratorDoubleDouble(cl::Device device) :
+ClGeneratorDoubleDouble::ClGeneratorDoubleDouble(mnd::MandelDevice& device) :
     ClGenerator{ device, getDoubleDouble_cl(), mnd::getPrecision<DoubleDouble>() }
 {
     kernel = Kernel(program, "iterate");
@@ -410,7 +412,7 @@ std::string ClGeneratorDoubleDouble::getKernelCode(bool smooth) const
 }
 
 
-ClGeneratorQuadDouble::ClGeneratorQuadDouble(cl::Device device) :
+ClGeneratorQuadDouble::ClGeneratorQuadDouble(mnd::MandelDevice& device) :
     ClGenerator{ device, getQuadDouble_cl(), mnd::getPrecision<QuadDouble>() }
 {
     kernel = Kernel(program, "iterate");
@@ -462,7 +464,7 @@ std::string ClGeneratorQuadDouble::getKernelCode(bool smooth) const
 }
 
 
-ClGenerator128::ClGenerator128(cl::Device device) :
+ClGenerator128::ClGenerator128(mnd::MandelDevice& device) :
     ClGenerator{ device, getFixed512_cl(), mnd::getPrecision<Fixed128>() }
 {
     kernel = Kernel(program, "iterate");
@@ -517,7 +519,7 @@ std::string ClGenerator128::getKernelCode(bool smooth) const
 }
 
 
-ClGenerator64::ClGenerator64(cl::Device device) :
+ClGenerator64::ClGenerator64(mnd::MandelDevice& device) :
     ClGenerator{ device, getFixed64_cl(), mnd::getPrecision<Fixed64>() }
 {
     kernel = Kernel(program, "iterate");

+ 2 - 2
libmandel/src/IterationCompiler.cpp

@@ -420,7 +420,7 @@ namespace mnd
     }
 
 #ifdef WITH_OPENCL
-    std::unique_ptr<MandelGenerator> compileCl(const ir::Formula& formula, const MandelDevice& md)
+    std::unique_ptr<MandelGenerator> compileCl(const ir::Formula& formula, MandelDevice& md)
     {
         return std::make_unique<CompiledClGenerator>(md, compileToOpenCl(formula));
     }
@@ -452,7 +452,7 @@ namespace mnd
         return vec;
     }
 
-    std::vector<std::unique_ptr<mnd::MandelGenerator>> compileOpenCl(const mnd::MandelDevice& dev,
+    std::vector<std::unique_ptr<mnd::MandelGenerator>> compileOpenCl(mnd::MandelDevice& dev,
         const IterationFormula& z0,
         const IterationFormula& zi)
     {

+ 11 - 4
libmandel/src/IterationGenerator.cpp

@@ -143,8 +143,8 @@ NaiveIRGenerator<T>::NaiveIRGenerator(const mnd::ir::Formula& irf,
 }
 
 
-template<typename T>
-void NaiveIRGenerator<T>::generate(const mnd::MandelInfo& info, float* data)
+template<typename U>
+void NaiveIRGenerator<U>::generate(const mnd::MandelInfo& info, float* data)
 {
     const MandelViewport& view = info.view;
 
@@ -261,6 +261,7 @@ double NaiveIRGenerator<T>::calc(mnd::ir::Node* expr, double a, double b, double
 
 using mnd::CompiledGenerator;
 using mnd::CompiledClGenerator;
+using mnd::CompiledClGeneratorDouble;
 
 
 CompiledGenerator::CompiledGenerator(std::unique_ptr<mnd::ExecData> execData) :
@@ -328,8 +329,8 @@ std::string CompiledGenerator::dump(void) const
 
 
 #ifdef WITH_OPENCL
-CompiledClGenerator::CompiledClGenerator(const mnd::MandelDevice& device, const std::string& code) :
-    ClGeneratorFloat{ device.getClDevice().device, code }
+CompiledClGenerator::CompiledClGenerator(mnd::MandelDevice& device, const std::string& code) :
+    ClGeneratorFloat{ device, code }
 {
 }
 
@@ -360,6 +361,12 @@ void CompiledClGenerator::generate(const mnd::MandelInfo& info, float* data)
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
 }
 
+
+CompiledClGeneratorDouble::CompiledClGeneratorDouble(mnd::MandelDevice& device, const std::string& code) :
+    ClGeneratorDouble{ device }
+{
+}
+
 #endif // WITH_OPENCL
 
 

+ 4 - 0
libmandel/src/IterationIR.cpp

@@ -368,6 +368,10 @@ struct ConstantPropagator
         else if (cb && cb->value == 0) {
             return *n.left;
         }
+        else if (cb) {
+            // move constants to the left
+            std::swap(n.left, n.right);
+        }
         else if (auto* nright = std::get_if<ir::Negation>(n.right)) {
             return ir::Subtraction{ n.left, nright->value };
         }

+ 6 - 6
libmandel/src/Mandel.cpp

@@ -278,9 +278,9 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
             md.vendor = device.getInfo<CL_DEVICE_VENDOR>();
             //printf("    using opencl device: %s\n", md.name.c_str());
             try {
-                md.mandelGenerators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(device, mnd::getFloat_cl()) });
-                md.mandelGenerators.insert({ GeneratorType::FIXED64, std::make_unique<ClGenerator64>(device) });
-                md.mandelGenerators.insert({ GeneratorType::DOUBLE_FLOAT, std::make_unique<ClGeneratorDoubleFloat>(device) });
+                md.mandelGenerators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(md, mnd::getFloat_cl()) });
+                md.mandelGenerators.insert({ GeneratorType::FIXED64, std::make_unique<ClGenerator64>(md) });
+                md.mandelGenerators.insert({ GeneratorType::DOUBLE_FLOAT, std::make_unique<ClGeneratorDoubleFloat>(md) });
             }
             catch (const std::string& err) {
                 printf("err: %s", err.c_str());
@@ -288,9 +288,9 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
 
             if (supportsDouble) {
                 try {
-                    md.mandelGenerators.insert({ GeneratorType::DOUBLE, std::make_unique<ClGeneratorDouble>(device) });
-                    md.mandelGenerators.insert({ GeneratorType::DOUBLE_DOUBLE, std::make_unique<ClGeneratorDoubleDouble>(device) });
-                    md.mandelGenerators.insert({ GeneratorType::QUAD_DOUBLE, std::make_unique<ClGeneratorQuadDouble>(device) });
+                    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::QUAD_DOUBLE, std::make_unique<ClGeneratorQuadDouble>(md) });
                 }
                 catch (const std::string& err) {
                     printf("err: %s", err.c_str());