From 04af780ea285936467431c6e3e8b3b6f6ac80cbe Mon Sep 17 00:00:00 2001 From: Dayoung Lee Date: Thu, 2 Nov 2023 15:16:12 +0900 Subject: [PATCH] [EdgeTPU] Implement EdgeTPUCfgData using the ICfgData interface (#1734) This commit is about implementing EdgeTPUCfgData using the ICfgData interface. ONE-vscode-DCO-1.0-Signed-off-by: Hyeon-Uk Co-authored-by: Bumsoo Ko Co-authored-by: hohee-hee --- src/CfgEditor/CfgData.ts | 104 +--- src/CfgEditor/EdgeTPUCfgData.ts | 51 ++ src/CfgEditor/ICfgData.ts | 84 +++- src/CfgEditor/Sections.ts | 36 ++ src/Tests/CfgEditor/EdgeTPUCfgData.test.ts | 560 +++++++++++++++++++++ 5 files changed, 744 insertions(+), 91 deletions(-) create mode 100644 src/CfgEditor/EdgeTPUCfgData.ts create mode 100644 src/CfgEditor/Sections.ts create mode 100644 src/Tests/CfgEditor/EdgeTPUCfgData.test.ts diff --git a/src/CfgEditor/CfgData.ts b/src/CfgEditor/CfgData.ts index b7b699caf..244d86cb8 100644 --- a/src/CfgEditor/CfgData.ts +++ b/src/CfgEditor/CfgData.ts @@ -16,18 +16,7 @@ import * as ini from "ini"; import { ICfgData } from "./ICfgData"; - -const sections = [ - "onecc", - "one-import-tf", - "one-import-tflite", - "one-import-bcq", - "one-import-onnx", - "one-optimize", - "one-quantize", - "one-codegen", - "one-profile", -]; +import { Sections } from "./Sections"; // NOTE: Why is not function overloadding used? Its maintain costs expensive. // Compared to C++, TS supports function overloading very compilcated like @@ -42,104 +31,59 @@ const sections = [ // } // } // -export class CfgData implements ICfgData { - private _oneConfig: any = undefined; - - constructor() {} - - getAsConfig(): any { - return this._oneConfig; - } - - getAsString(): string { - return ini.stringify(this._oneConfig); +export class CfgData extends ICfgData { + constructor(cfg = undefined) { + super(cfg, Sections.onecc); } setWithConfig(cfg: any): void { - this._oneConfig = cfg; + this.setConfig(cfg); this.resolveDeprecated(); } setWithString(text: string): void { - this._oneConfig = ini.parse(text); + this.setConfig(ini.parse(text)); this.resolveDeprecated(); } private resolveDeprecated(): void { // NOTE 'one-build' will be deprecated. // Therefore, when only 'one-build' is used, it will be replaced to 'onecc'. - if (this._oneConfig["one-build"] !== undefined) { - if (this._oneConfig["onecc"] === undefined) { - this._oneConfig["onecc"] = ini.parse( - ini.stringify(this._oneConfig["one-build"]) - ); + const config = this.getAsConfig(); + if (config["one-build"] !== undefined) { + if (config["onecc"] === undefined) { + config["onecc"] = ini.parse(ini.stringify(config["one-build"])); } - delete this._oneConfig["one-build"]; + delete config["one-build"]; } // NOTE 'input_dtype' is deprecated. // Therefore, when only 'input_dtype' is used, it will be replaced to 'onecc'. - if (this._oneConfig["one-quantize"]?.["input_dtype"] !== undefined) { - if (this._oneConfig["one-quantize"]["input_model_dtype"] === undefined) { - this._oneConfig["one-quantize"]["input_model_dtype"] = - this._oneConfig["one-quantize"]["input_dtype"]; + if (config["one-quantize"]?.["input_dtype"] !== undefined) { + if (config["one-quantize"]["input_model_dtype"] === undefined) { + config["one-quantize"]["input_model_dtype"] = + config["one-quantize"]["input_dtype"]; } - delete this._oneConfig["one-quantize"]["input_dtype"]; + delete config["one-quantize"]["input_dtype"]; } } updateSectionWithKeyValue(section: string, key: string, value: string): void { - if (this._oneConfig[section] === undefined) { - this._oneConfig[section] = {}; + const config = this.getAsConfig(); + if (config[section] === undefined) { + config[section] = {}; } - if (this._oneConfig[section][key] === undefined) { - this._oneConfig[section][key] = ""; + if (config[section][key] === undefined) { + config[section][key] = ""; } - this._oneConfig[section][key] = value; + config[section][key] = value; this.resolveDeprecated(); } updateSectionWithValue(section: string, value: string): void { // value should be encoded or stringfied - this._oneConfig[section] = ini.parse(value); + const config = this.getAsConfig(); + config[section] = ini.parse(value); this.resolveDeprecated(); } - - isSame(textStringified: string): boolean { - const iniDocument = ini.parse(textStringified); - for (const [sectionName, section] of Object.entries(this._oneConfig)) { - for (const [paramName, param] of Object.entries(section as any)) { - if ( - iniDocument[sectionName] !== undefined && - iniDocument[sectionName][paramName] === param - ) { - continue; - } - return false; - } - } - for (const [sectionName, section] of Object.entries(iniDocument)) { - for (const [paramName, param] of Object.entries(section as any)) { - if ( - this._oneConfig[sectionName] !== undefined && - this._oneConfig[sectionName][paramName] === param - ) { - continue; - } - return false; - } - } - return true; - } - - sort(): void { - // cfg file is written along with the order of array elements - let sorted: any = {}; - sections.forEach((section) => { - if (this._oneConfig[section] !== undefined) { - sorted[section] = this._oneConfig[section]; - } - }); - this.setWithConfig(sorted); - } } diff --git a/src/CfgEditor/EdgeTPUCfgData.ts b/src/CfgEditor/EdgeTPUCfgData.ts new file mode 100644 index 000000000..f648da3ee --- /dev/null +++ b/src/CfgEditor/EdgeTPUCfgData.ts @@ -0,0 +1,51 @@ +/* + * 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 ini from "ini"; +import { ICfgData } from "./ICfgData"; +import { Sections } from "./Sections"; + +export class EdgeTpuCfgData extends ICfgData { + constructor(cfg = undefined) { + super(cfg, Sections.edgetpu); + } + + setWithConfig(cfg: any): void { + this.setConfig(cfg); + } + + setWithString(text: string): void { + this.setConfig(ini.parse(text)); + } + + updateSectionWithKeyValue(section: string, key: string, value: string): void { + const config = this.getAsConfig(); + if (config[section] === undefined) { + config[section] = {}; + } + + if (config[section][key] === undefined) { + config[section][key] = ""; + } + config[section][key] = value; + } + + updateSectionWithValue(section: string, value: string): void { + // value should be encoded or stringfied + const config = this.getAsConfig(); + config[section] = ini.parse(value); + } +} diff --git a/src/CfgEditor/ICfgData.ts b/src/CfgEditor/ICfgData.ts index ea2a6ff3d..b45751182 100644 --- a/src/CfgEditor/ICfgData.ts +++ b/src/CfgEditor/ICfgData.ts @@ -13,18 +13,80 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as ini from "ini"; + +export abstract class ICfgData { + //config can be undefined + private _config: any; + //section must be existed + private _section!: string[]; + + constructor(_config: any, _section: string[]) { + this._config = _config; + this._section = _section; + } -export interface ICfgData { - // returns data decoded or parsed as object - getAsConfig(): any; - // returns data encoded or stringfied as string - getAsString(): string; // sets data with object decoded or parsed - setWithConfig(cfg: any): void; + abstract setWithConfig(cfg: any): void; // sets data with string encoded or stringfied - setWithString(text: string): void; - updateSectionWithKeyValue(section: string, key: string, value: string): void; - updateSectionWithValue(section: string, value: string): void; - isSame(textStringified: string): boolean; - sort(): void; + abstract setWithString(text: string): void; + abstract updateSectionWithKeyValue( + section: string, + key: string, + value: string + ): void; + abstract updateSectionWithValue(section: string, value: string): void; + + // set cfgData's config + // only child class can use this method + protected setConfig(cfg: any): void { + this._config = cfg; + } + + // returns data decoded or parsed as object + getAsConfig(): any { + return this._config; + } + // returns data encoded or stringfied as string + getAsString(): string { + return ini.stringify(this._config); + } + + isSame(textStringified: string): boolean { + const iniDocument = ini.parse(textStringified); + for (const [sectionName, section] of Object.entries(this._config)) { + for (const [paramName, param] of Object.entries(section as any)) { + if ( + iniDocument[sectionName] !== undefined && + iniDocument[sectionName][paramName] === param + ) { + continue; + } + return false; + } + } + for (const [sectionName, section] of Object.entries(iniDocument)) { + for (const [paramName, param] of Object.entries(section as any)) { + if ( + this._config[sectionName] !== undefined && + this._config[sectionName][paramName] === param + ) { + continue; + } + return false; + } + } + return true; + } + + sort(): void { + // cfg file is written along with the order of array elements + let sorted: any = {}; + this._section.forEach((section) => { + if (this._config[section] !== undefined) { + sorted[section] = this._config[section]; + } + }); + this.setWithConfig(sorted); + } } diff --git a/src/CfgEditor/Sections.ts b/src/CfgEditor/Sections.ts new file mode 100644 index 000000000..589520fc5 --- /dev/null +++ b/src/CfgEditor/Sections.ts @@ -0,0 +1,36 @@ +/* + * 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 class Sections { + static onecc: string[] = [ + "onecc", + "one-import-tf", + "one-import-tflite", + "one-import-bcq", + "one-import-onnx", + "one-optimize", + "one-quantize", + "one-codegen", + "one-profile", + "one-plus", + "one-minus", + ]; + static edgetpu: string[] = [ + "edgetpu-compiler", + "edgetpu-compile", + "edgetpu-profile", + ]; +} diff --git a/src/Tests/CfgEditor/EdgeTPUCfgData.test.ts b/src/Tests/CfgEditor/EdgeTPUCfgData.test.ts new file mode 100644 index 000000000..e37cc3bd2 --- /dev/null +++ b/src/Tests/CfgEditor/EdgeTPUCfgData.test.ts @@ -0,0 +1,560 @@ +/* + * 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 { EdgeTpuCfgData } from "../../CfgEditor/EdgeTPUCfgData"; + +// NOTE +// sampleEdgeTpuCfgText and sampleEdgeTpuCfgText1 are the same. +// But others are different. +const sampleEdgeTpuCfgText = ` +[edgetpu-compiler] +edgetpu-compile=True +edgetpu-profile=False + +[edgetpu-compile] +input_path=/home/usr/ONE-vscode/res/modelDir/truediv/model.tflite +output_path=/home/usr/ONE-vscode/res/modelDir/truediv/model_edgetpu.tflite +`; + +// eslint-disable-next-line no-unused-vars +const sampleEdgeTpuCfgText1 = ` +[edgetpu-compile] +input_path=/home/usr/ONE-vscode/res/modelDir/truediv/model.tflite +output_path=/home/usr/ONE-vscode/res/modelDir/truediv/model_edgetpu.tflite + +[edgetpu-compiler] +edgetpu-compile=True +edgetpu-profile=False +`; + +const sampleEdgeTpuCfgText2 = ` +[edgetpu-compiler] +edgetpu-compile=True +edgetpu-profile=False + +[edgetpu-compile] +input_path=/home/usr/ONE-vscode/res/modelDir/truediv/model.tflite +output_path=/home/usr/ONE-vscode/res/modelDir/truediv/model_edgetpu.tflite +intermediate_tensors=opr1 +show_operations=True +`; + +const sampleEdgeTpuCfgText3 = ` +[edgetpu-compiler] +edgetpu-compile=True +edgetpu-profile=False + +[edgetpu-compile] +input_path=/home/usr/ONE-vscode/res/modelDir/truediv/model.tflite +output_path=/home/usr/ONE-vscode/res/modelDir/truediv/model_edgetpu.tflite +show_operations=True +search_delegate=True +delegate_search_step=1 +`; + +suite("EdgetpuCfgEditor", function () { + suite("EdgetpuCfgData", function () { + suite("#constructor()", function () { + test("is constructed", function () { + const data = new EdgeTpuCfgData(); + assert.instanceOf(data, EdgeTpuCfgData); + }); + }); + + suite("#setWithConfig()", function () { + test("sets with decoded/parsed config param", function () { + let data = new EdgeTpuCfgData(); + const cfg = ini.parse(sampleEdgeTpuCfgText); + data.setWithConfig(cfg); + const dataCfg = data.getAsConfig(); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + }); + + test("sets with decoded/parsed config param 2", function () { + let data = new EdgeTpuCfgData(); + const cfg = ini.parse(sampleEdgeTpuCfgText2); + data.setWithConfig(cfg); + const dataCfg = data.getAsConfig(); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["intermediate_tensors"], + cfg["edgetpu-compile"]["intermediate_tensors"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["show_operations"], + cfg["edgetpu-compile"]["show_operations"] + ); + }); + + test("sets with decoded/parsed config param 3", function () { + let data = new EdgeTpuCfgData(); + const cfg = ini.parse(sampleEdgeTpuCfgText3); + data.setWithConfig(cfg); + const dataCfg = data.getAsConfig(); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["show_operations"], + cfg["edgetpu-compile"]["show_operations"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["search_delegate"], + cfg["edgetpu-compile"]["search_delegate"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["delegate_search_step"], + cfg["edgetpu-compile"]["delegate_search_step"] + ); + }); + }); + + suite("#setWithString()", function () { + test("sets with encoded/stringified text param", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const dataCfg = data.getAsConfig(); + const cfg = ini.parse(sampleEdgeTpuCfgText); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + }); + + test("sets with encoded/stringified text param 2", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText2); + const dataCfg = data.getAsConfig(); + const cfg = ini.parse(sampleEdgeTpuCfgText2); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["intermediate_tensors"], + cfg["edgetpu-compile"]["intermediate_tensors"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["show_operations"], + cfg["edgetpu-compile"]["show_operations"] + ); + }); + + test("sets with encoded/stringified text param 3", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText3); + const dataCfg = data.getAsConfig(); + const cfg = ini.parse(sampleEdgeTpuCfgText3); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["show_operations"], + cfg["edgetpu-compile"]["show_operations"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["search_delegate"], + cfg["edgetpu-compile"]["search_delegate"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["delegate_search_step"], + cfg["edgetpu-compile"]["delegate_search_step"] + ); + }); + }); + + suite("#getAsConfig()", function () { + test("gets OneConfig decoded/parsed", function () { + let data = new EdgeTpuCfgData(); + const cfg = ini.parse(sampleEdgeTpuCfgText); + data.setWithConfig(cfg); + const dataCfg = data.getAsConfig(); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + }); + + test("gets OneConfig decoded/parsed 2", function () { + let data = new EdgeTpuCfgData(); + const cfg = ini.parse(sampleEdgeTpuCfgText2); + data.setWithConfig(cfg); + const dataCfg = data.getAsConfig(); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["intermediate_tensors"], + cfg["edgetpu-compile"]["intermediate_tensors"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["show_operations"], + cfg["edgetpu-compile"]["show_operations"] + ); + }); + + test("gets OneConfig decoded/parsed 3", function () { + let data = new EdgeTpuCfgData(); + const cfg = ini.parse(sampleEdgeTpuCfgText3); + data.setWithConfig(cfg); + const dataCfg = data.getAsConfig(); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-compile"], + cfg["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compiler"]["edgetpu-profile"], + cfg["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["input_path"], + cfg["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["output_path"], + cfg["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["show_operations"], + cfg["edgetpu-compile"]["show_operations"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["search_delegate"], + cfg["edgetpu-compile"]["search_delegate"] + ); + assert.strictEqual( + dataCfg["edgetpu-compile"]["delegate_search_step"], + cfg["edgetpu-compile"]["delegate_search_step"] + ); + }); + }); + + suite("#getAsString()", function () { + test("gets string encoded/stringified", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const cfg1 = data.getAsConfig(); + + const stringfied = data.getAsString(); + let data2 = new EdgeTpuCfgData(); + data2.setWithString(stringfied); + const cfg2 = data2.getAsConfig(); + + assert.strictEqual( + cfg1["edgetpu-compiler"]["edgetpu-compile"], + cfg2["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + cfg1["edgetpu-compiler"]["edgetpu-profile"], + cfg2["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["input_path"], + cfg2["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["output_path"], + cfg2["edgetpu-compile"]["output_path"] + ); + }); + + test("gets string encoded/stringified 2", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const cfg1 = data.getAsConfig(); + + const stringfied = data.getAsString(); + let data2 = new EdgeTpuCfgData(); + data2.setWithString(stringfied); + const cfg2 = data2.getAsConfig(); + + assert.strictEqual( + cfg1["edgetpu-compiler"]["edgetpu-compile"], + cfg2["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + cfg1["edgetpu-compiler"]["edgetpu-profile"], + cfg2["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["input_path"], + cfg2["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["output_path"], + cfg2["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["intermediate_tensors"], + cfg2["edgetpu-compile"]["intermediate_tensors"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["show_operations"], + cfg2["edgetpu-compile"]["show_operations"] + ); + }); + + test("gets string encoded/stringified 3", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const cfg1 = data.getAsConfig(); + + const stringfied = data.getAsString(); + let data2 = new EdgeTpuCfgData(); + data2.setWithString(stringfied); + const cfg2 = data2.getAsConfig(); + + assert.strictEqual( + cfg1["edgetpu-compiler"]["edgetpu-compile"], + cfg2["edgetpu-compiler"]["edgetpu-compile"] + ); + assert.strictEqual( + cfg1["edgetpu-compiler"]["edgetpu-profile"], + cfg2["edgetpu-compiler"]["edgetpu-profile"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["input_path"], + cfg2["edgetpu-compile"]["input_path"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["output_path"], + cfg2["edgetpu-compile"]["output_path"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["show_operations"], + cfg2["edgetpu-compile"]["show_operations"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["search_delegate"], + cfg2["edgetpu-compile"]["search_delegate"] + ); + assert.strictEqual( + cfg1["edgetpu-compile"]["delegate_search_step"], + cfg2["edgetpu-compile"]["delegate_search_step"] + ); + }); + }); + + suite("#updateSectionWithKeyValue()", function () { + test("update key of section which already exists-1", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText2); + data.updateSectionWithKeyValue( + "edgetpu-compile", + "intermediate_tensors", + "opr1, opr2" + ); + const cfg = data.getAsConfig(); + assert.strictEqual( + cfg["edgetpu-compile"]["intermediate_tensors"], + "opr1, opr2" + ); + }); + test("update key of section which already exists-2", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText3); + data.updateSectionWithKeyValue( + "edgetpu-compile", + "delegate_search_step", + "3" + ); + const cfg = data.getAsConfig(); + assert.strictEqual(cfg["edgetpu-compile"]["delegate_search_step"], "3"); + }); + test("update section which is not written", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + data.updateSectionWithKeyValue( + "edgetpu-compile", + "intermediate_tensors", + "opr1, opr2" + ); + const cfg = data.getAsConfig(); + assert.strictEqual( + cfg["edgetpu-compile"]["intermediate_tensors"], + "opr1, opr2" + ); + }); + }); + + suite("#updateSectionWithValue()", function () { + test("update section of config with value encoded/stringified", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const stringified: string = ` +input_path=./inception_v3.tflite +output_path=./inception_v3_edgetpu.tflite +intermediate_tensors=opr1 +show_operations=True + `; + data.updateSectionWithValue("edgetpu-compile", stringified); + const cfg = data.getAsConfig(); + assert.strictEqual( + cfg["edgetpu-compile"]["input_path"], + "./inception_v3.tflite" + ); + assert.strictEqual( + cfg["edgetpu-compile"]["output_path"], + "./inception_v3_edgetpu.tflite" + ); + assert.strictEqual( + cfg["edgetpu-compile"]["intermediate_tensors"], + "opr1" + ); + assert.strictEqual(cfg["edgetpu-compile"]["show_operations"], "True"); + }); + }); + + suite("#isSame()", function () { + test("is same to string encoded/stringified", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const isSame: boolean = data.isSame(sampleEdgeTpuCfgText1); + assert.isTrue(isSame); + }); + test("is not same to string encoded/stringified", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const isSame: boolean = data.isSame(sampleEdgeTpuCfgText2); + assert.isNotTrue(isSame); + }); + test("is not same to string encoded/stringified - 2", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + const isSame: boolean = data.isSame(sampleEdgeTpuCfgText3); + assert.isNotTrue(isSame); + }); + }); + + suite("#sorted()", function () { + test("sorts config", function () { + let data = new EdgeTpuCfgData(); + data.setWithString(sampleEdgeTpuCfgText); + data.sort(); + const isSame: boolean = data.isSame(sampleEdgeTpuCfgText1); + assert.isTrue(isSame); + }); + }); + }); +});