multiarray 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+