Closed dalybrown closed 10 months ago
Hi Daly,
This is not a known problem. Typically, the compilation takes only a couple of seconds on a modern workstation, even for code generated from a complex specification. In the past, we have observed that certain compiler flags can negatively affect the compilation time, but the resulting compilation time was always still in the order of minutes, not hours.
Which toolchain are you using? Do you use specific compiler flags? Could you provide a small reproducer, where this issue can be observed?
Thanks for the quick reply. It seemed off to me too - I expect a few seconds to a few minutes to build. I can put together a reproducer and send to you this week.
Here are the compiler flags I am running with at the moment (I use Alire
to manage my projects):
"-Og" -- Optimize for debug
,"-ffunction-sections" -- Separate ELF section for each function
,"-fdata-sections" -- Separate ELF section for each variable
,"-g" -- Generate debug info
,"-gnatwa" -- Enable all warnings
,"-gnatw.X" -- Disable warnings for No_Exception_Propagation
,"-gnatVa" -- All validity checks
,"-gnaty3" -- Specify indentation level of 3
,"-gnatya" -- Check attribute casing
,"-gnatyA" -- Use of array index numbers in array attributes
,"-gnatyB" -- Check Boolean operators
,"-gnatyb" -- Blanks not allowed at statement end
,"-gnatyc" -- Check comments
,"-gnaty-d" -- Disable check no DOS line terminators present
,"-gnatye" -- Check end/exit labels
,"-gnatyf" -- No form feeds or vertical tabs
,"-gnatyh" -- No horizontal tabs
,"-gnatyi" -- Check if-then layout
,"-gnatyI" -- check mode IN keywords
,"-gnatyk" -- Check keyword casing
,"-gnatyl" -- Check layout
,"-gnatym" -- Check maximum line length
,"-gnatyn" -- Check casing of entities in Standard
,"-gnatyO" -- Check that overriding subprograms are explicitly marked as such
,"-gnatyp" -- Check pragma casing
,"-gnatyr" -- Check identifier references casing
,"-gnatyS" -- Check no statements after THEN/ELSE
,"-gnatyt" -- Check token spacing
,"-gnatyu" -- Check unnecessary blank lines
,"-gnatyx" -- Check extra parentheses
,"-gnatX" -- Enable GNAT Extensions
I should mention I'm using a Debian based docker container run on a Mac M1 (so the Debian container is an arm64
architecture, running natively and not using Rosetta). This isn't an issue normally: I have great performance developing in Ada/SPARK with this setup. I should also mention that the issue is also reproduced in our pipeline: we use GitLab internally and even on their beefier amd64
shared runners it was taking 1 hour++ (and burning our CI minutes :( ).
I'm using the following version of gnat
:
GNAT 13.2.0
Copyright (C) 1996-2023, Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I'm using the latest version of RecordFlux
from pypi
: 0.14.0
.
I'll make a reproducer that is a bit simpler than what I have but still demonstrates what is happening.
Here is a very basic example: this reproducer will only take a couple of minutes to build for me, but it shows the issue starting to creep in. Maybe I am not using the generated code properly and that is the issue.
To really expose my issue, I can add in more conditionals on the transitions and more fields in the messages to really highlight it (and make it more similar to the real messages we are trying to model). I'll hold off on that if this reproducer is good enough.
Let me know, thanks!
Thank you for the reproducer. A build time of a couple of minutes is much longer than we have seen with much more complicated specifications. We will investigate and let you know when we know more.
Thanks!
And to be clear: I trimmed this down quite a bit from the real application we are building. The message structure is similar but larger and more complicated and building takes 1 hour++.
The long compilation time is caused by the use of the -gnatX
flag. When the flag is removed, your reproducer builds in less than a second. It is unexpected that -gnatX
has such a severe impact and I have informed the compiler team about the problem. For now, the only workaround I can see is not to use -gnatX
.
Ahhhh thanks! Doh! I should of tried that instead of trying a bunch of other flags.
I should mention the same issue occurs with -gnat2022
, so it's not just the -gnatX
GNAT extensions.
Also, to avoid creating another issue, I've had problems with some more compiler switches:
GNAT style checks fail. I tried to run the generated files through the pretty printer to fix some of them but the GNAT pretty printer crashes. I've raised an issue for that one: https://github.com/AdaCore/libadalang-tools/issues/29. For now, I use sed
to prepend pragma Style_Checks (Off);
to every generated file. I'm using the Alire validation
profile to run these checks.
-gnatwq
causes issues for some of the generated code. For example (from the reproducer): recordflux-build/generated/rflx-variant_two-data.adb:628:52: warning: equality should be parenthesized here [-gnatwq]
.
-gnatw.a
causes issues in the generated code. For example (not from the reproducer but from my own specs): warning: in instantiation at rflx-rflx_message_sequence.ads:54 [-gnatw.a]
and warning: check will fail at run time [-gnatw.a]
. The line it is pointing to is here:
procedure Initialize (Ctx : out Context; Buffer : in out RFLX_Types.Bytes_Ptr) with
Pre =>
(not Ctx'Constrained
and then Buffer /= null
and then Buffer'Length > 0
and then Buffer'Last < RFLX_Types.Index'Last),
Post =>
(Has_Buffer (Ctx)
and Valid (Ctx)
and Buffer = null
and Ctx.Buffer_First = Buffer'First'Old
and Ctx.Buffer_Last = Buffer'Last'Old
and Ctx.First = RFLX_Types.To_First_Bit_Index (Ctx.Buffer_First)
and Ctx.Last = RFLX_Types.To_Last_Bit_Index (Ctx.Buffer_Last)
and Sequence_Last (Ctx) = Ctx.First - 1),
Depends =>
(Ctx => Buffer, Buffer => null);
Cheers!
- GNAT style checks fail. I tried to run the generated files through the pretty printer to fix some of them but the GNAT pretty printer crashes. I've raised an issue for that one: gnatpp crashes when setting -c3 to format commments and comment has no characters libadalang-tools#29. For now, I use
sed
to prependpragma Style_Checks (Off);
to every generated file. I'm using the Alirevalidation
profile to run these checks.
I already have seen some style check warnings in your reproducer. These warnings were caused by the use of -gnatyc
("Check comments, double space.") which enforces a different spacing than -gnatyC
("Check comments, single space.") that we use for our code. We already use pragma Style_Checks
to prevent such issues, but as this pragma is placed after the license header, GNAT still complains about the spacing there. We consider moving the pragma Style_Checks
to the top of the file to prevent this issue. Did you see any other style issues?
-gnatwq
causes issues for some of the generated code. For example (from the reproducer):recordflux-build/generated/rflx-variant_two-data.adb:628:52: warning: equality should be parenthesized here [-gnatwq]
.
I cannot reproduce the issue with RecordFlux 0.15.0. Please check if upgrading RecordFlux solves the issue for you.
-gnatw.a
causes issues in the generated code. For example (not from the reproducer but from my own specs):warning: in instantiation at rflx-rflx_message_sequence.ads:54 [-gnatw.a]
andwarning: check will fail at run time [-gnatw.a]
. The line it is pointing to is here:procedure Initialize (Ctx : out Context; Buffer : in out RFLX_Types.Bytes_Ptr) with Pre => (not Ctx'Constrained and then Buffer /= null and then Buffer'Length > 0 and then Buffer'Last < RFLX_Types.Index'Last), Post => (Has_Buffer (Ctx) and Valid (Ctx) and Buffer = null and Ctx.Buffer_First = Buffer'First'Old and Ctx.Buffer_Last = Buffer'Last'Old and Ctx.First = RFLX_Types.To_First_Bit_Index (Ctx.Buffer_First) and Ctx.Last = RFLX_Types.To_Last_Bit_Index (Ctx.Buffer_Last) and Sequence_Last (Ctx) = Ctx.First - 1), Depends => (Ctx => Buffer, Buffer => null);
I have seen this warning when using -gnatVo
. The only workaround I know is to not enable this switch. The bug does not exist in recent GNAT Pro releases. Only the FSF GNAT 13 seems to be affected, so it could make sense to report the issue to the FSF.
Awesome - thanks for the response! We are using 0.14.0
version of RecordFlux so I'll update today and check again. Cheers!
After updating to 0.15.0
I can confirm that the -gnatwq
has been addressed and the -gnatw.a
seems to have also gone away. (The installation issue I had raised in another issue is also fixed!).
Thanks for everything!
You are welcome! I'm glad to hear that most of your issues have been resolved in the new version. We will probably also fix the style check problem soon.
The style check warnings for the license header have been fixed in fbecae098ca0213bdc886c249ac99a3905e13e4b.
The long compilation time is caused by the use of the
-gnatX
flag. When the flag is removed, your reproducer builds in less than a second. It is unexpected that-gnatX
has such a severe impact and I have informed the compiler team about the problem. For now, the only workaround I can see is not to use-gnatX
.
Has any progress been made here? It's not just -gnatX
: it's any Ada2022 flag. I don't have a good workaround at the moment for code written to use Ada2022 to also make use of RecordFlux ... I just can't build it at all. Thanks!
The fix is currently in progress. Unfortunately, it appears to be a difficult problem and it is not yet clear how long it will take to complete.
As a workaround you could try to set the -gnatX
or -gnat2022
flag on a per-file basis in the project file, but this will only help for files that don't use RecordFlux directly.
The fix is currently in progress. Unfortunately, it appears to be a difficult problem and it is not yet clear how long it will take to complete.
As a workaround you could try to set the
-gnatX
or-gnat2022
flag on a per-file basis in the project file, but this will only help for files that don't use RecordFlux directly.
Thanks for the response! And glad to hear it is in progress :). I'll try your suggestion, I wasn't sure how to mix and match the two to be honest. The combinations I had tried so far weren't working as I expected. I'll try out your suggestion! The alternative which I think will work is to build my RecordFlux project as a separate library and link it.
So adding pragma Ada_2012
to all the generated code solves the problem! I think that would be a good thing to include automatically as part of the rflx generate
command so that others don't run into the issue. It is true either way that the code doesn't compile with Ada2022+ so probably a nice informative thing to put for now!
So adding
pragma Ada_2012
to all the generated code solves the problem! I think that would be a good thing to include automatically as part of therflx generate
command so that others don't run into the issue. It is true either way that the code doesn't compile with Ada2022+ so probably a nice informative thing to put for now!
Great to hear and thanks for reporting back! Adding that pragma to the generated code should be easy to do. I created an internal ticket for that.
@dalybrown This is to let you know that pragma Ada_2012
is now automatically added to all generated files. That change is on main
and will be part of the next public release.
Awesome - thanks!
Hello,
This is more of a question than an issue. My build times are extremely long for anything besides a trivial RecordFlux specification. Often times, I run out of memory. I've tried removing parallel compilation to (presumably) consume less memory but it takes forever (hour++) for just a trivial (in my opinion) example.
The specification I'm trying to model has a general format for messages, and then I use type refinement based on some fields in the common part. After implementing the specification for one of the refinements, and just a placeholder for a second, the build times seem to increase exponentially. I should mention that there are many conditional fields and so the transition logic between each field has many guard conditions.
Is this expected? Should we be using a (extremely) beefy server to build anything that uses RecordFlux generated code? Are we using the wrong tool here? Maybe this is documented somewhere some of these limitations but I can't find them.