Skip to content
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

support for "threads" and "min-optlevel" julia options #493

Merged
merged 13 commits into from
Nov 13, 2022
45 changes: 43 additions & 2 deletions src/julia/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,35 @@ def _domain(self): # used in test
return str


class IntEtc(OptionDescriptor):
def __init__(self, name, *, etc={}):
self.name = name
self.default = etc

def __set__(self, instance, value):
if instance is None:
raise AttributeError(self.name)
elif value in {None, *self.default} or isinstance(value, int):
setattr(instance, self.dataname, value)
else:
if self.default:
part = " or " + " ".join(map(str, self.default))
else:
part = ""
raise ValueError(
f"Option {self.name} only accepts integers{part}. Got: {value}"
)

def _domain(self):
return {int, *self.default}

def cli_argument_spec(self):
return dict(
super(IntEtc, self).cli_argument_spec(),
choices=list(self.default) + ["1", "2", "3", "..."],
)


class Choices(OptionDescriptor):
def __init__(self, name, choicemap, default=None):
self.name = name
Expand Down Expand Up @@ -110,6 +139,12 @@ def yes_no_etc(*etc):

warn_overwrite: {True, False, 'yes', 'no'}
Enable or disable method overwrite warnings.

min_optlevel: {0, 1, 2, 3}
Lower bound on the optimization level.

threads: {int, 'auto'}
How many threads to use.
"""


Expand All @@ -134,9 +169,11 @@ class JuliaOptions(object):
compile = Choices("compile", yes_no_etc("all", "min"))
depwarn = Choices("depwarn", yes_no_etc("error"))
warn_overwrite = Choices("warn_overwrite", yes_no_etc())
min_optlevel = Choices("min_optlevel", dict(zip(range(4), map(str, range(4)))))
optimize = Choices("optimize", dict(zip(range(4), map(str, range(4)))))
inline = Choices("inline", yes_no_etc())
check_bounds = Choices("check_bounds", yes_no_etc())
threads = IntEtc("threads", etc={"auto"})

def __init__(self, **kwargs):
unsupported = []
Expand Down Expand Up @@ -168,8 +205,12 @@ def specified(self):
def as_args(self):
args = []
for (desc, value) in self.specified():
args.append(desc.cli_argument_name())
args.append(value)
if value is None:
...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this new logic to avoid adding arguments if the value is unset. Not sure why this wasn't set up before - @mkitti or @marius311 any idea why?

elif len(desc.cli_argument_name()) == 1:
args.append(desc.cli_argument_name() + str(value))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need test case for this branch. (unless there already is one?)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, there are no options that could trigger this... Is that correct? So maybe this branch can be removed.

else:
args.append(desc.cli_argument_name() + "=" + str(value))
return args

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion src/julia/tests/test_compatible_exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def discover_other_pythons():
[sys.executable, "--version"], universal_newlines=True, stderr=subprocess.STDOUT
)

candidate_names = ["python", "python2", "python2.7", "python3"] + [
candidate_names = ["python", "python3"] + [
"python3.{}".format(i) for i in range(20)
]
found = {}
Expand Down
17 changes: 11 additions & 6 deletions src/julia/tests/test_juliaoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
@pytest.mark.parametrize("kwargs, args", [
({}, []),
(dict(compiled_modules=None), []),
(dict(compiled_modules=False), ["--compiled-modules", "no"]),
(dict(compiled_modules="no"), ["--compiled-modules", "no"]),
(dict(depwarn="error"), ["--depwarn", "error"]),
(dict(sysimage="PATH"), ["--sysimage", "PATH"]),
(dict(bindir="PATH"), ["--home", "PATH"]),
(dict(optimize=3), ["--optimize", "3"]),
(dict(compiled_modules=False), ["--compiled-modules=no"]),
(dict(compiled_modules="no"), ["--compiled-modules=no"]),
(dict(depwarn="error"), ["--depwarn=error"]),
(dict(sysimage="PATH"), ["--sysimage=PATH"]),
(dict(bindir="PATH"), ["--home=PATH"]),
(dict(optimize=3), ["--optimize=3"]),
(dict(threads=4), ["--threads=4"]),
(dict(min_optlevel=2), ["--min-optlevel=2"]),
(dict(threads="auto", optimize=3), ["--optimize=3", '--threads=auto']),
(dict(optimize=3, threads="auto"), ["--optimize=3", '--threads=auto']), # passed order doesn't matter
(dict(compiled_modules=None, depwarn="yes"), ["--depwarn=yes"]),
])
# fmt: on
def test_as_args(kwargs, args):
Expand Down