multiarray 0.4.1 → 0.5.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,146 @@
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
+ # Base class for representing native elements
21
+ class Element < Node
22
+
23
+ class << self
24
+
25
+ # Retrieve element from memory
26
+ #
27
+ # @param [Malloc,List] ptr Memory to load element from.
28
+ #
29
+ # @see Malloc#load
30
+ # @see List#load
31
+ def fetch( ptr )
32
+ new ptr.load( self )
33
+ end
34
+
35
+ # Type coercion for native elements
36
+ #
37
+ # @param [Node] other Other native datatype to coerce with.
38
+ #
39
+ # @return [Array<Node>] Result of coercion.
40
+ def coercion( other )
41
+ if self == other
42
+ self
43
+ else
44
+ x, y = other.coerce self
45
+ x.coercion y
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ # Constructor initialising element with a value
52
+ #
53
+ # @param [Object] value Initial value for element.
54
+ def initialize( value = self.class.default )
55
+ @value = value
56
+ end
57
+
58
+ # Get unique descriptor of this object
59
+ #
60
+ # @param [Hash] hash Labels for any variables.
61
+ #
62
+ # @return [String] Descriptor of this object,
63
+ #
64
+ # @private
65
+ def descriptor( hash )
66
+ "#{self.class.to_s}(#{@value.to_s})"
67
+ end
68
+
69
+ # Reevaluate computation
70
+ #
71
+ # @return [Node,Object] Result of computation
72
+ #
73
+ # @see #force
74
+ #
75
+ # @private
76
+ def dup
77
+ if @value.respond_to? :duplicate
78
+ self.class.new @value.duplicate( self.class )
79
+ else
80
+ self.class.new @value
81
+ end
82
+ end
83
+
84
+ # Strip of all values
85
+ #
86
+ # Split up into variables, values, and a term where all values have been
87
+ # replaced with variables.
88
+ #
89
+ # @return [Array<Array,Node>] Returns an array of variables, an array of
90
+ # values, and the term based on variables.
91
+ #
92
+ # @private
93
+ def strip
94
+ variable = Variable.new self.class
95
+ return [ variable ], [ self ], variable
96
+ end
97
+
98
+ # Check whether this term is compilable
99
+ #
100
+ # @return [FalseClass,TrueClass] Returns whether this term is compilable.
101
+ #
102
+ # @private
103
+ def compilable?
104
+ if @value.respond_to? :compilable?
105
+ @value.compilable?
106
+ else
107
+ super
108
+ end
109
+ end
110
+
111
+ # Get value of this native element
112
+ #
113
+ # @return [Object] Value of this native element.
114
+ def get
115
+ @value
116
+ end
117
+
118
+ # Store a value in this native element
119
+ #
120
+ # @param [Object] value New value for native element.
121
+ #
122
+ # @return [Object] Returns +value+.
123
+ def store( value )
124
+ if @value.respond_to? :store
125
+ @value.store value.simplify.get
126
+ else
127
+ @value = value.simplify.get
128
+ end
129
+ value
130
+ end
131
+
132
+ # Write element to memory
133
+ #
134
+ # @param [Malloc,List] ptr Memory to write element to.
135
+ #
136
+ # @see Malloc#save
137
+ # @see List#save
138
+ #
139
+ # @private
140
+ def write( ptr )
141
+ ptr.save self
142
+ end
143
+
144
+ end
145
+
146
+ end
@@ -0,0 +1,23 @@
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 GCCCache
21
+ end
22
+
23
+ end
@@ -0,0 +1,144 @@
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 GCCContext
21
+
22
+ LDSHARED = Config::CONFIG[ 'LDSHARED' ] # c:\mingw\bin\gcc
23
+ STRIP = Config::CONFIG[ 'STRIP' ]
24
+ RUBYHDRDIR = Config::CONFIG.member?( 'rubyhdrdir' ) ?
25
+ "-I#{Config::CONFIG['rubyhdrdir']} " +
26
+ "-I#{Config::CONFIG['rubyhdrdir']}/#{Config::CONFIG['arch']}" :
27
+ "-I#{Config::CONFIG['archdir']}"
28
+ LIBRUBYARG = Config::CONFIG[ 'LIBRUBYARG' ]
29
+ DIRNAME = "#{Dir.tmpdir}/hornetseye-ruby#{RUBY_VERSION}-#{ENV[ 'USER' ]}"
30
+ 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}"
34
+ end
35
+ @@dir.chmod 0700
36
+
37
+ @@lib_name = 'hornetseye_aaaaaaaa'
38
+
39
+ # while File.exist? "#{DIRNAME}/#{@@lib_name}.so"
40
+ # require "#{DIRNAME}/#{@@lib_name}.so"
41
+ # @@lib_name = @@lib_name.succ
42
+ # end
43
+
44
+ class << self
45
+
46
+ def build( &action )
47
+ lib_name, @@lib_name = @@lib_name, @@lib_name.succ
48
+ new( lib_name ).build &action
49
+ end
50
+
51
+ end
52
+
53
+ def initialize( lib_name )
54
+ @lib_name = lib_name
55
+ @instructions = ''
56
+ @wrappers = ''
57
+ @registrations = ''
58
+ end
59
+
60
+ def build( &action )
61
+ action.call self
62
+ end
63
+
64
+ def function( descriptor, *param_types )
65
+ @instructions << <<EOS
66
+ void #{descriptor}(#{
67
+ if param_types.empty?
68
+ ''
69
+ else
70
+ ' ' + ( 0 ... param_types.size ).collect do |i|
71
+ "#{param_types[ i ].identifier} param#{i}"
72
+ end.join( ', ' ) + ' '
73
+ end
74
+ }) {
75
+ EOS
76
+
77
+ @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
+ {
84
+ #{descriptor}(#{
85
+ if param_types.empty?
86
+ ''
87
+ else
88
+ s = ' ' + ( 0 ... param_types.size ).collect do |i|
89
+ param_types[ i ].r2c "rbParam#{i}"
90
+ end.join( ', ' ) + ' '
91
+ end
92
+ });
93
+ return Qnil;
94
+ }
95
+ EOS
96
+
97
+ @registrations << <<EOS
98
+ rb_define_singleton_method( cGCCCache, "#{descriptor}",
99
+ RUBY_METHOD_FUNC( wrap#{descriptor.capitalize} ),
100
+ #{param_types.size} );
101
+ EOS
102
+ end
103
+ def compile
104
+ template = <<EOS
105
+ #include <ruby.h>
106
+
107
+ inline void *mallocToPtr( VALUE rbMalloc )
108
+ {
109
+ VALUE rbValue = rb_iv_get( rbMalloc, "@value" );
110
+ void *retVal; Data_Get_Struct( rbValue, void, retVal );
111
+ return retVal;
112
+ }
113
+
114
+ #{@instructions}
115
+
116
+ #{@wrappers}
117
+ void Init_#{@lib_name}(void)
118
+ {
119
+ VALUE mHornetseye = rb_define_module( "Hornetseye" );
120
+ VALUE cGCCCache = rb_define_class_under( mHornetseye, "GCCCache", rb_cObject );
121
+ #{@registrations}
122
+ }
123
+ EOS
124
+ # File::EXCL no overwrite
125
+ File.open "#{DIRNAME}/#{@lib_name}.c", 'w', 0600 do |f|
126
+ f << template
127
+ end
128
+ gcc = "#{LDSHARED} -fPIC #{RUBYHDRDIR} -o #{DIRNAME}/#{@lib_name}.so " +
129
+ "#{DIRNAME}/#{@lib_name}.c #{LIBRUBYARG}"
130
+ strip = "#{STRIP} #{DIRNAME}/#{@lib_name}.so"
131
+ # puts template
132
+ raise "Error compiling #{DIRNAME}/#{@lib_name}.c" unless system gcc
133
+ raise "Error stripping #{DIRNAME}/#{@lib_name}.so" unless system strip
134
+ require "#{DIRNAME}/#{@lib_name}.so"
135
+ end
136
+
137
+ def <<( str )
138
+ @instructions << str
139
+ self
140
+ end
141
+
142
+ end
143
+
144
+ end
@@ -0,0 +1,109 @@
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 GCCFunction
21
+
22
+ class << self
23
+
24
+ def run( block )
25
+ keys, values, term = block.strip
26
+ labels = Hash[ *keys.zip( ( 0 ... keys.size ).to_a ).flatten ]
27
+ retval = block.pointer_type.new
28
+ retval_keys, retval_values, retval_term = retval.strip
29
+ method_name = '_' + term.descriptor( labels ).
30
+ tr( '(),+\-*/.@?~&|^<>',
31
+ '0123\456789ABCDEF' )
32
+ unless GCCCache.respond_to? method_name
33
+ GCCContext.build do |context|
34
+ function = new context, method_name,
35
+ *( retval_keys + keys ).collect { |var| var.meta }
36
+ term_subst = ( 0 ... keys.size ).collect do |i|
37
+ { keys[i] => function.param( i + retval_keys.size ) }
38
+ end.inject( {} ) { |a,b| a.merge b }
39
+ retval_subst = ( 0 ... retval_keys.size ).collect do |i|
40
+ { retval_keys[ i ] => function.param( i ) }
41
+ end.inject( {} ) { |a,b| a.merge b }
42
+ Hornetseye::lazy do
43
+ retval_term.subst( retval_subst ).store term.subst( term_subst )
44
+ end
45
+ function.insn_return
46
+ function.compile
47
+ end
48
+ end
49
+ args = ( retval_values + values ).collect { |arg| arg.get }
50
+ GCCCache.send method_name, *args
51
+ retval.simplify
52
+ end
53
+
54
+ end
55
+
56
+ def initialize( context, method_name, *param_types )
57
+ context.function method_name, *param_types.collect { |t| GCCType.new t }
58
+ @context = context
59
+ @method_name = method_name
60
+ @param_types = param_types
61
+ @indent = 1
62
+ @ids = 0
63
+ end
64
+
65
+ def compile
66
+ self << '}'
67
+ @context.compile
68
+ self
69
+ end
70
+
71
+ def id( prefix )
72
+ @ids += 1
73
+ "%s%02d"% [ prefix, @ids ]
74
+ end
75
+
76
+ def variable( typecode, prefix )
77
+ retval = typecode.new GCCValue.new( self, id( prefix ) )
78
+ self << "#{indent}#{GCCType.new( typecode ).identifier} #{retval.get};\n"
79
+ retval
80
+ end
81
+
82
+ def indent
83
+ ' ' * @indent
84
+ end
85
+
86
+ def indent_offset( offset )
87
+ @indent += offset
88
+ end
89
+
90
+ def param( i )
91
+ @param_types[ i ].new GCCValue.new( self, "param#{i}" )
92
+ end
93
+
94
+ def call( *args )
95
+ @context.send @method_name, *args.collect { |v| v.get }
96
+ end
97
+
98
+ def insn_return( value = nil )
99
+ self << "#{indent}return#{ value ? ' ' + value.get.to_s : '' };\n"
100
+ end
101
+
102
+ def <<( str )
103
+ @context << str
104
+ self
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,73 @@
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 GCCType
21
+
22
+ def initialize( typecode )
23
+ @typecode = typecode
24
+ end
25
+
26
+ def identifier
27
+ case @typecode
28
+ when nil
29
+ 'void'
30
+ when BOOL
31
+ 'char'
32
+ when BYTE
33
+ 'char'
34
+ when UBYTE
35
+ 'unsigned char'
36
+ when SINT
37
+ 'short int'
38
+ when USINT
39
+ 'unsigned short int'
40
+ when INT
41
+ 'int'
42
+ when UINT
43
+ 'unsigned int'
44
+ else
45
+ if @typecode < Pointer_
46
+ 'void *'
47
+ elsif @typecode < INDEX_
48
+ 'int'
49
+ else
50
+ raise "No identifier available for #{@typecode.inspect}"
51
+ end
52
+ end
53
+ end
54
+
55
+ def r2c( expr )
56
+ case @typecode
57
+ when BOOL
58
+ "( #{expr} ) != Qfalse"
59
+ when BYTE, UBYTE, SINT, USINT, INT, UINT
60
+ "NUM2INT( #{expr} )"
61
+ else
62
+ if @typecode < Pointer_
63
+ "(#{identifier})mallocToPtr( #{expr} )"
64
+ else
65
+ raise "No conversion available for #{@typecode.inspect}"
66
+ end
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+