From: "Maíra Canal" <maira.canal@usp.br>
To: Harry Wentland <harry.wentland@amd.com>,
Leo Li <sunpeng.li@amd.com>,
Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>,
Alex Deucher <alexander.deucher@amd.com>,
christian.koenig@amd.com,
Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>,
Jun Lei <jun.lei@amd.com>, Nicholas Choi <Nicholas.Choi@amd.com>,
Harrison Chiu <harrison.chiu@amd.com>,
Mark Yacoub <markyacoub@chromium.org>,
Sean Paul <seanpaul@chromium.org>,
Daniel Vetter <daniel@ffwll.ch>,
Javier Martinez Canillas <javierm@redhat.com>,
Isabella Basso <isabbasso@riseup.net>,
magalilemes00@gmail.com, tales.aparecida@gmail.com,
mwen@igalia.com, andrealmeid@riseup.net,
David Gow <davidgow@google.com>,
Daniel Latypov <dlatypov@google.com>,
brendanhiggins@google.com
Cc: "Maíra Canal" <maira.canal@usp.br>,
kunit-dev@googlegroups.com, dri-devel@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: [RFC 3/3] drm/amd/display: Introduce KUnit tests to the bw_fixed library
Date: Tue, 7 Jun 2022 22:07:11 -0300 [thread overview]
Message-ID: <20220608010709.272962-4-maira.canal@usp.br> (raw)
In-Reply-To: <20220608010709.272962-1-maira.canal@usp.br>
From: Magali Lemes <magalilemes00@gmail.com>
The bw_fixed library performs a lot of the mathematical operations
involving fixed-point arithmetic and the conversion of integers to
fixed-point representation.
As fixed-point representation is the base foundation of the DML calcs
operations, this unit tests intend to assure the proper functioning of
the basic mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number, and more.
Co-developed-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Co-developed-by: Maíra Canal <maira.canal@usp.br>
Signed-off-by: Maíra Canal <maira.canal@usp.br>
---
.../drm/amd/display/amdgpu_dm/tests/Kconfig | 12 +
.../drm/amd/display/amdgpu_dm/tests/Makefile | 4 +
.../amdgpu_dm/tests/calcs/bw_fixed_test.c | 322 ++++++++++++++++++
.../amd/display/amdgpu_dm/tests/dml_test.c | 3 +
.../amd/display/amdgpu_dm/tests/dml_test.h | 8 +
5 files changed, 349 insertions(+)
create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/tests/calcs/bw_fixed_test.c
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Kconfig b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Kconfig
index bd1d971d4452..540b2f79f971 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Kconfig
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Kconfig
@@ -2,6 +2,18 @@
menu "DML Unit Tests"
depends on DRM_AMD_DC && KUNIT=m
+config BW_FIXED_KUNIT_TEST
+ bool "Enable unit tests for dml/calcs/bw_fixed" if !DML_KUNIT_TEST
+ default y if DML_KUNIT_TEST
+ help
+ Enables unit tests for the dml/calcs/bw_fixed. Only useful for kernel
+ devs running KUnit.
+
+ For more information on KUnit and unit tests in general please refer to
+ the KUnit documentation in Documentation/dev-tools/kunit/.
+
+ If unsure, say N.
+
config DISPLAY_MODE_LIB_KUNIT_TEST
bool "Enable unit tests for dml/display_mode_lib" if !DML_KUNIT_TEST
default y if DML_KUNIT_TEST
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile
index 53b38e340564..23109e51cf32 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile
@@ -5,6 +5,10 @@
DML_TESTS = dml_test.o
+ifdef CONFIG_BW_FIXED_KUNIT_TEST
+DML_TESTS += calcs/bw_fixed_test.o
+endif
+
ifdef CONFIG_DISPLAY_MODE_LIB_KUNIT_TEST
DML_TESTS += display_mode_lib_test.o
endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/calcs/bw_fixed_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/calcs/bw_fixed_test.c
new file mode 100644
index 000000000000..344c1517745e
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/calcs/bw_fixed_test.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/calcs/bw_fixed.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include "../../../dc/inc/bw_fixed.h"
+#include "../dml_test.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML calcs/bw_fixed.h
+ *
+ * bw_fixed.h performs a lot of the mathematical operations involving
+ * fixed-point arithmetic and the conversion of integers to fixed-point
+ * representation.
+ *
+ * As fixed-point representation is the base foundation of the DML calcs
+ * operations, these tests intend to assure the proper functioning of the
+ * basic mathematical operations of fixed-point arithmetic, such as
+ * multiplication, conversion from fractional to fixed-point number, and more.
+ *
+ */
+
+static void abs_i64_test(struct kunit *test)
+{
+ KUNIT_EXPECT_EQ(test, 0ULL, abs_i64(0LL));
+
+ /* Argument type limits */
+ KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64, abs_i64(MAX_I64));
+ KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64 + 1, abs_i64(MIN_I64));
+}
+
+static void bw_int_to_fixed_nonconst_test(struct kunit *test)
+{
+ struct bw_fixed res;
+
+ /* Add BW_FIXED_BITS_PER_FRACTIONAL_PART trailing 0s to binary number */
+ res = bw_int_to_fixed_nonconst(1000); /* 0x3E8 */
+ KUNIT_EXPECT_EQ(test, 16777216000, res.value); /* 0x3E8000000 */
+
+ res = bw_int_to_fixed_nonconst(-1000); /* -0x3E8 */
+ KUNIT_EXPECT_EQ(test, -16777216000, res.value); /* -0x3E8000000 */
+
+ res = bw_int_to_fixed_nonconst(0LL);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+
+ /**
+ * Test corner cases, as the function's argument has to be an int64_t
+ * between BW_FIXED_MIN_I32 and BW_FIXED_MAX_I32.
+ */
+ res = bw_int_to_fixed_nonconst(BW_FIXED_MAX_I32 - 1); /* 0x7FFFFFFFFE */
+ KUNIT_EXPECT_EQ(test, 9223372036821221376, res.value); /* 0x7FFFFFFFFE000000 */
+
+ res = bw_int_to_fixed_nonconst(BW_FIXED_MIN_I32 + 1); /* -0x7FFFFFFFFF */
+ KUNIT_EXPECT_EQ(test, -9223372036837998592, res.value); /* -0x7FFFFFFFFF000000 */
+}
+
+static void bw_frc_to_fixed_test(struct kunit *test)
+{
+ struct bw_fixed res;
+
+ /* Extreme scenarios */
+
+ /* A fraction of N/N should result in "1.0" */
+ res = bw_frc_to_fixed(MAX_I64, MAX_I64);
+ KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+ res = bw_frc_to_fixed(1, MAX_I64);
+ KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+ res = bw_frc_to_fixed(0, MAX_I64);
+ KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+ /* Turn a repeating decimal to the fixed-point representation */
+
+ /* A repeating decimal that doesn't round up the LSB */
+ res = bw_frc_to_fixed(4, 3);
+ KUNIT_EXPECT_EQ(test, 22369621LL, res.value); /* 0x1555555 */
+
+ res = bw_frc_to_fixed(-4, 3);
+ KUNIT_EXPECT_EQ(test, -22369621LL, res.value); /* -0x1555555 */
+
+ res = bw_frc_to_fixed(99999997, 100000000);
+ KUNIT_EXPECT_EQ(test, 16777215LL, res.value); /* 0x0FFFFFF */
+
+ /* A repeating decimal that rounds up the MSB */
+ res = bw_frc_to_fixed(5, 3);
+ KUNIT_EXPECT_EQ(test, 27962027LL, res.value); /* 0x1AAAAAB */
+
+ res = bw_frc_to_fixed(-5, 3);
+ KUNIT_EXPECT_EQ(test, -27962027LL, res.value); /* -0x1AAAAAB */
+
+ res = bw_frc_to_fixed(99999998, 100000000);
+ KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+ /* Turn a terminating decimal to the fixed-point representation */
+ res = bw_frc_to_fixed(62609, 100);
+ KUNIT_EXPECT_EQ(test, 10504047165LL, res.value); /* 0X272170A3D */
+
+ res = bw_frc_to_fixed(-62609, 100);
+ KUNIT_EXPECT_EQ(test, -10504047165LL, res.value); /* -0X272170A3D */
+}
+
+static void bw_floor2_test(struct kunit *test)
+{
+ struct bw_fixed arg;
+ struct bw_fixed significance;
+ struct bw_fixed res;
+
+ /* Round 10 down to the nearest multiple of 3 */
+ arg.value = 10;
+ significance.value = 3;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 9, res.value);
+
+ /* Round 10 down to the nearest multiple of 5 */
+ arg.value = 10;
+ significance.value = 5;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 10, res.value);
+
+ /* Round 100 down to the nearest multiple of 7 */
+ arg.value = 100;
+ significance.value = 7;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 98, res.value);
+
+ /* Round an integer down to its nearest multiple should return itself */
+ arg.value = MAX_I64;
+ significance.value = MAX_I64;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+ arg.value = MIN_I64;
+ significance.value = MIN_I64;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, MIN_I64, res.value);
+
+ /* Value is a multiple of significance, result should be value */
+ arg.value = MAX_I64;
+ significance.value = MIN_I64 + 1;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+ /* Round 0 down to the nearest multiple of any number should return 0 */
+ arg.value = 0;
+ significance.value = MAX_I64;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+
+ arg.value = 0;
+ significance.value = MIN_I64;
+ res = bw_floor2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+static void bw_ceil2_test(struct kunit *test)
+{
+ struct bw_fixed arg;
+ struct bw_fixed significance;
+ struct bw_fixed res;
+
+ /* Round 10 up to the nearest multiple of 3 */
+ arg.value = 10;
+ significance.value = 3;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 12, res.value);
+
+ /* Round 10 up to the nearest multiple of 5 */
+ arg.value = 10;
+ significance.value = 5;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 10, res.value);
+
+ /* Round 100 up to the nearest multiple of 7 */
+ arg.value = 100;
+ significance.value = 7;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 105, res.value);
+
+ /* Round an integer up to its nearest multiple should return itself */
+ arg.value = MAX_I64;
+ significance.value = MAX_I64;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+ arg.value = MIN_I64 + 1;
+ significance.value = MIN_I64 + 1;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, MIN_I64 + 1, res.value);
+
+ /* Value is a multiple of significance, result should be value */
+ arg.value = MAX_I64;
+ significance.value = MIN_I64 + 1;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+ /* Round 0 up to the nearest multiple of any number should return 0 */
+ arg.value = 0;
+ significance.value = MAX_I64;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+
+ arg.value = 0;
+ significance.value = MIN_I64;
+ res = bw_ceil2(arg, significance);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+static void bw_mul_test(struct kunit *test)
+{
+ struct bw_fixed arg1;
+ struct bw_fixed arg2;
+ struct bw_fixed res;
+ struct bw_fixed ans;
+
+ /* Extreme scenario */
+ arg1.value = MAX_I64;
+ arg2.value = MIN_I64;
+ res = bw_mul(arg1, arg2);
+ KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+ /* Testing multiplication property: x * 1 = x */
+ arg1.value = 1;
+ arg2.value = MAX_I64;
+ res = bw_mul(arg1, arg2);
+ KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+ arg1.value = 1;
+ arg2.value = MIN_I64;
+ res = bw_mul(arg1, arg2);
+ KUNIT_EXPECT_EQ(test, BW_FIXED_MIN_I32, res.value);
+
+ /* Testing multiplication property: x * 0 = 0 */
+ arg1.value = 0;
+ arg2.value = 0;
+ res = bw_mul(arg1, arg2);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+
+ arg1.value = 0;
+ arg2.value = MAX_I64;
+ res = bw_mul(arg1, arg2);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+
+ arg1.value = 0;
+ arg2.value = MIN_I64;
+ res = bw_mul(arg1, arg2);
+ KUNIT_EXPECT_EQ(test, 0, res.value);
+
+ /* Testing multiplication between integers */
+ res = bw_mul(bw_int_to_fixed(8), bw_int_to_fixed(10));
+ KUNIT_EXPECT_EQ(test, 1342177280LL, res.value); /* 0x50000000 */
+
+ res = bw_mul(bw_int_to_fixed(10), bw_int_to_fixed(5));
+ KUNIT_EXPECT_EQ(test, 838860800LL, res.value); /* 0x32000000 */
+
+ res = bw_mul(bw_int_to_fixed(-10), bw_int_to_fixed(7));
+ KUNIT_EXPECT_EQ(test, -1174405120LL, res.value); /* -0x46000000 */
+
+ /* Testing multiplication between fractions and integers */
+ res = bw_mul(bw_frc_to_fixed(4, 3), bw_int_to_fixed(3));
+ ans = bw_int_to_fixed(4);
+
+ /**
+ * As bw_frc_to_fixed(4, 3) didn't round up the fixed-point representation,
+ * the ans must be subtrated by 1.
+ */
+ KUNIT_EXPECT_EQ(test, ans.value - 1, res.value);
+
+ res = bw_mul(bw_frc_to_fixed(5, 3), bw_int_to_fixed(3));
+ ans = bw_int_to_fixed(5);
+
+ /**
+ * As bw_frc_to_fixed(5, 3) rounds up the fixed-point representation,
+ * the ans must be added by 1.
+ */
+ KUNIT_EXPECT_EQ(test, ans.value + 1, res.value);
+}
+
+static struct kunit_case bw_fixed_test_cases[] = {
+ KUNIT_CASE(abs_i64_test),
+ KUNIT_CASE(bw_int_to_fixed_nonconst_test),
+ KUNIT_CASE(bw_frc_to_fixed_test),
+ KUNIT_CASE(bw_floor2_test),
+ KUNIT_CASE(bw_ceil2_test),
+ KUNIT_CASE(bw_mul_test),
+ { }
+};
+
+static struct kunit_suite bw_fixed_test_suite = {
+ .name = "dml-calcs-bw-fixed",
+ .test_cases = bw_fixed_test_cases,
+};
+
+static struct kunit_suite *bw_fixed_test_suites[] = { &bw_fixed_test_suite, NULL };
+
+int bw_fixed_test_init(void)
+{
+ pr_info("===> Running calcs/bw_fixed KUnit Tests");
+ pr_info("**********************************************************");
+ pr_info("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **");
+ pr_info("** **");
+ pr_info("** calcs/bw_fixed KUnit Tests are being run. This means **");
+ pr_info("** that this is a TEST kernel and should not be used **");
+ pr_info("** for production. **");
+ pr_info("** **");
+ pr_info("** If you see this message and you are not debugging **");
+ pr_info("** the kernel, report this immediately to your vendor! **");
+ pr_info("** **");
+ pr_info("**********************************************************");
+
+ return __kunit_test_suites_init(bw_fixed_test_suites);
+}
+
+void bw_fixed_test_exit(void)
+{
+ return __kunit_test_suites_exit(bw_fixed_test_suites);
+}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.c
index 9a5d47597c10..98ae4e8cd952 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.c
@@ -13,11 +13,14 @@
*/
int amdgpu_dml_test_init(void)
{
+ bw_fixed_test_init();
display_mode_lib_test_init();
+
return 0;
}
void amdgpu_dml_test_exit(void)
{
display_mode_lib_test_exit();
+ bw_fixed_test_exit();
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.h b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.h
index 2786db9d0e87..d8fe38abd9bc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/dml_test.h
@@ -2,6 +2,14 @@
#ifndef DML_TEST_H_
#define DML_TEST_H_
+#if defined (CONFIG_BW_FIXED_KUNIT_TEST)
+int bw_fixed_test_init(void);
+void bw_fixed_test_exit(void);
+#else
+static inline int bw_fixed_test_init(void) { return 0; }
+static inline void bw_fixed_test_exit(void) { }
+#endif
+
#if defined (CONFIG_DISPLAY_MODE_LIB_KUNIT_TEST)
int display_mode_lib_test_init(void);
void display_mode_lib_test_exit(void);
--
2.36.1
next prev parent reply other threads:[~2022-06-08 1:09 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-08 1:07 [RFC 0/3] drm/amd/display: Introduce KUnit to Display Mode Library Maíra Canal
2022-06-08 1:07 ` [RFC 1/3] drm/amd/display: Introduce KUnit to DML Maíra Canal
2022-06-08 2:36 ` Daniel Latypov
2022-06-15 15:05 ` Maíra Canal
2022-06-08 1:07 ` [RFC 2/3] drm/amd/display: Move bw_fixed macros to header file Maíra Canal
2022-06-08 1:07 ` Maíra Canal [this message]
2022-06-16 14:39 ` [RFC 0/3] drm/amd/display: Introduce KUnit to Display Mode Library David Gow
2022-06-16 22:41 ` Maíra Canal
2022-06-17 7:55 ` David Gow
2022-06-17 20:24 ` Maíra Canal
2022-06-18 9:08 ` David Gow
2022-06-22 22:55 ` Rodrigo Siqueira Jordao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220608010709.272962-4-maira.canal@usp.br \
--to=maira.canal@usp.br \
--cc=Dmytro.Laktyushkin@amd.com \
--cc=Nicholas.Choi@amd.com \
--cc=Rodrigo.Siqueira@amd.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=andrealmeid@riseup.net \
--cc=brendanhiggins@google.com \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=davidgow@google.com \
--cc=dlatypov@google.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=harrison.chiu@amd.com \
--cc=harry.wentland@amd.com \
--cc=isabbasso@riseup.net \
--cc=javierm@redhat.com \
--cc=jun.lei@amd.com \
--cc=kunit-dev@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=magalilemes00@gmail.com \
--cc=markyacoub@chromium.org \
--cc=mwen@igalia.com \
--cc=seanpaul@chromium.org \
--cc=sunpeng.li@amd.com \
--cc=tales.aparecida@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).