diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt index 415cd9c6354e3318db1675739c36a3f90bee2916..85e38089ee5a7389a34f1697ae7a6939e8cf8a45 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt @@ -1,2 +1,5 @@ -install(FILES DunePerftoolMacros.cmake +install(FILES deplist.py + DunePerftoolMacros.cmake + GeneratedSystemtest.cmake + perftool_sourcepath.py DESTINATION ${DUNE_INSTALL_MODULEDIR}) diff --git a/cmake/modules/DunePerftoolMacros.cmake b/cmake/modules/DunePerftoolMacros.cmake index 8c8aa346eb97e62cdefaac552007473f8e769385..ca33bfae93d7bcedc198d864518f424944924efb 100644 --- a/cmake/modules/DunePerftoolMacros.cmake +++ b/cmake/modules/DunePerftoolMacros.cmake @@ -96,23 +96,18 @@ function(add_generated_executable) endif() if(NOT GEN_SOURCE) # Generate a driver file - set(GEN_DRIVER ${GEN_TARGET}_driver.hh) - add_custom_command(OUTPUT ${GEN_DRIVER} + set(GEN_SOURCE ${GEN_TARGET}_driver.cc) + add_custom_command(OUTPUT ${GEN_SOURCE} COMMAND ${CMAKE_BINARY_DIR}/run-in-dune-env generate_driver --uflfile ${GEN_UFLFILE} --ini-file ${GEN_INIFILE} --target-name ${GEN_TARGET} - --driver-file ${GEN_DRIVER} + --driver-file ${GEN_SOURCE} --project-basedir ${CMAKE_BINARY_DIR} ${GEN_FORM_COMPILER_ARGS} DEPENDS ${GEN_UFLFILE} ${UFL2PDELAB_SOURCES} ${GEN_DEPENDS} ${DUNE_PERFTOOL_ADDITIONAL_PYTHON_SOURCES} COMMENT "Generating driver for the target ${GEN_TARGET}" ) - set(GEN_SOURCE ${GEN_TARGET}_main.cc) - dune_module_path(MODULE dune-perftool - RESULT perftool_path - CMAKE_MODULES) - configure_file(${perftool_path}/StandardMain.cmake ${GEN_SOURCE}) endif() if(GEN_EXCLUDE_FROM_ALL) set(GEN_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL") @@ -143,7 +138,7 @@ function(add_generated_executable) set(header_deps ${header_deps} ${depdata___${op}}) endforeach() - add_executable(${GEN_TARGET} ${GEN_EXCLUDE_FROM_ALL} ${GEN_SOURCE} ${GEN_DRIVER} ${header_deps}) + add_executable(${GEN_TARGET} ${GEN_EXCLUDE_FROM_ALL} ${GEN_SOURCE} ${header_deps}) target_include_directories(${GEN_TARGET} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) add_dependencies(generation ${GEN_TARGET}) endfunction() diff --git a/cmake/modules/StandardMain.cmake b/cmake/modules/StandardMain.cmake deleted file mode 100644 index 028c2efc0b208705845326fc9a621697c72ec408..0000000000000000000000000000000000000000 --- a/cmake/modules/StandardMain.cmake +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <dune/common/parallel/mpihelper.hh> -#include <dune/common/exceptions.hh> - -#include"@GEN_DRIVER@" - -int main(int argc, char** argv) -{ - try{ - //Maybe initialize Mpi - Dune::MPIHelper& helper = Dune::MPIHelper::instance(argc, argv); - if(Dune::MPIHelper::isFake) - std::cout<< "This is a sequential program." << std::endl; - else - std::cout<<"I am rank "<<helper.rank()<<" of "<<helper.size() - <<" processes!"<<std::endl; - - if (driver(argc, argv)) - return 1; - else - return 0; - } - catch (Dune::Exception &e){ - std::cerr << "Dune reported error: " << e << std::endl; - return 1; - } - catch (...){ - std::cerr << "Unknown exception thrown!" << std::endl; - return 1; - } -} diff --git a/python/dune/perftool/cgen/__init__.py b/python/dune/perftool/cgen/__init__.py index 128c4dedffb347b256ed64b518fdde9009ce9344..24af73e0d8a2b6dfce3c1146d86c9eeccf7e5a2a 100644 --- a/python/dune/perftool/cgen/__init__.py +++ b/python/dune/perftool/cgen/__init__.py @@ -3,6 +3,7 @@ from __future__ import absolute_import from cgen import * from dune.perftool.cgen.clazz import Class +from dune.perftool.cgen.exceptions import TryCatchBlock, CatchBlock class Namespace(PrivateNamespace): diff --git a/python/dune/perftool/cgen/exceptions.py b/python/dune/perftool/cgen/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..434b3a62eb7dbc7d4fcc2fbe40cb41b53e202401 --- /dev/null +++ b/python/dune/perftool/cgen/exceptions.py @@ -0,0 +1,40 @@ +""" Add Try/Catch blocks to cgen """ + +from cgen import Block, Generable, Value + + +class CatchBlock(Generable): + def __init__(self, exc_decl, catch_block): + assert isinstance(exc_decl, Value) + self.exc_decl = exc_decl + assert isinstance(catch_block, Block) + self.catch_block = catch_block + + def generate(self): + yield "catch ({})\n".format("".join(self.exc_decl.generate(with_semicolon=False))) + for item in self.catch_block.generate(): + yield item + yield "\n" + + +class TryCatchBlock(Generable): + def __init__(self, try_block, catch_blocks): + # Store the try block + assert isinstance(try_block, Block) + self.try_block = try_block + + assert all(isinstance(b, CatchBlock) for b in catch_blocks) + self.catch_blocks = catch_blocks + + def generate(self): + # Yield the try block + yield "\n" + yield "try\n" + for item in self.try_block.generate(): + yield item + yield "\n" + + # and now yield all the catch blocks + for catch_block in self.catch_blocks: + for item in catch_block.generate(): + yield item diff --git a/python/dune/perftool/generation/cpp.py b/python/dune/perftool/generation/cpp.py index 0f44b6950ef9b111f90f0d7a922835912c5b4500..858dc1fcaf50d07b08c044525db994f85ca8de29 100644 --- a/python/dune/perftool/generation/cpp.py +++ b/python/dune/perftool/generation/cpp.py @@ -18,7 +18,7 @@ template_parameter = generator_factory(item_tags=("template_param",), context_ta class_basename = generator_factory(item_tags=("basename",), context_tags=("classtag",)) -@generator_factory(item_tags=("file", "include"), context_tags=("filetag",)) +@generator_factory(item_tags=("file", "include"), context_tags=("filetag",), counted=True) def include_file(include, system=False): return cgen.Include(include, system=system) diff --git a/python/dune/perftool/pdelab/driver/__init__.py b/python/dune/perftool/pdelab/driver/__init__.py index 4a832ba7709c9f8ca7f7c6f6380230f43fa55579..c859c99d0ab964e298a55bf2c9854f170c507599 100644 --- a/python/dune/perftool/pdelab/driver/__init__.py +++ b/python/dune/perftool/pdelab/driver/__init__.py @@ -232,6 +232,12 @@ def check_parallel_execution(): def generate_driver(): + # Guarantee that config.h is the very first include in the generated file + include_file("config.h", filetag="driver") + + # Make sure that the MPI helper is instantiated + name_mpihelper() + # Add check to c++ file if this program should only be used in parallel mode if get_option("parallel"): check_parallel_execution() @@ -273,7 +279,7 @@ def generate_driver(): from dune.perftool.generation import retrieve_cache_items from cgen import FunctionDeclaration, FunctionBody, Block, Value, LineComment, Line - driver_signature = FunctionDeclaration(Value('bool', 'driver'), [Value('int', 'argc'), Value('char**', 'argv')]) + driver_signature = FunctionDeclaration(Value('int', 'main'), [Value('int', 'argc'), Value('char**', 'argv')]) contents = [] @@ -307,12 +313,27 @@ def generate_driver(): contents.insert(len(contents) - 1, Line(text="DUMP_TIMER({}, driver, {}, true);\n".format(get_option("instrumentation_level"), timestream))) contents.insert(0, Line(text="\n")) driver_body = Block(contents) + + # Wrap a try/catch block around the driver body + from dune.perftool.cgen import CatchBlock, TryCatchBlock, Value, Block, Line + catch_blocks = [CatchBlock(Value("Dune::Exception&", "e"), + Block([Line("std::cerr << \"Dune reported error: \" << e << std::endl;\n"), + Line("return 1;\n"), + ]) + ), + CatchBlock(Value("std::exception&", "e"), + Block([Line("std::cerr << \"Unknown exception thrown!\" << std::endl;\n"), + Line("return 1;\n"), + ]) + ) + ] + driver_body = Block([TryCatchBlock(driver_body, catch_blocks)]) driver = FunctionBody(driver_signature, driver_body) filename = get_option("driver_file") from dune.perftool.file import generate_file - generate_file(filename, "driver", [driver]) + generate_file(filename, "driver", [driver], headerguard=False) # Reset the caching data structure from dune.perftool.generation import delete_cache_items