From fc2f341f63d095272b9ef4a076190cec1baf24dc Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Wed, 5 Oct 2016 17:42:48 +0200
Subject: [PATCH] move transformer to ufl and remove separated pymbolic visitor

---
 python/dune/perftool/pdelab/localoperator.py  |  2 +-
 python/dune/perftool/pymbolic/__init__.py     |  0
 python/dune/perftool/pymbolic/uflmapper.py    | 48 ---------------
 .../{loopy/transformer.py => ufl/visitor.py}  | 61 ++++++++++++++++---
 4 files changed, 55 insertions(+), 56 deletions(-)
 delete mode 100644 python/dune/perftool/pymbolic/__init__.py
 delete mode 100644 python/dune/perftool/pymbolic/uflmapper.py
 rename python/dune/perftool/{loopy/transformer.py => ufl/visitor.py} (89%)

diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py
index 6773ca1a..b7ad0e72 100644
--- a/python/dune/perftool/pdelab/localoperator.py
+++ b/python/dune/perftool/pdelab/localoperator.py
@@ -257,7 +257,7 @@ def generate_kernel(integrals):
         accterms = split_into_accumulation_terms(integrand)
 
         # Get a transformer instance for this kernel
-        from dune.perftool.loopy.transformer import UFL2LoopyVisitor
+        from dune.perftool.ufl.visitor import UFL2LoopyVisitor
         visitor = UFL2LoopyVisitor(measure, subdomain_id, dimension_indices)
 
         # Iterate over the terms and generate a kernel
diff --git a/python/dune/perftool/pymbolic/__init__.py b/python/dune/perftool/pymbolic/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/python/dune/perftool/pymbolic/uflmapper.py b/python/dune/perftool/pymbolic/uflmapper.py
deleted file mode 100644
index c8f10c79..00000000
--- a/python/dune/perftool/pymbolic/uflmapper.py
+++ /dev/null
@@ -1,48 +0,0 @@
-""" A multi function mapping UFL expressions to pymbolic expressions
-
-This mapper only defines handler for those UFL expression types that have an
-equivalent in pymbolic (mainly algebraic operations).
-
-This is mainly intended as a base class for anything mapping ufl to pymbolic.
-"""
-
-from __future__ import absolute_import
-from ufl.algorithms import MultiFunction
-from pymbolic.primitives import Product, Quotient, Subscript, Sum, Variable, Call
-
-# The constructed pymbolic expressions use n-ary operators instead of ufls binary operators
-from dune.perftool.ufl.flatoperators import get_operands
-
-
-class UFL2PymbolicMapper(MultiFunction):
-    def __init__(self):
-        super(UFL2PymbolicMapper, self).__init__()
-
-    call = MultiFunction.__call__
-
-    def product(self, o):
-        return Product(tuple(self.call(op) for op in get_operands(o)))
-
-    def float_value(self, o):
-        return o.value()
-
-    def int_value(self, o):
-        return o.value()
-
-    def division(self, o):
-        assert len(o.ufl_operands) == 2
-
-        return Quotient(self.call(o.ufl_operands[0]), self.call(o.ufl_operands[1]))
-
-    def sum(self, o):
-        return Sum(tuple(self.call(op) for op in get_operands(o)))
-
-    def zero(self, o):
-        return 0
-
-    def abs(self, o):
-        from ufl.classes import JacobianDeterminant
-        if isinstance(o.ufl_operands[0], JacobianDeterminant):
-            return self.call(o.ufl_operands[0])
-        else:
-            return Call('abs', self.call(o.ufl_operands[0]))
diff --git a/python/dune/perftool/loopy/transformer.py b/python/dune/perftool/ufl/visitor.py
similarity index 89%
rename from python/dune/perftool/loopy/transformer.py
rename to python/dune/perftool/ufl/visitor.py
index a99121b2..cfc03a1f 100644
--- a/python/dune/perftool/loopy/transformer.py
+++ b/python/dune/perftool/ufl/visitor.py
@@ -1,13 +1,10 @@
 """
-This is the module that contains the main transformation from ufl to loopy
-(with pdelab as the hardcoded generation target)
+This module defines the main visitor algorithm transforming ufl expressions
+to pymbolic and loopy.
 """
 
-from __future__ import absolute_import
-
 from dune.perftool import Restriction
 from dune.perftool.ufl.modified_terminals import ModifiedTerminalTracker
-from dune.perftool.pymbolic.uflmapper import UFL2PymbolicMapper
 from dune.perftool.pdelab.geometry import GeometryMapper
 from dune.perftool.generation import (domain,
                                       get_temporary_name,
@@ -27,9 +24,9 @@ from dune.perftool.pdelab.basis import (lfs_iname,
                                         )
 from dune.perftool.pdelab.quadrature import quadrature_iname
 from pymbolic.primitives import Subscript, Variable
+from ufl.algorithms import MultiFunction
 
-
-class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapper):
+class UFL2LoopyVisitor(ModifiedTerminalTracker, GeometryMapper):
     def __init__(self, measure, subdomain_id, dimension_indices):
         # Some variables describing the integral measure of this integral
         self.measure = measure
@@ -39,6 +36,9 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapp
         # Call base class constructors
         super(UFL2LoopyVisitor, self).__init__()
 
+    # Allow recursion through self.call(..)
+    call = MultiFunction.__call__
+
     def __call__(self, o):
         # Reset some state variables that are reinitialized for each accumulation term
         self.argshape = 0
@@ -166,6 +166,11 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapp
                     predicates=predicates
                     )
 
+    #
+    # Form argument/coefficients handlers:
+    # This is where the actual domain specific work happens
+    #
+
     def argument(self, o):
         # Correct the restriction on boundary integrals
         restriction = self.restriction
@@ -260,6 +265,10 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapp
             # And return a symbol
             return Variable(name)
 
+    #
+    # Handlers for all indexing related stuff
+    #
+
     def indexed(self, o):
         """ Although indexed is something that we want to handle in the pymbolic mapper we
         need to handle it here, as we have to give special treatment to indices into vector
@@ -334,3 +343,41 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapp
 
     def index(self, o):
         return self._index_or_fixed_index(o)
+
+    #
+    # Handlers for arithmetic operators and functions
+    # Those handlers would be valid in any code going from UFL to pymbolic
+    #
+
+    def product(self, o):
+        from dune.perftool.ufl.flatoperators import get_operands
+        from pymbolic.primitives import Product
+        return Product(tuple(self.call(op) for op in get_operands(o)))
+
+    def float_value(self, o):
+        return o.value()
+
+    def int_value(self, o):
+        return o.value()
+
+    def division(self, o):
+        assert len(o.ufl_operands) == 2
+
+        from pymbolic.primitives import Quotient
+        return Quotient(self.call(o.ufl_operands[0]), self.call(o.ufl_operands[1]))
+
+    def sum(self, o):
+        from dune.perftool.ufl.flatoperators import get_operands
+        from pymbolic.primitives import Sum
+        return Sum(tuple(self.call(op) for op in get_operands(o)))
+
+    def zero(self, o):
+        return 0
+
+    def abs(self, o):
+        from ufl.classes import JacobianDeterminant
+        if isinstance(o.ufl_operands[0], JacobianDeterminant):
+            return self.call(o.ufl_operands[0])
+        else:
+            from pymbolic.primitives import Call
+            return Call('abs', self.call(o.ufl_operands[0]))
-- 
GitLab