From 2ca1fc2d5d0fa26110cf101e1dfb1d554d7e0b0e Mon Sep 17 00:00:00 2001 From: Seongwon Im Date: Tue, 26 Sep 2023 13:45:36 +0900 Subject: [PATCH] [EdgeTpu] Introduce EdgeTpuConfigSetting This commit introduce EdgeTpuConfigSetting that has ConfigObject logic for EdgeTpu Backend - Introduce class EdgeTpuConfigSetting extends ConfigSetting for EdgeTpu Backend logic - Apply EdgeTpuConfigSetting to ConfigObject - Add Test code for EdgeTpuConfigSetting ONE-vscode-DCO-1.0-Signed-off-by: Seongwon Im Co-authored-by: : SeungHyunH --- src/OneExplorer/ConfigObject.ts | 26 +++- .../ConfigSettings/EdgeTpuConfigSetting.ts | 126 ++++++++++++++++++ src/Tests/OneExplorer/ConfigObject.test.ts | 26 ++++ .../EdgeTpuConfigSetting.test.ts | 74 ++++++++++ 4 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 src/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.ts create mode 100644 src/Tests/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.test.ts diff --git a/src/OneExplorer/ConfigObject.ts b/src/OneExplorer/ConfigObject.ts index e61ef491..d0425ff6 100644 --- a/src/OneExplorer/ConfigObject.ts +++ b/src/OneExplorer/ConfigObject.ts @@ -24,14 +24,18 @@ import { RealPath } from "../Utils/Helpers"; import { Logger } from "../Utils/Logger"; import { Artifact } from "./ArtifactLocator"; -import { OneCfg, OneConfigSetting } from "./ConfigSettings/OneConfigSetting"; import { ConfigSetting } from "./ConfigSetting"; +import { OneCfg, OneConfigSetting } from "./ConfigSettings/OneConfigSetting"; +import { + EdgeTpuCfg, + EdgeTpuConfigSetting, +} from "./ConfigSettings/EdgeTpuConfigSetting"; /** * Type for rawObj. * Expand for additional Backend's section value */ -type Cfg = OneCfg; +type Cfg = OneCfg & EdgeTpuCfg; type CfgKeys = keyof Cfg; /** @@ -39,6 +43,7 @@ type CfgKeys = keyof Cfg; */ enum CfgType { one, + edgeTpu, } /** @@ -127,6 +132,9 @@ export class ConfigObj { public get configSetting(): ConfigSetting { let configSetting: ConfigSetting; switch (this.configType) { + case CfgType.edgeTpu: + configSetting = new EdgeTpuConfigSetting(); + break; case CfgType.one: default: configSetting = new OneConfigSetting(); @@ -139,7 +147,15 @@ export class ConfigObj { private constructor(uri: vscode.Uri, rawObj: Cfg) { this.uri = uri; this.rawObj = rawObj; - this.configType = CfgType.one; + const ext = path.extname(uri.fsPath); + switch (ext) { + case EdgeTpuConfigSetting.ext: + this.configType = CfgType.edgeTpu; + break; + case OneConfigSetting.ext: + default: + this.configType = CfgType.one; + } // TODO: separate to init() const configSetting = this.configSetting; @@ -212,6 +228,10 @@ export class ConfigObj { ); } + // EdgeTpu Compiler's output_path is fixed + // ex) `input_path`_edgetpu.tflite + this.configSetting.updateOutPath(newpath, this.rawObj, kSection); + return vscode.workspace.fs.writeFile( this.uri, new TextEncoder().encode(ini.stringify(this.rawObj)) diff --git a/src/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.ts b/src/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.ts new file mode 100644 index 00000000..9e1db287 --- /dev/null +++ b/src/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.ts @@ -0,0 +1,126 @@ +/* + * 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 * as vscode from "vscode"; +import * as path from "path"; + +import { Locator, LocatorRunner } from "../ArtifactLocator"; +import { ConfigSetting } from "../ConfigSetting"; + +export type EdgeTpuCfg = { + "edgetpu-compile": any; +}; + +export class EdgeTpuConfigSetting extends ConfigSetting { + static backendName = "EdgeTPU"; + static ext = ".edgetpucfg"; + + constructor() { + super(); + this.sections = { + ".tflite": "edgetpu-compile", + }; + } + + /** + * Add postfix(_edgetpu) to file name of new input path + * @returns void + */ + public updateOutPath( + newpath: string, + rawObj: { [key: string]: any }, + kSection: string + ): void { + const ext = path.extname(newpath); + const name = path.basename(newpath, ext) + "_edgetpu" + ext; + const dir = path.dirname(newpath); + const outpath = path.join(dir, name); + if (rawObj[kSection]) { + rawObj[kSection].output_path = outpath; + } + } + + protected _initBaseModelsLocatorRunner() { + let locatorRunner = new LocatorRunner(); + + locatorRunner.register({ + artifactAttr: { + ext: ".tflite", + icon: new vscode.ThemeIcon("symbol-variable"), + }, + locator: new Locator((value: string) => { + value += ""; + const filterd = value + .split(" ") + .filter((val) => !val.endsWith("_edgetpu.tflite")); + value = filterd.join(" "); + return LocatorRunner.searchWithExt(".tflite", value); + }), + }); + + this.baseModelsLocatorRunner = locatorRunner; + } + + protected _initProductsLocatorRunner() { + let locatorRunner = new LocatorRunner(); + + /** + * ABOUT ORDERING + * + * The registration order determines the order in the tree view + */ + + // NOTE + // Shows _edgetpu.tflite + // _edgetpu.tflite generated by .tflite is product type + locatorRunner.register({ + artifactAttr: { + ext: ".tflite", + icon: new vscode.ThemeIcon("symbol-variable"), + }, + locator: new Locator((value: string) => { + value += ""; + const filterd = value + .split(" ") + .filter((val) => val.endsWith("_edgetpu.tflite")); + value = filterd.join(" "); + return LocatorRunner.searchWithExt(".tflite", value); + }), + }); + + locatorRunner.register({ + // 'default' view type is 'text editor' (vscode.openWith) + artifactAttr: { + ext: ".log", + openViewType: "default", + icon: vscode.ThemeIcon.File, + canHide: true, + }, + locator: new Locator((value: string) => { + value += ""; + const filterd = value + .split(" ") + .filter((val) => val.endsWith("_edgetpu.tflite")); + value = filterd.join(" "); + return LocatorRunner.searchWithExt(".tflite", value).map((filepath) => + filepath.replace(".tflite", ".log") + ); + }), + }); + + this.productsLocatorRunner = locatorRunner; + } +} diff --git a/src/Tests/OneExplorer/ConfigObject.test.ts b/src/Tests/OneExplorer/ConfigObject.test.ts index 62c20ea0..3d2a9f43 100644 --- a/src/Tests/OneExplorer/ConfigObject.test.ts +++ b/src/Tests/OneExplorer/ConfigObject.test.ts @@ -20,6 +20,7 @@ import { ConfigObj } from "../../OneExplorer/ConfigObject"; import { TestBuilder } from "../TestBuilder"; import { OneConfigSetting } from "../../OneExplorer/ConfigSettings/OneConfigSetting"; +import { EdgeTpuConfigSetting } from "../../OneExplorer/ConfigSettings/EdgeTpuConfigSetting"; suite("OneExplorer", function () { suite("ConfigObject", function () { @@ -101,6 +102,31 @@ suite("OneExplorer", function () { assert.isTrue(configObj!.configSetting instanceof OneConfigSetting); } }); + + test("Get edge tpu config setting with .edgetpucfg file", function () { + const configName = "model.edgetpucfg"; + + const content = ` +`; + + // Write a file inside temp directory + testBuilder.writeFileSync(configName, content); + + // Get file paths inside the temp directory + const configPath = testBuilder.getPath(configName); + + const configObj = ConfigObj.createConfigObj( + vscode.Uri.file(configPath) + ); + + // Validate + { + assert.isDefined(configObj); + assert.isTrue( + configObj!.configSetting instanceof EdgeTpuConfigSetting + ); + } + }); }); suite("#one-import-onnx section", function () { diff --git a/src/Tests/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.test.ts b/src/Tests/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.test.ts new file mode 100644 index 00000000..06ab51ad --- /dev/null +++ b/src/Tests/OneExplorer/ConfigSettings/EdgeTpuConfigSetting.test.ts @@ -0,0 +1,74 @@ +/* + * 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 { assert } from "chai"; +import * as ini from "ini"; + +import { LocatorRunner } from "../../../OneExplorer/ArtifactLocator"; +import { EdgeTpuConfigSetting } from "../../../OneExplorer/ConfigSettings/EdgeTpuConfigSetting"; + +suite("OneExplorer", function () { + suite("ConfigSettings", function () { + suite("EdgeTpuConfigSetting", function () { + suite("#constructor", function () { + test("Create one config setting", function () { + assert.doesNotThrow(() => new EdgeTpuConfigSetting()); + + const configSetting = new EdgeTpuConfigSetting(); + assert.isTrue(configSetting instanceof EdgeTpuConfigSetting); + }); + }); + + suite("#init()", function () { + test("init one config setting", function () { + const configSetting = new EdgeTpuConfigSetting(); + assert.isTrue(configSetting instanceof EdgeTpuConfigSetting); + + assert.doesNotThrow(() => configSetting.init()); + assert.isTrue( + configSetting.baseModelsLocatorRunner instanceof LocatorRunner + ); + assert.isTrue( + configSetting.productsLocatorRunner instanceof LocatorRunner + ); + }); + }); + + suite("#updateOutPath()", function () { + test("edgetpu config setting change output_path by adding postfix(_edgetpu) to new_path", function () { + const inputPath = "model.tflite"; + const outputPath = "model_edgetpu.tflite"; + const kSection = "edgetpu-compile"; + const edgetpucfg = ` +[edgetpu-compile] +input_path=${inputPath} + `; + const rawObj = ini.parse(edgetpucfg); + + const configSetting = new EdgeTpuConfigSetting(); + assert.isTrue(configSetting instanceof EdgeTpuConfigSetting); + + assert.doesNotThrow(() => + configSetting.updateOutPath(inputPath, rawObj, kSection) + ); + console.log(rawObj); + assert.isDefined(rawObj["edgetpu-compile"].output_path); + assert.equal(outputPath, rawObj["edgetpu-compile"].output_path); + }); + }); + }); + }); +});