From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id ACD56A09FF; Mon, 11 Jan 2021 17:04:04 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 33DE1140F0D; Mon, 11 Jan 2021 17:04:04 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id A24AF140F08 for ; Mon, 11 Jan 2021 17:04:01 +0100 (CET) IronPort-SDR: pMFxb66HODR75j4Em4Oac/PU88En2+e2Vcow5HTEHftxMAgSrKFPybyF3UfyIhqRDCw1fvgk39 GK+nnAQIiz/w== X-IronPort-AV: E=McAfee;i="6000,8403,9860"; a="239428838" X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="239428838" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 08:03:55 -0800 IronPort-SDR: YkuvBHT2jDncLP3bHn0Zo7gp2xQv6HHWzkn+y+jHXt1h0eAjHzCxkD+MrGRN4t28qYhfIfakfl Hd801Xlj8r2w== X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="352651694" Received: from dwdohert-mobl.ger.corp.intel.com (HELO [10.213.207.99]) ([10.213.207.99]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 08:03:53 -0800 To: Ciara Power , dev@dpdk.org Cc: akhil.goyal@nxp.com, Thomas Monjalon References: <20201211173114.1924772-1-ciara.power@intel.com> <20201211173114.1924772-4-ciara.power@intel.com> From: "Doherty, Declan" Message-ID: <860982e9-a347-c0ef-86db-33f31ef6a63e@intel.com> Date: Mon, 11 Jan 2021 16:03:49 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0 MIME-Version: 1.0 In-Reply-To: <20201211173114.1924772-4-ciara.power@intel.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [PATCH 3/4] usertools: add script to graph crypto perf results X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On 11/12/2020 5:31 PM, Ciara Power wrote: > The python script introduced in this patch runs the crypto performance > test application for various test cases, and graphs the results. > > Test cases are defined in the config JSON file, this is where parameters > are specified for each test. Currently there are various test cases for > devices crypto_qat, crypto_aesni_mb and crypto_gcm. Tests for the > ptest types Throughput and Latency are supported for each. > > The results of each test case are graphed and saved in PDFs (one PDF for > each test suite, showing all test case graphs for that suite). > The graphs output include various grouped barcharts for throughput > tests, and histogram and boxplot graphs are used for latency tests. > > Usage: > The script uses the installed app by default (from ninja install). > Alternatively we can pass path to app by > "-f //app/dpdk-test-crypto-perf" > > All device test suites are run by default. > Alternatively we can specify by adding arguments, > "-t all" - to run all test suites > "-t crypto_qat_latency" - to run QAT latency test suite only > "-t crypto_aesni_mb_throughput crypto_aesni_gcm_latency" > - to run both AESNI_MB throughput and AESNI_GCM latency > test suites > > Signed-off-by: Ciara Power > --- > MAINTAINERS | 2 + > doc/guides/tools/cryptoperf.rst | 93 +++++++ > usertools/dpdk_graph_crypto_perf.py | 249 +++++++++++++++++++ > usertools/graph_crypto_perf_config.json | 309 ++++++++++++++++++++++++ > 4 files changed, 653 insertions(+) > create mode 100755 usertools/dpdk_graph_crypto_perf.py > create mode 100644 usertools/graph_crypto_perf_config.json > > diff --git a/MAINTAINERS b/MAINTAINERS > index eafe9f8c46..5e9dc1a1a7 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1588,6 +1588,8 @@ M: Declan Doherty > T: git://dpdk.org/next/dpdk-next-crypto > F: app/test-crypto-perf/ > F: doc/guides/tools/cryptoperf.rst > +F: usertools/dpdk_graph_crypto_perf.py > +F: usertools/graph_crypto_perf_config.json > > Eventdev test application > M: Jerin Jacob > diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst > index 79359fe894..63d97319a8 100644 > --- a/doc/guides/tools/cryptoperf.rst > +++ b/doc/guides/tools/cryptoperf.rst > @@ -453,3 +453,96 @@ Test vector file for cipher algorithm aes cbc 256 with authorization sha:: > digest = > 0x1C, 0xB2, 0x3D, 0xD1, 0xF9, 0xC7, 0x6C, 0x49, 0x2E, 0xDA, 0x94, 0x8B, 0xF1, 0xCF, 0x96, 0x43, > 0x67, 0x50, 0x39, 0x76, 0xB5, 0xA1, 0xCE, 0xA1, 0xD7, 0x77, 0x10, 0x07, 0x43, 0x37, 0x05, 0xB4 > + > + > +Graph Crypto Perf Results > +------------------------- > + > +The ``dpdk_graph_crypto_perf.py`` usertool is a simple script to automate > +running crypto performance tests, and graphing the results. > +The output graphs include various grouped barcharts for throughput > +tests, and histogram and boxplot graphs for latency tests. > +These are output to PDF files, with one PDF per test suite. > + > + Add section regarding required python modules needed. > +Test Configuration > +~~~~~~~~~~~~~~~~~~ > + > +The test cases run by the script are outlined in the ``graph_crypto_perf_config.json`` file. > +An example of this configuration is shown below for one test suite, > +showing the default config for the test suite, and one test case. > +The test case has additional app config that will be combined with > +the default config when running the test case. > + > +.. code-block:: c > + > + "crypto_aesni_mb_throughput": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1", > + "vdev": "crypto_aesni_mb" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "buffer-sz": "64,128,256,512,768,1024,1408,2048", > + "burst-sz": "1,4,8,16,32", > + "ptest": "throughput", > + "devtype": "crypto_aesni_mb" > + } > + }, > + "AES-CBC-128 SHA1-HMAC auth-then-cipher decrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "16", > + "auth-algo": "sha1-hmac", > + "optype": "auth-then-cipher", > + "cipher-op": "decrypt" > + } > + } > + > +Currently, crypto_qat, crypto_aesni_mb, and crypto_aesni_gcm devices for > +both throughput and latency ptests are supported. > + > + Should note that specific test cases only allow for modification of the application parameters and not the EAL parameters, and that a default configuration is required to specify EAL parameters. > +Usage > +~~~~~ > + > +.. code-block:: console > + > + ./dpdk_graph_crypto_perf > + > +The following are the application command-line options: > + > +* ``-f file_path`` > + > + Provide path to ``dpdk-test-crypto-perf`` application. > + The script uses the installed app by default. > + > + .. code-block:: console > + > + ./dpdk_graph_crypto_perf -f /app/dpdk-test-crypto-perf > + > + > +* ``-t test_suite_list`` > + > + Specify test suites to run. All test suites are run by default. > + > + To run all test suites > + > + .. code-block:: console > + > + ./dpdk_graph_crypto_perf -t all > + > + To run crypto_qat latency test suite only > + > + .. code-block:: console > + > + ./dpdk_graph_crypto_perf -t crypto_qat_latency > + > + To run both crypto_aesni_mb throughput and crypto_aesni_gcm latency test suites > + > + .. code-block:: console > + > + ./dpdk_graph_crypto_perf -t crypto_aesni_mb_throughput \ > + crypto_aesni_gcm_latency > diff --git a/usertools/dpdk_graph_crypto_perf.py b/usertools/dpdk_graph_crypto_perf.py > new file mode 100755 > index 0000000000..a1361fb625 > --- /dev/null > +++ b/usertools/dpdk_graph_crypto_perf.py > @@ -0,0 +1,249 @@ > +#! /usr/bin/env python3 > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright(c) 2020 Intel Corporation > + > +""" > +Script to automate running crypto performance tests for a range of test > +cases and devices as configured in the JSON file. > +The results are processed and output into various graphs in PDF files. > +Currently, throughput and latency tests are supported. > +""" > + > +import glob > +import json > +import os > +import shutil > +import subprocess > +from argparse import ArgumentParser > +from datetime import datetime > +import img2pdf > +import pandas as pd > +import plotly.express as px > + > +SCRIPT_PATH = os.path.dirname(__file__) + "/" > +GRAPHS_PATH = SCRIPT_PATH + "graph_crypto_perf_graphs/" > +PDFS_PATH = SCRIPT_PATH + "graph_crypto_perf_pdfs/" > + > + > +class Grapher: > + """Grapher object containing all graphing functions. """ > + def __init__(self, dev): > + self.graph_num = 0 > + self.dev = dev > + self.test = "" > + self.ptest = "" > + self.data = pd.DataFrame() > + if not os.path.exists(GRAPHS_PATH): > + os.makedirs(GRAPHS_PATH) > + > + def save_graph(self, fig): > + """ > + Update figure layout to increase readability, output to JPG file. > + """ > + fig.update_layout(font_size=30, title_x=0.5, title_font={"size": 30}, > + margin=dict(t=200, l=150, r=150, b=150)) > + fig.write_image(GRAPHS_PATH + "%s_%d.jpg" % (self.dev, > + self.graph_num)) > + > + def boxplot_graph(self, x_axis_label): > + """Plot a boxplot graph for the given parameters.""" > + fig = px.box(self.data, x=x_axis_label, > + title="Device: " + self.dev + "
" + self.test + > + "
(Outliers Included)", height=1200, width=2400) > + self.save_graph(fig) > + self.graph_num += 1 > + > + def grouped_graph(self, y_axis_label, x_axis_label, color_label): > + """Plot a grouped barchart using the given parameters.""" > + if (self.data[y_axis_label] == 0).all(): > + return > + fig = px.bar(self.data, x=x_axis_label, color=color_label, > + y=y_axis_label, > + title="Device: " + self.dev + "
" + self.test + "
" > + + y_axis_label + " for each " + x_axis_label + > + "/" + color_label, > + barmode="group", > + height=1200, > + width=2400) > + fig.update_xaxes(type='category') > + self.save_graph(fig) > + self.graph_num += 1 > + > + def histogram_graph(self, x_axis_label): > + """Plot a histogram graph using the given parameters.""" > + quart1 = self.data[x_axis_label].quantile(0.25) > + quart3 = self.data[x_axis_label].quantile(0.75) > + inter_quart_range = quart3 - quart1 > + dev_data_out = self.data[~((self.data[x_axis_label] < > + (quart1 - 1.5 * inter_quart_range)) | > + (self.data[x_axis_label] > > + (quart3 + 1.5 * inter_quart_range)))] > + fig = px.histogram(dev_data_out, x=x_axis_label, > + title="Device: " + self.dev + "
" + self.test + > + "
(Outliers removed using Interquartile Range)", > + height=1200, > + width=2400) > + max_val = dev_data_out[x_axis_label].max() > + min_val = dev_data_out[x_axis_label].min() > + fig.update_traces(xbins=dict( > + start=min_val, > + end=max_val, > + size=(max_val - min_val) / 200 > + )) > + self.save_graph(fig) > + self.graph_num += 1 > + > + > +def cleanup_throughput_datatypes(data): > + """Cleanup data types of throughput test results dataframe. """ > + data['burst_size'] = data['burst_size'].astype('int') > + data['buffer_size(b)'] = data['buffer_size(b)'].astype('int') > + data['burst_size'] = data['burst_size'].astype('category') > + data['buffer_size(b)'] = data['buffer_size(b)'].astype('category') > + data['failed_enq'] = data['failed_enq'].astype('int') > + data['throughput(gbps)'] = data['throughput(gbps)'].astype('float') > + data['ops(millions)'] = data['ops(millions)'].astype('float') > + data['cycles_per_buf'] = data['cycles_per_buf'].astype('float') > + return data > + > + > +def process_test_results(grapher, data): > + """ > + Process results from the test case, > + calling graph functions to output graph images. > + """ > + print("\tProcessing Test Case Results: " + grapher.test) > + if grapher.ptest == "throughput": > + grapher.data = cleanup_throughput_datatypes(data) > + for y_label in ["throughput(gbps)", "ops(millions)", > + "cycles_per_buf", "failed_enq"]: > + grapher.grouped_graph(y_label, "buffer_size(b)", > + "burst_size") > + elif grapher.ptest == "latency": > + data['time(us)'] = data['time(us)'].astype('float') > + grapher.data = data > + grapher.histogram_graph("time(us)") > + grapher.boxplot_graph("time(us)") > + else: > + print("Invalid ptest") > + return > + > + > +def create_results_pdf(dev): > + """Output results graphs to one PDF.""" > + if not os.path.exists(PDFS_PATH): > + os.makedirs(PDFS_PATH) > + dev_graphs = sorted(glob.glob(GRAPHS_PATH + "%s_*.jpg" % dev), key=( > + lambda x: int((x.rsplit('_', 1)[1]).split('.')[0]))) > + if dev_graphs: > + with open(PDFS_PATH + "/%s_results.pdf" % dev, "wb") as pdf_file: > + pdf_file.write(img2pdf.convert(dev_graphs)) > + > + > +def run_test(test_cmd, test, grapher, timestamp, params): > + """Run performance test app for the given test case parameters.""" > + print("\n\tRunning Test Case: " + test) > + try: > + process_out = subprocess.check_output([test_cmd] + params, > + universal_newlines=True, > + stderr=subprocess.STDOUT) > + rows = [] > + for line in process_out.split('\n'): > + if not line: > + continue > + if line.startswith('#'): > + columns = line[1:].split(',') > + elif line[0].isdigit(): > + rows.append(line.split(',')) > + else: > + continue > + data = pd.DataFrame(rows, columns=columns) > + data['date'] = timestamp > + grapher.test = test > + process_test_results(grapher, data) > + except subprocess.CalledProcessError as err: > + print("\tCannot run performance test application for: " + str(err)) > + return > + > + > +def run_test_suite(test_cmd, dut, test_cases, timestamp): > + """Parse test cases for the test suite and run each test.""" > + print("\nRunning Test Suite: " + dut) > + default_params = [] > + grapher = Grapher(dut) > + for (key, val) in test_cases['default']['eal'].items(): > + if len(key) == 1: > + default_params.append("-" + key + " " + val) > + else: > + default_params.append("--" + key + "=" + val) > + > + default_params.append("--") > + for (key, val) in test_cases['default']['app'].items(): > + if isinstance(val, bool): > + default_params.append("--" + key if val is True else "") > + else: > + default_params.append("--" + key + "=" + val) > + > + if 'ptest' not in test_cases['default']['app']: > + print("Test Suite must contain default ptest value, skipping") > + return > + grapher.ptest = test_cases['default']['app']['ptest'] > + > + for (test, params) in {k: v for (k, v) in test_cases.items() if > + k != "default"}.items(): > + extra_params = [] > + for (key, val) in params.items(): > + extra_params.append("--" + key + "=" + val) > + run_test(test_cmd, test, grapher, timestamp, > + default_params + extra_params) > + > + create_results_pdf(dut) > + > + > +def parse_args(): > + """Parse command-line arguments passed to script.""" > + parser = ArgumentParser() > + parser.add_argument('-f', '--file-path', > + default=shutil.which('dpdk-test-crypto-perf'), > + help="Path for test perf app") > + parser.add_argument('-t', '--test-suites', nargs='+', default=["all"], > + help="List of device test suites to run") > + args = parser.parse_args() > + return args.file_path, args.test_suites > + > + I think you should allow the user to specify paths for the configuration files and the output location. May also consider adding support for specifying a specific test case within a suite. > +def main(): > + """ > + Load JSON config and call relevant functions to run chosen test suites. > + """ > + test_cmd, test_suites = parse_args() > + if not os.path.isfile(test_cmd): > + print("Invalid filepath!") > + return > + try: > + with open(SCRIPT_PATH + 'graph_crypto_perf_config.json') as conf: > + test_suite_options = json.load(conf) > + except json.decoder.JSONDecodeError as err: > + print("Error loading JSON config: " + err.msg) > + return > + timestamp = pd.Timestamp(datetime.now()) > + > + if test_suites != ["all"]: > + dev_list = [] > + for (dut, test_cases) in {k: v for (k, v) in test_suite_options.items() > + if k in test_suites}.items(): > + dev_list.append(dut) > + run_test_suite(test_cmd, dut, test_cases, timestamp) > + if not dev_list: > + print("No valid device test suites chosen!") > + return > + else: > + for (dut, test_cases) in test_suite_options.items(): > + run_test_suite(test_cmd, dut, test_cases, timestamp) > + > + if os.path.exists(GRAPHS_PATH): > + shutil.rmtree(GRAPHS_PATH) > + > + > +if __name__ == "__main__": > + main() > diff --git a/usertools/graph_crypto_perf_config.json b/usertools/graph_crypto_perf_config.json > new file mode 100644 > index 0000000000..004ec3e84e > --- /dev/null > +++ b/usertools/graph_crypto_perf_config.json > @@ -0,0 +1,309 @@ > +{ > + "crypto_aesni_mb_throughput": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1", > + "vdev": "crypto_aesni_mb" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "buffer-sz": "64,128,256,512,768,1024,1408,2048", > + "burst-sz": "1,4,8,16,32", > + "ptest": "throughput", > + "devtype": "crypto_aesni_mb" > + } > + }, > + "AES-CBC-128 SHA1-HMAC auth-then-cipher decrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "16", > + "auth-algo": "sha1-hmac", > + "optype": "auth-then-cipher", > + "cipher-op": "decrypt" > + }, > + "AES-CBC-128 SHA1-HMAC cipher-then-auth encrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "16", > + "auth-algo": "sha1-hmac", > + "auth-op": "generate", > + "auth-key-sz": "64", > + "digest-sz": "20", > + "optype": "cipher-then-auth", > + "cipher-op": "encrypt" > + }, > + "AES-CBC-256 SHA2-256-HMAC auth-then-cipher decrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "32", > + "auth-algo": "sha2-256-hmac", > + "optype": "auth-then-cipher", > + "cipher-op": "decrypt" > + }, > + "AES-CBC-256 SHA2-256-HMAC cipher-then-auth encrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "32", > + "auth-algo": "sha2-256-hmac", > + "optype": "cipher-then-auth" > + }, > + "AES-GCM-128 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-iv-sz": "12", > + "aead-op": "encrypt", > + "aead-aad-sz": "16", > + "digest-sz": "16", > + "optype": "aead", > + "total-ops": "10000000" > + }, > + "AES-GCM-128 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-op": "decrypt" > + }, > + "AES-GCM-256 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "encrypt" > + }, > + "AES-GCM-256 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "decrypt" > + }, > + "AES-GMAC 128 auth-only generate": { > + "auth-algo": "aes-gmac", > + "auth-key-sz": "16", > + "auth-iv-sz": "12", > + "auth-op": "generate", > + "digest-sz": "16", > + "optype": "auth-only", > + "total-ops": "10000000" > + } > + }, > + "crypto_aesni_mb_latency": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1", > + "vdev": "crypto_aesni_mb" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "buffer-sz": "1024", > + "burst-sz": "16", > + "ptest": "latency", > + "devtype": "crypto_aesni_mb" > + } > + }, > + "AES-CBC-128 SHA1-HMAC auth-then-cipher decrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "16", > + "auth-algo": "sha1-hmac", > + "optype": "auth-then-cipher", > + "cipher-op": "decrypt" > + }, > + "AES-GCM-256 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "encrypt" > + } > + }, > + "crypto_aesni_gcm_throughput": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1", > + "vdev": "crypto_aesni_gcm" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "buffer-sz": "64,128,256,512,768,1024,1408,2048", > + "burst-sz": "1,4,8,16,32", > + "ptest": "throughput", > + "devtype": "crypto_aesni_gcm" > + } > + }, > + "AES-GCM-128 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-iv-sz": "12", > + "aead-op": "encrypt", > + "aead-aad-sz": "16", > + "digest-sz": "16", > + "optype": "aead", > + "total-ops": "10000000" > + }, > + "AES-GCM-128 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-op": "decrypt", > + "aead-aad-sz": "16", > + "aead-iv-sz": "12", > + "digest-sz": "16", > + "optype": "aead", > + "total-ops": "10000000" > + }, > + "AES-GCM-256 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "encrypt", > + "aead-aad-sz": "32", > + "aead-iv-sz": "12", > + "digest-sz": "16", > + "optype": "aead", > + "total-ops": "10000000" > + }, > + "AES-GCM-256 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "decrypt", > + "aead-aad-sz": "32", > + "aead-iv-sz": "12", > + "digest-sz": "16", > + "optype": "aead", > + "total-ops": "10000000" > + }, > + "AES-GMAC 128 auth-only generate": { > + "auth-algo": "aes-gmac", > + "auth-key-sz": "16", > + "auth-iv-sz": "12", > + "auth-op": "generate", > + "digest-sz": "16", > + "optype": "auth-only", > + "total-ops": "10000000" > + } > + }, > + "crypto_aesni_gcm_latency": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1", > + "vdev": "crypto_aesni_gcm" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "buffer-sz": "1024", > + "burst-sz": "16", > + "ptest": "latency", > + "devtype": "crypto_aesni_gcm" > + } > + }, > + "AES-GCM-128 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-op": "decrypt", > + "aead-aad-sz": "16", > + "aead-iv-sz": "12", > + "digest-sz": "16", > + "optype": "aead" > + }, > + "AES-GCM-256 aead-op encrypt latency": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "encrypt", > + "aead-aad-sz": "32", > + "aead-iv-sz": "12", > + "digest-sz": "16", > + "optype": "aead" > + } > + }, > + "crypto_qat_throughput": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "buffer-sz": "64,128,256,512,768,1024,1408,2048", > + "burst-sz": "1,4,8,16,32", > + "devtype": "crypto_qat", > + "ptest": "throughput" > + } > + }, > + "AES-CBC-128 SHA1-HMAC auth-then-cipher decrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "16", > + "auth-algo": "sha1-hmac", > + "optype": "auth-then-cipher", > + "cipher-op": "decrypt" > + }, > + "AES-CBC-128 SHA1-HMAC cipher-then-auth encrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "16", > + "auth-algo": "sha1-hmac", > + "optype": "cipher-then-auth", > + "cipher-op": "encrypt" > + }, > + "AES-CBC-256 SHA2-256-HMAC auth-then-cipher decrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "32", > + "auth-algo": "sha2-256-hmac", > + "optype": "auth-then-cipher", > + "cipher-op": "decrypt" > + }, > + "AES-CBC-256 SHA2-256-HMAC cipher-then-auth encrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "32", > + "auth-algo": "sha2-256-hmac", > + "optype": "cipher-then-auth", > + "cipher-op": "encrypt" > + }, > + "AES-GCM-128 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-iv-sz": "12", > + "aead-op": "encrypt", > + "aead-aad-sz": "16", > + "digest-sz": "16", > + "optype": "aead" > + }, > + "AES-GCM-128 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-op": "decrypt" > + }, > + "AES-GCM-256 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "encrypt" > + }, > + "AES-GCM-256 aead-op decrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "32", > + "aead-op": "decrypt" > + } > + }, > + "crypto_qat_latency": { > + "default": { > + "eal": { > + "l": "1,2", > + "log-level": "1" > + }, > + "app": { > + "csv-friendly": true, > + "silent": true, > + "ptest": "latency", > + "buffer-sz": "1024", > + "burst-sz": "16", > + "devtype": "crypto_qat" > + } > + }, > + "AES-CBC-256 SHA2-256-HMAC cipher-then-auth encrypt": { > + "cipher-algo": "aes-cbc", > + "cipher-key-sz": "32", > + "auth-algo": "sha2-256-hmac", > + "optype": "cipher-then-auth", > + "cipher-op": "encrypt" > + }, > + "AES-GCM-128 aead-op encrypt": { > + "aead-algo": "aes-gcm", > + "aead-key-sz": "16", > + "aead-op": "encrypt" > + } > + } > +} > \ No newline at end of file > I would suggest splitting the json file into one configuration per device type.