public static function run($r)
 {
     $compare_tests = array();
     $compare_subsystems = array();
     foreach ($r as $test_object) {
         $test_object = pts_types::identifier_to_object($test_object);
         if ($test_object instanceof pts_test_profile) {
             array_push($compare_tests, $test_object->get_identifier(false));
             if (!isset($compare_subsystems[$test_object->get_test_hardware_type()])) {
                 $compare_subsystems[$test_object->get_test_hardware_type()] = 1;
             } else {
                 $compare_subsystems[$test_object->get_test_hardware_type()] += 1;
             }
         }
     }
     if (empty($compare_tests)) {
         $subsystem_under_test = pts_user_io::prompt_text_menu('Sub-System To Test', array('Processor', 'Graphics', 'Disk'));
     } else {
         arsort($compare_subsystems);
         $compare_subsystems = array_keys($compare_subsystems);
         $subsystem_under_test = array_shift($compare_subsystems);
     }
     $system_info = array_merge(phodevi::system_hardware(false), phodevi::system_software(false));
     $to_include = array();
     $to_exclude = array();
     if (isset($system_info[$subsystem_under_test])) {
         $compare_component = $system_info[$subsystem_under_test];
     } else {
         return;
     }
     switch ($subsystem_under_test) {
         case 'Processor':
             self::system_component_to_format($system_info, $to_include, array('OS', 'Compiler', 'Kernel', 'Motherboard'), true);
             break;
         case 'Graphics':
             self::system_component_to_format($system_info, $to_include, array('OS', 'Display Driver', 'OpenGL', 'Processor', 'Kernel', 'Desktop'), true);
             break;
         case 'OS':
             self::system_component_to_format($system_info, $to_include, array('Processor', 'Motherboard', 'Graphics', 'Disk'), true);
             self::system_component_to_format($system_info, $to_exclude, array('OS'));
             break;
         case 'Disk':
             self::system_component_to_format($system_info, $to_include, array('Processor', 'OS', 'Chipset', 'Motherboard', 'Kernel'), true);
             break;
     }
     $payload = array('subsystem_under_test' => $subsystem_under_test, 'component_under_test' => $compare_component, 'include_components' => implode(',', $to_include), 'exclude_components' => implode(',', $to_exclude), 'include_tests' => implode(',', $compare_tests));
     echo PHP_EOL . 'Querying test data from OpenBenchmarking.org...' . PHP_EOL;
     $json = pts_openbenchmarking::make_openbenchmarking_request('auto_generate_comparison', $payload);
     $json = json_decode($json, true);
     if (isset($json['auto_compare']['public_ids']) && isset($json['auto_compare']['count']) && $json['auto_compare']['count'] > 0) {
         echo 'Found ' . $json['auto_compare']['count'] . ' comparable results on OpenBenchmarking.org with a ' . $json['auto_compare']['accuracy'] . '% accuracy.' . PHP_EOL;
         $compare_results = array();
         foreach ($json['auto_compare']['public_ids'] as $public_id) {
             $result_xml = pts_openbenchmarking::clone_openbenchmarking_result($public_id, true);
             if ($result_xml) {
                 $result_file = new pts_result_file($result_xml);
                 $result_objects = $result_file->get_result_objects();
                 foreach ($result_objects as $i => &$result_object) {
                     if (!empty($compare_tests)) {
                         if (!in_array($result_object->test_profile->get_identifier(false), $compare_tests)) {
                             unset($result_objects[$i]);
                         }
                     } else {
                         if ($result_object->test_profile->get_test_hardware_type() != $subsystem_under_test) {
                             unset($result_objects[$i]);
                         }
                     }
                 }
                 if (count($result_objects) == 0) {
                     continue;
                 }
                 $result_file->override_result_objects($result_objects);
                 array_push($compare_results, $result_file);
             }
         }
         if (count($compare_results) > 0) {
             $result_xml = pts_merge::merge_test_results_array($compare_results);
             if (count($compare_results) > 2) {
                 $result_file = new pts_result_file($result_xml);
                 $result_objects = $result_file->get_result_objects();
                 $system_count = $result_file->get_system_count();
                 $result_count = count($result_objects);
                 $result_match_count = array();
                 if ($result_count > 3) {
                     foreach ($result_objects as $i => &$result_object) {
                         $result_match_count[$i] = $result_object->test_result_buffer->get_count();
                     }
                     arsort($result_match_count);
                     $biggest_size = pts_arrays::first_element($result_match_count);
                     if ($biggest_size == $system_count || $biggest_size > 3) {
                         foreach ($result_match_count as $key => $value) {
                             if ($value < 2) {
                                 unset($result_objects[$key]);
                             }
                         }
                     }
                     $result_file->override_result_objects($result_objects);
                     $result_xml = pts_merge::merge_test_results_array(array($result_file));
                 }
             }
             pts_client::save_test_result('auto-comparison/composite.xml', $result_xml);
         }
     }
     pts_test_installer::standard_install(array('auto-comparison'));
     pts_test_run_manager::standard_run(array('auto-comparison'));
 }
 public static function evaluate_redundant_identifier_words($identifiers)
 {
     if (count($identifiers) < 4 || strpos(pts_arrays::first_element($identifiers), ':') !== false) {
         // Probably not worth shortening so few result identifiers
         return false;
     }
     // Breakup the an identifier into an array by spaces to be used for comparison
     $common_segments = explode(' ', pts_arrays::first_element($identifiers));
     $common_segments_last = explode(' ', pts_arrays::last_element($identifiers));
     if (!isset($common_segments_last[2]) || !isset($common_segments[2])) {
         // If there aren't at least three words in identifier, probably can't be shortened well
         return false;
     }
     foreach (array_reverse($identifiers) as $id) {
         $words = explode(' ', $id);
         foreach ($words as $i => $word) {
             if (isset($common_segments[$i]) && $word != $common_segments[$i] && isset($word[2]) && !ctype_alnum(substr($word, -1))) {
                 // IS COMMON WORD
             } else {
                 unset($common_segments[$i]);
             }
         }
         if (count($common_segments) == 0) {
             return false;
         }
     }
     return $common_segments;
 }
 public static function result_file_to_text(&$result_file, $terminal_width = 80)
 {
     $result_output = null;
     $result_output .= $result_file->get_title() . PHP_EOL;
     $result_output .= $result_file->get_description() . PHP_EOL . PHP_EOL . PHP_EOL;
     $system_identifiers = array();
     $system_hardware = array();
     $system_software = array();
     foreach ($result_file->get_systems() as $system) {
         array_push($system_identifiers, $system->get_identifier());
         array_push($system_hardware, $system->get_hardware());
         array_push($system_software, $system->get_software());
     }
     for ($i = 0; $i < count($system_identifiers); $i++) {
         $result_output .= $system_identifiers[$i] . ': ' . PHP_EOL . PHP_EOL;
         $result_output .= "\t" . $system_hardware[$i] . PHP_EOL . PHP_EOL . "\t" . $system_software[$i] . PHP_EOL . PHP_EOL;
     }
     $longest_identifier_length = strlen(pts_strings::find_longest_string($system_identifiers)) + 2;
     foreach ($result_file->get_result_objects() as $result_object) {
         $result_output .= trim($result_object->test_profile->get_title() . ' ' . $result_object->test_profile->get_app_version() . PHP_EOL . $result_object->get_arguments_description());
         if ($result_object->test_profile->get_result_scale() != null) {
             $result_output .= PHP_EOL . '  ' . $result_object->test_profile->get_result_scale();
         }
         foreach ($result_object->test_result_buffer as &$buffers) {
             $max_value = 0;
             $min_value = pts_arrays::first_element($buffers)->get_result_value();
             foreach ($buffers as &$buffer_item) {
                 if ($buffer_item->get_result_value() > $max_value) {
                     $max_value = $buffer_item->get_result_value();
                 } else {
                     if ($buffer_item->get_result_value() < $min_value) {
                         $min_value = $buffer_item->get_result_value();
                     }
                 }
             }
             $longest_result = strlen($max_value) + 1;
             foreach ($buffers as &$buffer_item) {
                 $val = $buffer_item->get_result_value();
                 if (stripos($val, ',') !== false) {
                     $vals = explode(',', $val);
                     $val = 'MIN: ' . min($vals) . ' / AVG: ' . round(array_sum($vals) / count($vals), 2) . ' / MAX: ' . max($vals);
                 }
                 $result_output .= PHP_EOL . '    ' . $buffer_item->get_result_identifier() . ' ';
                 $result_length_offset = $longest_identifier_length - strlen($buffer_item->get_result_identifier());
                 if ($result_length_offset > 0) {
                     $result_output .= str_repeat('.', $result_length_offset) . ' ';
                 }
                 $result_output .= $val;
                 if (is_numeric($val)) {
                     $result_output .= str_repeat(' ', $longest_result - strlen($val)) . '|';
                     $current_line_length = strlen(substr($result_output, strrpos($result_output, PHP_EOL) + 1)) + 1;
                     $result_output .= str_repeat('=', round($val / $max_value * ($terminal_width - $current_line_length)));
                 }
             }
         }
         $result_output .= PHP_EOL . PHP_EOL;
     }
     return $result_output;
 }
Esempio n. 4
0
 public static function environmental_variables()
 {
     // The PTS environmental variables passed during the testing process, etc
     static $env_variables = null;
     if ($env_variables == null) {
         $env_variables = array('PTS_VERSION' => PTS_VERSION, 'PTS_CODENAME' => PTS_CODENAME, 'PTS_DIR' => PTS_PATH, 'PHP_BIN' => PHP_BIN, 'NUM_CPU_CORES' => phodevi::read_property('cpu', 'core-count'), 'NUM_CPU_NODES' => phodevi::read_property('cpu', 'node-count'), 'NUM_CPU_JOBS' => phodevi::read_property('cpu', 'core-count') * 2, 'SYS_MEMORY' => phodevi::read_property('memory', 'capacity'), 'VIDEO_MEMORY' => phodevi::read_property('gpu', 'memory-capacity'), 'VIDEO_WIDTH' => pts_arrays::first_element(phodevi::read_property('gpu', 'screen-resolution')), 'VIDEO_HEIGHT' => pts_arrays::last_element(phodevi::read_property('gpu', 'screen-resolution')), 'VIDEO_MONITOR_COUNT' => phodevi::read_property('monitor', 'count'), 'VIDEO_MONITOR_LAYOUT' => phodevi::read_property('monitor', 'layout'), 'VIDEO_MONITOR_SIZES' => phodevi::read_property('monitor', 'modes'), 'OPERATING_SYSTEM' => phodevi::read_property('system', 'vendor-identifier'), 'OS_VERSION' => phodevi::read_property('system', 'os-version'), 'OS_ARCH' => phodevi::read_property('system', 'kernel-architecture'), 'OS_TYPE' => phodevi::operating_system(), 'THIS_RUN_TIME' => PTS_INIT_TIME, 'DEBUG_REAL_HOME' => pts_core::user_home_directory());
         if (!pts_client::executable_in_path('cc') && pts_client::executable_in_path('gcc') && getenv('CC') == false) {
             // This helps some test profiles build correctly if they don't do a cc check internally
             $env_variables['CC'] = 'gcc';
         }
     }
     return $env_variables;
 }
 public function increase_run_count_check(&$active_result_buffer, $scheduled_times_to_run, $latest_test_run_time)
 {
     // First make sure this test doesn't take too long to run where we don't want dynamic handling
     if (floor($latest_test_run_time / 60) > $this->dynamic_run_count_on_length_or_less) {
         return false;
     }
     // Determine if results are statistically significant, otherwise up the run count
     $std_dev = pts_math::percent_standard_deviation($active_result_buffer->results);
     if ($std_dev >= $this->dynamic_run_count_std_deviation_threshold) {
         static $last_run_count = 128;
         // just a number that should always cause the first check below to be true
         static $run_std_devs;
         $times_already_ran = $active_result_buffer->get_trial_run_count();
         if ($times_already_ran <= $last_run_count) {
             // We're now onto a new test so clear out the array
             $run_std_devs = array();
         }
         $last_run_count = $times_already_ran;
         $run_std_devs[$last_run_count] = $std_dev;
         // If we haven't reached scheduled times to run x 2, increase count straight away
         if ($times_already_ran < $scheduled_times_to_run * 2) {
             return true;
         } else {
             if ($times_already_ran < $scheduled_times_to_run * 3) {
                 // More aggressive determination whether to still keep increasing the run count
                 $first_and_now_diff = pts_arrays::first_element($run_std_devs) - pts_arrays::last_element($run_std_devs);
                 // Increasing the run count at least looks to be helping...
                 if ($first_and_now_diff > pts_arrays::first_element($run_std_devs) / 2) {
                     // If we are at least making progress in the right direction, increase the run count some more
                     return true;
                 }
                 // TODO: could add more checks and take better advantage of the array of data to better determine if it's still worth increasing
             }
         }
     }
     // Check to see if there is an external/custom script to export the results to in determining whether results are valid
     if (($ex_file = $this->dynamic_run_count_export_script) != null && is_executable($ex_file) || is_executable($ex_file = PTS_USER_PATH . $this->dynamic_run_count_export_script)) {
         $exit_status = trim(shell_exec($ex_file . ' ' . $active_result_buffer->get_values_as_string() . ' > /dev/null 2>&1; echo $?'));
         switch ($exit_status) {
             case 1:
                 // Run the test again
                 return true;
             case 2:
                 // Results are bad, abandon testing and do not record results
                 return -1;
             case 0:
             default:
                 // Return was 0 or something else, results are valid, or was some other exit status
                 break;
         }
     }
     // No reason to increase the run count with none of the previous checks requesting otherwise
     return false;
 }
 public static function cpu_default_frequency($cpu_core = 0)
 {
     // Find out the processor frequency
     $info = null;
     // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
     if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq')) {
         $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq');
         $info = intval($info) / 1000000;
         if ($info > 9) {
             // For some reason on Linux 3.10 the scaling_max_freq is reported as 25GHz...
             $info = null;
         }
     }
     if ($info == null && isset(phodevi::$vfs->cpuinfo)) {
         $cpu_mhz = self::read_cpuinfo_line('cpu MHz');
         $info = $cpu_mhz / 1000;
         if (empty($info)) {
             $cpu_mhz = self::read_cpuinfo_line('clock');
             $info = $cpu_mhz / 1000;
         }
     } else {
         if ($info == null && phodevi::is_bsd()) {
             $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq_levels'));
             if ($info != null) {
                 // Popping the top speed off of dev.cpu.0.freq_levels should be the default/highest supported frequency
                 $info = pts_arrays::first_element(explode(' ', str_replace('/', ' ', $info)));
                 if (!is_numeric($info)) {
                     $info = null;
                 }
             }
             if ($info == null) {
                 $info = phodevi_bsd_parser::read_sysctl(array('hw.acpi.cpu.px_global', 'machdep.est.frequency.target', 'hw.cpuspeed'));
             }
             if ($info == null) {
                 // dev.cpu.0.freq seems to be the real/current frequency, affected by power management, etc so only use as last fallback
                 $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq'));
             }
             if (is_numeric($info)) {
                 $info = $info / 1000;
             } else {
                 $info = null;
             }
         } else {
             if ($info == null && phodevi::is_windows()) {
                 $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Stock frequency');
                 if ($info != null) {
                     if (($e = strpos($info, ' MHz')) !== false) {
                         $info = substr($info, 0, $e);
                     }
                     $info = $info / 1000;
                 }
             } else {
                 if ($info == null) {
                     $info = phodevi::read_sensor(array('cpu', 'freq'));
                     if ($info > 1000) {
                         // Convert from MHz to GHz
                         $info = $info / 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }
 public function render_graph_dimensions()
 {
     $this->i['graph_max_value'] = $this->maximum_graph_value();
     $longest_identifier = $this->test_result->test_result_buffer->get_longest_identifier();
     // Make room for tick markings, left hand side
     if ($this->i['iveland_view'] == false) {
         if ($this->i['graph_value_type'] == 'NUMERICAL') {
             $this->i['left_start'] += self::text_string_width($this->i['graph_max_value'], self::$c['size']['tick_mark']) + 2;
         }
         if ($this->i['hide_graph_identifiers']) {
             $this->i['graph_top_end'] += $this->i['top_end_bottom'] / 2;
         }
         $this->i['top_start'] += $this->graph_key_height();
     } else {
         if ($this->i['graph_orientation'] == 'HORIZONTAL') {
             if ($this->is_multi_way_comparison && count($this->results) > 1) {
                 $longest_r = $longest_identifier;
                 $longest_r = explode(' - ', $longest_r);
                 $plus_extra = 0;
                 if (count($longest_r) > 1) {
                     $plus_extra = count($longest_r) * $this->i['identifier_size'] * 1.2;
                 }
                 $longest_identifier_width = self::text_string_width($this->i['graph_max_value'], $this->i['identifier_size']) + 60 + $plus_extra;
             } else {
                 $longest_identifier_width = self::text_string_width($longest_identifier, $this->i['identifier_size']) + 8;
             }
             $longest_identifier_max = $this->i['graph_width'] * 0.5 + 0.01;
             $this->i['left_start'] = min($longest_identifier_max, max($longest_identifier_width, 70));
             $this->i['left_end_right'] = 15;
             $this->i['graph_left_end'] = $this->i['graph_width'] - $this->i['left_end_right'];
         } else {
             if ($this->i['graph_value_type'] == 'NUMERICAL') {
                 $this->i['left_start'] += max(20, self::text_string_width($this->i['graph_max_value'] + 0.01, self::$c['size']['tick_mark']) + 2);
             }
         }
         // Pad 8px on top and bottom + title bar + sub-headings
         $this->i['top_heading_height'] = 16 + self::$c['size']['headers'] + count($this->graph_sub_titles) * (self::$c['size']['sub_headers'] + 4);
         if ($this->i['iveland_view']) {
             // Ensure there is enough room to print PTS logo
             $this->i['top_heading_height'] = max($this->i['top_heading_height'], 46);
         }
         $key_height = $this->graph_key_height();
         if ($key_height > $this->i['key_line_height']) {
             // Increase height so key doesn't take up too much room
             $this->i['graph_height'] += $key_height;
             $this->i['graph_top_end'] += $key_height;
         }
         $this->i['top_start'] = $this->i['top_heading_height'] + $key_height + 16;
         // + spacing before graph starts
         $bottom_heading = 14;
         if ($this->i['graph_orientation'] == 'HORIZONTAL') {
             if ($this->is_multi_way_comparison && count($this->results) > 1) {
                 $longest_string = explode(' - ', $longest_identifier);
                 $longest_string = pts_strings::find_longest_string($longest_string);
                 $rotated_text = round(self::text_string_width($longest_string, $this->i['identifier_size']) * 0.96);
                 $per_identifier_height = max(14 + 22 * count($this->results), $rotated_text);
             } else {
                 if (count($this->results) > 3) {
                     $per_identifier_height = count($this->results) * 18;
                 } else {
                     // If there's too much to plot, reduce the size so each graph doesn't take too much room
                     $id_count = count(pts_arrays::first_element($this->results));
                     if ($id_count < 10) {
                         $per_identifier_height = 46;
                     } else {
                         if ($id_count < 20) {
                             $per_identifier_height = 36;
                         } else {
                             if ($id_count <= 38) {
                                 $this->i['compact_result_view'] = true;
                                 $per_identifier_height = 30;
                             } else {
                                 $this->i['compact_result_view'] = true;
                                 $per_identifier_height = 26;
                             }
                         }
                     }
                 }
             }
             $num_identifiers = $this->test_result->test_result_buffer->get_count();
             $this->i['graph_top_end'] = $this->i['top_start'] + $num_identifiers * $per_identifier_height;
             // $this->i['top_end_bottom']
             $this->i['graph_height'] = $this->i['graph_top_end'] + 25 + $bottom_heading;
         } else {
             $this->i['graph_height'] += $bottom_heading + 4;
         }
         if (!empty($this->i['notes'])) {
             $this->i['graph_height'] += $this->note_display_height();
         }
     }
 }
 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);
 }
 public static function memory_string()
 {
     $mem_string = null;
     $mem_prefix = null;
     $mem_size = false;
     $mem_speed = false;
     $mem_type = false;
     $mem_manufacturer = false;
     $mem_part = false;
     if (phodevi::is_macosx()) {
         $mem_size = phodevi_osx_parser::read_osx_system_profiler('SPMemoryDataType', 'Size', true, array('Empty'));
         $mem_speed = phodevi_osx_parser::read_osx_system_profiler('SPMemoryDataType', 'Speed');
         $mem_type = phodevi_osx_parser::read_osx_system_profiler('SPMemoryDataType', 'Type');
     } else {
         if (phodevi::is_solaris()) {
             $mem_size = phodevi_solaris_parser::read_sun_ddu_dmi_info('MemoryDevice*,InstalledSize');
             $mem_speed = phodevi_solaris_parser::read_sun_ddu_dmi_info('MemoryDevice*,Speed');
             $mem_type = phodevi_solaris_parser::read_sun_ddu_dmi_info('MemoryDevice*,MemoryDeviceType');
             if (is_array($mem_speed) && count($mem_speed) > 0) {
                 $mem_speed = array_shift($mem_speed);
             }
             $mem_speed = str_replace('MHZ', 'MHz', $mem_speed);
         } else {
             if (phodevi::is_windows()) {
                 $mem_size = phodevi_windows_parser::read_cpuz('DIMM #', 'Size', true);
                 foreach ($mem_size as $key => &$individual_size) {
                     $individual_size = pts_arrays::first_element(explode(' ', $individual_size));
                     if (!is_numeric($individual_size)) {
                         unset($mem_size[$key]);
                     }
                 }
                 $mem_type = phodevi_windows_parser::read_cpuz('Memory Type', null);
                 $mem_speed = intval(phodevi_windows_parser::read_cpuz('Memory Frequency', null)) . 'MHz';
             } else {
                 if (phodevi::is_linux()) {
                     $mem_size = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Size', false, array('Not Installed', 'No Module Installed', 'Undefined'));
                     $mem_speed = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Speed', true, array('Unknown', 'Undefined'));
                     $mem_type = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Type', true, array('Unknown', 'Other', 'Flash', 'Undefined'));
                     $mem_manufacturer = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Manufacturer', true, array('Unknown', 'Undefined'));
                     $mem_part = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Part Number', true, array('Unknown', 'Undefined'));
                 }
             }
         }
     }
     if (is_array($mem_type)) {
         $mem_type = array_pop($mem_type);
     }
     if ($mem_size != false && (!is_array($mem_size) || count($mem_size) != 0)) {
         for ($i = 0; $i < count($mem_size); $i++) {
             switch (substr($mem_size[$i], -1)) {
                 case 'K':
                     // looks like sometimes Solaris now reports flash chip as memory. its string ends with K
                     unset($mem_size[$i]);
                     unset($mem_speed[$i]);
                     unset($mem_type[$i]);
                     break;
                 case 'M':
                     // report megabytes as MB, just not M, as on Solaris
                     $mem_size[$i] .= 'B';
                     break;
                 case 'B':
                     if (strtolower(substr($mem_size[$i], -2, 1)) == 'k') {
                         // some hardware on Linux via dmidecode reports flash chips
                         unset($mem_size[$i]);
                         //unset($mem_speed[$i]);
                         //unset($mem_type[$i]);
                     }
                     break;
             }
         }
         foreach ($mem_size as $i => $mem_stick) {
             if (!is_numeric(substr($mem_stick, 0, 3)) && stripos($mem_stick, 'GB') == false) {
                 // If the memory size isn't at least three digits (basically 128MB+), chances are something is wrong, i.e. reporting flash chip from dmidecode, so get rid of it.
                 unset($mem_size[$i]);
             }
         }
         $mem_count = count($mem_size);
         if (!empty($mem_type)) {
             if (($cut = strpos($mem_type, ' ')) > 0) {
                 $mem_type = substr($mem_type, 0, $cut);
             }
             if (!in_array($mem_type, array('Other')) && (pts_strings::keep_in_string($mem_type, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_LETTER) == $mem_type || phodevi::is_windows())) {
                 $mem_prefix = $mem_type;
             }
         } else {
             $mem_prefix = null;
         }
         if (!empty($mem_speed)) {
             if (($cut = strpos($mem_speed, ' (')) > 0) {
                 $mem_speed = substr($mem_speed, 0, $cut);
             }
             if (!empty($mem_prefix)) {
                 $mem_prefix .= '-';
             }
             $mem_prefix .= str_replace(' ', null, $mem_speed);
         }
         // TODO: Allow a combination of both functions below, so like 2 x 2GB + 3 x 1GB DDR2-800
         if ($mem_count > 1 && count(array_unique($mem_size)) > 1) {
             $mem_string = implode(' + ', $mem_size) . ' ' . $mem_prefix;
         } else {
             if ($mem_count * $mem_size[0] != phodevi::read_property('memory', 'capacity') && phodevi::read_property('memory', 'capacity') % $mem_size[0] == 0) {
                 // This makes sure the correct number of RAM modules is reported...
                 // On at least Linux with dmidecode on an AMD Opteron multi-socket setup it's only showing the data for one socket
                 if ($mem_size[0] < 1024) {
                     $mem_size[0] *= 1024;
                 }
                 $mem_count = phodevi::read_property('memory', 'capacity') / $mem_size[0];
             }
             $product_string = null;
             if (isset($mem_manufacturer[2]) && ctype_alpha($mem_manufacturer[0]) && stripos($mem_manufacturer, 'manufacturer') === false && stripos($mem_manufacturer, 'part') === false && stripos($mem_manufacturer, 'module') === false && stripos($mem_manufacturer, 'dimm') === false && isset($mem_manufacturer[2]) && ctype_alpha($mem_manufacturer)) {
                 $product_string .= ' ' . $mem_manufacturer;
             }
             if (isset($mem_part[2]) && stripos($mem_part, 'part') === false && stripos($mem_part, 'module') === false && stripos($mem_part, 'dimm') === false && substr($mem_part, 0, 2) != '0x' && !isset($mem_part[24]) && ctype_alnum($mem_part)) {
                 $product_string .= ' ' . $mem_part;
             }
             if (is_numeric($mem_size[0]) && stripos($mem_size[0], 'b') === false) {
                 if ($mem_size >= 1024) {
                     $mem_size[0] .= ' MB';
                 } else {
                     $mem_size[0] .= ' GB';
                 }
             }
             $mem_string = $mem_count . ' x ' . $mem_size[0] . ' ' . $mem_prefix . $product_string;
         }
     }
     if (empty($mem_string)) {
         $mem_string = phodevi::read_property('memory', 'capacity');
         if ($mem_string != null) {
             $mem_string .= 'MB';
         }
     }
     return trim($mem_string);
 }
 public static function mem_usage($TYPE = 'TOTAL', $READ = 'USED')
 {
     // Reads system memory usage
     $mem_usage = -1;
     if (pts_client::executable_in_path('free') != false) {
         $mem = explode("\n", shell_exec('free -t -m 2>&1'));
         $grab_line = null;
         $buffers_and_cache = 0;
         for ($i = 0; $i < count($mem); $i++) {
             $line_parts = pts_strings::colon_explode($mem[$i]);
             if (count($line_parts) == 2) {
                 $line_type = $line_parts[0];
                 if ($TYPE == 'MEMORY' && $line_type == 'Mem') {
                     $grab_line = $line_parts[1];
                 } else {
                     if ($TYPE == 'SWAP' && $line_type == 'Swap') {
                         $grab_line = $line_parts[1];
                     } else {
                         if ($TYPE == 'TOTAL' && $line_type == 'Total') {
                             $grab_line = $line_parts[1];
                         } else {
                             if ($line_type == '-/+ buffers/cache' && $TYPE != 'SWAP') {
                                 $buffers_and_cache = pts_arrays::first_element(explode(' ', pts_strings::trim_spaces($line_parts[1])));
                             }
                         }
                     }
                 }
             }
         }
         if (!empty($grab_line)) {
             $grab_line = pts_strings::trim_spaces($grab_line);
             $mem_parts = explode(' ', $grab_line);
             if ($READ == 'USED') {
                 if (count($mem_parts) >= 2 && is_numeric($mem_parts[1])) {
                     $mem_usage = $mem_parts[1] - $buffers_and_cache;
                 }
             } else {
                 if ($READ == 'TOTAL') {
                     if (count($mem_parts) >= 1 && is_numeric($mem_parts[0])) {
                         $mem_usage = $mem_parts[0];
                     }
                 } else {
                     if ($READ == 'FREE') {
                         if (count($mem_parts) >= 3 && is_numeric($mem_parts[2])) {
                             $mem_usage = $mem_parts[2];
                         }
                     }
                 }
             }
         }
     } else {
         if (pts_client::executable_in_path('vm_stat') != false) {
             $vmstats = explode("\n", shell_exec('vm_stat 2>&1'));
             $grab_line = null;
             // buffers_and_cache
             foreach ($vmstats as $vmstat_line) {
                 $line_parts = pts_strings::colon_explode($vmstat_line);
                 if (self::$page_size == -1) {
                     strtok($vmstat_line, ':');
                     $tok = strtok(' ');
                     while (self::$page_size == -1) {
                         if (is_numeric($tok)) {
                             self::$page_size = $tok;
                         } else {
                             $tok = strtok(' ');
                         }
                     }
                     continue;
                 }
                 //$line_parts[1] = pts_strings::trim_spaces($line_parts[1]);
                 $line_type = strtok($vmstat_line, ':');
                 $line_value = strtok(' .');
                 if ($TYPE == 'MEMORY') {
                     if ($line_type == 'Pages active' && $READ == 'USED') {
                         $mem_usage = $line_value / (1048576 / self::$page_size);
                         break;
                     }
                     if ($line_type == 'Pages free' && $READ == 'FREE') {
                         $mem_usage = $line_value / (1048576 / self::$page_size);
                         break;
                     }
                 }
             }
             $mem_usage = pts_math::set_precision($mem_usage);
         }
     }
     return $mem_usage;
 }