From bfd1c841cab3d84df5caa928a7f6f9c92b033589 Mon Sep 17 00:00:00 2001 From: xiayifan Date: Wed, 8 Jul 2020 15:47:15 +0800 Subject: [PATCH] add tensor feature --- mindinsight/ui/package.json | 2 + .../ui/src/components/gridTableSimple.vue | 486 +++++++ mindinsight/ui/src/components/header.vue | 1 + .../ui/src/components/histogramUnit.vue | 838 +++++++++++ mindinsight/ui/src/locales/zh-cn.json | 18 +- mindinsight/ui/src/main.js | 2 + mindinsight/ui/src/router.js | 4 + .../ui/src/services/request-service.js | 12 + mindinsight/ui/src/store.js | 4 + .../ui/src/views/train-manage/histogram.vue | 8 +- .../ui/src/views/train-manage/tensor.vue | 1222 +++++++++++++++++ .../views/train-manage/training-dashboard.vue | 185 ++- 12 files changed, 2755 insertions(+), 27 deletions(-) create mode 100644 mindinsight/ui/src/components/gridTableSimple.vue create mode 100644 mindinsight/ui/src/components/histogramUnit.vue create mode 100644 mindinsight/ui/src/views/train-manage/tensor.vue diff --git a/mindinsight/ui/package.json b/mindinsight/ui/package.json index 8720d03..3015f70 100644 --- a/mindinsight/ui/package.json +++ b/mindinsight/ui/package.json @@ -14,6 +14,8 @@ "d3": "5.9.7", "d3-graphviz": "3.0.4", "element-ui": "2.11.1", + "jquery": "3.5.0", + "slickgrid": "2.4.22", "vue": "2.6.11", "vue-i18n": "8.15.0", "vue-router": "3.1.3", diff --git a/mindinsight/ui/src/components/gridTableSimple.vue b/mindinsight/ui/src/components/gridTableSimple.vue new file mode 100644 index 0000000..eb6accb --- /dev/null +++ b/mindinsight/ui/src/components/gridTableSimple.vue @@ -0,0 +1,486 @@ + + + + + diff --git a/mindinsight/ui/src/components/header.vue b/mindinsight/ui/src/components/header.vue index 3915694..ebb7ad7 100644 --- a/mindinsight/ui/src/components/header.vue +++ b/mindinsight/ui/src/components/header.vue @@ -40,6 +40,7 @@ limitations under the License. v-if="this.$route.path.indexOf('/scalar') > 0 || this.$route.path.indexOf('/image') > 0 || this.$route.path.indexOf('/histogram') > 0 + || this.$route.path.indexOf('/tensor') > 0 || this.$route.path.indexOf('/training-dashboard') > 0 || !this.$route.path.indexOf('/compare-plate')"> diff --git a/mindinsight/ui/src/components/histogramUnit.vue b/mindinsight/ui/src/components/histogramUnit.vue new file mode 100644 index 0000000..6ff1dbf --- /dev/null +++ b/mindinsight/ui/src/components/histogramUnit.vue @@ -0,0 +1,838 @@ + + + + + diff --git a/mindinsight/ui/src/locales/zh-cn.json b/mindinsight/ui/src/locales/zh-cn.json index 4e9e3ce..f525c5d 100644 --- a/mindinsight/ui/src/locales/zh-cn.json +++ b/mindinsight/ui/src/locales/zh-cn.json @@ -21,7 +21,9 @@ }, "symbols": { "leftbracket": "(", - "rightbracket": ")" + "rightbracket": ")", + "point": "·", + "slashes": "/" }, "header": { "refreshData": "刷新数据", @@ -166,6 +168,14 @@ "dataMap": { "titleText": "数据图" }, + "tensors": { + "titleText": "张量", + "dimension": "形状:", + "tensorType": "数据类型:", + "viewTypeTitle": "视图", + "chartViewType": "表格", + "histogramViewType": "直方图" + }, "graph": { "titleText": "计算图", "downloadPic": "下载", @@ -381,7 +391,11 @@ "selectAll": "全选", "tagFilterPlaceHolder": "请输入需要的标签(支持正则表达式)", "open": "展开", - "close": "折叠" + "close": "折叠", + "gridIncorrectDataError": "当前只支持最多二维数组的展示", + "gridAccuracy": "保留小数位", + "inCorrectInput": "无效输入", + "gridTableNoData": "表格无数据" }, "error": { "50540000": "系统错误", diff --git a/mindinsight/ui/src/main.js b/mindinsight/ui/src/main.js index af966c4..19b8205 100644 --- a/mindinsight/ui/src/main.js +++ b/mindinsight/ui/src/main.js @@ -22,7 +22,9 @@ import ElementUI from 'element-ui'; import './assets/css/element.css'; import './assets/css/reset.scss'; import i18n from './i18n'; +import $ from 'jquery'; +window.$ = window.jQuery = $; Vue.use(ElementUI); Vue.prototype.$bus = new Vue(); diff --git a/mindinsight/ui/src/router.js b/mindinsight/ui/src/router.js index 27d8f96..c2f8942 100644 --- a/mindinsight/ui/src/router.js +++ b/mindinsight/ui/src/router.js @@ -54,6 +54,10 @@ export default new Router({ path: '/train-manage/histogram', component: () => import('./views/train-manage/histogram.vue'), }, + { + path: '/train-manage/tensor', + component: () => import('./views/train-manage/tensor.vue'), + }, { path: '/train-manage/graph', component: () => import('./views/train-manage/graph.vue'), diff --git a/mindinsight/ui/src/services/request-service.js b/mindinsight/ui/src/services/request-service.js index 6898f86..64bbac8 100644 --- a/mindinsight/ui/src/services/request-service.js +++ b/mindinsight/ui/src/services/request-service.js @@ -66,6 +66,18 @@ export default { }); }, + // query tensors sample + getTensorsSample(params) { + return axios({ + method: 'get', + url: 'v1/mindinsight/datavisual/tensors', + params: params, + headers: { + ignoreError: true, + }, + }); + }, + // query graph data queryGraphData(params) { return axios({ diff --git a/mindinsight/ui/src/store.js b/mindinsight/ui/src/store.js index 4d990f2..67aa9f2 100644 --- a/mindinsight/ui/src/store.js +++ b/mindinsight/ui/src/store.js @@ -33,6 +33,7 @@ export default new Vuex.Store({ // multiSelevtGroup component count multiSelectedGroupCount: 0, tableId: 0, + componentsCount: 0, }, mutations: { // set cancelTokenArr @@ -76,6 +77,9 @@ export default new Vuex.Store({ increaseTableId(state) { state.tableId++; }, + componentsNum(state) { + state.componentsCount++; + }, }, actions: {}, }); diff --git a/mindinsight/ui/src/views/train-manage/histogram.vue b/mindinsight/ui/src/views/train-manage/histogram.vue index f6ebd0c..5199eb1 100644 --- a/mindinsight/ui/src/views/train-manage/histogram.vue +++ b/mindinsight/ui/src/views/train-manage/histogram.vue @@ -90,7 +90,8 @@ limitations under the License.
-
{{sampleItem.tagName}}
+
{{sampleItem.tagName}}
@@ -1325,16 +1326,17 @@ export default { sampleObject.fullScreen = !sampleObject.fullScreen; if (sampleObject.fullScreen) { if (this.curAxisName === 2) { - sampleObject.charObj.setOption({grid: {right: 140}}); + sampleObject.charOption.grid.right = 140; } sampleObject.charOption.toolbox.feature.myToolFullScreen.iconStyle.borderColor = '#3E98C5'; } else { - sampleObject.charObj.setOption({grid: {right: 40}}); + sampleObject.charOption.grid.right = 40; sampleObject.charOption.toolbox.feature.myToolFullScreen.iconStyle.borderColor = '#6D7278'; } setTimeout(() => { + sampleObject.charObj.setOption(sampleObject.charOption); sampleObject.charObj.resize(); document.getElementById(sampleObject.domId).scrollIntoView(); }, 0); diff --git a/mindinsight/ui/src/views/train-manage/tensor.vue b/mindinsight/ui/src/views/train-manage/tensor.vue new file mode 100644 index 0000000..defdaaf --- /dev/null +++ b/mindinsight/ui/src/views/train-manage/tensor.vue @@ -0,0 +1,1222 @@ + + + + + diff --git a/mindinsight/ui/src/views/train-manage/training-dashboard.vue b/mindinsight/ui/src/views/train-manage/training-dashboard.vue index 624beb8..ec2cca6 100644 --- a/mindinsight/ui/src/views/train-manage/training-dashboard.vue +++ b/mindinsight/ui/src/views/train-manage/training-dashboard.vue @@ -146,12 +146,28 @@ limitations under the License. -
-
-
- -

- {{$t("public.stayTuned")}} +

+
{{$t("tensors.titleText")}}
+
+
+
+ +
+
{{tensorTag}}
+
+
+ +

+ {{$t("public.noData")}}

@@ -168,6 +184,7 @@ import {select, selectAll, format, precisionRound} from 'd3'; import 'd3-graphviz'; const d3 = {select, selectAll, format, precisionRound}; import echarts from 'echarts'; +import gridTableComponents from '../../components/gridTableSimple'; export default { data() { return { @@ -201,6 +218,8 @@ export default { reloadStopTime: 1000, wrongPlugin: false, fileTag: '', + tensorData: [], + tensorTag: '', }; }, computed: { @@ -218,6 +237,9 @@ export default { return this.$store.state.timeReloadValue; }, }, + components: { + gridTableComponents, + }, watch: { isReload(newVal) { if (newVal) { @@ -282,6 +304,10 @@ export default { if (this.histogramObj) { this.histogramObj.resize(); } + const elementItem = this.$refs.tensorChart; + if (elementItem) { + elementItem.resizeView(); + } }, 500); }, @@ -330,6 +356,7 @@ export default { const imageTags = data.image || []; const scalarTags = data.scalar || []; const graphIds = data.graph || []; + const tensorTags = data.tensor || []; if (graphIds.length) { this.fileTag = graphIds[0]; } @@ -337,6 +364,7 @@ export default { this.getHistogramTag(histogramTags); this.dealImageData(imageTags); this.getScalarList(scalarTags); + this.dealTensorData(tensorTags); if (!this.firstFloorNodes.length && graphIds.length) { this.queryGraphData(); } @@ -383,6 +411,20 @@ export default { }, }); }, + /** + * Viewing more tensors information + */ + viewMoreTensors() { + if (!this.tensorTag) { + return; + } + this.$router.push({ + path: '/train-manage/tensor', + query: { + train_id: this.trainingJobId, + }, + }); + }, /** * Go to data. */ @@ -785,6 +827,117 @@ export default { this.originImageDataArr = dataList; this.getSampleRandomly(); }, + dealTensorData(tags) { + if (tags.length) { + this.tensorTag = tags[0]; + } else { + this.tensorTag = ''; + } + if (this.tensorTag) { + this.getTensorGridData(); + } + }, + getTensorGridData() { + const params = { + train_id: this.trainingJobId, + tag: this.tensorTag, + detail: 'stats', + }; + RequestService.getTensorsSample(params).then( + (res) => { + if (!res || !res.data) { + return; + } + if (!res.data.tensors.length) { + return; + } + const resData = JSON.parse(JSON.stringify(res.data.tensors[0])); + if (!resData.values.length) { + this.tensorData = []; + this.$nextTick(() => { + const elementItem = this.$refs.tensorChart; + if (elementItem) { + elementItem.updateGridData(); + } + }); + return; + } + const data = resData.values[resData.values.length - 1]; + const filterStr = this.initFilterStr(data.value.dims); + this.freshtMartixData(data.step, filterStr); + }, + () => { + this.tensorData = []; + this.$nextTick(() => { + const elementItem = this.$refs.tensorChart; + if (elementItem) { + elementItem.updateGridData(); + } + }); + }, + ); + }, + initFilterStr(array) { + if (!array) { + return []; + } + const countLinit = array.length - 2; + const tempArr = []; + for (let i = 0; i < array.length; i++) { + tempArr.push(i >= countLinit ? ':' : '0'); + } + return `[${tempArr.toString()}]`; + }, + freshtMartixData(step, filterStr) { + const params = { + train_id: this.trainingJobId, + tag: this.tensorTag, + detail: 'data', + step: step, + dims: filterStr, + }; + RequestService.getTensorsSample(params).then( + (res) => { + if (!res || !res.data) { + return; + } + if (!res.data.tensors.length) { + return; + } + const resData = res.data.tensors[0]; + const curStepData = resData.values[0]; + let statistics = {}; + if (curStepData) { + this.tensorData = + curStepData.value.data instanceof Array + ? curStepData.value.data + : [curStepData.value.data]; + statistics = curStepData.value.statistics; + } else { + this.tensorData = [[]]; + } + this.$nextTick(() => { + const elementItem = this.$refs.tensorChart; + if (elementItem) { + elementItem.updateGridData( + true, + curStepData.value.dims, + statistics, + ); + } + }); + }, + () => { + this.tensorData = []; + this.$nextTick(() => { + const elementItem = this.$refs.tensorChart; + if (elementItem) { + elementItem.updateGridData(); + } + }); + }, + ); + }, getHistogramTag(tagList) { if (!tagList) { return; @@ -1889,20 +2042,6 @@ export default { } } - .coming-soon-content { - width: 100%; - height: 100%; - text-align: center; - .coming-soon-container { - position: relative; - top: calc(50% - 88px); - .coming-soon-text { - color: #000000; - font-size: 16px; - } - } - } - .no-data-hover { cursor: not-allowed; } @@ -1928,13 +2067,15 @@ export default { cursor: pointer; } } - #distribution-chart { + #distribution-chart, + #tensor-chart-container { height: calc(100% - 19px); canvas { cursor: pointer; } } - .histogram-char-container { + .histogram-char-container, + .tensor-char-container { height: 100%; width: 100%; cursor: pointer; -- GitLab