Skip to content
Snippets Groups Projects

Resolve "Re-Implement Evaluation"

Merged Ivar Härnqvist requested to merge 75-re-implement-evaluation into develop
21 files
+ 309
186
Compare changes
  • Side-by-side
  • Inline
Files
21
+ 28
15
@@ -3,17 +3,20 @@ B-ASIC Signal Flow Graph Module.
TODO: More info.
"""
from typing import List, Iterable, Sequence, Dict, Optional, DefaultDict, MutableSet
from typing import List, Iterable, Sequence, Dict, Optional, DefaultDict, MutableSet, Tuple
from numbers import Number
from collections import defaultdict, deque
from b_asic.port import SignalSourceProvider, OutputPort
from b_asic.operation import Operation, AbstractOperation, ResultKey, DelayMap, MutableResultMap, MutableDelayMap
from b_asic.operation import Operation, AbstractOperation, ResultKey, DelayMap, MutableResultMap, MutableDelayMap, ResultKey
from b_asic.signal import Signal
from b_asic.graph_component import GraphID, GraphIDNumber, GraphComponent, Name, TypeName
from b_asic.special_operations import Input, Output
DelayQueue = List[Tuple[str, ResultKey, OutputPort]]
class GraphIDGenerator:
"""A class that generates Graph IDs for objects."""
@@ -173,7 +176,7 @@ class SFG(AbstractOperation):
else:
output_string += "-, "
if component.type_name is "c":
if component.type_name == "c":
output_string += "value: " + str(component.value) + ", input: ["
else:
output_string += "input: ["
@@ -230,7 +233,13 @@ class SFG(AbstractOperation):
for op, arg in zip(self._input_operations, self.truncate_inputs(input_values, bits_override) if truncate else input_values):
op.value = arg
value = self._evaluate_source(self._output_operations[index].input(0).signals[0].source, results, delays, prefix, bits_override, truncate)
deferred_delays = []
value = self._evaluate_source(self._output_operations[index].input(0).signals[0].source, results, delays, prefix, bits_override, truncate, deferred_delays)
while deferred_delays:
new_deferred_delays = []
for key_base, key, src in deferred_delays:
self._do_evaluate_source(key_base, key, src, results, delays, prefix, bits_override, truncate, new_deferred_delays)
deferred_delays = new_deferred_delays
results[self.key(index, prefix)] = value
return value
@@ -422,22 +431,26 @@ class SFG(AbstractOperation):
# The old SFG will be deleted by Python GC
return self()
def _evaluate_source(self, src: OutputPort, results: MutableResultMap, delays: MutableDelayMap, prefix: str, bits_override: Optional[int], truncate: bool) -> Number:
src_prefix = prefix
if src_prefix:
src_prefix += "."
src_prefix += src.operation.graph_id
key = src.operation.key(src.index, src_prefix)
def _evaluate_source(self, src: OutputPort, results: MutableResultMap, delays: MutableDelayMap, prefix: str, bits_override: Optional[int], truncate: bool, deferred_delays: DelayQueue) -> Number:
key_base = (prefix + "." + src.operation.graph_id) if prefix else src.operation.graph_id
key = src.operation.key(src.index, key_base)
if key in results:
value = results[key]
if value is None:
raise RuntimeError(f"Direct feedback loop detected when evaluating operation.")
raise RuntimeError("Direct feedback loop detected when evaluating operation.")
return value
value = src.operation.current_output(src.index, delays, key_base)
results[key] = value
if value is None:
value = self._do_evaluate_source(key_base, key, src, results, delays, prefix, bits_override, truncate, deferred_delays)
else:
deferred_delays.append((key_base, key, src)) # Evaluate later. Use current value for now.
return value
results[key] = src.operation.current_output(src.index, delays, src_prefix)
input_values = [self._evaluate_source(input_port.signals[0].source, results, delays, prefix, bits_override, truncate) for input_port in src.operation.inputs]
value = src.operation.evaluate_output(src.index, input_values, results, delays, src_prefix, bits_override, truncate)
def _do_evaluate_source(self, key_base: str, key: ResultKey, src: OutputPort, results: MutableResultMap, delays: MutableDelayMap, prefix: str, bits_override: Optional[int], truncate: bool, deferred_delays: DelayQueue) -> Number:
input_values = [self._evaluate_source(input_port.signals[0].source, results, delays, prefix, bits_override, truncate, deferred_delays) for input_port in src.operation.inputs]
value = src.operation.evaluate_output(src.index, input_values, results, delays, key_base, bits_override, truncate)
results[key] = value
return value
Loading