def find_channel(self, name): """ Search for and retuen assigned channel by name (including indexes) """ original_channel_name = original_name(name) indexes = name_indexes(name) if original_channel_name not in self._channels_map: return None channels = self._channels_map[original_channel_name] if len(channels) == 0: return None for ch in channels: # Check if channels has the same original name if ch.original_name() == name: i = 0 #Check if channels have the same indexes ch_indexes = ch.indexes() while i < len(indexes): if indexes[i] != ch_indexes[i]: break i += 1 # If while loop was broken if i < len(indexes): continue else: # All indexes were the same return ch return None
def get_or_create_channel(existing_channels, channel_name): """ Get existing channel by name or create new channel. """ # Find repeated channel with indexes by name channel = find_channel(existing_channels, channel_name) # If repeated channel with indexes does not exist if channel is None: # Find first channel (zero indexes) with original name of repeated channel channel = find_channel(existing_channels, original_name(channel_name) + '.0.0') if channel is None: raise EnvironmentDefinitionException("Channel '%s' undefined." % original_name(channel_name)) channel = channel.clone() indexes = name_indexes(channel_name) for i in range(0, len(indexes)): channel.add_name_index(indexes[i]) indexes = name_indexes(channel.name) for i in range(len(indexes), 2): channel.add_name_index(0) existing_channels.append(channel) return channel
def _BuildHostsChoosePanel(self, simulator): """ """ for p in self.hostChoosePanels: p.Destroy() self.hostChoosePanels = [] self.checkBoxInformations = {} self.hostCheckBoxes = [] self.hostsBoxSizer.Layout() hosts = simulator.context.hosts hostsIndexes = {} for h in hosts: name = h.original_name() indexes = name_indexes(h.name) index = indexes[0] if name not in hostsIndexes or index > hostsIndexes[name]: hostsIndexes[name] = index for hostName in hostsIndexes: panel = wx.Panel(self) panelSizer = wx.BoxSizer(wx.HORIZONTAL) ch = wx.CheckBox(panel, label=hostName, size=(120, 20)) textCtrl = wx.TextCtrl(panel, size=(200, 20)) textCtrl.SetValue("0") rangeLabel = "Available range: 0" if hostsIndexes[hostName] > 0: rangeLabel += " - %d" % hostsIndexes[hostName] maxLbl = wx.StaticText(panel, label=rangeLabel) panelSizer.Add(ch, 0, wx.ALL | wx.ALIGN_CENTER) panelSizer.Add(wx.StaticText(self), 1, wx.ALL | wx.ALIGN_RIGHT) panelSizer.Add(textCtrl, 0, wx.ALL | wx.ALIGN_CENTER) panelSizer.Add(maxLbl, 0, wx.ALL | wx.ALIGN_CENTER) panel.SetSizer(panelSizer) self.hostsBoxSizer.Add(panel, 1, wx.ALL) self.checkBoxInformations[ch] = (hostName, textCtrl) self.hostChoosePanels.append(panel) self.hostCheckBoxes.append(ch) self.hostsBoxSizer.Layout() self.Layout()
def _GetSelectedHosts(self, simulator): """ Returns list of hosts selected by the user """ def ValidateHostsRange(indexesRange): """ """ return re.match(r'\d(-\d)?(,\d(-\d)?)*', indexesRange) def GetIndexesFromRange(indexesRange): """ Extracts numbers list of hosts from range text """ indexes = [] ranges = indexesRange.split(',') for r in ranges: parts = r.split('-') if len(parts) == 1: indexes.append(int(parts[0])) else: for i in range(int(parts[0]), int(parts[1]) + 1): indexes.append(i) return indexes hosts = [] for ch in self.hostCheckBoxes: if not ch.IsChecked(): continue hostName, hostRangeTextCtrl = self.checkBoxInformations[ch] indexesRange = hostRangeTextCtrl.GetValue() if not ValidateHostsRange(indexesRange): wx.MessageBox( "Range '%s' for host '%s' is invalid. Valid example: 0,12,20-25,30." % (indexesRange, hostName), 'Error', wx.OK | wx.ICON_ERROR) break else: indexes = GetIndexesFromRange(indexesRange) for h in simulator.context.hosts: hostIndexes = name_indexes(h.name) if h.original_name( ) == hostName and hostIndexes[0] in indexes: hosts.append(h) return hosts
def _GetSelectedHosts(self, simulator): """ Returns list of hosts selected by user """ def ValidateHostsRange(indexesRange): """ """ return re.match(r'\d(-\d)?(,\d(-\d)?)*', indexesRange) def GetIndexesFromRange(indexesRange): """ Extracts numbers list of hosts from range text """ indexes = [] ranges = indexesRange.split(',') for r in ranges: parts = r.split('-') if len(parts) == 1: indexes.append(int(parts[0])) else: for i in range(int(parts[0]), int(parts[1])+1): indexes.append(i) return indexes hosts = [] for ch in self.hostCheckBoxes: if not ch.IsChecked(): continue hostName, hostRangeTextCtrl = self.checkBoxInformations[ch] indexesRange = hostRangeTextCtrl.GetValue() if not ValidateHostsRange(indexesRange): wx.MessageBox("Range '%s' for host '%s' is invalid. Valid example: 0,12,20-25,30." % (indexesRange, hostName), 'Error', wx.OK | wx.ICON_ERROR) break else: indexes = GetIndexesFromRange(indexesRange) for h in simulator.context.hosts: hostIndexes = name_indexes(h.name) if h.original_name() == hostName and hostIndexes[0] in indexes: hosts.append(h) return hosts
def _build_channels(self, store, version, built_hosts): """ Validate, build and return simulation channels build from parsed channels. Includes channel repetitions. """ def find_channel(channels, name): """ Find channel by name. """ for ch in channels: if ch.name == name: return ch return None def find_built_host(built_hosts, name): for h in built_hosts: if h.name == name: return h return None def find_parsed_process(instructions_list, process_name): for instr in instructions_list: if not isinstance(instr, HostProcess): continue if instr.name == process_name: return instr return None def get_or_create_channel(existing_channels, channel_name): """ Get existing channel by name or create new channel. """ # Find repeated channel with indexes by name channel = find_channel(existing_channels, channel_name) # If repeated channel with indexes does not exist if channel is None: # Find first channel (zero indexes) with original name of repeated channel channel = find_channel(existing_channels, original_name(channel_name) + '.0.0') if channel is None: raise EnvironmentDefinitionException("Channel '%s' undefined." % original_name(channel_name)) channel = channel.clone() indexes = name_indexes(channel_name) for i in range(0, len(indexes)): channel.add_name_index(indexes[i]) indexes = name_indexes(channel.name) for i in range(len(indexes), 2): channel.add_name_index(0) existing_channels.append(channel) return channel built_channels = [] original_channels = [] for parsed_channel in store.channels: channel = communication.Channel(parsed_channel.name, parsed_channel.buffor_size) channel.add_name_index(0) channel.add_name_index(0) built_channels.append(channel) original_channels.append(channel) # Hosts numbers dict keeps the last used number of repeated channel for hosts. # For example: # run A(*){5} { ... } - will create channels ch1.1, ch1.2, ch1.3, ch1.4 and ch1.5 # run A(ch1,ch2){2} { ... } - will create channels for next numers which are ch1.6, ch2.6 and ch1.7, ch2.7 hosts_numbers = {} for run_host in version.run_hosts: parsed_host = store.find_host(run_host.host_name) # Load all channels names that host can use # Firstly it is checked in version, secondly in parsed host # List channel_names contains clean channel names (ch1, ch2) channel_names = [] if run_host.all_channels_active: if parsed_host.all_channels_active: channel_names += [ c.original_name() for c in original_channels ] else: channel_names += [ c for c in parsed_host.active_channels ] else: channel_names += [ c for c in run_host.active_channels ] # channel_names - clean names of channels that host can use if parsed_host.name not in hosts_numbers: hosts_numbers[parsed_host.name] = 0 host_first_number = hosts_numbers[parsed_host.name] # HOST-CHANNELS ASSIGNATION # Algorithm: # - For each channel name # - Check if channel is repeated # - Get the name of repeated shannel # - If yes: # - Find channel with repeated name with indexes # - If channel with indexes does not exist: # - Find channel with original name (zero indexes) # - Clone it and add indexes # - Add new channel to built channels # - If no for channel_name in channel_names: # Calculate the name of repeated channel (if it is repeated) # with indexes repeated_name = "" for repeated_channel in run_host.repeated_channels: repeated_channel_basename = original_name(repeated_channel) if channel_name == repeated_channel_basename: indexes = name_indexes(repeated_channel) if len(indexes) > 0: repeated_name = repeated_channel_basename + '.' + str(indexes[0]) + '.0' else: repeated_name += repeated_channel_basename + '.0.0' break # If channel is repeated if repeated_name != "": channel = get_or_create_channel(built_channels, repeated_name) # Assign channel to hosts created on the base of this "run host" for i in range(0, run_host.repetitions): host_number = host_first_number + i host_name = run_host.host_name + '.' + str(host_number) built_host = find_built_host(built_hosts, host_name) built_host.connect_with_channel(channel) else: # Channel is not repeated # New channel is created for each channel name # starting from the lately used number (hosts_numbers) for i in range(0, run_host.repetitions): host_number = host_first_number + i host_name = run_host.host_name + '.' + str(host_number) new_channel_name = channel_name + '.' + str(host_number) + '.0' channel = get_or_create_channel(built_channels, new_channel_name) built_host = find_built_host(built_hosts, host_name) built_host.connect_with_channel(channel) # PROCESS-CHANNEL ASSIGNATION # Update process-channel assignations in each build host # created on the base of this "run host" for i in range(0, run_host.repetitions): # Process numbers dict keeps the last used number of repeated channel for processes. # Works the same like hosts_numbers for hosts. processes_numbers = {} host_number = host_first_number + i host_name = run_host.host_name + '.' + str(host_number) built_host = find_built_host(built_hosts, host_name) parsed_host = store.find_host(built_host.original_name()) instruction_index = 0 for run_process in run_host.run_processes: # Find next process om host's instructions list while instruction_index < len(built_host.instructions_list): if isinstance(built_host.instructions_list[instruction_index], Process): break instruction_index += 1 # If no process found raise exception if instruction_index >= len(built_host.instructions_list): raise EnvironmentDefinitionException("Process '%s' not found in host '%s'." % (run_process.process_name, built_host.name)) if run_process.process_name not in processes_numbers: processes_numbers[run_process.process_name] = 0 # Get number of next channel for this process name process_first_number = processes_numbers[run_process.process_name] # Get process for this "run process" parsed_process = find_parsed_process(parsed_host.instructions_list, run_process.process_name) process_channel_names = [] # Get channel names uded by process if parsed_process.all_channels_active: process_channel_names = channel_names else: for process_channel_name in parsed_process.active_channels: process_channel_names.append(process_channel_name) for process_channel_name in process_channel_names: # Calculate the name of repeated channel (if it is repeated) # with indexes process_channel_repeated_name = "" # Name of repeated channel (may be with indexes) for repeated_channel in run_process.repeated_channels: process_channel_repeated_name_basename = original_name(repeated_channel) if process_channel_name == process_channel_repeated_name_basename: process_channel_repeated_name = repeated_channel # If channel is repeated if process_channel_repeated_name != "": repeated_indexes = name_indexes(process_channel_repeated_name) # If repeated channel is the same, that host is connected with (no indexes) if len(repeated_indexes) == 0: channel = built_host.find_channel(process_channel_repeated_name) # If host does not have channel with this name if channel is None: # Generate channel name for this process ch_name = original_name(process_channel_repeated_name) + '.' +\ str(host_number) + '.' + str(process_first_number) channel = get_or_create_channel(built_channels, ch_name) elif len(repeated_indexes) == 1: # Repeated index is the process index in channels (second index) # # Repeated channel has defined numer of channel from channels of current host # (for different copies of hosts, these are different channels) # For example: Repeated channel name ch1.1 in host A.5 means that all messages # from all copies of process will be sent through channel ch1.x.1 # (where x is the number of channel ch1 in hist A.5 - firstly it would be propably 5) channel = built_host.find_channel(original_name(process_channel_repeated_name)) if channel: # Host has channel with this original name # Lets check if its second index (process index) is the same # with repeated index ch_indexes = channel.indexes() # If channel proces index (2nd) is different from repeated index if ch_indexes[1] != repeated_indexes[0]: ch_name = original_name(process_channel_repeated_name) + '.' +\ str(ch_indexes[0]) + '.' + str(repeated_indexes[0]) channel = get_or_create_channel(built_channels, ch_name) else: # Channel is not connected with host # Generate channel name for this process and host ch_name = original_name(process_channel_repeated_name) + '.' +\ str(host_number) + '.' + str(repeated_indexes[0]) channel = get_or_create_channel(built_channels, ch_name) elif len(repeated_indexes) == 2: ch_name = process_channel_repeated_name channel = get_or_create_channel(built_channels, ch_name) else: raise EnvironmentDefinitionException( 'Invalid repeated channel definition %s in process %s (host %s).'\ % (process_channel_repeated_name, run_process.process_name, built_host.name)) # Connect repeated channel with all repeated processes # Repeated processes are found as list of next instructions in host's instructions list for i in range(0, run_process.repetitions): built_process = built_host.instructions_list[instruction_index+i] if not isinstance(built_process, Process): raise EnvironmentDefinitionException( 'Isntruction nr %d of host %s expected to be process.'\ % (instruction_index+i, built_host.name)) built_process.connect_with_channel(channel) else: # Channel is not repeated current_host_channel_index = host_number # Check if host is connected with any channel of this original name channel = built_host.find_channel(original_name(process_channel_name)) if channel: # Get current host channel index # from the second index of found channel indexes ch_indexes = channel.indexes() current_host_channel_index = ch_indexes[0] for i in range(0, run_process.repetitions): # Generate the channel name for all repetitions process_number = process_first_number + i # Search for channel with generated name or create one ch_name = original_name(process_channel_name) + '.' +\ str(current_host_channel_index) + '.' + str(process_number) channel = get_or_create_channel(built_channels, ch_name) # Connect channel with process built_process = built_host.instructions_list[instruction_index+i] if not isinstance(built_process, Process): raise EnvironmentDefinitionException( 'Isntruction nr %d of host %s expected to be process.'\ % (instruction_index+i, built_host.name)) built_process.connect_with_channel(channel) # Update process numbers dict processes_numbers[run_process.process_name] += run_process.repetitions instruction_index += run_process.repetitions # Update hosts numbers dict hosts_numbers[run_host.host_name] += run_host.repetitions return built_channels
def indexes(self): """ Return name indexes of channel """ return name_indexes(self.name)