[{"id":34988,"web_url":"https://patchwork.libcamera.org/comment/34988/","msgid":"<175312362023.50296.13260232665240057870@ping.linuxembedded.co.uk>","date":"2025-07-21T18:47:00","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Paging Paul and Stefan on this one ;-)\n\nThen I hope we can merge this series soon ...  The main C55 tuning files\ndo not impact any potential regression - and I'd rather see additional\nplatforms get their core tuning parameters in so we can build up the\ntuning platforms to generate for all supported targets sometime.\n\n\nQuoting Daniel Scally (2025-03-04 23:12:53)\n> The Linear distributor attempts to distribute pixels into sectors\n> of even size. Where the image width doesn't allow this it attempts\n> to create all but one sector of full size, and allows the caller\n> to choose to have the stunted sector at the front or the back. The\n> implicit assumption is that\n> \n>         domain == (sector_size * (n_sectors - 1)) + remainder\n> \n> which does not necessarily hold true. For example with 32 sectors and\n> a domain of 648 the calculated sector size will be 21 pixels, which\n> leads to 31 * 21 = 651 which is larger than the domain size.\n> \n> Correct the issue by checking if there's more one stunted sector to\n> be filled. If there is, rather than following the remainder hint for\n> distribution place one of the stunted sectors at the front and one at\n> the back.\n> \n> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> ---\n>  utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n>  1 file changed, 11 insertions(+), 5 deletions(-)\n> \n> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n> index b643f502..bb2edef2 100644\n> --- a/utils/tuning/libtuning/gradient.py\n> +++ b/utils/tuning/libtuning/gradient.py\n> @@ -55,17 +55,23 @@ class Linear(Gradient):\n>  \n>          size = math.ceil(size)\n>          rem = domain % size\n> -        output_sectors = [int(size)] * (sectors - 1)\n> +        n_full_sectors = math.floor(domain / size)\n> +        output_sectors = [int(size)] * n_full_sectors\n>  \n>          if self.remainder == lt.Remainder.Float:\n>              size = domain / sectors\n>              output_sectors = [size] * sectors\n> -        elif self.remainder == lt.Remainder.DistributeFront:\n> +        elif ((sectors - n_full_sectors) == 1):\n> +            if self.remainder == lt.Remainder.DistributeFront:\n> +                output_sectors.append(int(rem))\n> +            elif self.remainder == lt.Remainder.DistributeBack:\n> +                output_sectors.insert(0, int(rem))\n> +            else:\n> +                raise ValueError\n> +        else:\n> +            rem = rem / 2\n>              output_sectors.append(int(rem))\n> -        elif self.remainder == lt.Remainder.DistributeBack:\n>              output_sectors.insert(0, int(rem))\n> -        else:\n> -            raise ValueError\n>  \n>          return output_sectors\n>  \n> -- \n> 2.34.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 06141C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 21 Jul 2025 18:47:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0C3C869006;\n\tMon, 21 Jul 2025 20:47:04 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F097068FB1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 21 Jul 2025 20:47:02 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B80307917;\n\tMon, 21 Jul 2025 20:46:25 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"A09Fco97\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753123585;\n\tbh=syJ9ysO2Kv5mcSjXy1aVkprOUGMiOcBezFYJjAYESsg=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=A09Fco97rlyajFpY6LqSJUQ95G0rOtVT24aecmHahoc6ShSewWEza8F8Oa2p9isSd\n\tF6JB7D0vfu0/7CLjC65IEDRMZ1/KXnrNGnPwBUjBjQ26rb/+Br/buiBoFIzpxnWZik\n\tWE+0b3FzWek8QrKfks9/VKEmufS412M14mEUqOUc=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250304231254.10588-3-dan.scally@ideasonboard.com>","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Daniel Scally <dan.scally@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org,\n\tPaul Elder <paul.elder@ideasonboard.com>, \n\tStefan Klug <stefan.klug@ideasonboard.com>, ","Date":"Mon, 21 Jul 2025 19:47:00 +0100","Message-ID":"<175312362023.50296.13260232665240057870@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35017,"web_url":"https://patchwork.libcamera.org/comment/35017/","msgid":"<175318440242.3923365.18253479485341827@neptunite.rasen.tech>","date":"2025-07-22T11:40:02","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Daniel Scally (2025-03-05 08:12:53)\n> The Linear distributor attempts to distribute pixels into sectors\n> of even size. Where the image width doesn't allow this it attempts\n> to create all but one sector of full size, and allows the caller\n> to choose to have the stunted sector at the front or the back. The\n> implicit assumption is that\n> \n>         domain == (sector_size * (n_sectors - 1)) + remainder\n> \n> which does not necessarily hold true. For example with 32 sectors and\n> a domain of 648 the calculated sector size will be 21 pixels, which\n> leads to 31 * 21 = 651 which is larger than the domain size.\n\nDoesn't the equation hold true if sector_size is 20? (20 * 31) + 28 = 648\n\n(Which means the calculated sector size is wrong)\n\n>\n> Correct the issue by checking if there's more one stunted sector to\n> be filled. If there is, rather than following the remainder hint for\n> distribution place one of the stunted sectors at the front and one at\n> the back.\n\nSo this would get you 9 + (21 * 30) + 9 = 648 instead. Is that better than the\nabove?\n\n> \n> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n\nThe math below checks out with what you describe.\n\n\nThanks,\n\nPaul\n\n> ---\n>  utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n>  1 file changed, 11 insertions(+), 5 deletions(-)\n> \n> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n> index b643f502..bb2edef2 100644\n> --- a/utils/tuning/libtuning/gradient.py\n> +++ b/utils/tuning/libtuning/gradient.py\n> @@ -55,17 +55,23 @@ class Linear(Gradient):\n>  \n>          size = math.ceil(size)\n>          rem = domain % size\n> -        output_sectors = [int(size)] * (sectors - 1)\n> +        n_full_sectors = math.floor(domain / size)\n> +        output_sectors = [int(size)] * n_full_sectors\n>  \n>          if self.remainder == lt.Remainder.Float:\n>              size = domain / sectors\n>              output_sectors = [size] * sectors\n> -        elif self.remainder == lt.Remainder.DistributeFront:\n> +        elif ((sectors - n_full_sectors) == 1):\n> +            if self.remainder == lt.Remainder.DistributeFront:\n> +                output_sectors.append(int(rem))\n> +            elif self.remainder == lt.Remainder.DistributeBack:\n> +                output_sectors.insert(0, int(rem))\n> +            else:\n> +                raise ValueError\n> +        else:\n> +            rem = rem / 2\n>              output_sectors.append(int(rem))\n> -        elif self.remainder == lt.Remainder.DistributeBack:\n>              output_sectors.insert(0, int(rem))\n> -        else:\n> -            raise ValueError\n>  \n>          return output_sectors\n>  \n> -- \n> 2.34.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 1F862C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 22 Jul 2025 11:40:12 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 48D7969031;\n\tTue, 22 Jul 2025 13:40:11 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E347A68F93\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Jul 2025 13:40:08 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:5fe2:6df7:ad99:5884])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 646AD1198; \n\tTue, 22 Jul 2025 13:39:30 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ISR+CGQe\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753184370;\n\tbh=Z0vSdufSLJepg0MeuQeL7t7VEQ5PBqRmWaJSFCT2dls=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=ISR+CGQe2UfZqegfF+QLWlyfYzCNdm55+5wnMvGwFygDgEhGeXYc0fA6aJ9qbElbL\n\tTU1y8lEIoXC8B57UiSVZNlqe2rII02EGUKnL17XamU4EKN6V/AvzYHBPUZtQVL6p97\n\tbFZYm+X9pua1fo3QABq4edqHwnbKpP/ldpgchkUo=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250304231254.10588-3-dan.scally@ideasonboard.com>","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"Daniel Scally <dan.scally@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Tue, 22 Jul 2025 20:40:02 +0900","Message-ID":"<175318440242.3923365.18253479485341827@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35060,"web_url":"https://patchwork.libcamera.org/comment/35060/","msgid":"<20250723183708.GB11202@pendragon.ideasonboard.com>","date":"2025-07-23T18:37:08","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Dan,\n\nThank you for the patch.\n\nOn Tue, Mar 04, 2025 at 11:12:53PM +0000, Daniel Scally wrote:\n> The Linear distributor attempts to distribute pixels into sectors\n> of even size. Where the image width doesn't allow this it attempts\n> to create all but one sector of full size, and allows the caller\n> to choose to have the stunted sector at the front or the back. The\n> implicit assumption is that\n> \n> \tdomain == (sector_size * (n_sectors - 1)) + remainder\n> \n> which does not necessarily hold true. For example with 32 sectors and\n> a domain of 648 the calculated sector size will be 21 pixels, which\n> leads to 31 * 21 = 651 which is larger than the domain size.\n> \n> Correct the issue by checking if there's more one stunted sector to\n> be filled. If there is, rather than following the remainder hint for\n> distribution place one of the stunted sectors at the front and one at\n> the back.\n> \n> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> ---\n>  utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n>  1 file changed, 11 insertions(+), 5 deletions(-)\n> \n> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n> index b643f502..bb2edef2 100644\n> --- a/utils/tuning/libtuning/gradient.py\n> +++ b/utils/tuning/libtuning/gradient.py\n> @@ -55,17 +55,23 @@ class Linear(Gradient):\n>  \n>          size = math.ceil(size)\n>          rem = domain % size\n> -        output_sectors = [int(size)] * (sectors - 1)\n> +        n_full_sectors = math.floor(domain / size)\n> +        output_sectors = [int(size)] * n_full_sectors\n>  \n>          if self.remainder == lt.Remainder.Float:\n>              size = domain / sectors\n>              output_sectors = [size] * sectors\n> -        elif self.remainder == lt.Remainder.DistributeFront:\n> +        elif ((sectors - n_full_sectors) == 1):\n> +            if self.remainder == lt.Remainder.DistributeFront:\n> +                output_sectors.append(int(rem))\n> +            elif self.remainder == lt.Remainder.DistributeBack:\n> +                output_sectors.insert(0, int(rem))\n> +            else:\n> +                raise ValueError\n> +        else:\n> +            rem = rem / 2\n>              output_sectors.append(int(rem))\n> -        elif self.remainder == lt.Remainder.DistributeBack:\n>              output_sectors.insert(0, int(rem))\n> -        else:\n> -            raise ValueError\n\nThis looks relly convoluted. Could you simplify the whole function ?\n\n>  \n>          return output_sectors\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9F1E5C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 23 Jul 2025 18:37:13 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B29396906A;\n\tWed, 23 Jul 2025 20:37:12 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 48AB369064\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jul 2025 20:37:11 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 79050E70;\n\tWed, 23 Jul 2025 20:36:32 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ogUJSpID\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753295792;\n\tbh=JqRQfyeb5oeXfacOEaaWRLIIHSqx3hnOa3BKdAQtx1o=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=ogUJSpIDEqDEp84UmYBJUaq1Vh/z70XKM5xESeKlqI0QV5khLbS5X3a2k6WxHa7Ev\n\tsyGczkcfBVOp4nskhJy1Q9NjHQ85tJI1splG80fDK0a1vJQz7xqELUvoqeqGwMJ2LF\n\tsdxOGgI71q9ROEI3xlsMk+oUkLnP5bK5k1NX4umU=","Date":"Wed, 23 Jul 2025 21:37:08 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","Message-ID":"<20250723183708.GB11202@pendragon.ideasonboard.com>","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20250304231254.10588-3-dan.scally@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35063,"web_url":"https://patchwork.libcamera.org/comment/35063/","msgid":"<2a609720-f6aa-48a9-a1cb-2789575c839c@ideasonboard.com>","date":"2025-07-23T21:28:04","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":156,"url":"https://patchwork.libcamera.org/api/people/156/","name":"Dan Scally","email":"dan.scally@ideasonboard.com"},"content":"Hi Paul\n\nOn 22/07/2025 12:40, Paul Elder wrote:\n> Quoting Daniel Scally (2025-03-05 08:12:53)\n>> The Linear distributor attempts to distribute pixels into sectors\n>> of even size. Where the image width doesn't allow this it attempts\n>> to create all but one sector of full size, and allows the caller\n>> to choose to have the stunted sector at the front or the back. The\n>> implicit assumption is that\n>>\n>>          domain == (sector_size * (n_sectors - 1)) + remainder\n>>\n>> which does not necessarily hold true. For example with 32 sectors and\n>> a domain of 648 the calculated sector size will be 21 pixels, which\n>> leads to 31 * 21 = 651 which is larger than the domain size.\n> Doesn't the equation hold true if sector_size is 20? (20 * 31) + 28 = 648\n>\n> (Which means the calculated sector size is wrong)\n\n\nAt the moment you'd end up with 628 as the last sector would be calculated as 8 instead of 28 - the \ncurrent implementation doesn't allow for the unequal sector to be larger...but perhaps that's a \nbetter change than splitting the runt into two?\n\n>\n>> Correct the issue by checking if there's more one stunted sector to\n>> be filled. If there is, rather than following the remainder hint for\n>> distribution place one of the stunted sectors at the front and one at\n>> the back.\n> So this would get you 9 + (21 * 30) + 9 = 648 instead. Is that better than the\n> above?\n\nI think it is...unless I'm misremembering I think the effect of a single larger sector would be that \nmore of the more central pixels would be included in that \"slice\", would presumably be brighter and \ntherefore would have slightly less shading applied than the equivalent slice on the other side of \nthe image...but the effect is probably really really minimal. I can generate some LSC tables with \nboth methodologies and see how they're different?\n\n\nThanks\n\nDan\n\n>\n>> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> The math below checks out with what you describe.\n>\n>\n> Thanks,\n>\n> Paul\n>\n>> ---\n>>   utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n>>   1 file changed, 11 insertions(+), 5 deletions(-)\n>>\n>> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n>> index b643f502..bb2edef2 100644\n>> --- a/utils/tuning/libtuning/gradient.py\n>> +++ b/utils/tuning/libtuning/gradient.py\n>> @@ -55,17 +55,23 @@ class Linear(Gradient):\n>>   \n>>           size = math.ceil(size)\n>>           rem = domain % size\n>> -        output_sectors = [int(size)] * (sectors - 1)\n>> +        n_full_sectors = math.floor(domain / size)\n>> +        output_sectors = [int(size)] * n_full_sectors\n>>   \n>>           if self.remainder == lt.Remainder.Float:\n>>               size = domain / sectors\n>>               output_sectors = [size] * sectors\n>> -        elif self.remainder == lt.Remainder.DistributeFront:\n>> +        elif ((sectors - n_full_sectors) == 1):\n>> +            if self.remainder == lt.Remainder.DistributeFront:\n>> +                output_sectors.append(int(rem))\n>> +            elif self.remainder == lt.Remainder.DistributeBack:\n>> +                output_sectors.insert(0, int(rem))\n>> +            else:\n>> +                raise ValueError\n>> +        else:\n>> +            rem = rem / 2\n>>               output_sectors.append(int(rem))\n>> -        elif self.remainder == lt.Remainder.DistributeBack:\n>>               output_sectors.insert(0, int(rem))\n>> -        else:\n>> -            raise ValueError\n>>   \n>>           return output_sectors\n>>   \n>> -- \n>> 2.34.1\n>>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 4C006C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 23 Jul 2025 21:28:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3DCA86906D;\n\tWed, 23 Jul 2025 23:28:09 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 67D66614ED\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jul 2025 23:28:07 +0200 (CEST)","from [192.168.0.43]\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B8529C71;\n\tWed, 23 Jul 2025 23:27:28 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"c9bNg2pc\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753306048;\n\tbh=dimOBHFuV8XwsAxO0A4T/ID3YJZEHNWvFErPYclp6T0=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=c9bNg2pcXZO3OTabMhlQsxDu6KrrD/iEmpOANORil8K0Gyv4M8mN00xM7bHhulksT\n\tbTBpAbMm0BIrATiJ957vGErR0Zi+fRYXSNKhXZiiDnenst/DKATIF2qlX70O6AnwLB\n\tgDzy3E9kGX8Rbw5QaN+hz4Xt5jCgl0UEGHvBg5/U=","Message-ID":"<2a609720-f6aa-48a9-a1cb-2789575c839c@ideasonboard.com>","Date":"Wed, 23 Jul 2025 22:28:04 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","To":"Paul Elder <paul.elder@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>\n\t<175318440242.3923365.18253479485341827@neptunite.rasen.tech>","Content-Language":"en-US","From":"Dan Scally <dan.scally@ideasonboard.com>","Autocrypt":"addr=dan.scally@ideasonboard.com; keydata=\n\t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","In-Reply-To":"<175318440242.3923365.18253479485341827@neptunite.rasen.tech>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35074,"web_url":"https://patchwork.libcamera.org/comment/35074/","msgid":"<175334131908.774292.12715504951039835487@neptunite.rasen.tech>","date":"2025-07-24T07:15:19","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Dan Scally (2025-07-24 06:28:04)\n> Hi Paul\n> \n> On 22/07/2025 12:40, Paul Elder wrote:\n> > Quoting Daniel Scally (2025-03-05 08:12:53)\n> >> The Linear distributor attempts to distribute pixels into sectors\n> >> of even size. Where the image width doesn't allow this it attempts\n> >> to create all but one sector of full size, and allows the caller\n> >> to choose to have the stunted sector at the front or the back. The\n> >> implicit assumption is that\n> >>\n> >>          domain == (sector_size * (n_sectors - 1)) + remainder\n> >>\n> >> which does not necessarily hold true. For example with 32 sectors and\n> >> a domain of 648 the calculated sector size will be 21 pixels, which\n> >> leads to 31 * 21 = 651 which is larger than the domain size.\n> > Doesn't the equation hold true if sector_size is 20? (20 * 31) + 28 = 648\n> >\n> > (Which means the calculated sector size is wrong)\n> \n> \n> At the moment you'd end up with 628 as the last sector would be calculated as 8 instead of 28 - the \n> current implementation doesn't allow for the unequal sector to be larger...but perhaps that's a \n\nOh ok I see what you mean. That was indeed my assumption when I wrote it...\n\n> better change than splitting the runt into two?\n> \n> >\n> >> Correct the issue by checking if there's more one stunted sector to\n> >> be filled. If there is, rather than following the remainder hint for\n> >> distribution place one of the stunted sectors at the front and one at\n> >> the back.\n> > So this would get you 9 + (21 * 30) + 9 = 648 instead. Is that better than the\n> > above?\n> \n> I think it is...unless I'm misremembering I think the effect of a single larger sector would be that \n> more of the more central pixels would be included in that \"slice\", would presumably be brighter and \n> therefore would have slightly less shading applied than the equivalent slice on the other side of \n> the image...but the effect is probably really really minimal. I can generate some LSC tables with \n> both methodologies and see how they're different?\n\nI had a brain fart. Smaller sectors on the edges would give you more\ngranularity, and for lsc that's what you want. So of course it's better.\n\nI guess we can worry about it later when other things start using linear\ndistributions that want the opposite effect.\n\n\nOk, I'm convinced:\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> \n> \n> Thanks\n> \n> Dan\n> \n> >\n> >> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> > The math below checks out with what you describe.\n> >\n> >\n> > Thanks,\n> >\n> > Paul\n> >\n> >> ---\n> >>   utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n> >>   1 file changed, 11 insertions(+), 5 deletions(-)\n> >>\n> >> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n> >> index b643f502..bb2edef2 100644\n> >> --- a/utils/tuning/libtuning/gradient.py\n> >> +++ b/utils/tuning/libtuning/gradient.py\n> >> @@ -55,17 +55,23 @@ class Linear(Gradient):\n> >>   \n> >>           size = math.ceil(size)\n> >>           rem = domain % size\n> >> -        output_sectors = [int(size)] * (sectors - 1)\n> >> +        n_full_sectors = math.floor(domain / size)\n> >> +        output_sectors = [int(size)] * n_full_sectors\n> >>   \n> >>           if self.remainder == lt.Remainder.Float:\n> >>               size = domain / sectors\n> >>               output_sectors = [size] * sectors\n> >> -        elif self.remainder == lt.Remainder.DistributeFront:\n> >> +        elif ((sectors - n_full_sectors) == 1):\n> >> +            if self.remainder == lt.Remainder.DistributeFront:\n> >> +                output_sectors.append(int(rem))\n> >> +            elif self.remainder == lt.Remainder.DistributeBack:\n> >> +                output_sectors.insert(0, int(rem))\n> >> +            else:\n> >> +                raise ValueError\n> >> +        else:\n> >> +            rem = rem / 2\n> >>               output_sectors.append(int(rem))\n> >> -        elif self.remainder == lt.Remainder.DistributeBack:\n> >>               output_sectors.insert(0, int(rem))\n> >> -        else:\n> >> -            raise ValueError\n> >>   \n> >>           return output_sectors\n> >>   \n> >> -- \n> >> 2.34.1\n> >>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E09A8BDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 24 Jul 2025 07:15:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 696F8690A9;\n\tThu, 24 Jul 2025 09:15:26 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 171AC69097\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 24 Jul 2025 09:15:25 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:be7f:7fca:78b4:1343])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 6A0EDC70;\n\tThu, 24 Jul 2025 09:14:45 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"uDD5e/mZ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753341286;\n\tbh=x0s4zaWYYaCjGFO+0PC6XRYX0PwTJBrjfA+IxwLYHhc=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=uDD5e/mZqO7Ai8VF3PQ8cc6xu720zPEFeb6avflcMwL9nhwag4X6QOlM7lcPUq8qq\n\trFSRCltn9gxfw26BZDpwfxcQfgWajEow1L+/vjUkCBYECzmAUHBixDQtv4i9pNLRYV\n\t/IZxqVpDT0T3FsfbAkResPtVoFNTPzTXyfoPpoaU=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<2a609720-f6aa-48a9-a1cb-2789575c839c@ideasonboard.com>","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>\n\t<175318440242.3923365.18253479485341827@neptunite.rasen.tech>\n\t<2a609720-f6aa-48a9-a1cb-2789575c839c@ideasonboard.com>","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"Dan Scally <dan.scally@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 24 Jul 2025 16:15:19 +0900","Message-ID":"<175334131908.774292.12715504951039835487@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35116,"web_url":"https://patchwork.libcamera.org/comment/35116/","msgid":"<4d1b2a87-1572-4d52-8682-5d40dc844456@ideasonboard.com>","date":"2025-07-25T07:57:06","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":156,"url":"https://patchwork.libcamera.org/api/people/156/","name":"Dan Scally","email":"dan.scally@ideasonboard.com"},"content":"Hi Laurent, Paul\n\nOn 23/07/2025 19:37, Laurent Pinchart wrote:\n> Hi Dan,\n>\n> Thank you for the patch.\n>\n> On Tue, Mar 04, 2025 at 11:12:53PM +0000, Daniel Scally wrote:\n>> The Linear distributor attempts to distribute pixels into sectors\n>> of even size. Where the image width doesn't allow this it attempts\n>> to create all but one sector of full size, and allows the caller\n>> to choose to have the stunted sector at the front or the back. The\n>> implicit assumption is that\n>>\n>> \tdomain == (sector_size * (n_sectors - 1)) + remainder\n>>\n>> which does not necessarily hold true. For example with 32 sectors and\n>> a domain of 648 the calculated sector size will be 21 pixels, which\n>> leads to 31 * 21 = 651 which is larger than the domain size.\n>>\n>> Correct the issue by checking if there's more one stunted sector to\n>> be filled. If there is, rather than following the remainder hint for\n>> distribution place one of the stunted sectors at the front and one at\n>> the back.\n>>\n>> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n>> ---\n>>   utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n>>   1 file changed, 11 insertions(+), 5 deletions(-)\n>>\n>> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n>> index b643f502..bb2edef2 100644\n>> --- a/utils/tuning/libtuning/gradient.py\n>> +++ b/utils/tuning/libtuning/gradient.py\n>> @@ -55,17 +55,23 @@ class Linear(Gradient):\n>>   \n>>           size = math.ceil(size)\n>>           rem = domain % size\n>> -        output_sectors = [int(size)] * (sectors - 1)\n>> +        n_full_sectors = math.floor(domain / size)\n>> +        output_sectors = [int(size)] * n_full_sectors\n>>   \n>>           if self.remainder == lt.Remainder.Float:\n>>               size = domain / sectors\n>>               output_sectors = [size] * sectors\n>> -        elif self.remainder == lt.Remainder.DistributeFront:\n>> +        elif ((sectors - n_full_sectors) == 1):\n>> +            if self.remainder == lt.Remainder.DistributeFront:\n>> +                output_sectors.append(int(rem))\n>> +            elif self.remainder == lt.Remainder.DistributeBack:\n>> +                output_sectors.insert(0, int(rem))\n>> +            else:\n>> +                raise ValueError\n>> +        else:\n>> +            rem = rem / 2\n>>               output_sectors.append(int(rem))\n>> -        elif self.remainder == lt.Remainder.DistributeBack:\n>>               output_sectors.insert(0, int(rem))\n>> -        else:\n>> -            raise ValueError\n> This looks relly convoluted. Could you simplify the whole function ?\n\n\nI tried to simplify and in testing my simplified solution I found a whole bunch of situations in \nwhich neither the old nor new version worked...for example with a domain of 1174 and 64 sectors the \ncurrent method of calculating the \"normal\" sector size with roundup(domain / sectors) gives you 61 \nsectors of 19 and a remainder of 15 to divide across 3 sectors...which seems to me quite \nundesirable. I wonder if it's not better to change the function to calculate the \"normal\" sector \nsize with rounddown(domain / sectors) and then distribute the remainder (which in the above example \nwould be 4) by incrementally assigning 1 to each sector starting from either the front or back of \nthe array, or the outside inwards, or the centre outwards...That would leave us with four sectors of \n19 and 60 of 18 - I think that's a lot better than 61 sectors of 19 and 3 sectors of 5.\n\n\nOr possibly those parameters are so unrealistic that accounting for them is daft, and we should \ninstead define limits for the parameters that lets us simplify things...\n\n\nThoughts?\n\n\nDan\n\n>\n>>   \n>>           return output_sectors\n>>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 4B0AFBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Jul 2025 07:57:14 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 45F6B6908C;\n\tFri, 25 Jul 2025 09:57:13 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E44169080\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Jul 2025 09:57:10 +0200 (CEST)","from [192.168.0.43]\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 537F1C64;\n\tFri, 25 Jul 2025 09:56:30 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ihAAv8ta\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753430190;\n\tbh=Sw7fnYgDIs7WISyE7syeKTwwet8dp8agHdd5IY+EkQI=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=ihAAv8tazhYLO9Wv0oxLBSeuhWgrwjtWC3KIzegUgbvK93MWRTjQxodQa41909j+P\n\tSPsbZ+KXJeYvs4omcAzGS+3j1qKG7d1IdPrWuQSGWZprt/GeOZfoOqgLieKfMiro5A\n\tReb2YkLwevsO1L37rDi2/ZD5aXaENtejX+RTyCjk=","Message-ID":"<4d1b2a87-1572-4d52-8682-5d40dc844456@ideasonboard.com>","Date":"Fri, 25 Jul 2025 08:57:06 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>\n\t<20250723183708.GB11202@pendragon.ideasonboard.com>","Content-Language":"en-US","From":"Dan Scally <dan.scally@ideasonboard.com>","Autocrypt":"addr=dan.scally@ideasonboard.com; keydata=\n\t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","In-Reply-To":"<20250723183708.GB11202@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35129,"web_url":"https://patchwork.libcamera.org/comment/35129/","msgid":"<20250725114601.GE11202@pendragon.ideasonboard.com>","date":"2025-07-25T11:46:01","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Jul 25, 2025 at 08:57:06AM +0100, Daniel Scally wrote:\n> Hi Laurent, Paul\n> \n> On 23/07/2025 19:37, Laurent Pinchart wrote:\n> > Hi Dan,\n> >\n> > Thank you for the patch.\n> >\n> > On Tue, Mar 04, 2025 at 11:12:53PM +0000, Daniel Scally wrote:\n> >> The Linear distributor attempts to distribute pixels into sectors\n> >> of even size. Where the image width doesn't allow this it attempts\n> >> to create all but one sector of full size, and allows the caller\n> >> to choose to have the stunted sector at the front or the back. The\n> >> implicit assumption is that\n> >>\n> >> \tdomain == (sector_size * (n_sectors - 1)) + remainder\n> >>\n> >> which does not necessarily hold true. For example with 32 sectors and\n> >> a domain of 648 the calculated sector size will be 21 pixels, which\n> >> leads to 31 * 21 = 651 which is larger than the domain size.\n> >>\n> >> Correct the issue by checking if there's more one stunted sector to\n> >> be filled. If there is, rather than following the remainder hint for\n> >> distribution place one of the stunted sectors at the front and one at\n> >> the back.\n> >>\n> >> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> >> ---\n> >>   utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n> >>   1 file changed, 11 insertions(+), 5 deletions(-)\n> >>\n> >> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n> >> index b643f502..bb2edef2 100644\n> >> --- a/utils/tuning/libtuning/gradient.py\n> >> +++ b/utils/tuning/libtuning/gradient.py\n> >> @@ -55,17 +55,23 @@ class Linear(Gradient):\n> >>   \n> >>           size = math.ceil(size)\n> >>           rem = domain % size\n> >> -        output_sectors = [int(size)] * (sectors - 1)\n> >> +        n_full_sectors = math.floor(domain / size)\n> >> +        output_sectors = [int(size)] * n_full_sectors\n> >>   \n> >>           if self.remainder == lt.Remainder.Float:\n> >>               size = domain / sectors\n> >>               output_sectors = [size] * sectors\n> >> -        elif self.remainder == lt.Remainder.DistributeFront:\n> >> +        elif ((sectors - n_full_sectors) == 1):\n> >> +            if self.remainder == lt.Remainder.DistributeFront:\n> >> +                output_sectors.append(int(rem))\n> >> +            elif self.remainder == lt.Remainder.DistributeBack:\n> >> +                output_sectors.insert(0, int(rem))\n> >> +            else:\n> >> +                raise ValueError\n> >> +        else:\n> >> +            rem = rem / 2\n> >>               output_sectors.append(int(rem))\n> >> -        elif self.remainder == lt.Remainder.DistributeBack:\n> >>               output_sectors.insert(0, int(rem))\n> >> -        else:\n> >> -            raise ValueError\n> >\n> > This looks relly convoluted. Could you simplify the whole function ?\n> \n> I tried to simplify and in testing my simplified solution I found a whole bunch of situations in \n> which neither the old nor new version worked...for example with a domain of 1174 and 64 sectors the \n> current method of calculating the \"normal\" sector size with roundup(domain / sectors) gives you 61 \n> sectors of 19 and a remainder of 15 to divide across 3 sectors...which seems to me quite \n> undesirable. I wonder if it's not better to change the function to calculate the \"normal\" sector \n> size with rounddown(domain / sectors) and then distribute the remainder (which in the above example \n> would be 4) by incrementally assigning 1 to each sector starting from either the front or back of \n> the array, or the outside inwards, or the centre outwards...That would leave us with four sectors of \n> 19 and 60 of 18 - I think that's a lot better than 61 sectors of 19 and 3 sectors of 5.\n\nI had a similar idea, based on the gut feeling that distributing the\nerror could be better. I would possibly try to distribute it evenly.\n\nPaul, why did we add support for different distributions ? We only use\nDistributeFront as far as I can see.\n\n> Or possibly those parameters are so unrealistic that accounting for them is daft, and we should \n> instead define limits for the parameters that lets us simplify things...\n> \n> Thoughts?\n> \n> >>   \n> >>           return output_sectors\n> >>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0CB3EC3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Jul 2025 11:46:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 364DC690C3;\n\tFri, 25 Jul 2025 13:46:07 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D6912690A6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Jul 2025 13:46:05 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id CB39EC66;\n\tFri, 25 Jul 2025 13:45:25 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"hoTlZcEV\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753443926;\n\tbh=sPg9dBgGN1wY9JSeEQUDpfL5wU46bqPJwvEdpokyUNc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=hoTlZcEVkzRXgvtpF02UxZIiPEuXvYyAGSSZaPr8b4uyLzEdaQNwLD/VO6lUB3LaE\n\tW78ynU0Yt6vRQOmfdLRXZnydWmrMJmKNzuVSa+rhzmmqUCiXEdTfrwc4gHWvIAdn4m\n\t4L0D1bS++JlDvW0u4/aFlCcPRatnFNb1vM2t4d2w=","Date":"Fri, 25 Jul 2025 14:46:01 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Dan Scally <dan.scally@ideasonboard.com>","Cc":"Paul Elder <paul.elder@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","Message-ID":"<20250725114601.GE11202@pendragon.ideasonboard.com>","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>\n\t<20250723183708.GB11202@pendragon.ideasonboard.com>\n\t<4d1b2a87-1572-4d52-8682-5d40dc844456@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<4d1b2a87-1572-4d52-8682-5d40dc844456@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35559,"web_url":"https://patchwork.libcamera.org/comment/35559/","msgid":"<175618388595.607151.2547570141867172942@neptunite.rasen.tech>","date":"2025-08-26T04:51:25","subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2025-07-25 20:46:01)\n> On Fri, Jul 25, 2025 at 08:57:06AM +0100, Daniel Scally wrote:\n> > Hi Laurent, Paul\n> > \n> > On 23/07/2025 19:37, Laurent Pinchart wrote:\n> > > Hi Dan,\n> > >\n> > > Thank you for the patch.\n> > >\n> > > On Tue, Mar 04, 2025 at 11:12:53PM +0000, Daniel Scally wrote:\n> > >> The Linear distributor attempts to distribute pixels into sectors\n> > >> of even size. Where the image width doesn't allow this it attempts\n> > >> to create all but one sector of full size, and allows the caller\n> > >> to choose to have the stunted sector at the front or the back. The\n> > >> implicit assumption is that\n> > >>\n> > >>    domain == (sector_size * (n_sectors - 1)) + remainder\n> > >>\n> > >> which does not necessarily hold true. For example with 32 sectors and\n> > >> a domain of 648 the calculated sector size will be 21 pixels, which\n> > >> leads to 31 * 21 = 651 which is larger than the domain size.\n> > >>\n> > >> Correct the issue by checking if there's more one stunted sector to\n> > >> be filled. If there is, rather than following the remainder hint for\n> > >> distribution place one of the stunted sectors at the front and one at\n> > >> the back.\n> > >>\n> > >> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> > >> ---\n> > >>   utils/tuning/libtuning/gradient.py | 16 +++++++++++-----\n> > >>   1 file changed, 11 insertions(+), 5 deletions(-)\n> > >>\n> > >> diff --git a/utils/tuning/libtuning/gradient.py b/utils/tuning/libtuning/gradient.py\n> > >> index b643f502..bb2edef2 100644\n> > >> --- a/utils/tuning/libtuning/gradient.py\n> > >> +++ b/utils/tuning/libtuning/gradient.py\n> > >> @@ -55,17 +55,23 @@ class Linear(Gradient):\n> > >>   \n> > >>           size = math.ceil(size)\n> > >>           rem = domain % size\n> > >> -        output_sectors = [int(size)] * (sectors - 1)\n> > >> +        n_full_sectors = math.floor(domain / size)\n> > >> +        output_sectors = [int(size)] * n_full_sectors\n> > >>   \n> > >>           if self.remainder == lt.Remainder.Float:\n> > >>               size = domain / sectors\n> > >>               output_sectors = [size] * sectors\n> > >> -        elif self.remainder == lt.Remainder.DistributeFront:\n> > >> +        elif ((sectors - n_full_sectors) == 1):\n> > >> +            if self.remainder == lt.Remainder.DistributeFront:\n> > >> +                output_sectors.append(int(rem))\n> > >> +            elif self.remainder == lt.Remainder.DistributeBack:\n> > >> +                output_sectors.insert(0, int(rem))\n> > >> +            else:\n> > >> +                raise ValueError\n> > >> +        else:\n> > >> +            rem = rem / 2\n> > >>               output_sectors.append(int(rem))\n> > >> -        elif self.remainder == lt.Remainder.DistributeBack:\n> > >>               output_sectors.insert(0, int(rem))\n> > >> -        else:\n> > >> -            raise ValueError\n> > >\n> > > This looks relly convoluted. Could you simplify the whole function ?\n> > \n> > I tried to simplify and in testing my simplified solution I found a whole bunch of situations in \n> > which neither the old nor new version worked...for example with a domain of 1174 and 64 sectors the \n\nYeah those were the vibes I was getting too when I reviewd this.\n\n> > current method of calculating the \"normal\" sector size with roundup(domain / sectors) gives you 61 \n> > sectors of 19 and a remainder of 15 to divide across 3 sectors...which seems to me quite \n> > undesirable. I wonder if it's not better to change the function to calculate the \"normal\" sector \n> > size with rounddown(domain / sectors) and then distribute the remainder (which in the above example \n> > would be 4) by incrementally assigning 1 to each sector starting from either the front or back of \n> > the array, or the outside inwards, or the centre outwards...That would leave us with four sectors of \n> > 19 and 60 of 18 - I think that's a lot better than 61 sectors of 19 and 3 sectors of 5.\n> \n> I had a similar idea, based on the gut feeling that distributing the\n> error could be better. I would possibly try to distribute it evenly.\n> \n> Paul, why did we add support for different distributions ? We only use\n> DistributeFront as far as I can see.\n\niirc I wanted Float for, well, \"default behavior\". For DistributeBack, I think\nit's because choosing to distribute equally with the remainder *at the end* is\nkind of an arbitrary decision, so I thought it would be better to leave the\nopposite as an option.\n\nThough now that I think about it, because of what this series does, maybe we\nshould have a DistributeBoth or something along that line? To distribute the\nremainder equally on both sides. Although I'm not sure why you'd use\nDistributeFront or DistributeBack if that exists.\n\n\nPaul\n\n> \n> > Or possibly those parameters are so unrealistic that accounting for them is daft, and we should \n> > instead define limits for the parameters that lets us simplify things...\n> > \n> > Thoughts?\n> > \n> > >>   \n> > >>           return output_sectors\n> > >>   \n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B2E54BEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Aug 2025 04:51:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9C0CE692E9;\n\tTue, 26 Aug 2025 06:51:32 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 96D4C613BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Aug 2025 06:51:31 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:5d3f:5a62:a50a:b707])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 5BE835402; \n\tTue, 26 Aug 2025 06:50:28 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"MikHwaZ3\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1756183828;\n\tbh=he9uqrLiiEpbBMVwh5GxtIzc5xa923v/gGZWIbGM6+Q=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=MikHwaZ3bd0/lNiMwlu+Aj/eFZEMQTYPLMsCEKOLKxeriw9vN9RWkf+eG/hiEbmkZ\n\tCoKeOamkFh9wJ7lry+7R5QZtE6Xvx+/iJO+DANNm544SeZAQEfThqVID6lyh0jt+JP\n\tx+NEixtUuR2fuEQTo1z7xGUyozOVJ4eGXSlRVB4M=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250725114601.GE11202@pendragon.ideasonboard.com>","References":"<20250304231254.10588-1-dan.scally@ideasonboard.com>\n\t<20250304231254.10588-3-dan.scally@ideasonboard.com>\n\t<20250723183708.GB11202@pendragon.ideasonboard.com>\n\t<4d1b2a87-1572-4d52-8682-5d40dc844456@ideasonboard.com>\n\t<20250725114601.GE11202@pendragon.ideasonboard.com>","Subject":"Re: [PATCH 2/3] libtuning: Gradient: Correct Linear distribution","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","To":"Dan Scally <dan.scally@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Tue, 26 Aug 2025 13:51:25 +0900","Message-ID":"<175618388595.607151.2547570141867172942@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]