-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace the PARSE_ARGUMENTS() macro with the new CMake built-in command CMAKE_PARSE_ARGUMENTS() #181
Comments
I looked at the size of the function that implements PARSE_ARGUMENTS() and it is pretty small. But it will kill a bunch of documentation, which will be good. This should also be much faster with CMake 3.5+ due to the native CMake implementation (i.e. in C++ instead of CMake). |
@fryeguy52 and I pair programmed the start of this refactoring. Turns out that cmake_parse_arguments() does not assert one-value keyword args, it just ignores them! Therefore, we will not be using that feature :-( Therefore, we will always pass in "" for So we will need create a function
|
Once we finish the full refactoring, we should, hopefully, be able to get rid of the ParseVariableArguments.cmake module and the macro PARSE_ARGUMENTS() altogether. This change was needed to fix the unit tests with CMake versions prior to 3.5.0. Interestingly, the CMakeParseArguments.cmake module got pulled in by some of the common_tpls/utils/ helper modules by accident. Therefore, the rest of TriBITS was working without needing to include the module.
Still using PARSE_ARGUMENTS added what I tried in the comments
this function has 2 calls to PARSE_ARGUMENTS one is cahnged to use CAMKE_PARSE_ARGUMENTS the other causes TriBITS to die in configure
in addition to changing the function call, CMAKE_PARSE_ARGUMENTS puts unparsed argumrnts in a variable called #{PREFIX}_UNPARSED_ARGUMENTS PARSE_ARGUMENTS however puts them in #{PREFIX}_DEFAULT_ARGS
The test TribitsExampleProject_ALL_ST_NoFortran repeated TEST_5. With the PARSE_ARGUMENTS() implementation, it ignored the first TEST_5. With the CMAKE_PARSE_ARGUMENTS() implementation, it gathered up the CMND arguments. The new implementation therefore caught the user error, but just did not report it very nicely.
We fixed the last issue with the major part of the refactoring in the WIP commit 4a64534. Now, to finish this up we should:
|
Timing configure of TriBITS project itself for this branch vs. master ... For the do-configure script:
On branch
On
That is a 10% reduction for the full configure time. For a project like CASL VERA that uses long arguments lists for TRIBITS_ADD_ADVANCED_TEST() and lots of those. Therefore, this is a worthwhile change from just a performance perspective. |
I looked at finer-grained configure timing and this change reduces the time for configuring the TriBITS package and tests itself from 1.581s to just 0.894s. This is a 43% reduction in the configure time. Therefore, we should see a very sizable reduction in configure times for projects with many TriBITS packages like Trilinos and especially CASL VERA. @fryeguy52, from looking at the commits you pushed yesterday, it looks like you are just about through the tasks listed out above. If that is the case, I think it makes sense to meet early next week and pair program the clean up this branch and then the final testing so we can merge and push this. After this, I am excited to try this out with Trilinos and especially CASL VERA to see the reduction in configure times that we might see. DETAILED NOTES: I realized that most of the time configuring the TriBITS CMake project is just finding compilers. Therefore, I reran the configures with internal timing turned on to show the impact this has on just configuring the TriBITS tests. The results are more striking. For the do-configure script:
A) Timing on For the following version on
the configure timing on my machine crf450 was:
B) Timing on For the following version on
timing configure timing on my machine crf450 was:
C) Analysis of timings: From looking at the above more detailed timings, we can see that almost all of the total reduction in time is for actually configuring the enabled TriBITS package and its tests. That time dropped from 1.581s to just 0.894s. This is a 43% reduction in the configure time. That is pretty big and that shows just how expensive the parsing that goes on with the old |
…181) For the most part, this was a simple refactoring (just reorder the arguments and put in an empty argument for the new one_value_keywords). We did not use the one_value_keywords argument because CMAKE_PARSE_ARGUMENTS() does not actually validate that, it just ignores additional arguments (which is **NOT** what we want). We will need to add new functions to validate these arguments instead :-( In addition to changing the function call, CMAKE_PARSE_ARGUMENTS puts unparsed arguments in a variable called #{PREFIX}_UNPARSED_ARGUMENTS PARSE_ARGUMENTS however puts them in #{PREFIX}_DEFAULT_ARGS. Some functions had to be changed for this. The test TribitsExampleProject_ALL_ST_NoFortran repeated TEST_5 and had to be fixed. With the PARSE_ARGUMENTS() implementation, it ignored the first TEST_5 block and used the second block. With the CMAKE_PARSE_ARGUMENTS() implementation, it gathered up the CMND arguments. The new implementation therefore caught the user error, but just did not report it very nicely. The module ParseVariableArguments.cmake now generates a deprecated warning when it is included and calling PARSE_ARGUMENTS() will generate a deprecated warning every time you call it! And this seems to improve configure time for CMake code using this by upwards of 40% based on tests from TriBITS configures! (The full configure time will be less because of probing the env takes a lot of time.) The test TribitsExampleProject_ALL_ST_NoFortran repeated TEST_5. With the PARSE_ARGUMENTS() implementation, it ignored the first TEST_5. With the CMAKE_PARSE_ARGUMENTS() implementation, it gathered up the CMND arguments. The new implementation therefore caught the user error, but just did not report it very nicely.
@fryeguy52 and I spent some time yesterday reviewing the branch 'cmake-parse-arguments-181'. We made two final commits on the branch:
The state of that branch was pushed to: to archive it. We then tried to rebase that branch on top of 'github/master'. That resulted in several merge conflicts on rebase due to the conflicting changes from #193 that I pushed recently. We made some mistakes in the merge and lost some work that we had to carefully bring back after careful review. The final squashed commit for the change, ready for final review and testing is 2f4c1ab. To complete this story, I will now do the following:
|
Final review of the squashed commit 2f4c1ab ... Looking for remaining references to the old module:
That is as it should be. The module is not included anywhere and We also manually tested the include of I ran the full TriBITS test suite on crf450 and it passed:
This included submitting to CDash: for the new tests added in #193. Now I will do configure performance timing with Trilinos ... |
…181) For the most part, this was a simple refactoring (just reorder the arguments and put in an empty argument for the new one_value_keywords). We did not use the one_value_keywords argument because CMAKE_PARSE_ARGUMENTS() does not actually validate that, it just ignores additional arguments (which is **NOT** what we want). We will need to add new functions to validate these arguments instead :-( In addition to changing the function call, CMAKE_PARSE_ARGUMENTS puts unparsed arguments in a variable called #{PREFIX}_UNPARSED_ARGUMENTS PARSE_ARGUMENTS however puts them in #{PREFIX}_DEFAULT_ARGS. Some functions had to be changed for this. The test TribitsExampleProject_ALL_ST_NoFortran repeated TEST_5 and had to be fixed. With the PARSE_ARGUMENTS() implementation, it ignored the first TEST_5 block and used the second block. With the CMAKE_PARSE_ARGUMENTS() implementation, it gathered up the CMND arguments. The new implementation therefore caught the user error, but just did not report it very nicely. The module ParseVariableArguments.cmake now generates a deprecated warning when it is included and calling PARSE_ARGUMENTS() will generate a deprecated warning every time you call it! And this seems to improve configure time for CMake code using this by upwards of 40% based on tests from TriBITS configures! (The full configure time will be less because of probing the env takes a lot of time.) The test TribitsExampleProject_ALL_ST_NoFortran repeated TEST_5. With the PARSE_ARGUMENTS() implementation, it ignored the first TEST_5. With the CMAKE_PARSE_ARGUMENTS() implementation, it gathered up the CMND arguments. The new implementation therefore caught the user error, but just did not report it very nicely. Build/Test Cases Summary Enabled Packages: Enabled all Packages 0) MPI_DEBUG => passed: passed=243,notpassed=0 (0.60 min) 1) SERIAL_RELEASE => passed: passed=243,notpassed=0 (0.64 min)
This generates a warning with CMAKE_PARSE_ARGUMENTS() but was ignored in PARSE_ARGUMENTS(). This did not cause any TriBITS tests to fail but it did show a warning in the test TriBITS_TestingFunctionMacro_UnitTests. Howver, this was not noticed before the last push. This was not noticed until testing against Trilinos in trilinos/Trilinos#1378. Build/Test Cases Summary Enabled Packages: Enabled all Packages 0) MPI_DEBUG => passed: passed=243,notpassed=0 (0.58 min) 1) SERIAL_RELEASE => passed: passed=243,notpassed=0 (0.61 min)
I had to fix an issue in Trilinos for the udpated TriBITS, but once I did that, I ran configure times comparing the old and new TriBITS implementations (see details below). Bottom line, the time needed to configure all of the Trilinos packages in the standard CI went build down from 1m3.009s to 0m29.979s! That is a 54% reduction in the configure time for the Trilinos packages and tests. This resulted in big reduction in the total configure (but not generation) time from 1m12.353s to just 0m39.735s. Unfortunately, the generation cost for Trilinos is quite high (almost 2 minutes) so the total configure+generation time only comes down from 2m49.308s to 2m23.799s, or a 15% reduction. But cutting 30s off the configure time for all of Trilinos will be welcome. I would expect to see similar reductions for CASL VERA as well. Anyway, this is positive but not as positive as I would have hopped (I forgot how expensive the generation time is for Trilinos). DETAILED NOTES: A) Introduction: Running configure times on my machine crf450 with the Trilinos SEMS CI env of Trilinos for version:
(This is a patch, see #1378.) Using CMake version:
Using the
B) Configure time for Trilinos with old version of TriBITS using PARSE_ARGUMENTS(): First I test with the current TriBITS implementation using
C) Configure time for Trilinos with new version of TriBITS using CMAKE_PARSE_ARGUMENTS(): Now to try the configure with the TriBITS version:
Here is the configure timing of Trilinos now using that updated TriBITS:
D) Analysis: I ran these configure times several times for each case back and forth and got similar timings (within 5% or so). The reduction in the configure time for the packages was large. It went down from 1m3.009s to 0m29.979s. That is a 54% reduction in the configure time for the Trilinos packages and tests. That is huge. That huge reduction reduced the total configure (but not generation) time to come down from 1m12.353s to just 0m39.735s. Unfortunately, the generation cost for Trilinos is high so the total configure+generation time only comes down from 2m49.308s to 2m23.799s, or a 15% reduction. But cutting 30s off the configure time for all of Trilinos will be welcome. I would expect to see similar reductions for CASL VERA as well. |
Addresses #1378 that goes along with TriBITSPub/TriBITS#181.
Related to #1378 and TriBITSPub/TriBITS#181 Build/Test Cases Summary Enabled Packages: Disabled Packages: PyTrilinos,Claps,TriKota Enabled all Packages 0) MPI_RELEASE_DEBUG_SHARED_PT => passed: passed=2325,notpassed=0 (100.40 min) Other local commits for this build/test group: 12c4cf6, d7bcd6d, ce82bb8
I snapshotted this into Trilinos and pushed (see trilinos/Trilinos#1378). I did not manually test the TriBITS Dashboard Driver, but actually a lot of Trilinos builds don't even use that anymore. Also, the changes were pretty minimal so I am hopeful that it will not be broken. I am now putting this in review and we can watch and see what happens for a few days. |
When that refactoring was completed, the ninja tests would not enabled and run and therefore this was not caught. Amazingly, the tests still work, even after this change. Build/Test Cases Summary Enabled Packages: Enabled all Packages 0) MPI_DEBUG => passed: passed=243,notpassed=0 (0.61 min) 1) SERIAL_RELEASE => passed: passed=243,notpassed=0 (0.65 min) Other local commits for this build/test group: 6be1a83
It has been a long time and I have not heard of any more issues related to these changes. Therefore, I am closing. |
Since CMake 3.5, CMake now has a native argument parser function:
To support older versions of CMake, we would just include the module CMakeParseArgument.cmake:
To take full advantage of the new
CMAKE_PARSE_ARGUMENTS()
function (i.e. single-value arguments), we would likely need to replace the usage ofPARSE_ARGUMENTS()
withCMAKE_PARSE_ARGUMENTS()
one call at a time. But that should not be too hard.This will also allow us to shrink the size of TriBITS Core.
The text was updated successfully, but these errors were encountered: