damsi 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/pdd.yml +1 -1
- data/.github/workflows/xcop.yml +1 -1
- data/.rubocop.yml +2 -0
- data/Gemfile +1 -1
- data/README.md +8 -24
- data/lib/damsi/advisor.rb +54 -0
- data/lib/damsi/dfg.rb +48 -7
- data/lib/damsi/version.rb +1 -1
- data/test/test_advisor.rb +38 -0
- data/test/test_dfg.rb +149 -11
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0444c06e388d5a2f3607c93e295bfea0ee4e05fe6e35f061bb2a06c1db829b1b
|
4
|
+
data.tar.gz: dcacff4b6f85d24e100c3f44c558dc296c4f7f39c420223a013ab6cade5982fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c43ad00f6d505468a7124a0ec888ca211fcef03fb90d84730b856c3bf6b2e69f43a83ede23b5f4a355b08c80756cf4168ef4bc8d953f8603c4bdad18750d1617
|
7
|
+
data.tar.gz: b1e55fdc9ea45a9b874e1b9ae3de078a655617f37cfc3fba39a3262c82d290458ede2943ab3291208021384335c91f46461ba559ebff79aad19b0e3faf0be883
|
data/.github/workflows/pdd.yml
CHANGED
data/.github/workflows/xcop.yml
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -26,6 +26,6 @@ gem 'minitest', '5.19.0', require: false
|
|
26
26
|
gem 'rake', '13.0.6', require: false
|
27
27
|
gem 'rdoc', '6.5.0', require: false
|
28
28
|
gem 'rubocop', '1.55.1', require: false
|
29
|
-
gem 'rubocop-rspec', '2.23.
|
29
|
+
gem 'rubocop-rspec', '2.23.2', require: false
|
30
30
|
gem 'simplecov', '0.22.0', require: false
|
31
31
|
gem 'xcop', '0.7.1', require: false
|
data/README.md
CHANGED
@@ -9,34 +9,18 @@
|
|
9
9
|
|
10
10
|
It's a simulator of a dataflow machine.
|
11
11
|
|
12
|
-
First, you define a dataflow graph and save it to `
|
13
|
-
(this is the calculator of the 5th Fibonacci number):
|
12
|
+
First, you define a dataflow graph and save it to `test.dfg`:
|
14
13
|
|
15
14
|
```
|
16
|
-
|
17
|
-
send :
|
18
|
-
|
19
|
-
send :gt n:n
|
20
|
-
send :dec1 n:n
|
21
|
-
send :dec2 n:n
|
22
|
-
send :sum a:n # if tagged
|
23
|
-
send :sum b:n # if tagged right
|
15
|
+
recv :start do
|
16
|
+
send :sum, :a, 10
|
17
|
+
send :sum, :b, 15
|
24
18
|
end
|
25
|
-
recv :
|
26
|
-
|
27
|
-
send :fibo n:t
|
28
|
-
else
|
29
|
-
send :fibo n:f
|
30
|
-
end
|
19
|
+
recv :sum do |a, b|
|
20
|
+
send :mul, :x, (a+b)
|
31
21
|
end
|
32
|
-
recv :
|
33
|
-
send :
|
34
|
-
end
|
35
|
-
recv :dec1 [:n] do
|
36
|
-
send :fibo n:(n-1)
|
37
|
-
end
|
38
|
-
recv :dec2 [:n] do
|
39
|
-
send :fibo n:(n-2)
|
22
|
+
recv :mul do |x|
|
23
|
+
send :stop, :x, x
|
40
24
|
end
|
41
25
|
```
|
42
26
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright (c) 2023 Yegor Bugayenko
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
11
|
+
# copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
# SOFTWARE.
|
20
|
+
|
21
|
+
# Distribution Advisor.
|
22
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
23
|
+
# Copyright:: Copyright (c) 2023 Yegor Bugayenko
|
24
|
+
# License:: MIT
|
25
|
+
class Damsi::Advisor
|
26
|
+
def initialize(dfg, ticks, log)
|
27
|
+
@dfg = dfg
|
28
|
+
@ticks = ticks
|
29
|
+
@log = log
|
30
|
+
end
|
31
|
+
|
32
|
+
# The instruction cell (IC) is coming here and the method
|
33
|
+
# should return a possibly empty array of ICs.
|
34
|
+
def redirect(cell)
|
35
|
+
v1 = cell[:v1]
|
36
|
+
vw = cell[:v2]
|
37
|
+
v2 = vw
|
38
|
+
arc = cell[:arc]
|
39
|
+
data = cell[:data]
|
40
|
+
a = @dfg.m?(vw, nil)
|
41
|
+
vr = @dfg.e?(:k, vw, nil)
|
42
|
+
@log.debug("DA: a:#{a}, vr:#{vr}")
|
43
|
+
if @dfg.e?(:d, v1, vw) && @dfg.m?(vr, a)
|
44
|
+
v2 = @dfg.e?(:d, vr, nil)
|
45
|
+
@log.debug("DA: v1:#{v1}, v2:#{vw}->#{v2}, arc:#{arc}, data:#{data}")
|
46
|
+
@ticks.push(cell[:tick], "\\texttt{\\frenchspacing{}DA: #{vw}.#{arc} → #{v2}.#{arc}}")
|
47
|
+
else
|
48
|
+
@log.debug("DA: v1:#{v1}, v2:#{v2}, arc:#{arc}, data:#{data}")
|
49
|
+
end
|
50
|
+
after = cell
|
51
|
+
after[:v2] = v2
|
52
|
+
[after]
|
53
|
+
end
|
54
|
+
end
|
data/lib/damsi/dfg.rb
CHANGED
@@ -19,8 +19,9 @@
|
|
19
19
|
# SOFTWARE.
|
20
20
|
|
21
21
|
require_relative 'ticks'
|
22
|
+
require_relative 'advisor'
|
22
23
|
|
23
|
-
# Dataflow Graph (DFG)
|
24
|
+
# Dataflow Graph (DFG).
|
24
25
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
25
26
|
# Copyright:: Copyright (c) 2023 Yegor Bugayenko
|
26
27
|
# License:: MIT
|
@@ -34,6 +35,45 @@ class Damsi::DFG
|
|
34
35
|
@tick = 0
|
35
36
|
@op = nil
|
36
37
|
@started = []
|
38
|
+
@advisor = Damsi::Advisor.new(self, @ticks, log)
|
39
|
+
@links = []
|
40
|
+
@edges = []
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add edge (only for information).
|
44
|
+
def edge(arc, left, right)
|
45
|
+
@edges.push({ arc: arc, v1: left, v2: right })
|
46
|
+
end
|
47
|
+
|
48
|
+
# The edge exists?
|
49
|
+
def e?(arc, left, right)
|
50
|
+
@edges.each do |e|
|
51
|
+
next if !arc.nil? && e[:arc] != arc
|
52
|
+
next if !left.nil? && e[:v1] != left
|
53
|
+
next if !right.nil? && e[:v2] != right
|
54
|
+
return e[:arc] if arc.nil?
|
55
|
+
return e[:v1] if left.nil?
|
56
|
+
return e[:v2] if right.nil?
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
# Add link to external entity, like RAM.
|
63
|
+
def link(vtx, ext)
|
64
|
+
@links.push({ vtx: vtx, ext: ext })
|
65
|
+
end
|
66
|
+
|
67
|
+
# The semantic of the vertex is memory related?
|
68
|
+
def m?(vtx, ext)
|
69
|
+
@links.each do |l|
|
70
|
+
next if !vtx.nil? && l[:vtx] != vtx
|
71
|
+
next if !ext.nil? && l[:ext] != ext
|
72
|
+
return l[:vtx] if vtx.nil?
|
73
|
+
return l[:ext] if ext.nil?
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
false
|
37
77
|
end
|
38
78
|
|
39
79
|
def cell(vtx)
|
@@ -44,12 +84,13 @@ class Damsi::DFG
|
|
44
84
|
@ticks.push(@tick, "\\texttt{\\frenchspacing{}#{@op}: #{tex}}")
|
45
85
|
end
|
46
86
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@cells[
|
51
|
-
@
|
52
|
-
@
|
87
|
+
# Send "data" through the "arc" to the vertex "vtx"
|
88
|
+
def send(vtx, arc, data)
|
89
|
+
@advisor.redirect({ tick: @tick, v1: @op, v2: vtx, arc: arc, data: data }).each do |ic|
|
90
|
+
@cells[ic[:v2]] = {} if @cells[ic[:v2]].nil?
|
91
|
+
@cells[ic[:v2]][ic[:arc]] = ic[:data]
|
92
|
+
@ticks.push(@tick, "\\texttt{\\frenchspacing{}#{@op}: \"#{ic[:data]}\" → #{ic[:v2]}.#{ic[:arc]}}")
|
93
|
+
@log.debug("#{@tick}| #{ic[:data]} -> #{ic[:v2]}.#{ic[:arc]}")
|
53
94
|
end
|
54
95
|
end
|
55
96
|
|
data/lib/damsi/version.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2023 Yegor Bugayenko
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
11
|
+
# copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
# SOFTWARE.
|
20
|
+
|
21
|
+
require 'minitest/autorun'
|
22
|
+
require 'loog'
|
23
|
+
require_relative '../lib/damsi/ticks'
|
24
|
+
require_relative '../lib/damsi/advisor'
|
25
|
+
|
26
|
+
# Test for Advisor.
|
27
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
+
# Copyright:: Copyright (c) 2023 Yegor Bugayenko
|
29
|
+
# License:: MIT
|
30
|
+
class TestAdvisor < Minitest::Test
|
31
|
+
def test_simple_redirect
|
32
|
+
dfg = Damsi::DFG.new('', Loog::NULL)
|
33
|
+
da = Damsi::Advisor.new(dfg, Damsi::Ticks.new, Loog::NULL)
|
34
|
+
cell = {}
|
35
|
+
ics = da.redirect(cell)
|
36
|
+
assert_equal(1, ics.length)
|
37
|
+
end
|
38
|
+
end
|
data/test/test_dfg.rb
CHANGED
@@ -29,18 +29,68 @@ require_relative '../lib/damsi/ticks'
|
|
29
29
|
# Copyright:: Copyright (c) 2023 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestDFG < Minitest::Test
|
32
|
+
def test_edges_finding
|
33
|
+
dfg = Damsi::DFG.new(
|
34
|
+
'
|
35
|
+
edge :a, :v1, :v2
|
36
|
+
edge :b, :v1, :v2
|
37
|
+
',
|
38
|
+
Loog::NULL
|
39
|
+
)
|
40
|
+
dfg.simulate
|
41
|
+
assert(dfg.e?(:a, :v1, :v2))
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_edges_finding_by_mask
|
45
|
+
dfg = Damsi::DFG.new(
|
46
|
+
'
|
47
|
+
edge :a, :v1, :v2
|
48
|
+
edge :b, :v1, :v2
|
49
|
+
',
|
50
|
+
Loog::NULL
|
51
|
+
)
|
52
|
+
dfg.simulate
|
53
|
+
assert_equal(:v2, dfg.e?(:a, :v1, nil))
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_links_finding
|
57
|
+
dfg = Damsi::DFG.new(
|
58
|
+
'
|
59
|
+
link :v1, "foo"
|
60
|
+
link :v2, "bar"
|
61
|
+
',
|
62
|
+
Loog::NULL
|
63
|
+
)
|
64
|
+
dfg.simulate
|
65
|
+
assert(dfg.m?(:v1, 'foo'))
|
66
|
+
assert(!dfg.m?(:v1, 'bar'))
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_links_finding_by_mask
|
70
|
+
dfg = Damsi::DFG.new(
|
71
|
+
'
|
72
|
+
link :v1, "foo"
|
73
|
+
link :v2, "bar"
|
74
|
+
',
|
75
|
+
Loog::NULL
|
76
|
+
)
|
77
|
+
dfg.simulate
|
78
|
+
assert_equal(:v1, dfg.m?(nil, 'foo'))
|
79
|
+
assert_equal('bar', dfg.m?(:v2, nil))
|
80
|
+
end
|
81
|
+
|
32
82
|
def test_primitive_summator
|
33
83
|
dfg = Damsi::DFG.new(
|
34
84
|
'
|
35
85
|
recv :start do
|
36
|
-
send :sum, a
|
37
|
-
send :sum, b
|
86
|
+
send :sum, :a, 10
|
87
|
+
send :sum, :b, 15
|
38
88
|
end
|
39
89
|
recv :sum do |a, b|
|
40
|
-
send :mul, x
|
90
|
+
send :mul, :x, (a+b)
|
41
91
|
end
|
42
92
|
recv :mul do |x|
|
43
|
-
send :stop, x
|
93
|
+
send :stop, :x, x
|
44
94
|
end
|
45
95
|
',
|
46
96
|
Loog::NULL
|
@@ -61,30 +111,118 @@ class TestDFG < Minitest::Test
|
|
61
111
|
end
|
62
112
|
recv :r1 do
|
63
113
|
msg "Read #{@data} from RAM"
|
64
|
-
send :nxt1, d
|
114
|
+
send :nxt1, :d, @data
|
115
|
+
end
|
116
|
+
recv :nxt1 do |d|
|
117
|
+
n = next_random(d)
|
118
|
+
msg "Shift from #{d} to #{n}"
|
119
|
+
send :w1, :d, n
|
120
|
+
end
|
121
|
+
recv :w1 do |d|
|
122
|
+
@data = d
|
123
|
+
msg "Write #{d} to RAM"
|
124
|
+
send :r2, :k, 1
|
125
|
+
end
|
126
|
+
recv :r2 do |k|
|
127
|
+
msg "Read #{@data} from RAM"
|
128
|
+
send :nxt2, :d, @data
|
129
|
+
end
|
130
|
+
recv :nxt2 do |d|
|
131
|
+
n = next_random(d)
|
132
|
+
msg "Shift from #{d} to #{n}"
|
133
|
+
send :w2, :d, n
|
134
|
+
send :seq, :d, n
|
135
|
+
end
|
136
|
+
recv :seq do |d|
|
137
|
+
send :stop, :x, d
|
138
|
+
end
|
139
|
+
',
|
140
|
+
Loog::VERBOSE
|
141
|
+
)
|
142
|
+
ticks = dfg.simulate
|
143
|
+
assert_equal(756, dfg.cell(:stop)[:x])
|
144
|
+
tex = TeX.new
|
145
|
+
ticks.to_latex(tex)
|
146
|
+
tex.to_pdf(path: '/tmp/damsi.pdf', tex: '/tmp/damsi.tex')
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_prng_with_links
|
150
|
+
dfg = Damsi::DFG.new(
|
151
|
+
'
|
152
|
+
@data = 42
|
153
|
+
def next_random(n)
|
154
|
+
(n * n) / 16 & 0xffff
|
155
|
+
end
|
156
|
+
|
157
|
+
edge :d, :r1, :nxt1
|
158
|
+
edge :d, :nxt1, :w1
|
159
|
+
edge :k, :w1, :r2
|
160
|
+
edge :d, :r2, :nxt2
|
161
|
+
edge :d, :nxt2, :w2
|
162
|
+
edge :d, :nxt2, :seq
|
163
|
+
|
164
|
+
link :r1, "RAM"
|
165
|
+
recv :r1 do
|
166
|
+
msg "Read #{@data} from RAM"
|
167
|
+
send :nxt1, :d, @data
|
65
168
|
end
|
66
169
|
recv :nxt1 do |d|
|
67
170
|
n = next_random(d)
|
68
171
|
msg "Shift from #{d} to #{n}"
|
69
|
-
send :w1, d
|
172
|
+
send :w1, :d, n
|
70
173
|
end
|
174
|
+
link :w1, "RAM"
|
71
175
|
recv :w1 do |d|
|
72
176
|
@data = d
|
73
177
|
msg "Write #{d} to RAM"
|
74
|
-
send :r2, k
|
178
|
+
send :r2, :k, 1
|
75
179
|
end
|
180
|
+
link :r2, "RAM"
|
76
181
|
recv :r2 do |k|
|
77
182
|
msg "Read #{@data} from RAM"
|
78
|
-
send :nxt2, d
|
183
|
+
send :nxt2, :d, @data
|
184
|
+
end
|
185
|
+
link :w2, "RAM"
|
186
|
+
recv :nxt2 do |d|
|
187
|
+
n = next_random(d)
|
188
|
+
msg "Shift from #{d} to #{n}"
|
189
|
+
send :w2, :d, n
|
190
|
+
send :seq, :d, n
|
191
|
+
end
|
192
|
+
',
|
193
|
+
Loog::VERBOSE
|
194
|
+
)
|
195
|
+
ticks = dfg.simulate
|
196
|
+
assert_equal(756, dfg.cell(:seq)[:d])
|
197
|
+
tex = TeX.new
|
198
|
+
ticks.to_latex(tex)
|
199
|
+
tex.to_pdf(path: '/tmp/damsi.pdf', tex: '/tmp/damsi.tex')
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_prng_optimized
|
203
|
+
dfg = Damsi::DFG.new(
|
204
|
+
'
|
205
|
+
@data = 42
|
206
|
+
def next_random(n)
|
207
|
+
(n * n) / 16 & 0xffff
|
208
|
+
end
|
209
|
+
recv :r1 do
|
210
|
+
msg "Read #{@data} from RAM"
|
211
|
+
send :nxt1, :d, @data
|
212
|
+
end
|
213
|
+
recv :nxt1 do |d|
|
214
|
+
n = next_random(d)
|
215
|
+
msg "Shift from #{d} to #{n}"
|
216
|
+
send :nxt2, :d, n
|
79
217
|
end
|
80
218
|
recv :nxt2 do |d|
|
81
219
|
n = next_random(d)
|
82
220
|
msg "Shift from #{d} to #{n}"
|
83
|
-
send :w2, d
|
84
|
-
send :seq, d
|
221
|
+
send :w2, :d, n
|
222
|
+
send :seq, :d, n
|
85
223
|
end
|
86
224
|
recv :seq do |d|
|
87
|
-
send :stop, x
|
225
|
+
send :stop, :x, d
|
88
226
|
end
|
89
227
|
',
|
90
228
|
Loog::VERBOSE
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: damsi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backtrace
|
@@ -95,11 +95,13 @@ files:
|
|
95
95
|
- features/support/env.rb
|
96
96
|
- fixtures/fibonacci.dfg
|
97
97
|
- fixtures/sum.dfg
|
98
|
+
- lib/damsi/advisor.rb
|
98
99
|
- lib/damsi/dfg.rb
|
99
100
|
- lib/damsi/ticks.rb
|
100
101
|
- lib/damsi/version.rb
|
101
102
|
- renovate.json
|
102
103
|
- test/test__helper.rb
|
104
|
+
- test/test_advisor.rb
|
103
105
|
- test/test_dfg.rb
|
104
106
|
- test/test_tex.rb
|
105
107
|
- test/test_ticks.rb
|