def generate_kernel(slate_expr, tsfc_parameters=None): cpu_time = time.time() # TODO: Get PyOP2 to write into mixed dats if slate_expr.is_mixed: raise NotImplementedError("Compiling mixed slate expressions") if len(slate_expr.ufl_domains()) > 1: raise NotImplementedError("Multiple domains not implemented.") Citations().register("Gibson2018") # Create a builder for the Slate expression builder = LocalKernelBuilder(expression=slate_expr, tsfc_parameters=tsfc_parameters) # Keep track of declared temporaries declared_temps = {} statements = [] # Declare terminal tensor temporaries terminal_declarations = terminal_temporaries(builder, declared_temps) statements.extend(terminal_declarations) # Generate assembly calls for tensor assembly subkernel_calls = tensor_assembly_calls(builder) statements.extend(subkernel_calls) # Create coefficient temporaries if necessary if builder.coefficient_vecs: coefficient_temps = coefficient_temporaries(builder, declared_temps) statements.extend(coefficient_temps) # Create auxiliary temporaries/expressions (if necessary) statements.extend(auxiliary_expressions(builder, declared_temps)) # Generate the kernel information with complete AST kinfo = generate_kernel_ast(builder, statements, declared_temps) # Cache the resulting kernel idx = tuple([0] * slate_expr.rank) logger.info(GREEN % "compile_slate_expression finished in %g seconds.", time.time() - cpu_time) return (SplitKernel(idx, kinfo), )
def compile_expression(slate_expr, tsfc_parameters=None): """Takes a Slate expression `slate_expr` and returns the appropriate :class:`firedrake.op2.Kernel` object representing the Slate expression. :arg slate_expr: a :class:'TensorBase' expression. :arg tsfc_parameters: an optional `dict` of form compiler parameters to be passed onto TSFC during the compilation of ufl forms. Returns: A `tuple` containing a `SplitKernel(idx, kinfo)` """ if not isinstance(slate_expr, slate.TensorBase): raise ValueError("Expecting a `TensorBase` object, not %s" % type(slate_expr)) # TODO: Get PyOP2 to write into mixed dats if slate_expr.is_mixed: raise NotImplementedError("Compiling mixed slate expressions") if len(slate_expr.ufl_domains()) > 1: raise NotImplementedError("Multiple domains not implemented.") # If the expression has already been symbolically compiled, then # simply reuse the produced kernel. if slate_expr._metakernel_cache is not None: return slate_expr._metakernel_cache # Create a builder for the Slate expression builder = LocalKernelBuilder(expression=slate_expr, tsfc_parameters=tsfc_parameters) # Keep track of declared temporaries declared_temps = {} statements = [] # Declare terminal tensor temporaries terminal_declarations = terminal_temporaries(builder, declared_temps) statements.extend(terminal_declarations) # Generate assembly calls for tensor assembly subkernel_calls = tensor_assembly_calls(builder) statements.extend(subkernel_calls) # Create coefficient temporaries if necessary if builder.coefficient_vecs: coefficient_temps = coefficient_temporaries(builder, declared_temps) statements.extend(coefficient_temps) # Create auxiliary temporaries if necessary if builder.aux_exprs: aux_temps = auxiliary_temporaries(builder, declared_temps) statements.extend(aux_temps) # Generate the kernel information with complete AST kinfo = generate_kernel_ast(builder, statements, declared_temps) # Cache the resulting kernel idx = tuple([0] * slate_expr.rank) kernel = (SplitKernel(idx, kinfo), ) slate_expr._metakernel_cache = kernel return kernel