Skip to content

Commit

Permalink
[EdgeTPU] Implement EdgeTPUCfgData using the ICfgData interface (#1734)
Browse files Browse the repository at this point in the history
This commit is about implementing EdgeTPUCfgData using the ICfgData interface.

ONE-vscode-DCO-1.0-Signed-off-by: Hyeon-Uk <[email protected]>
Co-authored-by: Bumsoo Ko <[email protected]>
Co-authored-by: hohee-hee <[email protected]>
  • Loading branch information
3 people authored Nov 2, 2023
1 parent c8de56b commit 04af780
Show file tree
Hide file tree
Showing 5 changed files with 744 additions and 91 deletions.
104 changes: 24 additions & 80 deletions src/CfgEditor/CfgData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}
51 changes: 51 additions & 0 deletions src/CfgEditor/EdgeTPUCfgData.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
84 changes: 73 additions & 11 deletions src/CfgEditor/ICfgData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
36 changes: 36 additions & 0 deletions src/CfgEditor/Sections.ts
Original file line number Diff line number Diff line change
@@ -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",
];
}
Loading

0 comments on commit 04af780

Please sign in to comment.