evoasm 0.0.2.pre7 → 0.1.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.gdbinit +41 -0
  3. data/.gitignore +1 -2
  4. data/.gitmodules +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +660 -0
  8. data/Makefile +1 -1
  9. data/README.md +17 -9
  10. data/Rakefile +39 -107
  11. data/bin/gdb +1 -1
  12. data/bin/gdb_loop +4 -0
  13. data/docs/FindingInstructions.md +17 -0
  14. data/docs/JIT.md +14 -0
  15. data/docs/SymbolicRegression.md +102 -0
  16. data/docs/Visualization.md +29 -0
  17. data/docs/examples/bit_insts.rb +44 -0
  18. data/docs/examples/jit.rb +26 -0
  19. data/docs/examples/loss.gif +0 -0
  20. data/docs/examples/program.png +0 -0
  21. data/docs/examples/sym_reg.rb +64 -0
  22. data/docs/examples/vis.rb +38 -0
  23. data/evoasm.gemspec +21 -15
  24. data/ext/evoasm_ext/Rakefile +3 -0
  25. data/ext/evoasm_ext/compile.rake +35 -0
  26. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
  27. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
  28. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
  29. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
  30. data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
  31. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
  32. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
  33. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
  34. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
  35. data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
  36. data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
  37. data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
  38. data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
  39. data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
  40. data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
  41. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
  42. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
  43. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
  44. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
  45. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
  46. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
  47. data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
  48. data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
  49. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
  50. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
  51. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
  52. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
  53. data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
  54. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
  55. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
  56. data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
  57. data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
  58. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
  59. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
  60. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
  61. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
  62. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
  63. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
  64. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
  65. data/lib/evoasm.rb +28 -11
  66. data/lib/evoasm/buffer.rb +105 -0
  67. data/lib/evoasm/capstone.rb +100 -0
  68. data/lib/evoasm/domain.rb +116 -0
  69. data/lib/evoasm/error.rb +37 -16
  70. data/lib/evoasm/exception_error.rb +19 -0
  71. data/lib/evoasm/ffi_ext.rb +53 -0
  72. data/lib/evoasm/libevoasm.rb +286 -0
  73. data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
  74. data/lib/evoasm/parameter.rb +20 -0
  75. data/lib/evoasm/population.rb +145 -0
  76. data/lib/evoasm/population/parameters.rb +227 -0
  77. data/lib/evoasm/population/plotter.rb +89 -0
  78. data/lib/evoasm/prng.rb +64 -0
  79. data/lib/evoasm/program.rb +195 -12
  80. data/lib/evoasm/program/io.rb +144 -0
  81. data/lib/evoasm/test.rb +8 -0
  82. data/lib/evoasm/version.rb +1 -1
  83. data/lib/evoasm/x64.rb +115 -0
  84. data/lib/evoasm/x64/cpu_state.rb +95 -0
  85. data/lib/evoasm/x64/instruction.rb +109 -0
  86. data/lib/evoasm/x64/operand.rb +156 -0
  87. data/lib/evoasm/x64/parameters.rb +211 -0
  88. data/test/helpers/population_helper.rb +128 -0
  89. data/test/helpers/test_helper.rb +1 -0
  90. data/test/helpers/x64_helper.rb +24 -0
  91. data/test/integration/bitwise_reverse_test.rb +41 -0
  92. data/test/integration/gcd_test.rb +52 -0
  93. data/test/integration/popcnt_test.rb +46 -0
  94. data/test/integration/sym_reg_test.rb +68 -0
  95. data/test/unit/evoasm/buffer_test.rb +48 -0
  96. data/test/unit/evoasm/capstone_test.rb +18 -0
  97. data/test/unit/evoasm/domain_test.rb +55 -0
  98. data/test/unit/evoasm/population/parameters_test.rb +106 -0
  99. data/test/unit/evoasm/population_test.rb +96 -0
  100. data/test/unit/evoasm/prng_test.rb +47 -0
  101. data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
  102. data/test/unit/evoasm/x64/encoding_test.rb +320 -0
  103. data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
  104. data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
  105. data/test/unit/evoasm/x64/instruction_test.rb +62 -0
  106. data/test/unit/evoasm/x64/parameters_test.rb +65 -0
  107. data/test/unit/evoasm/x64_test.rb +52 -0
  108. metadata +195 -89
  109. data/Gemfile.rake +0 -8
  110. data/Gemfile.rake.lock +0 -51
  111. data/LICENSE.txt +0 -373
  112. data/data/tables/README.md +0 -19
  113. data/data/tables/x64.csv +0 -1684
  114. data/data/templates/evoasm-x64.c.erb +0 -319
  115. data/data/templates/evoasm-x64.h.erb +0 -126
  116. data/examples/abs.yml +0 -20
  117. data/examples/popcnt.yml +0 -17
  118. data/examples/sym_reg.yml +0 -26
  119. data/exe/evoasm-search +0 -13
  120. data/ext/evoasm_ext/evoasm-alloc.c +0 -145
  121. data/ext/evoasm_ext/evoasm-alloc.h +0 -59
  122. data/ext/evoasm_ext/evoasm-arch.c +0 -44
  123. data/ext/evoasm_ext/evoasm-arch.h +0 -161
  124. data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
  125. data/ext/evoasm_ext/evoasm-buf.c +0 -130
  126. data/ext/evoasm_ext/evoasm-buf.h +0 -47
  127. data/ext/evoasm_ext/evoasm-error.c +0 -31
  128. data/ext/evoasm_ext/evoasm-error.h +0 -75
  129. data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
  130. data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
  131. data/ext/evoasm_ext/evoasm-log.h +0 -69
  132. data/ext/evoasm_ext/evoasm-misc.c +0 -23
  133. data/ext/evoasm_ext/evoasm-misc.h +0 -282
  134. data/ext/evoasm_ext/evoasm-param.h +0 -37
  135. data/ext/evoasm_ext/evoasm-search.c +0 -2145
  136. data/ext/evoasm_ext/evoasm-search.h +0 -214
  137. data/ext/evoasm_ext/evoasm-util.h +0 -40
  138. data/ext/evoasm_ext/evoasm-x64.c +0 -275624
  139. data/ext/evoasm_ext/evoasm-x64.h +0 -5436
  140. data/ext/evoasm_ext/evoasm.c +0 -7
  141. data/ext/evoasm_ext/evoasm.h +0 -23
  142. data/ext/evoasm_ext/evoasm_ext.c +0 -1757
  143. data/ext/evoasm_ext/extconf.rb +0 -31
  144. data/lib/evoasm/cli.rb +0 -6
  145. data/lib/evoasm/cli/search.rb +0 -127
  146. data/lib/evoasm/core_ext.rb +0 -1
  147. data/lib/evoasm/core_ext/array.rb +0 -9
  148. data/lib/evoasm/core_ext/integer.rb +0 -10
  149. data/lib/evoasm/core_ext/kwstruct.rb +0 -13
  150. data/lib/evoasm/core_ext/range.rb +0 -5
  151. data/lib/evoasm/examples.rb +0 -27
  152. data/lib/evoasm/gen.rb +0 -8
  153. data/lib/evoasm/gen/enum.rb +0 -169
  154. data/lib/evoasm/gen/name_util.rb +0 -80
  155. data/lib/evoasm/gen/state.rb +0 -176
  156. data/lib/evoasm/gen/state_dsl.rb +0 -152
  157. data/lib/evoasm/gen/strio.rb +0 -27
  158. data/lib/evoasm/gen/translator.rb +0 -1102
  159. data/lib/evoasm/gen/version.rb +0 -5
  160. data/lib/evoasm/gen/x64.rb +0 -237
  161. data/lib/evoasm/gen/x64/funcs.rb +0 -495
  162. data/lib/evoasm/gen/x64/inst.rb +0 -781
  163. data/lib/evoasm/search.rb +0 -40
  164. data/lib/evoasm/tasks/gen_task.rb +0 -86
  165. data/lib/evoasm/tasks/template_task.rb +0 -52
  166. data/test/test_helper.rb +0 -1
  167. data/test/x64/test_helper.rb +0 -19
  168. data/test/x64/x64_test.rb +0 -87
data/Makefile CHANGED
@@ -3,4 +3,4 @@ all:
3
3
  clean:
4
4
  rake clean
5
5
  debug:
6
- rake compile -- --enable-debug
6
+ rake compile -- --debug
data/README.md CHANGED
@@ -9,24 +9,32 @@ It will then try to come up with a short program (in the form of machine code) t
9
9
  by means of genetic programming.
10
10
  *Evoasm* contains a JIT that executes the generated machine code on the fly.
11
11
 
12
- Currently, the only supported architecture is **x86_64**.
12
+ Currently, the only supported architecture is **x86-64**.
13
13
 
14
- **NOTE:** *Evoasm* is in a very early stage.
14
+ ## Features
15
+
16
+ * Fast JIT
17
+ * Non-linear control flow
18
+ * [x86-64](https://github.com/evoasm/evoasm-gen/blob/master/data/tables/x64.csv) up to AVX2 (no FPU)
19
+ * Lightweight backend [C library](https://github.com/evoasm/libevoasm) with no third-party dependencies
20
+ * Ruby bindings
15
21
 
16
22
  ## Installation
17
23
 
18
- $ gem install evoasm --pre
24
+ $ gem install evoasm
19
25
 
20
26
  ### Requirements
21
27
 
22
- * Ruby 2.3 (MRI)
28
+ * Ruby (MRI >= 2.3, JRuby >= 9.1.2)
23
29
  * [Capstone](http://www.capstone-engine.org/) for disassembling (*optional*).
30
+ * [Graphviz](http://www.graphviz.org/) (libgraphviz) for visualizing programs (*optional*).
31
+ * [Gnuplot](http://gnuplot.sourceforge.net) for visualizing loss functions (*optional*)
24
32
  * POSIX-compliant OS (Linux and Mac OS X should both work).
25
33
 
26
- ## Usage
27
-
28
- Please see [Getting Started](https://github.com/furunkel/evoasm/wiki/Getting-Started).
34
+ ## Documentation
29
35
 
36
+ Please see the [API documentation](https://evoasm.github.io/evoasm/doc/) or
37
+ have a look at the [examples](https://evoasm.github.io/evoasm/doc/file.SymbolicRegression.html).
30
38
 
31
39
  ## Contributing
32
40
 
@@ -38,6 +46,6 @@ Please see [Getting Started](https://github.com/furunkel/evoasm/wiki/Getting-Sta
38
46
 
39
47
  ## License
40
48
 
41
- [MPL-2.0][license]
49
+ [AGPL-3.0][license]
42
50
 
43
- [license]: https://github.com/furunkel/evoasm/blob/master/LICENSE.txt
51
+ [license]: https://github.com/furunkel/evoasm/blob/master/LICENSE.md
data/Rakefile CHANGED
@@ -1,128 +1,60 @@
1
1
  require 'bundler/gem_tasks'
2
-
3
2
  require 'rake/testtask'
4
- require 'rake/extensiontask'
5
3
 
6
- require 'evoasm/tasks/gen_task'
7
- require 'evoasm/tasks/template_task'
4
+ require 'evoasm/gen'
8
5
 
9
- Rake::ExtensionTask.new('evoasm_ext')
6
+ import 'ext/evoasm_ext/compile.rake'
10
7
 
11
- Rake::TestTask.new do |t|
12
- t.libs.push 'lib'
13
- t.pattern = "test/**/*_test.rb"
14
- end
15
8
 
16
- Evoasm::Tasks::GenTask.new
9
+ namespace :test do
10
+ Rake::TestTask.new :unit do |t|
11
+ t.libs.push 'lib', 'test/unit', 'test/helpers'
12
+ t.pattern = "test/unit/**/*_test.rb"
13
+ t.verbose = true
14
+ end
17
15
 
18
- begin
19
- require 'evoasm/scrapers'
20
- Evoasm::Scrapers::X64.new do |t|
21
- t.output_filename = Evoasm::Tasks::GenTask::X64_TABLE_FILENAME
16
+ Rake::TestTask.new :integration do |t|
17
+ t.libs.push 'lib', 'test/integration', 'test/helpers'
18
+ t.pattern = "test/integration/**/*_test.rb"
19
+ t.verbose = true
22
20
  end
23
- rescue LoadError
24
21
  end
25
22
 
26
- directory 'lib' => ['evoasm:gen', 'evoasm:templates']
23
+ task :test => ['test:unit', 'test:integration']
24
+ task :default => :test
27
25
 
28
- task :console do
29
- sh "pry --gem"
30
- end
31
-
32
- =begin
33
- Evoasm::Tasks::TemplateTask.new do |t|
34
- t.source = %w(evoasm-edge.h.tmpl)
35
- t.target = %w(evoasm-asg-edge.h)
36
- t.subs = {
37
- t: 'evoasm_sym',
38
- s: 'evoasm_asg_edge',
39
- w: 32,
40
- includes: <<~EOL
41
- #include "evoasm-sym.h"
42
- EOL
43
- }
44
- end
45
26
 
46
- Evoasm::Tasks::TemplateTask.new do |t|
47
- t.source = %w(evoasm-node.h.tmpl)
48
- t.target = %w(evoasm-asg-node.h)
49
- t.subs = {
50
- t: 'evoasm_token',
51
- l: 'token',
52
- s: 'evoasm_asg_node',
53
- w: 32,
54
- includes: <<~EOL
55
- #include "evoasm-token.h"
56
- EOL
57
- }
27
+ require 'evoasm/gen'
28
+ Evoasm::Gen::GenTask.new 'lib/evoasm/libevoasm' do |t|
29
+ t.file_types = %i(ruby_ffi)
58
30
  end
59
31
 
60
- Evoasm::Tasks::TemplateTask.new do |t|
61
- t.source = %w(evoasm-free-list.c.tmpl evoasm-free-list.h.tmpl)
62
- t.target = %w(evoasm-asg-edge-list.c evoasm-asg-edge-list.h)
63
- t.subs = {
64
- s: 'evoasm_asg_edge_list',
65
- e: 'evoasm_asg_edge',
66
- includes: '#include "gen/evoasm-asg-edge.h"',
67
- embed: 0,
68
- w: 32,
69
- eql: <<~EOL
70
- return a->dir == b->dir &&
71
- a->node_idx == b->node_idx &&
72
- a->label == b->label;
73
- EOL
74
- }
32
+ begin
33
+ require 'evoasm/scrapers'
34
+ Evoasm::Scrapers::X64.new do |t|
35
+ t.output_filename = Evoasm::Tasks::GenTask::X64_TABLE_FILENAME
36
+ end
37
+ rescue LoadError
75
38
  end
76
39
 
77
- Evoasm::Tasks::TemplateTask.new do |t|
78
- t.source = %w(evoasm-free-list.c.tmpl evoasm-free-list.h.tmpl)
79
- t.target = %w(evoasm-asg-node-list.c evoasm-asg-node-list.h)
80
- t.subs = {
81
- s: 'evoasm_asg_node_list',
82
- e: 'evoasm_asg_node',
83
- w: 32,
84
- includes: '#include "evoasm-asg-node.h"',
85
- embed: 0,
86
- }
87
- end
40
+ namespace :yard do
41
+ require 'yard'
42
+ YARD::Rake::YardocTask.new :build do |t|
43
+ t.files = %w(lib/**/*.rb - docs/**/*.md)
44
+ t.options = %w(--asset docs/examples:examples)
45
+ end
88
46
 
89
- Evoasm::Tasks::TemplateTask.new do |t|
90
- t.source = %w(evoasm-graph.c.tmpl evoasm-graph.h.tmpl)
91
- t.target = %w(evoasm-asg.c evoasm-asg.h)
92
- t.subs = {
93
- s: 'evoasm_asg',
94
- el: 'evoasm_asg_edge_list',
95
- nl: 'evoasm_asg_node_list',
96
- e: 'evoasm_asg_edge',
97
- n: 'evoasm_asg_node',
98
- l: 'evoasm_sym',
99
- w: 32,
100
- includes: <<~END,
101
- #include "evoasm-asg-edge-list.h"
102
- #include "evoasm-asg-node-list.h"
103
- #include "evoasm-sym.h"
104
- END
105
- edge_eql: <<~EOL,
106
- return a->dir == b->dir &&
107
- a->node_index == b->node_index &&
108
- a->index == b->index;
109
- EOL
110
- embed: 0,
111
- }
112
- end
47
+ desc "Push YARD documentation to GitHub Pages"
48
+ task :push => :build do
49
+ cp_r 'doc', Dir.tmpdir
50
+ sh 'git checkout gh-pages'
51
+ rm_r 'doc'
52
+ mv File.join(Dir.tmpdir, 'doc'), 'doc'
53
+ sh 'git commit doc -m "Update documentation"'
54
+ sh 'git push origin gh-pages'
55
+ sh 'git checkout master'
56
+ end
113
57
 
114
- Evoasm::Tasks::TemplateTask.new do |t|
115
- t.source = %w(evoasm-free-list.c.tmpl evoasm-free-list.h.tmpl)
116
- t.target = %w(evoasm-page-list.c evoasm-page-list.h)
117
- t.subs = {
118
- s: 'evoasm_page_list',
119
- e: 'evoasm_page',
120
- w: 32,
121
- includes: '#include "evoasm-page.h"',
122
- embed: 0,
123
- }
124
58
  end
125
59
 
126
- =end
127
60
 
128
- task 'evoasm:templates' => Evoasm::Tasks::TemplateTask.all
data/bin/gdb CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/bin/sh
2
- gdb -ex 'handle SIGFPE noprint nostop' --args $(rbenv which ruby) -rbundler/setup $@
2
+ gdb -ex 'handle SIGFPE noprint pass' --args $(rbenv which ruby) -rbundler/setup $@
data/bin/gdb_loop ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ while true; do
3
+ gdb -ex 'handle SIGFPE noprint nostop' -ex run -ex quit --args $(rbenv which ruby) -rbundler/setup $@
4
+ done
@@ -0,0 +1,17 @@
1
+ # @title Finding Instructions
2
+ # Finding Instructions
3
+
4
+ *Evoasm* can be used to find instructions that exhibit a certain behavior.
5
+ Let's assume we want to find an instruction that counts the number of 1s or the number
6
+ of trailing 0s in a binary number.
7
+ Is there an instruction for that? Let's find out.
8
+
9
+ {include:file:docs/examples/bit_insts.rb}
10
+
11
+ Depending on your CPU model this might output the following:
12
+
13
+ ```
14
+ popcnt
15
+
16
+ bsf
17
+ ```
data/docs/JIT.md ADDED
@@ -0,0 +1,14 @@
1
+ # @title Just-in-time Compilation
2
+ # Just-in-time Compilation
3
+
4
+ Using *Evoasm*'s {Evoasm::Buffer Buffer} class, it is possible to do simple just-in-time compilation.
5
+
6
+ {include:file:docs/examples/jit.rb}
7
+
8
+ The second block executes a division-by-zero, causing an exception to be thrown.
9
+ The expected output is thus:
10
+
11
+ ```
12
+ Result: 3
13
+ Execution failed with exception `de'
14
+ ```
@@ -0,0 +1,102 @@
1
+ # @title Symbolic Regression
2
+ # Symbolic Regression
3
+
4
+ A classical application of genetic programming is [symbolic regression](https://en.wikipedia.org/wiki/Symbolic_regression).
5
+ Symbolic regression is the task of finding a mathematical expression that approximates a given set of data points as closely as possible.
6
+
7
+ ## Example Data
8
+
9
+ For purposes of illustration, assume we are given the following
10
+ table of data points, sampled from the function
11
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
12
+ <mi>y</mi>
13
+ <mo>=</mo>
14
+ <msqrt>
15
+ <msup>
16
+ <mi>x</mi>
17
+ <mn>3</mn>
18
+ </msup>
19
+ <mo>+</mo>
20
+ <mrow>
21
+ <mn>2</mn>
22
+ <mi>x</mi>
23
+ </mrow>
24
+ </msqrt>
25
+ </math>.
26
+
27
+ | x | y |
28
+ | ------- | ----- |
29
+ | 0.0 | 0.0 |
30
+ | 0.5 | 1.0606601717798212 |
31
+ | 1.0 | 1.7320508075688772 |
32
+ | 1.5 | 2.5248762345905194 |
33
+ | 2.0 | 3.4641016151377544 |
34
+ | 2.5 | 4.541475531146237 |
35
+ | 3.0 | 5.744562646538029 |
36
+ | 3.5 | 7.0622234459127675 |
37
+ | 4.0 | 8.48528137423857 |
38
+ | 4.5 | 10.00624804809475 |
39
+ | 5.0 | 11.61895003862225 |
40
+
41
+ Using only the points in this table, we now want *Evoasm*
42
+ to come up with a program that, given *x*, will output the corresponding
43
+ *y* for all *x* (i.e. not only those listed in the table).
44
+
45
+ ## Finding a Solution Program
46
+
47
+ Here is how it is done:
48
+
49
+ {include:file:docs/examples/sym_reg.rb}
50
+
51
+ On my machine, *Evoasm* will find a solution in less than a second:
52
+
53
+ ```
54
+ 0x555556b9e270: vmulsd xmm2, xmm0, xmm2
55
+ 0x555556b9e274: vfmadd213sd xmm2, xmm1, xmm0
56
+ 0x555556b9e279: vaddsd xmm3, xmm3, xmm2
57
+ 0x555556b9e27d: vfnmadd231sd xmm2, xmm2, xmm2
58
+ 0x555556b9e282: vfnmadd231sd xmm0, xmm1, xmm0
59
+ 0x555556b9e287: vfmadd132sd xmm0, xmm0, xmm0
60
+ 0x555556b9e28c: vsqrtsd xmm1, xmm1, xmm3
61
+ 0x555556b9e290: addsd xmm0, xmm2
62
+ 0x555556b9e294: vaddsd xmm3, xmm3, xmm2
63
+ 0x555556b9e298: vmulsd xmm0, xmm2, xmm2
64
+ ```
65
+
66
+ ## Examining the Solution
67
+ You can now experiment with the found program.
68
+ Use the {Evoasm::Program#run Program#run} method to run the found program with arbitrary input.
69
+
70
+ ```ruby
71
+ program.run 1.0 # => [1.7320508075688772]
72
+ # test for values not given in table
73
+ program.run 10.0 # => [31.937438845342623]
74
+ ```
75
+
76
+ ## Intron Elimination
77
+ The solutions found by *Evoasm* will usually contain large
78
+ portions of noneffective code (so-called introns).
79
+
80
+ Introns can be removed using the `eliminate_introns!` method.
81
+ This will considerably shorten the size of the solution:
82
+
83
+ ```ruby
84
+ program.eliminate_introns.disassembly format: true
85
+ ```
86
+ gives
87
+
88
+ ```
89
+ 0x555556ba59f0: vmulsd xmm2, xmm0, xmm2
90
+ 0x555556ba59f4: vfmadd213sd xmm2, xmm1, xmm0
91
+ 0x555556ba59f9: vaddsd xmm3, xmm3, xmm2
92
+ 0x555556ba59fd: vsqrtsd xmm1, xmm1, xmm3
93
+ ```
94
+
95
+ For comparison, here is what GCC 6.2 outputs with `-O3 -march=core-avx2`
96
+ ```
97
+ vmulsd %xmm0, %xmm0, %xmm2
98
+ vaddsd %xmm0, %xmm0, %xmm1
99
+ vfmadd132sd %xmm2, %xmm1, %xmm0
100
+ vsqrtsd %xmm0, %xmm1, %xmm1
101
+ ```
102
+
@@ -0,0 +1,29 @@
1
+ # @title Visualization
2
+ # Visualization
3
+
4
+ *Evoasm* provides means to visualize loss functions and found programs.
5
+
6
+ {include:file:docs/examples/vis.rb}
7
+
8
+
9
+ ## Loss Functions
10
+
11
+ Loss functions can be visualized by using {Evoasm::Population#plot} which
12
+ will plot the loss function using [Gnuplot](https://gnuplot.sourceforge.net/).
13
+ If a filename is provided, the loss function graph is saved to file. Otherwise,
14
+ a window will open.
15
+
16
+ Each column represents a deme. The first row shows program losses, the following
17
+ rows kernel losses.
18
+
19
+ ![Loss functions](examples/loss.gif)
20
+
21
+
22
+ ## Programs
23
+
24
+ In a similar fashion, programs can be visualized using [Graphviz](https://www.graphviz.org/).
25
+ Use {Evoasm::Program#to_gv} to obtain a [GV::Graph](http://www.rubydoc.info/github/furunkel/gv/GV/Graph), which
26
+ can be saved to a file using [GV::Graph#save](http://www.rubydoc.info/github/furunkel/gv/GV/Graph#save-instance_method).
27
+
28
+ ![Function](examples/program.png)
29
+
@@ -0,0 +1,44 @@
1
+ require 'evoasm'
2
+ require 'evoasm/x64'
3
+
4
+ count_1s = {
5
+ 0b0 => 0,
6
+ 0b1 => 1,
7
+ 0b100 => 1,
8
+ 0b101 => 2,
9
+ 0b111 => 3,
10
+ 0b1000 => 1
11
+ }
12
+
13
+ parameters = Evoasm::Population::Parameters.new do |p|
14
+ p.instructions = Evoasm::X64.instruction_names(:gp, :rflags)
15
+ p.deme_size = 1024
16
+ p.deme_count = 1
17
+ p.kernel_size = 1
18
+ p.program_size = 1
19
+ p.parameters = %i(reg0 reg1 reg2 reg3)
20
+ end
21
+
22
+ parameters.examples = count_1s
23
+
24
+ population = Evoasm::Population.new parameters
25
+ program, loss = population.run
26
+
27
+ puts "#{program.disassemble.first[1]}"
28
+
29
+ puts
30
+
31
+ count_trailing_0s = {
32
+ 0b100 => 2,
33
+ 0b1 => 0,
34
+ 0b10 => 1,
35
+ 0b101 => 0,
36
+ 0b10000 => 4
37
+ }
38
+
39
+ parameters.examples = count_trailing_0s
40
+
41
+ population = Evoasm::Population.new parameters
42
+ program, loss = population.run
43
+
44
+ puts "#{program.disassemble.first[1]}"