Class: GRX::Storage
- Inherits:
-
Object
- Object
- GRX::Storage
- Defined in:
- lib/grx/storage.rb
Overview
Storage — Buffer de memoria nativa
Cuando CAPI está cargado:
@ptr → Fiddle::Pointer a un bloque de doubles alineado a 32 bytes
reservado con grx_alloc() (malloc alineado en C).
Los datos viven en el heap de C, NO en el GC de Ruby.
Cuando CAPI NO está cargado (fallback):
@data → Array de Ruby normal (lento pero siempre correcto).
La separación entre los dos modos es transparente para Tensor.
Instance Attribute Summary collapse
-
#ptr ⇒ Object
readonly
ptr expuesto para que CAPI pueda leerlo directamente.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(array_plano) ⇒ Storage
constructor
A new instance of Storage.
-
#read(indice) ⇒ Object
—————————————————————— Lectura / escritura — usadas solo en modo fallback y por get() Las operaciones masivas (add, mul, etc.) van directo por @ptr en C.
-
#to_ruby_array ⇒ Object
Vuelca todo el buffer a un Array de Ruby (para to_a, inspect, tests).
- #write(indice, valor) ⇒ Object
Constructor Details
#initialize(array_plano) ⇒ Storage
Returns a new instance of Storage.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/grx/storage.rb', line 25 def initialize(array_plano) @size = array_plano.size if CAPI::LOADED # --- MODO RÁPIDO: memoria C alineada --- # grx_alloc devuelve un double* alineado a 32 bytes @ptr = CAPI.grx_alloc(@size) raise StorageError, "grx_alloc falló (OOM)" if @ptr.null? # Empaquetamos el Array de Ruby en el buffer C como doubles (little-endian) # Array#pack("d*") → String binaria de IEEE 754 doubles bytes = array_plano.pack("d*") @ptr[0, bytes.bytesize] = bytes # Registramos un finalizer para liberar la memoria C cuando el objeto # Ruby sea recolectado por el GC. Usamos ObjectSpace para evitar # que el closure capture self (lo que impediría la recolección). ptr_to_free = @ptr ObjectSpace.define_finalizer(self, self.class.make_finalizer(ptr_to_free)) else # --- MODO FALLBACK: Array de Ruby --- @data = array_plano.map(&:to_f) @ptr = nil end end |
Instance Attribute Details
#ptr ⇒ Object (readonly)
ptr expuesto para que CAPI pueda leerlo directamente
23 24 25 |
# File 'lib/grx/storage.rb', line 23 def ptr @ptr end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
20 21 22 |
# File 'lib/grx/storage.rb', line 20 def size @size end |
Class Method Details
.make_finalizer(ptr) ⇒ Object
51 52 53 |
# File 'lib/grx/storage.rb', line 51 def self.make_finalizer(ptr) proc { CAPI.grx_free(ptr) } end |
Instance Method Details
#read(indice) ⇒ Object
Lectura / escritura — usadas solo en modo fallback y por get() Las operaciones masivas (add, mul, etc.) van directo por @ptr en C.
59 60 61 62 63 64 65 66 |
# File 'lib/grx/storage.rb', line 59 def read(indice) if CAPI::LOADED # Leemos 8 bytes desde el offset correcto y los desempaquetamos como double @ptr[indice * 8, 8].unpack1("d") else @data[indice] end end |