From 7e5f5219b53989088f134cf0279fc41999cb131d Mon Sep 17 00:00:00 2001 From: Joseph D Hughes Date: Mon, 12 Feb 2024 17:31:34 -0600 Subject: [PATCH 1/5] feat(cli): add --precision option to make-program --- autotest/test_cli_cmds.py | 15 +++++++++++++++ docs/build_apps.md | 31 +++++++++++++++++++------------ pymake/cmds/build.py | 34 ++++++++++++++++++++-------------- pymake/pymake_build_apps.py | 34 +++++++++++++++++++++------------- pymake/utils/usgsprograms.py | 4 ++-- 5 files changed, 77 insertions(+), 41 deletions(-) diff --git a/autotest/test_cli_cmds.py b/autotest/test_cli_cmds.py index b82aaf4..743ac68 100644 --- a/autotest/test_cli_cmds.py +++ b/autotest/test_cli_cmds.py @@ -52,6 +52,21 @@ def test_make_program(function_tmpdir, target: str) -> None: ] run_cli_cmd(cmd) +@flaky(max_runs=RERUNS) +@pytest.mark.dependency(name="make_program") +@pytest.mark.base +def test_make_program_double(function_tmpdir) -> None: + cmd = [ + "make-program", + "mf2005,mfusg", + "--appdir", + str(function_tmpdir), + "--precision", + "double", + "--verbose", + ] + run_cli_cmd(cmd) + @pytest.mark.dependency(name="make_program_all") @pytest.mark.schedule diff --git a/docs/build_apps.md b/docs/build_apps.md index 12b15b9..835bdfb 100644 --- a/docs/build_apps.md +++ b/docs/build_apps.md @@ -7,7 +7,7 @@ and options can be determined by executing: ```console $ make-program --help -usage: make-program [-h] [--release_precision] +usage: make-program [-h] [--precision {default,double}] [-fc {ifort,mpiifort,gfortran,none}] [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] [-dr] [-ff FFLAGS] [-cf CFLAGS] [-ad APPDIR] [-v] [--keep] @@ -17,19 +17,23 @@ usage: make-program [-h] [--release_precision] Download and build USGS MODFLOW and related programs. positional arguments: - targets Program(s) to build. Options: crt, gridgen, libmf6, - mf2000, mf2005, mf6, mflgr, mfnwt, mfusg, mfusg_gsi, - mp6, mp7, mt3dms, mt3dusgs, sutra, swtv4, triangle, - vs2dt, zbud6, zonbud3, zonbudusg, :. Specifying the - target to be ':' will build all of the programs. + targets Program(s) to build. Options: crt, gridgen, gsflow, + libmf6, mf2000, mf2005, mf6, mflgr, mfnwt, mfusg, + mfusg_gsi, mp6, mp7, mt3dms, mt3dusgs, sutra, swtv4, + triangle, vs2dt, zbud6, zonbud3, zonbudusg, :. + Specifying the target to be ':' will build all of the + programs. Multiple targets can be specified by + separating individual targets by a comma (i.e., + mf6,zbud6). -optional arguments: +options: -h, --help show this help message and exit - --release_precision If release_precision is False, then the release - precision version will be compiled along with a double - precision version of the program for programs where - the standard_switch and double_switch in - usgsprograms.txt is True. default is True. + --precision {default,double} + If precision is 'default', then the default precision + version of the program will be compiled (this could be + a single or double precision version). If precision is + 'double', a double precision version will be compiled + using compiler switches. default is `default`. -fc {ifort,mpiifort,gfortran,none} Fortran compiler to use. (default is gfortran) -cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none} @@ -64,6 +68,9 @@ Examples: Download and compile triangle in the ./temp subdirectory: $ make-program triangle --appdir temp + Download and compile double precision versions of mf2005 and mfusg + $ make-program mf2005,mfusg --precision double + Download and compile all programs in the ./temp subdirectory: $ make-program : --appdir temp diff --git a/pymake/cmds/build.py b/pymake/cmds/build.py index 7d2a723..3bbb90b 100755 --- a/pymake/cmds/build.py +++ b/pymake/cmds/build.py @@ -60,6 +60,9 @@ def main() -> None: Download and compile triangle in the ./temp subdirectory: $ {prog} triangle --appdir temp + Download and compile double precision versions of mf2005 and mfusg + $ {prog} mf2005,mfusg --precision double + Download and compile all programs in the ./temp subdirectory: $ {prog} : --appdir temp """ @@ -75,16 +78,16 @@ def main() -> None: "Program(s) to build. Options:\n " + ", ".join(all_targets) + ". Specifying the target to be ':' will " - + "build all of the programs." + + "build all of the programs. Multiple targets can be specified " + + "by separating individual targets by a comma (i.e., mf6,zbud6)." ) - release_precision_help = ( - "If release_precision is False, then the " - + "release precision version will be compiled " - + "along with a double precision version of " - + "the program for programs where the standard_" - + "switch and double_switch in " - + "usgsprograms.txt is True. default is True." + precision_help = ( + "If precision is 'default', then the default precision version of " + + "the program will be compiled (this could be a single or double " + + "precision version). If precision is 'double', a double precision " + + "version will be compiled using compiler switches. default is " + + "`default`." ) # command line arguments specific to make-program @@ -96,12 +99,15 @@ def main() -> None: "choices": None, "action": None, }, - "release_precision": { - "tag": ("--release_precision",), - "help": release_precision_help, - "default": False, - "choices": None, - "action": "store_true", + "precision": { + "tag": ("--precision",), + "help": precision_help, + "default": "default", + "choices": [ + "default", + "double", + ], + "action": None, }, } diff --git a/pymake/pymake_build_apps.py b/pymake/pymake_build_apps.py index a76e526..61f8f7d 100644 --- a/pymake/pymake_build_apps.py +++ b/pymake/pymake_build_apps.py @@ -41,7 +41,7 @@ def build_apps( download_dir=None, appdir=None, verbose=None, - release_precision=True, + precision="default", meson=False, mesondir=".", clean=True, @@ -59,12 +59,12 @@ def build_apps( download directory path appdir : str target path - release_precision : bool - boolean indicating if only the release precision version should be - build. If release_precision is False, then the release precision - version will be compiled along with a double precision version of - the program for programs where the standard_switch and double_switch - in usgsprograms.txt is True. default is True. + precision : str + string indicating if the default precision version should be built. + If precision is 'default', then the default precision version of + the program will be compiled (this could be a single or double + precision version). If precision is 'double', a double precision + version will be compiled using compiler switches. default is `default`. meson : bool boolean indicating that the executable should be built using the meson build system. (default is False) @@ -92,7 +92,7 @@ def build_apps( targets = usgs_program_data.get_keys(current=True) else: if isinstance(targets, str): - targets = [targets] + targets = targets.split(",") code_dict = {} @@ -221,16 +221,24 @@ def build_apps( ) # determine if single, double, or both should be built - precision = usgs_program_data.get_precision(target) + prog_precision = usgs_program_data.get_precision(target) # just build the first precision in precision list if # standard_precision is True - if release_precision: - precision = precision[0:1] + if precision != "default": + prog_precision = [precision] - for double in precision: + for precision_str in prog_precision: # set double flag - pmobj.double = double + if precision_str == "default": + pmobj.double = False + elif precision_str == "double": + pmobj.double = True + else: + ValueError( + f"precision ({precision_str}) must be " + + "'single' or 'double'." + ) # determine if the target should be built build_target = pmobj.set_build_target_bool( diff --git a/pymake/utils/usgsprograms.py b/pymake/utils/usgsprograms.py index 23bfba6..792149c 100644 --- a/pymake/utils/usgsprograms.py +++ b/pymake/utils/usgsprograms.py @@ -248,9 +248,9 @@ def get_precision(key): target = usgs_program_data().get_target(key) precision = [] if target.standard_switch: - precision.append(False) + precision.append("default") if target.double_switch: - precision.append(True) + precision.append("double") return precision @staticmethod From 7d00a0322fb52127405965af09297aaab628dcaa Mon Sep 17 00:00:00 2001 From: Joseph D Hughes Date: Tue, 13 Feb 2024 10:55:58 -0600 Subject: [PATCH 2/5] * convert --precision default/double to --double --- autotest/test_cli_cmds.py | 4 ++-- docs/build_apps.md | 18 ++++++------------ pymake/cmds/build.py | 21 ++------------------- pymake/pymake_build_apps.py | 25 ++++++++----------------- 4 files changed, 18 insertions(+), 50 deletions(-) diff --git a/autotest/test_cli_cmds.py b/autotest/test_cli_cmds.py index 743ac68..69d97b4 100644 --- a/autotest/test_cli_cmds.py +++ b/autotest/test_cli_cmds.py @@ -52,6 +52,7 @@ def test_make_program(function_tmpdir, target: str) -> None: ] run_cli_cmd(cmd) + @flaky(max_runs=RERUNS) @pytest.mark.dependency(name="make_program") @pytest.mark.base @@ -61,8 +62,7 @@ def test_make_program_double(function_tmpdir) -> None: "mf2005,mfusg", "--appdir", str(function_tmpdir), - "--precision", - "double", + "--double", "--verbose", ] run_cli_cmd(cmd) diff --git a/docs/build_apps.md b/docs/build_apps.md index 835bdfb..62b89df 100644 --- a/docs/build_apps.md +++ b/docs/build_apps.md @@ -7,11 +7,10 @@ and options can be determined by executing: ```console $ make-program --help -usage: make-program [-h] [--precision {default,double}] - [-fc {ifort,mpiifort,gfortran,none}] - [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] [-dr] - [-ff FFLAGS] [-cf CFLAGS] [-ad APPDIR] [-v] [--keep] - [--zip ZIP] [--meson] +usage: make-program [-h] [-fc {ifort,mpiifort,gfortran,none}] + [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] + [-dbl] [-dr] [-ff FFLAGS] [-cf CFLAGS] [-ad APPDIR] [-v] + [--keep] [--zip ZIP] [--meson] targets Download and build USGS MODFLOW and related programs. @@ -28,16 +27,11 @@ positional arguments: options: -h, --help show this help message and exit - --precision {default,double} - If precision is 'default', then the default precision - version of the program will be compiled (this could be - a single or double precision version). If precision is - 'double', a double precision version will be compiled - using compiler switches. default is `default`. -fc {ifort,mpiifort,gfortran,none} Fortran compiler to use. (default is gfortran) -cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none} C/C++ compiler to use. (default is gcc) + -dbl, --double Force double precision. (default is False) -dr, --dryrun Do not actually compile. Files will be deleted, if --makeclean is used. Does not work yet for ifort. (default is False) @@ -69,7 +63,7 @@ Examples: $ make-program triangle --appdir temp Download and compile double precision versions of mf2005 and mfusg - $ make-program mf2005,mfusg --precision double + $ make-program mf2005,mfusg --double Download and compile all programs in the ./temp subdirectory: $ make-program : --appdir temp diff --git a/pymake/cmds/build.py b/pymake/cmds/build.py index 3bbb90b..a45b87b 100755 --- a/pymake/cmds/build.py +++ b/pymake/cmds/build.py @@ -22,6 +22,7 @@ "cc", "fflags", "cflags", + "double", "verbose", "zip", "keep", @@ -61,7 +62,7 @@ def main() -> None: $ {prog} triangle --appdir temp Download and compile double precision versions of mf2005 and mfusg - $ {prog} mf2005,mfusg --precision double + $ {prog} mf2005,mfusg --double Download and compile all programs in the ./temp subdirectory: $ {prog} : --appdir temp @@ -82,14 +83,6 @@ def main() -> None: + "by separating individual targets by a comma (i.e., mf6,zbud6)." ) - precision_help = ( - "If precision is 'default', then the default precision version of " - + "the program will be compiled (this could be a single or double " - + "precision version). If precision is 'double', a double precision " - + "version will be compiled using compiler switches. default is " - + "`default`." - ) - # command line arguments specific to make-program parser_dict = { "targets": { @@ -99,16 +92,6 @@ def main() -> None: "choices": None, "action": None, }, - "precision": { - "tag": ("--precision",), - "help": precision_help, - "default": "default", - "choices": [ - "default", - "double", - ], - "action": None, - }, } # add standard command line arguments to parser dictionary for make-program diff --git a/pymake/pymake_build_apps.py b/pymake/pymake_build_apps.py index 61f8f7d..456c322 100644 --- a/pymake/pymake_build_apps.py +++ b/pymake/pymake_build_apps.py @@ -41,7 +41,7 @@ def build_apps( download_dir=None, appdir=None, verbose=None, - precision="default", + double=False, meson=False, mesondir=".", clean=True, @@ -59,12 +59,8 @@ def build_apps( download directory path appdir : str target path - precision : str - string indicating if the default precision version should be built. - If precision is 'default', then the default precision version of - the program will be compiled (this could be a single or double - precision version). If precision is 'double', a double precision - version will be compiled using compiler switches. default is `default`. + double : bool + force double precision. (default is False) meson : bool boolean indicating that the executable should be built using the meson build system. (default is False) @@ -224,21 +220,16 @@ def build_apps( prog_precision = usgs_program_data.get_precision(target) # just build the first precision in precision list if - # standard_precision is True - if precision != "default": - prog_precision = [precision] + # reset prog_precision if double + if double: + prog_precision = ["double"] for precision_str in prog_precision: # set double flag - if precision_str == "default": - pmobj.double = False - elif precision_str == "double": + if precision_str == "double": pmobj.double = True else: - ValueError( - f"precision ({precision_str}) must be " - + "'single' or 'double'." - ) + pmobj.double = False # determine if the target should be built build_target = pmobj.set_build_target_bool( From d449c15c6aa2f27c30e15331522be08d69178dd8 Mon Sep 17 00:00:00 2001 From: Joseph D Hughes Date: Tue, 13 Feb 2024 13:52:14 -0600 Subject: [PATCH 3/5] no message --- autotest/test_cli_cmds.py | 2 +- pymake/cmds/build.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/autotest/test_cli_cmds.py b/autotest/test_cli_cmds.py index 69d97b4..69e7390 100644 --- a/autotest/test_cli_cmds.py +++ b/autotest/test_cli_cmds.py @@ -20,7 +20,7 @@ def run_cli_cmd(cmd: list) -> None: - process = subprocess.Popen( + process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.getcwd() ) stdout, stderr = process.communicate() diff --git a/pymake/cmds/build.py b/pymake/cmds/build.py index a45b87b..a25dde6 100755 --- a/pymake/cmds/build.py +++ b/pymake/cmds/build.py @@ -35,6 +35,7 @@ "fflags", "cflags", "zip", + "double", "keep", "dryrun", ) From 51981ce6341417b17709781d1ff77da03d3aa845 Mon Sep 17 00:00:00 2001 From: Joseph D Hughes Date: Tue, 13 Feb 2024 14:07:16 -0600 Subject: [PATCH 4/5] * fix issue in build.py --- autotest/test_cli_cmds.py | 2 +- pymake/cmds/build.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/autotest/test_cli_cmds.py b/autotest/test_cli_cmds.py index 69e7390..69d97b4 100644 --- a/autotest/test_cli_cmds.py +++ b/autotest/test_cli_cmds.py @@ -20,7 +20,7 @@ def run_cli_cmd(cmd: list) -> None: - process = subprocess.Popen( + process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.getcwd() ) stdout, stderr = process.communicate() diff --git a/pymake/cmds/build.py b/pymake/cmds/build.py index a25dde6..a45b87b 100755 --- a/pymake/cmds/build.py +++ b/pymake/cmds/build.py @@ -35,7 +35,6 @@ "fflags", "cflags", "zip", - "double", "keep", "dryrun", ) From d7da3b19e678fc04f487a07fe7cc13248cea46fa Mon Sep 17 00:00:00 2001 From: Joseph D Hughes Date: Tue, 13 Feb 2024 17:51:32 -0600 Subject: [PATCH 5/5] * fix issue in build.py --- autotest/test_cli_cmds.py | 6 +++--- pymake/cmds/build.py | 10 ++++++++-- pymake/pymake_build_apps.py | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/autotest/test_cli_cmds.py b/autotest/test_cli_cmds.py index 69d97b4..661bd72 100644 --- a/autotest/test_cli_cmds.py +++ b/autotest/test_cli_cmds.py @@ -59,11 +59,11 @@ def test_make_program(function_tmpdir, target: str) -> None: def test_make_program_double(function_tmpdir) -> None: cmd = [ "make-program", - "mf2005,mfusg", - "--appdir", - str(function_tmpdir), + "mf2005", "--double", "--verbose", + "--appdir", + str(function_tmpdir), ] run_cli_cmd(cmd) diff --git a/pymake/cmds/build.py b/pymake/cmds/build.py index a45b87b..297674d 100755 --- a/pymake/cmds/build.py +++ b/pymake/cmds/build.py @@ -17,7 +17,6 @@ "targets", "appdir", "verbose", - "release_precision", "fc", "cc", "fflags", @@ -29,16 +28,22 @@ "dryrun", "meson", ) + +# command arguments (sys.argv) to pop from ARGS COM_ARG_KEYS = ( "fc", "cc", "fflags", "cflags", + "double", "zip", "keep", "dryrun", ) +# ARGS to keep and pass to build_apps() +KEEP_ARG_KEYS = ("double",) + def main() -> None: """Command line interface @@ -127,7 +132,8 @@ def main() -> None: # delete arguments that are used by Pymake() class in build_apps for key in arg_key_pop: - del args[key] + if key not in KEEP_ARG_KEYS: + del args[key] # remove args from command line arguments for key in com_arg_pop: diff --git a/pymake/pymake_build_apps.py b/pymake/pymake_build_apps.py index 456c322..95e48ee 100644 --- a/pymake/pymake_build_apps.py +++ b/pymake/pymake_build_apps.py @@ -52,7 +52,7 @@ def build_apps( ---------- targets : str or list of str targets to build. If targets is None, all current targets will - be build. Default is None + be built. Default is None pymake_object : Pymake() Pymake object created outside of build_apps download_dir : str