• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

NeuralNetworks.tD23-Mar-2024111.3 KiB2,5802,438

README.mdD23-Mar-20248 KiB216143

generate_api.pyD23-Mar-202414.4 KiB377273

generate_api.shD23-Mar-20241.7 KiB6860

types.specD23-Mar-2024279.2 KiB6,4056,265

README.md

1# API File Generation
2
3There are certain pieces of `NeuralNetworks.h` and of our various `*.hal` files
4that ought to be kept in sync -- most notably the operand type and operation
5type definitions and descriptions in our `NeuralNetworks.h` and `types.hal`
6files.  To avoid having to do this manually, a tool `generate_api.py` is
7employed to combine a single *specification file* with one *template file* per
8API file (`NeuralNetworks.h` or `types.hal`) to produce that API file.  The
9script `generate_api.sh` invokes `generate_api.py` once per API file, passing
10appropriate arguments.
11
12## `generate_api.sh`
13
14The environment variable `ANDROID_BUILD_TOP` must be set.
15
16Invoked with no arguments, this script regenerates the `NeuralNetworks.h` file
17and every `types.hal` file in place, by invoking `generate_api.py` once per
18generated file.
19
20Invoked with the `--dryrun` argument, this script instead shows how it would
21invoke `generate_api.py`.
22
23## `generate_api.py`
24
25This tool generates a single output file from an input specification file and an
26input template file.  It takes the following mandatory arguments:
27
28* `--output OUTPUT` path to generated output file (such as `NeuralNetworks.h`)
29* `--specification SPECIFICATION` path to input specification file
30* `--template TEMPLATE` path to input template file
31* `--kind KIND` token identifying kind of file to generate
32
33The "kind" is an arbitrary token that the specification file can reference with
34the `%kind` directive to help generate different text in different situations.
35It has no meaning to the tool itself.  Today, the following kinds are used:
36`ndk` (when generating `NeuralNetworks.h`), `hal_1.0` (when generating
37`1.0/types.hal`), `hal_1.1`, `hal_1.2` and `hal_1.3`.
38
39## Template File Syntax
40
41Every line of the template file is copied verbatim to the output file *unless*
42that line begins with `%`.
43
44A line that begins with `%%` is a comment, and is ignored.
45
46A line that begins with `%` and is not a comment is a *directive*.
47
48### Directives
49
50#### `%insert *name*`
51
52Copy the *section* with the specified *name* from the specification file to the
53output file.  The section is defined by a `%section` directive in the
54specification file.
55
56## Specification File Syntax
57
58The specification file consists of comments, *directives*, and other text.
59
60A line that begins with `%%` is a comment, and is ignored.
61
62A line that begins with `%` and is not a comment is a *directive*.
63
64The meaning of a line that is neither a comment nor a directive depends on the
65context -- the *region* in which that line appears.
66
67### Regions
68
69The specification file is divided into *regions*, which are sequences of lines
70delimited by certain directives.
71
72Certain regions can enclose certain other regions, but this is very limited:
73
74* A conditional region can enclose a definition region.
75* A section region can enclose a conditional region or a definition region.
76
77Equivalently:
78
79* A conditional region can be enclosed by a section region.
80* A definition region can be enclosed by a conditional region or a section
81  region.
82
83#### null region
84
85A *null region* is a sequence of lines that is not part of any other region.
86For example, a specification file that contains no directives other than
87`%define` and `%define-kinds` consists of a single null region.
88
89Within a null region, all lines other than directives are treated as comments
90and are ignored.
91
92#### conditional region
93
94A *conditional region* is a sequence of lines immediately preceded by the `%kind
95*list*` directive and immediately followed by the `%/kind` directive.  The
96`%kind` directive establishes a condition state **on** or **off** (see the
97description of the directive for details).  When the condition is **on**, the
98lines in the region are processed normally (i.e., directives have their usual
99effect, and non-directive lines are added to the enclosing section region, if
100any).  When the condition is **off**, lines in the region other than the `%else`
101directive are ignored *except* that even ignored directives undergo some level
102of syntactic and semantic checking.
103
104#### definition region
105
106A *definition region* is a sequence of lines immediately preceded by the
107`%define-lines *name*` directive and immediately followed by the
108`%/define-lines` directive.  Every non-comment line in the sequence undergoes
109macro substitution, and the resulting lines are associated with the region name.
110They can later be added to a section region with the `%insert-lines` directive.
111
112This can be thought of as a multi-line macro facility.
113
114#### section region
115
116A *section region* is a sequence of lines immediately preceded by the `%section
117*name*` directive and immediately followed by the `%/section` directive.  Every
118non-comment line in the sequence undergoes macro substitution, and the resulting
119lines are associated with the section name.  They can be inserted into the
120generated output file as directed by the template file's `%insert` directive.
121
122This is the mechanism by which a specification file contributes text to the
123generated output file.
124
125### Directives
126
127#### `%define *name* *body*`
128
129Defines a macro identified by the token *name*.  The *body* is separated from
130the *name* by exactly one whitespace character, and extends to the end of the
131line -- it may contain whitespace itself. For example,
132
133  %define test  this body begins and ends with a space character
134
135Macro substitution occurs within a definition region or a section region: a
136substring `%{*name*}` is replaced with the corresponding *body*.  Macro
137substitution is *not* recursive: A substring `%{*name2*}` in *body* will not
138undergo macro substitution, except as discussed for *macro arguments* below.
139
140Permitted in regions: null, conditional, section
141
142##### macro arguments
143
144The more general form of a macro invocation is `%{*name* *arglist*}`, where
145*arglist* is a list of whitespace-separated arguments.  Within the *body*, a
146substring of the form `%{argnum}` will be replaced by the corresponding argument
147from *arglist*.  For example, if the definition is
148
149  %define test second is %{2}, first is %{1}
150
151then the macro invocation
152
153  %{test alpha beta}
154
155is expanded to
156
157  second is beta, first is alpha
158
159The only check on the number of arguments supplied at macro invocation time is
160that there must be at least as many arguments as the highest `%{argnum}`
161reference in the macro body.  In the example above, `%{test alpha}` would be an
162error, but `%{test alpha beta gamma}` would not.
163
164#### `%define-lines *name*`, `%/define-lines`
165
166`%define-lines *name*` creates a *definition region* terminated by
167`%/define-lines`.
168
169Permitted in regions: null, conditional, section
170
171#### `%insert-lines *name*`
172
173Adds all lines from the named definition region to the current section region.
174
175Permitted in regions: section
176
177#### `%kind *list*`, `%else`, `%/kind`
178
179`%kind *list*` creates a *conditional region* terminated by `%/kind`.
180
181The *list* consists of a space-delimited list of tokens, any of which may end in
182`*` to indicate a *wildcard pattern* or `+` to indicate a *lowest version
183pattern*. Any other pattern is a *simple pattern*. The condition is **on** in
184three cases:
185* One of the simple pattern tokens equals the "kind"
186* One of the wildcard pattern tokens less the `*` is a prefix of the "kind"
187* One of the lowest version pattern tokens less the `+` matches the "kind" or
188  the "kind" matches any token to the right from the lowest version pattern in
189  the list passed to %define-kinds
190
191In all other cases, the condition is **off**.
192
193Within the region, the condition is inverted every time the `%else` directive
194appears.
195
196Permitted in regions: null, section
197
198#### `%define-kinds *list*`
199
200This directive has two purposes:
201
202* Validity-checking. If the "kind" is not on the space-delimited *list* of tokens,
203  `generate_api.py` terminates with an error.
204* Ordering the possible kinds for the *lowest version pattern* (see the section
205  above for the explanation of the pattern).
206
207Only one such directive is allowed per specification file.
208
209Permitted in regions: null, section
210
211#### `%section *name*`, `%/section`
212
213`%section *name*` creates a *section region* terminated by `%/section`.
214
215Permitted in regions: null
216