Class: ComputeUnit::Cpu

Inherits:
ComputeBase show all
Defined in:
lib/compute_unit/cpu.rb

Constant Summary collapse

DEVICE_CLASS =
'060000'
DEVICE_CLASS_NAME =
'CPU'
VOLTAGE_MSR =
0x198

Constants inherited from ComputeBase

ComputeUnit::ComputeBase::CACHE_TIMEOUT

Constants inherited from Device

Device::PROC_PATH, Device::SYSFS_DEVICES_PATH

Instance Attribute Summary

Attributes inherited from ComputeBase

#compute_type, #index, #meta, #power_offset, #serial, #timestamp, #type

Attributes inherited from Device

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

Class Method Summary collapse

Instance Method Summary collapse

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

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_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) ⇒ Cpu

Returns a new instance of Cpu.



174
175
176
177
178
179
180
181
# File 'lib/compute_unit/cpu.rb', line 174

def initialize(_device_path, opts)
  super
  @type = :CPU
  @pci_loc = device_path
  @index = opts[:index].to_i
  @power_offset = 0
  @uuid = opts[:uuid] || opts[:serial]
end

Class Method Details

.attached_processes(field = :pctcpu, _filter = nil) ⇒ Array

Returns - an array of attached processes.

Parameters:

  • field (Symbol) (defaults to: :pctcpu)
    • the field to sort by

  • filter (Regex)
    • if supplied filter out devices from fd list

Returns:

  • (Array)
    • an array of attached processes



30
31
32
# File 'lib/compute_unit/cpu.rb', line 30

def self.attached_processes(field = :pctcpu, _filter = nil)
  Sys::ProcTable.ps(smaps: false).sort_by(&field)
end

.create_from_path(device_path, index) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
# File 'lib/compute_unit/cpu.rb', line 188

def self.create_from_path(device_path, index)
  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),
    index: index
  }
  new(device_path, opts)
end

.devicesArray

Returns - returns a list of device paths of all devices considered for display.

Returns:

  • (Array)
    • returns a list of device paths of all devices considered for display



12
13
14
15
16
# File 'lib/compute_unit/cpu.rb', line 12

def self.devices
  ComputeUnit::ComputeBase.devices.find_all do |device|
    ComputeUnit::Device.device_class(device) == DEVICE_CLASS
  end
end

.find_all(_use_opencl = false) ⇒ Object



200
201
202
203
204
# File 'lib/compute_unit/cpu.rb', line 200

def self.find_all(_use_opencl = false)
  devices.sort.map.with_index do |device_path, index|
    create_from_path(device_path, index)
  end
end

Instance Method Details

#base_hwmon_pathString

Returns the path of the hwmon path for monitoring temps.

Returns:

  • (String)

    the path of the hwmon path for monitoring temps



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

def base_hwmon_path
  File.join(ComputeUnit::SYSFS_PATH, 'devices/platform/coretemp.0/hwmon')
end

#biosObject



18
19
20
# File 'lib/compute_unit/cpu.rb', line 18

def bios
  'N/A'
end

#current_freq_mhzFloat

Returns - current mhz of cpu.

Returns:

  • (Float)
    • current mhz of cpu



84
85
86
# File 'lib/compute_unit/cpu.rb', line 84

def current_freq_mhz
  raw_cpu_data[:cpu_mhz].to_f.round(0)
end

#fanObject



128
129
130
# File 'lib/compute_unit/cpu.rb', line 128

def fan
  2500 # until we can calculate fan speed
end

#makeString

Returns - the maker of the cpu.

Returns:

  • (String)
    • the maker of the cpu



64
65
66
# File 'lib/compute_unit/cpu.rb', line 64

def make
  raw_cpu_data[:vendor_id]
end

#max_freq_mhzFloat

Returns - max mhz of cpu.

Returns:

  • (Float)
    • max mhz of cpu



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

def max_freq_mhz
  raw_cpu_data[:cpu_max_mhz].to_f.round(0)
end

#mem_tempObject



132
133
134
# File 'lib/compute_unit/cpu.rb', line 132

def mem_temp
  0 # until we can get the mem temp
end

#metricsObject



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/compute_unit/cpu.rb', line 154

def metrics
  {
    uuid: uuid,
    temp: temp,
    minFreqMhz: min_freq_mhz,
    maxFreqMhz: max_freq_mhz,
    currentFreqMhz: current_freq_mhz,
    model: model,
    make: make,
    numCores: num_cores,
    numThreads: num_threads,
    nproc: nproc,
    temps: temps
  }
end

#min_freq_mhzFloat

Returns - current min of cpu.

Returns:

  • (Float)
    • current min of cpu



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

def min_freq_mhz
  raw_cpu_data[:cpu_min_mhz].to_f.round(0)
end

#modelString

Returns - the model / name of the cpu.

Returns:

  • (String)
    • the model / name of the cpu



54
55
56
# File 'lib/compute_unit/cpu.rb', line 54

def model
  raw_cpu_data[:model_name]
end

#nameString

Returns - the model / name of the cpu.

Returns:

  • (String)
    • the model / name of the cpu



59
60
61
# File 'lib/compute_unit/cpu.rb', line 59

def name
  model
end

#nprocInteger

Returns - the number of cpus.

Returns:

  • (Integer)
    • the number of cpus



79
80
81
# File 'lib/compute_unit/cpu.rb', line 79

def nproc
  raw_cpu_data[:cpus].to_i
end

#num_coresInteger

Returns - the number of cores.

Returns:

  • (Integer)
    • the number of cores



69
70
71
# File 'lib/compute_unit/cpu.rb', line 69

def num_cores
  raw_cpu_data[:cores_per_socket].to_i
end

#num_threadsInteger

Returns - the number of threads.

Returns:

  • (Integer)
    • the number of threads



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

def num_threads
  raw_cpu_data[:threads_per_core].to_i
end

#pci_locObject



136
137
138
# File 'lib/compute_unit/cpu.rb', line 136

def pci_loc
  device_path
end

#powerObject



124
125
126
# File 'lib/compute_unit/cpu.rb', line 124

def power
  ENV.fetch('CPU_POWER', 60).to_i # until we can calculate power we will just use 60
end

#statusObject



120
121
122
# File 'lib/compute_unit/cpu.rb', line 120

def status
  0
end

#status_infoObject



140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/compute_unit/cpu.rb', line 140

def status_info
  { index: uuid,
    name: model,
    bios: 'N/A',
    core_clock: current_freq_mhz,
    memory_clock: 'N/A',
    power: power,
    fan: fan,
    core_volt: voltage,
    temp: temp,
    mem_temp: mem_temp,
    status: status }
end

#tempInteger

Returns - the temperature of the cpu package in Celsius.

Returns:

  • (Integer)
    • the temperature of the cpu package in Celsius



116
117
118
# File 'lib/compute_unit/cpu.rb', line 116

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

#tempsHash

Returns - a hash of temp readings and their labels.

Examples:

temps => :core_1=>31, :package_id_0=>27

Returns:

  • (Hash)
    • a hash of temp readings and their labels



105
106
107
108
109
110
111
112
113
# File 'lib/compute_unit/cpu.rb', line 105

def temps
  Dir.glob(File.join(hwmon_path, 'temp*_label')).each_with_object({}) do |label_file, acc|
    temp_file = label_file.sub('label', 'input')
    label = normalize_name(read_file(label_file))
    reading = read_file(temp_file).to_f.round(0) / 1000
    acc[label] = reading
    acc
  end
end

#to_hObject



170
171
172
# File 'lib/compute_unit/cpu.rb', line 170

def to_h
  super.merge(metrics)
end

#utilizationObject



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

def utilization
  1 # until we can calculate this.  Is loadavg a good metric? or load / cpus
end

#uuidString

Returns - the type and index of the device.

Returns:

  • (String)
    • the type and index of the device



184
185
186
# File 'lib/compute_unit/cpu.rb', line 184

def uuid
  @uuid ||= "#{type}#{index}"
end

#voltage(processor_id = 0) ⇒ Object

Parameters:

  • processor_id (Integer) (defaults to: 0)
    • the id of the cpu



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/compute_unit/cpu.rb', line 36

def voltage(processor_id = 0)
  file = "/dev/cpu/#{processor_id}/msr"
  return 0 unless File.exist?(file)

  # read 8 bytes, then unpack it by turning it into an integer
  # make it a binary string, pluck out some specific bits, then
  # convert it back to an integer
  # divide by 8192 to give the voltage
  # lowbit = 32
  # highbit = 47
  # bits = 47 - 32 + 1 # we want to read bits 32-47
  msr = IO.new IO.sysopen(file, 'rb')
  msr.sysseek(VOLTAGE_MSR)
  data, = msr.sysread(8).unpack('q')
  format('%.2f', ((data >> 32) / 8192.to_f))
end