kmodel.js 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468
  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', '');
  871. register(0x1001, 'cpu_conv2d', 'Layer');
  872. register(0x1002, 'cpu_depthwise_conv2d', 'Layer');
  873. register(0x1003, 'cpu_reduce_window2d');
  874. register(0x1004, 'cpu_quantized_conv2d', 'Layer');
  875. register(0x1005, 'cpu_quantized_depthwise_conv2d', 'Layer');
  876. register(0x2001, 'kpu_upload', '', (layer, reader) => {
  877. layer.inputs = [ reader.parameter('input') ];
  878. layer.outputs = [ reader.parameter('output') ];
  879. layer.inputs[0].arguments[0].shape = reader.runtime_shape_t();
  880. });
  881. register(0x2002, 'kpu_conv2d', 'Layer', (layer, reader) => {
  882. layer.outputs = [ reader.parameter('output') ];
  883. layer.batches = reader.int32();
  884. layer.reserved0 = reader.int32();
  885. layer.interrupt_enabe = reader.uint64_bits({ int_en: 0, ram_flag: 1, full_add: 2, depth_wise_layer: 3 });
  886. const image_src_addr = reader.uint32();
  887. const image_dst_addr = reader.uint32();
  888. layer.inputs = [ { name: 'input', arguments: [ { name: 'kpu:' + image_src_addr.toString() } ] } ];
  889. const outputs = [ { name: 'output', arguments: [ { name: 'kpu:' + image_dst_addr.toString() } ] } ];
  890. layer.outputs[0].arguments.push(outputs[0].arguments[0]);
  891. // layer.outputs = layer.flags & 1 ? layer.outputs : outputs;
  892. layer.image_channel_num = reader.uint64_bits({ i_ch_num: 0, o_ch_num: 32, o_ch_num_coef: 48 });
  893. layer.image_size = reader.uint64_bits({ i_row_wid: 0, i_col_high: 10, o_row_wid: 32, o_col_high : 42 });
  894. 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 });
  895. layer.kernel_load_cfg = reader.uint64_bits({ load_coor: 0, load_time: 1, para_size: 15, para_start_addr: 32 });
  896. layer.kernel_offset = reader.uint64_bits({ coef_column_offset: 0, coef_row_offset: 4 });
  897. 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 });
  898. layer.write_back_cfg = reader.uint64_bits({ wb_channel_switch_addr: 0, wb_row_switch_addr: 16, wb_group: 20 });
  899. layer.conv_value = reader.uint64_bits({ shr_w: 0, shr_x: 4, arg_w: 8, arg_x: 32 });
  900. layer.conv_value2 = reader.uint64_bits({ arg_add: 0 });
  901. layer.dma_parameter = reader.uint64_bits({ send_data_out: 0, reserved: 1, channel_byte_num: 16, dma_total_byte: 32 });
  902. layer.chain = [];
  903. const ic = layer.image_channel_num.i_ch_num + 1;
  904. const oc = layer.image_channel_num.o_ch_num + 1;
  905. const filter = [ 1, 3 ][layer.kernel_pool_type_cfg.kernel_type];
  906. const weights_shape = layer.interrupt_enabe.depth_wise_layer ? [ oc, filter, filter ] : [ ic, oc, filter, filter ];
  907. const weights_size = weights_shape.reduce((a, b) => a * b);
  908. reader.skip(layer.kernel_pool_type_cfg.bwsx_base_addr);
  909. delete layer.kernel_pool_type_cfg.bwsx_base_addr;
  910. const batch_norm = {
  911. type: { name: 'batch_norm', category: 'Normalization' },
  912. weights: []
  913. };
  914. batch_norm.weights = new Array(oc);
  915. for (let i = 0; i < oc; i++) {
  916. batch_norm.weights[i] = reader.uint64_bits({ norm_mul: 0, norm_add: 24, norm_shift: 56, reserved: 60 });
  917. delete batch_norm.weights[i].reserved;
  918. }
  919. layer.chain.push(batch_norm);
  920. reader.skip(layer.kernel_calc_type_cfg.active_addr);
  921. delete layer.kernel_calc_type_cfg.active_addr;
  922. const activation = reader.kpu_activate_table_t();
  923. activation.type = { name: 'activation', category: 'Activation' };
  924. layer.chain.push(activation);
  925. reader.skip(layer.kernel_load_cfg.para_start_addr);
  926. delete layer.kernel_load_cfg.para_start_addr;
  927. layer.inputs.push({
  928. name: 'weights',
  929. arguments: [ {
  930. name: 'const',
  931. datatype: 'uint8',
  932. shape: weights_shape,
  933. data: reader.read(weights_size)
  934. } ]
  935. });
  936. });
  937. for (const layer of layers) {
  938. const type = types.get(layer.opcode);
  939. if (!type) {
  940. throw new kmodel.Error("Unsupported version '" + this._version.toString() + "' layer type '" + layer.type.toString() + "'.");
  941. }
  942. if (!type.callback) {
  943. throw new kmodel.Error("Unsupported version '" + this._version.toString() + "' layer '" + type.type.name + "'.");
  944. }
  945. layer.type = type.type;
  946. reader.seek(layer.offset);
  947. if (type.callback) {
  948. type.callback(layer, reader);
  949. }
  950. delete layer.offset;
  951. delete layer.body_size;
  952. delete layer.opcode;
  953. if (reader.position != (layer.offset + layer.body_size)) {
  954. // debugger;
  955. }
  956. }
  957. for (const input of inputs) {
  958. layers.unshift({
  959. type: { name: 'INPUT' },
  960. outputs: [ input ]
  961. });
  962. }
  963. for (const output of outputs) {
  964. layers.push({
  965. type: { name: 'OUTPUT' },
  966. inputs: [ output ]
  967. });
  968. }
  969. this._modules.push({
  970. name: '',
  971. layers: layers
  972. });
  973. break;
  974. }
  975. case 5: {
  976. const reader = new kmodel.BinaryReader.v5(this._stream);
  977. const model_header = reader.model_header();
  978. if (model_header.header_size < 32) {
  979. throw new kmodel.Error("Invalid header size '" + model_header.header_size + "'.");
  980. }
  981. if (model_header.header_size > reader.position) {
  982. reader.skip(model_header.header_size - reader.position);
  983. }
  984. delete model_header.header_size;
  985. this._modules = new Array(model_header.modules);
  986. for (let i = 0; i < this._modules.length; i++) {
  987. const start = reader.position;
  988. const module_header = reader.module_header();
  989. if (module_header.header_size > (reader.position - start)) {
  990. reader.skip(module_header.header_size - (reader.position - start));
  991. }
  992. const mempools = new Array(module_header.mempools);
  993. for (let i = 0; i < mempools.length; i++) {
  994. mempools[i] = reader.mempool_desc();
  995. }
  996. const shared_mempools = new Array(module_header.shared_mempools);
  997. for (let i = 0; i < shared_mempools.length; i++) {
  998. shared_mempools[i] = reader.mempool_desc();
  999. }
  1000. const function_headers = new Array(module_header.functions);
  1001. const functions = new Array(module_header.functions);
  1002. for (let i = 0; i < functions.length; i++) {
  1003. const position = reader.position;
  1004. const function_header = reader.function_header();
  1005. const header_size = reader.position - position;
  1006. if (function_header.header_size > header_size) {
  1007. reader.skip(function_header.header_size - header_size);
  1008. }
  1009. const inputs = new Array(function_header.inputs);
  1010. for (let i = 0; i < inputs.length; i++) {
  1011. inputs[i] = reader.parameter('input' + (i == 0 ? '' : (i + 1).toString()));
  1012. }
  1013. for (let i = 0; i < inputs.length; i++) {
  1014. inputs[i].arguments[0].shape = reader.shape();
  1015. }
  1016. const outputs = new Array(function_header.outputs);
  1017. for (let i = 0; i < outputs.length; i++) {
  1018. outputs[i] = reader.parameter('output' + (i == 0 ? '' : (i + 1).toString()));
  1019. }
  1020. for (let i = 0; i < outputs.length; i++) {
  1021. outputs[i].arguments[0].shape = reader.shape();
  1022. }
  1023. reader.align_position(8);
  1024. const size = reader.size - position;
  1025. if (function_header.size > size) {
  1026. reader.skip(function_header.size - size);
  1027. }
  1028. function_headers[i] = function_header;
  1029. functions[i] = {
  1030. type: { name: 'Unknown' },
  1031. inputs: inputs,
  1032. outputs: outputs
  1033. };
  1034. }
  1035. const sections = new Map();
  1036. for (let i = 0; i < module_header.sections; i++) {
  1037. const section_header = reader.section_header();
  1038. reader.skip(section_header.body_start);
  1039. const body = reader.read(section_header.body_size);
  1040. const section = {
  1041. reader: new base.BinaryReader(body),
  1042. flags: section_header.flags
  1043. };
  1044. reader.align_position(8);
  1045. sections.set(section_header.name, section);
  1046. }
  1047. for (let i = 0; i < function_headers.length; i++) {
  1048. const function_header = function_headers[i];
  1049. const reader = sections.get('.text').reader;
  1050. reader.seek(function_header.entrypoint);
  1051. function_header.text = reader.read(function_header.text_size);
  1052. const layer = functions[i];
  1053. switch (module_header.type) {
  1054. case 'stackvm':
  1055. layer.type = { name: 'stackvm' };
  1056. break;
  1057. case 'k210':
  1058. break;
  1059. case 'k510':
  1060. break;
  1061. default:
  1062. throw new kmodel.Error("Unsupported module type '" + module_header.type + "'.");
  1063. }
  1064. }
  1065. const name = this._modules.length > 1 ? i.toString() : '';
  1066. this._modules[i] = {
  1067. name: name,
  1068. type: module_header.type,
  1069. layers: functions
  1070. };
  1071. }
  1072. break;
  1073. }
  1074. default: {
  1075. throw new kmodel.Error("Unsupported model version '" + this.version.toString() + "'.");
  1076. }
  1077. }
  1078. delete this._stream;
  1079. }
  1080. }
  1081. };
  1082. kmodel.BinaryReader = class extends base.BinaryReader {
  1083. uint64_bits(fields) {
  1084. const buffer = this.read(8);
  1085. fields = Object.entries(fields);
  1086. fields.push([ null, Math.min(64, fields[fields.length - 1][1] + 56)]);
  1087. const obj = {};
  1088. for (let i = 0; i < fields.length - 1; i++) {
  1089. const key = fields[i][0];
  1090. let value = 0;
  1091. let position = fields[i][1];
  1092. const end = fields[i + 1][1];
  1093. while (position < end) {
  1094. const offset = (position / 8) >> 0;
  1095. const start = (position & 7);
  1096. const count = Math.min((offset + 1) * 8, end) - position;
  1097. value = value | ((buffer[offset] >>> start) & ((1 << count) - 1)) << (position - fields[i][1]);
  1098. position += count;
  1099. }
  1100. obj[key] = value;
  1101. }
  1102. return obj;
  1103. }
  1104. };
  1105. kmodel.BinaryReader.v3 = class extends kmodel.BinaryReader {
  1106. constructor(buffer) {
  1107. super(buffer);
  1108. this.skip(4);
  1109. }
  1110. kpu_model_header_t() {
  1111. return {
  1112. flags: this.uint32(),
  1113. arch: this.uint32(),
  1114. layers_length: this.uint32(),
  1115. max_start_address: this.uint32(),
  1116. main_mem_usage: this.uint32(),
  1117. output_count: this.uint32()
  1118. };
  1119. }
  1120. kpu_model_output_t(name) {
  1121. return {
  1122. address: [ this.parameter(name) ],
  1123. size: this.uint32()
  1124. };
  1125. }
  1126. kpu_model_layer_header_t() {
  1127. return {
  1128. type: this.uint32(),
  1129. body_size: this.uint32()
  1130. };
  1131. }
  1132. argument(memory_type) {
  1133. memory_type = memory_type || 'main';
  1134. const address = this.uint32();
  1135. return { name: memory_type + ':' + address.toString() };
  1136. }
  1137. parameter(name, memory_type) {
  1138. const argument = this.argument(memory_type);
  1139. return { name: name, arguments: [ argument ] };
  1140. }
  1141. };
  1142. kmodel.BinaryReader.v4 = class extends kmodel.BinaryReader {
  1143. constructor(buffer) {
  1144. super(buffer);
  1145. this.skip(8);
  1146. this._memory_types = [ 'const', 'main', 'kpu' ];
  1147. this._datatypes = [ 'float32', 'uint8' ];
  1148. }
  1149. memory_type_t() {
  1150. const value = this.uint32();
  1151. return this._memory_types[value];
  1152. }
  1153. datatype_t() {
  1154. const value = this.uint32();
  1155. return this._datatypes[value];
  1156. }
  1157. memory_range() {
  1158. return {
  1159. memory_type: this.memory_type_t(),
  1160. datatype: this.datatype_t(),
  1161. start: this.uint32(),
  1162. size: this.uint32()
  1163. };
  1164. }
  1165. argument() {
  1166. const memory = this.memory_range();
  1167. const value = {
  1168. name: memory.memory_type + ':' + memory.start.toString(),
  1169. datatype: memory.datatype
  1170. };
  1171. if (memory.memory_type === 'const') {
  1172. value.data = this._constants.slice(memory.start, memory.start + memory.size);
  1173. switch (value.datatype) {
  1174. case 'uint8': value.shape = [ value.data.length ]; break;
  1175. case 'float32': value.shape = [ value.data.length >> 2 ]; break;
  1176. default: break;
  1177. }
  1178. }
  1179. return value;
  1180. }
  1181. parameter(name) {
  1182. const argument = this.argument();
  1183. return { name: name, arguments: [ argument ] };
  1184. }
  1185. runtime_shape_t() {
  1186. return [ this.uint32(), this.uint32(), this.uint32(), this.uint32() ];
  1187. }
  1188. padding() {
  1189. return { before: this.int32(), after: this.int32() };
  1190. }
  1191. runtime_paddings_t() {
  1192. return [ this.padding(), this.padding(), this.padding(), this.padding() ];
  1193. }
  1194. scalar() {
  1195. return {
  1196. datatype_t: this.uint32(),
  1197. storage: this.read(4)
  1198. };
  1199. }
  1200. kpu_activate_table_t() {
  1201. const value = {};
  1202. value.activate_para = new Array(16);
  1203. for (let i = 0; i < 16; i++) {
  1204. value.activate_para[i] = this.uint64_bits({ shift_number: 0, y_mul: 8, x_start: 24, reserved: 60 });
  1205. delete value.activate_para[i].reserved;
  1206. }
  1207. for (let i = 0; i < 16; i++) {
  1208. value.activate_para[i].bias = this.int8();
  1209. }
  1210. return value;
  1211. }
  1212. unary_op_t() {
  1213. const value = this.uint32();
  1214. return [ 'abs', 'ceil', 'cos', 'exp', 'floor', 'log', 'neg', 'rsqrt', 'sin', 'square' ][value];
  1215. }
  1216. binary_op_t() {
  1217. const value = this.uint32();
  1218. return [ 'add', 'sub', 'mul', 'div', 'min', 'max' ][value];
  1219. }
  1220. reduce_op_t() {
  1221. const value = this.uint32();
  1222. return [ 'mean', 'min', 'max', 'sum' ][value];
  1223. }
  1224. image_resize_mode_t() {
  1225. const value = this.uint32();
  1226. return [ 'bilinear', 'nearest_neighbor' ][value];
  1227. }
  1228. constants(size) {
  1229. this._constants = this.read(size);
  1230. }
  1231. };
  1232. kmodel.BinaryReader.v5 = class extends kmodel.BinaryReader {
  1233. constructor(buffer) {
  1234. super(buffer);
  1235. this.skip(8);
  1236. this._datatypes = [ 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'float16', 'float32', 'float64', 'bfloat16' ];
  1237. this._memory_locations = new Map([ [ 0, 'input' ], [ 1, 'output' ], [ 2, 'rdata' ], [ 3, 'data' ], [ 4, 'shared_data' ], [ 64, 'kpu' ] ]);
  1238. }
  1239. model_header() {
  1240. return {
  1241. header_size: this.uint32(),
  1242. flags: this.uint32(),
  1243. alignment: this.uint32(),
  1244. modules: this.uint32(),
  1245. entry_module: this.uint32(),
  1246. entry_function: this.uint32()
  1247. };
  1248. }
  1249. module_type_t() {
  1250. const buffer = this.read(16);
  1251. const decoder = new TextDecoder('ascii');
  1252. const text = decoder.decode(buffer);
  1253. return text.replace(/\0.*$/, '');
  1254. }
  1255. module_header() {
  1256. return {
  1257. type: this.module_type_t(),
  1258. version: this.uint32(),
  1259. header_size: this.uint32(),
  1260. size: this.uint32(),
  1261. mempools: this.uint32(),
  1262. shared_mempools: this.uint32(),
  1263. sections: this.uint32(),
  1264. functions: this.uint32(),
  1265. reserved0: this.uint32()
  1266. };
  1267. }
  1268. mempool_desc() {
  1269. return {
  1270. location: this.byte(),
  1271. reserved0: this.read(3),
  1272. size: this.uint32()
  1273. };
  1274. }
  1275. section_header() {
  1276. const buffer = this.read(16);
  1277. const decoder = new TextDecoder('ascii');
  1278. const name = decoder.decode(buffer);
  1279. return {
  1280. name: name.replace(/\0.*$/, ''),
  1281. flags: this.uint32(),
  1282. body_start: this.uint32(),
  1283. body_size: this.uint32(),
  1284. reserved0: this.uint32()
  1285. };
  1286. }
  1287. function_header() {
  1288. return {
  1289. header_size: this.uint32(),
  1290. size: this.uint32(),
  1291. input_pool_size: this.uint32(),
  1292. output_pool_size: this.uint32(),
  1293. inputs: this.uint32(),
  1294. outputs: this.uint32(),
  1295. entrypoint: this.uint32(),
  1296. text_size: this.uint32()
  1297. };
  1298. }
  1299. memory_location_t() {
  1300. const value = this.byte();
  1301. if (!this._memory_locations.has(value)) {
  1302. throw new kmodel.Error("Unsupported memory location '" + value + "'.");
  1303. }
  1304. return this._memory_locations.get(value);
  1305. }
  1306. datatype_t() {
  1307. const value = this.byte();
  1308. return this._datatypes[value];
  1309. }
  1310. memory_range() {
  1311. return {
  1312. memory_location: this.memory_location_t(),
  1313. datatype: this.datatype_t(),
  1314. shared_module: this.uint16(),
  1315. start: this.uint32(),
  1316. size: this.uint32()
  1317. };
  1318. }
  1319. argument() {
  1320. const memory = this.memory_range();
  1321. const value = {
  1322. name: memory.memory_location + ':' + memory.start.toString(),
  1323. datatype: memory.datatype
  1324. };
  1325. /*
  1326. if (memory.memory_type === 'const') {
  1327. value.data = constants.slice(memory.start, memory.start + memory.size);
  1328. switch (value.datatype) {
  1329. case 'uint8': value.shape = [ value.data.length ]; break;
  1330. case 'float32': value.shape = [ value.data.length >> 2 ]; break;
  1331. default: break;
  1332. }
  1333. }
  1334. */
  1335. return value;
  1336. }
  1337. parameter(name) {
  1338. const argument = this.argument();
  1339. return { name: name, arguments: [ argument ] };
  1340. }
  1341. shape() {
  1342. const array = new Array(this.uint32());
  1343. for (let i = 0; i < array.length; i++) {
  1344. array[i] = this.uint32();
  1345. }
  1346. return array;
  1347. }
  1348. align_position(alignment) {
  1349. const remainder = this._position % alignment;
  1350. if (remainder !== 0) {
  1351. this.skip(alignment - remainder);
  1352. }
  1353. }
  1354. };
  1355. kmodel.Error = class extends Error {
  1356. constructor(message) {
  1357. super(message);
  1358. this.name = 'Error loading kmodel.';
  1359. }
  1360. };
  1361. if (typeof module !== 'undefined' && typeof module.exports === 'object') {
  1362. module.exports.ModelFactory = kmodel.ModelFactory;
  1363. }