Skip to content

Commit 122b26b

Browse files
authored
fixed missing wires of multiple blocks when connected to single port issue (#339)
1 parent 84f585a commit 122b26b

File tree

1 file changed

+118
-67
lines changed

1 file changed

+118
-67
lines changed

backend/synthesis/synthesis.py

Lines changed: 118 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def syntheize_modules(data: dict, zipfile: InMemoryZip) -> Tuple[InMemoryZip, Di
2929
Blocks, parameters and the connections (wires) between the blocks stored in a
3030
JSON file.
3131
'''
32-
# Initialize an empty dictionary for tracking dependencies, blocks, parameters, synhronize_frequency, optional_files
3332
dependencies = {}
3433
blocks = {}
3534
parameters = {}
@@ -157,103 +156,155 @@ def process_dependency(dep, zipfile, synhronize_frequency, optional_files, dep_n
157156
# Add the wire to the valid_wires list
158157
valid_wires.append(wire)
159158

160-
# Function to process wires and handle absent blocks
161-
def process_wires(valid_wires):
162-
# Initialize dictionaries to track source and target ports
163-
wire_check_source = {}
164-
wire_check_target = {}
165159

166-
# Initialize a counter for iteration
167-
count = 0
168-
# Set a flag to detect changes
169-
changes_detected = True
160+
def process_wires(valid_wires):
161+
count = 0 # Initialize a counter for processing iterations
162+
changes_detected = True # Boolean flag to track if changes were made in the current iteration
170163

171-
# Continue processing while changes are detected
164+
# Loop until no changes are detected
172165
while changes_detected:
173-
changes_detected = False
166+
wire_check_source = {} # Dictionary to store wires' source info where 'ob' is absent
167+
wire_check_target = {}
168+
changes_detected = False # Reset changes_detected to False before processing wires
169+
170+
new_wires = [] # List to store newly created wires
174171

175-
# Iterate over valid wires in reverse order
172+
# Iterate through valid_wires in reverse order
176173
for i in range(len(valid_wires) - 1, -1, -1):
177-
wire = valid_wires[i]
178-
remove_wire = False # Flag to determine if the wire should be removed
179-
180-
count += 1 # Increment the counter
174+
wire = valid_wires[i] # Access the current wire from valid_wires
175+
remove_wire = False # Flag to mark whether the current wire should be removed
176+
177+
count += 1 # Increment the processing counter
181178

182179
# Check if the source port is 'input-out'
183180
if wire['source']['port'] == 'input-out':
184-
port_name = wire['source']['block']
185-
# Check if the target is marked 'absent'
181+
port_name = wire['source']['block'] # Get the block name of the source port
182+
183+
# If the target has 'ob' and it's 'absent', track it for processing later
186184
if 'ob' in wire['target'] and wire['target']['ob'] == 'absent':
187-
# Add target details to wire_check_source with 'input-out' port
188-
wire_check_source[port_name] = wire['target'].copy()
189-
wire_check_source[port_name]['port'] = port_name
185+
if port_name not in wire_check_source:
186+
wire_check_source[port_name] = [] # Initialize list if it's not present
187+
wire_check_source[port_name].append(wire['target'].copy()) # Append a copy of the target
188+
wire_check_source[port_name][-1]['port'] = port_name # Set the port name for the new entry
190189
else:
191-
# Add target details to wire_check_source
192-
wire_check_source[port_name] = wire['target']
193-
# Mark the wire for removal
194-
remove_wire = True
190+
# Otherwise, add the target to wire_check_source and mark for removal
191+
if port_name not in wire_check_source:
192+
wire_check_source[port_name] = []
193+
wire_check_source[port_name].append(wire['target']) # Add target to the dictionary
194+
remove_wire = True # Mark the wire for removal later
195195

196196
# Check if the target port is 'output-in'
197197
if wire['target']['port'] == 'output-in':
198-
port_name = wire['target']['block']
199-
# Check if the source is marked 'absent'
198+
port_name = wire['target']['block'] # Get the block name of the target port
199+
200+
# If the source has 'ob' and it's 'absent', track it for processing later
200201
if 'ob' in wire['source'] and wire['source']['ob'] == 'absent':
201-
# Add source details to wire_check_target with 'output-in' port
202-
wire_check_target[port_name] = wire['source'].copy()
203-
wire_check_target[port_name]['port'] = port_name
202+
if port_name not in wire_check_target:
203+
wire_check_target[port_name] = [] # Initialize list if it's not present
204+
wire_check_target[port_name].append(wire['source'].copy()) # Append a copy of the source
205+
wire_check_target[port_name][-1]['port'] = port_name # Set the port name for the new entry
204206
else:
205-
# Add source details to wire_check_target
206-
wire_check_target[port_name] = wire['source']
207-
# Mark the wire for removal
208-
remove_wire = True
207+
# Otherwise, add the source to wire_check_target and mark for removal
208+
if port_name not in wire_check_target:
209+
wire_check_target[port_name] = []
210+
wire_check_target[port_name].append(wire['source']) # Add source to the dictionary
211+
remove_wire = True # Mark the wire for removal later
209212

210-
# Remove the wire from valid_wires if marked for removal
213+
# Remove the wire if it was marked for removal
211214
if remove_wire:
212-
del valid_wires[i]
213-
changes_detected = True # Set flag to true since changes were made
215+
del valid_wires[i] # Remove the wire from valid_wires
216+
changes_detected = True # Set changes_detected to True as wires were modified
217+
218+
i = 0 # Initialize counter for iterating through valid_wires
219+
new_wires = [] # Reset the list to store any newly created wires
220+
221+
# Iterate through valid_wires starting from the beginning
222+
while i < len(valid_wires):
223+
wire = valid_wires[i] # Access the current wire
214224

215-
# Iterate over the valid wires to update ports
216-
for i, wire in enumerate(valid_wires):
217-
# Check if the source port name has 36 characters
225+
# Check if the source port is exactly 36 characters (for specific port length)
218226
if len(wire['source'].get('port', '')) == 36:
219-
port_name = wire['source']['port']
220-
# Update source with wire_check_target details if present
221-
if port_name in wire_check_target:
222-
valid_wires[i]['source'] = wire_check_target[port_name]
223-
# Update port name if 'absent' flag is present
224-
if 'ob' in valid_wires[i]['source']:
227+
port_name = wire['source']['port'] # Get the port name of the source
228+
229+
# If the port name exists in wire_check_target, process the sources
230+
if port_name in wire_check_target and wire_check_target[port_name]:
231+
new_sources = wire_check_target[port_name] # Get the list of sources for the port
232+
233+
# Replace the source of the current wire with the first new source
234+
valid_wires[i]['source'] = new_sources[0]
235+
if 'ob' in valid_wires[i]['source']: # If 'ob' exists, set the port name
225236
valid_wires[i]['source']['port'] = port_name
226-
227-
# Check if the target port name has 36 characters
237+
238+
# For remaining sources, create new wires
239+
for new_source in new_sources[1:]:
240+
new_wire = wire.copy() # Copy the current wire
241+
new_wire['source'] = new_source # Set the new source for the copied wire
242+
if 'ob' in new_wire['source']: # If 'ob' exists, set the port name
243+
new_wire['source']['port'] = port_name
244+
new_wires.append(new_wire) # Add the new wire to new_wires
245+
246+
# Check if the target port is exactly 36 characters (for specific port length)
228247
if len(wire['target'].get('port', '')) == 36:
229-
port_name = wire['target']['port']
230-
# Update target with wire_check_source details if present
231-
if port_name in wire_check_source:
232-
valid_wires[i]['target'] = wire_check_source[port_name]
233-
# Update port name if 'absent' flag is present
234-
if 'ob' in valid_wires[i]['target']:
248+
port_name = wire['target']['port'] # Get the port name of the target
249+
250+
# If the port name exists in wire_check_source, process the targets
251+
if port_name in wire_check_source and wire_check_source[port_name]:
252+
new_targets = wire_check_source[port_name] # Get the list of targets for the port
253+
254+
# Replace the target of the current wire with the first new target
255+
valid_wires[i]['target'] = new_targets[0]
256+
if 'ob' in valid_wires[i]['target']: # If 'ob' exists, set the port name
235257
valid_wires[i]['target']['port'] = port_name
258+
259+
# For remaining targets, create new wires
260+
for new_target in new_targets[1:]:
261+
new_wire = wire.copy() # Copy the current wire
262+
new_wire['target'] = new_target # Set the new target for the copied wire
263+
if 'ob' in new_wire['target']: # If 'ob' exists, set the port name
264+
new_wire['target']['port'] = port_name
265+
new_wires.append(new_wire) # Add the new wire to new_wires
266+
267+
i += 1 # Move to the next wire in the valid_wires list
268+
269+
# Append newly created wires to the valid_wires list
270+
valid_wires.extend(new_wires)
271+
272+
# Remove duplicate wires by checking for uniqueness
273+
unique_wires = [] # List to store unique wires
274+
seen_wires = set() # Set to track already seen wires
275+
276+
# Iterate over valid_wires to remove duplicates
277+
for wire in valid_wires:
278+
# Convert the wire dictionary to a frozenset for hashability (so it can be added to a set)
279+
wire_tuple = frozenset((key, frozenset(value.items())) if isinstance(value, dict) else (key, value) for key, value in wire.items())
280+
281+
# Only add unique wires to unique_wires
282+
if wire_tuple not in seen_wires:
283+
seen_wires.add(wire_tuple) # Add the wire to the set of seen wires
284+
unique_wires.append(wire) # Append the wire to unique_wires
285+
286+
valid_wires = unique_wires # Assign the unique wires back to valid_wires
236287

237-
# Return the processed list of valid wires
238-
return valid_wires
288+
return valid_wires # Return the processed valid_wires
239289

240-
# Process the wires to handle 'absent' blocks
290+
291+
# Call the process_wires function to process the wires
241292
processed_wires = process_wires(valid_wires)
242293

243-
# Create a final data dictionary with blocks, parameters, frequencies, and wires
294+
# Package processed data into a JSON file for saving or further use
244295
data = {
245-
'blocks': blocks,
246-
'parameters': parameters,
247-
'synchronize_frequency': synhronize_frequency,
248-
'wires': processed_wires
296+
'blocks': blocks, # Block-related data
297+
'parameters': parameters, # Parameter-related data
298+
'synchronize_frequency': synhronize_frequency, # Synchronization frequency information
299+
'wires': processed_wires # The processed wire data
249300
}
250-
# Add the data dictionary as a JSON file in the zipfile
251-
zipfile.append('data.json', json.dumps(data))
252301

253-
# Return the updated zipfile and optional files dictionary
302+
# Add data to a zipfile (the zipfile object must be defined elsewhere in the code)
303+
zipfile.append('data.json', json.dumps(data)) # Append the JSON data to the zipfile
304+
305+
254306
return zipfile, optional_files
255307

256-
257308
def synthesize_executioner(zipfile: InMemoryZip, optional_files: Dict[str, bool]) -> InMemoryZip:
258309
'''Synthesize python code necessary to run the blocks.
259310
All these files are present in django static directory.

0 commit comments

Comments
 (0)