Class: CooCoo::CUDA::DeviceBuffer

Inherits:
FFI::Struct
  • Object
show all
Defined in:
lib/coo-coo/cuda/device_buffer.rb,
lib/coo-coo/cuda/device_buffer/ffi.rb

Defined Under Namespace

Modules: FFI

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.[](other, length = nil) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/coo-coo/cuda/device_buffer.rb', line 34

def self.[](other, length = nil)
  if other.respond_to?(:each)
    length ||= other.size
  else
    length ||= 1
  end
  self.create(length).set(other)
end

.create(size, initial_value = 0.0) ⇒ Object



12
13
14
# File 'lib/coo-coo/cuda/device_buffer.rb', line 12

def self.create(size, initial_value = 0.0)
  FFI.new(size, initial_value.to_f)
end

.ffi_operator(op, ffi_method) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
# File 'lib/coo-coo/cuda/device_buffer.rb', line 201

def self.ffi_operator(op, ffi_method)
  define_method(op) do |other|
    if other.respond_to?(:each)
      other = self.class[other] unless other.kind_of?(self.class)
      raise ArgumentError.new("size mismatch: #{size} != #{other.size}") if size != other.size
      FFI.send(ffi_method, self, other)
    else
      FFI.send(ffi_method.to_s + "d", self, other.to_f)
    end
  end
end

.identity(w, h) ⇒ Object



219
220
221
# File 'lib/coo-coo/cuda/device_buffer.rb', line 219

def self.identity(w, h)
  FFI.buffer_identity(w, h)
end

.release(ptr) ⇒ Object



16
17
18
19
20
# File 'lib/coo-coo/cuda/device_buffer.rb', line 16

def self.release(ptr)
  FFI.buffer_free(ptr)
rescue
  CooCoo.debug(__method__, $!.inspect)
end

Instance Method Details

#==(other) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/coo-coo/cuda/device_buffer.rb', line 146

def ==(other)
  if other.kind_of?(self.class)
    1 == FFI.buffer_eq(self, other)
  else
    return false
  end
end

#[](index, len = nil, pad = false) ⇒ Object

Raises:

  • (RangeError)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/coo-coo/cuda/device_buffer.rb', line 79

def [](index, len = nil, pad = false)
  return super(index) if index.kind_of?(Symbol)
  
  index = size + index if index < 0
  raise RangeError.new if index >= size || index < 0
  if len
    len = (size - index) if pad == false && (index + len) >= size
    raise ArgumentError.new("length must be > 0") if len <= 0
  end

  if len
    FFI.slice(self, index, len)
  else
    out = HostBuffer.new(1)
    FFI.host_slice(self, out.to_ptr, index, 1)
    out[0]
  end
end

#[]=(index, value, length = nil) ⇒ Object

Raises:

  • (RangeError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/coo-coo/cuda/device_buffer.rb', line 55

def []=(index, value, length = nil)
  index = size + index if index < 0
  raise RangeError.new("#{index} >= #{size}") if index >= size
  raise RangeError.new("#{index} < 0") if index < 0

  if length
    value, length = length, value
    if value.kind_of?(self.class)
      FFI.setn(self, index, value, length)
    else
      buffer = HostBuffer[value, length]
      FFI.setvn(self, index, buffer.to_ptr, buffer.size)
    end
  else
    FFI.set_element(self, index, value)
  end
end

#cloneObject



28
29
30
31
32
# File 'lib/coo-coo/cuda/device_buffer.rb', line 28

def clone
  self.class.
    create(self.size).
    set(self)
end

#coerce(other) ⇒ Object



185
186
187
188
189
190
191
# File 'lib/coo-coo/cuda/device_buffer.rb', line 185

def coerce(other)
  if other.respond_to?(:each)
    return self.class[other], self
  else
    return self.class.create(self.size).set(other), self
  end
end

#diagflatObject



223
224
225
# File 'lib/coo-coo/cuda/device_buffer.rb', line 223

def diagflat
  FFI.buffer_diagflat(self)
end

#dot(w, h, other, ow = nil, oh = nil) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/coo-coo/cuda/device_buffer.rb', line 114

def dot(w, h, other, ow = nil, oh = nil)
  if other.kind_of?(self.class)
    ow ||= w
    oh ||= h
    raise ArgumentError.new("width (#{w}) must match the other's height (#{oh})") if w != oh
    raise ArgumentError.new("width * height != size") if size != w * h
    raise ArgumentError.new("other's width * height != other's size (#{ow} * #{oh} != #{other.size})") if other.size != ow * oh
    raise ArgumentError.new("other is null") if other.null?
    raise ArgumentError.new("self is null") if null?
    
    FFI.dot(self, w, h, other, ow, oh)
  else
    b, a = coerce(other)
    dot(w, h, b, ow, oh)
  end
end

#each(&block) ⇒ Object



98
99
100
# File 'lib/coo-coo/cuda/device_buffer.rb', line 98

def each(&block)
  get.each(&block)
end

#each_slice(n, &block) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/coo-coo/cuda/device_buffer.rb', line 102

def each_slice(n, &block)
  return to_enum(__method__, n) unless block

  (size / n.to_f).ceil.to_i.times do |i|
    block.call(self[i * n, n, true])
  end
end

#getObject



73
74
75
76
77
# File 'lib/coo-coo/cuda/device_buffer.rb', line 73

def get
  out = HostBuffer.new(size)
  FFI.get(self, out.to_ptr, size)
  out
end

#maxObject



231
232
233
# File 'lib/coo-coo/cuda/device_buffer.rb', line 231

def max
  FFI.buffer_max(self)
end

#minObject



227
228
229
# File 'lib/coo-coo/cuda/device_buffer.rb', line 227

def min
  FFI.buffer_min(self)
end

#minmaxObject



235
236
237
# File 'lib/coo-coo/cuda/device_buffer.rb', line 235

def minmax
  return min, max
end

#null?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/coo-coo/cuda/device_buffer.rb', line 197

def null?
  super || self[:data].null?
end

#set(buffer) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/coo-coo/cuda/device_buffer.rb', line 43

def set(buffer)
  case buffer
  when self.class then FFI.set(self, buffer)
  when Numeric then FFI.setd(self, buffer.to_f, 0, size)
  else
    buffer = HostBuffer[buffer]
    FFI.setv(self, buffer.to_ptr, buffer.size)
  end

  self
end

#set2d!(width, src, src_width, x, y) ⇒ Object



135
136
137
138
139
140
141
142
143
144
# File 'lib/coo-coo/cuda/device_buffer.rb', line 135

def set2d!(width, src, src_width, x, y)
  case src
  when self.class then FFI.set2d(self, width, src, src_width, x, y)
  else
    src = HostBuffer[src] unless src.kind_of?(HostBuffer)
    FFI.set2dv(self, width, src.to_ptr, src_width, src.size / src_width, x, y)
  end

  self
end

#sizeObject



24
25
26
# File 'lib/coo-coo/cuda/device_buffer.rb', line 24

def size
  FFI.buffer_length(self)
end

#slice_2d(width, height, x, y, out_width, out_height, initial = 0.0) ⇒ Object



131
132
133
# File 'lib/coo-coo/cuda/device_buffer.rb', line 131

def slice_2d(width, height, x, y, out_width, out_height, initial = 0.0)
  FFI.slice_2d(self, width, height, x, y, out_width, out_height, initial)
end

#sumObject



110
111
112
# File 'lib/coo-coo/cuda/device_buffer.rb', line 110

def sum
  FFI.buffer_sum(self)
end

#to_aObject



193
194
195
# File 'lib/coo-coo/cuda/device_buffer.rb', line 193

def to_a
  get.to_a
end