diff --git a/python/dune/codegen/options.py b/python/dune/codegen/options.py index eb9d73aef388124ab61ad75faa0aa15f1252d3fb..9a29c5701523c62d7e68ea4c2b9faaa403966caa 100644 --- a/python/dune/codegen/options.py +++ b/python/dune/codegen/options.py @@ -3,132 +3,58 @@ from argparse import ArgumentParser from os.path import abspath from pytools import ImmutableRecord, memoize +import cerberus +import yaml +import pkg_resources +from six.moves import configparser +from six import StringIO from contextlib import contextmanager -from dune.testtools.parametertree.parser import parse_ini_file +class CodegenOptionsValidator(cerberus.Validator): + # A validator that accepts the helpstr field in the scheme + def _validate_helpstr(self, helpstr, field, value): + """ Describe the option -class CodegenOption(ImmutableRecord): - """ Data structure representing a single formcompiler option """ - def __init__(self, - default=None, - helpstr="Undocumented feature!", - process=lambda x: x, - _type=type(None), - ): - _type = type(default) - if issubclass(_type, type(None)): - _type = str - ImmutableRecord.__init__(self, - helpstr=helpstr, - default=default, - type=_type, - ) + The rule's arguments are validated against this schema: + {'type': 'string'} + """ + return True + + +def _load_scheme(form=False): + resource_package = __name__ + if form: + resource_path = 'options_form.yaml' + else: + resource_path = 'options_global.yaml' + yaml_stream = pkg_resources.resource_string(resource_package, resource_path) + try: + scheme = yaml.safe_load(yaml_stream) + except Exception as e: + raise e + return scheme class CodegenGlobalOptionsArray(ImmutableRecord): """ A collection of form compiler arguments """ def __init__(self, **kwargs): - opts = {k: v.default for k, v in CodegenGlobalOptionsArray.__dict__.items() if isinstance(v, CodegenOption)} + # Set the default values from the yaml scheme as defaults + scheme = _load_scheme() + opts = {k: v['default'] for k, v in scheme.items()} opts.update(**kwargs) ImmutableRecord.__init__(self, **opts) - # Arguments that are to be set from the outside - uflfile = CodegenOption(helpstr="the UFL file to compile") - debug_cache_with_stack = CodegenOption(default=False, helpstr="Store stack along with cache objects. Makes debugging caching issues easier.") - driver_file = CodegenOption(helpstr="The filename for the generated driver header") - explicit_time_stepping = CodegenOption(default=False, helpstr="use explicit time stepping") - time_stepping_order = CodegenOption(default=1, helpstr="Order of the time stepping method") - exact_solution_expression = CodegenOption(helpstr="name of the exact solution expression in the ufl file") - compare_l2errorsquared = CodegenOption(helpstr="maximal allowed l2 error squared of difference between numerical solution and interpolation of exact solution (NOTE: requires --exact-solution-expression)") - grid_info = CodegenOption(default=None, helpstr="Path to file with information about facedir and facemod variations. This can be used to limit the generation of skeleton kernels.") - l2error_tree_path = CodegenOption(default=None, helpstr="Tree pathes that should be considered for l2 error calculation. Default None means we take all of them into account.") - ini_file = CodegenOption(helpstr="An inifile to use. A generated driver will be hard-coded to it, a [formcompiler] section will be used as default values to form compiler arguments (use snake case)") - opcounter = CodegenOption(default=False, helpstr="Count operations. Note: In this case only operator applications are generated since solving and operator counting does not work. You probably want to set instrumentation level>0.") - performance_measuring = CodegenOption(default=False, helpstr="Generate opcounter codepath, but only measure times!") - instrumentation_level = CodegenOption(default=0, helpstr="Control time/opcounter measurements. 0-do nothing, 1-measure program as a whole, 2-operator applications, 3-measure kernel (eg. alpha-volume, ...), 4-parts of kernel (eg. stage 1-3 of SF)") - project_basedir = CodegenOption(helpstr="The base (build) directory of the dune-codegen project") - architecture = CodegenOption(default="haswell", helpstr="The architecture to optimize for. Possible values: haswell|knl|skylake") - yaspgrid_offset = CodegenOption(default=False, helpstr="Set to true if you want a yasp grid where the lower left corner is not in the origin.") - grid_unstructured = CodegenOption(default=False, helpstr="Set to true if you want to use an unstructured grid.") - grid_consistent = CodegenOption(default=False, helpstr="The used grid is already consistent.") - precision_bits = CodegenOption(default=64, helpstr="The number of bits for the floating point type") - overlapping = CodegenOption(default=False, helpstr="Use an overlapping solver and constraints. You still need to make sure to construct a grid with overlap! The parallel option will be set automatically.") - operators = CodegenOption(default="r", helpstr="A comma separated list of operators, each name will be interpreted as a subsection name within the formcompiler section") - target_name = CodegenOption(default=None, helpstr="The target name from CMake") - operator_to_build = CodegenOption(default=None, helpstr="The operators from the list that is about to be build now. CMake sets this one!!!") - debug_interpolate_input = CodegenOption(default=False, helpstr="Should the input for printresidual and printmatix be interpolated (instead of random input).") - use_likwid = CodegenOption(default=False, helpstr="Use likwid instead of own performance measurements.") - use_sde = CodegenOption(default=False, helpstr="Use sde instead of own performance measurements.") - autotune_google_benchmark = CodegenOption(default=False, helpstr="Use google-benchmark library for autotuning (when autotuning is activated).") - with_mpi = CodegenOption(default=True, helpstr="The module was configured with mpi") - permuting_horizontal_add = CodegenOption(default=True, helpstr="Whether SIMD horizontal_add should use a permuting implementation.") - - # Arguments that are mainly to be set by logic depending on other options - max_vector_width = CodegenOption(default=256, helpstr=None) - parallel = CodegenOption(default=False, helpstr="Mark that this program should be run in parallel. If set to true the c++ code will check that there are more than 1 MPI-ranks involved and the error computation will use communication.") - class CodegenFormOptionsArray(ImmutableRecord): """ A collection of form-specific form compiler arguments """ def __init__(self, **kwargs): - opts = {k: v.default for k, v in CodegenFormOptionsArray.__dict__.items() if isinstance(v, CodegenOption)} + # Set the default values from the yaml scheme as defaults + scheme = _load_scheme(form=True) + opts = {k: v['default'] for k, v in scheme.items()} opts.update(**kwargs) ImmutableRecord.__init__(self, **opts) - # Form specific options - form = CodegenOption(default=None, helpstr="The name of the UFL object representing the form in the UFL file") - filename = CodegenOption(default=None, helpstr="The filename to use for this LocalOperator") - classname = CodegenOption(default=None, helpstr="The name of the C++ class to generate") - numerical_jacobian = CodegenOption(default=False, helpstr="use numerical jacobians (only makes sense, if uflpdelab for some reason fails to generate analytic jacobians)") - matrix_free = CodegenOption(default=False, helpstr="Generate jacobian_apply_* methods for matrix free solvers") - print_transformations = CodegenOption(default=False, helpstr="print out dot files after ufl tree transformations") - print_transformations_dir = CodegenOption(default=".", helpstr="place where to put dot files (can be omitted)") - quadrature_order = CodegenOption(_type=int, helpstr="Quadrature order used for all integrals.") - diagonal_transformation_matrix = CodegenOption(default=False, helpstr="set option if the jacobian of the transformation is diagonal (axiparallel grids)") - constant_transformation_matrix = CodegenOption(default=False, helpstr="set option if the jacobian of the transformation is constant on a cell") - fastdg = CodegenOption(default=False, helpstr="Use FastDGGridOperator from PDELab.") - sumfact = CodegenOption(default=False, helpstr="Use sumfactorization") - sumfact_regular_jacobians = CodegenOption(default=False, helpstr="Generate non sum-factorized jacobians (only useful if sumfact is set)") - sumfact_on_boundary = CodegenOption(default=True, helpstr="Whether boundary integrals should be vectorized. It might not be worth the hassle...") - sumfact_optimize_loop_order = CodegenOption(default=False, helpstr="Optimize order of loops in sumf factorization function using autotuning.") - sumfact_performance_transformations = CodegenOption(default=False, helpstr="Apply sum factorization specific performance transformations.") - sumfact_performance_transformations_testrun = CodegenOption(default=0, helpstr="If larger than zero determines test case to run.") - vectorization_quadloop = CodegenOption(default=False, helpstr="whether to generate code with explicit vectorization") - vectorization_strategy = CodegenOption(default="none", helpstr="The identifier of the vectorization cost model. Possible values: none|explicit|model|target|autotune") - vectorization_not_fully_vectorized_error = CodegenOption(default=False, helpstr="throw an error if nonquadloop vectorization did not fully vectorize") - vectorization_horizontal = CodegenOption(default=None, helpstr="an explicit value for horizontal vectorization read by the 'explicit' strategy") - vectorization_vertical = CodegenOption(default=None, helpstr="an explicit value for vertical vectorization read by the 'explicit' strategy") - vectorization_padding = CodegenOption(default=None, helpstr="an explicit value for the allowed padding in vectorization") - vectorization_allow_quadrature_changes = CodegenOption(default=False, helpstr="whether the vectorization strategy is allowed to alter quadrature point numbers") - vectorization_list_index = CodegenOption(default=None, helpstr="Which vectorization to pick from a list (only valid with vectorization_strategy=fromlist).") - vectorization_jacobians = CodegenOption(default=True, helpstr="Whether to attempt to vectorize jacobians (takes time, often not needed)") - vectorization_target = CodegenOption(_type=float, helpstr="The cost function target for the 'target' cost model. Only needed to verify the cost model itself, do not use light-heartedly!!!") - simplify = CodegenOption(default=False, helpstr="Whether to simplify expressions using sympy") - generate_jacobians = CodegenOption(default=True, helpstr="Whether jacobian_* methods should be generated. This is set to false automatically, when numerical_jacobian is set to true.") - generate_jacobian_apply = CodegenOption(default=False, helpstr="Wether jacobian_allpy_* methods should be generated.") - generate_residuals = CodegenOption(default=True, helpstr="Whether alpha_* methods should be generated.") - unroll_dimension_loops = CodegenOption(default=False, helpstr="whether loops over the geometric dimension should be unrolled") - blockstructured = CodegenOption(default=False, helpstr="Use block structure") - number_of_blocks = CodegenOption(default=1, helpstr="Number of sub blocks in one direction") - vectorization_blockstructured = CodegenOption(default=False, helpstr="Vectorize block structuring") - vectorization_blockstructured_tail = CodegenOption(default=True, helpstr="Try to fully vectorize block structuring even when 'nunmber_of_blocks' is not divisible by vector length") - vectorization_blockstructured_tail_ordering = CodegenOption(default='consecutive', helpstr="Ordering of the tail w.r.t the vectorized loop. Possible values: consecutive|blocked") - adjoint = CodegenOption(default=False, helpstr="Generate adjoint operator") - control = CodegenOption(default=False, helpstr="Generate operator of derivative w.r.t. the control variable") - objective_function = CodegenOption(default=None, helpstr="Name of form representing the objective function in UFL file") - control_variable = CodegenOption(default=None, helpstr="Name of control variable in UFL file") - block_preconditioner_diagonal = CodegenOption(default=False, helpstr="Whether this operator should implement the diagonal part of a block preconditioner") - block_preconditioner_offdiagonal = CodegenOption(default=False, helpstr="Whether this operator should implement the off-diagonal part of a block preconditioner") - block_preconditioner_pointdiagonal = CodegenOption(default=False, helpstr="Whether this operator should implement the point diagonal part of a block preconditioner") - geometry_mixins = CodegenOption(default="generic", helpstr="A comma separated list of mixin identifiers to use for geometries. Currently implemented mixins: generic, axiparallel, equidistant, sumfact_multilinear, sumfact_axiparallel, sumfact_equidistant") - quadrature_mixins = CodegenOption(default="generic", helpstr="A comma separated list of mixin identifiers to use for quadrature. Currently implemented: generic, sumfact") - basis_mixins = CodegenOption(default="generic", helpstr="A comma separated list of mixin identifiers to use for basis function evaluation. Currently implemented: generic, sumfact") - accumulation_mixins = CodegenOption(default="generic", helpstr="A comma separated list of mixin identifiers to use for accumulation. Currently implemented: generic, sumfact, control, blockstructured") - enable_volume = CodegenOption(default=True, helpstr="Whether to assemble volume integrals") - enable_skeleton = CodegenOption(default=True, helpstr="Whether to assemble skeleton integrals") - enable_boundary = CodegenOption(default=True, helpstr="Whether to assemble boundary integrals") - # Until more sophisticated logic is needed, we keep the actual option data in this module _global_options = CodegenGlobalOptionsArray() @@ -136,17 +62,17 @@ _form_options = {} def show_options(): - def subopt(arr): - for k, v in arr.__dict__.items(): - if isinstance(v, CodegenOption) and v.helpstr is not None: - print("{}\n {}".format(k, v.helpstr)) + def print_options(form=False): + scheme = _load_scheme(form=form) + for k, v in scheme.items(): + print("{}\n {}".format(k, v['helpstr'])) print("This is a summary of options available for the code generation process:\n") print("The following options can be given in the [formcompiler] section:") - subopt(CodegenGlobalOptionsArray) + print_options(form=False) print("\nThefollowing options can be given in a form-specific subsection of [formcompiler]:") - subopt(CodegenFormOptionsArray) + print_options(form=True) def initialize_options(): @@ -155,6 +81,38 @@ def initialize_options(): _global_options = update_options_from_commandline(_global_options) _global_options = update_options_from_inifile(_global_options) + # Validate global options + scheme_global = _load_scheme() + validator_global = CodegenOptionsValidator(scheme_global, require_all=True) + if not validator_global.validate(_global_options.__dict__): + raise RuntimeError("Global options validation failed: {}".format(validator_global.errors)) + + # Validate form options + scheme_form = _load_scheme(form=True) + validator_form = CodegenOptionsValidator(scheme_form, require_all=True) + for form in [i.strip() for i in _global_options.operators.split(",")]: + if not validator_form.validate(_form_options[form].__dict__): + raise RuntimeError("Form options validation failed: {}".format(validator_form.errors)) + + +def _scheme_type_to_type(scheme_type): + assert isinstance(scheme_type, str) + if scheme_type == 'string': + return str + if scheme_type == 'boolean': + return bool + if scheme_type == 'integer': + return int + if scheme_type == 'float': + return float + + +def _transform_type(scheme_type, a): + if scheme_type == 'boolean': + return bool(int(a)) + else: + return _scheme_type_to_type(scheme_type)(a) + def update_options_from_commandline(opt): """ Return an options array object with updated values from the commandline """ @@ -163,10 +121,15 @@ def update_options_from_commandline(opt): epilog="Please report bugs to dominic.kempf@iwr.uni-heidelberg.de", ) parser.add_argument('--version', action='version', version='%(prog)s 0.1') - for k, v in type(opt).__dict__.items(): - if isinstance(v, CodegenOption) and v.helpstr is not None: + + # Load global options scheme + scheme = _load_scheme() + + # Add all options that have a helpstr to the command line parser + for k, v in scheme.items(): + if v['helpstr'] is not None: cmdopt = "--{}".format(k.replace('_', '-')) - parser.add_argument(cmdopt, help=v.helpstr, type=v.type) + parser.add_argument(cmdopt, help=v['helpstr'], type=_scheme_type_to_type(v['type'])) parsedargs = {k: v for k, v in vars(parser.parse_args()).items() if v is not None} return opt.copy(**parsedargs) @@ -174,20 +137,38 @@ def update_options_from_commandline(opt): def update_options_from_inifile(opt): """ Return an options array object with updated values from an inifile """ if opt.ini_file: - def parse_ini(section, opttype): - def _fix_types(k, v): - if hasattr(opttype, k) and getattr(opttype, k).type is bool: - return bool(eval(v)) - if hasattr(opttype, k): - return getattr(opttype, k).type(v) - return v - ini = parse_ini_file(opt.ini_file).get(section, {}) - return {k: _fix_types(k, v) for k, v in ini.items()} - - opt = opt.copy(**parse_ini("formcompiler", CodegenGlobalOptionsArray)) - # Also parse form-specific options + config = configparser.ConfigParser() + + # Read ini file + try: + config.read(opt.ini_file) + except configparser.MissingSectionHeaderError: + # Config parser doesn't like ini files where without section. For + # this case we introduce a [root] section on top. + ini_str = '[root]\n' + open(opt.ini_file, 'r').read() + ini_fp = StringIO(ini_str) + config = configparser.RawConfigParser() + config.readfp(ini_fp) + + # Parse global options + scheme = _load_scheme() + options = dict(config.items('formcompiler')) + for k, v in options.items(): + assert k in scheme + options[k] = _transform_type(scheme[k]['type'], v) + opt = opt.copy(**options) + + # Parse form options + scheme = _load_scheme(form=True) for form in [i.strip() for i in opt.operators.split(",")]: - _form_options[form] = CodegenFormOptionsArray(**parse_ini("formcompiler.{}".format(form), CodegenFormOptionsArray)) + section = 'formcompiler.{}'.format(form) + options = {} + if config.has_section(section): + options = dict(config.items('formcompiler.{}'.format(form))) + for k, v in options.items(): + assert k in scheme + options[k] = _transform_type(scheme[k]['type'], v) + _form_options[form] = CodegenFormOptionsArray(**options) return opt diff --git a/python/dune/codegen/options_form.yaml b/python/dune/codegen/options_form.yaml new file mode 100644 index 0000000000000000000000000000000000000000..97c0a733a327718009d25eaa32486747d21cfaa4 --- /dev/null +++ b/python/dune/codegen/options_form.yaml @@ -0,0 +1,215 @@ +accumulation_mixins: + type: string + default: "generic" + helpstr: "A comma separated list of mixin identifiers to use for accumulation. Currently implemented: generic, sumfact, control, blockstructured" +adjoint: + type: boolean + default: False + helpstr: "Generate adjoint operator" +basis_mixins: + type: string + default: "generic" + helpstr: "A comma separated list of mixin identifiers to use for basis function evaluation. Currently implemented: generic, sumfact" +block_preconditioner_diagonal: + type: boolean + default: False + helpstr: "Whether this operator should implement the diagonal part of a block preconditioner" +block_preconditioner_offdiagonal: + type: boolean + default: False + helpstr: "Whether this operator should implement the off-diagonal part of a block preconditioner" +block_preconditioner_pointdiagonal: + type: boolean + default: False + helpstr: "Whether this operator should implement the point diagonal part of a block preconditioner" +blockstructured: + type: boolean + default: False + helpstr: "Use block structure" +classname: + type: string + default: + nullable: True + helpstr: "The name of the C++ class to generate" +constant_transformation_matrix: + type: boolean + default: False + helpstr: "set option if the jacobian of the transformation is constant on a cell" +control: + type: boolean + default: False + helpstr: "Generate operator of derivative w.r.t. the control variable" +control_variable: + type: string + default: + nullable: True + helpstr: "Name of control variable in UFL file" +diagonal_transformation_matrix: + type: boolean + default: False + helpstr: "set option if the jacobian of the transformation is diagonal (axiparallel grids)" +enable_boundary: + type: boolean + default: True + helpstr: "Whether to assemble boundary integrals" +enable_skeleton: + type: boolean + default: True + helpstr: "Whether to assemble skeleton integrals" +enable_volume: + type: boolean + default: True + helpstr: "Whether to assemble volume integrals" +fastdg: + type: boolean + default: False + helpstr: "Use FastDGGridOperator from PDELab." +filename: + type: string + default: + nullable: True + helpstr: "The filename to use for this LocalOperator" +form: + type: string + default: + nullable: True + helpstr: "The name of the UFL object representing the form in the UFL file" +generate_jacobian_apply: + type: boolean + default: False + helpstr: "Wether jacobian_allpy_* methods should be generated." +generate_jacobians: + type: boolean + default: True + helpstr: "Whether jacobian_* methods should be generated. This is set to false automatically, when numerical_jacobian is set to true." +generate_residuals: + type: boolean + default: True + helpstr: "Whether alpha_* methods should be generated." +geometry_mixins: + type: string + default: "generic" + helpstr: "A comma separated list of mixin identifiers to use for geometries. Currently implemented mixins: generic, axiparallel, equidistant, sumfact_multilinear, sumfact_axiparallel, sumfact_equidistant" +matrix_free: + type: boolean + default: False + helpstr: "Generate jacobian_apply_* methods for matrix free solvers" +number_of_blocks: + type: integer + default: 1 + helpstr: "Number of sub blocks in one direction" +numerical_jacobian: + type: boolean + default: False + helpstr: "use numerical jacobians (only makes sense, if uflpdelab for some reason fails to generate analytic jacobians)" +objective_function: + type: string + default: + nullable: True + helpstr: "Name of form representing the objective function in UFL file" +print_transformations: + type: boolean + default: False + helpstr: "print out dot files after ufl tree transformations" +print_transformations_dir: + type: string + default: "." + helpstr: "place where to put dot files (can be omitted)" +quadrature_mixins: + type: string + default: "generic" + helpstr: "A comma separated list of mixin identifiers to use for quadrature. Currently implemented: generic, sumfact" +quadrature_order: + type: string + default: + nullable: True + helpstr: "Quadrature order used for all integrals." +simplify: + type: boolean + default: False + helpstr: "Whether to simplify expressions using sympy" +sumfact: + type: boolean + default: False + helpstr: "Use sumfactorization" +sumfact_on_boundary: + type: boolean + default: True + helpstr: "Whether boundary integrals should be vectorized. It might not be worth the hassle..." +sumfact_optimize_loop_order: + type: boolean + default: False + helpstr: "Optimize order of loops in sumf factorization function using autotuning." +sumfact_performance_transformations: + type: boolean + default: False + helpstr: "Apply sum factorization specific performance transformations." +sumfact_performance_transformations_testrun: + type: integer + default: 0 + helpstr: "If larger than zero determines test case to run." +sumfact_regular_jacobians: + type: boolean + default: False + helpstr: "Generate non sum-factorized jacobians (only useful if sumfact is set)" +unroll_dimension_loops: + type: boolean + default: False + helpstr: "whether loops over the geometric dimension should be unrolled" +vectorization_allow_quadrature_changes: + type: boolean + default: False + helpstr: "whether the vectorization strategy is allowed to alter quadrature point numbers" +vectorization_blockstructured: + type: boolean + default: False + helpstr: "Vectorize block structuring" +vectorization_blockstructured_tail: + type: boolean + default: True + helpstr: "Try to fully vectorize block structuring even when 'nunmber_of_blocks' is not divisible by vector length" +vectorization_blockstructured_tail_ordering: + type: string + default: "consecutive" + helpstr: "Ordering of the tail w.r.t the vectorized loop. Possible values: consecutive|blocked" +vectorization_horizontal: + type: string + default: + nullable: True + helpstr: "an explicit value for horizontal vectorization read by the 'explicit' strategy" +vectorization_jacobians: + type: boolean + default: True + helpstr: "Whether to attempt to vectorize jacobians (takes time, often not needed)" +vectorization_list_index: + type: string + default: + nullable: True + helpstr: "Which vectorization to pick from a list (only valid with vectorization_strategy=fromlist)." +vectorization_not_fully_vectorized_error: + type: boolean + default: False + helpstr: "throw an error if nonquadloop vectorization did not fully vectorize" +vectorization_padding: + type: string + default: + nullable: True + helpstr: "an explicit value for the allowed padding in vectorization" +vectorization_quadloop: + type: boolean + default: False + helpstr: "whether to generate code with explicit vectorization" +vectorization_strategy: + type: string + default: "none" + helpstr: "The identifier of the vectorization cost model. Possible values: none|explicit|model|target|autotune" +vectorization_target: + type: float + default: + nullable: True + helpstr: "The cost function target for the 'target' cost model. Only needed to verify the cost model itself, do not use light-heartedly!!!" +vectorization_vertical: + type: string + default: + nullable: True + helpstr: "an explicit value for vertical vectorization read by the 'explicit' strategy" \ No newline at end of file diff --git a/python/dune/codegen/options_global.yaml b/python/dune/codegen/options_global.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4db7aa253ae8e58810a25da9904622ca2f671cf9 --- /dev/null +++ b/python/dune/codegen/options_global.yaml @@ -0,0 +1,136 @@ +architecture: + type: string + default: "haswell" + helpstr: "The architecture to optimize for. Possible values: haswell|knl|skylake" +autotune_google_benchmark: + type: boolean + default: False + helpstr: "Use google-benchmark library for autotuning (when autotuning is activated)." +compare_l2errorsquared: + type: string + default: + nullable: True + helpstr: "maximal allowed l2 error squared of difference between numerical solution and interpolation of exact solution (NOTE: requires --exact-solution-expression)" +debug_cache_with_stack: + type: boolean + default: False + helpstr: "Store stack along with cache objects. Makes debugging caching issues easier." +debug_interpolate_input: + type: boolean + default: False + helpstr: "Should the input for printresidual and printmatix be interpolated (instead of random input)." +driver_file: + type: string + default: + nullable: True + helpstr: "The filename for the generated driver header" +exact_solution_expression: + type: string + default: + nullable: True + helpstr: "name of the exact solution expression in the ufl file" +explicit_time_stepping: + type: boolean + default: False + helpstr: "use explicit time stepping" +grid_consistent: + type: boolean + default: False + helpstr: "The used grid is already consistent" +grid_info: + type: string + default: + nullable: True + helpstr: "Path to file with information about facedir and facemod variations. This can be used to limit the generation of skeleton kernels." +grid_unstructured: + type: boolean + default: False + helpstr: "Set to true if you want to use an unstructured grid." +ini_file: + type: string + default: + nullable: True + helpstr: "An inifile to use. A generated driver will be hard-coded to it, a [formcompiler] section will be used as default values to form compiler arguments (use snake case)" +instrumentation_level: + type: integer + default: 0 + helpstr: "Control time/opcounter measurements. 0-do nothing, 1-measure program as a whole, 2-operator applications, 3-measure kernel (eg. alpha-volume, ...), 4-parts of kernel (eg. stage 1-3 of SF)" +l2error_tree_path: + type: string + default: + nullable: True + helpstr: "Tree pathes that should be considered for l2 error calculation. Default None means we take all of them into account." +opcounter: + type: boolean + default: False + helpstr: "Count operations. Note: In this case only operator applications are generated since solving and operator counting does not work. You probably want to set instrumentation level>0." +operator_to_build: + type: string + default: + nullable: True + helpstr: "The operators from the list that is about to be build now. CMake sets this one!!!" +operators: + type: string + default: "r" + helpstr: "A comma separated list of operators, each name will be interpreted as a subsection name within the formcompiler section" +overlapping: + type: boolean + default: False + helpstr: "Use an overlapping solver and constraints. You still need to make sure to construct a grid with overlap! The parallel option will be set automatically." +performance_measuring: + type: boolean + default: False + helpstr: "Generate opcounter codepath, but only measure times!" +permuting_horizontal_add: + type: boolean + default: True + helpstr: "Whether SIMD horizontal_add should use a permuting implementation." +precision_bits: + type: integer + default: 64 + helpstr: "The number of bits for the floating point type" +project_basedir: + type: string + default: + nullable: True + helpstr: "The base (build) directory of the dune-codegen project" +target_name: + type: string + default: + nullable: True + helpstr: "The target name from CMake" +time_stepping_order: + type: integer + default: 1 + helpstr: "Order of the time stepping method" +uflfile: + type: string + default: + nullable: True + helpstr: "the UFL file to compile" +use_likwid: + type: boolean + default: False + helpstr: "Use likwid instead of own performance measurements." +use_sde: + type: boolean + default: False + helpstr: "Use sde instead of own performance measurements." +with_mpi: + type: boolean + default: True + helpstr: "The module was configured with mpi" +yaspgrid_offset: + type: boolean + default: False + helpstr: "Set to true if you want a yasp grid where the lower left corner is not in the origin." + +# Arguments that are mainly to be set by logic depending on other options +max_vector_width: + type: integer + default: 256 + helpstr: None +parallel: + type: boolean + default: False + helpstr: "Mark that this program should be run in parallel. If set to true the c++ code will check that there are more than 1 MPI-ranks involved and the error computation will use communication." diff --git a/python/setup.py b/python/setup.py index 713ffbab9d5761f775764a67c2807a017a817da4..35c300e82115cf08d1cfb753e9ed66662427c5e4 100644 --- a/python/setup.py +++ b/python/setup.py @@ -42,7 +42,7 @@ setup(name='dune.codegen', 'dune.codegen.ufl', 'dune.codegen.ufl.transformations', ], - install_requires=['dune.testtools', 'sympy', 'frozendict', 'pytest', 'pytest-pep8', 'filelock'], + install_requires=['sympy', 'frozendict', 'pytest', 'pytest-pep8', 'filelock', 'cerberus', 'pyaml'], cmdclass={'test': PyTest}, entry_points = { "console_scripts": [ diff --git a/test/nonlinear/diffusivewave.mini b/test/nonlinear/diffusivewave.mini index e02ec95646d5838b95d3be5793adeebc4e060a72..f7c67fe5dd4b2fb7bf9d39b68cd9e8f9f5e93816 100644 --- a/test/nonlinear/diffusivewave.mini +++ b/test/nonlinear/diffusivewave.mini @@ -21,7 +21,7 @@ geometry_mixins = equidistant, sumfact_equidistant | expand sf sumfact = 0, 1 | expand sf fastdg = 0, 0 | expand sf -[formcompiler.operator] +[formcompiler.poisson] geometry_mixins = equidistant, sumfact_equidistant | expand sf sumfact = 0, 1 | expand sf fastdg = 0, 0 | expand sf diff --git a/test/poisson/opcount_poisson_dg_symdiff.mini b/test/poisson/opcount_poisson_dg_symdiff.mini index 186c4344f9fed7512cde913433145259a76bf7b5..90df6bdc2889d13e7fa849face5df6fc7e5daf2d 100644 --- a/test/poisson/opcount_poisson_dg_symdiff.mini +++ b/test/poisson/opcount_poisson_dg_symdiff.mini @@ -10,4 +10,6 @@ extension = vtu [formcompiler] opcounter = 1 instrumentation_level = 3 + +[formcompiler.r] geometry_mixins = equidistant