simd 0.3.0 → 0.4.0

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 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