From a6a23077dbcf998f468a5003fb5e24f860247c5b Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Wed, 19 Oct 2016 17:54:12 +0200
Subject: [PATCH] Implement a first draft of a 'flip flop buffer'

Get endless temporaries who circularly switch around their base storage.
Any temporary may have different shape or dim_tags, reinterpreting the
data at will.
---
 python/dune/perftool/loopy/buffer.py | 51 ++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 python/dune/perftool/loopy/buffer.py

diff --git a/python/dune/perftool/loopy/buffer.py b/python/dune/perftool/loopy/buffer.py
new file mode 100644
index 00000000..265cc051
--- /dev/null
+++ b/python/dune/perftool/loopy/buffer.py
@@ -0,0 +1,51 @@
+from dune.perftool.generation import (generator_factory,
+                                      temporary_variable,
+                                      )
+
+
+class FlipFlopBuffer(object):
+    def __init__(self, identifier, base_storage_size=None, num=2):
+        self.identifier = identifier
+        self.num = num
+
+        # Initialize the counter that switches between the base storages!
+        self._current = 0
+
+        # Initialize a total counter for the issued temporaries
+        self._counter = 0
+
+        # Get the base storage temporaries that actually hold the data!
+        # TODO: Use heap-allocated ones instead (easy with DuneTarget)
+        self.base_storage = tuple("{}_base_{}".format(self.identifier, i) for i in range(self.num))
+
+        for bs in self.base_storage:
+            temporary_variable(bs, shape=(base_storage_size,))
+
+    def get_temporary(self, **kwargs):
+        assert("base_storage" not in kwargs)
+
+        # Select the base storage and increase counter
+        base = self.base_storage[self._current]
+        self._current = (self._current + 1) % self.num
+
+        # Construct a temporary name
+        name = "{}_{}".format(self.identifier, self._counter)
+        self._counter = self._counter + 1
+
+        # Construct the temporary and return it
+        temporary_variable(name, base_storage=base, **kwargs)
+        return name
+
+
+@generator_factory(item_tags=("kernel", "buffer"), cache_key_generator=lambda i, **kw: i)
+def initialize_buffer(identifier, base_storage_size=None, num=2):
+    if base_storage_size is None:
+        raise ValueError("The buffer for identifier {} has not been initialized.".format(identifier))
+    return FlipFlopBuffer(identifier,
+                          base_storage_size=base_storage_size,
+                          num=num,
+                          )
+
+
+def get_buffer_temporary(identifier, **kwargs):
+    return initialize_buffer(identifier).get_temporary(**kwargs)
-- 
GitLab