def test_walk_tree(): a = Node.Node('a') b = Node.Node('b') c = Node.Node('c') d = Node.Node('d') e = Node.Node('e') a.dependsOn(b) a.dependsOn(d) a.dependsOn(c) b.dependsOn(c) b.dependsOn(e) c.dependsOn(d) c.dependsOn(e) print("\nDependency Tree:") resolved = [] a.resolve_dependencies(a, resolved) print("Dependencies: ", end='') for item in resolved: print(item.name, end=' => ') print("|\n") expected_result = ['d', 'e', 'c', 'b', 'a'] for result, expected in zip(resolved, expected_result): assert result.name == expected
def Equal(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef) == 2) return (None, { curNode.getName() : AST.BOp(AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), TFNodesAST.getOperatorsIdx('=='), AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]) )})
def Split(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef) == 2) axisNodeName = inputsRef[0] # split_dim input. Has to be a constant. We don't support dynamic codegen yet axisNode = graph.__getitem__(axisNodeName) axisTensor = axisNode.getAttrVal("value").getTensor() axis = axisTensor.getConstantVal() numSplits = curNode.getAttrVal("num_split").getI() inputTensorShape = extraNodeInfoDict[inputsRef[1]][0] assert(axis < len(inputTensorShape)) assert(inputTensorShape[axis] % numSplits == 0) #Should perfectly split sizeAlongSplitDim = int(inputTensorShape[axis]/numSplits) outputAsts = {} for i in range(0, numSplits): output_name = curNode.getName() if i != 0: output_name += ":" + str(i) subscriptRanges = [] for j in range(0, len(inputTensorShape)): start = 0 end = inputTensorShape[j] - 1 if j == axis: start = i*sizeAlongSplitDim end = start + sizeAlongSplitDim - 1 subscriptRanges.append((start,end)) outputAsts[output_name] = AST.Slice(AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]), subscriptRanges) return (None, outputAsts)
def Reshape(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() assert (len(inputsRef) == 2) return (None, AST.Reshape(AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), extraNodeInfoDict[curNode.getName()][0], None))
def StopGradient(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() return (None, { curNode.getName(): AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]) })
def ExpandDims(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef) == 2) retAST = AST.UninterpFuncCall(extraNodeInfoDict[curNode.getName()][0], TFNodesAST.UninterpFuncCallNames.ExpandDims.name, list(map(lambda x : AST.ID(dictNodeNameToOutVarStr[x]), inputsRef))) return (None, { curNode.getName() : retAST})
def Mean(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() attrMapRef = curNode.getAttrMapRef() assert (len(inputsRef) == 2) keepdims = False if ("keep_dims" in attrMapRef): keepdims = attrMapRef["keep_dims"].getB() reductionAxesNodeName = inputsRef[1] redAxesN = graph.__getitem__(reductionAxesNodeName) redAxesT = redAxesN.getAttrVal("value").getTensor() rank = redAxesT.getShapeRef().getRank() if rank != 0: reductionAxesList = redAxesT.getContentAsValArr() else: reductionAxesList = [redAxesT.getConstantVal()] curNodeShapeLi = extraNodeInfoDict[curNode.getName()][0] return (None, { curNode.getName(): AST.Reduce(AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), keepdims, curNodeShapeLi, TFNodesAST.getOperatorsIdx('mean'), reductionAxesList) })
def Placeholder( graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict, ): curNodeShapeLi = extraNodeInfoDict[curNode.getName()][0] curNodeInputType = curNode.getAttrMapRef()["dtype"].getDataType() assert curNodeInputType is not Graph.DataTypeEnum.DT_INVALID # NOTE: There has to be some way for Athos to differentiate model from image, since in the compiled code # (in the scenario of secure inference), model is input by server and image by client. # We assume in the following that the PlaceHolder op node represents the image and # all model parameters are represented using Variable op nodes. # Hence, in the call to AST.Input, we pass inputByParty=1. return ( None, { curNode.getName(): AST.Input( curNodeShapeLi, curNodeInputType.name, isSecret=True, inputByParty=AST.Party.CLIENT, ) }, )
def readGFA(gfaFile): gfa = open(gfaFile).read().split('\n')[:-1] nodesSeq = dict() edges = list() for line in gfa: if line[0] == 'S': fields = line.split('\t') nodesSeq[fields[1]] = fields[2] elif line[0] == 'L': fields = line.split('\t') node1 = fields[1] node1dir = fields[2] node2 = fields[3] node2dir = fields[4] ovlp = int(fields[5][:-1]) edges.append((node1, node1dir, node2, node2dir, ovlp)) G = Graph() for node1, node1dir, node2, node2dir, ovlp in edges: if node1 not in G.nodemap: n1_seq = nodesSeq[node1] n1 = Node(node1, len(n1_seq), n1_seq) else: n1 = G.nodemap[node1] if node2 not in G.nodemap: n2_seq = nodesSeq[node2] n2 = Node(node2, len(n2_seq), n2_seq) else: n2 = G.nodemap[node2] G.addEdge(n1, node1dir, n2, node2dir, ovlp) return G
def MatMul( graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict, ): inputsRef = curNode.getInputsRef() assert len(inputsRef) == 2 inp1Str = dictNodeNameToOutVarStr[inputsRef[0]] inp2Str = dictNodeNameToOutVarStr[inputsRef[1]] inp1AST = AST.ID(inp1Str) inp2AST = AST.ID(inp2Str) attrMapRef = curNode.getAttrMapRef() transposeABool = transposeBBool = False if "transpose_a" in attrMapRef: transposeABool = attrMapRef["transpose_a"].getB() if "transpose_b" in attrMapRef: transposeBBool = attrMapRef["transpose_b"].getB() if transposeABool: inp1AST = AST.Transp(inp1AST) if transposeBBool: inp2AST = AST.Transp(inp2AST) return ( None, { curNode.getName(): AST.BOp(inp1AST, TFNodesAST.getOperatorsIdx("*"), inp2AST) }, )
def helper_processPool( graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict, typeOfPool: str, ): inputsRef = curNode.getInputsRef() assert len(inputsRef) == 1 options = {} stridesUsed = curNode.getAttrMapRef()["strides"].getList().getILi() assert (stridesUsed[0] == 1) and (stridesUsed[3] == 1) strideH = stridesUsed[1] strideW = stridesUsed[2] kSizeUsed = curNode.getAttrMapRef()["ksize"].getList().getILi() assert (kSizeUsed[0] == 1) and (kSizeUsed[3] == 1) kSizeH = kSizeUsed[1] kSizeW = kSizeUsed[2] inputShape = extraNodeInfoDict[inputsRef[0]][0] imgH = inputShape[1] imgW = inputShape[2] paddingUsedStr = curNode.getAttrMapRef()["padding"].getS() [zPadHLeft, zPadHRight, zPadWLeft, zPadWRight] = TFNodesAST.helper_findPadding(imgH, imgW, kSizeH, kSizeW, strideH, strideW, paddingUsedStr) poolType = None if typeOfPool == "MAXPOOL": poolType = AST.Pool.PoolType.MaxPool elif typeOfPool == "AVGPOOL": poolType = AST.Pool.PoolType.AvgPool else: print("Unknown type of pooling layer.", file=sys.stderr) assert False return ( None, { curNode.getName(): AST.Pool( poolType, AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), { AST.PaddingKeysDict.FH: kSizeH, AST.PaddingKeysDict.FW: kSizeW, AST.PaddingKeysDict.zPadHLeft: zPadHLeft, AST.PaddingKeysDict.zPadHRight: zPadHRight, AST.PaddingKeysDict.zPadWLeft: zPadWLeft, AST.PaddingKeysDict.zPadWRight: zPadWRight, AST.PaddingKeysDict.strideH: strideH, AST.PaddingKeysDict.strideW: strideW, }, ) }, )
def Cast( graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict, ): inputsRef = curNode.getInputsRef() assert len(inputsRef) == 1 sourceType = curNode.getAttrMapRef()["SrcT"].getDataType() destType = curNode.getAttrMapRef()["DstT"].getDataType() return ( None, { curNode.getName(): AST.UninterpFuncCall( extraNodeInfoDict[curNode.getName()][0], TFNodesAST.UninterpFuncCallNames.Cast.name, [ AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), AST.ID(sourceType.name), AST.ID(destType.name), ], ) }, )
def VariableV2( graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict, ): curNodeShapeLi = curNode.getAttrMapRef()["shape"].getShape().getDimRef( )[:] curNodeInputType = curNode.getAttrMapRef()["dtype"].getDataType() # NOTE : since this becomes an input node right now, i have also added to be prefixed at top in ProcessTFGraph::prefixAllPlaceHolderNodes() # NOTE: There has to be some way for Athos to differentiate model from image, since in the compiled code # (in the scenario of secure inference), model is input by server and image by client. # We assume in the following that the PlaceHolder op node represents the image and # all model parameters are represented using Variable op nodes. # Hence, in the call to AST.Input, we pass inputByParty as SERVER. return ( None, { curNode.getName(): AST.Input( curNodeShapeLi, curNodeInputType.name, isSecret=True, inputByParty=AST.Party.SERVER, ) }, )
def Squeeze( graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict, ): inputsRef = curNode.getInputsRef() inputTensorShape = extraNodeInfoDict[inputsRef[0]][0] inputTensorRank = len(inputTensorShape) squeezeDims = curNode.getAttrMapRef()["squeeze_dims"].getList().getILi( ) squeezeDimsRank = len(squeezeDims) return ( None, { curNode.getName(): AST.UninterpFuncCall( extraNodeInfoDict[curNode.getName()][0], TFNodesAST.UninterpFuncCallNames.Squeeze.name, list( map(lambda x: AST.Int(x, 32, isSecret=False), squeezeDims)) + [AST.ID(dictNodeNameToOutVarStr[inputsRef[0]])], ) }, )
def Const(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): assert(len(curNode.getInputsRef()) == 0) tensor = curNode.getAttrMapRef()["value"].getTensor() curNodeDataType = curNode.getAttrMapRef()["dtype"].getDataType() curNodeShape = tensor.getShapeRef()[:] #create a different copy to not change the original copy tensorConstantVal = tensor.getConstantVal() if tensorConstantVal is not None: # Use uinterpreted call of CreateTensor to create the tensor and fill it with a constant value dataPassed = None if curNodeDataType == Graph.DataTypeEnum.DT_INT32: dataPassed = AST.Int(tensorConstantVal, 32, isSecret=False) elif curNodeDataType == Graph.DataTypeEnum.DT_FLOAT: dataPassed = AST.Float(tensorConstantVal, isSecret=False) else: assert False if (len(curNodeShape) == 0): # This is a constant element retAST = dataPassed else: retAST = AST.UninterpFuncCall(curNodeShape, TFNodesAST.UninterpFuncCallNames.CreateTensor.name, [dataPassed], isSecret=False) else: # The tensor content is given as byte array. Extract val array from the byte array and create ast. if curNodeDataType == Graph.DataTypeEnum.DT_INT32: dataPassed = list(map(lambda x: AST.Int(x, 32, isSecret=False), tensor.getContentAsValArr()[:])) elif curNodeDataType == Graph.DataTypeEnum.DT_FLOAT: dataPassed = list(map(lambda x: AST.Float(x, isSecret=False), tensor.getContentAsValArr()[:])) else: assert False retAST = AST.Decl(curNodeShape, None, dataPassed, isSecret=False) return (None, { curNode.getName() : retAST})
def Slice(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() assert (len(inputsRef) == 3) beginNode = graph.__getitem__(inputsRef[1]) sizeNode = graph.__getitem__(inputsRef[2]) assert beginNode.getAttrVal( "value" ) is not None, "begin {} of Slice node {} has to be a constant".format( inputsRef[1], curNode.getName()) assert sizeNode.getAttrVal( "value" ) is not None, "size {} of Slice node {} has to be a constant".format( inputsRef[2], curNode.getName()) begin = beginNode.getAttrVal("value").getTensor().getContentAsValArr() size = sizeNode.getAttrVal("value").getTensor().getContentAsValArr() assert begin is not None assert size is not None assert len(begin) == len(size) subscriptRanges = [] for i in range(0, len(size)): subscriptRanges.append((begin[i], begin[i] + size[i] - 1)) return (None, { curNode.getName(): AST.Slice(AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), subscriptRanges) })
def ArgMax(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef) == 2) return (None, { curNode.getName() : AST.ArgMax(extraNodeInfoDict[curNode.getName()][0], AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]), extraNodeInfoDict[inputsRef[0]][0])})
def FloorDiv(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef) == 2) realDivAST = AST.BOp(AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), TFNodesAST.getOperatorsIdx('./'), AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]) ) return (None, { curNode.getName() : AST.Func(TFNodesAST.getOperatorsIdx('floor'), realDivAST)})
def test_addNode(): tree = Tree.Tree() tree.addNode(Node.Node('a')) tree.addNode(Node.Node('b')) with pytest.raises(RuntimeError): tree.addNode(Node.Node('a'))
def Placeholder(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): #curNodeShapeLi = curNode.getAttrMapRef()["\"shape\""].getShape().getDimRef() curNodeShapeLi = extraNodeInfoDict[curNode.getName()][0] curNodeInputType = curNode.getAttrMapRef()["\"dtype\""].getDataType() assert (curNodeInputType is not Graph.DataTypeEnum.DT_INVALID) #TODO : There has to be some way to take range, understand the dimensions for SeeDot return (None, AST.Input(curNodeShapeLi, curNodeInputType.name))
def Main(): host = '127.0.0.1' port = 5000 s = socket.socket() s.bind((host, port)) print('Server started') s.listen(5) c, addr = s.accept() while True: print('client connected ip: ' + str(addr) + '>') string = c.recv(1024).decode('utf-8') if not string: break if '[' in string: string = string.replace('[', '') if ']' in string: string = string.replace(']', '') L = string.split(',') source = int(L[0]) target = int(L[1]) g = Graph() V = [Node(1), Node(2), Node(3), Node(4), Node(5), \ Node(6), Node(7), Node(8), Node(9), Node(10)] E = [[1, 2, 1], \ [1, 3, 3], \ [1, 4, 3], \ [2, 3, 1], \ [2, 5, 1], \ [2, 6, 8], \ [3, 4, 1], \ [3, 5, 1], \ [3, 6, 1], \ [3, 7, 2], \ [4, 6, 2], \ [4, 7, 3], \ [4, 8, 1], \ [5, 9, 1], \ [6, 9, 1], \ [6, 10, 7], \ [7, 9, 3], \ [7, 10, 2],\ [8, 10, 4]] g.addVertices(V) g.addEdges(E) path = DijkstrasAlgorithm(g, source, target) path_string = ','.join(str(e) for e in path) c.send(path_string.encode('utf-8')) s.close()
def Shape(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() assert (len(inputsRef) == 1) return (None, { curNode.getName(): AST.Func(TFNodesAST.getOperatorsIdx('shape'), AST.ID(dictNodeNameToOutVarStr[inputsRef[0]])) })
def cloneGraph(self, node): if not node: return node if node in self.visited: return self.visited[node] clone_node = Node(node.val, []) self.visited[node] = clone_node if node.neighbors: clone_node.neighbors = [self.cloneGraph(n) for n in node.neighbors] return clone_node
def ZerosLike(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef)==1) curNodeOutputType = curNode.getAttrMapRef()["T"].getDataType() assert(curNodeOutputType is not Graph.DataTypeEnum.DT_INVALID) retAST = AST.UninterpFuncCall(extraNodeInfoDict[curNode.getName()][0], TFNodesAST.UninterpFuncCallNames.CreateTensor.name, [AST.Int(0, isSecret=False)], isSecret=False) return (None, { curNode.getName() : retAST})
def test(): pathOfCollection = '.\\data\\test.csv' # 解析文件 # 读取csv文件,转为二维数组 collection = pd.read_csv(pathOfCollection) collectionList = collection.values.tolist() # 对图上的点和边进行插入 graph = Graph() for i in range(len(collectionList)): node_A = Node(collectionList[i][0], collectionList[i][1], collectionList[i][2]) if collectionList[i][0] in graph.G_node_dict: node_A = graph.G_node_dict[collectionList[i][0]] elif collectionList[i][0] in graph.H_node_dict: node_A = graph.H_node_dict[collectionList[i][0]] elif collectionList[i][0] in graph.J_node_dict: node_A = graph.J_node_dict[collectionList[i][0]] node_B = Node(collectionList[i][3], collectionList[i][4], collectionList[i][5]) if collectionList[i][3] in graph.G_node_dict: node_B = graph.G_node_dict[collectionList[i][3]] elif collectionList[i][3] in graph.H_node_dict: node_B = graph.H_node_dict[collectionList[i][3]] elif collectionList[i][3] in graph.J_node_dict: node_B = graph.J_node_dict[collectionList[i][3]] graph.insert_node(node_A) graph.insert_node(node_B) graph.add_edge(node_A, node_B) print(len(graph.G_node_dict)) print(len(graph.H_node_dict)) print(len(graph.J_node_dict)) print("文件阅读完毕。。。") # 生成所有的链路 topology_link_dict = graph.gen_all_topology_link() print(len(topology_link_dict)) print("带有主链路的链路解析完毕。。。") topology_link_list = list(topology_link_dict.values()) # 展示一个链路 # topology_link_list[0].show_main_link() # 打印链路 f = open(".\\data\\topology_link.txt", 'w+') for topology_link in topology_link_list: f.write(topology_link.main_link.hashcode_1 + "\n") print(1)
def Tile(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() assert (len(inputsRef) == 2) return (None, AST.UninterpFuncCall( extraNodeInfoDict[curNode.getName()][0], TFNodesAST.UninterpFuncCallNames.Tile.name, [ AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]) ]))
def FusedBatchNorm(graph: Graph.Graph, curNode: Graph.Node, dictNodeNameToOutVarStr: dict, extraNodeInfoDict: dict): inputsRef = curNode.getInputsRef() return (None, { curNode.getName(): AST.FusedBatchNorm( AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]), AST.ID(dictNodeNameToOutVarStr[inputsRef[2]]), ) })
def search (self, initialState): #Creating a Queue open = deque() open.append(Node(initialState, None)) while (len(open) > 0): n = open.popleft() if (n.state.is_goal()): return n for i in n.state.sucessors(): open.append(Node(i,n)) return None
def Transpose(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef) == 2) permNodeName = inputsRef[1] # We need to fetch the tensor value of the perm Node permNode = graph.__getitem__(permNodeName) permTensor = permNode.getAttrVal("value").getTensor() permList = permTensor.getContentAsValArr() assert(permTensor.getDType().kind == "i") assert(permTensor.getShapeRef().getRank() == 1) return (None, { curNode.getName() : AST.Transpose(AST.ID(dictNodeNameToOutVarStr[inputsRef[0]]), permList)})
def Conv3DBackpropInputV2(graph : Graph.Graph, curNode : Graph.Node, dictNodeNameToOutVarStr : dict, extraNodeInfoDict : dict): inputsRef = curNode.getInputsRef() assert(len(inputsRef)==3) #output_shape, filter, input stridesUsed = curNode.getAttrMapRef()["strides"].getList().getILi() assert(stridesUsed[0]==1 and stridesUsed[4]==1) strideD = stridesUsed[1] strideH = stridesUsed[2] strideW = stridesUsed[3] filterShape = extraNodeInfoDict[inputsRef[1]][0] FD = filterShape[0] FH = filterShape[1] FW = filterShape[2] inputShape = extraNodeInfoDict[inputsRef[2]][0] inputD = inputShape[1] inputH = inputShape[2] inputW = inputShape[3] outputShape = extraNodeInfoDict[curNode.getName()][0] outputD = outputShape[1] outputH = outputShape[2] outputW = outputShape[3] paddingUsedStr = curNode.getAttrMapRef()["padding"].getS() # Important: Using outputH and outputW in the below is not an error! # For convTranspose, the parameters passed in the node are of the conv of which this convTranspose is an inverse. # Which is why the call to helper_findPadding makes sense. # The zPads below are of the conv of which this convTranspose is an inverse. [zPadDLeft, zPadDRight, zPadHLeft, zPadHRight, zPadWLeft, zPadWRight] = TFNodesAST.helper_findPadding(outputH, outputW, FH, FW, strideH, strideW, paddingUsedStr, imgD = outputD, FD = FD, strideD = strideD) options = {} options[AST.PaddingKeysDict.FD] = FD options[AST.PaddingKeysDict.FH] = FH options[AST.PaddingKeysDict.FW] = FW options[AST.PaddingKeysDict.zPadDLeft] = zPadDLeft options[AST.PaddingKeysDict.zPadDRight] = zPadDRight options[AST.PaddingKeysDict.zPadHLeft] = zPadHLeft options[AST.PaddingKeysDict.zPadHRight] = zPadHRight options[AST.PaddingKeysDict.zPadWLeft] = zPadWLeft options[AST.PaddingKeysDict.zPadWRight] = zPadWRight options[AST.PaddingKeysDict.strideD] = strideD options[AST.PaddingKeysDict.strideH] = strideH options[AST.PaddingKeysDict.strideW] = strideW options[AST.PaddingKeysDict.ConvDim] = 3 options[AST.PaddingKeysDict.outputImgD] = outputD options[AST.PaddingKeysDict.outputImgH] = outputH options[AST.PaddingKeysDict.outputImgW] = outputW return (None, { curNode.getName() : AST.BOp(AST.ID(dictNodeNameToOutVarStr[inputsRef[2]]), TFNodesAST.getOperatorsIdx('#T'), AST.ID(dictNodeNameToOutVarStr[inputsRef[1]]), options)})
""" from Graph import Node from collections import deque def bfs(start, end): to_visit = deque() to_visit.append(start) visited = set() while len(to_visit) > 0: current = to_visit.popleft() if current is end: return True visited.add(current) for node in current.neighbors: if node not in visited: to_visit.append(node) # If control reaches here, the nodes are not connected return False if __name__ == '__main__': start = Node() start.add_neighbor(Node()) start.neighbors[0].add_neighbor(Node()) end = start.neighbors[0].neighbors[0] print(bfs(start, end)) # Expect: True print(bfs(end, start)) # Expect: False