From 603c1896ca38aa7cdbdad805a894a8f188695789 Mon Sep 17 00:00:00 2001 From: Sohee Kwon <122425990+hohee-hee@users.noreply.github.com> Date: Wed, 4 Oct 2023 10:44:12 +0900 Subject: [PATCH 1/3] [EdgeTPU] Create new panel for EdgeTPU config file (#1692) This commit creates EdgeTPUCfgEditorPanel.ts that is a panel for .edgetpucfg. - Create EdgetpuCfgEditorPanel.ts : Cfg Editor Panel for edgetpu cfg editor - Add register in extension.ts - Map a new view type with a new file extension - .edgetpucfg - Error fix : Duplication of setDefaultValues causes error so changed the command name to "setDefaultEdgetpuValues". - Add objects about setDefaultEdgetpuValues in Commands and Keybindings in package.json ONE-vscode-DCO-1.0-Signed-off-by: hohee-hee Co-authored-by: Bumsoo Ko Co-authored-by: Hyeon-Uk --- package.json | 20 ++ src/CfgEditor/EdgeTPUCfgEditorPanel.ts | 294 +++++++++++++++++++++++++ src/extension.ts | 3 + 3 files changed, 317 insertions(+) create mode 100644 src/CfgEditor/EdgeTPUCfgEditorPanel.ts diff --git a/package.json b/package.json index fca3025a2..51a433d4d 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,16 @@ ], "priority": "option" }, + { + "viewType": "one.editor.edgetpucfg", + "displayName": "Edge TPU Configuration Editor", + "selector": [ + { + "filenamePattern": "*.edgetpucfg" + } + ], + "priority": "option" + }, { "viewType": "one.viewer.mondrian", "displayName": "Mondrian", @@ -287,6 +297,11 @@ "title": "ONE: Set Default Values", "category": "ONE" }, + { + "command": "one.editor.edgetpucfg.setDefaultValues", + "title": "ONE: Set Default EdgeTPU Compiler Values", + "category": "ONE" + }, { "command": "one.editor.mpq.createFromDefaultExplorer", "title": "ONE: Create Mixed Precision Quantization Configuration", @@ -309,6 +324,11 @@ "key": "ctrl+shift+/", "when": "activeCustomEditorId == one.editor.cfg" }, + { + "command": "one.cfgEditor.setDefaultEdgetpuValues", + "key": "ctrl+shift+/", + "when": "activeCustomEditorId == one.editor.edgetpucfg" + }, { "command": "one.explorer.deleteOnShortcut", "key": "delete", diff --git a/src/CfgEditor/EdgeTPUCfgEditorPanel.ts b/src/CfgEditor/EdgeTPUCfgEditorPanel.ts new file mode 100644 index 000000000..b96e9b2bb --- /dev/null +++ b/src/CfgEditor/EdgeTPUCfgEditorPanel.ts @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Copyright (c) Microsoft Corporation + * + * All rights reserved. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* +Some part of this code refers to +https://github.com/microsoft/vscode-extension-samples/blob/2556c82cb333cf65d372bd01ac30c35ea1898a0e/custom-editor-sample/src/catScratchEditor.ts +*/ + +import * as path from "path"; +import * as vscode from "vscode"; + +import { getNonce } from "../Utils/external/Nonce"; +import { getUri } from "../Utils/external/Uri"; + +import { EdgeTPUCfgData } from "./EdgeTPUCfgData"; + +/* istanbul ignore next */ +export class EdgeTPUCfgEditorPanel implements vscode.CustomTextEditorProvider { + private _disposables: vscode.Disposable[] = []; + private _oneConfigMap: any = {}; + private _activeDocument: vscode.TextDocument | undefined; + private _activeWebviewPanel: vscode.WebviewPanel | undefined; + + public static readonly viewType = "one.editor.edgetpucfg"; + + public static register(context: vscode.ExtensionContext): void { + const provider = new EdgeTPUCfgEditorPanel(context); + + const registrations = [ + vscode.window.registerCustomEditorProvider( + EdgeTPUCfgEditorPanel.viewType, + provider, + { + webviewOptions: { + retainContextWhenHidden: true, + }, + } + ), + // Add command registration here + vscode.commands.registerCommand( + "one.cfgEditor.setDefaultEdgetpuValues", + () => { + if (!provider._activeWebviewPanel || !provider._activeDocument) { + return; + } + + const cfgName = path.parse(provider._activeDocument!.fileName).name; + + provider._activeWebviewPanel!.webview.postMessage({ + type: "setDefaultEdgetpuValues", + name: cfgName, + }); + } + ), + ]; + + registrations.forEach((disposable) => + context.subscriptions.push(disposable) + ); + } + + constructor(private readonly context: vscode.ExtensionContext) {} + + async resolveCustomTextEditor( + document: vscode.TextDocument, + webviewPanel: vscode.WebviewPanel, + _token: vscode.CancellationToken + ): Promise { + this._activeWebviewPanel = webviewPanel; + this._activeDocument = document; + this._oneConfigMap[document.uri.toString()] = new EdgeTPUCfgData(); + await this.initWebview(document, webviewPanel.webview); + this.initWebviewPanel(document, webviewPanel); + this.updateWebview(document, webviewPanel.webview); + } + + async initWebview( + document: vscode.TextDocument, + webview: vscode.Webview + ): Promise { + webview.options = { + enableScripts: true, + }; + + const nonce = getNonce(); + const toolkitUri = getUri(webview, this.context.extensionUri, [ + "node_modules", + "@vscode", + "webview-ui-toolkit", + "dist", + "toolkit.js", + ]); + + const codiconUri = getUri(webview, this.context.extensionUri, [ + "node_modules", + "@vscode", + "codicons", + "dist", + "codicon.css", + ]); + + const jsUri = getUri(webview, this.context.extensionUri, [ + "media", + "EdgeTPUCfgEditor", + "index.js", + ]); + + const cssUri = getUri(webview, this.context.extensionUri, [ + "media", + "EdgeTPUCfgEditor", + "cfgeditor.css", + ]); + + const htmlUri = vscode.Uri.joinPath( + this.context.extensionUri, + "media/EdgeTPUCfgEditor/cfgeditor.html" + ); + + let html = Buffer.from( + await vscode.workspace.fs.readFile(htmlUri) + ).toString(); + html = html.replace(/\${nonce}/g, `${nonce}`); + html = html.replace(/\${webview.cspSource}/g, `${webview.cspSource}`); + html = html.replace(/\${toolkitUri}/g, `${toolkitUri}`); + html = html.replace(/\${codiconUri}/g, `${codiconUri}`); + html = html.replace(/\${jsUri}/g, `${jsUri}`); + html = html.replace(/\${cssUri}/g, `${cssUri}`); + webview.html = html; + + // Receive message from the webview. + webview.onDidReceiveMessage((e) => { + switch (e.type) { + case "requestDisplayCfg": + this.updateWebview(document, webview); + break; + case "setParam": + this._oneConfigMap[document.uri.toString()].updateSectionWithKeyValue( + e.section, + e.param, + e.value + ); + break; + case "setSection": + this._oneConfigMap[document.uri.toString()].updateSectionWithValue( + e.section, + e.param + ); + break; + case "updateDocument": + if ( + this._oneConfigMap[document.uri.toString()].isSame( + document.getText() + ) === false + ) { + this._oneConfigMap[document.uri.toString()].sort(); + + // TODO Optimize this to modify only changed lines + const edit = new vscode.WorkspaceEdit(); + edit.replace( + document.uri, + new vscode.Range(0, 0, document.lineCount, 0), + this._oneConfigMap[document.uri.toString()].getAsString() + ); + vscode.workspace.applyEdit(edit); + } + break; + case "getPathByDialog": { + const dialogOptions = { + canSelectMany: false, + canSelectFolders: e.isFolder, + openLabel: "Open", + filters: { "target files": e.ext, "all files": ["*"] }, + }; + let newPath = e.oldPath; + vscode.window.showOpenDialog(dialogOptions).then((fileUri) => { + if (fileUri && fileUri[0]) { + newPath = fileUri[0].fsPath.toString(); + webview.postMessage({ + type: "applyDialogPath", + step: e.postStep, + elemID: e.postElemID, + path: newPath, + }); + } + }); + break; + } + default: + break; + } + }); + } + + initWebviewPanel( + document: vscode.TextDocument, + webviewPanel: vscode.WebviewPanel + ): void { + vscode.commands.executeCommand( + "setContext", + EdgeTPUCfgEditorPanel.viewType, + true + ); + + const changeDocumentSubscription = vscode.workspace.onDidChangeTextDocument( + (e) => { + if ( + e.contentChanges.length > 0 && + e.document.uri.toString() === document.uri.toString() + ) { + this.updateWebview(document, webviewPanel.webview); + } + } + ); + + webviewPanel.onDidChangeViewState( + () => { + if (webviewPanel.visible) { + this._activeWebviewPanel = webviewPanel; + this._activeDocument = document; + vscode.commands.executeCommand( + "one.explorer.revealInOneExplorer", + document.fileName + ); + } + vscode.commands.executeCommand( + "setContext", + EdgeTPUCfgEditorPanel.viewType, + webviewPanel.visible + ); + }, + null, + this._disposables + ); + + webviewPanel.onDidDispose(() => { + changeDocumentSubscription.dispose(); + while (this._disposables.length) { + const x = this._disposables.pop(); + if (x) { + x.dispose(); + } + } + vscode.commands.executeCommand( + "setContext", + EdgeTPUCfgEditorPanel.viewType, + false + ); + }); + } + + updateWebview(document: vscode.TextDocument, webview: vscode.Webview): void { + this._oneConfigMap[document.uri.toString()].setWithString( + document.getText() + ); + webview.postMessage({ + type: "displayCfgToEditor", + text: this._oneConfigMap[document.uri.toString()].getAsConfig(), + }); + } +} diff --git a/src/extension.ts b/src/extension.ts index 28220ecda..80e8a6e9b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,6 +19,7 @@ import * as vscode from "vscode"; import { API } from "./Backend/API"; import { OneToolchain } from "./Backend/One/OneToolchain"; import { CfgEditorPanel } from "./CfgEditor/CfgEditorPanel"; +import { EdgeTPUCfgEditorPanel } from "./CfgEditor/EdgeTPUCfgEditorPanel"; import { CircleEditorProvider } from "./CircleEditor/CircleEditorProvider"; import { CircleViewerProvider } from "./CircleGraph/CircleViewer"; import { DeviceViewProvider } from "./Execute/DeviceViewProvider"; @@ -65,6 +66,8 @@ export function activate(context: vscode.ExtensionContext) { CfgEditorPanel.register(context); + EdgeTPUCfgEditorPanel.register(context); + JsonTracerViewerPanel.register(context); MondrianEditorProvider.register(context); From 0e3e4c705b4a647149e823e0379de8a870a32ac5 Mon Sep 17 00:00:00 2001 From: Sohee Kwon <122425990+hohee-hee@users.noreply.github.com> Date: Tue, 3 Oct 2023 16:39:40 +0900 Subject: [PATCH 2/3] [EdgeTPU] Add files for EdgeTPUCfgEditor (#1671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For modularization of EdgeTPU, we decided to add a new file name extension for config file for edgetpu compiler. Its name is 'edgetpucfg'. 'edgetpucfg' has different steps and options than the original cfg file. Therefore, this commit adds a new directory and files for .edgetpucfg in /media/EdgetpuCfgEditor. ONE-vscode-DCO-1.0-Signed-off-by: hohee-hee Co-authored-by: Bumsoo Ko Co-authored-by: 김현욱 --- media/EdgeTPUCfgEditor/cfgeditor.css | 191 ++++++++++++++++++++++++ media/EdgeTPUCfgEditor/cfgeditor.html | 132 ++++++++++++++++ media/EdgeTPUCfgEditor/displaycfg.js | 65 ++++++++ media/EdgeTPUCfgEditor/index.js | 176 ++++++++++++++++++++++ media/EdgeTPUCfgEditor/updateContent.js | 128 ++++++++++++++++ media/EdgeTPUCfgEditor/updateUI.js | 79 ++++++++++ media/EdgeTPUCfgEditor/vscodeapi.js | 21 +++ 7 files changed, 792 insertions(+) create mode 100644 media/EdgeTPUCfgEditor/cfgeditor.css create mode 100644 media/EdgeTPUCfgEditor/cfgeditor.html create mode 100644 media/EdgeTPUCfgEditor/displaycfg.js create mode 100644 media/EdgeTPUCfgEditor/index.js create mode 100644 media/EdgeTPUCfgEditor/updateContent.js create mode 100644 media/EdgeTPUCfgEditor/updateUI.js create mode 100644 media/EdgeTPUCfgEditor/vscodeapi.js diff --git a/media/EdgeTPUCfgEditor/cfgeditor.css b/media/EdgeTPUCfgEditor/cfgeditor.css new file mode 100644 index 000000000..c08479892 --- /dev/null +++ b/media/EdgeTPUCfgEditor/cfgeditor.css @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +label { + white-space: pre-wrap; +} + +.maintitle { + width: 100%; + display: flex; +} + +.maintitle span { + float: left; + display: block; + padding-left: 5px; +} + +.statusbar { + width: 100%; + display: flex; + margin-top: 10px; + margin-bottom: 20px; +} + +.statusbar .detail { + box-sizing: border-box; + float: left; + background: #007acc; + color: #fff; + position: relative; + padding-left: 10px; + padding-right: 10px; + width: 70px; + height: 32px; + line-height: 32px; + text-align: center; + display: block; +} + +.statusbar .detail:after { + box-sizing: border-box; + content: ''; + border-left: 16px solid #007acc; + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + position: absolute; + top: 0; + left: 100%; + z-index: 1; +} + +.statusbar .detail .expanded { + display: inline-block; +} + +.statusbar .steps { + display: inline-flex; +} + +.statusbar .steps .step { + box-sizing: border-box; + float: left; + background: #007acc; + color: #fff; + position: relative; + padding-left: 10px; + width: 110px; + height: 32px; + line-height: 32px; + display: flex; + justify-content: center; +} + +.statusbar .steps .step span { + padding-left: 5px; +} + +.statusbar .steps .step:before { + box-sizing: border-box; + content: ''; + border-left: 16px solid #fff; + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + position: absolute; + top: 0; + left: 0; +} + +.statusbar .steps .step:after { + box-sizing: border-box; + content: ''; + border-left: 16px solid #007acc; + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + position: absolute; + top: 0; + left: 100%; + z-index: 1; +} + +.statusbar .steps .step.current { + box-sizing: border-box; + float: left; + background: #4298da; + color: #fff; + position: relative; + padding-left: 10px; + width: 110px; + height: 32px; + line-height: 32px; + display: flex; + justify-content: center; +} + +.statusbar .steps .step.current:after { + box-sizing: border-box; + content: ''; + border-left: 16px solid #4298da; + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + position: absolute; + top: 0; + left: 100%; + z-index: 1; +} + +.statusbar .steps .step .title { + cursor: pointer; +} + +.optionPanel { + display: flex; +} + +.optionPanel .options { + display: none; +} + +#optionImport .basic, +#optionImport .advanced, +#optionQuantize .basic, +#optionQuantize .advanced { + display: none; +} + +.optionPanel .options .prerequisite .title, +.optionPanel .options .basic .title, +.optionPanel .options .advanced .title { + font-weight: bold; + font-size: 15px; + margin-bottom: 15px; + margin-top: 15px; +} + +.optionPanel .options .prerequisite .option, +.optionPanel .options .basic .option, +.optionPanel .options .advanced .option { + margin-bottom: 5px; +} + +.codicon.codicon-question .help { + visibility: hidden; + width: auto; + background-color: var(--vscode-editorSuggestWidget-background); + color: var(--vscode-editorSuggestWidget-foreground); + border: 2px solid var(--vscode-editorSuggestWidget-border); + font-size: small; + text-align: left; + position: absolute; + z-index: 1; + margin-left: 10px; + padding: 6px 6px 10px 8px; +} + +.codicon.codicon-question:hover .help { + visibility: visible; +} diff --git a/media/EdgeTPUCfgEditor/cfgeditor.html b/media/EdgeTPUCfgEditor/cfgeditor.html new file mode 100644 index 000000000..90be97e73 --- /dev/null +++ b/media/EdgeTPUCfgEditor/cfgeditor.html @@ -0,0 +1,132 @@ + + + + + + + + + + + + cfg editor + + +
+ + Click checkbox to enable each step. +
+
+
+
+
+ Steps +
+
+
+
+ + Compile +
+
+ + Profile +
+
+
+
+
+ +
+
+
+ +
+
+
+
+ Basic Options +
+
+ + Input Path + + +
+
+ + Output Path + + +
+
+
+
+ Advanced Options +
+
+ + Intermediate_tensors + + + + This option cannot be with 'search delegate' + + +
+
+ + Show Operations + + + + Print the log showing operations that mapped to the Edge TPU. + + +
+
+ + Search Delegate + + + + Enable repeated search for a new compilation stopping point earlier in the graph, to avoid rare compiler failures when it encounters an unsupported operation. + + +
+
+ + Delegate Search Step + + + + Specify a step size (the number of ops to move backward)
+ Default size is 1 and the mindest size is also 1. +
+
+
+
+
+
+
+
+ + diff --git a/media/EdgeTPUCfgEditor/displaycfg.js b/media/EdgeTPUCfgEditor/displaycfg.js new file mode 100644 index 000000000..6df6a9505 --- /dev/null +++ b/media/EdgeTPUCfgEditor/displaycfg.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function displayCfgToEditor(cfg) { + const edgeTPUCompiler = cfg["edgetpu-compiler"]; + document.getElementById("checkboxEdgeTPUCompile").checked = cfgBoolean( + edgeTPUCompiler["edgetpu-compile"] + ); + document.getElementById("checkboxEdgeTPUProfile").checked = cfgBoolean( + edgeTPUCompiler["edgetpu-profile"] + ); + + + const edgeTPUCompile = cfg["edgetpu-compile"]; + document.getElementById("EdgeTPUInputPath").value = cfgString( + edgeTPUCompile?.["input_path"] + ); + document.getElementById("EdgeTPUOutputPath").value = cfgString( + edgeTPUCompile?.["output_path"] + ); + document.getElementById("EdgeTPUIntermediateTensorsInputArrays").value = + cfgString(edgeTPUCompile?.["intermediate_tensors"]); + document.getElementById("EdgeTPUShowOperations").checked = cfgBoolean( + edgeTPUCompile?.["show_operations"] + ); + document.getElementById("EdgeTPUSearchDelegate").checked = cfgBoolean( + edgeTPUCompile?.["search_delegate"] + ); + document.getElementById("EdgeTPUDelegateSearchStep").value = cfgString( + edgeTPUCompile?.["delegate_search_step"], + "1" + ); +} + +function cfgString(str, defaultStr = "") { + if (str === null || str === undefined) { + return defaultStr; + } + return str.trim(); +} + +function cfgBoolean(str) { + if (str === null || str === undefined) { + return false; + } + + if (str === "True") { + return true; + } + + return false; +} \ No newline at end of file diff --git a/media/EdgeTPUCfgEditor/index.js b/media/EdgeTPUCfgEditor/index.js new file mode 100644 index 000000000..9ec177216 --- /dev/null +++ b/media/EdgeTPUCfgEditor/index.js @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { displayCfgToEditor } from "./displaycfg.js"; +import { + applyUpdates, + updateEdgeTPUStep, + updateEdgeTPUCompile +} from "./updateContent.js"; +import { + updateStepUI, +} from "./updateUI.js"; +import { postMessageToVsCode } from "./vscodeapi.js"; + +// Just like a regular webpage we need to wait for the webview +// DOM to load before we can reference any of the HTML elements +// or toolkit components +window.addEventListener("load", main); + +// Main function that gets executed once the webview DOM loads +function main() { + registerCompilerStep(); + registerCompileOptions(); + registerCodiconEvents(); + + // event from vscode extension + window.addEventListener("message", (event) => { + const message = event.data; + switch (message.type) { + case "displayCfgToEditor": + displayCfgToEditor(message.text); + break; + case "setDefaultEdgetpuValues": + setDefaultEdgetpuValues(message.name); + break; + case "applyDialogPath": + document.getElementById(message.elemID).value = message.path; + switch (message.step) { + case "EdgeTPUCompile": + updateEdgeTPUCompile(); + break; + default: + break; + } + applyUpdates(); + break; + default: + break; + } + }); + + postMessageToVsCode({ type: "requestDisplayCfg" }); +} + +function setDefaultEdgetpuValues(name) { + // EdgeTPu COmpiler steps + document.getElementById("checkboxEdgeTPUCompile").checked = true; + + updateEdgeTPUStep(); + + // compile step + let compiledName = name + ".tflite"; + let compiledExt = name + "_edgetpu.tflite"; + document.getElementById("EdgeTPUInputPath").value = compiledName; + document.getElementById("EdgeTPUOutputPath").value = compiledExt; + + updateEdgeTPUCompile(); + + // apply + applyUpdates(); +} + +function registerCompilerStep() { + const checkboxEdgeTPUCompile = document.getElementById("checkboxEdgeTPUCompile"); + const checkboxEdgeTPUProfile = document.getElementById("checkboxEdgeTPUProfile"); + const stepEdgeTPUCompile = document.getElementById("stepEdgeTPUCompile"); + const stepEdgeTPUProfile = document.getElementById("stepEdgeTPUProfile"); + + checkboxEdgeTPUCompile.addEventListener("click", function () { + updateEdgeTPUStep(); + applyUpdates(); + }); + checkboxEdgeTPUProfile.addEventListener("click", function () { + updateEdgeTPUStep(); + applyUpdates(); + }); + + stepEdgeTPUCompile.addEventListener("click", function () { + updateStepUI("EdgeTPUCompile"); + }); + stepEdgeTPUProfile.addEventListener("click", function () { + updateStepUI("EdgeTPUProfile"); + }); +} + +function registerCompileOptions() { + const edgeTPUInputPath = document.getElementById("EdgeTPUInputPath"); + const edgeTPUIntermediateTensors = document.getElementById( + "EdgeTPUIntermediateTensorsInputArrays" + ); + const edgeTPUShowOperations = document.getElementById( + "EdgeTPUShowOperations" + ); + const edgeTPUSearchDelegate = document.getElementById( + "EdgeTPUSearchDelegate" + ); + const edgeTPUDelegateSearchStep = document.getElementById( + "EdgeTPUDelegateSearchStep" + ); + const edgeTPUDelegateSearchStepDiv = document.getElementById( + "EdgeTPUDelegateSearchStepDiv" + ); + + edgeTPUInputPath.addEventListener("input", function () { + updateEdgeTPUCompile(); + applyUpdates(); + }); + edgeTPUIntermediateTensors.addEventListener("input", function () { + if (edgeTPUSearchDelegate.checked) { + edgeTPUSearchDelegate.checked = false; + edgeTPUDelegateSearchStepDiv.style.display = "none"; + } + updateEdgeTPUCompile(); + applyUpdates(); + }); + edgeTPUShowOperations.addEventListener("click", function () { + updateEdgeTPUCompile(); + applyUpdates(); + }); + edgeTPUSearchDelegate.addEventListener("click", function () { + if (edgeTPUSearchDelegate.checked) { + edgeTPUIntermediateTensors.value = ""; + edgeTPUDelegateSearchStepDiv.style.display = "block"; + } else { + edgeTPUDelegateSearchStepDiv.style.display = "none"; + } + updateEdgeTPUCompile(); + applyUpdates(); + }); + edgeTPUDelegateSearchStep.addEventListener("input", function () { + edgeTPUDelegateSearchStep.value = + edgeTPUDelegateSearchStep.value < 1 + ? "1" + : edgeTPUDelegateSearchStep.value; + updateEdgeTPUCompile(); + applyUpdates(); + }); +} + +function registerCodiconEvents() { + document + .getElementById("EdgeTPUInputPathSearch") + .addEventListener("click", function () { + postMessageToVsCode({ + type: "getPathByDialog", + isFolder: false, + ext: ["tflite"], + oldPath: document.getElementById("EdgeTPUInputPath").value, + postStep: "EdgeTPUCompile", + postElemID: "EdgeTPUInputPath", + }); + }); +} diff --git a/media/EdgeTPUCfgEditor/updateContent.js b/media/EdgeTPUCfgEditor/updateContent.js new file mode 100644 index 000000000..6406a03ba --- /dev/null +++ b/media/EdgeTPUCfgEditor/updateContent.js @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { postMessageToVsCode } from "./vscodeapi.js"; + +function iniKeyValueString(iniKey, iniValue, noEffectValue = undefined) { + if (iniValue === null || iniValue === undefined) { + return ""; + } + + if (iniValue === false) { + return ""; + } else if (iniValue === true) { + return iniKey + "=True\n"; + } + + const trimmedValue = iniValue.trim(); + if (trimmedValue === "" || trimmedValue === noEffectValue) { + return ""; + } + + return iniKey + "=" + trimmedValue + "\n"; +} + +export function applyUpdates() { + postMessageToVsCode({ type: "updateDocument" }); +} + +export function updateEdgeTPUStep(){ + postMessageToVsCode({ + type: "setParam", + section: "edgetpu-compiler", + param: "edgetpu-compile", + value: document.getElementById("checkboxEdgeTPUCompile").checked + ? "True" + : "False", + }); + postMessageToVsCode({ + type: "setParam", + section: "edgetpu-compiler", + param: "edgetpu-profile", + value: document.getElementById("checkboxEdgeTPUProfile").checked + ? "True" + : "False", + }); +} + +function addPostfixToFileName(filePath = "", postfix = "") { + if (filePath.trim() === "") { + return ""; + } + const parts = filePath.split("."); + let newFilePath = ""; + if (parts.length < 2) { + newFilePath = `${filePath}${postfix}`; + } else { + const fileName = parts.slice(0, -1).join("."); + const fileExtension = parts[parts.length - 1]; + const newFileName = `${fileName}${postfix}`; + newFilePath = `${newFileName}.${fileExtension}`; + } + + return newFilePath; +} + +export function updateEdgeTPUCompile() { + let content = ""; + content += iniKeyValueString( + "input_path", + document.getElementById("EdgeTPUInputPath").value + ); + content += iniKeyValueString( + "output_path", + addPostfixToFileName( + document.getElementById("EdgeTPUInputPath").value, + "_edgetpu" + ) + ); + content += iniKeyValueString( + "intermediate_tensors", + document.getElementById("EdgeTPUIntermediateTensorsInputArrays").value + ); + content += iniKeyValueString( + "show_operations", + document.getElementById("EdgeTPUShowOperations").checked + ); + content += iniKeyValueString( + "search_delegate", + document.getElementById("EdgeTPUSearchDelegate").checked + ); + content += iniKeyValueString( + "delegate_search_step", + document.getElementById("EdgeTPUSearchDelegate").checked + ? document.getElementById("EdgeTPUDelegateSearchStep").value < 1 + ? "1" + : document.getElementById("EdgeTPUDelegateSearchStep").value + : undefined + ); + + postMessageToVsCode({ + type: "setSection", + section: "edgetpu-compile", + param: content, + }); +} + +export function updateEdgeTPUProfile() { + let content = ""; + + postMessageToVsCode({ + type: "setSection", + section: "edgetpu-profile", + param: content, + }); +} diff --git a/media/EdgeTPUCfgEditor/updateUI.js b/media/EdgeTPUCfgEditor/updateUI.js new file mode 100644 index 000000000..2f3f7e0a7 --- /dev/null +++ b/media/EdgeTPUCfgEditor/updateUI.js @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function updateStepUI(step) { + const allOptionPanels = document.querySelectorAll(".optionPanel .options"); + allOptionPanels.forEach(function (panel) { + panel.style.display = "none"; + }); + + const optionPanel = document.getElementById("option" + step); + optionPanel.style.display = "block"; + + const edgeTPUSearchDelegate = document.getElementById( + "EdgeTPUSearchDelegate" + ); + const edgeTPUDelegateSearchStepDiv = document.getElementById( + "EdgeTPUDelegateSearchStepDiv" + ); + const edgeTPUIntermediateTensors = document.getElementById( + "EdgeTPUIntermediateTensors" + ); + + if (edgeTPUSearchDelegate.checked) { + edgeTPUIntermediateTensors.value = ""; + edgeTPUDelegateSearchStepDiv.style.display = "block"; + } else { + edgeTPUDelegateSearchStepDiv.style.display = "none"; + } + + const allSteps = document.querySelectorAll(".statusbar .steps .step"); + allSteps.forEach(function (step) { + step.classList.remove("current"); + }); + + const stepbar = document.getElementById("stepbar" + step); + stepbar.classList.add("current"); +} + +export function updateEdgeTPUCompileUI() { + const allOptionPanels = document.querySelectorAll(".optionPanel .options"); + allOptionPanels.forEach(function (panel) { + panel.style.display = "none"; + }); + + const edgeTPUBasicOptions = document.getElementById( + "optionImportEdgeTPUBasic" + ); + const edgeTPUAdvancedOptions = document.getElementById( + "optionImportEdgeTPUAdvanced" + ); + const edgeTPUSearchDelegate = document.getElementById( + "EdgeTPUSearchDelegate" + ); + const edgeTPUDelegateSearchStepDiv = document.getElementById( + "EdgeTPUDelegateSearchStepDiv" + ); + + edgeTPUBasicOptions.style.display = "none"; + edgeTPUAdvancedOptions.style.display = "none"; + + edgeTPUDelegateSearchStepDiv.style.display = edgeTPUSearchDelegate.checked + ? "block" + : "none"; + edgeTPUBasicOptions.style.display = "block"; + edgeTPUAdvancedOptions.style.display = "block"; +} diff --git a/media/EdgeTPUCfgEditor/vscodeapi.js b/media/EdgeTPUCfgEditor/vscodeapi.js new file mode 100644 index 000000000..6cdfaf356 --- /dev/null +++ b/media/EdgeTPUCfgEditor/vscodeapi.js @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const vscode = acquireVsCodeApi(); + +export function postMessageToVsCode(msg) { + vscode.postMessage(msg); +} From 1ba53af83c6f9b59f0408786b61f48671805e554 Mon Sep 17 00:00:00 2001 From: Dayoung Lee Date: Wed, 1 Nov 2023 21:11:20 +0900 Subject: [PATCH 3/3] Format files ONE-vscode-DCO-1.0-Signed-off-by: Dayoung Lee --- media/EdgeTPUCfgEditor/displaycfg.js | 3 +-- media/EdgeTPUCfgEditor/index.js | 24 +++++++++++++----------- media/EdgeTPUCfgEditor/updateContent.js | 14 +++++++------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/media/EdgeTPUCfgEditor/displaycfg.js b/media/EdgeTPUCfgEditor/displaycfg.js index 6df6a9505..f0a0cf60c 100644 --- a/media/EdgeTPUCfgEditor/displaycfg.js +++ b/media/EdgeTPUCfgEditor/displaycfg.js @@ -23,7 +23,6 @@ export function displayCfgToEditor(cfg) { edgeTPUCompiler["edgetpu-profile"] ); - const edgeTPUCompile = cfg["edgetpu-compile"]; document.getElementById("EdgeTPUInputPath").value = cfgString( edgeTPUCompile?.["input_path"] @@ -62,4 +61,4 @@ function cfgBoolean(str) { } return false; -} \ No newline at end of file +} diff --git a/media/EdgeTPUCfgEditor/index.js b/media/EdgeTPUCfgEditor/index.js index 9ec177216..44cad82f2 100644 --- a/media/EdgeTPUCfgEditor/index.js +++ b/media/EdgeTPUCfgEditor/index.js @@ -18,11 +18,9 @@ import { displayCfgToEditor } from "./displaycfg.js"; import { applyUpdates, updateEdgeTPUStep, - updateEdgeTPUCompile + updateEdgeTPUCompile, } from "./updateContent.js"; -import { - updateStepUI, -} from "./updateUI.js"; +import { updateStepUI } from "./updateUI.js"; import { postMessageToVsCode } from "./vscodeapi.js"; // Just like a regular webpage we need to wait for the webview @@ -48,7 +46,7 @@ function main() { break; case "applyDialogPath": document.getElementById(message.elemID).value = message.path; - switch (message.step) { + switch (message.step) { case "EdgeTPUCompile": updateEdgeTPUCompile(); break; @@ -84,20 +82,24 @@ function setDefaultEdgetpuValues(name) { } function registerCompilerStep() { - const checkboxEdgeTPUCompile = document.getElementById("checkboxEdgeTPUCompile"); - const checkboxEdgeTPUProfile = document.getElementById("checkboxEdgeTPUProfile"); + const checkboxEdgeTPUCompile = document.getElementById( + "checkboxEdgeTPUCompile" + ); + const checkboxEdgeTPUProfile = document.getElementById( + "checkboxEdgeTPUProfile" + ); const stepEdgeTPUCompile = document.getElementById("stepEdgeTPUCompile"); const stepEdgeTPUProfile = document.getElementById("stepEdgeTPUProfile"); checkboxEdgeTPUCompile.addEventListener("click", function () { - updateEdgeTPUStep(); + updateEdgeTPUStep(); applyUpdates(); }); checkboxEdgeTPUProfile.addEventListener("click", function () { - updateEdgeTPUStep(); + updateEdgeTPUStep(); applyUpdates(); }); - + stepEdgeTPUCompile.addEventListener("click", function () { updateStepUI("EdgeTPUCompile"); }); @@ -155,7 +157,7 @@ function registerCompileOptions() { edgeTPUDelegateSearchStep.value < 1 ? "1" : edgeTPUDelegateSearchStep.value; - updateEdgeTPUCompile(); + updateEdgeTPUCompile(); applyUpdates(); }); } diff --git a/media/EdgeTPUCfgEditor/updateContent.js b/media/EdgeTPUCfgEditor/updateContent.js index 6406a03ba..f4dee5941 100644 --- a/media/EdgeTPUCfgEditor/updateContent.js +++ b/media/EdgeTPUCfgEditor/updateContent.js @@ -39,23 +39,23 @@ export function applyUpdates() { postMessageToVsCode({ type: "updateDocument" }); } -export function updateEdgeTPUStep(){ +export function updateEdgeTPUStep() { postMessageToVsCode({ type: "setParam", section: "edgetpu-compiler", param: "edgetpu-compile", value: document.getElementById("checkboxEdgeTPUCompile").checked - ? "True" - : "False", - }); + ? "True" + : "False", + }); postMessageToVsCode({ type: "setParam", section: "edgetpu-compiler", param: "edgetpu-profile", value: document.getElementById("checkboxEdgeTPUProfile").checked - ? "True" - : "False", - }); + ? "True" + : "False", + }); } function addPostfixToFileName(filePath = "", postfix = "") {