multiarray 0.2.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ module Hornetseye
2
+
3
+ class Malloc
4
+
5
+ def fetch( type )
6
+ type.import read( type.storage_size )
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -21,6 +21,24 @@ module Hornetseye
21
21
  Hornetseye::MultiArray( element_type, *shape ).new
22
22
  end
23
23
 
24
+ def []( *args )
25
+ probe = proc do |s,a|
26
+ if a.is_a? Array
27
+ if s.empty?
28
+ a.inject( [], &probe ) + [ a.size ]
29
+ else
30
+ a.inject( s[ 0 ... -1 ], &probe ) + [ [ a.size, s.last ].max ]
31
+ end
32
+ else
33
+ s
34
+ end
35
+ end
36
+ shape = probe.call [], args
37
+ retval = MultiArray.new OBJECT, *shape
38
+ retval[] = args
39
+ retval
40
+ end
41
+
24
42
  end
25
43
 
26
44
  end
@@ -33,7 +51,7 @@ module Hornetseye
33
51
  # @param [Class] element_type Element type of the array type. Should derive
34
52
  # from +Type+.
35
53
  # @param [Array<Integer>] *shape The dimensions of the array type.
36
- # @return [Class] A class deriving from +Type+ or +Sequence_+.
54
+ # @return [Class] A class deriving from +Pointer_+.
37
55
  #
38
56
  # @see MultiArray.new
39
57
  # @see #Sequence
@@ -5,49 +5,66 @@ module Hornetseye
5
5
 
6
6
  class << self
7
7
 
8
- # Returns the type of storage object for storing values
8
+ # Get memory type for storing objects of this type
9
9
  #
10
10
  # @return [Class] Returns +List+.
11
11
  #
12
+ # @see List
13
+ #
12
14
  # @private
13
- def storage
15
+ def memory
14
16
  List
15
17
  end
16
18
 
17
- # Number of storage elements for storing an object of this type
19
+ # Get string with information about this type
18
20
  #
19
- # @return [Integer] Returns +1+.
21
+ # @return [String] Returns +'OBJECT'+.
22
+ def to_s
23
+ 'OBJECT'
24
+ end
25
+
26
+ # Get string with information about this type
20
27
  #
21
- # @private
22
- def bytesize
23
- 1
28
+ # @return [String] Returns +'OBJECT'+.
29
+ def inspect
30
+ to_s
24
31
  end
25
32
 
26
- # Default value for Ruby objects.
33
+ # Default value for Ruby objects
27
34
  #
28
- # @return [Object] Returns +nil+.
35
+ # @return [Object] Returns +nil+.
29
36
  #
30
37
  # @private
31
38
  def default
32
39
  nil
33
40
  end
34
41
 
35
- # Get string with information about this type
42
+ # Size of storage required to store an element of this type
36
43
  #
37
- # @return [String] Returns +'OBJECT'+.
38
- def to_s
39
- 'OBJECT'
40
- end
41
-
42
- # Get string with information about this type
44
+ # @return [Integer] Size of storage required. Returns +1+.
43
45
  #
44
- # @return [String] Returns +'OBJECT'+.
45
- def inspect
46
- to_s
46
+ # @private
47
+ def storage_size
48
+ 1
47
49
  end
48
50
 
49
51
  end
50
52
 
53
+ def store( ptr )
54
+ ptr.write @value
55
+ self
56
+ end
57
+
58
+ end
59
+
60
+ module RubyMatching
61
+
62
+ def fit( *value )
63
+ OBJECT
64
+ end
65
+
51
66
  end
52
67
 
68
+ Type.extend RubyMatching
69
+
53
70
  end
@@ -0,0 +1,11 @@
1
+ module Hornetseye
2
+
3
+ def Pointer( primitive )
4
+ retval = Class.new Pointer_
5
+ retval.primitive = primitive
6
+ retval
7
+ end
8
+
9
+ module_function :Pointer
10
+
11
+ end
@@ -0,0 +1,223 @@
1
+ module Hornetseye
2
+
3
+ class Pointer_ < Type
4
+
5
+ class << self
6
+
7
+ attr_accessor :primitive
8
+
9
+ def inspect
10
+ if primitive
11
+ if primitive < Sequence_
12
+ primitive.inspect
13
+ else
14
+ "Pointer(#{primitive.inspect})"
15
+ end
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ def to_s
22
+ if primitive
23
+ if primitive < Sequence_
24
+ primitive.to_s
25
+ else
26
+ "Pointer(#{primitive.to_s})"
27
+ end
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def default
34
+ if Thread.current[ :lazy ]
35
+ Lazy.new :action => proc { self.class.primitive.typecode.new }
36
+ else
37
+ primitive.memory.new primitive.storage_size
38
+ end
39
+ end
40
+
41
+ def dereference
42
+ primitive.dereference
43
+ end
44
+
45
+ end
46
+
47
+ def inspect( indent = nil, lines = nil )
48
+ if self.class.primitive < Sequence_
49
+ if @value.is_a? Lazy
50
+ "#{self.class.primitive.inspect}:#{@value.inspect}"
51
+ else
52
+ if indent
53
+ prepend = ''
54
+ else
55
+ prepend = "#{self.class.inspect}:\n"
56
+ indent = 0
57
+ lines = 0
58
+ end
59
+ if empty?
60
+ retval = '[]'
61
+ else
62
+ retval = '[ '
63
+ for i in 0 ... self.class.primitive.num_elements
64
+ x = self[i]
65
+ if x.is_a? Pointer_
66
+ if i > 0
67
+ retval += ",\n "
68
+ lines += 1
69
+ if lines >= 10
70
+ retval += '...' if indent == 0
71
+ break
72
+ end
73
+ retval += ' ' * indent
74
+ end
75
+ str = x.inspect indent + 1, lines
76
+ lines += str.count "\n"
77
+ retval += str
78
+ if lines >= 10
79
+ retval += '...' if indent == 0
80
+ break
81
+ end
82
+ else
83
+ retval += ', ' if i > 0
84
+ str = x.inspect
85
+ if retval.size + str.size >= 74 - '...'.size -
86
+ '[ ]'.size * indent.succ
87
+ retval += '...'
88
+ break
89
+ else
90
+ retval += str
91
+ end
92
+ end
93
+ end
94
+ retval += ' ]' unless lines >= 10
95
+ end
96
+ prepend + retval
97
+ end
98
+ else
99
+ super()
100
+ end
101
+ end
102
+
103
+ def to_a
104
+ if self.class.primitive < Sequence_
105
+ ( 0 ... self.class.primitive.num_elements ).collect do |i|
106
+ element( i ).to_a
107
+ end
108
+ else
109
+ force.fetch.get
110
+ end
111
+ end
112
+
113
+ def []( *args )
114
+ if args.empty?
115
+ if self.class.primitive < Sequence_
116
+ self
117
+ else
118
+ fetch[]
119
+ end
120
+ else
121
+ index = args.pop
122
+ element( index )[ *args ]
123
+ end
124
+ end
125
+
126
+ def []=( *args )
127
+ value = args.pop
128
+ if args.empty?
129
+ if self.class.primitive < Sequence_
130
+ if value.is_a? Array
131
+ for i in 0 ... self.class.primitive.num_elements
132
+ if i < value.size
133
+ element( i )[] = value[ i ]
134
+ else
135
+ element( i )[] = self.class.primitive.typecode.default
136
+ end
137
+ end
138
+ else
139
+ operation( self.class.primitive.new( value ) ) { |x| set x }
140
+ end
141
+ else
142
+ store self.class.primitive.new( value )
143
+ end
144
+ else
145
+ index = args.pop
146
+ element( index )[ *args ] = value
147
+ end
148
+ end
149
+
150
+ def set( value )
151
+ unless value.is_a?( List ) or value.is_a?( Malloc ) or
152
+ value.is_a?( Lazy )
153
+ store self.class.primitive.new( value )
154
+ else
155
+ super value
156
+ end
157
+ value
158
+ end
159
+
160
+ def fetch
161
+ if self.class.primitive < Sequence_
162
+ delay
163
+ else
164
+ get.fetch self.class.primitive
165
+ end
166
+ end
167
+
168
+ def force
169
+ if Thread.current[ :lazy ] or not @value.is_a? Lazy
170
+ self
171
+ else
172
+ if self.class.primitive < Sequence_ and @value.is_a? Lazy
173
+ self.class.new.operation( self ) { |x| set x }
174
+ else
175
+ super
176
+ end
177
+ end
178
+ end
179
+
180
+ def store( value )
181
+ value.force.store @value
182
+ end
183
+
184
+ def element( index )
185
+ if @value.is_a? Lazy
186
+ Hornetseye::Pointer( self.class.primitive.element_type ).
187
+ new @value.element( index )
188
+ else
189
+ pointer = @value + index * self.class.primitive.stride *
190
+ self.class.primitive.typecode.storage_size
191
+ Hornetseye::Pointer( self.class.primitive.element_type ).new pointer
192
+ end
193
+ end
194
+
195
+ def empty?
196
+ self.class.primitive.size == 0
197
+ end
198
+
199
+ def operation( *args, &action )
200
+ if self.class.primitive < Sequence_
201
+ if Thread.current[ :lazy ]
202
+ super *args.collect { |arg| arg.delay }, &action
203
+ else
204
+ for i in 0 ... self.class.primitive.num_elements
205
+ subargs = args.collect do |arg|
206
+ if arg.is_a?( Pointer_ ) and arg.class.primitive < Sequence_
207
+ arg.element( i ).fetch
208
+ else
209
+ arg.force.fetch
210
+ end
211
+ end
212
+ element( i ).operation *subargs, &action
213
+ end
214
+ self
215
+ end
216
+ else
217
+ super *args, &action
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ end
@@ -20,11 +20,17 @@ module Hornetseye
20
20
  Hornetseye::Sequence( element_type, num_elements ).new
21
21
  end
22
22
 
23
+ def []( *args )
24
+ retval = Hornetseye::Sequence( OBJECT, args.size ).new
25
+ retval[] = args
26
+ retval
27
+ end
28
+
23
29
  end
24
30
 
25
31
  end
26
32
 
27
- # Create a class deriving from +Sequence_+
33
+ # Create an array class
28
34
  #
29
35
  # The parameters +element_type+, +num_elements+, and +stride+ are assigned
30
36
  # to the corresponding attributes of the resulting class.
@@ -34,19 +40,17 @@ module Hornetseye
34
40
  # @param [Integer] num_elements Number of elements of the array type.
35
41
  # @param [Integer] stride Optional stride size for transposed or
36
42
  # non-contiguous array types.
37
- # @return [Class] A class deriving from +Sequence_+.
43
+ # @return [Class] An array class deriving from +Pointer_+.
38
44
  #
39
45
  # @see Sequence.new
40
46
  # @see #MultiArray
41
- # @see CompositeType.element_type
42
- # @see CompositeType.num_elements
43
47
  def Sequence( element_type, num_elements,
44
- stride = element_type.size )
45
- retval = Class.new Sequence_
46
- retval.element_type = element_type
47
- retval.num_elements = num_elements
48
- retval.stride = stride
49
- retval
48
+ stride = element_type.dereference.size )
49
+ sequence = Class.new Sequence_
50
+ sequence.element_type = element_type.dereference
51
+ sequence.num_elements = num_elements
52
+ sequence.stride = stride
53
+ Pointer sequence
50
54
  end
51
55
 
52
56
  module_function :Sequence
@@ -8,17 +8,38 @@ module Hornetseye
8
8
  # @see MultiArray
9
9
  #
10
10
  # @abstract
11
- class Sequence_ < CompositeType
11
+ class Sequence_ < Type
12
12
 
13
13
  class << self
14
14
 
15
+ # Get memory type for storing objects of this type
16
+ #
17
+ # @return [Class] Returns +element_type.memory+.
18
+ #
19
+ # @see Malloc
20
+ #
21
+ # @private
22
+ def memory
23
+ element_type.memory
24
+ end
25
+
26
+ # Type of elements this type is composed of
27
+ #
28
+ # @return [Type,Sequence_] The element type of this type.
29
+ attr_accessor :element_type
30
+
31
+ # Number of elements this type is composed of
32
+ #
33
+ # @return [Integer] The number of elements this type is composed of.
34
+ attr_accessor :num_elements
35
+
15
36
  # Distance of two consecutive elements divided by size of single element
16
37
  #
17
38
  # @return [Integer] Stride size to iterate over array.
18
39
  #
19
40
  # @see #Sequence
20
41
  # @see List#+
21
- # @see Memory#+
42
+ # @see Malloc#+
22
43
  #
23
44
  # @private
24
45
  attr_accessor :stride
@@ -27,26 +48,24 @@ module Hornetseye
27
48
  #
28
49
  # @return [String] Information about this array type.
29
50
  def inspect
30
- to_s
31
- end
32
-
33
- # Get default value for this array type.
34
- #
35
- # @return [Object] Returns a multi-dimensional array filled with the
36
- # default value of the element type.
37
- #
38
- # @private
39
- def default
40
- retval = new
41
- retval.set
42
- retval
51
+ if element_type and num_elements
52
+ shortcut = element_type < Sequence_ ? 'MultiArray' : 'Sequence'
53
+ typename = typecode.inspect
54
+ if typename =~ /^[A-Z]+$/
55
+ "#{shortcut}.#{typename.downcase}(#{shape.join ','})"
56
+ else
57
+ "#{shortcut}(#{typename},#{shape.join ','})"
58
+ end
59
+ else
60
+ super
61
+ end
43
62
  end
44
63
 
45
64
  # Get string with information about this type
46
65
  #
47
66
  # @return [String] Information about this array type.
48
67
  def to_s
49
- if element_type
68
+ if element_type and num_elements
50
69
  shortcut = element_type < Sequence_ ? 'MultiArray' : 'Sequence'
51
70
  typename = typecode.to_s
52
71
  if typename =~ /^[A-Z]+$/
@@ -55,7 +74,7 @@ module Hornetseye
55
74
  "#{shortcut}(#{typename},#{shape.join ','})"
56
75
  end
57
76
  else
58
- 'Sequence_'
77
+ super
59
78
  end
60
79
  end
61
80
 
@@ -66,103 +85,18 @@ module Hornetseye
66
85
  element_type.typecode
67
86
  end
68
87
 
69
- # Check whether arrays of this type are empty or not
70
- #
71
- # @return [FalseClass,TrueClass] Returns boolean indicating whether
72
- # arrays of this type are empty or not.
73
- def empty?
74
- num_elements == 0
88
+ def size
89
+ num_elements * element_type.size
75
90
  end
76
91
 
77
- # Get shape of multi-dimensional array
78
- #
79
- # @return [Array<Integer>] Ruby array with the shape of this array type.
80
92
  def shape
81
93
  element_type.shape + [ num_elements ]
82
94
  end
83
95
 
84
- end
85
-
86
- # Distance of two consecutive elements divided by size of single element
87
- #
88
- # @return [Integer] Stride size to iterate over array.
89
- #
90
- # @see #Sequence
91
- # @see List#+
92
- # @see Memory#+
93
- #
94
- # @private
95
- def stride
96
- self.class.stride
97
- end
98
-
99
- # Display type and values of this array
100
- #
101
- # @return [String] Returns string with information about the type and the
102
- # values of this array.
103
- def inspect( indent = nil, lines = nil )
104
- if indent
105
- prepend = ''
106
- else
107
- prepend = "#{self.class.inspect}:\n"
108
- indent = 0
109
- lines = 0
110
- end
111
- if empty?
112
- retval = '[]'
113
- else
114
- retval = '[ '
115
- for i in 0 ... num_elements
116
- x = at i
117
- if x.is_a? Sequence_
118
- if i > 0
119
- retval += ",\n "
120
- lines += 1
121
- if lines >= 10
122
- retval += '...' if indent == 0
123
- break
124
- end
125
- retval += ' ' * indent
126
- end
127
- str = x.inspect indent + 1, lines
128
- lines += str.count "\n"
129
- retval += str
130
- if lines >= 10
131
- retval += '...' if indent == 0
132
- break
133
- end
134
- else
135
- retval += ', ' if i > 0
136
- str = x.inspect
137
- if retval.size + str.size >= 74 - '...'.size -
138
- '[ ]'.size * indent.succ
139
- retval += '...'
140
- break
141
- else
142
- retval += str
143
- end
144
- end
145
- end
146
- retval += ' ]' unless lines >= 10
96
+ def storage_size
97
+ element_type.storage_size * num_elements
147
98
  end
148
- prepend + retval
149
- end
150
-
151
- # Display values of this array
152
- #
153
- # @return [String] Returns string with the values of this array.
154
- def to_s
155
- to_a.to_s
156
- end
157
99
 
158
- # Convert to Ruby array
159
- #
160
- # @return [Array<Object>] Result of the conversion.
161
- def to_a
162
- ( 0 ... num_elements ).collect do |i|
163
- x = at i
164
- x.is_a?( Sequence_ ) ? x.to_a : x
165
- end
166
100
  end
167
101
 
168
102
  end