From 4ad7d7e95a582630d2347b7ca768c50f26d301e9 Mon Sep 17 00:00:00 2001 From: Timo Stripf Date: Mon, 21 Sep 2026 14:26:20 +0000 Subject: [PATCH 1/2] Separate the two packings, and name the IR version this edition specifies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two findings from checking how new the 6-bit floating-point types are. The 6-bit types are new in ONNX 1.23.0, the vendored baseline, and they arrive under IR version 14 — which the upstream schema carries as current with its publication date given as "TBD". IR version 14 is not published. Three things this document specifies exist only in it: FLOAT6E2M3, FLOAT6E3M2, and the opaque type outside the ONNX-ML build. A standard cannot specify an unpublished version of its own subject. Clause 14 now states which IR version this edition specifies, carries the version history as a table, and says plainly that the choice — hold the three for an amendment and specify IR version 13, or publish 14 first — is the Steering Committee's and should not fall out of whichever ONNX release happened to be vendored. Annex C records it as blocking. The second finding is a defect in the packing subclause as committed. A tensor carries its elements either as an octet string or in a field typed for them, and the two pack a narrow type differently. For 4-bit and 2-bit types the packing coincides, which is why the single statement looked right; for the 6-bit types it does not. Typed storage puts one 6-bit element in the low six bits of a 32-bit integer and requires the rest to be zero, so it costs at least an octet per element and is not a packing at all. The subclause now states the two separately, with a table for typed storage, and says a producer should use raw storage for a 6-bit type. Also stated there: a floating-point element narrower than 32 bits goes into typed storage as the unsigned integer holding its bits. Twenty gaps now close rather than eighteen; Part 1 carries 25 editorial notes rather than 24, the IR version note being the third that came out of reading the source rather than skimming it. Verified: all three parts compile with "Syntax Valid", clean at severity 3 only. The rendered packing subclause was read back. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01DeGJcqqgBdz7kUpH6EsYxD --- STRUCTURE.md | 10 +-- sources/part1/sections/06-type-system.adoc | 61 +++++++++++-------- sources/part1/sections/14-versioning.adoc | 40 ++++++++++++ .../part1/sections/annex-c-known-gaps.adoc | 16 +++++ 4 files changed, 95 insertions(+), 32 deletions(-) diff --git a/STRUCTURE.md b/STRUCTURE.md index 876ba2f..e6ff78c 100644 --- a/STRUCTURE.md +++ b/STRUCTURE.md @@ -224,11 +224,11 @@ every such clause. The count rose from 16 notes to 44 across the three parts, which was not a regression: the new clauses — validation, security, inference, test vectors — are places the previous structure had no room to admit a gap in. -A pass over the vendored upstream documentation has since closed 18 gaps, -taking Part 1 from 34 editorial notes to 24 and the three parts together from -44 to 34. (Twelve notes went; two new ones came, both in the narrow-type -conversion rules, where reading the source closely raised a question the -previous note had not seen.) The clauses concerned are the ones where ONNX does +A pass over the vendored upstream documentation has since closed 20 gaps, +taking Part 1 from 34 editorial notes to 25 and the three parts together from +44 to 35. (Twelve notes went; three new ones came, all from reading the source +closely: two in the narrow-type conversion rules, and one on the IR version +this edition specifies, which turns out to be one ONNX has not published.) The clauses concerned are the ones where ONNX does state a rule and this document simply had not yet said so: the complete element type enumeration, the narrow types and their packing, broadcasting, denotation, opaque types, the model and its operator set imports, namespaces and subgraph diff --git a/sources/part1/sections/06-type-system.adoc b/sources/part1/sections/06-type-system.adoc index 4fd27c2..376bc98 100644 --- a/sources/part1/sections/06-type-system.adoc +++ b/sources/part1/sections/06-type-system.adoc @@ -144,33 +144,19 @@ leading bits; the two differ in sign as well as in magnitude. State one. [[packing]] ==== Packing -A tensor whose element type is narrower than eight bits SHALL be stored as a -bit stream, the elements in order, each element occupying the next free bits of -the current octet counting from its least significant bit. - -For a 4-bit element type, two elements occupy one octet: the first in the four -least significant bits, the second in the four most significant bits. For -consecutive elements `x` and `y`, the octet `z` is - -[%unnumbered] ----- -z = ((y & 0x0F) << 4) | (x & 0x0F) ----- - -and the elements are recovered as `x = z & 0x0F` and `y = (z >> 4) & 0x0F`. - -For a 2-bit element type, four elements occupy one octet, the element at index -`i` of the group occupying bits `2i` and `2i + 1`. - -For a 6-bit element type, the codes are packed into a contiguous bit stream in -the same direction; an element therefore MAY span two octets. - -The storage size in octets of a tensor of `N` elements of a type of width `w` -bits SHALL be the least integer not less than `N * w / 8`. Any bits of the -final octet not occupied by an element SHALL be zero, and a consumer SHALL -ignore them. - -.Storage size +A tensor carries its elements either as an octet string, called raw storage +here, or in a field typed for its elements, called typed storage. The two pack +a narrow element type differently, and a tensor uses one or the other, not +both. + +In raw storage, the elements SHALL be a bit stream, in order, each element +occupying the next free bits of the current octet counting from its least +significant bit. The storage size in octets of a tensor of `N` elements of a +type of width `w` bits SHALL be the least integer not less than `N * w / 8`. +Any bits of the final octet not occupied by an element SHALL be zero, and a +consumer SHALL ignore them. + +.Storage size in raw storage [example] ==== A tensor of 7 `INT4` elements occupies 4 octets, of which the four most @@ -179,6 +165,27 @@ elements occupies 6 octets, of which the two most significant bits of the sixth octet are padding. ==== +In typed storage, a narrow element type uses a sequence of 32-bit integers, and +<> states how many elements each integer carries and which +of its bits they occupy. Every other bit of such an integer SHALL be zero. + +[[tbl-typed-storage]] +.Narrow element types in typed storage +[cols="2,1,4"] +|=== +| Element width | Elements per integer | Bits occupied + +| 2 bits | 4 | bits 0 to 1, 2 to 3, 4 to 5 and 6 to 7, in element order +| 4 bits | 2 | bits 0 to 3 and 4 to 7, in element order +| 6 bits | 1 | bits 0 to 5 +|=== + +A producer SHOULD use raw storage for a 6-bit element type. Typed storage costs +at least one octet per element there, so it is not a packing at all. + +A floating-point element type narrower than 32 bits SHALL be written to typed +storage as the unsigned integer whose bits are those of the element. + [[string-elements]] === String elements and character encoding diff --git a/sources/part1/sections/14-versioning.adoc b/sources/part1/sections/14-versioning.adoc index 840802d..4be9378 100644 --- a/sources/part1/sections/14-versioning.adoc +++ b/sources/part1/sections/14-versioning.adoc @@ -3,6 +3,8 @@ === Version axes +==== General + ONNX has three independent version axes: IR version:: the version of the structural and serialization rules given in @@ -14,6 +16,44 @@ published in <>. Model version:: an identifier assigned by the <>, opaque to this document. +[[ir-version-specified]] +==== The IR version this edition specifies + +This edition specifies IR version 14. + +[IMPORTANT] +.Editorial note +==== +IR version 14 is not published. The upstream schema carries it as the current +version with its publication date given as "TBD", and it is the version that +introduces `FLOAT6E2M3`, `FLOAT6E3M2` and the opaque type outside the ONNX-ML +build --- all three of which this document specifies, in +<> and <>. + +A standard cannot specify an unpublished version of the thing it standardizes. +Either this edition specifies IR version 13, and those three are removed from +it and held for an amendment, or the Steering Committee publishes 14 first. +The choice is theirs; it should not be made by whichever ONNX release happened +to be vendored when the draft was written. + +<> is the version history, from the upstream schema. +==== + +[[tbl-ir-versions]] +.IR versions and what each introduced +[cols="1,2,4"] +|=== +| Version | Published | Introduced + +| 8 | 2021-07-30 | the sparse tensor and optional types; model-local functions +| 9 | 2023-05-05 | attribute default values in a function; the four FP8 types +| 10 | 2024-03-25 | `UINT4` and `INT4`; the function overload; metadata properties +| 11 | 2025-05-12 | `FLOAT4E2M1`; multi-device configuration +| 12 | 2025-08-26 | `FLOAT8E8M0` +| 13 | 2025-11-06 | `UINT2` and `INT2` +| 14 | not published | `FLOAT6E2M3` and `FLOAT6E3M2`; the opaque type outside the ONNX-ML build +|=== + === IR version evolution The IR version is a positive integer that increases monotonically. diff --git a/sources/part1/sections/annex-c-known-gaps.adoc b/sources/part1/sections/annex-c-known-gaps.adoc index 8ed3906..2779cec 100644 --- a/sources/part1/sections/annex-c-known-gaps.adoc +++ b/sources/part1/sections/annex-c-known-gaps.adoc @@ -51,6 +51,16 @@ form a standard cannot adopt. them. They cannot be generated and have to be written per operator. | Blocking +| <> +| This edition specifies IR version 14, which the upstream schema carries as + current with its publication date given as "TBD". Three things this document + specifies --- the two 6-bit floating-point types and the opaque type outside + the ONNX-ML build --- exist only in that unpublished version. A standard + cannot specify an unpublished version of its subject: either they are held + for an amendment and this edition specifies IR version 13, or 14 is published + first. +| Blocking + | <> (conversion) | Whether a conversion to a narrow floating-point type saturates or yields NaN is settled per operator, by an attribute of `Cast`, rather than per type, so @@ -171,6 +181,12 @@ transcription rather than take it on trust, and so that a refresh of | <> (complete enumeration) | `onnx-ml.proto`, `TensorProto.DataType` +| <> (typed storage) +| `onnx-ml.proto`, `TensorProto.int32_data` + +| <> (IR version history) +| `onnx-ml.proto`, `Version` + | <> (narrow types and their packing) | `docs/docsgen/source/technical/`: `float4.md`, `float6.md`, `float8.md`, `int2.md`, `int4.md` From 827d0de298409a7cbbb4668e5246a40075417ddc Mon Sep 17 00:00:00 2001 From: Timo Stripf Date: Mon, 21 Sep 2026 19:41:24 +0000 Subject: [PATCH 2/2] Correct the IR version statement: 14 is released, in ONNX 1.23.0 The previous commit claimed IR version 14 is unpublished and recorded it in Annex C as a blocking gap. That is wrong, and the evidence against it was in the same vendored baseline, in the file this part's versioning clause was written from: docs/Versioning.md, "Released Versions" ... 1.22.0 | 13 | 27 | 5 | 1 1.23.0 | 14 | 28 | 5 | 1 IR version 14 shipped in ONNX release 1.23.0, which is the release this document is drafted against. There is no gap. What I read instead was a comment in the schema, "IR VERSION 14 published on TBD", and took a date field nobody had filled in at release time for a statement that the version does not exist. A release is the publication event; a comment is not. I asserted the opposite in a normative clause and raised it as blocking, on a source I had not checked against the one table that answers the question directly. Clause 14.1.2 now states that this edition specifies IR version 14 as published in ONNX release 1.23.0, and the version history table gives the release each version was published in rather than the schema's date, which is not maintained. A note records that the schema still reads TBD for 14, so that a reader who finds it is not misled the same way. The Annex C row is removed; nothing replaces it. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01DeGJcqqgBdz7kUpH6EsYxD --- STRUCTURE.md | 8 ++-- sources/part1/sections/14-versioning.adoc | 47 +++++++------------ .../part1/sections/annex-c-known-gaps.adoc | 14 +----- 3 files changed, 24 insertions(+), 45 deletions(-) diff --git a/STRUCTURE.md b/STRUCTURE.md index e6ff78c..515559c 100644 --- a/STRUCTURE.md +++ b/STRUCTURE.md @@ -225,10 +225,10 @@ which was not a regression: the new clauses — validation, security, inference, test vectors — are places the previous structure had no room to admit a gap in. A pass over the vendored upstream documentation has since closed 20 gaps, -taking Part 1 from 34 editorial notes to 25 and the three parts together from -44 to 35. (Twelve notes went; three new ones came, all from reading the source -closely: two in the narrow-type conversion rules, and one on the IR version -this edition specifies, which turns out to be one ONNX has not published.) The clauses concerned are the ones where ONNX does +taking Part 1 from 34 editorial notes to 24 and the three parts together from +44 to 34. (Twelve notes went; two new ones came, both in the narrow-type +conversion rules, where reading the source closely raised a question the +previous note had not seen.) The clauses concerned are the ones where ONNX does state a rule and this document simply had not yet said so: the complete element type enumeration, the narrow types and their packing, broadcasting, denotation, opaque types, the model and its operator set imports, namespaces and subgraph diff --git a/sources/part1/sections/14-versioning.adoc b/sources/part1/sections/14-versioning.adoc index 4be9378..d93ed25 100644 --- a/sources/part1/sections/14-versioning.adoc +++ b/sources/part1/sections/14-versioning.adoc @@ -19,41 +19,30 @@ document. [[ir-version-specified]] ==== The IR version this edition specifies -This edition specifies IR version 14. +This edition specifies IR version 14, as published in ONNX release 1.23.0. -[IMPORTANT] -.Editorial note -==== -IR version 14 is not published. The upstream schema carries it as the current -version with its publication date given as "TBD", and it is the version that -introduces `FLOAT6E2M3`, `FLOAT6E3M2` and the opaque type outside the ONNX-ML -build --- all three of which this document specifies, in -<> and <>. - -A standard cannot specify an unpublished version of the thing it standardizes. -Either this edition specifies IR version 13, and those three are removed from -it and held for an amendment, or the Steering Committee publishes 14 first. -The choice is theirs; it should not be made by whichever ONNX release happened -to be vendored when the draft was written. - -<> is the version history, from the upstream schema. -==== +<> is the version history. [[tbl-ir-versions]] -.IR versions and what each introduced -[cols="1,2,4"] +.IR versions, the release each was published in, and what each introduced +[cols="1,1,4"] |=== -| Version | Published | Introduced - -| 8 | 2021-07-30 | the sparse tensor and optional types; model-local functions -| 9 | 2023-05-05 | attribute default values in a function; the four FP8 types -| 10 | 2024-03-25 | `UINT4` and `INT4`; the function overload; metadata properties -| 11 | 2025-05-12 | `FLOAT4E2M1`; multi-device configuration -| 12 | 2025-08-26 | `FLOAT8E8M0` -| 13 | 2025-11-06 | `UINT2` and `INT2` -| 14 | not published | `FLOAT6E2M3` and `FLOAT6E3M2`; the opaque type outside the ONNX-ML build +| IR version | ONNX release | Introduced + +| 8 | 1.10.0 | the sparse tensor and optional types; model-local functions +| 9 | 1.14.0 | attribute default values in a function; the four FP8 types +| 10 | 1.16.0 | `UINT4` and `INT4`; the function overload; metadata properties +| 11 | 1.18.0 | `FLOAT4E2M1`; multi-device configuration +| 12 | 1.19.0 | `FLOAT8E8M0` +| 13 | 1.20.0 | `UINT2` and `INT2` +| 14 | 1.23.0 | `FLOAT6E2M3` and `FLOAT6E3M2`; the opaque type outside the ONNX-ML build |=== +NOTE: The release is the publication event. The schema source carries a +publication date against each IR version as well, and for IR version 14 it +still reads "TBD" although 1.23.0 shipped it; the date in the schema is not +maintained and is not relied on here. + === IR version evolution The IR version is a positive integer that increases monotonically. diff --git a/sources/part1/sections/annex-c-known-gaps.adoc b/sources/part1/sections/annex-c-known-gaps.adoc index 2779cec..947ab0b 100644 --- a/sources/part1/sections/annex-c-known-gaps.adoc +++ b/sources/part1/sections/annex-c-known-gaps.adoc @@ -51,16 +51,6 @@ form a standard cannot adopt. them. They cannot be generated and have to be written per operator. | Blocking -| <> -| This edition specifies IR version 14, which the upstream schema carries as - current with its publication date given as "TBD". Three things this document - specifies --- the two 6-bit floating-point types and the opaque type outside - the ONNX-ML build --- exist only in that unpublished version. A standard - cannot specify an unpublished version of its subject: either they are held - for an amendment and this edition specifies IR version 13, or 14 is published - first. -| Blocking - | <> (conversion) | Whether a conversion to a narrow floating-point type saturates or yields NaN is settled per operator, by an attribute of `Cast`, rather than per type, so @@ -184,8 +174,8 @@ transcription rather than take it on trust, and so that a refresh of | <> (typed storage) | `onnx-ml.proto`, `TensorProto.int32_data` -| <> (IR version history) -| `onnx-ml.proto`, `Version` +| <> (the IR version history) +| `docs/Versioning.md`, "Released Versions"; `onnx-ml.proto`, `Version` | <> (narrow types and their packing) | `docs/docsgen/source/technical/`: `float4.md`, `float6.md`, `float8.md`,