nnil.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* Copyright 2019-2020 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #pragma once
  16. #include "../datatypes.h"
  17. #include "binary_writer.h"
  18. #include "span_reader.h"
  19. namespace nncase
  20. {
  21. namespace runtime
  22. {
  23. typedef enum _nnil_opcode
  24. {
  25. nnil_nop = 0x00,
  26. nnil_dup = 0x01,
  27. nnil_pop = 0x02,
  28. nnil_lda_0 = 0x03,
  29. nnil_ldc_r4_0 = 0x04,
  30. nnil_ldc_r4_1 = 0x05,
  31. nnil_ldc_r4 = 0x06,
  32. nnil_abs = 0x20,
  33. nnil_ceil = 0x21,
  34. nnil_cos = 0x22,
  35. nnil_exp = 0x23,
  36. nnil_floor = 0x24,
  37. nnil_log = 0x25,
  38. nnil_neg = 0x26,
  39. nnil_rsqrt = 0x27,
  40. nnil_sin = 0x28,
  41. nnil_square = 0x29,
  42. nnil_add = 0x40,
  43. nnil_sub = 0x41,
  44. nnil_mul = 0x42,
  45. nnil_div = 0x43,
  46. nnil_min = 0x44,
  47. nnil_max = 0x45,
  48. nnil_clamp = 0x80,
  49. nnil_ret = 0xA0
  50. } nnil_opcode_t;
  51. typedef struct _nnil_ldc_r4
  52. {
  53. float r4;
  54. } nnil_ldc_r4_t;
  55. typedef struct _nnil_op
  56. {
  57. nnil_opcode_t opcode;
  58. union {
  59. nnil_ldc_r4_t ldc_r4;
  60. };
  61. } nnil_op_t;
  62. class nnil_builder
  63. {
  64. public:
  65. nnil_builder(binary_writer &writer)
  66. : writer_(writer) {}
  67. void emit_nop() { emit_opcode(nnil_nop); }
  68. void emit_dup() { emit_opcode(nnil_dup); }
  69. void emit_pop() { emit_opcode(nnil_pop); }
  70. void emit_lda_0() { emit_opcode(nnil_lda_0); }
  71. void emit_ldc_r4_0() { emit_opcode(nnil_ldc_r4_0); }
  72. void emit_ldc_r4_1() { emit_opcode(nnil_ldc_r4_1); }
  73. void emit_ldc_r4(float value)
  74. {
  75. emit_opcode(nnil_ldc_r4);
  76. writer_.write(nnil_ldc_r4_t { value });
  77. }
  78. void emit_abs() { emit_opcode(nnil_abs); }
  79. void emit_ceil() { emit_opcode(nnil_ceil); }
  80. void emit_cos() { emit_opcode(nnil_cos); }
  81. void emit_exp() { emit_opcode(nnil_exp); }
  82. void emit_floor() { emit_opcode(nnil_floor); }
  83. void emit_log() { emit_opcode(nnil_log); }
  84. void emit_neg() { emit_opcode(nnil_neg); }
  85. void emit_rsqrt() { emit_opcode(nnil_rsqrt); }
  86. void emit_sin() { emit_opcode(nnil_sin); }
  87. void emit_square() { emit_opcode(nnil_square); }
  88. void emit_add() { emit_opcode(nnil_add); }
  89. void emit_sub() { emit_opcode(nnil_sub); }
  90. void emit_mul() { emit_opcode(nnil_mul); }
  91. void emit_div() { emit_opcode(nnil_div); }
  92. void emit_min() { emit_opcode(nnil_min); }
  93. void emit_max() { emit_opcode(nnil_max); }
  94. void emit_clamp() { emit_opcode(nnil_clamp); }
  95. void emit_ret() { emit_opcode(nnil_ret); }
  96. private:
  97. void emit_opcode(nnil_opcode_t opcode) { writer_.write((uint8_t)opcode); }
  98. private:
  99. binary_writer &writer_;
  100. };
  101. class nnil_reader
  102. {
  103. public:
  104. nnil_reader(span_reader &reader)
  105. : reader_(reader) {}
  106. bool avail() const noexcept { return !reader_.empty(); }
  107. nnil_op_t next()
  108. {
  109. assert(avail());
  110. nnil_op_t op;
  111. op.opcode = (nnil_opcode_t)reader_.read<uint8_t>();
  112. switch (op.opcode)
  113. {
  114. case nnil_ldc_r4:
  115. op.ldc_r4 = reader_.read_unaligned<nnil_ldc_r4_t>();
  116. break;
  117. default:
  118. break;
  119. }
  120. return op;
  121. }
  122. private:
  123. span_reader &reader_;
  124. };
  125. class nnil_evalstack
  126. {
  127. public:
  128. nnil_evalstack() noexcept
  129. : top(0)
  130. {
  131. }
  132. void push(float value)
  133. {
  134. if (top < _stack.size())
  135. _stack[top++] = value;
  136. else
  137. NNCASE_THROW(std::runtime_error, "stack overflow");
  138. }
  139. float pop()
  140. {
  141. if (top > 0)
  142. return _stack[--top];
  143. else
  144. NNCASE_THROW(std::runtime_error, "stack underflow");
  145. }
  146. void dup()
  147. {
  148. if (top > 0)
  149. {
  150. _stack[top] = _stack[top - 1];
  151. top++;
  152. }
  153. else
  154. {
  155. NNCASE_THROW(std::runtime_error, "empty stack");
  156. }
  157. }
  158. private:
  159. std::array<float, 64> _stack;
  160. size_t top;
  161. };
  162. }
  163. }