added a configurator for poweredge c6420 based on prices coming from a tab separated value file

This commit is contained in:
Guillaume Raffy 2020-09-29 19:09:42 +02:00
parent a22f88ec6a
commit 1340c1b980
4 changed files with 100 additions and 6 deletions

View File

Can't render this file because it contains an unexpected character in line 3 and column 98.

View File

@ -18,6 +18,8 @@ class Chassis(Item):
self.num_cpu_slots_per_server = 2 self.num_cpu_slots_per_server = 2
if re.match('dell-poweredge-r9.*', uid): if re.match('dell-poweredge-r9.*', uid):
self.num_cpu_slots_per_server = 4 self.num_cpu_slots_per_server = 4
if re.match('dell-poweredge-c6.*', uid):
self.max_num_servers = 4
self.num_dimm_slots_per_channel = 2 self.num_dimm_slots_per_channel = 2
class Dimm(Item): class Dimm(Item):

View File

@ -408,8 +408,8 @@ class DellConfiguratorParser():
@classmethod @classmethod
def price_str_as_float(cls, price_as_str): def price_str_as_float(cls, price_as_str):
match = re.match(r'^\s*(?P<sign>[-+]?)\s*(?P<numbers>[0-9.]*)\s*€\s*$', price_as_str) match = re.match(r'^\s*(?P<sign>[-+]?)\s*(?P<numbers>[0-9.]*)\s*€\s*$', price_as_str.replace(',',''))
assert match assert match, 'unexpected price string (%s)' % price_as_str
# print(match['sign'], match['numbers']) # print(match['sign'], match['numbers'])
price_as_float = float("%s%s" % (match['sign'], match['numbers'])) price_as_float = float("%s%s" % (match['sign'], match['numbers']))
return price_as_float return price_as_float
@ -594,6 +594,9 @@ class DellConfiguratorParser():
configurator.chassis.price = base_price - configurator.base_config.num_cpus * configurator.get_item_price(configurator.base_config.cpu.uid) - configurator.base_config.ram_price configurator.chassis.price = base_price - configurator.base_config.num_cpus * configurator.get_item_price(configurator.base_config.cpu.uid) - configurator.base_config.ram_price
class DellMatinfoConfigurator(Configurator): class DellMatinfoConfigurator(Configurator):
'''
a configurator using the web page from dell matinfo
'''
def __init__(self, dell_configurator_html_file_path): def __init__(self, dell_configurator_html_file_path):
super().__init__(self) super().__init__(self)
@ -613,3 +616,88 @@ class DellMatinfoConfigurator(Configurator):
return config return config
class DellMatinfoCsvConfigurator(Configurator):
'''
a configurator using the excel sheet from dell matinfo
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
COLUMN_MODEL = 1
COLUMN_PRICE = 4
with open(dell_csv_file_path, 'rt') as csv_file:
self.base_config = Config(self)
proc_options = Module('processor')
ram_options = Module('ram')
for line in csv_file.readlines():
line_cells = line.split('\t')
label = line_cells[COLUMN_LABEL]
match = re.match(r'^CAT3_Configuration n°1 \(Châssis rempli de serveurs identiques\)$', label)
if match:
match = re.match(r'poweredge (?P<chassis_id>c6[0-9]20)', line_cells[COLUMN_MODEL].lower())
assert match, "failed to recognize the chassis in '%s'" % line_cells[COLUMN_MODEL].lower()
self.chassis = Option(Chassis('dell-poweredge-%s' % match['chassis_id']), DellConfiguratorParser.price_str_as_float(line_cells[COLUMN_PRICE]))
continue
# 2 processeurs Intel Xeon Silver 4210R 2.4GHz, 13.75M Cache,9.60GT/s, 2UPI, Turbo, HT,10C/20T (100W) - DDR4-2400
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]?).*$', label)
if match:
cpu_class = match['cpu_class'].lower()
if cpu_class == 'platinium':
cpu_class = 'platinum'
base_cpu_id = "intel-xeon-%s-%s" % (cpu_class, match['cpu_number'].lower())
assert self.chassis is not None
self.base_config.num_servers = self.chassis.item.max_num_servers
self.base_config.num_cpu_per_server = self.chassis.item.num_cpu_slots_per_server
self.base_config.set_cpu(Cpu(base_cpu_id))
continue
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][RLYU]?).*', label)
if match:
price = DellConfiguratorParser.price_str_as_float(line_cells[COLUMN_PRICE])
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/self.chassis.item.max_num_servers/self.chassis.item.num_cpu_slots_per_server)
proc_options.add_option(option)
continue
# Ajout d'une barette de 8Go 2667 Mhz DDR-4 - Pour les 4 serveurs
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_technology>DDR-4) - Pour les 4 serveurs$', label)
if match:
price_for_four = DellConfiguratorParser.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)
ram_options.add_option(option)
continue
assert len(proc_options.options) > 0
assert len(ram_options.options) > 0
self.add_module(proc_options)
self.add_module(ram_options)
def create_config(self):
# config = copy.deepcopy(self.base_config)
config = Config(self)
config.num_servers = self.base_config.num_servers
config.num_cpu_per_server = self.base_config.num_cpu_per_server
config.set_cpu(self.base_config.cpu)
config.cpu_slots_mem = copy.deepcopy(self.base_config.cpu_slots_mem)
return config

View File

@ -89,7 +89,7 @@ def plot_system_efficiency():
def getColorCodeFromItemLabel(label): def getColorCodeFromItemLabel(label):
generation=label[-1] generation=label[-1]
(model, proc_id, ram_size) = re.split('_', label) (num_servers, model, proc_id, ram_size) = re.split('_', label)
saturation = { saturation = {
'sandy bridge':0.0, 'sandy bridge':0.0,
'ivy bridge':0.2, 'ivy bridge':0.2,
@ -135,8 +135,10 @@ def plot_system_efficiency():
item_speed = numpy.array([]) item_speed = numpy.array([])
item_label = numpy.array([]) item_label = numpy.array([])
configurators = [ configurators = [
dell.DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html')] dell.DellMatinfoCsvConfigurator('c6420-20200716-price.tsv'),
# dell.DellPowerEdgeR940()] dell.DellMatinfoConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html'),
# dell.DellPowerEdgeR940(),
]
for configurator in configurators: for configurator in configurators:
for cpu in configurator.get_cpu_options(): for cpu in configurator.get_cpu_options():
if not cpu.architecture in ['coffeelake', 'skylake','cascadelake']: if not cpu.architecture in ['coffeelake', 'skylake','cascadelake']:
@ -145,7 +147,9 @@ def plot_system_efficiency():
config.num_cpu_per_server = config.configurator.chassis.item.num_cpu_slots_per_server config.num_cpu_per_server = config.configurator.chassis.item.num_cpu_slots_per_server
config.set_cpu(cpu) config.set_cpu(cpu)
config.set_ram(ram_per_core=4.0e9) config.set_ram(ram_per_core=4.0e9)
item_label = numpy.append( item_label, config.chassis.uid + '_' + cpu.uid + '_' + str(config.ram_size) + 'gb' )
config_label = str(config.num_servers) + '_' + config.chassis.uid + '_' + cpu.uid + '_' + str(config.ram_size/config.num_servers) + 'gb'
item_label = numpy.append( item_label, config_label)
# print('procOptionPrice', procOptionPrice) # print('procOptionPrice', procOptionPrice)
# config_price = procOptionPrice # config_price = procOptionPrice
# config_price += config.get_empty_price() # config_price += config.get_empty_price()