ryeppp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.so
4
+ *.swp
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ ext/ryeppp/ryeppp.c
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ryeppp.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Ryeppp
2
+
3
+ This gem provides bindings to the [Yeppp!](http://www.yeppp.info/) library.
4
+ According to the documentation, "Yeppp! is a high-performance SIMD-optimized
5
+ mathematical library for x86, ARM, and MIPS processors on Windows, Android, Mac
6
+ OS X, and GNU/Linux systems."
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'ryeppp'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install ryeppp
21
+
22
+ You'll also need to [download](http://www.yeppp.info/downloads.html) the Yeppp!
23
+ library and unpack it in $HOME.
24
+
25
+ ## Usage
26
+
27
+ The Ryeppp gem provides a single class `Ryeppp` with the following methods:
28
+
29
+ * `add_v64fv64f_v64f` - pairwise add 2 vectors of floats
30
+ * `add_v64sv64s_v64s` - pairwise add 2 vectors of integers
31
+
32
+ * `subtract_v64fv64f_v64f` - pairwise subtract 2 vectors of floats
33
+ * `subtract_v64sv64s_v64s` - pairwise subtract 2 vectors of integers
34
+
35
+ * `multiply_v64fs64f_v64f` - multiply a vector of floats by a float
36
+ * `multiply_v64sv64s_v64s` - multiply a vector of integers by an integer
37
+ * `multiply_v64fv64f_v64f` - pairwise multiply 2 vectors of floats
38
+ * `multiply_v64ss64s_v64s` - pairwise multiply 2 vectors of integers
39
+
40
+ * `dotproduct_v64fv64f_s64f` - compute the dot product of 2 vectors of floats
41
+
42
+ * `min_v64f_s64f` - find the minimum in a vector of floats
43
+ * `min_v64s_s64s` - find the minimum in a vector of integers
44
+
45
+ * `max_v64f_s64f` - find the maximum in a vector of floats
46
+ * `max_v64s_s64s` - find the maximum in a vector of integers
47
+
48
+ * `min_v64fv64f_v64f` - find the pairwise minimum in 2 vectors of floats
49
+
50
+ * `max_v64fv64f_v64f` - find the pairwise maximum in 2 vectors of floats
51
+
52
+ * `min_v64fs64f_v64f` - find the pairwise minimum of a vector of floats and a
53
+ constant
54
+
55
+ * `max_v64fs64f_v64f` - find the pairwise maximum of a vector of floats and a
56
+ constant
57
+
58
+ * `negate_v64f_s64f` - negate a vector of floats
59
+ * `negate_v64s_s64s` - negate a vector of integers
60
+
61
+ * `sum_v64f_s64f` - compute the sum of a vector of floats
62
+ * `sumabs_v64f_s64f` - compute the sum of the absolute values of a vector of
63
+ floats
64
+ * `sumsquares_v64f_s64f` - compute the sum of the squares of the values of a
65
+ vector of floats
66
+
67
+ * `log_v64f_v64f` - compute the natural logarithm of the values of a vector of
68
+ floats
69
+ * `exp_v64f_v64f` - compute the base-_e_ exponent of the values of a vector of
70
+ floats
71
+ * `sin_v64f_v64f` - compute the sine of the values of a vector of floats
72
+ * `cos_v64f_v64f` - compute the cosine of the values of a vector of floats
73
+ * `tan_v64f_v64f` - compute the tangent of the values of a vector of floats
74
+
75
+ * `evaluatepolynomial_v64fv64f_v64f` - evaluate the polynomial with the given
76
+ float coefficients in standard form at the given _x_-values
77
+
78
+ ## TODO
79
+
80
+ Add benchmarks.
81
+
82
+ ## Contributing
83
+
84
+ 1. Fork it
85
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
86
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
87
+ 4. Push to the branch (`git push origin my-new-feature`)
88
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
3
+ require "rspec/core/rake_task"
4
+
5
+ spec = Gem::Specification.load('ryeppp.gemspec')
6
+ Rake::ExtensionTask.new('ryeppp', spec)
7
+
8
+ desc "Ryeppp unit tests"
9
+ RSpec::Core::RakeTask.new(:spec) do |t|
10
+ t.pattern = "spec/*_spec.rb"
11
+ t.verbose = true
12
+ end
13
+
14
+ desc "Ryeppp c generation"
15
+ task :c_generation do
16
+ current_dir = __FILE__.split(/\//)[0..-2].join('/')
17
+ require File.join(current_dir, 'ext/templates/ryeppp.c.rb')
18
+ c_code = [
19
+ HEADERS,
20
+ PRIMARY,
21
+ FUNCS.call('Add'),
22
+ FUNCS.call('Subtract'),
23
+ FUNCS.call('Multiply'),
24
+ DOT_PRODUCT,
25
+ MIN_MAX,
26
+ PAIRWISE_MIN_MAX,
27
+ CONSTANT_MIN_MAX,
28
+ NEGATE,
29
+ SUMS,
30
+ MATHS,
31
+ POLYNOMIAL,
32
+ INITIALIZER
33
+ ].join("\n\n")
34
+ File.open(File.join(current_dir, 'ext/ryeppp/ryeppp.c'), 'w') do |f|
35
+ f.write(c_code)
36
+ end
37
+ end
38
+
39
+ task :default => [:c_generation, :compile, :spec]
@@ -0,0 +1,23 @@
1
+ require 'mkmf'
2
+
3
+ home_dir = `echo $HOME`.strip
4
+ dirs = [
5
+ File.join(home_dir, 'yeppp-1.0.0/library/headers'),
6
+ File.join(home_dir, 'yeppp-1.0.0/binaries/linux/x86_64')
7
+ ]
8
+
9
+ dirs.each{|d| puts d}
10
+
11
+ extension_name = 'ryeppp'
12
+ dir_config(extension_name)
13
+ dir_config('yeppp-1.0.0',
14
+ # Include paths.
15
+ dirs,
16
+ # Library paths.
17
+ dirs
18
+ )
19
+ if have_library('yeppp')
20
+ create_makefile(extension_name)
21
+ else
22
+ puts 'No yeppp! support available.'
23
+ end
@@ -0,0 +1,496 @@
1
+ def allocate_yep64_typed_array_and_assert(var_names, len_var_name, opts={})
2
+ var_names = Array(var_names)
3
+ type = opts[:type] || '{{type}}'
4
+ assert = opts[:assert].nil? ? true : opts[:assert]
5
+ %{#{var_names.map{|vn| %{Yep64#{type} *yep_#{vn} = (Yep64#{type}*)calloc(#{len_var_name}, sizeof(Yep64#{type}));}}.join("\n")}
6
+ #{assert ? var_names.map{|vn| %{assert(yep_#{vn} != NULL);}}.join("\n") : nil}}
7
+ end
8
+
9
+ def deinitialize_yeppp
10
+ %{/* Deinitialize the Yeppp! library */
11
+ status = yepLibrary_Release();
12
+ assert(status == YepStatusOk);}
13
+ end
14
+
15
+ def initialize_yeppp
16
+ %{/* Initialize the Yeppp! library */
17
+ status = yepLibrary_Init();
18
+ assert(status == YepStatusOk);}
19
+ end
20
+
21
+ def load_ruby_array_from_yeppp_array(var_name, iteration_var_name, len_var_name, type)
22
+ %{/* Load the Ruby Array */
23
+ new_ary = rb_ary_new2(#{len_var_name});
24
+ for (#{iteration_var_name}=0; #{iteration_var_name}<#{len_var_name}; #{iteration_var_name}++) {
25
+ rb_ary_push(new_ary, #{type == 'f' ? 'DBL' : 'INT'}2NUM((#{type == 'f' ? 'double' : 'long'})yep_#{var_name}[#{iteration_var_name}]));
26
+ }}
27
+ end
28
+ def load_ruby_array_from_yeppp_array_parameterized(var_name, iteration_var_name, len_var_name)
29
+ %{/* Load the Ruby Array */
30
+ new_ary = rb_ary_new2(#{len_var_name});
31
+ for (#{iteration_var_name}=0; #{iteration_var_name}<#{len_var_name}; #{iteration_var_name}++) {
32
+ rb_ary_push(new_ary, {{ruby_type}}2NUM(({{c_type}})yep_#{var_name}[#{iteration_var_name}]));
33
+ }}
34
+ end
35
+ def load_ruby_array_into_yeppp_array(var_name, iteration_var_name, len_var_name, type, permitted_types)
36
+ pt = permitted_types.map do |t|
37
+ case t
38
+ when :float
39
+ "TYPE(#{var_name}_a[#{iteration_var_name}]) != T_FLOAT"
40
+ when :integer
41
+ "TYPE(#{var_name}_a[#{iteration_var_name}]) != T_FIXNUM"
42
+ else
43
+ raise "Invalid permitted_type: #{t}."
44
+ end
45
+ end.join(' && ')
46
+ %{/* Load #{var_name}_a into yep_#{var_name}. */
47
+ for (#{iteration_var_name}=0; #{iteration_var_name}<#{len_var_name}; #{iteration_var_name}++) {
48
+ if (#{pt}) {
49
+ rb_raise(rb_eTypeError, "input was not all #{permitted_types.map(&:to_s).join(' and ')}");
50
+ }
51
+ yep_#{var_name}[#{iteration_var_name}] = (Yep64#{type})NUM2#{type == 'f' ? 'DBL' : 'INT'}(#{var_name}_a[#{iteration_var_name}]);
52
+ }}
53
+ end
54
+ def load_ruby_array_into_yeppp_array_parameterized(var_name, iteration_var_name, len_var_name)
55
+ %{/* Load #{var_name}_a into yep_#{var_name}. */
56
+ for (#{iteration_var_name}=0; #{iteration_var_name}<#{len_var_name}; #{iteration_var_name}++) {
57
+ if (TYPE(#{var_name}_a[#{iteration_var_name}]) != {{ruby_klass}}) {
58
+ rb_raise(rb_eTypeError, "input was not all {{ruby_klass_human}}");
59
+ }
60
+ yep_#{var_name}[#{iteration_var_name}] = (Yep64{{type}})NUM2{{ruby_type}}(#{var_name}_a[#{iteration_var_name}]);
61
+ }}
62
+ end
63
+
64
+ def release_array_memory(var_names)
65
+ var_names = Array(var_names)
66
+ %{/* Release the memory allocated for array#{var_names.size == 1 ? nil : 's'} */
67
+ #{var_names.map{|vn| %{free(yep_#{vn});}}.join("\n")}}
68
+ end
69
+
70
+ def typed_variants(s, opts={})
71
+ [
72
+ ['s', 'long', 'INT', 'T_FIXNUM', 'integers'],
73
+ ['f', 'double', 'DBL', 'T_FLOAT', 'floats']
74
+ ].map do |(type, c_type, ruby_type, ruby_klass, ruby_klass_human)|
75
+ if !opts[:only_type] || opts[:only_type] == type
76
+ s.gsub(/{{type}}/, type)
77
+ .gsub(/{{c_type}}/, c_type)
78
+ .gsub(/{{ruby_type}}/, ruby_type)
79
+ .gsub(/{{ruby_klass}}/, ruby_klass)
80
+ .gsub(/{{ruby_klass_human}}/, ruby_klass_human)
81
+ else
82
+ ''
83
+ end
84
+ end.map(&:strip).join("\n\n")
85
+ end
86
+
87
+ HEADERS = %{
88
+ // Include the Ruby headers and goodies
89
+ #include "ruby.h"
90
+
91
+ #include "stdio.h"
92
+ #include "assert.h"
93
+
94
+ #include "yepCore.h"
95
+ #include "yepLibrary.h"
96
+ #include "yepMath.h"
97
+ }.strip.freeze
98
+
99
+ PRIMARY = %{
100
+ // Defining a space for information and references about the module to be stored
101
+ // internally
102
+ VALUE cRyeppp;
103
+ }.strip.freeze
104
+
105
+ # verb_name is in [Add, Subtract, Multiply]
106
+ FUNCS = Proc.new do |verb_name|
107
+ %{#{if verb_name == 'Multiply'
108
+ typed_variants(%{
109
+ static VALUE multiply_v64{{type}}s64{{type}}_v64{{type}}(VALUE self, VALUE x, VALUE multiply_by) {
110
+ enum YepStatus status;
111
+ long i;
112
+ VALUE new_ary;
113
+ VALUE *x_a = RARRAY_PTR(x);
114
+ long l = RARRAY_LEN(x);
115
+ Yep64{{type}} mult_by = (Yep64{{type}})NUM2DBL(multiply_by);
116
+
117
+ /* Allocate arrays of inputs and outputs */
118
+ #{allocate_yep64_typed_array_and_assert(%w{x y}, 'l')}
119
+
120
+ #{initialize_yeppp}
121
+
122
+ #{load_ruby_array_into_yeppp_array_parameterized('x', 'i', 'l')}
123
+
124
+ /* Perform the operation */
125
+ status = yepCore_Multiply_V64{{type}}S64{{type}}_V64{{type}}(yep_x, mult_by, yep_y, (YepSize)l);
126
+ assert(status == YepStatusOk);
127
+
128
+ #{load_ruby_array_from_yeppp_array_parameterized('y', 'i', 'l')}
129
+
130
+ #{deinitialize_yeppp}
131
+
132
+ #{release_array_memory(%w{x y})}
133
+
134
+ return new_ary;
135
+ }
136
+ }).strip.freeze
137
+ end
138
+ }
139
+
140
+ #{typed_variants(%{
141
+ // #{verb_name} Arrays of Fixnums.
142
+ static VALUE #{verb_name.downcase}_v64{{type}}v64{{type}}_v64{{type}}(VALUE self, VALUE x, VALUE y) {
143
+ enum YepStatus status;
144
+ VALUE new_ary;
145
+ long i;
146
+ VALUE *x_a = RARRAY_PTR(x);
147
+ VALUE *y_a = RARRAY_PTR(y);
148
+ long l = RARRAY_LEN(x);
149
+
150
+ /* Allocate arrays of inputs and outputs */
151
+ #{allocate_yep64_typed_array_and_assert(%w{x y z}, 'l')}
152
+
153
+ #{initialize_yeppp}
154
+
155
+ #{load_ruby_array_into_yeppp_array_parameterized('x', 'i', 'l')}
156
+ #{load_ruby_array_into_yeppp_array_parameterized('y', 'i', 'l')}
157
+
158
+ /* Perform the addition */
159
+ status = yepCore_#{verb_name}_V64{{type}}V64{{type}}_V64{{type}}(yep_x, yep_y, yep_z, (YepSize)l);
160
+ assert(status == YepStatusOk);
161
+
162
+ #{load_ruby_array_from_yeppp_array_parameterized('z', 'i', 'l')}
163
+
164
+ #{deinitialize_yeppp}
165
+
166
+ #{release_array_memory(%w{x y z})}
167
+
168
+ return new_ary;
169
+ }
170
+ })}
171
+ }
172
+ end
173
+
174
+ DOT_PRODUCT = %{
175
+ // Get the dot product of 2 Arrays.
176
+ static VALUE dotproduct_v64fv64f_s64f(VALUE self, VALUE x, VALUE y) {
177
+ enum YepStatus status;
178
+ long i;
179
+ Yep64f dp;
180
+ VALUE *x_a = RARRAY_PTR(x);
181
+ VALUE *y_a = RARRAY_PTR(y);
182
+ long l = RARRAY_LEN(x);
183
+
184
+ /* Allocate arrays of inputs and outputs */
185
+ #{allocate_yep64_typed_array_and_assert(%w{x y}, 'l', :type => 'f')}
186
+
187
+ #{initialize_yeppp}
188
+
189
+ #{load_ruby_array_into_yeppp_array('x', 'i', 'l', 'f', [:integer, :float])}
190
+ #{load_ruby_array_into_yeppp_array('y', 'i', 'l', 'f', [:integer, :float])}
191
+
192
+ /* Perform the operation */
193
+ status = yepCore_DotProduct_V64fV64f_S64f(yep_x, yep_y, &dp, (YepSize)l);
194
+ assert(status == YepStatusOk);
195
+
196
+ #{deinitialize_yeppp}
197
+
198
+ #{release_array_memory(%w{x y})}
199
+
200
+ return DBL2NUM((double)dp);
201
+ }
202
+ }.strip
203
+
204
+ MIN_MAX = typed_variants(%w{Min Max}.map do |kind|
205
+ %{
206
+ // Get the #{kind.downcase} value from an Array.
207
+ static VALUE #{kind.downcase}_v64{{type}}_s64{{type}}(VALUE self, VALUE x) {
208
+ enum YepStatus status;
209
+ long i;
210
+ Yep64{{type}} #{kind.downcase};
211
+ VALUE *x_a = RARRAY_PTR(x);
212
+ long l = RARRAY_LEN(x);
213
+
214
+ /* Allocate arrays of inputs and outputs */
215
+ #{allocate_yep64_typed_array_and_assert('x', 'l')}
216
+
217
+ #{initialize_yeppp}
218
+
219
+ #{load_ruby_array_into_yeppp_array_parameterized('x', 'i', 'l')}
220
+
221
+ /* Perform the operation */
222
+ status = yepCore_#{kind}_V64{{type}}_S64{{type}}(yep_x, &#{kind.downcase}, (YepSize)l);
223
+ assert(status == YepStatusOk);
224
+
225
+ #{deinitialize_yeppp}
226
+
227
+ #{release_array_memory(%w{x})}
228
+
229
+ return {{ruby_type}}2NUM(({{c_type}})#{kind.downcase});
230
+ }
231
+ }.strip
232
+ end.join("\n\n"))
233
+
234
+ PAIRWISE_MIN_MAX = typed_variants(%w{Min Max}.map do |kind|
235
+ %{
236
+ // Get the pairwise #{kind.downcase}ima from Arrays.
237
+ static VALUE #{kind.downcase}_v64{{type}}v64{{type}}_v64{{type}}(VALUE self, VALUE x, VALUE y) {
238
+ enum YepStatus status;
239
+ long i;
240
+ VALUE new_ary;
241
+ VALUE *x_a = RARRAY_PTR(x);
242
+ VALUE *y_a = RARRAY_PTR(y);
243
+ long l = RARRAY_LEN(x);
244
+
245
+ /* Allocate arrays of inputs and outputs */
246
+ #{allocate_yep64_typed_array_and_assert(%w{x y z}, 'l')}
247
+
248
+ #{initialize_yeppp}
249
+
250
+ #{load_ruby_array_into_yeppp_array_parameterized('x', 'i', 'l')}
251
+ #{load_ruby_array_into_yeppp_array_parameterized('y', 'i', 'l')}
252
+
253
+ /* Perform the operation */
254
+ status = yepCore_#{kind}_V64{{type}}V64{{type}}_V64{{type}}(yep_x, yep_y, yep_z, (YepSize)l);
255
+ assert(status == YepStatusOk);
256
+
257
+ #{load_ruby_array_from_yeppp_array_parameterized('z', 'i', 'l')}
258
+
259
+ #{deinitialize_yeppp}
260
+
261
+ #{release_array_memory(%w{x y z})}
262
+
263
+ return new_ary;
264
+ }
265
+ }.strip
266
+ end.join("\n\n"), :only_type => 'f')
267
+
268
+ CONSTANT_MIN_MAX = typed_variants(%w{Min Max}.map do |kind|
269
+ %{
270
+ // Get the #{kind.downcase}ima from an Array and a constant.
271
+ static VALUE #{kind.downcase}_v64{{type}}s64{{type}}_v64{{type}}(VALUE self, VALUE x, VALUE c) {
272
+ enum YepStatus status;
273
+ long i;
274
+ VALUE new_ary;
275
+ VALUE *x_a = RARRAY_PTR(x);
276
+ long l = RARRAY_LEN(x);
277
+ Yep64f konst = (Yep64f)NUM2{{ruby_type}}(c);
278
+
279
+ /* Allocate arrays of inputs and outputs */
280
+ #{allocate_yep64_typed_array_and_assert(%w{x y}, 'l')}
281
+
282
+ #{initialize_yeppp}
283
+
284
+ #{load_ruby_array_into_yeppp_array_parameterized('x', 'i', 'l')}
285
+
286
+ /* Perform the operation */
287
+ status = yepCore_#{kind}_V64{{type}}S64{{type}}_V64{{type}}(yep_x, konst, yep_y, (YepSize)l);
288
+ assert(status == YepStatusOk);
289
+
290
+ #{load_ruby_array_from_yeppp_array_parameterized('y', 'i', 'l')}
291
+
292
+ #{deinitialize_yeppp}
293
+
294
+ #{release_array_memory(%w{x y})}
295
+
296
+ return new_ary;
297
+ }
298
+ }.strip
299
+ end.join("\n\n"), :only_type => 'f')
300
+
301
+ NEGATE = typed_variants(%{
302
+ // Negate an Array.
303
+ static VALUE negate_v64{{type}}_s64{{type}}(VALUE self, VALUE x) {
304
+ enum YepStatus status;
305
+ long i;
306
+ VALUE new_ary;
307
+ VALUE *x_a = RARRAY_PTR(x);
308
+ long l = RARRAY_LEN(x);
309
+
310
+ /* Allocate arrays of inputs and outputs */
311
+ #{allocate_yep64_typed_array_and_assert(%w{x y}, 'l')}
312
+
313
+ #{initialize_yeppp}
314
+
315
+ #{load_ruby_array_into_yeppp_array_parameterized('x', 'i', 'l')}
316
+
317
+ /* Perform the negation */
318
+ status = yepCore_Negate_V64{{type}}_V64{{type}}(yep_x, yep_y, (YepSize)l);
319
+ assert(status == YepStatusOk);
320
+
321
+ #{load_ruby_array_from_yeppp_array_parameterized('y', 'i', 'l')}
322
+
323
+ #{deinitialize_yeppp}
324
+
325
+ #{release_array_memory(%w{x y})}
326
+
327
+ return new_ary;
328
+ }
329
+ }).freeze
330
+
331
+ SUMS = %w{Sum SumAbs SumSquares}.map do |kind|
332
+ %{
333
+ static VALUE #{kind.downcase}_v64f_s64f(VALUE self, VALUE x) {
334
+ enum YepStatus status;
335
+ long i;
336
+ Yep64f sum;
337
+ long l = RARRAY_LEN(x);
338
+ VALUE *x_a = RARRAY_PTR(x);
339
+
340
+ /* Allocate arrays of inputs and outputs */
341
+ #{allocate_yep64_typed_array_and_assert('x', 'l', :type => 'f')}
342
+
343
+ #{initialize_yeppp}
344
+
345
+ #{load_ruby_array_into_yeppp_array('x', 'i', 'l', 'f', [:integer, :float])}
346
+
347
+ /* Perform the operation */
348
+ status = yepCore_#{kind}_V64f_S64f(yep_x, &sum, (YepSize)l);
349
+ assert(status == YepStatusOk);
350
+
351
+ #{deinitialize_yeppp}
352
+
353
+ #{release_array_memory(%w{x})}
354
+
355
+ return DBL2NUM((double)sum);
356
+ }
357
+ }.strip
358
+ end.join("\n\n").freeze
359
+
360
+ MATHS_KINDS = %w{Log Exp Sin Cos Tan}.freeze
361
+ MATHS = MATHS_KINDS.map do |kind|
362
+ %{
363
+ static VALUE #{kind.downcase}_v64f_v64f(VALUE self, VALUE x) {
364
+ enum YepStatus status;
365
+ long i;
366
+ VALUE new_ary;
367
+ long l = RARRAY_LEN(x);
368
+ VALUE *x_a = RARRAY_PTR(x);
369
+
370
+ /* Allocate arrays of inputs and outputs */
371
+ #{allocate_yep64_typed_array_and_assert(%w{x y}, 'l', :type => 'f')}
372
+
373
+ #{initialize_yeppp}
374
+
375
+ #{load_ruby_array_into_yeppp_array('x', 'i', 'l', 'f', [:integer, :float])}
376
+
377
+ /* Perform the operation */
378
+ status = yepMath_#{kind}_V64f_V64f(yep_x, yep_y, (YepSize)l);
379
+ assert(status == YepStatusOk);
380
+
381
+ #{load_ruby_array_from_yeppp_array('y', 'i', 'l', 'f')}
382
+
383
+ #{deinitialize_yeppp}
384
+
385
+ #{release_array_memory(%w{x y})}
386
+
387
+ return new_ary;
388
+ }
389
+ }.strip
390
+ end.join("\n\n").freeze
391
+
392
+ POLYNOMIAL = %{
393
+ // x is the coefficients
394
+ // where is the set of points at which to evaluate x
395
+ static VALUE evaluatepolynomial_v64fv64f_v64f(VALUE self, VALUE x, VALUE where) {
396
+ enum YepStatus status;
397
+ long i;
398
+ VALUE new_ary;
399
+ long x_l = RARRAY_LEN(x);
400
+ long y_l = RARRAY_LEN(where);
401
+ VALUE *x_a = RARRAY_PTR(x);
402
+ VALUE *y_a = RARRAY_PTR(where);
403
+
404
+ /* Allocate arrays of inputs and outputs */
405
+ #{allocate_yep64_typed_array_and_assert(%w{x}, 'x_l', :assert => false, :type => 'f')}
406
+ #{allocate_yep64_typed_array_and_assert(%w{y z}, 'y_l', :assert => false, :type => 'f')}
407
+ assert(yep_x != NULL);
408
+ assert(yep_y != NULL);
409
+ assert(yep_z != NULL);
410
+
411
+ #{initialize_yeppp}
412
+
413
+ #{load_ruby_array_into_yeppp_array('x', 'i', 'x_l', 'f', [:integer, :float])}
414
+ #{load_ruby_array_into_yeppp_array('y', 'i', 'y_l', 'f', [:integer, :float])}
415
+
416
+ /* Perform the operation */
417
+ status = yepMath_EvaluatePolynomial_V64fV64f_V64f(yep_x, yep_y, yep_z, (YepSize)x_l, (YepSize)y_l);
418
+ assert(status == YepStatusOk);
419
+
420
+ #{load_ruby_array_from_yeppp_array('z', 'i', 'y_l', 'f')}
421
+
422
+ #{deinitialize_yeppp}
423
+
424
+ #{release_array_memory(%w{x y z})}
425
+
426
+ return new_ary;
427
+ }
428
+ }.strip.freeze
429
+
430
+ INITIALIZER = %{
431
+ // The initialization method for this module
432
+ void Init_ryeppp() {
433
+ cRyeppp = rb_define_class("Ryeppp", rb_cObject);
434
+
435
+ /* Addition */
436
+ rb_define_singleton_method(cRyeppp, "add_v64fv64f_v64f", add_v64fv64f_v64f, 2);
437
+ rb_define_singleton_method(cRyeppp, "add_v64sv64s_v64s", add_v64sv64s_v64s, 2);
438
+
439
+ /* Subtraction */
440
+ rb_define_singleton_method(cRyeppp, "subtract_v64fv64f_v64f", subtract_v64fv64f_v64f, 2);
441
+ rb_define_singleton_method(cRyeppp, "subtract_v64sv64s_v64s", subtract_v64sv64s_v64s, 2);
442
+
443
+ /* Multiplication */
444
+ rb_define_singleton_method(cRyeppp, "multiply_v64fs64f_v64f", multiply_v64fs64f_v64f, 2);
445
+ rb_define_singleton_method(cRyeppp, "multiply_v64sv64s_v64s", multiply_v64sv64s_v64s, 2);
446
+ rb_define_singleton_method(cRyeppp, "multiply_v64fv64f_v64f", multiply_v64fv64f_v64f, 2);
447
+ rb_define_singleton_method(cRyeppp, "multiply_v64ss64s_v64s", multiply_v64ss64s_v64s, 2);
448
+
449
+ /* Dot Product */
450
+ rb_define_singleton_method(cRyeppp, "dotproduct_v64fv64f_s64f", dotproduct_v64fv64f_s64f, 2);
451
+
452
+ /* Minimum */
453
+ rb_define_singleton_method(cRyeppp, "min_v64f_s64f", min_v64f_s64f, 1);
454
+ rb_define_singleton_method(cRyeppp, "min_v64s_s64s", min_v64s_s64s, 1);
455
+
456
+ /* Maximum */
457
+ rb_define_singleton_method(cRyeppp, "max_v64f_s64f", max_v64f_s64f, 1);
458
+ rb_define_singleton_method(cRyeppp, "max_v64s_s64s", max_v64s_s64s, 1);
459
+
460
+ /* Pairwise Minima */
461
+ rb_define_singleton_method(cRyeppp, "min_v64fv64f_v64f", min_v64fv64f_v64f, 2);
462
+ // Pairwise signed min is not available.
463
+
464
+ /* Pairwise Maxima */
465
+ rb_define_singleton_method(cRyeppp, "max_v64fv64f_v64f", max_v64fv64f_v64f, 2);
466
+ // Pairwise signed max is not available.
467
+
468
+ /* Constant Minima */
469
+ rb_define_singleton_method(cRyeppp, "min_v64fs64f_v64f", min_v64fs64f_v64f, 2);
470
+ // Constant signed min is not available.
471
+
472
+ /* Constant Maxima */
473
+ rb_define_singleton_method(cRyeppp, "max_v64fs64f_v64f", max_v64fs64f_v64f, 2);
474
+ // Constant signed max is not available.
475
+
476
+ /* Negation */
477
+ rb_define_singleton_method(cRyeppp, "negate_v64f_s64f", negate_v64f_s64f, 1);
478
+ rb_define_singleton_method(cRyeppp, "negate_v64s_s64s", negate_v64s_s64s, 1);
479
+
480
+ /* Sums */
481
+ rb_define_singleton_method(cRyeppp, "sum_v64f_s64f", sum_v64f_s64f, 1);
482
+ // Signed sum is not available.
483
+ rb_define_singleton_method(cRyeppp, "sumabs_v64f_s64f", sumabs_v64f_s64f, 1);
484
+ // Signed abs sum is not available.
485
+ rb_define_singleton_method(cRyeppp, "sumsquares_v64f_s64f", sumsquares_v64f_s64f, 1);
486
+ // Signed squares sum is not available.
487
+
488
+ /* Maths */
489
+ #{MATHS_KINDS.map do |kind|
490
+ %{rb_define_singleton_method(cRyeppp, "#{kind.downcase}_v64f_v64f", #{kind.downcase}_v64f_v64f, 1);}
491
+ end.join("\n")}
492
+
493
+ /* Polynomial */
494
+ rb_define_singleton_method(cRyeppp, "evaluatepolynomial_v64fv64f_v64f", evaluatepolynomial_v64fv64f_v64f, 2);
495
+ }
496
+ }.strip.freeze
data/lib/ryeppp.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "ryeppp/version"
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'ryeppp.so')
3
+
4
+ #module Carray
5
+ # # Your code goes here...
6
+ #end
@@ -0,0 +1,3 @@
1
+ class Ryeppp
2
+ VERSION = "0.0.1"
3
+ end
data/ryeppp.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ryeppp/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ryeppp"
8
+ spec.version = Ryeppp::VERSION
9
+ spec.authors = ["Brad Cater"]
10
+ spec.email = ["bradcater@gmail.com"]
11
+ spec.description = %q{This gem provides bindings to the Yeppp! library. According to the documentation, "Yeppp! is a high-performance SIMD-optimized mathematical library for x86, ARM, and MIPS processors on Windows, Android, Mac OS X, and GNU/Linux systems."}
12
+ spec.summary = %q{This gem provides bindings to the Yeppp! library.}
13
+ spec.homepage = "https://github.com/bradcater/ruby-yeppp"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.extensions << "ext/ryeppp/extconf.rb"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake-compiler"
25
+ spec.add_development_dependency "rake", ">= 1.9.1"
26
+ spec.add_development_dependency "rspec", ">= 2.13.0"
27
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ryeppp do
4
+ # Addition
5
+ it 'should add vectors of Fixnums' do
6
+ Ryeppp.add_v64sv64s_v64s([1], [2]).should eq([3])
7
+ expect{Ryeppp.add_v64sv64s_v64s([1, 'a'], [2, 'b'])}.to raise_error(TypeError)
8
+ end
9
+ it 'should add vectors of Floats' do
10
+ Ryeppp.add_v64fv64f_v64f([1.1], [1.1]).should eq([2.2])
11
+ expect{Ryeppp.add_v64fv64f_v64f([1.1, 'a'], [2.2, 'b'])}.to raise_error(TypeError)
12
+ end
13
+
14
+ # Subtraction
15
+ it 'should subtract vectors of Fixnums' do
16
+ Ryeppp.subtract_v64sv64s_v64s([1], [2]).should eq([-1])
17
+ expect{Ryeppp.subtract_v64sv64s_v64s([1, 'a'], [2, 'b'])}.to raise_error(TypeError)
18
+ end
19
+ it 'should subtract vectors of Floats' do
20
+ Ryeppp.subtract_v64fv64f_v64f([1.1], [1.1]).should eq([0])
21
+ expect{Ryeppp.subtract_v64fv64f_v64f([1.1, 'a'], [2.2, 'b'])}.to raise_error(TypeError)
22
+ end
23
+
24
+ # Multiplication
25
+ it 'should multiply a vector of Fixnums by a constant' do
26
+ Ryeppp.multiply_v64ss64s_v64s([1, 2, 3], 2).should eq([2, 4, 6])
27
+ expect{Ryeppp.multiply_v64ss64s_v64s([1, 'a'], 2)}.to raise_error(TypeError)
28
+ end
29
+ it 'should multiply a vector of Floats by a constant' do
30
+ Ryeppp.multiply_v64fs64f_v64f([1.0, 2.0, 3.0], 2.0).should eq([2.0, 4.0, 6.0])
31
+ expect{Ryeppp.multiply_v64fs64f_v64f([1, 'a'], 2)}.to raise_error(TypeError)
32
+ end
33
+ it 'should multiply vectors of Fixnums' do
34
+ Ryeppp.multiply_v64sv64s_v64s([2], [3]).should eq([6])
35
+ expect{Ryeppp.multiply_v64sv64s_v64s([1, 'a'], [2, 'b'])}.to raise_error(TypeError)
36
+ end
37
+ it 'should multiply vectors of Floats' do
38
+ Ryeppp.multiply_v64fv64f_v64f([2.5], [3.5]).should eq([8.75])
39
+ expect{Ryeppp.multiply_v64fv64f_v64f([1.1, 'a'], [2.2, 'b'])}.to raise_error(TypeError)
40
+ end
41
+
42
+ # Dot Product
43
+ it 'should do the dot product of vectors' do
44
+ Ryeppp.dotproduct_v64fv64f_s64f([1, 2, 3], [4, 5, 6]).should eq(32.0)
45
+ expect{Ryeppp.dotproduct_v64fv64f_s64f([1, 2, 'a'], [4, 5, 'b'])}.to raise_error(TypeError)
46
+ end
47
+
48
+ # Minimum
49
+ it 'should find the minimum in a vector of Fixnums' do
50
+ Ryeppp.min_v64s_s64s([3, 2, 1]).should eq(1)
51
+ expect{Ryeppp.min_v64s_s64s([1, 'a'])}.to raise_error(TypeError)
52
+ end
53
+ it 'should find the minimum in a vector of Floats' do
54
+ Ryeppp.min_v64f_s64f([1.0, 2.0, 3.0]).should eq(1.0)
55
+ expect{Ryeppp.min_v64f_s64f([1.0, 'a'])}.to raise_error(TypeError)
56
+ end
57
+
58
+ # Maximum
59
+ it 'should find the maximum in a vector of Fixnums' do
60
+ Ryeppp.max_v64s_s64s([3, 2, 1]).should eq(3)
61
+ expect{Ryeppp.max_v64s_s64s([1, 'a'])}.to raise_error(TypeError)
62
+ end
63
+ it 'should find the maximum in a vector of Floats' do
64
+ Ryeppp.max_v64f_s64f([1.0, 2.0, 3.0]).should eq(3.0)
65
+ expect{Ryeppp.max_v64f_s64f([1.0, 'a'])}.to raise_error(TypeError)
66
+ end
67
+
68
+ # Pairwise Minima
69
+ it 'should find the pairwise minima in vectors of Floats' do
70
+ Ryeppp.min_v64fv64f_v64f([1.0, 2.0, 3.0], [3.0, 2.0, 1.0]).should eq([1.0, 2.0, 1.0])
71
+ expect{Ryeppp.min_v64fv64f_v64f([1.0, 'a'], [2.0, 'b'])}.to raise_error(TypeError)
72
+ end
73
+ # Pairwise Maxima
74
+ it 'should find the pairwise maxima in vectors of Floats' do
75
+ Ryeppp.max_v64fv64f_v64f([1.0, 2.0, 3.0], [3.0, 2.0, 1.0]).should eq([3.0, 2.0, 3.0])
76
+ expect{Ryeppp.max_v64fv64f_v64f([1.0, 'a'], [2.0, 'b'])}.to raise_error(TypeError)
77
+ end
78
+
79
+ # Constant Minima
80
+ it 'should find the minima in a vector of Floats and a constant' do
81
+ Ryeppp.min_v64fs64f_v64f([1.0, 2.0, 3.0], 2.0).should eq([1.0, 2.0, 2.0])
82
+ expect{Ryeppp.min_v64fs64f_v64f([1.0, 'a'], 2.0)}.to raise_error(TypeError)
83
+ end
84
+ # Constant Maxima
85
+ it 'should find the maxima in a vector of Floats and a constant' do
86
+ Ryeppp.max_v64fs64f_v64f([1.0, 2.0, 3.0], 2.5).should eq([2.5, 2.5, 3.0])
87
+ expect{Ryeppp.max_v64fs64f_v64f([1.0, 'a'], 2.5)}.to raise_error(TypeError)
88
+ end
89
+
90
+ # Negation
91
+ it 'should negate vectors of Fixnums' do
92
+ Ryeppp.negate_v64s_s64s([1]).should eq([-1])
93
+ expect{Ryeppp.negate_v64s_s64s([1, 'a'])}.to raise_error(TypeError)
94
+ end
95
+ it 'should negate vectors of Floats' do
96
+ Ryeppp.negate_v64f_s64f([1.1]).should eq([-1.1])
97
+ expect{Ryeppp.negate_v64f_s64f([1.1, 'a'])}.to raise_error(TypeError)
98
+ end
99
+
100
+ # Sum
101
+ it 'should sum a vector' do
102
+ Ryeppp.sum_v64f_s64f([1, 2, 3]).should eq(6.0)
103
+ expect{Ryeppp.sum_v64f_s64f([1, 'a'])}.to raise_error(TypeError)
104
+ end
105
+ # Sum Absolute Values
106
+ it 'should sum absolute values of a vector' do
107
+ Ryeppp.sumabs_v64f_s64f([1.0, -1.0, 2.0]).should eq(4.0)
108
+ expect{Ryeppp.sumabs_v64f_s64f([1.0, -1.0, 'a'])}.to raise_error(TypeError)
109
+ end
110
+ # Sum Square Values
111
+ it 'should sum square values of a vector' do
112
+ Ryeppp.sumsquares_v64f_s64f([1.0, -1.0, 2.0]).should eq(6.0)
113
+ expect{Ryeppp.sumsquares_v64f_s64f([1.0, -1.0, 'a'])}.to raise_error(TypeError)
114
+ end
115
+
116
+ # Log
117
+ it 'should find the natural logarithm of elements of a vector' do
118
+ Ryeppp.log_v64f_v64f([1.0, 2.0, 3.0]).map{|o| o.round(5)}.should eq([0.0, 0.69315, 1.09861])
119
+ expect{Ryeppp.log_v64f_v64f([1.0, 'a'])}.to raise_error(TypeError)
120
+ end
121
+ # Exp
122
+ it 'should find the base e exponent of elements of a vector' do
123
+ Ryeppp.exp_v64f_v64f([1.0, 2.0, 3.0]).map{|o| o.round(5)}.should eq([2.71828, 7.38906, 20.08554])
124
+ expect{Ryeppp.exp_v64f_v64f([1.0, 'a'])}.to raise_error(TypeError)
125
+ end
126
+ # Sin
127
+ it 'should find the sine of elements of a vector' do
128
+ Ryeppp.sin_v64f_v64f([1.0, 2.0, 3.0]).map{|o| o.round(5)}.should eq([0.84147, 0.9093, 0.14112])
129
+ expect{Ryeppp.sin_v64f_v64f([1.0, 'a'])}.to raise_error(TypeError)
130
+ end
131
+ # Cos
132
+ it 'should find the cosine of elements of a vector' do
133
+ Ryeppp.cos_v64f_v64f([1.0, 2.0, 3.0]).map{|o| o.round(5)}.should eq([0.5403, -0.41615, -0.98999])
134
+ expect{Ryeppp.cos_v64f_v64f([1.0, 'a'])}.to raise_error(TypeError)
135
+ end
136
+ # Tan
137
+ it 'should find the tangent of elements of a vector' do
138
+ Ryeppp.tan_v64f_v64f([1.0, 2.0, 3.0]).map{|o| o.round(5)}.should eq([1.55741, -2.18504, -0.14255])
139
+ expect{Ryeppp.tan_v64f_v64f([1.0, 'a'])}.to raise_error(TypeError)
140
+ end
141
+
142
+ # Polynomial
143
+ it 'should evaluate a polynomial for a vector' do
144
+ # x^2 + x + 1
145
+ # evaluated at x=1.
146
+ Ryeppp.evaluatepolynomial_v64fv64f_v64f([1.0, 1.0, 1.0], [1.0]).should eq([3.0])
147
+ # -5x^3 - 4x^2 + 2x + 1
148
+ # evaluated at x=0, x=1, and x=2.
149
+ Ryeppp.evaluatepolynomial_v64fv64f_v64f([-5, -4, 2, 1], [0, 1, 2]).should eq([-5.0, -6.0, 3.0])
150
+ expect{Ryeppp.evaluatepolynomial_v64fv64f_v64f([1, 'a'], [0, 1])}.to raise_error(TypeError)
151
+ end
152
+ end
@@ -0,0 +1,7 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'ryeppp'
4
+
5
+ RSpec.configure do |config|
6
+ # some (optional) config here
7
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ryeppp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brad Cater
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ prerelease: false
23
+ type: :development
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake-compiler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ prerelease: false
39
+ type: :development
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 1.9.1
54
+ prerelease: false
55
+ type: :development
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.9.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 2.13.0
70
+ prerelease: false
71
+ type: :development
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 2.13.0
78
+ description: This gem provides bindings to the Yeppp! library. According to the documentation,
79
+ "Yeppp! is a high-performance SIMD-optimized mathematical library for x86, ARM,
80
+ and MIPS processors on Windows, Android, Mac OS X, and GNU/Linux systems."
81
+ email:
82
+ - bradcater@gmail.com
83
+ executables: []
84
+ extensions:
85
+ - ext/ryeppp/extconf.rb
86
+ extra_rdoc_files: []
87
+ files:
88
+ - .gitignore
89
+ - .rspec
90
+ - Gemfile
91
+ - LICENSE.txt
92
+ - README.md
93
+ - Rakefile
94
+ - ext/ryeppp/extconf.rb
95
+ - ext/templates/ryeppp.c.rb
96
+ - lib/ryeppp.rb
97
+ - lib/ryeppp/version.rb
98
+ - ryeppp.gemspec
99
+ - spec/ryeppp_spec.rb
100
+ - spec/spec_helper.rb
101
+ homepage: https://github.com/bradcater/ruby-yeppp
102
+ licenses:
103
+ - MIT
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.25
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: This gem provides bindings to the Yeppp! library.
126
+ test_files:
127
+ - spec/ryeppp_spec.rb
128
+ - spec/spec_helper.rb