From 7c27277d23dee19f117be8883b77730043dc961a Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Wed, 6 Dec 2017 11:36:14 +0100
Subject: [PATCH] Implement a printing facility for vectorization strategies

---
 python/dune/perftool/loopy/symbolic.py        |  2 +-
 python/dune/perftool/sumfact/accumulation.py  |  3 +++
 python/dune/perftool/sumfact/basis.py         |  3 +++
 python/dune/perftool/sumfact/symbolic.py      | 12 +++++++++++
 python/dune/perftool/sumfact/tabulation.py    | 16 +++++++++++++++
 python/dune/perftool/sumfact/vectorization.py | 20 +++++++++++++++++++
 6 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/python/dune/perftool/loopy/symbolic.py b/python/dune/perftool/loopy/symbolic.py
index a592c461..01a99225 100644
--- a/python/dune/perftool/loopy/symbolic.py
+++ b/python/dune/perftool/loopy/symbolic.py
@@ -49,7 +49,7 @@ def walk_map_sumfact_kernel(self, expr, *args):
 
 
 def stringify_map_sumfact_kernel(self, expr, *args):
-    return "SUMFACT"
+    return str(expr)
 
 
 def dependency_map_sumfact_kernel(self, expr):
diff --git a/python/dune/perftool/sumfact/accumulation.py b/python/dune/perftool/sumfact/accumulation.py
index 53d949c9..3c935161 100644
--- a/python/dune/perftool/sumfact/accumulation.py
+++ b/python/dune/perftool/sumfact/accumulation.py
@@ -92,6 +92,9 @@ class AlreadyAssembledInput(SumfactKernelInputBase):
     def __hash__(self):
         return hash(self.index)
 
+    def __str__(self):
+        return "Input{}".format(self.index[0])
+
 
 class SumfactAccumulationInfo(ImmutableRecord):
     def __init__(self,
diff --git a/python/dune/perftool/sumfact/basis.py b/python/dune/perftool/sumfact/basis.py
index 1c1823df..889f464f 100644
--- a/python/dune/perftool/sumfact/basis.py
+++ b/python/dune/perftool/sumfact/basis.py
@@ -64,6 +64,9 @@ class LFSSumfactKernelInput(SumfactKernelInputBase, ImmutableRecord):
                                  restriction=restriction,
                                  )
 
+    def __str__(self):
+        return "{}".format(self.coeff_func(self.restriction))
+
     def realize(self, sf, index, insn_dep):
         lfs = name_lfs(self.element, self.restriction, self.element_index)
         basisiname = sumfact_iname(name_lfs_bound(lfs), "basis")
diff --git a/python/dune/perftool/sumfact/symbolic.py b/python/dune/perftool/sumfact/symbolic.py
index 44ae9f79..857a1d97 100644
--- a/python/dune/perftool/sumfact/symbolic.py
+++ b/python/dune/perftool/sumfact/symbolic.py
@@ -146,6 +146,12 @@ class SumfactKernel(SumfactKernelBase, ImmutableRecord, prim.Variable):
     def stringifier(self):
         return lp.symbolic.StringifyMapper
 
+    def __str__(self):
+        # Above stringifier just calls back into this
+        return "SF{}:[{}]->[{}]".format(self.stage,
+                                        str(self.input),
+                                        ", ".join(str(m) for m in self.matrix_sequence))
+
     mapper_method = "map_sumfact_kernel"
 
     #
@@ -385,6 +391,12 @@ class VectorizedSumfactKernel(SumfactKernelBase, ImmutableRecord, prim.Variable)
     def stringifier(self):
         return lp.symbolic.StringifyMapper
 
+    def __str__(self):
+        # Above stringifier just calls back into this
+        return "VSF{}:[{}]->[{}]".format(self.stage,
+                                         ", ".join(str(k.input) for k in self.kernels),
+                                         ", ".join(str(mat) for mat in self.matrix_sequence))
+
     mapper_method = "map_vectorized_sumfact_kernel"
 
     init_arg_names = ("kernels", "horizontal_width", "vertical_width", "buffer", "insn_dep")
diff --git a/python/dune/perftool/sumfact/tabulation.py b/python/dune/perftool/sumfact/tabulation.py
index 177c476b..c4ce095b 100644
--- a/python/dune/perftool/sumfact/tabulation.py
+++ b/python/dune/perftool/sumfact/tabulation.py
@@ -63,6 +63,15 @@ class BasisTabulationMatrix(BasisTabulationMatrixBase, ImmutableRecord):
                                  slice_index=slice_index,
                                  )
 
+    def __str__(self):
+        return "{}{}A{}{}{}" \
+                .format("face{}_".format(self.face) if self.face is not None else "",
+                        "d" if self.derivative else "",
+                        self.basis_size,
+                        "T" if self.transpose else "",
+                        "_slice{}".format(self.slice_index) if self.slice_size is not None else "",
+                        )
+
     @property
     def rows(self):
         if self.transpose:
@@ -131,6 +140,13 @@ class BasisTabulationMatrixArray(BasisTabulationMatrixBase):
             width = len(tabs)
         self.width = width
 
+    def __str__(self):
+        abbrevs = tuple("{}A{}{}".format("d" if t.derivative else "",
+                                         self.basis_size,
+                                         "s{}".format(t.slice_index) if t.slice_size is not None else "")
+                        for t in self.tabs)
+        return "_".join(abbrevs)
+
     @property
     def quadrature_size(self):
         return self.tabs[0].quadrature_size
diff --git a/python/dune/perftool/sumfact/vectorization.py b/python/dune/perftool/sumfact/vectorization.py
index 6261a380..53a5c278 100644
--- a/python/dune/perftool/sumfact/vectorization.py
+++ b/python/dune/perftool/sumfact/vectorization.py
@@ -203,6 +203,26 @@ def greedy_vectorization_strategy(sumfacts, width):
     return result
 
 
+def print_vectorization_strategy(strategy):
+    qp, strategy = strategy
+    print "\nPrinting potential vectorization strategy:"
+    print "Quadrature point tuple: {}".format(qp)
+
+    # Look for all realizations in the strategy and iterate over them
+    cache_keys = frozenset(v.cache_key for v in strategy.values())
+    for ck in cache_keys:
+        # Filter all the kernels that are realized by this and print
+        for key in strategy:
+            if strategy[key].cache_key == ck:
+                print "{}:".format(key)
+
+        # Find one representative to print
+        for val in strategy.values():
+            if val.cache_key == ck:
+                print "    {}".format(val)
+                break
+
+
 def decide_vectorization_strategy():
     """ Decide how to vectorize!
     Note that the vectorization of the quadrature loop is independent of this,
-- 
GitLab