nomnigraph_test.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. from caffe2.python import core, test_util
  2. from caffe2.proto import caffe2_pb2
  3. import caffe2.python.nomnigraph as ng
  4. from hypothesis import given
  5. import hypothesis.strategies as st
  6. import random
  7. class TestBindings(test_util.TestCase):
  8. def test_simple(self):
  9. nn = ng.NNModule()
  10. dfg = nn.dataFlow
  11. dfg.createNode(ng.NeuralNetData("X"))
  12. dfg.createNode(ng.NeuralNetOperator("FC"))
  13. assert len(nn.dataFlow.getMutableNodes()) == 2
  14. def test_core_net_simple(self):
  15. net = core.Net("name")
  16. net.FC(["X", "W"], ["Y"])
  17. nn = ng.NNModule(net)
  18. for node in nn.dataFlow.getMutableNodes():
  19. if node.isOperator():
  20. assert node.getName() == "FC"
  21. elif node.isTensor():
  22. assert node.getName() in ["X", "W", "Y"]
  23. def test_core_net_controlflow(self):
  24. net = core.Net("name")
  25. net.FC(["X", "W"], ["Y"])
  26. net.Relu(["Y"], ["Z"])
  27. nn = ng.NNModule(net)
  28. assert len(nn.controlFlow) == 2
  29. for instr in nn.controlFlow:
  30. assert instr.getType() == "Operator"
  31. assert nn.controlFlow[0].getName() == "FC"
  32. assert nn.controlFlow[1].getName() == "Relu"
  33. def test_core_net_nn_accessors(self):
  34. net = core.Net("name")
  35. net.FC(["X", "W"], ["Y"])
  36. net.Relu(["Y"], ["Z"])
  37. nn = ng.NNModule(net)
  38. tensors = set()
  39. for t in nn.tensors:
  40. tensors.add(t.name)
  41. assert tensors == set(["X", "W", "Y", "Z"])
  42. ops = set()
  43. for op in nn.operators:
  44. ops.add(op.name)
  45. assert ops == set(["FC", "Relu"])
  46. nodes = set()
  47. for node in nn.nodes:
  48. nodes.add(node.name)
  49. assert nodes == (ops | tensors)
  50. def test_netdef_simple(self):
  51. net = core.Net("name")
  52. net.FC(["X", "W"], ["Y"])
  53. nn = ng.NNModule(net.Proto())
  54. for node in nn.dataFlow.getMutableNodes():
  55. if node.isOperator():
  56. assert node.getOperator().getName() == "FC"
  57. elif node.isTensor():
  58. assert node.getTensor().getName() in ["X", "W", "Y"]
  59. def test_operatordef_simple(self):
  60. nn = ng.NNModule()
  61. dfg = nn.dataFlow
  62. op = core.CreateOperator("Ceil", ["X"], ["Y"], engine="CUDNN")
  63. dfg.createNode(op)
  64. for node in dfg.getMutableNodes():
  65. assert node.isOperator()
  66. assert node.getOperator().getName() == "Ceil"
  67. def test_invalid_node(self):
  68. nn = ng.NNModule()
  69. dfg = nn.dataFlow
  70. with self.assertRaises(Exception):
  71. dfg.createNode(7)
  72. def test_edges_simple(self):
  73. nn = ng.NNModule()
  74. dfg = nn.dataFlow
  75. x = dfg.createNode(ng.NeuralNetData("X"))
  76. w = dfg.createNode(ng.NeuralNetData("W"))
  77. op = dfg.createNode(ng.NeuralNetOperator("Op"))
  78. with self.assertRaises(Exception):
  79. dfg.createEdge(x, w)
  80. dfg.createEdge(op, w)
  81. dfg.createEdge(x, op)
  82. # Dot generation
  83. assert(str(dfg).startswith("digraph G"))
  84. # subgraph
  85. sg = ng.NNSubgraph()
  86. sg.addNode(x)
  87. sg.addNode(op)
  88. sg.induceEdges()
  89. assert len(sg) == 2
  90. # subgraph dot generation
  91. assert(str(sg).startswith("digraph G"))
  92. @given(size=st.sampled_from([10, 50]))
  93. def test_edges_complex(self, size):
  94. random.seed(1337)
  95. nn = ng.NNModule()
  96. dfg = nn.dataFlow
  97. data = []
  98. ops = []
  99. for _ in range(size):
  100. data.append(dfg.createNode(ng.NeuralNetData("X")))
  101. for i in range(size):
  102. ops.append(dfg.createNode(ng.NeuralNetOperator("Op" + str(i))))
  103. for i in range(size):
  104. for j in range(size):
  105. if bool(random.getrandbits(1)):
  106. dfg.createEdge(data[i], ops[j])
  107. def test_traversal(self):
  108. net = core.Net("test")
  109. net.FC(["X", "W"], ["Y"])
  110. net.Relu(["Y"], ["Z"])
  111. nn = ng.NNModule(net)
  112. fc = nn.controlFlow[0]
  113. relu = nn.controlFlow[1]
  114. assert not fc.inputs[0].hasProducer()
  115. assert fc.inputs[0].name == "X"
  116. assert fc.inputs[1].name == "W"
  117. assert relu.outputs[0].name == "Z"
  118. assert relu.inputs[0].name == "Y"
  119. assert relu.inputs[0].hasProducer()
  120. assert relu.inputs[0].producer.name == "FC"
  121. assert fc.outputs[0].consumers[0].name == "Relu"
  122. def test_debug(self):
  123. nn = ng.NNModule()
  124. dfg = nn.dataFlow
  125. dfg.createNode(ng.NeuralNetData("X"))
  126. dfg.createNode(ng.NeuralNetData("W"))
  127. dfg.createNode(ng.NeuralNetOperator("Op"))
  128. ng.render(nn.dataFlow)
  129. def test_match_graph_node(self):
  130. mg = ng.NNMatchGraph()
  131. mg.createNode(ng.NeuralNetOperator("test"))
  132. nn = ng.NNModule()
  133. test = nn.dataFlow.createNode(ng.NeuralNetOperator("test"))
  134. x = nn.dataFlow.createNode(ng.NeuralNetData("X"))
  135. nn.dataFlow.createEdge(x, test)
  136. count = 0
  137. for match in nn.match(mg):
  138. assert len(match) == 1
  139. count += 1
  140. # Dot generation of subgraph
  141. assert(str(match).startswith("digraph G"))
  142. assert count == 1
  143. def test_match_graph_node_strict(self):
  144. mg = ng.NNMatchGraph()
  145. mg.createNode(ng.NeuralNetOperator("test"), strict=True)
  146. nn = ng.NNModule()
  147. test = nn.dataFlow.createNode(ng.NeuralNetOperator("test"))
  148. x = nn.dataFlow.createNode(ng.NeuralNetData("X"))
  149. nn.dataFlow.createEdge(test, x)
  150. count = 0
  151. for match in nn.match(mg):
  152. assert len(match) == 1
  153. count += 1
  154. with self.assertRaises(Exception):
  155. assert count == 1
  156. def test_match_graph(self):
  157. mg = ng.NNMatchGraph()
  158. test2m = mg.createNode(ng.NeuralNetOperator("test2"), strict=True)
  159. xm = mg.createNode(ng.NeuralNetData("X"), strict=True)
  160. testm = mg.createNode(ng.NeuralNetOperator("test"))
  161. mg.createEdge(test2m, xm)
  162. mg.createEdge(xm, testm)
  163. nn = ng.NNModule()
  164. test2 = nn.dataFlow.createNode(ng.NeuralNetOperator("test2"))
  165. x = nn.dataFlow.createNode(ng.NeuralNetData("X"))
  166. test = nn.dataFlow.createNode(ng.NeuralNetOperator("test"))
  167. nn.dataFlow.createEdge(test2, x)
  168. nn.dataFlow.createEdge(x, test)
  169. count = 0
  170. for match in nn.match(mg):
  171. print(len(match))
  172. assert len(match) == 3
  173. count += 1
  174. assert count == 1
  175. def test_delete_subgraph(self):
  176. mg = ng.NNMatchGraph()
  177. test2m = mg.createNode(ng.NeuralNetOperator("test2"), strict=True)
  178. xm = mg.createNode(ng.NeuralNetData("X"), strict=True)
  179. testm = mg.createNode(ng.NeuralNetOperator("test"))
  180. mg.createEdge(test2m, xm)
  181. mg.createEdge(xm, testm)
  182. nn = ng.NNModule()
  183. test2 = nn.dataFlow.createNode(ng.NeuralNetOperator("test2"))
  184. x = nn.dataFlow.createNode(ng.NeuralNetData("X"))
  185. test = nn.dataFlow.createNode(ng.NeuralNetOperator("test"))
  186. nn.dataFlow.createEdge(test2, x)
  187. nn.dataFlow.createEdge(x, test)
  188. for m in nn.match(mg):
  189. match = m
  190. nn.deleteSubgraph(match)
  191. assert len(nn.controlFlow) == 0
  192. def test_replace_subraph(self):
  193. mg = ng.NNMatchGraph()
  194. test2m = mg.createNode(ng.NeuralNetOperator("test2"), strict=True)
  195. xm = mg.createNode(ng.NeuralNetData("X"), strict=True)
  196. testm = mg.createNode(ng.NeuralNetOperator("test"))
  197. mg.createEdge(test2m, xm)
  198. mg.createEdge(xm, testm)
  199. nn = ng.NNModule()
  200. test2 = nn.dataFlow.createNode(ng.NeuralNetOperator("test2"))
  201. x = nn.dataFlow.createNode(ng.NeuralNetData("X"))
  202. test = nn.dataFlow.createNode(ng.NeuralNetOperator("test"))
  203. nn.dataFlow.createEdge(test2, x)
  204. nn.dataFlow.createEdge(x, test)
  205. for m in nn.match(mg):
  206. match = m
  207. new_op = nn.dataFlow.createNode(ng.NeuralNetOperator("new_op"))
  208. nn.replaceSubgraph(match, new_op, [], [])
  209. assert len(nn.controlFlow) == 1
  210. assert nn.controlFlow[0].name == "new_op"
  211. def test_genericGraph(self):
  212. g = ng.Graph()
  213. n1 = g.createNode("hello1")
  214. n2 = g.createNode("hello2")
  215. e = g.createEdge(n1, n2)
  216. ng.render(g)
  217. def test_createUniqueDataNode(self):
  218. net = core.Net("name")
  219. nn = ng.NNModule(net)
  220. n1 = nn.createUniqueDataNode("a")
  221. self.assertEqual(n1.name[0], "a")
  222. n2 = nn.dataFlow.createNode(ng.Operator("test1"))
  223. nn.createEdge(n1, n2)
  224. n3 = nn.createUniqueDataNode("a")
  225. nn.createEdge(n2, n3)
  226. self.assertEqual(n3.name[0], "a")
  227. self.assertNotEqual(n1.name, n3.name)
  228. n1 = nn.createUniqueDataNode("b")
  229. n2 = nn.createUniqueDataNode("b")
  230. self.assertNotEqual(n1.name, n2.name)
  231. def test_convertToProto(self):
  232. net = core.Net("name")
  233. net.FC(["X", "W"], ["Y"])
  234. nn = ng.NNModule(net)
  235. new_netdef = nn.convertToCaffe2Proto()
  236. print(new_netdef)
  237. print(net.Proto())
  238. assert len(new_netdef.op) == len(net.Proto().op)
  239. for i in range(len(new_netdef.op)):
  240. op = net.Proto().op[i]
  241. new_op = new_netdef.op[i]
  242. assert op.type == new_op.type
  243. assert len(op.input) == len(new_op.input)
  244. assert len(op.output) == len(new_op.output)
  245. for a, b in zip(op.input, new_op.input):
  246. assert a == b
  247. for a, b in zip(op.output, new_op.output):
  248. assert a == b
  249. for a, b in zip(new_netdef.external_input, net.Proto().external_input):
  250. assert a == b
  251. for a, b in zip(new_netdef.external_output, net.Proto().external_output):
  252. assert a == b
  253. def test_node_interactions(self):
  254. nn = ng.NNModule()
  255. dfg = nn.dataFlow
  256. test1 = dfg.createNode(ng.Operator("test1"))
  257. test2 = dfg.createNode(ng.Operator("test2"))
  258. x = dfg.createNode(ng.Data("x"))
  259. dfg.createEdge(test1, x)
  260. dfg.createEdge(x, test2)
  261. p = test2.getOperatorPredecessors()
  262. assert len(p) == 1
  263. assert p[0] == test1
  264. # Add another node
  265. test3 = dfg.createNode(ng.Operator("test3"))
  266. y = dfg.createNode(ng.Data("y"))
  267. dfg.createEdge(test3, y)
  268. dfg.createEdge(y, test2)
  269. p = test2.getOperatorPredecessors()
  270. assert len(p) == 2
  271. assert test1 in p
  272. assert test3 in p
  273. # Successors
  274. assert len(test2.getOperatorSuccessors()) == 0
  275. assert len(test1.getOperatorSuccessors()) == 1
  276. assert test1.getOperatorSuccessors()[0] == test2
  277. # Check all the nodes are valid (pybind ownership test)
  278. for node in [test1, test2, test3]:
  279. assert node.isOperator()
  280. for node in [x, y]:
  281. assert node.isTensor()
  282. def test_delete_node(self):
  283. nn = ng.NNModule()
  284. node = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  285. nn.dataFlow.deleteNode(node)
  286. assert len(nn.dataFlow.getMutableNodes()) == 0
  287. def test_replace_producer(self):
  288. net = core.Net("name")
  289. net.FC(["X", "W"], ["Y"])
  290. nn = ng.NNModule(net)
  291. fc = nn.controlFlow[0]
  292. test_op = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  293. nn.replaceProducer(fc.outputs[0], test_op)
  294. nn.deleteNode(fc)
  295. assert len(nn.controlFlow) == 1
  296. assert nn.controlFlow[0].name == "TestOp"
  297. def test_replace_all_uses_with(self):
  298. net = core.Net("name")
  299. net.FC(["X", "W"], ["Y"])
  300. net.FC(["X", "W2"], ["Y2"])
  301. nn = ng.NNModule(net)
  302. fc = nn.controlFlow[0]
  303. test_tensor = nn.dataFlow.createNode(ng.NeuralNetData("T"))
  304. nn.replaceAllUsesWith(fc.inputs[0], test_tensor)
  305. for op in nn.controlFlow:
  306. assert op.inputs[0].name == "T"
  307. def test_replace_as_consumer(self):
  308. net = core.Net("name")
  309. net.FC(["X", "W"], ["Y"])
  310. nn = ng.NNModule(net)
  311. fc = nn.controlFlow[0]
  312. test_op = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  313. nn.replaceAsConsumer(fc, test_op)
  314. nn.deleteNode(fc)
  315. assert len(nn.controlFlow) == 1
  316. assert nn.controlFlow[0].name == "TestOp"
  317. assert nn.controlFlow[0].inputs[0].name == "X"
  318. assert nn.controlFlow[0].inputs[1].name == "W"
  319. def test_annotation_basic(self):
  320. annot = ng.Annotation()
  321. annot.setDevice("woot")
  322. assert annot.getDevice() == "woot"
  323. annot.setDeviceType(7)
  324. assert annot.getDeviceType() == 7
  325. def test_annotation_from_graph(self):
  326. nn = ng.NNModule()
  327. node = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  328. annot = node.getAnnotation()
  329. annot.setDeviceType(7)
  330. node.setAnnotation(annot)
  331. new_annot = node.getAnnotation()
  332. assert new_annot.getDeviceType() == 7
  333. def test_annotation_operator_def(self):
  334. nn = ng.NNModule()
  335. opdef = core.CreateOperator("Conv", [], [], engine="SENTINEL")
  336. node = nn.dataFlow.createNode(opdef)
  337. assert node.annotation.operator_def.engine == "SENTINEL"
  338. opdef = core.CreateOperator("Conv", [], [], engine="NEW_SENTINEL")
  339. node.annotation.operator_def = opdef
  340. netdef = nn.convertToCaffe2Proto()
  341. assert len(netdef.op) == 1
  342. assert netdef.op[0].engine == "NEW_SENTINEL"
  343. def test_annotation_device_option(self):
  344. nn = ng.NNModule()
  345. node = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  346. d = caffe2_pb2.DeviceOption()
  347. d.node_name = "test"
  348. node.annotation.device_option = d
  349. # access in a different way
  350. d_2 = nn.controlFlow[0].annotation.device_option
  351. assert d == d_2
  352. def test_has_device_option(self):
  353. nn = ng.NNModule()
  354. node = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  355. assert not node.annotation.hasDeviceOption()
  356. d = caffe2_pb2.DeviceOption()
  357. node.annotation.device_option = d
  358. assert node.annotation.hasDeviceOption()
  359. def test_distributed_annotations(self):
  360. nn = ng.NNModule()
  361. key = nn.dataFlow.createNode(ng.NeuralNetData("key"))
  362. length = nn.dataFlow.createNode(ng.NeuralNetData("length"))
  363. node = nn.dataFlow.createNode(ng.NeuralNetOperator("TestOp"))
  364. annot = ng.Annotation()
  365. annot.setKeyNode(key)
  366. annot.setLengthNode(length)
  367. annot.setComponentLevels(["", "test", "woot"])
  368. node.setAnnotation(annot)
  369. new_annot = node.getAnnotation()
  370. #assert new_annot.getLengthNode() == length
  371. assert new_annot.getKeyNode() == key
  372. assert len(new_annot.getComponentLevels()) == 3
  373. assert new_annot.getComponentLevels()[0] == ""
  374. assert new_annot.getComponentLevels()[2] == "woot"
  375. def test_distributed_device_map(self):
  376. net = core.Net("name")
  377. net.FC(["X", "W"], ["Y"])
  378. d = caffe2_pb2.DeviceOption()
  379. nn = ng.NNModule(net, {"X": d, "W": d})
  380. with self.assertRaises(Exception):
  381. nn = ng.NNModule(net, {"X": d, "Fake": d})