Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[one-cmds] Support command schema for one-codegen #12886

Open
mhs4670go opened this issue Apr 19, 2024 · 7 comments
Open

[one-cmds] Support command schema for one-codegen #12886

mhs4670go opened this issue Apr 19, 2024 · 7 comments
Labels
enhancement New feature or making things better

Comments

@mhs4670go
Copy link
Contributor

What

Let's support a command schema feature for one-codegen.

Why

When we write a one-codegen section in the configuration file, below keys are required.

# only one backend
[one-codegen]
backend=dummyV2
command=-O onecc_048.tvn inception_v3.onecc_048.circle

# for multi-backend
[one-codegen]
backends=dummy,dummyV2
dummy=-o onecc_054.tvn inception_v3.onecc_054.circle
dummyV2=-O onecc_054.2.tvn inception_v3.onecc_054.2.circle

Then, onecc internally calls the backend driver as if running the below commands in the bash. And, these work well.

$ ${backend}-compile ${command}
# For example, above first section will be called like below.
# dummyV2-compile -O onecc_048.tvn inception_v3.onecc_048.circle

But, actually, this kind of style doesn't match a bit with the styles of the other one-cmds tools. It would be like below if we make it get matched.

# command=-O onecc_048.tvn inception_v3.onecc_048.circle
[one-codegen]
output=onecc_048.tvn
input=inception_v3.onecc_048.circle

So, what I'm trying to achieve in this issue is to give a chance to match the style to the backend users. Moreover, it would be easier for the backend tools to collaborate with the other one-cmds tools later.

@mhs4670go
Copy link
Contributor Author

mhs4670go commented Apr 19, 2024

How

How to support this feature? I'm thinking of a schema file for the command. Each backend users who want to use this feature write a schema about their arguments of the backend driver. Then, onecc would refer to that schema file and run the configuration file accordingly.

There are two things we need to decide - where and schema format.

Where

There are few options.

  1. Under the same directory with the driver
  2. /usr/share/one/command/

I prefer the latter.

Format

Let's investigate and cover it in the following comments.

Backward probability

Running order

One concern is how to apply this feature with currently supporting keys in the one-codegen section - backend, command, backends.

I decided to follow the steps.

  1. Check if there is schema file.
  2. If it exist, onecc run the backend tools only according to that schema file.
  3. If it doesn't exist, run the backend tools as normal.

Configuration file spec

If a schema file is introduced, backend key can't be used anymore because some backend driver happen to have options named backend or command. So, for the backward compatibility, I think we need to introduce new spec for the configuration file.

The change looks like below. If one-codegen in the onecc section has string values rather than the boolean one, they are the names for the backend tools. And, only these backend tools - written in the onecc section - will be checked if they has a schema file for the command.

[onecc]
one-import-tf=True
one-optimize=True
one-codegen=dummy,dummyV2

[one-import-tf]
# ..
[one-optimize]
# ..

[dummy]
input=onecc_054.opt.circle
output=onecc_054.tvn

[dummyV2]
input_file=onecc_054.opt.circle
out=dummy.bin

@mhs4670go mhs4670go added the enhancement New feature or making things better label Apr 19, 2024
@mhs4670go
Copy link
Contributor Author

Schema format

Python argument parser

This method is to have backend users write a function that returns the argument parser.

# /usr/share/one/command/dummy.py
def command_schema():
  parser = argparse.ArgumentParser()
    parser.add_argument(
        "-i",
        "--input",
        required=True,
        help="provide a path to .circle model.",
    )

    parser.add_argument(
        "-o",
        "--output",
        required=True,
        help="provide a path to .tvn model.",
    )

  return parser

Then, onecc calls get the argument parser from above function and check if the keys in the configuration are valid. It is convenient but users have to write a python script who only use c++ in the tools.

INI

[input]
type=string
description=provide a path to .circle model.
required=True

[output]
type=string
description=provide a path to .tvn model.
required=True

json or yaml

{
  "input": {
    "description": "provide a path to .circle model.",
    "type": "string"
  },
  "output": {
    "description": "provide a path to .tvn model.",
    "type": "string"
  }
  "DSP_quota": {
    "type": "string"
  }
  "required": [ "DSP_quota" ]
  "positional": [ "input", "output" ]
}

@mhs4670go
Copy link
Contributor Author

@ejjeong @parjong @Samsung/one_compiler Please feel free to give me an opinion for this feature.

@ejjeong
Copy link
Contributor

ejjeong commented Apr 22, 2024

Question about the motivation

Just out of curiosity, may I ask why you want do it “now”? :)
I ask this because I wonder if it’s somehow related to the recent backend target expansion.

Question about the scope

Do you target only codegen? (If so, may I ask why? 😃)
Or do you plan to expand it into e.g. profile and infer?

Question about the details

TBH I think I don't fully understand your suggestion yet 😢

IIUC, in the scenario you suggested, there should be two schemas and a converter as below.
But I failed to find the corresponding modules in the above description 😢

  1. schema1 that describes “onecc cfg interface”
    • input
    • output
    • DSP_quota (an underscore btw DSP and quota)
    • Otraffic
    • ...
  2. schema2 that describes “backend cli interface”
    • no input (positional argument)
    • --output
    • --DSP-quota (a hyphen btw DSP and quota)
    • -Otraffic (single hyphen)
    • ...
  3. Some rules that convert the option w/ schema1 into the option w/ schema2

It’d be helpful for me to understand what you suggest if you could provide a sample of a schema file for an "existing" onecc tool, e.g. “onecc quantize” command. AFAIK the python one-quantize is responsible for MANUALLY filling such subtle gaps between schema1 and schema2 (i.e., onecc quantize vs circle-quantize).
I also wonder how to manage such a tool for onecc codegen for each backend (i.e., onecc codegen vs ${backend}-compile)

Please feel free to correct me if I understand something wrong!

@mhs4670go
Copy link
Contributor Author

mhs4670go commented Apr 25, 2024

@ejjeong

Just out of curiosity, may I ask why you want do it “now”? :)

No specific reason. As you said, I thought that it would be more convenient to support upcoming(?) target configuration feature with this command schema feature.

Do you target only codegen?

I thought so in the first place. But, it would be better to think of such expansion as well when designing the detail.

TBH I think I don't fully understand your suggestion yet

It should be only one schema that users have to make.

Let me show you the example with the case that you worried about.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument(
    "-o",
    required=True,
)
parser.add_argument(
    "--DSP-quota",
)
parser.add_argument(
    "-Otraffic",
    action='store_true',
)

args = parser.parse_args()

Then, command line can be like below.

$ python MyCommand.py -o ${OUTPUT} --DSP-quota ${QUOTA} -Otraffic ${INPUT}

Of course there are some corner case where the commands of the backend driver can't match the argparse features. But, I don't think we should fully support such cases.

@ejjeong
Copy link
Contributor

ejjeong commented Apr 25, 2024

Well, I think I'm still missing something :)

Q1: Who's responsible for converting the former (user input) into the latter (arguments)?
Q2: And how? 🤔

AFAIK the python wrappers like one-quantize are responsible for this MANUAL conversion.
Do you expect the backend tools (i.e., ${backend}-compile) to maintain such an adapter? :)
(FYI I'm not saying we should never do it. I just want to know what you're thinking 😄)

User Input

[one-codegen]
output=onecc_048.tvn
input=inception_v3.onecc_048.circle
DSP_quota=64K
Otraffic=True

Expected arguments for the backend

-o onecc_048.tvn --DSP-quota 64K -Otraffic inception_v3.onecc_048.circle

But, I don't think we should fully support such cases.

Q3: If what you suggested is possible,
is it possible to remove all python wrappers like one-quantize and leave only the schema file?

@mhs4670go
Copy link
Contributor Author

@ejjeong I leave the answers for the history.

Who's responsible for converting the former (user input) into the latter (arguments)?

It is onecc. It converts the user inputs to the backend tool's commands according to the given command schema.

And how?

This is a pseudo code that I'm thinking about. Accessing the _action attribute is a bit hack though. We can implement a custom action instead, which force users to give action keyword argument to the add_argumnet api.

import ArgShcemaClass # schema file

k_to_v = cfgparser.parse('llama.cfg')
parser = ArgSchemaClass.get_argparser()

command = []
for action for parser._actions:
  # action.dest -> Otraffic, DSP-qutoa, etc
  # action.option_string -> -Otraffic, --DSP-quota 
  value_from_user = k_to_v[action.dest]
  command += [action.option_string, value_from_user]

run('tv2-compile' + command)

is it possible to remove all python wrappers like one-quantize and leave only the schema file?

Technically speaking it is possible. But, we won't. Because, AFAIK, one-cmds tools has been introduced for the two purpose.

  1. To have a unified driver name.
  2. To only expose options that we want to expose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or making things better
Projects
None yet
Development

No branches or pull requests

2 participants