You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

debugger-mixin.vue 65 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903
  1. <script>
  2. import RequestService from '@/services/request-service';
  3. import {select, selectAll, zoom, dispatch} from 'd3';
  4. import 'd3-graphviz';
  5. const d3 = {select, selectAll, zoom, dispatch};
  6. export default {
  7. data() {
  8. return {
  9. conditionRulesMap: this.$t('debugger.tensorTuningRule'),
  10. };
  11. },
  12. methods: {
  13. handleCurrentChange(page) {
  14. this.pagination.currentPage = page;
  15. this.searchWatchpointHits(false);
  16. },
  17. showOrigin() {
  18. this.loadOriginalTree();
  19. this.queryWatchPoints();
  20. },
  21. /**
  22. * Initialize the condition
  23. */
  24. initCondition() {
  25. if (this.metadata.state === this.state.running || this.metadata.state === this.state.sending) {
  26. return;
  27. }
  28. RequestService.queryConditions(this.trainId).then((res) => {
  29. if (res && res.data) {
  30. this.conditionCollections = res.data;
  31. this.addWatchPoint();
  32. }
  33. });
  34. },
  35. transCondition(str) {
  36. if (!str) {
  37. return '';
  38. }
  39. let temp;
  40. if (this.conditionRulesMap[str]) {
  41. temp = this.conditionRulesMap[str];
  42. } else if (str.endsWith('_lt')) {
  43. temp = str.replace(/_lt$/, ' <');
  44. } else if (str.endsWith('_gt')) {
  45. temp = str.replace(/_gt$/, ' >');
  46. } else if (str.endsWith('_ge')) {
  47. temp = str.replace(/_ge$/, ' >=');
  48. } else {
  49. temp = str;
  50. }
  51. if (temp.includes('max_min')) {
  52. temp = temp.replace('max_min', 'max-min');
  53. }
  54. return temp;
  55. },
  56. /**
  57. * Collaspe btn click function
  58. */
  59. collapseBtnClick() {
  60. this.leftShow = !this.leftShow;
  61. setTimeout(() => {
  62. this.initSvg(false);
  63. }, 500);
  64. },
  65. /**
  66. * Step input validation
  67. */
  68. stepChange() {
  69. if (this.step === '') {
  70. return;
  71. }
  72. const maxStep = 2147483648;
  73. this.step = this.step
  74. .toString()
  75. .replace(/[^\.\d]/g, '')
  76. .replace(/\./g, '');
  77. this.step = Number(this.step);
  78. if (this.step === 0) {
  79. this.step = 1;
  80. }
  81. if (this.step >= maxStep) {
  82. this.step = maxStep - 1;
  83. }
  84. },
  85. /**
  86. * Query current node info
  87. */
  88. getCurrentNodeInfo() {
  89. this.loadingInstance = this.$loading(this.loadingOption);
  90. let name = this.currentNodeName;
  91. const params = {
  92. mode: 'node',
  93. params: {
  94. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  95. name,
  96. single_node: true,
  97. node_type: 'leaf',
  98. },
  99. };
  100. if (this.graphFiles.value === this.$t('debugger.all')) {
  101. name = `${this.metadata.graph_name}/${this.currentNodeName}`;
  102. params.params.name = name;
  103. } else {
  104. if (this.metadata.graph_name !== this.graphFiles.value) {
  105. this.graphFiles.value = this.metadata.graph_name;
  106. this.isCurrentGraph = false;
  107. }
  108. params.params.graph_name = this.graphFiles.value;
  109. }
  110. RequestService.retrieve(params).then(
  111. (res) => {
  112. if (res.data) {
  113. if (res.data.metadata) {
  114. this.dealMetadata(res.data.metadata);
  115. }
  116. if (res.data.graph) {
  117. const graph = res.data.graph;
  118. if (graph.nodes && !this.isCurrentGraph) {
  119. this.node.childNodes = [];
  120. this.origialTree = graph.nodes.map((val) => {
  121. return {
  122. label: val.name.split('/').pop(),
  123. leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
  124. ...val,
  125. showCheckbox: val.watched !== -1,
  126. };
  127. });
  128. this.resolve(this.origialTree);
  129. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  130. this.node.childNodes.forEach((val) => {
  131. if (val.data.watched === this.checkboxStatus.checked) {
  132. val.checked = true;
  133. }
  134. if (val.data.watched === this.checkboxStatus.indeterminate) {
  135. val.indeterminate = true;
  136. }
  137. });
  138. this.isCurrentGraph = true;
  139. this.firstFloorNodes = [];
  140. this.allGraphData = {};
  141. d3.select('#graph svg').remove();
  142. this.selectedNode.name = '';
  143. this.packageDataToObject('', true, JSON.parse(JSON.stringify(graph.nodes)));
  144. this.querySingleNode(JSON.parse(JSON.stringify(graph)), name, true);
  145. } else {
  146. this.querySingleNode(JSON.parse(JSON.stringify(graph)), name, true);
  147. }
  148. if (graph.children) {
  149. this.dealTreeData(graph.children, name);
  150. this.defaultCheckedArr = this.$refs.tree.getCheckedKeys();
  151. }
  152. }
  153. }
  154. this.loadingInstance.close();
  155. },
  156. (err) => {
  157. this.showErrorMsg(err);
  158. this.loadingInstance.close();
  159. },
  160. );
  161. },
  162. /**
  163. * Query next node info
  164. */
  165. getNextNodeInfo() {
  166. this.loadingInstance = this.$loading(this.loadingOption);
  167. this.pagination.currentPage = 1;
  168. this.watchPointHits = [];
  169. this.pagination.total = 0;
  170. const params = {
  171. mode: 'continue',
  172. level: 'node',
  173. name: '',
  174. graph_name: this.graphFiles.value,
  175. };
  176. if (this.graphFiles.value === this.$t('debugger.all')) {
  177. delete params.graph_name;
  178. }
  179. RequestService.control(params).then(
  180. (res) => {},
  181. (err) => {
  182. this.showErrorMsg(err);
  183. },
  184. );
  185. },
  186. /**
  187. * In Ascend environment,query node info.
  188. * @param {Boolean} ascend previous or next
  189. */
  190. getNodeByBfs(ascend) {
  191. const data = this.$refs.tree.getCurrentNode();
  192. let name = this.$refs.tree.getCurrentKey();
  193. if (
  194. (data && (data.type === 'name_scope' || data.type === 'aggregation_scope')) ||
  195. this.curLeafNodeName === null
  196. ) {
  197. name = this.curLeafNodeName;
  198. }
  199. const params = {
  200. ascend,
  201. name,
  202. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  203. graph_name: this.graphFiles.value,
  204. };
  205. if (this.graphFiles.value === this.$t('debugger.all')) {
  206. delete params.graph_name;
  207. }
  208. RequestService.retrieveNodeByBfs(params).then(
  209. (res) => {
  210. if (res.data && res.data.graph && res.data.name) {
  211. this.retrieveTensorHistory({name: res.data.name});
  212. const graph = res.data.graph;
  213. this.curLeafNodeName = res.data.name;
  214. this.nodeName = res.data.name;
  215. if (graph.children) {
  216. this.dealTreeData(graph.children, name);
  217. this.defaultCheckedArr = this.$refs.tree.getCheckedKeys();
  218. }
  219. this.querySingleNode(JSON.parse(JSON.stringify(graph)), res.data.name);
  220. } else if (ascend) {
  221. this.$message.success(this.$t('debugger.nextNodeTip'));
  222. } else {
  223. this.$message.success(this.$t('debugger.previousNodeTip'));
  224. }
  225. },
  226. (err) => {
  227. this.showErrorMsg(err);
  228. },
  229. );
  230. },
  231. /**
  232. * Terminate current training
  233. */
  234. terminate() {
  235. this.$confirm(this.$t('debugger.ternimateConfirm'), this.$t('public.notice'), {
  236. confirmButtonText: this.$t('public.sure'),
  237. cancelButtonText: this.$t('public.cancel'),
  238. type: 'warning',
  239. }).then(
  240. () => {
  241. this.control(2);
  242. },
  243. (err) => {
  244. this.showErrorMsg(err);
  245. },
  246. );
  247. },
  248. /**
  249. * Table row add className
  250. * @return { String }
  251. */
  252. tableRowClassName({row}) {
  253. if (row.is_hit) {
  254. return 'success-row';
  255. }
  256. return '';
  257. },
  258. /**
  259. * Table merged cells
  260. * @return { Object }
  261. */
  262. objectSpanMethod({row, column, rowIndex, columnIndex}) {
  263. let inputLength = 0;
  264. let outputLength = 0;
  265. if (this.tabs.activeName === 'tensor') {
  266. inputLength = this.inputLength;
  267. outputLength = this.outputLength;
  268. } else {
  269. inputLength = this.selectedNode.inputNum;
  270. outputLength = this.selectedNode.outputNum;
  271. }
  272. if (columnIndex === 0 && outputLength > 0) {
  273. if (rowIndex === 0) {
  274. return {
  275. rowspan: outputLength,
  276. colspan: 1,
  277. };
  278. } else if (rowIndex > 0 && rowIndex < outputLength) {
  279. return {
  280. rowspan: 0,
  281. colspan: 0,
  282. };
  283. } else if (rowIndex === outputLength) {
  284. return {
  285. rowspan: inputLength,
  286. colspan: 1,
  287. };
  288. } else {
  289. return {
  290. rowspan: 0,
  291. colspan: 0,
  292. };
  293. }
  294. }
  295. },
  296. /**
  297. * Table header merged cells
  298. * @return { Object }
  299. */
  300. discountHeaderStyle({row, column, rowIndex, columnIndex}) {
  301. if (rowIndex === 1) {
  302. return {display: 'none'};
  303. }
  304. },
  305. /**
  306. * Handle node click
  307. * @param { Object } data node data
  308. */
  309. handleNodeClick(data) {
  310. this.isIntoView = false;
  311. this.selectedNode.name = data.name;
  312. if (this.treeFlag) {
  313. this.querySingleNode({}, data.name, true);
  314. } else {
  315. if (this.graphFiles.value === this.$t('debugger.all')) {
  316. if (data.name.includes('/')) {
  317. const graphName = data.name.split('/')[0];
  318. this.queryAllTreeData(data.name.replace(`${graphName}/`, ''), true, graphName, true);
  319. } else {
  320. this.queryAllTreeData(data.name, true, data.name, true);
  321. }
  322. } else {
  323. this.queryAllTreeData(data.name, true, this.graphFiles.value, true);
  324. }
  325. }
  326. },
  327. /**
  328. * Query tensor value
  329. * @param { Object } data node info
  330. * @param { String } graphName Graph name
  331. */
  332. retrieveTensorHistory(data, graphName) {
  333. const params = {
  334. name: data.name,
  335. };
  336. if (this.graphFiles.value === this.$t('debugger.all')) {
  337. params.name = `${graphName}/${data.name}`;
  338. } else {
  339. params.graph_name = graphName;
  340. }
  341. RequestService.retrieveTensorHistory(params).then(
  342. (res) => {
  343. if (res.data && res.data.metadata) {
  344. this.dealMetadata(res.data.metadata);
  345. }
  346. if (data.name === this.nodeName) {
  347. if (res.data && res.data.tensor_history) {
  348. this.tableData = res.data.tensor_history;
  349. this.dealTableData(this.tableData);
  350. } else {
  351. this.tableData = [];
  352. }
  353. }
  354. },
  355. (err) => {
  356. this.showErrorMsg(err);
  357. },
  358. );
  359. },
  360. /**
  361. * Deal tensor history table data
  362. * @param {Array} arr tensor history data
  363. */
  364. dealTableData(arr) {
  365. const output = arr.filter((val) => val.type === 'output');
  366. const input = arr.filter((val) => val.type === 'input');
  367. this.outputLength = output.length;
  368. this.inputLength = input.length;
  369. arr.splice(0, arr.length, ...output.concat(input));
  370. arr.forEach((val) => {
  371. if (Array.isArray(val.shape)) {
  372. val.shape = `[${val.shape.toString()}]`;
  373. } else {
  374. if (val.shape !== undefined) {
  375. val.shape = val.shape + '';
  376. }
  377. }
  378. if (val.value === 'click to view') {
  379. } else {
  380. if (Array.isArray(val.value)) {
  381. val.value = `[${val.value.toString()}]`;
  382. } else {
  383. if (val.value !== undefined) {
  384. val.value = val.value + '';
  385. }
  386. }
  387. }
  388. if (val.dtype !== undefined) {
  389. val.dtype = val.dtype + '';
  390. }
  391. });
  392. },
  393. /**
  394. * Deal metadata
  395. * @param {Object} metadata metadata
  396. * @param {Boolean} isQuery wheather to query tree data
  397. */
  398. dealMetadata(metadata) {
  399. if (
  400. metadata.graph_name &&
  401. metadata.graph_name !== this.graphFiles.value &&
  402. this.graphFiles.value !== this.$t('debugger.all')
  403. ) {
  404. this.graphFiles.value = metadata.graph_name;
  405. this.isCurrentGraph = false;
  406. }
  407. this.metadata.pos = metadata.pos;
  408. if (metadata.enable_recheck !== undefined) {
  409. this.enableRecheck = metadata.enable_recheck;
  410. }
  411. if (metadata.state) {
  412. this.metadata.state = metadata.state;
  413. }
  414. if (metadata.debugger_version) {
  415. this.debuggerVersion = metadata.debugger_version;
  416. }
  417. if (metadata.node_name !== undefined && metadata.step !== undefined) {
  418. const nodeName = metadata.node_name;
  419. if ((nodeName !== this.currentNodeName && nodeName !== '') || this.metadata.step !== metadata.step) {
  420. if (nodeName) {
  421. this.nodeName = nodeName;
  422. this.currentNodeName = nodeName;
  423. }
  424. this.metadata.step = metadata.step;
  425. let graphName = this.graphFiles.value === this.$t('debugger.all') ? '' : this.graphFiles.value;
  426. if (this.graphFiles.value === this.$t('debugger.all') && this.selectedNode.name) {
  427. graphName = this.selectedNode.name.split('/')[0];
  428. }
  429. if (metadata.graph_name) {
  430. this.metadata.graph_name = metadata.graph_name;
  431. graphName = metadata.graph_name;
  432. }
  433. if (nodeName) {
  434. if (this.selectedNode.name) {
  435. if (nodeName === this.selectedNode.name) {
  436. this.selectNode(true, true);
  437. } else {
  438. this.queryAllTreeData(nodeName, true, graphName);
  439. }
  440. } else {
  441. this.queryAllTreeData(nodeName, true, graphName);
  442. }
  443. } else {
  444. if (this.selectedNode.name) {
  445. if (this.nodeName === this.selectedNode.name) {
  446. this.selectNode(true, true);
  447. } else {
  448. this.queryAllTreeData(this.nodeName, true, graphName);
  449. }
  450. }
  451. }
  452. } else {
  453. this.loadingInstance.close();
  454. }
  455. }
  456. if (metadata.step && metadata.step > this.metadata.step) {
  457. this.metadata.step = metadata.step;
  458. }
  459. },
  460. /**
  461. * Long polling,update some info
  462. */
  463. pollData() {
  464. const params = {
  465. pos: this.metadata.pos,
  466. graph_name: this.graphFiles.value,
  467. };
  468. if (this.graphFiles.value === this.$t('debugger.all')) {
  469. delete params.graph_name;
  470. }
  471. RequestService.pollData(params).then(
  472. (res) => {
  473. if (res.data) {
  474. if (res.data.metadata) {
  475. this.dealMetadata(res.data.metadata);
  476. }
  477. let name = null;
  478. if (this.$refs.tree && this.$refs.tree.getCurrentKey()) {
  479. name = this.$refs.tree.getCurrentKey();
  480. }
  481. let graphName = this.graphFiles.value;
  482. if (
  483. res.data.receive_tensor &&
  484. res.data.metadata &&
  485. res.data.metadata.step >= this.metadata.step &&
  486. res.data.receive_tensor.node_name === name
  487. ) {
  488. if (this.graphFiles.value === this.$t('debugger.all')) {
  489. graphName = name.split('/')[0];
  490. name = name.replace(`${graphName}/`, '');
  491. }
  492. this.retrieveTensorHistory(
  493. {
  494. name,
  495. },
  496. graphName,
  497. );
  498. }
  499. if (res.data.receive_watchpoint_hits) {
  500. this.radio1 = 'hit';
  501. this.pagination.currentPage = 1;
  502. this.watchPointHits = [];
  503. this.pagination.total = 0;
  504. this.searchWatchpointHits(true);
  505. }
  506. if (
  507. res.data.receive_tensor &&
  508. res.data.receive_tensor.graph_name &&
  509. res.data.receive_tensor.tensor_name &&
  510. this.tensorCompareFlag
  511. ) {
  512. const debTensor = this.$refs['deb-tensor'];
  513. if (debTensor) {
  514. debTensor.updateGraphData(res.data.receive_tensor.graph_name, res.data.receive_tensor.tensor_name);
  515. }
  516. }
  517. this.pollData();
  518. }
  519. },
  520. (err) => {
  521. if (!err || (err && err.message !== 'routeJump')) {
  522. this.initFail = true;
  523. this.dialogVisible = true;
  524. }
  525. },
  526. );
  527. },
  528. /**
  529. * Step,continue,pause,terminate opesssrate
  530. * @param {Number} type
  531. */
  532. control(type) {
  533. if (type !== 3) {
  534. this.pagination.currentPage = 1;
  535. this.watchPointHits = [];
  536. this.pagination.total = 0;
  537. }
  538. const params = {};
  539. if (type === 0) {
  540. if (!this.step) {
  541. return;
  542. }
  543. params.mode = 'continue';
  544. params.steps = parseInt(this.step);
  545. } else if (type === 1) {
  546. params.mode = 'continue';
  547. params.steps = -1;
  548. } else if (type === 2) {
  549. params.mode = 'terminate';
  550. } else if (type === 3) {
  551. params.mode = 'pause';
  552. }
  553. RequestService.control(params).then(
  554. (res) => {
  555. if (res.data && res.data.metadata) {
  556. setTimeout(() => {
  557. let msg = '';
  558. if (this.metadata.state === this.state.sending) {
  559. msg = this.$t('debugger.stateMsg.sending');
  560. } else if (this.metadata.state === this.state.running) {
  561. msg = this.$t('debugger.stateMsg.running');
  562. } else {
  563. msg = `${this.$t('debugger.backstageStatus')}${this.metadata.state}`;
  564. }
  565. this.$message(msg);
  566. }, 500);
  567. this.metadata.state = res.data.metadata.state;
  568. }
  569. },
  570. (err) => {
  571. this.showErrorMsg(err);
  572. },
  573. );
  574. },
  575. /**
  576. * Show orginal tree
  577. */
  578. loadOriginalTree() {
  579. this.node.childNodes = [];
  580. this.curWatchPointId = null;
  581. this.defaultCheckedArr = [];
  582. this.resolve(JSON.parse(JSON.stringify(this.origialTree)));
  583. this.resetGraph();
  584. },
  585. recheckWatchpoint() {
  586. if (!this.enableRecheck) {
  587. return;
  588. }
  589. RequestService.recheckWatchPoints().then(
  590. (res) => {
  591. if (res && res.data && res.data.metadata) {
  592. if (res.data.metadata.enable_recheck !== undefined) {
  593. this.enableRecheck = res.data.metadata.enable_recheck;
  594. this.pagination.currentPage = 1;
  595. this.watchPointHits = [];
  596. this.pagination.total = 0;
  597. }
  598. if (res.data.metadata.state) {
  599. this.metadata.state = res.data.metadata.state;
  600. }
  601. }
  602. this.$message.success(this.$t('debugger.recheckSuccess'));
  603. },
  604. (err) => {},
  605. );
  606. },
  607. /**
  608. * Add watchpoint
  609. */
  610. addWatchPoint() {
  611. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.errorType');
  612. this.createWatchPointArr = [];
  613. this.createWatchPointArr.push({
  614. collection: {
  615. selectedId: this.conditionCollections[0].id,
  616. },
  617. condition: {
  618. selectedId: '',
  619. options: [],
  620. },
  621. param: {
  622. options: [],
  623. name: '',
  624. value: '',
  625. type: '',
  626. },
  627. compositeParams: {
  628. options: [],
  629. selections: [],
  630. },
  631. });
  632. this.collectionChange(this.createWatchPointArr[0]);
  633. this.createWPDialogVisible = true;
  634. this.curWatchPointId = null;
  635. },
  636. /**
  637. * Delete new watchpoint
  638. * @param {Object} item watchpoint data
  639. */
  640. deleteWatchpoint(item) {
  641. if (
  642. !this.watchPointArr.length ||
  643. this.metadata.state === this.state.running ||
  644. this.metadata.state === this.state.sending
  645. ) {
  646. return;
  647. }
  648. if ((item && item.id) || !item) {
  649. const msg = item ? this.$t('debugger.deleteWatchpointConfirm') : this.$t('debugger.clearWatchpointConfirm');
  650. this.$confirm(msg, this.$t('public.notice'), {
  651. confirmButtonText: this.$t('public.sure'),
  652. cancelButtonText: this.$t('public.cancel'),
  653. type: 'warning',
  654. }).then(() => {
  655. const params = {watch_point_id: item ? item.id : null};
  656. RequestService.deleteWatchpoint(params).then(
  657. (res) => {
  658. if (!item) {
  659. this.curWatchPointId = null;
  660. this.watchPointArr = [];
  661. }
  662. this.loadOriginalTree();
  663. this.queryWatchPoints();
  664. this.$message.success(this.$t('debugger.successDeleteWP'));
  665. if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
  666. this.enableRecheck = res.data.metadata.enable_recheck;
  667. }
  668. this.curWatchPointId = null;
  669. },
  670. (err) => {
  671. this.showErrorMsg(err);
  672. },
  673. );
  674. });
  675. } else {
  676. this.curWatchPointId = null;
  677. }
  678. },
  679. validateParam(item) {
  680. const reg = /^(\-|\+)?\d+(\.\d+)?$/;
  681. this.validPram = reg.test(item.param.value);
  682. item.compositeParams.selections.forEach((i) => {
  683. this.validPram = this.validPram && reg.test(i.value);
  684. });
  685. if (!this.validPram) {
  686. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.errorType');
  687. } else {
  688. this.paramErrorMsg = '';
  689. const inputValue = parseFloat(item.param.value);
  690. const absParams = [
  691. 'abs_mean_gt',
  692. 'abs_mean_lt',
  693. 'rtol',
  694. 'abs_mean_update_ratio_gt',
  695. 'abs_mean_update_ratio_lt',
  696. ];
  697. if (absParams.includes(item.param.name) && inputValue < 0) {
  698. this.validPram = false;
  699. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.nonnegative');
  700. }
  701. const positiveParams = ['max_min_lt', 'max_min_gt'];
  702. if (positiveParams.includes(item.param.name) && inputValue <= 0) {
  703. this.validPram = false;
  704. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.allPositive');
  705. }
  706. if (this.percentParams.includes(item.param.name)) {
  707. const percentRange = {min: 0, max: 100};
  708. if (inputValue < percentRange.min || inputValue > percentRange.max) {
  709. this.validPram = false;
  710. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.percentError');
  711. }
  712. }
  713. if (this.validPram && item.compositeParams.selections.length) {
  714. const rangeKey = ['range_start_inclusive', 'range_end_inclusive'];
  715. const rangeStart = item.compositeParams.selections.filter((i) => {
  716. return i.name === rangeKey[0];
  717. });
  718. const rangeEnd = item.compositeParams.selections.filter((i) => {
  719. return i.name === rangeKey[1];
  720. });
  721. if (rangeStart.length && rangeEnd.length) {
  722. const start = parseFloat(rangeStart[0].value);
  723. const end = parseFloat(rangeEnd[0].value);
  724. if (start > end) {
  725. this.validPram = false;
  726. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.rangeError');
  727. }
  728. }
  729. }
  730. }
  731. this.$forceUpdate();
  732. },
  733. /**
  734. * Create new watchpoint
  735. * @param {Boolean} creatFlag Whether create watchpoint
  736. */
  737. createWatchPoint(creatFlag) {
  738. if (creatFlag) {
  739. const item = this.createWatchPointArr[0];
  740. const params = {
  741. condition: {
  742. id: item.condition.selectedId,
  743. params: [],
  744. },
  745. watch_nodes: [],
  746. graph_name: this.graphFiles.value,
  747. };
  748. if (this.graphFiles.value === this.$t('debugger.all')) {
  749. delete params.graph_name;
  750. }
  751. if (item.param.options.length) {
  752. params.condition.params = [
  753. {
  754. name: item.param.name,
  755. value: item.param.type === 'BOOL' ? Boolean(item.param.value) : Number(item.param.value),
  756. },
  757. ];
  758. }
  759. if (item.compositeParams.selections.length) {
  760. item.compositeParams.selections.forEach((i) => {
  761. params.condition.params.push({
  762. name: i.name,
  763. value: i.type === 'BOOL' ? Boolean(i.value) : Number(i.value),
  764. });
  765. });
  766. }
  767. RequestService.createWatchpoint(params).then(
  768. (res) => {
  769. this.createWatchPointArr = [];
  770. this.createWPDialogVisible = false;
  771. this.$message.success(this.$t('debugger.successCreateWP'));
  772. if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
  773. this.enableRecheck = res.data.metadata.enable_recheck;
  774. }
  775. this.queryWatchPoints(true);
  776. },
  777. (err) => {
  778. this.loadOriginalTree();
  779. this.queryWatchPoints();
  780. this.showErrorMsg(err);
  781. },
  782. );
  783. } else {
  784. this.createWatchPointArr = [];
  785. this.createWPDialogVisible = false;
  786. }
  787. },
  788. /**
  789. * Collection change processing
  790. * @param {Object} item
  791. */
  792. collectionChange(item) {
  793. const collection = this.conditionCollections.filter((i) => {
  794. return i.id === item.collection.selectedId;
  795. })[0];
  796. if (collection.conditions && collection.conditions.length) {
  797. item.condition.options = collection.conditions;
  798. item.condition.selectedId = item.condition.options[0].id;
  799. this.conditionChange(item);
  800. } else {
  801. item.condition.options = [];
  802. item.condition.selectedId = '';
  803. item.param.options = [];
  804. item.param.name = '';
  805. item.param.type = '';
  806. item.param.value = '';
  807. this.validPram = false;
  808. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.errorType');
  809. }
  810. },
  811. /**
  812. * Condition change processing
  813. * @param {Object} item
  814. */
  815. conditionChange(item) {
  816. const condition = item.condition.options.filter((i) => {
  817. return i.id === item.condition.selectedId;
  818. })[0];
  819. if (condition.parameters && condition.parameters.length) {
  820. item.param.options = condition.parameters.filter((i) => {
  821. return i.param_type !== 'SUPPORT_PARAM';
  822. });
  823. item.compositeParams.options = condition.parameters.filter((i) => {
  824. return i.param_type === 'SUPPORT_PARAM';
  825. });
  826. item.param.name = item.param.options[0].name;
  827. this.paramChange(item);
  828. } else {
  829. item.param.options = [];
  830. item.param.name = '';
  831. item.param.type = '';
  832. item.param.value = '';
  833. this.validPram = true;
  834. item.compositeParams.options = [];
  835. item.compositeParams.selections = [];
  836. }
  837. },
  838. /**
  839. * Parameter change processing
  840. * @param {Object} item
  841. */
  842. paramChange(item) {
  843. const param = item.param.options.filter((i) => {
  844. return i.name === item.param.name;
  845. })[0];
  846. if (param.required_params && param.required_params.length) {
  847. item.compositeParams.selections = item.compositeParams.options.filter((i) => {
  848. return param.required_params.includes(i.name);
  849. });
  850. item.compositeParams.selections.forEach((i) => {
  851. i.value = i.type === 'BOOL' ? true : '';
  852. });
  853. } else {
  854. item.compositeParams.selections = [];
  855. }
  856. item.param.type = param.type;
  857. item.param.value = '';
  858. this.validPram = false;
  859. this.paramErrorMsg = this.$t('debugger.paramErrorMsg.errorType');
  860. if (item.param.type === 'BOOL') {
  861. item.param.value = true;
  862. this.validPram = true;
  863. }
  864. },
  865. /** Draw the tree
  866. * @param {Object} obj Current checked obj
  867. */
  868. check(obj) {
  869. const node = this.$refs.tree.getNode(obj.name);
  870. const check = node.checked;
  871. if (check) {
  872. node.data.watched = this.checkboxStatus.checked;
  873. } else {
  874. node.data.watched = this.checkboxStatus.unchecked;
  875. }
  876. if (this.treeFlag && node.childNodes) {
  877. this.dealCheckPro(node.childNodes, node.indeterminate || check);
  878. }
  879. if (this.curWatchPointId) {
  880. this.$refs.tree.getCheckedKeys().forEach((val) => {
  881. const node = this.$refs.tree.getNode(val);
  882. if (node.data.watched === this.checkboxStatus.noCheckbox) {
  883. node.checked = false;
  884. }
  885. });
  886. const checkedKeys = this.$refs.tree.getCheckedKeys();
  887. const watchNodes = [];
  888. if (this.defaultCheckedArr.length === checkedKeys.length) {
  889. return;
  890. } else if (this.defaultCheckedArr.length > checkedKeys.length) {
  891. watchNodes.push(obj.name);
  892. } else {
  893. checkedKeys.forEach((val) => {
  894. if (this.defaultCheckedArr.indexOf(val) === -1) {
  895. watchNodes.push(val);
  896. }
  897. });
  898. }
  899. const params = {
  900. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  901. watch_nodes: watchNodes,
  902. mode: node.indeterminate || check ? 1 : 0,
  903. graph_name: this.graphFiles.value,
  904. };
  905. if (this.graphFiles.value === this.$t('debugger.all')) {
  906. delete params.graph_name;
  907. }
  908. if (this.searchWord !== '') {
  909. params.name = this.searchWord;
  910. params.watch_nodes = [obj.name];
  911. params.mode = check ? 1 : 0;
  912. }
  913. RequestService.updateWatchpoint(params).then(
  914. (res) => {
  915. this.defaultCheckedArr = checkedKeys;
  916. if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
  917. this.enableRecheck = res.data.metadata.enable_recheck;
  918. }
  919. this.$nextTick(() => {
  920. if (node.indeterminate) {
  921. node.checked = true;
  922. node.indeterminate = false;
  923. }
  924. if (check) {
  925. this.dealParentNode(node);
  926. }
  927. });
  928. },
  929. (err) => {
  930. this.showErrorMsg(err);
  931. },
  932. );
  933. }
  934. },
  935. dealParentNode(node) {
  936. const parent = node.parent;
  937. if (
  938. parent &&
  939. !parent.childNodes.filter((val) => val.data.watched !== -1).find((val) => val.checked === false)
  940. ) {
  941. parent.checked = true;
  942. parent.indeterminate = false;
  943. this.dealParentNode(parent);
  944. }
  945. },
  946. searchCheck(obj) {
  947. const node = this.$refs.searchTree.getNode(obj.name);
  948. const check = node.checked;
  949. if (check) {
  950. node.data.watched = this.checkboxStatus.checked;
  951. } else {
  952. node.data.watched = this.checkboxStatus.unchecked;
  953. }
  954. if (node.childNodes) {
  955. this.dealCheckPro(node.childNodes, node.indeterminate || check);
  956. }
  957. const checkedKeys = this.$refs.searchTree.getCheckedKeys();
  958. const watchNodes = [];
  959. if (this.searchCheckedArr.length === checkedKeys.length) {
  960. return;
  961. } else if (this.searchCheckedArr.length > checkedKeys.length) {
  962. watchNodes.push(obj.name);
  963. } else {
  964. checkedKeys.forEach((val) => {
  965. if (this.searchCheckedArr.indexOf(val) === -1) {
  966. watchNodes.push(val);
  967. }
  968. });
  969. }
  970. const params = {
  971. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  972. watch_nodes: watchNodes,
  973. mode: check ? 1 : 0,
  974. graph_name: this.graphFiles.value,
  975. search_pattern: {name: this.searchedWord},
  976. };
  977. if (this.graphFiles.value === this.$t('debugger.all')) {
  978. delete params.graph_name;
  979. }
  980. if (this.nodeTypes.value !== 'all') {
  981. params.search_pattern.node_category = this.nodeTypes.value;
  982. }
  983. RequestService.updateWatchpoint(params).then(
  984. (res) => {
  985. this.searchCheckedArr = checkedKeys;
  986. if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
  987. this.enableRecheck = res.data.metadata.enable_recheck;
  988. }
  989. this.$nextTick(() => {
  990. if (node.indeterminate) {
  991. node.checked = true;
  992. node.indeterminate = false;
  993. }
  994. if (check) {
  995. this.dealParentNode(node);
  996. }
  997. });
  998. },
  999. (err) => {
  1000. this.showErrorMsg(err);
  1001. },
  1002. );
  1003. },
  1004. /** Deal tree data
  1005. * @param {Object} childNodes tree node
  1006. * @param { Boolean } check check status
  1007. */
  1008. dealCheckPro(childNodes, check) {
  1009. childNodes.forEach((val) => {
  1010. val.indeterminate = false;
  1011. if (val.data.watched !== -1) {
  1012. val.checked = check;
  1013. if (check) {
  1014. val.data.watched = this.checkboxStatus.checked;
  1015. } else {
  1016. val.data.watched = this.checkboxStatus.unchecked;
  1017. }
  1018. } else {
  1019. val.checked = false;
  1020. }
  1021. if (val.childNodes) {
  1022. this.dealCheckPro(val.childNodes, check);
  1023. }
  1024. });
  1025. },
  1026. /**
  1027. * Collapse node
  1028. * @param {Object} _
  1029. * @param {Object} node node data
  1030. */
  1031. nodeCollapse(_, node) {
  1032. node.loaded = false;
  1033. node.childNodes = [];
  1034. if (this.treeFlag) {
  1035. this.dealDoubleClick(node.data.name);
  1036. }
  1037. },
  1038. /**
  1039. * Function to be executed after the search value changes
  1040. */
  1041. filterChange() {
  1042. if (this.searchWord === '' && this.nodeTypes.value === 'all') {
  1043. this.treeFlag = true;
  1044. this.$nextTick(() => {
  1045. setTimeout(() => {
  1046. const dom = document.querySelector('.el-tree-node.is-current.is-focusable');
  1047. if (dom) {
  1048. dom.scrollIntoView();
  1049. }
  1050. }, 800);
  1051. });
  1052. }
  1053. },
  1054. /**
  1055. * Filter tree data by node name
  1056. */
  1057. filter() {
  1058. this.treeFlag = this.searchWord === '' && this.nodeTypes.value === 'all';
  1059. if (this.searchWord || this.nodeTypes.value !== 'all') {
  1060. this.searchedWord = this.searchWord;
  1061. const params = {
  1062. name: this.searchWord,
  1063. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  1064. graph_name: this.graphFiles.value,
  1065. };
  1066. if (this.graphFiles.value === this.$t('debugger.all')) {
  1067. delete params.graph_name;
  1068. }
  1069. if (this.nodeTypes.value !== 'all') {
  1070. params.node_category = this.nodeTypes.value;
  1071. }
  1072. const loadingInstance = this.$loading(this.loadingOption);
  1073. RequestService.search(params).then(
  1074. (res) => {
  1075. loadingInstance.close();
  1076. if (res.data && res.data.nodes) {
  1077. this.searchTreeData = res.data.nodes;
  1078. this.searchHalfCheckedArr = [];
  1079. this.searchCheckedArr = [];
  1080. this.dealSearchResult(this.searchTreeData);
  1081. this.searchNode.childNodes = [];
  1082. const data = res.data.nodes.map((val) => {
  1083. return {
  1084. label: val.name.split('/').pop(),
  1085. ...val,
  1086. showCheckbox: val.watched !== -1,
  1087. };
  1088. });
  1089. const currentData = JSON.parse(JSON.stringify(data));
  1090. currentData.forEach((val) => {
  1091. val.nodes = [];
  1092. });
  1093. this.searchResolve(currentData);
  1094. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1095. this.searchNode.childNodes.forEach((val) => {
  1096. if (val.data.watched === this.checkboxStatus.indeterminate) {
  1097. val.indeterminate = true;
  1098. }
  1099. if (val.data.watched === this.checkboxStatus.checked) {
  1100. val.checked = true;
  1101. }
  1102. if (val.data.watched === this.checkboxStatus.unchecked) {
  1103. val.checked = false;
  1104. }
  1105. });
  1106. data.forEach((val, key) => {
  1107. if (val.nodes && val.nodes.length) {
  1108. val.nodes.forEach((value) => {
  1109. value.parentName = val.name;
  1110. });
  1111. this.dealSearchTreeData(val.nodes);
  1112. }
  1113. });
  1114. this.searchHalfCheckedArr.forEach((val) => {
  1115. this.$refs.searchTree.getNode(val).indeterminate = true;
  1116. });
  1117. }
  1118. },
  1119. (err) => {
  1120. loadingInstance.close();
  1121. this.showErrorMsg(err);
  1122. },
  1123. );
  1124. }
  1125. },
  1126. dealSearchTreeData(children) {
  1127. children.forEach((val) => {
  1128. const node = this.$refs.searchTree.getNode(val.parentName);
  1129. val.label = val.name.split('/').pop();
  1130. val.leaf = val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true;
  1131. val.showCheckbox = val.watched !== -1;
  1132. this.$refs.searchTree.append(val, node);
  1133. node.expanded = true;
  1134. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1135. node.childNodes.forEach((value) => {
  1136. if (value.data.watched === this.checkboxStatus.indeterminate) {
  1137. value.indeterminate = true;
  1138. }
  1139. if (value.data.watched === this.checkboxStatus.checked) {
  1140. value.checked = true;
  1141. }
  1142. if (value.data.watched === this.checkboxStatus.unchecked) {
  1143. value.checked = false;
  1144. }
  1145. });
  1146. if (val.nodes && val.nodes.length) {
  1147. val.nodes.forEach((value) => {
  1148. value.parentName = val.name;
  1149. });
  1150. this.dealSearchTreeData(val.nodes);
  1151. }
  1152. });
  1153. },
  1154. /**
  1155. * Deal search data
  1156. * @param {Array} arr search tree data
  1157. */
  1158. dealSearchResult(arr) {
  1159. arr.forEach((val) => {
  1160. if (val.nodes) {
  1161. this.dealSearchResult(val.nodes);
  1162. }
  1163. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1164. if (val.watched === this.checkboxStatus.checked) {
  1165. this.searchCheckedArr.push(val.name);
  1166. }
  1167. val.label = val.name.split('/').pop();
  1168. });
  1169. },
  1170. /**
  1171. * Draw the tree
  1172. * @param {Object} node tree root node
  1173. * @param {Function} resolve callback function ,return next node data
  1174. */
  1175. loadNode(node, resolve) {
  1176. this.loadingInstance = this.$loading(this.loadingOption);
  1177. if (node.level === 0) {
  1178. node.childNodes = [];
  1179. if (!this.node && !this.resolve) {
  1180. this.node = node;
  1181. this.resolve = resolve;
  1182. }
  1183. const params = {
  1184. mode: 'all',
  1185. };
  1186. RequestService.retrieve(params).then(
  1187. (res) => {
  1188. this.initFail = false;
  1189. this.dialogVisible = false;
  1190. if (res.data) {
  1191. if (res.data.graph && res.data.graph.nodes) {
  1192. this.graphFiles.options = res.data.graph.graph_names || [];
  1193. if (this.graphFiles.options.length > 1) {
  1194. this.graphFiles.options.unshift(this.$t('debugger.all'));
  1195. }
  1196. this.graphFiles.value = this.graphFiles.options[0];
  1197. this.origialTree = res.data.graph.nodes.map((val) => {
  1198. return {
  1199. label: val.name.split('/').pop(),
  1200. leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
  1201. ...val,
  1202. };
  1203. });
  1204. resolve(this.origialTree);
  1205. this.dealGraphData(JSON.parse(JSON.stringify(res.data.graph.nodes)));
  1206. }
  1207. if (res.data.watch_points) {
  1208. this.watchPointArr = res.data.watch_points.map((val) => {
  1209. return {
  1210. id: val.id,
  1211. condition: val.watch_condition.id,
  1212. params: val.watch_condition.params || [],
  1213. selected: false,
  1214. };
  1215. });
  1216. }
  1217. if (res.data.metadata) {
  1218. if (res.data.metadata.debugger_version) {
  1219. this.debuggerVersion = res.data.metadata.debugger_version;
  1220. }
  1221. this.metadata = res.data.metadata;
  1222. if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
  1223. this.enableRecheck = res.data.metadata.enable_recheck;
  1224. }
  1225. if (this.metadata.backend) {
  1226. this.version = this.metadata.backend;
  1227. }
  1228. this.trainId = encodeURIComponent(res.data.metadata.ip);
  1229. if (!res.data.metadata.recommendation_confirmed && this.trainId) {
  1230. this.recommendWatchPointDialog = true;
  1231. }
  1232. this.nodeName = this.metadata.node_name;
  1233. this.currentNodeName = this.nodeName;
  1234. if (this.metadata.state === this.state.pending || this.metadata.state === this.state.mismatch) {
  1235. this.loadingInstance.close();
  1236. }
  1237. if (this.pollInit) {
  1238. this.pollData();
  1239. this.pollInit = false;
  1240. }
  1241. }
  1242. }
  1243. },
  1244. (err) => {
  1245. this.initFail = true;
  1246. this.dialogVisible = true;
  1247. this.loadingInstance.close();
  1248. },
  1249. );
  1250. } else if (node.level >= 1) {
  1251. this.isIntoView = false;
  1252. const curHalfCheckedKeys = this.$refs.tree.getHalfCheckedKeys();
  1253. const params = {
  1254. mode: 'node',
  1255. params: {
  1256. node_type: node.data.type,
  1257. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  1258. name: node.data.name,
  1259. graph_name: this.graphFiles.value,
  1260. },
  1261. };
  1262. if (this.graphFiles.value === this.$t('debugger.all')) {
  1263. delete params.params.graph_name;
  1264. }
  1265. RequestService.retrieve(params).then(
  1266. (res) => {
  1267. if (res.data && res.data.metadata) {
  1268. this.dealMetadata(res.data.metadata);
  1269. }
  1270. if (res.data && res.data.graph) {
  1271. const graph = res.data.graph;
  1272. this.curNodeData = graph.nodes.map((val) => {
  1273. return {
  1274. label: val.name.split('/').pop(),
  1275. leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
  1276. ...val,
  1277. showCheckbox: val.watched !== -1,
  1278. };
  1279. });
  1280. resolve(this.curNodeData);
  1281. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1282. this.defaultCheckedArr = this.defaultCheckedArr.concat(
  1283. this.curNodeData
  1284. .filter((val) => {
  1285. return val.watched === this.checkboxStatus.checked;
  1286. })
  1287. .map((val) => val.name),
  1288. );
  1289. const halfSelectArr = this.curNodeData
  1290. .filter((val) => {
  1291. return val.watched === this.checkboxStatus.indeterminate;
  1292. })
  1293. .map((val) => val.name);
  1294. node.childNodes.forEach((val) => {
  1295. if (halfSelectArr.indexOf(val.data.name) !== -1) {
  1296. val.indeterminate = true;
  1297. node.indeterminate = true;
  1298. }
  1299. if (val.data.watched === this.checkboxStatus.checked) {
  1300. val.checked = true;
  1301. } else if (val.data.watched === this.checkboxStatus.unchecked) {
  1302. val.checked = false;
  1303. }
  1304. });
  1305. [...new Set(curHalfCheckedKeys.concat(this.$refs.tree.getHalfCheckedKeys()))].forEach((val) => {
  1306. this.$refs.tree.getNode(val).indeterminate = true;
  1307. });
  1308. this.selectedNode.name = node.data.name;
  1309. if (!this.allGraphData[node.data.name].isUnfold) {
  1310. this.dealGraphData(JSON.parse(JSON.stringify(graph.nodes)), node.data.name);
  1311. } else {
  1312. this.selectNode(true);
  1313. }
  1314. } else {
  1315. this.selectedNode.name = node.data.name;
  1316. this.selectNode(true);
  1317. resolve([]);
  1318. }
  1319. },
  1320. (err) => {
  1321. this.showErrorMsg(err);
  1322. resolve([]);
  1323. },
  1324. );
  1325. }
  1326. },
  1327. /**
  1328. * Draw the tree
  1329. * @param {Object} node tree root node
  1330. * @param {Function} resolve callback function ,return next node data
  1331. */
  1332. loadSearchNode(node, resolve) {
  1333. if (node.level === 0) {
  1334. node.childNodes = [];
  1335. if (!this.searchNode && !this.searchResolve) {
  1336. this.searchNode = node;
  1337. this.searchResolve = resolve;
  1338. }
  1339. } else if (node.level >= 1) {
  1340. const curHalfCheckedKeys = this.$refs.searchTree.getHalfCheckedKeys();
  1341. if (node.childNodes && node.childNodes.length) {
  1342. node.expanded = true;
  1343. node.loaded = true;
  1344. node.loading = false;
  1345. return;
  1346. }
  1347. const params = {
  1348. mode: 'node',
  1349. params: {
  1350. node_type: node.data.type,
  1351. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  1352. name: node.data.name,
  1353. graph_name: this.graphFiles.value,
  1354. },
  1355. };
  1356. if (this.graphFiles.value === this.$t('debugger.all')) {
  1357. delete params.params.graph_name;
  1358. }
  1359. RequestService.retrieve(params).then((res) => {
  1360. if (res.data && res.data.metadata) {
  1361. this.dealMetadata(res.data.metadata);
  1362. }
  1363. if (res.data && res.data.graph && res.data.graph.nodes) {
  1364. this.curNodeData = res.data.graph.nodes.map((val) => {
  1365. return {
  1366. label: val.name.split('/').pop(),
  1367. leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
  1368. ...val,
  1369. showCheckbox: val.watched !== -1,
  1370. };
  1371. });
  1372. resolve(this.curNodeData);
  1373. this.searchCheckedArr = this.searchCheckedArr.concat(
  1374. this.curNodeData
  1375. .filter((val) => {
  1376. return val.watched === this.checkboxStatus.checked;
  1377. })
  1378. .map((val) => val.name),
  1379. );
  1380. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1381. const halfSelectArr = this.curNodeData
  1382. .filter((val) => {
  1383. return val.watched === this.checkboxStatus.indeterminate;
  1384. })
  1385. .map((val) => val.name);
  1386. node.childNodes.forEach((val) => {
  1387. if (val.data.watched === this.checkboxStatus.checked) {
  1388. val.checked = true;
  1389. }
  1390. if (halfSelectArr.indexOf(val.data.name) !== -1) {
  1391. val.indeterminate = true;
  1392. node.indeterminate = true;
  1393. }
  1394. });
  1395. [...new Set(curHalfCheckedKeys.concat(this.$refs.searchTree.getHalfCheckedKeys()))].forEach((val) => {
  1396. this.$refs.searchTree.getNode(val).indeterminate = true;
  1397. });
  1398. }
  1399. });
  1400. }
  1401. },
  1402. initRecommendWatchPoints(value) {
  1403. this.recommendWatchPointDialog = false;
  1404. const params = {
  1405. trainId: this.trainId,
  1406. body: {
  1407. requestBody: {
  1408. set_recommended: value,
  1409. },
  1410. },
  1411. };
  1412. RequestService.setRecommendWatchPoints(params).then((res) => {
  1413. if (res && res.data) {
  1414. if (value) {
  1415. this.queryWatchPoints(false);
  1416. }
  1417. }
  1418. });
  1419. },
  1420. /**
  1421. * Show data of current selected watchpoint
  1422. * @param {Number} key watchpoint id
  1423. */
  1424. selectWatchPoint(key) {
  1425. this.curLeafNodeName = null;
  1426. this.curHalfCheckedKeys = [];
  1427. this.watchPointArr.forEach((val, index) => {
  1428. if (index === key) {
  1429. if (val.id) {
  1430. val.selected = true;
  1431. this.curWatchPointId = val.id;
  1432. this.queryGraphByWatchpoint(val.id);
  1433. if (this.searchWord !== '' || this.nodeTypes.value !== 'all') {
  1434. this.filter();
  1435. }
  1436. } else {
  1437. this.loadOriginalTree();
  1438. }
  1439. } else {
  1440. if (val.selected) {
  1441. val.selected = false;
  1442. }
  1443. }
  1444. });
  1445. },
  1446. /**
  1447. * Query WatchPoints
  1448. * @param {Boolean} focusLast
  1449. */
  1450. queryWatchPoints(focusLast) {
  1451. const params = {
  1452. mode: 'watchpoint',
  1453. graph_name: this.graphFiles.value,
  1454. };
  1455. if (this.graphFiles.value === this.$t('debugger.all')) {
  1456. delete params.graph_name;
  1457. }
  1458. RequestService.retrieve(params).then(
  1459. (res) => {
  1460. if (res.data.watch_points) {
  1461. this.watchPointArr = res.data.watch_points.map((val) => {
  1462. return {
  1463. id: val.id,
  1464. condition: val.watch_condition.id,
  1465. params: val.watch_condition.params || [],
  1466. selected: false,
  1467. };
  1468. });
  1469. if (focusLast) {
  1470. this.selectWatchPoint(this.watchPointArr.length - 1);
  1471. this.$nextTick(() => {
  1472. const newWatchPointDom = document.querySelector('#watch-point-list>li:last-child');
  1473. if (newWatchPointDom) {
  1474. newWatchPointDom.scrollIntoView();
  1475. }
  1476. });
  1477. }
  1478. }
  1479. },
  1480. (err) => {
  1481. this.showErrorMsg(err);
  1482. },
  1483. );
  1484. },
  1485. /**
  1486. * Tree linkage with graph Expand of current node
  1487. * @param {Obejct} nodes Data of children of current node
  1488. * @param {Obejct} name The name of the current node
  1489. */
  1490. nodeExpandLinkage(nodes, name) {
  1491. const curNodeData = nodes.map((val) => {
  1492. return {
  1493. label: val.name.split('/').pop(),
  1494. ...val,
  1495. showCheckbox: val.watched !== -1,
  1496. };
  1497. });
  1498. const node = this.$refs.tree.getNode(name);
  1499. curNodeData.forEach((val) => {
  1500. this.$refs.tree.append(val, name);
  1501. });
  1502. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1503. node.childNodes.forEach((val) => {
  1504. if (node.checked && !node.childNodes.find((val) => val.data.watched !== 2) && val.data.watched !== -1) {
  1505. val.checked = true;
  1506. }
  1507. if (val.data.watched === this.checkboxStatus.checked) {
  1508. val.checked = true;
  1509. }
  1510. if (val.data.watched === this.checkboxStatus.indeterminate) {
  1511. val.indeterminate = true;
  1512. }
  1513. if (val.data.type !== 'name_scope' && val.data.type !== 'aggregation_scope') {
  1514. val.isLeaf = true;
  1515. }
  1516. });
  1517. node.expanded = true;
  1518. node.loading = false;
  1519. this.$refs.tree.setCurrentKey(name);
  1520. this.defaultCheckedArr = this.$refs.tree.getCheckedKeys();
  1521. this.$nextTick(() => {
  1522. if (
  1523. node.indeterminate &&
  1524. !node.childNodes.filter((val) => val.data.watched !== -1).find((val) => val.checked === false)
  1525. ) {
  1526. node.indeterminate = false;
  1527. node.checked = true;
  1528. this.dealParentNode(node);
  1529. }
  1530. setTimeout(() => {
  1531. const dom = document.querySelector('.el-tree-node.is-current.is-focusable');
  1532. if (dom) {
  1533. dom.scrollIntoView();
  1534. }
  1535. }, 800);
  1536. });
  1537. },
  1538. /**
  1539. * @param {Boolean} type true: search watchpointhits false:query watchpointhits
  1540. */
  1541. searchWatchpointHits(type) {
  1542. if (this.radio1 === 'hit') {
  1543. const params = {};
  1544. const condition = {};
  1545. if (type) {
  1546. if (this.selectedNode.name) {
  1547. if (this.graphFiles.value === this.$t('debugger.all')) {
  1548. const arr = this.selectedNode.name.split('/');
  1549. condition.node_name = arr[1] ? this.selectedNode.name.replace(`${arr[0]}/`, '') : arr[0];
  1550. condition.graph_name = arr[0];
  1551. } else {
  1552. condition.node_name = this.selectedNode.name;
  1553. condition.graph_name = this.graphFiles.value;
  1554. }
  1555. } else {
  1556. condition.offset = this.pagination.currentPage - 1;
  1557. }
  1558. } else {
  1559. condition.offset = this.pagination.currentPage - 1;
  1560. }
  1561. condition.limit = this.pagination.pageSize;
  1562. params.group_condition = condition;
  1563. RequestService.searchWatchpointHits(params).then(
  1564. (res) => {
  1565. if (res.data.metadata) {
  1566. this.dealMetadata(res.data.metadata);
  1567. }
  1568. if (res.data && res.data.watch_point_hits) {
  1569. this.hitsOutdated = res.data.outdated;
  1570. this.watchPointHits = [];
  1571. this.pagination.total = res.data.total;
  1572. this.pagination.currentPage = res.data.offset + 1;
  1573. this.dealWatchpointHits(res.data.watch_point_hits);
  1574. } else {
  1575. if (condition.node_name) {
  1576. if (this.watchPointHits.length > 0) {
  1577. this.watchPointHits.forEach((val) => {
  1578. val.selected = false;
  1579. });
  1580. } else {
  1581. this.searchWatchpointHits(false);
  1582. }
  1583. } else {
  1584. this.pagination.currentPage = 1;
  1585. this.watchPointHits = [];
  1586. this.pagination.total = 0;
  1587. }
  1588. }
  1589. },
  1590. (err) => {
  1591. this.showErrorMsg(err);
  1592. },
  1593. );
  1594. } else {
  1595. this.$nextTick(() => {
  1596. setTimeout(() => {
  1597. const dom = document.querySelector('.el-tree-node.is-current.is-focusable');
  1598. if (dom) {
  1599. dom.scrollIntoView();
  1600. }
  1601. }, 200);
  1602. });
  1603. }
  1604. },
  1605. dealWatchpointHits(data) {
  1606. if (data && data.length) {
  1607. data.forEach((hit) => {
  1608. const obj = {
  1609. name: hit.node_name,
  1610. lists: [],
  1611. selected: false,
  1612. id: hit.node_name,
  1613. graph_name: hit.graph_name,
  1614. };
  1615. if (hit.tensors && hit.tensors.length) {
  1616. hit.tensors.forEach((i) => {
  1617. const tensorName = `slot: ${i.slot}, `;
  1618. if (i.watch_points && i.watch_points.length) {
  1619. i.watch_points.forEach((j, key) => {
  1620. let item = `${tensorName}${this.$t('debugger.watchPoint')} ${j.id}, `;
  1621. let params = [];
  1622. if (j.watch_condition) {
  1623. item += ` ${this.transCondition(j.watch_condition.id)}`;
  1624. this.formateWatchpointParams(j.watch_condition.params || []);
  1625. params = JSON.parse(JSON.stringify(j.watch_condition.params));
  1626. }
  1627. obj.lists.push({
  1628. name: item,
  1629. params,
  1630. id: `${key}${hit.node_name}`,
  1631. tip:
  1632. j.error_list && j.error_list.length
  1633. ? j.error_list
  1634. .map((i) => {
  1635. return this.$t('debugger.checkTips')[i];
  1636. })
  1637. .join('') + this.$t('debugger.checkTips').cannotCheck
  1638. : '',
  1639. });
  1640. });
  1641. }
  1642. });
  1643. }
  1644. this.watchPointHits.push(obj);
  1645. });
  1646. this.focusWatchpointHit();
  1647. } else {
  1648. this.pagination.currentPage = 1;
  1649. this.watchPointHits = [];
  1650. this.pagination.total = 0;
  1651. }
  1652. },
  1653. focusWatchpointHit() {
  1654. if (this.selectedNode.name) {
  1655. let selectedNodeName = this.selectedNode.name;
  1656. if (this.graphFiles.value === this.$t('debugger.all')) {
  1657. selectedNodeName = selectedNodeName.replace(`${selectedNodeName.split('/')[0]}/`, '');
  1658. }
  1659. this.expandKeys = [];
  1660. let focused = false;
  1661. this.watchPointHits.forEach((val) => {
  1662. if (val.name === selectedNodeName) {
  1663. val.selected = true;
  1664. focused = true;
  1665. this.expandKeys.push(val.id);
  1666. } else {
  1667. val.selected = false;
  1668. }
  1669. });
  1670. this.$nextTick(() => {
  1671. setTimeout(() => {
  1672. const dom = document.querySelector('.hit-item.selected');
  1673. if (dom) {
  1674. dom.scrollIntoView();
  1675. }
  1676. }, 200);
  1677. });
  1678. return focused;
  1679. }
  1680. },
  1681. /**
  1682. * Update tensor value
  1683. * @param {number} key The index of the node of the watchPointHits currently clicked
  1684. */
  1685. updateTensorValue(key) {
  1686. this.loadingInstance = this.$loading(this.loadingOption);
  1687. const currentHit = this.watchPointHits[key];
  1688. const name = currentHit.name;
  1689. const temName = this.nodeName;
  1690. this.nodeName = name;
  1691. this.isHitIntoView = false;
  1692. const params = {
  1693. mode: 'node',
  1694. params: {
  1695. name,
  1696. single_node: true,
  1697. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  1698. graph_name: currentHit.graph_name,
  1699. },
  1700. };
  1701. if (this.graphFiles.value === this.$t('debugger.all')) {
  1702. delete params.params.graph_name;
  1703. params.params.name = `${currentHit.graph_name}/${name}`;
  1704. }
  1705. this.watchPointHits.forEach((val, index) => {
  1706. if (key === index) {
  1707. val.selected = true;
  1708. } else {
  1709. val.selected = false;
  1710. }
  1711. });
  1712. this.watchPointHits = JSON.parse(JSON.stringify(this.watchPointHits));
  1713. RequestService.retrieve(params).then(
  1714. (res) => {
  1715. if (res.data.metadata) {
  1716. this.dealMetadata(res.data.metadata);
  1717. }
  1718. this.retrieveTensorHistory({name: this.nodeName}, currentHit.graph_name);
  1719. if (res.data && res.data.graph) {
  1720. const graph = res.data.graph;
  1721. if (
  1722. this.graphFiles.value !== currentHit.graph_name &&
  1723. this.graphFiles.value !== this.$t('debugger.all')
  1724. ) {
  1725. this.graphFiles.value = currentHit.graph_name;
  1726. this.resetAllData(graph, params.params.name);
  1727. } else {
  1728. this.querySingleNode(JSON.parse(JSON.stringify(graph)), params.params.name, true);
  1729. }
  1730. if (graph.children) {
  1731. this.dealTreeData(graph.children, name);
  1732. this.defaultCheckedArr = this.$refs.tree.getCheckedKeys();
  1733. }
  1734. }
  1735. },
  1736. (err) => {
  1737. this.showErrorMsg(err);
  1738. this.nodeName = temName;
  1739. },
  1740. );
  1741. },
  1742. /**
  1743. * Query the graph data
  1744. * @param {String} nodeName The name of the node that needs to be query
  1745. * @param {Boolean} isQueryTensor The name of the node that needs to be query
  1746. * @param {String} graphName Graph file name
  1747. * @param {Boolean} needLoading Whether to display loading
  1748. */
  1749. queryAllTreeData(nodeName, isQueryTensor, graphName, needLoading) {
  1750. if (needLoading) {
  1751. this.loadingInstance = this.$loading(this.loadingOption);
  1752. }
  1753. let name = nodeName ? nodeName.split(':')[0] : '';
  1754. const params = {
  1755. mode: 'node',
  1756. params: {
  1757. name,
  1758. single_node: true,
  1759. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  1760. },
  1761. };
  1762. if (this.graphFiles.value === this.$t('debugger.all') && graphName && name) {
  1763. if (name !== graphName) {
  1764. name = `${graphName}/${name}`;
  1765. params.params.name = name;
  1766. }
  1767. } else {
  1768. params.params.graph_name = graphName;
  1769. }
  1770. RequestService.retrieve(params).then(
  1771. (res) => {
  1772. if (res.data && res.data.metadata) {
  1773. this.dealMetadata(res.data.metadata);
  1774. }
  1775. if (res.data && res.data.graph) {
  1776. const graph = res.data.graph;
  1777. if (graph.nodes && !this.isCurrentGraph) {
  1778. this.resetAllData(graph, name);
  1779. this.isCurrentGraph = true;
  1780. } else {
  1781. this.querySingleNode(JSON.parse(JSON.stringify(graph)), name, true);
  1782. }
  1783. if (graph.children) {
  1784. this.dealTreeData(graph.children, name);
  1785. this.defaultCheckedArr = this.$refs.tree.getCheckedKeys();
  1786. }
  1787. }
  1788. },
  1789. (err) => {
  1790. this.showErrorMsg(err);
  1791. },
  1792. );
  1793. },
  1794. /**
  1795. * Draw the tree
  1796. * @param {Object} children child node
  1797. * @param {String} name The name of the node that needs to be highlighted
  1798. */
  1799. dealTreeData(children, name) {
  1800. if (children.nodes) {
  1801. const data = children.nodes.map((val) => {
  1802. return {
  1803. label: val.name.split('/').pop(),
  1804. ...val,
  1805. showCheckbox: val.watched !== -1,
  1806. };
  1807. });
  1808. data.forEach((val) => {
  1809. const node = this.$refs.tree.getNode(children.scope_name);
  1810. if (node.childNodes) {
  1811. if (node.childNodes.map((value) => value.data.name).indexOf(val.name) === -1) {
  1812. this.$refs.tree.append(val, node);
  1813. }
  1814. } else {
  1815. this.$refs.tree.append(val, node);
  1816. }
  1817. });
  1818. const node = this.$refs.tree.getNode(children.scope_name);
  1819. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1820. node.childNodes.forEach((val) => {
  1821. if (val.data.watched === this.checkboxStatus.checked) {
  1822. val.checked = true;
  1823. }
  1824. if (val.data.watched === this.checkboxStatus.indeterminate) {
  1825. val.indeterminate = true;
  1826. }
  1827. if (val.data.type !== 'name_scope' && val.data.type !== 'aggregation_scope') {
  1828. val.isLeaf = true;
  1829. }
  1830. });
  1831. node.expanded = true;
  1832. node.loading = false;
  1833. } else {
  1834. this.$refs.tree.setCurrentKey(name);
  1835. this.$nextTick(() => {
  1836. setTimeout(() => {
  1837. const dom = document.querySelector('.el-tree-node.is-current.is-focusable');
  1838. if (dom) {
  1839. dom.scrollIntoView();
  1840. }
  1841. }, 800);
  1842. });
  1843. }
  1844. if (children.children) {
  1845. this.dealTreeData(children.children, name);
  1846. }
  1847. },
  1848. resetAllData(graph, name) {
  1849. this.node.childNodes = [];
  1850. this.origialTree = graph.nodes.map((val) => {
  1851. return {
  1852. label: val.name.split('/').pop(),
  1853. leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
  1854. ...val,
  1855. showCheckbox: val.watched !== -1,
  1856. };
  1857. });
  1858. this.resolve(this.origialTree);
  1859. // watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
  1860. this.node.childNodes.forEach((val) => {
  1861. if (val.data.watched === this.checkboxStatus.checked) {
  1862. val.checked = true;
  1863. }
  1864. if (val.data.watched === this.checkboxStatus.indeterminate) {
  1865. val.indeterminate = true;
  1866. }
  1867. });
  1868. this.firstFloorNodes = [];
  1869. this.allGraphData = {};
  1870. d3.select('#graph svg').remove();
  1871. this.packageDataToObject('', true, JSON.parse(JSON.stringify(graph.nodes)));
  1872. if (name) {
  1873. this.querySingleNode(JSON.parse(JSON.stringify(graph)), name, true);
  1874. } else {
  1875. this.resetGraph();
  1876. }
  1877. },
  1878. },
  1879. };
  1880. </script>