#ifndef MANDEL_GENERATORS_H #define MANDEL_GENERATORS_H #include "MandelUtil.h" #include #include #include namespace mnd { class MandelGenerator; class AdaptiveGenerator; enum class GeneratorType : int; enum class Precision : int { FLOAT, DOUBLE_FLOAT, DOUBLE, DOUBLE_DOUBLE, TRIPLE_DOUBLE, FLOAT128, FLOAT256, FLOAT512, FIXED64, FIXED128, FIXED512, QUAD_DOUBLE, INF_PREC, }; enum CpuExtension : int { NONE, X86_SSE2, X86_AVX, X86_AVX_FMA, X86_AVX_512, ARM_NEON, }; std::string toString(Precision); std::string toString(CpuExtension); Real getPrecision(Precision p); template Real getPrecision(void); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template<> Real getPrecision(); template Precision getType(void); template<> inline Precision getType() { return Precision::FLOAT; } template<> inline Precision getType() { return Precision::DOUBLE; } template<> inline Precision getType() { return Precision::DOUBLE_DOUBLE; } template<> inline Precision getType() { return Precision::TRIPLE_DOUBLE; } template<> inline Precision getType() { return Precision::QUAD_DOUBLE; } template<> inline Precision getType() { return Precision::FIXED64; } template<> inline Precision getType() { return Precision::FIXED128; } template<> inline Precision getType() { return Precision::FIXED512; } template<> inline Precision getType() { return Precision::FLOAT128; } template<> inline Precision getType() { return Precision::FLOAT256; } template<> inline Precision getType() { return Precision::FLOAT512; } class MandelDevice; } /* enum class mnd::GeneratorType : int { UNSPECIFIED, FLOAT, FLOAT_SSE2, FLOAT_AVX, FLOAT_AVX_FMA, FLOAT_AVX512, FLOAT_NEON, DOUBLE_FLOAT, DOUBLE, DOUBLE_SSE2, DOUBLE_AVX, DOUBLE_AVX_FMA, DOUBLE_AVX512, DOUBLE_NEON, DOUBLE_DOUBLE, DOUBLE_DOUBLE_AVX, DOUBLE_DOUBLE_AVX_FMA, DOUBLE_DOUBLE_NEON, TRIPLE_DOUBLE, TRIPLE_DOUBLE_AVX, QUAD_DOUBLE, QUAD_DOUBLE_AVX_FMA, FLOAT128, FLOAT256, FIXED64, FIXED128, FIXED512 }; */ class mnd::MandelGenerator { protected: Real precision; Precision type; CpuExtension extension; public: MandelGenerator(void); inline MandelGenerator(Precision type) : precision{ mnd::getPrecision(type) }, type{ type }, extension{ mnd::CpuExtension::NONE } { } inline MandelGenerator(Precision type, CpuExtension extension) : precision{ mnd::getPrecision(type) }, type{ type }, extension{ extension } { } inline MandelGenerator(Precision type, CpuExtension extension, const Real& precision) : precision{ precision }, type{ type }, extension{ extension } { } virtual ~MandelGenerator(void); MandelGenerator(const MandelGenerator&) = default; MandelGenerator& operator=(const MandelGenerator&) = default; MandelGenerator(MandelGenerator&&) = default; MandelGenerator& operator=(MandelGenerator&&) = default; virtual void generate(const MandelInfo& info, float* data) = 0; virtual mnd::MandelDevice* getDevice(void); virtual Real getPrecision(void) const; virtual Precision getType(void) const; virtual CpuExtension getExtension(void) const; }; class mnd::AdaptiveGenerator : public MandelGenerator { std::map> generators; public: AdaptiveGenerator(void); AdaptiveGenerator(AdaptiveGenerator&) = delete; AdaptiveGenerator(AdaptiveGenerator&&) = default; AdaptiveGenerator(MandelGenerator* floatGen, MandelGenerator* doubleGen); virtual ~AdaptiveGenerator(void) = default; void addGenerator(const Real& precision, MandelGenerator& generator); void addGenerator(Precision p, MandelGenerator& generator); void addGenerator(MandelGenerator& generator); const std::map>& getGenerators(void) const { return generators; } inline void clear(void) { generators.clear(); } virtual void generate(const MandelInfo& info, float* data) override; }; #endif // MANDEL_GENERATORS_H