get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/66256/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 66256,
    "url": "http://patches.dpdk.org/api/patches/66256/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1583346152-10186-8-git-send-email-nicolas.chautru@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1583346152-10186-8-git-send-email-nicolas.chautru@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1583346152-10186-8-git-send-email-nicolas.chautru@intel.com",
    "date": "2020-03-04T18:22:24",
    "name": "[v2,07/15] test-bbdev: support for performance tests",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0ee3d17b377ba8ce68b89c9d217bcb6b8082040d",
    "submitter": {
        "id": 1314,
        "url": "http://patches.dpdk.org/api/people/1314/?format=api",
        "name": "Chautru, Nicolas",
        "email": "nicolas.chautru@intel.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1583346152-10186-8-git-send-email-nicolas.chautru@intel.com/mbox/",
    "series": [
        {
            "id": 8783,
            "url": "http://patches.dpdk.org/api/series/8783/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8783",
            "date": "2020-03-04T18:22:17",
            "name": "bbdev new features",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/8783/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/66256/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/66256/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 9E6F5A0573;\n\tWed,  4 Mar 2020 19:24:07 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 145231C029;\n\tWed,  4 Mar 2020 19:22:58 +0100 (CET)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by dpdk.org (Postfix) with ESMTP id 2E73B1BFAB\n for <dev@dpdk.org>; Wed,  4 Mar 2020 19:22:47 +0100 (CET)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n 04 Mar 2020 10:22:43 -0800",
            "from skx-5gnr-sc12-4.sc.intel.com ([172.25.69.210])\n by fmsmga008.fm.intel.com with ESMTP; 04 Mar 2020 10:22:43 -0800"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.70,514,1574150400\"; d=\"scan'208\";a=\"234199013\"",
        "From": "Nicolas Chautru <nicolas.chautru@intel.com>",
        "To": "thomas@monjalon.net,\n\takhil.goyal@nxp.com,\n\tdev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com,\n\tNic Chautru <nicolas.chautru@intel.com>",
        "Date": "Wed,  4 Mar 2020 10:22:24 -0800",
        "Message-Id": "<1583346152-10186-8-git-send-email-nicolas.chautru@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1583346152-10186-1-git-send-email-nicolas.chautru@intel.com>",
        "References": "<1582778348-113547-15-git-send-email-nicolas.chautru@intel.com>\n <1583346152-10186-1-git-send-email-nicolas.chautru@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 07/15] test-bbdev: support for performance\n\ttests",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Nic Chautru <nicolas.chautru@intel.com>\n\nIncludes support for BLER wireless performance test with\nnew arguments for SNR and number of iterations for 5G.\n\nSigned-off-by: Nic Chautru <nicolas.chautru@intel.com>\n---\n app/test-bbdev/main.c            |  29 ++-\n app/test-bbdev/main.h            |   9 +-\n app/test-bbdev/test_bbdev_perf.c | 523 ++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 548 insertions(+), 13 deletions(-)",
    "diff": "diff --git a/app/test-bbdev/main.c b/app/test-bbdev/main.c\nindex 8a42115..ff65173 100644\n--- a/app/test-bbdev/main.c\n+++ b/app/test-bbdev/main.c\n@@ -29,6 +29,8 @@\n \tunsigned int num_ops;\n \tunsigned int burst_sz;\n \tunsigned int num_lcores;\n+\tdouble snr;\n+\tunsigned int iter_max;\n \tchar test_vector_filename[PATH_MAX];\n \tbool init_device;\n } test_params;\n@@ -140,6 +142,18 @@\n \treturn test_params.num_lcores;\n }\n \n+double\n+get_snr(void)\n+{\n+\treturn test_params.snr;\n+}\n+\n+unsigned int\n+get_iter_max(void)\n+{\n+\treturn test_params.iter_max;\n+}\n+\n bool\n get_init_device(void)\n {\n@@ -180,12 +194,15 @@\n \t\t{ \"test-cases\", 1, 0, 'c' },\n \t\t{ \"test-vector\", 1, 0, 'v' },\n \t\t{ \"lcores\", 1, 0, 'l' },\n+\t\t{ \"snr\", 1, 0, 's' },\n+\t\t{ \"iter_max\", 6, 0, 't' },\n \t\t{ \"init-device\", 0, 0, 'i'},\n \t\t{ \"help\", 0, 0, 'h' },\n \t\t{ NULL,  0, 0, 0 }\n \t};\n+\ttp->iter_max = DEFAULT_ITER;\n \n-\twhile ((opt = getopt_long(argc, argv, \"hin:b:c:v:l:\", lgopts,\n+\twhile ((opt = getopt_long(argc, argv, \"hin:b:c:v:l:s:t:\", lgopts,\n \t\t\t&option_index)) != EOF)\n \t\tswitch (opt) {\n \t\tcase 'n':\n@@ -237,6 +254,16 @@\n \t\t\t\t\tsizeof(tp->test_vector_filename),\n \t\t\t\t\t\"%s\", optarg);\n \t\t\tbreak;\n+\t\tcase 's':\n+\t\t\tTEST_ASSERT(strlen(optarg) > 0,\n+\t\t\t\t\t\"SNR is not provided\");\n+\t\t\ttp->snr = strtod(optarg, NULL);\n+\t\t\tbreak;\n+\t\tcase 't':\n+\t\t\tTEST_ASSERT(strlen(optarg) > 0,\n+\t\t\t\t\t\"Iter_max is not provided\");\n+\t\t\ttp->iter_max = strtol(optarg, NULL, 10);\n+\t\t\tbreak;\n \t\tcase 'l':\n \t\t\tTEST_ASSERT(strlen(optarg) > 0,\n \t\t\t\t\t\"Num of lcores is not provided\");\ndiff --git a/app/test-bbdev/main.h b/app/test-bbdev/main.h\nindex 23b4d58..fb3dec8 100644\n--- a/app/test-bbdev/main.h\n+++ b/app/test-bbdev/main.h\n@@ -19,6 +19,8 @@\n #define MAX_BURST 512U\n #define DEFAULT_BURST 32U\n #define DEFAULT_OPS 64U\n+#define DEFAULT_ITER 6U\n+\n \n \n #define TEST_ASSERT(cond, msg, ...) do {  \\\n@@ -104,8 +106,7 @@ struct test_command {\n \t\t.command = RTE_STR(name), \\\n \t\t.callback = test_func_##name, \\\n \t}; \\\n-\tstatic void __attribute__((constructor, used)) \\\n-\ttest_register_##name(void) \\\n+\tRTE_INIT(test_register_##name) \\\n \t{ \\\n \t\tadd_test_command(&test_struct_##name); \\\n \t}\n@@ -118,6 +119,10 @@ struct test_command {\n \n unsigned int get_num_lcores(void);\n \n+double get_snr(void);\n+\n+unsigned int get_iter_max(void);\n+\n bool get_init_device(void);\n \n #endif\ndiff --git a/app/test-bbdev/test_bbdev_perf.c b/app/test-bbdev/test_bbdev_perf.c\nindex 978ccd6..7bc824b 100644\n--- a/app/test-bbdev/test_bbdev_perf.c\n+++ b/app/test-bbdev/test_bbdev_perf.c\n@@ -111,6 +111,8 @@ struct thread_params {\n \tdouble ops_per_sec;\n \tdouble mbps;\n \tuint8_t iter_count;\n+\tdouble iter_average;\n+\tdouble bler;\n \trte_atomic16_t nb_dequeued;\n \trte_atomic16_t processing_status;\n \trte_atomic16_t burst_sz;\n@@ -1204,6 +1206,213 @@ typedef int (test_case_function)(struct active_device *ad,\n \t}\n }\n \n+\n+/* Returns a random number drawn from a normal distribution\n+ * with mean of 0 and variance of 1\n+ * Marsaglia algorithm\n+ */\n+static double\n+randn(int n)\n+{\n+\tdouble S, Z, U1, U2, u, v, fac;\n+\n+\tdo {\n+\t\tU1 = (double)rand() / RAND_MAX;\n+\t\tU2 = (double)rand() / RAND_MAX;\n+\t\tu = 2. * U1 - 1.;\n+\t\tv = 2. * U2 - 1.;\n+\t\tS = u * u + v * v;\n+\t} while (S >= 1 || S == 0);\n+\tfac = sqrt(-2. * log(S) / S);\n+\tZ = (n % 2) ? u * fac : v * fac;\n+\treturn Z;\n+}\n+\n+static inline double\n+maxstar(double A, double B)\n+{\n+\tif (fabs(A - B) > 5)\n+\t\treturn fmax(A, B);\n+\telse\n+\t\treturn fmax(A, B) + log1p(exp(-fabs(A - B)));\n+}\n+\n+\n+/*\n+ * Generate Qm LLRS for Qm==6\n+ * Modulation, AWGN and LLR estimation from max log development\n+ */\n+static void\n+gen_qm6_llr(int8_t *llrs, uint32_t i, double N0, double llr_max)\n+{\n+\tint qm = 6;\n+\tint qam = 64;\n+\tint m, k;\n+\tdouble I, Q, p0, p1, llr_, b[qm], log_syml_prob[qam];\n+\t/* 5.1.4 of TS38.211 */\n+\tconst double symbols_I[64] = {\n+\t\t\t3, 3, 1, 1, 3, 3, 1, 1, 5, 5, 7, 7, 5, 5, 7, 7,\n+\t\t\t3, 3, 1, 1, 3, 3, 1, 1, 5, 5, 7, 7, 5, 5, 7, 7,\n+\t\t\t-3, -3, -1, -1, -3, -3, -1, -1, -5, -5, -7, -7,\n+\t\t\t-5, -5, -7, -7, -3, -3, -1, -1, -3, -3, -1, -1,\n+\t\t\t-5, -5, -7, -7, -5, -5, -7, -7};\n+\tconst double symbols_Q[64] = {\n+\t\t\t3, 1, 3, 1, 5, 7, 5, 7, 3, 1, 3, 1, 5, 7, 5, 7,\n+\t\t\t-3, -1, -3, -1, -5, -7, -5, -7, -3, -1, -3, -1,\n+\t\t\t-5, -7, -5, -7, 3, 1, 3, 1, 5, 7, 5, 7, 3, 1, 3, 1,\n+\t\t\t5, 7, 5, 7, -3, -1, -3, -1, -5, -7, -5, -7,\n+\t\t\t-3, -1, -3, -1, -5, -7, -5, -7};\n+\t/* Average constellation point energy */\n+\tN0 *= 42.0;\n+\tfor (k = 0; k < qm; k++)\n+\t\tb[k] = llrs[qm * i + k] < 0 ? 1.0 : 0.0;\n+\t/* 5.1.4 of TS38.211 */\n+\tI = (1 - 2 * b[0])*(4 - (1 - 2 * b[2]) * (2 - (1 - 2 * b[4])));\n+\tQ = (1 - 2 * b[1])*(4 - (1 - 2 * b[3]) * (2 - (1 - 2 * b[5])));\n+\t/* AWGN channel */\n+\tI += sqrt(N0 / 2) * randn(0);\n+\tQ += sqrt(N0 / 2) * randn(1);\n+\t/*\n+\t * Calculate the log of the probability that each of\n+\t * the constellation points was transmitted\n+\t */\n+\tfor (m = 0; m < qam; m++)\n+\t\tlog_syml_prob[m] = -(pow(I - symbols_I[m], 2.0)\n+\t\t\t\t+ pow(Q - symbols_Q[m], 2.0)) / N0;\n+\t/* Calculate an LLR for each of the k_64QAM bits in the set */\n+\tfor (k = 0; k < qm; k++) {\n+\t\tp0 = -999999;\n+\t\tp1 = -999999;\n+\t\t/* For each constellation point */\n+\t\tfor (m = 0; m < qam; m++) {\n+\t\t\tif ((m >> (qm - k - 1)) & 1)\n+\t\t\t\tp1 = maxstar(p1, log_syml_prob[m]);\n+\t\t\telse\n+\t\t\t\tp0 = maxstar(p0, log_syml_prob[m]);\n+\t\t}\n+\t\t/* Calculate the LLR */\n+\t\tllr_ = p0 - p1;\n+\t\tllr_ *= (1 << ldpc_llr_decimals);\n+\t\tllr_ = round(llr_);\n+\t\tif (llr_ > llr_max)\n+\t\t\tllr_ = llr_max;\n+\t\tif (llr_ < -llr_max)\n+\t\t\tllr_ = -llr_max;\n+\t\tllrs[qm * i + k] = (int8_t) llr_;\n+\t}\n+}\n+\n+/*\n+ * Generate Qm LLRS for Qm==4\n+ * Modulation, AWGN and LLR estimation from max log development\n+ */\n+static void\n+gen_qm4_llr(int8_t *llrs, uint32_t i, double N0, double llr_max)\n+{\n+\tint qm = 4;\n+\tint qam = 16;\n+\tint m, k;\n+\tdouble I, Q, p0, p1, llr_, b[qm], log_syml_prob[qam];\n+\t/* 5.1.4 of TS38.211 */\n+\tconst double symbols_I[16] = {1, 1, 3, 3, 1, 1, 3, 3,\n+\t\t\t-1, -1, -3, -3, -1, -1, -3, -3};\n+\tconst double symbols_Q[16] = {1, 3, 1, 3, -1, -3, -1, -3,\n+\t\t\t1, 3, 1, 3, -1, -3, -1, -3};\n+\t/* Average constellation point energy */\n+\tN0 *= 10.0;\n+\tfor (k = 0; k < qm; k++)\n+\t\tb[k] = llrs[qm * i + k] < 0 ? 1.0 : 0.0;\n+\t/* 5.1.4 of TS38.211 */\n+\tI = (1 - 2 * b[0]) * (2 - (1 - 2 * b[2]));\n+\tQ = (1 - 2 * b[1]) * (2 - (1 - 2 * b[3]));\n+\t/* AWGN channel */\n+\tI += sqrt(N0 / 2) * randn(0);\n+\tQ += sqrt(N0 / 2) * randn(1);\n+\t/*\n+\t * Calculate the log of the probability that each of\n+\t * the constellation points was transmitted\n+\t */\n+\tfor (m = 0; m < qam; m++)\n+\t\tlog_syml_prob[m] = -(pow(I - symbols_I[m], 2.0)\n+\t\t\t\t+ pow(Q - symbols_Q[m], 2.0)) / N0;\n+\t/* Calculate an LLR for each of the k_64QAM bits in the set */\n+\tfor (k = 0; k < qm; k++) {\n+\t\tp0 = -999999;\n+\t\tp1 = -999999;\n+\t\t/* For each constellation point */\n+\t\tfor (m = 0; m < qam; m++) {\n+\t\t\tif ((m >> (qm - k - 1)) & 1)\n+\t\t\t\tp1 = maxstar(p1, log_syml_prob[m]);\n+\t\t\telse\n+\t\t\t\tp0 = maxstar(p0, log_syml_prob[m]);\n+\t\t}\n+\t\t/* Calculate the LLR */\n+\t\tllr_ = p0 - p1;\n+\t\tllr_ *= (1 << ldpc_llr_decimals);\n+\t\tllr_ = round(llr_);\n+\t\tif (llr_ > llr_max)\n+\t\t\tllr_ = llr_max;\n+\t\tif (llr_ < -llr_max)\n+\t\t\tllr_ = -llr_max;\n+\t\tllrs[qm * i + k] = (int8_t) llr_;\n+\t}\n+}\n+\n+static void\n+gen_qm2_llr(int8_t *llrs, uint32_t j, double N0, double llr_max)\n+{\n+\tdouble b, b1, n;\n+\tdouble coeff = 2.0 * sqrt(N0);\n+\n+\t/* Ignore in vectors rare quasi null LLRs not to be saturated */\n+\tif (llrs[j] < 8 && llrs[j] > -8)\n+\t\treturn;\n+\n+\t/* Note don't change sign here */\n+\tn = randn(j % 2);\n+\tb1 = ((llrs[j] > 0 ? 2.0 : -2.0)\n+\t\t\t+ coeff * n) / N0;\n+\tb = b1 * (1 << ldpc_llr_decimals);\n+\tb = round(b);\n+\tif (b > llr_max)\n+\t\tb = llr_max;\n+\tif (b < -llr_max)\n+\t\tb = -llr_max;\n+\tllrs[j] = (int8_t) b;\n+}\n+\n+/* Generate LLR for a given SNR */\n+static void\n+generate_llr_input(uint16_t n, struct rte_bbdev_op_data *inputs,\n+\t\tstruct rte_bbdev_dec_op *ref_op)\n+{\n+\tstruct rte_mbuf *m;\n+\tuint16_t qm;\n+\tuint32_t i, j, e, range;\n+\tdouble N0, llr_max;\n+\n+\te = ref_op->ldpc_dec.cb_params.e;\n+\tqm = ref_op->ldpc_dec.q_m;\n+\tllr_max = (1 << (ldpc_llr_size - 1)) - 1;\n+\trange = e / qm;\n+\tN0 = 1.0 / pow(10.0, get_snr() / 10.0);\n+\n+\tfor (i = 0; i < n; ++i) {\n+\t\tm = inputs[i].data;\n+\t\tint8_t *llrs = rte_pktmbuf_mtod_offset(m, int8_t *, 0);\n+\t\tif (qm == 6) {\n+\t\t\tfor (j = 0; j < range; ++j)\n+\t\t\t\tgen_qm6_llr(llrs, j, N0, llr_max);\n+\t\t} else if (qm == 4) {\n+\t\t\tfor (j = 0; j < range; ++j)\n+\t\t\t\tgen_qm4_llr(llrs, j, N0, llr_max);\n+\t\t} else {\n+\t\t\tfor (j = 0; j < e; ++j)\n+\t\t\t\tgen_qm2_llr(llrs, j, N0, llr_max);\n+\t\t}\n+\t}\n+}\n+\n static void\n copy_reference_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n,\n \t\tunsigned int start_idx,\n@@ -1301,7 +1510,7 @@ typedef int (test_case_function)(struct active_device *ad,\n {\n \tint status = op->status;\n \t/* ignore parity mismatch false alarms for long iterations */\n-\t{\n+\tif (get_iter_max() >= 10) {\n \t\tif (!(expected_status & (1 << RTE_BBDEV_SYNDROME_ERROR)) &&\n \t\t\t\t(status & (1 << RTE_BBDEV_SYNDROME_ERROR))) {\n \t\t\tprintf(\"WARNING: Ignore Syndrome Check mismatch\\n\");\n@@ -1587,6 +1796,30 @@ typedef int (test_case_function)(struct active_device *ad,\n \treturn TEST_SUCCESS;\n }\n \n+/* Check Number of code blocks errors */\n+static int\n+validate_ldpc_bler(struct rte_bbdev_dec_op **ops, const uint16_t n)\n+{\n+\tunsigned int i;\n+\tstruct op_data_entries *hard_data_orig =\n+\t\t\t&test_vector.entries[DATA_HARD_OUTPUT];\n+\tstruct rte_bbdev_op_ldpc_dec *ops_td;\n+\tstruct rte_bbdev_op_data *hard_output;\n+\tint errors = 0;\n+\tstruct rte_mbuf *m;\n+\n+\tfor (i = 0; i < n; ++i) {\n+\t\tops_td = &ops[i]->ldpc_dec;\n+\t\thard_output = &ops_td->hard_output;\n+\t\tm = hard_output->data;\n+\t\tif (memcmp(rte_pktmbuf_mtod_offset(m, uint32_t *, 0),\n+\t\t\t\thard_data_orig->segments[0].addr,\n+\t\t\t\thard_data_orig->segments[0].length))\n+\t\t\terrors++;\n+\t}\n+\treturn errors;\n+}\n+\n static int\n validate_ldpc_dec_op(struct rte_bbdev_dec_op **ops, const uint16_t n,\n \t\tstruct rte_bbdev_dec_op *ref_op, const int vector_mask)\n@@ -2500,6 +2733,139 @@ typedef int (test_case_function)(struct active_device *ad,\n }\n \n static int\n+bler_pmd_lcore_ldpc_dec(void *arg)\n+{\n+\tstruct thread_params *tp = arg;\n+\tuint16_t enq, deq;\n+\tuint64_t total_time = 0, start_time;\n+\tconst uint16_t queue_id = tp->queue_id;\n+\tconst uint16_t burst_sz = tp->op_params->burst_sz;\n+\tconst uint16_t num_ops = tp->op_params->num_to_process;\n+\tstruct rte_bbdev_dec_op *ops_enq[num_ops];\n+\tstruct rte_bbdev_dec_op *ops_deq[num_ops];\n+\tstruct rte_bbdev_dec_op *ref_op = tp->op_params->ref_dec_op;\n+\tstruct test_buffers *bufs = NULL;\n+\tint i, j, ret;\n+\tfloat parity_bler = 0;\n+\tstruct rte_bbdev_info info;\n+\tuint16_t num_to_enq;\n+\tbool extDdr = check_bit(ldpc_cap_flags,\n+\t\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE);\n+\tbool loopback = check_bit(ref_op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK);\n+\tbool hc_out = check_bit(ref_op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE);\n+\n+\tTEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),\n+\t\t\t\"BURST_SIZE should be <= %u\", MAX_BURST);\n+\n+\trte_bbdev_info_get(tp->dev_id, &info);\n+\n+\tTEST_ASSERT_SUCCESS((num_ops > info.drv.queue_size_lim),\n+\t\t\t\"NUM_OPS cannot exceed %u for this device\",\n+\t\t\tinfo.drv.queue_size_lim);\n+\n+\tbufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];\n+\n+\twhile (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)\n+\t\trte_pause();\n+\n+\tret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp, ops_enq, num_ops);\n+\tTEST_ASSERT_SUCCESS(ret, \"Allocation failed for %d ops\", num_ops);\n+\n+\t/* For BLER tests we need to enable early termination */\n+\tif (!check_bit(ref_op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE))\n+\t\tref_op->ldpc_dec.op_flags +=\n+\t\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE;\n+\tref_op->ldpc_dec.iter_max = get_iter_max();\n+\tref_op->ldpc_dec.iter_count = ref_op->ldpc_dec.iter_max;\n+\n+\tif (test_vector.op_type != RTE_BBDEV_OP_NONE)\n+\t\tcopy_reference_ldpc_dec_op(ops_enq, num_ops, 0, bufs->inputs,\n+\t\t\t\tbufs->hard_outputs, bufs->soft_outputs,\n+\t\t\t\tbufs->harq_inputs, bufs->harq_outputs, ref_op);\n+\tgenerate_llr_input(num_ops, bufs->inputs, ref_op);\n+\n+\t/* Set counter to validate the ordering */\n+\tfor (j = 0; j < num_ops; ++j)\n+\t\tops_enq[j]->opaque_data = (void *)(uintptr_t)j;\n+\n+\tfor (i = 0; i < 1; ++i) { /* Could add more iterations */\n+\t\tfor (j = 0; j < num_ops; ++j) {\n+\t\t\tif (!loopback)\n+\t\t\t\tmbuf_reset(\n+\t\t\t\tops_enq[j]->ldpc_dec.hard_output.data);\n+\t\t\tif (hc_out || loopback)\n+\t\t\t\tmbuf_reset(\n+\t\t\t\tops_enq[j]->ldpc_dec.harq_combined_output.data);\n+\t\t}\n+\t\tif (extDdr) {\n+\t\t\tbool preload = i == (TEST_REPETITIONS - 1);\n+\t\t\tpreload_harq_ddr(tp->dev_id, queue_id, ops_enq,\n+\t\t\t\t\tnum_ops, preload);\n+\t\t}\n+\t\tstart_time = rte_rdtsc_precise();\n+\n+\t\tfor (enq = 0, deq = 0; enq < num_ops;) {\n+\t\t\tnum_to_enq = burst_sz;\n+\n+\t\t\tif (unlikely(num_ops - enq < num_to_enq))\n+\t\t\t\tnum_to_enq = num_ops - enq;\n+\n+\t\t\tenq += rte_bbdev_enqueue_ldpc_dec_ops(tp->dev_id,\n+\t\t\t\t\tqueue_id, &ops_enq[enq], num_to_enq);\n+\n+\t\t\tdeq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id,\n+\t\t\t\t\tqueue_id, &ops_deq[deq], enq - deq);\n+\t\t}\n+\n+\t\t/* dequeue the remaining */\n+\t\twhile (deq < enq) {\n+\t\t\tdeq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id,\n+\t\t\t\t\tqueue_id, &ops_deq[deq], enq - deq);\n+\t\t}\n+\n+\t\ttotal_time += rte_rdtsc_precise() - start_time;\n+\t}\n+\n+\ttp->iter_count = 0;\n+\ttp->iter_average = 0;\n+\t/* get the max of iter_count for all dequeued ops */\n+\tfor (i = 0; i < num_ops; ++i) {\n+\t\ttp->iter_count = RTE_MAX(ops_enq[i]->ldpc_dec.iter_count,\n+\t\t\t\ttp->iter_count);\n+\t\ttp->iter_average += (double) ops_enq[i]->ldpc_dec.iter_count;\n+\t\tif (ops_enq[i]->status & (1 << RTE_BBDEV_SYNDROME_ERROR))\n+\t\t\tparity_bler += 1.0;\n+\t}\n+\n+\tparity_bler /= num_ops; /* This one is based on SYND */\n+\ttp->iter_average /= num_ops;\n+\ttp->bler = (double) validate_ldpc_bler(ops_deq, num_ops) / num_ops;\n+\n+\tif (test_vector.op_type != RTE_BBDEV_OP_NONE\n+\t\t\t&& tp->bler == 0\n+\t\t\t&& parity_bler == 0\n+\t\t\t&& !hc_out) {\n+\t\tret = validate_ldpc_dec_op(ops_deq, num_ops, ref_op,\n+\t\t\t\ttp->op_params->vector_mask);\n+\t\tTEST_ASSERT_SUCCESS(ret, \"Validation failed!\");\n+\t}\n+\n+\trte_bbdev_dec_op_free_bulk(ops_enq, num_ops);\n+\n+\tdouble tb_len_bits = calc_ldpc_dec_TB_size(ref_op);\n+\ttp->ops_per_sec = ((double)num_ops * 1) /\n+\t\t\t((double)total_time / (double)rte_get_tsc_hz());\n+\ttp->mbps = (((double)(num_ops * 1 * tb_len_bits)) /\n+\t\t\t1000000.0) / ((double)total_time /\n+\t\t\t(double)rte_get_tsc_hz());\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n throughput_pmd_lcore_ldpc_dec(void *arg)\n {\n \tstruct thread_params *tp = arg;\n@@ -2544,7 +2910,7 @@ typedef int (test_case_function)(struct active_device *ad,\n \t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE))\n \t\tref_op->ldpc_dec.op_flags -=\n \t\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE;\n-\tref_op->ldpc_dec.iter_max = 6;\n+\tref_op->ldpc_dec.iter_max = get_iter_max();\n \tref_op->ldpc_dec.iter_count = ref_op->ldpc_dec.iter_max;\n \n \tif (test_vector.op_type != RTE_BBDEV_OP_NONE)\n@@ -2825,27 +3191,147 @@ typedef int (test_case_function)(struct active_device *ad,\n \t\tused_cores, total_mops, total_mbps);\n }\n \n+/* Aggregate the performance results over the number of cores used */\n static void\n print_dec_throughput(struct thread_params *t_params, unsigned int used_cores)\n {\n-\tunsigned int iter = 0;\n+\tunsigned int core_idx = 0;\n \tdouble total_mops = 0, total_mbps = 0;\n \tuint8_t iter_count = 0;\n \n-\tfor (iter = 0; iter < used_cores; iter++) {\n+\tfor (core_idx = 0; core_idx < used_cores; core_idx++) {\n \t\tprintf(\n \t\t\t\"Throughput for core (%u): %.8lg Ops/s, %.8lg Mbps @ max %u iterations\\n\",\n-\t\t\tt_params[iter].lcore_id, t_params[iter].ops_per_sec,\n-\t\t\tt_params[iter].mbps, t_params[iter].iter_count);\n-\t\ttotal_mops += t_params[iter].ops_per_sec;\n-\t\ttotal_mbps += t_params[iter].mbps;\n-\t\titer_count = RTE_MAX(iter_count, t_params[iter].iter_count);\n+\t\t\tt_params[core_idx].lcore_id,\n+\t\t\tt_params[core_idx].ops_per_sec,\n+\t\t\tt_params[core_idx].mbps,\n+\t\t\tt_params[core_idx].iter_count);\n+\t\ttotal_mops += t_params[core_idx].ops_per_sec;\n+\t\ttotal_mbps += t_params[core_idx].mbps;\n+\t\titer_count = RTE_MAX(iter_count,\n+\t\t\t\tt_params[core_idx].iter_count);\n \t}\n \tprintf(\n \t\t\"\\nTotal throughput for %u cores: %.8lg MOPS, %.8lg Mbps @ max %u iterations\\n\",\n \t\tused_cores, total_mops, total_mbps, iter_count);\n }\n \n+/* Aggregate the performance results over the number of cores used */\n+static void\n+print_dec_bler(struct thread_params *t_params, unsigned int used_cores)\n+{\n+\tunsigned int core_idx = 0;\n+\tdouble total_mbps = 0, total_bler = 0, total_iter = 0;\n+\tdouble snr = get_snr();\n+\n+\tfor (core_idx = 0; core_idx < used_cores; core_idx++) {\n+\t\tprintf(\"Core%u BLER %.1f %% - Iters %.1f - Tp %.1f Mbps %s\\n\",\n+\t\t\t\tt_params[core_idx].lcore_id,\n+\t\t\t\tt_params[core_idx].bler * 100,\n+\t\t\t\tt_params[core_idx].iter_average,\n+\t\t\t\tt_params[core_idx].mbps,\n+\t\t\t\tget_vector_filename());\n+\t\ttotal_mbps += t_params[core_idx].mbps;\n+\t\ttotal_bler += t_params[core_idx].bler;\n+\t\ttotal_iter += t_params[core_idx].iter_average;\n+\t}\n+\ttotal_bler /= used_cores;\n+\ttotal_iter /= used_cores;\n+\n+\tprintf(\"SNR %.2f BLER %.1f %% - Iterations %.1f %d - Tp %.1f Mbps %s\\n\",\n+\t\t\tsnr, total_bler * 100, total_iter, get_iter_max(),\n+\t\t\ttotal_mbps, get_vector_filename());\n+}\n+\n+/*\n+ * Test function that determines BLER wireless performance\n+ */\n+static int\n+bler_test(struct active_device *ad,\n+\t\tstruct test_op_params *op_params)\n+{\n+\tint ret;\n+\tunsigned int lcore_id, used_cores = 0;\n+\tstruct thread_params *t_params;\n+\tstruct rte_bbdev_info info;\n+\tlcore_function_t *bler_function;\n+\tuint16_t num_lcores;\n+\tconst char *op_type_str;\n+\n+\trte_bbdev_info_get(ad->dev_id, &info);\n+\n+\top_type_str = rte_bbdev_op_type_str(test_vector.op_type);\n+\tTEST_ASSERT_NOT_NULL(op_type_str, \"Invalid op type: %u\",\n+\t\t\ttest_vector.op_type);\n+\n+\tprintf(\"+ ------------------------------------------------------- +\\n\");\n+\tprintf(\"== test: bler\\ndev: %s, nb_queues: %u, burst size: %u, num ops: %u, num_lcores: %u, op type: %s, itr mode: %s, GHz: %lg\\n\",\n+\t\t\tinfo.dev_name, ad->nb_queues, op_params->burst_sz,\n+\t\t\top_params->num_to_process, op_params->num_lcores,\n+\t\t\top_type_str,\n+\t\t\tintr_enabled ? \"Interrupt mode\" : \"PMD mode\",\n+\t\t\t(double)rte_get_tsc_hz() / 1000000000.0);\n+\n+\t/* Set number of lcores */\n+\tnum_lcores = (ad->nb_queues < (op_params->num_lcores))\n+\t\t\t? ad->nb_queues\n+\t\t\t: op_params->num_lcores;\n+\n+\t/* Allocate memory for thread parameters structure */\n+\tt_params = rte_zmalloc(NULL, num_lcores * sizeof(struct thread_params),\n+\t\t\tRTE_CACHE_LINE_SIZE);\n+\tTEST_ASSERT_NOT_NULL(t_params, \"Failed to alloc %zuB for t_params\",\n+\t\t\tRTE_ALIGN(sizeof(struct thread_params) * num_lcores,\n+\t\t\t\tRTE_CACHE_LINE_SIZE));\n+\n+\tif (test_vector.op_type == RTE_BBDEV_OP_LDPC_DEC)\n+\t\tbler_function = bler_pmd_lcore_ldpc_dec;\n+\telse\n+\t\treturn TEST_SKIPPED;\n+\n+\trte_atomic16_set(&op_params->sync, SYNC_WAIT);\n+\n+\t/* Master core is set at first entry */\n+\tt_params[0].dev_id = ad->dev_id;\n+\tt_params[0].lcore_id = rte_lcore_id();\n+\tt_params[0].op_params = op_params;\n+\tt_params[0].queue_id = ad->queue_ids[used_cores++];\n+\tt_params[0].iter_count = 0;\n+\n+\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\t\tif (used_cores >= num_lcores)\n+\t\t\tbreak;\n+\n+\t\tt_params[used_cores].dev_id = ad->dev_id;\n+\t\tt_params[used_cores].lcore_id = lcore_id;\n+\t\tt_params[used_cores].op_params = op_params;\n+\t\tt_params[used_cores].queue_id = ad->queue_ids[used_cores];\n+\t\tt_params[used_cores].iter_count = 0;\n+\n+\t\trte_eal_remote_launch(bler_function,\n+\t\t\t\t&t_params[used_cores++], lcore_id);\n+\t}\n+\n+\trte_atomic16_set(&op_params->sync, SYNC_START);\n+\tret = bler_function(&t_params[0]);\n+\n+\t/* Master core is always used */\n+\tfor (used_cores = 1; used_cores < num_lcores; used_cores++)\n+\t\tret |= rte_eal_wait_lcore(t_params[used_cores].lcore_id);\n+\n+\tprint_dec_bler(t_params, num_lcores);\n+\n+\t/* Return if test failed */\n+\tif (ret) {\n+\t\trte_free(t_params);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Function to print something  here*/\n+\trte_free(t_params);\n+\treturn ret;\n+}\n+\n /*\n  * Test function that determines how long an enqueue + dequeue of a burst\n  * takes on available lcores.\n@@ -3113,7 +3599,7 @@ typedef int (test_case_function)(struct active_device *ad,\n \t\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE))\n \t\t\tref_op->ldpc_dec.op_flags -=\n \t\t\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE;\n-\t\tref_op->ldpc_dec.iter_max = 6;\n+\t\tref_op->ldpc_dec.iter_max = get_iter_max();\n \t\tref_op->ldpc_dec.iter_count = ref_op->ldpc_dec.iter_max;\n \n \t\tif (test_vector.op_type != RTE_BBDEV_OP_NONE)\n@@ -3971,6 +4457,12 @@ typedef int (test_case_function)(struct active_device *ad,\n }\n \n static int\n+bler_tc(void)\n+{\n+\treturn run_test_case(bler_test);\n+}\n+\n+static int\n throughput_tc(void)\n {\n \treturn run_test_case(throughput_test);\n@@ -4000,6 +4492,16 @@ typedef int (test_case_function)(struct active_device *ad,\n \treturn run_test_case(throughput_test);\n }\n \n+static struct unit_test_suite bbdev_bler_testsuite = {\n+\t.suite_name = \"BBdev BLER Tests\",\n+\t.setup = testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, bler_tc),\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n static struct unit_test_suite bbdev_throughput_testsuite = {\n \t.suite_name = \"BBdev Throughput Tests\",\n \t.setup = testsuite_setup,\n@@ -4051,6 +4553,7 @@ typedef int (test_case_function)(struct active_device *ad,\n \t}\n };\n \n+REGISTER_TEST_COMMAND(bler, bbdev_bler_testsuite);\n REGISTER_TEST_COMMAND(throughput, bbdev_throughput_testsuite);\n REGISTER_TEST_COMMAND(validation, bbdev_validation_testsuite);\n REGISTER_TEST_COMMAND(latency, bbdev_latency_testsuite);\n",
    "prefixes": [
        "v2",
        "07/15"
    ]
}