From 2a56e7bae429a014c285c1275b621e61392c9ef6 Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Mon, 8 Oct 2018 13:54:36 +0200
Subject: [PATCH] Add a penalty for quadrature point increase

This penalty accounts for the increased work in the quadrature loop.
Still a bit experimental.
---
 python/dune/perftool/sumfact/vectorization.py | 39 +++++++++++++++----
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/python/dune/perftool/sumfact/vectorization.py b/python/dune/perftool/sumfact/vectorization.py
index 58df262f..cb6e8793 100644
--- a/python/dune/perftool/sumfact/vectorization.py
+++ b/python/dune/perftool/sumfact/vectorization.py
@@ -99,6 +99,20 @@ def target_costfunction(sf):
     return abs(realcost - ratio * target)
 
 
+def accumulate_for_strategy(strategy, func, reduce=lambda x, y: x + y, start=0):
+    """ Accumulate a quantity over a given vectorization strategy """
+    accum = start
+
+    # Make sure to count each implementation exactly once
+    keys = set(sf.cache_key for sf in strategy.values())
+    for sf in strategy.values():
+        if sf.cache_key in keys:
+            accum = reduce(accum, func(sf))
+            keys.discard(sf.cache_key)
+
+    return accum
+
+
 def strategy_cost(strat_tuple):
     qp, strategy = strat_tuple
 
@@ -119,14 +133,23 @@ def strategy_cost(strat_tuple):
     keys = set(sf.cache_key for sf in strategy.values())
     set_quadrature_points(qp)
 
-    # Sum over all the sum factorization kernels in the realization
-    score = 0.0
-    for sf in strategy.values():
-        if sf.cache_key in keys:
-            score = score + float(func(sf))
-            keys.discard(sf.cache_key)
+    return accumulate_for_strategy(strategy, lambda sf: float(func(sf)))
+
+
+def quadrature_penalized_strategy_cost(strat_tuple):
+    cost = strategy_cost(strat_tuple)
+
+    qp, strategy = strat_tuple
+    num_qp_new = product(qp)
+    sf_flops = accumulate_for_strategy(strategy, lambda sf: sf.operations)
+
+    set_quadrature_points(None)
+    num_qp_old = product(quadrature_points_per_direction())
+    set_quadrature_points(qp)
 
-    return score
+    # TODO determine this
+    ops_per_qp = 100
+    return float((sf_flops + ops_per_qp * num_qp_new) / (sf_flops + ops_per_qp * num_qp_old)) * cost
 
 
 def fixedqp_strategy_costfunction(qp):
@@ -300,7 +323,7 @@ def level1_optimal_vectorization_strategy(sumfacts, width):
         with open("mapping.csv", 'a') as f:
             f.write(" ".join((identifier, str(cost), short_stringify_vectorization_strategy((qp, optimal_strategies[qp])))) + "\n")
     else:
-        qp = min(optimal_strategies, key=lambda qp: strategy_cost((qp, optimal_strategies[qp])))
+        qp = min(optimal_strategies, key=lambda qp: quadrature_penalized_strategy_cost((qp, optimal_strategies[qp])))
 
     return qp, optimal_strategies[qp]
 
-- 
GitLab