// =================== GENERAL OUTPUT CONFIG ========================= const chartDisclaimers = { Value: 'Value: Performance/(No_of_sockets * Price_of_CPU_dGPU), where prices are in USD as of December 2022.', Efficiency: 'Efficiency: Performance/(No_of_sockets * TDP_of_CPU_dGPU), where total power dissipation (TDP) is in Watt as of December 2022.' } const OVdefaultSelections = { platforms: {name: 'platform', data: [ 'Intel® Core™ i9-12900K CPU-only', 'Intel® Core™ i9-13900K CPU-only', 'Intel® Core™ i5-10500TE CPU-only', 'Intel® Core™ i5-13600K CPU-only', 'Intel® Core™ i5-8500 CPU-only', 'Intel® Core™ i7-8700T CPU-only', 'Intel® Core™ i9-10900TE CPU-only', 'Intel® Core™ i7-1165G7 CPU-only' ] }, platformFilters: {name: 'coretype', data: ['CPU']}, models: {name: 'networkmodel', data: [ 'bert-large-uncased-whole-word-masking-squad-0001 ', 'mobilenet-ssd ', 'resnet-50', 'yolo_v3_tiny' ] }, parameters: {name: 'kpi', data: ['Throughput']}, pracision: {name: 'precision', data: ['INT8', 'FP32']} } const OVMSdefaultSelections = { platforms: {name: 'platform', data: [ 'Intel® Core™ i3-10100 CPU-only', 'Intel® Core™ i5-8500 CPU-only', 'Intel® Core™ i7-8700T CPU-only', 'Intel® Core™ i9-10920X CPU-only', ] }, models: {name: 'networkmodel', data: [ 'bert-small-uncased-whole-word-masking-squad-0002', 'mobilenet-ssd ', 'resnet-50', 'yolo_v3_tiny' ] }, parameters: {name: 'kpi', data: ['Throughput']}, pracision: {name: 'precision', data: ['OV-INT8 (reference)', 'INT8']} } // ==================================================== class Filter { // param: GraphData[], networkModels[] static FilterByNetworkModel(graphDataArr, networkModels) { // This is a bit obtuse, collect all options from all models // Some of them might return dupes, so convert them to a map, and get unique objects based on names const optionMap = new Map(); networkModels.map((model) => graphDataArr.filter((graphData => graphData.networkModel === model))) .flat(1) .forEach(item => optionMap.set(item.platformName, item)); // convert the option map back to an array with just the values return Array.from(optionMap.values()); } // param: GraphData[], ieType static FilterByIeType(graphDataArr, value) { return graphDataArr.filter((data) => data.ieType.includes(value)); } // param: GraphData[], clientPlatforms[] static FilterByClientPlatforms(graphDataArr, platformsArr) { return graphDataArr.filter((data) => platformsArr.includes(data.platformName)); } // param: GraphData[], coreTypes[] static FilterByCoreTypes(graphDataArr, coreTypes) { if (coreTypes) { return graphDataArr.filter((data) => coreTypes.includes(data.ieType)); } return graphDataArr; } // param: GraphData[] (of one networkModel), key (throughput, latency, efficiency, value) static getKpiData(graphDataArr, key) { return graphDataArr.map((data) => { return data[key]; }); } } class ExcelDataTransformer { static transform(csvdata, version) { const entries = csvdata.filter((entry) => { return !entry.includes('begin_rec') && !entry.includes('end_rec'); }); // do other purging and data massaging here // else generate return entries.map((entry) => { if (version == 'ovms') return new GraphData(new OVMSExcelData(entry)); return new GraphData(new ExcelData(entry)); }); } } class ExcelData { constructor(csvdataline) { if (!csvdataline) { return; } this.networkModel = csvdataline[0].toLowerCase(); this.release = csvdataline[1]; this.ieType = csvdataline[2]; this.platformName = csvdataline[3]; this.throughputInt8 = csvdataline[4]; this.throughputFP16 = csvdataline[5]; this.throughputFP32 = csvdataline[6]; this.value = csvdataline[7]; this.efficiency = csvdataline[8]; this.price = csvdataline[9]; this.tdp = csvdataline[10]; this.sockets = csvdataline[11]; this.pricePerSocket = csvdataline[12]; this.tdpPerSocket = csvdataline[13]; this.latency = csvdataline[14]; } } class OVMSExcelData extends ExcelData { constructor(csvdataline) { super(csvdataline); this.throughputOVMSInt8 = csvdataline[5]; this.throughputInt8 = csvdataline[4]; this.throughputOVMSFP32 = csvdataline[7]; this.throughputFP32 = csvdataline[6]; } } class GraphData { constructor(excelData) { if (!excelData) { return; } this.networkModel = excelData.networkModel; this.release = excelData.release; this.ieType = excelData.ieType; this.platformName = excelData.platformName; this.kpi = new KPI( { 'ovmsint8': excelData.throughputOVMSInt8, 'ovmsfp32': excelData.throughputOVMSFP32, 'int8': excelData.throughputInt8, 'fp16': excelData.throughputFP16, 'fp32': excelData.throughputFP32 }, excelData.value, excelData.efficiency, excelData.latency); this.price = excelData.price; this.tdp = excelData.tdp; this.sockets = excelData.sockets; this.pricePerSocket = excelData.pricePerSocket; this.tdpPerSocket = excelData.tdpPerSocket; this.latency = excelData.latency; } } class KPI { constructor(precisions, value, efficiency, latency) { this.throughput = precisions; this.value = value; this.efficiency = efficiency; this.latency = latency; } } class Modal { static getIeTypeLabel(ietype) { switch (ietype) { case 'core': return 'Client Platforms (Intel® Core™)'; case 'xeon': return 'Server Platforms (Intel® Xeon®)'; case 'atom': return 'Mobile Platforms (Intel® Atom™)'; case 'accel': return 'Accelerator Platforms'; default: return ''; } } static getCoreTypesLabels() { return ['CPU', 'iGPU', 'CPU+iGPU']; } static getKpisLabels(version) { if (version == 'ovms') return ['Throughput']; return ['Throughput', 'Value', 'Efficiency', 'Latency']; } static getPrecisionsLabels(version) { if (version == 'ovms') return ['OV-INT8 (reference)', 'INT8', 'OV-FP32 (reference)', 'FP32']; return ['INT8', 'FP16', 'FP32']; } static getCoreTypes(labels) { return labels.map((label) => { switch (label) { case 'CPU': return 'core'; case 'iGPU': return 'core-iGPU'; case 'CPU+iGPU': return 'core-CPU+iGPU'; default: return ''; } }); } static getPrecisions(labels) { return labels.map((label) => { switch (label) { case 'OV-INT8 (reference)': return 'ovmsint8'; case 'OV-FP32 (reference)': return 'ovmsfp32'; case 'INT8': return 'int8'; case 'FP16': return 'fp16'; case 'FP32': return 'fp32'; default: return ''; } }); } } class Graph { constructor(data) { this.data = data; } data = new GraphData(); // functions to get unique keys static getNetworkModels(graphDataArr) { return Array.from(new Set(graphDataArr.map((obj) => obj.networkModel))); } static getIeTypes(graphDataArr) { return Array.from(new Set(graphDataArr.map((obj) => obj.ieType))); } static getPlatforms(graphDataArr) { return Array.from(new Set(graphDataArr.map((obj) => obj.platformName))); } static getCoreTypes(graphDataArr) { return Array.from(new Set(graphDataArr.map((obj) => obj.ieType))); } // param: GraphData[] static getPlatformNames(graphDataArr) { return graphDataArr.map((data) => data.platformName); } // param: GraphData[], kpi: string static getDatabyKPI(graphDataArr, kpi) { switch (kpi) { case 'throughput': return graphDataArr.map((data) => data.kpi.throughput); case 'latency': return graphDataArr.map((data) => data.kpi.latency); case 'efficiency': return graphDataArr.map((data) => data.kpi.efficiency); case 'value': return graphDataArr.map((data) => data.kpi.value); default: return []; } } // this returns an object that is used to ender the chart static getGraphConfig(kpi, precisions) { switch (kpi) { case 'throughput': return { chartTitle: 'Throughput', chartSubtitle: '(higher is better)', iconClass: 'throughput-icon', datasets: precisions.map((precision) => this.getPrecisionConfig(precision)), }; case 'latency': return { chartTitle: 'Latency', chartSubtitle: '(lower is better)', iconClass: 'latency-icon', datasets: [{ data: null, color: '#8F5DA2', label: 'Milliseconds' }], }; case 'value': return { chartTitle: 'Value', chartSubtitle: '(higher is better)', iconClass: 'value-icon', datasets: [{ data: null, color: '#8BAE46', label: 'FPS/$ (INT8)' }], }; case 'efficiency': return { chartTitle: 'Efficiency', chartSubtitle: '(higher is better)', iconClass: 'efficiency-icon', datasets: [{ data: null, color: '#E96115', label: 'FPS/TDP (INT8)' }], }; default: return {}; } } static getPrecisionConfig(precision) { switch (precision) { case 'ovmsint8': return { data: null, color: '#FF8F51', label: 'FPS (OV Ref. INT8)' }; case 'ovmsfp32': return { data: null, color: '#B24501', label: 'FPS (OV Ref. FP32)' }; case 'int8': return { data: null, color: '#00C7FD', label: 'FPS (INT8)' }; case 'fp16': return { data: null, color: '#009fca', label: 'FPS (FP16)' }; case 'fp32': return { data: null, color: '#007797', label: 'FPS (FP32)' }; default: return {}; } } static getGraphPlatformText(platform) { switch (platform) { case 'atom': return 'Mobile Platforms'; case 'core': return 'Client Platforms'; case 'xeon': return 'Server Platforms'; case 'accel': return 'Accelerated Platforms'; default: return ''; } } } class ChartDisplay { constructor(mode, numberOfCharts) { this.mode = mode; this.numberOfChartsInRow = numberOfCharts; } } $(document).ready(function () { $('.ov-toolkit-benchmark-results').on('click', () => showModal('ov')); $('.ovms-toolkit-benchmark-results').on('click', () => showModal('ovms')); function clickBuildGraphs(graph, networkModels, ietype, platforms, kpis, precisions) { renderData(graph, networkModels, ietype, platforms, kpis, precisions); $('.modal-footer').show(); $('#modal-display-graphs').show(); $('.edit-settings-btn').on('click', (event) => { $('#modal-configure-graphs').show(); $('#modal-display-graphs').hide(); $('.modal-footer').hide(); $('.chart-placeholder').empty(); }); $('.graph-chart-title-header').on('click', (event) => { var parent = event.target.parentElement; if ($(parent).children('.chart-wrap,.empty-chart-container').is(":visible")) { $(parent).children('.chart-wrap,.empty-chart-container').hide(); $(parent).children('.chevron-right-btn').show(); $(parent).children('.chevron-down-btn').hide(); $ } else { $(parent).children('.chart-wrap,.empty-chart-container').show(); $(parent).children('.chevron-down-btn').show(); $(parent).children('.chevron-right-btn').hide(); } }); } function hideModal() { $('#graphModal').remove(); $('body').css('overflow', 'auto'); } function showModal(version) { $('body').css('overflow', 'hidden'); let dataPath = '_static/benchmarks_files/OV-benchmark-data.csv'; if (version == 'ovms') dataPath = '_static/benchmarks_files/OVMS-benchmark-data.csv'; Papa.parse(dataPath, { download: true, complete: (result) => renderModal(result, version) }); } function getSelectedNetworkModels() { return $('.models-column-one input:checked, .models-column-two input:checked').not('[data-networkmodel="Select All"]').map(function () { return $(this).data('networkmodel'); }).get(); } function getSelectedIeType() { return $('.ietype-column input:checked').map(function () { return $(this).data('ietype'); }).get().pop(); } function getSelectedCoreTypes() { return $('.client-platform-column .selected').map(function () { return $(this).data('coretype'); }).get(); } function getSelectedClientPlatforms() { return $('.client-platform-column input:checked').map(function () { return $(this).data('platform'); }).get(); } function getSelectedKpis() { return $('.kpi-column input:checked').map(function () { return $(this).data('kpi'); }).get(); } function getSelectedPrecisions() { return $('.precisions-column input:checked').map(function () { return $(this).data('precision'); }).get(); } function validateSelections() { if (getSelectedNetworkModels().length > 0 && getSelectedIeType() && getSelectedClientPlatforms().length > 0 && getSelectedKpis().length > 0) { if (getSelectedKpis().includes('Throughput')) { if (getSelectedPrecisions().length > 0) { $('#build-graphs-btn').prop('disabled', false); return; } $('#build-graphs-btn').prop('disabled', true); return; } $('#build-graphs-btn').prop('disabled', false); return; } $('#build-graphs-btn').prop('disabled', true); } function renderModal(result, version) { // remove header from csv line result.data.shift(); var graph = new Graph(ExcelDataTransformer.transform(result.data, version)); var networkModels = Graph.getNetworkModels(graph.data); var ieTypes = Graph.getIeTypes(graph.data); fetch('_static/html/modal.html').then((response) => response.text()).then((text) => { // generate and configure modal container var modal = $('
'); modal.attr('id', 'graphModal'); modal.addClass('modal'); // generate and configure modal content from html import var modalContent = $(text); modalContent.attr('id', 'graphModalContent'); modalContent.addClass('modal-content'); modal.append(modalContent); const models = networkModels.map((networkModel) => createCheckMark(networkModel, 'networkmodel')); const selectAllModelsButton = createCheckMark('Select All', 'networkmodel') modal.find('.models-column-one').append(selectAllModelsButton).append(models.slice(0, models.length / 2)); modal.find('.models-column-two').append(models.slice(models.length / 2)); const precisions = Modal.getPrecisionsLabels(version).map((precision) => createCheckMark(precision, 'precision')); modal.find('.precisions-column').append(precisions); selectAllCheckboxes(precisions); disableAllCheckboxes(precisions); const types = ieTypes.map((ieType) => { var labelText = Modal.getIeTypeLabel(ieType); if (labelText) { const item = $('