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.
- checksums.yaml +4 -4
- data/.gdbinit +41 -0
- data/.gitignore +1 -2
- data/.gitmodules +3 -0
- data/.rubocop.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.md +660 -0
- data/Makefile +1 -1
- data/README.md +17 -9
- data/Rakefile +39 -107
- data/bin/gdb +1 -1
- data/bin/gdb_loop +4 -0
- data/docs/FindingInstructions.md +17 -0
- data/docs/JIT.md +14 -0
- data/docs/SymbolicRegression.md +102 -0
- data/docs/Visualization.md +29 -0
- data/docs/examples/bit_insts.rb +44 -0
- data/docs/examples/jit.rb +26 -0
- data/docs/examples/loss.gif +0 -0
- data/docs/examples/program.png +0 -0
- data/docs/examples/sym_reg.rb +64 -0
- data/docs/examples/vis.rb +38 -0
- data/evoasm.gemspec +21 -15
- data/ext/evoasm_ext/Rakefile +3 -0
- data/ext/evoasm_ext/compile.rake +35 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
- data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
- data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
- data/lib/evoasm.rb +28 -11
- data/lib/evoasm/buffer.rb +105 -0
- data/lib/evoasm/capstone.rb +100 -0
- data/lib/evoasm/domain.rb +116 -0
- data/lib/evoasm/error.rb +37 -16
- data/lib/evoasm/exception_error.rb +19 -0
- data/lib/evoasm/ffi_ext.rb +53 -0
- data/lib/evoasm/libevoasm.rb +286 -0
- data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
- data/lib/evoasm/parameter.rb +20 -0
- data/lib/evoasm/population.rb +145 -0
- data/lib/evoasm/population/parameters.rb +227 -0
- data/lib/evoasm/population/plotter.rb +89 -0
- data/lib/evoasm/prng.rb +64 -0
- data/lib/evoasm/program.rb +195 -12
- data/lib/evoasm/program/io.rb +144 -0
- data/lib/evoasm/test.rb +8 -0
- data/lib/evoasm/version.rb +1 -1
- data/lib/evoasm/x64.rb +115 -0
- data/lib/evoasm/x64/cpu_state.rb +95 -0
- data/lib/evoasm/x64/instruction.rb +109 -0
- data/lib/evoasm/x64/operand.rb +156 -0
- data/lib/evoasm/x64/parameters.rb +211 -0
- data/test/helpers/population_helper.rb +128 -0
- data/test/helpers/test_helper.rb +1 -0
- data/test/helpers/x64_helper.rb +24 -0
- data/test/integration/bitwise_reverse_test.rb +41 -0
- data/test/integration/gcd_test.rb +52 -0
- data/test/integration/popcnt_test.rb +46 -0
- data/test/integration/sym_reg_test.rb +68 -0
- data/test/unit/evoasm/buffer_test.rb +48 -0
- data/test/unit/evoasm/capstone_test.rb +18 -0
- data/test/unit/evoasm/domain_test.rb +55 -0
- data/test/unit/evoasm/population/parameters_test.rb +106 -0
- data/test/unit/evoasm/population_test.rb +96 -0
- data/test/unit/evoasm/prng_test.rb +47 -0
- data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
- data/test/unit/evoasm/x64/encoding_test.rb +320 -0
- data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
- data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
- data/test/unit/evoasm/x64/instruction_test.rb +62 -0
- data/test/unit/evoasm/x64/parameters_test.rb +65 -0
- data/test/unit/evoasm/x64_test.rb +52 -0
- metadata +195 -89
- data/Gemfile.rake +0 -8
- data/Gemfile.rake.lock +0 -51
- data/LICENSE.txt +0 -373
- data/data/tables/README.md +0 -19
- data/data/tables/x64.csv +0 -1684
- data/data/templates/evoasm-x64.c.erb +0 -319
- data/data/templates/evoasm-x64.h.erb +0 -126
- data/examples/abs.yml +0 -20
- data/examples/popcnt.yml +0 -17
- data/examples/sym_reg.yml +0 -26
- data/exe/evoasm-search +0 -13
- data/ext/evoasm_ext/evoasm-alloc.c +0 -145
- data/ext/evoasm_ext/evoasm-alloc.h +0 -59
- data/ext/evoasm_ext/evoasm-arch.c +0 -44
- data/ext/evoasm_ext/evoasm-arch.h +0 -161
- data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
- data/ext/evoasm_ext/evoasm-buf.c +0 -130
- data/ext/evoasm_ext/evoasm-buf.h +0 -47
- data/ext/evoasm_ext/evoasm-error.c +0 -31
- data/ext/evoasm_ext/evoasm-error.h +0 -75
- data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
- data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
- data/ext/evoasm_ext/evoasm-log.h +0 -69
- data/ext/evoasm_ext/evoasm-misc.c +0 -23
- data/ext/evoasm_ext/evoasm-misc.h +0 -282
- data/ext/evoasm_ext/evoasm-param.h +0 -37
- data/ext/evoasm_ext/evoasm-search.c +0 -2145
- data/ext/evoasm_ext/evoasm-search.h +0 -214
- data/ext/evoasm_ext/evoasm-util.h +0 -40
- data/ext/evoasm_ext/evoasm-x64.c +0 -275624
- data/ext/evoasm_ext/evoasm-x64.h +0 -5436
- data/ext/evoasm_ext/evoasm.c +0 -7
- data/ext/evoasm_ext/evoasm.h +0 -23
- data/ext/evoasm_ext/evoasm_ext.c +0 -1757
- data/ext/evoasm_ext/extconf.rb +0 -31
- data/lib/evoasm/cli.rb +0 -6
- data/lib/evoasm/cli/search.rb +0 -127
- data/lib/evoasm/core_ext.rb +0 -1
- data/lib/evoasm/core_ext/array.rb +0 -9
- data/lib/evoasm/core_ext/integer.rb +0 -10
- data/lib/evoasm/core_ext/kwstruct.rb +0 -13
- data/lib/evoasm/core_ext/range.rb +0 -5
- data/lib/evoasm/examples.rb +0 -27
- data/lib/evoasm/gen.rb +0 -8
- data/lib/evoasm/gen/enum.rb +0 -169
- data/lib/evoasm/gen/name_util.rb +0 -80
- data/lib/evoasm/gen/state.rb +0 -176
- data/lib/evoasm/gen/state_dsl.rb +0 -152
- data/lib/evoasm/gen/strio.rb +0 -27
- data/lib/evoasm/gen/translator.rb +0 -1102
- data/lib/evoasm/gen/version.rb +0 -5
- data/lib/evoasm/gen/x64.rb +0 -237
- data/lib/evoasm/gen/x64/funcs.rb +0 -495
- data/lib/evoasm/gen/x64/inst.rb +0 -781
- data/lib/evoasm/search.rb +0 -40
- data/lib/evoasm/tasks/gen_task.rb +0 -86
- data/lib/evoasm/tasks/template_task.rb +0 -52
- data/test/test_helper.rb +0 -1
- data/test/x64/test_helper.rb +0 -19
- data/test/x64/x64_test.rb +0 -87
data/Makefile
CHANGED
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 **
|
|
12
|
+
Currently, the only supported architecture is **x86-64**.
|
|
13
13
|
|
|
14
|
-
|
|
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
|
|
24
|
+
$ gem install evoasm
|
|
19
25
|
|
|
20
26
|
### Requirements
|
|
21
27
|
|
|
22
|
-
* Ruby 2.3
|
|
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
|
-
##
|
|
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
|
-
[
|
|
49
|
+
[AGPL-3.0][license]
|
|
42
50
|
|
|
43
|
-
[license]: https://github.com/furunkel/evoasm/blob/master/LICENSE.
|
|
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/
|
|
7
|
-
require 'evoasm/tasks/template_task'
|
|
4
|
+
require 'evoasm/gen'
|
|
8
5
|
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
t.
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
t.
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
2
|
+
gdb -ex 'handle SIGFPE noprint pass' --args $(rbenv which ruby) -rbundler/setup $@
|
data/bin/gdb_loop
ADDED
|
@@ -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
|
+

|
|
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
|
+

|
|
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]}"
|