Class: ComputeUnit::AmdGpu

Inherits:
Gpu show all
Defined in:
lib/compute_unit/gpus/amd_gpu.rb

Constant Summary collapse

MAKE =
'AMD'
VENDOR_ID =
'1002'
SUBTYPE =
'amdgpu'
SYS_DEBUG_PATH =
File.join(ComputeUnit::SYSFS_PATH, 'kernel', 'debug', 'dri')

Constants inherited from Gpu

Gpu::DEVICE_CLASS, Gpu::DEVICE_CLASS_NAME

Constants inherited from ComputeBase

ComputeBase::CACHE_TIMEOUT

Constants inherited from Device

Device::PROC_PATH, Device::SYSFS_DEVICES_PATH

Instance Attribute Summary

Attributes inherited from Gpu

#pci_loc, #use_opencl

Attributes inherited from ComputeBase

#compute_type, #index, #power_offset, #timestamp, #type, #uuid

Attributes inherited from Device

#device_class_id, #device_id, #device_path, #device_vendor_id, #make, #subsystem_device_id, #subsystem_vendor_id, #vendor

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Gpu

attached_processes, #compute_type, found_devices, #hardware_info, #mem_info, #memory_volt, #opencl_board_name, opencl_cache, #opencl_device, opencl_devices, opencl_devices_from_cache, opencl_devices_from_platform, #opencl_name, #opencl_units, #status, #status_info, #to_h

Methods inherited from ComputeBase

#attached_processes, compute_classes, #device_class_name, #expired_metadata?, #top_processes

Methods included from Logger

color, log_file, log_level, logger, #logger

Methods inherited from Device

#base_hwmon_path, device, device_class, device_lookup, device_vendor, #expired_metadata?, #generic_model, #hwmon_path, #lock_rom, logger, manual_device_database, manual_device_lookup, manual_vendor_lookup, manual_vendors, name_map, name_translation, pci_database, #read_file, #read_hwmon_data, #read_kernel_setting, read_kernel_setting, #rom_data, #rom_path, subsystem_device, subsystem_device_lookup, subsystem_vendor, subsystem_vendor_lookup, #sysfs_model_name, system_checksum, #to_h, #to_json, #unlock_rom, vendor_lookup, #write_hwmon_data, #write_kernel_setting, write_kernel_setting

Methods included from Utils

check_for_root, #root?, root?

Constructor Details

#initialize(device_path, opts = {}) ⇒ AmdGpu

Returns a new instance of AmdGpu.



14
15
16
17
18
19
20
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 14

def initialize(device_path, opts = {})
  super(device_path, opts)
  @pci_loc = File.basename(device_path)
  @model = opts[:model] if opts[:use_opencl]

  @uuid = "GPU#{index}"
end

Class Method Details

.create_from_path(device_path, index, use_opencl = false) ⇒ Object



311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 311

def self.create_from_path(device_path, index, use_opencl = false)
  opts = {
    device_class_id: device_class(device_path),
    device_id: device(device_path),
    device_vendor_id: device_vendor(device_path),
    subsystem_vendor_id: subsystem_vendor(device_path),
    subsystem_device_id: subsystem_device(device_path),
    use_opencl: use_opencl,
    index: index
  }
  new(device_path, opts)
end

.devicesArray

Returns - returns a list of device paths of all devices specific to the vendor id.

Returns:

  • (Array)
    • returns a list of device paths of all devices specific to the vendor id



74
75
76
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 74

def self.devices
  ComputeUnit::Gpu.devices.find_all { |f| device_vendor(f) == VENDOR_ID }
end

.find_all(use_opencl = false) ⇒ Array

Returns - returns and array of gpu instances of AMD type only.

Returns:

  • (Array)
    • returns and array of gpu instances of AMD type only



325
326
327
328
329
330
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 325

def self.find_all(use_opencl = false)
  devices.map.with_index do |device_path, _index|
    found_index = ComputeUnit::Gpu.found_devices.index(device_path)
    create_from_path(device_path, found_index, use_opencl)
  end
end

Instance Method Details

#amdgpu_pm_infoObject

:unit=>“MHz”, :sclk=>:unit=>“MHz”,

:vddgfx=>{:value=>"950", :unit=>"mV"},
:vddc=>{:value=>"61.49", :unit=>"W"},
:vddci=>{:value=>"1.0", :unit=>"W"},
:max_gpu=>{:value=>"81.243", :unit=>"W"},
:average_gpu=>{:value=>"82.117", :unit=>"W"},
:temperature=>{:value=>"41", :unit=>"C"},
:load=>{:value=>"100", :unit=>"%"}}


365
366
367
368
369
370
371
372
373
374
375
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 365

def amdgpu_pm_info
  @amdgpu_pm_info ||= begin
    content = read_dri_debug_file('amdgpu_pm_info')
    data = content.scan(/(\d+\.?\d*)\s+(\w*)\s\(([\w\s]*)\)?/) + content.scan(/(\w*):\s(\d+)\s(.*)/).map(&:rotate)
    data_hash = {}
    data.each do |value, unit, name|
      data_hash[name.gsub(/\s/, '_').downcase.to_sym] = { value: value, unit: unit }
    end
    data_hash
  end
end

#asic_tempInteger

Returns - the temperature of the asic chip.

Returns:

  • (Integer)
    • the temperature of the asic chip



94
95
96
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 94

def asic_temp
  read_hwmon_data('temp2_input', 0).to_i / 1000
end

#biosString

Returns - the name of the bios which is unique for every card.

Returns:

  • (String)
    • the name of the bios which is unique for every card



203
204
205
206
207
208
209
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 203

def bios
  @bios ||= begin
    a = read_kernel_setting('vbios_version', 'unreadable').upcase
    b = rom_bios
    /\d{3}-/.match?(b) ? b : a
  end
end

#board_nameString

for vegas we have to also get the compute units

Returns:

  • (String)
    • returns the name of compute board



64
65
66
67
68
69
70
71
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 64

def board_name
  @board_name ||= begin
    return nil unless opencl_board_name

    name = opencl_board_name.sub(/Series|\(TM\)/, '').sub('Graphics', '').sub(/\s{2}/, ' ').strip
    /vega/i.match?(name) ? "#{name} #{opencl_units}" : name
  end
end

#clock_limitsObject



156
157
158
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 156

def clock_limits
  read_kernel_setting('pp_od_clk_limits', '')
end

#clock_max_defaultsArray

reading from file “Sclk Limit: 2000 Mhz”, “Mclk Limit: 2250 Mhz”

Examples:

2000, 2250

Returns:

  • (Array)


400
401
402
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 400

def clock_max_defaults
  read_kernel_setting('pp_od_clk_limits', '0 0').scan(/\d+/).map(&:to_i)
end

#configured_core_voltageObject



118
119
120
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 118

def configured_core_voltage
  vddc
end

#core_clockInteger

Returns - the core clock speed.

Returns:

  • (Integer)
    • the core clock speed



130
131
132
133
134
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 130

def core_clock
  data = read_kernel_setting('pp_dpm_sclk', '').split("\n")
  item = data.find { |d| d.include?('*') }
  item.nil? ? item : item.match(/\d{2,6}/).to_a.first.to_i
end

#core_voltageNumeric

Returns - returns voltage of core in mV.

Returns:

  • (Numeric)
    • returns voltage of core in mV



114
115
116
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 114

def core_voltage
  dpm_core_vddc.zero? ? vddgfx.to_i : dpm_core_vddc
end

#debug_dri_dirString

ie. “/sys/kernel/debug/dri/0”

Returns:

  • (String)
    • returns the path the debug dri directory



345
346
347
348
349
350
351
352
353
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 345

def debug_dri_dir
  @debug_dri_dir ||= begin
    # if the user does not have permission the path will be nil
    path = Dir.glob(File.join(SYS_DEBUG_PATH, '*', 'name')).find { |file| File.read(file).include?(pci_loc) }
    raise Errno::EACCES.new("Permission denied #{SYS_DEBUG_PATH}") unless path

    File.dirname(path)
  end
end

#debug_rom_pathString

Returns - the path to the readonly rom file.

Returns:

  • (String)
    • the path to the readonly rom file



50
51
52
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 50

def debug_rom_path
  @rom_path ||= File.join(SYS_DEBUG_PATH, index.to_s, 'amdgpu_vbios')
end

#dpm_core_vddcObject

currently running gpu core voltage



148
149
150
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 148

def dpm_core_vddc
  read_kernel_setting('pp_core_vddc', 0).to_i
end

#dpm_force_performanceString

Returns - reads the setting after writing the setting and returns current value.

Returns:

  • (String)
    • reads the setting after writing the setting and returns current value



378
379
380
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 378

def dpm_force_performance
  read_kernel_setting('power_dpm_force_performance_level', nil)
end

#dpm_force_performance_setting(setting = 'manual') ⇒ String

Returns - reads the setting after writing the setting and returns current value.

Parameters:

  • setting (String) (defaults to: 'manual')
    • the dpm performance setting to adjust the dpm (manual or auto)

Returns:

  • (String)
    • reads the setting after writing the setting and returns current value

Raises:

  • (ArgumentError)


384
385
386
387
388
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 384

def dpm_force_performance_setting(setting = 'manual')
  raise ArgumentError.new('setting must be one of manual or auto') unless setting =~ /manual|auto/

  write_kernel_setting('power_dpm_force_performance_level', "#{setting}\n")
end

#fanInteger

Returns - returns fan rpm speed, 0 if cannot be found.

Returns:

  • (Integer)
    • returns fan rpm speed, 0 if cannot be found



109
110
111
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 109

def fan
  read_hwmon_data('fan1_input', 0).to_i
end

#fan_limitNumeric

Note:

the OS values is between 0 - 255

Returns - current fan limit as a percentage.

Returns:

  • (Numeric)
    • current fan limit as a percentage



258
259
260
261
262
263
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 258

def fan_limit
  cur = read_hwmon_data('pwm1', 0).to_i
  return cur unless cur > 0

  ((cur / 255.0) * 100).round(0)
end

#fan_max_limitNumeric

Note:

the OS values is between 0 - 255

Returns - current fan limit as a percentage.

Returns:

  • (Numeric)
    • current fan limit as a percentage



267
268
269
270
271
272
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 267

def fan_max_limit
  cur = read_hwmon_data('pwm1_max', 0).to_i
  return cur unless cur > 0

  ((cur / 255.0) * 100).round(0)
end

#fan_min_limitNumeric

Note:

the OS values is between 0 - 255

Returns - current fan limit as a percentage.

Returns:

  • (Numeric)
    • current fan limit as a percentage



276
277
278
279
280
281
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 276

def fan_min_limit
  cur = read_hwmon_data('pwm1_min', 0).to_i
  return cur unless cur > 0

  ((cur / 255.0) * 100).round(0)
end

#gpu_defaultsObject



160
161
162
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 160

def gpu_defaults
  read_kernel_setting('gpu_defaults', '')
end

#loadObject



89
90
91
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 89

def load
  utilization
end

#max_core_clockInteger

Returns:

  • (Integer)


405
406
407
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 405

def max_core_clock
  clock_max_defaults.first
end

#max_mem_clockInteger

Returns:

  • (Integer)


415
416
417
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 415

def max_mem_clock
  clock_max_defaults.last # or vddci_voltage_table.last[:clk]
end

#max_mem_voltInteger

Returns:

  • (Integer)


425
426
427
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 425

def max_mem_volt
  vddci_voltage_table.last[:volt]
end

#mem_tempInteger

Returns - temperature of the memory.

Returns:

  • (Integer)
    • temperature of the memory



99
100
101
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 99

def mem_temp
  read_hwmon_data('temp3_input', 0).to_i / 1000
end

#memory_clockInteger

Returns - the memory speed.

Returns:

  • (Integer)
    • the memory speed



123
124
125
126
127
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 123

def memory_clock
  data = read_kernel_setting('pp_dpm_mclk', '').split("\n")
  item = data.find { |d| d.include?('*') }
  item.nil? ? item : item.match(/\d{2,6}/).to_a.first.to_i
end

#memory_freeObject



301
302
303
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 301

def memory_free
  0
end

#memory_totalObject



293
294
295
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 293

def memory_total
  0
end

#memory_usedObject



297
298
299
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 297

def memory_used
  0
end

#metaObject



22
23
24
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 22

def meta
  {}
end

#min_core_clockInteger

Returns:

  • (Integer)


410
411
412
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 410

def min_core_clock
  voltage_table[0][:clk]
end

#min_mem_clockInteger

Returns:

  • (Integer)


420
421
422
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 420

def min_mem_clock
  vddci_voltage_table.first[:clk]
end

#min_mem_voltInteger

Returns:

  • (Integer)


430
431
432
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 430

def min_mem_volt
  vddci_voltage_table.first[:volt]
end

#modelString

Returns - the name of the device model (specific name).

Returns:

  • (String)
    • the name of the device model (specific name)



83
84
85
86
87
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 83

def model
  @model ||= begin
    board_name || sysfs_model_name
  end
end

#nameObject



78
79
80
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 78

def name
  model
end

#powerFloat

Returns the power being used by the gpu.

Returns:

  • (Float)

    the power being used by the gpu



196
197
198
199
200
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 196

def power
  pp_value = read_kernel_setting('pp_power_usage', 0).to_i
  value = pp_value > 0 ? pp_value : power_average
  value + power_offset
end

#power_averageFloat

Returns the average power being used by the gpu.

Returns:

  • (Float)

    the average power being used by the gpu



190
191
192
193
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 190

def power_average
  # TODO: if a gpu crashes the average power can sometimes take 3000 ms to read!
  read_hwmon_data('power1_average', 0).to_i / 1000000
end

#power_limitNumeric

Returns - current power limit.

Returns:

  • (Numeric)
    • current power limit



284
285
286
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 284

def power_limit
  read_hwmon_data('power1_cap', 0).to_i / 1000000
end

#power_limit=(value) ⇒ Numeric

Returns - original passed in value after being set.

Parameters:

  • value (Numeric)
    • the power limit that should be applied to the gpu

Returns:

  • (Numeric)
    • original passed in value after being set

Raises:

  • (ArgumentError)


222
223
224
225
226
227
228
229
230
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 222

def power_limit=(value)
  max = power_max_limit
  raise ArgumentError.new("Power Value #{value} cannot exceed #{max}") if value > max
  raise ArgumentError.new("Value must be between 10 and #{max}") if value < 10

  # hwmon expects the value to have 6 zeros
  write_hwmon_data('power1_cap', value * 1000000)
  # logger.info("GPU#{index} power set to #{value} Watts")
end

#power_max_limitNumeric

Returns - the maximum power that can be set.

Returns:

  • (Numeric)
    • the maximum power that can be set



289
290
291
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 289

def power_max_limit
  read_hwmon_data('power1_cap_max').to_i / 1000000
end

#pstateObject



211
212
213
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 211

def pstate
  -1
end

#read_dri_debug_file(file_name, default = '') ⇒ Object



332
333
334
335
336
337
338
339
340
341
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 332

def read_dri_debug_file(file_name, default = '')
  File.read(File.join(debug_dri_dir, file_name))
rescue Errno::EINVAL
  default
rescue Errno::ENOENT
  default
rescue Errno::EACCES
  logger.debug('run this command as root or with sudo, using default values')
  default
end

#read_rom_dataString::IO

Returns - the contents of the rom file.

Returns:

  • (String::IO)
    • the contents of the rom file



39
40
41
42
43
44
45
46
47
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 39

def read_rom_data
  if File.exist?(debug_rom_path)
    IO.read(debug_rom_path, mode: 'rb')
  elsif File.exist?(rom_path)
    rom_data
  else
    ''
  end
end

#reset_to_defaultsObject



390
391
392
393
394
395
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 390

def reset_to_defaults
  dpm_force_performance_setting('auto')
  write_kernel_setting('pp_od_clk_voltage', 'r')
  write_kernel_setting('pp_od_clk_voltage', 'c')
  write_hwmon_data('pwm1_enable', '2')
end

#rom_biosString

sometimes the kernel / driver extracted rom can be incorrect this is the bios gathered from the vbios itself.

Returns:

  • (String)
    • the bios according to the vbios rom



29
30
31
32
33
34
35
36
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 29

def rom_bios
  if !/\d{3}-/.match?([2])
    logger.warn("Invalid rom bios name for GPU#{index} using alternate name for #{[3]}")
    [3]
  elsif /\d{3}-/.match?([2])
    [2]
  end
end

#rom_metadataArray

Returns - an array of readable strings from the rom file.

Returns:

  • (Array)
    • an array of readable strings from the rom file



55
56
57
58
59
60
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 55

def 
  @rom_metadata || begin
    printable_chars = %r{[A-Za-z0-9`~!@#%^&*()-_=+|'";:/?.>,< \t\$\{\}\[\]\\]{10,}}
    read_rom_data.scan(printable_chars)[0..9]
  end
end

#serialString

Returns - the serial number of the card.

Returns:

  • (String)
    • the serial number of the card



216
217
218
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 216

def serial
  'unknown'
end

#set_fan_limit(value, type = 'current') ⇒ Numeric

Returns - original passed in value after being set.

Parameters:

  • value (Numeric)
    • the fan limit that should be applied to the gpu as a percentage

Returns:

  • (Numeric)
    • original passed in value after being set

Raises:

  • (ArgumentError)


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 234

def set_fan_limit(value, type = 'current')
  write_hwmon_data('fan1_enable', '1')
  hwmon_file = if type == 'min'
                 'pwm1_min'
               elsif type == 'max'
                 'pwm1_max'
               elsif type == 'current'
                 'pwm1'
               else
                 raise ArgumentError.new("Invalid fan setting type, must be one of 'current, min or max'")
               end
  raise ArgumentError.new('Fan limit cannot exceed 100') if value > 100
  raise ArgumentError.new('Fan limit value must be between 20 and 100') if value < 20

  # Value must be between 0-255
  amount = (255 * (value / 100.0)).round
  logger.debug("Setting #{type} Fan on GPU#{index} to #{amount}")
  write_hwmon_data(hwmon_file, amount)
  logger.info("GPU#{index} #{type} fan set to #{value} percent")
  value
end

#set_mem_clock_and_vddc(mem_clock, mem_volt) ⇒ Object

Raises:

  • (ArgumentError)


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 434

def set_mem_clock_and_vddc(mem_clock, mem_volt)
  return unless experimental_on?

  mem_clock = mem_clock.to_i
  mem_volt = mem_volt.to_i
  # TODO: find max and min values and limit input
  dpm_force_performance_setting('manual')
  raise ArgumentError.new("MemClock value #{mem_clock} must be between #{min_mem_clock}-#{max_mem_clock}") unless mem_clock.between?(min_mem_clock, max_mem_clock)
  raise ArgumentError.new("MemVolt value #{mem_volt} must be between #{min_mem_volt}-#{max_mem_volt}") unless mem_volt.between?(min_mem_volt, max_mem_volt)

  write_kernel_setting('pp_od_clk_voltage', "r\n") # unlocks in order to write
  # set row in table (m = manual), 3 = row,
  write_kernel_setting('pp_od_clk_voltage', "m 3 #{mem_clock} #{mem_volt}\n")
  write_kernel_setting('pp_od_clk_voltage', "c\n") # locks file
  write_kernel_setting('pp_mclk_od', "3\n")
  logger.info("Successfully applied overclock #{mem_clock} #{mem_volt} to #{name} at #{pci_loc}")
end

#subtypeObject



152
153
154
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 152

def subtype
  SUBTYPE
end

#tempInteger

Returns - returns temp of gpu in celius.

Returns:

  • (Integer)
    • returns temp of gpu in celius



104
105
106
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 104

def temp
  read_hwmon_data('temp1_input', 0).to_i / 1000
end

#utilizationObject



305
306
307
308
309
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 305

def utilization
  return 0 unless amdgpu_pm_info[:load]

  amdgpu_pm_info[:load][:value].to_i || 0
end

#vddcNumeric

currently configured gpu core voltage

Returns:

  • (Numeric)
    • returns voltage of core in mV



143
144
145
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 143

def vddc
  read_kernel_setting('pp_voltage', 0).to_i
end

#vddci_voltage_tableArray

Returns - array of hashes of voltages :mclk=>300, :volt=>750.

Returns:

  • (Array)
    • array of hashes of voltages :mclk=>300, :volt=>750



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 177

def vddci_voltage_table
  # not sure if this is what mclk is but left it here anyways
  data = read_kernel_setting('pp_od_clk_voltage', nil)
  return data if data.nil?

  _, _, mclk = data.split(/OD_[S,M]CLK:\s?\n/)
  mclk.split("\n").map do |line|
    pstate, clk, volt, = line.gsub(/:|Mhz|mV/, '').split(/\s{2,}/).map(&:to_i)
    { pstate: pstate, clk: clk, volt: volt, type: :mclk }
  end
end

#vddgfxInteger

Returns - the core voltage reading of the GPU via HWMON.

Returns:

  • (Integer)
    • the core voltage reading of the GPU via HWMON



137
138
139
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 137

def vddgfx
  read_hwmon_data('in0_input', 0).to_i
end

#voltage_tableArray

Returns - array of hashes of voltages :sclk=>300, :volt=>750.

Returns:

  • (Array)
    • array of hashes of voltages :sclk=>300, :volt=>750



165
166
167
168
169
170
171
172
173
174
# File 'lib/compute_unit/gpus/amd_gpu.rb', line 165

def voltage_table
  data = read_kernel_setting('pp_od_clk_voltage', nil)
  return [] if data.nil?

  _, sclk, = data.split(/OD_[S,M]CLK:\s?\n/)
  sclk.split("\n").map do |line|
    pstate, clk, volt, = line.gsub(/:|Mhz|mV/, '').split(/\s{2,}/).map(&:to_i)
    { pstate: pstate, clk: clk, volt: volt, type: :sclk }
  end
end