from ufl.classes import (Terminal, GeometricQuantity,
Grad, Restricted, Indexed,
from uflacs.utils.log import error, uflacs_assert
from uflacs.analysis.datastructures import (int_array, object_array,
invdeps[d] = invdeps[d] + (i,)
return rows_to_crs(invdeps, n, m, int)
-def default_cache_score_policy(vtype, ndeps, ninvdeps, partition):
- # Start at 1 and then multiply with various heuristic factors
+def default_cache_score_policy(vtype, ndeps, ninvdeps, partition, highest_used_partition):
+ # Terminals always get zero score
- # Is the type particularly expensive to compute?
- expensive = (MathFunction,)
+ # Estimate cost of computation
+ expensive = (MathFunction, BesselFunction, Power, Abs, Conditional)
if vtype in expensive: # Could make a type-to-cost mapping, but this should do.
- # More deps roughly correlates to more operations
+ # More deps correlates to higher cost
- # If it is reused several times let that count significantly
- s *= ninvdeps**3 # 1->1, 2->8, 3->27
+ # Estimate reuses based on inverse dependencies and highest used partition (possible to count this more accurately!)
+ reuses = ninvdeps * max(1, 10*(highest_used_partition - partition)**2)
- # Finally let partition count for something?
- # Or perhaps we need some more information, such as
- # when x from outer loop is used by y within inner loop.
+ # Multiply cost with number of reuses
+def compute_partition_dependencies(dependencies, inverse_dependencies, partitions):
+ "TODO: Use this? Not tested. Idea: marking vertices that are used in higher partitions for reuse."
+ highest_used_partition = int_array(n)
+ for i, p in enumerate(partitions):
+ ideps = inverse_dependencies[i]
+ highest_used_partition[i] = p
+ highest_used_partition[i] = max(highest_used_partition[i], partitions[j])
+ return highest_used_partition
def compute_cache_scores(V, active, dependencies, inverse_dependencies, partitions,
"""FIXME: Cover with tests.
TODO: Experiment with heuristics later when we have functional code generation.
+ highest_used_partition = compute_partition_dependencies(dependencies, inverse_dependencies, partitions)
invdeps = inverse_dependencies[i]
+ hup = highest_used_partition[i]
- s = cache_score_policy(type(v), ndeps, ninvdeps, p)
+ s = cache_score_policy(type(v), ndeps, ninvdeps, p)