@@ -7,11 +7,20 @@ const mlir = {};
7
7
mlir . ModelFactory = class {
8
8
9
9
match ( context ) {
10
+ const stream = context . stream ;
11
+ if ( stream && stream . length > 4 ) {
12
+ const buffer = stream . peek ( 4 ) ;
13
+ const signature = String . fromCharCode . apply ( null , buffer ) ;
14
+ if ( signature === 'ML\xEFR' ) {
15
+ context . type = 'mlir.binary' ;
16
+ return ;
17
+ }
18
+ }
10
19
try {
11
20
const reader = context . read ( 'text' , 0x10000 ) ;
12
21
for ( let line = reader . read ( '\n' ) ; line !== undefined ; line = reader . read ( '\n' ) ) {
13
22
if ( / m o d u l e \s + ( \w + \s + ) ? { / . test ( line ) || / t e n s o r < \w + > / . test ( line ) ) {
14
- context . type = 'mlir' ;
23
+ context . type = 'mlir.text ' ;
15
24
return ;
16
25
}
17
26
}
@@ -21,10 +30,22 @@ mlir.ModelFactory = class {
21
30
}
22
31
23
32
async open ( context ) {
24
- const decoder = context . read ( 'text.decoder' ) ;
25
- const parser = new mlir . Parser ( decoder ) ;
26
- const obj = parser . read ( ) ;
27
- return new mlir . Model ( obj ) ;
33
+ switch ( context . type ) {
34
+ case 'mlir.text' : {
35
+ const decoder = context . read ( 'text.decoder' ) ;
36
+ const parser = new mlir . Parser ( decoder ) ;
37
+ const obj = parser . read ( ) ;
38
+ return new mlir . Model ( obj ) ;
39
+ }
40
+ case 'mlir.binary' : {
41
+ const reader = new mlir . BytecodeReader ( context ) ;
42
+ reader . read ( ) ;
43
+ throw new mlir . Error ( 'Invalid content. File contains MLIR bytecode data.' ) ;
44
+ }
45
+ default : {
46
+ throw new mlir . Error ( `Unsupported MLIR format '${ context . type } '.` ) ;
47
+ }
48
+ }
28
49
}
29
50
} ;
30
51
@@ -1168,6 +1189,174 @@ mlir.Utility = class {
1168
1189
}
1169
1190
} ;
1170
1191
1192
+ mlir . BytecodeReader = class {
1193
+
1194
+ constructor ( context ) {
1195
+ this . _reader = new mlir . BinaryReader ( context ) ;
1196
+ this . _decoder = new TextDecoder ( 'utf-8' ) ;
1197
+ }
1198
+
1199
+ read ( ) {
1200
+ const reader = this . _reader ;
1201
+ reader . read ( 4 ) ; // signature 'ML\xEFR'
1202
+ this . version = reader . varint ( ) . toNumber ( ) ;
1203
+ this . producer = reader . string ( ) ;
1204
+ this . sections = [ ] ;
1205
+ while ( reader . position < reader . length ) {
1206
+ const code = reader . byte ( ) ;
1207
+ const identifier = code & 0x7F ;
1208
+ const length = reader . varint ( ) . toNumber ( ) ;
1209
+ if ( code >> 7 ) {
1210
+ const alignment = reader . varint ( ) ;
1211
+ reader . skip ( alignment ) ;
1212
+ }
1213
+ const next = reader . position + length ;
1214
+ switch ( identifier ) {
1215
+ case 0 : { // string
1216
+ const lengths = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1217
+ for ( let i = 0 ; i < lengths . length ; i ++ ) {
1218
+ lengths [ i ] = reader . varint ( ) . toNumber ( ) ;
1219
+ }
1220
+ this . strings = new Array ( lengths . length ) ;
1221
+ for ( let i = 0 ; i < this . strings . length ; i ++ ) {
1222
+ const size = lengths [ lengths . length - i - 1 ] ;
1223
+ const buffer = reader . read ( size ) ;
1224
+ this . strings [ i ] = this . _decoder . decode ( buffer ) ;
1225
+ }
1226
+ break ;
1227
+ }
1228
+ case 1 : { // dialect
1229
+ const numDialects = reader . varint ( ) . toNumber ( ) ;
1230
+ this . dialectNames = new Array ( numDialects ) ;
1231
+ this . opNames = new Array ( numDialects ) ;
1232
+ for ( let i = 0 ; i < this . dialectNames . length ; i ++ ) {
1233
+ const group = { } ;
1234
+ const nameAndIsVersioned = reader . varint ( ) ;
1235
+ group . name = ( nameAndIsVersioned >> 1n ) . toNumber ( ) ;
1236
+ if ( nameAndIsVersioned & 1n ) {
1237
+ const size = reader . varint ( ) . toNumber ( ) ;
1238
+ group . version = reader . read ( size ) ;
1239
+ }
1240
+ this . dialectNames [ i ] = group ;
1241
+ }
1242
+ for ( let i = 0 ; i < this . opNames . length ; i ++ ) {
1243
+ const dialect_ops_group = { } ;
1244
+ dialect_ops_group . dialect = reader . varint ( ) ;
1245
+ dialect_ops_group . opNames = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1246
+ for ( let j = 0 ; j < dialect_ops_group . opNames . length ; j ++ ) {
1247
+ const op_name_group = { } ;
1248
+ const nameAndIsRegistered = reader . varint ( ) ;
1249
+ op_name_group . isRegistered = ( nameAndIsRegistered & 1n ) === 1n ;
1250
+ op_name_group . name = ( nameAndIsRegistered >> 1n ) . toNumber ( ) ;
1251
+ dialect_ops_group . opNames [ j ] = op_name_group ;
1252
+ }
1253
+ this . opNames [ i ] = dialect_ops_group ;
1254
+ }
1255
+ break ;
1256
+ }
1257
+ case 2 : // attrType
1258
+ case 3 : { // attrTypeOffset
1259
+ /*
1260
+ const numAttrs = reader.varint().toNumber();
1261
+ const numTypes = reader.varint().toNumber();
1262
+ for (let i = 0; i < (numAttrs + numTypes); i++) {
1263
+
1264
+ }
1265
+ break;
1266
+ */
1267
+ this . attrType = reader . stream ( length ) ;
1268
+ break ;
1269
+ }
1270
+ case 4 : { // IR
1271
+ reader . skip ( length ) ;
1272
+ break ;
1273
+ }
1274
+ case 5 : { // resource
1275
+ this . resource = reader . stream ( length ) ;
1276
+ break ;
1277
+ }
1278
+ case 6 : { // resourceOffset
1279
+ reader . skip ( length ) ;
1280
+ break ;
1281
+ }
1282
+ case 7 : { // dialectVersions
1283
+ reader . skip ( length ) ;
1284
+ break ;
1285
+ }
1286
+ case 8 : { // properties
1287
+ reader . skip ( length ) ;
1288
+ break ;
1289
+ }
1290
+ default : {
1291
+ throw new mlir . Error ( `Unsupported section identifier '${ identifier } '.` ) ;
1292
+ }
1293
+ }
1294
+ if ( reader . position !== next ) {
1295
+ throw new mlir . Error ( 'Invalid section length.' ) ;
1296
+ }
1297
+ }
1298
+ }
1299
+ } ;
1300
+
1301
+ mlir . BinaryReader = class {
1302
+
1303
+ constructor ( context ) {
1304
+ this . _reader = context . read ( 'binary' ) ;
1305
+ }
1306
+
1307
+ get length ( ) {
1308
+ return this . _reader . length ;
1309
+ }
1310
+
1311
+ get position ( ) {
1312
+ return this . _reader . position ;
1313
+ }
1314
+
1315
+ skip ( length ) {
1316
+ this . _reader . skip ( length ) ;
1317
+ }
1318
+
1319
+ read ( length ) {
1320
+ return this . _reader . read ( length ) ;
1321
+ }
1322
+
1323
+ stream ( length ) {
1324
+ return this . _reader . stream ( length ) ;
1325
+ }
1326
+
1327
+ byte ( ) {
1328
+ return this . _reader . byte ( ) ;
1329
+ }
1330
+
1331
+ varint ( ) {
1332
+ let value = 0n ;
1333
+ let shift = 0n ;
1334
+ for ( let i = 0 ; i < 10 && this . _reader . position < this . _reader . length ; i ++ ) {
1335
+ const byte = this . _reader . byte ( ) ;
1336
+ value |= BigInt ( byte >> 1 ) << shift ;
1337
+ if ( ( byte & 1 ) === 1 ) {
1338
+ return value ;
1339
+ }
1340
+ shift += 7n ;
1341
+ }
1342
+ throw new mlir . Error ( 'Invalid varint value.' ) ;
1343
+ }
1344
+
1345
+ string ( ) {
1346
+ const reader = this . _reader ;
1347
+ let result = '' ;
1348
+ let value = - 1 ;
1349
+ for ( ; ; ) {
1350
+ value = reader . byte ( ) ;
1351
+ if ( value === 0x00 ) {
1352
+ break ;
1353
+ }
1354
+ result += String . fromCharCode ( value ) ;
1355
+ }
1356
+ return result ;
1357
+ }
1358
+ } ;
1359
+
1171
1360
mlir . Error = class extends Error {
1172
1361
1173
1362
constructor ( message ) {
0 commit comments