[{"id":36833,"web_url":"https://patchwork.libcamera.org/comment/36833/","msgid":"<53024f26-af47-4eb4-88f3-e4bccc8fdcf7@ideasonboard.com>","date":"2025-11-14T18:08:13","subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2025. 11. 14. 1:54 keltezéssel, Kieran Bingham írta:\n> Validate the new fixed-point Quantized types with tests covering Q1.7,\n> UQ1.7, Q12.4 and UQ12.4 types.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> ---\n> v3:\n> - Rename quantized_type to QuantizedType\n> \n>   test/ipa/libipa/fixedpoint.cpp | 120 +++++++++++++++++++++++++++++++--\n>   1 file changed, 116 insertions(+), 4 deletions(-)\n> \n> diff --git a/test/ipa/libipa/fixedpoint.cpp b/test/ipa/libipa/fixedpoint.cpp\n> index 99eb662ddf4e..935412771851 100644\n> --- a/test/ipa/libipa/fixedpoint.cpp\n> +++ b/test/ipa/libipa/fixedpoint.cpp\n> @@ -5,12 +5,14 @@\n>    * Fixed / Floating point utility tests\n>    */\n>   \n> +#include \"../src/ipa/libipa/fixedpoint.h\"\n> +\n>   #include <cmath>\n>   #include <iostream>\n>   #include <map>\n>   #include <stdint.h>\n>   \n> -#include \"../src/ipa/libipa/fixedpoint.h\"\n> +#include <libcamera/base/utils.h>\n>   \n>   #include \"test.h\"\n>   \n> @@ -95,14 +97,124 @@ protected:\n>   \t\treturn TestPass;\n>   \t}\n>   \n> -\tint run()\n> +\ttemplate<typename Q>\n> +\tint quantizedCheck(float input, typename Q::QuantizedType expected, float value)\n>   \t{\n> -\t\t/* fixed point conversion test */\n> -\t\tif (testFixedPoint() != TestPass)\n> +\t\tQ q(input);\n> +\t\tusing T = typename Q::QuantizedType;\n> +\n> +\t\tcerr << \"  Checking \" << input << \" == \" << q.toString() << std::endl;\n> +\n> +\t\tT quantized = q.quantized();\n> +\t\tif (quantized != expected) {\n> +\t\t\tcerr << \"    ** Q Expected \" << input\n> +\t\t\t     << \" to quantize to \" << utils::hex(expected)\n> +\t\t\t     << \", got \" << utils::hex(quantized)\n> +\t\t\t     << \" - (\" << q.toString() << \")\"\n> +\t\t\t     << std::endl;\n> +\t\t\treturn 1;\n> +\t\t}\n> +\n> +\t\tif ((std::abs(q.value() - value)) > 0.0001f) {\n> +\t\t\tcerr << \"    ** V Expected \" << input\n> +\t\t\t     << \" to quantize to \" << value\n> +\t\t\t     << \", got \" << q.value()\n> +\t\t\t     << \" - (\" << q.toString() << \")\"\n> +\t\t\t     << std::endl;\n> +\t\t\treturn 1;\n> +\t\t}\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\ttemplate<typename Q>\n> +\tint introduce(std::string type)\n\nI'd use `const char *` or `std::string_view`.\n\n\n> +\t{\n> +\t\tusing T = typename Q::QuantizedType;\n> +\n> +\t\tstd::cerr << std::endl;\n> +\n> +\t\tcerr << type << \"(\" << Q::TraitsType::min << \" .. \" << Q::TraitsType::max << \") \"\n> +\t\t     << \" Min: \" << Q(Q::TraitsType::min).toString()\n> +\t\t     << \" -- Max: \" << Q(Q::TraitsType::max).toString()\n> +\t\t     << \" Step:\" << Q(T(1)).value()\n> +\t\t     << std::endl;\n> +\n> +\t\tif (Q::TraitsType::min > Q::TraitsType::max) {\n> +\t\t\tcerr << \"    *** \" << type\n> +\t\t\t     << \" Min (\" << Q::TraitsType::min\n> +\t\t\t     << \") must be less than max (\"\n> +\t\t\t     << Q::TraitsType::max << \")\" << std::endl;\n> +\t\t\treturn 1;\n\nIs the return value checked anywhere? I think this check is something that\ncould belong to a static_assert somewhere, possibly in `Quantized`.\n\n\n> +\t\t}\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tint testFixedPointQuantizers()\n> +\t{\n> +\t\tunsigned int fails = 0;\n> +\n> +\t\t/* clang-format off */\n> +\n> +\t\t/* Q1_7(-1 .. 0.992188)  Min: [0x80:-1] -- Max: [0x7f:0.992188] Step:0.0078125*/\n> +\t\tfails += introduce<Q1_7>(\"Q1_7\");\n> +\t\tfails += quantizedCheck<Q1_7>(-1.000f, 0b1'0000000, -1.0f);\t\t/* Min */\n> +\t\tfails += quantizedCheck<Q1_7>(-0.992f, 0b1'0000001, -0.992188f);\t/* Min + 1 step */\n> +\t\tfails += quantizedCheck<Q1_7>(-0.006f, 0b1'1111111, -0.0078125f);\t/* -1 step */\n> +\t\tfails += quantizedCheck<Q1_7>( 0.000f, 0b0'0000000,  0.0f);\t\t/* Zero */\n> +\t\tfails += quantizedCheck<Q1_7>( 0.008f, 0b0'0000001,  0.0078125f);\t/* +1 step */\n> +\t\tfails += quantizedCheck<Q1_7>( 0.992f, 0b0'1111111,  0.992188f);\t/* Max */\n> +\n> +\t\t/* UQ1_7(0 .. 1.99219)  Min: [0x00:0] -- Max: [0xff:1.99219] Step:0.0078125 */\n> +\t\tfails += introduce<UQ1_7>(\"UQ1_7\");\n> +\t\tfails += quantizedCheck<UQ1_7>(0.0f,   0b0'0000000, 0.0f);\t\t/* Min / Zero */\n> +\t\tfails += quantizedCheck<UQ1_7>(1.0f,   0b1'0000000, 1.0f);\t\t/* Mid */\n> +\t\tfails += quantizedCheck<UQ1_7>(1.992f, 0b1'1111111, 1.99219f);\t\t/* Max */\n> +\n> +\t\t/* Q12.4(-2048 .. 2047.94)  Min: [0x8000:-2048] -- Max: [0x7fff:2047.94] Step:0.0625 */\n> +\t\tintroduce<Q12_4>(\"Q12_4\");\n> +\t\tfails += quantizedCheck<Q12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> +\t\tfails += quantizedCheck<Q12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> +\n> +\t\t/* UQ12_4(0 .. 4095.94)  Min: [0x0000:0] -- Max: [0xffff:4095.94] Step:0.0625 */\n> +\t\tintroduce<UQ12_4>(\"UQ12_4\");\n> +\t\tfails += quantizedCheck<UQ12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> +\t\tfails += quantizedCheck<UQ12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> +\n> +\t\t/* Validate that exceeding limits clamps to type range */\n> +\t\tcerr << std::endl << \"Range validation:\" << std::endl;\n> +\t\tfails += quantizedCheck<Q1_7>(-100.0f, 0b1'0000000, -1.0f);\n> +\t\tfails += quantizedCheck<Q1_7>(+100.0f, 0b0'1111111, 0.992188f);\n> +\t\tfails += quantizedCheck<UQ1_7>(-100.0f, 0b0'0000000, 0.0f);\n> +\t\tfails += quantizedCheck<UQ1_7>(+100.0f, 0b1'1111111, 1.99219f);\n> +\n> +\t\t/* clang-format on */\n> +\n> +\t\tstd::cerr << std::endl;\n> +\n> +\t\tif (fails > 0) {\n> +\t\t\tcerr << \"Fixed point quantizer tests failed: \"\n> +\t\t\t     << std::dec << fails << \" failures.\" << std::endl;\n>   \t\t\treturn TestFail;\n> +\t\t}\n>   \n>   \t\treturn TestPass;\n>   \t}\n> +\n> +\tint run()\n> +\t{\n> +\t\tunsigned int fails = 0;\n> +\n> +\t\t/* fixed point conversion test */\n> +\t\tif (testFixedPoint() != TestPass)\n> +\t\t\tfails++;\n> +\n> +\t\tif (testFixedPointQuantizers() != TestPass)\n> +\t\t\tfails++;\n> +\n> +\t\treturn fails ? TestFail : TestPass;\n> +\t}\n>   };\n>   \n>   TEST_REGISTER(FixedPointUtilsTest)","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 20B4BC32DB\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 14 Nov 2025 18:08:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C12A260AA4;\n\tFri, 14 Nov 2025 19:08:15 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C614609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Nov 2025 19:08:14 +0100 (CET)","from [192.168.33.35] (185.221.143.100.nat.pool.zt.hu\n\t[185.221.143.100])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4D7421198;\n\tFri, 14 Nov 2025 19:06:13 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"OobXNEyz\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763143573;\n\tbh=mNWa9x5ZSwiYcJADpt4doCN3U13KH6M6lUhhQk5KVZ0=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=OobXNEyzx+YOh4MLkZLXRBg7M4N2PU7VK5KQxbx1OXUP/ABf/OIo82xyS6W1uOPNM\n\tjSwHArUAdIy7W2zxhJ826VmOUqmuB2u17/n7ahRIqe0RoRj5YPeoRUrMWSP1WgLfQE\n\trXB845NYT7XJmIQAd6cDEGQoCIrahxxrn8YG34m0=","Message-ID":"<53024f26-af47-4eb4-88f3-e4bccc8fdcf7@ideasonboard.com>","Date":"Fri, 14 Nov 2025 19:08:13 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-5-kieran.bingham@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20251114005428.90024-5-kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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":36870,"web_url":"https://patchwork.libcamera.org/comment/36870/","msgid":"<176346947956.880260.2482814302827015789@isaac-ThinkPad-T16-Gen-2>","date":"2025-11-18T12:37:59","subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","submitter":{"id":215,"url":"https://patchwork.libcamera.org/api/people/215/","name":"Isaac Scott","email":"isaac.scott@ideasonboard.com"},"content":"Hi Kieran,\n\nThank you for the patch!\n\nReviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>\n\nQuoting Kieran Bingham (2025-11-14 00:54:08)\n> Validate the new fixed-point Quantized types with tests covering Q1.7,\n> UQ1.7, Q12.4 and UQ12.4 types.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> ---\n> v3:\n> - Rename quantized_type to QuantizedType\n> \n>  test/ipa/libipa/fixedpoint.cpp | 120 +++++++++++++++++++++++++++++++--\n>  1 file changed, 116 insertions(+), 4 deletions(-)\n> \n> diff --git a/test/ipa/libipa/fixedpoint.cpp b/test/ipa/libipa/fixedpoint.cpp\n> index 99eb662ddf4e..935412771851 100644\n> --- a/test/ipa/libipa/fixedpoint.cpp\n> +++ b/test/ipa/libipa/fixedpoint.cpp\n> @@ -5,12 +5,14 @@\n>   * Fixed / Floating point utility tests\n>   */\n>  \n> +#include \"../src/ipa/libipa/fixedpoint.h\"\n> +\n>  #include <cmath>\n>  #include <iostream>\n>  #include <map>\n>  #include <stdint.h>\n>  \n> -#include \"../src/ipa/libipa/fixedpoint.h\"\n> +#include <libcamera/base/utils.h>\n>  \n>  #include \"test.h\"\n>  \n> @@ -95,14 +97,124 @@ protected:\n>                 return TestPass;\n>         }\n>  \n> -       int run()\n> +       template<typename Q>\n> +       int quantizedCheck(float input, typename Q::QuantizedType expected, float value)\n>         {\n> -               /* fixed point conversion test */\n> -               if (testFixedPoint() != TestPass)\n> +               Q q(input);\n> +               using T = typename Q::QuantizedType;\n> +\n> +               cerr << \"  Checking \" << input << \" == \" << q.toString() << std::endl;\n> +\n> +               T quantized = q.quantized();\n> +               if (quantized != expected) {\n> +                       cerr << \"    ** Q Expected \" << input\n> +                            << \" to quantize to \" << utils::hex(expected)\n> +                            << \", got \" << utils::hex(quantized)\n> +                            << \" - (\" << q.toString() << \")\"\n> +                            << std::endl;\n> +                       return 1;\n> +               }\n> +\n> +               if ((std::abs(q.value() - value)) > 0.0001f) {\n> +                       cerr << \"    ** V Expected \" << input\n> +                            << \" to quantize to \" << value\n> +                            << \", got \" << q.value()\n> +                            << \" - (\" << q.toString() << \")\"\n> +                            << std::endl;\n> +                       return 1;\n> +               }\n> +\n> +               return 0;\n> +       }\n> +\n> +       template<typename Q>\n> +       int introduce(std::string type)\n> +       {\n> +               using T = typename Q::QuantizedType;\n> +\n> +               std::cerr << std::endl;\n> +\n> +               cerr << type << \"(\" << Q::TraitsType::min << \" .. \" << Q::TraitsType::max << \") \"\n> +                    << \" Min: \" << Q(Q::TraitsType::min).toString()\n> +                    << \" -- Max: \" << Q(Q::TraitsType::max).toString()\n> +                    << \" Step:\" << Q(T(1)).value()\n> +                    << std::endl;\n> +\n> +               if (Q::TraitsType::min > Q::TraitsType::max) {\n> +                       cerr << \"    *** \" << type\n> +                            << \" Min (\" << Q::TraitsType::min\n> +                            << \") must be less than max (\"\n> +                            << Q::TraitsType::max << \")\" << std::endl;\n> +                       return 1;\n> +               }\n> +\n> +               return 0;\n> +       }\n> +\n> +       int testFixedPointQuantizers()\n> +       {\n> +               unsigned int fails = 0;\n> +\n> +               /* clang-format off */\n> +\n> +               /* Q1_7(-1 .. 0.992188)  Min: [0x80:-1] -- Max: [0x7f:0.992188] Step:0.0078125*/\n> +               fails += introduce<Q1_7>(\"Q1_7\");\n> +               fails += quantizedCheck<Q1_7>(-1.000f, 0b1'0000000, -1.0f);             /* Min */\n> +               fails += quantizedCheck<Q1_7>(-0.992f, 0b1'0000001, -0.992188f);        /* Min + 1 step */\n> +               fails += quantizedCheck<Q1_7>(-0.006f, 0b1'1111111, -0.0078125f);       /* -1 step */\n> +               fails += quantizedCheck<Q1_7>( 0.000f, 0b0'0000000,  0.0f);             /* Zero */\n> +               fails += quantizedCheck<Q1_7>( 0.008f, 0b0'0000001,  0.0078125f);       /* +1 step */\n> +               fails += quantizedCheck<Q1_7>( 0.992f, 0b0'1111111,  0.992188f);        /* Max */\n> +\n> +               /* UQ1_7(0 .. 1.99219)  Min: [0x00:0] -- Max: [0xff:1.99219] Step:0.0078125 */\n> +               fails += introduce<UQ1_7>(\"UQ1_7\");\n> +               fails += quantizedCheck<UQ1_7>(0.0f,   0b0'0000000, 0.0f);              /* Min / Zero */\n> +               fails += quantizedCheck<UQ1_7>(1.0f,   0b1'0000000, 1.0f);              /* Mid */\n> +               fails += quantizedCheck<UQ1_7>(1.992f, 0b1'1111111, 1.99219f);          /* Max */\n> +\n> +               /* Q12.4(-2048 .. 2047.94)  Min: [0x8000:-2048] -- Max: [0x7fff:2047.94] Step:0.0625 */\n> +               introduce<Q12_4>(\"Q12_4\");\n> +               fails += quantizedCheck<Q12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> +               fails += quantizedCheck<Q12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> +\n> +               /* UQ12_4(0 .. 4095.94)  Min: [0x0000:0] -- Max: [0xffff:4095.94] Step:0.0625 */\n> +               introduce<UQ12_4>(\"UQ12_4\");\n> +               fails += quantizedCheck<UQ12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> +               fails += quantizedCheck<UQ12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> +\n> +               /* Validate that exceeding limits clamps to type range */\n> +               cerr << std::endl << \"Range validation:\" << std::endl;\n> +               fails += quantizedCheck<Q1_7>(-100.0f, 0b1'0000000, -1.0f);\n> +               fails += quantizedCheck<Q1_7>(+100.0f, 0b0'1111111, 0.992188f);\n> +               fails += quantizedCheck<UQ1_7>(-100.0f, 0b0'0000000, 0.0f);\n> +               fails += quantizedCheck<UQ1_7>(+100.0f, 0b1'1111111, 1.99219f);\n> +\n> +               /* clang-format on */\n> +\n> +               std::cerr << std::endl;\n> +\n> +               if (fails > 0) {\n> +                       cerr << \"Fixed point quantizer tests failed: \"\n> +                            << std::dec << fails << \" failures.\" << std::endl;\n>                         return TestFail;\n> +               }\n>  \n>                 return TestPass;\n>         }\n> +\n> +       int run()\n> +       {\n> +               unsigned int fails = 0;\n> +\n> +               /* fixed point conversion test */\n> +               if (testFixedPoint() != TestPass)\n> +                       fails++;\n> +\n> +               if (testFixedPointQuantizers() != TestPass)\n> +                       fails++;\n> +\n> +               return fails ? TestFail : TestPass;\n> +       }\n>  };\n>  \n>  TEST_REGISTER(FixedPointUtilsTest)\n> -- \n> 2.51.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 97271BD80A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Nov 2025 12:38:05 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4C99460AA0;\n\tTue, 18 Nov 2025 13:38:05 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 15F99606D5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Nov 2025 13:38:03 +0100 (CET)","from thinkpad.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 509E9D52;\n\tTue, 18 Nov 2025 13:35:59 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Dl/sZV3k\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763469359;\n\tbh=FUz3zXM4R5u+XwGp8zg3+ttrg/LdpE+D00xQSEJ33S0=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=Dl/sZV3kGvCgVw9Tii96ZSLK4avFHHQWkd3gQbnIfY7AoEq8aGS6VOkOiFCBYbGpQ\n\tEMxEcFBDy1Ln0T1jt2qoUFBSvnQsKnICNX7N2WXQma4bVPgjhMpJDy8zbZrlyyQLtV\n\trO+Tfc7IGZ2QlAQSBRTss1MUzcjESQHnauPeHWmc=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251114005428.90024-5-kieran.bingham@ideasonboard.com>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-5-kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","From":"Isaac Scott <isaac.scott@ideasonboard.com>","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Tue, 18 Nov 2025 12:37:59 +0000","Message-ID":"<176346947956.880260.2482814302827015789@isaac-ThinkPad-T16-Gen-2>","User-Agent":"alot/0.10","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":36890,"web_url":"https://patchwork.libcamera.org/comment/36890/","msgid":"<176350911226.3013501.14573621690538635379@ping.linuxembedded.co.uk>","date":"2025-11-18T23:38:32","subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2025-11-14 18:08:13)\n> 2025. 11. 14. 1:54 keltezéssel, Kieran Bingham írta:\n> > Validate the new fixed-point Quantized types with tests covering Q1.7,\n> > UQ1.7, Q12.4 and UQ12.4 types.\n> > \n> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > \n> > ---\n> > v3:\n> > - Rename quantized_type to QuantizedType\n> > \n> >   test/ipa/libipa/fixedpoint.cpp | 120 +++++++++++++++++++++++++++++++--\n> >   1 file changed, 116 insertions(+), 4 deletions(-)\n> > \n> > diff --git a/test/ipa/libipa/fixedpoint.cpp b/test/ipa/libipa/fixedpoint.cpp\n> > index 99eb662ddf4e..935412771851 100644\n> > --- a/test/ipa/libipa/fixedpoint.cpp\n> > +++ b/test/ipa/libipa/fixedpoint.cpp\n> > @@ -5,12 +5,14 @@\n> >    * Fixed / Floating point utility tests\n> >    */\n> >   \n> > +#include \"../src/ipa/libipa/fixedpoint.h\"\n> > +\n> >   #include <cmath>\n> >   #include <iostream>\n> >   #include <map>\n> >   #include <stdint.h>\n> >   \n> > -#include \"../src/ipa/libipa/fixedpoint.h\"\n> > +#include <libcamera/base/utils.h>\n> >   \n> >   #include \"test.h\"\n> >   \n> > @@ -95,14 +97,124 @@ protected:\n> >               return TestPass;\n> >       }\n> >   \n> > -     int run()\n> > +     template<typename Q>\n> > +     int quantizedCheck(float input, typename Q::QuantizedType expected, float value)\n> >       {\n> > -             /* fixed point conversion test */\n> > -             if (testFixedPoint() != TestPass)\n> > +             Q q(input);\n> > +             using T = typename Q::QuantizedType;\n> > +\n> > +             cerr << \"  Checking \" << input << \" == \" << q.toString() << std::endl;\n> > +\n> > +             T quantized = q.quantized();\n> > +             if (quantized != expected) {\n> > +                     cerr << \"    ** Q Expected \" << input\n> > +                          << \" to quantize to \" << utils::hex(expected)\n> > +                          << \", got \" << utils::hex(quantized)\n> > +                          << \" - (\" << q.toString() << \")\"\n> > +                          << std::endl;\n> > +                     return 1;\n> > +             }\n> > +\n> > +             if ((std::abs(q.value() - value)) > 0.0001f) {\n> > +                     cerr << \"    ** V Expected \" << input\n> > +                          << \" to quantize to \" << value\n> > +                          << \", got \" << q.value()\n> > +                          << \" - (\" << q.toString() << \")\"\n> > +                          << std::endl;\n> > +                     return 1;\n> > +             }\n> > +\n> > +             return 0;\n> > +     }\n> > +\n> > +     template<typename Q>\n> > +     int introduce(std::string type)\n> \n> I'd use `const char *` or `std::string_view`.\n> \n\nAck,\n\n> > +     {\n> > +             using T = typename Q::QuantizedType;\n> > +\n> > +             std::cerr << std::endl;\n> > +\n> > +             cerr << type << \"(\" << Q::TraitsType::min << \" .. \" << Q::TraitsType::max << \") \"\n> > +                  << \" Min: \" << Q(Q::TraitsType::min).toString()\n> > +                  << \" -- Max: \" << Q(Q::TraitsType::max).toString()\n> > +                  << \" Step:\" << Q(T(1)).value()\n> > +                  << std::endl;\n> > +\n> > +             if (Q::TraitsType::min > Q::TraitsType::max) {\n> > +                     cerr << \"    *** \" << type\n> > +                          << \" Min (\" << Q::TraitsType::min\n> > +                          << \") must be less than max (\"\n> > +                          << Q::TraitsType::max << \")\" << std::endl;\n> > +                     return 1;\n> \n> Is the return value checked anywhere? I think this check is something that\n> could belong to a static_assert somewhere, possibly in `Quantized`.\n\nI think this caught issues when I was developing and got the\nsigned/unsigned types wrong - but I don't expect it to come up again now\nit's all sorted. A static assert is reasonable though.\n\n> \n> > +             }\n> > +\n> > +             return 0;\n> > +     }\n> > +\n> > +     int testFixedPointQuantizers()\n> > +     {\n> > +             unsigned int fails = 0;\n> > +\n> > +             /* clang-format off */\n> > +\n> > +             /* Q1_7(-1 .. 0.992188)  Min: [0x80:-1] -- Max: [0x7f:0.992188] Step:0.0078125*/\n> > +             fails += introduce<Q1_7>(\"Q1_7\");\n\nLike here I think - but I'll make introduce return void.\n\n> > +             fails += quantizedCheck<Q1_7>(-1.000f, 0b1'0000000, -1.0f);             /* Min */\n> > +             fails += quantizedCheck<Q1_7>(-0.992f, 0b1'0000001, -0.992188f);        /* Min + 1 step */\n> > +             fails += quantizedCheck<Q1_7>(-0.006f, 0b1'1111111, -0.0078125f);       /* -1 step */\n> > +             fails += quantizedCheck<Q1_7>( 0.000f, 0b0'0000000,  0.0f);             /* Zero */\n> > +             fails += quantizedCheck<Q1_7>( 0.008f, 0b0'0000001,  0.0078125f);       /* +1 step */\n> > +             fails += quantizedCheck<Q1_7>( 0.992f, 0b0'1111111,  0.992188f);        /* Max */\n> > +\n> > +             /* UQ1_7(0 .. 1.99219)  Min: [0x00:0] -- Max: [0xff:1.99219] Step:0.0078125 */\n> > +             fails += introduce<UQ1_7>(\"UQ1_7\");\n> > +             fails += quantizedCheck<UQ1_7>(0.0f,   0b0'0000000, 0.0f);              /* Min / Zero */\n> > +             fails += quantizedCheck<UQ1_7>(1.0f,   0b1'0000000, 1.0f);              /* Mid */\n> > +             fails += quantizedCheck<UQ1_7>(1.992f, 0b1'1111111, 1.99219f);          /* Max */\n> > +\n> > +             /* Q12.4(-2048 .. 2047.94)  Min: [0x8000:-2048] -- Max: [0x7fff:2047.94] Step:0.0625 */\n> > +             introduce<Q12_4>(\"Q12_4\");\n> > +             fails += quantizedCheck<Q12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> > +             fails += quantizedCheck<Q12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> > +\n> > +             /* UQ12_4(0 .. 4095.94)  Min: [0x0000:0] -- Max: [0xffff:4095.94] Step:0.0625 */\n> > +             introduce<UQ12_4>(\"UQ12_4\");\n> > +             fails += quantizedCheck<UQ12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> > +             fails += quantizedCheck<UQ12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> > +\n> > +             /* Validate that exceeding limits clamps to type range */\n> > +             cerr << std::endl << \"Range validation:\" << std::endl;\n> > +             fails += quantizedCheck<Q1_7>(-100.0f, 0b1'0000000, -1.0f);\n> > +             fails += quantizedCheck<Q1_7>(+100.0f, 0b0'1111111, 0.992188f);\n> > +             fails += quantizedCheck<UQ1_7>(-100.0f, 0b0'0000000, 0.0f);\n> > +             fails += quantizedCheck<UQ1_7>(+100.0f, 0b1'1111111, 1.99219f);\n> > +\n> > +             /* clang-format on */\n> > +\n> > +             std::cerr << std::endl;\n> > +\n> > +             if (fails > 0) {\n> > +                     cerr << \"Fixed point quantizer tests failed: \"\n> > +                          << std::dec << fails << \" failures.\" << std::endl;\n> >                       return TestFail;\n> > +             }\n> >   \n> >               return TestPass;\n> >       }\n> > +\n> > +     int run()\n> > +     {\n> > +             unsigned int fails = 0;\n> > +\n> > +             /* fixed point conversion test */\n> > +             if (testFixedPoint() != TestPass)\n> > +                     fails++;\n> > +\n> > +             if (testFixedPointQuantizers() != TestPass)\n> > +                     fails++;\n> > +\n> > +             return fails ? TestFail : TestPass;\n> > +     }\n> >   };\n> >   \n> >   TEST_REGISTER(FixedPointUtilsTest)\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 5F50DC0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Nov 2025 23:38:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 744F260A80;\n\tWed, 19 Nov 2025 00:38:36 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7ADE360856\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 19 Nov 2025 00:38:35 +0100 (CET)","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 20AB6BCA;\n\tWed, 19 Nov 2025 00:36:31 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"V8Mj1c2z\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763508991;\n\tbh=oJh68Lvg3d9M8z6GqyVOVStDhhwV5EK/Ui/RBeACT+4=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=V8Mj1c2zNsiL8PBUMh21OcXhmISKgKpvlUmbtI9Ue39hMbJx8F8zmXJMV+V4kYhnl\n\t206y++AUhK4t0p6KTCz5I0CCT4KxHsXoVb9T0JA33PB+zqeq74HwsuZmVvlkGsrKdf\n\t0oKWlipl4EM+uup2S8ZUV6YGMPJEuX8pZNi5wjUI=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<53024f26-af47-4eb4-88f3-e4bccc8fdcf7@ideasonboard.com>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-5-kieran.bingham@ideasonboard.com>\n\t<53024f26-af47-4eb4-88f3-e4bccc8fdcf7@ideasonboard.com>","Subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Tue, 18 Nov 2025 23:38:32 +0000","Message-ID":"<176350911226.3013501.14573621690538635379@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":36906,"web_url":"https://patchwork.libcamera.org/comment/36906/","msgid":"<20251119043120.GF17526@pendragon.ideasonboard.com>","date":"2025-11-19T04:31:20","subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Nov 14, 2025 at 12:54:08AM +0000, Kieran Bingham wrote:\n> Validate the new fixed-point Quantized types with tests covering Q1.7,\n> UQ1.7, Q12.4 and UQ12.4 types.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> ---\n> v3:\n> - Rename quantized_type to QuantizedType\n> \n>  test/ipa/libipa/fixedpoint.cpp | 120 +++++++++++++++++++++++++++++++--\n>  1 file changed, 116 insertions(+), 4 deletions(-)\n> \n> diff --git a/test/ipa/libipa/fixedpoint.cpp b/test/ipa/libipa/fixedpoint.cpp\n> index 99eb662ddf4e..935412771851 100644\n> --- a/test/ipa/libipa/fixedpoint.cpp\n> +++ b/test/ipa/libipa/fixedpoint.cpp\n> @@ -5,12 +5,14 @@\n>   * Fixed / Floating point utility tests\n>   */\n>  \n> +#include \"../src/ipa/libipa/fixedpoint.h\"\n> +\n>  #include <cmath>\n>  #include <iostream>\n>  #include <map>\n>  #include <stdint.h>\n>  \n> -#include \"../src/ipa/libipa/fixedpoint.h\"\n> +#include <libcamera/base/utils.h>\n>  \n>  #include \"test.h\"\n>  \n> @@ -95,14 +97,124 @@ protected:\n>  \t\treturn TestPass;\n>  \t}\n>  \n> -\tint run()\n> +\ttemplate<typename Q>\n> +\tint quantizedCheck(float input, typename Q::QuantizedType expected, float value)\n>  \t{\n> -\t\t/* fixed point conversion test */\n> -\t\tif (testFixedPoint() != TestPass)\n> +\t\tQ q(input);\n> +\t\tusing T = typename Q::QuantizedType;\n> +\n> +\t\tcerr << \"  Checking \" << input << \" == \" << q.toString() << std::endl;\n\nYou mix qualified and unqualified cout/cerr through the file. Let's\nqualify them all.\n\n> +\n> +\t\tT quantized = q.quantized();\n> +\t\tif (quantized != expected) {\n> +\t\t\tcerr << \"    ** Q Expected \" << input\n> +\t\t\t     << \" to quantize to \" << utils::hex(expected)\n> +\t\t\t     << \", got \" << utils::hex(quantized)\n> +\t\t\t     << \" - (\" << q.toString() << \")\"\n> +\t\t\t     << std::endl;\n> +\t\t\treturn 1;\n> +\t\t}\n> +\n> +\t\tif ((std::abs(q.value() - value)) > 0.0001f) {\n> +\t\t\tcerr << \"    ** V Expected \" << input\n> +\t\t\t     << \" to quantize to \" << value\n> +\t\t\t     << \", got \" << q.value()\n> +\t\t\t     << \" - (\" << q.toString() << \")\"\n> +\t\t\t     << std::endl;\n> +\t\t\treturn 1;\n> +\t\t}\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\ttemplate<typename Q>\n> +\tint introduce(std::string type)\n> +\t{\n> +\t\tusing T = typename Q::QuantizedType;\n> +\n> +\t\tstd::cerr << std::endl;\n> +\n> +\t\tcerr << type << \"(\" << Q::TraitsType::min << \" .. \" << Q::TraitsType::max << \") \"\n> +\t\t     << \" Min: \" << Q(Q::TraitsType::min).toString()\n> +\t\t     << \" -- Max: \" << Q(Q::TraitsType::max).toString()\n> +\t\t     << \" Step:\" << Q(T(1)).value()\n> +\t\t     << std::endl;\n\nThis seems more suitable for std::cout than cerr.\n\n> +\n> +\t\tif (Q::TraitsType::min > Q::TraitsType::max) {\n> +\t\t\tcerr << \"    *** \" << type\n> +\t\t\t     << \" Min (\" << Q::TraitsType::min\n> +\t\t\t     << \") must be less than max (\"\n> +\t\t\t     << Q::TraitsType::max << \")\" << std::endl;\n> +\t\t\treturn 1;\n> +\t\t}\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tint testFixedPointQuantizers()\n> +\t{\n> +\t\tunsigned int fails = 0;\n> +\n> +\t\t/* clang-format off */\n> +\n> +\t\t/* Q1_7(-1 .. 0.992188)  Min: [0x80:-1] -- Max: [0x7f:0.992188] Step:0.0078125*/\n> +\t\tfails += introduce<Q1_7>(\"Q1_7\");\n> +\t\tfails += quantizedCheck<Q1_7>(-1.000f, 0b1'0000000, -1.0f);\t\t/* Min */\n> +\t\tfails += quantizedCheck<Q1_7>(-0.992f, 0b1'0000001, -0.992188f);\t/* Min + 1 step */\n> +\t\tfails += quantizedCheck<Q1_7>(-0.006f, 0b1'1111111, -0.0078125f);\t/* -1 step */\n> +\t\tfails += quantizedCheck<Q1_7>( 0.000f, 0b0'0000000,  0.0f);\t\t/* Zero */\n> +\t\tfails += quantizedCheck<Q1_7>( 0.008f, 0b0'0000001,  0.0078125f);\t/* +1 step */\n> +\t\tfails += quantizedCheck<Q1_7>( 0.992f, 0b0'1111111,  0.992188f);\t/* Max */\n> +\n> +\t\t/* UQ1_7(0 .. 1.99219)  Min: [0x00:0] -- Max: [0xff:1.99219] Step:0.0078125 */\n> +\t\tfails += introduce<UQ1_7>(\"UQ1_7\");\n> +\t\tfails += quantizedCheck<UQ1_7>(0.0f,   0b0'0000000, 0.0f);\t\t/* Min / Zero */\n> +\t\tfails += quantizedCheck<UQ1_7>(1.0f,   0b1'0000000, 1.0f);\t\t/* Mid */\n> +\t\tfails += quantizedCheck<UQ1_7>(1.992f, 0b1'1111111, 1.99219f);\t\t/* Max */\n> +\n> +\t\t/* Q12.4(-2048 .. 2047.94)  Min: [0x8000:-2048] -- Max: [0x7fff:2047.94] Step:0.0625 */\n> +\t\tintroduce<Q12_4>(\"Q12_4\");\n> +\t\tfails += quantizedCheck<Q12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> +\t\tfails += quantizedCheck<Q12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> +\n> +\t\t/* UQ12_4(0 .. 4095.94)  Min: [0x0000:0] -- Max: [0xffff:4095.94] Step:0.0625 */\n> +\t\tintroduce<UQ12_4>(\"UQ12_4\");\n> +\t\tfails += quantizedCheck<UQ12_4>(0.0f, 0b000000000000'0000, 0.0f);\n> +\t\tfails += quantizedCheck<UQ12_4>(7.5f, 0b000000000111'1000, 7.5f);\n> +\n> +\t\t/* Validate that exceeding limits clamps to type range */\n> +\t\tcerr << std::endl << \"Range validation:\" << std::endl;\n> +\t\tfails += quantizedCheck<Q1_7>(-100.0f, 0b1'0000000, -1.0f);\n> +\t\tfails += quantizedCheck<Q1_7>(+100.0f, 0b0'1111111, 0.992188f);\n> +\t\tfails += quantizedCheck<UQ1_7>(-100.0f, 0b0'0000000, 0.0f);\n> +\t\tfails += quantizedCheck<UQ1_7>(+100.0f, 0b1'1111111, 1.99219f);\n> +\n> +\t\t/* clang-format on */\n> +\n> +\t\tstd::cerr << std::endl;\n\nstd::cout here too.\n\n> +\n> +\t\tif (fails > 0) {\n> +\t\t\tcerr << \"Fixed point quantizer tests failed: \"\n> +\t\t\t     << std::dec << fails << \" failures.\" << std::endl;\n>  \t\t\treturn TestFail;\n> +\t\t}\n>  \n>  \t\treturn TestPass;\n>  \t}\n> +\n> +\tint run()\n> +\t{\n> +\t\tunsigned int fails = 0;\n> +\n> +\t\t/* fixed point conversion test */\n> +\t\tif (testFixedPoint() != TestPass)\n> +\t\t\tfails++;\n> +\n> +\t\tif (testFixedPointQuantizers() != TestPass)\n> +\t\t\tfails++;\n> +\n> +\t\treturn fails ? TestFail : TestPass;\n> +\t}\n>  };\n>  \n>  TEST_REGISTER(FixedPointUtilsTest)","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 48D29C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 19 Nov 2025 04:31:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E938D60AA1;\n\tWed, 19 Nov 2025 05:31:56 +0100 (CET)","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 6DC3960A7B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 19 Nov 2025 05:31:55 +0100 (CET)","from pendragon.ideasonboard.com (unknown [205.220.129.225])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id B206B14B0; \n\tWed, 19 Nov 2025 05:29:46 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"LOM6EZA6\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763526591;\n\tbh=VtnZxiaaURssyqU8I1bhloNwA0kBaLtx80kJZ8UBFsI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=LOM6EZA6KJi8F9j1HfcT798i9tRlSGXdRZfqytiAYmudEhIJO1w6m0SuHX3S0+CZt\n\tU/hFGsuKdkVP5XNZlxJu5QhpmxuMnbBa0RxtZn6lWof6uWt1ROl4XltC6MoqjblFBB\n\t8isBn1Sa7iQUqEfdcpartNR7NkRz2jiS9YGLtEYU=","Date":"Wed, 19 Nov 2025 13:31:20 +0900","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Subject":"Re: [PATCH v4 04/21] test: libipa: Provide FixedPoint Quantized\n\ttests","Message-ID":"<20251119043120.GF17526@pendragon.ideasonboard.com>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-5-kieran.bingham@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20251114005428.90024-5-kieran.bingham@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>"}}]