simd 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2917ec7ede39c14aaac0a85f4e0c6cd6cf204cd
4
- data.tar.gz: 8bf4b61b6337ba5e5d833797dcffec0e2de32480
3
+ metadata.gz: c15d248c872e4369c45e4151faf81e9761ea1587
4
+ data.tar.gz: cdfc5170454be15be1bc75ccc5eba08aa96c884d
5
5
  SHA512:
6
- metadata.gz: e7ffa5a5ca85d1affc0326871517ba1dfde05d46544c0c8d803edf307d10ffe87dfdd8f78bbfd74b672f488d266037718dfd0c7d59b96967cb69ab3d8943b64e
7
- data.tar.gz: 69a5db3a4baf9fa3b68ff13a7d418337b20a237b150253d2cfd09421b8f63f2a11a50f51cd86d5412ab5a71bc46841143132cbe6af74f31d618408b9b1040d03
6
+ metadata.gz: 38df7b30a113b325bba7be834fcbe24c44738706495579af5a9e4b508e4db4375e2f36b16a97612eab4dd8da379c450d062c6e0bceb6e8ddf308a952ecf6419c
7
+ data.tar.gz: 342680d7f4f6690c8b3338de32ef192aaadb2952461e62e86a848650414b09d793d71e70c5b38909e0c882f062e346995f86f40d3dbf1de692cbe3eb0cfb0c73
@@ -7,4 +7,5 @@ void Init_simd()
7
7
  Init_SIMD_FloatArray(SIMD);
8
8
  Init_SIMD_SmallFloatArray(SIMD);
9
9
  Init_SIMD_IntArray(SIMD);
10
+ Init_SIMD_LongArray(SIMD);
10
11
  }
@@ -4,3 +4,4 @@ void Init_simd();
4
4
  void Init_SIMD_FloatArray(VALUE parent);
5
5
  void Init_SIMD_SmallFloatArray(VALUE parent);
6
6
  void Init_SIMD_IntArray(VALUE parent);
7
+ void Init_SIMD_LongArray(VALUE parent);
@@ -12,6 +12,9 @@ void Init_SIMD_IntArray(VALUE parent)
12
12
  rb_define_method(SIMD_IntArray, "/", method_divide, 1);
13
13
  rb_define_method(SIMD_IntArray, "+", method_add, 1);
14
14
  rb_define_method(SIMD_IntArray, "-", method_subtract, 1);
15
+ rb_define_method(SIMD_IntArray, "&", method_and, 1);
16
+ rb_define_method(SIMD_IntArray, "|", method_or, 1);
17
+ rb_define_method(SIMD_IntArray, "^", method_xor, 1);
15
18
  rb_define_method(SIMD_IntArray, "length", method_length, 0);
16
19
  rb_define_method(SIMD_IntArray, "to_a", method_to_a, 0);
17
20
  }
@@ -73,6 +76,27 @@ static VALUE method_add(VALUE self, VALUE obj)
73
76
  return(internal_apply_operation(self, obj, func_add));
74
77
  }
75
78
 
79
+ /* Public: and values contained in the data array with those contained in
80
+ * another FloatArray object, returning a new FloatArray. */
81
+ static VALUE method_and(VALUE self, VALUE obj)
82
+ {
83
+ return(internal_apply_operation(self, obj, func_and));
84
+ }
85
+
86
+ /* Public: or values contained in the data array with those contained in
87
+ * another FloatArray object, returning a new FloatArray. */
88
+ static VALUE method_or(VALUE self, VALUE obj)
89
+ {
90
+ return(internal_apply_operation(self, obj, func_or));
91
+ }
92
+
93
+ /* Public: xor values contained in the data array with those contained in
94
+ * another FloatArray object, returning a new FloatArray. */
95
+ static VALUE method_xor(VALUE self, VALUE obj)
96
+ {
97
+ return(internal_apply_operation(self, obj, func_xor));
98
+ }
99
+
76
100
  /* Public: Subtract values contained in another FloatArray object from those
77
101
  * contained in the current data array object, returning a new FloatArray. */
78
102
  static VALUE method_subtract(VALUE self, VALUE obj)
@@ -179,3 +203,21 @@ static void func_subtract(void *v1, void *v2, void *r)
179
203
  {
180
204
  *(i4v *)r = *(i4v *)v1 - *(i4v *)v2;
181
205
  }
206
+
207
+ /* Function: Perform a binary AND on two vectors. */
208
+ static void func_and(void *v1, void *v2, void *r)
209
+ {
210
+ *(i4v *)r = *(i4v *)v1 & *(i4v *)v2;
211
+ }
212
+
213
+ /* Function: Perform a binary OR on two vectors. */
214
+ static void func_or(void *v1, void *v2, void *r)
215
+ {
216
+ *(i4v *)r = *(i4v *)v1 | *(i4v *)v2;
217
+ }
218
+
219
+ /* Function: Perform a binary XOR on two vectors. */
220
+ static void func_xor(void *v1, void *v2, void *r)
221
+ {
222
+ *(i4v *)r = *(i4v *)v1 ^ *(i4v *)v2;
223
+ }
@@ -5,6 +5,9 @@ static VALUE method_initialize(VALUE self, VALUE rb_array);
5
5
  static VALUE method_multiply(VALUE self, VALUE obj);
6
6
  static VALUE method_divide(VALUE self, VALUE obj);
7
7
  static VALUE method_add(VALUE self, VALUE obj);
8
+ static VALUE method_and(VALUE self, VALUE obj);
9
+ static VALUE method_or(VALUE self, VALUE obj);
10
+ static VALUE method_xor(VALUE self, VALUE obj);
8
11
  static VALUE method_subtract(VALUE self, VALUE obj);
9
12
  static VALUE method_to_a(VALUE self);
10
13
 
@@ -14,3 +17,6 @@ static void func_multiply(void *v1, void *v2, void *r);
14
17
  static void func_divide(void *v1, void *v2, void *r);
15
18
  static void func_add(void *v1, void *v2, void *r);
16
19
  static void func_subtract(void *v1, void *v2, void *r);
20
+ static void func_and(void *v1, void *v2, void *r);
21
+ static void func_or(void *v1, void *v2, void *r);
22
+ static void func_xor(void *v1, void *v2, void *r);
@@ -0,0 +1,220 @@
1
+ #include "simd_longarray.h"
2
+
3
+ VALUE SIMD_LongArray = Qnil;
4
+
5
+ /* Internal: Create the SIMD::FloatArray class. */
6
+ void Init_SIMD_LongArray(VALUE parent)
7
+ {
8
+ SIMD_LongArray = rb_define_class_under(parent, "LongArray", rb_cObject);
9
+ rb_define_alloc_func(SIMD_LongArray, allocate);
10
+ rb_define_method(SIMD_LongArray, "initialize", method_initialize, 1);
11
+ rb_define_method(SIMD_LongArray, "*", method_multiply, 1);
12
+ rb_define_method(SIMD_LongArray, "/", method_divide, 1);
13
+ rb_define_method(SIMD_LongArray, "+", method_add, 1);
14
+ rb_define_method(SIMD_LongArray, "-", method_subtract, 1);
15
+ rb_define_method(SIMD_LongArray, "&", method_and, 1);
16
+ rb_define_method(SIMD_LongArray, "|", method_or, 1);
17
+ rb_define_method(SIMD_LongArray, "^", method_xor, 1);
18
+ rb_define_method(SIMD_LongArray, "length", method_length, 0);
19
+ rb_define_method(SIMD_LongArray, "to_a", method_to_a, 0);
20
+ }
21
+
22
+ /* Public: Initialize the FloatArray object given a Ruby Array of values
23
+ * which can be cast to a double. */
24
+ static VALUE method_initialize(VALUE self, VALUE rb_array)
25
+ {
26
+ vector_t *vector;
27
+ l2v_t *data;
28
+ unsigned long n,m,i;
29
+
30
+ Check_Type(rb_array, T_ARRAY);
31
+ Data_Get_Struct(self, vector_t, vector);
32
+
33
+ vector->len = n = RARRAY_LEN(rb_array);
34
+
35
+ if(vector->len < 2)
36
+ {
37
+ rb_raise(rb_eArgError, "Vectors must be at least 2 long");
38
+ }
39
+
40
+ vector->data = internal_allocate_vector_array(vector->len, sizeof(l2v_t));
41
+
42
+ data = (l2v_t *)vector->data;
43
+ for(i = 0; i < vector->len; i++)
44
+ {
45
+ data[i/2].f[i%2] = NUM2LONG(rb_ary_entry(rb_array, i));
46
+ }
47
+
48
+ /* If the array is an odd number of elements, set the final element to 1 */
49
+ m = n + (n % 2);
50
+ for(i = n % 2; i > 0; i--)
51
+ {
52
+ data[m/2].f[i] = 1;
53
+ }
54
+
55
+ return(self);
56
+ }
57
+
58
+ /* Public: Multiply values contained in the data array with those contained in
59
+ * another FloatArray object, returning a new FloatArray. */
60
+ static VALUE method_multiply(VALUE self, VALUE obj)
61
+ {
62
+ return(internal_apply_operation(self, obj, func_multiply));
63
+ }
64
+
65
+ /* Public: Divide values contained in the data array by those contained in
66
+ * another FloatArray object, returning a new FloatArray. */
67
+ static VALUE method_divide(VALUE self, VALUE obj)
68
+ {
69
+ return(internal_apply_operation(self, obj, func_divide));
70
+ }
71
+
72
+ /* Public: add values contained in the data array with those contained in
73
+ * another FloatArray object, returning a new FloatArray. */
74
+ static VALUE method_add(VALUE self, VALUE obj)
75
+ {
76
+ return(internal_apply_operation(self, obj, func_add));
77
+ }
78
+
79
+ /* Public: and values contained in the data array with those contained in
80
+ * another FloatArray object, returning a new FloatArray. */
81
+ static VALUE method_and(VALUE self, VALUE obj)
82
+ {
83
+ return(internal_apply_operation(self, obj, func_and));
84
+ }
85
+
86
+ /* Public: or values contained in the data array with those contained in
87
+ * another FloatArray object, returning a new FloatArray. */
88
+ static VALUE method_or(VALUE self, VALUE obj)
89
+ {
90
+ return(internal_apply_operation(self, obj, func_or));
91
+ }
92
+
93
+ /* Public: xor values contained in the data array with those contained in
94
+ * another FloatArray object, returning a new FloatArray. */
95
+ static VALUE method_xor(VALUE self, VALUE obj)
96
+ {
97
+ return(internal_apply_operation(self, obj, func_xor));
98
+ }
99
+
100
+ /* Public: Subtract values contained in another FloatArray object from those
101
+ * contained in the current data array object, returning a new FloatArray. */
102
+ static VALUE method_subtract(VALUE self, VALUE obj)
103
+ {
104
+ return(internal_apply_operation(self, obj, func_subtract));
105
+ }
106
+
107
+ /* Public: Return a Ruby Array containing the doubles within the data array. */
108
+ static VALUE method_to_a(VALUE self)
109
+ {
110
+ unsigned long i;
111
+ vector_t *vector;
112
+ l2v_t *data;
113
+ VALUE rb_array = rb_ary_new();
114
+
115
+ Data_Get_Struct(self, vector_t, vector);
116
+ data = (l2v_t *)vector->data;
117
+ for(i = 0; i < vector->len; i++)
118
+ {
119
+ rb_ary_store(rb_array, i, LONG2NUM(data[i/2].f[i%2]));
120
+ }
121
+
122
+ return(rb_array);
123
+ }
124
+
125
+ /* Internal: Given another FloatArray object, perform an action specified via a
126
+ * function pointer against both. */
127
+ static VALUE internal_apply_operation(VALUE self, VALUE obj, b_operation func)
128
+ {
129
+ unsigned long size, i;
130
+ int align;
131
+ vector_t *v1, *v2, *rv;
132
+ l2v_t *d1, *d2, *r;
133
+ VALUE result_obj = allocate(SIMD_LongArray);
134
+
135
+ Data_Get_Struct(self, vector_t, v1);
136
+ Data_Get_Struct(obj, vector_t, v2);
137
+ Data_Get_Struct(result_obj, vector_t, rv);
138
+ rv->data = internal_allocate_vector_array(v1->len, sizeof(l2v_t));
139
+
140
+ align = internal_align_vectors(v1->len, v2->len, 2);
141
+
142
+ /* Ensure that size will be the result of ceil(len / 4.0) */
143
+ size = (v1->len + 1) / 2;
144
+
145
+ d1 = (l2v_t *)v1->data;
146
+ d2 = (l2v_t *)v2->data;
147
+ r = (l2v_t *)rv->data;
148
+
149
+ rv->len = v1->len;
150
+
151
+ switch(align)
152
+ {
153
+ case 0: /* Same size arrays */
154
+ for(i = 0; i < size; i++)
155
+ {
156
+ func(&d1[i].v, &d2[i].v, &r[i].v);
157
+ }
158
+ break;
159
+ case 1: /* Operand is exactly 4 long (size of 1 sse register) */
160
+ for(i = 0; i < size; i++)
161
+ {
162
+ func(&d1[i].v, &d2[0].v, &r[i].v);
163
+ }
164
+ break;
165
+ default: /* Self is a multiple of operand's length long */
166
+ for(i = 0; i < size; i++)
167
+ {
168
+ func(&d1[i].v, &d2[i % v2->len].v, &r[i].v);
169
+ }
170
+ }
171
+
172
+ if(rv->len != rv->len + (rv->len % 2))
173
+ {
174
+ r[size].f[1] = 1;
175
+ }
176
+
177
+ return(result_obj);
178
+ }
179
+
180
+ /* Function: Multiply two vectors. */
181
+ static void func_multiply(void *v1, void *v2, void *r)
182
+ {
183
+ *(l2v *)r = *(l2v *)v1 * *(l2v *)v2;
184
+ }
185
+
186
+ /* Function: Divide two vectors. */
187
+ static void func_divide(void *v1, void *v2, void *r)
188
+ {
189
+ *(l2v *)r = *(l2v *)v1 / *(l2v *)v2;
190
+ }
191
+
192
+ /* Function: Add two vectors. */
193
+ static void func_add(void *v1, void *v2, void *r)
194
+ {
195
+ *(l2v *)r = *(l2v *)v1 + *(l2v *)v2;
196
+ }
197
+
198
+ /* Function: Subtract two vectors. */
199
+ static void func_subtract(void *v1, void *v2, void *r)
200
+ {
201
+ *(l2v *)r = *(l2v *)v1 - *(l2v *)v2;
202
+ }
203
+
204
+ /* Function: Perform a binary AND on two vectors. */
205
+ static void func_and(void *v1, void *v2, void *r)
206
+ {
207
+ *(l2v *)r = *(l2v *)v1 & *(l2v *)v2;
208
+ }
209
+
210
+ /* Function: Perform a binary OR on two vectors. */
211
+ static void func_or(void *v1, void *v2, void *r)
212
+ {
213
+ *(l2v *)r = *(l2v *)v1 | *(l2v *)v2;
214
+ }
215
+
216
+ /* Function: Perform a binary XOR on two vectors. */
217
+ static void func_xor(void *v1, void *v2, void *r)
218
+ {
219
+ *(l2v *)r = *(l2v *)v1 ^ *(l2v *)v2;
220
+ }
@@ -0,0 +1,22 @@
1
+ #include "ruby.h"
2
+ #include "simd_common.h"
3
+
4
+ static VALUE method_initialize(VALUE self, VALUE rb_array);
5
+ static VALUE method_multiply(VALUE self, VALUE obj);
6
+ static VALUE method_divide(VALUE self, VALUE obj);
7
+ static VALUE method_add(VALUE self, VALUE obj);
8
+ static VALUE method_and(VALUE self, VALUE obj);
9
+ static VALUE method_or(VALUE self, VALUE obj);
10
+ static VALUE method_xor(VALUE self, VALUE obj);
11
+ static VALUE method_subtract(VALUE self, VALUE obj);
12
+ static VALUE method_to_a(VALUE self);
13
+
14
+ static VALUE internal_apply_operation(VALUE self, VALUE obj, b_operation func);
15
+
16
+ static void func_multiply(void *v1, void *v2, void *r);
17
+ static void func_divide(void *v1, void *v2, void *r);
18
+ static void func_add(void *v1, void *v2, void *r);
19
+ static void func_subtract(void *v1, void *v2, void *r);
20
+ static void func_and(void *v1, void *v2, void *r);
21
+ static void func_or(void *v1, void *v2, void *r);
22
+ static void func_xor(void *v1, void *v2, void *r);
@@ -1,18 +1,5 @@
1
1
  #pragma once
2
2
 
3
- /*
4
- * Types for FloatArray
5
- *
6
- * Since ruby internally uses doubles for the Float type, SIMD::FloatArray will
7
- * use packed double operations by default.
8
- */
9
- typedef double __attribute__ ((vector_size (16))) d2v;
10
- typedef union d2v_t
11
- {
12
- d2v v;
13
- double f[2];
14
- } d2v_t;
15
-
16
3
  /*
17
4
  * Types for SmallFloatArray
18
5
  *
@@ -27,6 +14,19 @@ typedef union f4v_t
27
14
  float f[4];
28
15
  } f4v_t;
29
16
 
17
+ /*
18
+ * Types for FloatArray
19
+ *
20
+ * Since ruby internally uses doubles for the Float type, SIMD::FloatArray will
21
+ * use packed double operations by default.
22
+ */
23
+ typedef double __attribute__ ((vector_size (16))) d2v;
24
+ typedef union d2v_t
25
+ {
26
+ d2v v;
27
+ double f[2];
28
+ } d2v_t;
29
+
30
30
  /*
31
31
  * Types for IntArray
32
32
  */
@@ -37,6 +37,16 @@ typedef union i4v_t
37
37
  int f[4];
38
38
  } i4v_t;
39
39
 
40
+ /*
41
+ * Types for LongArray
42
+ */
43
+ typedef long int __attribute__ ((vector_size (16))) l2v;
44
+ typedef union l2v_t
45
+ {
46
+ l2v v;
47
+ long int f[2];
48
+ } l2v_t;
49
+
40
50
  typedef struct vector_t
41
51
  {
42
52
  void *data;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tina Wuest
@@ -40,6 +40,8 @@ files:
40
40
  - ext/simd/simd_floatarray.h
41
41
  - ext/simd/simd_intarray.c
42
42
  - ext/simd/simd_intarray.h
43
+ - ext/simd/simd_longarray.c
44
+ - ext/simd/simd_longarray.h
43
45
  - ext/simd/simd_smallfloatarray.c
44
46
  - ext/simd/simd_smallfloatarray.h
45
47
  - ext/simd/simd_types.h