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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/LICENSE.txt +23 -0
- data/README.md +100 -0
- data/Rakefile +9 -0
- data/ext/vector_sse/.gitignore +1 -0
- data/ext/vector_sse/extconf.rb +13 -0
- data/ext/vector_sse/vector_sse.c +80 -0
- data/ext/vector_sse/vector_sse_add.c +127 -0
- data/ext/vector_sse/vector_sse_add.h +48 -0
- data/ext/vector_sse/vector_sse_mul.c +340 -0
- data/ext/vector_sse/vector_sse_mul.h +43 -0
- data/ext/vector_sse/vector_sse_sum.c +118 -0
- data/ext/vector_sse/vector_sse_sum.h +43 -0
- data/ext/vector_sse/vector_sse_vec_mul.c +157 -0
- data/ext/vector_sse/vector_sse_vec_mul.h +43 -0
- data/lib/.gitignore +1 -0
- data/lib/vector_sse.rb +475 -0
- data/spec/vector_mat_spec.rb +374 -0
- data/spec/vector_vec_spec.rb +150 -0
- data/vector_sse.gemspec +19 -0
- metadata +93 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
//
|
2
|
+
// Copyright (c) 2015, Robert Glissmann
|
3
|
+
// All rights reserved.
|
4
|
+
//
|
5
|
+
// Redistribution and use in source and binary forms, with or without
|
6
|
+
// modification, are permitted provided that the following conditions are met:
|
7
|
+
//
|
8
|
+
// * Redistributions of source code must retain the above copyright notice, this
|
9
|
+
// list of conditions and the following disclaimer.
|
10
|
+
//
|
11
|
+
// * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
// this list of conditions and the following disclaimer in the documentation
|
13
|
+
// and/or other materials provided with the distribution.
|
14
|
+
//
|
15
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
//
|
26
|
+
|
27
|
+
// %% license-end-token %%
|
28
|
+
//
|
29
|
+
// Author: Robert.Glissmann@gmail.com (Robert Glissmann)
|
30
|
+
//
|
31
|
+
//
|
32
|
+
|
33
|
+
#ifndef VECTOR_SSE_VEC_MUL_H
|
34
|
+
#define VECTOR_SSE_VEC_MUL_H
|
35
|
+
|
36
|
+
#include <ruby.h>
|
37
|
+
|
38
|
+
VALUE method_vec_mul_s32( VALUE self, VALUE left, VALUE right );
|
39
|
+
VALUE method_vec_mul_s64( VALUE self, VALUE left, VALUE right );
|
40
|
+
VALUE method_vec_mul_f32( VALUE self, VALUE left, VALUE right );
|
41
|
+
VALUE method_vec_mul_f64( VALUE self, VALUE left, VALUE right );
|
42
|
+
|
43
|
+
#endif // VECTOR_SSE_VEC_MUL_H
|
data/lib/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
vector_sse/
|
data/lib/vector_sse.rb
ADDED
@@ -0,0 +1,475 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015, Robert Glissmann
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#
|
26
|
+
|
27
|
+
# %% license-end-token %%
|
28
|
+
#
|
29
|
+
# Author: Robert.Glissmann@gmail.com (Robert Glissmann)
|
30
|
+
#
|
31
|
+
#
|
32
|
+
|
33
|
+
bin_root = File.join( File.dirname( __FILE__ ), 'vector_sse' )
|
34
|
+
require File.join( bin_root, 'vector_sse.so' )
|
35
|
+
|
36
|
+
|
37
|
+
module VectorSSE
|
38
|
+
|
39
|
+
VERSION = "0.0.1.pre"
|
40
|
+
|
41
|
+
module Type
|
42
|
+
S32 = 0
|
43
|
+
S64 = 1
|
44
|
+
F32 = 4
|
45
|
+
F64 = 5
|
46
|
+
INVALID = -1
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.valid_type( type )
|
50
|
+
[ Type::S32, Type::S64, Type::F32, Type::F64 ].include?( type )
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
class Mat
|
55
|
+
|
56
|
+
MIN_ROW_COL_COUNT = 1
|
57
|
+
|
58
|
+
attr_reader :type
|
59
|
+
attr_reader :rows
|
60
|
+
attr_reader :cols
|
61
|
+
|
62
|
+
def initialize( type, rows, cols, data=nil )
|
63
|
+
|
64
|
+
if VectorSSE::valid_type( type )
|
65
|
+
@type = type
|
66
|
+
else
|
67
|
+
raise ArgumentError.new( "invalid SSE matrix type for argument 0" )
|
68
|
+
end
|
69
|
+
|
70
|
+
if rows < MIN_ROW_COL_COUNT
|
71
|
+
raise ArgumentError.new( "row count must be greater than zero for argument 1" )
|
72
|
+
end
|
73
|
+
|
74
|
+
if cols < MIN_ROW_COL_COUNT
|
75
|
+
raise ArgumentError.new( "column count must be greater than zero for argument 2" )
|
76
|
+
end
|
77
|
+
|
78
|
+
if data && ( data.class != ::Array )
|
79
|
+
raise ArgumentError.new( "expected value of type Array for argument 3" )
|
80
|
+
end
|
81
|
+
|
82
|
+
@rows = rows
|
83
|
+
@cols = cols
|
84
|
+
@linear_size = @rows * @cols
|
85
|
+
|
86
|
+
@data = ::Array.new( @linear_size, 0 )
|
87
|
+
|
88
|
+
fill( data ) if data
|
89
|
+
end
|
90
|
+
|
91
|
+
def at( row, col )
|
92
|
+
valid_row_col( row, col )
|
93
|
+
@data[ linear_index( row, col ) ]
|
94
|
+
end
|
95
|
+
|
96
|
+
def set( row, col, val )
|
97
|
+
valid_row_col( row, col )
|
98
|
+
valid_data_type( val )
|
99
|
+
@data[ linear_index( row, col ) ] = val
|
100
|
+
end
|
101
|
+
|
102
|
+
def fill( data )
|
103
|
+
if data.length != @rows * @cols
|
104
|
+
raise ArgumentError.new( "size does not match matrix size" )
|
105
|
+
end
|
106
|
+
|
107
|
+
data.each do |value|
|
108
|
+
valid_data_type( value )
|
109
|
+
end
|
110
|
+
|
111
|
+
@data = data
|
112
|
+
end
|
113
|
+
|
114
|
+
def []( pos )
|
115
|
+
valid_linear_index( pos )
|
116
|
+
@data[ pos ]
|
117
|
+
end
|
118
|
+
|
119
|
+
def []=( pos, val )
|
120
|
+
valid_linear_index( pos )
|
121
|
+
valid_data_type( val )
|
122
|
+
@data[ pos ] = val
|
123
|
+
end
|
124
|
+
|
125
|
+
def to_s
|
126
|
+
text = ""
|
127
|
+
@rows.times do |r|
|
128
|
+
vals = []
|
129
|
+
@cols.times do |c|
|
130
|
+
vals << @data[r*@cols + c]
|
131
|
+
end
|
132
|
+
text << "|#{vals.join(' ')}|\n"
|
133
|
+
end
|
134
|
+
text
|
135
|
+
end
|
136
|
+
|
137
|
+
def *( other )
|
138
|
+
|
139
|
+
scalar_mul = false
|
140
|
+
|
141
|
+
if [ Fixnum, Float ].include? other.class
|
142
|
+
|
143
|
+
scalar_mul = true
|
144
|
+
scalar_value = other
|
145
|
+
other = Mat.new( @type, @rows, @cols )
|
146
|
+
other.data.replace( ::Array.new( @linear_size, scalar_value ) )
|
147
|
+
|
148
|
+
elsif other.class == self.class
|
149
|
+
|
150
|
+
if @cols != other.rows
|
151
|
+
raise "invalid matrix dimensions"
|
152
|
+
end
|
153
|
+
|
154
|
+
else
|
155
|
+
raise ArgumentError.new(
|
156
|
+
"expected argument of type #{self.class} for argument 0" )
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
result = Mat.new( @type, @rows, other.cols )
|
161
|
+
|
162
|
+
case @type
|
163
|
+
when Type::S32
|
164
|
+
if scalar_mul
|
165
|
+
result.data.replace( VectorSSE::vec_mul_s32( self.data, other.data ) )
|
166
|
+
else
|
167
|
+
result.data.replace( VectorSSE::mul_s32(
|
168
|
+
@data, @rows, @cols, other.data, other.rows, other.cols ) )
|
169
|
+
end
|
170
|
+
when Type::S64
|
171
|
+
if scalar_mul
|
172
|
+
result.data.replace( VectorSSE::vec_mul_s32( self.data, other.data ) )
|
173
|
+
else
|
174
|
+
result.data.replace( VectorSSE::mul_s64(
|
175
|
+
@data, @rows, @cols, other.data, other.rows, other.cols ) )
|
176
|
+
end
|
177
|
+
when Type::F32
|
178
|
+
if scalar_mul
|
179
|
+
result.data.replace( VectorSSE::vec_mul_f32( self.data, other.data ) )
|
180
|
+
else
|
181
|
+
result.data.replace( VectorSSE::mul_f32(
|
182
|
+
@data, @rows, @cols, other.data, other.rows, other.cols ) )
|
183
|
+
end
|
184
|
+
when Type::F64
|
185
|
+
if scalar_mul
|
186
|
+
result.data.replace( VectorSSE::vec_mul_f64( self.data, other.data ) )
|
187
|
+
else
|
188
|
+
result.data.replace( VectorSSE::mul_f64(
|
189
|
+
@data, @rows, @cols, other.data, other.rows, other.cols ) )
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
result
|
194
|
+
end
|
195
|
+
|
196
|
+
def +( other )
|
197
|
+
|
198
|
+
if [ Fixnum, Float ].include? other.class
|
199
|
+
|
200
|
+
scalar_value = other
|
201
|
+
other = Mat.new( @type, @rows, @cols )
|
202
|
+
other.data.replace( ::Array.new( @linear_size, scalar_value ) )
|
203
|
+
|
204
|
+
elsif other.class == self.class
|
205
|
+
|
206
|
+
if ( @rows != other.rows ) || ( @cols != other.cols )
|
207
|
+
raise ArgumentError.new(
|
208
|
+
"matrix addition requires operands of equal size")
|
209
|
+
end
|
210
|
+
|
211
|
+
else
|
212
|
+
|
213
|
+
raise ArgumentError.new(
|
214
|
+
"expect argument of type #{self.class}, Fixnum, or Float for argument 0" )
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
result = Mat.new( @type, @rows, @cols )
|
219
|
+
|
220
|
+
case @type
|
221
|
+
when Type::S32
|
222
|
+
result.data.replace( VectorSSE::add_s32( self.data, other.data ) )
|
223
|
+
when Type::S64
|
224
|
+
result.data.replace( VectorSSE::add_s64( self.data, other.data ) )
|
225
|
+
when Type::F32
|
226
|
+
result.data.replace( VectorSSE::add_f32( self.data, other.data ) )
|
227
|
+
when Type::F64
|
228
|
+
result.data.replace( VectorSSE::add_f64( self.data, other.data ) )
|
229
|
+
end
|
230
|
+
|
231
|
+
result
|
232
|
+
end
|
233
|
+
|
234
|
+
def -( other )
|
235
|
+
|
236
|
+
if [ Fixnum, Float ].include? other.class
|
237
|
+
|
238
|
+
scalar_value = other
|
239
|
+
other = Mat.new( @type, @rows, @cols )
|
240
|
+
other.data = ::Array.new( @linear_size, scalar_value )
|
241
|
+
|
242
|
+
elsif other.class == self.class
|
243
|
+
|
244
|
+
if ( @rows != other.rows ) || ( @cols != other.cols )
|
245
|
+
raise ArgumentError.new(
|
246
|
+
"matrix subtraction requires operands of equal size")
|
247
|
+
end
|
248
|
+
|
249
|
+
else
|
250
|
+
|
251
|
+
raise ArgumentError.new(
|
252
|
+
"expect argument of type #{self.class}, Fixnum, or Float for argument 0" )
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
result = Mat.new( @type, @rows, @cols )
|
257
|
+
|
258
|
+
case @type
|
259
|
+
when Type::S32
|
260
|
+
result.data.replace( VectorSSE::sub_s32( self.data, other.data ) )
|
261
|
+
when Type::S64
|
262
|
+
result.data.replace( VectorSSE::sub_s64( self.data, other.data ) )
|
263
|
+
when Type::F32
|
264
|
+
result.data.replace( VectorSSE::sub_f32( self.data, other.data ) )
|
265
|
+
when Type::F64
|
266
|
+
result.data.replace( VectorSSE::sub_f64( self.data, other.data ) )
|
267
|
+
end
|
268
|
+
|
269
|
+
result
|
270
|
+
end
|
271
|
+
|
272
|
+
def transpose
|
273
|
+
raise "unimplemented"
|
274
|
+
end
|
275
|
+
|
276
|
+
def reshape( rows, cols )
|
277
|
+
raise "unimplemented"
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
protected
|
282
|
+
|
283
|
+
|
284
|
+
def linear_index( row, col )
|
285
|
+
|
286
|
+
row * @cols + col
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
def valid_linear_index( pos )
|
291
|
+
|
292
|
+
if ( pos < 0 ) || ( pos >= @linear_size )
|
293
|
+
raise IndexError.new( "index out of bounds" )
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
def valid_row_col( row, col )
|
299
|
+
|
300
|
+
if ( row < 0 ) || ( row >= @rows )
|
301
|
+
raise IndexError.new( "row index out of bounds" )
|
302
|
+
end
|
303
|
+
|
304
|
+
if ( col < 0 ) || ( col >= @cols )
|
305
|
+
raise IndexError.new( "column index out of bounds" )
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
def valid_data_type( value )
|
311
|
+
|
312
|
+
unless [ Fixnum, Float ].include? value.class
|
313
|
+
raise ArgumentError.new( "expected argument of type Fixnum or Float" )
|
314
|
+
end
|
315
|
+
|
316
|
+
end
|
317
|
+
|
318
|
+
attr_accessor :data
|
319
|
+
|
320
|
+
end
|
321
|
+
Matrix = Mat
|
322
|
+
|
323
|
+
|
324
|
+
class Array < Array
|
325
|
+
|
326
|
+
attr_reader :type
|
327
|
+
|
328
|
+
def initialize( type, size=0, val=nil )
|
329
|
+
super( size, val )
|
330
|
+
|
331
|
+
if VectorSSE::valid_type( type )
|
332
|
+
@type = type
|
333
|
+
else
|
334
|
+
raise "invalid SSE vector type"
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def <<( value )
|
339
|
+
unless [ Fixnum, Float ].include? value.class
|
340
|
+
raise ArgumentError.new(
|
341
|
+
"expected argument of type Fixnum or Float for argument 0" )
|
342
|
+
end
|
343
|
+
super( value )
|
344
|
+
end
|
345
|
+
|
346
|
+
def insert( index, *values )
|
347
|
+
values.each_with_index do |value,arg_index|
|
348
|
+
unless [ Fixnum, Float ].include? value.class
|
349
|
+
raise ArgumentError.new(
|
350
|
+
"expected argument of type Fixnum or Float for argument #{arg_index}" )
|
351
|
+
end
|
352
|
+
end
|
353
|
+
super( index, values )
|
354
|
+
end
|
355
|
+
|
356
|
+
def []=( index, value )
|
357
|
+
unless [ Fixnum, Float ].include? value.class
|
358
|
+
raise ArgumentError.new(
|
359
|
+
"expected argument of type Fixnum or Float for argument 1" )
|
360
|
+
end
|
361
|
+
super( index, value )
|
362
|
+
end
|
363
|
+
|
364
|
+
# Note:
|
365
|
+
# This method replaces the base class implementation of '+', which
|
366
|
+
# performs concatenation. To concatenate, see #concat.
|
367
|
+
#
|
368
|
+
def +( other )
|
369
|
+
|
370
|
+
if [ Fixnum, Float ].include? other.class
|
371
|
+
|
372
|
+
other = ::Array.new( self.length, other )
|
373
|
+
|
374
|
+
elsif other.class != self.class
|
375
|
+
|
376
|
+
raise ArgumentError.new(
|
377
|
+
"expect argument of type #{self.class}, Fixnum, or Float for argument 0" )
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
result = self.class.new( @type )
|
382
|
+
|
383
|
+
case @type
|
384
|
+
when Type::S32
|
385
|
+
result.replace( VectorSSE::add_s32( self, other ) )
|
386
|
+
when Type::S64
|
387
|
+
result.replace( VectorSSE::add_s64( self, other ) )
|
388
|
+
when Type::F32
|
389
|
+
result.replace( VectorSSE::add_f32( self, other ) )
|
390
|
+
when Type::F64
|
391
|
+
result.replace( VectorSSE::add_f64( self, other ) )
|
392
|
+
end
|
393
|
+
|
394
|
+
result
|
395
|
+
end
|
396
|
+
|
397
|
+
# Note:
|
398
|
+
# This method replaces the base class implementation of '-', which
|
399
|
+
# removes items that are found in 'other'.
|
400
|
+
#
|
401
|
+
def -( other )
|
402
|
+
|
403
|
+
if [ Fixnum, Float ].include? other.class
|
404
|
+
other = ::Array.new( self.length, other )
|
405
|
+
elsif other.class != self.class
|
406
|
+
raise ArgumentError.new(
|
407
|
+
"expected argument of type #{self.class}, Fixnum, or Float for argument 0" )
|
408
|
+
end
|
409
|
+
|
410
|
+
result = self.class.new( @type )
|
411
|
+
|
412
|
+
case @type
|
413
|
+
when Type::S32
|
414
|
+
result.replace( VectorSSE::sub_s32( self, other ) )
|
415
|
+
when Type::S64
|
416
|
+
result.replace( VectorSSE::sub_s64( self, other ) )
|
417
|
+
when Type::F32
|
418
|
+
result.replace( VectorSSE::sub_f32( self, other ) )
|
419
|
+
when Type::F64
|
420
|
+
result.replace( VectorSSE::sub_f64( self, other ) )
|
421
|
+
end
|
422
|
+
|
423
|
+
result
|
424
|
+
end
|
425
|
+
|
426
|
+
def sum
|
427
|
+
sum_result = 0
|
428
|
+
|
429
|
+
case @type
|
430
|
+
when Type::S32
|
431
|
+
sum_result = VectorSSE::sum_s32( self )
|
432
|
+
when Type::S64
|
433
|
+
sum_result = VectorSSE::sum_s64( self )
|
434
|
+
when Type::F32
|
435
|
+
sum_result = VectorSSE::sum_f32( self )
|
436
|
+
when Type::F64
|
437
|
+
sum_result = VectorSSE::sum_f64( self )
|
438
|
+
else
|
439
|
+
raise "invalid SSE vector type"
|
440
|
+
end
|
441
|
+
|
442
|
+
sum_result
|
443
|
+
end
|
444
|
+
|
445
|
+
def *( other )
|
446
|
+
|
447
|
+
unless [ Fixnum, Float ].include? other.class
|
448
|
+
|
449
|
+
raise ArgumentError.new( "expected argument of type Float or Fixnum for argument 0" )
|
450
|
+
|
451
|
+
end
|
452
|
+
|
453
|
+
other = self.class.new( @type, self.length, other )
|
454
|
+
result = self.class.new( @type )
|
455
|
+
|
456
|
+
case @type
|
457
|
+
when Type::S32
|
458
|
+
result.replace( VectorSSE::vec_mul_s32( self, other ) )
|
459
|
+
when Type::S64
|
460
|
+
result.replace( VectorSSE::vec_mul_s64( self, other ) )
|
461
|
+
when Type::F32
|
462
|
+
result.replace( VectorSSE::vec_mul_f32( self, other ) )
|
463
|
+
when Type::F64
|
464
|
+
result.replace( VectorSSE::vec_mul_f64( self, other ) )
|
465
|
+
end
|
466
|
+
|
467
|
+
result
|
468
|
+
end
|
469
|
+
|
470
|
+
end
|
471
|
+
Arr = Array
|
472
|
+
|
473
|
+
|
474
|
+
end # module VectorSSE
|
475
|
+
|