kmodel.js 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
  1. var kmodel = kmodel || {};
  2. var base = base || require('./base');
  3. kmodel.ModelFactory = class {
  4. match(context) {
  5. return kmodel.Reader.open(context.stream);
  6. }
  7. open(context, match) {
  8. return Promise.resolve().then(() => new kmodel.Model(match));
  9. }
  10. };
  11. kmodel.Model = class {
  12. constructor(model) {
  13. this._format = 'kmodel v' + model.version.toString();
  14. this._graphs = model.modules.map((module) => new kmodel.Graph(module));
  15. }
  16. get format() {
  17. return this._format;
  18. }
  19. get graphs() {
  20. return this._graphs;
  21. }
  22. };
  23. kmodel.Graph = class {
  24. constructor(module) {
  25. this._name = module.name || '';
  26. this._type = module.type || '';
  27. this._inputs = [];
  28. this._outputs = [];
  29. this._nodes = [];
  30. const scopes = new Map();
  31. let index = 0;
  32. for (const layer of module.layers) {
  33. for (const input of layer.inputs || []) {
  34. for (const argument of input.arguments) {
  35. argument.name = scopes.has(argument.name) ? scopes.get(argument.name) : argument.name;
  36. }
  37. }
  38. for (const output of layer.outputs || []) {
  39. for (const argument of output.arguments) {
  40. const value = scopes.has(argument.name) ? argument.name + '#' + index.toString() : argument.name;
  41. scopes.set(argument.name, value); // custom argument id
  42. argument.name = value;
  43. }
  44. }
  45. index++;
  46. }
  47. for (const layer of module.layers) {
  48. switch (layer.type.name) {
  49. case 'INPUT':
  50. case 'input': {
  51. for (const input of layer.outputs) {
  52. this._inputs.push(new kmodel.Parameter('input', input.arguments.map((argument) => {
  53. return new kmodel.Argument(argument.name);
  54. })));
  55. }
  56. break;
  57. }
  58. case 'OUTPUT':
  59. case 'output': {
  60. for (const output of layer.inputs) {
  61. this._outputs.push(new kmodel.Parameter(output.name, output.arguments.map((argument) => {
  62. return new kmodel.Argument(argument.name);
  63. })));
  64. }
  65. break;
  66. }
  67. default:
  68. this._nodes.push(new kmodel.Node(layer));
  69. break;
  70. }
  71. }
  72. }
  73. get name() {
  74. return this._name;
  75. }
  76. get type() {
  77. return this._type;
  78. }
  79. get inputs() {
  80. return this._inputs;
  81. }
  82. get outputs() {
  83. return this._outputs;
  84. }
  85. get nodes() {
  86. return this._nodes;
  87. }
  88. };
  89. kmodel.Parameter = class {
  90. constructor(name, args) {
  91. this._name = name;
  92. this._arguments = args;
  93. }
  94. get name() {
  95. return this._name;
  96. }
  97. get visible() {
  98. return true;
  99. }
  100. get arguments() {
  101. return this._arguments;
  102. }
  103. };
  104. kmodel.Argument = class {
  105. constructor(name, type, initializer) {
  106. if (typeof name !== 'string') {
  107. throw new kmodel.Error("Invalid argument identifier '" + JSON.stringify(name) + "'.");
  108. }
  109. this._name = name;
  110. this._type = type;
  111. this._initializer = initializer;
  112. }
  113. get name() {
  114. return this._name;
  115. }
  116. get type() {
  117. if (this._initializer) {
  118. return this._initializer.type;
  119. }
  120. return this._type;
  121. }
  122. get initializer() {
  123. return this._initializer;
  124. }
  125. };
  126. kmodel.TensorType = class {
  127. constructor(dataType, shape) {
  128. this._dataType = dataType;
  129. this._shape = new kmodel.TensorShape(shape);
  130. }
  131. get dataType() {
  132. return this._dataType;
  133. }
  134. get shape() {
  135. return this._shape;
  136. }
  137. toString() {
  138. return this._dataType + this._shape.toString();
  139. }
  140. };
  141. kmodel.TensorShape = class {
  142. constructor(shape) {
  143. this._shape = shape;
  144. }
  145. get dimensions() {
  146. return this._shape;
  147. }
  148. toString() {
  149. if (this._shape && Array.isArray(this._shape) && this._shape.length > 0) {
  150. return '[' + this._shape.map((dim) => dim ? dim.toString() : '?').join(',') + ']';
  151. }
  152. return '';
  153. }
  154. };
  155. kmodel.Tensor = class {
  156. constructor(type, data) {
  157. this._type = type;
  158. this._data = data;
  159. }
  160. get type() {
  161. return this._type;
  162. }
  163. get state() {
  164. return this._context().state;
  165. }
  166. get value() {
  167. const context = this._context();
  168. if (context.state) {
  169. return null;
  170. }
  171. context.limit = Number.MAX_SAFE_INTEGER;
  172. return this._decode(context, 0);
  173. }
  174. toString() {
  175. const context = this._context();
  176. if (context.state) {
  177. return '';
  178. }
  179. context.limit = 10000;
  180. const value = this._decode(context, 0);
  181. return JSON.stringify(value, null, 4);
  182. }
  183. _context() {
  184. const context = {};
  185. context.state = null;
  186. context.index = 0;
  187. context.count = 0;
  188. if (this._data == null || this._data.length === 0) {
  189. context.state = 'Tensor data is empty.';
  190. return context;
  191. }
  192. const dataType = this.type.dataType;
  193. const shape = this.type.shape.dimensions;
  194. if (dataType !== 'uint8' && dataType !== 'int32' && dataType !== 'float32') {
  195. context.state = "Tensor data type '" + dataType + "' is not implemented.";
  196. return context;
  197. }
  198. context.dataType = dataType;
  199. context.shape = shape;
  200. context.data = new DataView(this._data.buffer, this._data.byteOffset, this._data.byteLength);
  201. return context;
  202. }
  203. _decode(context, dimension) {
  204. const shape = (context.shape.length == 0) ? [ 1 ] : context.shape;
  205. const size = shape[dimension];
  206. const results = [];
  207. if (dimension == shape.length - 1) {
  208. for (let i = 0; i < size; i++) {
  209. if (context.count > context.limit) {
  210. results.push('...');
  211. return results;
  212. }
  213. switch (context.dataType) {
  214. case 'uint8':
  215. results.push(context.data.getUint8(context.index));
  216. context.index += 1;
  217. context.count++;
  218. break;
  219. case 'int32':
  220. results.push(context.data.getInt32(context.index));
  221. context.index += 4;
  222. context.count++;
  223. break;
  224. case 'float32':
  225. results.push(context.data.getFloat32(context.index, true));
  226. context.index += 4;
  227. context.count++;
  228. break;
  229. default:
  230. throw new kmodel.Error("Unsupported data type '" + context.dataType + "'.");
  231. }
  232. }
  233. }
  234. else {
  235. for (let j = 0; j < size; j++) {
  236. if (context.count > context.limit) {
  237. results.push('...');
  238. return results;
  239. }
  240. results.push(this._decode(context, dimension + 1));
  241. }
  242. }
  243. if (context.shape.length == 0) {
  244. return results[0];
  245. }
  246. return results;
  247. }
  248. };
  249. kmodel.Node = class {
  250. constructor(layer) {
  251. this._location = layer.location !== undefined ? layer.location.toString() : layer.location;
  252. this._type = layer.type;
  253. this._inputs = [];
  254. this._outputs = [];
  255. this._chain = [];
  256. this._attributes = [];
  257. this._chain = [];
  258. for (const entry of Object.entries(layer)) {
  259. const name = entry[0];
  260. if (name === 'type' || name === 'location' || name === 'inputs' || name === 'outputs' || name === 'chain') {
  261. continue;
  262. }
  263. const value = entry[1];
  264. const attribute = new kmodel.Attribute(name, value);
  265. this._attributes.push(attribute);
  266. }
  267. for (const input of layer.inputs || []) {
  268. this._inputs.push(new kmodel.Parameter(input.name, input.arguments.map((argument) => {
  269. const type = argument.shape ? new kmodel.TensorType(argument.datatype || '?', argument.shape) : null;
  270. const tensor = argument.data ? new kmodel.Tensor(type, argument.data) : null;
  271. return new kmodel.Argument(argument.name, type, tensor);
  272. })));
  273. }
  274. for (const output of layer.outputs || []) {
  275. this._outputs.push(new kmodel.Parameter(output.name, output.arguments.map((argument) => {
  276. const type = argument.shape ? new kmodel.TensorType(argument.datatype || '?', argument.shape) : null;
  277. return new kmodel.Argument(argument.name, type);
  278. })));
  279. }
  280. for (const chain of layer.chain || []) {
  281. this._chain.push(new kmodel.Node(chain));
  282. }
  283. }
  284. get location() {
  285. return this._location;
  286. }
  287. get name() {
  288. return '';
  289. }
  290. get type() {
  291. return this._type;
  292. }
  293. get inputs() {
  294. return this._inputs;
  295. }
  296. get outputs() {
  297. return this._outputs;
  298. }
  299. get attributes() {
  300. return this._attributes;
  301. }
  302. get chain() {
  303. return this._chain;
  304. }
  305. };
  306. kmodel.Attribute = class {
  307. constructor(name, value) {
  308. this._name = name;
  309. this._value = value;
  310. }
  311. get name() {
  312. return this._name;
  313. }
  314. get value() {
  315. return this._value;
  316. }
  317. };
  318. kmodel.Reader = class {
  319. static open(stream) {
  320. if (stream && stream.length >= 4) {
  321. const length = Math.min(8, stream.length);
  322. const buffer = stream.peek(length);
  323. if ([ 0x03, 0x00, 0x00, 0x00 ].every((value, index) => value === buffer[index])) {
  324. return new kmodel.Reader(stream, 3);
  325. }
  326. if ([ 0x4C, 0x44, 0x4D, 0x4B ].every((value, index) => value === buffer[index]) && buffer.length >= 8) {
  327. const reader = new base.BinaryReader(buffer);
  328. reader.skip(4);
  329. const version = reader.uint32();
  330. return new kmodel.Reader(stream, version);
  331. }
  332. }
  333. return null;
  334. }
  335. constructor(stream, version) {
  336. this._stream = stream;
  337. this._version = version;
  338. this._modules = [];
  339. }
  340. get version() {
  341. return this._version;
  342. }
  343. get modules() {
  344. this._read();
  345. return this._modules;
  346. }
  347. _read() {
  348. if (this._stream) {
  349. if (this._version < 3 || this._version > 5) {
  350. throw new kmodel.Error("Unsupported model version '" + this.version.toString() + "'.");
  351. }
  352. const types = new Map();
  353. const register = (type, name, category, callback) => {
  354. types.set(type, { type: { name: name, category: category || '' }, callback: callback });
  355. };
  356. switch (this._version) {
  357. case 3: {
  358. const reader = new kmodel.BinaryReader.v3(this._stream);
  359. const model_header = reader.kpu_model_header_t();
  360. const layers = new Array(model_header.layers_length);
  361. const outputs = new Array(model_header.output_count);
  362. for (let i = 0; i < model_header.output_count; i++) {
  363. outputs[i] = reader.kpu_model_output_t('output' + (i > 0 ? i.toString() : ''));
  364. }
  365. for (let i = 0; i < layers.length; i++) {
  366. layers[i] = reader.kpu_model_layer_header_t();
  367. layers[i].location = i;
  368. }
  369. let offset = reader.position;
  370. for (const layer of layers) {
  371. layer.offset = offset;
  372. offset += layer.body_size;
  373. }
  374. register( -1, 'DUMMY');
  375. register( 0, 'INVALID');
  376. register( 1, 'ADD');
  377. register( 2, 'QUANTIZED_ADD');
  378. register( 3, 'GLOBAL_MAX_POOL2D', 'Pool');
  379. register( 4, 'QUANTIZED_GLOBAL_MAX_POOL2D', 'Pool');
  380. register( 5, 'GLOBAL_AVERAGE_POOL2D', 'Pool', (layer, reader) => {
  381. layer.flags = reader.uint32();
  382. layer.inputs = [ reader.parameter('input') ];
  383. layer.outputs = [ reader.parameter('output') ];
  384. layer.kernel_size = reader.uint32();
  385. layer.channels = reader.uint32();
  386. });
  387. register( 6, 'QUANTIZED_GLOBAL_AVERAGE_POOL2D', 'Pool');
  388. register( 7, 'MAX_POOL2D', 'Pool');
  389. register( 8, 'QUANTIZED_MAX_POOL2D', 'Pool', (layer, reader) => {
  390. layer.flags = reader.uint32();
  391. layer.inputs = [ reader.parameter('input') ];
  392. layer.outputs = [ reader.parameter('output') ];
  393. layer.inputs[0].arguments[0].shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  394. layer.outputs[0].arguments[0].shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  395. layer.kernel = [ reader.uint32(), reader.uint32() ];
  396. layer.stride = [ reader.uint32(), reader.uint32() ];
  397. layer.padding = [ reader.uint32(), reader.uint32() ];
  398. });
  399. register( 9, 'AVERAGE_POOL2D', 'Pool');
  400. register( 10, 'QUANTIZED_AVERAGE_POOL2D', 'Pool');
  401. register( 11, 'QUANTIZE', '', (layer, reader) => {
  402. layer.flags = reader.uint32();
  403. layer.inputs = [ reader.parameter('input') ];
  404. layer.outputs = [ reader.parameter('output') ];
  405. layer.count = reader.uint32();
  406. layer.scale = reader.float32();
  407. layer.bias = reader.float32();
  408. });
  409. register( 12, 'DEQUANTIZE', '', (layer, reader) => {
  410. layer.flags = reader.uint32();
  411. layer.inputs = [ reader.parameter('input') ];
  412. layer.outputs = [ reader.parameter('output') ];
  413. layer.count = reader.uint32();
  414. layer.scale = reader.float32();
  415. layer.bias = reader.float32();
  416. });
  417. register( 13, 'REQUANTIZE', '', (layer, reader) => {
  418. layer.flags = reader.uint32();
  419. layer.inputs = [ reader.parameter('input') ];
  420. layer.outputs = [ reader.parameter('output') ];
  421. layer.count = reader.uint32();
  422. layer.table = reader.read(256);
  423. });
  424. register( 14, 'L2_NORMALIZATION', 'Normalization');
  425. register( 15, 'SOFTMAX', 'Activation', (layer, reader) => {
  426. layer.flags = reader.uint32();
  427. layer.inputs = [ reader.parameter('input') ];
  428. layer.outputs = [ reader.parameter('output') ];
  429. layer.channels = reader.uint32();
  430. });
  431. register( 16, 'CONCAT', 'Tensor', (layer, reader) => {
  432. layer.flags = reader.uint32();
  433. layer.outputs = [ reader.parameter('output') ];
  434. layer.inputs_mem = new Array(reader.uint32());
  435. for (let i = 0; i < layer.inputs_mem.length; i++) {
  436. layer.inputs_mem[i] = {
  437. start: reader.uint32(),
  438. end: reader.uint32()
  439. };
  440. }
  441. });
  442. register( 17, 'QUANTIZED_CONCAT', 'Tensor', (layer, reader) => {
  443. layer.flags = reader.uint32();
  444. layer.outputs = [ reader.parameter('output') ];
  445. layer.inputs_mem = new Array(reader.uint32());
  446. for (let i = 0; i < layer.inputs_mem.length; i++) {
  447. layer.inputs_mem[i] = {
  448. start: reader.uint32(),
  449. end: reader.uint32()
  450. };
  451. }
  452. });
  453. register( 18, 'FULLY_CONNECTED', 'Layer', (layer, reader) => {
  454. layer.flags = reader.uint32();
  455. layer.inputs = [ reader.parameter('input') ];
  456. layer.outputs = [ reader.parameter('output') ];
  457. layer.in_channels = reader.uint32();
  458. layer.out_channels = reader.uint32();
  459. const act = reader.uint32();
  460. const activations = [
  461. { name: 'LINEAR', category: 'Activation' },
  462. { name: 'RELU', category: 'Activation' },
  463. { name: 'RELU6', category: 'Activation' },
  464. ];
  465. if (act !== 0) {
  466. if (act > activations.length) {
  467. throw new kmodel.Error("Unsupported FULLY_CONNECTED activation '" + act.toString() + "'.");
  468. }
  469. layer.chain = [ { type: activations[act] } ];
  470. }
  471. layer.inputs.push({ name: 'weights', arguments: [ { name: '', datatype: 'float32', shape: [ layer.in_channels, layer.out_channels ], data: reader.read(4 * layer.in_channels * layer.out_channels) } ] });
  472. layer.inputs.push({ name: 'bias', arguments: [ { name: '', datatype: 'float32', shape: [ layer.out_channels ], data: reader.read(4 * layer.out_channels) } ] });
  473. });
  474. register( 19, 'QUANTIZED_FULLY_CONNECTED', 'Layer');
  475. register( 20, 'TENSORFLOW_FLATTEN', 'Shape', (layer, reader) => {
  476. layer.flags = reader.uint32();
  477. layer.inputs = [ reader.parameter('input') ];
  478. layer.outputs = [ reader.parameter('output') ];
  479. const shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  480. layer.inputs[0].arguments[0].shape = shape;
  481. layer.outputs[0].arguments[0].shape = shape;
  482. });
  483. register( 21, 'QUANTIZED_TENSORFLOW_FLATTEN', 'Shape', (layer, reader) => {
  484. layer.flags = reader.uint32();
  485. layer.inputs = [ reader.parameter('input') ];
  486. layer.outputs = [ reader.parameter('output') ];
  487. const shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  488. layer.inputs[0].arguments[0].shape = shape;
  489. layer.outputs[0].arguments[0].shape = shape;
  490. });
  491. register( 22, 'RESIZE_NEAREST_NEIGHBOR', '', (layer, reader) => {
  492. layer.flags = reader.uint32();
  493. layer.inputs = [ reader.parameter('input') ];
  494. layer.outputs = [ reader.parameter('output') ];
  495. layer.inputs[0].arguments[0].shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  496. layer.out_width = reader.uint32();
  497. layer.out_height = reader.uint32();
  498. layer.align_corners = reader.uint32();
  499. });
  500. register( 23, 'QUANTIZED_RESIZE_NEAREST_NEIGHBOR', '', (layer, reader) => {
  501. layer.flags = reader.uint32();
  502. layer.inputs = [ reader.parameter('input') ];
  503. layer.outputs = [ reader.parameter('output') ];
  504. layer.inputs[0].arguments[0].shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  505. layer.out_width = reader.uint32();
  506. layer.out_height = reader.uint32();
  507. layer.align_corners = reader.uint32();
  508. });
  509. register( 1000, 'CONV', 'Layer');
  510. register( 1001, 'DWCONV', 'Layer');
  511. register( 1002, 'QUANTIZED_RESHAPE', 'Shape');
  512. register( 1003, 'RESHAPE', 'Shape');
  513. register(10240, 'K210_CONV', 'Layer', (layer, reader) => {
  514. layer.flags = reader.uint32();
  515. layer.outputs = [ reader.parameter('output') ];
  516. const layer_offset = reader.uint32();
  517. const weights_offset = reader.uint32();
  518. const bn_offset = reader.uint32();
  519. const act_offset = reader.uint32();
  520. reader.seek(layer_offset);
  521. layer.interrupt_enabe = reader.uint64_bits({ int_en: 0, ram_flag: 1, full_add: 2, depth_wise_layer: 3 });
  522. layer.inputs = [ reader.parameter('input', 'kpu') ];
  523. const outputs = [ reader.parameter('output', 'kpu') ];
  524. layer.outputs[0].arguments.push(outputs[0].arguments[0]);
  525. // layer.outputs = layer.flags & 1 ? layer.outputs : outputs;
  526. layer.image_channel_num = reader.uint64_bits({ i_ch_num: 0, o_ch_num: 32, o_ch_num_coef: 48 });
  527. layer.image_size = reader.uint64_bits({ i_row_wid: 0, i_col_high: 10, o_row_wid: 32, o_col_high : 42 });
  528. layer.kernel_pool_type_cfg = reader.uint64_bits({ kernel_type: 0, pad_type: 3, pool_type: 4, first_stride: 8, bypass_conv: 9, load_para: 10, dma_burst_size: 16, pad_value: 24, bwsx_base_addr: 32 });
  529. layer.kernel_load_cfg = reader.uint64_bits({ load_coor: 0, load_time: 1, para_size: 15, para_start_addr: 32 });
  530. layer.kernel_offset = reader.uint64_bits({ coef_column_offset: 0, coef_row_offset: 4 });
  531. layer.kernel_calc_type_cfg = reader.uint64_bits({ channel_switch_addr: 0, row_switch_addr: 16, coef_size: 20, coef_group: 28, load_act: 31, active_addr: 32 });
  532. layer.write_back_cfg = reader.uint64_bits({ wb_channel_switch_addr: 0, wb_row_switch_addr: 16, wb_group: 20 });
  533. layer.conv_value = reader.uint64_bits({ shr_w: 0, shr_x: 4, arg_w: 8, arg_x: 32 });
  534. layer.conv_value2 = reader.uint64_bits({ arg_add: 0 });
  535. layer.dma_parameter = reader.uint64_bits({ send_data_out: 0, channel_byte_num: 16, dma_total_byte: 32 });
  536. layer.chain = [];
  537. const ic = layer.image_channel_num.i_ch_num + 1;
  538. const oc = layer.image_channel_num.o_ch_num + 1;
  539. const filter = [ 1, 3 ][layer.kernel_pool_type_cfg.kernel_type];
  540. const weights_shape = layer.interrupt_enabe.depth_wise_layer ? [ oc, filter, filter ] : [ ic, oc, filter, filter ];
  541. const weights_size = weights_shape.reduce((a, b) => a * b);
  542. reader.seek(bn_offset);
  543. const batch_norm = {
  544. type: { name: 'BATCH_NORM', category: 'Normalization' },
  545. weights: []
  546. };
  547. batch_norm.weights = new Array(oc);
  548. for (let i = 0; i < oc; i++) {
  549. batch_norm.weights[i] = reader.uint64_bits({ norm_mul: 0, norm_add: 24, norm_shift: 56, reserved: 60 });
  550. delete batch_norm.weights[i].reserved;
  551. }
  552. layer.chain.push(batch_norm);
  553. reader.seek(act_offset);
  554. const activation = {};
  555. activation.type = { name: 'ACTIVATION', category: 'Activation' };
  556. activation.activate_para = new Array(16);
  557. for (let i = 0; i < 16; i++) {
  558. activation.activate_para[i] = reader.uint64_bits({ shift_number: 0, y_mul: 8, x_start: 24, reserved: 60 });
  559. delete activation.activate_para[i].reserved;
  560. }
  561. for (let i = 0; i < 16; i++) {
  562. activation.activate_para[i].bias = reader.int8();
  563. }
  564. layer.chain.push(activation);
  565. reader.seek(weights_offset);
  566. layer.inputs.push({
  567. name: 'weights',
  568. arguments: [ {
  569. name: 'const',
  570. datatype: 'uint8',
  571. shape: weights_shape,
  572. data: reader.read(weights_size)
  573. } ]
  574. });
  575. delete layer.kernel_pool_type_cfg.bwsx_base_addr;
  576. delete layer.kernel_calc_type_cfg.active_addr;
  577. delete layer.kernel_load_cfg.para_start_addr;
  578. });
  579. register(10241, 'K210_ADD_PADDING', '', (layer, reader) => {
  580. layer.flags = reader.uint32();
  581. layer.inputs = [ reader.parameter('input') ];
  582. layer.outputs = [ reader.parameter('output', 'kpu') ];
  583. layer.channels = reader.uint32();
  584. });
  585. register(10242, 'K210_REMOVE_PADDING', '', (layer, reader) => {
  586. layer.flags = reader.uint32();
  587. layer.inputs = [ reader.parameter('input') ];
  588. layer.outputs = [ reader.parameter('output') ];
  589. layer.channels = reader.uint32();
  590. });
  591. register(10243, 'K210_UPLOAD', '', (layer, reader) => {
  592. layer.flags = reader.uint32();
  593. layer.inputs = [ reader.parameter('input') ];
  594. layer.outputs = [ reader.parameter('output', 'kpu') ];
  595. const shape = [ reader.uint32(), reader.uint32(), reader.uint32() ];
  596. layer.inputs[0].arguments[0].shape = shape;
  597. layer.outputs[0].arguments[0].shape = shape;
  598. });
  599. for (const layer of layers) {
  600. const type = types.get(layer.type);
  601. if (!type) {
  602. throw new kmodel.Error("Unsupported version '" + this._version.toString() + "' layer type '" + layer.type.toString() + "'.");
  603. }
  604. if (!type.callback) {
  605. throw new kmodel.Error("Unsupported version '" + this._version.toString() + "' layer '" + type.type.name + "'.");
  606. }
  607. layer.type = type.type;
  608. reader.seek(layer.offset);
  609. type.callback(layer, reader);
  610. delete layer.offset;
  611. delete layer.body_size;
  612. }
  613. if (layers.length > 0) {
  614. layers.unshift({
  615. type: { name: 'input' },
  616. outputs: [ layers[0].inputs[0] ]
  617. });
  618. }
  619. for (const output of outputs) {
  620. layers.push({
  621. type: { name: 'output' },
  622. inputs: output.address
  623. });
  624. }
  625. this._modules.push({
  626. name: '',
  627. layers: layers
  628. });
  629. break;
  630. }
  631. case 4: {
  632. const reader = new kmodel.BinaryReader.v4(this._stream);
  633. const model_header = {
  634. flags: reader.uint32(),
  635. target: reader.uint32(), // 0=CPU, 1=K210
  636. constants: reader.uint32(),
  637. main_mem: reader.uint32(),
  638. nodes: reader.uint32(),
  639. inputs: reader.uint32(),
  640. outputs: reader.uint32(),
  641. reserved0: reader.uint32(),
  642. };
  643. const inputs = new Array(model_header.inputs);
  644. for (let i = 0; i < inputs.length; i++) {
  645. inputs[i] = reader.parameter('input' + (i == 0 ? '' : (i + 1).toString()));
  646. }
  647. for (let i = 0; i < inputs.length; i++) {
  648. inputs[i].arguments[0].shape = reader.runtime_shape_t();
  649. }
  650. const outputs = new Array(model_header.outputs);
  651. for (let i = 0; i < outputs.length; i++) {
  652. outputs[i] = reader.parameter('output' + (i == 0 ? '' : (i + 1).toString()));
  653. }
  654. reader.constants(model_header.constants);
  655. const layers = new Array(model_header.nodes);
  656. for (let i = 0; i < layers.length; i++) {
  657. layers[i] = {
  658. location: i,
  659. opcode: reader.uint32(),
  660. body_size: reader.uint32()
  661. };
  662. }
  663. let offset = reader.position;
  664. for (const layer of layers) {
  665. layer.offset = offset;
  666. offset += layer.body_size;
  667. }
  668. register( 0x00, 'binary', '', (layer, reader) => {
  669. layer.inputs = [
  670. reader.parameter('a'),
  671. reader.parameter('b')
  672. ];
  673. layer.outputs = [ reader.parameter('outputs') ];
  674. layer.binary_op = reader.binary_op_t();
  675. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  676. layer.inputs[1].arguments[0].shape = reader.runtime_shape_t();
  677. layer.outputs[0].arguments[0].shape = reader.runtime_shape_t();
  678. layer.fused_activation = [ reader.float32(), reader.float32() ];
  679. });
  680. register( 0x01, 'concat', 'Tensor', (layer, reader) => {
  681. layer.outputs = [ reader.parameter('output') ];
  682. layer.inner_size = reader.uint32();
  683. layer.outer_size = reader.uint32();
  684. const inputs_count = reader.uint32();
  685. layer.inputs = [ { name: 'inputs', arguments: [] } ];
  686. for (let i = 0; i < inputs_count; i++) {
  687. layer.inputs[0].arguments[i] = reader.argument();
  688. }
  689. layer.dims = new Array(inputs_count);
  690. for (let i = 0; i < inputs_count; i++) {
  691. layer.dims[i] = reader.int32();
  692. }
  693. });
  694. register( 0x02, 'conv2d', 'Layer', (layer, reader) => {
  695. layer.inputs = [ reader.parameter('input') ];
  696. layer.outputs = [ reader.parameter('output') ];
  697. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  698. layer.groups = reader.int32();
  699. layer.out_channels = reader.int32();
  700. layer.padding_h = reader.padding();
  701. layer.padding_w = reader.padding();
  702. layer.filter_h = reader.int32();
  703. layer.filter_w = reader.int32();
  704. layer.stride_h = reader.int32();
  705. layer.stride_w = reader.int32();
  706. layer.dilation_h = reader.int32();
  707. layer.dilation_w = reader.int32();
  708. layer.fused_activation = [ reader.float32(), reader.float32() ];
  709. const weights_shape = [ layer.out_channels, layer.inputs[0].arguments[0].shape[1] / layer.groups, layer.filter_h, layer.filter_w ];
  710. const weights_size = 4 * weights_shape.reduce((a, b) => a * b);
  711. layer.inputs.push({
  712. name: 'weights',
  713. arguments: [ {
  714. name: 'const',
  715. datatype: 'float32',
  716. shape: weights_shape,
  717. data: reader.read(weights_size)
  718. } ]
  719. });
  720. const bias_shape = [ layer.out_channels ];
  721. const bias_size = 4 * layer.out_channels;
  722. layer.inputs.push({
  723. name: 'bias',
  724. arguments: [ {
  725. name: 'const',
  726. datatype: 'float32',
  727. shape: bias_shape,
  728. data: reader.read(bias_size)
  729. } ]
  730. });
  731. });
  732. register( 0x03, 'dequantize', '', (layer, reader) => {
  733. layer.inputs = [ reader.parameter('input') ];
  734. layer.outputs = [ reader.parameter('output') ];
  735. layer.zero_point = reader.int32();
  736. layer.scale = reader.float32();
  737. });
  738. register( 0x04, 'matmul', '', (layer, reader) => {
  739. layer.inputs = [
  740. reader.parameter('a'),
  741. reader.parameter('b'),
  742. ];
  743. layer.outputs = [ reader.parameter('output') ];
  744. layer.a_rows = reader.int32();
  745. layer.a_cols = reader.int32();
  746. layer.b_cols = reader.int32();
  747. layer.inputs[1].arguments[0].shape = [ layer.a_cols, layer.b_cols ];
  748. layer.fused_activation = [ reader.float32(), reader.float32() ];
  749. const bias = reader.read(4 * layer.b_cols);
  750. if (!bias.every((value) => value === 0)) {
  751. layer.inputs.push({
  752. name: 'bias',
  753. arguments: [ { name: 'const', datatype: 'float32', shape: [ layer.b_cols ], data: bias } ]
  754. });
  755. }
  756. });
  757. register( 0x05, 'pad', 'Shape', (layer, reader) => {
  758. layer.inputs = [ reader.parameter('input') ];
  759. layer.outputs = [ reader.parameter('output') ];
  760. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  761. layer.paddings = reader.runtime_paddings_t();
  762. layer.pad_value = reader.scalar();
  763. });
  764. register( 0x06, 'quantize', '', (layer, reader) => {
  765. layer.inputs = [ reader.parameter('input') ];
  766. layer.outputs = [ reader.parameter('output') ];
  767. layer.zero_point = reader.int32();
  768. layer.scale = reader.float32();
  769. });
  770. register( 0x07, 'reduce', '', (layer, reader) => {
  771. layer.inputs = [ reader.parameter('input') ];
  772. layer.outputs = [ reader.parameter('output') ];
  773. layer.reduce_op = reader.reduce_op_t();
  774. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  775. layer.outputs[0].arguments[0].shape = reader.runtime_shape_t();
  776. layer.init_value = reader.float32();
  777. });
  778. register( 0x08, 'reduce_window2d', '', (layer, reader) => {
  779. layer.inputs = [ reader.parameter('input') ];
  780. layer.outputs = [ reader.parameter('output') ];
  781. layer.reduce_op = reader.reduce_op_t();
  782. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  783. layer.padding_h = reader.padding();
  784. layer.padding_w = reader.padding();
  785. layer.filter_h = reader.int32();
  786. layer.filter_w = reader.int32();
  787. layer.stride_h = reader.int32();
  788. layer.stride_w = reader.int32();
  789. layer.dilation_h = reader.int32();
  790. layer.dilation_w = reader.int32();
  791. layer.init_value = reader.float32();
  792. layer.fused_activation = [ reader.float32(), reader.float32() ];
  793. });
  794. register( 0x09, 'memory_copy', '', (layer, reader) => {
  795. layer.inputs = [ reader.parameter('input') ];
  796. layer.outputs = [ reader.parameter('output') ];
  797. });
  798. register( 0x0A, 'resize_image', '', (layer, reader) => {
  799. layer.inputs = [ reader.parameter('input') ];
  800. layer.outputs = [ reader.parameter('output') ];
  801. layer.reduce_op = reader.reduce_op_t();
  802. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  803. layer.out_h = reader.int32();
  804. layer.out_w = reader.int32();
  805. layer.mode = reader.image_resize_mode_t();
  806. layer.align_corners = reader.boolean();
  807. });
  808. register( 0x0B, 'softmax', 'Activation');
  809. register( 0x0C, 'transpose', 'Transform', (layer, reader) => {
  810. layer.inputs = [ reader.parameter('input') ];
  811. layer.outputs = [ reader.parameter('output') ];
  812. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  813. layer.perm = reader.runtime_shape_t();
  814. });
  815. register( 0x0D, 'strided_slice', 'Tensor');
  816. register( 0x0E, 'unary', '', (layer, reader) => {
  817. layer.inputs = [ reader.parameter('input') ];
  818. layer.outputs = [ reader.parameter('output') ];
  819. layer.unary_op = reader.unary_op_t();
  820. });
  821. register( 0x0F, 'quantized_conv2d', 'Layer');
  822. register( 0x10, 'quantized_matmul', '', (layer, reader) => {
  823. layer.inputs = [
  824. reader.parameter('a'),
  825. reader.parameter('b'),
  826. ];
  827. layer.outputs = [ reader.parameter('output') ];
  828. layer.a_rows = reader.int32();
  829. layer.a_cols = reader.int32();
  830. layer.b_cols = reader.int32();
  831. layer.inputs[1].arguments[0].shape = [ layer.a_cols, layer.b_cols ];
  832. layer.input_a_offset = reader.int32();
  833. layer.input_b_offset = reader.int32();
  834. layer.output_mul = reader.int32();
  835. layer.output_shift = reader.int32();
  836. layer.output_offset = reader.int32();
  837. const bias = reader.read(4 * layer.b_cols);
  838. if (!bias.every((value) => value === 0)) {
  839. layer.inputs.push({
  840. name: 'bias',
  841. arguments: [ { name: 'const', datatype: 'int32', shape: [ layer.b_cols ], data: bias } ]
  842. });
  843. }
  844. });
  845. register( 0x11, 'quantized_binary', '', (layer, reader) => {
  846. layer.inputs = [
  847. reader.parameter('a'),
  848. reader.parameter('b')
  849. ];
  850. layer.outputs = [ reader.parameter('outputs') ];
  851. layer.binary_op = reader.binary_op_t();
  852. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  853. layer.inputs[1].arguments[0].shape = reader.runtime_shape_t();
  854. layer.outputs[0].arguments[0].shape = reader.runtime_shape_t();
  855. layer.input_a_offset = reader.int32();
  856. layer.input_a_mul = reader.int32();
  857. layer.input_a_shift = reader.int32();
  858. layer.input_b_offset = reader.int32();
  859. layer.input_b_mul = reader.int32();
  860. layer.input_b_shift = reader.int32();
  861. layer.output_offset = reader.int32();
  862. layer.output_mul = reader.int32();
  863. layer.output_shift = reader.int32();
  864. });
  865. register( 0x12, 'table_lookup1d', '', (layer, reader) => {
  866. layer.inputs = [ reader.parameter('input'), reader.parameter('table') ];
  867. layer.outputs = [ reader.parameter('output') ];
  868. });
  869. register( 0x13, 'conv2d_transpose', 'Layer');
  870. register( 0x14, 'nnil_unary_method', '', (layer, reader, size) => {
  871. const position = reader.position;
  872. layer.inputs = [ reader.parameter('input') ];
  873. layer.outputs = [ reader.parameter('output') ];
  874. layer.body = reader.read(size - (reader.position - position));
  875. });
  876. register(0x1001, 'cpu_conv2d', 'Layer');
  877. register(0x1002, 'cpu_depthwise_conv2d', 'Layer');
  878. register(0x1003, 'cpu_reduce_window2d');
  879. register(0x1004, 'cpu_quantized_conv2d', 'Layer');
  880. register(0x1005, 'cpu_quantized_depthwise_conv2d', 'Layer');
  881. register(0x2001, 'kpu_upload', '', (layer, reader) => {
  882. layer.inputs = [ reader.parameter('input') ];
  883. layer.outputs = [ reader.parameter('output') ];
  884. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  885. });
  886. register(0x2002, 'kpu_conv2d', 'Layer', (layer, reader) => {
  887. layer.outputs = [ reader.parameter('output') ];
  888. layer.batches = reader.int32();
  889. layer.reserved0 = reader.int32();
  890. layer.interrupt_enabe = reader.uint64_bits({ int_en: 0, ram_flag: 1, full_add: 2, depth_wise_layer: 3 });
  891. const image_src_addr = reader.uint32();
  892. const image_dst_addr = reader.uint32();
  893. layer.inputs = [ { name: 'input', arguments: [ { name: 'kpu:' + image_src_addr.toString() } ] } ];
  894. const outputs = [ { name: 'output', arguments: [ { name: 'kpu:' + image_dst_addr.toString() } ] } ];
  895. layer.outputs[0].arguments.push(outputs[0].arguments[0]);
  896. // layer.outputs = layer.flags & 1 ? layer.outputs : outputs;
  897. layer.image_channel_num = reader.uint64_bits({ i_ch_num: 0, o_ch_num: 32, o_ch_num_coef: 48 });
  898. layer.image_size = reader.uint64_bits({ i_row_wid: 0, i_col_high: 10, o_row_wid: 32, o_col_high : 42 });
  899. layer.kernel_pool_type_cfg = reader.uint64_bits({ kernel_type: 0, pad_type: 3, pool_type: 4, first_stride: 8, bypass_conv: 9, load_para: 10, dma_burst_size: 16, pad_value: 24, bwsx_base_addr: 32 });
  900. layer.kernel_load_cfg = reader.uint64_bits({ load_coor: 0, load_time: 1, para_size: 15, para_start_addr: 32 });
  901. layer.kernel_offset = reader.uint64_bits({ coef_column_offset: 0, coef_row_offset: 4 });
  902. layer.kernel_calc_type_cfg = reader.uint64_bits({ channel_switch_addr: 0, row_switch_addr: 16, coef_size: 20, coef_group: 28, load_act: 31, active_addr: 32 });
  903. layer.write_back_cfg = reader.uint64_bits({ wb_channel_switch_addr: 0, wb_row_switch_addr: 16, wb_group: 20 });
  904. layer.conv_value = reader.uint64_bits({ shr_w: 0, shr_x: 4, arg_w: 8, arg_x: 32 });
  905. layer.conv_value2 = reader.uint64_bits({ arg_add: 0 });
  906. layer.dma_parameter = reader.uint64_bits({ send_data_out: 0, reserved: 1, channel_byte_num: 16, dma_total_byte: 32 });
  907. layer.chain = [];
  908. const ic = layer.image_channel_num.i_ch_num + 1;
  909. const oc = layer.image_channel_num.o_ch_num + 1;
  910. const filter = [ 1, 3 ][layer.kernel_pool_type_cfg.kernel_type];
  911. const weights_shape = layer.interrupt_enabe.depth_wise_layer ? [ oc, filter, filter ] : [ ic, oc, filter, filter ];
  912. const weights_size = weights_shape.reduce((a, b) => a * b);
  913. reader.skip(layer.kernel_pool_type_cfg.bwsx_base_addr);
  914. delete layer.kernel_pool_type_cfg.bwsx_base_addr;
  915. const batch_norm = {
  916. type: { name: 'batch_norm', category: 'Normalization' },
  917. weights: []
  918. };
  919. batch_norm.weights = new Array(oc);
  920. for (let i = 0; i < oc; i++) {
  921. batch_norm.weights[i] = reader.uint64_bits({ norm_mul: 0, norm_add: 24, norm_shift: 56, reserved: 60 });
  922. delete batch_norm.weights[i].reserved;
  923. }
  924. layer.chain.push(batch_norm);
  925. reader.skip(layer.kernel_calc_type_cfg.active_addr);
  926. delete layer.kernel_calc_type_cfg.active_addr;
  927. const activation = reader.kpu_activate_table_t();
  928. activation.type = { name: 'activation', category: 'Activation' };
  929. layer.chain.push(activation);
  930. reader.skip(layer.kernel_load_cfg.para_start_addr);
  931. delete layer.kernel_load_cfg.para_start_addr;
  932. layer.inputs.push({
  933. name: 'weights',
  934. arguments: [ {
  935. name: 'const',
  936. datatype: 'uint8',
  937. shape: weights_shape,
  938. data: reader.read(weights_size)
  939. } ]
  940. });
  941. });
  942. for (const layer of layers) {
  943. const type = types.get(layer.opcode);
  944. if (!type) {
  945. throw new kmodel.Error("Unsupported version '" + this._version.toString() + "' layer type '" + layer.type.toString() + "'.");
  946. }
  947. if (!type.callback) {
  948. throw new kmodel.Error("Unsupported version '" + this._version.toString() + "' layer '" + type.type.name + "'.");
  949. }
  950. layer.type = type.type;
  951. reader.seek(layer.offset);
  952. if (type.callback) {
  953. type.callback(layer, reader, layer.body_size);
  954. }
  955. delete layer.offset;
  956. delete layer.body_size;
  957. delete layer.opcode;
  958. }
  959. for (const input of inputs) {
  960. layers.unshift({
  961. type: { name: 'INPUT' },
  962. outputs: [ input ]
  963. });
  964. }
  965. for (const output of outputs) {
  966. layers.push({
  967. type: { name: 'OUTPUT' },
  968. inputs: [ output ]
  969. });
  970. }
  971. this._modules.push({
  972. name: '',
  973. layers: layers
  974. });
  975. break;
  976. }
  977. case 5: {
  978. const reader = new kmodel.BinaryReader.v5(this._stream);
  979. const model_header = reader.model_header();
  980. if (model_header.header_size < 32) {
  981. throw new kmodel.Error("Invalid header size '" + model_header.header_size + "'.");
  982. }
  983. if (model_header.header_size > reader.position) {
  984. reader.skip(model_header.header_size - reader.position);
  985. }
  986. delete model_header.header_size;
  987. this._modules = new Array(model_header.modules);
  988. for (let i = 0; i < this._modules.length; i++) {
  989. const start = reader.position;
  990. const module_header = reader.module_header();
  991. if (module_header.header_size > (reader.position - start)) {
  992. reader.skip(module_header.header_size - (reader.position - start));
  993. }
  994. const mempools = new Array(module_header.mempools);
  995. for (let i = 0; i < mempools.length; i++) {
  996. mempools[i] = reader.mempool_desc();
  997. }
  998. const shared_mempools = new Array(module_header.shared_mempools);
  999. for (let i = 0; i < shared_mempools.length; i++) {
  1000. shared_mempools[i] = reader.mempool_desc();
  1001. }
  1002. const function_headers = new Array(module_header.functions);
  1003. const functions = new Array(module_header.functions);
  1004. for (let i = 0; i < functions.length; i++) {
  1005. const position = reader.position;
  1006. const function_header = reader.function_header();
  1007. const header_size = reader.position - position;
  1008. if (function_header.header_size > header_size) {
  1009. reader.skip(function_header.header_size - header_size);
  1010. }
  1011. const inputs = new Array(function_header.inputs);
  1012. for (let i = 0; i < inputs.length; i++) {
  1013. inputs[i] = reader.parameter('input' + (i == 0 ? '' : (i + 1).toString()));
  1014. }
  1015. for (let i = 0; i < inputs.length; i++) {
  1016. inputs[i].arguments[0].shape = reader.shape();
  1017. }
  1018. const outputs = new Array(function_header.outputs);
  1019. for (let i = 0; i < outputs.length; i++) {
  1020. outputs[i] = reader.parameter('output' + (i == 0 ? '' : (i + 1).toString()));
  1021. }
  1022. for (let i = 0; i < outputs.length; i++) {
  1023. outputs[i].arguments[0].shape = reader.shape();
  1024. }
  1025. reader.align_position(8);
  1026. const size = reader.size - position;
  1027. if (function_header.size > size) {
  1028. reader.skip(function_header.size - size);
  1029. }
  1030. function_headers[i] = function_header;
  1031. functions[i] = {
  1032. type: { name: 'Unknown' },
  1033. inputs: inputs,
  1034. outputs: outputs
  1035. };
  1036. }
  1037. const sections = new Map();
  1038. for (let i = 0; i < module_header.sections; i++) {
  1039. const section_header = reader.section_header();
  1040. reader.skip(section_header.body_start);
  1041. const body = reader.read(section_header.body_size);
  1042. const section = {
  1043. reader: new base.BinaryReader(body),
  1044. flags: section_header.flags
  1045. };
  1046. reader.align_position(8);
  1047. sections.set(section_header.name, section);
  1048. }
  1049. for (let i = 0; i < function_headers.length; i++) {
  1050. const function_header = function_headers[i];
  1051. const reader = sections.get('.text').reader;
  1052. reader.seek(function_header.entrypoint);
  1053. function_header.text = reader.read(function_header.text_size);
  1054. const layer = functions[i];
  1055. switch (module_header.type) {
  1056. case 'stackvm':
  1057. layer.type = { name: 'stackvm' };
  1058. break;
  1059. case 'k210':
  1060. break;
  1061. case 'k510':
  1062. break;
  1063. default:
  1064. throw new kmodel.Error("Unsupported module type '" + module_header.type + "'.");
  1065. }
  1066. }
  1067. const name = this._modules.length > 1 ? i.toString() : '';
  1068. this._modules[i] = {
  1069. name: name,
  1070. type: module_header.type,
  1071. layers: functions
  1072. };
  1073. }
  1074. break;
  1075. }
  1076. default: {
  1077. throw new kmodel.Error("Unsupported model version '" + this.version.toString() + "'.");
  1078. }
  1079. }
  1080. delete this._stream;
  1081. }
  1082. }
  1083. };
  1084. kmodel.BinaryReader = class extends base.BinaryReader {
  1085. uint64_bits(fields) {
  1086. const buffer = this.read(8);
  1087. fields = Object.entries(fields);
  1088. fields.push([ null, Math.min(64, fields[fields.length - 1][1] + 56)]);
  1089. const obj = {};
  1090. for (let i = 0; i < fields.length - 1; i++) {
  1091. const key = fields[i][0];
  1092. let value = 0;
  1093. let position = fields[i][1];
  1094. const end = fields[i + 1][1];
  1095. while (position < end) {
  1096. const offset = (position / 8) >> 0;
  1097. const start = (position & 7);
  1098. const count = Math.min((offset + 1) * 8, end) - position;
  1099. value = value | ((buffer[offset] >>> start) & ((1 << count) - 1)) << (position - fields[i][1]);
  1100. position += count;
  1101. }
  1102. obj[key] = value;
  1103. }
  1104. return obj;
  1105. }
  1106. };
  1107. kmodel.BinaryReader.v3 = class extends kmodel.BinaryReader {
  1108. constructor(buffer) {
  1109. super(buffer);
  1110. this.skip(4);
  1111. }
  1112. kpu_model_header_t() {
  1113. return {
  1114. flags: this.uint32(),
  1115. arch: this.uint32(),
  1116. layers_length: this.uint32(),
  1117. max_start_address: this.uint32(),
  1118. main_mem_usage: this.uint32(),
  1119. output_count: this.uint32()
  1120. };
  1121. }
  1122. kpu_model_output_t(name) {
  1123. return {
  1124. address: [ this.parameter(name) ],
  1125. size: this.uint32()
  1126. };
  1127. }
  1128. kpu_model_layer_header_t() {
  1129. return {
  1130. type: this.uint32(),
  1131. body_size: this.uint32()
  1132. };
  1133. }
  1134. argument(memory_type) {
  1135. memory_type = memory_type || 'main';
  1136. const address = this.uint32();
  1137. return { name: memory_type + ':' + address.toString() };
  1138. }
  1139. parameter(name, memory_type) {
  1140. const argument = this.argument(memory_type);
  1141. return { name: name, arguments: [ argument ] };
  1142. }
  1143. };
  1144. kmodel.BinaryReader.v4 = class extends kmodel.BinaryReader {
  1145. constructor(buffer) {
  1146. super(buffer);
  1147. this.skip(8);
  1148. this._memory_types = [ 'const', 'main', 'kpu' ];
  1149. this._datatypes = [ 'float32', 'uint8' ];
  1150. }
  1151. memory_type_t() {
  1152. const value = this.uint32();
  1153. return this._memory_types[value];
  1154. }
  1155. datatype_t() {
  1156. const value = this.uint32();
  1157. return this._datatypes[value];
  1158. }
  1159. memory_range() {
  1160. return {
  1161. memory_type: this.memory_type_t(),
  1162. datatype: this.datatype_t(),
  1163. start: this.uint32(),
  1164. size: this.uint32()
  1165. };
  1166. }
  1167. argument() {
  1168. const memory = this.memory_range();
  1169. const value = {
  1170. name: memory.memory_type + ':' + memory.start.toString(),
  1171. datatype: memory.datatype
  1172. };
  1173. if (memory.memory_type === 'const') {
  1174. value.data = this._constants.slice(memory.start, memory.start + memory.size);
  1175. switch (value.datatype) {
  1176. case 'uint8': value.shape = [ value.data.length ]; break;
  1177. case 'float32': value.shape = [ value.data.length >> 2 ]; break;
  1178. default: break;
  1179. }
  1180. }
  1181. return value;
  1182. }
  1183. parameter(name) {
  1184. const argument = this.argument();
  1185. return { name: name, arguments: [ argument ] };
  1186. }
  1187. runtime_shape_t() {
  1188. return [ this.uint32(), this.uint32(), this.uint32(), this.uint32() ];
  1189. }
  1190. padding() {
  1191. return { before: this.int32(), after: this.int32() };
  1192. }
  1193. runtime_paddings_t() {
  1194. return [ this.padding(), this.padding(), this.padding(), this.padding() ];
  1195. }
  1196. scalar() {
  1197. return {
  1198. datatype_t: this.uint32(),
  1199. storage: this.read(4)
  1200. };
  1201. }
  1202. kpu_activate_table_t() {
  1203. const value = {};
  1204. value.activate_para = new Array(16);
  1205. for (let i = 0; i < 16; i++) {
  1206. value.activate_para[i] = this.uint64_bits({ shift_number: 0, y_mul: 8, x_start: 24, reserved: 60 });
  1207. delete value.activate_para[i].reserved;
  1208. }
  1209. for (let i = 0; i < 16; i++) {
  1210. value.activate_para[i].bias = this.int8();
  1211. }
  1212. return value;
  1213. }
  1214. unary_op_t() {
  1215. const value = this.uint32();
  1216. return [ 'abs', 'ceil', 'cos', 'exp', 'floor', 'log', 'neg', 'rsqrt', 'sin', 'square' ][value];
  1217. }
  1218. binary_op_t() {
  1219. const value = this.uint32();
  1220. return [ 'add', 'sub', 'mul', 'div', 'min', 'max' ][value];
  1221. }
  1222. reduce_op_t() {
  1223. const value = this.uint32();
  1224. return [ 'mean', 'min', 'max', 'sum' ][value];
  1225. }
  1226. image_resize_mode_t() {
  1227. const value = this.uint32();
  1228. return [ 'bilinear', 'nearest_neighbor' ][value];
  1229. }
  1230. constants(size) {
  1231. this._constants = this.read(size);
  1232. }
  1233. };
  1234. kmodel.BinaryReader.v5 = class extends kmodel.BinaryReader {
  1235. constructor(buffer) {
  1236. super(buffer);
  1237. this.skip(8);
  1238. this._datatypes = [ 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'float16', 'float32', 'float64', 'bfloat16' ];
  1239. this._memory_locations = new Map([ [ 0, 'input' ], [ 1, 'output' ], [ 2, 'rdata' ], [ 3, 'data' ], [ 4, 'shared_data' ], [ 64, 'kpu' ] ]);
  1240. }
  1241. model_header() {
  1242. return {
  1243. header_size: this.uint32(),
  1244. flags: this.uint32(),
  1245. alignment: this.uint32(),
  1246. modules: this.uint32(),
  1247. entry_module: this.uint32(),
  1248. entry_function: this.uint32()
  1249. };
  1250. }
  1251. module_type_t() {
  1252. const buffer = this.read(16);
  1253. const decoder = new TextDecoder('ascii');
  1254. const text = decoder.decode(buffer);
  1255. return text.replace(/\0.*$/, '');
  1256. }
  1257. module_header() {
  1258. return {
  1259. type: this.module_type_t(),
  1260. version: this.uint32(),
  1261. header_size: this.uint32(),
  1262. size: this.uint32(),
  1263. mempools: this.uint32(),
  1264. shared_mempools: this.uint32(),
  1265. sections: this.uint32(),
  1266. functions: this.uint32(),
  1267. reserved0: this.uint32()
  1268. };
  1269. }
  1270. mempool_desc() {
  1271. return {
  1272. location: this.byte(),
  1273. reserved0: this.read(3),
  1274. size: this.uint32()
  1275. };
  1276. }
  1277. section_header() {
  1278. const buffer = this.read(16);
  1279. const decoder = new TextDecoder('ascii');
  1280. const name = decoder.decode(buffer);
  1281. return {
  1282. name: name.replace(/\0.*$/, ''),
  1283. flags: this.uint32(),
  1284. body_start: this.uint32(),
  1285. body_size: this.uint32(),
  1286. reserved0: this.uint32()
  1287. };
  1288. }
  1289. function_header() {
  1290. return {
  1291. header_size: this.uint32(),
  1292. size: this.uint32(),
  1293. input_pool_size: this.uint32(),
  1294. output_pool_size: this.uint32(),
  1295. inputs: this.uint32(),
  1296. outputs: this.uint32(),
  1297. entrypoint: this.uint32(),
  1298. text_size: this.uint32()
  1299. };
  1300. }
  1301. memory_location_t() {
  1302. const value = this.byte();
  1303. if (!this._memory_locations.has(value)) {
  1304. throw new kmodel.Error("Unsupported memory location '" + value + "'.");
  1305. }
  1306. return this._memory_locations.get(value);
  1307. }
  1308. datatype_t() {
  1309. const value = this.byte();
  1310. return this._datatypes[value];
  1311. }
  1312. memory_range() {
  1313. return {
  1314. memory_location: this.memory_location_t(),
  1315. datatype: this.datatype_t(),
  1316. shared_module: this.uint16(),
  1317. start: this.uint32(),
  1318. size: this.uint32()
  1319. };
  1320. }
  1321. argument() {
  1322. const memory = this.memory_range();
  1323. const value = {
  1324. name: memory.memory_location + ':' + memory.start.toString(),
  1325. datatype: memory.datatype
  1326. };
  1327. /*
  1328. if (memory.memory_type === 'const') {
  1329. value.data = constants.slice(memory.start, memory.start + memory.size);
  1330. switch (value.datatype) {
  1331. case 'uint8': value.shape = [ value.data.length ]; break;
  1332. case 'float32': value.shape = [ value.data.length >> 2 ]; break;
  1333. default: break;
  1334. }
  1335. }
  1336. */
  1337. return value;
  1338. }
  1339. parameter(name) {
  1340. const argument = this.argument();
  1341. return { name: name, arguments: [ argument ] };
  1342. }
  1343. shape() {
  1344. const array = new Array(this.uint32());
  1345. for (let i = 0; i < array.length; i++) {
  1346. array[i] = this.uint32();
  1347. }
  1348. return array;
  1349. }
  1350. align_position(alignment) {
  1351. const remainder = this._position % alignment;
  1352. if (remainder !== 0) {
  1353. this.skip(alignment - remainder);
  1354. }
  1355. }
  1356. };
  1357. kmodel.Error = class extends Error {
  1358. constructor(message) {
  1359. super(message);
  1360. this.name = 'Error loading kmodel.';
  1361. }
  1362. };
  1363. if (typeof module !== 'undefined' && typeof module.exports === 'object') {
  1364. module.exports.ModelFactory = kmodel.ModelFactory;
  1365. }