vector_sse 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,374 @@
1
+ begin
2
+ require 'vector_sse'
3
+ rescue StandardError => e
4
+ # vector_sse is not installed as a gem
5
+ require File.join( '..', 'lib', 'vector_sse' )
6
+ end
7
+
8
+ RSpec.describe VectorSSE::Mat do
9
+
10
+ describe "constructor" do
11
+
12
+ it "raises exception on invalid type" do
13
+ expect {
14
+ VectorSSE::Mat.new( VectorSSE::Type::INVALID, 2, 1 )
15
+ }.to raise_error ArgumentError, "invalid SSE matrix type for argument 0"
16
+ end
17
+
18
+ it "raises exception on invalid row dimension" do
19
+ expect {
20
+ VectorSSE::Mat.new( VectorSSE::Type::S32, 0, 1 )
21
+ }.to raise_error ArgumentError, "row count must be greater than zero for argument 1"
22
+ end
23
+
24
+ it "raises exception on invalid column dimension" do
25
+ expect {
26
+ VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 0 )
27
+ }.to raise_error ArgumentError, "column count must be greater than zero for argument 2"
28
+ end
29
+
30
+ it "initializes with correct type and dimensions" do
31
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 10, 8 )
32
+ expect( mat.type ).to eq( VectorSSE::Type::S32 )
33
+ expect( mat.rows ).to eq( 10 )
34
+ expect( mat.cols ).to eq( 8 )
35
+ end
36
+
37
+ it "initializes all elements to zero" do
38
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 4, 2 )
39
+ 8.times do |index|
40
+ expect( mat[ index ] ).to eq( 0 )
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ describe "attributes" do
47
+ it "raises exception on attempt to access protected field" do
48
+ expect {
49
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 4 )
50
+ protected_data = mat.data
51
+ }.to raise_error NoMethodError
52
+ expect {
53
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 4 )
54
+ mat.data = []
55
+ }.to raise_error NoMethodError
56
+ end
57
+ end
58
+
59
+ describe "read element" do
60
+
61
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 4 )
62
+ mat.fill([
63
+ 1, 2, 3, 4,
64
+ 5, 6, 7, 8
65
+ ])
66
+
67
+ it "raises exception on invalid row with 'at' reader" do
68
+ expect {
69
+ mat.at( -1, 0 )
70
+ }.to raise_error "row index out of bounds"
71
+ expect {
72
+ mat.at( 2, 0 )
73
+ }.to raise_error "row index out of bounds"
74
+ end
75
+
76
+ it "raises exception on invalid column with 'at' reader" do
77
+ expect {
78
+ mat.at( 0, -1 )
79
+ }.to raise_error "column index out of bounds"
80
+ expect {
81
+ mat.at( 0, 4 )
82
+ }.to raise_error "column index out of bounds"
83
+ end
84
+
85
+ it "raises exception on invalid index with '[]' reader" do
86
+ expect {
87
+ mat[ -1 ]
88
+ }.to raise_error "index out of bounds"
89
+ expect {
90
+ mat[ 8 ]
91
+ }.to raise_error "index out of bounds"
92
+ end
93
+
94
+ it "returns value from correct row/col location with 'at' reader" do
95
+ expect( mat.at( 1, 2) ).to eq( 7 )
96
+ end
97
+
98
+ it "returns value from correct index with '[]' reader" do
99
+ expect( mat[ 6 ] ).to eq( 7 )
100
+ end
101
+ end
102
+
103
+ describe "write element" do
104
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 4 )
105
+
106
+ it "raises exception on invalid row with 'set' writer" do
107
+ expect {
108
+ mat.set( -1, 0, 0 )
109
+ }.to raise_error "row index out of bounds"
110
+ expect {
111
+ mat.set( 2, 0, 0 )
112
+ }.to raise_error "row index out of bounds"
113
+ end
114
+
115
+ it "raises exception on invalid column with 'set' writer" do
116
+ expect {
117
+ mat.set( 0, -1, 0 )
118
+ }.to raise_error "column index out of bounds"
119
+ expect {
120
+ mat.set( 0, 4, 0 )
121
+ }.to raise_error "column index out of bounds"
122
+ end
123
+
124
+ it "raises exception on invalid index with '[]=' write" do
125
+ expect {
126
+ mat[ -1 ] = 0
127
+ }.to raise_error "index out of bounds"
128
+ expect {
129
+ mat[ 8 ] = 0
130
+ }.to raise_error "index out of bounds"
131
+ end
132
+
133
+ it "sets value at correct row/col location with 'set' writer" do
134
+ mat.set( 1, 2, 7 )
135
+ expect( mat.at( 1, 2) ).to eq( 7 )
136
+ end
137
+
138
+ it "sets value at correct index with '[]=' writer" do
139
+ mat[ 3 ] = 4
140
+ expect( mat[ 3 ] ).to eq( 4 )
141
+ end
142
+ end
143
+
144
+ describe "to string" do
145
+ it "renders matrix as string" do
146
+ mat = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 4 )
147
+ mat.fill([
148
+ 1, 2, 3, 4,
149
+ 5, 6, 7, 8
150
+ ])
151
+
152
+ expect( mat.to_s ).to eq( "|1 2 3 4|\n|5 6 7 8|\n" )
153
+ end
154
+ end
155
+
156
+ describe "matrix addition and subtraction" do
157
+ it "raises exception if the addends are not of equal size" do
158
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
159
+ left.fill([
160
+ 1, 2,
161
+ 3, 4,
162
+ 5, 6
163
+ ])
164
+ right = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 1 )
165
+ right.fill([
166
+ 1,
167
+ 2
168
+ ])
169
+
170
+ expect {
171
+ left + right
172
+ }.to raise_error ArgumentError, "matrix addition requires operands of equal size"
173
+
174
+ expect {
175
+ left - right
176
+ }.to raise_error ArgumentError, "matrix subtraction requires operands of equal size"
177
+ end
178
+
179
+ it "returns correct sum" do
180
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
181
+ left.fill([
182
+ 1, 2,
183
+ 3, 4,
184
+ 5, 6
185
+ ])
186
+ right = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
187
+ right.fill([
188
+ 1, 2,
189
+ 3, 4,
190
+ 5, 6
191
+ ])
192
+
193
+ result = left + right
194
+ expect( result.type ).to eq( left.type )
195
+ expect( result.rows ).to eq( left.rows )
196
+ expect( result.cols ).to eq( left.cols )
197
+
198
+ [ 2, 4,
199
+ 6, 8,
200
+ 10, 12 ].each_with_index do |value,index|
201
+ expect( result[ index ] ).to eq( value )
202
+ end
203
+
204
+ result = left - right
205
+ expect( result.type ).to eq( left.type )
206
+ expect( result.rows ).to eq( left.rows )
207
+ expect( result.cols ).to eq( left.cols )
208
+
209
+ [ 0, 0,
210
+ 0, 0,
211
+ 0, 0 ].each_with_index do |value,index|
212
+ expect( result[ index ] ).to eq( value )
213
+ end
214
+ end
215
+
216
+ it "returns correct sum when added to self" do
217
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
218
+ left.fill([
219
+ 1, 2,
220
+ 3, 4,
221
+ 5, 6
222
+ ])
223
+
224
+ result = left + left
225
+ expect( result.type ).to eq( left.type )
226
+ expect( result.rows ).to eq( left.rows )
227
+ expect( result.cols ).to eq( left.cols )
228
+
229
+ [ 2, 4,
230
+ 6, 8,
231
+ 10, 12 ].each_with_index do |value,index|
232
+ expect( result[ index ] ).to eq( value )
233
+ end
234
+ end
235
+
236
+ it "returns correct sum when added and assigned to self" do
237
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
238
+ left.fill([
239
+ 1, 2,
240
+ 3, 4,
241
+ 5, 6
242
+ ])
243
+ right = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
244
+ right.fill([
245
+ 1, 2,
246
+ 3, 4,
247
+ 5, 6
248
+ ])
249
+
250
+ left += right
251
+ expect( left.type ).to eq( VectorSSE::Type::S32 )
252
+ expect( left.rows ).to eq( 3 )
253
+ expect( left.cols ).to eq( 2 )
254
+
255
+ [ 2, 4,
256
+ 6, 8,
257
+ 10, 12 ].each_with_index do |value,index|
258
+ expect( left[ index ] ).to eq( value )
259
+ end
260
+ end
261
+ end
262
+
263
+ describe "matrix multiplication" do
264
+ it "raises exception for invalid argument" do
265
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 2 )
266
+ right = "this is not a matrix"
267
+
268
+ expect {
269
+ left * right
270
+ }.to raise_error ArgumentError, "expected argument of type VectorSSE::Mat for argument 0"
271
+ end
272
+
273
+ it "raises exception on invalid factor dimensions" do
274
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 2 )
275
+ right = VectorSSE::Mat.new( VectorSSE::Type::S32, 1, 2 )
276
+
277
+ expect {
278
+ left * right
279
+ }.to raise_error "invalid matrix dimensions"
280
+ end
281
+
282
+ it "returns correct signed 32-bit result" do
283
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
284
+ left.fill([
285
+ 1, 2,
286
+ 3, 4,
287
+ 5, 6
288
+ ])
289
+ right = VectorSSE::Mat.new( VectorSSE::Type::S32, 2, 1 )
290
+ right.fill([
291
+ 1,
292
+ 2
293
+ ])
294
+
295
+ result = left * right
296
+ expect( result.type ).to eq( left.type )
297
+ expect( result.rows ).to eq( left.rows )
298
+ expect( result.cols ).to eq( right.cols )
299
+
300
+ [ 5, 11, 17 ].each_with_index do |value,index|
301
+ expect( result[ index ] ).to eq( value )
302
+ end
303
+ end
304
+
305
+ it "returns result with same type as left factor" do
306
+ left = VectorSSE::Mat.new( VectorSSE::Type::S32, 3, 2 )
307
+ left.fill([
308
+ 1, 2,
309
+ 3, 4,
310
+ 5, 6
311
+ ])
312
+ right = VectorSSE::Mat.new( VectorSSE::Type::F32, 2, 1 )
313
+ right.fill([
314
+ 1.9,
315
+ 2.3
316
+ ])
317
+
318
+ result = left * right
319
+ expect( result.type ).to eq( left.type )
320
+ expect( result.rows ).to eq( left.rows )
321
+ expect( result.cols ).to eq( right.cols )
322
+
323
+ [ 5, 11, 17 ].each_with_index do |value,index|
324
+ expect( result[ index ] ).to eq( value )
325
+ end
326
+ end
327
+
328
+ it "returns correct float 32-bit product" do
329
+ left = VectorSSE::Mat.new( VectorSSE::Type::F32, 3, 2 )
330
+ left.fill([
331
+ 1.2, 2.3,
332
+ 3.4, 4.5,
333
+ 5.6, 6.7
334
+ ])
335
+ right = VectorSSE::Mat.new( VectorSSE::Type::F32, 2, 1 )
336
+ right.fill([
337
+ 1.9,
338
+ 2.3
339
+ ])
340
+
341
+ result = left * right
342
+ expect( result.type ).to eq( VectorSSE::Type::F32 )
343
+ expect( result.rows ).to eq( left.rows )
344
+ expect( result.cols ).to eq( right.cols )
345
+
346
+ [ 1.2 * 1.9 + 2.3 * 2.3,
347
+ 3.4 * 1.9 + 4.5 * 2.3,
348
+ 5.6 * 1.9 + 6.7 * 2.3 ].each_with_index do |value,index|
349
+ expect( result[ index ] ).to be_within( 1e-6 ).of( value )
350
+ end
351
+ end
352
+
353
+ it "returns sum of matrix and scalar" do
354
+ original_values = [
355
+ 1.2, 2.3,
356
+ 3.4, 4.5,
357
+ 5.6, 6.7
358
+ ]
359
+
360
+ scalar_value = 1.1
361
+
362
+ left = VectorSSE::Mat.new( VectorSSE::Type::F32, 3, 2 )
363
+ left.fill( original_values )
364
+
365
+ left -= scalar_value
366
+
367
+ original_values.each_with_index do |value,index|
368
+ expected_value = value - scalar_value
369
+ expect( left[ index ] ).to be_within( 1e-6 ).of( expected_value )
370
+ end
371
+ end
372
+ end
373
+
374
+ end
@@ -0,0 +1,150 @@
1
+ begin
2
+ require 'vector_sse'
3
+ rescue StandardError => e
4
+ # vector_sse is not installed as a gem
5
+ require File.join( '..', 'lib', 'vector_sse' )
6
+ end
7
+
8
+ RSpec.describe VectorSSE::Array do
9
+
10
+ describe "constructor" do
11
+ end
12
+
13
+ describe "element insertion" do
14
+
15
+ it "rejects insertion of invalid data types" do
16
+ arr = VectorSSE::Array.new( VectorSSE::Type::S32 )
17
+
18
+ expect {
19
+ arr << "not a valid data type"
20
+ }.to raise_error ArgumentError
21
+
22
+ expect {
23
+ arr.insert( 0, [ 1, "not a valid data type" ] )
24
+ }.to raise_error ArgumentError
25
+
26
+ expect {
27
+ arr[ 0 ] = "not a valid data type"
28
+ }.to raise_error ArgumentError
29
+ end
30
+ end
31
+
32
+ describe "vector addition" do
33
+ it "returns difference between vectors" do
34
+ left = VectorSSE::Array.new( VectorSSE::Type::S32 )
35
+ left.replace [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
36
+ right = VectorSSE::Array.new( VectorSSE::Type::S32 )
37
+ right.replace [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
38
+
39
+ result = left - right
40
+ expect( result.type ).to eq( left.type )
41
+ expect( result.length ).to eq( left.length )
42
+
43
+ [ 9, 7, 5, 3, 1, -1, -3, -5, -7, -9 ].each_with_index do |value,index|
44
+ expect( result[ index ] ).to eq( value )
45
+ end
46
+ end
47
+
48
+ it "returns difference after subtracting scalar Fixnum" do
49
+ left = VectorSSE::Array.new( VectorSSE::Type::S32 )
50
+ left.replace [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
51
+
52
+ left -= 2
53
+
54
+ expect( left.type ).to eq( VectorSSE::Type::S32 )
55
+ expect( left.length ).to eq( 10 )
56
+
57
+ [ 8, 7, 6, 5, 4, 3, 2, 1, 0, -1 ].each_with_index do |value,index|
58
+ expect( left[ index ] ).to eq( value )
59
+ end
60
+ end
61
+
62
+ it "returns difference after subtracting scalar Float" do
63
+
64
+ values = [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
65
+ scalar_value = 2.8
66
+
67
+ left = VectorSSE::Array.new( VectorSSE::Type::F32 )
68
+ left.replace values
69
+
70
+ left -= scalar_value
71
+
72
+ expect( left.type ).to eq( VectorSSE::Type::F32 )
73
+ expect( left.length ).to eq( 10 )
74
+
75
+ values.each_with_index do |value,index|
76
+ expected_value = value - scalar_value
77
+ expect( left[ index ] ).to be_within( 1e-6 ).of( expected_value )
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "scalar vector multiplication" do
83
+
84
+ it "performs scalar multiplication when right factor is scalar integer" do
85
+ data = [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
86
+ scalar_value = -2
87
+
88
+ left = VectorSSE::Array.new( VectorSSE::Type::S32 )
89
+ left.replace data
90
+
91
+ left *= scalar_value
92
+
93
+ expect( left.length ).to eq( data.length )
94
+ data.each_with_index do |value,index|
95
+ expect( left[ index ] ).to eq( value * scalar_value )
96
+ end
97
+
98
+ end
99
+
100
+ it "performs scalar multiplication when right factor is 64-bit scalar integer" do
101
+ data = [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
102
+ scalar_value = -2
103
+
104
+ left = VectorSSE::Array.new( VectorSSE::Type::S64 )
105
+ left.replace data
106
+
107
+ left *= scalar_value
108
+
109
+ expect( left.length ).to eq( data.length )
110
+ data.each_with_index do |value,index|
111
+ expect( left[ index ] ).to eq( value * scalar_value )
112
+ end
113
+
114
+ end
115
+
116
+ it "performs scalar multiplication when right factor is scalar float" do
117
+ data = [ 10.1, 9.2, 8.3, 7.4, 6.5, 5.6, 4.7, 3.8, 2.9, 1.93 ]
118
+ scalar_value = -2.2
119
+
120
+ left = VectorSSE::Array.new( VectorSSE::Type::F32 )
121
+ left.replace data
122
+
123
+ left *= scalar_value
124
+
125
+ expect( left.length ).to eq( data.length )
126
+ data.each_with_index do |value,index|
127
+ expect( left[ index ] ).to be_within( 2e-6 ).of( value * scalar_value )
128
+ end
129
+
130
+ end
131
+
132
+ it "performs scalar multiplication when right factor is scalar double" do
133
+ data = [ 10.1, 9.2, 8.3, 7.4, 6.5, 5.6, 4.7, 3.8, 2.9, 1.93 ]
134
+ scalar_value = -2.2
135
+
136
+ left = VectorSSE::Array.new( VectorSSE::Type::F64 )
137
+ left.replace data
138
+
139
+ left *= scalar_value
140
+
141
+ expect( left.length ).to eq( data.length )
142
+ data.each_with_index do |value,index|
143
+ expect( left[ index ] ).to be_within( 1e-6 ).of( value * scalar_value )
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
150
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require_relative 'lib/vector_sse'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'vector_sse'
6
+ s.version = VectorSSE::VERSION
7
+ s.date = '2015-12-28'
8
+ s.summary = "SIMD accelerated vector and matrix operations"
9
+ s.description = "VectorSse employs x86 Streaming SIMD Extensions (SSE), v3 or greater, to accelerate basic vector and matrix computations in Ruby."
10
+ s.authors = [ "Robert Glissmann" ]
11
+ s.email = 'Robert.Glissmann@gmail.com'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.extensions = %w[ext/vector_sse/extconf.rb]
14
+ s.licenses = ['BSD']
15
+ s.homepage = 'https://github.com/rgmann/vector_sse'
16
+
17
+ s.add_development_dependency 'rake-compiler', '~> 0.9.5'
18
+ s.add_development_dependency 'rspec', '~> 3.1.0'
19
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vector_sse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre
5
+ platform: ruby
6
+ authors:
7
+ - Robert Glissmann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.5
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.1.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 3.1.0
41
+ description: VectorSse employs x86 Streaming SIMD Extensions (SSE), v3 or greater,
42
+ to accelerate basic vector and matrix computations in Ruby.
43
+ email: Robert.Glissmann@gmail.com
44
+ executables: []
45
+ extensions:
46
+ - ext/vector_sse/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - ext/vector_sse/.gitignore
54
+ - ext/vector_sse/extconf.rb
55
+ - ext/vector_sse/vector_sse.c
56
+ - ext/vector_sse/vector_sse_add.c
57
+ - ext/vector_sse/vector_sse_add.h
58
+ - ext/vector_sse/vector_sse_mul.c
59
+ - ext/vector_sse/vector_sse_mul.h
60
+ - ext/vector_sse/vector_sse_sum.c
61
+ - ext/vector_sse/vector_sse_sum.h
62
+ - ext/vector_sse/vector_sse_vec_mul.c
63
+ - ext/vector_sse/vector_sse_vec_mul.h
64
+ - lib/.gitignore
65
+ - lib/vector_sse.rb
66
+ - spec/vector_mat_spec.rb
67
+ - spec/vector_vec_spec.rb
68
+ - vector_sse.gemspec
69
+ homepage: https://github.com/rgmann/vector_sse
70
+ licenses:
71
+ - BSD
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - '>'
85
+ - !ruby/object:Gem::Version
86
+ version: 1.3.1
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.0.14
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: SIMD accelerated vector and matrix operations
93
+ test_files: []