|
@@ -1,10 +1,10 @@
|
|
#include "IterationCompiler.h"
|
|
#include "IterationCompiler.h"
|
|
|
|
|
|
|
|
+#include "ExecData.h"
|
|
#include "Mandel.h"
|
|
#include "Mandel.h"
|
|
#include "OpenClInternal.h"
|
|
#include "OpenClInternal.h"
|
|
#include "OpenClCode.h"
|
|
#include "OpenClCode.h"
|
|
|
|
|
|
-#include <asmjit/asmjit.h>
|
|
|
|
#include <cmath>
|
|
#include <cmath>
|
|
#include <omp.h>
|
|
#include <omp.h>
|
|
#include <any>
|
|
#include <any>
|
|
@@ -13,31 +13,6 @@
|
|
using namespace std::string_literals;
|
|
using namespace std::string_literals;
|
|
namespace mnd
|
|
namespace mnd
|
|
{
|
|
{
|
|
- struct ExecData
|
|
|
|
- {
|
|
|
|
- std::unique_ptr<asmjit::JitRuntime> jitRuntime;
|
|
|
|
- std::unique_ptr<asmjit::CodeHolder> code;
|
|
|
|
- std::unique_ptr<asmjit::x86::Compiler> compiler;
|
|
|
|
- void* iterationFunc;
|
|
|
|
-
|
|
|
|
- ExecData(void) :
|
|
|
|
- jitRuntime{ std::make_unique<asmjit::JitRuntime>() },
|
|
|
|
- code{ std::make_unique<asmjit::CodeHolder>() },
|
|
|
|
- compiler{ nullptr },
|
|
|
|
- iterationFunc{ nullptr }
|
|
|
|
- {
|
|
|
|
- code->init(jitRuntime->codeInfo());
|
|
|
|
- compiler = std::make_unique<asmjit::x86::Compiler>(code.get());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ExecData(ExecData&&) = default;
|
|
|
|
- ExecData(const ExecData&) = delete;
|
|
|
|
- ExecData& operator=(ExecData&&) = default;
|
|
|
|
- ExecData& operator=(const ExecData&) = delete;
|
|
|
|
-
|
|
|
|
- ~ExecData(void) = default;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
|
|
|
|
struct CompileVisitor
|
|
struct CompileVisitor
|
|
{
|
|
{
|
|
@@ -413,123 +388,6 @@ namespace mnd
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-using mnd::CompiledGenerator;
|
|
|
|
-using mnd::CompiledClGenerator;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-CompiledGenerator::CompiledGenerator(mnd::MandelContext& mndContext) :
|
|
|
|
- MandelGenerator{ 1.0e-15 },
|
|
|
|
- execData{ std::make_unique<ExecData>(compile(mndContext)) }
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-CompiledGenerator::CompiledGenerator(std::unique_ptr<mnd::ExecData> execData) :
|
|
|
|
- MandelGenerator{ 1.0e-15 },
|
|
|
|
- execData{ std::move(execData) }
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-CompiledGenerator::CompiledGenerator(CompiledGenerator&&) = default;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-CompiledGenerator::~CompiledGenerator(void)
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/*__declspec(noinline)
|
|
|
|
-int iter(double x, double y, int maxIter)
|
|
|
|
-{
|
|
|
|
- int k = 0;
|
|
|
|
-
|
|
|
|
- double a = x;
|
|
|
|
- double b = y;
|
|
|
|
-
|
|
|
|
- for (k = 0; k < maxIter; k++) {
|
|
|
|
- double aa = a * a;
|
|
|
|
- double bb = b * b;
|
|
|
|
- double abab = a * b + a * b;
|
|
|
|
- a = aa - bb + x;
|
|
|
|
- b = abab + y;
|
|
|
|
- if (aa + bb >= 16)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return k;
|
|
|
|
-}*/
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-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)
|
|
|
|
- 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++) {
|
|
|
|
- double x = mnd::convert<double>(info.view.x + info.view.width * j / info.bWidth);
|
|
|
|
- IterFunc iterFunc = asmjit::ptr_as_func<IterFunc>(this->execData->iterationFunc);
|
|
|
|
- int k = iterFunc(x, y, info.maxIter);
|
|
|
|
- data[i * info.bWidth + j] = k;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-std::string CompiledGenerator::dump(void) const
|
|
|
|
-{
|
|
|
|
- asmjit::String d;
|
|
|
|
- execData->compiler->dump(d);
|
|
|
|
- return d.data();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-#ifdef WITH_OPENCL
|
|
|
|
-CompiledClGenerator::CompiledClGenerator(const mnd::MandelDevice& device, const std::string& code) :
|
|
|
|
- ClGeneratorFloat{ device.getClDevice().device, code }
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-std::string CompiledClGenerator::getKernelCode(bool smooth) const
|
|
|
|
-{
|
|
|
|
- return "";
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void CompiledClGenerator::generate(const mnd::MandelInfo& info, float* data)
|
|
|
|
-{
|
|
|
|
- ::size_t bufferSize = info.bWidth * info.bHeight * sizeof(float);
|
|
|
|
-
|
|
|
|
- cl::Buffer buffer_A(context, CL_MEM_WRITE_ONLY, bufferSize);
|
|
|
|
- float pixelScaleX = float(info.view.width / info.bWidth);
|
|
|
|
- float pixelScaleY = float(info.view.height / info.bHeight);
|
|
|
|
-
|
|
|
|
- static cl::Kernel iterate = cl::Kernel(program, "iterate");
|
|
|
|
- iterate.setArg(0, buffer_A);
|
|
|
|
- iterate.setArg(1, int(info.bWidth));
|
|
|
|
- iterate.setArg(2, float(info.view.x));
|
|
|
|
- iterate.setArg(3, float(info.view.y));
|
|
|
|
- iterate.setArg(4, float(pixelScaleX));
|
|
|
|
- iterate.setArg(5, float(pixelScaleY));
|
|
|
|
- iterate.setArg(6, int(info.maxIter));
|
|
|
|
- iterate.setArg(7, int(info.smooth ? 1 : 0));
|
|
|
|
- iterate.setArg(8, int(info.julia ? 1 : 0));
|
|
|
|
- iterate.setArg(9, float(info.juliaX));
|
|
|
|
- iterate.setArg(10, float(info.juliaY));
|
|
|
|
-
|
|
|
|
- queue.enqueueNDRangeKernel(iterate, 0, cl::NDRange(info.bWidth * info.bHeight));
|
|
|
|
-
|
|
|
|
- queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#endif // WITH_OPENCL
|
|
|
|
-
|
|
|
|
using namespace asmjit;
|
|
using namespace asmjit;
|
|
|
|
|
|
struct Visitor
|
|
struct Visitor
|