made code style compliant with pep8 conventions
This commit is contained in:
		
							parent
							
								
									9de8a22cd0
								
							
						
					
					
						commit
						f1f8686373
					
				
							
								
								
									
										122
									
								
								concho/config.py
								
								
								
								
							
							
						
						
									
										122
									
								
								concho/config.py
								
								
								
								
							|  | @ -1,9 +1,10 @@ | |||
| import re | ||||
| from abc import ABCMeta, abstractmethod | ||||
| from abc import abstractmethod | ||||
| import numpy | ||||
| from concho import dell | ||||
| # from concho import dell | ||||
| import math | ||||
| 
 | ||||
| 
 | ||||
| class Item(): | ||||
| 
 | ||||
|     def __init__(self, uid): | ||||
|  | @ -22,6 +23,7 @@ class Chassis(Item): | |||
|             self.max_num_servers = 4 | ||||
|         self.num_dimm_slots_per_channel = 2 | ||||
| 
 | ||||
| 
 | ||||
| class Dimm(Item): | ||||
| 
 | ||||
|     def __init__(self, num_gb, num_mhz, mem_type): | ||||
|  | @ -88,7 +90,7 @@ class Cpu(Item): | |||
|             return 'milan' | ||||
|         else: | ||||
|             assert False, 'unhandled processor id : %s' % proc_id | ||||
|      | ||||
| 
 | ||||
|     @property | ||||
|     def num_dp_flop_per_cycle(self): | ||||
|         proc_arch = self.architecture | ||||
|  | @ -102,7 +104,7 @@ class Cpu(Item): | |||
|             # https://en.wikichip.org/wiki/intel/xeon_gold/5222 : 'Note that this is the only processor in the Xeon Gold 52xx series with two 512b FMA units.' | ||||
|             if re.match('intel-xeon-gold-5222', self.uid): | ||||
|                 num_simd_per_core = 2 | ||||
|                  | ||||
| 
 | ||||
|             if re.match('intel-xeon-gold-61[0-9][0-9]', self.uid): | ||||
|                 num_simd_per_core = 2 | ||||
|             if re.match('intel-xeon-gold-62[0-9][0-9]', self.uid): | ||||
|  | @ -134,80 +136,83 @@ class Cpu(Item): | |||
|             'rome': 8 | ||||
|         }[self.architecture] | ||||
| 
 | ||||
| 
 | ||||
| def get_proc_architecture(proc_id): | ||||
|     return Cpu(proc_id).architecture | ||||
| 
 | ||||
| def get_proc_arch_transistor_size(proc_id):  | ||||
| 
 | ||||
| def get_proc_arch_transistor_size(proc_id): | ||||
|     return { | ||||
|         'woodcrest':65, | ||||
|         'harpertown':45, | ||||
|         'gainestown':45, | ||||
|         'gulftown':32, | ||||
|         'sandy bridge':32, | ||||
|         'ivy bridge':22, | ||||
|         'haswell':22, | ||||
|         'broadwell':14, | ||||
|         'skylake':14, | ||||
|         'coffeelake':14, | ||||
|         'cascadelake':14 | ||||
|         }[get_proc_architecture(proc_id)] | ||||
|         'woodcrest': 65, | ||||
|         'harpertown': 45, | ||||
|         'gainestown': 45, | ||||
|         'gulftown': 32, | ||||
|         'sandy bridge': 32, | ||||
|         'ivy bridge': 22, | ||||
|         'haswell': 22, | ||||
|         'broadwell': 14, | ||||
|         'skylake': 14, | ||||
|         'coffeelake': 14, | ||||
|         'cascadelake': 14 | ||||
|     }[get_proc_architecture(proc_id)] | ||||
| 
 | ||||
| 
 | ||||
| def simd_id_to_dp_flops_per_cycle(simd_id): | ||||
|     """ | ||||
|     :param str simd_id: eg 'avx2' | ||||
|      | ||||
| 
 | ||||
|     """ | ||||
|     # from https://stackoverflow.com/questions/15655835/flops-per-cycle-for-sandy-bridge-and-haswell-sse2-avx-avx2 | ||||
|     # Intel Core 2 and Nehalem: | ||||
|     #  | ||||
|     # | ||||
|     #     4 DP FLOPs/cycle: 2-wide SSE2 addition + 2-wide SSE2 multiplication | ||||
|     #     8 SP FLOPs/cycle: 4-wide SSE addition + 4-wide SSE multiplication | ||||
|     #  | ||||
|     # | ||||
|     # Intel Sandy Bridge/Ivy Bridge: | ||||
|     #  | ||||
|     # | ||||
|     #     8 DP FLOPs/cycle: 4-wide AVX addition + 4-wide AVX multiplication | ||||
|     #     16 SP FLOPs/cycle: 8-wide AVX addition + 8-wide AVX multiplication | ||||
|     #  | ||||
|     # | ||||
|     # Intel Haswell/Broadwell/Skylake/Kaby Lake: | ||||
|     #  | ||||
|     # | ||||
|     #     16 DP FLOPs/cycle: two 4-wide FMA (fused multiply-add) instructions | ||||
|     #     32 SP FLOPs/cycle: two 8-wide FMA (fused multiply-add) instructions | ||||
| 
 | ||||
|     # https://www.dell.com/support/kbdoc/fr-fr/000137696/amd-rome-is-it-for-real-architecture-and-initial-hpc-performance | ||||
|     # The Rome micro-architecture can retire 16 DP FLOP/cycle, double that of Naples which was 8 FLOPS/cycle | ||||
| 
 | ||||
|     return {     | ||||
|         'sse4.1':4, | ||||
|         'sse4.2':4, | ||||
|         'avx':8, | ||||
|         'avx2':16, | ||||
|         'avx-512':16, | ||||
|         }[simd_id] | ||||
|      | ||||
|     return { | ||||
|         'sse4.1': 4, | ||||
|         'sse4.2': 4, | ||||
|         'avx': 8, | ||||
|         'avx2': 16, | ||||
|         'avx-512': 16, | ||||
|     }[simd_id] | ||||
| 
 | ||||
| 
 | ||||
| def get_simd_id(proc_arch): | ||||
|     """ | ||||
|         :param str proc_arch: eg 'broadwell' | ||||
|         :return str: eg 'sse4' | ||||
|     """ | ||||
|     return { | ||||
|         'woodcrest':'sse4.1', | ||||
|         'harpertown':'sse4.1', | ||||
|         'gainestown':'sse4.2', | ||||
|         'gulftown':'sse4.2', | ||||
|         'sandy bridge':'avx', | ||||
|         'ivy bridge':'avx', | ||||
|         'haswell':'avx2', | ||||
|         'broadwell':'avx2', | ||||
|         'skylake':'avx-512', | ||||
|         'cascadelake':'avx-512', | ||||
|         'coffeelake':'avx2', | ||||
|         'woodcrest': 'sse4.1', | ||||
|         'harpertown': 'sse4.1', | ||||
|         'gainestown': 'sse4.2', | ||||
|         'gulftown': 'sse4.2', | ||||
|         'sandy bridge': 'avx', | ||||
|         'ivy bridge': 'avx', | ||||
|         'haswell': 'avx2', | ||||
|         'broadwell': 'avx2', | ||||
|         'skylake': 'avx-512', | ||||
|         'cascadelake': 'avx-512', | ||||
|         'coffeelake': 'avx2', | ||||
|         # from https://www.microway.com/knowledge-center-articles/detailed-specifications-of-the-amd-epyc-rome-cpus/: | ||||
|         # - Full support for 256-bit AVX2 instructions with two 256-bit FMA units per CPU core. The previous “Naples” architecture split 256-bit instructions into two separate 128-bit operations | ||||
|         # - Up to 16 double-precision FLOPS per cycle per core | ||||
|         # - Double-precision floating point multiplies complete in 3 cycles (down from 4) | ||||
|         'rome': 'avx2', | ||||
|         }[proc_arch] | ||||
| 
 | ||||
|     }[proc_arch] | ||||
| 
 | ||||
| 
 | ||||
| class MemChannel(): | ||||
|  | @ -215,11 +220,13 @@ class MemChannel(): | |||
|     def __init__(self): | ||||
|         self.dimms = [] | ||||
| 
 | ||||
| 
 | ||||
| class CpuSlotMem(): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         self.mem_channels = [] | ||||
| 
 | ||||
| 
 | ||||
| class Config(): | ||||
| 
 | ||||
|     def __init__(self, configurator): | ||||
|  | @ -229,14 +236,13 @@ class Config(): | |||
|         self.cpu = None | ||||
|         self.cpu_slots_mem = [] | ||||
| 
 | ||||
| 
 | ||||
|     @property | ||||
|     def chassis(self): | ||||
|         return self.configurator.chassis.item | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def _find_dimm_combination(num_dimm_slots_per_channel, min_ram_per_channel, available_dimms): | ||||
|         available_dimms.append(Option(Dimm(0,0,'dummy'), 0.0))  # fake dimm to represent empty slot | ||||
|         available_dimms.append(Option(Dimm(0, 0, 'dummy'), 0.0))  # fake dimm to represent empty slot | ||||
|         slot_options = [] | ||||
| 
 | ||||
|         # try all combinations of dimms | ||||
|  | @ -245,7 +251,7 @@ class Config(): | |||
|         for slot_index in range(num_dimm_slots_per_channel): | ||||
|             slot_options.append(0) | ||||
|         no_more_configs = False | ||||
|         while no_more_configs == False: | ||||
|         while no_more_configs is False: | ||||
|             config_capacity = 0 | ||||
|             config_price = 0 | ||||
|             for slot_index in range(num_dimm_slots_per_channel): | ||||
|  | @ -263,7 +269,7 @@ class Config(): | |||
|                     break | ||||
|                 else: | ||||
|                     if slot_index == num_dimm_slots_per_channel - 1: | ||||
|                         no_more_configs = True # all combinations of dimm in the slots have been covered | ||||
|                         no_more_configs = True  # all combinations of dimm in the slots have been covered | ||||
|                     else: | ||||
|                         slot_options[slot_index] = 0 | ||||
| 
 | ||||
|  | @ -280,7 +286,7 @@ class Config(): | |||
| 
 | ||||
|         # ramUpgradePrice128Gb = { | ||||
|         #     'c6220':3520.0, | ||||
|         #     'r620':2010.0,  | ||||
|         #     'r620':2010.0, | ||||
|         #     'r630':1778.0, | ||||
|         #     'r640':1780.0, | ||||
|         #     'r730':1778.0, | ||||
|  | @ -337,13 +343,13 @@ class Config(): | |||
| 
 | ||||
|     def get_price(self): | ||||
|         price = self.configurator.chassis.price | ||||
|          | ||||
| 
 | ||||
|         price += self.num_servers * self.num_cpu_per_server * self.configurator.get_item_price(self.cpu.uid) + self.ram_price | ||||
|         assert price > 0.0 | ||||
|         return price | ||||
| 
 | ||||
|     def get_power_consumption(self): | ||||
|         server_base_power_consumption = 100.0 # rough estimation in watts | ||||
|         server_base_power_consumption = 100.0  # rough estimation in watts | ||||
|         power_consumption = (self.cpu.tdp * self.num_cpu_per_server + server_base_power_consumption) * self.num_servers | ||||
|         return power_consumption | ||||
| 
 | ||||
|  | @ -351,7 +357,6 @@ class Config(): | |||
|         flops = self.cpu.num_dp_flop_per_cycle * self.cpu.clock * 1.e9 * self.cpu.num_cores * self.num_cpu_per_server * self.num_servers | ||||
|         return flops | ||||
| 
 | ||||
| 
 | ||||
|     def _init_dimm_slots(self): | ||||
|         # create the dimm slots | ||||
|         self.cpu_slots_mem = [] | ||||
|  | @ -361,7 +366,7 @@ class Config(): | |||
| 
 | ||||
|         for cpu_index in range(self.num_cpu_per_server): | ||||
|             cpu_slot_mem = CpuSlotMem() | ||||
|              | ||||
| 
 | ||||
|             for channel_index in range(self.cpu.num_ram_channels): | ||||
|                 mem_channel = MemChannel() | ||||
|                 for dimm_slot_index in range(self.configurator.chassis.item.num_dimm_slots_per_channel): | ||||
|  | @ -388,12 +393,14 @@ class Config(): | |||
|     def num_cpus(self): | ||||
|         return self.num_cpu_per_server * self.num_servers | ||||
| 
 | ||||
| 
 | ||||
| class Option(): | ||||
| 
 | ||||
|     def __init__(self, item, price): | ||||
|         self.item = item | ||||
|         self.price = price | ||||
| 
 | ||||
| 
 | ||||
| class Module(): | ||||
| 
 | ||||
|     def __init__(self, name): | ||||
|  | @ -443,6 +450,7 @@ class Configurator(): | |||
|             if item_uid in module.options: | ||||
|                 return module.options[item_uid].price | ||||
| 
 | ||||
| 
 | ||||
| class TableBasedConfigurator(Configurator): | ||||
| 
 | ||||
|     def __init__(self, host_type_id, num_cpu_per_server, num_servers=1): | ||||
|  | @ -453,7 +461,7 @@ class TableBasedConfigurator(Configurator): | |||
|         self.base_config = Config(self) | ||||
|         self.base_config.num_servers = self.num_servers | ||||
|         self.base_config.num_cpu_per_server = self.num_cpu_per_server | ||||
|          | ||||
| 
 | ||||
|     @abstractmethod | ||||
|     def get_empty_price(self): | ||||
|         pass | ||||
|  | @ -469,7 +477,7 @@ class TableBasedConfigurator(Configurator): | |||
|     @abstractmethod | ||||
|     def get_disk_upgrade_price(self, disk_capacity): | ||||
|         pass | ||||
|              | ||||
| 
 | ||||
|     def get_cpu_options(self): | ||||
|         supported_cpus = [] | ||||
|         for host_type_id, proc_id, proc_option_price in zip(self.dell_price_table['host_type_id'], self.dell_price_table['proc_id'], self.dell_price_table['proc_option_price']): | ||||
|  | @ -497,8 +505,4 @@ class TableBasedConfigurator(Configurator): | |||
| #         return dell.DellPrecision3630(host_type_id) | ||||
| #     assert False | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     # dom = parse(dell_configurator_html_file_path) | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ from concho.config import Config | |||
| from concho.config import Chassis | ||||
| from concho.config import Cpu, Dimm | ||||
| 
 | ||||
| from abc import ABCMeta, abstractmethod | ||||
| from xml.dom.minidom import parse | ||||
| from abc import abstractmethod | ||||
| # from xml.dom.minidom import parse | ||||
| from lxml.html import parse | ||||
| import re | ||||
| import copy | ||||
|  | @ -79,12 +79,12 @@ class DellPowerEdgeR630(TableBasedConfigurator): | |||
|         assert 1.9e12 < asked_disk_capacity < 2.1e12, 'only 2To upgrades are handled for %s' % self.host_type_id | ||||
|         return 0.0 * self.num_servers | ||||
| 
 | ||||
| 
 | ||||
| class DellPowerEdgeR730(TableBasedConfigurator): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         super().__init__('r730', num_cpu_per_server=2, num_servers=1) | ||||
| 
 | ||||
| 
 | ||||
|     def get_empty_price(self): | ||||
|         # for r730 on 06/10/2016 | ||||
|         #   (x: price without procs, p1 : price of e5-2603v4, p2: price of e5-2609v4) | ||||
|  | @ -106,6 +106,7 @@ class DellPowerEdgeR730(TableBasedConfigurator): | |||
|         assert 1.9e12 < asked_disk_capacity < 2.1e12, 'only 2To upgrades are handled for %s' % self.host_type_id | ||||
|         return 0.0 * self.num_servers | ||||
| 
 | ||||
| 
 | ||||
| class DellPowerEdgeC4130(TableBasedConfigurator): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|  | @ -302,6 +303,7 @@ class DellPrecision3630(TableBasedConfigurator): | |||
|         assert 1.9e12 < asked_disk_capacity < 2.1e12, 'only 2To upgrades are handled for %s' % self.host_type_id | ||||
|         return 0.0 | ||||
| 
 | ||||
| 
 | ||||
| class DellPowerEdgeC6420(TableBasedConfigurator): | ||||
| 
 | ||||
|     def __init__(self, host_type_id): | ||||
|  | @ -309,15 +311,15 @@ class DellPowerEdgeC6420(TableBasedConfigurator): | |||
| 
 | ||||
|     def get_empty_price(self): | ||||
|         # for 4xc6420 on 19/06/2020 (from excel quotation) | ||||
|         #  | ||||
|         #  | ||||
|         # | ||||
|         # | ||||
|         #   (x: price without procs, p2630: price of xeon gold 6230) | ||||
|         # x + 4 x (2 x p4210r + p48g) =  5368 € HT | ||||
|         # x + 4 x (2 x p6230r + p192g) = 27213 € HT | ||||
|         #  | ||||
|         # | ||||
|         # p48g = 3 * 160.0  # the price of a 16G ram is 160.0 € | ||||
|         # p4210r = p4210r=978./2 # from r640 prices | ||||
|         #  | ||||
|         # | ||||
| 
 | ||||
|         # >>> p4210r=978./2 | ||||
|         # >>> p6230r_upgrade = 13408.0 | ||||
|  | @ -329,7 +331,7 @@ class DellPowerEdgeC6420(TableBasedConfigurator): | |||
|         # 2165.0 | ||||
| 
 | ||||
|         # => p4210r seems to be the same on r640 and c6420 | ||||
|         #  | ||||
|         # | ||||
|         # pc6000 = 5368 - (p4210r * num_cpu_per_server + p48g) * num_servers_per_c6000 | ||||
|         # >>> p16g = 160.0 | ||||
|         # >>> p48g = p16g * 3 | ||||
|  | @ -349,8 +351,8 @@ class DellPowerEdgeC6420(TableBasedConfigurator): | |||
|         # 27213.0 | ||||
|         num_servers_per_c6000 = 4 | ||||
|         num_cpu_per_server = 2 | ||||
|         ram_price_per_gigabyte = 160.0 / 16 # 16G ram price : 160.0 € | ||||
|         xeon_silver_4210r_price = 978.0 / 2 # from r640 prices | ||||
|         ram_price_per_gigabyte = 160.0 / 16  # 16G ram price : 160.0 € | ||||
|         xeon_silver_4210r_price = 978.0 / 2  # from r640 prices | ||||
|         basic_config_price = 5368.0 | ||||
|         poweredge_c6000_price = basic_config_price - (xeon_silver_4210r_price * num_cpu_per_server + ram_price_per_gigabyte * 48) * num_servers_per_c6000 | ||||
|         return poweredge_c6000_price | ||||
|  | @ -379,8 +381,6 @@ class DellPowerEdgeC6420(TableBasedConfigurator): | |||
|         return 361.0 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class DellConfiguratorParser(): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|  | @ -414,7 +414,7 @@ class DellConfiguratorParser(): | |||
|     @abstractmethod | ||||
|     def price_str_as_float(self, price_as_str): | ||||
|         assert False | ||||
|      | ||||
| 
 | ||||
|     @abstractmethod | ||||
|     def get_module_label(self, module_id): | ||||
|         assert False | ||||
|  | @ -429,7 +429,7 @@ class DellConfiguratorParser(): | |||
| 
 | ||||
|     def _parse_proc_change_options(self, html_root): | ||||
|         proc_options = Module('processor-change') | ||||
|         #module_root_element = self._get_module(html_root, 'Processeurs (Passage)') | ||||
|         # module_root_element = self._get_module(html_root, 'Processeurs (Passage)') | ||||
|         module_root_element = self._get_module(html_root, self.get_module_label('cpu_change')) | ||||
|         for option_root_element in module_root_element.xpath(self.get_xpath_filter('module_to_options')): | ||||
|             label_elements = option_root_element.xpath(self.get_xpath_filter('option_to_label')) | ||||
|  | @ -469,7 +469,7 @@ class DellConfiguratorParser(): | |||
| 
 | ||||
|     def _parse_proc_options(self, html_root): | ||||
|         proc_options = Module('processor') | ||||
|         #module_root_element = self._get_module(html_root, 'Processeurs (Passage)') | ||||
|         # module_root_element = self._get_module(html_root, 'Processeurs (Passage)') | ||||
|         module_root_element = self._get_module(html_root, self.get_module_label('additional_cpus')) | ||||
|         if module_root_element is not None: | ||||
|             for option_root_element in module_root_element.xpath(self.get_xpath_filter('module_to_options')): | ||||
|  | @ -498,7 +498,7 @@ class DellConfiguratorParser(): | |||
| 
 | ||||
|     def _parse_ram_options(self, html_root): | ||||
|         ram_options = Module('ram') | ||||
|         #module_root_element = self._get_module(html_root, 'Processeurs (Passage)') | ||||
|         # module_root_element = self._get_module(html_root, 'Processeurs (Passage)') | ||||
|         module_root_element = self._get_module(html_root, self.get_module_label('ram_additions')) | ||||
|         for option_root_element in module_root_element.xpath(self.get_xpath_filter('module_to_options')): | ||||
|             label_elements = option_root_element.xpath(self.get_xpath_filter('option_to_label')) | ||||
|  | @ -554,10 +554,10 @@ class DellConfiguratorParser(): | |||
|                 cpu_id = "intel-xeon-%s-%s" % (match['cpu_class'].lower(), match['cpu_number'].lower()) | ||||
|         if match is None: | ||||
|             print('item_label=%s' % item_label) | ||||
|              | ||||
|             #match = re.match(r'^2 Processeurs AMD EPYC (?P<cpu_number>[0-9][0-9][0-9][0-9]).*', item_label) | ||||
| 
 | ||||
|             # match = re.match(r'^2 Processeurs AMD EPYC (?P<cpu_number>[0-9][0-9][0-9][0-9]).*', item_label) | ||||
|             match = re.match(r'^2 Processeurs AMD EPYC (?P<cpu_number>[0-9][0-9][0-9][0-9]).*', clean_string(item_label)) | ||||
|              | ||||
| 
 | ||||
|             if match: | ||||
|                 base_config.num_cpu_per_server = 2 | ||||
|                 cpu_id = "amd-epyc-%s" % (match['cpu_number'].lower()) | ||||
|  | @ -618,7 +618,7 @@ class DellConfiguratorParser(): | |||
|                 if base_cpu_price is None: | ||||
|                     base_cpu_price = deduced_base_cpu_price | ||||
|                 else: | ||||
|                     assert abs(base_cpu_price-deduced_base_cpu_price) <= 0.01 | ||||
|                     assert abs(base_cpu_price - deduced_base_cpu_price) <= 0.01 | ||||
| 
 | ||||
|         return base_cpu_price | ||||
| 
 | ||||
|  | @ -635,14 +635,13 @@ class DellConfiguratorParser(): | |||
|         # div = body.find('div') | ||||
|         # for e in div: | ||||
|         #     print(e.tag, e.attrib) | ||||
|          | ||||
|         # modules_element = body.xpath("//div[@class='col-md-10']") | ||||
| 
 | ||||
|         # modules_element = body.xpath("//div[@class='col-md-10']") | ||||
| 
 | ||||
|         module_root_element = self._get_module(html_root, 'Base') | ||||
|         assert module_root_element is not None | ||||
|         #option_root_elements = module_root_element.xpath(".//div[@class='row']") | ||||
|         #assert len(option_root_elements) > 0 | ||||
|         # option_root_elements = module_root_element.xpath(".//div[@class='row']") | ||||
|         # assert len(option_root_elements) > 0 | ||||
| 
 | ||||
|         # option_root_element = option_root_elements[0] | ||||
|         label_elements = module_root_element.xpath(self.get_xpath_filter('base_module_to_label')) | ||||
|  | @ -671,7 +670,7 @@ class DellConfiguratorParser(): | |||
|                 # so we fallback to an hardcoded estimated price from wikipedia | ||||
|                 base_cpu_price = { | ||||
|                     'amd-epyc-7262': 550.0, | ||||
|                     }[base_cpu.uid] | ||||
|                 }[base_cpu.uid] | ||||
|             configurator.modules['processor'].add_option(Option(base_cpu, base_cpu_price)) | ||||
|             assert configurator.get_item_price(base_cpu.uid) is not None, 'failed to find the price of base cpu %s' % base_cpu.uid | ||||
| 
 | ||||
|  | @ -693,7 +692,7 @@ class DellConfiguratorParser(): | |||
|                 configurator.modules['processor'].add_option(Option(Cpu(proc_change_option.item.uid), cpu_price)) | ||||
|         # delete the 'processor-change' module as its items ids are the same as the ones in the 'processor' modules but their prices are 'wrong' (upgrade prices rather than item price). | ||||
|         # in a configuration, no item should be found more than once | ||||
|         del configurator.modules['processor-change']         | ||||
|         del configurator.modules['processor-change'] | ||||
| 
 | ||||
|         one_cpu_price = configurator.get_item_price(configurator.base_config.cpu.uid) | ||||
|         ram_price = configurator.base_config.ram_price | ||||
|  | @ -711,7 +710,7 @@ class DellConfiguratorParser2020(DellConfiguratorParser): | |||
|             'additional_cpus': 'Processeurs  additionnels', | ||||
|             'ram_change': 'Mémoires (Passage)', | ||||
|             'ram_additions': 'Mémoire: Ajout de barettes additionnelles', | ||||
|             }[module_id] | ||||
|         }[module_id] | ||||
| 
 | ||||
|     def get_xpath_filter(self, filter_id): | ||||
|         return { | ||||
|  | @ -723,11 +722,11 @@ class DellConfiguratorParser2020(DellConfiguratorParser): | |||
|             'option_to_label': ".//div[@class='option-not-selected ']", | ||||
|             'option_to_price': ".//div[@class='col-md-3 text-right option-price ']", | ||||
|             'base_module_to_label': ".//div[@class='option-selected ']", | ||||
|             }[filter_id] | ||||
|         }[filter_id] | ||||
| 
 | ||||
|     def price_str_as_float(self, price_as_str): | ||||
|         # eg '+ 2,255.00 €' | ||||
|         match = re.match(r'^\s*(?P<sign>[-+]?)\s*(?P<numbers>[0-9.]*)\s*€\s*$', price_as_str.replace(',','')) | ||||
|         match = re.match(r'^\s*(?P<sign>[-+]?)\s*(?P<numbers>[0-9.]*)\s*€\s*$', price_as_str.replace(',', '')) | ||||
|         assert match, 'unexpected price string (%s)' % price_as_str | ||||
|         # print(match['sign'], match['numbers']) | ||||
|         price_as_float = float("%s%s" % (match['sign'], match['numbers'])) | ||||
|  | @ -771,6 +770,7 @@ class DellConfiguratorParser2020(DellConfiguratorParser): | |||
|         assert base_price is not None | ||||
|         return base_price | ||||
| 
 | ||||
| 
 | ||||
| class DellConfiguratorParser2021(DellConfiguratorParser): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|  | @ -782,7 +782,7 @@ class DellConfiguratorParser2021(DellConfiguratorParser): | |||
|             'additional_cpus': 'Processeurs  additionnels', | ||||
|             'ram_change': 'Mémoires (Passage)', | ||||
|             'ram_additions': 'Mémoire: Ajout de barettes additionnelles', | ||||
|             }[module_id] | ||||
|         }[module_id] | ||||
| 
 | ||||
|     def get_xpath_filter(self, filter_id): | ||||
|         return { | ||||
|  | @ -794,12 +794,12 @@ class DellConfiguratorParser2021(DellConfiguratorParser): | |||
|             'option_to_label': ".//div[@class='option-info']", | ||||
|             'option_to_price': ".//div[@class='option-price']", | ||||
|             'base_module_to_label': ".//div[@class='product-options-configuration-block option-selected']", | ||||
|             }[filter_id] | ||||
|         }[filter_id] | ||||
| 
 | ||||
|     def price_str_as_float(self, price_as_str): | ||||
|         # eg '+ 2 255,00 €' # contains a Narrow No-Break Space (NNBSP) https://www.compart.com/en/unicode/U+202F | ||||
|         nnbsp = ' ' | ||||
|         match = re.match(r'^\s*(?P<sign>[-+]?)\s*(?P<numbers>[0-9.]*)\s*€\s*$', price_as_str.replace(',','.').replace(nnbsp, '')) | ||||
|         match = re.match(r'^\s*(?P<sign>[-+]?)\s*(?P<numbers>[0-9.]*)\s*€\s*$', price_as_str.replace(',', '.').replace(nnbsp, '')) | ||||
|         assert match, 'unexpected price string (%s)' % price_as_str | ||||
|         # print(match['sign'], match['numbers']) | ||||
|         price_as_float = float("%s%s" % (match['sign'], match['numbers'])) | ||||
|  | @ -854,7 +854,7 @@ class DellConfiguratorParser2021(DellConfiguratorParser): | |||
|             if label == 'Prix de base': | ||||
|                 price_value_element = price_element.xpath(".//span[@class='info-value strong']")[0] | ||||
|                 assert price_value_element is not None | ||||
|                 base_price = self.price_str_as_float(price_value_element.text_content().replace(' HT','')) | ||||
|                 base_price = self.price_str_as_float(price_value_element.text_content().replace(' HT', '')) | ||||
|         assert base_price is not None | ||||
|         return base_price | ||||
| 
 | ||||
|  | @ -870,7 +870,6 @@ class DellMatinfoConfigurator(Configurator): | |||
|         self.chassis = None | ||||
|         html_parser.parse(dell_configurator_html_file_path, self) | ||||
| 
 | ||||
| 
 | ||||
|     def create_config(self): | ||||
|         # config = copy.deepcopy(self.base_config) | ||||
|         config = Config(self) | ||||
|  | @ -889,13 +888,11 @@ class DellMatinfoCsvConfigurator(Configurator): | |||
|     eg the excel sheet sent to guillaume.raffy@univ-rennes1.fr on 16/07/2020 | ||||
|     ''' | ||||
| 
 | ||||
| 
 | ||||
|     def __init__(self, dell_csv_file_path): | ||||
|         super().__init__(self) | ||||
|         self.base_config = None | ||||
|         self.chassis = None | ||||
|         self.parse_csv_configurator(dell_csv_file_path) | ||||
|          | ||||
| 
 | ||||
|     def parse_csv_configurator(self, dell_csv_file_path): | ||||
|         COLUMN_LABEL = 0 | ||||
|  | @ -903,7 +900,6 @@ class DellMatinfoCsvConfigurator(Configurator): | |||
|         COLUMN_PRICE = 4 | ||||
| 
 | ||||
|         with open(dell_csv_file_path, 'rt') as csv_file: | ||||
|              | ||||
|             self.base_config = Config(self) | ||||
| 
 | ||||
|             proc_options = Module('processor') | ||||
|  | @ -939,7 +935,7 @@ class DellMatinfoCsvConfigurator(Configurator): | |||
|                     if cpu_class == 'platinium': | ||||
|                         cpu_class = 'platinum' | ||||
|                     cpu_id = "intel-xeon-%s-%s" % (cpu_class, match['cpu_number'].lower()) | ||||
|                     option = Option(Cpu(cpu_id), price/self.chassis.item.max_num_servers/self.chassis.item.num_cpu_slots_per_server) | ||||
|                     option = Option(Cpu(cpu_id), price / self.chassis.item.max_num_servers / self.chassis.item.num_cpu_slots_per_server) | ||||
|                     proc_options.add_option(option) | ||||
|                     continue | ||||
| 
 | ||||
|  | @ -948,7 +944,7 @@ class DellMatinfoCsvConfigurator(Configurator): | |||
|                 if match: | ||||
|                     price_for_four = self.price_str_as_float(line_cells[COLUMN_PRICE]) | ||||
|                     dimm = Dimm(mem_type='rdimm', num_gb=int(match['num_gb']), num_mhz=int(match['num_mhz'])) | ||||
|                     option = Option(dimm, price_for_four/4.0) | ||||
|                     option = Option(dimm, price_for_four / 4.0) | ||||
|                     ram_options.add_option(option) | ||||
|                     continue | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,33 +1,35 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from abc import ABCMeta, abstractmethod | ||||
| from abc import abstractmethod | ||||
| import numpy | ||||
| import pylab | ||||
| # import pylab | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.colors | ||||
| import itertools | ||||
| import re | ||||
| import hashlib | ||||
| from string import ascii_lowercase | ||||
| from concho.config import Configurator | ||||
| from concho.config import Config | ||||
| # from string import ascii_lowercase | ||||
| # from concho.config import Configurator | ||||
| # from concho.config import Config | ||||
| from concho.config import Cpu | ||||
| from concho import dell | ||||
| # from concho import dell | ||||
| 
 | ||||
| markerTypes=[',', '+', '.', '^', 'v', '<', '>', 'o', '*', '1', '2', '3', '4', '8', 's', 'p', 'h', 'H', 'x', 'X', 'D', 'd', '|', '_'] | ||||
| #for c in ascii_lowercase: | ||||
| markerTypes = [',', '+', '.', '^', 'v', '<', '>', 'o', '*', '1', '2', '3', '4', '8', 's', 'p', 'h', 'H', 'x', 'X', 'D', 'd', '|', '_'] | ||||
| # for c in ascii_lowercase: | ||||
| #    markerTypes.append('$%s$' % c) | ||||
| #markerColors=('r', 'g', 'b') | ||||
| markerColors=('r') | ||||
| # markerColors=('r', 'g', 'b') | ||||
| markerColors = ('r') | ||||
| 
 | ||||
| 
 | ||||
| def get_marker(proc_id): | ||||
|     hash_object = hashlib.md5(proc_id.encode('utf-8')) | ||||
|     hash = int(hash_object.hexdigest(), 16) | ||||
|     return markerTypes[ hash % len(markerTypes) ] | ||||
|     return markerTypes[hash % len(markerTypes)] | ||||
| 
 | ||||
| 
 | ||||
| def plotCpuPassmark(): | ||||
|     cpuTable = numpy.genfromtxt('cpu_table.tsv', dtype=("|U10", float, int, float, float), names=True, delimiter='\t') | ||||
|     plt.subplot(1,1,0) | ||||
|     plt.subplots_adjust(bottom = 0.1) | ||||
|     plt.subplot(1, 1, 0) | ||||
|     plt.subplots_adjust(bottom=0.1) | ||||
|     markersCycler = itertools.cycle(itertools.product(markerTypes, markerColors)) | ||||
|     labels = cpuTable['id'] | ||||
|     x = cpuTable['clock'] * cpuTable['num_cores'] | ||||
|  | @ -35,28 +37,28 @@ def plotCpuPassmark(): | |||
|     markerSize = 50 | ||||
|     color = 'b' | ||||
|     for label, x1, y1 in zip(labels, x, y): | ||||
|         if  y1 <= 0.0: | ||||
|             continue # no passmark available fo this data | ||||
|         generation=label[-1] | ||||
|         if y1 <= 0.0: | ||||
|             continue  # no passmark available fo this data | ||||
|         generation = label[-1] | ||||
|         if generation == '2': | ||||
|             color = 'b' | ||||
|         else: | ||||
|             color = 'r'             | ||||
|             color = 'r' | ||||
|         marker = markersCycler.next() | ||||
|         plt.scatter( x1, y1, color = color, s = markerSize, marker = marker[0], label = label)     | ||||
|         plt.scatter(x1, y1, color=color, s=markerSize, marker=marker[0], label=label) | ||||
|     plt.xlabel(u'theoretical cpu speed [core.GHz]') | ||||
|     plt.ylabel(u'passmark [?]') | ||||
|     plt.title(u'comparison between cpu theoretical and effective speed') | ||||
|     plt.xlim( xmin = 0.0 ) | ||||
|     plt.ylim( ymin = 0.0 ) | ||||
|     plt.xlim(xmin=0.0) | ||||
|     plt.ylim(ymin=0.0) | ||||
|     plt.legend(bbox_to_anchor=(0.2, 1.0)) | ||||
|     #plt.legend() | ||||
|     # plt.legend() | ||||
|     plt.draw() | ||||
|     plt.show() | ||||
| 
 | ||||
| 
 | ||||
| def create_unique_marker(config_index): | ||||
|     marker_string='' | ||||
|     marker_string = '' | ||||
|     alphabet_size = 26 | ||||
|     alphabel_base = 0x41 | ||||
|     while True: | ||||
|  | @ -68,6 +70,7 @@ def create_unique_marker(config_index): | |||
|             config_index = config_index // alphabet_size | ||||
|     return marker_string | ||||
| 
 | ||||
| 
 | ||||
| class ConfigAxisDef(): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|  | @ -81,6 +84,7 @@ class ConfigAxisDef(): | |||
|     def get_value_for_config(self, config): | ||||
|         pass | ||||
| 
 | ||||
| 
 | ||||
| class ConfigPrice(ConfigAxisDef): | ||||
| 
 | ||||
|     def get_axis_label(self): | ||||
|  | @ -89,6 +93,7 @@ class ConfigPrice(ConfigAxisDef): | |||
|     def get_value_for_config(self, config): | ||||
|         return config.get_price() | ||||
| 
 | ||||
| 
 | ||||
| class ConfigFlops(ConfigAxisDef): | ||||
| 
 | ||||
|     def get_axis_label(self): | ||||
|  | @ -97,6 +102,7 @@ class ConfigFlops(ConfigAxisDef): | |||
|     def get_value_for_config(self, config): | ||||
|         return config.get_flops() | ||||
| 
 | ||||
| 
 | ||||
| class ConfigFlopsPerEuro(ConfigAxisDef): | ||||
| 
 | ||||
|     def get_axis_label(self): | ||||
|  | @ -104,48 +110,49 @@ class ConfigFlopsPerEuro(ConfigAxisDef): | |||
| 
 | ||||
|     def get_value_for_config(self, config): | ||||
|         kWHPrice = 0.07 * 1.5 | ||||
|         containerLifetime = 7.0 # in years | ||||
|         containerLifetime = 7.0  # in years | ||||
|         powerUsageEfficiency = 0.5 | ||||
|          | ||||
| 
 | ||||
|         powerUsedInLifetime = (config.get_power_consumption() * containerLifetime * 365 * 24) / powerUsageEfficiency | ||||
|         itemTotalCost = config.get_price() + (powerUsedInLifetime / 1000.0 * kWHPrice ) | ||||
|         itemTotalCost = config.get_price() + (powerUsedInLifetime / 1000.0 * kWHPrice) | ||||
| 
 | ||||
|         item_total_num_ops = config.get_flops() * containerLifetime * 365 * 24 * 3600 | ||||
|         return item_total_num_ops / itemTotalCost | ||||
| 
 | ||||
| 
 | ||||
| def plot_configs(configs, xaxis_def, yaxis_def, plot_title): | ||||
|     """ | ||||
|     Args: | ||||
|         configs (list(Config)): the tist of configurations to plot | ||||
|     """ | ||||
| 
 | ||||
|     def GHzToMHz( frequency ): | ||||
|     def GHzToMHz(frequency): | ||||
|         return frequency * 1000.0 | ||||
|          | ||||
| 
 | ||||
|     def getColorCodeFromItemLabel(label): | ||||
|         generation=label[-1] | ||||
|         # generation = label[-1] | ||||
|         (num_servers, model, num_cpus, proc_id, ram_size) = re.split('_', label) | ||||
|         saturation = { | ||||
|             'sandy bridge':0.0, | ||||
|             'ivy bridge':0.2, | ||||
|             'haswell':0.2, | ||||
|             'broadwell':0.2, | ||||
|             'skylake':0.4, | ||||
|             'coffeelake':0.6, | ||||
|             'cascadelake':1.0, | ||||
|             'sandy bridge': 0.0, | ||||
|             'ivy bridge': 0.2, | ||||
|             'haswell': 0.2, | ||||
|             'broadwell': 0.2, | ||||
|             'skylake': 0.4, | ||||
|             'coffeelake': 0.6, | ||||
|             'cascadelake': 1.0, | ||||
|             'rome': 0.8, | ||||
|             }[Cpu(proc_id).architecture] | ||||
|             #         if model == 'r620': | ||||
|             #             color = 'r' | ||||
|             #         elif model == 'r630': | ||||
|             #             color = 'g' | ||||
|             #         elif model == 'r730': | ||||
|             #             color = 'm' | ||||
|             #         elif model == 'c6220': | ||||
|             #             if generation == '2': | ||||
|             #                 color = 'b' | ||||
|             #             else: | ||||
|             #                 color = 'y' | ||||
|         }[Cpu(proc_id).architecture] | ||||
|         #         if model == 'r620': | ||||
|         #             color = 'r' | ||||
|         #         elif model == 'r630': | ||||
|         #             color = 'g' | ||||
|         #         elif model == 'r730': | ||||
|         #             color = 'm' | ||||
|         #         elif model == 'c6220': | ||||
|         #             if generation == '2': | ||||
|         #                 color = 'b' | ||||
|         #             else: | ||||
|         #                 color = 'y' | ||||
|         hue = { | ||||
|             'dell-poweredge-r620': 0.6, | ||||
|             'dell-poweredge-r630': 0.6, | ||||
|  | @ -159,7 +166,7 @@ def plot_configs(configs, xaxis_def, yaxis_def, plot_title): | |||
|             'dell-poweredge-c6320': 1.0, | ||||
|             'dell-poweredge-c6420': 1.0, | ||||
|             'dell-precision-3630': 0.2 | ||||
|             }[model] | ||||
|         }[model] | ||||
|         value = 0.9 | ||||
|         return matplotlib.colors.hsv_to_rgb((hue, saturation, value)) | ||||
| 
 | ||||
|  | @ -169,15 +176,15 @@ def plot_configs(configs, xaxis_def, yaxis_def, plot_title): | |||
| 
 | ||||
|     markerSize = 50 | ||||
| 
 | ||||
|     plt.subplot(1,2,1) | ||||
|     plt.subplot(1, 2, 1) | ||||
| 
 | ||||
|     markersCycler = itertools.cycle(itertools.product(markerTypes, markerColors)) | ||||
|     # markersCycler = itertools.cycle(itertools.product(markerTypes, markerColors)) | ||||
| 
 | ||||
|     config_index = 0 | ||||
|     for config in configs: | ||||
|         cpu = config.cpu | ||||
|         config_label = str(config.num_servers) + '_' + config.chassis.uid + '_' + str(config.num_cpu_per_server) + '_' + cpu.uid + '_' + str(config.ram_size/config.num_servers) + 'gb' | ||||
|          | ||||
|         config_label = str(config.num_servers) + '_' + config.chassis.uid + '_' + str(config.num_cpu_per_server) + '_' + cpu.uid + '_' + str(config.ram_size / config.num_servers) + 'gb' | ||||
| 
 | ||||
|         x1 = xaxis_def.get_value_for_config(config) | ||||
|         y1 = yaxis_def.get_value_for_config(config) | ||||
| 
 | ||||
|  | @ -186,22 +193,22 @@ def plot_configs(configs, xaxis_def, yaxis_def, plot_title): | |||
|             color = getColorCodeFromItemLabel(config_label) | ||||
|             # marker = markersCycler.next() | ||||
|             # marker = get_marker_from_label( label ) | ||||
|             #print(x1, y1) | ||||
|             short_label = config_label.replace('dell-poweredge-','').replace('intel-xeon-','') | ||||
|             plt.scatter( x1, y1, facecolors=color, s=(markerSize * len(create_unique_marker(config_index))) , marker='$\mathrm{%s}$' % create_unique_marker(config_index), label=short_label) | ||||
|             if False: # y1 > 5.0e16: | ||||
|                 plt.annotate( u'%s' % short_label,  | ||||
|                     xy = (x1, y1), xytext = (x1*4.0, (y1-5.2e16)*7.1), | ||||
|                     textcoords = 'data', ha = 'right', va = 'bottom', | ||||
|                     bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5), | ||||
|                     arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) | ||||
|             # print(x1, y1) | ||||
|             short_label = config_label.replace('dell-poweredge-', '').replace('intel-xeon-', '') | ||||
|             plt.scatter(x1, y1, facecolors=color, s=(markerSize * len(create_unique_marker(config_index))), marker='$\mathrm{%s}$' % create_unique_marker(config_index), label=short_label) | ||||
|             if False:  # y1 > 5.0e16: | ||||
|                 plt.annotate(u'%s' % short_label, | ||||
|                              xy=(x1, y1), xytext=(x1 * 4.0, (y1 - 5.2e16) * 7.1), | ||||
|                              textcoords='data', ha='right', va='bottom', | ||||
|                              bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5), | ||||
|                              arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0')) | ||||
|             config_index += 1 | ||||
| 
 | ||||
|     plt.xlabel(xaxis_def.get_axis_label()) | ||||
|     plt.ylabel(yaxis_def.get_axis_label()) | ||||
|     plt.title(plot_title) | ||||
|     plt.xlim( xmin = 0.0 ) | ||||
|     plt.ylim( ymin = 0.0 ) | ||||
|     plt.xlim(xmin=0.0) | ||||
|     plt.ylim(ymin=0.0) | ||||
|     plt.minorticks_on() | ||||
|     plt.grid(b=True, which='major', color='b', linestyle='-', linewidth=0.5) | ||||
|     plt.grid(b=True, which='minor', color='b', linestyle='-', linewidth=0.2)     | ||||
|  | @ -210,7 +217,8 @@ def plot_configs(configs, xaxis_def, yaxis_def, plot_title): | |||
| 
 | ||||
|     plt.show() | ||||
| 
 | ||||
| def plot_configurators(configurators, ram_per_core, xaxis_def, yaxis_def, plot_title, config_filter=lambda config : True): | ||||
| 
 | ||||
| def plot_configurators(configurators, ram_per_core, xaxis_def, yaxis_def, plot_title, config_filter=lambda config: True): | ||||
|     configs = [] | ||||
|     for configurator in configurators: | ||||
|         for cpu in configurator.get_cpu_options(): | ||||
|  | @ -222,7 +230,3 @@ def plot_configurators(configurators, ram_per_core, xaxis_def, yaxis_def, plot_t | |||
|                 configs.append(config) | ||||
| 
 | ||||
|     plot_configs(configs, xaxis_def=xaxis_def, yaxis_def=yaxis_def, plot_title=plot_title) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     plot_2020_matinfo_configs | ||||
|  |  | |||
|  | @ -4,9 +4,10 @@ from concho.dell import DellConfiguratorParser2020 | |||
| from concho.dell import DellConfiguratorParser2021 | ||||
| from concho.procs_chooser import plot_configurators | ||||
| from concho.procs_chooser import ConfigPrice | ||||
| from concho.procs_chooser import ConfigFlops | ||||
| # from concho.procs_chooser import ConfigFlops | ||||
| from concho.procs_chooser import ConfigFlopsPerEuro | ||||
| 
 | ||||
| 
 | ||||
| def test_all_matinfo_2020_configs(): | ||||
|     # configurator = DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html') | ||||
|     # print(configurator) | ||||
|  | @ -15,10 +16,11 @@ def test_all_matinfo_2020_configs(): | |||
|         DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html', DellConfiguratorParser2020()), | ||||
|         DellMatinfoConfigurator('rcrc1406676-4824727 - Cat 2 Conf 7 PowerEdge R940 - Dell.html', DellConfiguratorParser2020()), | ||||
|         # dell.DellPowerEdgeR940(), | ||||
|         ] | ||||
|      | ||||
|     ] | ||||
| 
 | ||||
|     plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlopsPerEuro(), plot_title='total cost including electricity') | ||||
| 
 | ||||
| 
 | ||||
| def test_credits_2020_configs(): | ||||
|     # configurator = DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html') | ||||
|     # print(configurator) | ||||
|  | @ -27,8 +29,8 @@ def test_credits_2020_configs(): | |||
|         DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html', DellConfiguratorParser2020()), | ||||
|         DellMatinfoConfigurator('rcrc1406676-4824727 - Cat 2 Conf 7 PowerEdge R940 - Dell.html', DellConfiguratorParser2020()), | ||||
|         # dell.DellPowerEdgeR940(), | ||||
|         ] | ||||
|      | ||||
|     ] | ||||
| 
 | ||||
|     # config_filter = lambda config : config.cpu.uid in [ | ||||
|     #     'intel-xeon-gold-5222', | ||||
|     #     'intel-xeon-gold-6226r', | ||||
|  | @ -40,18 +42,19 @@ def test_credits_2020_configs(): | |||
|     #     'intel-xeon-gold-6240', | ||||
|     #     ] | ||||
| 
 | ||||
|     config_filter = lambda config : config.get_price() < 40000.0 | ||||
|     def config_filter(config): | ||||
|         return config.get_price() < 40000.0 | ||||
| 
 | ||||
|     plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlopsPerEuro(), plot_title='physmol/ts credit 2020 configs', config_filter=config_filter) | ||||
| 
 | ||||
| 
 | ||||
| def test_credits_2021_configs(): | ||||
|     configurators = [ | ||||
|         DellMatinfoConfigurator('20210407 - Cat2 Conf4 PowerEdge R640 - Dell.html', DellConfiguratorParser2021()), | ||||
|         DellMatinfoConfigurator('20210407 - Cat2 Conf7 PowerEdge R940 - Dell.html', DellConfiguratorParser2021()), | ||||
|         DellMatinfoConfigurator('20210407 - Cat2 Conf8 PowerEdge R7525 - Dell.html', DellConfiguratorParser2021()), | ||||
|         DellMatinfoConfigurator('20210407 - Cat2 Conf10 PowerEdge R6525 - Dell.html', DellConfiguratorParser2021()), | ||||
|         ] | ||||
|      | ||||
|         # DellMatinfoConfigurator('20210407 - Cat2 Conf10 PowerEdge R6525 - Dell.html', DellConfiguratorParser2021()), | ||||
|     ] | ||||
|     # config_filter = lambda config : config.cpu.uid in [ | ||||
|     #     'intel-xeon-gold-5222', | ||||
|     #     'intel-xeon-gold-6226r', | ||||
|  | @ -63,10 +66,11 @@ def test_credits_2021_configs(): | |||
|     #     'intel-xeon-gold-6240', | ||||
|     #     ] | ||||
| 
 | ||||
|     config_filter = lambda config : config.get_price() < 20000.0 | ||||
|     def config_filter(config): | ||||
|         return config.get_price() < 40000.0 | ||||
| 
 | ||||
|     plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlopsPerEuro(), plot_title='physmol/ts credit 2021 configs', config_filter=config_filter) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     test_credits_2021_configs() | ||||
|     test_credits_2021_configs() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue