cumo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (266) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.travis.yml +5 -0
  4. data/3rd_party/mkmf-cu/.gitignore +36 -0
  5. data/3rd_party/mkmf-cu/Gemfile +3 -0
  6. data/3rd_party/mkmf-cu/LICENSE +21 -0
  7. data/3rd_party/mkmf-cu/README.md +36 -0
  8. data/3rd_party/mkmf-cu/Rakefile +11 -0
  9. data/3rd_party/mkmf-cu/bin/mkmf-cu-nvcc +4 -0
  10. data/3rd_party/mkmf-cu/lib/mkmf-cu.rb +32 -0
  11. data/3rd_party/mkmf-cu/lib/mkmf-cu/cli.rb +80 -0
  12. data/3rd_party/mkmf-cu/lib/mkmf-cu/nvcc.rb +157 -0
  13. data/3rd_party/mkmf-cu/mkmf-cu.gemspec +16 -0
  14. data/3rd_party/mkmf-cu/test/test_mkmf-cu.rb +67 -0
  15. data/CODE_OF_CONDUCT.md +46 -0
  16. data/Gemfile +8 -0
  17. data/LICENSE.txt +82 -0
  18. data/README.md +252 -0
  19. data/Rakefile +43 -0
  20. data/bench/broadcast_fp32.rb +138 -0
  21. data/bench/cumo_bench.rb +193 -0
  22. data/bench/numo_bench.rb +138 -0
  23. data/bench/reduction_fp32.rb +117 -0
  24. data/bin/console +14 -0
  25. data/bin/setup +8 -0
  26. data/cumo.gemspec +32 -0
  27. data/ext/cumo/cuda/cublas.c +278 -0
  28. data/ext/cumo/cuda/driver.c +421 -0
  29. data/ext/cumo/cuda/memory_pool.cpp +185 -0
  30. data/ext/cumo/cuda/memory_pool_impl.cpp +308 -0
  31. data/ext/cumo/cuda/memory_pool_impl.hpp +370 -0
  32. data/ext/cumo/cuda/memory_pool_impl_test.cpp +554 -0
  33. data/ext/cumo/cuda/nvrtc.c +207 -0
  34. data/ext/cumo/cuda/runtime.c +167 -0
  35. data/ext/cumo/cumo.c +148 -0
  36. data/ext/cumo/depend.erb +58 -0
  37. data/ext/cumo/extconf.rb +179 -0
  38. data/ext/cumo/include/cumo.h +25 -0
  39. data/ext/cumo/include/cumo/compat.h +23 -0
  40. data/ext/cumo/include/cumo/cuda/cublas.h +153 -0
  41. data/ext/cumo/include/cumo/cuda/cumo_thrust.hpp +187 -0
  42. data/ext/cumo/include/cumo/cuda/cumo_thrust_complex.hpp +79 -0
  43. data/ext/cumo/include/cumo/cuda/driver.h +22 -0
  44. data/ext/cumo/include/cumo/cuda/memory_pool.h +28 -0
  45. data/ext/cumo/include/cumo/cuda/nvrtc.h +22 -0
  46. data/ext/cumo/include/cumo/cuda/runtime.h +40 -0
  47. data/ext/cumo/include/cumo/indexer.h +238 -0
  48. data/ext/cumo/include/cumo/intern.h +142 -0
  49. data/ext/cumo/include/cumo/intern_fwd.h +38 -0
  50. data/ext/cumo/include/cumo/intern_kernel.h +6 -0
  51. data/ext/cumo/include/cumo/narray.h +429 -0
  52. data/ext/cumo/include/cumo/narray_kernel.h +149 -0
  53. data/ext/cumo/include/cumo/ndloop.h +95 -0
  54. data/ext/cumo/include/cumo/reduce_kernel.h +126 -0
  55. data/ext/cumo/include/cumo/template.h +158 -0
  56. data/ext/cumo/include/cumo/template_kernel.h +77 -0
  57. data/ext/cumo/include/cumo/types/bit.h +40 -0
  58. data/ext/cumo/include/cumo/types/bit_kernel.h +34 -0
  59. data/ext/cumo/include/cumo/types/complex.h +402 -0
  60. data/ext/cumo/include/cumo/types/complex_kernel.h +414 -0
  61. data/ext/cumo/include/cumo/types/complex_macro.h +382 -0
  62. data/ext/cumo/include/cumo/types/complex_macro_kernel.h +186 -0
  63. data/ext/cumo/include/cumo/types/dcomplex.h +46 -0
  64. data/ext/cumo/include/cumo/types/dcomplex_kernel.h +13 -0
  65. data/ext/cumo/include/cumo/types/dfloat.h +47 -0
  66. data/ext/cumo/include/cumo/types/dfloat_kernel.h +14 -0
  67. data/ext/cumo/include/cumo/types/float_def.h +34 -0
  68. data/ext/cumo/include/cumo/types/float_def_kernel.h +39 -0
  69. data/ext/cumo/include/cumo/types/float_macro.h +191 -0
  70. data/ext/cumo/include/cumo/types/float_macro_kernel.h +158 -0
  71. data/ext/cumo/include/cumo/types/int16.h +24 -0
  72. data/ext/cumo/include/cumo/types/int16_kernel.h +23 -0
  73. data/ext/cumo/include/cumo/types/int32.h +24 -0
  74. data/ext/cumo/include/cumo/types/int32_kernel.h +19 -0
  75. data/ext/cumo/include/cumo/types/int64.h +24 -0
  76. data/ext/cumo/include/cumo/types/int64_kernel.h +19 -0
  77. data/ext/cumo/include/cumo/types/int8.h +24 -0
  78. data/ext/cumo/include/cumo/types/int8_kernel.h +19 -0
  79. data/ext/cumo/include/cumo/types/int_macro.h +67 -0
  80. data/ext/cumo/include/cumo/types/int_macro_kernel.h +48 -0
  81. data/ext/cumo/include/cumo/types/real_accum.h +486 -0
  82. data/ext/cumo/include/cumo/types/real_accum_kernel.h +101 -0
  83. data/ext/cumo/include/cumo/types/robj_macro.h +80 -0
  84. data/ext/cumo/include/cumo/types/robj_macro_kernel.h +0 -0
  85. data/ext/cumo/include/cumo/types/robject.h +27 -0
  86. data/ext/cumo/include/cumo/types/robject_kernel.h +7 -0
  87. data/ext/cumo/include/cumo/types/scomplex.h +46 -0
  88. data/ext/cumo/include/cumo/types/scomplex_kernel.h +13 -0
  89. data/ext/cumo/include/cumo/types/sfloat.h +48 -0
  90. data/ext/cumo/include/cumo/types/sfloat_kernel.h +14 -0
  91. data/ext/cumo/include/cumo/types/uint16.h +25 -0
  92. data/ext/cumo/include/cumo/types/uint16_kernel.h +20 -0
  93. data/ext/cumo/include/cumo/types/uint32.h +25 -0
  94. data/ext/cumo/include/cumo/types/uint32_kernel.h +20 -0
  95. data/ext/cumo/include/cumo/types/uint64.h +25 -0
  96. data/ext/cumo/include/cumo/types/uint64_kernel.h +20 -0
  97. data/ext/cumo/include/cumo/types/uint8.h +25 -0
  98. data/ext/cumo/include/cumo/types/uint8_kernel.h +20 -0
  99. data/ext/cumo/include/cumo/types/uint_macro.h +58 -0
  100. data/ext/cumo/include/cumo/types/uint_macro_kernel.h +38 -0
  101. data/ext/cumo/include/cumo/types/xint_macro.h +169 -0
  102. data/ext/cumo/include/cumo/types/xint_macro_kernel.h +88 -0
  103. data/ext/cumo/narray/SFMT-params.h +97 -0
  104. data/ext/cumo/narray/SFMT-params19937.h +46 -0
  105. data/ext/cumo/narray/SFMT.c +620 -0
  106. data/ext/cumo/narray/SFMT.h +167 -0
  107. data/ext/cumo/narray/array.c +638 -0
  108. data/ext/cumo/narray/data.c +961 -0
  109. data/ext/cumo/narray/gen/cogen.rb +56 -0
  110. data/ext/cumo/narray/gen/cogen_kernel.rb +58 -0
  111. data/ext/cumo/narray/gen/def/bit.rb +37 -0
  112. data/ext/cumo/narray/gen/def/dcomplex.rb +39 -0
  113. data/ext/cumo/narray/gen/def/dfloat.rb +37 -0
  114. data/ext/cumo/narray/gen/def/int16.rb +36 -0
  115. data/ext/cumo/narray/gen/def/int32.rb +36 -0
  116. data/ext/cumo/narray/gen/def/int64.rb +36 -0
  117. data/ext/cumo/narray/gen/def/int8.rb +36 -0
  118. data/ext/cumo/narray/gen/def/robject.rb +37 -0
  119. data/ext/cumo/narray/gen/def/scomplex.rb +39 -0
  120. data/ext/cumo/narray/gen/def/sfloat.rb +37 -0
  121. data/ext/cumo/narray/gen/def/uint16.rb +36 -0
  122. data/ext/cumo/narray/gen/def/uint32.rb +36 -0
  123. data/ext/cumo/narray/gen/def/uint64.rb +36 -0
  124. data/ext/cumo/narray/gen/def/uint8.rb +36 -0
  125. data/ext/cumo/narray/gen/erbpp2.rb +346 -0
  126. data/ext/cumo/narray/gen/narray_def.rb +268 -0
  127. data/ext/cumo/narray/gen/spec.rb +425 -0
  128. data/ext/cumo/narray/gen/tmpl/accum.c +86 -0
  129. data/ext/cumo/narray/gen/tmpl/accum_binary.c +121 -0
  130. data/ext/cumo/narray/gen/tmpl/accum_binary_kernel.cu +61 -0
  131. data/ext/cumo/narray/gen/tmpl/accum_index.c +119 -0
  132. data/ext/cumo/narray/gen/tmpl/accum_index_kernel.cu +66 -0
  133. data/ext/cumo/narray/gen/tmpl/accum_kernel.cu +12 -0
  134. data/ext/cumo/narray/gen/tmpl/alloc_func.c +107 -0
  135. data/ext/cumo/narray/gen/tmpl/allocate.c +37 -0
  136. data/ext/cumo/narray/gen/tmpl/aref.c +66 -0
  137. data/ext/cumo/narray/gen/tmpl/aref_cpu.c +50 -0
  138. data/ext/cumo/narray/gen/tmpl/aset.c +56 -0
  139. data/ext/cumo/narray/gen/tmpl/binary.c +162 -0
  140. data/ext/cumo/narray/gen/tmpl/binary2.c +70 -0
  141. data/ext/cumo/narray/gen/tmpl/binary2_kernel.cu +15 -0
  142. data/ext/cumo/narray/gen/tmpl/binary_kernel.cu +31 -0
  143. data/ext/cumo/narray/gen/tmpl/binary_s.c +45 -0
  144. data/ext/cumo/narray/gen/tmpl/binary_s_kernel.cu +15 -0
  145. data/ext/cumo/narray/gen/tmpl/bincount.c +181 -0
  146. data/ext/cumo/narray/gen/tmpl/cast.c +44 -0
  147. data/ext/cumo/narray/gen/tmpl/cast_array.c +13 -0
  148. data/ext/cumo/narray/gen/tmpl/class.c +9 -0
  149. data/ext/cumo/narray/gen/tmpl/class_kernel.cu +6 -0
  150. data/ext/cumo/narray/gen/tmpl/clip.c +121 -0
  151. data/ext/cumo/narray/gen/tmpl/coerce_cast.c +10 -0
  152. data/ext/cumo/narray/gen/tmpl/complex_accum_kernel.cu +129 -0
  153. data/ext/cumo/narray/gen/tmpl/cond_binary.c +68 -0
  154. data/ext/cumo/narray/gen/tmpl/cond_binary_kernel.cu +18 -0
  155. data/ext/cumo/narray/gen/tmpl/cond_unary.c +46 -0
  156. data/ext/cumo/narray/gen/tmpl/cum.c +50 -0
  157. data/ext/cumo/narray/gen/tmpl/each.c +47 -0
  158. data/ext/cumo/narray/gen/tmpl/each_with_index.c +70 -0
  159. data/ext/cumo/narray/gen/tmpl/ewcomp.c +79 -0
  160. data/ext/cumo/narray/gen/tmpl/ewcomp_kernel.cu +19 -0
  161. data/ext/cumo/narray/gen/tmpl/extract.c +22 -0
  162. data/ext/cumo/narray/gen/tmpl/extract_cpu.c +26 -0
  163. data/ext/cumo/narray/gen/tmpl/extract_data.c +53 -0
  164. data/ext/cumo/narray/gen/tmpl/eye.c +105 -0
  165. data/ext/cumo/narray/gen/tmpl/eye_kernel.cu +19 -0
  166. data/ext/cumo/narray/gen/tmpl/fill.c +52 -0
  167. data/ext/cumo/narray/gen/tmpl/fill_kernel.cu +29 -0
  168. data/ext/cumo/narray/gen/tmpl/float_accum_kernel.cu +106 -0
  169. data/ext/cumo/narray/gen/tmpl/format.c +62 -0
  170. data/ext/cumo/narray/gen/tmpl/format_to_a.c +49 -0
  171. data/ext/cumo/narray/gen/tmpl/frexp.c +38 -0
  172. data/ext/cumo/narray/gen/tmpl/gemm.c +203 -0
  173. data/ext/cumo/narray/gen/tmpl/init_class.c +20 -0
  174. data/ext/cumo/narray/gen/tmpl/init_module.c +12 -0
  175. data/ext/cumo/narray/gen/tmpl/inspect.c +21 -0
  176. data/ext/cumo/narray/gen/tmpl/lib.c +50 -0
  177. data/ext/cumo/narray/gen/tmpl/lib_kernel.cu +24 -0
  178. data/ext/cumo/narray/gen/tmpl/logseq.c +102 -0
  179. data/ext/cumo/narray/gen/tmpl/logseq_kernel.cu +31 -0
  180. data/ext/cumo/narray/gen/tmpl/map_with_index.c +98 -0
  181. data/ext/cumo/narray/gen/tmpl/median.c +66 -0
  182. data/ext/cumo/narray/gen/tmpl/minmax.c +47 -0
  183. data/ext/cumo/narray/gen/tmpl/module.c +9 -0
  184. data/ext/cumo/narray/gen/tmpl/module_kernel.cu +1 -0
  185. data/ext/cumo/narray/gen/tmpl/new_dim0.c +15 -0
  186. data/ext/cumo/narray/gen/tmpl/new_dim0_kernel.cu +8 -0
  187. data/ext/cumo/narray/gen/tmpl/poly.c +50 -0
  188. data/ext/cumo/narray/gen/tmpl/pow.c +97 -0
  189. data/ext/cumo/narray/gen/tmpl/pow_kernel.cu +29 -0
  190. data/ext/cumo/narray/gen/tmpl/powint.c +17 -0
  191. data/ext/cumo/narray/gen/tmpl/qsort.c +212 -0
  192. data/ext/cumo/narray/gen/tmpl/rand.c +168 -0
  193. data/ext/cumo/narray/gen/tmpl/rand_norm.c +121 -0
  194. data/ext/cumo/narray/gen/tmpl/real_accum_kernel.cu +75 -0
  195. data/ext/cumo/narray/gen/tmpl/seq.c +112 -0
  196. data/ext/cumo/narray/gen/tmpl/seq_kernel.cu +43 -0
  197. data/ext/cumo/narray/gen/tmpl/set2.c +57 -0
  198. data/ext/cumo/narray/gen/tmpl/sort.c +48 -0
  199. data/ext/cumo/narray/gen/tmpl/sort_index.c +111 -0
  200. data/ext/cumo/narray/gen/tmpl/store.c +41 -0
  201. data/ext/cumo/narray/gen/tmpl/store_array.c +187 -0
  202. data/ext/cumo/narray/gen/tmpl/store_array_kernel.cu +58 -0
  203. data/ext/cumo/narray/gen/tmpl/store_bit.c +86 -0
  204. data/ext/cumo/narray/gen/tmpl/store_bit_kernel.cu +66 -0
  205. data/ext/cumo/narray/gen/tmpl/store_from.c +81 -0
  206. data/ext/cumo/narray/gen/tmpl/store_from_kernel.cu +58 -0
  207. data/ext/cumo/narray/gen/tmpl/store_kernel.cu +3 -0
  208. data/ext/cumo/narray/gen/tmpl/store_numeric.c +9 -0
  209. data/ext/cumo/narray/gen/tmpl/to_a.c +43 -0
  210. data/ext/cumo/narray/gen/tmpl/unary.c +132 -0
  211. data/ext/cumo/narray/gen/tmpl/unary2.c +60 -0
  212. data/ext/cumo/narray/gen/tmpl/unary_kernel.cu +72 -0
  213. data/ext/cumo/narray/gen/tmpl/unary_ret2.c +34 -0
  214. data/ext/cumo/narray/gen/tmpl/unary_s.c +86 -0
  215. data/ext/cumo/narray/gen/tmpl/unary_s_kernel.cu +58 -0
  216. data/ext/cumo/narray/gen/tmpl_bit/allocate.c +24 -0
  217. data/ext/cumo/narray/gen/tmpl_bit/aref.c +54 -0
  218. data/ext/cumo/narray/gen/tmpl_bit/aref_cpu.c +57 -0
  219. data/ext/cumo/narray/gen/tmpl_bit/aset.c +56 -0
  220. data/ext/cumo/narray/gen/tmpl_bit/binary.c +98 -0
  221. data/ext/cumo/narray/gen/tmpl_bit/bit_count.c +64 -0
  222. data/ext/cumo/narray/gen/tmpl_bit/bit_count_cpu.c +88 -0
  223. data/ext/cumo/narray/gen/tmpl_bit/bit_count_kernel.cu +76 -0
  224. data/ext/cumo/narray/gen/tmpl_bit/bit_reduce.c +133 -0
  225. data/ext/cumo/narray/gen/tmpl_bit/each.c +48 -0
  226. data/ext/cumo/narray/gen/tmpl_bit/each_with_index.c +70 -0
  227. data/ext/cumo/narray/gen/tmpl_bit/extract.c +30 -0
  228. data/ext/cumo/narray/gen/tmpl_bit/extract_cpu.c +29 -0
  229. data/ext/cumo/narray/gen/tmpl_bit/fill.c +69 -0
  230. data/ext/cumo/narray/gen/tmpl_bit/format.c +64 -0
  231. data/ext/cumo/narray/gen/tmpl_bit/format_to_a.c +51 -0
  232. data/ext/cumo/narray/gen/tmpl_bit/inspect.c +21 -0
  233. data/ext/cumo/narray/gen/tmpl_bit/mask.c +136 -0
  234. data/ext/cumo/narray/gen/tmpl_bit/none_p.c +14 -0
  235. data/ext/cumo/narray/gen/tmpl_bit/store_array.c +108 -0
  236. data/ext/cumo/narray/gen/tmpl_bit/store_bit.c +70 -0
  237. data/ext/cumo/narray/gen/tmpl_bit/store_from.c +60 -0
  238. data/ext/cumo/narray/gen/tmpl_bit/to_a.c +47 -0
  239. data/ext/cumo/narray/gen/tmpl_bit/unary.c +81 -0
  240. data/ext/cumo/narray/gen/tmpl_bit/where.c +90 -0
  241. data/ext/cumo/narray/gen/tmpl_bit/where2.c +95 -0
  242. data/ext/cumo/narray/index.c +880 -0
  243. data/ext/cumo/narray/kwargs.c +153 -0
  244. data/ext/cumo/narray/math.c +142 -0
  245. data/ext/cumo/narray/narray.c +1948 -0
  246. data/ext/cumo/narray/ndloop.c +2105 -0
  247. data/ext/cumo/narray/rand.c +45 -0
  248. data/ext/cumo/narray/step.c +474 -0
  249. data/ext/cumo/narray/struct.c +886 -0
  250. data/lib/cumo.rb +3 -0
  251. data/lib/cumo/cuda.rb +11 -0
  252. data/lib/cumo/cuda/compile_error.rb +36 -0
  253. data/lib/cumo/cuda/compiler.rb +161 -0
  254. data/lib/cumo/cuda/device.rb +47 -0
  255. data/lib/cumo/cuda/link_state.rb +31 -0
  256. data/lib/cumo/cuda/module.rb +40 -0
  257. data/lib/cumo/cuda/nvrtc_program.rb +27 -0
  258. data/lib/cumo/linalg.rb +12 -0
  259. data/lib/cumo/narray.rb +2 -0
  260. data/lib/cumo/narray/extra.rb +1278 -0
  261. data/lib/erbpp.rb +294 -0
  262. data/lib/erbpp/line_number.rb +137 -0
  263. data/lib/erbpp/narray_def.rb +381 -0
  264. data/numo-narray-version +1 -0
  265. data/run.gdb +7 -0
  266. metadata +353 -0
@@ -0,0 +1,46 @@
1
+ #ifndef SFMT_PARAMS19937_H
2
+ #define SFMT_PARAMS19937_H
3
+
4
+ #define POS1 122
5
+ #define SL1 18
6
+ #define SL2 1
7
+ #define SR1 11
8
+ #define SR2 1
9
+ #define MSK1 0xdfffffefU
10
+ #define MSK2 0xddfecb7fU
11
+ #define MSK3 0xbffaffffU
12
+ #define MSK4 0xbffffff6U
13
+ #define PARITY1 0x00000001U
14
+ #define PARITY2 0x00000000U
15
+ #define PARITY3 0x00000000U
16
+ #define PARITY4 0x13c9e684U
17
+
18
+
19
+ /* PARAMETERS FOR ALTIVEC */
20
+ #if defined(__APPLE__) /* For OSX */
21
+ #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
22
+ #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
23
+ #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
24
+ #define ALTI_MSK64 \
25
+ (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
26
+ #define ALTI_SL2_PERM \
27
+ (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
28
+ #define ALTI_SL2_PERM64 \
29
+ (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
30
+ #define ALTI_SR2_PERM \
31
+ (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
32
+ #define ALTI_SR2_PERM64 \
33
+ (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
34
+ #else /* For OTHER OSs(Linux?) */
35
+ #define ALTI_SL1 {SL1, SL1, SL1, SL1}
36
+ #define ALTI_SR1 {SR1, SR1, SR1, SR1}
37
+ #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
38
+ #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
39
+ #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
40
+ #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
41
+ #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
42
+ #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
43
+ #endif /* For OSX */
44
+ #define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
45
+
46
+ #endif /* SFMT_PARAMS19937_H */
@@ -0,0 +1,620 @@
1
+ /**
2
+ * @file SFMT.c
3
+ * @brief SIMD oriented Fast Mersenne Twister(SFMT)
4
+ *
5
+ * @author Mutsuo Saito (Hiroshima University)
6
+ * @author Makoto Matsumoto (Hiroshima University)
7
+ *
8
+ * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
9
+ * University. All rights reserved.
10
+ *
11
+ * The new BSD License is applied to this software, see LICENSE.txt
12
+ */
13
+ #include <string.h>
14
+ #include <assert.h>
15
+ #include "SFMT.h"
16
+ #include "SFMT-params.h"
17
+
18
+ #if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
19
+ #define BIG_ENDIAN64 1
20
+ #endif
21
+ #if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
22
+ #define BIG_ENDIAN64 1
23
+ #endif
24
+ #if defined(ONLY64) && !defined(BIG_ENDIAN64)
25
+ #if defined(__GNUC__)
26
+ #error "-DONLY64 must be specified with -DBIG_ENDIAN64"
27
+ #endif
28
+ #undef ONLY64
29
+ #endif
30
+ /*------------------------------------------------------
31
+ 128-bit SIMD data type for Altivec, SSE2 or standard C
32
+ ------------------------------------------------------*/
33
+ #if defined(HAVE_ALTIVEC)
34
+ #if !defined(__APPLE__)
35
+ #include <altivec.h>
36
+ #endif
37
+ /** 128-bit data structure */
38
+ union W128_T {
39
+ vector unsigned int s;
40
+ uint32_t u[4];
41
+ };
42
+ /** 128-bit data type */
43
+ typedef union W128_T w128_t;
44
+
45
+ #elif defined(HAVE_SSE2)
46
+ #include <emmintrin.h>
47
+
48
+ /** 128-bit data structure */
49
+ union W128_T {
50
+ __m128i si;
51
+ uint32_t u[4];
52
+ };
53
+ /** 128-bit data type */
54
+ typedef union W128_T w128_t;
55
+
56
+ #else
57
+
58
+ /** 128-bit data structure */
59
+ struct W128_T {
60
+ uint32_t u[4];
61
+ };
62
+ /** 128-bit data type */
63
+ typedef struct W128_T w128_t;
64
+
65
+ #endif
66
+
67
+ /*--------------------------------------
68
+ FILE GLOBAL VARIABLES
69
+ internal state, index counter and flag
70
+ --------------------------------------*/
71
+ /** the 128-bit internal state array */
72
+ static w128_t sfmt[N];
73
+ /** the 32bit integer pointer to the 128-bit internal state array */
74
+ static uint32_t *psfmt32 = &sfmt[0].u[0];
75
+ #if !defined(BIG_ENDIAN64) || defined(ONLY64)
76
+ /** the 64bit integer pointer to the 128-bit internal state array */
77
+ static uint64_t *psfmt64 = (uint64_t *)&sfmt[0].u[0];
78
+ #endif
79
+ /** index counter to the 32-bit internal state array */
80
+ static int idx;
81
+ /** a flag: it is 0 if and only if the internal state is not yet
82
+ * initialized. */
83
+ static int initialized = 0;
84
+ /** a parity check vector which certificate the period of 2^{MEXP} */
85
+ static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
86
+
87
+ /*----------------
88
+ STATIC FUNCTIONS
89
+ ----------------*/
90
+ inline static int idxof(int i);
91
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift);
92
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift);
93
+ inline static void gen_rand_all(void);
94
+ inline static void gen_rand_array(w128_t *array, int size);
95
+ inline static uint32_t func1(uint32_t x);
96
+ inline static uint32_t func2(uint32_t x);
97
+ static void period_certification(void);
98
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
99
+ inline static void swap(w128_t *array, int size);
100
+ #endif
101
+
102
+ #if defined(HAVE_ALTIVEC)
103
+ #include "SFMT-alti.h"
104
+ #elif defined(HAVE_SSE2)
105
+ #include "SFMT-sse2.h"
106
+ #endif
107
+
108
+ /**
109
+ * This function simulate a 64-bit index of LITTLE ENDIAN
110
+ * in BIG ENDIAN machine.
111
+ */
112
+ #ifdef ONLY64
113
+ inline static int idxof(int i) {
114
+ return i ^ 1;
115
+ }
116
+ #else
117
+ inline static int idxof(int i) {
118
+ return i;
119
+ }
120
+ #endif
121
+ /**
122
+ * This function simulates SIMD 128-bit right shift by the standard C.
123
+ * The 128-bit integer given in in is shifted by (shift * 8) bits.
124
+ * This function simulates the LITTLE ENDIAN SIMD.
125
+ * @param out the output of this function
126
+ * @param in the 128-bit data to be shifted
127
+ * @param shift the shift value
128
+ */
129
+ #ifdef ONLY64
130
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
131
+ uint64_t th, tl, oh, ol;
132
+
133
+ th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
134
+ tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
135
+
136
+ oh = th >> (shift * 8);
137
+ ol = tl >> (shift * 8);
138
+ ol |= th << (64 - shift * 8);
139
+ out->u[0] = (uint32_t)(ol >> 32);
140
+ out->u[1] = (uint32_t)ol;
141
+ out->u[2] = (uint32_t)(oh >> 32);
142
+ out->u[3] = (uint32_t)oh;
143
+ }
144
+ #else
145
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
146
+ uint64_t th, tl, oh, ol;
147
+
148
+ th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
149
+ tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
150
+
151
+ oh = th >> (shift * 8);
152
+ ol = tl >> (shift * 8);
153
+ ol |= th << (64 - shift * 8);
154
+ out->u[1] = (uint32_t)(ol >> 32);
155
+ out->u[0] = (uint32_t)ol;
156
+ out->u[3] = (uint32_t)(oh >> 32);
157
+ out->u[2] = (uint32_t)oh;
158
+ }
159
+ #endif
160
+ /**
161
+ * This function simulates SIMD 128-bit left shift by the standard C.
162
+ * The 128-bit integer given in in is shifted by (shift * 8) bits.
163
+ * This function simulates the LITTLE ENDIAN SIMD.
164
+ * @param out the output of this function
165
+ * @param in the 128-bit data to be shifted
166
+ * @param shift the shift value
167
+ */
168
+ #ifdef ONLY64
169
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
170
+ uint64_t th, tl, oh, ol;
171
+
172
+ th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
173
+ tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
174
+
175
+ oh = th << (shift * 8);
176
+ ol = tl << (shift * 8);
177
+ oh |= tl >> (64 - shift * 8);
178
+ out->u[0] = (uint32_t)(ol >> 32);
179
+ out->u[1] = (uint32_t)ol;
180
+ out->u[2] = (uint32_t)(oh >> 32);
181
+ out->u[3] = (uint32_t)oh;
182
+ }
183
+ #else
184
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
185
+ uint64_t th, tl, oh, ol;
186
+
187
+ th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
188
+ tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
189
+
190
+ oh = th << (shift * 8);
191
+ ol = tl << (shift * 8);
192
+ oh |= tl >> (64 - shift * 8);
193
+ out->u[1] = (uint32_t)(ol >> 32);
194
+ out->u[0] = (uint32_t)ol;
195
+ out->u[3] = (uint32_t)(oh >> 32);
196
+ out->u[2] = (uint32_t)oh;
197
+ }
198
+ #endif
199
+
200
+ /**
201
+ * This function represents the recursion formula.
202
+ * @param r output
203
+ * @param a a 128-bit part of the internal state array
204
+ * @param b a 128-bit part of the internal state array
205
+ * @param c a 128-bit part of the internal state array
206
+ * @param d a 128-bit part of the internal state array
207
+ */
208
+ #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
209
+ #ifdef ONLY64
210
+ inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
211
+ w128_t *d) {
212
+ w128_t x;
213
+ w128_t y;
214
+
215
+ lshift128(&x, a, SL2);
216
+ rshift128(&y, c, SR2);
217
+ r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
218
+ ^ (d->u[0] << SL1);
219
+ r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
220
+ ^ (d->u[1] << SL1);
221
+ r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
222
+ ^ (d->u[2] << SL1);
223
+ r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
224
+ ^ (d->u[3] << SL1);
225
+ }
226
+ #else
227
+ inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
228
+ w128_t *d) {
229
+ w128_t x;
230
+ w128_t y;
231
+
232
+ lshift128(&x, a, SL2);
233
+ rshift128(&y, c, SR2);
234
+ r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
235
+ ^ (d->u[0] << SL1);
236
+ r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
237
+ ^ (d->u[1] << SL1);
238
+ r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
239
+ ^ (d->u[2] << SL1);
240
+ r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
241
+ ^ (d->u[3] << SL1);
242
+ }
243
+ #endif
244
+ #endif
245
+
246
+ #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
247
+ /**
248
+ * This function fills the internal state array with pseudorandom
249
+ * integers.
250
+ */
251
+ inline static void gen_rand_all(void) {
252
+ int i;
253
+ w128_t *r1, *r2;
254
+
255
+ r1 = &sfmt[N - 2];
256
+ r2 = &sfmt[N - 1];
257
+ for (i = 0; i < N - POS1; i++) {
258
+ do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
259
+ r1 = r2;
260
+ r2 = &sfmt[i];
261
+ }
262
+ for (; i < N; i++) {
263
+ do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1 - N], r1, r2);
264
+ r1 = r2;
265
+ r2 = &sfmt[i];
266
+ }
267
+ }
268
+
269
+ /**
270
+ * This function fills the user-specified array with pseudorandom
271
+ * integers.
272
+ *
273
+ * @param array an 128-bit array to be filled by pseudorandom numbers.
274
+ * @param size number of 128-bit pseudorandom numbers to be generated.
275
+ */
276
+ inline static void gen_rand_array(w128_t *array, int size) {
277
+ int i, j;
278
+ w128_t *r1, *r2;
279
+
280
+ r1 = &sfmt[N - 2];
281
+ r2 = &sfmt[N - 1];
282
+ for (i = 0; i < N - POS1; i++) {
283
+ do_recursion(&array[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
284
+ r1 = r2;
285
+ r2 = &array[i];
286
+ }
287
+ for (; i < N; i++) {
288
+ do_recursion(&array[i], &sfmt[i], &array[i + POS1 - N], r1, r2);
289
+ r1 = r2;
290
+ r2 = &array[i];
291
+ }
292
+ for (; i < size - N; i++) {
293
+ do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
294
+ r1 = r2;
295
+ r2 = &array[i];
296
+ }
297
+ for (j = 0; j < 2 * N - size; j++) {
298
+ sfmt[j] = array[j + size - N];
299
+ }
300
+ for (; i < size; i++, j++) {
301
+ do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
302
+ r1 = r2;
303
+ r2 = &array[i];
304
+ sfmt[j] = array[i];
305
+ }
306
+ }
307
+ #endif
308
+
309
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
310
+ inline static void swap(w128_t *array, int size) {
311
+ int i;
312
+ uint32_t x, y;
313
+
314
+ for (i = 0; i < size; i++) {
315
+ x = array[i].u[0];
316
+ y = array[i].u[2];
317
+ array[i].u[0] = array[i].u[1];
318
+ array[i].u[2] = array[i].u[3];
319
+ array[i].u[1] = x;
320
+ array[i].u[3] = y;
321
+ }
322
+ }
323
+ #endif
324
+ /**
325
+ * This function represents a function used in the initialization
326
+ * by init_by_array
327
+ * @param x 32-bit integer
328
+ * @return 32-bit integer
329
+ */
330
+ static uint32_t func1(uint32_t x) {
331
+ return (x ^ (x >> 27)) * (uint32_t)1664525UL;
332
+ }
333
+
334
+ /**
335
+ * This function represents a function used in the initialization
336
+ * by init_by_array
337
+ * @param x 32-bit integer
338
+ * @return 32-bit integer
339
+ */
340
+ static uint32_t func2(uint32_t x) {
341
+ return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
342
+ }
343
+
344
+ /**
345
+ * This function certificate the period of 2^{MEXP}
346
+ */
347
+ static void period_certification(void) {
348
+ int inner = 0;
349
+ int i, j;
350
+ uint32_t work;
351
+
352
+ for (i = 0; i < 4; i++)
353
+ inner ^= psfmt32[idxof(i)] & parity[i];
354
+ for (i = 16; i > 0; i >>= 1)
355
+ inner ^= inner >> i;
356
+ inner &= 1;
357
+ /* check OK */
358
+ if (inner == 1) {
359
+ return;
360
+ }
361
+ /* check NG, and modification */
362
+ for (i = 0; i < 4; i++) {
363
+ work = 1;
364
+ for (j = 0; j < 32; j++) {
365
+ if ((work & parity[i]) != 0) {
366
+ psfmt32[idxof(i)] ^= work;
367
+ return;
368
+ }
369
+ work = work << 1;
370
+ }
371
+ }
372
+ }
373
+
374
+ /*----------------
375
+ PUBLIC FUNCTIONS
376
+ ----------------*/
377
+ /**
378
+ * This function returns the identification string.
379
+ * The string shows the word size, the Mersenne exponent,
380
+ * and all parameters of this generator.
381
+ */
382
+ const char *get_idstring(void) {
383
+ return IDSTR;
384
+ }
385
+
386
+ /**
387
+ * This function returns the minimum size of array used for \b
388
+ * fill_array32() function.
389
+ * @return minimum size of array used for fill_array32() function.
390
+ */
391
+ int get_min_array_size32(void) {
392
+ return N32;
393
+ }
394
+
395
+ /**
396
+ * This function returns the minimum size of array used for \b
397
+ * fill_array64() function.
398
+ * @return minimum size of array used for fill_array64() function.
399
+ */
400
+ int get_min_array_size64(void) {
401
+ return N64;
402
+ }
403
+
404
+ #ifndef ONLY64
405
+ /**
406
+ * This function generates and returns 32-bit pseudorandom number.
407
+ * init_gen_rand or init_by_array must be called before this function.
408
+ * @return 32-bit pseudorandom number
409
+ */
410
+ uint32_t gen_rand32(void) {
411
+ uint32_t r;
412
+
413
+ assert(initialized);
414
+ if (idx >= N32) {
415
+ gen_rand_all();
416
+ idx = 0;
417
+ }
418
+ r = psfmt32[idx++];
419
+ return r;
420
+ }
421
+ #endif
422
+ /**
423
+ * This function generates and returns 64-bit pseudorandom number.
424
+ * init_gen_rand or init_by_array must be called before this function.
425
+ * The function gen_rand64 should not be called after gen_rand32,
426
+ * unless an initialization is again executed.
427
+ * @return 64-bit pseudorandom number
428
+ */
429
+ uint64_t gen_rand64(void) {
430
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
431
+ uint32_t r1, r2;
432
+ #else
433
+ uint64_t r;
434
+ #endif
435
+
436
+ assert(initialized);
437
+ assert(idx % 2 == 0);
438
+
439
+ if (idx >= N32) {
440
+ gen_rand_all();
441
+ idx = 0;
442
+ }
443
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
444
+ r1 = psfmt32[idx];
445
+ r2 = psfmt32[idx + 1];
446
+ idx += 2;
447
+ return ((uint64_t)r2 << 32) | r1;
448
+ #else
449
+ r = psfmt64[idx / 2];
450
+ idx += 2;
451
+ return r;
452
+ #endif
453
+ }
454
+
455
+ #ifndef ONLY64
456
+ /**
457
+ * This function generates pseudorandom 32-bit integers in the
458
+ * specified array[] by one call. The number of pseudorandom integers
459
+ * is specified by the argument size, which must be at least 624 and a
460
+ * multiple of four. The generation by this function is much faster
461
+ * than the following gen_rand function.
462
+ *
463
+ * For initialization, init_gen_rand or init_by_array must be called
464
+ * before the first call of this function. This function can not be
465
+ * used after calling gen_rand function, without initialization.
466
+ *
467
+ * @param array an array where pseudorandom 32-bit integers are filled
468
+ * by this function. The pointer to the array must be \b "aligned"
469
+ * (namely, must be a multiple of 16) in the SIMD version, since it
470
+ * refers to the address of a 128-bit integer. In the standard C
471
+ * version, the pointer is arbitrary.
472
+ *
473
+ * @param size the number of 32-bit pseudorandom integers to be
474
+ * generated. size must be a multiple of 4, and greater than or equal
475
+ * to (MEXP / 128 + 1) * 4.
476
+ *
477
+ * @note \b memalign or \b posix_memalign is available to get aligned
478
+ * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
479
+ * returns the pointer to the aligned memory block.
480
+ */
481
+ void fill_array32(uint32_t *array, int size) {
482
+ assert(initialized);
483
+ assert(idx == N32);
484
+ assert(size % 4 == 0);
485
+ assert(size >= N32);
486
+
487
+ gen_rand_array((w128_t *)array, size / 4);
488
+ idx = N32;
489
+ }
490
+ #endif
491
+
492
+ /**
493
+ * This function generates pseudorandom 64-bit integers in the
494
+ * specified array[] by one call. The number of pseudorandom integers
495
+ * is specified by the argument size, which must be at least 312 and a
496
+ * multiple of two. The generation by this function is much faster
497
+ * than the following gen_rand function.
498
+ *
499
+ * For initialization, init_gen_rand or init_by_array must be called
500
+ * before the first call of this function. This function can not be
501
+ * used after calling gen_rand function, without initialization.
502
+ *
503
+ * @param array an array where pseudorandom 64-bit integers are filled
504
+ * by this function. The pointer to the array must be "aligned"
505
+ * (namely, must be a multiple of 16) in the SIMD version, since it
506
+ * refers to the address of a 128-bit integer. In the standard C
507
+ * version, the pointer is arbitrary.
508
+ *
509
+ * @param size the number of 64-bit pseudorandom integers to be
510
+ * generated. size must be a multiple of 2, and greater than or equal
511
+ * to (MEXP / 128 + 1) * 2
512
+ *
513
+ * @note \b memalign or \b posix_memalign is available to get aligned
514
+ * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
515
+ * returns the pointer to the aligned memory block.
516
+ */
517
+ void fill_array64(uint64_t *array, int size) {
518
+ assert(initialized);
519
+ assert(idx == N32);
520
+ assert(size % 2 == 0);
521
+ assert(size >= N64);
522
+
523
+ gen_rand_array((w128_t *)array, size / 2);
524
+ idx = N32;
525
+
526
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
527
+ swap((w128_t *)array, size /2);
528
+ #endif
529
+ }
530
+
531
+ /**
532
+ * This function initializes the internal state array with a 32-bit
533
+ * integer seed.
534
+ *
535
+ * @param seed a 32-bit integer used as the seed.
536
+ */
537
+ void init_gen_rand(uint32_t seed) {
538
+ int i;
539
+
540
+ psfmt32[idxof(0)] = seed;
541
+ for (i = 1; i < N32; i++) {
542
+ psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
543
+ ^ (psfmt32[idxof(i - 1)] >> 30))
544
+ + i;
545
+ }
546
+ idx = N32;
547
+ period_certification();
548
+ initialized = 1;
549
+ }
550
+
551
+ /**
552
+ * This function initializes the internal state array,
553
+ * with an array of 32-bit integers used as the seeds
554
+ * @param init_key the array of 32-bit integers, used as a seed.
555
+ * @param key_length the length of init_key.
556
+ */
557
+ void init_by_array(uint32_t *init_key, int key_length) {
558
+ int i, j, count;
559
+ uint32_t r;
560
+ int lag;
561
+ int mid;
562
+ int size = N * 4;
563
+
564
+ if (size >= 623) {
565
+ lag = 11;
566
+ } else if (size >= 68) {
567
+ lag = 7;
568
+ } else if (size >= 39) {
569
+ lag = 5;
570
+ } else {
571
+ lag = 3;
572
+ }
573
+ mid = (size - lag) / 2;
574
+
575
+ memset(sfmt, 0x8b, sizeof(sfmt));
576
+ if (key_length + 1 > N32) {
577
+ count = key_length + 1;
578
+ } else {
579
+ count = N32;
580
+ }
581
+ r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
582
+ ^ psfmt32[idxof(N32 - 1)]);
583
+ psfmt32[idxof(mid)] += r;
584
+ r += key_length;
585
+ psfmt32[idxof(mid + lag)] += r;
586
+ psfmt32[idxof(0)] = r;
587
+
588
+ count--;
589
+ for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
590
+ r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
591
+ ^ psfmt32[idxof((i + N32 - 1) % N32)]);
592
+ psfmt32[idxof((i + mid) % N32)] += r;
593
+ r += init_key[j] + i;
594
+ psfmt32[idxof((i + mid + lag) % N32)] += r;
595
+ psfmt32[idxof(i)] = r;
596
+ i = (i + 1) % N32;
597
+ }
598
+ for (; j < count; j++) {
599
+ r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
600
+ ^ psfmt32[idxof((i + N32 - 1) % N32)]);
601
+ psfmt32[idxof((i + mid) % N32)] += r;
602
+ r += i;
603
+ psfmt32[idxof((i + mid + lag) % N32)] += r;
604
+ psfmt32[idxof(i)] = r;
605
+ i = (i + 1) % N32;
606
+ }
607
+ for (j = 0; j < N32; j++) {
608
+ r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
609
+ + psfmt32[idxof((i + N32 - 1) % N32)]);
610
+ psfmt32[idxof((i + mid) % N32)] ^= r;
611
+ r -= i;
612
+ psfmt32[idxof((i + mid + lag) % N32)] ^= r;
613
+ psfmt32[idxof(i)] = r;
614
+ i = (i + 1) % N32;
615
+ }
616
+
617
+ idx = N32;
618
+ period_certification();
619
+ initialized = 1;
620
+ }