Browse Source

In order to improve the user experience, debugger monitor point parameter list display and tensor support boolean and null display

tags/v1.1.0
fengxuefeng 5 years ago
parent
commit
6dd0e5999a
6 changed files with 143 additions and 76 deletions
  1. +13
    -4
      mindinsight/ui/src/components/debugger-grid-table-simple.vue
  2. +63
    -32
      mindinsight/ui/src/components/debugger-tensor.vue
  3. +0
    -1
      mindinsight/ui/src/locales/en-us.json
  4. +1
    -1
      mindinsight/ui/src/locales/zh-cn.json
  5. +38
    -27
      mindinsight/ui/src/mixins/debugger-mixin.vue
  6. +28
    -11
      mindinsight/ui/src/views/debugger/debugger.vue

+ 13
- 4
mindinsight/ui/src/components/debugger-grid-table-simple.vue View File

@@ -284,7 +284,7 @@ export default {
* @return {String}
*/
formateValueColor(row, cell, value, columnDef, dataContext) {
if (!cell || !value || isNaN(value) || value === Infinity || value === -Infinity) {
if (!cell || !value || this.judgeDataType(value)) {
return value;
} else if (value < 0) {
return `<span class="table-item-span" style="background:rgba(227, 125, 41, ${
@@ -296,6 +296,15 @@ export default {
})">${value}</span>`;
}
},
judgeDataType(value) {
return (
isNaN(value) ||
value === 'Infinity' ||
value === '-Infinity' ||
typeof value === 'boolean' ||
value === 'null'
);
},
/**
* Setting the background color of data
* @param {Number} row
@@ -308,7 +317,7 @@ export default {
formateCompareColor(row, cell, value, columnDef, dataContext) {
if (value instanceof Array && value.length >= 3) {
const valueNum = value[2];
if (!cell || !valueNum || isNaN(valueNum) || valueNum === Infinity || valueNum === -Infinity) {
if (!cell || !valueNum || this.judgeDataType(valueNum)) {
return `<span class="table-item-span" title="${value[0]}→${value[1]}">${valueNum}</span>`;
} else if (valueNum < 0) {
return `<span class="table-item-span" title="${value[0]}→${
@@ -360,7 +369,7 @@ export default {
const innerOrder = innerIndex + this.tableStartIndex.colStartIndex;
const tempArr = [];
innerData.forEach((innerValue) => {
if (isNaN(innerValue) || innerValue === 'Infinity' || innerValue === '-Infinity') {
if (this.judgeDataType(innerValue)) {
tempArr.push(innerValue);
} else {
if (this.category === 'science') {
@@ -381,7 +390,7 @@ export default {
};
outerData.forEach((innerData, innerIndex) => {
const innerOrder = innerIndex + this.tableStartIndex.colStartIndex;
if (isNaN(innerData) || innerData === 'Infinity' || innerData === '-Infinity') {
if (this.judgeDataType(innerData)) {
tempData[innerOrder] = innerData;
} else {
if (this.category === 'science') {


+ 63
- 32
mindinsight/ui/src/components/debugger-tensor.vue View File

@@ -50,7 +50,8 @@ limitations under the License.
v-if="item.tip">
<i class="el-icon-warning"></i>{{item.tip}}
</div>
<div class="tensor-advice">
<div class="tensor-advice"
v-if="!item.tip">
<span>{{ $t('debugger.tuningAdvice') }}</span>
<div class="advice-list-title">
<div class="adviceTitle">{{ item.tuningAdviceTitle }}</div>
@@ -64,7 +65,7 @@ limitations under the License.
</div>
</div>
<div v-show="!leftDataShow"
class="leftNoData">{{ $t('public.noData') }}</div>
class="leftNoData">{{ $t('debugger.noWatchPoint') }}</div>
</div>
<div class="collapse-btn"
:class="{collapse:leftShow}"
@@ -94,15 +95,24 @@ limitations under the License.
</label>
<label v-if="key===1">{{$t('debugger.preStatisticsLabel')}}<span>{{ curRowObj.step-1 }}</span></label>
<label v-if="key===2">{{$t('debugger.diffStatisticsLabel')}}</label>
<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') }} {{ 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') }} {{ statistics.overall_neg_zero_count }}</span>
<span>{{ $t('debugger.positiveNum') }} {{ statistics.overall_pos_zero_count }}</span>
<span>{{ $t('debugger.max') }} {{ statistics.overall_max===undefined?'--':statistics.overall_max }}</span>
<span>{{ $t('debugger.min') }} {{ statistics.overall_min===undefined?'--':statistics.overall_min }}</span>
<span>{{ $t('debugger.mean') }} {{ statistics.overall_avg===undefined?'--':statistics.overall_avg }}</span>
<span>{{ $t('debugger.nan') }}
{{ statistics.overall_nan_count===undefined?'--':statistics.overall_nan_count }}
</span>
<span>{{ $t('debugger.negativeInf') }}
{{ statistics.overall_neg_inf_count===undefined?'--':statistics.overall_neg_inf_count }}
</span>
<span>{{ $t('debugger.inf') }}
{{ statistics.overall_pos_inf_count===undefined?'--': statistics.overall_pos_inf_count}}
</span>
<span>{{ $t('debugger.zero') }}
{{ statistics.overall_zero_count===undefined?'--': statistics.overall_zero_count}}</span>
<span>{{ $t('debugger.negativeNum') }}
{{ statistics.overall_neg_zero_count===undefined?'--':statistics.overall_neg_zero_count }}</span>
<span>{{ $t('debugger.positiveNum') }}
{{ statistics.overall_pos_zero_count===undefined?'--':statistics.overall_pos_zero_count }}</span>
</div>
</div>
<div class="deb-con-slide">
@@ -110,16 +120,17 @@ limitations under the License.
<el-button size="mini"
class="custom-btn"
:class="{green:gridType==='value'}"
:disabled="state==='running'"
@click="tabChange('value')">{{ $t('debugger.curStep') }}</el-button>
<el-button size="mini"
class="custom-btn"
:class="{green:gridType==='preStep'}"
:disabled="!curRowObj.has_prev_step"
:disabled="!curRowObj.has_prev_step || state==='running'"
@click="tabChange('preStep')">{{ $t('debugger.preStep') }}</el-button>
<el-button size="mini"
class="custom-btn"
:class="{green:gridType==='compare'}"
:disabled="!curRowObj.has_prev_step"
:disabled="!curRowObj.has_prev_step || state==='running'"
@click="tabChange('compare')">{{ $t('debugger.compareResult') }}</el-button>
</div>
<div class="deb-con-slide-left"
@@ -201,6 +212,7 @@ limitations under the License.
<div class="tensor">
<div class="tensor-title">{{$t('debugger.tensorMsg')}}</div>
<div class="tensor-detail">
<span>{{ $t('graph.name') + $t('symbols.colon') }} {{ statistics.name }}</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>
@@ -217,7 +229,8 @@ limitations under the License.
</div>
<div class="watch-point">
<div class="watchPoint-title">{{ $t('debugger.watchList') }}</div>
<div class="point-list">
<div class="point-list"
v-show="rightDataShow">
<div v-for="(item,key) in watchPoints"
:key="key">
<div class="watch-judgment">
@@ -229,6 +242,8 @@ limitations under the License.
</div>
</div>
</div>
<div v-show="!rightDataShow"
class="leftNoData">{{ $t('debugger.noWatchPoint') }}</div>
</div>
</div>
</div>
@@ -276,12 +291,18 @@ export default {
selectedNode: {},
statistics: {},
leftDataShow: true,
rightDataShow: true,
tuningAdvice: [],
tuningAdviceTitle: '',
watchPoints: [],
callbackFun: null,
};
},
computed: {
state() {
return this.$parent.metadata.state;
},
},
mounted() {
this.$nextTick(() => {
this.callbackFun = this.debounce(this.resizeCallback, 200);
@@ -330,6 +351,10 @@ export default {
this.selectedNode.name = this.curRowObj.name;
const dot = this.packageData();
this.initGraph(dot);
} else {
if (this.selectedNode.name) {
this.setNodeData();
}
}
}
},
@@ -578,19 +603,16 @@ export default {
const selectedNode = nodesList[index];
if (selectedNode.id !== this.curRowObj.name) {
const data = this.tensorGraphData[selectedNode.id];
if (data.statistics && JSON.stringify(data.statistics) !== '{}') {
this.curRowObj.name = data.name;
this.curRowObj.full_name = data.full_name;
this.curRowObj.graph_name = data.graph_name;
this.curRowObj.has_prev_step = data.has_prev_step;
this.curRowObj.shape = JSON.stringify(data.shape || []);

nodes.on('click', null);
nodes.on('dblclick', null);
this.resetTensor();
} else {
this.$message.error(this.$t('debugger.jumpFailInformation'));
}
this.curRowObj.name = data.name;
this.curRowObj.full_name = data.full_name;
this.curRowObj.graph_name = data.graph_name;
this.curRowObj.has_prev_step = data.has_prev_step;
this.curRowObj.shape = JSON.stringify(data.shape || []);

nodes.on('click', null);
nodes.on('dblclick', null);
this.resetTensor();
}
});

@@ -701,13 +723,14 @@ export default {
},
setNodeData() {
window.getSelection().removeAllRanges();
const selectedNode = document.querySelector(`g[id="${this.selectedNode.name}"]`);
d3.selectAll('.node').classed('selected', false);
const selectedNode = document.querySelector(`#tensor-graph g[id="${this.selectedNode.name}"]`);
d3.selectAll('#tensor-graph .node').classed('selected', false);
selectedNode.classList.add('selected');
d3.selectAll('.edge').classed('selected', false);
d3.selectAll('#tensor-graph .edge').classed('selected', false);
this.selectedNode = JSON.parse(JSON.stringify(this.tensorGraphData[this.selectedNode.name]));

const keys = [
'name',
'overall_avg',
'overall_count',
'overall_max',
@@ -727,6 +750,8 @@ export default {
} else {
this.statistics = JSON.parse(JSON.stringify(this.selectedNode.statistics));
}
this.statistics.name = JSON.parse(JSON.stringify(this.selectedNode.name));

if (this.selectedNode.watch_points && this.selectedNode.watch_points.length) {
this.watchPoints = this.selectedNode.watch_points.map((val) => {
return {
@@ -736,16 +761,18 @@ export default {
selected: false,
};
});
this.rightDataShow = true;
} else {
this.watchPoints = [];
this.rightDataShow = false;
}
} else {
keys.forEach((key) => {
this.statistics[key] = '--';
});
this.watchPoints = [];
this.rightDataShow = false;
this.highLightEdges();
}
this.$forceUpdate();
},
highLightEdges() {
const edges = [];
@@ -985,7 +1012,7 @@ export default {
this.showFilterInput = true;
}
if (res.data.tensor_value) {
const value = res.data.tensor_value.value;
let value = res.data.tensor_value.value;
const statistics = res.data.tensor_value.statistics || {};
this.statisticsArr = [statistics];
if (value === 'Too large to show.') {
@@ -1000,6 +1027,9 @@ export default {
});
return;
}
if (value === null) {
value = 'null';
}
this.tensorValue = value instanceof Array ? value : [value];
this.$nextTick(() => {
this.$refs.tensorValue.updateGridData(this.tensorValue, JSON.parse(row.shape), statistics, shape);
@@ -1374,6 +1404,7 @@ export default {
display: inline-block;
padding: 5px 0px;
min-width: 50%;
word-break: break-all;
}
ul {
li {


+ 0
- 1
mindinsight/ui/src/locales/en-us.json View File

@@ -542,7 +542,6 @@
"tensorDiagram": "Tensor Relationship Diagram",
"selectDetail": "Select a tensor and double-click it to view details.",
"operator": "Operator",
"jumpFailInformation": "Redirection fails because the tensor information is empty.",
"optimizationOrientation": "Optimization Guide",
"tuningAdvice": "Optimization Suggestions",
"setValue": "Preset Value",


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

@@ -541,11 +541,11 @@
"tensorDiagram": "张量关系图",
"selectDetail": "单击张量选中,双击张量查看详情",
"operator": "算子",
"jumpFailInformation": "跳转失败,张量信息为空",
"optimizationOrientation": "调优向导",
"tuningAdvice": "调优建议",
"setValue": "设置值",
"actualValue": "实际值",
"noWatchPoint": "没有命中的监测点",
"tensorTuningRule": {
"operator_real_data_validation": "真实数据单算子验证",
"loss_overflow": "检查loss值溢出(NAN,INF)",


+ 38
- 27
mindinsight/ui/src/mixins/debugger-mixin.vue View File

@@ -392,7 +392,10 @@ export default {
this.isCurrentGraph = false;
}
this.metadata.pos = metadata.pos;
this.enableRecheck = metadata.enable_recheck;
if (metadata.enable_recheck !== undefined) {
this.enableRecheck = metadata.enable_recheck;
}

if (metadata.state) {
this.metadata.state = metadata.state;
}
@@ -421,13 +424,6 @@ export default {
if (metadata.step && metadata.step > this.metadata.step) {
this.metadata.step = metadata.step;
}

if (metadata.graph_name && metadata.tensor_name && this.tensorCompareFlag) {
const debTensor = this.$refs['deb-tensor'];
if (debTensor) {
debTensor.updateGraphData(metadata.graph_name, metadata.tensor_name);
}
}
},
/**
* Long polling,update some info
@@ -472,6 +468,18 @@ export default {
this.radio1 = 'hit';
this.getWatchpointHits();
}

if (
res.data.receive_tensor &&
res.data.receive_tensor.graph_name &&
res.data.receive_tensor.tensor_name &&
this.tensorCompareFlag
) {
const debTensor = this.$refs['deb-tensor'];
if (debTensor) {
debTensor.updateGraphData(res.data.receive_tensor.graph_name, res.data.receive_tensor.tensor_name);
}
}
this.pollData();
}
},
@@ -537,7 +545,7 @@ export default {
recheckWatchpoint() {
RequestService.recheckWatchPoints().then(
(res) => {
if (res && res.data && res.data.metadata) {
if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
this.enableRecheck = res.data.metadata.enable_recheck;
}
this.$message.success(this.$t('debugger.recheckSuccess'));
@@ -598,7 +606,7 @@ export default {
this.loadOriginalTree();
this.queryWatchPoints();
this.$message.success(this.$t('debugger.successDeleteWP'));
if (res && res.data && res.data.metadata) {
if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
this.enableRecheck = res.data.metadata.enable_recheck;
}
this.curWatchPointId = null;
@@ -660,7 +668,7 @@ export default {
this.createWatchPointArr = [];
this.createWPDialogVisible = false;
this.$message.success(this.$t('debugger.successCreateWP'));
if (res && res.data && res.data.metadata) {
if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
this.enableRecheck = res.data.metadata.enable_recheck;
}

@@ -806,7 +814,9 @@ export default {
RequestService.updateWatchpoint(params).then(
(res) => {
this.defaultCheckedArr = checkedKeys;
this.enableRecheck = res.data.metadata.enable_recheck;
if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
this.enableRecheck = res.data.metadata.enable_recheck;
}
this.$nextTick(() => {
if (node.indeterminate) {
node.checked = true;
@@ -869,7 +879,9 @@ export default {
RequestService.updateWatchpoint(params).then(
(res) => {
this.searchCheckedArr = checkedKeys;
this.enableRecheck = res.data.metadata.enable_recheck;
if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
this.enableRecheck = res.data.metadata.enable_recheck;
}
this.$nextTick(() => {
if (node.indeterminate) {
node.checked = true;
@@ -1096,7 +1108,9 @@ export default {
this.debuggerVersion = res.data.metadata.debugger_version;
}
this.metadata = res.data.metadata;
this.enableRecheck = res.data.metadata.enable_recheck;
if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) {
this.enableRecheck = res.data.metadata.enable_recheck;
}
if (this.metadata.backend) {
this.version = this.metadata.backend;
}
@@ -1462,24 +1476,21 @@ export default {
const tensorName = `slot: ${i.slot}, `;
if (i.watch_points && i.watch_points.length) {
i.watch_points.forEach((j, key) => {
let item = `${tensorName} Watch Point Id: ${j.id}, `;
let item = `${tensorName}${this.$t('debugger.watchPoint')} ${j.id}, `;
let params = [];
if (j.watch_condition) {
item += ` ${this.transCondition(j.watch_condition.id)}`;
const param = (j.watch_condition.params || [])
.map((k) =>
k.actual_value === undefined || k.actual_value === null
? `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}`
: `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}, ${this.$t(
'debugger.actualValue',
)}:${k.actual_value}`,
)
.join(', ');
if (param) {
item += ` (${param})`;
}
params = (j.watch_condition.params || []).map((k) =>
k.actual_value === undefined || k.actual_value === null
? `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}`
: `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}, ${this.$t(
'debugger.actualValue',
)}:${k.actual_value}`,
);
}
obj.lists.push({
name: item,
params,
id: `${key}${hit.node_name}`,
tip: j.error_code ? this.$t('debugger.checkTips', {msg: tipsMapping[j.error_code]}) : '',
});


+ 28
- 11
mindinsight/ui/src/views/debugger/debugger.vue View File

@@ -214,6 +214,12 @@ limitations under the License.
<ul>
<li v-for="(i, index) in props.row.lists"
:key="index">{{i.name}}
<div v-for="(j, ind) in i.params"
:key="ind"
class="param">
<div class="tensor-icon"></div>
{{j}}
</div>
<div class="hit-tip"
v-if="i.tip">
<i class="el-icon-warning"></i>{{i.tip}}
@@ -394,19 +400,22 @@ limitations under the License.
<div class="value-wrap">
<el-button size="mini"
type="text"
:disabled="metadata.state==='running'"
v-if="scope.row.value === 'click to view'"
@click="showTensor(scope.row,'value')">
{{ $t('debugger.view') }}
</el-button>
<span v-else
class="value-tip"
:class="{point:!isNaN(scope.row.value)}"
:title="isNaN(scope.row.value)?'':scope.row.value"
@click="isNaN(scope.row.value)?'javascript:;':showTensor(scope.row,'value')">
{{ scope.row.value }}</span>
<el-button v-else
class="value-tip"
size="mini"
type="text"
:disabled="metadata.state==='running'"
:title="isNaN(scope.row.value)?'':scope.row.value"
@click="showTensor(scope.row,'value')">
{{ scope.row.value }}</el-button>
<el-button size="mini"
type="text"
:disabled="!scope.row.has_prev_step"
:disabled="metadata.state==='running' || !scope.row.has_pre_step"
@click="showTensor(scope.row,'compare')">
{{ $t('debugger.compareToPre') }}
</el-button>
@@ -471,7 +480,8 @@ limitations under the License.
<el-option v-for="i in conditionCollections"
:key="i.id"
:label="transCondition(i.id)"
:value="i.id">
:value="i.id"
:class="{'deb-indent': i.id != 'tensor_condition_collection'}">
</el-option>
</el-select>
<el-select v-model="item.condition.selectedId"
@@ -1830,6 +1840,16 @@ export default {
&:hover {
background-color: #ebeef5;
}
.param {
.tensor-icon {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 3px;
background-color: #00a5a7;
margin-top: 8px;
}
}
.hit-tip {
margin-top: 10px;
font-size: 12px;
@@ -2081,9 +2101,6 @@ export default {
vertical-align: middle;
text-align: center;
}
.value-tip.point {
cursor: pointer;
}
.el-table--border {
border-right: none;
border-left: none;


Loading…
Cancel
Save