multiarray 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,7 +18,7 @@
18
18
  module Hornetseye
19
19
 
20
20
  # Class for representing binary operations on scalars and arrays
21
- class Binary_ < Node
21
+ class BinaryOp_ < Node
22
22
 
23
23
  class << self
24
24
 
@@ -47,7 +47,7 @@ module Hornetseye
47
47
  #
48
48
  # @private
49
49
  def descriptor( hash )
50
- operation.to_s
50
+ inspect
51
51
  end
52
52
 
53
53
  end
@@ -68,7 +68,8 @@ module Hornetseye
68
68
  #
69
69
  # @private
70
70
  def descriptor( hash )
71
- "(#{@value1.descriptor( hash )}).#{self.class.descriptor( hash )}(#{@value2.descriptor( hash )})"
71
+ "(#{@value1.descriptor( hash )}).#{self.class.descriptor( hash )}" +
72
+ "(#{@value2.descriptor( hash )})"
72
73
  end
73
74
 
74
75
  # Array type of this term
@@ -128,6 +129,12 @@ module Hornetseye
128
129
  @value1.send self.class.operation, @value2
129
130
  end
130
131
 
132
+ def skip( index, start )
133
+ element1 = @value1.skip( index, start )
134
+ element2 = @value2.skip( index, start )
135
+ self.class.new( element1, element2 ).demand
136
+ end
137
+
131
138
  # Get element of unary operation
132
139
  #
133
140
  # @param [Integer,Node] i Index of desired element.
@@ -136,7 +143,15 @@ module Hornetseye
136
143
  def element( i )
137
144
  element1 = @value1.dimension == 0 ? @value1 : @value1.element( i )
138
145
  element2 = @value2.dimension == 0 ? @value2 : @value2.element( i )
139
- element1.send self.class.operation, element2
146
+ self.class.new( element1, element2 ).demand
147
+ end
148
+
149
+ def slice( start, length )
150
+ element1 = @value1.dimension == 0 ? @value1 :
151
+ @value1.slice( start, length )
152
+ element2 = @value2.dimension == 0 ? @value2 :
153
+ @value2.slice( start, length )
154
+ self.class.new( element1, element2 ).demand
140
155
  end
141
156
 
142
157
  # Check whether this term is compilable
@@ -150,25 +165,25 @@ module Hornetseye
150
165
 
151
166
  end
152
167
 
153
- # Create a class deriving from +Binary_+
168
+ # Create a class deriving from +BinaryOp_+
154
169
  #
155
170
  # @param [Symbol,String] operation Name of operation.
156
171
  # @param [Symbol,String] conversion Name of method for type conversion.
157
172
  #
158
- # @return [Class] A class deriving from +Binary_+.
173
+ # @return [Class] A class deriving from +BinaryOp_+.
159
174
  #
160
- # @see Binary_
161
- # @see Binary_.operation
162
- # @see Binary_.coercion
175
+ # @see BinaryOp_
176
+ # @see BinaryOp_.operation
177
+ # @see BinaryOp_.coercion
163
178
  #
164
179
  # @private
165
- def Binary( operation, coercion = :coercion )
166
- retval = Class.new Binary_
180
+ def BinaryOp( operation, coercion = :coercion )
181
+ retval = Class.new BinaryOp_
167
182
  retval.operation = operation
168
183
  retval.coercion = coercion
169
184
  retval
170
185
  end
171
186
 
172
- module_function :Binary
187
+ module_function :BinaryOp
173
188
 
174
189
  end
@@ -36,7 +36,7 @@ module Hornetseye
36
36
  #
37
37
  # @private
38
38
  def descriptor( hash )
39
- 'BOOL'
39
+ inspect
40
40
  end
41
41
 
42
42
  # Retrieve element from memory
@@ -49,7 +49,7 @@ module Hornetseye
49
49
  #
50
50
  # @private
51
51
  def fetch( ptr )
52
- new ptr.load( self ).ne( 0 )
52
+ new ptr.load( self ).first.ne( 0 )
53
53
  end
54
54
 
55
55
  # Memory type required to store elements of this type
@@ -135,4 +135,10 @@ module Hornetseye
135
135
 
136
136
  end
137
137
 
138
+ def BOOL( value )
139
+ BOOL.new value
140
+ end
141
+
142
+ module_function :BOOL
143
+
138
144
  end
@@ -24,7 +24,8 @@ module Hornetseye
24
24
  #
25
25
  # @param [Node] value Initial value of injection
26
26
  # @param [Node] index0 Index for
27
- def initialize( value, index0, index1, index2, initial, block, var1, var2 )
27
+ def initialize( value, index0, index1, index2, initial, block, var1,
28
+ var2 )
28
29
  @value, @index0, @index1, @index2, @initial, @block, @var1, @var2 =
29
30
  value, index0, index1, index2, initial, block, var1, var2
30
31
  end
@@ -37,12 +38,14 @@ module Hornetseye
37
38
  #
38
39
  # @private
39
40
  def descriptor( hash )
40
- hash = hash.merge @index0 => ( ( hash.values.max || 0 ) + 1 )
41
41
  hash = hash.merge @index1 => ( ( hash.values.max || 0 ) + 1 )
42
42
  hash = hash.merge @index2 => ( ( hash.values.max || 0 ) + 1 )
43
43
  hash = hash.merge @var1 => ( ( hash.values.max || 0 ) + 1 )
44
44
  hash = hash.merge @var2 => ( ( hash.values.max || 0 ) + 1 )
45
- "Diagonal(#{@value.descriptor( hash )},#{@initial ? @initial.descriptor( hash ) : 'nil'},#{@block.descriptor( hash )})"
45
+ "Diagonal(#{@value.descriptor( hash )},#{@index0.descriptor( hash )}," +
46
+ "#{@index1.descriptor( hash )},#{@index2.descriptor( hash )}," +
47
+ "#{@initial ? @initial.descriptor( hash ) : 'nil'}," +
48
+ "#{@block.descriptor( hash )})"
46
49
  end
47
50
 
48
51
  # Array type of this term
@@ -62,18 +65,21 @@ module Hornetseye
62
65
  #
63
66
  # @private
64
67
  def demand
65
- retval = @initial
66
- offset = @index2.size.get / 2
67
- @index2.size.get.times do |j|
68
- k = j - offset
69
- i = @index0.get - k
70
- if i >= 0 and i < @index1.size.get
71
- sub = @value.subst( @index1 => INT.new( i ),
72
- @index2 => INT.new( j ) ).simplify
73
- retval = retval ? @block.subst( @var1 => retval,
74
- @var2 => sub ).simplify :
75
- sub
76
- end
68
+ s1 = @index2.size / 2
69
+ j0 = INT.new( 0 ).major( @index0 + s1 + 1 - @index1.size )
70
+ if @initial
71
+ retval = @initial.simplify
72
+ else
73
+ j = j0.get
74
+ i = @index0.get + s1.get - j
75
+ retval = @value.subst( @index1 => INT.new( i ),
76
+ @index2 => INT.new( j ) ).simplify
77
+ j0 = ( j0 + 1 ).simplify
78
+ end
79
+ j0.upto( ( @index2.size - 1 ).minor( @index0 + s1 ) ) do |j|
80
+ i = @index0.get + s1.get - j
81
+ sub = @value.subst @index1 => INT.new( i ), @index2 => INT.new( j )
82
+ retval.store @block.subst( @var1 => retval, @var2 => sub )
77
83
  end
78
84
  retval
79
85
  end
@@ -95,13 +101,7 @@ module Hornetseye
95
101
  # @private
96
102
  def variables
97
103
  initial_variables = @initial ? @initial.variables : Set[]
98
- @value.variables + initial_variables -
99
- ( @index1.variables + @index2.variables )
100
- end
101
-
102
- def variables
103
- initial_variables = @initial ? @initial.variables : Set[]
104
- @value.variables + initial_variables -
104
+ @value.variables + initial_variables + @index0.variables -
105
105
  ( @index1.variables + @index2.variables )
106
106
  end
107
107
 
@@ -115,9 +115,10 @@ module Hornetseye
115
115
  #
116
116
  # @private
117
117
  def strip
118
- vars1, values1, term1 = @value.strip
119
118
  meta_vars1, meta_values1, var1 = @index1.strip
120
119
  meta_vars2, meta_values2, var2 = @index2.strip
120
+ vars1, values1, term1 =
121
+ @value.subst( @index1 => var1, @index2 => var2 ).strip
121
122
  if @initial
122
123
  vars2, values2, term2 = @initial.strip
123
124
  else
@@ -126,8 +127,7 @@ module Hornetseye
126
127
  vars3, values3, term3 = @block.strip
127
128
  return vars1 + meta_vars1 + meta_vars2 + vars2 + vars3,
128
129
  values1 + meta_values1 + meta_values2 + values2 + values3,
129
- Diagonal.new( term1.subst( @index1 => var1, @index2 => var2 ),
130
- @index0, var1, var2, term2, term3, @var1, @var2 )
130
+ Diagonal.new( term1, @index0, var1, var2, term2, term3, @var1, @var2 )
131
131
  end
132
132
 
133
133
  # Substitute variables
@@ -145,7 +145,7 @@ module Hornetseye
145
145
  subst_var2 = @index2.subst hash
146
146
  value = @value.subst( @index0 => subst_var0, @index1 => subst_var1,
147
147
  @index2 => subst_var2 ).subst hash
148
- initial = @intial ? @initial.subst( hash ) : nil
148
+ initial = @initial ? @initial.subst( hash ) : nil
149
149
  block = @block.subst hash
150
150
  Diagonal.new value, subst_var0, subst_var1, subst_var2, initial,
151
151
  block, @var1, @var2
@@ -159,7 +159,6 @@ module Hornetseye
159
159
  def compilable?
160
160
  initial_compilable = @initial ? @initial.compilable? : true
161
161
  @value.compilable? and initial_compilable and @block.compilable?
162
- false # !!!
163
162
  end
164
163
 
165
164
  end
@@ -29,7 +29,11 @@ module Hornetseye
29
29
  # @see Malloc#load
30
30
  # @see List#load
31
31
  def fetch( ptr )
32
- new ptr.load( self )
32
+ construct *ptr.load( self )
33
+ end
34
+
35
+ def construct( *args )
36
+ new *args
33
37
  end
34
38
 
35
39
  # Type coercion for native elements
@@ -52,7 +56,11 @@ module Hornetseye
52
56
  #
53
57
  # @param [Object] value Initial value for element.
54
58
  def initialize( value = self.class.default )
55
- @value = value
59
+ if Thread.current[ :function ].nil? or value.is_a? GCCValue
60
+ @value = value
61
+ else
62
+ @value = GCCValue.new Thread.current[ :function ], value.to_s
63
+ end
56
64
  end
57
65
 
58
66
  # Get unique descriptor of this object
@@ -74,10 +82,12 @@ module Hornetseye
74
82
  #
75
83
  # @private
76
84
  def dup
77
- if @value.respond_to? :duplicate
78
- self.class.new @value.duplicate( self.class )
85
+ if Thread.current[ :function ]
86
+ value = Thread.current[ :function ].variable self.class, 'v'
87
+ value.get.store get
88
+ value
79
89
  else
80
- self.class.new @value
90
+ self.class.new get
81
91
  end
82
92
  end
83
93
 
@@ -108,6 +118,10 @@ module Hornetseye
108
118
  end
109
119
  end
110
120
 
121
+ def skip( index, start )
122
+ self
123
+ end
124
+
111
125
  # Get value of this native element
112
126
  #
113
127
  # @return [Object] Value of this native element.
@@ -141,6 +155,10 @@ module Hornetseye
141
155
  ptr.save self
142
156
  end
143
157
 
158
+ def values
159
+ [ @value ]
160
+ end
161
+
144
162
  end
145
163
 
146
164
  end
@@ -0,0 +1,142 @@
1
+ # multiarray - Lazy multi-dimensional arrays for Ruby
2
+ # Copyright (C) 2010 Jan Wedekind
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # Namespace of Hornetseye computer vision library
18
+ module Hornetseye
19
+
20
+ class FLOAT_ < Element
21
+
22
+ class << self
23
+
24
+ attr_accessor :double
25
+
26
+ def memory
27
+ Malloc
28
+ end
29
+
30
+ def storage_size
31
+ double ? 8 : 4
32
+ end
33
+
34
+ def default
35
+ 0.0
36
+ end
37
+
38
+ def coercion( other )
39
+ if other < FLOAT_
40
+ Hornetseye::FLOAT( ( double or other.double ) )
41
+ elsif other < INT_
42
+ self
43
+ else
44
+ super other
45
+ end
46
+ end
47
+
48
+ def coerce( other )
49
+ if other < FLOAT_
50
+ return other, self
51
+ elsif other < INT_
52
+ return self, self
53
+ else
54
+ super other
55
+ end
56
+ end
57
+
58
+ def float
59
+ self
60
+ end
61
+
62
+ def directive
63
+ double ? 'd' : 'f'
64
+ end
65
+
66
+ def inspect
67
+ "#{ double ? 'D' : 'S' }FLOAT"
68
+ end
69
+
70
+ def descriptor( hash )
71
+ inspect
72
+ end
73
+
74
+ def ==( other )
75
+ other.is_a? Class and other < FLOAT_ and double == other.double
76
+ end
77
+
78
+ def hash
79
+ [ :FLOAT_, double ].hash
80
+ end
81
+
82
+ def eql?( other )
83
+ self == other
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ module Match
91
+
92
+ def fit( *values )
93
+ if values.all? { |value| value.is_a? Float or value.is_a? Integer }
94
+ if values.any? { |value| value.is_a? Float }
95
+ DFLOAT
96
+ else
97
+ super *values
98
+ end
99
+ else
100
+ super *values
101
+ end
102
+ end
103
+
104
+ def align( context )
105
+ if self < FLOAT_ and context < FLOAT_
106
+ context
107
+ else
108
+ super context
109
+ end
110
+ end
111
+
112
+ end
113
+
114
+ Node.extend Match
115
+
116
+ SINGLE = false
117
+ DOUBLE = true
118
+
119
+ def FLOAT( double )
120
+ retval = Class.new FLOAT_
121
+ retval.double = double
122
+ retval
123
+ end
124
+
125
+ module_function :FLOAT
126
+
127
+ SFLOAT = FLOAT SINGLE
128
+ DFLOAT = FLOAT DOUBLE
129
+
130
+ def SFLOAT( value )
131
+ SFLOAT.new value
132
+ end
133
+
134
+ module_function :SFLOAT
135
+
136
+ def DFLOAT( value )
137
+ DFLOAT.new value
138
+ end
139
+
140
+ module_function :DFLOAT
141
+
142
+ end
@@ -26,20 +26,23 @@ module Hornetseye
26
26
  "-I#{Config::CONFIG['rubyhdrdir']}/#{Config::CONFIG['arch']}" :
27
27
  "-I#{Config::CONFIG['archdir']}"
28
28
  LIBRUBYARG = Config::CONFIG[ 'LIBRUBYARG' ]
29
- DIRNAME = "#{Dir.tmpdir}/hornetseye-ruby#{RUBY_VERSION}-#{ENV[ 'USER' ]}"
29
+ DIRNAME = "#{Dir.tmpdir}/hornetseye-ruby#{RUBY_VERSION}-" +
30
+ "#{ENV[ 'USER' ] || ENV[ 'USERNAME' ]}"
31
+ LOCKFILE = "#{DIRNAME}/lock"
30
32
  Dir.mkdir DIRNAME, 0700 unless File.exist? DIRNAME
31
- @@dir = File.new DIRNAME
32
- unless @@dir.flock File::LOCK_EX | File::LOCK_NB
33
- raise "Could not lock directory #{DIRNAME}"
33
+ @@lock = File.new LOCKFILE, 'w', 0600
34
+ unless @@lock.flock File::LOCK_EX | File::LOCK_NB
35
+ raise "Could not lock file \"#{LOCKFILE}\""
34
36
  end
35
- @@dir.chmod 0700
36
37
 
37
38
  @@lib_name = 'hornetseye_aaaaaaaa'
38
39
 
39
- # while File.exist? "#{DIRNAME}/#{@@lib_name}.so"
40
- # require "#{DIRNAME}/#{@@lib_name}.so"
41
- # @@lib_name = @@lib_name.succ
42
- # end
40
+ if ENV[ 'HORNETSEYE_PRELOAD_CACHE' ]
41
+ while File.exist? "#{DIRNAME}/#{@@lib_name}.so"
42
+ require "#{DIRNAME}/#{@@lib_name}.so"
43
+ @@lib_name = @@lib_name.succ
44
+ end
45
+ end
43
46
 
44
47
  class << self
45
48
 
@@ -67,26 +70,26 @@ void #{descriptor}(#{
67
70
  if param_types.empty?
68
71
  ''
69
72
  else
70
- ' ' + ( 0 ... param_types.size ).collect do |i|
71
- "#{param_types[ i ].identifier} param#{i}"
73
+ ' ' + param_types.collect do |t|
74
+ t.identifiers
75
+ end.flatten.collect_with_index do |ident,i|
76
+ "#{ident} param#{i}"
72
77
  end.join( ', ' ) + ' '
73
78
  end
74
79
  }) {
75
80
  EOS
76
81
 
77
82
  @wrappers << <<EOS
78
- VALUE wrap#{descriptor.capitalize}( VALUE rbSelf#{
79
- ( 0 ... param_types.size ).inject '' do |s,i|
80
- s << ", VALUE rbParam#{i}"
81
- end
82
- } )
83
+ VALUE wrap#{descriptor.capitalize}( int argc, VALUE *argv, VALUE rbSelf )
83
84
  {
84
85
  #{descriptor}(#{
85
86
  if param_types.empty?
86
87
  ''
87
88
  else
88
- s = ' ' + ( 0 ... param_types.size ).collect do |i|
89
- param_types[ i ].r2c "rbParam#{i}"
89
+ s = ' ' + param_types.collect do |t|
90
+ t.r2c
91
+ end.flatten.collect_with_index do |conv,i|
92
+ conv.call "argv[ #{i} ]"
90
93
  end.join( ', ' ) + ' '
91
94
  end
92
95
  });
@@ -96,18 +99,17 @@ EOS
96
99
 
97
100
  @registrations << <<EOS
98
101
  rb_define_singleton_method( cGCCCache, "#{descriptor}",
99
- RUBY_METHOD_FUNC( wrap#{descriptor.capitalize} ),
100
- #{param_types.size} );
102
+ RUBY_METHOD_FUNC( wrap#{descriptor.capitalize} ), -1 );
101
103
  EOS
102
104
  end
103
105
  def compile
104
106
  template = <<EOS
105
107
  #include <ruby.h>
108
+ #include <math.h>
106
109
 
107
110
  inline void *mallocToPtr( VALUE rbMalloc )
108
111
  {
109
- VALUE rbValue = rb_iv_get( rbMalloc, "@value" );
110
- void *retVal; Data_Get_Struct( rbValue, void, retVal );
112
+ void *retVal; Data_Get_Struct( rbMalloc, void, retVal );
111
113
  return retVal;
112
114
  }
113
115
 
@@ -117,7 +119,8 @@ inline void *mallocToPtr( VALUE rbMalloc )
117
119
  void Init_#{@lib_name}(void)
118
120
  {
119
121
  VALUE mHornetseye = rb_define_module( "Hornetseye" );
120
- VALUE cGCCCache = rb_define_class_under( mHornetseye, "GCCCache", rb_cObject );
122
+ VALUE cGCCCache = rb_define_class_under( mHornetseye, "GCCCache",
123
+ rb_cObject );
121
124
  #{@registrations}
122
125
  }
123
126
  EOS
@@ -125,8 +128,9 @@ EOS
125
128
  File.open "#{DIRNAME}/#{@lib_name}.c", 'w', 0600 do |f|
126
129
  f << template
127
130
  end
128
- gcc = "#{LDSHARED} -fPIC #{RUBYHDRDIR} -o #{DIRNAME}/#{@lib_name}.so " +
129
- "#{DIRNAME}/#{@lib_name}.c #{LIBRUBYARG}"
131
+ gcc = "#{LDSHARED} -fPIC #{RUBYHDRDIR} -O " +
132
+ "-o #{DIRNAME}/#{@lib_name}.so " +
133
+ "#{DIRNAME}/#{@lib_name}.c #{LIBRUBYARG}"
130
134
  strip = "#{STRIP} #{DIRNAME}/#{@lib_name}.so"
131
135
  # puts template
132
136
  raise "Error compiling #{DIRNAME}/#{@lib_name}.c" unless system gcc