Browse Source

UI support tensor detection view

tags/v1.1.0
fengxuefeng WeiFeng-mindinsight 5 years ago
parent
commit
61b8f15d1a
6 changed files with 356 additions and 236 deletions
  1. +2
    -1
      mindinsight/ui/src/components/debugger-grid-table-simple.vue
  2. +186
    -137
      mindinsight/ui/src/components/debugger-tensor.vue
  3. +25
    -3
      mindinsight/ui/src/locales/en-us.json
  4. +4
    -4
      mindinsight/ui/src/locales/zh-cn.json
  5. +95
    -64
      mindinsight/ui/src/mixins/debugger-mixin.vue
  6. +44
    -27
      mindinsight/ui/src/views/debugger/debugger.vue

+ 2
- 1
mindinsight/ui/src/components/debugger-grid-table-simple.vue View File

@@ -39,7 +39,7 @@ limitations under the License.
@keyup.enter="filterChange">
<div class="filter-input-title">{{$t('components.dimsFilterInputTitle')}}
<span :title="$t('components.dimsFilterInputTip')"
class="el-icon-question"></span>
class="el-icon-warning"></span>
</div>
<div v-for="(item, itemIndex) in filterArr"
:key="itemIndex">
@@ -552,6 +552,7 @@ export default {
* @param {Boolean} isUpdate Whether to reset
*/
showRequestErrorMessage(errorMsg, dimension, filterStr, isUpdate) {
this.shape = dimension;
this.errorMsg = errorMsg;
if ((!this.filterArr.length && dimension && filterStr) || isUpdate) {
this.initializeFilterArr(dimension, filterStr);


+ 186
- 137
mindinsight/ui/src/components/debugger-tensor.vue View File

@@ -176,7 +176,7 @@ limitations under the License.
<el-tooltip placement="bottom"
effect="light"
popper-class="legend-tip">
<i class="el-icon-question"></i>
<i class="el-icon-warning"></i>
<div slot="content">
<div>{{$t('debugger.selectDetail')}}</div>
<div class="legend">
@@ -197,36 +197,36 @@ limitations under the License.
</div>
<div id="tensor-graph"
class="deb-graph"></div>
<div class="deb-tensor-info"
v-show="tensorShow">
<div class="deb-tensor-info">
<div class="tensor">
<div class="tensor-title">{{$t('debugger.tensorMsg')}}</div>
<div class="tensor-detail">
<span>{{ $t('debugger.max') }} {{ selectedStatistics.overall_max }}</span>
<span>{{ $t('debugger.min') }} {{ selectedStatistics.overall_min }}</span>
<span>{{ $t('debugger.mean') }} {{ selectedStatistics.overall_avg }}</span>
<span>{{ $t('debugger.nan') }} {{ selectedStatistics.overall_nan_count }}</span>
<span>{{ $t('debugger.max') }} {{ statistics.overall_max }}</span>
<span>{{ $t('debugger.min') }} {{ statistics.overall_min }}</span>
<span>{{ $t('debugger.mean') }} {{ statistics.overall_avg }}</span>
<span>{{ $t('debugger.nan') }} {{ statistics.overall_nan_count }}</span>
<span>{{ $t('debugger.negativeInf') }}
{{ selectedStatistics.overall_neg_inf_count }}</span>
<span>{{ $t('debugger.inf') }} {{ selectedStatistics.overall_pos_inf_count }}</span>
<span>{{ $t('debugger.zero') }} {{ selectedStatistics.overall_zero_count }}</span>
{{ statistics.overall_neg_inf_count }}</span>
<span>{{ $t('debugger.inf') }} {{ statistics.overall_pos_inf_count }}</span>
<span>{{ $t('debugger.zero') }} {{ statistics.overall_zero_count }}</span>
<span>{{ $t('debugger.negativeNum') }}
{{ selectedStatistics.overall_neg_zero_count }}</span>
{{ statistics.overall_neg_zero_count }}</span>
<span>{{ $t('debugger.positiveNum') }}
{{ selectedStatistics.overall_pos_zero_count }}</span>
{{ statistics.overall_pos_zero_count }}</span>
</div>
</div>
<div class="watchPoint">
<div class="watch-point">
<div class="watchPoint-title">{{ $t('debugger.watchList') }}</div>
<div v-for="(item,key) in watchPoints"
:key="key"
class="point-list">
<div class="watch-judgment">
<span>{{ $t('debugger.watchPoint') }}{{item.id}}</span>
<span>{{ $t('symbols.colon') }}</span>
<span>
{{ getWatchPointContent(item) }}
</span>
<div class="point-list">
<div v-for="(item,key) in watchPoints"
:key="key">
<div class="watch-judgment">
<span>{{ $t('debugger.watchPoint') }}{{item.id}}</span>
<span>{{ $t('symbols.colon') }}</span>
<span>
{{ getWatchPointContent(item) }}
</span>
</div>
</div>
</div>
</div>
@@ -274,13 +274,11 @@ export default {
tensorGraphData: {},
tensorGraphviz: null,
selectedNode: {},
selectedStatistics: {},
tensorShow: true,
statistics: {},
leftDataShow: true,
tuningAdvice: [],
tuningAdviceTitle: '',
watchPoints: [],
actualValue: '',
};
},
mounted() {
@@ -326,39 +324,9 @@ export default {
});
}
});
this.selectedNode = this.tensorGraphData[initPage ? this.curRowObj.name : this.selectedNode.name];

if (this.selectedNode.statistics && Object.keys(this.selectedNode.statistics).length) {
this.selectedStatistics = this.selectedNode.statistics;
} else {
const noStatistics = {
overall_avg: '--',
overall_count: '--',
overall_max: '--',
overall_min: '--',
overall_nan_count: '--',
overall_neg_inf_count: '--',
overall_neg_zero_count: '--',
overall_pos_inf_count: '--',
overall_pos_zero_count: '--',
overall_zero_count: '--',
};
this.selectedStatistics = noStatistics;
}
if (this.selectedNode.watch_points && this.selectedNode.watch_points.length) {
this.watchPoints = this.selectedNode.watch_points.map((val) => {
return {
id: val.id,
condition: val.watch_condition.id,
params: val.watch_condition.params || [],
selected: false,
};
});
} else {
this.watchPoints = [];
}

if (initPage) {
this.selectedNode.name = this.curRowObj.name;
const dot = this.packageData();
this.initGraph(dot);
}
@@ -402,13 +370,12 @@ export default {
}
item.params.forEach((element) => {
if (!element.actual_value) {
this.actualValue = this.$t('symbols.rightbracket');
element.actual = this.$t('symbols.rightbracket');
} else {
this.actualValue = `${this.$t('debugger.actualValue')}${this.$t('symbols.colon')}${
element.actual = `${this.$t('debugger.actualValue')}${this.$t('symbols.colon')}${
element.actual_value
}${this.$t('symbols.rightbracket')}`;
}
element.actual = this.actualValue;
});
});
} else {
@@ -482,7 +449,9 @@ export default {
this.$parent.uniqueEdges(edges);

edges.forEach((edge) => {
edgeStr += `<${edge.source}>-><${edge.target}>[label="${edge.count > 1 ? edge.count + 'tensor' : ''}"]`;
edgeStr +=
`<${edge.source}>-><${edge.target}>[id="${edge.source}->${edge.target}";` +
`label="${edge.count > 1 ? edge.count + 'tensor' : ''}"]`;
});

const initSetting = 'node[style="filled";fontsize="10px"];edge[fontsize="6px";];';
@@ -507,7 +476,7 @@ export default {
`{rank=min;<${subGraphInput}>[shape="circle";` +
`id="${subGraphInput}";width=0.02;fixedsize=true;` +
`label=""]};`;
edgeStr += `<${name}>-><${subGraphInput}>[label="${slots.length}tensor"]`;
edgeStr += `<${name}>-><${subGraphInput}>[id="${name}->${subGraphInput}";label="${slots.length}tensor"]`;

const outputKeys = Object.keys(node.output || {});
if (outputKeys.length) {
@@ -525,7 +494,7 @@ export default {
slotName === this.curRowObj.name ? ' current selected' : ''
}";fillcolor="#c5e0b3"];`;

edgeStr += `<${subGraphInput}>-><${slotName}>;`;
edgeStr += `<${subGraphInput}>-><${slotName}>[id="${subGraphInput}->${slotName}"];`;
});

strTemp =
@@ -581,49 +550,18 @@ export default {
graphDom.selectAll('title').remove();
this.initZooming();

const nodes = graphDom.selectAll('.node.slot');
const nodes = graphDom.selectAll('.node');
nodes.on('click', (target, index, nodesList) => {
const event = currentEvent;
event.stopPropagation();
event.preventDefault();

const selectedNode = nodesList[index];
d3.selectAll('.node').classed('selected', false);
selectedNode.classList.add('selected');
this.selectedNode = this.tensorGraphData[selectedNode.id];
if (this.selectedNode.statistics && Object.keys(this.selectedNode.statistics).length) {
this.selectedStatistics = this.selectedNode.statistics;
this.tensorShow = true;
} else {
const noStatistics = {
overall_avg: '--',
overall_count: '--',
overall_max: '--',
overall_min: '--',
overall_nan_count: '--',
overall_neg_inf_count: '--',
overall_neg_zero_count: '--',
overall_pos_inf_count: '--',
overall_pos_zero_count: '--',
overall_zero_count: '--',
};
this.selectedStatistics = noStatistics;
}
if (this.selectedNode.watch_points && this.selectedNode.watch_points.length) {
this.watchPoints = this.selectedNode.watch_points.map((val) => {
return {
id: val.id,
condition: val.watch_condition.id,
params: val.watch_condition.params || [],
selected: false,
};
});
} else {
this.watchPoints = [];
}
this.selectedNode.name = nodesList[index].id;
this.setNodeData();
});

nodes.on('dblclick', (target, index, nodesList) => {
const slots = graphDom.selectAll('.node.slot');
slots.on('dblclick', (target, index, nodesList) => {
const event = currentEvent;
event.stopPropagation();
event.preventDefault();
@@ -646,6 +584,10 @@ export default {
}
}
});

if (this.selectedNode.name) {
this.setNodeData();
}
},
/**
* Initializing the Zoom Function of a Graph
@@ -748,6 +690,84 @@ export default {
graph0.on('.zoom', null);
graph0.call(zoom);
},
setNodeData() {
window.getSelection().removeAllRanges();
const selectedNode = document.querySelector(`g[id="${this.selectedNode.name}"]`);
d3.selectAll('.node').classed('selected', false);
selectedNode.classList.add('selected');
d3.selectAll('.edge').classed('selected', false);
this.selectedNode = JSON.parse(JSON.stringify(this.tensorGraphData[this.selectedNode.name]));

const keys = [
'overall_avg',
'overall_count',
'overall_max',
'overall_min',
'overall_nan_count',
'overall_neg_inf_count',
'overall_neg_zero_count',
'overall_pos_inf_count',
'overall_pos_zero_count',
'overall_zero_count',
];
if (this.selectedNode.type === 'slot') {
if (!(this.selectedNode.statistics && Object.keys(this.selectedNode.statistics).length)) {
keys.forEach((key) => {
this.statistics[key] = '--';
});
} else {
this.statistics = JSON.parse(JSON.stringify(this.selectedNode.statistics));
}
if (this.selectedNode.watch_points && this.selectedNode.watch_points.length) {
this.watchPoints = this.selectedNode.watch_points.map((val) => {
return {
id: val.id,
condition: val.watch_condition.id,
params: val.watch_condition.params || [],
selected: false,
};
});
} else {
this.watchPoints = [];
}
} else {
keys.forEach((key) => {
this.statistics[key] = '--';
});
this.watchPoints = [];
this.highLightEdges();
}
},
highLightEdges() {
const edges = [];
const input = this.selectedNode.input || {};
const inputKeys = Object.keys(input);
if (inputKeys.length) {
inputKeys.forEach((key) => {
const mapping = input[key].slot_mapping;
if (mapping && mapping.length) {
mapping.forEach((map) => {
if (map && map.length) {
edges.push(`${key}:${map[0]}->outputOf${key}_slots`);
edges.push(`outputOf${key}_slots->${this.selectedNode.name}`);
}
});
}
});
}

const slots = this.selectedNode.slots || [];
if (slots.length) {
edges.push(`${this.selectedNode.name}->inputOf${this.selectedNode.name}_slots`);
slots.forEach((slot) => {
edges.push(`inputOf${this.selectedNode.name}_slots->${this.selectedNode.name}:${slot.slot}`);
});
}

edges.forEach((edge) => {
d3.select(`#tensor-graph g[id="${edge}"]`).classed('selected', true);
});
},
resetTensor() {
const svg = document.querySelector('#tensor-graph svg');
if (svg) {
@@ -763,7 +783,7 @@ export default {
this.init();
},
closeTensor() {
this.$emit('close');
this.$emit('close', this.selectedNode.name, this.curRowObj.graph_name);
},
/**
* Collaspe btn click function
@@ -1042,6 +1062,7 @@ export default {
.reason {
display: flex;
padding: 1px 15px;
width: 100%;
}
.tensor-icon {
width: 6px;
@@ -1050,10 +1071,11 @@ export default {
}
.icon-secondary {
background-color: #00a5a7;
margin-top: 7px;
margin-top: 8px;
}
.tensor-content {
padding: 0px 6px;
padding-left: 6px;
width: calc(100% - 12px);
}
.tensor-value {
padding: 5px 2px;
@@ -1294,7 +1316,7 @@ export default {
}
}
}
.node.slot {
.node {
&:hover {
cursor: pointer;
& > polygon,
@@ -1308,57 +1330,84 @@ export default {
stroke: #e4e7ed;
fill: #e9fcf9;
}
.selected {
.node.selected {
polygon,
ellipse {
stroke: red !important;
stroke-width: 2px;
}
}
.edge.selected {
path {
stroke: red;
}
polygon {
stroke: red;
fill: red;
}
}
}
.deb-tensor-info {
width: 375px;
height: 100%;
border-left: solid 2px #e4e7ed;
padding-left: 20px;
.tensor-title {
font-size: 14px;
font-weight: bold;
padding-bottom: 8px;
}
.tensor-detail {
overflow: auto;
height: calc(100% - 30px);
span {
display: inline-block;
padding: 5px 0px;
min-width: 50%;
.tensor {
.tensor-title {
font-size: 14px;
font-weight: bold;
padding-bottom: 8px;
}
ul {
li {
padding: 5px 10px;
& > div {
display: inline-block;
vertical-align: top;
word-break: break-all;
line-height: 16px;
}
.attr-key {
width: 30%;
}
.attr-value {
width: 70%;
padding-left: 10px;
}
&:hover {
background-color: #e9fcf9;
.tensor-detail {
overflow: auto;
height: calc(100% - 30px);
span {
display: inline-block;
padding: 5px 0px;
min-width: 50%;
}
ul {
li {
padding: 5px 10px;
& > div {
display: inline-block;
vertical-align: top;
word-break: break-all;
line-height: 16px;
}
.attr-key {
width: 30%;
}
.attr-value {
width: 70%;
padding-left: 10px;
}
&:hover {
background-color: #e9fcf9;
}
}
}
}
}
.watchPoint-title {
padding: 8px 0;
font-size: 14px;
font-weight: bold;
.tensor {
height: 50%;
overflow: auto;
}
.watch-point {
height: 50%;
.point-list {
height: calc(100% - 35px);
overflow: auto;
text-overflow: ellipsis;
}
.watchPoint-title {
padding: 8px 0;
font-size: 14px;
font-weight: bold;
}
.watch-judgment {
padding: 5px 0;
}
}
}
}


+ 25
- 3
mindinsight/ui/src/locales/en-us.json View File

@@ -522,7 +522,7 @@
"negativeNum": "Negative number:",
"all": "All",
"tensorTip": "tensor",
"recheck": "Recheck",
"recheck": "Recheck (only for watchpoints with tensor values)",
"clearWatchpoint": "Clear Watchpoint",
"nodeType": {
"all": "All",
@@ -541,6 +541,8 @@
"jumpFailInformation": "Redirection fails because the tensor information is empty.",
"optimizationOrientation": "Optimization Guide",
"tuningAdvice": "Optimization Suggestions",
"setValue": "Preset Value",
"actualValue": "Actual Value",
"tensorTuningRule": {
"operator_real_data_validation": "Real data validation using single operator",
"loss_overflow": "Loss overflow (NAN,INF)",
@@ -568,7 +570,21 @@
"tensor_all_zero": "Whether tensor values are all 0",
"tensor_change_too_large": "Tensor change above threshold",
"tensor_change_too_small": "Tensor change below threshold",
"tensor_not_changed": "Unchanged tensor"
"tensor_not_changed": "Unchanged tensor",
"zero_percentage_ge": "Percentage of 0 values ≥",
"abs_mean_gt": "Average of the absolute value >",
"abs_mean_lt": "Average of the absolute value <",
"range_start_inclusive": "Lower limit of the range (inclusive)",
"range_end_inclusive": "Upper limit of the range (inclusive)",
"range_percentage_lt": "Percentage of the value in the range <",
"range_percentage_gt": "Percentage of the value in the range >",
"rtol": "Relative tolerance",
"abs_updata_ratio_mean_gt": "Average of the absolute value of the change ratio >",
"abs_updata_ratio_mean_lt": "Average of the absolute value of the change ratio <",
"param": "Threshold",
"max_min_lt": "MAX-MIN <",
"max_min_gt": "MAX-MIN >",
"outdateTip": "When a watchpoint list is modified, the result may be outdated. Check again or perform subsequent step training. "
},
"tensorTuningAdvice": {
"operator_real_data_validation": [
@@ -701,7 +717,13 @@
"noAdvice": "No suggestions available",
"curStep": "Current Step",
"preStep": "Previous Step",
"compareResult": "Comparison Result"
"compareResult": "Comparison Result",
"recommendTip": "Use the recommended watchpoints?",
"recommendDetail": "The recommended watchpoints check zero tensors, gradient disappearances, and update weight above threshold, helping you quickly detect faults in training. ",
"use": "Yes",
"notUse": "No",
"versionConflictTip": "MindSpore and MindInsight versions do not match. MindSpore version: {msv}; MindInsight version: {miv}",
"checkTips": "Note: The tensor contains {msg}, resulting in value check failure. "
},
"explain": {
"explain": "Model Explanation",


+ 4
- 4
mindinsight/ui/src/locales/zh-cn.json View File

@@ -521,7 +521,7 @@
"negativeNum": "负数:",
"all": "全部",
"tensorTip": "张量",
"recheck": "重新检查",
"recheck": "重新检查(只针对目前有张量值的监测点)",
"clearWatchpoint": "清空监测点",
"nodeType": {
"all": "全部节点",
@@ -581,8 +581,8 @@
"abs_updata_ratio_mean_gt": "变化比例绝对值的平均值>",
"abs_updata_ratio_mean_lt": "变化比例绝对值的平均值<",
"param": "阈值",
"max_min_lt": "MAX-MIN>",
"max_min_gt": "MAX-MIN<"
"max_min_lt": "MAX-MIN<",
"max_min_gt": "MAX-MIN>"
},
"tensorTuningAdvice": {
"operator_real_data_validation": [
@@ -717,7 +717,7 @@
"use": "使用",
"notUse": "不使用",
"outdateTip": "监测点列表发生修改,结果可能过时,请重新检查或执行后续step训练。",
"versionConflictTip": "Mindspore和Mindinsight版本不匹配,Mindspore版本:{msv};Mindinsight版本:{miv};",
"versionConflictTip": "MindSpore和MindInsight版本不匹配,MindSpore版本:{msv};MindInsight版本:{miv};",
"checkTips": "提示:张量中含有{msg},无法进行数值检查。"
},
"explain": {


+ 95
- 64
mindinsight/ui/src/mixins/debugger-mixin.vue View File

@@ -114,16 +114,16 @@ export default {
label: val.name.split('/').pop(),
leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
this.resolve(this.origialTree);
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
this.node.childNodes.forEach((val) => {
if (val.data.watched === 2 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
if (val.data.watched === 1 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.indeterminate) {
val.indeterminate = true;
}
});
@@ -536,7 +536,7 @@ export default {
if (res && res.data && res.data.metadata) {
this.enableRecheck = res.data.metadata.enable_recheck;
}
this.$message.success(this.$t('debugger.recheckSucess'));
this.$message.success(this.$t('debugger.recheckSuccess'));
},
(err) => {},
);
@@ -583,13 +583,13 @@ export default {
cancelButtonText: this.$t('public.cancel'),
type: 'warning',
}).then(() => {
if (!item) {
this.curWatchPointId = null;
this.watchPointArr = [];
}
const params = {watch_point_id: item ? item.id : null};
RequestService.deleteWatchpoint(params).then(
(res) => {
if (!item) {
this.curWatchPointId = null;
this.watchPointArr = [];
}
this.loadOriginalTree();
this.queryWatchPoints();
this.$message.success(this.$t('debugger.successDeleteWP'));
@@ -767,7 +767,7 @@ export default {
if (this.curWatchPointId) {
this.$refs.tree.getCheckedKeys().forEach((val) => {
const node = this.$refs.tree.getNode(val);
if (node.data.type === this.unCheckedNodeType) {
if (node.data.watched === this.checkboxStatus.noCheckbox) {
node.checked = false;
}
});
@@ -822,9 +822,7 @@ export default {
const parent = node.parent;
if (
parent &&
!parent.childNodes
.filter((val) => val.data.type !== this.unCheckedNodeType)
.find((val) => val.checked === false)
!parent.childNodes.filter((val) => val.data.watched !== -1).find((val) => val.checked === false)
) {
parent.checked = true;
parent.indeterminate = false;
@@ -837,19 +835,45 @@ export default {
if (node.childNodes) {
this.dealCheckPro(node.childNodes, node.indeterminate || check);
}
const checkedKeys = this.$refs.searchTree.getCheckedKeys();
const watchNodes = [];
if (this.searchCheckedArr.length === checkedKeys.length) {
return;
} else if (this.searchCheckedArr.length > checkedKeys.length) {
watchNodes.push(obj.name);
} else {
checkedKeys.forEach((val) => {
if (this.searchCheckedArr.indexOf(val) === -1) {
watchNodes.push(val);
}
});
}
const params = {
watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
watch_nodes: [obj.name],
watch_nodes: watchNodes,
mode: check ? 1 : 0,
graph_name: this.graphFiles.value,
search_pattern: {name: this.searchedWord, node_category: obj.type},
search_pattern: {name: this.searchedWord},
};
if (this.graphFiles.value === this.$t('debugger.all')) {
delete params.graph_name;
}
if (this.nodeTypes.value !== 'all') {
params.search_pattern.node_category = this.nodeTypes.value;
}
RequestService.updateWatchpoint(params).then(
(res) => {
this.searchCheckedArr = checkedKeys;
this.enableRecheck = res.data.metadata.enable_recheck;
this.$nextTick(() => {
if (node.indeterminate) {
node.checked = true;
node.indeterminate = false;
}
if (check) {
this.dealParentNode(node);
}
});
},
(err) => {
this.showErrorMsg(err);
@@ -863,7 +887,7 @@ export default {
dealCheckPro(childNodes, check) {
childNodes.forEach((val) => {
val.indeterminate = false;
if (val.data.type !== this.unCheckedNodeType) {
if (val.data.watched !== -1) {
val.checked = check;
} else {
val.checked = false;
@@ -924,13 +948,14 @@ export default {
if (res.data && res.data.nodes) {
this.searchTreeData = res.data.nodes;
this.searchHalfCheckedArr = [];
this.searchCheckedArr = [];
this.dealSearchResult(this.searchTreeData);
this.defaultCheckedArr = this.searchCheckedArr;
this.searchNode.childNodes = [];
const data = res.data.nodes.map((val) => {
return {
label: val.name.split('/').pop(),
...val,
showCheckbox: val.watched !== -1,
};
});
const currentData = JSON.parse(JSON.stringify(data));
@@ -938,14 +963,17 @@ export default {
val.nodes = [];
});
this.searchResolve(currentData);
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
this.searchNode.childNodes.forEach((val) => {
if (val.data.watched === 1) {
if (val.data.watched === this.checkboxStatus.indeterminate) {
val.indeterminate = true;
}
if (val.data.watched === 2) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
if (val.data.watched === this.checkboxStatus.unchecked) {
val.checked = false;
}
});
data.forEach((val, key) => {
if (val.nodes && val.nodes.length) {
@@ -971,16 +999,20 @@ export default {
const node = this.$refs.searchTree.getNode(val.parentName);
val.label = val.name.split('/').pop();
val.leaf = val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true;
val.showCheckbox = val.watched !== -1;
this.$refs.searchTree.append(val, node);
node.expanded = true;
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
node.childNodes.forEach((value) => {
if (value.data.watched === 1) {
if (value.data.watched === this.checkboxStatus.indeterminate) {
value.indeterminate = true;
}
if (value.data.watched === 2) {
if (value.data.watched === this.checkboxStatus.checked) {
value.checked = true;
}
if (value.data.watched === this.checkboxStatus.unchecked) {
value.checked = false;
}
});
if (val.nodes && val.nodes.length) {
val.nodes.forEach((value) => {
@@ -999,8 +1031,8 @@ export default {
if (val.nodes) {
this.dealSearchResult(val.nodes);
}
// watched 0:unchecked 1:indeterminate 2:checked
if (val.watched === 2 && val.type !== this.unCheckedNodeType) {
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
if (val.watched === this.checkboxStatus.checked) {
this.searchCheckedArr.push(val.name);
}
val.label = val.name.split('/').pop();
@@ -1113,32 +1145,32 @@ export default {
label: val.name.split('/').pop(),
leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
resolve(this.curNodeData);
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
this.defaultCheckedArr = this.defaultCheckedArr.concat(
this.curNodeData
.filter((val) => {
return val.watched === 2 && val.type !== this.unCheckedNodeType;
return val.watched === this.checkboxStatus.checked;
})
.map((val) => val.name),
);
const halfSelectArr = this.curNodeData
.filter((val) => {
return val.watched === 1 && val.type !== this.unCheckedNodeType;
return val.watched === this.checkboxStatus.indeterminate;
})
.map((val) => val.name);
node.childNodes.forEach((val) => {
if (halfSelectArr.indexOf(val.data.name) !== -1) {
val.indeterminate = true;
node.indeterminate = true;
[...new Set(curHalfCheckedKeys.concat(this.$refs.tree.getHalfCheckedKeys()))].forEach((val) => {
this.$refs.tree.getNode(val).indeterminate = true;
});
}
});
[...new Set(curHalfCheckedKeys.concat(this.$refs.tree.getHalfCheckedKeys()))].forEach((val) => {
this.$refs.tree.getNode(val).indeterminate = true;
});
this.selectedNode.name = node.data.name;
if (!this.allGraphData[node.data.name].isUnfold) {
this.dealGraphData(JSON.parse(JSON.stringify(graph.nodes)), node.data.name);
@@ -1200,28 +1232,35 @@ export default {
label: val.name.split('/').pop(),
leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
resolve(this.curNodeData);
// watched 0:unchecked 1:indeterminate 2:checked
this.searchCheckedArr = this.searchCheckedArr.concat(
this.curNodeData
.filter((val) => {
return val.watched === this.checkboxStatus.checked;
})
.map((val) => val.name),
);
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
const halfSelectArr = this.curNodeData
.filter((val) => {
return val.watched === 1;
return val.watched === this.checkboxStatus.indeterminate;
})
.map((val) => val.name);
node.childNodes.forEach((val) => {
if (val.data.watched === 2) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
if (halfSelectArr.indexOf(val.data.name) !== -1) {
val.indeterminate = true;
node.indeterminate = true;
[...new Set(curHalfCheckedKeys.concat(this.$refs.searchTree.getHalfCheckedKeys()))].forEach((val) => {
this.$refs.searchTree.getNode(val).indeterminate = true;
});
}
});
[...new Set(curHalfCheckedKeys.concat(this.$refs.searchTree.getHalfCheckedKeys()))].forEach((val) => {
this.$refs.searchTree.getNode(val).indeterminate = true;
});
}
});
}
@@ -1256,7 +1295,7 @@ export default {
if (val.id) {
val.selected = true;
this.curWatchPointId = val.id;
if (this.searchWord === '') {
if (this.searchWord === '' && this.nodeTypes.value === 'all') {
this.queryGraphByWatchpoint(val.id);
} else {
this.filter();
@@ -1321,26 +1360,22 @@ export default {
return {
label: val.name.split('/').pop(),
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
const node = this.$refs.tree.getNode(name);
curNodeData.forEach((val) => {
this.$refs.tree.append(val, name);
});
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
node.childNodes.forEach((val) => {
if (
node.checked &&
!node.childNodes.find((val) => val.data.watched !== 2) &&
val.data.type !== this.unCheckedNodeType
) {
if (node.checked && !node.childNodes.find((val) => val.data.watched !== 2) && val.data.watched !== -1) {
val.checked = true;
}
if (val.data.watched === 2 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
if (val.data.watched === 1 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.indeterminate) {
val.indeterminate = true;
}
if (val.data.type !== 'name_scope' && val.data.type !== 'aggregation_scope') {
@@ -1354,9 +1389,7 @@ export default {
this.$nextTick(() => {
if (
node.indeterminate &&
!node.childNodes
.filter((val) => val.data.type !== this.unCheckedNodeType)
.find((val) => val.checked === false)
!node.childNodes.filter((val) => val.data.watched !== -1).find((val) => val.checked === false)
) {
node.indeterminate = false;
node.checked = true;
@@ -1431,7 +1464,7 @@ export default {
.map((k) =>
!k.actual_value
? `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}`
: `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}${this.$t(
: `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}, ${this.$t(
'debugger.actualValue',
)}:${k.actual_value}`,
)
@@ -1443,9 +1476,7 @@ export default {
obj.lists.push({
name: item,
id: `${key}${hit.node_name}`,
tip: j.watch_condition.error_code
? this.$t('debugger.checkTips', {msg: tipsMapping[j.watch_condition.error_code]})
: '',
tip: j.error_code ? this.$t('debugger.checkTips', {msg: tipsMapping[j.error_code]}) : '',
});
});
}
@@ -1599,7 +1630,7 @@ export default {
return {
label: val.name.split('/').pop(),
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
data.forEach((val) => {
@@ -1613,12 +1644,12 @@ export default {
}
});
const node = this.$refs.tree.getNode(children.scope_name);
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
node.childNodes.forEach((val) => {
if (val.data.watched === 2 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
if (val.data.watched === 1 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.indeterminate) {
val.indeterminate = true;
}
if (val.data.type !== 'name_scope' && val.data.type !== 'aggregation_scope') {
@@ -1649,16 +1680,16 @@ export default {
label: val.name.split('/').pop(),
leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
this.resolve(this.origialTree);
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
this.node.childNodes.forEach((val) => {
if (val.data.watched === 2 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
if (val.data.watched === 1 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.indeterminate) {
val.indeterminate = true;
}
});


+ 44
- 27
mindinsight/ui/src/views/debugger/debugger.vue View File

@@ -20,7 +20,8 @@ limitations under the License.
<div class="left"
v-show="!leftShow">
<div class="header">
{{radio1==='tree' ? $t('debugger.nodeList') : $t('debugger.curHitNode')}}
{{radio1==='tree' ? $t('debugger.nodeList') :
($t('debugger.curHitNode') + '(' + watchPointHits.length + ')')}}
<div class="outdate-tip"
v-if="hitsOutdated && radio1==='hit'">
<el-tooltip class="item"
@@ -120,20 +121,20 @@ limitations under the License.
<span class="custom-tree-node">{{ node.label }}</span>
</span>
</tree>
<el-tree v-show="!treeFlag"
:props="defaultProps"
:load="loadSearchNode"
:lazy="true"
node-key="name"
:default-checked-keys="searchCheckedArr"
:expand-on-click-node="false"
@node-click="handleNodeClick"
:show-checkbox="!!curWatchPointId"
@check="searchCheck"
ref="searchTree">
<tree v-show="!treeFlag"
:props="defaultProps"
:load="loadSearchNode"
:lazy="true"
node-key="name"
:default-checked-keys="searchCheckedArr"
:expand-on-click-node="false"
@node-click="handleNodeClick"
:show-checkbox="!!curWatchPointId"
@check="searchCheck"
ref="searchTree">
<span class="custom-tree-node"
slot-scope="{ node ,data }">
<span>
<span :class="{const:data.type==='Const'}">
<img v-if="data.type ==='name_scope'"
:src="require('@/assets/images/name-scope.svg')"
class="image-type" />
@@ -149,7 +150,7 @@ limitations under the License.
</span>
<span class="custom-tree-node">{{ node.label }}</span>
</span>
</el-tree>
</tree>
</div>
<div class="watch-point-wrap">
<div class="title-wrap">
@@ -165,12 +166,13 @@ limitations under the License.
<div class="delete-wrap">
<i class="el-icon-delete"
:title="$t('debugger.clearWatchpoint')"
:class="{disable: !watchPointArr.length}"
:class="{disable: !(watchPointArr.length && metadata.state !== 'running')}"
@click="deleteWatchpoint()"></i>
</div>
<div class="add-wrap">
<i class="el-icon-circle-plus"
:title="$t('debugger.createWP')"
:class="{disable: metadata.state === 'running'}"
@click="addWatchPoint"></i>
</div>
</div>
@@ -449,7 +451,7 @@ limitations under the License.
v-if="tensorCompareFlag">
<debugger-tensor :row="curRowObj"
ref="deb-tensor"
@close="tensorCompareFlag=false"></debugger-tensor>
@close="closeTensor"></debugger-tensor>
</div>
<el-dialog :title="$t('debugger.createWP')"
:visible.sync="createWPDialogVisible"
@@ -757,9 +759,14 @@ export default {
trainId: '',
recommendWatchPointDialog: false,
hitsOutdated: false,
unCheckedNodeType: 'Const',
conflictFlag: false,
debuggerVersion: {},
checkboxStatus: {
unchecked: 0,
indeterminate: 1,
checked: 2,
noCheckbox: -1,
},
};
},
components: {debuggerTensor, tree},
@@ -802,6 +809,12 @@ export default {
this.curRowObj.step = this.metadata.step;
this.tensorCompareFlag = true;
},
closeTensor(tensor, graphName) {
this.tensorCompareFlag = false;
if (tensor && graphName) {
this.queryAllTreeData(tensor, true, graphName);
}
},
queryGraphByFile() {
this.searchWord = '';
this.nodeTypes.value = 'all';
@@ -828,25 +841,25 @@ export default {
label: val.name.split('/').pop(),
leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
this.node.childNodes = [];
this.resolve(this.origialTree);
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
this.defaultCheckedArr = this.origialTree
.filter((val) => {
return val.watched === 2 && val.type !== this.unCheckedNodeType;
return val.watched === this.checkboxStatus.checked;
})
.map((val) => val.name);
this.node.childNodes.forEach((val) => {
if (val.data.watched === 1 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.indeterminate) {
val.indeterminate = true;
}
if (val.data.watched === 0) {
if (val.data.watched === this.checkboxStatus.unchecked) {
val.checked = false;
}
if (val.data.watched === 2 && val.data.type !== this.unCheckedNodeType) {
if (val.data.watched === this.checkboxStatus.checked) {
val.checked = true;
}
});
@@ -935,7 +948,7 @@ export default {
return {
label: val.name.split('/').pop(),
...val,
showCheckbox: val.type !== this.unCheckedNodeType,
showCheckbox: val.watched !== -1,
};
});
this.node.childNodes = [];
@@ -944,15 +957,15 @@ export default {
this.$refs.tree.getCheckedKeys().forEach((val) => {
this.$refs.tree.setChecked(val, false);
});
// watched 0:unchecked 1:indeterminate 2:checked
// watched 0:unchecked 1:indeterminate 2:checked -1:no checkbox
this.defaultCheckedArr = this.curNodeData
.filter((val) => {
return val.watched === 2 && val.type !== this.unCheckedNodeType;
return val.watched === this.checkboxStatus.checked;
})
.map((val) => val.name);
const halfSelectArr = this.curNodeData
.filter((val) => {
return val.watched === 1 && val.type !== this.unCheckedNodeType;
return val.watched === this.checkboxStatus.indeterminate;
})
.map((val) => val.name);
this.node.childNodes.forEach((val) => {
@@ -1734,6 +1747,10 @@ export default {
color: #00a5a7;
cursor: pointer;
}
.disable:before {
cursor: not-allowed;
color: #adb0b8;
}
}
.content-wrap {
padding-left: 20px;


Loading…
Cancel
Save