code wiki / (root) / nx_nxa_morf_admit.nx

nx_nxa_morf_admit.nx source

↩ module page · 202 lines · 11018 B

1// ORIGINAL. Allocation-free extraction of mf_eval's FACE/MORF admission. 2// nx_nxa owns the container/checksums. Caller owns immutable file bytes, output 3// view, and one membership byte per vertex. No channel naming policy. 4import "nx_nxa.nx" 5import "nx_morf_eval_core.nx" 6const NMI_E_MISSING: i64 = 0-81 7const NMI_E_SHAPE: i64 = 0-82 8const NMI_E_IDENTITY: i64 = 0-83 9const NMI_E_SCRATCH: i64 = 0-84 10const NMI_FACE_HEADER: i64 = 4 11const NMI_MORF_HEADER: i64 = 4 12const NMI_CHANNEL_WORDS: i64 = 2 13const NMI_R_NO_VERT: i64 = 0-901 14const NMI_R_NO_FACE: i64 = 0-902 15const NMI_R_NO_MORF: i64 = 0-903 16const NMI_R_BAD_VERT: i64 = 0-904 17const NMI_R_BAD_FACE: i64 = 0-905 18const NMI_R_BAD_MORF: i64 = 0-906 19const NMI_R_VERT_SHAPE: i64 = 0-907 20const NMI_R_DUP_VERT: i64 = 0-908 21const NMI_R_DUP_FACE: i64 = 0-909 22const NMI_R_DUP_MORF: i64 = 0-910 23const NMI_R_FACE_HEADER: i64 = 0-911 24const NMI_R_MORF_HEADER: i64 = 0-912 25const NMI_R_EMPTY_VERT: i64 = 0-913 26const NMI_R_EMPTY_FACE: i64 = 0-914 27const NMI_R_FACE_SHAPE: i64 = 0-915 28const NMI_R_FACE_COUNT: i64 = 0-916 29const NMI_R_EMPTY_MORF: i64 = 0-917 30const NMI_R_ROW_COUNT: i64 = 0-918 31const NMI_R_STRIDE: i64 = 0-919 32const NMI_R_UNIT: i64 = 0-920 33const NMI_R_CHANNEL_RECORDS: i64 = 0-921 34const NMI_R_CHANNEL_SHAPE: i64 = 0-922 35const NMI_R_ROW_SHAPE: i64 = 0-923 36const NMI_R_DELTA_COUNT: i64 = 0-924 37const NMI_R_SUPPORT_NEGATIVE: i64 = 0-925 38const NMI_R_SUPPORT_COUNT: i64 = 0-926 39const NMI_R_FACE_NEGATIVE: i64 = 0-927 40const NMI_R_FACE_RANGE: i64 = 0-928 41const NMI_R_FACE_DUPLICATE: i64 = 0-929 42const NMI_R_VERT_FACE: i64 = 0-930 43const NMI_R_VERT_MORF: i64 = 0-931 44const NMI_R_FACE_MORF: i64 = 0-932 45const NMI_R_CHANNEL_RANGE: i64 = 0-933 46struct NmiAsset { 47 view: *MvcView 48 tags: *i64 49 tag_words: i64 50} 51func nmi_scratch_bytes(b: *u8,flen: i64) -> i64 { 52 if flen < 0 { return NMI_E_SHAPE } 53 var file_words: i64 = flen/MVC_WORD 54 if flen%MVC_WORD != 0 { file_words = file_words+1 } 55 if mvc_span(b as *i64,file_words) == 0 { return NMI_E_SHAPE } 56 let vw: i64 = nxa_counted_section(b,flen,nxa_tag4("VERT" as *u8),MVC_AXES) 57 if vw < 0 { return NMI_R_VERT_SHAPE } 58 let h: *i64 = b as *i64 59 if h[vw] < 1 { return NMI_R_EMPTY_VERT } 60 return h[vw] 61} 62func nmi_admit_channel(b: *u8,flen: i64,seen: *u8,seen_bytes: i64,out: *NmiAsset,channel: i64) -> i64 { 63 if flen < 0 { return NMI_E_SHAPE } 64 var file_words: i64 = flen/MVC_WORD 65 if flen%MVC_WORD != 0 { file_words = file_words+1 } 66 if mvc_span(b as *i64,file_words) == 0 { return NMI_E_SHAPE } 67 if mvc_span(out as *i64,__size_of(NmiAsset)/MVC_WORD) == 0 { return NMI_E_SHAPE } 68 let v: *MvcView = out.view 69 if mvc_span(v as *i64,__size_of(MvcView)/MVC_WORD) == 0 { return NMI_E_SHAPE } 70 if nmi_byte_span(seen,seen_bytes) == 0 { return NMI_E_SCRATCH } 71 if nmi_byte_overlap(seen,seen_bytes,b,flen) != 0 { return NMI_E_SCRATCH } 72 if nmi_byte_overlap(seen,seen_bytes,out as *u8,__size_of(NmiAsset)) != 0 { return NMI_E_SCRATCH } 73 if nmi_byte_overlap(seen,seen_bytes,v as *u8,__size_of(MvcView)) != 0 { return NMI_E_SCRATCH } 74 if mvc_overlap(out as *i64,__size_of(NmiAsset)/MVC_WORD,b as *i64,file_words) != 0 { return NMI_E_IDENTITY } 75 if mvc_overlap(v as *i64,__size_of(MvcView)/MVC_WORD,b as *i64,file_words) != 0 { return NMI_E_IDENTITY } 76 if mvc_overlap(v as *i64,__size_of(MvcView)/MVC_WORD,out as *i64,__size_of(NmiAsset)/MVC_WORD) != 0 { return NMI_E_IDENTITY } 77 let vt: i64 = nxa_tag4("VERT" as *u8) 78 let ft: i64 = nxa_tag4("FACE" as *u8) 79 let mt: i64 = nxa_tag4("MORF" as *u8) 80 let ve: i64 = nxa_section_entry(b,flen,vt) 81 let fe: i64 = nxa_section_entry(b,flen,ft) 82 let me: i64 = nxa_section_entry(b,flen,mt) 83 if ve == 0-1 { return NMI_R_NO_VERT } 84 if fe == 0-1 { return NMI_R_NO_FACE } 85 if me == 0-1 { return NMI_R_NO_MORF } 86 if ve < 0 { return NMI_R_BAD_VERT }; if fe < 0 { return NMI_R_BAD_FACE }; if me < 0 { return NMI_R_BAD_MORF } 87 let vw: i64 = nxa_counted_section(b,flen,vt,MVC_AXES) 88 if vw < 0 { return NMI_R_VERT_SHAPE } 89 let h: *i64 = b as *i64 90 let vo: i64 = h[ve+1]; let fo: i64 = h[fe+1]; let mo: i64 = h[me+1] 91 let vwords: i64 = h[ve+2]; let fwords: i64 = h[fe+2]; let mwords: i64 = h[me+2] 92 var s: i64 = 0; var vc: i64 = 0; var fc: i64 = 0; var mc: i64 = 0 93 while s < h[2] { 94 let tag: i64 = h[4+s*4] 95 if tag == vt { vc = vc+1 }; if tag == ft { fc = fc+1 }; if tag == mt { mc = mc+1 } 96 s = s+1 97 } 98 if vc != 1 { return NMI_R_DUP_VERT }; if fc != 1 { return NMI_R_DUP_FACE }; if mc != 1 { return NMI_R_DUP_MORF } 99 if vo < fo+fwords*MVC_WORD { if fo < vo+vwords*MVC_WORD { return NMI_R_VERT_FACE } } 100 if vo < mo+mwords*MVC_WORD { if mo < vo+vwords*MVC_WORD { return NMI_R_VERT_MORF } } 101 if fo < mo+mwords*MVC_WORD { if mo < fo+fwords*MVC_WORD { return NMI_R_FACE_MORF } } 102 if fwords < NMI_FACE_HEADER { return NMI_R_FACE_HEADER } 103 if mwords < NMI_MORF_HEADER { return NMI_R_MORF_HEADER } 104 let f: *i64 = ((b as i64)+fo) as *i64 105 let m: *i64 = ((b as i64)+mo) as *i64 106 let nv: i64 = h[vw]; let nf: i64 = f[0]; let nc: i64 = m[0] 107 if nv < 1 { return NMI_R_EMPTY_VERT } 108 if nf < 1 { return NMI_R_EMPTY_FACE } 109 if nf != fwords-NMI_FACE_HEADER { return NMI_R_FACE_SHAPE } 110 if nf > nv { return NMI_R_FACE_COUNT } 111 if nc < 1 { return NMI_R_EMPTY_MORF }; if m[1] != nf { return NMI_R_ROW_COUNT } 112 if m[2] != MVC_AXES { return NMI_R_STRIDE }; if m[3] < 1 { return NMI_R_UNIT } 113 if channel >= nc { return NMI_R_CHANNEL_RANGE } 114 let rem: i64 = mwords-NMI_MORF_HEADER 115 if nc > rem/NMI_CHANNEL_WORDS { return NMI_R_CHANNEL_RECORDS } 116 let dw: i64 = rem-nc*NMI_CHANNEL_WORDS 117 if dw%nc != 0 { return NMI_R_CHANNEL_SHAPE } 118 let cw: i64 = dw/nc 119 if cw%MVC_AXES != 0 { return NMI_R_ROW_SHAPE } 120 if cw/MVC_AXES != nf { return NMI_R_DELTA_COUNT } 121 var c: i64 = 0 122 while c < nc { 123 let support: i64 = m[NMI_MORF_HEADER+c*NMI_CHANNEL_WORDS+1] 124 if support < 0 { return NMI_R_SUPPORT_NEGATIVE }; if support > nf { return NMI_R_SUPPORT_COUNT } 125 c = c+1 126 } 127 if seen_bytes < nv { return NMI_E_SCRATCH } 128 var i: i64 = 0 129 while i < nv { seen[i] = 0 as u8; i = i+1 } 130 i = 0 131 while i < nf { 132 let id: i64 = f[NMI_FACE_HEADER+i] 133 if id < 0 { return NMI_R_FACE_NEGATIVE }; if id >= nv { return NMI_R_FACE_RANGE } 134 if seen[id] != (0 as u8) { return NMI_R_FACE_DUPLICATE } 135 seen[id] = 1 as u8; i = i+1 136 } 137 // Publish only after all checks. Views borrow the immutable file lifetime. 138 v.bind = ((b as i64)+(vw+1)*MVC_WORD) as *i64; v.bind_words = vwords-1 139 v.face = ((f as i64)+NMI_FACE_HEADER*MVC_WORD) as *i64; v.face_words = nf 140 v.delta = ((m as i64)+(NMI_MORF_HEADER+nc*NMI_CHANNEL_WORDS)*MVC_WORD) as *i64 141 v.delta_words = dw; v.vertices = nv; v.faces = nf; v.channels = nc; v.unit = m[3] 142 out.tags = ((m as i64)+NMI_MORF_HEADER*MVC_WORD) as *i64 143 out.tag_words = nc*NMI_CHANNEL_WORDS 144 return 0 145} 146 147func nmi_byte_span(p: *u8,n: i64) -> i64 { 148 if n < 0 { return 0 }; if n == 0 { return 1 } 149 let addr: i64 = p as i64 150 if addr <= 0 { return 0 }; if addr > MVC_I64_MAX-n { return 0 } 151 return 1 152} 153func nmi_byte_overlap(a: *u8,an: i64,b: *u8,bn: i64) -> i64 { 154 if an == 0 { return 0 }; if bn == 0 { return 0 } 155 if (a as i64) < (b as i64)+bn { if (b as i64) < (a as i64)+an { return 1 } } 156 return 0 157} 158func nmi_admit(b: *u8,flen: i64,seen: *u8,seen_bytes: i64,out: *NmiAsset) -> i64 { 159 return nmi_admit_channel(b,flen,seen,seen_bytes,out,0-1) 160} 161func nmi_missing(rc: i64) -> i64 { 162 if rc == NMI_R_NO_VERT { return 1 }; if rc == NMI_R_NO_FACE { return 1 }; if rc == NMI_R_NO_MORF { return 1 } 163 return 0 164} 165func nmi_diagnostic(rc: i64) -> *u8 { 166 if rc == NMI_R_NO_VERT { return "MORF-REFUSE no VERT section\n" as *u8 } 167 if rc == NMI_R_NO_FACE { return "MORF-REFUSE no FACE section -- run derive first\n" as *u8 } 168 if rc == NMI_R_NO_MORF { return "MORF-REFUSE no MORF section -- run derive first\n" as *u8 } 169 if rc == NMI_R_BAD_VERT { return "MORF-REFUSE absent or invalid VERT/container\n" as *u8 } 170 if rc == NMI_R_BAD_FACE { return "MORF-REFUSE absent or invalid FACE/container\n" as *u8 } 171 if rc == NMI_R_BAD_MORF { return "MORF-REFUSE absent or invalid MORF/container\n" as *u8 } 172 if rc == NMI_R_VERT_SHAPE { return "MORF-REFUSE invalid VERT shape\n" as *u8 } 173 if rc == NMI_R_DUP_VERT { return "MORF-REFUSE duplicate VERT section\n" as *u8 } 174 if rc == NMI_R_DUP_FACE { return "MORF-REFUSE duplicate FACE section\n" as *u8 } 175 if rc == NMI_R_DUP_MORF { return "MORF-REFUSE duplicate MORF section\n" as *u8 } 176 if rc == NMI_R_FACE_HEADER { return "MORF-REFUSE truncated FACE header\n" as *u8 } 177 if rc == NMI_R_MORF_HEADER { return "MORF-REFUSE truncated MORF header\n" as *u8 } 178 if rc == NMI_R_EMPTY_VERT { return "MORF-REFUSE empty VERT\n" as *u8 } 179 if rc == NMI_R_EMPTY_FACE { return "MORF-REFUSE empty or negative FACE count\n" as *u8 } 180 if rc == NMI_R_FACE_SHAPE { return "MORF-REFUSE invalid FACE shape\n" as *u8 } 181 if rc == NMI_R_FACE_COUNT { return "MORF-REFUSE FACE count exceeds VERT count\n" as *u8 } 182 if rc == NMI_R_EMPTY_MORF { return "MORF-REFUSE empty or negative MORF channels\n" as *u8 } 183 if rc == NMI_R_ROW_COUNT { return "MORF-REFUSE MORF/FACE count mismatch\n" as *u8 } 184 if rc == NMI_R_STRIDE { return "MORF-REFUSE unsupported MORF stride\n" as *u8 } 185 if rc == NMI_R_UNIT { return "MORF-REFUSE declared weight unit is not positive\n" as *u8 } 186 if rc == NMI_R_CHANNEL_RECORDS { return "MORF-REFUSE truncated MORF channel records\n" as *u8 } 187 if rc == NMI_R_CHANNEL_SHAPE { return "MORF-REFUSE invalid MORF channel shape\n" as *u8 } 188 if rc == NMI_R_ROW_SHAPE { return "MORF-REFUSE invalid MORF row shape\n" as *u8 } 189 if rc == NMI_R_DELTA_COUNT { return "MORF-REFUSE invalid MORF delta count\n" as *u8 } 190 if rc == NMI_R_SUPPORT_NEGATIVE { return "MORF-REFUSE negative channel support count\n" as *u8 } 191 if rc == NMI_R_SUPPORT_COUNT { return "MORF-REFUSE channel support exceeds FACE count\n" as *u8 } 192 if rc == NMI_R_FACE_NEGATIVE { return "MORF-REFUSE negative FACE vertex ID\n" as *u8 } 193 if rc == NMI_R_FACE_RANGE { return "MORF-REFUSE FACE vertex ID outside VERT\n" as *u8 } 194 if rc == NMI_R_FACE_DUPLICATE { return "MORF-REFUSE duplicate FACE vertex ID\n" as *u8 } 195 if rc == NMI_R_VERT_FACE { return "MORF-REFUSE VERT/FACE overlap\n" as *u8 } 196 if rc == NMI_R_VERT_MORF { return "MORF-REFUSE VERT/MORF overlap\n" as *u8 } 197 if rc == NMI_R_FACE_MORF { return "MORF-REFUSE FACE/MORF overlap\n" as *u8 } 198 if rc == NMI_R_CHANNEL_RANGE { return "MORF-REFUSE channel past the asset's declared channels\n" as *u8 } 199 if rc == NMI_E_SCRATCH { return "MORF-REFUSE admission membership scratch size or alias\n" as *u8 } 200 if rc == NMI_E_IDENTITY { return "MORF-REFUSE admission output aliases immutable input or another output\n" as *u8 } 201 return "MORF-REFUSE invalid admission pointer or length\n" as *u8 202}