added support for r940 (obtained from dell matinfo web page)
This commit is contained in:
parent
1340c1b980
commit
c588821707
103
concho/dell.py
103
concho/dell.py
|
@ -425,15 +425,20 @@ class DellConfiguratorParser():
|
|||
label = label_elements[0].text_content().replace('\n', '')
|
||||
price = DellConfiguratorParser.price_str_as_float(option_root_element.xpath(".//div[@class='col-md-3 text-right option-price ']")[0].text_content())
|
||||
# print(label, price)
|
||||
num_cpus = 1
|
||||
# Passage à processeur Intel Xeon Gold 6240L 2.6GHz, 24.75M Cache,10.40GT/s, 2UPI, Turbo, HT,18C/36T (150W) - DDR4-2933
|
||||
match = re.match(r'^Passage à processeur Intel Xeon (?P<cpu_class>Silver|Gold|Platinium) (?P<cpu_number>[0-9][0-9][0-9][0-9][RLYU]?).*', label)
|
||||
assert match, 'unhandled label : %s' % label
|
||||
if match is None:
|
||||
# Passage à 2 Processeurs Intel Xeon Gold 6240L 2.6GHz, 24.75M Cache,10.40GT/s, 2UPI, Turbo, HT,18C/36T (150W) - DDR4-2933
|
||||
match = re.match(r'^passage à 2 processeurs intel xeon (?P<cpu_class>silver|gold|platinium) (?P<cpu_number>[0-9][0-9][0-9][0-9][rly]?).*', label.lower())
|
||||
assert match, 'unhandled label : %s' % label
|
||||
num_cpus = 2
|
||||
# print(match['cpu_class'], match['cpu_number'])
|
||||
cpu_class = match['cpu_class'].lower()
|
||||
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)
|
||||
option = Option(Cpu(cpu_id), price / num_cpus)
|
||||
proc_options.add_option(option)
|
||||
return proc_options
|
||||
|
||||
|
@ -447,15 +452,21 @@ class DellConfiguratorParser():
|
|||
label = label_elements[0].text_content()
|
||||
price = DellConfiguratorParser.price_str_as_float(option_root_element.xpath(".//div[@class='col-md-3 text-right option-price ']")[0].text_content())
|
||||
# print(label, price)
|
||||
num_additional_cpus = 1
|
||||
match = re.match(r'^Processeur additionnel Intel Xeon (?P<cpu_class>Silver|Gold|Platinium) (?P<cpu_number>[0-9][0-9][0-9][0-9][RLY]?).*', label)
|
||||
assert match
|
||||
if match is None:
|
||||
# Ajout de 2 Processeurs Intel Xeon Gold 6240L 2.6GHz, 24.75M Cache,10.40GT/s, 2UPI, Turbo, HT,18C/36T (150W) - DDR4-2933
|
||||
match = re.match(r'^ajout de 2 processeurs intel xeon (?P<cpu_class>silver|gold|platinium) (?P<cpu_number>[0-9][0-9][0-9][0-9][rly]?).*', label.lower())
|
||||
assert match, 'unhandled label : %s' % label
|
||||
num_additional_cpus = 2
|
||||
# print(match['cpu_class'], match['cpu_number'])
|
||||
cpu_class = match['cpu_class'].lower()
|
||||
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)
|
||||
option = Option(Cpu(cpu_id), price / num_additional_cpus)
|
||||
proc_options.add_option(option)
|
||||
assert len(proc_options.options) > 0
|
||||
return proc_options
|
||||
|
||||
def _parse_ram_options(self, html_root):
|
||||
|
@ -471,8 +482,14 @@ class DellConfiguratorParser():
|
|||
# Ajout d'une barette de 128Go 2667 Mhz LRDIMM
|
||||
match = re.match(r'^Ajout d\'une barette de (?P<num_gb>[0-9]+)Go (?P<num_mhz>[0-9][0-9][0-9][0-9]) Mhz (?P<mem_type>LRDIMM|RDIMM)$', label)
|
||||
if match:
|
||||
|
||||
# print(match['num_gb'], match['num_mhz'])
|
||||
dimm = Dimm(num_gb=int(match['num_gb']), num_mhz=int(match['num_mhz']), mem_type=match['mem_type'].lower())
|
||||
num_gb = int(match['num_gb'])
|
||||
num_mhz = int(match['num_mhz'])
|
||||
mem_type = match['mem_type'].lower()
|
||||
if num_gb == 8 and num_mhz == 2667 and mem_type == 'rdimm':
|
||||
num_mhz = 2933 # error in r940 configurator : incoherence between 'Mémoire 32 Go DDR4 à 2933MHz (4x8Go)' and 'Ajout d'une barette de 8Go 2667 Mhz RDIMM'
|
||||
dimm = Dimm(num_gb=num_gb, num_mhz=num_mhz, mem_type=mem_type)
|
||||
option = Option(dimm, price)
|
||||
ram_options.add_option(option)
|
||||
else:
|
||||
|
@ -485,6 +502,7 @@ class DellConfiguratorParser():
|
|||
ram_options.add_option(option)
|
||||
else:
|
||||
assert False, 'unhandled label : %s' % label
|
||||
assert len(ram_options.options) > 0
|
||||
return ram_options
|
||||
|
||||
@classmethod
|
||||
|
@ -510,7 +528,10 @@ class DellConfiguratorParser():
|
|||
item_label = DellConfiguratorParser._get_module_default_item('Processeurs (Passage)', html_root)
|
||||
# Processeur Intel Xeon Silver 4208 2.1GHz,11M Cache,9.60GT/s, 2UPI,No Turbo, HT,8C/16T (85W) - DDR4-2400
|
||||
match = re.match(r'^Processeur Intel Xeon (?P<cpu_class>Silver|Gold|Platinium) (?P<cpu_number>[0-9][0-9][0-9][0-9][RLYU]?).*', item_label)
|
||||
assert match, 'unhandled label : %s' % item_label
|
||||
if match is None:
|
||||
match = re.match(r'^2 processeurs Intel Xeon (?P<cpu_class>Silver|Gold|Platinium) (?P<cpu_number>[0-9][0-9][0-9][0-9][RLYU]?).*', item_label)
|
||||
assert match, 'unhandled label : %s' % item_label
|
||||
base_config.num_cpu_per_server = 2
|
||||
# print(match['cpu_class'], match['cpu_number'])
|
||||
cpu_id = "intel-xeon-%s-%s" % (match['cpu_class'].lower(), match['cpu_number'].lower())
|
||||
base_config.set_cpu(Cpu(cpu_id))
|
||||
|
@ -518,18 +539,59 @@ class DellConfiguratorParser():
|
|||
# initialize the default ram dimms
|
||||
item_label = DellConfiguratorParser._get_module_default_item('Mémoires (Passage)', html_root)
|
||||
# Mémoire 16 Go DDR4 à 2933MHz (1x16Go)
|
||||
match = re.match(r'^Mémoire (?P<num_gb>[0-9]+) Go DDR4 à (?P<num_mhz>[0-9]+)MHz \((?P<num_dimms>[0-9]+)x(?P<num_gb2>[0-9]+)Go\)', item_label)
|
||||
match = re.match(r'^Mémoire (?P<num_gb>[0-9]+) Go DDR4 à (?P<num_mhz>[0-9]+)MHz \((?P<num_dimms>[0-9]+)x(?P<num_gb_per_dimm>[0-9]+)Go\)', item_label)
|
||||
assert match, 'unhandled label : %s' % item_label
|
||||
assert int(match['num_dimms']) == 1
|
||||
assert match['num_gb'] == match['num_gb2']
|
||||
# print(match['cpu_class'], match['cpu_number'])
|
||||
cpu_slot_index = 0
|
||||
mem_channel_index = 0
|
||||
dimm_slot = 0
|
||||
base_config.cpu_slots_mem[cpu_slot_index].mem_channels[mem_channel_index].dimms[dimm_slot] = Dimm(num_gb=int(match['num_gb']), num_mhz=int(match['num_mhz']), mem_type='rdimm')
|
||||
dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), num_mhz=int(match['num_mhz']), mem_type='rdimm')
|
||||
num_dimms = int(match['num_dimms'])
|
||||
if num_dimms == 1:
|
||||
assert match['num_gb'] == match['num_gb_per_dimm']
|
||||
# print(match['cpu_class'], match['cpu_number'])
|
||||
cpu_slot_index = 0
|
||||
mem_channel_index = 0
|
||||
dimm_slot = 0
|
||||
base_config.cpu_slots_mem[cpu_slot_index].mem_channels[mem_channel_index].dimms[dimm_slot] = dimm
|
||||
else:
|
||||
# evenly split dimms on channels
|
||||
assert (num_dimms % base_config.num_cpu_per_server) == 0
|
||||
num_dimms_per_cpu = num_dimms // base_config.num_cpu_per_server
|
||||
for cpu_slot_index in range(base_config.num_cpu_per_server):
|
||||
cpu_slots_mem = base_config.cpu_slots_mem[cpu_slot_index]
|
||||
assert len(cpu_slots_mem.mem_channels) >= num_dimms_per_cpu
|
||||
for channel_index in range(num_dimms_per_cpu):
|
||||
mem_channel = cpu_slots_mem.mem_channels[channel_index]
|
||||
dimm_slot = 0
|
||||
mem_channel.dimms[dimm_slot] = dimm
|
||||
|
||||
return base_config
|
||||
|
||||
@staticmethod
|
||||
def _deduce_base_cpu_price(base_cpu, cpu_options, additional_cpu_options):
|
||||
'''
|
||||
The price of the base config processor is not always available directly in the section 'additional processors' : as an example, r940's default processors are 2 xeon gold 5215 but it's not possible to add 2 other 5215 (probably because 5215 can only talk to another cpu, not 3). In this case the price of this base cpu can be deduced from the price for other cpus (difference between cpu upgrade and additional cpu)
|
||||
|
||||
Args:
|
||||
base_cpu (Cpu): the cpu of the base configuration
|
||||
cpu_options (Module): the available cpu options
|
||||
additional_cpu_options (Module): the available additional cpu options
|
||||
|
||||
returns:
|
||||
float: the estimated price of base_cpu
|
||||
'''
|
||||
base_cpu_price = None
|
||||
|
||||
for cpu_option in additional_cpu_options.options.values():
|
||||
cpu = cpu_option.item
|
||||
# assert cpu.uid in cpu_options.options, "unexpected case : %s is available in additional cpus but not in cpu upgrade options" % cpu.uid
|
||||
if cpu.uid in cpu_options.options:
|
||||
cpu_upgrade_option = cpu_options.options[cpu.uid]
|
||||
deduced_base_cpu_price = cpu_option.price - cpu_upgrade_option.price
|
||||
print('price of %s estimated from %s : %f (%f-%f)' % (base_cpu.uid, cpu.uid, deduced_base_cpu_price, cpu_option.price, cpu_upgrade_option.price))
|
||||
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
|
||||
|
||||
return base_cpu_price
|
||||
|
||||
def parse(self, dell_configurator_html_file_path, configurator):
|
||||
|
||||
|
@ -563,10 +625,17 @@ class DellConfiguratorParser():
|
|||
|
||||
configurator.base_config = self._parse_base_config(html_root, configurator)
|
||||
|
||||
# configurator.add_module(self._parse_proc_change_options(html_root))
|
||||
proc_change_module = self._parse_proc_change_options(html_root)
|
||||
configurator.add_module(self._parse_proc_options(html_root))
|
||||
configurator.add_module(self._parse_ram_options(html_root))
|
||||
|
||||
# compute the price of the base config cpu because for example in r940 configurator, the xeon gold 5215 appears in the basic config but not in additional cpus
|
||||
base_cpu = configurator.base_config.cpu
|
||||
if configurator.get_item_price(base_cpu.uid) is None:
|
||||
base_cpu_price = DellConfiguratorParser._deduce_base_cpu_price(base_cpu, proc_change_module, configurator.modules['processor'])
|
||||
configurator.modules['processor'].add_option(Option(base_cpu, base_cpu_price))
|
||||
assert configurator.get_item_price(base_cpu.uid) is not None
|
||||
|
||||
# compute the price of the chassis
|
||||
base_price = None
|
||||
price_preview_element = html_root.xpath(".//div[@class='price-preview']")[0]
|
||||
|
@ -591,7 +660,9 @@ class DellConfiguratorParser():
|
|||
base_price = DellConfiguratorParser.price_str_as_float(price_value_element.text_content())
|
||||
assert base_price is not None
|
||||
|
||||
configurator.chassis.price = base_price - configurator.base_config.num_cpus * configurator.get_item_price(configurator.base_config.cpu.uid) - configurator.base_config.ram_price
|
||||
one_cpu_price = configurator.get_item_price(configurator.base_config.cpu.uid)
|
||||
ram_price = configurator.base_config.ram_price
|
||||
configurator.chassis.price = base_price - configurator.base_config.num_cpus * one_cpu_price - ram_price
|
||||
|
||||
class DellMatinfoConfigurator(Configurator):
|
||||
'''
|
||||
|
|
|
@ -137,6 +137,7 @@ def plot_system_efficiency():
|
|||
configurators = [
|
||||
dell.DellMatinfoCsvConfigurator('c6420-20200716-price.tsv'),
|
||||
dell.DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html'),
|
||||
dell.DellMatinfoConfigurator('rcrc1406676-4824727 - Cat 2 Conf 7 PowerEdge R940 - Dell.html'),
|
||||
# dell.DellPowerEdgeR940(),
|
||||
]
|
||||
for configurator in configurators:
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue