multiarray 0.2.4 → 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.
@@ -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