Message ID | 20240708155943.2314427-2-devarsht@ti.com (mailing list archive) |
---|---|
State | TODO |
Delegated to: | Sebastian Fricke |
Headers |
Received: from ny.mirrors.kernel.org ([147.75.199.223]) by linuxtv.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from <linux-media+bounces-14705-patchwork=linuxtv.org@vger.kernel.org>) id 1sQqnR-0003hN-1Z for patchwork@linuxtv.org; Mon, 08 Jul 2024 16:00:58 +0000 Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 0DA8A1C21FD2 for <patchwork@linuxtv.org>; Mon, 8 Jul 2024 16:00:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E44CF145B12; Mon, 8 Jul 2024 16:00:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="d857G0Wz" X-Original-To: linux-media@vger.kernel.org Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8808145340; Mon, 8 Jul 2024 16:00:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720454410; cv=none; b=d8sq/9xghSr+Lr4abLE3ydDGe/2Oy1HdL/6alfnZ52wgE7OieKc5DQ+RaDxNyOIn/OqV9EOMsRf8vV9nfox/tT2/L/YZxH19iugbNCS9UGNRDdGY7uvQ+vTMQVDdWCO16nsgGxBUMCof9G47n2TEnHwCC4KrQlu5jzjQqhJt28U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720454410; c=relaxed/simple; bh=nFbJnq23XTYikyNFznKLNb2hOHJ7fDlvEzP7lvzRdss=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ArKThmqxh+zb2qJRVT2ON51U2LEy/+/DMSeFGFI7kAJNjw2jwJF6M2LxPjvTAHo8BTchDU6ID+PhVT//mQI2o8bS4uiQl1ildd+L1D6v4RQBpcgCgD25793wZy41E8gYxzM9IXY3IowDC1BCRj6tD6KVYJXW3ddjd8X7V2rAJAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=d857G0Wz; arc=none smtp.client-ip=198.47.19.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 468FxkRq046174; Mon, 8 Jul 2024 10:59:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1720454386; bh=S1jiyaqWjuWtWeLWTjTTn+GeFYYElSU9yqWMjOuLZc8=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=d857G0Wz2wf8dAWlvF9zVBUZ9LG20T6juG/8uicnGa8Pzqz8GwMKe47w+S9XOg0oq nFpzvjq/ciHuiVJNyfyPiGhfyhG0zM00HTBs6RC4sb1hDhhADafX435TSsOySpbjUj PAeXws324cSdW0T3ko3xAsdHev7ZQgp7UK8GOKKg= Received: from DLEE110.ent.ti.com (dlee110.ent.ti.com [157.170.170.21]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 468FxkGm021706 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 8 Jul 2024 10:59:46 -0500 Received: from DLEE106.ent.ti.com (157.170.170.36) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Mon, 8 Jul 2024 10:59:46 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Mon, 8 Jul 2024 10:59:45 -0500 Received: from localhost (ti.dhcp.ti.com [172.24.227.95] (may be forged)) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 468Fxj1A103461; Mon, 8 Jul 2024 10:59:45 -0500 From: Devarsh Thakkar <devarsht@ti.com> To: <mchehab@kernel.org>, <hverkuil-cisco@xs4all.nl>, <linux-media@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <sebastian.fricke@collabora.com>, <andriy.shevchenko@linux.intel.com>, <jani.nikula@intel.com>, <jirislaby@kernel.org>, <corbet@lwn.net>, <broonie@kernel.org>, <rdunlap@infradead.org>, <linux-doc@vger.kernel.org> CC: <laurent.pinchart@ideasonboard.com>, <praneeth@ti.com>, <nm@ti.com>, <vigneshr@ti.com>, <a-bhatia1@ti.com>, <j-luthra@ti.com>, <b-brnich@ti.com>, <detheridge@ti.com>, <p-mantena@ti.com>, <vijayp@ti.com>, <devarsht@ti.com>, <andi.shyti@linux.intel.com>, <nicolas@ndufresne.ca>, <davidgow@google.com>, <dlatypov@google.com> Subject: [PATCH 1/6] math.h: Add macros for rounding to closest value Date: Mon, 8 Jul 2024 21:29:38 +0530 Message-ID: <20240708155943.2314427-2-devarsht@ti.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20240708155943.2314427-1-devarsht@ti.com> References: <20240708155943.2314427-1-devarsht@ti.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: <linux-media.vger.kernel.org> List-Subscribe: <mailto:linux-media+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-media+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-LSpam-Score: -3.6 (---) X-LSpam-Report: No, score=-3.6 required=5.0 tests=ARC_SIGNED=0.001,ARC_VALID=-0.1,BAYES_00=-1.9,DKIMWL_WL_HIGH=-1,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,DMARC_PASS=-0.001,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,SPF_HELO_NONE=0.001,SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no |
Series |
Add rounding macros and enable KUnit tests
|
|
Commit Message
Devarsh Thakkar
July 8, 2024, 3:59 p.m. UTC
Add below rounding related macros: round_closest_up(x, y) : Rounds x to closest multiple of y where y is a power of 2, with a preference to round up in case two nearest values are possible. round_closest_down(x, y) : Rounds x to closest multiple of y where y is a power of 2, with a preference to round down in case two nearest values are possible. roundclosest(x, y) : Rounds x to closest multiple of y, this macro should generally be used only when y is not multiple of 2 as otherwise round_closest* macros should be used which are much faster. Examples: * round_closest_up(17, 4) = 16 * round_closest_up(15, 4) = 16 * round_closest_up(14, 4) = 16 * round_closest_down(17, 4) = 16 * round_closest_down(15, 4) = 16 * round_closest_down(14, 4) = 12 * roundclosest(21, 5) = 20 * roundclosest(19, 5) = 20 * roundclosest(17, 5) = 15 Signed-off-by: Devarsh Thakkar <devarsht@ti.com> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] which uses similar macro locally and which is updated in further patch in the series to use this generic macro instead along with other drivers having similar requirements. Link: https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] --- include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
Comments
On 08. 07. 24, 17:59, Devarsh Thakkar wrote: > Add below rounding related macros: > > round_closest_up(x, y) : Rounds x to closest multiple of y where y is a > power of 2, with a preference to round up in case two nearest values are > possible. > > round_closest_down(x, y) : Rounds x to closest multiple of y where y is a > power of 2, with a preference to round down in case two nearest values are > possible. > > roundclosest(x, y) : Rounds x to closest multiple of y, this macro should > generally be used only when y is not multiple of 2 as otherwise > round_closest* macros should be used which are much faster. > > Examples: > * round_closest_up(17, 4) = 16 > * round_closest_up(15, 4) = 16 > * round_closest_up(14, 4) = 16 > * round_closest_down(17, 4) = 16 > * round_closest_down(15, 4) = 16 > * round_closest_down(14, 4) = 12 > * roundclosest(21, 5) = 20 With consistency in mind, why is there no underscore? > * roundclosest(19, 5) = 20 > * roundclosest(17, 5) = 15 > > Signed-off-by: Devarsh Thakkar <devarsht@ti.com> > Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > --- > NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] > which uses similar macro locally and which is updated in further patch > in the series to use this generic macro instead along with other drivers > having similar requirements. > > Link: https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] > --- > include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > > diff --git a/include/linux/math.h b/include/linux/math.h > index dd4152711de7..79e3dfda77fc 100644 > --- a/include/linux/math.h > +++ b/include/linux/math.h > @@ -34,6 +34,52 @@ > */ > #define round_down(x, y) ((x) & ~__round_mask(x, y)) > > +/** > + * round_closest_up - round closest to be multiple of specified value (which is > + * power of 2) with preference to rounding up > + * @x: the value to round > + * @y: multiple to round closest to (must be a power of 2) > + * > + * Rounds @x to closest multiple of @y (which must be a power of 2). > + * The value can be either rounded up or rounded down depending upon rounded > + * value's closeness to the specified value. If there are two closest possible > + * values, i.e. the difference between the specified value and it's rounded up > + * and rounded down values is same then preference is given to rounded up > + * value. > + * > + * To perform arbitrary rounding to closest value (not multiple of 2), use > + * roundclosest(). > + * > + * Examples: > + * * round_closest_up(17, 4) = 16 > + * * round_closest_up(15, 4) = 16 > + * * round_closest_up(14, 4) = 16 > + */ > +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) > + > +/** > + * round_closest_down - round closest to be multiple of specified value (which > + * is power of 2) with preference to rounding down > + * @x: the value to round > + * @y: multiple to round closest to (must be a power of 2) > + * > + * Rounds @x to closest multiple of @y (which must be a power of 2). > + * The value can be either rounded up or rounded down depending upon rounded > + * value's closeness to the specified value. If there are two closest possible > + * values, i.e. the difference between the specified value and it's rounded up > + * and rounded down values is same then preference is given to rounded up > + * value. Too heavy sentence. Did you mean "its" not "it's"? What about: There can be two closest values. I.e. the difference between the specified value and its rounded up and down values is the same. In that case, the rounded up value is preferred. ? The same for round_closest_up(). > + * > + * To perform arbitrary rounding to closest value (not multiple of 2), use > + * roundclosest(). > + * > + * Examples: > + * * round_closest_down(17, 4) = 16 > + * * round_closest_down(15, 4) = 16 > + * * round_closest_down(14, 4) = 12 > + */ > +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) > + > #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP > > #define DIV_ROUND_DOWN_ULL(ll, d) \ > @@ -77,6 +123,23 @@ > } \ > ) > > +/** > + * roundclosest - round to nearest multiple > + * @x: the value to round > + * @y: multiple to round nearest to > + * > + * Rounds @x to nearest multiple of @y. > + * The rounded value can be greater than or less than @x depending greater or less than > + * upon it's nearness to @x. "its" > If @y will always be a power of 2, consider If @y is always a power... > + * using the faster round_closest_up() or round_closest_down(). > + * > + * Examples: > + * * roundclosest(21, 5) = 20 > + * * roundclosest(19, 5) = 20 > + * * roundclosest(17, 5) = 15 > + */ > +#define roundclosest(x, y) rounddown((x) + (y) / 2, (y)) > + > /* > * Divide positive or negative dividend by positive or negative divisor > * and round to closest integer. Result is undefined for negative
On 8.07.24 г. 18:59 ч., Devarsh Thakkar wrote: > Add below rounding related macros: > > round_closest_up(x, y) : Rounds x to closest multiple of y where y is a > power of 2, with a preference to round up in case two nearest values are > possible. > > round_closest_down(x, y) : Rounds x to closest multiple of y where y is a > power of 2, with a preference to round down in case two nearest values are > possible. > > roundclosest(x, y) : Rounds x to closest multiple of y, this macro should > generally be used only when y is not multiple of 2 as otherwise > round_closest* macros should be used which are much faster. > > Examples: > * round_closest_up(17, 4) = 16 > * round_closest_up(15, 4) = 16 > * round_closest_up(14, 4) = 16 > * round_closest_down(17, 4) = 16 > * round_closest_down(15, 4) = 16 > * round_closest_down(14, 4) = 12 > * roundclosest(21, 5) = 20 > * roundclosest(19, 5) = 20 > * roundclosest(17, 5) = 15 > > Signed-off-by: Devarsh Thakkar <devarsht@ti.com> > Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > --- > NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] > which uses similar macro locally and which is updated in further patch > in the series to use this generic macro instead along with other drivers > having similar requirements. > > Link: https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] > --- > include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > > diff --git a/include/linux/math.h b/include/linux/math.h > index dd4152711de7..79e3dfda77fc 100644 > --- a/include/linux/math.h > +++ b/include/linux/math.h > @@ -34,6 +34,52 @@ > */ > #define round_down(x, y) ((x) & ~__round_mask(x, y)) > > +/** > + * round_closest_up - round closest to be multiple of specified value (which is > + * power of 2) with preference to rounding up > + * @x: the value to round > + * @y: multiple to round closest to (must be a power of 2) > + * > + * Rounds @x to closest multiple of @y (which must be a power of 2). > + * The value can be either rounded up or rounded down depending upon rounded > + * value's closeness to the specified value. If there are two closest possible > + * values, i.e. the difference between the specified value and it's rounded up > + * and rounded down values is same then preference is given to rounded up > + * value. > + * > + * To perform arbitrary rounding to closest value (not multiple of 2), use > + * roundclosest(). > + * > + * Examples: > + * * round_closest_up(17, 4) = 16 > + * * round_closest_up(15, 4) = 16 > + * * round_closest_up(14, 4) = 16 > + */ > +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) > + > +/** > + * round_closest_down - round closest to be multiple of specified value (which > + * is power of 2) with preference to rounding down > + * @x: the value to round > + * @y: multiple to round closest to (must be a power of 2) > + * > + * Rounds @x to closest multiple of @y (which must be a power of 2). > + * The value can be either rounded up or rounded down depending upon rounded > + * value's closeness to the specified value. If there are two closest possible > + * values, i.e. the difference between the specified value and it's rounded up > + * and rounded down values is same then preference is given to rounded up > + * value. > + * > + * To perform arbitrary rounding to closest value (not multiple of 2), use > + * roundclosest(). > + * > + * Examples: > + * * round_closest_down(17, 4) = 16 > + * * round_closest_down(15, 4) = 16 > + * * round_closest_down(14, 4) = 12 > + */ > +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) This is already identical to the existing round_down, no ? <snip>
Hi Jiri, Thanks for the review. On 09/07/24 11:29, Jiri Slaby wrote: > On 08. 07. 24, 17:59, Devarsh Thakkar wrote: >> Add below rounding related macros: >> >> round_closest_up(x, y) : Rounds x to closest multiple of y where y is a >> power of 2, with a preference to round up in case two nearest values are >> possible. >> >> round_closest_down(x, y) : Rounds x to closest multiple of y where y is a >> power of 2, with a preference to round down in case two nearest values are >> possible. >> >> roundclosest(x, y) : Rounds x to closest multiple of y, this macro should >> generally be used only when y is not multiple of 2 as otherwise >> round_closest* macros should be used which are much faster. >> >> Examples: >> * round_closest_up(17, 4) = 16 >> * round_closest_up(15, 4) = 16 >> * round_closest_up(14, 4) = 16 >> * round_closest_down(17, 4) = 16 >> * round_closest_down(15, 4) = 16 >> * round_closest_down(14, 4) = 12 >> * roundclosest(21, 5) = 20 > > With consistency in mind, why is there no underscore? > This is as per the convention followed in math.h for existing rounding macros round_up, roundup, round_down, rounddown : for e.g. It use "_" for macros which work on power of 2 for e.g. we have round_down, round_up macros which work on power of 2 and it remove "_" for normal rounding macros for e.g. rounddown and roundup which are normal rounding macros. There was already a discussion around naming convention in previous patch versions here [1] we aligned on this. >> * roundclosest(19, 5) = 20 >> * roundclosest(17, 5) = 15 >> >> Signed-off-by: Devarsh Thakkar <devarsht@ti.com> >> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> >> --- >> NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] >> which uses similar macro locally and which is updated in further patch >> in the series to use this generic macro instead along with other drivers >> having similar requirements. >> >> Link: >> https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] >> --- >> include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 63 insertions(+) >> >> diff --git a/include/linux/math.h b/include/linux/math.h >> index dd4152711de7..79e3dfda77fc 100644 >> --- a/include/linux/math.h >> +++ b/include/linux/math.h >> @@ -34,6 +34,52 @@ >> */ >> #define round_down(x, y) ((x) & ~__round_mask(x, y)) >> +/** >> + * round_closest_up - round closest to be multiple of specified value >> (which is >> + * power of 2) with preference to rounding up >> + * @x: the value to round >> + * @y: multiple to round closest to (must be a power of 2) >> + * >> + * Rounds @x to closest multiple of @y (which must be a power of 2). >> + * The value can be either rounded up or rounded down depending upon rounded >> + * value's closeness to the specified value. If there are two closest possible >> + * values, i.e. the difference between the specified value and it's rounded up >> + * and rounded down values is same then preference is given to rounded up >> + * value. >> + * >> + * To perform arbitrary rounding to closest value (not multiple of 2), use >> + * roundclosest(). >> + * >> + * Examples: >> + * * round_closest_up(17, 4) = 16 >> + * * round_closest_up(15, 4) = 16 >> + * * round_closest_up(14, 4) = 16 >> + */ >> +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) >> + >> +/** >> + * round_closest_down - round closest to be multiple of specified value (which >> + * is power of 2) with preference to rounding down >> + * @x: the value to round >> + * @y: multiple to round closest to (must be a power of 2) >> + * >> + * Rounds @x to closest multiple of @y (which must be a power of 2). >> + * The value can be either rounded up or rounded down depending upon rounded >> + * value's closeness to the specified value. If there are two closest possible >> + * values, i.e. the difference between the specified value and it's rounded up >> + * and rounded down values is same then preference is given to rounded up >> + * value. > > Too heavy sentence. Did you mean "its" not "it's"? Yeah "its" is the correct one. > > What about: > There can be two closest values. I.e. the difference between the specified > value and its rounded up and down values is the same. In that case, the > rounded up value is preferred. > ? > Yeah this looks good but I would still prefer to prepend to this the text "The value can be either rounded up or rounded down depending upon rounded value's closeness to the specified value" just to avoid any confusion as it caused a bit of confusions in earlier iterations. > The same for round_closest_up(). > >> + * >> + * To perform arbitrary rounding to closest value (not multiple of 2), use >> + * roundclosest(). >> + * >> + * Examples: >> + * * round_closest_down(17, 4) = 16 >> + * * round_closest_down(15, 4) = 16 >> + * * round_closest_down(14, 4) = 12 >> + */ >> +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) >> + >> #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP >> #define DIV_ROUND_DOWN_ULL(ll, d) \ >> @@ -77,6 +123,23 @@ >> } \ >> ) >> +/** >> + * roundclosest - round to nearest multiple >> + * @x: the value to round >> + * @y: multiple to round nearest to >> + * >> + * Rounds @x to nearest multiple of @y. >> + * The rounded value can be greater than or less than @x depending > > greater or less than > Agreed. >> + * upon it's nearness to @x. > > "its" > Agreed. >> If @y will always be a power of 2, consider > > If @y is always a power... > Agreed. [1]: https://lore.kernel.org/all/Zj42vTpyH71TWeTk@smile.fi.intel.com/ Regards Devarsh
On Mon, Jul 08, 2024 at 09:29:38PM +0530, Devarsh Thakkar wrote: > Add below rounding related macros: > > round_closest_up(x, y) : Rounds x to closest multiple of y where y is a > power of 2, with a preference to round up in case two nearest values are > possible. > > round_closest_down(x, y) : Rounds x to closest multiple of y where y is a > power of 2, with a preference to round down in case two nearest values are > possible. > > roundclosest(x, y) : Rounds x to closest multiple of y, this macro should > generally be used only when y is not multiple of 2 as otherwise > round_closest* macros should be used which are much faster. > > Examples: > * round_closest_up(17, 4) = 16 > * round_closest_up(15, 4) = 16 > * round_closest_up(14, 4) = 16 > * round_closest_down(17, 4) = 16 > * round_closest_down(15, 4) = 16 > * round_closest_down(14, 4) = 12 > * roundclosest(21, 5) = 20 > * roundclosest(19, 5) = 20 > * roundclosest(17, 5) = 15 > > Signed-off-by: Devarsh Thakkar <devarsht@ti.com> > Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > --- > NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] > which uses similar macro locally and which is updated in further patch > in the series to use this generic macro instead along with other drivers > having similar requirements. > > Link: https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] > --- > include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > > diff --git a/include/linux/math.h b/include/linux/math.h > index dd4152711de7..79e3dfda77fc 100644 > --- a/include/linux/math.h > +++ b/include/linux/math.h > @@ -34,6 +34,52 @@ > */ > #define round_down(x, y) ((x) & ~__round_mask(x, y)) > > +/** > + * round_closest_up - round closest to be multiple of specified value (which is > + * power of 2) with preference to rounding up > + * @x: the value to round > + * @y: multiple to round closest to (must be a power of 2) > + * > + * Rounds @x to closest multiple of @y (which must be a power of 2). > + * The value can be either rounded up or rounded down depending upon rounded > + * value's closeness to the specified value. If there are two closest possible > + * values, i.e. the difference between the specified value and it's rounded up > + * and rounded down values is same then preference is given to rounded up > + * value. > + * > + * To perform arbitrary rounding to closest value (not multiple of 2), use > + * roundclosest(). > + * > + * Examples: > + * * round_closest_up(17, 4) = 16 > + * * round_closest_up(15, 4) = 16 > + * * round_closest_up(14, 4) = 16 > + */ > +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) > + > +/** > + * round_closest_down - round closest to be multiple of specified value (which > + * is power of 2) with preference to rounding down > + * @x: the value to round > + * @y: multiple to round closest to (must be a power of 2) > + * > + * Rounds @x to closest multiple of @y (which must be a power of 2). > + * The value can be either rounded up or rounded down depending upon rounded > + * value's closeness to the specified value. If there are two closest possible > + * values, i.e. the difference between the specified value and it's rounded up > + * and rounded down values is same then preference is given to rounded up > + * value. > + * > + * To perform arbitrary rounding to closest value (not multiple of 2), use > + * roundclosest(). > + * > + * Examples: > + * * round_closest_down(17, 4) = 16 > + * * round_closest_down(15, 4) = 16 > + * * round_closest_down(14, 4) = 12 > + */ > +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) > + Naming aside, is there an actual use case for having both roundclosest() and round_closest_up() today? (i.e., is there any potential caller that would actually care about the rounding direction for borderline cases?) > #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP > > #define DIV_ROUND_DOWN_ULL(ll, d) \ > @@ -77,6 +123,23 @@ > } \ > ) > > +/** > + * roundclosest - round to nearest multiple > + * @x: the value to round > + * @y: multiple to round nearest to > + * > + * Rounds @x to nearest multiple of @y. > + * The rounded value can be greater than or less than @x depending > + * upon it's nearness to @x. If @y will always be a power of 2, consider > + * using the faster round_closest_up() or round_closest_down(). > + * > + * Examples: > + * * roundclosest(21, 5) = 20 > + * * roundclosest(19, 5) = 20 > + * * roundclosest(17, 5) = 15 > + */ > +#define roundclosest(x, y) rounddown((x) + (y) / 2, (y)) Won't this go wrong if (x) + (y) / 2 overflows? This may happen even in some cases where the correctly rounded value would be in range. The existing rounddown() already leaves something to be desired IIUC: if given a negative dividend, it looks like it actually rounds up, at least on some arches. But maybe people don't use it that way very often. Perhaps I'm missing something. [...] Cheers ---Dave
Hi Nikolay, Sorry for the delay. On 09/07/24 14:19, Nikolay Borisov wrote: > > > On 8.07.24 г. 18:59 ч., Devarsh Thakkar wrote: >> Add below rounding related macros: >> >> round_closest_up(x, y) : Rounds x to closest multiple of y where y is a >> power of 2, with a preference to round up in case two nearest values are >> possible. >> >> round_closest_down(x, y) : Rounds x to closest multiple of y where y is a >> power of 2, with a preference to round down in case two nearest values >> are >> possible. >> >> roundclosest(x, y) : Rounds x to closest multiple of y, this macro should >> generally be used only when y is not multiple of 2 as otherwise >> round_closest* macros should be used which are much faster. >> >> Examples: >> * round_closest_up(17, 4) = 16 >> * round_closest_up(15, 4) = 16 >> * round_closest_up(14, 4) = 16 >> * round_closest_down(17, 4) = 16 >> * round_closest_down(15, 4) = 16 >> * round_closest_down(14, 4) = 12 >> * roundclosest(21, 5) = 20 >> * roundclosest(19, 5) = 20 >> * roundclosest(17, 5) = 15 >> >> Signed-off-by: Devarsh Thakkar <devarsht@ti.com> >> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> >> --- >> NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] >> which uses similar macro locally and which is updated in further patch >> in the series to use this generic macro instead along with other drivers >> having similar requirements. >> >> Link: >> https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] >> --- >> include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 63 insertions(+) >> >> diff --git a/include/linux/math.h b/include/linux/math.h >> index dd4152711de7..79e3dfda77fc 100644 >> --- a/include/linux/math.h >> +++ b/include/linux/math.h >> @@ -34,6 +34,52 @@ >> */ >> #define round_down(x, y) ((x) & ~__round_mask(x, y)) >> +/** >> + * round_closest_up - round closest to be multiple of specified value >> (which is >> + * power of 2) with preference to rounding up >> + * @x: the value to round >> + * @y: multiple to round closest to (must be a power of 2) >> + * >> + * Rounds @x to closest multiple of @y (which must be a power of 2). >> + * The value can be either rounded up or rounded down depending upon >> rounded >> + * value's closeness to the specified value. If there are two closest >> possible >> + * values, i.e. the difference between the specified value and it's >> rounded up >> + * and rounded down values is same then preference is given to >> rounded up >> + * value. >> + * >> + * To perform arbitrary rounding to closest value (not multiple of >> 2), use >> + * roundclosest(). >> + * >> + * Examples: >> + * * round_closest_up(17, 4) = 16 >> + * * round_closest_up(15, 4) = 16 >> + * * round_closest_up(14, 4) = 16 >> + */ >> +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) >> + >> +/** >> + * round_closest_down - round closest to be multiple of specified >> value (which >> + * is power of 2) with preference to rounding down >> + * @x: the value to round >> + * @y: multiple to round closest to (must be a power of 2) >> + * >> + * Rounds @x to closest multiple of @y (which must be a power of 2). >> + * The value can be either rounded up or rounded down depending upon >> rounded >> + * value's closeness to the specified value. If there are two closest >> possible >> + * values, i.e. the difference between the specified value and it's >> rounded up >> + * and rounded down values is same then preference is given to >> rounded up >> + * value. >> + * >> + * To perform arbitrary rounding to closest value (not multiple of >> 2), use >> + * roundclosest(). >> + * >> + * Examples: >> + * * round_closest_down(17, 4) = 16 >> + * * round_closest_down(15, 4) = 16 >> + * * round_closest_down(14, 4) = 12 >> + */ >> +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) > > This is already identical to the existing round_down, no ? > Nopes both are different as described in the comments, round_down rounds down to next specified power of 2, but round_closest_down rounds to closest multiple of the specified power (which could be higher or lower) and if there are two closest multiples then it gives preference to lower value as shown in below examples : - round_closest_down(15, 4) = 16 - round_down(15,4) = 12 - round_closest_down(14, 4) = 12 - round_closest_up(14, 4) = 16 Regards Devarsh
Hi Dave, Thanks for the review. On 09/07/24 22:48, Dave Martin wrote: > On Mon, Jul 08, 2024 at 09:29:38PM +0530, Devarsh Thakkar wrote: >> Add below rounding related macros: >> >> round_closest_up(x, y) : Rounds x to closest multiple of y where y is a >> power of 2, with a preference to round up in case two nearest values are >> possible. >> >> round_closest_down(x, y) : Rounds x to closest multiple of y where y is a >> power of 2, with a preference to round down in case two nearest values are >> possible. >> >> roundclosest(x, y) : Rounds x to closest multiple of y, this macro should >> generally be used only when y is not multiple of 2 as otherwise >> round_closest* macros should be used which are much faster. >> >> Examples: >> * round_closest_up(17, 4) = 16 >> * round_closest_up(15, 4) = 16 >> * round_closest_up(14, 4) = 16 >> * round_closest_down(17, 4) = 16 >> * round_closest_down(15, 4) = 16 >> * round_closest_down(14, 4) = 12 >> * roundclosest(21, 5) = 20 >> * roundclosest(19, 5) = 20 >> * roundclosest(17, 5) = 15 >> >> Signed-off-by: Devarsh Thakkar <devarsht@ti.com> >> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> >> --- >> NOTE: This patch is inspired from the Mentor Graphics IPU driver [1] >> which uses similar macro locally and which is updated in further patch >> in the series to use this generic macro instead along with other drivers >> having similar requirements. >> >> Link: https://elixir.bootlin.com/linux/v6.8.9/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 [1] >> --- >> include/linux/math.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 63 insertions(+) >> >> diff --git a/include/linux/math.h b/include/linux/math.h >> index dd4152711de7..79e3dfda77fc 100644 >> --- a/include/linux/math.h >> +++ b/include/linux/math.h >> @@ -34,6 +34,52 @@ >> */ >> #define round_down(x, y) ((x) & ~__round_mask(x, y)) >> >> +/** >> + * round_closest_up - round closest to be multiple of specified value (which is >> + * power of 2) with preference to rounding up >> + * @x: the value to round >> + * @y: multiple to round closest to (must be a power of 2) >> + * >> + * Rounds @x to closest multiple of @y (which must be a power of 2). >> + * The value can be either rounded up or rounded down depending upon rounded >> + * value's closeness to the specified value. If there are two closest possible >> + * values, i.e. the difference between the specified value and it's rounded up >> + * and rounded down values is same then preference is given to rounded up >> + * value. >> + * >> + * To perform arbitrary rounding to closest value (not multiple of 2), use >> + * roundclosest(). >> + * >> + * Examples: >> + * * round_closest_up(17, 4) = 16 >> + * * round_closest_up(15, 4) = 16 >> + * * round_closest_up(14, 4) = 16 >> + */ >> +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) >> + >> +/** >> + * round_closest_down - round closest to be multiple of specified value (which >> + * is power of 2) with preference to rounding down >> + * @x: the value to round >> + * @y: multiple to round closest to (must be a power of 2) >> + * >> + * Rounds @x to closest multiple of @y (which must be a power of 2). >> + * The value can be either rounded up or rounded down depending upon rounded >> + * value's closeness to the specified value. If there are two closest possible >> + * values, i.e. the difference between the specified value and it's rounded up >> + * and rounded down values is same then preference is given to rounded up >> + * value. >> + * >> + * To perform arbitrary rounding to closest value (not multiple of 2), use >> + * roundclosest(). >> + * >> + * Examples: >> + * * round_closest_down(17, 4) = 16 >> + * * round_closest_down(15, 4) = 16 >> + * * round_closest_down(14, 4) = 12 >> + */ >> +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) >> + > > Naming aside, is there an actual use case for having both roundclosest() > and round_closest_up() today? > Both the macros are different, roundclosest is for arbitrary rounding (not multiple of 2) where round_closest_up/down are optimized for rounding to values which are powers of 2. So where there is a surety that rounding value would be power of 2, round_closest* macros are recommended. Regarding the use-cases, there are drivers already using such type of macros locally [1] and new drivers such as [2] required it, so we aligned to have generic macros for all rounding to nearest value scenarios (this patch was earlier part of another series with 7 revisions, see the discussions here [2]). > (i.e., is there any potential caller that would actually care about the > rounding direction for borderline cases?) I think a transparent scheme is better where caller should be aware of rounding direction for borderline cases too so that it gets predictable values w.r.t what it requested for rather than leaving it ambiguous. For e.g. in this patchset [3], it suited more to use round_closest_down instead of round_closest_up keeping in mind hw constraints and use-case requirements, but same might not be true for other drivers. Same was aligned in earlier patch submissions too [2]. > >> #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP >> >> #define DIV_ROUND_DOWN_ULL(ll, d) \ >> @@ -77,6 +123,23 @@ >> } \ >> ) >> >> +/** >> + * roundclosest - round to nearest multiple >> + * @x: the value to round >> + * @y: multiple to round nearest to >> + * >> + * Rounds @x to nearest multiple of @y. >> + * The rounded value can be greater than or less than @x depending >> + * upon it's nearness to @x. If @y will always be a power of 2, consider >> + * using the faster round_closest_up() or round_closest_down(). >> + * >> + * Examples: >> + * * roundclosest(21, 5) = 20 >> + * * roundclosest(19, 5) = 20 >> + * * roundclosest(17, 5) = 15 >> + */ >> +#define roundclosest(x, y) rounddown((x) + (y) / 2, (y)) > > Won't this go wrong if (x) + (y) / 2 overflows? This may happen even in > some cases where the correctly rounded value would be in range. > Yes I think it is possible, it actually depends upon the datatype of x. But anyways, I could make it as below which would yield the same result as arguments are non-multiple of 2: #define roundclosest(x, y) roundup((x) - (y) / 2, (y)) > The existing rounddown() already leaves something to be desired IIUC: if > given a negative dividend, it looks like it actually rounds up, at least > on some arches. But maybe people don't use it that way very often. > Perhaps I'm missing something. I am not sure about above. [1]: https://elixir.bootlin.com/linux/v6.10/source/drivers/gpu/ipu-v3/ipu-image-convert.c#L480 https://elixir.bootlin.com/linux/v6.10/source/drivers/staging/media/ipu3/ipu3-css-params.c#L443 https://lore.kernel.org/all/ZlTt-YWzyRyhmT9n@smile.fi.intel.com/ [2]: https://lore.kernel.org/all/7e3ad816-6a2a-4e02-9b41-03a8562812ad@ti.com/#r https://lore.kernel.org/all/ZkISG6p1tn9Do-xY@smile.fi.intel.com/#r https://lore.kernel.org/all/ZlTt-YWzyRyhmT9n@smile.fi.intel.com/ https://lore.kernel.org/all/ZmHDWeuezCEgj20m@smile.fi.intel.com/ https://lore.kernel.org/all/ZloMFfGKLry6EWNL@smile.fi.intel.com/ [3]: https://lore.kernel.org/all/20240708155943.2314427-7-devarsht@ti.com/ Regards Devarsh
diff --git a/include/linux/math.h b/include/linux/math.h index dd4152711de7..79e3dfda77fc 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -34,6 +34,52 @@ */ #define round_down(x, y) ((x) & ~__round_mask(x, y)) +/** + * round_closest_up - round closest to be multiple of specified value (which is + * power of 2) with preference to rounding up + * @x: the value to round + * @y: multiple to round closest to (must be a power of 2) + * + * Rounds @x to closest multiple of @y (which must be a power of 2). + * The value can be either rounded up or rounded down depending upon rounded + * value's closeness to the specified value. If there are two closest possible + * values, i.e. the difference between the specified value and it's rounded up + * and rounded down values is same then preference is given to rounded up + * value. + * + * To perform arbitrary rounding to closest value (not multiple of 2), use + * roundclosest(). + * + * Examples: + * * round_closest_up(17, 4) = 16 + * * round_closest_up(15, 4) = 16 + * * round_closest_up(14, 4) = 16 + */ +#define round_closest_up(x, y) round_down((x) + (y) / 2, (y)) + +/** + * round_closest_down - round closest to be multiple of specified value (which + * is power of 2) with preference to rounding down + * @x: the value to round + * @y: multiple to round closest to (must be a power of 2) + * + * Rounds @x to closest multiple of @y (which must be a power of 2). + * The value can be either rounded up or rounded down depending upon rounded + * value's closeness to the specified value. If there are two closest possible + * values, i.e. the difference between the specified value and it's rounded up + * and rounded down values is same then preference is given to rounded up + * value. + * + * To perform arbitrary rounding to closest value (not multiple of 2), use + * roundclosest(). + * + * Examples: + * * round_closest_down(17, 4) = 16 + * * round_closest_down(15, 4) = 16 + * * round_closest_down(14, 4) = 12 + */ +#define round_closest_down(x, y) round_up((x) - (y) / 2, (y)) + #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP #define DIV_ROUND_DOWN_ULL(ll, d) \ @@ -77,6 +123,23 @@ } \ ) +/** + * roundclosest - round to nearest multiple + * @x: the value to round + * @y: multiple to round nearest to + * + * Rounds @x to nearest multiple of @y. + * The rounded value can be greater than or less than @x depending + * upon it's nearness to @x. If @y will always be a power of 2, consider + * using the faster round_closest_up() or round_closest_down(). + * + * Examples: + * * roundclosest(21, 5) = 20 + * * roundclosest(19, 5) = 20 + * * roundclosest(17, 5) = 15 + */ +#define roundclosest(x, y) rounddown((x) + (y) / 2, (y)) + /* * Divide positive or negative dividend by positive or negative divisor * and round to closest integer. Result is undefined for negative