Browse Source

UI support tensor detection view

tags/v1.1.0
WeiFeng-mindinsight 5 years ago
parent
commit
f5ea481acf
8 changed files with 1878 additions and 849 deletions
  1. BIN
      mindinsight/ui/src/assets/images/deb-operator.png
  2. BIN
      mindinsight/ui/src/assets/images/deb-slot.png
  3. +28
    -66
      mindinsight/ui/src/components/debugger-grid-table-simple.vue
  4. +1384
    -0
      mindinsight/ui/src/components/debugger-tensor.vue
  5. +24
    -4
      mindinsight/ui/src/locales/zh-cn.json
  6. +225
    -437
      mindinsight/ui/src/mixins/debugger-mixin.vue
  7. +21
    -0
      mindinsight/ui/src/services/request-service.js
  8. +196
    -342
      mindinsight/ui/src/views/debugger/debugger.vue

BIN
mindinsight/ui/src/assets/images/deb-operator.png View File

Before After
Width: 60  |  Height: 39  |  Size: 7.1 kB

BIN
mindinsight/ui/src/assets/images/deb-slot.png View File

Before After
Width: 56  |  Height: 39  |  Size: 6.6 kB

+ 28
- 66
mindinsight/ui/src/components/debugger-grid-table-simple.vue View File

@@ -55,10 +55,14 @@ limitations under the License.
size="mini" size="mini"
v-if="!!filterArr.length" v-if="!!filterArr.length"
@click="filterChange"> @click="filterChange">
<i class="el-icon-check"></i></el-button>
<i class="el-icon-check"></i>
</el-button>
<span class="filter-incorrect-text" <span class="filter-incorrect-text"
v-if="!filterCorrect">{{$t('components.inCorrectInput')}}</span> v-if="!filterCorrect">{{$t('components.inCorrectInput')}}</span>
</div> </div>
<div class="shape-wrap">
<span>{{ $t('tensors.dimension') }} {{ shape }}</span>
</div>
<div class="accuracy-container"> <div class="accuracy-container">
{{$t('components.gridAccuracy')}}<el-select v-model="accuracy" {{$t('components.gridAccuracy')}}<el-select v-model="accuracy"
class="select-item" class="select-item"
@@ -157,6 +161,7 @@ export default {
rowStartIndex: 0, rowStartIndex: 0,
colStartIndex: 0, colStartIndex: 0,
}, },
shape: '',
}; };
}, },
computed: {}, computed: {},
@@ -173,8 +178,7 @@ export default {
* Initialize * Initialize
*/ */
init() { init() {
this.itemId =
`${new Date().getTime()}` + `${this.$store.state.componentsCount}`;
this.itemId = `${new Date().getTime()}` + `${this.$store.state.componentsCount}`;
this.$store.commit('componentsNum'); this.$store.commit('componentsNum');
}, },
/** /**
@@ -201,8 +205,7 @@ export default {
const curFilterArr = tempFilterArr[i].split(':'); const curFilterArr = tempFilterArr[i].split(':');
if (curFilterArr[0]) { if (curFilterArr[0]) {
let startIndex = Number(curFilterArr[0]); let startIndex = Number(curFilterArr[0]);
startIndex =
startIndex < 0 ? dimension[i] + startIndex : startIndex;
startIndex = startIndex < 0 ? dimension[i] + startIndex : startIndex;
multiDimsArr.push(startIndex); multiDimsArr.push(startIndex);
} else { } else {
multiDimsArr.push(0); multiDimsArr.push(0);
@@ -251,9 +254,7 @@ export default {
width: 100, width: 100,
headerCssClass: 'headerStyle', headerCssClass: 'headerStyle',
formatter: formatter:
this.gridType === this.gridTypeKeys.compare
? this.formateCompareColor
: this.formateValueColor,
this.gridType === this.gridTypeKeys.compare ? this.formateCompareColor : this.formateValueColor,
}); });
}); });
} else { } else {
@@ -270,13 +271,7 @@ export default {
* @return {String} * @return {String}
*/ */
formateValueColor(row, cell, value, columnDef, dataContext) { formateValueColor(row, cell, value, columnDef, dataContext) {
if (
!cell ||
!value ||
isNaN(value) ||
value === Infinity ||
value === -Infinity
) {
if (!cell || !value || isNaN(value) || value === Infinity || value === -Infinity) {
return value; return value;
} else if (value < 0) { } else if (value < 0) {
return `<span class="table-item-span" style="background:rgba(227, 125, 41, ${ return `<span class="table-item-span" style="background:rgba(227, 125, 41, ${
@@ -300,24 +295,14 @@ export default {
formateCompareColor(row, cell, value, columnDef, dataContext) { formateCompareColor(row, cell, value, columnDef, dataContext) {
if (value instanceof Array && value.length >= 3) { if (value instanceof Array && value.length >= 3) {
const valueNum = value[2]; const valueNum = value[2];
if (
!cell ||
!valueNum ||
isNaN(valueNum) ||
valueNum === Infinity ||
valueNum === -Infinity
) {
if (!cell || !valueNum || isNaN(valueNum) || valueNum === Infinity || valueNum === -Infinity) {
return `<span class="table-item-span" title="${value[0]}→${value[1]}">${valueNum}</span>`; return `<span class="table-item-span" title="${value[0]}→${value[1]}">${valueNum}</span>`;
} else if (valueNum < 0) { } else if (valueNum < 0) {
return `<span class="table-item-span" title="${value[0]}→${ return `<span class="table-item-span" title="${value[0]}→${
value[1] value[1]
}" style="background:rgba(227, 125, 41, ${
valueNum / this.statistics.overall_min
})">${valueNum}</span>`;
}" style="background:rgba(227, 125, 41, ${valueNum / this.statistics.overall_min})">${valueNum}</span>`;
} else { } else {
return `<span class="table-item-span" title="${value[0]}→${
value[1]
}" style="background:rgba(0, 165, 167, ${
return `<span class="table-item-span" title="${value[0]}→${value[1]}" style="background:rgba(0, 165, 167, ${
valueNum / this.statistics.overall_max valueNum / this.statistics.overall_max
})">${valueNum}</span>`; })">${valueNum}</span>`;
} }
@@ -362,11 +347,7 @@ export default {
const innerOrder = innerIndex + this.tableStartIndex.colStartIndex; const innerOrder = innerIndex + this.tableStartIndex.colStartIndex;
const tempArr = []; const tempArr = [];
innerData.forEach((innerValue) => { innerData.forEach((innerValue) => {
if (
isNaN(innerValue) ||
innerValue === 'Infinity' ||
innerValue === '-Infinity'
) {
if (isNaN(innerValue) || innerValue === 'Infinity' || innerValue === '-Infinity') {
tempArr.push(innerValue); tempArr.push(innerValue);
} else { } else {
tempArr.push(innerValue.toFixed(this.accuracy)); tempArr.push(innerValue.toFixed(this.accuracy));
@@ -383,11 +364,7 @@ export default {
}; };
outerData.forEach((innerData, innerIndex) => { outerData.forEach((innerData, innerIndex) => {
const innerOrder = innerIndex + this.tableStartIndex.colStartIndex; const innerOrder = innerIndex + this.tableStartIndex.colStartIndex;
if (
isNaN(innerData) ||
innerData === 'Infinity' ||
innerData === '-Infinity'
) {
if (isNaN(innerData) || innerData === 'Infinity' || innerData === '-Infinity') {
tempData[innerOrder] = innerData; tempData[innerOrder] = innerData;
} else { } else {
tempData[innerOrder] = innerData.toFixed(this.accuracy); tempData[innerOrder] = innerData.toFixed(this.accuracy);
@@ -404,12 +381,7 @@ export default {
updateGrid() { updateGrid() {
this.$nextTick(() => { this.$nextTick(() => {
if (!this.gridObj) { if (!this.gridObj) {
this.gridObj = new Slick.Grid(
`#${this.itemId}`,
this.formateArr,
this.columnsData,
this.optionObj,
);
this.gridObj = new Slick.Grid(`#${this.itemId}`, this.formateArr, this.columnsData, this.optionObj);
this.columnsLength = this.columnsData.length; this.columnsLength = this.columnsData.length;
} }
this.gridObj.setData(this.formateArr, this.scrollTop); this.gridObj.setData(this.formateArr, this.scrollTop);
@@ -445,12 +417,7 @@ export default {
this.filterArr.forEach((filter) => { this.filterArr.forEach((filter) => {
let value = filter.model.trim(); let value = filter.model.trim();
if (!isNaN(value)) { if (!isNaN(value)) {
if (
value < -(filter.max + 1) ||
value > filter.max ||
value === '' ||
value % 1
) {
if (value < -(filter.max + 1) || value > filter.max || value === '' || value % 1) {
filter.showError = true; filter.showError = true;
filterCorrect = false; filterCorrect = false;
} else { } else {
@@ -499,20 +466,12 @@ export default {
const startValue = tempArr[0]; const startValue = tempArr[0];
const endValue = tempArr[1]; const endValue = tempArr[1];
const limitCount = 2; const limitCount = 2;
if (
!!startValue &&
(isNaN(startValue) ||
startValue < -(filter.max + 1) ||
startValue > filter.max)
) {
if (!!startValue && (isNaN(startValue) || startValue < -(filter.max + 1) || startValue > filter.max)) {
return false; return false;
} }
if ( if (
!!endValue && !!endValue &&
(isNaN(endValue) ||
endValue <= -(filter.max + 1) ||
endValue > (filter.max + 1) ||
!Number(endValue))
(isNaN(endValue) || endValue <= -(filter.max + 1) || endValue > filter.max + 1 || !Number(endValue))
) { ) {
return false; return false;
} }
@@ -521,12 +480,8 @@ export default {
} else if (!startValue && !endValue) { } else if (!startValue && !endValue) {
return true; return true;
} else if (!!startValue && !!endValue) { } else if (!!startValue && !!endValue) {
const sv =
startValue < 0
? filter.max + Number(startValue) + 1
: Number(startValue);
const ev =
endValue < 0 ? filter.max + Number(endValue) + 1 : Number(endValue);
const sv = startValue < 0 ? filter.max + Number(startValue) + 1 : Number(startValue);
const ev = endValue < 0 ? filter.max + Number(endValue) + 1 : Number(endValue);
if (ev <= sv) { if (ev <= sv) {
return false; return false;
} else { } else {
@@ -544,6 +499,7 @@ export default {
* @param {String} filterStr String of dimension selection * @param {String} filterStr String of dimension selection
*/ */
updateGridData(newDataFlag, dimension, statistics, filterStr) { updateGridData(newDataFlag, dimension, statistics, filterStr) {
this.shape = dimension;
this.updated = true; this.updated = true;
this.requestError = false; this.requestError = false;
this.$nextTick(() => { this.$nextTick(() => {
@@ -708,10 +664,16 @@ export default {
color: red; color: red;
} }
} }
.shape-wrap {
float: left;
line-height: 34px;
margin-left: 10px;
}
.accuracy-container { .accuracy-container {
float: right; float: right;
.select-item { .select-item {
width: 65px; width: 65px;
margin-left: 5px;
} }
} }
} }


+ 1384
- 0
mindinsight/ui/src/components/debugger-tensor.vue
File diff suppressed because it is too large
View File


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

@@ -538,10 +538,10 @@
"selectDetail": "单击张量选中,双击张量查看详情", "selectDetail": "单击张量选中,双击张量查看详情",
"operator": "算子", "operator": "算子",
"jumpFailInformation": "跳转失败,张量信息为空", "jumpFailInformation": "跳转失败,张量信息为空",
"tensorMax": "最大值",
"tensorMin": "最小值",
"optimizationOrientation": "调优向导", "optimizationOrientation": "调优向导",
"tuningAdvice": "调优建议", "tuningAdvice": "调优建议",
"setValue": "设置值",
"actualValue": "实际值",
"tensorTuningRule": { "tensorTuningRule": {
"operator_real_data_validation": "真实数据单算子验证", "operator_real_data_validation": "真实数据单算子验证",
"loss_overflow": "检查loss值溢出(NAN,INF)", "loss_overflow": "检查loss值溢出(NAN,INF)",
@@ -569,7 +569,20 @@
"tensor_all_zero": "检查张量是否全为0", "tensor_all_zero": "检查张量是否全为0",
"tensor_change_too_large": "检查张量变化过大", "tensor_change_too_large": "检查张量变化过大",
"tensor_change_too_small": "检查张量变化过小", "tensor_change_too_small": "检查张量变化过小",
"tensor_not_changed": "检查未变化张量"
"tensor_not_changed": "检查未变化张量",
"zero_percentage_ge": "0值比例>=",
"abs_mean_gt": "绝对值的平均值>",
"abs_mean_lt": "绝对值的平均值<",
"range_start_inclusive": "范围下界(含)",
"range_end_inclusive": "范围上界(含)",
"range_percentage_lt": "在范围中的值所占百分比<",
"range_percentage_gt": "在范围中的值所占百分比>",
"rtol": "相对容忍度",
"abs_updata_ratio_mean_gt": "变化比例绝对值的平均值>",
"abs_updata_ratio_mean_lt": "变化比例绝对值的平均值<",
"param": "阈值",
"max_min_lt": "MAX-MIN>",
"max_min_gt": "MAX-MIN<"
}, },
"tensorTuningAdvice": { "tensorTuningAdvice": {
"operator_real_data_validation": [ "operator_real_data_validation": [
@@ -698,7 +711,14 @@
"noAdvice": "没有可用的建议", "noAdvice": "没有可用的建议",
"curStep": "显示当前step", "curStep": "显示当前step",
"preStep": "显示上一step", "preStep": "显示上一step",
"compareResult": "显示对比结果"
"compareResult": "显示对比结果",
"recommendTip": "是否使用推荐监测点?",
"recommendDetail": "推荐监测点包括针对张量全为零、梯度消失、权重更新过大等现象的监测点,有助于您更快发现训练中存在的问题。",
"use": "使用",
"notUse": "不使用",
"outdateTip": "监测点列表发生修改,结果可能过时,请重新检查或执行后续step训练。",
"versionConflictTip": "Mindspore和Mindinsight版本不匹配,Mindspore版本:{msv};Mindinsight版本:{miv};",
"checkTips": "提示:张量中含有{msg},无法进行数值检查。"
}, },
"explain": { "explain": {
"explain": "模型解释", "explain": "模型解释",


+ 225
- 437
mindinsight/ui/src/mixins/debugger-mixin.vue
File diff suppressed because it is too large
View File


+ 21
- 0
mindinsight/ui/src/services/request-service.js View File

@@ -433,4 +433,25 @@ export default {
params: params, params: params,
}); });
}, },
tensorHitsData(params) {
return axios({
method: 'get',
url: 'v1/mindinsight/debugger/tensor-hits',
params: params,
});
},
getTensorGraphData(params) {
return axios({
method: 'get',
url: 'v1/mindinsight/debugger/tensor-graphs',
params: params,
});
},
setRecommendWatchPoints(params) {
return axios({
method: 'post',
url: `v1/mindinsight/conditionmgr/train-jobs/${params.trainId}/set-recommended-watch-points`,
data: params.body,
});
},
}; };

+ 196
- 342
mindinsight/ui/src/views/debugger/debugger.vue View File

@@ -21,6 +21,15 @@ limitations under the License.
v-show="!leftShow"> v-show="!leftShow">
<div class="header"> <div class="header">
{{radio1==='tree' ? $t('debugger.nodeList') : $t('debugger.curHitNode')}} {{radio1==='tree' ? $t('debugger.nodeList') : $t('debugger.curHitNode')}}
<div class="outdate-tip"
v-if="hitsOutdated && radio1==='hit'">
<el-tooltip class="item"
effect="light"
:content="$t('debugger.outdateTip')"
placement="top">
<i class="el-icon-warning"></i>
</el-tooltip>
</div>
<div class="radio-tabs"> <div class="radio-tabs">
<el-radio-group v-model="radio1" <el-radio-group v-model="radio1"
size='mini' size='mini'
@@ -119,6 +128,8 @@ limitations under the License.
:default-checked-keys="searchCheckedArr" :default-checked-keys="searchCheckedArr"
:expand-on-click-node="false" :expand-on-click-node="false"
@node-click="handleNodeClick" @node-click="handleNodeClick"
:show-checkbox="!!curWatchPointId"
@check="searchCheck"
ref="searchTree"> ref="searchTree">
<span class="custom-tree-node" <span class="custom-tree-node"
slot-scope="{ node ,data }"> slot-scope="{ node ,data }">
@@ -200,7 +211,12 @@ limitations under the License.
<template slot-scope="props"> <template slot-scope="props">
<ul> <ul>
<li v-for="(i, index) in props.row.lists" <li v-for="(i, index) in props.row.lists"
:key="index">{{i.name}}</li>
:key="index">{{i.name}}
<div class="hit-tip"
v-if="i.tip">
<i class="el-icon-warning"></i>{{i.tip}}
</div>
</li>
</ul> </ul>
</template> </template>
</el-table-column> </el-table-column>
@@ -229,7 +245,6 @@ limitations under the License.
@keyup.native.enter="control(0)"> @keyup.native.enter="control(0)">
</el-input> </el-input>
</el-tooltip> </el-tooltip>

<el-button type="primary" <el-button type="primary"
size="mini" size="mini"
class="custom-btn green" class="custom-btn green"
@@ -378,16 +393,19 @@ limitations under the License.
<el-button size="mini" <el-button size="mini"
type="text" type="text"
v-if="scope.row.value === 'click to view'" v-if="scope.row.value === 'click to view'"
@click="viewValueDetail(scope.row)">
@click="showTensor(scope.row,'value')">
{{ $t('debugger.view') }} {{ $t('debugger.view') }}
</el-button> </el-button>
<span v-else <span v-else
class="value-tip" class="value-tip"
:title="isNaN(scope.row.value)?'':scope.row.value">{{ scope.row.value }}</span>
: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 size="mini" <el-button size="mini"
type="text" type="text"
:disabled="!scope.row.has_prev_step" :disabled="!scope.row.has_prev_step"
@click="tensorComparisons(scope.row)">
@click="showTensor(scope.row,'compare')">
{{ $t('debugger.compareToPre') }} {{ $t('debugger.compareToPre') }}
</el-button> </el-button>
</div> </div>
@@ -429,89 +447,9 @@ limitations under the License.
</div> </div>
<div class="deb-con" <div class="deb-con"
v-if="tensorCompareFlag"> v-if="tensorCompareFlag">
<div class="deb-con-title">
<div class="deb-con-title-left"
:title="curRowObj.name">
{{ curRowObj.name }}
</div>
<div class="deb-con-title-middle">
MIN
<div class="grident">0</div>
MAX
</div>
<div class="deb-con-title-right">
<div class="close-btn">
<img src="@/assets/images/close-page.png"
@click="tensorCompareFlag=false;dims=null;tolerance=0;">
</div>
</div>

</div>
<div class="deb-con-slide">
<div class="deb-con-slide-left"
v-if="gridType === 'compare'">
<div class="deb-slide-title">{{ $t('debugger.tolerance') }}</div>
<div class="deb-slide-width">
<el-slider v-model="tolerance"
:format-tooltip="formatTolenrance"
@change="tensorComparisons(curRowObj,dims)"
@input="toleranceInputChange()"></el-slider>
</div>
<div class="deb-slide-input">
<el-input v-model="toleranceInput"
@input="toleranceValueChange"
@keyup.native.enter="tensorComparisons(curRowObj,dims)"></el-input>
</div>
</div>
<div class="deb-con-slide-right">
<el-button size="mini"
class="custom-btn"
:class="{green:gridType==='value'}"
@click="tabChange('value')">{{ $t('debugger.curValue') }}</el-button>
<el-button size="mini"
class="custom-btn"
:class="{green:gridType==='compare'}"
:disabled="!curRowObj.has_prev_step"
@click="tabChange('compare')">{{ $t('debugger.compareToPre') }}</el-button>
</div>
</div>

<div class="deb-con-table">
<div class="deb-compare-wrap">
<debuggerGridTable v-if="gridType==='value'"
:fullData="tensorValue"
:showFilterInput="showFilterInput"
ref="tensorValue"
gridType="value"
@martixFilterChange="tensorFilterChange($event)">
</debuggerGridTable>
<debuggerGridTable v-else
:fullData="tensorValue"
:showFilterInput="showFilterInput"
ref="tensorValue"
gridType="compare"
@martixFilterChange="tensorFilterChange($event)">
</debuggerGridTable>
</div>
<div class="deb-compare-detail">
<span>{{ $t('tensors.dimension') }} {{ curRowObj.shape }}</span>
<div v-for="(statistics,key) in statisticsArr"
:key="key">
<label v-if="key===0">{{$t('debugger.curStatisticsLabel')}}<span>{{ metadata.step }}</span></label>
<label v-if="key===1">{{$t('debugger.preStatisticsLabel')}}<span>{{ metadata.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>
</div>
</div>
</div>
<debugger-tensor :row="curRowObj"
ref="deb-tensor"
@close="tensorCompareFlag=false"></debugger-tensor>
</div> </div>
<el-dialog :title="$t('debugger.createWP')" <el-dialog :title="$t('debugger.createWP')"
:visible.sync="createWPDialogVisible" :visible.sync="createWPDialogVisible"
@@ -519,7 +457,7 @@ limitations under the License.
:close-on-click-modal="false" :close-on-click-modal="false"
:modal-append-to-body="false" :modal-append-to-body="false"
class="creat-watch-point-dialog" class="creat-watch-point-dialog"
width="900px">
width="870px">


<div class="conditions-container"> <div class="conditions-container">
<div class="condition-item" <div class="condition-item"
@@ -551,7 +489,8 @@ limitations under the License.
<el-option v-for="i in item.param.options" <el-option v-for="i in item.param.options"
:key="i.name" :key="i.name"
:label="transCondition(i.name)" :label="transCondition(i.name)"
:value="i.name">
:value="i.name"
v-show="i.paran_type !== 'SUPPORT_PARAM'">
</el-option> </el-option>
</el-select> </el-select>


@@ -574,6 +513,33 @@ limitations under the License.
:value="false"> :value="false">
</el-option> </el-option>
</el-select> </el-select>

<div class="inclusive-param"
v-if="item.compositeParams.selections.length">
<div class="item"
v-for="(i, index) in item.compositeParams.selections"
:key="index">
{{transCondition(i.name)}}

<el-input v-model="item.compositeParams.selections[index].value"
:placeholder="$t('scalar.placeHolderNumber')"
v-if="i.type !== 'BOOL'"
@input="validateParam(item)"
class="param-value"></el-input>
<el-select v-model="i.value"
v-if="i.type === 'BOOL'"
class="param-value">
<el-option :key="true"
label="true"
:value="true">
</el-option>
<el-option :key="false"
label="false"
:value="false">
</el-option>
</el-select>
</div>
</div>
</div> </div>
</div> </div>
<span slot="footer" <span slot="footer"
@@ -616,16 +582,70 @@ limitations under the License.
@click="toSummeryList()">{{$t('debugger.toSummeryList')}}</el-button> @click="toSummeryList()">{{$t('debugger.toSummeryList')}}</el-button>
</span> </span>
</el-dialog> </el-dialog>

<el-dialog :title="$t('debugger.recommendTip')"
:visible.sync="recommendWatchPointDialog"
:show-close="false"
:close-on-click-modal="false"
:modal-append-to-body="false"
class="pendingTips"
width="420px">

<span class="dialog-icon">
<span class="el-icon-warning"></span>
</span>
<span class="dialog-content">{{ $t('debugger.recommendDetail') }}</span>

<span slot="footer"
class="dialog-footer">
<el-button type="primary"
size="mini"
class="custom-btn green"
@click="initRecommendWatchPoints(true)">
{{$t('debugger.use')}}
</el-button>
<el-button type="primary"
size="mini"
class="custom-btn"
@click="initRecommendWatchPoints(false)">
{{ $t('debugger.notUse') }}
</el-button>
</span>

</el-dialog>
<el-dialog :title="$t('public.notice')"
:visible.sync="conflictFlag"
:show-close="false"
:close-on-click-modal="false"
:modal-append-to-body="false"
class="pendingTips"
width="420px">

<span class="dialog-icon">
<span class="el-icon-warning"></span>
</span>
<span class="dialog-content">
{{ $t('debugger.versionConflictTip',{msv:debuggerVersion.ms,miv:debuggerVersion.mi}) }}
</span>
<span slot="footer"
class="dialog-footer">
<el-button type="primary"
size="mini"
class="custom-btn green"
@click="control(2)">{{$t('public.sure')}}</el-button>
</span>
</el-dialog>

</div> </div>
</template> </template>
<script> <script>
import {select, selectAll, zoom, dispatch} from 'd3'; import {select, selectAll, zoom, dispatch} from 'd3';
import 'd3-graphviz'; import 'd3-graphviz';
import debuggerGridTable from '../../components/debugger-grid-table-simple.vue';
const d3 = {select, selectAll, zoom, dispatch}; const d3 = {select, selectAll, zoom, dispatch};
import RequestService from '@/services/request-service'; import RequestService from '@/services/request-service';
import commonGraph from '../../mixins/common-graph.vue'; import commonGraph from '../../mixins/common-graph.vue';
import debuggerMixin from '../../mixins/debugger-mixin.vue'; import debuggerMixin from '../../mixins/debugger-mixin.vue';
import debuggerTensor from '@/components/debugger-tensor.vue';
import tree from '../../components/tree.vue'; import tree from '../../components/tree.vue';


export default { export default {
@@ -733,18 +753,19 @@ export default {
isCurrentGraph: true, // Check whether the new and old graphs are the same. isCurrentGraph: true, // Check whether the new and old graphs are the same.
expandKeys: [], expandKeys: [],
isHitIntoView: true, isHitIntoView: true,
searchedWord: '',
trainId: '',
recommendWatchPointDialog: false,
hitsOutdated: false,
unCheckedNodeType: 'Const', unCheckedNodeType: 'Const',
conflictFlag: false,
debuggerVersion: {},
}; };
}, },
components: {debuggerGridTable, tree},
components: {debuggerTensor, tree},
computed: {}, computed: {},
mounted() { mounted() {
document.title = `${this.$t('debugger.debugger')}-MindInsight`; document.title = `${this.$t('debugger.debugger')}-MindInsight`;
window.addEventListener(
'resize',
this.debounce(this.resizeCallback, 200),
false,
);
this.nodeTypes.label = this.$t('debugger.nodeType'); this.nodeTypes.label = this.$t('debugger.nodeType');
}, },
watch: { watch: {
@@ -764,11 +785,23 @@ export default {
} else { } else {
this.dialogVisible = false; this.dialogVisible = false;
} }
if (newValue === 'mismatch') {
this.conflictFlag = true;
} else {
this.conflictFlag = false;
}
}, },
deep: true, deep: true,
}, },
}, },
methods: { methods: {
showTensor(row, type) {
this.curRowObj = row;
this.curRowObj.type = type;
this.curRowObj.curFileName = this.graphFiles.value;
this.curRowObj.step = this.metadata.step;
this.tensorCompareFlag = true;
},
queryGraphByFile() { queryGraphByFile() {
this.searchWord = ''; this.searchWord = '';
this.nodeTypes.value = 'all'; this.nodeTypes.value = 'all';
@@ -793,10 +826,7 @@ export default {
this.origialTree = res.data.graph.nodes.map((val) => { this.origialTree = res.data.graph.nodes.map((val) => {
return { return {
label: val.name.split('/').pop(), label: val.name.split('/').pop(),
leaf:
val.type === 'name_scope' || val.type === 'aggregation_scope'
? false
: true,
leaf: val.type === 'name_scope' || val.type === 'aggregation_scope' ? false : true,
...val, ...val,
showCheckbox: val.type !== this.unCheckedNodeType, showCheckbox: val.type !== this.unCheckedNodeType,
}; };
@@ -834,11 +864,7 @@ export default {
); );
}, },
selectAllFiles(type) { selectAllFiles(type) {
if (
!type &&
!this.$refs.tree.getCheckedKeys().length &&
!this.$refs.tree.getHalfCheckedKeys().length
) {
if (!type && !this.$refs.tree.getCheckedKeys().length && !this.$refs.tree.getHalfCheckedKeys().length) {
return; return;
} }
if (type && !this.node.childNodes.find((val) => val.checked === false)) { if (type && !this.node.childNodes.find((val) => val.checked === false)) {
@@ -968,9 +994,7 @@ export default {
param = `(${param})`; param = `(${param})`;
} }


const str = `${this.$t('debugger.watchPoint')} ${
item.id
}: ${this.transCondition(item.condition)} ${param}`;
const str = `${this.$t('debugger.watchPoint')} ${item.id}: ${this.transCondition(item.condition)} ${param}`;
return str; return str;
}, },
/** ************************ graph **********************/ /** ************************ graph **********************/
@@ -1031,10 +1055,8 @@ export default {
}; };


this.graph.minScale = this.graph.minScale =
Math.min(
this.svg.rect.width / 2 / graphRect.width,
this.svg.rect.height / 2 / graphRect.height,
) * this.graph.transform.k;
Math.min(this.svg.rect.width / 2 / graphRect.width, this.svg.rect.height / 2 / graphRect.height) *
this.graph.transform.k;


this.startApp(); this.startApp();
}, },
@@ -1071,14 +1093,7 @@ export default {
initContextMenu() { initContextMenu() {
this.contextmenu.dom = document.querySelector('#contextMenu'); this.contextmenu.dom = document.querySelector('#contextMenu');
const svgDom = document.querySelector('#graph svg'); const svgDom = document.querySelector('#graph svg');
const ignoreType = [
'Parameter',
'Const',
'Depend',
'make_tuple',
'tuple_getitem',
'ControlDepend',
];
const ignoreType = ['Parameter', 'Const', 'Depend', 'make_tuple', 'tuple_getitem', 'ControlDepend'];


const dispatch = d3 const dispatch = d3
.dispatch('start', 'contextmenu') .dispatch('start', 'contextmenu')
@@ -1088,12 +1103,8 @@ export default {
}) })
.on('contextmenu', (target) => { .on('contextmenu', (target) => {
const svgRect = svgDom.getBoundingClientRect(); const svgRect = svgDom.getBoundingClientRect();
this.contextmenu.dom.style.left = `${
this.contextmenu.point.x - svgRect.x
}px`;
this.contextmenu.dom.style.top = `${
this.contextmenu.point.y - svgRect.y
}px`;
this.contextmenu.dom.style.left = `${this.contextmenu.point.x - svgRect.x}px`;
this.contextmenu.dom.style.top = `${this.contextmenu.point.y - svgRect.y}px`;
this.contextmenu.dom.style.display = 'block'; this.contextmenu.dom.style.display = 'block';


this.selectedNode.name = target.name; this.selectedNode.name = target.name;
@@ -1105,9 +1116,7 @@ export default {
'contextmenu', 'contextmenu',
(target, index, nodesList) => { (target, index, nodesList) => {
event.preventDefault(); event.preventDefault();
const node = this.allGraphData[
nodesList[index].id.replace('_unfold', '')
];
const node = this.allGraphData[nodesList[index].id.replace('_unfold', '')];
if (node) { if (node) {
if ( if (
!( !(
@@ -1211,9 +1220,7 @@ export default {
* @param {String} name Name of the current node. * @param {String} name Name of the current node.
*/ */
queryGraphData(name) { queryGraphData(name) {
const type = this.allGraphData[name]
? this.allGraphData[name].type
: 'name_scope';
const type = this.allGraphData[name] ? this.allGraphData[name].type : 'name_scope';
const mode = name ? 'node' : 'all'; const mode = name ? 'node' : 'all';
const params = { const params = {
mode: mode, mode: mode,
@@ -1268,9 +1275,7 @@ export default {
dealGraphData(nodes, name) { dealGraphData(nodes, name) {
const namescopeChildLimit = 3500; const namescopeChildLimit = 3500;
const nodesCountLimit = name ? this.nodesCountLimit : namescopeChildLimit; const nodesCountLimit = name ? this.nodesCountLimit : namescopeChildLimit;
const independentLayout = this.allGraphData[name]
? this.allGraphData[name].independent_layout
: false;
const independentLayout = this.allGraphData[name] ? this.allGraphData[name].independent_layout : false;


if (!independentLayout && nodes.length > nodesCountLimit) { if (!independentLayout && nodes.length > nodesCountLimit) {
this.$message.error(this.$t('graph.tooManyNodes')); this.$message.error(this.$t('graph.tooManyNodes'));
@@ -1307,9 +1312,7 @@ export default {
*/ */
selectNode(needFocus = false, isQueryTensor) { selectNode(needFocus = false, isQueryTensor) {
window.getSelection().removeAllRanges(); window.getSelection().removeAllRanges();
d3.selectAll(
'.node polygon, .node ellipse, .node rect, .node path',
).classed('selected', false);
d3.selectAll('.node polygon, .node ellipse, .node rect, .node path').classed('selected', false);
const path = this.selectedNode.name.split('^'); const path = this.selectedNode.name.split('^');
const node = {}; const node = {};
let id = path[0].replace('_unfold', ''); let id = path[0].replace('_unfold', '');
@@ -1325,9 +1328,7 @@ export default {
this.selectNodePosition(id, needDelay); this.selectNodePosition(id, needDelay);
} }


d3.select(`#graph g[id="${id}"]`)
.select('polygon, rect, ellipse, path')
.classed('selected', true);
d3.select(`#graph g[id="${id}"]`).select('polygon, rect, ellipse, path').classed('selected', true);


this.highlightProxyNodes(id.replace('_unfold', '')); this.highlightProxyNodes(id.replace('_unfold', ''));
this.highLightEdges(node.data); this.highLightEdges(node.data);
@@ -1336,9 +1337,7 @@ export default {
if (this.isIntoView) { if (this.isIntoView) {
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
const dom = document.querySelector(
'.el-tree-node.is-current.is-focusable',
);
const dom = document.querySelector('.el-tree-node.is-current.is-focusable');
if (dom) { if (dom) {
dom.scrollIntoView(); dom.scrollIntoView();
} }
@@ -1348,21 +1347,14 @@ export default {
this.isIntoView = true; this.isIntoView = true;
const type = this.allGraphData[path[0].replace('_unfold', '')].type; const type = this.allGraphData[path[0].replace('_unfold', '')].type;
const ignoreType = ['name_scope', 'aggregation_scope']; const ignoreType = ['name_scope', 'aggregation_scope'];
if (
isQueryTensor &&
!this.selectedNode.name.includes('more...') &&
!ignoreType.includes(type)
) {
if (isQueryTensor && !this.selectedNode.name.includes('more...') && !ignoreType.includes(type)) {
if (this.graph.timer) { if (this.graph.timer) {
clearTimeout(this.graph.timer); clearTimeout(this.graph.timer);
} }
this.graph.timer = setTimeout(() => { this.graph.timer = setTimeout(() => {
const name = path[0].replace('_unfold', ''); const name = path[0].replace('_unfold', '');
if (this.graphFiles.value === this.$t('debugger.all')) { if (this.graphFiles.value === this.$t('debugger.all')) {
this.retrieveTensorHistory(
{name: name.replace(`${name.split('/')[0]}/`, '')},
name.split('/')[0],
);
this.retrieveTensorHistory({name: name.replace(`${name.split('/')[0]}/`, '')}, name.split('/')[0]);
} else { } else {
this.retrieveTensorHistory( this.retrieveTensorHistory(
{ {
@@ -1377,10 +1369,7 @@ export default {
this.tableData = []; this.tableData = [];
} else { } else {
if (this.graphFiles.value === this.$t('debugger.all')) { if (this.graphFiles.value === this.$t('debugger.all')) {
this.nodeName = this.selectedNode.name.replace(
`${this.selectedNode.name.split('/')[0]}/`,
'',
);
this.nodeName = this.selectedNode.name.replace(`${this.selectedNode.name.split('/')[0]}/`, '');
} else { } else {
this.nodeName = this.selectedNode.name; this.nodeName = this.selectedNode.name;
} }
@@ -1388,11 +1377,7 @@ export default {
} }
} }
this.setSelectedNodeData(node.data); this.setSelectedNodeData(node.data);
if (
this.watchPointHits.length &&
this.radio1 === 'hit' &&
this.isHitIntoView
) {
if (this.watchPointHits.length && this.radio1 === 'hit' && this.isHitIntoView) {
this.focusWatchpointHit(); this.focusWatchpointHit();
} }
this.isHitIntoView = true; this.isHitIntoView = true;
@@ -1445,25 +1430,16 @@ export default {
graphObj.initHeight = graphObj.rect.height / this.graph.transform.k; graphObj.initHeight = graphObj.rect.height / this.graph.transform.k;


const screenChange = { const screenChange = {
x:
nodeRect.left +
nodeRect.width / 2 -
(this.svg.rect.left + this.svg.rect.width / 2),
y:
nodeRect.top +
nodeRect.height / 2 -
(this.svg.rect.top + this.svg.rect.height / 2),
x: nodeRect.left + nodeRect.width / 2 - (this.svg.rect.left + this.svg.rect.width / 2),
y: nodeRect.top + nodeRect.height / 2 - (this.svg.rect.top + this.svg.rect.height / 2),
}; };


this.graph.transform.x -=
screenChange.x * (this.svg.originSize.width / graphObj.initWidth);
this.graph.transform.y -=
screenChange.y * (this.svg.originSize.height / graphObj.initHeight);
this.graph.transform.x -= screenChange.x * (this.svg.originSize.width / graphObj.initWidth);
this.graph.transform.y -= screenChange.y * (this.svg.originSize.height / graphObj.initHeight);


this.graph.dom.setAttribute( this.graph.dom.setAttribute(
'transform', 'transform',
`translate(${this.graph.transform.x},` +
`${this.graph.transform.y}) scale(${this.graph.transform.k})`,
`translate(${this.graph.transform.x},` + `${this.graph.transform.y}) scale(${this.graph.transform.k})`,
); );


const transitionTime = Math.min( const transitionTime = Math.min(
@@ -1514,10 +1490,7 @@ export default {
this.selectNode(true, isQueryTensor); this.selectNode(true, isQueryTensor);
} else { } else {
const parentId = name.substring(0, name.lastIndexOf('/')); const parentId = name.substring(0, name.lastIndexOf('/'));
if (
this.allGraphData[parentId] &&
this.allGraphData[parentId].isUnfold
) {
if (this.allGraphData[parentId] && this.allGraphData[parentId].isUnfold) {
const aggregationNode = this.allGraphData[parentId]; const aggregationNode = this.allGraphData[parentId];
if (aggregationNode && aggregationNode.childIdsList) { if (aggregationNode && aggregationNode.childIdsList) {
for (let i = 0; i < aggregationNode.childIdsList.length; i++) { for (let i = 0; i < aggregationNode.childIdsList.length; i++) {
@@ -1552,10 +1525,7 @@ export default {
} else { } else {
// If the namespace is a namespace and the number of subnodes exceeds the upper limit, // If the namespace is a namespace and the number of subnodes exceeds the upper limit,
// an error is reported and the namespace is selected. // an error is reported and the namespace is selected.
if (
this.allGraphData[data.scope_name].type === 'name_scope' &&
data.nodes.length > this.nodesCountLimit
) {
if (this.allGraphData[data.scope_name].type === 'name_scope' && data.nodes.length > this.nodesCountLimit) {
this.selectedNode.name = data.scope_name; this.selectedNode.name = data.scope_name;
this.querySingleNode(data, data.scope_name, true); this.querySingleNode(data, data.scope_name, true);
this.selectNode(true, true); this.selectNode(true, true);
@@ -1564,27 +1534,18 @@ export default {
// Normal expansion // Normal expansion
const nodes = JSON.parse(JSON.stringify(data.nodes)); const nodes = JSON.parse(JSON.stringify(data.nodes));
this.packageDataToObject(data.scope_name, true, nodes); this.packageDataToObject(data.scope_name, true, nodes);
if (
this.allGraphData[data.scope_name].type === 'aggregation_scope'
) {
if (this.allGraphData[data.scope_name].type === 'aggregation_scope') {
this.dealAggregationNodes(data.scope_name); this.dealAggregationNodes(data.scope_name);
const aggregationNode = this.allGraphData[data.scope_name]; const aggregationNode = this.allGraphData[data.scope_name];
if (aggregationNode) { if (aggregationNode) {
for (let i = 0; i < aggregationNode.childIdsList.length; i++) { for (let i = 0; i < aggregationNode.childIdsList.length; i++) {
if (
aggregationNode.childIdsList[i].includes(
this.selectedNode.name,
)
) {
if (aggregationNode.childIdsList[i].includes(this.selectedNode.name)) {
aggregationNode.index = i; aggregationNode.index = i;
break; break;
} }
} }
} }
if (
this.allGraphData[data.scope_name].maxChainNum >
this.maxChainNum
) {
if (this.allGraphData[data.scope_name].maxChainNum > this.maxChainNum) {
this.selectedNode.name = data.scope_name; this.selectedNode.name = data.scope_name;
this.allGraphData[data.scope_name].isUnfold = false; this.allGraphData[data.scope_name].isUnfold = false;
this.deleteNamespace(data.scope_name); this.deleteNamespace(data.scope_name);
@@ -1607,16 +1568,9 @@ export default {
* @param {Object} error Error data * @param {Object} error Error data
*/ */
showErrorMsg(error) { showErrorMsg(error) {
if (
error &&
error.response &&
error.response.data &&
error.response.data.error_code
) {
if (error && error.response && error.response.data && error.response.data.error_code) {
if (this.$t('error')[`${error.response.data.error_code}`]) { if (this.$t('error')[`${error.response.data.error_code}`]) {
this.$message.error(
this.$t('error')[`${error.response.data.error_code}`],
);
this.$message.error(this.$t('error')[`${error.response.data.error_code}`]);
} else { } else {
if (error.response.data.error_code === '5054B101') { if (error.response.data.error_code === '5054B101') {
// The error "The graph does not exist" should not display in front page; // The error "The graph does not exist" should not display in front page;
@@ -1642,13 +1596,7 @@ export default {
}, 500); }, 500);
}, },
}, },
destroyed() {
window.removeEventListener(
'resize',
this.debounce(this.resizeCallback, 200),
false,
);
},
destroyed() {},
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -1685,6 +1633,15 @@ export default {
right: 10px; right: 10px;
top: 10px; top: 10px;
} }
.outdate-tip {
display: inline-block;
margin-left: 7px;
.el-icon-warning {
color: #e6a23c;
font-size: 16px;
cursor: pointer;
}
}
} }
.content { .content {
height: calc(100% - 145px); height: calc(100% - 145px);
@@ -1750,7 +1707,6 @@ export default {
.el-icon-circle-check { .el-icon-circle-check {
color: #00a5a7; color: #00a5a7;
cursor: pointer; cursor: pointer;
display: none;
} }
.disable:before { .disable:before {
cursor: not-allowed; cursor: not-allowed;
@@ -1857,6 +1813,15 @@ export default {
&:hover { &:hover {
background-color: #ebeef5; background-color: #ebeef5;
} }
.hit-tip {
margin-top: 10px;
font-size: 12px;
.el-icon-warning {
font-size: 14px;
color: #e6a23c;
padding-right: 4px;
}
}
} }
} }
} }
@@ -2010,7 +1975,7 @@ export default {
} }
.plain > path, .plain > path,
.plain ellipse { .plain ellipse {
stroke: #e37d29;
stroke: #e6a23c;
fill: #ffd0a6; fill: #ffd0a6;
stroke-dasharray: 1.5, 1.5; stroke-dasharray: 1.5, 1.5;
} }
@@ -2099,6 +2064,9 @@ export default {
vertical-align: middle; vertical-align: middle;
text-align: center; text-align: center;
} }
.value-tip.point {
cursor: pointer;
}
.el-table--border { .el-table--border {
border-right: none; border-right: none;
border-left: none; border-left: none;
@@ -2171,25 +2139,29 @@ export default {
.collection { .collection {
width: 200px; width: 200px;
} }
.condition {
margin-left: 10px;
width: 200px;
}
.param {
margin-left: 10px;
width: 200px;
}
.condition,
.param,
.param-value { .param-value {
margin-left: 10px; margin-left: 10px;
width: 200px; width: 200px;
} }
.inclusive-param {
text-align: right;
.item {
margin-top: 10px;
display: inline-block;
}
.item + .item {
margin-left: 10px;
}
}
} }
.el-dialog__wrapper.pendingTips { .el-dialog__wrapper.pendingTips {
position: absolute; position: absolute;
.dialog-icon { .dialog-icon {
.el-icon-warning { .el-icon-warning {
font-size: 24px; font-size: 24px;
color: #e37d29;
color: #e6a23c;
vertical-align: bottom; vertical-align: bottom;
} }
} }
@@ -2215,124 +2187,6 @@ export default {
height: 100%; height: 100%;
background-color: #fff; background-color: #fff;
z-index: 999; z-index: 999;
display: flex;
flex-direction: column;

.deb-con-title {
height: 56px;
line-height: 56px;
flex-shrink: 0;
position: relative;

.deb-con-title-left {
position: absolute;
left: 32px;
font-weight: bold;
font-size: 16px;
width: 50%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.deb-con-title-middle {
position: absolute;
left: calc(50% + 32px);
width: 300px;
padding: 10px 0;
line-height: 36px;
.grident {
display: inline-block;
width: calc(100% - 70px);
background-image: linear-gradient(
to right,
rgba(227, 125, 41),
#fff,
rgba(0, 165, 167)
);
text-align: center;
color: transparent;
}
}
.deb-con-title-right {
position: absolute;
right: 32px;

.close-btn {
width: 20px;
height: 20px;
vertical-align: -3px;
cursor: pointer;
display: inline-block;
line-height: 20px;
margin-left: 32px;
}
}
}

.deb-con-slide {
height: 40px;
line-height: 40px;
flex-shrink: 0;
position: relative;

.deb-con-slide-left {
position: absolute;
left: 32px;
display: flex;

.deb-slide-title {
margin-right: 20px;
}

.deb-slide-width {
width: 400px;
}
.deb-slide-input {
width: 100px;
margin-left: 10px;
}
}
.deb-con-slide-right {
position: absolute;
right: 32px;

.custom-btn {
border: 1px solid #00a5a7;
border-radius: 2px;
}
.green {
background-color: #00a5a7;
color: white;
}
.white {
background-color: white;
color: #00a5a7;
}
}
}

.deb-con-table {
margin-top: 20px;
flex: 1;
padding: 0 32px;
.deb-compare-wrap {
height: calc(100% - 120px);
}
.deb-compare-detail {
height: 120px;
overflow: auto;
span {
margin-right: 15px;
}
& > div {
margin-top: 10px;
}
label {
display: inline-block;
min-width: 100px;
}
}
}
} }
} }
.deb-indent { .deb-indent {


Loading…
Cancel
Save