message.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Experimental
  2. const message = {};
  3. message.ModelFactory = class {
  4. async match(context) {
  5. const stream = context.stream;
  6. if (stream) {
  7. const buffer = stream.peek(Math.min(64, stream.length));
  8. const content = String.fromCharCode.apply(null, buffer);
  9. const match = content.match(/^{\s*"signature":\s*"(.*)"\s*,\s*/);
  10. if (match && match[1].startsWith('netron:')) {
  11. const obj = await context.peek('json');
  12. if (obj && obj.signature && obj.signature.startsWith('netron:')) {
  13. return context.set('message', obj);
  14. }
  15. }
  16. }
  17. return null;
  18. }
  19. async open(context) {
  20. return new message.Model(context.value);
  21. }
  22. };
  23. message.Model = class {
  24. constructor(data) {
  25. this.format = data.format || '';
  26. this.format = this.format.replace(/\s+(\d+\.\d+)$/, ' v$1'); // Format v2.0
  27. this.producer = data.producer || '';
  28. this.version = data.version || '';
  29. this.description = data.description || '';
  30. this.metadata = (data.metadata || []).map((entry) => {
  31. return { name: entry.name, value: entry.value };
  32. });
  33. const modules = data.modules || data.graphs || [];
  34. this.modules = modules.map((module) => new message.Module(module));
  35. }
  36. };
  37. message.Module = class {
  38. constructor(data) {
  39. this.inputs = [];
  40. this.outputs = [];
  41. this.nodes = [];
  42. const values = new Map();
  43. values.map = (index) => {
  44. if (!values.has(index)) {
  45. values.set(index, new message.Value({ name: index.toString() }));
  46. }
  47. return values.get(index);
  48. };
  49. if (Array.isArray(data.values)) {
  50. for (let i = 0; i < data.values.length; i++) {
  51. values.set(i, new message.Value(data.values[i]));
  52. }
  53. }
  54. if (Array.isArray(data.arguments)) {
  55. for (let i = 0; i < data.arguments.length; i++) {
  56. values.set(data.arguments[i].name, new message.Value(data.arguments[i]));
  57. }
  58. }
  59. for (const argument of data.inputs || []) {
  60. argument.value = argument.value.map((index) => values.map(index)).filter((argument) => !argument.initializer);
  61. if (argument.value.filter((argument) => !argument.initializer).length > 0) {
  62. this.inputs.push(new message.Argument(argument));
  63. }
  64. }
  65. for (const argument of data.outputs || []) {
  66. argument.value = argument.value.map((index) => values.map(index));
  67. if (argument.value.filter((argument) => !argument.initializer).length > 0) {
  68. this.outputs.push(new message.Argument(argument));
  69. }
  70. }
  71. for (const node of data.nodes || []) {
  72. for (const argument of node.inputs || []) {
  73. if (!argument.value && argument.arguments) {
  74. argument.value = argument.arguments;
  75. delete argument.arguments;
  76. }
  77. argument.value = argument.value.map((index) => values.map(index));
  78. }
  79. for (const argument of node.outputs || []) {
  80. if (!argument.value && argument.arguments) {
  81. argument.value = argument.arguments;
  82. delete argument.arguments;
  83. }
  84. argument.value = argument.value.map((index) => values.map(index));
  85. }
  86. this.nodes.push(new message.Node(node));
  87. }
  88. }
  89. };
  90. message.Argument = class {
  91. constructor(data) {
  92. this.name = data.name || '';
  93. this.value = data.value || [];
  94. this.type = data.type || null;
  95. }
  96. };
  97. message.Value = class {
  98. constructor(data) {
  99. this.name = data.name !== undefined && data.name !== null ? data.name.toString() : '';
  100. this.initializer = data.initializer ? new message.Tensor(data.initializer) : null;
  101. if (this.initializer && this.initializer.type) {
  102. this.type = this.initializer.type;
  103. } else {
  104. this.type = data.type ? new message.TensorType(data.type) : null;
  105. }
  106. }
  107. };
  108. message.Node = class {
  109. constructor(data) {
  110. this.type = { name: data.type.name, category: data.type.category };
  111. this.name = data.name || '';
  112. this.inputs = (data.inputs || []).map((input) => new message.Argument(input));
  113. this.outputs = (data.outputs || []).map((output) => new message.Argument(output));
  114. this.attributes = (data.attributes || []).map((attribute) => new message.Argument(attribute));
  115. }
  116. };
  117. message.TensorType = class {
  118. constructor(data) {
  119. this.dataType = data.dataType;
  120. this.shape = new message.TensorShape(data.shape);
  121. }
  122. toString() {
  123. return this.dataType + this.shape.toString();
  124. }
  125. };
  126. message.TensorShape = class {
  127. constructor(data) {
  128. this.dimensions = data.dimensions;
  129. }
  130. toString() {
  131. return `[${this.dimensions}]`;
  132. }
  133. };
  134. message.Tensor = class {
  135. constructor(data) {
  136. this.type = new message.TensorType(data.type);
  137. }
  138. };
  139. message.Error = class extends Error {
  140. constructor(message) {
  141. super(message);
  142. this.name = 'Message Error';
  143. }
  144. };
  145. export const ModelFactory = message.ModelFactory;