2
0

kmodel.js 63 KB

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