diff --git a/concho/config.py b/concho/config.py index 2d004d7..f155ac8 100644 --- a/concho/config.py +++ b/concho/config.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Union import re from abc import abstractmethod import numpy @@ -55,6 +55,14 @@ class SdramChip(): self.transfer_rate = transfer_rate +class PmmChip(): + '''persistant memory module''' + transfer_rate: int # in mega transfer per second + + def __init__(self, transfer_rate: int): + self.transfer_rate = transfer_rate + + class DimmCas(): # https://en.wikipedia.org/wiki/CAS_latency cas1: int @@ -69,11 +77,11 @@ class DimmCas(): class Dimm(Item): num_gb: int - sdram_chip: SdramChip + sdram_chip: Union[SdramChip, PmmChip] mem_type: MemType cas: Optional[DimmCas] - def __init__(self, num_gb: int, sdram_chip: SdramChip, cas: Optional[DimmCas], mem_type: str): + def __init__(self, num_gb: int, sdram_chip: Union[SdramChip, PmmChip], cas: Optional[DimmCas], mem_type: str): ''' mem_type: 'rdimm', 'pmm' ''' diff --git a/concho/dell.py b/concho/dell.py index a572268..a35d83c 100644 --- a/concho/dell.py +++ b/concho/dell.py @@ -6,7 +6,7 @@ from concho.config import Module from concho.config import Option from concho.config import Config from concho.config import Chassis -from concho.config import Cpu, Dimm, Price, MemSizeGb, MemSize, CpuId +from concho.config import Cpu, Dimm, Price, MemSizeGb, MemSize, CpuId, SdramChip, PmmChip from concho.config import IHtmlConfiguratorParser from abc import abstractmethod @@ -520,7 +520,8 @@ class DellConfiguratorParser(IHtmlConfiguratorParser): 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) + sdram_chip = SdramChip(chip_type='ddr', generation=4, transfer_rate=num_mhz) + dimm = Dimm(num_gb=num_gb, sdram_chip=sdram_chip, cas=None, mem_type=mem_type) option = Option(dimm, price) ram_options.add_option(option) else: @@ -528,7 +529,8 @@ class DellConfiguratorParser(IHtmlConfiguratorParser): match = re.match(r'^Optane DC Persistent Memory - (?P[0-9]+)Go (?P[0-9][0-9][0-9][0-9])Mhz$', 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='pmm') # persistent memory module + chip = PmmChip(transfer_rate=int(match['num_mhz'])) + dimm = Dimm(num_gb=int(match['num_gb']), sdram_chip=chip, cas=None, mem_type='pmm') # persistent memory module option = Option(dimm, price) ram_options.add_option(option) else: @@ -574,7 +576,8 @@ class DellConfiguratorParser(IHtmlConfiguratorParser): # Mémoire 16 Go DDR4 à 2933MHz (1x16Go) match = re.match(r'^Mémoire (?P[0-9]+) Go DDR[\-]?4 à (?P[0-9]+)MHz \((?P[0-9]+)x(?P[0-9]+)Go\)', item_label.replace('Mémoire de base : ', '').replace('De base ', '')) assert match, 'unhandled label : %s' % item_label - dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), num_mhz=int(match['num_mhz']), mem_type='rdimm') + sdram_chip = SdramChip(chip_type='ddr', generation=4, transfer_rate=int(match['num_mhz'])) + dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), sdram_chip=sdram_chip, cas=None, mem_type='rdimm') num_dimms = int(match['num_dimms']) if num_dimms == 1: assert match['num_gb'] == match['num_gb_per_dimm'] @@ -863,6 +866,94 @@ class DellConfiguratorParser2021(DellConfiguratorParser): return base_price +class DellV2ConfiguratorParser(DellConfiguratorParser): + + def __init__(self): + super().__init__() + + def get_module_label(self, module_id): + return { + 'cpu_change': 'Processeurs (Passage)', + 'additional_cpus': 'Processeurs additionnels', + 'ram_change': 'Mémoires (Passage)', + 'ram_additions': 'Mémoire: Ajout de barettes additionnelles', + }[module_id] + + def get_xpath_filter(self, filter_id): + return { + 'root_to_modules_element': ".//div[@id='technicalspecification_section']", + 'modules_element_to_modules': ".//div[@class='product-module-configuration']", + 'module_to_blue_title': ".//header", + 'module_to_grey_title': ".//div[@class='col-md-4 module-title color-808080']", + 'module_to_options': ".//div[@class='product-options-configuration-line']", + '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] + + 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[-+]?)\s*(?P[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'])) + return price_as_float + + def _get_module_default_item(self, module_label, html_root): + module_root_element = self._get_module(html_root, module_label) + assert module_root_element is not None + + if module_label == self.get_module_label('ram_change'): + #
+ #
Mémoire 16 Go DDR4 à 3200MHz (1x16Go)
+ #
+ #
+ 0,00 €
+ #
+ selected_option_filter = ".//div[@class='product-options-configuration-block option-selected']" + label_filter = ".//header" + price_filter = ".//div[@class='mt-2 option-price']" + else: + selected_option_filter = ".//div[@class='product-options-configuration-line option-selected']" + label_filter = ".//div[@class='option-info']" + price_filter = ".//div[@class='option-price']" + + for selected_option_root_element in module_root_element.xpath(selected_option_filter): + label_elements = selected_option_root_element.xpath(label_filter) + assert label_elements is not None + if len(label_elements) > 0: + label = label_elements[0].text_content().replace('\n', '') + price = self.price_str_as_float(selected_option_root_element.xpath(price_filter)[0].text_content()) + assert price == 0.0, 'default items are expected to have a price of 0.0 € (%s s price is %f)' % (label, price) + return label + assert False, 'failed to find the default item of module %s' % module_label + + def get_base_price(self, html_root): + base_price = None + price_preview_element = html_root.xpath(".//div[@class='product-info']")[0] + assert price_preview_element is not None + for price_element in price_preview_element.xpath(".//div[@class='info']"): + price_label_element = price_element.xpath(".//span[@class='info-label']")[0] + #
Prix de base1175 € HT
+ #
+ #
Avec options1175 € HT
+ #
+ + assert price_label_element is not None + label = price_label_element.text_content().replace('\n', '') + 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', '')) + assert base_price is not None + return base_price + + class DellMatinfoCsvConfigurator(Configurator): ''' a configurator using the excel sheet from dell matinfo @@ -894,7 +985,7 @@ class DellMatinfoCsvConfigurator(Configurator): if match: match = re.match(r'poweredge (?Pc6[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])) + self.chassis = Option(Chassis('dell-poweredge-%s' % match['chassis_id']), DellConfiguratorParser2020().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 @@ -912,7 +1003,7 @@ class DellMatinfoCsvConfigurator(Configurator): match = re.match(r'^Passage à 2 Processeurs Intel Xeon (?PSilver|Gold|Platinium) (?P[0-9][0-9][0-9][0-9][RLYUM]?) .*', label) if match: - price = self.price_str_as_float(line_cells[COLUMN_PRICE]) + price = DellConfiguratorParser2020().price_str_as_float(line_cells[COLUMN_PRICE]) cpu_class = match['cpu_class'].lower() if cpu_class == 'platinium': cpu_class = 'platinum' @@ -924,8 +1015,9 @@ class DellMatinfoCsvConfigurator(Configurator): # Ajout d'une barette de 8Go 2667 Mhz DDR-4 - Pour les 4 serveurs match = re.match(r'^Ajout d\'une barette de (?P[0-9]+)Go (?P[0-9][0-9][0-9][0-9]) Mhz (?PDDR-4) - Pour les 4 serveurs$', label) 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'])) + price_for_four = DellConfiguratorParser2020().price_str_as_float(line_cells[COLUMN_PRICE]) + sdram_chip = SdramChip(chip_type='ddr', generation=4, transfer_rate=int(match['num_mhz'])) + dimm = Dimm(mem_type='rdimm', num_gb=int(match['num_gb']), sdram_chip=sdram_chip, cas=None) option = Option(dimm, price_for_four / 4.0) ram_options.add_option(option) continue @@ -944,3 +1036,5 @@ class DellMatinfoCsvConfigurator(Configurator): config.cpu_slots_mem = copy.deepcopy(self.base_config.cpu_slots_mem) return config + + diff --git a/concho/hpe.py b/concho/hpe.py index 0792430..edfc721 100644 --- a/concho/hpe.py +++ b/concho/hpe.py @@ -4,7 +4,7 @@ from concho.config import Module from concho.config import Option from concho.config import Config from concho.config import Chassis -from concho.config import Cpu, Dimm +from concho.config import Cpu, Dimm, SdramChip from concho.config import IHtmlConfiguratorParser # from xml.dom.minidom import parse @@ -109,7 +109,8 @@ class HpeCatalogParser(): num_gb = int(match['num_gb']) num_mhz = int(match['num_mhz']) mem_type = 'rdimm' # not sure about that - dimm = Dimm(num_gb=num_gb, num_mhz=num_mhz, mem_type=mem_type) + sdram_chip = SdramChip(chip_type='ddr', generation=4, transfer_rate=num_mhz) + dimm = Dimm(num_gb=num_gb, sdram_chip=sdram_chip, cas=None, mem_type=mem_type) option = Option(dimm, price) ram_options.add_option(option) assert len(ram_options.options) > 0 @@ -141,7 +142,9 @@ class HpeCatalogParser(): # HPE 32GB (1x32GB) Dual Rank x4 DDR4-2933 CAS-21-21-21 Registered Smart Memory Kit match = re.match(r'^HPE (?P[0-9]+)GB \((?P[0-9]+)x(?P[0-9]+)GB\) Dual Rank x4 DDR4-(?P[0-9]+).*', label) assert match, 'unhandled label : %s' % label - dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), num_mhz=int(match['num_mhz']), mem_type='rdimm') + + sdram_chip = SdramChip(chip_type='ddr', generation=4, transfer_rate=int(match['num_mhz'])) + dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), sdram_chip=sdram_chip, cas=None, mem_type='rdimm') num_dimms = int(match['num_dimms']) if num_dimms == 1: assert match['num_gb'] == match['num_gb_per_dimm'] @@ -197,7 +200,8 @@ class HpeCatalogWoutCpuParser(HpeCatalogParser): # HPE 32GB (1x32GB) Dual Rank x4 DDR4-2933 CAS-21-21-21 Registered Smart Memory Kit match = re.match(r'^HPE (?P[0-9]+)GB \((?P[0-9]+)x(?P[0-9]+)GB\) Dual Rank x4 DDR4-(?P[0-9]+).*', label) assert match, 'unhandled label : %s' % label - dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), num_mhz=int(match['num_mhz']), mem_type='rdimm') + sdram_chip = SdramChip(chip_type='ddr', generation=4, transfer_rate=int(match['num_mhz'])) + dimm = Dimm(num_gb=int(match['num_gb_per_dimm']), sdram_chip=sdram_chip, cas=None, mem_type='rdimm') num_dimms = int(match['num_dimms']) if num_dimms == 1: assert match['num_gb'] == match['num_gb_per_dimm'] diff --git a/readme.md b/readme.md index 3979745..9b11243 100644 --- a/readme.md +++ b/readme.md @@ -64,7 +64,7 @@ Successfully built concho Installing collected packages: zipp, six, pyparsing, pillow, packaging, numpy, lxml, kiwisolver, fonttools, cycler, python-dateutil, importlib-resources, contourpy, matplotlib, concho Successfully installed concho-1.0 contourpy-1.1.1 cycler-0.12.1 fonttools-4.56.0 importlib-resources-6.4.5 kiwisolver-1.4.7 lxml-5.3.1 matplotlib-3.7.5 numpy-1.24.4 packaging-24.2 pillow-10.4.0 pyparsing-3.1.4 python-dateutil-2.9.0.post0 six-1.17.0 zipp-3.20.2 last command status : [0] -20250314-10:57:41 graffy@graffy-ws2:~/work/concho$ PYTHONPATH=. python3 ./tests/test1.py +20250314-10:57:41 graffy@graffy-ws2:~/work/concho$ python3 -m unittest discover --start-directory ./tests ``` diff --git a/tests/test1.py b/tests/test1.py deleted file mode 100644 index fd66511..0000000 --- a/tests/test1.py +++ /dev/null @@ -1,107 +0,0 @@ -from pathlib import Path -from concho.dell import DellMatinfoCsvConfigurator -from concho.config import HtmlConfigurator -from concho.dell import DellConfiguratorParser2020 -from concho.dell import DellConfiguratorParser2021 -from concho.hpe import HpeConfiguratorParser, HpeCpuChoiceConfiguratorParser -from concho.hpev2 import HpeV2ConfiguratorParser -from concho.procs_chooser import plot_configurators -from concho.procs_chooser import ConfigPrice -from concho.procs_chooser import ConfigFlops -from concho.procs_chooser import ConfigFlopsPerEuro - - -def test_all_matinfo_2020_configs(): - # configurator = DellHtmlConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html') - # print(configurator) - configurators = [ - DellMatinfoCsvConfigurator(Path('catalogs/dell/c6420-20200716-price.tsv')), - HtmlConfigurator(Path('catalogs/dell/rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html'), DellConfiguratorParser2020()), - HtmlConfigurator(Path('catalogs/dell/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 = DellHtmlConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html') - # print(configurator) - configurators = [ - DellMatinfoCsvConfigurator(Path('catalogs/dell/c6420-20200716-price.tsv')), - HtmlConfigurator(Path('catalogs/dell/rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html'), DellConfiguratorParser2020()), - HtmlConfigurator(Path('catalogs/dell/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', - # 'intel-xeon-gold-6230r', - # 'intel-xeon-gold-6234r', - # 'intel-xeon-gold-6240r', - # 'intel-xeon-gold-6248r', - # 'intel-xeon-gold-6230', - # 'intel-xeon-gold-6240', - # ] - - 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 = [ - HtmlConfigurator(Path('catalogs/dell/20210407 - Cat2 Conf4 PowerEdge R640 - Dell.html'), DellConfiguratorParser2021()), - HtmlConfigurator(Path('catalogs/dell/20210407 - Cat2 Conf7 PowerEdge R940 - Dell.html'), DellConfiguratorParser2021()), - HtmlConfigurator(Path('catalogs/dell/20210407 - Cat2 Conf8 PowerEdge R7525 - Dell.html'), DellConfiguratorParser2021()), - # HtmlConfigurator('20210407 - Cat2 Conf10 PowerEdge R6525 - Dell.html', DellConfiguratorParser2021()), - ] - # config_filter = lambda config : config.cpu.uid in [ - # 'intel-xeon-gold-5222', - # 'intel-xeon-gold-6226r', - # 'intel-xeon-gold-6230r', - # 'intel-xeon-gold-6234r', - # 'intel-xeon-gold-6240r', - # 'intel-xeon-gold-6248r', - # 'intel-xeon-gold-6230', - # 'intel-xeon-gold-6240', - # ] - - 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) - - -def test_ur1_presents_2023_configs(): - configurators = [ - # HtmlConfigurator('20210407 - Cat2 Conf4 PowerEdge R640 - Dell.html', DellConfiguratorParser2021()), - HtmlConfigurator(Path('catalogs/hpev1/20230120-cat2-conf3-hpe-dl360-gen10.html'), HpeConfiguratorParser()), - HtmlConfigurator(Path('catalogs/hpev1/20230123-cat2-conf10-hpe-dl360-gen10plus-cpuchoice.html'), HpeCpuChoiceConfiguratorParser()), - HtmlConfigurator(Path('catalogs/hpev1/20230123-cat2-conf11-hpe-dl385-gen10plus-cpuchoice.html'), HpeCpuChoiceConfiguratorParser()), - ] - - def config_filter(config): - return True # 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 2023 configs', config_filter=config_filter) - # plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlops(), plot_title='physmol/ts credit 2023 configs', config_filter=config_filter) - - -def test_hpe_bpu11_configs(): - configurators = [ - HtmlConfigurator(Path('catalogs/hpev2/20250314-cat2-conf16-hpe-dl380-gen11.html'), HpeV2ConfiguratorParser()), - HtmlConfigurator(Path('catalogs/hpev2/20250314-cat2-conf19-hpe-dl365-gen11.html'), HpeV2ConfiguratorParser()), - ] - - def config_filter(config): - return True # config.get_price() < 40000.0 - - plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlopsPerEuro(), plot_title='physmol/dbossion ais configs', config_filter=config_filter, figure_file_path='./hpe-2025-03-14.pdf') - - # plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlops(), plot_title='physmol/dbossion ais configs', config_filter=config_filter) - -if __name__ == '__main__': - test_hpe_bpu11_configs() diff --git a/tests/test_dell_2020.py b/tests/test_dell_2020.py new file mode 100644 index 0000000..b9755b9 --- /dev/null +++ b/tests/test_dell_2020.py @@ -0,0 +1,58 @@ +import unittest +from pathlib import Path +from concho.dell import DellMatinfoCsvConfigurator +from concho.config import HtmlConfigurator +from concho.dell import DellConfiguratorParser2020 +from concho.procs_chooser import plot_configurators +from concho.procs_chooser import ConfigPrice +from concho.procs_chooser import ConfigFlopsPerEuro + + +class Test(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.plots_dir = Path('./plots/') + self.plots_dir.mkdir(exist_ok=True, parents=True) + + def test_all_matinfo_2020_configs(self): + # configurator = DellHtmlConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html') + # print(configurator) + configurators = [ + DellMatinfoCsvConfigurator(Path('catalogs/dell/c6420-20200716-price.tsv')), + HtmlConfigurator(Path('catalogs/dell/rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html'), DellConfiguratorParser2020()), + HtmlConfigurator(Path('catalogs/dell/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', figure_file_path=self.plots_dir / '2020-all-matinfo-configs.pdf') + + def test_credits_2020_configs(self): + # configurator = DellHtmlConfigurator('rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html') + # print(configurator) + configurators = [ + DellMatinfoCsvConfigurator(Path('catalogs/dell/c6420-20200716-price.tsv')), + HtmlConfigurator(Path('catalogs/dell/rcrc1406676-4834664 - Cat2 Conf4 PowerEdge R640 - Dell.html'), DellConfiguratorParser2020()), + HtmlConfigurator(Path('catalogs/dell/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', + # 'intel-xeon-gold-6230r', + # 'intel-xeon-gold-6234r', + # 'intel-xeon-gold-6240r', + # 'intel-xeon-gold-6248r', + # 'intel-xeon-gold-6230', + # 'intel-xeon-gold-6240', + # ] + + 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, figure_file_path=self.plots_dir / '2020-credits-configs.pdf') + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_dell_2021.py b/tests/test_dell_2021.py new file mode 100644 index 0000000..2ca288d --- /dev/null +++ b/tests/test_dell_2021.py @@ -0,0 +1,42 @@ +import unittest +from pathlib import Path +from concho.config import HtmlConfigurator +from concho.dell import DellConfiguratorParser2021 +from concho.procs_chooser import plot_configurators +from concho.procs_chooser import ConfigPrice +from concho.procs_chooser import ConfigFlopsPerEuro + + +class Test(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.plots_dir = Path('./plots/') + self.plots_dir.mkdir(exist_ok=True, parents=True) + + def test_credits_2021_configs(self): + configurators = [ + HtmlConfigurator(Path('catalogs/dell/20210407 - Cat2 Conf4 PowerEdge R640 - Dell.html'), DellConfiguratorParser2021()), + HtmlConfigurator(Path('catalogs/dell/20210407 - Cat2 Conf7 PowerEdge R940 - Dell.html'), DellConfiguratorParser2021()), + HtmlConfigurator(Path('catalogs/dell/20210407 - Cat2 Conf8 PowerEdge R7525 - Dell.html'), DellConfiguratorParser2021()), + # HtmlConfigurator('20210407 - Cat2 Conf10 PowerEdge R6525 - Dell.html', DellConfiguratorParser2021()), + ] + # config_filter = lambda config : config.cpu.uid in [ + # 'intel-xeon-gold-5222', + # 'intel-xeon-gold-6226r', + # 'intel-xeon-gold-6230r', + # 'intel-xeon-gold-6234r', + # 'intel-xeon-gold-6240r', + # 'intel-xeon-gold-6248r', + # 'intel-xeon-gold-6230', + # 'intel-xeon-gold-6240', + # ] + + 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, figure_file_path=self.plots_dir / '2021-credits-configs.pdf') + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_hpe_2023.py b/tests/test_hpe_2023.py new file mode 100644 index 0000000..9bfeafa --- /dev/null +++ b/tests/test_hpe_2023.py @@ -0,0 +1,32 @@ +import unittest +from pathlib import Path +from concho.config import HtmlConfigurator +from concho.hpe import HpeConfiguratorParser, HpeCpuChoiceConfiguratorParser +from concho.procs_chooser import plot_configurators +from concho.procs_chooser import ConfigPrice +from concho.procs_chooser import ConfigFlopsPerEuro + + +class Test(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.plots_dir = Path('./plots/') + self.plots_dir.mkdir(exist_ok=True, parents=True) + + def test_ur1_presents_2023_configs(self): + configurators = [ + # HtmlConfigurator('20210407 - Cat2 Conf4 PowerEdge R640 - Dell.html', DellConfiguratorParser2021()), + HtmlConfigurator(Path('catalogs/hpev1/20230120-cat2-conf3-hpe-dl360-gen10.html'), HpeConfiguratorParser()), + HtmlConfigurator(Path('catalogs/hpev1/20230123-cat2-conf10-hpe-dl360-gen10plus-cpuchoice.html'), HpeCpuChoiceConfiguratorParser()), + HtmlConfigurator(Path('catalogs/hpev1/20230123-cat2-conf11-hpe-dl385-gen10plus-cpuchoice.html'), HpeCpuChoiceConfiguratorParser()), + ] + + def config_filter(config): + return True # 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 2023 configs', config_filter=config_filter, figure_file_path=self.plots_dir / '2023-ur1-presents-configs.pdf') + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_hpe_2025.py b/tests/test_hpe_2025.py new file mode 100644 index 0000000..35a360a --- /dev/null +++ b/tests/test_hpe_2025.py @@ -0,0 +1,30 @@ +import unittest +from pathlib import Path +from concho.config import HtmlConfigurator +from concho.hpev2 import HpeV2ConfiguratorParser +from concho.procs_chooser import plot_configurators +from concho.procs_chooser import ConfigPrice +from concho.procs_chooser import ConfigFlopsPerEuro + + +class Test(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.plots_dir = Path('./plots/') + self.plots_dir.mkdir(exist_ok=True, parents=True) + + def test_hpe_bpu11_configs(self): + configurators = [ + HtmlConfigurator(Path('catalogs/hpev2/20250314-cat2-conf16-hpe-dl380-gen11.html'), HpeV2ConfiguratorParser()), + HtmlConfigurator(Path('catalogs/hpev2/20250314-cat2-conf19-hpe-dl365-gen11.html'), HpeV2ConfiguratorParser()), + ] + + def config_filter(config): + return True # config.get_price() < 40000.0 + + plot_configurators(configurators=configurators, ram_per_core=4.0e9, xaxis_def=ConfigPrice(), yaxis_def=ConfigFlopsPerEuro(), plot_title='physmol/dbossion ais configs', config_filter=config_filter, figure_file_path=self.plots_dir / '2025-dbossion-ais-configs.pdf') # './hpe-2025-03-14.pdf') + + +if __name__ == '__main__': + unittest.main()