Skip to content
Snippets Groups Projects
Commit b0d9fcf0 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Add support for parallel interleaver generation

parent 4f32ce08
No related branches found
No related tags found
1 merge request!253Add support for parallel interleaver generation
Pipeline #92544 passed
...@@ -3,6 +3,7 @@ Functions to generate memory-variable test data that are used for research. ...@@ -3,6 +3,7 @@ Functions to generate memory-variable test data that are used for research.
""" """
import random import random
from itertools import product
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
from b_asic.process import PlainMemoryVariable from b_asic.process import PlainMemoryVariable
...@@ -10,21 +11,25 @@ from b_asic.resources import ProcessCollection ...@@ -10,21 +11,25 @@ from b_asic.resources import ProcessCollection
def _insert_delays( def _insert_delays(
inputorder: List[int], outputorder: List[int], min_lifetime: int, cyclic: bool inputorder: List[Tuple[int, int]],
) -> Tuple[List[int], List[int]]: outputorder: List[Tuple[int, int]],
min_lifetime: int,
cyclic: bool,
time: int,
) -> Tuple[List[Tuple[int, int]], List[Tuple[int, int]]]:
size = len(inputorder) size = len(inputorder)
maxdiff = min(outputorder[i] - inputorder[i] for i in range(size)) maxdiff = min(outputorder[i][0] - inputorder[i][0] for i in range(size))
outputorder = [o - maxdiff + min_lifetime for o in outputorder] outputorder = [(o[0] - maxdiff + min_lifetime, o[1]) for o in outputorder]
maxdelay = max(outputorder[i] - inputorder[i] for i in range(size)) maxdelay = max(outputorder[i][0] - inputorder[i][0] for i in range(size))
if cyclic: if cyclic:
if maxdelay >= size: if maxdelay >= time:
inputorder = inputorder + [i + size for i in inputorder] inputorder = inputorder + [(i[0] + time, i[1]) for i in inputorder]
outputorder = outputorder + [o + size for o in outputorder] outputorder = outputorder + [(o[0] + time, o[1]) for o in outputorder]
return inputorder, outputorder return inputorder, outputorder
def generate_random_interleaver( def generate_random_interleaver(
size: int, min_lifetime: int = 0, cyclic: bool = True size: int, min_lifetime: int = 0, cyclic: bool = True, parallelism: int = 1
) -> ProcessCollection: ) -> ProcessCollection:
""" """
Generate a ProcessCollection with memory variable corresponding to a random Generate a ProcessCollection with memory variable corresponding to a random
...@@ -40,24 +45,28 @@ def generate_random_interleaver( ...@@ -40,24 +45,28 @@ def generate_random_interleaver(
cyclic : bool, default: True cyclic : bool, default: True
If the interleaver should operate continuously in a cyclic manner. That is, If the interleaver should operate continuously in a cyclic manner. That is,
start a new interleaving operation directly after the previous. start a new interleaving operation directly after the previous.
parallelism : int, default: 1
Number of values to input and output every cycle.
Returns Returns
------- -------
ProcessCollection ProcessCollection
""" """
inputorders = list(range(size)) inputorders = list(product(range(size), range(parallelism)))
outputorders = inputorders[:] outputorders = inputorders[:]
random.shuffle(outputorders) random.shuffle(outputorders)
inputorders, outputorders = _insert_delays( inputorders, outputorders = _insert_delays(
inputorders, outputorders, min_lifetime, cyclic inputorders, outputorders, min_lifetime, cyclic, size
) )
return ProcessCollection( return ProcessCollection(
{ {
PlainMemoryVariable(inputorder, 0, {0: outputorders[i] - inputorder}) PlainMemoryVariable(
*inputorder, {outputorders[i][1]: outputorders[i][0] - inputorder[0]}
)
for i, inputorder in enumerate(inputorders) for i, inputorder in enumerate(inputorders)
}, },
len(inputorders), len(inputorders) // parallelism,
cyclic, cyclic,
) )
...@@ -67,6 +76,7 @@ def generate_matrix_transposer( ...@@ -67,6 +76,7 @@ def generate_matrix_transposer(
cols: Optional[int] = None, cols: Optional[int] = None,
min_lifetime: int = 0, min_lifetime: int = 0,
cyclic: bool = True, cyclic: bool = True,
parallelism: int = 1,
) -> ProcessCollection: ) -> ProcessCollection:
r""" r"""
Generate a ProcessCollection with memory variable corresponding to transposing a Generate a ProcessCollection with memory variable corresponding to transposing a
...@@ -86,6 +96,8 @@ def generate_matrix_transposer( ...@@ -86,6 +96,8 @@ def generate_matrix_transposer(
cyclic : bool, default: True cyclic : bool, default: True
If the interleaver should operate continuously in a cyclic manner. That is, If the interleaver should operate continuously in a cyclic manner. That is,
start a new interleaving operation directly after the previous. start a new interleaving operation directly after the previous.
parallelism : int, default: 1
Number of values to input and output every cycle.
Returns Returns
------- -------
...@@ -94,29 +106,34 @@ def generate_matrix_transposer( ...@@ -94,29 +106,34 @@ def generate_matrix_transposer(
if cols is None: if cols is None:
cols = rows cols = rows
inputorder = [] if (rows * cols // parallelism) * parallelism != rows * cols:
raise ValueError(
f"parallelism ({parallelism}) must be an integer multiple of rows*cols"
f" ({rows}*{cols} = {rows*cols})"
)
inputorders = []
for col in range(cols): for col in range(cols):
for row in range(rows): for row in range(rows):
inputorder.append(row + rows * col) inputorders.append(((row + rows * col) // parallelism, row % parallelism))
outputorder = [] outputorders = []
for row in range(rows): for row in range(rows):
for col in range(cols): for col in range(cols):
outputorder.append(col * rows + row) outputorders.append(((col * rows + row) // parallelism, col % parallelism))
inputorder, outputorder = _insert_delays( inputorders, outputorders = _insert_delays(
inputorder, outputorder, min_lifetime, cyclic inputorders, outputorders, min_lifetime, cyclic, rows * cols // parallelism
) )
return ProcessCollection( return ProcessCollection(
{ {
PlainMemoryVariable( PlainMemoryVariable(
inputorder[i], *inputorder,
0, {outputorders[i][1]: outputorders[i][0] - inputorder[0]},
{0: outputorder[i] - inputorder[i]}, name=f"{inputorders[i][0]*parallelism + inputorders[i][1]}",
name=f"{inputorder[i]}",
) )
for i in range(len(inputorder)) for i, inputorder in enumerate(inputorders)
}, },
len(inputorder), len(inputorders) // parallelism,
cyclic, cyclic,
) )
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment