vector_sse 0.0.1.pre

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.
@@ -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: []