|
| 1 | +# INC Coding Conventions |
| 2 | + |
| 3 | + (Mostly for Version 3 and later) |
| 4 | + |
| 5 | +## Background |
| 6 | + |
| 7 | +To improve the quality and maintainability of INC code, we summarized some common coding standards and conventions. |
| 8 | + |
| 9 | +There are many style guides, and they may conflict with each other. To avoid overly arguing formatting, we make decisions based on the following priorities: |
| 10 | + |
| 11 | +- [Google Python Style](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings), [PEP 8](https://peps.python.org/pep-0008/) |
| 12 | +- Framework Style |
| 13 | +- INC Internal Style |
| 14 | +- Sub-module specific Style |
| 15 | + |
| 16 | +## Rules |
| 17 | + |
| 18 | +> Note: The sub-tile naming is following [Google Python Style](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) and [PEP 8](https://peps.python.org/pep-0008/). See the relevant section for more details. |
| 19 | +
|
| 20 | + |
| 21 | +### Imports |
| 22 | + |
| 23 | +- Recommend |
| 24 | + |
| 25 | +```python |
| 26 | +import os |
| 27 | +import sys |
| 28 | + |
| 29 | +from x import py |
| 30 | +from x import y as z |
| 31 | +from copy import deepcopy |
| 32 | +from subprocess import Popen, PIPE |
| 33 | +``` |
| 34 | + |
| 35 | +- Not recommend |
| 36 | + |
| 37 | +```python |
| 38 | +from sub_module import * # May lead to namespace pollution |
| 39 | +import os, sys # Import on separate lines |
| 40 | +import copy # May import local copy.py |
| 41 | +``` |
| 42 | + |
| 43 | +### Strings |
| 44 | + |
| 45 | +- Recommend |
| 46 | + |
| 47 | +```python |
| 48 | +long_string = """This is fine if your use case can accept |
| 49 | + extraneous leading spaces.""" |
| 50 | + |
| 51 | +long_string = "And this is fine if you cannot accept\n" "extraneous leading spaces." |
| 52 | +``` |
| 53 | + |
| 54 | +- Not recommend |
| 55 | + |
| 56 | +```python |
| 57 | +logger.info("This is fine if your use case can accept") |
| 58 | +logger.info("extraneous leading spaces.") |
| 59 | +``` |
| 60 | + |
| 61 | +### Logger |
| 62 | + |
| 63 | +- Recommend |
| 64 | + |
| 65 | +```python |
| 66 | +from neural_compressor.common import logger |
| 67 | + |
| 68 | +logger.info("Current TensorFlow Version is: %s", tf.__version__) # Use a pattern-string (with %-placeholders) |
| 69 | + |
| 70 | +logger.info("Current $PAGER is: %s", os.getenv("PAGER", default="")) # Better readability |
| 71 | + |
| 72 | +# Handle long string |
| 73 | +logger.warning( |
| 74 | + "All tuning options for the current strategy have been tried. \n" |
| 75 | + "If the quantized model does not seem to work well, it might be worth considering other strategies." |
| 76 | +) |
| 77 | + |
| 78 | +logger.warning( |
| 79 | + "This is a long string, this is a long string," |
| 80 | + "override the user config's smooth quant alpha into the best alpha(%.4f) found in pre-strategy.", |
| 81 | + 0.65421, |
| 82 | +) |
| 83 | +``` |
| 84 | + |
| 85 | +- Not recommend |
| 86 | + |
| 87 | +```python |
| 88 | +logger.info(f"Current TensorFlow Version is: {tf.__version__}") # Use f-string |
| 89 | + |
| 90 | +logger.info("Current $PAGER is:") # One sentence in two lines |
| 91 | +logger.info(os.getenv("PAGER", default="")) |
| 92 | +``` |
| 93 | + |
| 94 | + |
| 95 | +### Type Annotations |
| 96 | + |
| 97 | +- Recommend |
| 98 | + |
| 99 | +```python |
| 100 | +def register_config(framework_name: str, algo_name: str, priority: int = 0) -> Callable[..., Any]: ... |
| 101 | + |
| 102 | + |
| 103 | +eval_result: float = evaluator.eval(model) |
| 104 | + |
| 105 | +# Declare aliases of complex types |
| 106 | +from typing import TypeAlias |
| 107 | + |
| 108 | +_LossAndGradient: TypeAlias = tuple[tf.Tensor, tf.Tensor] |
| 109 | +ComplexTFMap: TypeAlias = Mapping[str, _LossAndGradient] |
| 110 | +``` |
| 111 | + |
| 112 | +- Not recommend |
| 113 | + |
| 114 | +```python |
| 115 | +def xx_func(cls) -> Dict[str, OrderedDict[str, Dict[str, object]]]: # Can't improve the readability |
| 116 | +``` |
| 117 | + |
| 118 | +- Plugs: |
| 119 | + - [python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) |
| 120 | + - [pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) |
| 121 | + |
| 122 | + |
| 123 | +### Comments |
| 124 | + |
| 125 | +- Recommend |
| 126 | + |
| 127 | +```python |
| 128 | +class CheeseShopAddress: |
| 129 | + """The address of a cheese shop. |
| 130 | +
|
| 131 | + ... |
| 132 | + """ |
| 133 | + |
| 134 | + |
| 135 | +class OutOfCheeseError(Exception): |
| 136 | + """No more cheese is available.""" |
| 137 | +``` |
| 138 | + |
| 139 | +- Not recommend |
| 140 | + |
| 141 | +```python |
| 142 | +class CheeseShopAddress: |
| 143 | + """Class that describes the address of a cheese shop. |
| 144 | +
|
| 145 | + ... |
| 146 | + """ |
| 147 | + |
| 148 | + |
| 149 | +class OutOfCheeseError(Exception): |
| 150 | + """Raised when no more cheese is available.""" |
| 151 | +``` |
| 152 | + |
| 153 | + |
| 154 | +### TODO Comments |
| 155 | + |
| 156 | +- Recommend |
| 157 | + |
| 158 | +```python |
| 159 | +# TODO: crbug.com/192795 - Investigate cpufreq optimizations. |
| 160 | + |
| 161 | +# * Important information |
| 162 | +# ? Need decision |
| 163 | +# ! Deprecated method, do not use |
| 164 | +``` |
| 165 | + |
| 166 | +> A `TODO` comment begins with the word `TODO:` for facilitate searching. |
| 167 | +
|
| 168 | +- Plug: |
| 169 | + [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) |
| 170 | + |
| 171 | + |
| 172 | +### Public and Internal Interfaces |
| 173 | + |
| 174 | +Use `__all__` to help the developer and user know the supported interface and components. |
| 175 | + |
| 176 | +```python |
| 177 | +__all__ = [ |
| 178 | + "options", |
| 179 | + "register_config", |
| 180 | + "get_all_config_set_from_config_registry", |
| 181 | + "BaseConfig", |
| 182 | + "ComposableConfig", |
| 183 | +] |
| 184 | +``` |
| 185 | + |
| 186 | + |
| 187 | +## Folder structure |
| 188 | + |
| 189 | +```shell |
| 190 | +├── fwk_name |
| 191 | +│ ├── __init__.py |
| 192 | +│ ├── quantization |
| 193 | +│ │ ├── algorithm_entry.py |
| 194 | +│ │ ├── autotune.py |
| 195 | +│ │ ├── config.py |
| 196 | +│ │ ├── __init__.py |
| 197 | +│ │ └── quantize.py |
| 198 | +│ ├── algorithms |
| 199 | +│ │ ├── __init__.py |
| 200 | +│ │ ├── smooth_quant |
| 201 | +│ │ │ ├── __init__.py |
| 202 | +│ │ │ ├── smooth_quant.py |
| 203 | +│ │ │ └── utility.py |
| 204 | +│ │ ├── static_quant |
| 205 | +│ │ │ ├── __init__.py |
| 206 | +│ │ │ ├── static_quant.py |
| 207 | +│ │ │ └── utility.py |
| 208 | +│ │ └── weight_only |
| 209 | +│ │ ├── gptq.py |
| 210 | +│ │ ├── __init__.py |
| 211 | +│ │ └── rtn.py |
| 212 | +│ └── utils |
| 213 | +│ ├── constants.py |
| 214 | +│ ├── __init__.py |
| 215 | +│ └── utility.py |
| 216 | +└── __init__.py |
| 217 | +``` |
| 218 | + |
| 219 | +```python |
| 220 | +# * Note: some code snippets about register algorithm entry |
| 221 | +# filepath: neural_compressor/fwk_name/quantization/algorithm_entry.py |
| 222 | +@register_algo(RTN) |
| 223 | +def rtn_algo_entry() |
| 224 | + from neural_compressor.fwk_name.algorithms import rtn |
| 225 | + ... |
| 226 | + |
| 227 | +@register_algo(SMOOTH_QUANT) |
| 228 | +def smooth_quant_entry(): |
| 229 | + from neural_compressor.fwk_name.algorithms import smooth_quant |
| 230 | + ... |
| 231 | + |
| 232 | +``` |
| 233 | + |
| 234 | + |
| 235 | +## Recommend VS Code `settings.json` |
| 236 | +To keep the coding style consistent, we suggest you replace `.vscode/settings.json` with `neural-compressor/.vscode/settings_recommended.json`. |
| 237 | + |
| 238 | + |
| 239 | +## Reference |
| 240 | + |
| 241 | +- [Google Python Style](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |
| 242 | +- [PEP 8](https://peps.python.org/pep-0008/) |
| 243 | +- [PyTorch](https://github.com/pytorch/pytorch) |
0 commit comments