diff --git a/dawn/src/dawn/CodeGen/CMakeLists.txt b/dawn/src/dawn/CodeGen/CMakeLists.txt index 318e72bf4..2940ca720 100644 --- a/dawn/src/dawn/CodeGen/CMakeLists.txt +++ b/dawn/src/dawn/CodeGen/CMakeLists.txt @@ -50,6 +50,8 @@ add_library(DawnCodeGen Cuda/ASTStencilFunctionParamVisitor.h Cuda/MSCodeGen.cpp Cuda/MSCodeGen.h + Driver.cpp + Driver.h GridTools/ASTStencilBody.cpp GridTools/ASTStencilBody.h GridTools/ASTStencilDesc.cpp @@ -58,6 +60,7 @@ add_library(DawnCodeGen GridTools/CodeGenUtils.h GridTools/GTCodeGen.cpp GridTools/GTCodeGen.h + Options.h Options.inc StencilFunctionAsBCGenerator.cpp StencilFunctionAsBCGenerator.h diff --git a/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.cpp b/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.cpp index d4d01368e..2d7e51569 100644 --- a/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.cpp +++ b/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.cpp @@ -89,7 +89,22 @@ std::string makeKLoop(bool isBackward, iir::Interval const& interval) { } } // namespace -CXXNaiveIcoCodeGen::CXXNaiveIcoCodeGen(const stencilInstantiationContext& ctx, +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options) { + DiagnosticsEngine diagnostics; + CXXNaiveIcoCodeGen CG(stencilInstantiationMap, diagnostics, options.MaxHaloSize); + if(diagnostics.hasDiags()) { + for(const auto& diag : diagnostics.getQueue()) + DAWN_LOG(INFO) << diag->getMessage(); + throw std::runtime_error("An error occured in code generation"); + } + + return CG.generateCode(); +} + +CXXNaiveIcoCodeGen::CXXNaiveIcoCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoint) : CodeGen(ctx, engine, maxHaloPoint) {} diff --git a/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.h b/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.h index 1665f730b..2e1311e2e 100644 --- a/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.h +++ b/dawn/src/dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.h @@ -17,6 +17,7 @@ #include "dawn/CodeGen/CodeGen.h" #include "dawn/CodeGen/CodeGenProperties.h" +#include "dawn/CodeGen/Options.h" #include "dawn/IIR/Interval.h" #include "dawn/Support/IndexRange.h" #include @@ -32,12 +33,18 @@ class StencilInstantiation; namespace codegen { namespace cxxnaiveico { +/// @brief Run the cxx-naive-ico code generation +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options = {}); + /// @brief GridTools C++ code generation for the gtclang DSL /// @ingroup cxxnaiveico class CXXNaiveIcoCodeGen : public CodeGen { public: ///@brief constructor - CXXNaiveIcoCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, + CXXNaiveIcoCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoint); virtual ~CXXNaiveIcoCodeGen(); virtual std::unique_ptr generateCode() override; diff --git a/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.cpp b/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.cpp index aeb433e07..a064d0e82 100644 --- a/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.cpp +++ b/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.cpp @@ -84,7 +84,22 @@ std::string makeKLoop(bool isBackward, iir::Interval const& interval) { } } // namespace -CXXNaiveCodeGen::CXXNaiveCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options) { + DiagnosticsEngine diagnostics; + CXXNaiveCodeGen CG(stencilInstantiationMap, diagnostics, options.MaxHaloSize); + if(diagnostics.hasDiags()) { + for(const auto& diag : diagnostics.getQueue()) + DAWN_LOG(INFO) << diag->getMessage(); + throw std::runtime_error("An error occured in code generation"); + } + + return CG.generateCode(); +} + +CXXNaiveCodeGen::CXXNaiveCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoint) : CodeGen(ctx, engine, maxHaloPoint) {} diff --git a/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.h b/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.h index d50448211..6fd45c809 100644 --- a/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.h +++ b/dawn/src/dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.h @@ -17,6 +17,7 @@ #include "dawn/CodeGen/CodeGen.h" #include "dawn/CodeGen/CodeGenProperties.h" +#include "dawn/CodeGen/Options.h" #include "dawn/IIR/Interval.h" #include "dawn/Support/IndexRange.h" #include @@ -32,12 +33,18 @@ class StencilInstantiation; namespace codegen { namespace cxxnaive { +/// @brief Run the cxx-naive code generation +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options = {}); + /// @brief GridTools C++ code generation for the gtclang DSL /// @ingroup cxxnaive class CXXNaiveCodeGen : public CodeGen { public: ///@brief constructor - CXXNaiveCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, + CXXNaiveCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoint); virtual ~CXXNaiveCodeGen(); virtual std::unique_ptr generateCode() override; diff --git a/dawn/src/dawn/CodeGen/CodeGen.cpp b/dawn/src/dawn/CodeGen/CodeGen.cpp index 566b64225..2602ccb8f 100644 --- a/dawn/src/dawn/CodeGen/CodeGen.cpp +++ b/dawn/src/dawn/CodeGen/CodeGen.cpp @@ -1,3 +1,17 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + #include "dawn/CodeGen/CodeGen.h" #include "dawn/CodeGen/StencilFunctionAsBCGenerator.h" #include "dawn/IIR/Extents.h" @@ -6,7 +20,7 @@ namespace dawn { namespace codegen { -CodeGen::CodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, +CodeGen::CodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoints) : context_(ctx), diagEngine(engine), codeGenOptions{maxHaloPoints} {} @@ -30,7 +44,7 @@ size_t CodeGen::getVerticalTmpHaloSizeForMultipleStencils( return fullIntervals ? std::max(fullIntervals->overEnd(), fullIntervals->belowBegin()) : 0; } -std::string CodeGen::generateGlobals(const stencilInstantiationContext& context, +std::string CodeGen::generateGlobals(const StencilInstantiationContext& context, std::string outer_namespace_, std::string inner_namespace_) { std::stringstream ss; @@ -43,7 +57,7 @@ std::string CodeGen::generateGlobals(const stencilInstantiationContext& context, return ss.str(); } -std::string CodeGen::generateGlobals(const stencilInstantiationContext& context, +std::string CodeGen::generateGlobals(const StencilInstantiationContext& context, std::string namespace_) { if(context.size() > 0) { const auto& globalsMap = context.begin()->second->getIIR()->getGlobalVariableMap(); @@ -382,7 +396,7 @@ void CodeGen::addMplIfdefs(std::vector& ppDefines, int mplContainer makeIfNotDefinedString("BOOST_MPL_LIMIT_VECTOR_SIZE", "GT_VECTOR_LIMIT_SIZE")); } -std::string CodeGen::generateFileName(const stencilInstantiationContext& context) const { +std::string CodeGen::generateFileName(const StencilInstantiationContext& context) const { if(context.size() > 0) { return context_.begin()->second->getMetaData().getFileName(); } diff --git a/dawn/src/dawn/CodeGen/CodeGen.h b/dawn/src/dawn/CodeGen/CodeGen.h index 93976d8b9..dca50a9cf 100644 --- a/dawn/src/dawn/CodeGen/CodeGen.h +++ b/dawn/src/dawn/CodeGen/CodeGen.h @@ -27,14 +27,14 @@ namespace dawn { namespace codegen { -using stencilInstantiationContext = +using StencilInstantiationContext = std::map>; /// @brief Interface of the backend code generation /// @ingroup codegen class CodeGen { protected: - const stencilInstantiationContext& context_; + const StencilInstantiationContext& context_; DiagnosticsEngine& diagEngine; struct codeGenOption { int MaxHaloPoints; @@ -78,7 +78,7 @@ class CodeGen { const std::string bigWrapperMetadata_ = "m_meta_data"; public: - CodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoints); + CodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoints); virtual ~CodeGen() {} /// @brief Generate code @@ -99,16 +99,16 @@ class CodeGen { Class& stencilWrapperClass, const sir::GlobalVariableMap& globalsMap, const CodeGenProperties& codeGenProperties) const; - virtual std::string generateGlobals(const stencilInstantiationContext& context, + virtual std::string generateGlobals(const StencilInstantiationContext& context, std::string namespace_); - virtual std::string generateGlobals(const stencilInstantiationContext& context, + virtual std::string generateGlobals(const StencilInstantiationContext& context, std::string outer_namespace_, std::string inner_namespace_); virtual std::string generateGlobals(const sir::GlobalVariableMap& globalsMaps, std::string namespace_) const; void generateBCHeaders(std::vector& ppDefines) const; - std::string generateFileName(const stencilInstantiationContext& context) const; + std::string generateFileName(const StencilInstantiationContext& context) const; }; } // namespace codegen diff --git a/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.cpp b/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.cpp index 7ff5c1dde..92b2aaa9c 100644 --- a/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.cpp +++ b/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.cpp @@ -52,7 +52,24 @@ std::string makeIntervalBoundExplicit(std::string dim, const iir::Interval& inte } } // namespace -CudaCodeGen::CudaCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options) { + DiagnosticsEngine diagnostics; + const Array3i domain_size{options.DomainSizeI, options.DomainSizeJ, options.DomainSizeK}; + CudaCodeGen CG(stencilInstantiationMap, diagnostics, options.MaxHaloSize, options.nsms, + options.MaxBlocksPerSM, domain_size); + if(diagnostics.hasDiags()) { + for(const auto& diag : diagnostics.getQueue()) + DAWN_LOG(INFO) << diag->getMessage(); + throw std::runtime_error("An error occured in code generation"); + } + + return CG.generateCode(); +} + +CudaCodeGen::CudaCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoints, int nsms, int maxBlocksPerSM, const Array3i& domainSize) : CodeGen(ctx, engine, maxHaloPoints), codeGenOptions_{nsms, maxBlocksPerSM, domainSize} {} diff --git a/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.h b/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.h index b9f4431a3..fa9524e7d 100644 --- a/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.h +++ b/dawn/src/dawn/CodeGen/Cuda/CudaCodeGen.h @@ -18,6 +18,7 @@ #include "dawn/CodeGen/CodeGen.h" #include "dawn/CodeGen/CodeGenProperties.h" #include "dawn/CodeGen/Cuda/CacheProperties.h" +#include "dawn/CodeGen/Options.h" #include "dawn/Support/Array.h" #include "dawn/Support/IndexRange.h" #include @@ -30,6 +31,12 @@ class StencilInstantiation; namespace codegen { namespace cuda { +/// @brief Run the Cuda code generation +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options = {}); + /// @brief CUDA code generation for cartesian grids /// @ingroup cxxnaive cartesian class CudaCodeGen : public CodeGen { @@ -37,7 +44,7 @@ class CudaCodeGen : public CodeGen { public: ///@brief constructor - CudaCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoints, + CudaCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, int maxHaloPoints, int nsms, int maxBlocksPerSM, const Array3i& domainSize); virtual ~CudaCodeGen(); virtual std::unique_ptr generateCode() override; @@ -119,6 +126,7 @@ class CudaCodeGen : public CodeGen { CudaCodeGenOptions codeGenOptions_; bool iterationSpaceSet_; }; + } // namespace cuda } // namespace codegen } // namespace dawn diff --git a/dawn/src/dawn/CodeGen/Driver.cpp b/dawn/src/dawn/CodeGen/Driver.cpp new file mode 100644 index 000000000..962cf0515 --- /dev/null +++ b/dawn/src/dawn/CodeGen/Driver.cpp @@ -0,0 +1,71 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + +#include "dawn/CodeGen/Driver.h" +#include "dawn/CodeGen/CXXNaive-ico/CXXNaiveCodeGen.h" +#include "dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.h" +#include "dawn/CodeGen/Cuda/CudaCodeGen.h" +#include "dawn/CodeGen/GridTools/GTCodeGen.h" +#include + +namespace dawn { +namespace codegen { + +std::string generate(const std::unique_ptr& translationUnit) { + std::string code; + for(const auto& p : translationUnit->getPPDefines()) + code += p + "\n"; + + code += translationUnit->getGlobals() + "\n\n"; + for(const auto& p : translationUnit->getStencils()) + code += p.second; + + return code; +} + +codegen::Backend parseBackendString(const std::string& backendStr) { + if(backendStr == "gt" || backendStr == "gridtools") { + return codegen::Backend::GridTools; + } else if(backendStr == "naive" || backendStr == "cxxnaive" || backendStr == "c++-naive") { + return codegen::Backend::CXXNaive; + } else if(backendStr == "ico" || backendStr == "naive-ico" || backendStr == "c++-naive-ico") { + return codegen::Backend::CXXNaiveIco; + } else if(backendStr == "cuda" || backendStr == "CUDA") { + return codegen::Backend::CUDA; + } else { + throw std::invalid_argument("Backend not supported"); + } +} + +std::unique_ptr +run(const std::map>& context, + Backend backend, const Options& options) { + switch(backend) { + case Backend::CUDA: + return cuda::run(context, options); + case Backend::CXXNaive: + return cxxnaive::run(context, options); + case Backend::CXXNaiveIco: + return cxxnaiveico::run(context, options); + case Backend::GridTools: + return gt::run(context, options); + case Backend::CXXOpt: + throw std::invalid_argument("Backend not supported"); + } + // This line should not be needed but the compiler seems to complain if it is not present. + return nullptr; +} + +} // namespace codegen +} // namespace dawn diff --git a/dawn/src/dawn/CodeGen/Driver.h b/dawn/src/dawn/CodeGen/Driver.h new file mode 100644 index 000000000..851a0c776 --- /dev/null +++ b/dawn/src/dawn/CodeGen/Driver.h @@ -0,0 +1,42 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + +#ifndef DAWN_CODEGEN_DRIVER_H +#define DAWN_CODEGEN_DRIVER_H + +#include "dawn/CodeGen/Options.h" +#include "dawn/CodeGen/TranslationUnit.h" +#include "dawn/IIR/StencilInstantiation.h" +#include +#include +#include + +namespace dawn { +namespace codegen { + +/// @brief Parse the backend string to enumeration +Backend parseBackendString(const std::string& backendStr); + +/// @brief Run the code generation +std::unique_ptr +run(const std::map>& context, + Backend backend, const Options& options = {}); + +/// @brief Shortcut to generate code from a translation unit +std::string generate(const std::unique_ptr& translationUnit); + +} // namespace codegen +} // namespace dawn + +#endif diff --git a/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.cpp b/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.cpp index 53ee41e05..3b4ecaedd 100644 --- a/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.cpp +++ b/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.cpp @@ -34,7 +34,22 @@ namespace dawn { namespace codegen { namespace gt { -GTCodeGen::GTCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options) { + DiagnosticsEngine diagnostics; + GTCodeGen CG(stencilInstantiationMap, diagnostics, options.UseParallelEP, options.MaxHaloSize); + if(diagnostics.hasDiags()) { + for(const auto& diag : diagnostics.getQueue()) + DAWN_LOG(INFO) << diag->getMessage(); + throw std::runtime_error("An error occured in code generation"); + } + + return CG.generateCode(); +} + +GTCodeGen::GTCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, bool useParallelEP, int maxHaloPoints) : CodeGen(ctx, engine, maxHaloPoints), mplContainerMaxSize_(20), codeGenOptions_{useParallelEP} {} diff --git a/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.h b/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.h index a6bdd3500..21c1fc39c 100644 --- a/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.h +++ b/dawn/src/dawn/CodeGen/GridTools/GTCodeGen.h @@ -17,6 +17,7 @@ #include "dawn/CodeGen/CodeGen.h" #include "dawn/CodeGen/CodeGenProperties.h" +#include "dawn/CodeGen/Options.h" #include "dawn/IIR/Interval.h" #include #include @@ -33,11 +34,17 @@ class Stencil; namespace codegen { namespace gt { +/// @brief Run the GridTools code generation +std::unique_ptr +run(const std::map>& + stencilInstantiationMap, + const Options& options = {}); + /// @brief GridTools C++ code generation for the gtclang DSL /// @ingroup gt class GTCodeGen : public CodeGen { public: - GTCodeGen(const stencilInstantiationContext& ctx, DiagnosticsEngine& engine, bool useParallelEP, + GTCodeGen(const StencilInstantiationContext& ctx, DiagnosticsEngine& engine, bool useParallelEP, int maxHaloPoints); virtual ~GTCodeGen(); diff --git a/dawn/src/dawn/CodeGen/Options.h b/dawn/src/dawn/CodeGen/Options.h new file mode 100644 index 000000000..6db556603 --- /dev/null +++ b/dawn/src/dawn/CodeGen/Options.h @@ -0,0 +1,37 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + +#ifndef DAWN_CODEGEN_OPTIONS_H +#define DAWN_CODEGEN_OPTIONS_H + +namespace dawn { +namespace codegen { + +/// @brief CodeGen backends +enum class Backend { GridTools, CXXNaive, CXXNaiveIco, CUDA, CXXOpt }; + +/// @brief Options for all codegen backends combined. +/// +/// These have to be disjoint from the options for other dawn and gtc-parse components. +struct Options { +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + TYPE NAME = DEFAULT_VALUE; +#include "dawn/CodeGen/Options.inc" +#undef OPT +}; + +} // namespace codegen +} // namespace dawn + +#endif diff --git a/dawn/src/dawn/CodeGen/Options.inc b/dawn/src/dawn/CodeGen/Options.inc index 24b4bfcb0..b6405c05a 100644 --- a/dawn/src/dawn/CodeGen/Options.inc +++ b/dawn/src/dawn/CodeGen/Options.inc @@ -32,6 +32,11 @@ // command-line target will be generated which allows to negate the option i.e // +// TODO Rename this to (MaxHaloPoints, "max-halo") after combined struct is eliminated +OPT(int, MaxHaloSize, 3, "max-halo-size", "", + "Set the maximum number of allowed halo points", "", true, false) +OPT(bool, UseParallelEP, false, "use-parallel-ep", "", + "Make use of the parallel execution policy", "", false, true) OPT(int, MaxBlocksPerSM, 0, "max-blocks-sm", "", "Maximum number of blocks that can be registered per SM", "", true, false) OPT(int, nsms, 0, "nsms", "", "Number of (CUDA) SMs", "", true, false) diff --git a/dawn/src/dawn/Compiler/CMakeLists.txt b/dawn/src/dawn/Compiler/CMakeLists.txt index 4b465aea6..65798fc9a 100644 --- a/dawn/src/dawn/Compiler/CMakeLists.txt +++ b/dawn/src/dawn/Compiler/CMakeLists.txt @@ -15,6 +15,8 @@ add_library(DawnCompiler DawnCompiler.h DawnCompiler.cpp + Driver.h + Driver.cpp Options.h Options.inc ) diff --git a/dawn/src/dawn/Compiler/DawnCompiler.cpp b/dawn/src/dawn/Compiler/DawnCompiler.cpp index da24f15fa..b9adc5fcc 100644 --- a/dawn/src/dawn/Compiler/DawnCompiler.cpp +++ b/dawn/src/dawn/Compiler/DawnCompiler.cpp @@ -18,6 +18,7 @@ #include "dawn/CodeGen/CXXNaive/CXXNaiveCodeGen.h" #include "dawn/CodeGen/CodeGen.h" #include "dawn/CodeGen/Cuda/CudaCodeGen.h" +#include "dawn/CodeGen/Driver.h" #include "dawn/CodeGen/GridTools/GTCodeGen.h" #include "dawn/Optimizer/OptimizerContext.h" #include "dawn/Optimizer/PassDataLocalityMetric.h" @@ -64,23 +65,6 @@ namespace dawn { namespace { -// CodeGen backends -enum class BackendType { GridTools, CXXNaive, CXXNaiveIco, CUDA, CXXOpt }; - -BackendType parseBackendString(const std::string& backendStr) { - if(backendStr == "gt" || backendStr == "gridtools") { - return BackendType::GridTools; - } else if(backendStr == "naive" || backendStr == "cxxnaive" || backendStr == "c++-naive") { - return BackendType::CXXNaive; - } else if(backendStr == "ico" || backendStr == "naive-ico" || backendStr == "c++-naive-ico") { - return BackendType::CXXNaiveIco; - } else if(backendStr == "cuda" || backendStr == "CUDA") { - return BackendType::CUDA; - } else { - throw CompileError("Backend not supported"); - } -} - /// @brief Make a suggestion to the user if there is a small typo (only works with string options) template struct ComputeEditDistance { @@ -146,11 +130,6 @@ DiagnosticsBuilder buildDiag(const std::string& option, const T& value, std::str } } // namespace -std::list DawnCompiler::defaultPassGroups() { - return {PassGroup::SetStageName, PassGroup::StageReordering, PassGroup::StageMerger, - PassGroup::SetCaches, PassGroup::SetBlockSize}; -} - DawnCompiler::DawnCompiler(const Options& options) : diagnostics_(), options_(options) {} std::map> @@ -377,9 +356,9 @@ std::unique_ptr DawnCompiler::generate(const std::map>& stencilInstantiationMap) { // Generate code - BackendType backend; + codegen::Backend backend; try { - backend = parseBackendString(options_.Backend); + backend = codegen::parseBackendString(options_.Backend); } catch(CompileError& e) { diagnostics_.report(buildDiag("-backend", options_.Backend, "backend options must be : " + @@ -388,32 +367,12 @@ DawnCompiler::generate(const std::map #include +#include namespace dawn { struct SIR; -/// @brief Enumeration of all pass groups -enum class PassGroup { - Parallel, - SSA, - PrintStencilGraph, - SetStageName, - StageReordering, - StageMerger, - TemporaryMerger, - Inlining, - IntervalPartitioning, - TmpToStencilFunction, - SetNonTempCaches, - SetCaches, - SetBlockSize, - DataLocalityMetric -}; - /// @brief The DawnCompiler class /// @ingroup compiler class DawnCompiler : NonCopyable { @@ -76,8 +60,6 @@ class DawnCompiler : NonCopyable { generate(const std::map>& stencilInstantiationMap); - static std::list defaultPassGroups(); - /// @brief Get options const Options& getOptions() const; Options& getOptions(); diff --git a/dawn/src/dawn/Compiler/Driver.cpp b/dawn/src/dawn/Compiler/Driver.cpp new file mode 100644 index 000000000..1b1a91025 --- /dev/null +++ b/dawn/src/dawn/Compiler/Driver.cpp @@ -0,0 +1,64 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + +#include "dawn/Compiler/Driver.h" +#include "dawn/CodeGen/TranslationUnit.h" +#include "dawn/Compiler/DawnCompiler.h" +#include "dawn/Compiler/Options.h" + +namespace dawn { + +std::list defaultPassGroups() { + return {PassGroup::SetStageName, PassGroup::StageReordering, PassGroup::StageMerger, + PassGroup::SetCaches, PassGroup::SetBlockSize}; +} + +std::map> +run(const std::shared_ptr& stencilIR, const std::list& groups, + const OptimizerOptions& options) { + // Put all options there + dawn::Options dawnOptions; + // Copy over options passed in +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + dawnOptions.NAME = options.NAME; +#include "dawn/Optimizer/Options.inc" +#undef OPT + DawnCompiler compiler(dawnOptions); + return compiler.optimize(compiler.lowerToIIR(stencilIR), groups); +} + +std::map> +run(const std::map>& + stencilInstantiationMap, + const std::list& groups, const OptimizerOptions& options) { + // Put all options there + dawn::Options dawnOptions; + // Copy over options passed in +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + dawnOptions.NAME = options.NAME; +#include "dawn/Optimizer/Options.inc" +#undef OPT + DawnCompiler compiler(dawnOptions); + return compiler.optimize(stencilInstantiationMap, groups); +} + +std::unique_ptr compile(const std::shared_ptr& stencilIR, + const std::list& passGroups, + const OptimizerOptions& optimizerOptions, + codegen::Backend backend, + const codegen::Options& codegenOptions) { + return codegen::run(run(stencilIR, passGroups, optimizerOptions), backend, codegenOptions); +} + +} // namespace dawn diff --git a/dawn/src/dawn/Compiler/Driver.h b/dawn/src/dawn/Compiler/Driver.h new file mode 100644 index 000000000..af26baae5 --- /dev/null +++ b/dawn/src/dawn/Compiler/Driver.h @@ -0,0 +1,56 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + +#ifndef DAWN_COMPILER_DRIVER_H +#define DAWN_COMPILER_DRIVER_H + +#include "dawn/CodeGen/Driver.h" +#include "dawn/CodeGen/Options.h" +#include "dawn/CodeGen/TranslationUnit.h" +#include "dawn/IIR/StencilInstantiation.h" +#include "dawn/Optimizer/OptimizerOptions.h" +#include +#include +#include + +namespace dawn { + +/// @brief List of default optimizer pass groups. +std::list defaultPassGroups(); + +// TODO Move these to Optimizer/Driver.{cpp,h} when DawnCompiler is removed +// { +/// @brief Lower to IIR and run groups +std::map> +run(const std::shared_ptr& stencilIR, const std::list& groups, + const OptimizerOptions& options = {}); + +/// @brief Run groups +std::map> +run(const std::map>& + stencilInstantiationMap, + const std::list& groups, const OptimizerOptions& options = {}); +// } + +/// @brief Compile SIR to a translation unit +std::unique_ptr +compile(const std::shared_ptr& stencilIR, + const std::list& passGroups = defaultPassGroups(), + const OptimizerOptions& optimizerOptions = {}, + codegen::Backend backend = codegen::Backend::GridTools, + const codegen::Options& codegenOptions = {}); + +} // namespace dawn + +#endif diff --git a/dawn/src/dawn/Optimizer/CMakeLists.txt b/dawn/src/dawn/Optimizer/CMakeLists.txt index 9329f69ca..48e520084 100644 --- a/dawn/src/dawn/Optimizer/CMakeLists.txt +++ b/dawn/src/dawn/Optimizer/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(DawnOptimizer CreateVersionAndRename.h OptimizerContext.cpp OptimizerContext.h + OptimizerOptions.h Options.inc Pass.h PassDataLocalityMetric.cpp diff --git a/dawn/src/dawn/Optimizer/OptimizerOptions.h b/dawn/src/dawn/Optimizer/OptimizerOptions.h new file mode 100644 index 000000000..7b679179a --- /dev/null +++ b/dawn/src/dawn/Optimizer/OptimizerOptions.h @@ -0,0 +1,49 @@ +//===--------------------------------------------------------------------------------*- C++ -*-===// +// _ +// | | +// __| | __ ___ ___ ___ +// / _` |/ _` \ \ /\ / / '_ | +// | (_| | (_| |\ V V /| | | | +// \__,_|\__,_| \_/\_/ |_| |_| - Compiler Toolchain +// +// +// This file is distributed under the MIT License (MIT). +// See LICENSE.txt for details. +// +//===------------------------------------------------------------------------------------------===// + +#ifndef DAWN_OPTIMIZER_OPTIMIZEROPTIONS_H +#define DAWN_OPTIMIZER_OPTIMIZEROPTIONS_H + +namespace dawn { + +// TODO This will be moved to Compiler/Driver.h when +/// @brief Enumeration of all pass groups +enum class PassGroup { + Parallel, + SSA, + PrintStencilGraph, + SetStageName, + StageReordering, + StageMerger, + TemporaryMerger, + Inlining, + IntervalPartitioning, + TmpToStencilFunction, + SetNonTempCaches, + SetCaches, + SetBlockSize, + DataLocalityMetric +}; + +// TODO Rename this to dawn::Options after the larger dawn::Options is removed +struct OptimizerOptions { +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + TYPE NAME = DEFAULT_VALUE; +#include "dawn/Optimizer/Options.inc" +#undef OPT +}; + +} // namespace dawn + +#endif diff --git a/dawn/src/dawn/Optimizer/Options.inc b/dawn/src/dawn/Optimizer/Options.inc index f6e707751..bfe489a14 100644 --- a/dawn/src/dawn/Optimizer/Options.inc +++ b/dawn/src/dawn/Optimizer/Options.inc @@ -51,8 +51,6 @@ OPT(bool, SplitStencils, false, "split-stencils", "", "Split stencil whose number of fields exceeds a threshold", "", false, true) OPT(bool, MergeDoMethods, true, "merge-do-methods", "", "Merge Do-Methods with different vertical intervals into the same stage if possible", "", false, true) -OPT(bool, UseParallelEP, false, "use-parallel-ep", "", - "Make use of the parallel execution policy", "", false, true) OPT(bool, DisableKCaches, false, "disable-kcaches", "", "Disable use of the k-caches", "", false, true) OPT(bool, UseNonTempCaches, false, "cache-non-temp-fields", "", diff --git a/dawn/src/dawn/Unittest/CompilerUtil.cpp b/dawn/src/dawn/Unittest/CompilerUtil.cpp index d0169117e..2fb165dd7 100644 --- a/dawn/src/dawn/Unittest/CompilerUtil.cpp +++ b/dawn/src/dawn/Unittest/CompilerUtil.cpp @@ -64,7 +64,7 @@ CompilerUtil::load(const std::string& irFilename, filename = envPath + "/" + filename; if(filename.find(".sir") != std::string::npos) { - stencilInstantiationContext siMap = lower(filename, options, context, envPath); + StencilInstantiationContext siMap = lower(filename, options, context, envPath); return siMap.begin()->second; } else { std::shared_ptr sir = std::make_shared(ast::GridType::Cartesian); @@ -73,7 +73,7 @@ CompilerUtil::load(const std::string& irFilename, } } -stencilInstantiationContext +StencilInstantiationContext CompilerUtil::lower(const std::shared_ptr& sir, const dawn::OptimizerContext::OptimizerContextOptions& options, std::unique_ptr& context) { @@ -81,7 +81,7 @@ CompilerUtil::lower(const std::shared_ptr& sir, return context->getStencilInstantiationMap(); } -stencilInstantiationContext +StencilInstantiationContext CompilerUtil::lower(const std::string& sirFilename, const dawn::OptimizerContext::OptimizerContextOptions& options, std::unique_ptr& context, const std::string& envPath) { @@ -110,9 +110,9 @@ void dump(CG& generator, std::ostream& os) { os << ss.str(); } -dawn::codegen::stencilInstantiationContext +dawn::codegen::StencilInstantiationContext siToContext(std::shared_ptr si) { - dawn::codegen::stencilInstantiationContext ctx; + dawn::codegen::StencilInstantiationContext ctx; ctx[si->getName()] = si; return ctx; } diff --git a/dawn/src/dawn/Unittest/CompilerUtil.h b/dawn/src/dawn/Unittest/CompilerUtil.h index 54fc040bc..be993e00d 100644 --- a/dawn/src/dawn/Unittest/CompilerUtil.h +++ b/dawn/src/dawn/Unittest/CompilerUtil.h @@ -28,7 +28,7 @@ namespace dawn { -using stencilInstantiationContext = +using StencilInstantiationContext = std::map>; /// @brief Compiler utilities for unit tests @@ -42,11 +42,11 @@ class CompilerUtil { load(const std::string& iirFilename, const dawn::OptimizerContext::OptimizerContextOptions& options, std::unique_ptr& context, const std::string& envPath = ""); - static stencilInstantiationContext + static StencilInstantiationContext lower(const std::shared_ptr& sir, const dawn::OptimizerContext::OptimizerContextOptions& options, std::unique_ptr& context); - static stencilInstantiationContext + static StencilInstantiationContext lower(const std::string& sirFilename, const dawn::OptimizerContext::OptimizerContextOptions& options, std::unique_ptr& context, const std::string& envPath = ""); diff --git a/dawn/src/dawn/Unittest/IIRBuilder.cpp b/dawn/src/dawn/Unittest/IIRBuilder.cpp index f24e64dcf..45dbdafce 100644 --- a/dawn/src/dawn/Unittest/IIRBuilder.cpp +++ b/dawn/src/dawn/Unittest/IIRBuilder.cpp @@ -107,7 +107,7 @@ IIRBuilder::build(std::string const& name, std::unique_ptr stencil } DAWN_ASSERT(GridTypeChecker::checkGridTypeConsistency(*new_si->getIIR().get())); - dawn::codegen::stencilInstantiationContext map; + dawn::codegen::StencilInstantiationContext map; return new_si; } diff --git a/dawn/src/dawn/dawn-codegen.cpp b/dawn/src/dawn/dawn-codegen.cpp index 84df74b8d..03640bebf 100644 --- a/dawn/src/dawn/dawn-codegen.cpp +++ b/dawn/src/dawn/dawn-codegen.cpp @@ -12,7 +12,7 @@ // //===------------------------------------------------------------------------------------------===// -#include "dawn/Compiler/DawnCompiler.h" +#include "dawn/CodeGen/Driver.h" #include "dawn/Compiler/Options.h" #include "dawn/IIR/StencilInstantiation.h" #include "dawn/Serialization/IIRSerializer.h" @@ -110,28 +110,23 @@ int main(int argc, char* argv[]) { std::istreambuf_iterator begin(std::cin), end; input.insert(input.begin(), begin, end); } - dawn::Options dawnOptions; -#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ - dawnOptions.NAME = result[OPTION].as(); -#include "dawn/CodeGen/Options.inc" -#undef OPT - dawnOptions.Backend = result["backend"].as(); - dawn::DawnCompiler compiler(dawnOptions); auto internalIR = deserializeInput(input); std::map> stencilInstantiationMap{ {"restoredIIR", internalIR}}; - auto translationUnit = compiler.generate(stencilInstantiationMap); + dawn::codegen::Backend backend = + dawn::codegen::parseBackendString(result["backend"].as()); - std::string code; - for(auto p : translationUnit->getPPDefines()) - code += p + "\n"; + dawn::codegen::Options codegenOptions; +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + codegenOptions.NAME = result[OPTION].as(); +#include "dawn/CodeGen/Options.inc" +#undef OPT + auto translationUnit = dawn::codegen::run(stencilInstantiationMap, backend, codegenOptions); - code += translationUnit->getGlobals() + "\n\n"; - for(auto p : translationUnit->getStencils()) - code += p.second; + auto code = dawn::codegen::generate(translationUnit); if(result.count("out") > 0) { std::ofstream out(result["out"].as()); diff --git a/dawn/src/dawn/dawn-opt.cpp b/dawn/src/dawn/dawn-opt.cpp index 12b1ba6d5..23e72ce00 100644 --- a/dawn/src/dawn/dawn-opt.cpp +++ b/dawn/src/dawn/dawn-opt.cpp @@ -12,7 +12,7 @@ // //===------------------------------------------------------------------------------------------===// -#include "dawn/Compiler/DawnCompiler.h" +#include "dawn/Compiler/Driver.h" #include "dawn/Compiler/Options.h" #include "dawn/IIR/StencilInstantiation.h" #include "dawn/SIR/SIR.h" @@ -162,7 +162,7 @@ int main(int argc, char* argv[]) { ("v,verbose", "Set verbosity level to info. If set, use -o or --out to redirect IIR.") ("default-opt", "Add default groups before those in --pass-groups.") ("p,pass-groups", - "Comma-separated ordered list of pass groups to run. See DawnCompiler.h for list. If unset, runs the basic, default groups.", + "Comma-separated ordered list of pass groups to run. See dawn/Compiler/Driver.h for list. If unset and --default-opts is not passed, only lowers to IIR.", cxxopts::value>()->default_value({})) ("h,help", "Display usage."); @@ -185,20 +185,10 @@ int main(int argc, char* argv[]) { return 0; } - // Create a dawn::Options struct for the driver - dawn::Options dawnOptions; -#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ - dawnOptions.NAME = result[OPTION].as(); -#include "dawn/Optimizer/Options.inc" -#undef OPT - // Never serialize IIR here - dawnOptions.SerializeIIR = false; - dawn::DawnCompiler compiler(dawnOptions); - // Determine the list of pass groups to run std::list passGroups; if(result.count("default-opt") > 0) { - passGroups = dawn::DawnCompiler::defaultPassGroups(); + passGroups = dawn::defaultPassGroups(); } for(auto pg : result["pass-groups"].as>()) { passGroups.push_back(parsePassGroup(pg)); @@ -217,17 +207,23 @@ int main(int argc, char* argv[]) { auto [stencilIR, internalIR, format] = deserializeInput(input); - // Fill map either by lowering or adding the single StencilInstantiation (from IIR) - std::map> stencilInstantiationMap; + // Create a dawn::OptimizerOptions struct for the driver + dawn::OptimizerOptions optimizerOptions; +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + optimizerOptions.NAME = result[OPTION].as(); +#include "dawn/Optimizer/Options.inc" +#undef OPT + + // Call optimizer + std::map> optimizedSIM; if(stencilIR) { - stencilInstantiationMap = compiler.lowerToIIR(stencilIR); + optimizedSIM = dawn::run(stencilIR, passGroups, optimizerOptions); } else { - stencilInstantiationMap.emplace("restoredIIR", internalIR); + std::map> stencilInstantiationMap{ + {"restoredIIR", internalIR}}; + optimizedSIM = dawn::run(stencilInstantiationMap, passGroups, optimizerOptions); } - // Call optimizer groups - auto optimizedSIM = compiler.optimize(stencilInstantiationMap, passGroups); - if(optimizedSIM.size() > 1) { DAWN_LOG(WARNING) << "More than one StencilInstantiation is not supported in IIR"; } @@ -238,7 +234,7 @@ int main(int argc, char* argv[]) { : dawn::IIRSerializer::Format::Json; if(result.count("out")) dawn::IIRSerializer::serialize(result["out"].as(), instantiation, iirFormat); - else if(!dawnOptions.DumpStencilInstantiation) { + else if(!optimizerOptions.DumpStencilInstantiation) { std::cout << dawn::IIRSerializer::serializeToString(instantiation, iirFormat); } else { diff --git a/dawn/src/dawn4py/_dawn4py.cpp b/dawn/src/dawn4py/_dawn4py.cpp index e3e08081a..dcbd859ee 100644 --- a/dawn/src/dawn4py/_dawn4py.cpp +++ b/dawn/src/dawn4py/_dawn4py.cpp @@ -17,86 +17,89 @@ PYBIND11_MODULE(_dawn4py, m) { // Classes py::class_(m, "Options") - .def(py::init( - [](int MaxBlocksPerSM, int nsms, int DomainSizeI, int DomainSizeJ, int DomainSizeK, - const std::string& Backend, const std::string& OutputFile, bool SerializeIIR, - const std::string& DeserializeIIR, const std::string& IIRFormat, - int MaxHaloPoints, const std::string& ReorderStrategy, int MaxFieldsPerStencil, - bool MaxCutMSS, int BlockSizeI, int BlockSizeJ, int BlockSizeK, - bool SplitStencils, bool MergeDoMethods, bool UseParallelEP, bool DisableKCaches, - bool UseNonTempCaches, bool KeepVarnames, bool PassVerbose, bool ReportAccesses, - bool DumpSplitGraphs, bool DumpStageGraph, bool DumpTemporaryGraphs, - bool DumpRaceConditionGraph, bool DumpStencilInstantiation, bool DumpStencilGraph, - bool SSA, bool PrintStencilGraph, bool SetStageName, bool StageReordering, - bool StageMerger, bool TemporaryMerger, bool Inlining, bool IntervalPartitioning, - bool TmpToStencilFunction, bool SetNonTempCaches, bool SetCaches, - bool SetBlockSize, bool DataLocalityMetric, bool ReportBoundaryConditions, - bool ReportDataLocalityMetric, bool ReportPassTmpToFunction, - bool ReportPassRemoveScalars, bool ReportPassStageSplit, - bool ReportPassMultiStageSplit, bool ReportPassFieldVersioning, - bool ReportPassTemporaryMerger, bool ReportPassTemporaryType, - bool ReportPassStageReodering, bool ReportPassStageMerger, - bool ReportPassSetCaches, bool ReportPassSetBlockSize, - bool ReportPassSetNonTempCaches) { - return dawn::Options{MaxBlocksPerSM, - nsms, - DomainSizeI, - DomainSizeJ, - DomainSizeK, - Backend, - OutputFile, - SerializeIIR, - DeserializeIIR, - IIRFormat, - MaxHaloPoints, - ReorderStrategy, - MaxFieldsPerStencil, - MaxCutMSS, - BlockSizeI, - BlockSizeJ, - BlockSizeK, - SplitStencils, - MergeDoMethods, - UseParallelEP, - DisableKCaches, - UseNonTempCaches, - KeepVarnames, - PassVerbose, - ReportAccesses, - DumpSplitGraphs, - DumpStageGraph, - DumpTemporaryGraphs, - DumpRaceConditionGraph, - DumpStencilInstantiation, - DumpStencilGraph, - SSA, - PrintStencilGraph, - SetStageName, - StageReordering, - StageMerger, - TemporaryMerger, - Inlining, - IntervalPartitioning, - TmpToStencilFunction, - SetNonTempCaches, - SetCaches, - SetBlockSize, - DataLocalityMetric, - ReportBoundaryConditions, - ReportDataLocalityMetric, - ReportPassTmpToFunction, - ReportPassRemoveScalars, - ReportPassStageSplit, - ReportPassMultiStageSplit, - ReportPassFieldVersioning, - ReportPassTemporaryMerger, - ReportPassTemporaryType, - ReportPassStageReodering, - ReportPassStageMerger, - ReportPassSetCaches, - ReportPassSetBlockSize, - ReportPassSetNonTempCaches}; - }), + .def(py::init([](int MaxHaloSize, bool UseParallelEP, int MaxBlocksPerSM, int nsms, + int DomainSizeI, int DomainSizeJ, int DomainSizeK, + const std::string& Backend, const std::string& OutputFile, bool SerializeIIR, + const std::string& DeserializeIIR, const std::string& IIRFormat, + int MaxHaloPoints, const std::string& ReorderStrategy, + int MaxFieldsPerStencil, bool MaxCutMSS, int BlockSizeI, int BlockSizeJ, + int BlockSizeK, bool SplitStencils, bool MergeDoMethods, bool DisableKCaches, + bool UseNonTempCaches, bool KeepVarnames, bool PassVerbose, + bool ReportAccesses, bool DumpSplitGraphs, bool DumpStageGraph, + bool DumpTemporaryGraphs, bool DumpRaceConditionGraph, + bool DumpStencilInstantiation, bool DumpStencilGraph, bool SSA, + bool PrintStencilGraph, bool SetStageName, bool StageReordering, + bool StageMerger, bool TemporaryMerger, bool Inlining, + bool IntervalPartitioning, bool TmpToStencilFunction, bool SetNonTempCaches, + bool SetCaches, bool SetBlockSize, bool DataLocalityMetric, + bool ReportBoundaryConditions, bool ReportDataLocalityMetric, + bool ReportPassTmpToFunction, bool ReportPassRemoveScalars, + bool ReportPassStageSplit, bool ReportPassMultiStageSplit, + bool ReportPassFieldVersioning, bool ReportPassTemporaryMerger, + bool ReportPassTemporaryType, bool ReportPassStageReodering, + bool ReportPassStageMerger, bool ReportPassSetCaches, + bool ReportPassSetBlockSize, bool ReportPassSetNonTempCaches) { + return dawn::Options{MaxHaloSize, + UseParallelEP, + MaxBlocksPerSM, + nsms, + DomainSizeI, + DomainSizeJ, + DomainSizeK, + Backend, + OutputFile, + SerializeIIR, + DeserializeIIR, + IIRFormat, + MaxHaloPoints, + ReorderStrategy, + MaxFieldsPerStencil, + MaxCutMSS, + BlockSizeI, + BlockSizeJ, + BlockSizeK, + SplitStencils, + MergeDoMethods, + DisableKCaches, + UseNonTempCaches, + KeepVarnames, + PassVerbose, + ReportAccesses, + DumpSplitGraphs, + DumpStageGraph, + DumpTemporaryGraphs, + DumpRaceConditionGraph, + DumpStencilInstantiation, + DumpStencilGraph, + SSA, + PrintStencilGraph, + SetStageName, + StageReordering, + StageMerger, + TemporaryMerger, + Inlining, + IntervalPartitioning, + TmpToStencilFunction, + SetNonTempCaches, + SetCaches, + SetBlockSize, + DataLocalityMetric, + ReportBoundaryConditions, + ReportDataLocalityMetric, + ReportPassTmpToFunction, + ReportPassRemoveScalars, + ReportPassStageSplit, + ReportPassMultiStageSplit, + ReportPassFieldVersioning, + ReportPassTemporaryMerger, + ReportPassTemporaryType, + ReportPassStageReodering, + ReportPassStageMerger, + ReportPassSetCaches, + ReportPassSetBlockSize, + ReportPassSetNonTempCaches}; + }), + py::arg("max_halo_size") = 3, py::arg("use_parallel_ep") = false, py::arg("max_blocks_per_sm") = 0, py::arg("nsms") = 0, py::arg("domain_size_i") = 0, py::arg("domain_size_j") = 0, py::arg("domain_size_k") = 0, py::arg("backend") = "gridtools", py::arg("output_file") = "", @@ -105,12 +108,11 @@ PYBIND11_MODULE(_dawn4py, m) { py::arg("reorder_strategy") = "greedy", py::arg("max_fields_per_stencil") = 40, py::arg("max_cut_mss") = false, py::arg("block_size_i") = 0, py::arg("block_size_j") = 0, py::arg("block_size_k") = 0, py::arg("split_stencils") = false, - py::arg("merge_do_methods") = true, py::arg("use_parallel_ep") = false, - py::arg("disable_k_caches") = false, py::arg("use_non_temp_caches") = false, - py::arg("keep_varnames") = false, py::arg("pass_verbose") = false, - py::arg("report_accesses") = false, py::arg("dump_split_graphs") = false, - py::arg("dump_stage_graph") = false, py::arg("dump_temporary_graphs") = false, - py::arg("dump_race_condition_graph") = false, + py::arg("merge_do_methods") = true, py::arg("disable_k_caches") = false, + py::arg("use_non_temp_caches") = false, py::arg("keep_varnames") = false, + py::arg("pass_verbose") = false, py::arg("report_accesses") = false, + py::arg("dump_split_graphs") = false, py::arg("dump_stage_graph") = false, + py::arg("dump_temporary_graphs") = false, py::arg("dump_race_condition_graph") = false, py::arg("dump_stencil_instantiation") = false, py::arg("dump_stencil_graph") = false, py::arg("ssa") = false, py::arg("print_stencil_graph") = false, py::arg("set_stage_name") = false, py::arg("stage_reordering") = false, @@ -131,6 +133,8 @@ PYBIND11_MODULE(_dawn4py, m) { py::arg("report_pass_stage_merger") = false, py::arg("report_pass_set_caches") = false, py::arg("report_pass_set_block_size") = false, py::arg("report_pass_set_non_temp_caches") = false) + .def_readwrite("max_halo_size", &dawn::Options::MaxHaloSize) + .def_readwrite("use_parallel_ep", &dawn::Options::UseParallelEP) .def_readwrite("max_blocks_per_sm", &dawn::Options::MaxBlocksPerSM) .def_readwrite("nsms", &dawn::Options::nsms) .def_readwrite("domain_size_i", &dawn::Options::DomainSizeI) @@ -150,7 +154,6 @@ PYBIND11_MODULE(_dawn4py, m) { .def_readwrite("block_size_k", &dawn::Options::BlockSizeK) .def_readwrite("split_stencils", &dawn::Options::SplitStencils) .def_readwrite("merge_do_methods", &dawn::Options::MergeDoMethods) - .def_readwrite("use_parallel_ep", &dawn::Options::UseParallelEP) .def_readwrite("disable_k_caches", &dawn::Options::DisableKCaches) .def_readwrite("use_non_temp_caches", &dawn::Options::UseNonTempCaches) .def_readwrite("keep_varnames", &dawn::Options::KeepVarnames) @@ -191,7 +194,9 @@ PYBIND11_MODULE(_dawn4py, m) { .def_readwrite("report_pass_set_non_temp_caches", &dawn::Options::ReportPassSetNonTempCaches) .def("__repr__", [](const dawn::Options& self) { std::ostringstream ss; - ss << "max_blocks_per_sm=" << self.MaxBlocksPerSM << ",\n " + ss << "max_halo_size=" << self.MaxHaloSize << ",\n " + << "use_parallel_ep=" << self.UseParallelEP << ",\n " + << "max_blocks_per_sm=" << self.MaxBlocksPerSM << ",\n " << "nsms=" << self.nsms << ",\n " << "domain_size_i=" << self.DomainSizeI << ",\n " << "domain_size_j=" << self.DomainSizeJ << ",\n " @@ -220,7 +225,6 @@ PYBIND11_MODULE(_dawn4py, m) { << "block_size_k=" << self.BlockSizeK << ",\n " << "split_stencils=" << self.SplitStencils << ",\n " << "merge_do_methods=" << self.MergeDoMethods << ",\n " - << "use_parallel_ep=" << self.UseParallelEP << ",\n " << "disable_k_caches=" << self.DisableKCaches << ",\n " << "use_non_temp_caches=" << self.UseNonTempCaches << ",\n " << "keep_varnames=" << self.KeepVarnames << ",\n " diff --git a/gtclang/src/gtclang/Driver/Driver.cpp b/gtclang/src/gtclang/Driver/Driver.cpp index c614f0f98..fe3f7236f 100644 --- a/gtclang/src/gtclang/Driver/Driver.cpp +++ b/gtclang/src/gtclang/Driver/Driver.cpp @@ -86,4 +86,57 @@ ReturnValue Driver::run(const llvm::SmallVectorImpl& args) { return ReturnValue{ret, returnSIR}; } +std::shared_ptr run(const std::string& fileName, const ParseOptions& options) { + // Initialize the GTClangContext + auto context = std::make_unique(); + + // Skip Dawn + context->useDawn() = false; + + // Set options that were passed in + context->getOptions().DumpPP = options.DumpPP; + context->getOptions().ConfigFile = options.ConfigFile; + context->getOptions().DumpAST = options.DumpAST; + context->getOptions().ReportPassPreprocessor = options.ReportPassPreprocessor; + context->getOptions().Verbose = options.Verbose; + + llvm::SmallVector clangArgs; + clangArgs.push_back("gtc-parse"); + clangArgs.push_back(fileName.c_str()); + + // Initialize the Logger + auto logger = std::make_unique(); + if(options.Verbose) + dawn::Logger::getSingleton().registerLogger(logger.get()); + + gtclang::GTClangIncludeChecker includeChecker; + if(clangArgs.size() > 1) + includeChecker.Update(clangArgs[1]); + + // Create GTClang + std::unique_ptr GTClang(gtclang::createCompilerInstance(clangArgs)); + + // Create SIR as return value + std::shared_ptr stencilIR = nullptr; + + int ret = 0; + if(GTClang) { + std::unique_ptr PPAction( + new gtclang::GTClangPreprocessorAction(context.get())); + ret |= !GTClang->ExecuteAction(*PPAction); + + if(ret == 0) { + std::unique_ptr ASTAction( + new gtclang::GTClangASTAction(context.get())); + ret |= !GTClang->ExecuteAction(*ASTAction); + stencilIR = ASTAction->getSIR(); + } + DAWN_LOG(INFO) << "Compilation finished " << (ret ? "with errors" : "successfully"); + } + + includeChecker.Restore(); + + return stencilIR; +} + } // namespace gtclang diff --git a/gtclang/src/gtclang/Driver/Driver.h b/gtclang/src/gtclang/Driver/Driver.h index f775a343e..b5b5a79db 100644 --- a/gtclang/src/gtclang/Driver/Driver.h +++ b/gtclang/src/gtclang/Driver/Driver.h @@ -19,6 +19,7 @@ #include "dawn/SIR/SIR.h" #include "dawn/Support/NonCopyable.h" +#include "gtclang/Driver/Options.h" #include "llvm/ADT/SmallVector.h" #include #include @@ -44,6 +45,10 @@ struct Driver : public dawn::NonCopyable { static bool isInitialized; }; +/// @brief Driver for the gtclang parser +/// @ingroup driver +std::shared_ptr run(const std::string& fileName, const ParseOptions& options = {}); + } // namespace gtclang #endif diff --git a/gtclang/src/gtclang/Driver/Options.h b/gtclang/src/gtclang/Driver/Options.h index 39405e481..69bbaa9d5 100644 --- a/gtclang/src/gtclang/Driver/Options.h +++ b/gtclang/src/gtclang/Driver/Options.h @@ -36,6 +36,27 @@ struct Options { #undef OPT }; +/// @brief Configuration options used by gtclang and the DAWN library (most of them are parsed from +/// the command-line) +/// +/// @ingroup driver +struct ParseOptions { +#define OPT(TYPE, NAME, DEFAULT_VALUE, OPTION, OPTION_SHORT, HELP, VALUE_NAME, HAS_VALUE, F_GROUP) \ + TYPE NAME = DEFAULT_VALUE; + // clang-format off +OPT(bool, DumpPP, false, "dump-pp", "", "Dump the preprocessed code to stdout", "", false, false) +OPT(std::string, ConfigFile, "", "config", "", + "json with a single key \"globals\" which contains \"key\" : \"value\" pairs of global variables and their respective values. " + "Global variables defined in the config file are treated as compile time constants and are replaced by their value", + "", true, false) +OPT(bool, DumpAST, false, "dump-ast", "", "Dump the clang AST of the preprocessed input to stdout", "", false, false) +OPT(bool, ReportPassPreprocessor, false, "report-pass-preprocessor", "", + "Print each line of the preprocessed source prepended by the line number (comments and indentation are removed)", "", false, true) +OPT(bool, Verbose, false, "verbose", "", "Enable verbose output by using step-by-step logging", "", false, false) + // clang-format on +#undef OPT +}; + } // namespace gtclang #endif diff --git a/gtclang/src/gtclang/Frontend/GTClangASTConsumer.cpp b/gtclang/src/gtclang/Frontend/GTClangASTConsumer.cpp index 220bb0bee..cebff3279 100644 --- a/gtclang/src/gtclang/Frontend/GTClangASTConsumer.cpp +++ b/gtclang/src/gtclang/Frontend/GTClangASTConsumer.cpp @@ -104,7 +104,7 @@ void GTClangASTConsumer::HandleTranslationUnit(clang::ASTContext& ASTContext) { DAWN_LOG(INFO) << "Done parsing translation unit"; if(context_->getASTContext().getDiagnostics().hasErrorOccurred()) { - DAWN_LOG(INFO) << "Erros occurred. Aborting"; + DAWN_LOG(INFO) << "Errors occurred. Aborting"; return; } diff --git a/gtclang/src/gtclang/gtc-parse.cpp b/gtclang/src/gtclang/gtc-parse.cpp index 8f97ff02d..95f9f41ba 100644 --- a/gtclang/src/gtclang/gtc-parse.cpp +++ b/gtclang/src/gtclang/gtc-parse.cpp @@ -17,6 +17,7 @@ #include "dawn/Serialization/SIRSerializer.h" #include "gtclang/Driver/CompilerInstance.h" #include "gtclang/Driver/Driver.h" +#include "gtclang/Driver/Options.h" #include "gtclang/Driver/OptionsParser.h" #include "gtclang/Frontend/GTClangASTAction.h" #include "gtclang/Frontend/GTClangContext.h" @@ -45,7 +46,7 @@ int main(int argc, char* argv[]) { ("v,verbose", "Set verbosity level to info. If set, use -o or --out to redirect SIR.") ("h,help", "Display usage."); - options.add_options() + options.add_options("Frontend") ("dump-ast", "Dump the clang AST.", cxxopts::value()->default_value("false")) ("dump-pp", "Dump the preprocessed file.", cxxopts::value()->default_value("false")); @@ -60,24 +61,12 @@ int main(int argc, char* argv[]) { return 0; } - // Create SIR as return value - std::shared_ptr returnSIR = nullptr; - - // Initialize the GTClangContext - auto context = std::make_unique(); - - // Skip Dawn - context->useDawn() = false; + gtclang::ParseOptions parseOptions; // Set options from cxxopts - context->getOptions().Verbose = result["verbose"].as(); - context->getOptions().DumpAST = result["dump-ast"].as(); - context->getOptions().DumpPP = result["dump-pp"].as(); - - const std::string InputFile = result["input"].as(); - llvm::SmallVector clangArgs; - clangArgs.push_back(argv[0]); - clangArgs.push_back(InputFile.c_str()); + parseOptions.Verbose = result["verbose"].as(); + parseOptions.DumpAST = result["dump-ast"].as(); + parseOptions.DumpPP = result["dump-pp"].as(); // we must call this only once llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); @@ -86,32 +75,8 @@ int main(int argc, char* argv[]) { // Call llvm_shutdown() on exit llvm::llvm_shutdown_obj Y; - // Initialize the Logger - auto logger = std::make_unique(); - if(context->getOptions().Verbose) - dawn::Logger::getSingleton().registerLogger(logger.get()); - - gtclang::GTClangIncludeChecker includeChecker; - if(clangArgs.size() > 1) - includeChecker.Update(clangArgs[1]); - - // Create GTClang - std::unique_ptr GTClang(gtclang::createCompilerInstance(clangArgs)); - - int ret = 0; - if(GTClang) { - std::unique_ptr PPAction( - new gtclang::GTClangPreprocessorAction(context.get())); - ret |= !GTClang->ExecuteAction(*PPAction); - - if(ret == 0) { - std::unique_ptr ASTAction( - new gtclang::GTClangASTAction(context.get())); - ret |= !GTClang->ExecuteAction(*ASTAction); - returnSIR = ASTAction->getSIR(); - } - DAWN_LOG(INFO) << "Compilation finished " << (ret ? "with errors" : "successfully"); - } + // Create SIR as return value + auto returnSIR = run(result["input"].as(), parseOptions); // Parse format to enumeration dawn::SIRSerializer::Format format; @@ -135,7 +100,5 @@ int main(int argc, char* argv[]) { std::cout << sirString; } - includeChecker.Restore(); - return 0; }