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.
- data/Rakefile +5 -2
- data/lib/multiarray.rb +45 -20
- data/lib/multiarray/int.rb +1 -1
- data/lib/multiarray/int_.rb +87 -60
- data/lib/multiarray/lazy.rb +76 -0
- data/lib/multiarray/list.rb +33 -74
- data/lib/multiarray/malloc.rb +11 -0
- data/lib/multiarray/multiarray.rb +19 -1
- data/lib/multiarray/object.rb +36 -19
- data/lib/multiarray/pointer.rb +11 -0
- data/lib/multiarray/pointer_.rb +223 -0
- data/lib/multiarray/sequence.rb +14 -10
- data/lib/multiarray/sequence_.rb +40 -106
- data/lib/multiarray/type.rb +101 -129
- data/test/tc_int.rb +78 -76
- data/test/tc_multiarray.rb +97 -15
- data/test/tc_object.rb +52 -45
- data/test/tc_sequence.rb +89 -106
- data/test/ts_multiarray.rb +0 -1
- metadata +6 -8
- data/lib/multiarray/composite_type.rb +0 -67
- data/lib/multiarray/descriptortype.rb +0 -43
- data/lib/multiarray/memory.rb +0 -112
- data/lib/multiarray/sequence_operation.rb +0 -52
- data/lib/multiarray/storage.rb +0 -23
- data/lib/multiarray/type_operation.rb +0 -32
@@ -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 +
|
54
|
+
# @return [Class] A class deriving from +Pointer_+.
|
37
55
|
#
|
38
56
|
# @see MultiArray.new
|
39
57
|
# @see #Sequence
|
data/lib/multiarray/object.rb
CHANGED
@@ -5,49 +5,66 @@ module Hornetseye
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
8
|
-
#
|
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
|
15
|
+
def memory
|
14
16
|
List
|
15
17
|
end
|
16
18
|
|
17
|
-
#
|
19
|
+
# Get string with information about this type
|
18
20
|
#
|
19
|
-
# @return [
|
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
|
-
# @
|
22
|
-
def
|
23
|
-
|
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
|
-
#
|
42
|
+
# Size of storage required to store an element of this type
|
36
43
|
#
|
37
|
-
# @return [
|
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
|
-
# @
|
45
|
-
def
|
46
|
-
|
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,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
|
data/lib/multiarray/sequence.rb
CHANGED
@@ -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
|
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]
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
data/lib/multiarray/sequence_.rb
CHANGED
@@ -8,17 +8,38 @@ module Hornetseye
|
|
8
8
|
# @see MultiArray
|
9
9
|
#
|
10
10
|
# @abstract
|
11
|
-
class Sequence_ <
|
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
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|