-
Notifications
You must be signed in to change notification settings - Fork 0
Adding tuner #2
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
Open
sbacchio
wants to merge
128
commits into
master
Choose a base branch
from
user/raphdem
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Adding tuner #2
Changes from 25 commits
Commits
Show all changes
128 commits
Select commit
Hold shift + click to select a range
01ba8e8
fixed package name to varname
psyrd1 8790fb7
removed instruction pylint: disable=C0303,C033
raphdem a0b4920
fixing default value
raphdem 9a2e439
adding store_value
raphdem 4d99381
Adding data type
sbacchio 1b9d57c
Fixing initialization of Node
sbacchio 7f212e7
Setting values also of variables
sbacchio 912816e
Adding draft of tuner
sbacchio 065321b
added optuna as an optional package
raphdem 100c012
fixed typo
raphdem 5210fc8
a sampler based on the optuna package
raphdem d683c48
tuner was changed to work with OptunaSampler
raphdem cbdd411
fixed package name
raphdem 514b2f5
fixed JSON serializable error
raphdem 4bc8238
new pytest file for the Tuner class
raphdem 4a504f0
removing OptunaSampler
raphdem cbce515
using a list for variables
raphdem b329937
functions for merging nodes have been added
raphdem 88408d7
changes were made to visualize groups within a graph
raphdem db50ddd
added documentation
raphdem c1cf27e
added documentation
raphdem b3371bf
tests for the optuna class
raphdem a83aa38
tests for the sampler class
raphdem 1a35102
outline of a new subgraph class that enables the merging of nodes
raphdem 7d75053
formatting changed
raphdem 277e3fe
Removing test/__init__.py
sbacchio 07e5d4a
Few changes
sbacchio 398be09
new tests for merge functions added
raphdem 323acf4
tests commented out after changes in code
raphdem 707ecf1
var_name changed for variables created using alternatives
raphdem c683d0d
dependencies function was changed
raphdem ad6c75c
Merge branch 'user/raphdem' of github.com:Lyncs-API/tuneit into user/…
raphdem 859488a
changed visualize function to enable different visualization of nodes…
raphdem d7c7d9b
1. updated get_attributes function to extract the information used fo…
raphdem ad50e2b
this file is not needed anymore
raphdem 4f4a6a5
added a copy function for the Tuner class
raphdem c4d1c11
updated README file with example
raphdem 35a5961
added a boolean precompute attribute to the class Object and now the …
raphdem 86b366c
updated tests to work with the new changes made to the code
raphdem 615f9d8
1. created get_key function and changed other functions (get_node(),_…
raphdem fcfc272
Adding workflows
sbacchio 466a02b
Removing unwated MPI
sbacchio 454b18b
Updating pylint score (from Github Action)
sbacchio 1bef44d
added tests for the example in README
raphdem ebbc89a
Merge branch 'user/raphdem' of github.com:Lyncs-API/tuneit into user/…
raphdem af6c10e
1.added functionality that records the results in a panda dataframe, …
raphdem 1e3be9f
reformatted
raphdem d20b0ee
added record argument
raphdem 056c203
changed dot_attrs
raphdem a9a8fa4
changed dot_attrs
raphdem c266f40
changed crosscheck method to allow a delayed execution
raphdem b98f396
README: removed example that now exists in docs, conf: added an instr…
raphdem a1de802
reformatted
raphdem d5c41e3
new documentation pages about installation and some examples along wi…
raphdem 7d61e47
add_deps now works for all types and a new function get_info was adde…
raphdem b0731bb
added an index to each node in the visualization of the graph and the…
raphdem 6c74fc7
removed function get_attributes and used function get_info from final…
raphdem 9a8f850
changed the headers of the dataframe
raphdem ee5847c
changed data attribute names to contain only one _
raphdem 3733ecc
updated images to match changes in code
raphdem 93f8658
updated alternatives to accept a name chosen by the user for the vari…
raphdem 4203d8c
updated example doc
raphdem 9918511
deleted files
raphdem 37521aa
updated example
raphdem 749b5ba
added pandas to the requirements
raphdem 77c626c
updated plot
raphdem a1e6477
updated tests after get_attributes function was removed from optuna.py
raphdem 09f0e0b
reformatted
raphdem ad3d99a
updated index file
raphdem 9284700
added option in get_info() for short names
raphdem 3ae6e6b
added data output node in the visualized graph
raphdem 7ad7c4d
1. updated datarame headers after get_info() was changed, 2. added *a…
raphdem bf3fe80
changed how self.n_trials is assigned
raphdem a65f9ac
removed commented code
raphdem 9c6f60b
reformatted
raphdem 6955643
pandas are now imported inside record
raphdem 1722fa8
updated index file
raphdem 15bf4da
these tests are now only performed if optuna is installed
raphdem 71efb0c
image used in index file (docs)
raphdem 9abd1ba
added optuna to extras
raphdem a6135c1
changed definition of remove to include *nodes instead of nodes and c…
raphdem 486c386
removed dependencies function from Object (not used anywhere)
raphdem 7a151cf
updated index file with code block
raphdem 25e1ab8
updated image to match code block
raphdem 14b89a9
alternatives changed to allow the user to pass a name for the functio…
raphdem a5d4875
new images for index.rst
raphdem e491964
deleted unnecessary file
raphdem 6e93846
visualize can now be called on a HighLevel object (obj.visualize())
raphdem 34cd801
the functions benchmark, crosscheck and optimise can now be called on…
raphdem 5eb61aa
updated index file with additional picture
raphdem 6ad47a8
fixed alternatives because it was setting the name of the first optio…
raphdem 48248dc
set HighLevel.optimise equal to optimise
raphdem 7d11cda
changed how the name in alternatives is set
raphdem f48aa1b
updated README file
raphdem cc8d42b
updated images to match changes in the code
raphdem efc9d28
updated example.rst file
raphdem 62c30f2
updated image to match changes in example.rst
raphdem 2a72c19
updated picture
raphdem 79ef8a6
removed pictures with wrong extension
raphdem 4cf99fc
images with correct extensions
raphdem 40c6e96
image with correct extension
raphdem 24a7a33
fixed typo
raphdem 696f1bf
updated README file
raphdem 32876e7
fixed image placement
raphdem 38240c5
Updating workflows
sbacchio 85492b1
Updating pylint score (from Github Action)
sbacchio 68debbc
Updating workflow
sbacchio b11939d
Incrementing version number
sbacchio 5d644e7
Merge branch 'user/raphdem' of github.com:sbacchio/tunable into user/…
sbacchio d6b305b
Updating workflow
sbacchio aeacd2b
Updating __init__
sbacchio 2d17504
Updating workflow
sbacchio dd63ceb
data object values are now passed correctly as kwargs
raphdem 1439039
data object values are now included in sampler_kwargs
raphdem ee45f03
Merge branch 'user/raphdem' of github.com:Lyncs-API/tuneit into user/…
raphdem c60ed82
added tests that check if an object is able to be pickled
raphdem dfad749
changed dict_keys in alternatives to a tuple because they are not pic…
raphdem 5c05746
added __reduce__ methods to classes in order to make them picklable
raphdem f3afaf5
1. added maximum number of failed trials before error is raise, 2. fi…
raphdem 2f7c361
Updating pylint score (from Github Action)
sbacchio 06f74da
updated setup file with testfixtures
raphdem e0327ec
Merge branch 'user/raphdem' of github.com:Lyncs-API/tuneit into user/…
raphdem a4fa61a
Applying black formatting (from Github Action)
sbacchio 7516160
call to optimize updated to match changes about the handling of compu…
raphdem 3ae9344
1. added logging using context managers, 2. added the __reduce__ meth…
raphdem b737470
formatted
raphdem 990a449
Merge branch 'user/raphdem' of github.com:Lyncs-API/tuneit into user/…
raphdem d7e216f
Updating pylint score (from Github Action)
sbacchio File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| from tuneit import * | ||
| import numpy | ||
| from tuneit.tools.time import Time, default_timer | ||
| from tuneit.tools.optuna import OptunaSampler | ||
| import pytest | ||
| import optuna | ||
| from optuna.trial import Trial | ||
| from optuna.trial import create_trial | ||
| from optuna.distributions import CategoricalDistribution | ||
| from optuna.trial import TrialState | ||
| from tuneit.finalize import HighLevel | ||
| from optuna.study import Study | ||
| from hashlib import md5 | ||
| from dill import dumps | ||
|
|
||
|
|
||
| def test_optuna_sampler(): | ||
| # simple example to use in tests | ||
| # building a graph with variables for sorting (preprocessing) and searching to be tuned: | ||
|
|
||
| @alternatives( | ||
| mergesort=lambda a: numpy.sort(a, kind="mergesort"), | ||
| heapsort=lambda a: numpy.sort(a, kind="heapsort"), | ||
| timsort=lambda a: numpy.array(sorted(a)), | ||
| ) | ||
| def preprocessing(array): | ||
| res = numpy.sort(array) | ||
| return res | ||
|
|
||
| @alternatives( | ||
| indices=lambda a, b: [i for i, x in enumerate(a.tolist()) if x == b][0], | ||
| array_search=lambda a, b: numpy.where(a == b)[0][0], | ||
| binary_search=lambda a, b: numpy.searchsorted(a, b), | ||
| ) | ||
| def searching(array, element): | ||
| l = array.tolist() | ||
| index = l.index(element) | ||
| return index | ||
|
|
||
| element = 65 | ||
| result = searching( | ||
| preprocessing(numpy.random.randint(1000, size=(10000))), element | ||
| ) # input size: 10 000, type: integers | ||
| fz = finalize(result) | ||
|
|
||
| callback_function = lambda fnc: Time(default_timer(fnc)) | ||
| obj_A = OptunaSampler( | ||
| fz, callback=callback_function, storage="sqlite:///example.db" | ||
| ) | ||
| assert isinstance(obj_A, OptunaSampler) | ||
| assert isinstance(obj_A.tunable, HighLevel) | ||
| assert not bool( | ||
| obj_A.compute_kwargs | ||
| ) # at the moment no kwargs are used for the compute function, so compute_kwargs must be empty | ||
| assert callable(obj_A.callback) | ||
| assert obj_A.n_trials > 0 | ||
|
|
||
| # test get_attributes function | ||
| assert obj_A.get_attributes()["callback"] == obj_A.callback | ||
|
|
||
| # test get_study function | ||
| study = obj_A.get_study() | ||
| assert isinstance(study, Study) | ||
| assert study.study_name == md5(dumps(obj_A.get_attributes())).hexdigest() | ||
| assert [*study.user_attrs.keys()] == ["callback"] | ||
| obj_B = OptunaSampler( | ||
| fz, callback=callback_function, storage="sqlite:///example.db", n_trials=10 | ||
| ) | ||
| assert obj_A.compute() == finalize(result).compute() # test compute function | ||
| assert obj_B.compute() == finalize(result).compute() | ||
| name_A = obj_A.get_study().study_name | ||
| name_B = obj_B.get_study().study_name | ||
| assert name_A == name_B | ||
| assert len(study.trials) >= 11 | ||
|
|
||
| # test _call_wrapper function | ||
| assert obj_A._call_wrapper(obj_A.tunable) == finalize(result).compute() | ||
|
|
||
| # test objective function | ||
| tid = study._storage.create_new_trial(study._study_id) | ||
| trial = Trial(study, trial_id=tid) | ||
| assert isinstance(obj_A.objective(trial), Time) | ||
|
|
||
| # test get_next_trial | ||
| temp = obj_A.get_next_trial(trial) | ||
| assert len(temp.fixed_variables) == 2 | ||
| var_A = temp.get_variable("preprocessing") | ||
| var_B = temp.get_variable("searching") | ||
| assert var_A.fixed and var_B.fixed | ||
|
|
||
| # test get_suggetions | ||
| selected_options = obj_A.get_suggestions(trial) | ||
| assert len(selected_options) == len(fz.variables) | ||
| assert [*selected_options.values()][0] in preprocessing.keys() | ||
| assert [*selected_options.values()][1] in searching.keys() | ||
|
|
||
| # test get_var_args function | ||
| assert OptunaSampler.get_var_args("categorical", ["a", "b", "c"]) == ( | ||
| tuple(["a", "b", "c"]), | ||
| ) | ||
| args = OptunaSampler.get_var_args("discrete_uniform", range(100)) | ||
| assert len(args) == 3 | ||
| assert args[0] == min(range(100)) | ||
| assert args[1] == max(range(100)) | ||
| assert args[2] == 1 | ||
|
|
||
| # test deduce_type function | ||
| assert OptunaSampler.deduce_type(range(100)) == "discrete_uniform" | ||
| assert OptunaSampler.deduce_type([1, 2, 17, 25]) == "categorical" | ||
| assert OptunaSampler.deduce_type(preprocessing.values()) == "categorical" | ||
|
|
||
| # test best_params | ||
| best = obj_A.best_params() | ||
| assert len(best.keys()) == len(fz.variables) | ||
| assert [*best.values()][0] in preprocessing.keys() | ||
| assert [*best.values()][1] in searching.keys() | ||
|
|
||
| optuna.delete_study(name_A, storage="sqlite:///example.db") | ||
|
|
||
|
|
||
| # If I want to delete the study and start a new one the next time I run the tests | ||
| # optuna.delete_study(name_B, storage="sqlite:///example.db") | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| from tuneit import * | ||
| import numpy | ||
| from tuneit.tools.time import Time, default_timer | ||
| from tuneit.tools.base import Sampler | ||
| from tuneit.finalize import HighLevel | ||
| import itertools | ||
|
|
||
|
|
||
| def test_sampler(): | ||
| # simple example to use in tests | ||
| # building a graph with variables for sorting (preprocessing) and searching to be tuned: | ||
|
|
||
| @alternatives( | ||
| mergesort=lambda a: numpy.sort(a, kind="mergesort"), | ||
| heapsort=lambda a: numpy.sort(a, kind="heapsort"), | ||
| timsort=lambda a: numpy.array(sorted(a)), | ||
| ) | ||
| def preprocessing(array): | ||
| res = numpy.sort(array) | ||
| return res | ||
|
|
||
| @alternatives( | ||
| indices=lambda a, b: [i for i, x in enumerate(a.tolist()) if x == b][0], | ||
| array_search=lambda a, b: numpy.where(a == b)[0][0], | ||
| binary_search=lambda a, b: numpy.searchsorted(a, b), | ||
| ) | ||
| def searching(array, element): | ||
| l = array.tolist() | ||
| index = l.index(element) | ||
| return index | ||
|
|
||
| element = 65 | ||
| result = searching(preprocessing(numpy.random.randint(1000, size=(10000))), element) | ||
| fz = finalize(result) | ||
|
|
||
| callback_function = lambda fnc: Time(default_timer(fnc)) | ||
|
|
||
| obj = sample( | ||
| result, | ||
| ["preprocessing", "searching"], | ||
| callback=callback_function, | ||
| callback_calls=True, | ||
| ) | ||
| assert isinstance(obj, Sampler) | ||
| assert callable(obj.callback) | ||
| assert obj.callback == callback_function | ||
| assert len(obj.variables) == 2 | ||
| assert obj.variables[0] in fz.variables | ||
| assert obj.variables[1] in fz.variables | ||
| assert not obj.compute_kwargs | ||
| assert isinstance(obj.tunable, HighLevel) | ||
|
|
||
| assert obj.max_samples == 16 | ||
| assert obj.n_samples == 16 | ||
| assert obj.samples == tuple( | ||
| itertools.product([*preprocessing.keys()], [*searching.keys()]), | ||
| ) | ||
| values = obj.sample_values() | ||
| for a in [x[1] for x in values]: | ||
| assert isinstance(a, Time) | ||
| assert [x[0] for x in values] == list(obj.samples) | ||
| assert obj.value == fz.compute() | ||
|
|
||
| obj_B = benchmark(fz.copy(reset=True)) | ||
| assert isinstance(obj_B, Sampler) | ||
| assert obj_B.samples == obj.samples | ||
| assert obj_B.value == obj.value | ||
|
|
||
| obj_C = crosscheck(fz.copy(reset=True)) | ||
| assert isinstance(obj_C, Sampler) | ||
| values2 = obj_C.sample_values() | ||
| for a in [x[1] for x in values2]: | ||
| assert isinstance(a, bool) | ||
| assert obj_C.samples == obj.samples |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| from tuneit import * | ||
| import numpy | ||
| from tuneit.tools.tuner import Tuner | ||
| from tuneit.tools.time import Time, default_timer | ||
| from tuneit.tools.optuna import OptunaSampler | ||
| from tuneit.tools.base import Sampler | ||
| import pytest | ||
|
|
||
|
|
||
| def test_tuner(): | ||
| # simple example to use in tests | ||
| # building a graph with variables for sorting (preprocessing) and searching to be tuned: | ||
|
|
||
| @alternatives( | ||
| mergesort=lambda a: numpy.sort(a, kind="mergesort"), | ||
| heapsort=lambda a: numpy.sort(a, kind="heapsort"), | ||
| timsort=lambda a: numpy.array(sorted(a)), | ||
| ) | ||
| def preprocessing(array): | ||
| res = numpy.sort(array) | ||
| return res | ||
|
|
||
| @alternatives( | ||
| indices=lambda a, b: [i for i, x in enumerate(a.tolist()) if x == b][0], | ||
| array_search=lambda a, b: numpy.where(a == b)[0][0], | ||
| binary_search=lambda a, b: numpy.searchsorted(a, b), | ||
| ) | ||
| def searching(array, element): | ||
| l = array.tolist() | ||
| index = l.index(element) | ||
| return index | ||
|
|
||
| element = 65 | ||
| result = searching( | ||
| preprocessing(numpy.random.randint(1000, size=(10000))), element | ||
| ) # input size: 10 000, type: integers | ||
|
|
||
| # test optimise function | ||
| obj_A = optimise(result, sampler="optuna") | ||
| assert isinstance(obj_A, Tuner) | ||
|
|
||
| # test tune function | ||
| obj_B = tune(result, callback=lambda fnc: Time(default_timer(fnc))) | ||
| assert isinstance(obj_B, Tuner) | ||
|
|
||
| # test Tuner class | ||
| obj_C = Tuner( | ||
| result, sampler="optuna", callback=lambda fnc: Time(default_timer(fnc)) | ||
| ) | ||
| assert isinstance(obj_C, Tuner) | ||
| assert bool(obj_C.tuner_kwargs) | ||
| assert callable(obj_B.tuner_kwargs.get("callback", None)) | ||
| # test compute function in Tuner | ||
| assert obj_C.compute() == finalize(result).compute() | ||
| # test get_best_trial function in Tuner | ||
| res = obj_C.get_best_trial() | ||
| assert isinstance(res, dict) | ||
| assert "preprocessing" in {k.split("-")[0]: v for k, v in res.items()} | ||
| assert ( | ||
| next(v for k, v in res.items() if k.startswith("preprocessing")) | ||
| in preprocessing.keys() | ||
| ) | ||
| assert "searching" in {k.split("-")[0]: v for k, v in res.items()} | ||
| assert ( | ||
| next(v for k, v in res.items() if k.startswith("searching")) in searching.keys() | ||
| ) | ||
| # test get_sampler function in Tuner | ||
| assert obj_C.get_sampler() == OptunaSampler | ||
| assert ( | ||
| Tuner( | ||
| result, sampler=None, callback=lambda fnc: Time(default_timer(fnc)) | ||
| ).get_sampler() | ||
| == Sampler | ||
| ) | ||
| with pytest.raises(ValueError): | ||
| Tuner( | ||
| result, sampler="hello", callback=lambda fnc: Time(default_timer(fnc)) | ||
| ).get_sampler() | ||
| # test get_sampler_kwargs function in Tuner | ||
| kwargs = obj_C.get_sampler_kwargs() | ||
| assert kwargs["storage"] == "sqlite:///example.db" | ||
| assert kwargs["callback"] == obj_C.tuner_kwargs.get("callback", None) | ||
| kwargs = Tuner( | ||
| result, sampler=None, callback=lambda fnc: Time(default_timer(fnc)) | ||
| ).get_sampler_kwargs() | ||
| assert not bool(kwargs) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.