Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dune-codegen
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Christian Heinigk
dune-codegen
Commits
4dd92e28
Commit
4dd92e28
authored
9 years ago
by
Dominic Kempf
Browse files
Options
Downloads
Patches
Plain Diff
Add the work on preamble generation infrastructure
parent
7f573c27
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
python/dune/perftool/preambles.py
+132
-0
132 additions, 0 deletions
python/dune/perftool/preambles.py
with
132 additions
and
0 deletions
python/dune/perftool/preambles.py
0 → 100644
+
132
−
0
View file @
4dd92e28
"""
This module provides the infrastructure for loopy preambles that have
a complex requirement structure. This includes:
* preambles triggering the creation of other preambles
* a caching mechanism to avoid duplicated preambles where harmful
"""
class
UFL2LoopyDataCache
(
dict
):
"""
The cache data structure
The data is stored as key value pairs of the following form:
(function, cache_tuple) -> (code, priority_tag, preamble)
The parameters are:
function : the function that generates the preamble code snippet
cache_tuple : A frozen (sub)set of arguments to the function.
The map from function arguments to cache tuple controls
the amount of caching.
code : The code snippet to generate. No assumptions made.
priority_tag : Will later decide the ordering of the preambles.
preamble : A bool whether this cache entry does generate a loopy preamble.
This is usually not the case, when you generate someting
like symbol names. Those are inserted into other snippets,
but not on their own right.
"""
def
__init__
(
self
):
self
.
counter
=
0
def
register
(
self
,
cachekey
,
code
,
preamble
):
self
.
counter
=
self
.
counter
-
1
self
[
cachekey
]
=
(
code
,
self
.
counter
,
preamble
)
def
extract_preambles
(
self
):
print
self
.
values
()
return
[(
p
[
1
],
p
[
0
])
for
p
in
self
.
values
()
if
p
[
2
]]
# have one such cache on the module level. It is easier than handing around an instance of it.
_cache
=
UFL2LoopyDataCache
()
def
generate_cache_tuple
(
*
args
):
"""
A function that maps its arguments to a mutable tuple
This is used as the cache key generator for the default case
when caching is wanted invariably/
"""
from
collections
import
Hashable
,
Iterable
,
MutableMapping
def
freeze
(
data
):
# Strings are iterable and hashable, but they do not pose any problems.
if
isinstance
(
data
,
str
):
return
data
# Check if the given data is already hashable
if
isinstance
(
data
,
Hashable
):
if
isinstance
(
data
,
Iterable
):
return
type
(
data
)(
freeze
(
i
)
for
i
in
data
)
return
data
# convert standard mutable containers
if
isinstance
(
data
,
MutableMapping
):
return
tuple
((
freeze
(
k
),
freeze
(
v
))
for
k
,
v
in
data
.
iteritems
())
if
isinstance
(
data
,
Iterable
):
return
tuple
(
freeze
(
i
)
for
i
in
data
)
# we don't know how to handle this object, so we give up
raise
TypeError
(
'
Cannot freeze non-hashable object {} of type {}
'
.
format
(
data
,
type
(
data
)))
return
freeze
(
args
)
# We do also provide a shortcut for no caching at all.
no_caching
=
lambda
*
a
:
()
# Data structure for a registered function to be used when decorating something
class
RegisteredFunction
(
object
):
"""
The data structure for a function that generates a preambel
"""
def
__init__
(
self
,
func
,
cache_key_generator
=
generate_cache_tuple
,
generate_preamble
=
True
):
self
.
func
=
func
self
.
cache_key_generator
=
cache_key_generator
self
.
generate_preamble
=
generate_preamble
# TODO: do we want this to contain kwargs?
def
__call__
(
self
,
*
args
):
cache_key
=
(
self
.
func
,
self
.
cache_key_generator
(
*
args
))
if
cache_key
in
_cache
:
if
not
self
.
generate_preamble
:
return
_cache
[
cache_key
][
0
]
else
:
code
=
self
.
func
(
*
args
)
_cache
.
register
(
cache_key
,
code
,
self
.
generate_preamble
)
if
not
self
.
generate_preamble
:
return
code
# The decorator: it works both with and without (keyword!) arguments.
def
dune_preambel
(
*
args
,
**
kwargs
):
"""
The decorator for a function that generates a preambel
Note that this may be used with or without arguments.
Possible keyword arguments:
---------------------------
cache_key_generator : function
A function that maps the arguments to the function to an immutable cache key.
Defaults to generate_cache_tuple.
"""
if
args
:
assert
len
(
args
)
==
1
return
RegisteredFunction
(
args
[
0
])
else
:
return
lambda
f
:
RegisteredFunction
(
f
,
**
kwargs
)
def
dune_symbol
(
*
args
,
**
kwargs
):
"""
The decorator for a function that generates a dune symbol name.
Note that this may be used with or without arguments.
Possible keyword arguments:
---------------------------
cache_key_generator : function
A function that maps the arguments to the function to an immutable cache key.
Defaults to generate_cache_tuple.
"""
if
args
:
assert
len
(
args
)
==
1
return
RegisteredFunction
(
args
[
0
],
generate_preamble
=
False
)
else
:
assert
"
generate_preamble
"
not
in
kwargs
return
lambda
f
:
RegisteredFunction
(
f
,
generate_preamble
=
False
,
**
kwargs
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment