Class: NDAV
- Inherits:
-
Object
- Object
- NDAV
- Includes:
- MemoryViewable
- Defined in:
- lib/ndav.rb,
lib/ndav/ffi.rb,
lib/ndav/flags.rb,
lib/ndav/converter.rb,
lib/ndav/memory_viewable.rb,
ext/ndav.c
Overview
TODO: Manage flags of internal data object
Defined Under Namespace
Modules: Converter, FFI, Flags, MemoryViewable
Constant Summary collapse
- ITEM_SIZES =
TODO: Want to use return value of rb_memory_view_parse_item_format
["c", "C", "s", "S", "l", "L", "q", "Q", "f", "d", "s!", "S!", "n", "v", "i", "i!", "I", "I!", "l!", "L!", "N", "V", "e", "g", "q!", "Q!", "E", "G"].collect {|format| [format, [0].pack(format).bytesize] }.to_h
Instance Attribute Summary collapse
-
#byte_size ⇒ Object
readonly
Returns the value of attribute byte_size.
-
#format ⇒ Object
readonly
Returns the value of attribute format.
-
#item_size ⇒ Object
readonly
Returns the value of attribute item_size.
-
#lifetime ⇒ Object
readonly
Returns the value of attribute lifetime.
-
#ndim ⇒ Object
readonly
Returns the value of attribute ndim.
-
#shape ⇒ Object
readonly
Returns the value of attribute shape.
-
#strides ⇒ Object
readonly
Returns the value of attribute strides.
-
#to_s ⇒ Object
readonly
Returns the value of attribute to_s.
Class Method Summary collapse
-
.column_major_contiguous?(format:, shape:, strides:) ⇒ Boolean
Algorithm stolen from memory_view.c.
- .default_strides(shape:, item_size:, row_major: true) ⇒ Object
- .from_string(str) ⇒ Object
- .register(cls, mdl, name:) ⇒ Object
-
.row_major_contiguous?(format:, shape:, strides:) ⇒ Boolean
Algorithm stolen from memory_view.c.
Instance Method Summary collapse
- #column_major_contiguous? ⇒ Boolean
-
#initialize(obj, shape: nil, strides: nil, format: nil, lifetime: nil) ⇒ NDAV
constructor
TODO: More options to trick for the case of MemoryView export is wrong but developer don't fix it.
- #readonly? ⇒ Boolean
- #row_major_contiguous? ⇒ Boolean
- #to_ptr ⇒ Object (also: #to_fiddle_pointer)
Methods included from MemoryViewable
Constructor Details
#initialize(obj, shape: nil, strides: nil, format: nil, lifetime: nil) ⇒ NDAV
TODO: More options to trick for the case of MemoryView export is wrong but developer don't fix it
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ndav.rb', line 63 def initialize(obj, shape: nil, strides: nil, format: nil, lifetime: nil) fmv = obj.kind_of?(::Fiddle::MemoryView) ? obj : ::Fiddle::MemoryView.new(obj) # Fiddle::MemoryView#to_s is zero-copy # Fiddle::MemoryView#to_s embeds obj into the String, so we can prevent GC from collecting it @to_s = fmv.to_s @lifetime = lifetime @format = format || fmv.format raise ArgumentError, %Q|unsupported format: #{@format.to_s.dump}, currently supported: #{ITEM_SIZES.keys}| unless ITEM_SIZES.key?(@format) item_size_by_format = ITEM_SIZES[@format] @byte_size = fmv.byte_size @item_size = obj.kind_of?(::Fiddle::Pointer) ? item_size_by_format : fmv.item_size || item_size_by_format @shape = shape || fmv.shape case [@shape, @byte_size] in [nil, nil] raise ArgumentError, "either shape or byte_size must be present in obj or arguments" in [_, nil] @byte_size = @shape.reduce(@item_size, :*) in [nil, _] n, r = @byte_size.divmod(@item_size) raise ArgumentError, "byte_size must be n-times of item_size" unless r.zero? @shape = [n] else # noop end @ndim = @shape.size @readonly = fmv.readonly? @strides = strides || fmv.strides || self.class.default_strides(shape: @shape, item_size: @item_size) @sub_offsets = fmv.sub_offsets @row_major_contiguous = self.class.row_major_contiguous?(format: @format, shape: @shape, strides: @strides) @column_major_contiguous = self.class.column_major_contiguous?(format: @format, shape: @shape, strides: @strides) validate fmv end |
Instance Attribute Details
#byte_size ⇒ Object (readonly)
Returns the value of attribute byte_size.
16 17 18 |
# File 'lib/ndav.rb', line 16 def byte_size @byte_size end |
#format ⇒ Object (readonly)
Returns the value of attribute format.
16 17 18 |
# File 'lib/ndav.rb', line 16 def format @format end |
#item_size ⇒ Object (readonly)
Returns the value of attribute item_size.
16 17 18 |
# File 'lib/ndav.rb', line 16 def item_size @item_size end |
#lifetime ⇒ Object (readonly)
Returns the value of attribute lifetime.
16 17 18 |
# File 'lib/ndav.rb', line 16 def lifetime @lifetime end |
#ndim ⇒ Object (readonly)
Returns the value of attribute ndim.
16 17 18 |
# File 'lib/ndav.rb', line 16 def ndim @ndim end |
#shape ⇒ Object (readonly)
Returns the value of attribute shape.
16 17 18 |
# File 'lib/ndav.rb', line 16 def shape @shape end |
#strides ⇒ Object (readonly)
Returns the value of attribute strides.
16 17 18 |
# File 'lib/ndav.rb', line 16 def strides @strides end |
#to_s ⇒ Object (readonly)
Returns the value of attribute to_s.
16 17 18 |
# File 'lib/ndav.rb', line 16 def to_s @to_s end |
Class Method Details
.column_major_contiguous?(format:, shape:, strides:) ⇒ Boolean
Algorithm stolen from memory_view.c
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ndav.rb', line 47 def column_major_contiguous?(format:, shape:, strides:, **) ndim = shape.length n = ITEM_SIZES[format] return strides[0] == n if ndim == 1 0.upto(ndim - 1) do |i| return false unless strides[i] == n n *= shape[i] end true end |
.default_strides(shape:, item_size:, row_major: true) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/ndav.rb', line 19 def default_strides(shape:, item_size:, row_major: true) each_shape = row_major ? shape.reverse_each : shape.each each_shape.reduce([[], item_size]) {|(strides, stride), s| if row_major strides.unshift stride else strides << stride end [strides, stride * s] }[0] end |
.from_string(str) ⇒ Object
7 8 9 |
# File 'lib/ndav/converter.rb', line 7 def from_string(str, *, **) new(Fiddle::Pointer[str], *, **) end |
.register(cls, mdl, name:) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/ndav/converter.rb', line 11 def register(cls, mdl, name:) if mdl.const_defined?(:FromNDAV) cls.extend mdl::FromNDAV define_method "to_#{name}" do |*args, **kwargs| cls.from_ndav(self, *args, **kwargs) end end if mdl.const_defined?(:MemoryViewable) cls.include ::NDAV::MemoryViewable cls.include mdl::MemoryViewable unless mdl.const_defined?(:ToNDAV) mdl.const_set(:ToNDAV, Module.new { def to_ndav(lifetime: self, **) ::NDAV.new(self, lifetime:, **) end }) end end if mdl.const_defined?(:ToNDAV) cls.include mdl::ToNDAV define_singleton_method "from_#{name}" do |array, *args, **kwargs| array.to_ndav(*args, **kwargs) end end if mdl.const_defined?(:Converter) Converter.prepend mdl::Converter Converter.singleton_class.prepend mdl::Converter end end |
.row_major_contiguous?(format:, shape:, strides:) ⇒ Boolean
Algorithm stolen from memory_view.c
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ndav.rb', line 32 def row_major_contiguous?(format:, shape:, strides:, **) ndim = shape.length n = ITEM_SIZES[format] return strides[0] == n if ndim == 1 (ndim - 1).downto 0 do |i| return false unless strides[i] == n n *= shape[i] end true end |
Instance Method Details
#column_major_contiguous? ⇒ Boolean
108 109 110 |
# File 'lib/ndav.rb', line 108 def column_major_contiguous? @column_major_contiguous end |
#readonly? ⇒ Boolean
100 101 102 |
# File 'lib/ndav.rb', line 100 def readonly? @readonly end |
#row_major_contiguous? ⇒ Boolean
104 105 106 |
# File 'lib/ndav.rb', line 104 def row_major_contiguous? @row_major_contiguous end |
#to_ptr ⇒ Object Also known as: to_fiddle_pointer
112 113 114 |
# File 'lib/ndav.rb', line 112 def to_ptr ::Fiddle::Pointer[@to_s] end |