1 /*
  2  * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package oracle.code.onnx.proto;
 27 
 28 import java.io.ByteArrayOutputStream;
 29 import java.nio.charset.StandardCharsets;
 30 import java.util.function.BiConsumer;
 31 import java.util.function.IntSupplier;
 32 
 33 import oracle.code.onnx.proto.OnnxConstants.*;
 34 
 35 // Generated from onnx.in.proto
 36 public sealed class OnnxBuilder<T extends OnnxBuilder> {
 37 
 38     /// Attributes
 39     ///
 40     /// A named attribute containing either singular float, integer, string, graph,
 41     /// and tensor values, or repeated float, integer, string, graph, and tensor values.
 42     /// An AttributeProto MUST contain the name field, and *only one* of the
 43     /// following content fields, effectively enforcing a C/C++ union equivalent.
 44     public static final class AttributeProto extends OnnxBuilder<AttributeProto> {
 45 
 46         /// The name field MUST be present for this version of the IR.
 47         /// namespace Attribute
 48         public AttributeProto name(String name) {return _f(1, name);}
 49 
 50         /// if ref_attr_name is not empty, ref_attr_name is the attribute name in parent function.
 51         /// In this case, this AttributeProto does not contain data, and it's a reference of attribute
 52         /// in parent scope.
 53         /// NOTE: This should ONLY be used in function (sub-graph). It's invalid to be used in main graph.
 54         public AttributeProto refAttrName(String refAttrName) {return _f(21, refAttrName);}
 55 
 56         /// A human-readable documentation for this attribute. Markdown is allowed.
 57         public AttributeProto docString(String docString) {return _f(13, docString);}
 58 
 59         /// The type field MUST be present for this version of the IR.
 60         /// For 0.0.1 versions of the IR, this field was not defined, and
 61         /// implementations needed to use has_field heuristics to determine
 62         /// which value field was in use.  For IR_VERSION 0.0.2 or later, this
 63         /// field MUST be set and match the f|i|s|t|... field in use.  This
 64         /// change was made to accommodate proto3 implementations.
 65         /// discriminator that indicates which field below is in use
 66         public AttributeProto type(AttributeType type) {return _f(20, type);}
 67 
 68         /// Exactly ONE of the following fields must be present for this version of the IR
 69         /// float
 70         public AttributeProto f(float f) {return _f(2, f);}
 71 
 72         /// int
 73         public AttributeProto i(long i) {return _f(3, i);}
 74 
 75         /// UTF-8 string
 76         public AttributeProto s(byte[] s) {return _f(4, s);}
 77 
 78         /// tensor value
 79         public AttributeProto t(TensorProto t) {return _f(5, t);}
 80 
 81         /// graph
 82         public AttributeProto g(GraphProto g) {return _f(6, g);}
 83 
 84         /// sparse tensor value
 85         public AttributeProto sparseTensor(SparseTensorProto sparseTensor) {return _f(22, sparseTensor);}
 86 
 87         /// Do not use field below, it's deprecated.
 88         /// optional ValueProto v = 12;         // value - subsumes everything but graph
 89         /// type proto
 90         public AttributeProto tp(TypeProto tp) {return _f(14, tp);}
 91 
 92         /// list of floats
 93         public AttributeProto floats(float... floats) {return _f(7, floats);}
 94 
 95         /// list of ints
 96         public AttributeProto ints(long... ints) {return _f(8, ints);}
 97 
 98         /// list of UTF-8 strings
 99         public AttributeProto strings(byte[] strings) {return _f(9, strings);}
100 
101         /// list of tensors
102         public AttributeProto tensors(TensorProto tensors) {return _f(10, tensors);}
103 
104         /// list of graph
105         public AttributeProto graphs(GraphProto graphs) {return _f(11, graphs);}
106 
107         /// list of sparse tensors
108         public AttributeProto sparseTensors(SparseTensorProto sparseTensors) {return _f(23, sparseTensors);}
109 
110         /// list of type protos
111         public AttributeProto typeProtos(TypeProto typeProtos) {return _f(15, typeProtos);}
112     }
113 
114     /// Defines information on value, including the name, the type, and
115     /// the shape of the value.
116     public static final class ValueInfoProto extends OnnxBuilder<ValueInfoProto> {
117 
118         /// This field MUST be present in this version of the IR.
119         /// namespace Value
120         public ValueInfoProto name(String name) {return _f(1, name);}
121 
122         /// This field MUST be present in this version of the IR for
123         /// inputs and outputs of the top-level graph.
124         public ValueInfoProto type(TypeProto type) {return _f(2, type);}
125 
126         /// A human-readable documentation for this value. Markdown is allowed.
127         public ValueInfoProto docString(String docString) {return _f(3, docString);}
128 
129         /// Named metadata values; keys should be distinct.
130         public ValueInfoProto metadataProps(StringStringEntryProto metadataProps) {return _f(4, metadataProps);}
131     }
132 
133     /// Nodes
134     ///
135     /// Computation graphs are made up of a DAG of nodes, which represent what is
136     /// commonly called a "layer" or "pipeline stage" in machine learning frameworks.
137     ///
138     /// For example, it can be a node of type "Conv" that takes in an image, a filter
139     /// tensor and a bias tensor, and produces the convolved output.
140     public static final class NodeProto extends OnnxBuilder<NodeProto> {
141 
142         /// namespace Value
143         public NodeProto input(String input) {return _f(1, input);}
144 
145         /// namespace Value
146         public NodeProto output(String output) {return _f(2, output);}
147 
148         /// An optional identifier for this node in a graph.
149         /// This field MAY be absent in this version of the IR.
150         /// namespace Node
151         public NodeProto name(String name) {return _f(3, name);}
152 
153         /// The symbolic identifier of the Operator to execute.
154         /// namespace Operator
155         public NodeProto opType(String opType) {return _f(4, opType);}
156 
157         /// The domain of the OperatorSet that specifies the operator named by op_type.
158         /// namespace Domain
159         public NodeProto domain(String domain) {return _f(7, domain);}
160 
161         /// Overload identifier, used only to map this to a model-local function.
162         public NodeProto overload(String overload) {return _f(8, overload);}
163 
164         /// Additional named attributes.
165         public NodeProto attribute(AttributeProto attribute) {return _f(5, attribute);}
166 
167         /// A human-readable documentation for this node. Markdown is allowed.
168         public NodeProto docString(String docString) {return _f(6, docString);}
169 
170         /// Named metadata values; keys should be distinct.
171         public NodeProto metadataProps(StringStringEntryProto metadataProps) {return _f(9, metadataProps);}
172 
173         /// Configuration of multi-device annotations.
174         public NodeProto deviceConfigurations(NodeDeviceConfigurationProto deviceConfigurations) {return _f(10, deviceConfigurations);}
175     }
176 
177     /// IntIntListEntryProto follows the pattern for cross-proto-version maps.
178     /// See https://developers.google.com/protocol-buffers/docs/proto3#maps
179     public static final class IntIntListEntryProto extends OnnxBuilder<IntIntListEntryProto> {
180 
181         public IntIntListEntryProto key(long key) {return _f(1, key);}
182 
183         public IntIntListEntryProto value(long... value) {return _f(2, value);}
184     }
185 
186     /// Multi-device configuration proto for NodeProto.
187     public static final class NodeDeviceConfigurationProto extends OnnxBuilder<NodeDeviceConfigurationProto> {
188 
189         /// This field MUST be present for this version of the IR.
190         /// ID of the configuration. MUST match the name of a DeviceConfigurationProto.
191         public NodeDeviceConfigurationProto configurationId(String configurationId) {return _f(1, configurationId);}
192 
193         /// Sharding spec for the node.
194         public NodeDeviceConfigurationProto shardingSpec(ShardingSpecProto shardingSpec) {return _f(2, shardingSpec);}
195 
196         /// Pipeline stage of this node.
197         public NodeDeviceConfigurationProto pipelineStage(int pipelineStage) {return _f(3, pipelineStage);}
198     }
199 
200     /// ShardingSpecProto: This describes the sharding spec for a specific
201     /// input or output tensor of a node.
202     public static final class ShardingSpecProto extends OnnxBuilder<ShardingSpecProto> {
203 
204         /// This field MUST be present for this version of the IR.
205         /// Identifies the input or output of the node that is being sharded.
206         /// Required to match a name specified in the node's input or output list of ValueInfoProtos.
207         /// It is called `logical tensor` in subsequent descriptions.
208         public ShardingSpecProto tensorName(String tensorName) {return _f(1, tensorName);}
209 
210         /// The following is the list of devices across which the logical
211         /// tensor is sharded or replicated.
212         public ShardingSpecProto device(long... device) {return _f(2, device);}
213 
214         /// Each element v in above field devices may represent either a
215         /// device or a set of devices (when we want the same shard/tensor
216         /// to be replicated across a subset of devices), as indicated by
217         /// the following optional map. If the map contains an entry for v,
218         /// then v represents a device group, and the map indicates the set
219         /// of devices in that group.
220         public ShardingSpecProto indexToDeviceGroupMap(IntIntListEntryProto indexToDeviceGroupMap) {return _f(3, indexToDeviceGroupMap);}
221 
222         /// The following is the sharded-shape of the tensor, consisting of
223         /// the sharding-spec for each axis of the tensor.
224         public ShardingSpecProto shardedDim(ShardedDimProto shardedDim) {return _f(4, shardedDim);}
225     }
226 
227     /// ShardedDimProto: This describes the sharding spec for a single
228     /// axis of a sharded tensor.
229     public static final class ShardedDimProto extends OnnxBuilder<ShardedDimProto> {
230 
231         /// This field MUST be present for this version of the IR.
232         /// The axis this sharding corresponds to. Must be in the range of
233         /// [-r, r - 1], where r is the rank of the tensor. Negative axis values means
234         /// counting from the back.
235         public ShardedDimProto axis(long axis) {return _f(1, axis);}
236 
237         /// Describes how the tensor on the provided axis is sharded.
238         /// The common-case is described by a single instance of SimpleShardedDimProto.
239         /// Multiple instances can be used to handle cases where a sharded
240         /// tensor is reshaped, fusing multiple axes into one.
241         public ShardedDimProto simpleSharding(SimpleShardedDimProto simpleSharding) {return _f(2, simpleSharding);}
242     }
243 
244     /// SimpleShardedDimProto: Indicates that N blocks are divided into M shards.
245     /// N is allowed to be symbolic where M is required to be a constant.
246     public static final class SimpleShardedDimProto extends OnnxBuilder<SimpleShardedDimProto> {
247 
248         /// Dimension value to be sharded.
249         public SimpleShardedDimProto dimValue(long dimValue) {return _f(1, dimValue);}
250 
251         public SimpleShardedDimProto dimParam(String dimParam) {return _f(2, dimParam);}
252 
253         /// This field MUST be present for this version of the IR.
254         /// Number of shards to split dim into.
255         public SimpleShardedDimProto numShards(long numShards) {return _f(3, numShards);}
256     }
257 
258     /// Training information
259     /// TrainingInfoProto stores information for training a model.
260     /// In particular, this defines two functionalities: an initialization-step
261     /// and a training-algorithm-step. Initialization resets the model
262     /// back to its original state as if no training has been performed.
263     /// Training algorithm improves the model based on input data.
264     ///
265     /// The semantics of the initialization-step is that the initializers
266     /// in ModelProto.graph and in TrainingInfoProto.algorithm are first
267     /// initialized as specified by the initializers in the graph, and then
268     /// updated by the "initialization_binding" in every instance in
269     /// ModelProto.training_info.
270     ///
271     /// The field "algorithm" defines a computation graph which represents a
272     /// training algorithm's step. After the execution of a
273     /// TrainingInfoProto.algorithm, the initializers specified by "update_binding"
274     /// may be immediately updated. If the targeted training algorithm contains
275     /// consecutive update steps (such as block coordinate descent methods),
276     /// the user needs to create a TrainingInfoProto for each step.
277     public static final class TrainingInfoProto extends OnnxBuilder<TrainingInfoProto> {
278 
279         /// This field describes a graph to compute the initial tensors
280         /// upon starting the training process. Initialization graph has no input
281         /// and can have multiple outputs. Usually, trainable tensors in neural
282         /// networks are randomly initialized. To achieve that, for each tensor,
283         /// the user can put a random number operator such as RandomNormal or
284         /// RandomUniform in TrainingInfoProto.initialization.node and assign its
285         /// random output to the specific tensor using "initialization_binding".
286         /// This graph can also set the initializers in "algorithm" in the same
287         /// TrainingInfoProto; a use case is resetting the number of training
288         /// iteration to zero.
289         ///
290         /// By default, this field is an empty graph and its evaluation does not
291         /// produce any output. Thus, no initializer would be changed by default.
292         public TrainingInfoProto initialization(GraphProto initialization) {return _f(1, initialization);}
293 
294         /// This field represents a training algorithm step. Given required inputs,
295         /// it computes outputs to update initializers in its own or inference graph's
296         /// initializer lists. In general, this field contains loss node, gradient node,
297         /// optimizer node, increment of iteration count.
298         ///
299         /// An execution of the training algorithm step is performed by executing the
300         /// graph obtained by combining the inference graph (namely "ModelProto.graph")
301         /// and the "algorithm" graph. That is, the actual
302         /// input/initializer/output/node/value_info/sparse_initializer list of
303         /// the training graph is the concatenation of
304         /// "ModelProto.graph.input/initializer/output/node/value_info/sparse_initializer"
305         /// and "algorithm.input/initializer/output/node/value_info/sparse_initializer"
306         /// in that order. This combined graph must satisfy the normal ONNX conditions.
307         /// Now, let's provide a visualization of graph combination for clarity.
308         /// Let the inference graph (i.e., "ModelProto.graph") be
309         ///    tensor_a, tensor_b -> MatMul -> tensor_c -> Sigmoid -> tensor_d
310         /// and the "algorithm" graph be
311         ///    tensor_d -> Add -> tensor_e
312         /// The combination process results
313         ///    tensor_a, tensor_b -> MatMul -> tensor_c -> Sigmoid -> tensor_d -> Add -> tensor_e
314         ///
315         /// Notice that an input of a node in the "algorithm" graph may reference the
316         /// output of a node in the inference graph (but not the other way round). Also, inference
317         /// node cannot reference inputs of "algorithm". With these restrictions, inference graph
318         /// can always be run independently without training information.
319         ///
320         /// By default, this field is an empty graph and its evaluation does not
321         /// produce any output. Evaluating the default training step never
322         /// update any initializers.
323         public TrainingInfoProto algorithm(GraphProto algorithm) {return _f(2, algorithm);}
324 
325         /// This field specifies the bindings from the outputs of "initialization" to
326         /// some initializers in "ModelProto.graph.initializer" and
327         /// the "algorithm.initializer" in the same TrainingInfoProto.
328         /// See "update_binding" below for details.
329         ///
330         /// By default, this field is empty and no initializer would be changed
331         /// by the execution of "initialization".
332         public TrainingInfoProto initializationBinding(StringStringEntryProto initializationBinding) {return _f(3, initializationBinding);}
333 
334         /// Gradient-based training is usually an iterative procedure. In one gradient
335         /// descent iteration, we apply
336         ///
337         /// x = x - r * g
338         ///
339         /// where "x" is the optimized tensor, "r" stands for learning rate, and "g" is
340         /// gradient of "x" with respect to a chosen loss. To avoid adding assignments
341         /// into the training graph, we split the update equation into
342         ///
343         /// y = x - r * g
344         /// x = y
345         ///
346         /// The user needs to save "y = x - r * g" into TrainingInfoProto.algorithm. To
347         /// tell that "y" should be assigned to "x", the field "update_binding" may
348         /// contain a key-value pair of strings, "x" (key of StringStringEntryProto)
349         /// and "y" (value of StringStringEntryProto).
350         /// For a neural network with multiple trainable (mutable) tensors, there can
351         /// be multiple key-value pairs in "update_binding".
352         ///
353         /// The initializers appears as keys in "update_binding" are considered
354         /// mutable variables. This implies some behaviors
355         /// as described below.
356         ///
357         ///  1. We have only unique keys in all "update_binding"s so that two
358         ///     variables may not have the same name. This ensures that one
359         ///     variable is assigned up to once.
360         ///  2. The keys must appear in names of "ModelProto.graph.initializer" or
361         ///     "TrainingInfoProto.algorithm.initializer".
362         ///  3. The values must be output names of "algorithm" or "ModelProto.graph.output".
363         ///  4. Mutable variables are initialized to the value specified by the
364         ///     corresponding initializer, and then potentially updated by
365         ///     "initializer_binding"s and "update_binding"s in "TrainingInfoProto"s.
366         ///
367         /// This field usually contains names of trainable tensors
368         /// (in ModelProto.graph), optimizer states such as momentums in advanced
369         /// stochastic gradient methods (in TrainingInfoProto.graph),
370         /// and number of training iterations (in TrainingInfoProto.graph).
371         ///
372         /// By default, this field is empty and no initializer would be changed
373         /// by the execution of "algorithm".
374         public TrainingInfoProto updateBinding(StringStringEntryProto updateBinding) {return _f(4, updateBinding);}
375     }
376 
377     /// Models
378     ///
379     /// ModelProto is a top-level file/container format for bundling a ML model and
380     /// associating its computation graph with metadata.
381     ///
382     /// The semantics of the model are described by the associated GraphProto's.
383     public static final class ModelProto extends OnnxBuilder<ModelProto> {
384 
385         /// The version of the IR this model targets. See Version enum above.
386         /// This field MUST be present.
387         public ModelProto irVersion(long irVersion) {return _f(1, irVersion);}
388 
389         /// The OperatorSets this model relies on.
390         /// All ModelProtos MUST have at least one entry that
391         /// specifies which version of the ONNX OperatorSet is
392         /// being imported.
393         ///
394         /// All nodes in the ModelProto's graph will bind against the operator
395         /// with the same-domain/same-op_type operator with the HIGHEST version
396         /// in the referenced operator sets.
397         public ModelProto opsetImport(OperatorSetIdProto opsetImport) {return _f(8, opsetImport);}
398 
399         /// The name of the framework or tool used to generate this model.
400         /// This field SHOULD be present to indicate which implementation/tool/framework
401         /// emitted the model.
402         public ModelProto producerName(String producerName) {return _f(2, producerName);}
403 
404         /// The version of the framework or tool used to generate this model.
405         /// This field SHOULD be present to indicate which implementation/tool/framework
406         /// emitted the model.
407         public ModelProto producerVersion(String producerVersion) {return _f(3, producerVersion);}
408 
409         /// Domain name of the model.
410         /// We use reverse domain names as name space indicators. For example:
411         /// `com.facebook.fair` or `com.microsoft.cognitiveservices`
412         ///
413         /// Together with `model_version` and GraphProto.name, this forms the unique identity of
414         /// the graph.
415         public ModelProto domain(String domain) {return _f(4, domain);}
416 
417         /// The version of the graph encoded. See Version enum below.
418         public ModelProto modelVersion(long modelVersion) {return _f(5, modelVersion);}
419 
420         /// A human-readable documentation for this model. Markdown is allowed.
421         public ModelProto docString(String docString) {return _f(6, docString);}
422 
423         /// The parameterized graph that is evaluated to execute the model.
424         public ModelProto graph(GraphProto graph) {return _f(7, graph);}
425 
426         /// Named metadata values; keys should be distinct.
427         public ModelProto metadataProps(StringStringEntryProto metadataProps) {return _f(14, metadataProps);}
428 
429         /// Training-specific information. Sequentially executing all stored
430         /// `TrainingInfoProto.algorithm`s and assigning their outputs following
431         /// the corresponding `TrainingInfoProto.update_binding`s is one training
432         /// iteration. Similarly, to initialize the model
433         /// (as if training hasn't happened), the user should sequentially execute
434         /// all stored `TrainingInfoProto.initialization`s and assigns their outputs
435         /// using `TrainingInfoProto.initialization_binding`s.
436         ///
437         /// If this field is empty, the training behavior of the model is undefined.
438         public ModelProto trainingInfo(TrainingInfoProto trainingInfo) {return _f(20, trainingInfo);}
439 
440         /// A list of function protos local to the model.
441         ///
442         /// The (domain, name, overload) tuple must be unique across the function protos in this list.
443         /// In case of any conflicts the behavior (whether the model local functions are given higher priority,
444         /// or standard operator sets are given higher priority or this is treated as error) is defined by
445         /// the runtimes.
446         ///
447         /// The operator sets imported by FunctionProto should be compatible with the ones
448         /// imported by ModelProto and other model local FunctionProtos.
449         /// Example, if same operator set say 'A' is imported by a FunctionProto and ModelProto
450         /// or by 2 FunctionProtos then versions for the operator set may be different but,
451         /// the operator schema returned for op_type, domain, version combination
452         /// for both the versions should be same for every node in the function body.
453         ///
454         /// One FunctionProto can reference other FunctionProto in the model, however, recursive reference
455         /// is not allowed.
456         public ModelProto functions(FunctionProto functions) {return _f(25, functions);}
457 
458         /// Describes different target configurations for a multi-device use case.
459         /// A model MAY describe multiple multi-device configurations for execution.
460         public ModelProto configuration(DeviceConfigurationProto configuration) {return _f(26, configuration);}
461     }
462 
463     /// DeviceConfigurationProto describes a multi-device configuration for a model.
464     public static final class DeviceConfigurationProto extends OnnxBuilder<DeviceConfigurationProto> {
465 
466         /// This field MUST be present for this version of the IR.
467         /// Name of the configuration.
468         public DeviceConfigurationProto name(String name) {return _f(1, name);}
469 
470         /// This field MUST be present for this version of the IR.
471         /// Number of devices inside this configuration.
472         public DeviceConfigurationProto numDevices(int numDevices) {return _f(2, numDevices);}
473 
474         /// Optional names of the devices. MUST be length of num_devices if provided.
475         public DeviceConfigurationProto device(String device) {return _f(3, device);}
476     }
477 
478     /// StringStringEntryProto follows the pattern for cross-proto-version maps.
479     /// See https://developers.google.com/protocol-buffers/docs/proto3#maps
480     public static final class StringStringEntryProto extends OnnxBuilder<StringStringEntryProto> {
481 
482         public StringStringEntryProto key(String key) {return _f(1, key);}
483 
484         public StringStringEntryProto value(String value) {return _f(2, value);}
485     }
486 
487     public static final class TensorAnnotation extends OnnxBuilder<TensorAnnotation> {
488 
489         public TensorAnnotation tensorName(String tensorName) {return _f(1, tensorName);}
490 
491         /// <key, value> pairs to annotate tensor specified by <tensor_name> above.
492         /// The keys used in the mapping below must be pre-defined in ONNX spec.
493         /// For example, for 8-bit linear quantization case, 'SCALE_TENSOR', 'ZERO_POINT_TENSOR' will be pre-defined as
494         /// quantization parameter keys.
495         public TensorAnnotation quantParameterTensorNames(StringStringEntryProto quantParameterTensorNames) {return _f(2, quantParameterTensorNames);}
496     }
497 
498     /// Graphs
499     ///
500     /// A graph defines the computational logic of a model and is comprised of a parameterized
501     /// list of nodes that form a directed acyclic graph based on their inputs and outputs.
502     /// This is the equivalent of the "network" or "graph" in many deep learning
503     /// frameworks.
504     public static final class GraphProto extends OnnxBuilder<GraphProto> {
505 
506         /// The nodes in the graph, sorted topologically.
507         public GraphProto node(NodeProto node) {return _f(1, node);}
508 
509         /// The name of the graph.
510         /// namespace Graph
511         public GraphProto name(String name) {return _f(2, name);}
512 
513         /// A list of named tensor values, used to specify constant inputs of the graph.
514         /// Each initializer (both TensorProto as well SparseTensorProto) MUST have a name.
515         /// The name MUST be unique across both initializer and sparse_initializer,
516         /// but the name MAY also appear in the input list.
517         public GraphProto initializer(TensorProto initializer) {return _f(5, initializer);}
518 
519         /// Initializers (see above) stored in sparse format.
520         public GraphProto sparseInitializer(SparseTensorProto sparseInitializer) {return _f(15, sparseInitializer);}
521 
522         /// A human-readable documentation for this graph. Markdown is allowed.
523         public GraphProto docString(String docString) {return _f(10, docString);}
524 
525         /// The inputs and outputs of the graph.
526         public GraphProto input(ValueInfoProto input) {return _f(11, input);}
527 
528         public GraphProto output(ValueInfoProto output) {return _f(12, output);}
529 
530         /// Information for the values in the graph. The ValueInfoProto.name's
531         /// must be distinct. It is optional for a value to appear in value_info list.
532         public GraphProto valueInfo(ValueInfoProto valueInfo) {return _f(13, valueInfo);}
533 
534         /// This field carries information to indicate the mapping among a tensor and its
535         /// quantization parameter tensors. For example:
536         /// For tensor 'a', it may have {'SCALE_TENSOR', 'a_scale'} and {'ZERO_POINT_TENSOR', 'a_zero_point'} annotated,
537         /// which means, tensor 'a_scale' and tensor 'a_zero_point' are scale and zero point of tensor 'a' in the model.
538         public GraphProto quantizationAnnotation(TensorAnnotation quantizationAnnotation) {return _f(14, quantizationAnnotation);}
539 
540         /// Named metadata values; keys should be distinct.
541         public GraphProto metadataProps(StringStringEntryProto metadataProps) {return _f(16, metadataProps);}
542     }
543 
544     /// Tensors
545     ///
546     /// A serialized tensor value.
547     public static final class TensorProto extends OnnxBuilder<TensorProto> {
548 
549         /// The shape of the tensor.
550         public TensorProto dims(long... dims) {return _f(1, dims);}
551 
552         /// The data type of the tensor.
553         /// This field MUST have a valid TensorProto.DataType value
554         public TensorProto dataType(int dataType) {return _f(2, dataType);}
555 
556         /// For very large tensors, we may want to store them in chunks, in which
557         /// case the following fields will specify the segment that is stored in
558         /// the current TensorProto.
559         public static final class Segment extends OnnxBuilder<Segment> {
560 
561             public Segment begin(long begin) {return _f(1, begin);}
562 
563             public Segment end(long end) {return _f(2, end);}
564         }
565 
566         public TensorProto segment(Segment segment) {return _f(3, segment);}
567 
568         /// For float and complex64 values
569         /// Complex64 tensors are encoded as a single array of floats,
570         /// with the real components appearing in odd numbered positions,
571         /// and the corresponding imaginary component appearing in the
572         /// subsequent even numbered position. (e.g., [1.0 + 2.0i, 3.0 + 4.0i]
573         /// is encoded as [1.0, 2.0 ,3.0 ,4.0]
574         /// When this field is present, the data_type field MUST be FLOAT or COMPLEX64.
575         public TensorProto floatData(float... floatData) {return _f(4, floatData);}
576 
577         /// For int32, uint8, int8, uint16, int16, uint4, int4, bool, (b)float16, float8, and float4:
578         /// - (b)float16 and float8 values MUST be converted bit-wise into an unsigned integer
579         ///   representation before being written to the buffer.
580         /// - Each pair of uint4, int4, and float4 values MUST be packed as two 4-bit elements into a single byte.
581         ///   The first element is stored in the 4 least significant bits (LSB),
582         ///   and the second element is stored in the 4 most significant bits (MSB).
583         ///
584         /// Consequently:
585         /// - For data types with a bit-width of 8 or greater, each `int32_data` stores one element.
586         /// - For 4-bit data types, each `int32_data` stores two elements.
587         ///
588         /// When this field is present, the data_type field MUST be
589         /// INT32, INT16, INT8, INT4, UINT16, UINT8, UINT4, BOOL, FLOAT16, BFLOAT16, FLOAT8E4M3FN, FLOAT8E4M3FNUZ, FLOAT8E5M2, FLOAT8E5M2FNUZ, FLOAT8E8M0, FLOAT4E2M1
590         public TensorProto int32Data(int... int32Data) {return _f(5, int32Data);}
591 
592         /// For strings.
593         /// Each element of string_data is a UTF-8 encoded Unicode
594         /// string. No trailing null, no leading BOM. The protobuf "string"
595         /// scalar type is not used to match ML community conventions.
596         /// When this field is present, the data_type field MUST be STRING
597         public TensorProto stringData(byte[] stringData) {return _f(6, stringData);}
598 
599         /// For int64.
600         /// When this field is present, the data_type field MUST be INT64
601         public TensorProto int64Data(long... int64Data) {return _f(7, int64Data);}
602 
603         /// Optionally, a name for the tensor.
604         /// namespace Value
605         public TensorProto name(String name) {return _f(8, name);}
606 
607         /// A human-readable documentation for this tensor. Markdown is allowed.
608         public TensorProto docString(String docString) {return _f(12, docString);}
609 
610         /// Serializations can either use one of the fields above, or use this
611         /// raw bytes field. The only exception is the string case, where one is
612         /// required to store the content in the repeated bytes string_data field.
613         ///
614         /// When this raw_data field is used to store tensor value, elements MUST
615         /// be stored in as fixed-width, little-endian order.
616         /// Floating-point data types MUST be stored in IEEE 754 format.
617         /// Complex64 elements must be written as two consecutive FLOAT values, real component first.
618         /// Complex128 elements must be written as two consecutive DOUBLE values, real component first.
619         /// Boolean type MUST be written one byte per tensor element (00000001 for true, 00000000 for false).
620         /// uint4 and int4 values must be packed to 4bitx2, the first element is stored in the 4 LSB and the second element is stored in the 4 MSB.
621         ///
622         /// Note: the advantage of specific field rather than the raw_data field is
623         /// that in some cases (e.g. int data), protobuf does a better packing via
624         /// variable length storage, and may lead to smaller binary footprint.
625         /// When this field is present, the data_type field MUST NOT be STRING or UNDEFINED
626         public TensorProto rawData(byte[] rawData) {return _f(9, rawData);}
627 
628         /// Data can be stored inside the protobuf file using type-specific fields or raw_data.
629         /// Alternatively, raw bytes data can be stored in an external file, using the external_data field.
630         /// external_data stores key-value pairs describing data location. Recognized keys are:
631         /// - "location" (required) - POSIX filesystem path relative to the directory where the ONNX
632         ///                           protobuf model was stored
633         /// - "offset" (optional) - position of byte at which stored data begins. Integer stored as string.
634         ///                         Offset values SHOULD be multiples 4096 (page size) to enable mmap support.
635         /// - "length" (optional) - number of bytes containing data. Integer stored as string.
636         /// - "checksum" (optional) - SHA1 digest of file specified in under 'location' key.
637         public TensorProto externalData(StringStringEntryProto externalData) {return _f(13, externalData);}
638 
639         /// If value not set, data is stored in raw_data (if set) otherwise in type-specified field.
640         public TensorProto dataLocation(DataLocation dataLocation) {return _f(14, dataLocation);}
641 
642         /// For double
643         /// Complex128 tensors are encoded as a single array of doubles,
644         /// with the real components appearing in odd numbered positions,
645         /// and the corresponding imaginary component appearing in the
646         /// subsequent even numbered position. (e.g., [1.0 + 2.0i, 3.0 + 4.0i]
647         /// is encoded as [1.0, 2.0 ,3.0 ,4.0]
648         /// When this field is present, the data_type field MUST be DOUBLE or COMPLEX128
649         public TensorProto doubleData(double... doubleData) {return _f(10, doubleData);}
650 
651         /// For uint64 and uint32 values
652         /// When this field is present, the data_type field MUST be
653         /// UINT32 or UINT64
654         public TensorProto uint64Data(long... uint64Data) {return _f(11, uint64Data);}
655 
656         /// Named metadata values; keys should be distinct.
657         public TensorProto metadataProps(StringStringEntryProto metadataProps) {return _f(16, metadataProps);}
658     }
659 
660     /// A serialized sparse-tensor value
661     public static final class SparseTensorProto extends OnnxBuilder<SparseTensorProto> {
662 
663         /// The sequence of non-default values are encoded as a tensor of shape [NNZ].
664         /// The default-value is zero for numeric tensors, and empty-string for string tensors.
665         /// values must have a non-empty name present which serves as a name for SparseTensorProto
666         /// when used in sparse_initializer list.
667         public SparseTensorProto values(TensorProto values) {return _f(1, values);}
668 
669         /// The indices of the non-default values, which may be stored in one of two formats.
670         /// (a) Indices can be a tensor of shape [NNZ, rank] with the [i,j]-th value
671         /// corresponding to the j-th index of the i-th value (in the values tensor).
672         /// (b) Indices can be a tensor of shape [NNZ], in which case the i-th value
673         /// must be the linearized-index of the i-th value (in the values tensor).
674         /// The linearized-index can be converted into an index tuple (k_1,...,k_rank)
675         /// using the shape provided below.
676         /// The indices must appear in ascending order without duplication.
677         /// In the first format, the ordering is lexicographic-ordering:
678         /// e.g., index-value [1,4] must appear before [2,1]
679         public SparseTensorProto indices(TensorProto indices) {return _f(2, indices);}
680 
681         /// The shape of the underlying dense-tensor: [dim_1, dim_2, ... dim_rank]
682         public SparseTensorProto dims(long... dims) {return _f(3, dims);}
683     }
684 
685     /// Defines a tensor shape. A dimension can be either an integer value
686     /// or a symbolic variable. A symbolic variable represents an unknown
687     /// dimension.
688     public static final class TensorShapeProto extends OnnxBuilder<TensorShapeProto> {
689 
690         public static final class Dimension extends OnnxBuilder<Dimension> {
691 
692             public Dimension dimValue(long dimValue) {return _f(1, dimValue);}
693 
694             /// namespace Shape
695             public Dimension dimParam(String dimParam) {return _f(2, dimParam);}
696 
697             /// Standard denotation can optionally be used to denote tensor
698             /// dimensions with standard semantic descriptions to ensure
699             /// that operations are applied to the correct axis of a tensor.
700             /// Refer to https://github.com/onnx/onnx/blob/main/docs/DimensionDenotation.md#denotation-definition
701             /// for pre-defined dimension denotations.
702             public Dimension denotation(String denotation) {return _f(3, denotation);}
703         }
704 
705         public TensorShapeProto dim(Dimension dim) {return _f(1, dim);}
706     }
707 
708     /// Types
709     ///
710     /// The standard ONNX data types.
711     public static final class TypeProto extends OnnxBuilder<TypeProto> {
712 
713         public static final class Tensor extends OnnxBuilder<Tensor> {
714 
715             /// This field MUST NOT have the value of UNDEFINED
716             /// This field MUST have a valid TensorProto.DataType value
717             /// This field MUST be present for this version of the IR.
718             public Tensor elemType(int elemType) {return _f(1, elemType);}
719 
720             public Tensor shape(TensorShapeProto shape) {return _f(2, shape);}
721         }
722 
723         /// repeated T
724         public static final class Sequence extends OnnxBuilder<Sequence> {
725 
726             /// The type and optional shape of each element of the sequence.
727             /// This field MUST be present for this version of the IR.
728             public Sequence elemType(TypeProto elemType) {return _f(1, elemType);}
729         }
730 
731         /// map<K,V>
732         public static final class Map extends OnnxBuilder<Map> {
733 
734             /// This field MUST have a valid TensorProto.DataType value
735             /// This field MUST be present for this version of the IR.
736             /// This field MUST refer to an integral type ([U]INT{8|16|32|64}) or STRING
737             public Map keyType(int keyType) {return _f(1, keyType);}
738 
739             /// This field MUST be present for this version of the IR.
740             public Map valueType(TypeProto valueType) {return _f(2, valueType);}
741         }
742 
743         /// wrapper for Tensor, Sequence, or Map
744         public static final class Optional extends OnnxBuilder<Optional> {
745 
746             /// The type and optional shape of the element wrapped.
747             /// This field MUST be present for this version of the IR.
748             /// Possible values correspond to OptionalProto.DataType enum
749             public Optional elemType(TypeProto elemType) {return _f(1, elemType);}
750         }
751 
752         public static final class SparseTensor extends OnnxBuilder<SparseTensor> {
753 
754             /// This field MUST NOT have the value of UNDEFINED
755             /// This field MUST have a valid TensorProto.DataType value
756             /// This field MUST be present for this version of the IR.
757             public SparseTensor elemType(int elemType) {return _f(1, elemType);}
758 
759             public SparseTensor shape(TensorShapeProto shape) {return _f(2, shape);}
760         }
761 
762         public static final class Opaque extends OnnxBuilder<Opaque> {
763 
764             /// When missing, the domain is the same as the model's.
765             public Opaque domain(String domain) {return _f(1, domain);}
766 
767             /// The name is optional but significant when provided.
768             public Opaque name(String name) {return _f(2, name);}
769         }
770 
771         /// The type of a tensor.
772         public TypeProto tensorType(Tensor tensorType) {return _f(1, tensorType);}
773 
774         /// The type of a sequence.
775         public TypeProto sequenceType(Sequence sequenceType) {return _f(4, sequenceType);}
776 
777         /// The type of a map.
778         public TypeProto mapType(Map mapType) {return _f(5, mapType);}
779 
780         /// The type of an optional.
781         public TypeProto optionalType(Optional optionalType) {return _f(9, optionalType);}
782 
783         /// Type of the sparse tensor
784         public TypeProto sparseTensorType(SparseTensor sparseTensorType) {return _f(8, sparseTensorType);}
785 
786         public TypeProto opaqueType(Opaque opaqueType) {return _f(7, opaqueType);}
787 
788         /// An optional denotation can be used to denote the whole
789         /// type with a standard semantic description as to what is
790         /// stored inside. Refer to https://github.com/onnx/onnx/blob/main/docs/TypeDenotation.md#type-denotation-definition
791         /// for pre-defined type denotations.
792         public TypeProto denotation(String denotation) {return _f(6, denotation);}
793     }
794 
795     /// Operator Sets
796     ///
797     /// OperatorSets are uniquely identified by a (domain, opset_version) pair.
798     public static final class OperatorSetIdProto extends OnnxBuilder<OperatorSetIdProto> {
799 
800         /// The domain of the operator set being identified.
801         /// The empty string ("") or absence of this field implies the operator
802         /// set that is defined as part of the ONNX specification.
803         /// This field MUST be present in this version of the IR when referring to any other operator set.
804         public OperatorSetIdProto domain(String domain) {return _f(1, domain);}
805 
806         /// The version of the operator set being identified.
807         /// This field MUST be present in this version of the IR.
808         public OperatorSetIdProto version(long version) {return _f(2, version);}
809     }
810 
811     public static final class FunctionProto extends OnnxBuilder<FunctionProto> {
812 
813         /// The name of the function, similar to op_type in NodeProto.
814         /// This is part of the unique-id (domain, name, overload) of FunctionProtos in a model.
815         public FunctionProto name(String name) {return _f(1, name);}
816 
817         /// The inputs and outputs of the function.
818         public FunctionProto input(String input) {return _f(4, input);}
819 
820         public FunctionProto output(String output) {return _f(5, output);}
821 
822         /// The attribute parameters of the function.
823         /// It is for function parameters without default values.
824         public FunctionProto attribute(String attribute) {return _f(6, attribute);}
825 
826         /// The attribute protos of the function.
827         /// It is for function attributes with default values.
828         /// A function attribute shall be represented either as
829         /// a string attribute or an AttributeProto, not both.
830         public FunctionProto attributeProto(AttributeProto attributeProto) {return _f(11, attributeProto);}
831 
832         /// The nodes in the function.
833         public FunctionProto node(NodeProto node) {return _f(7, node);}
834 
835         /// A human-readable documentation for this function. Markdown is allowed.
836         public FunctionProto docString(String docString) {return _f(8, docString);}
837 
838         public FunctionProto opsetImport(OperatorSetIdProto opsetImport) {return _f(9, opsetImport);}
839 
840         /// The domain which this function belongs to.
841         /// This is part of the unique-id (domain, name, overload) of FunctionProtos in a model.
842         public FunctionProto domain(String domain) {return _f(10, domain);}
843 
844         /// The overload identifier of the function.
845         /// This is part of the unique-id (domain, name, overload) of FunctionProtos in a model.
846         public FunctionProto overload(String overload) {return _f(13, overload);}
847 
848         /// Information for the values in the function. The ValueInfoProto.name's
849         /// must be distinct and refer to names in the function (including inputs,
850         /// outputs, and intermediate values). It is optional for a value to appear
851         /// in value_info list.
852         public FunctionProto valueInfo(ValueInfoProto valueInfo) {return _f(12, valueInfo);}
853 
854         /// Named metadata values; keys should be distinct.
855         public FunctionProto metadataProps(StringStringEntryProto metadataProps) {return _f(14, metadataProps);}
856     }
857 
858     // Implementation
859 
860     final ByteArrayOutputStream buf = new ByteArrayOutputStream();
861 
862     public byte[] getBytes() {
863         return buf.toByteArray();
864     }
865 
866     @SuppressWarnings("unchecked")
867     public <P> T forEach(Iterable<P> sup, BiConsumer<T, ? super P> cons) {
868         sup.forEach(p -> cons.accept((T)this, p));
869         return (T)this;
870     }
871 
872     void _encode(long number) {
873         for (int i = 64 - Long.numberOfLeadingZeros(number); i > 7; i -= 7) {
874             buf.write(0x80 | (int)number & 0x7f);
875             number >>= 7;
876         }
877         buf.write((int)number & 0x7f);
878     }
879 
880     void _encode(float value) {
881         int bits =  Float.floatToRawIntBits(value);
882         buf.write((byte)bits);
883         buf.write((byte)(bits >> 8));
884         buf.write((byte)(bits >> 16));
885         buf.write((byte)(bits >> 24));
886     }
887 
888     void _encode(double value) {
889         long bits =  Double.doubleToRawLongBits(value);
890         buf.write((byte)bits);
891         buf.write((byte)(bits >> 8));
892         buf.write((byte)(bits >> 16));
893         buf.write((byte)(bits >> 24));
894         buf.write((byte)(bits >> 32));
895         buf.write((byte)(bits >> 40));
896         buf.write((byte)(bits >> 48));
897         buf.write((byte)(bits >> 56));
898     }
899 
900     @SuppressWarnings("unchecked")
901     T _f(int fieldIndex, String value) {
902         return value == null ? (T)this : _f(fieldIndex, value.getBytes(StandardCharsets.UTF_8));
903     }
904 
905     @SuppressWarnings("unchecked")
906     T _f(int fieldIndex, byte[] bytes) {
907         _encode(fieldIndex << 3 | 2);
908         _encode(bytes.length);
909         buf.writeBytes(bytes);
910         return (T)this;
911     }
912 
913     @SuppressWarnings("unchecked")
914     T _f(int fieldIndex, float value) {
915         _encode(fieldIndex << 3 | 5);
916         _encode(value);
917         return (T)this;
918     }
919 
920     @SuppressWarnings("unchecked")
921     T _f(int fieldIndex, float... values) {
922         if (values.length == 1) {
923             return _f(fieldIndex, values[0]);
924         }
925         var b = new OnnxBuilder();
926         for (var v : values) b._encode(v);
927         _f(fieldIndex, b);
928         return (T)this;
929     }
930 
931     @SuppressWarnings("unchecked")
932     T _f(int fieldIndex, double value) {
933         _encode(fieldIndex << 3 | 1);
934         _encode(value);
935         return (T)this;
936     }
937 
938     @SuppressWarnings("unchecked")
939     T _f(int fieldIndex, double... values) {
940         if (values.length == 1) {
941             return _f(fieldIndex, values[0]);
942         }
943         var b = new OnnxBuilder();
944         for (var v : values) b._encode(v);
945         _f(fieldIndex, b);
946         return (T)this;
947     }
948 
949     @SuppressWarnings("unchecked")
950     T _f(int fieldIndex, long value) {
951         _encode(fieldIndex << 3);
952         _encode(value);
953         return (T)this;
954     }
955 
956     @SuppressWarnings("unchecked")
957     T _f(int fieldIndex, long... values) {
958         if (values.length == 1) {
959             return _f(fieldIndex, values[0]);
960         }
961         var b = new OnnxBuilder();
962         for (var v : values) b._encode(v);
963         _f(fieldIndex, b);
964         return (T)this;
965     }
966 
967     @SuppressWarnings("unchecked")
968     T _f(int fieldIndex, int... values) {
969         if (values.length == 1) {
970             return _f(fieldIndex, values[0]);
971         }
972         var b = new OnnxBuilder();
973         for (var v : values) b._encode(v);
974         _f(fieldIndex, b);
975         return (T)this;
976     }
977 
978     @SuppressWarnings("unchecked")
979     T _f(int fieldIndex, OnnxBuilder value) {
980         return _f(fieldIndex, value.buf.toByteArray());
981     }
982 
983     @SuppressWarnings("unchecked")
984     T _f(int fieldIndex, IntSupplier value) {
985         return _f(fieldIndex, value.getAsInt());
986     }
987 }