public function read_sensor() { // Report graphics processor fan speed as a percent $fan_speed = -1; if (phodevi::is_nvidia_graphics()) { // NVIDIA fan speed reading support in NVIDIA 190.xx and newer // TODO: support for multiple fans, also for reading GPUFanTarget to get appropriate fan // nvidia-settings --describe GPUFanTarget $fan_speed = phodevi_parser::read_nvidia_extension('[fan:0]/GPUCurrentFanSpeed'); } else { if (phodevi::is_ati_graphics() && phodevi::is_linux()) { $fan_speed = phodevi_linux_parser::read_ati_overdrive('FanSpeed'); } } return $fan_speed; }
public static function read_sensor() { // Report graphics processor temperature $temp_c = -1; if (phodevi::is_nvidia_graphics()) { $temp_c = phodevi_parser::read_nvidia_extension('GPUCoreTemp'); } else { if (phodevi::is_ati_graphics() && phodevi::is_linux()) { $temp_c = phodevi_linux_parser::read_ati_overdrive('Temperature'); } else { foreach (array_merge(array('/sys/class/drm/card0/device/temp1_input'), pts_file_io::glob('/sys/class/drm/card0/device/hwmon/hwmon*/temp1_input')) as $temp_input) { // This works for at least Nouveau driver with Linux 2.6.37 era DRM if (is_readable($temp_input) == false) { continue; } $temp_input = pts_file_io::file_get_contents($temp_input); if (is_numeric($temp_input)) { if ($temp_input > 1000) { $temp_input /= 1000; } $temp_c = $temp_input; break; } } if ($temp_c == -1 && is_readable('/sys/kernel/debug/dri/0/i915_emon_status')) { // Intel thermal $i915_emon_status = file_get_contents('/sys/kernel/debug/dri/0/i915_emon_status'); $temp = strpos($i915_emon_status, 'GMCH temp: '); if ($temp !== false) { $temp = substr($i915_emon_status, $temp + 11); $temp = substr($temp, 0, strpos($temp, PHP_EOL)); if (is_numeric($temp) && $temp > 0) { $temp_c = $temp; } } } } } if ($temp_c > 1000 || $temp_c < 9) { // Invalid data return -1; } return $temp_c; }
public static function ati_overdrive_core_usage() { return phodevi_linux_parser::read_ati_overdrive('GPUload'); }
public function read_sensor() { // Graphics processor real/current frequency $show_memory = false; $core_freq = 0; $mem_freq = 0; if (phodevi::is_nvidia_graphics()) { $nv_freq = phodevi_parser::read_nvidia_extension('GPUCurrentClockFreqs'); $nv_freq = pts_strings::comma_explode($nv_freq); $core_freq = isset($nv_freq[0]) ? $nv_freq[0] : 0; $mem_freq = isset($nv_freq[1]) ? $nv_freq[1] : 0; } else { if (phodevi::is_ati_graphics() && phodevi::is_linux()) { $od_clocks = phodevi_linux_parser::read_ati_overdrive('CurrentClocks'); if (is_array($od_clocks) && count($od_clocks) >= 2) { $core_freq = array_shift($od_clocks); $mem_freq = array_pop($od_clocks); } } else { if (phodevi::is_linux()) { if (isset(phodevi::$vfs->radeon_pm_info)) { // radeon_pm_info should be present with Linux 2.6.34+ foreach (pts_strings::trim_explode("\n", phodevi::$vfs->radeon_pm_info) as $pm_line) { $pm_line = pts_strings::colon_explode($pm_line); if (isset($pm_line[1])) { list($descriptor, $value) = $pm_line; } else { continue; } switch ($descriptor) { case 'current engine clock': $core_freq = pts_arrays::first_element(explode(' ', $value)) / 1000; break; case 'current memory clock': $mem_freq = pts_arrays::first_element(explode(' ', $value)) / 1000; break; } } if ($core_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'sclk: '))) { $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('sclk: ')); $x = substr($x, 0, strpos($x, ' ')); if (is_numeric($x)) { if ($x > 1000) { $x = $x / 100; } $core_freq = $x; } } if ($mem_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'mclk: '))) { $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('mclk: ')); $x = substr($x, 0, strpos($x, ' ')); if (is_numeric($x)) { if ($x > 1000) { $x = $x / 100; } $mem_freq = $x; } } } else { if (is_file('/sys/class/drm/card0/gt_cur_freq_mhz')) { $gt_cur_freq_mhz = pts_file_io::file_get_contents('/sys/class/drm/card0/gt_cur_freq_mhz'); if ($gt_cur_freq_mhz > 2) { $core_freq = $gt_cur_freq_mhz; } } else { if (is_file('/sys/class/drm/card0/device/performance_level')) { $performance_level = pts_file_io::file_get_contents('/sys/class/drm/card0/device/performance_level'); $performance_level = explode(' ', $performance_level); $core_string = array_search('core', $performance_level); if ($core_string !== false && isset($performance_level[$core_string + 1])) { $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]); if (is_numeric($core_string) && $core_string > $core_freq) { $core_freq = $core_string; } } $mem_string = array_search('memory', $performance_level); if ($mem_string !== false && isset($performance_level[$mem_string + 1])) { $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]); if (is_numeric($mem_string) && $mem_string > $mem_freq) { $mem_freq = $mem_string; } } } else { if (isset(phodevi::$vfs->i915_cur_delayinfo)) { $i915_cur_delayinfo = phodevi::$vfs->i915_cur_delayinfo; $cagf = strpos($i915_cur_delayinfo, 'CAGF: '); if ($cagf !== false) { $cagf_mhz = substr($i915_cur_delayinfo, $cagf + 6); $cagf_mhz = substr($cagf_mhz, 0, strpos($cagf_mhz, 'MHz')); if (is_numeric($cagf_mhz)) { $core_freq = $cagf_mhz; } } } } } } } } } if (!is_numeric($core_freq)) { $core_freq = 0; } if (!is_numeric($mem_freq)) { $mem_freq = 0; } if ($core_freq == 0 && $mem_freq == 0) { $show_memory = false; $core_freq = -1; } return $show_memory ? array($core_freq, $mem_freq) : $core_freq; }
public static function gpu_stock_frequency() { // Graphics processor stock frequency $core_freq = 0; $mem_freq = 0; if (phodevi::is_nvidia_graphics() && phodevi::is_macosx() == false) { // GPUDefault3DClockFreqs is the default and does not show under/over-clocking $clock_freqs_3d = pts_strings::comma_explode(phodevi_parser::read_nvidia_extension('GPU3DClockFreqs')); $clock_freqs_current = pts_strings::comma_explode(phodevi_parser::read_nvidia_extension('GPUCurrentClockFreqs')); if (is_array($clock_freqs_3d) && isset($clock_freqs_3d[1])) { list($core_freq, $mem_freq) = $clock_freqs_3d; } if (is_array($clock_freqs_current) && isset($clock_freqs_current[1])) { $core_freq = max($core_freq, $clock_freqs_current[0]); $mem_freq = max($mem_freq, $clock_freqs_current[1]); } } else { if (phodevi::is_ati_graphics() && phodevi::is_linux()) { $od_clocks = phodevi_linux_parser::read_ati_overdrive('CurrentPeak'); if (is_array($od_clocks) && count($od_clocks) >= 2) { list($core_freq, $mem_freq) = $od_clocks; } } else { if (phodevi::is_linux()) { $display_driver = phodevi::read_property('system', 'display-driver'); switch ($display_driver) { case '': case 'nouveau': if (is_file('/sys/class/drm/card0/device/performance_level')) { /* EXAMPLE OUTPUTS: memory 1000MHz core 500MHz voltage 1300mV fanspeed 100% 3: memory 333MHz core 500MHz shader 1250MHz fanspeed 100% c: memory 333MHz core 500MHz shader 1250MHz */ $performance_level = pts_file_io::file_get_contents('/sys/class/drm/card0/device/performance_level'); $performance_level = explode(' ', $performance_level); $core_string = array_search('core', $performance_level); if ($core_string !== false && isset($performance_level[$core_string + 1])) { $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]); if (is_numeric($core_string)) { $core_freq = $core_string; } } $mem_string = array_search('memory', $performance_level); if ($mem_string !== false && isset($performance_level[$mem_string + 1])) { $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]); if (is_numeric($mem_string)) { $mem_freq = $mem_string; } } } else { if (is_file('/sys/class/drm/card0/device/pstate')) { // pstate is present with Linux 3.13 as the new performance states on Fermi/Kepler $performance_state = pts_file_io::file_get_contents('/sys/class/drm/card0/device/pstate'); $performance_level = substr($performance_state, 0, strpos($performance_state, ' *')); if ($performance_level == null) { // Method for Linux 3.17+ $performance_level = substr($performance_state, strpos($performance_state, 'AC: ') + 4); if ($t = strpos($performance_level, PHP_EOL)) { $performance_level = substr($performance_level, 0, $t); } } else { // Method for Linux ~3.13 through Linux 3.16 $performance_level = substr($performance_level, strrpos($performance_level, ': ') + 2); } $performance_level = explode(' ', $performance_level); $core_string = array_search('core', $performance_level); if ($core_string !== false && isset($performance_level[$core_string + 1])) { $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]); if (strpos($core_string, '-') !== false) { // to work around a range of values, e.g. // 0a: core 405-1032 MHz memory 1620 MHz AC DC * $core_string = max(explode('-', $core_string)); } if (is_numeric($core_string)) { $core_freq = $core_string; } } $mem_string = array_search('memory', $performance_level); if ($mem_string !== false && isset($performance_level[$mem_string + 1])) { $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]); if (strpos($mem_string, '-') !== false) { // to work around a range of values, e.g. // 0a: core 405-1032 MHz memory 1620 MHz AC DC * $mem_string = max(explode('-', $mem_string)); } if (is_numeric($mem_string)) { $mem_freq = $mem_string; } } } } if ($display_driver != null) { break; } case 'radeon': if (isset(phodevi::$vfs->radeon_pm_info)) { // radeon_pm_info should be present with Linux 2.6.34+ but was changed with Linux 3.11 Radeon DPM if (stripos(phodevi::$vfs->radeon_pm_info, 'default')) { foreach (pts_strings::trim_explode("\n", phodevi::$vfs->radeon_pm_info) as $pm_line) { if ($pm_line == null) { continue; } list($descriptor, $value) = pts_strings::colon_explode($pm_line); switch ($descriptor) { case 'default engine clock': $core_freq = pts_arrays::first_element(explode(' ', $value)) / 1000; break; case 'default memory clock': $mem_freq = pts_arrays::first_element(explode(' ', $value)) / 1000; break; } } } if ($core_freq == 0 && ($x = stripos(phodevi::$vfs->radeon_pm_info, 'sclk: ')) != false) { $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('sclk: ')); $x = substr($x, 0, strpos($x, ' ')); if (is_numeric($x) && $x > 100) { if ($x > 10000) { $x = $x / 100; } $core_freq = $x; } if (($x = stripos(phodevi::$vfs->radeon_pm_info, 'mclk: ')) != false) { $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('mclk: ')); $x = substr($x, 0, strpos($x, ' ')); if (is_numeric($x) && $x > 100) { if ($x > 10000) { $x = $x / 100; } $mem_freq = $x; } } } } if ($core_freq == null) { // Attempt to read the LAST power level reported to dmesg, this is the current way for Radeon DPM on Linux 3.11+ $dmesg_parse = isset(phodevi::$vfs->dmesg) ? phodevi::$vfs->dmesg : null; if ($x = strrpos($dmesg_parse, ' sclk:')) { $dmesg_parse = substr($dmesg_parse, $x); $dmesg_parse = explode(' ', substr($dmesg_parse, 0, strpos($dmesg_parse, PHP_EOL))); $sclk = array_search('sclk:', $dmesg_parse); if ($sclk !== false && isset($dmesg_parse[$sclk + 1]) && is_numeric($dmesg_parse[$sclk + 1])) { $sclk = $dmesg_parse[$sclk + 1]; if ($sclk > 10000) { $sclk = $sclk / 100; } $core_freq = $sclk; } $mclk = array_search('mclk:', $dmesg_parse); if ($mclk !== false && isset($dmesg_parse[$mclk + 1]) && is_numeric($dmesg_parse[$mclk + 1])) { $mclk = $dmesg_parse[$mclk + 1]; if ($mclk > 10000) { $mclk = $mclk / 100; } $mem_freq = $mclk; } } } if ($core_freq == null) { // Old ugly way of handling the clock information $log_parse = isset(phodevi::$vfs->xorg_log) ? phodevi::$vfs->xorg_log : null; if ($engine_clock = strpos($log_parse, 'Default Engine Clock: ')) { $core_freq = substr($log_parse, $engine_clock + 22); $core_freq = substr($core_freq, 0, strpos($core_freq, "\n")); $core_freq = is_numeric($core_freq) ? $core_freq / 1000 : 0; if ($core_freq && ($mem_clock = strpos($log_parse, 'Default Memory Clock: '))) { $mem_freq = substr($log_parse, $mem_clock + 22); $mem_freq = substr($mem_freq, 0, strpos($mem_freq, "\n")); $mem_freq = is_numeric($mem_freq) ? $mem_freq / 1000 : 0; } else { $core_freq = 0; } } } if ($display_driver != null) { break; } case 'intel': // try to read the maximum dynamic frequency if (is_file('/sys/class/drm/card0/gt_max_freq_mhz')) { $gt_max_freq_mhz = pts_file_io::file_get_contents('/sys/class/drm/card0/gt_max_freq_mhz'); if (is_numeric($gt_max_freq_mhz) && $gt_max_freq_mhz > 100) { // Tested on Linux 3.11. Assume the max frequency on any competent GPU is beyond 100MHz $core_freq = $gt_max_freq_mhz; } } if ($core_freq == 0 && is_file('/sys/kernel/debug/dri/0/i915_max_freq')) { $i915_max_freq = pts_file_io::file_get_contents('/sys/kernel/debug/dri/0/i915_max_freq'); $freq_mhz = substr($i915_max_freq, strpos($i915_max_freq, ': ') + 2); if (is_numeric($freq_mhz)) { $core_freq = $freq_mhz; } } // Fallback to base frequency if ($core_freq == 0 && isset(phodevi::$vfs->i915_cur_delayinfo)) { $i915_cur_delayinfo = phodevi::$vfs->i915_cur_delayinfo; $freq = strpos($i915_cur_delayinfo, 'Max overclocked frequency: '); if ($freq === false) { $freq = strpos($i915_cur_delayinfo, 'Max non-overclocked (RP0) frequency: '); } if ($freq === false) { $freq = strpos($i915_cur_delayinfo, 'Nominal (RP1) frequency: '); } if ($freq !== false) { $freq_mhz = substr($i915_cur_delayinfo, strpos($i915_cur_delayinfo, ': ', $freq) + 2); $freq_mhz = trim(substr($freq_mhz, 0, strpos($freq_mhz, 'MHz'))); if (is_numeric($freq_mhz)) { $core_freq = $freq_mhz; } } } if ($display_driver != null) { break; } } } } } $core_freq = !is_numeric($core_freq) ? 0 : round($core_freq); $mem_freq = !is_numeric($mem_freq) ? 0 : round($mem_freq); return array($core_freq, $mem_freq); }