import re import sys from scipy.optimize import linprog def addHTMLCodeForOperands(instrNode, html): if instrNode.find('operand') is not None: html.append('

Operands

') html.append('') def canonicalizeInstrString(instrString): return re.sub('[(){}, ]+', '_', instrString).strip('_') def getTP_LP(PU): if len(PU) == 0: return 0 if len(PU) == 1: pc, uops = PU[0] return round(float(uops)/len(pc), 2) ports = list(set.union(*[set(pc) for pc, _ in PU])) zeroConstraint = [] for p in ports: for pc, uops in PU: if not p in pc: zeroConstraint.append(1) else: zeroConstraint.append(0) zeroConstraint.append(0) #z nonZeroConstraints = [] nonZeroConstraintsRHS = [] for pu in PU: pc, uops = pu nonZeroConstraintsRHS.append(uops) nonZeroConstraint = [] for p in ports: for pu2 in PU: if pu != pu2 or p not in pc: nonZeroConstraint.append(0) else: nonZeroConstraint.append(1) nonZeroConstraint.append(0) #z nonZeroConstraints.append(nonZeroConstraint) A_eq = [zeroConstraint] + nonZeroConstraints b_eq = [0] + nonZeroConstraintsRHS zConstraints = [] for p in ports: zConstraint = [] for p2 in ports: for pu in PU: if p != p2: zConstraint.append(0) else: zConstraint.append(1) zConstraint.append(-1) zConstraints.append(zConstraint) A_ub = zConstraints b_ub = [0] * len(zConstraints) c = [0]*(len(PU)*len(ports)) + [1] res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq) return round(res.fun, 2) # Example output: "Latency operand 2 -> 1 (memory): <=3" def latencyNodeToStr(latNode, sameReg, addr_mem): suffix = ('_'+addr_mem if addr_mem else '') + ('_same_reg' if sameReg else '') if not any((a in ['cycles'+suffix, 'min_cycles'+suffix]) for a in latNode.attrib): return None ret = 'Latency operand ' + latNode.attrib['start_op'] + ' → ' + latNode.attrib['target_op'] if sameReg: ret += ', with the same register for different operands' if addr_mem == 'addr': ret += ' (address, base register)' elif addr_mem in ['addr_index']: ret += ' (address, index register)' elif addr_mem == 'mem': ret += ' (memory)' ret += ': ' if 'cycles'+suffix in latNode.attrib: if latNode.attrib.get('cycles'+suffix+'_is_upper_bound', '') == '1': ret += '≤' cycles = latNode.attrib['cycles'+suffix] ret += cycles else: minCycles = latNode.attrib['min_cycles'+suffix] maxCycles = latNode.attrib['max_cycles'+suffix] if latNode.attrib.get('min_cycles'+suffix+'_is_upper_bound', '') == '1': ret += '≤' + minCycles else: ret += minCycles + ' ≤ lat ≤ ' + maxCycles return ret # Returns (string, minLat, minLatUB, maxLat, maxLatUB) # Example output: ("[1;<=7]", 1, False, 7, True) def getLatencyTableEntry(measurementNode): if measurementNode is None or measurementNode.find('./latency') is None: return None minLat = sys.maxsize maxLat = 0 minLatUB = False maxLatUB = False for latNode in measurementNode.findall('./latency'): for sameReg in [False, True]: for addr_mem in ['', 'addr', 'addr_index', 'mem']: suffix = ('_'+addr_mem if addr_mem else '') + ('_same_reg' if sameReg else '') if 'cycles'+suffix in latNode.attrib: cycles = int(latNode.attrib['cycles'+suffix]) isUB = (latNode.attrib.get('cycles'+suffix+'_is_upper_bound', '') == '1') if cycles == maxLat: maxLatUB = (maxLatUB and isUB) elif cycles > maxLat: maxLat = cycles maxLatUB = isUB if cycles == minLat: minLatUB = (minLatUB or isUB) elif cycles < minLat: minLat = cycles minLatUB = isUB if 'max_cycles'+suffix in latNode.attrib: cycles = int(latNode.attrib['max_cycles'+suffix]) isUB = (latNode.attrib.get('max_cycles'+suffix+'_is_upper_bound', '') == '1') if cycles == maxLat: maxLatUB = (maxLatUB and isUB) elif cycles > maxLat: maxLat = cycles maxLatUB = isUB if 'min_cycles'+suffix in latNode.attrib: cycles = float(latNode.attrib['min_cycles'+suffix]) isUB = (latNode.attrib.get('min_cycles'+suffix+'_is_upper_bound', '') == '1') if cycles == minLat: minLatUB = (minLatUB or isUB) elif cycles < minLat: minLat = cycles minLatUB = isUB if minLat == maxLat: latStr = str(maxLat) if minLatUB or maxLatUB: latStr = '≤' + latStr else: latStr = '[' if minLatUB: latStr += '≤' latStr += str(minLat) latStr += ';' if maxLatUB: latStr += '≤' latStr += str(maxLat) latStr += ']' return (latStr, minLat, minLatUB, maxLat, maxLatUB)