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

ASK/TELL DEVELOP #1307

Open
wants to merge 360 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
360 commits
Select commit Hold shift + click to select a range
263dce9
refactoring
jlnav Apr 12, 2024
215403e
add set_history() to generator standard
jlnav Apr 12, 2024
5ba5457
for Surmise and APOSMM, the input_H of final_tell *defaults* as None
jlnav Apr 12, 2024
14c4a38
add create_results_array to interfacer class to create an already-rea…
jlnav Apr 12, 2024
8e482d4
tentative remove of initial_ask, make num_points in ask optional
jlnav Apr 17, 2024
d92d7a5
disregard "updates" from aposmm/surmise's first ask
jlnav Apr 17, 2024
904ca39
various fixes
jlnav Apr 17, 2024
6ef8768
removing some redundant method defs, removing surmise unit test on ma…
jlnav Apr 18, 2024
7f7c4b3
first attempt to implement .ask_updates(), add to current ask/tell gens
jlnav Apr 18, 2024
858c5ad
only combine points and updates if we get updates back. otherwise jus…
jlnav Apr 19, 2024
02e60c4
only try combining also if updates is not None
jlnav Apr 19, 2024
94ad94b
Merge branch 'develop' into feature/asktell_gens
shuds13 Apr 19, 2024
1ed9022
Add RandSample ask/tell generator
shuds13 Apr 19, 2024
57db8c6
surmise needs to start first for ask to work - do so by calling super…
jlnav Apr 19, 2024
ce79b2a
surmise was creating a too-big template result array. let user specif…
jlnav Apr 19, 2024
c23476f
fix
jlnav Apr 19, 2024
9353e00
lets just make this simple for now.......
jlnav Apr 19, 2024
7f1ef57
move test_asktell_surmise in-place test to regression_tests
jlnav Apr 22, 2024
ac5ecb4
Merge branch 'develop' into experimental/class_gens_ask_tell
jlnav Apr 22, 2024
8a345f0
Merge branch 'develop' into experimental/class_gens_ask_tell
jlnav Apr 24, 2024
273ea96
Merge branch 'develop' into experimental/class_gens_ask_tell
jlnav Apr 24, 2024
f54dbc6
unique ensemble_dir_path
jlnav Apr 24, 2024
3d97790
dunno why this error occurs on tcp, but may be worth investigating...
jlnav Apr 24, 2024
9932e0a
perhaps we dont need to combine points and updates for libE. just sim…
jlnav Apr 25, 2024
aeb28db
be more careful with returning updates from surmise back to libE. kee…
jlnav Apr 25, 2024
bba59bb
the "for" condition is evaluated once, and may be inaccurate if ask/a…
jlnav Apr 26, 2024
41d429c
Merge branch 'develop' into experimental/class_gens_ask_tell
jlnav Apr 26, 2024
0953eb4
Merge branch 'develop' into experimental/class_gens_ask_tell
jlnav May 3, 2024
86000e8
Merge remote-tracking branch 'remotes/origin/feature/asktell_gens' in…
jlnav May 8, 2024
9591365
Make RandSample and ask/tell GPCAM subclasses of Generator, make test…
jlnav May 8, 2024
e225e6c
an attempt at allowing users (Optimas) to ask APOSMM for selections o…
jlnav May 10, 2024
960dd3f
cache the copy of last_ask before clearing it, primarily for results_…
jlnav May 10, 2024
39c3ab2
huh, not sure why this evaluation worked fine for me
jlnav May 14, 2024
38721f1
put back create_results_array(empty=True), which I disappeared somehow
jlnav May 14, 2024
0e7d6e2
ensure gens like APOSMM are allowed to return their entire initial sa…
jlnav May 14, 2024
4b2da4a
various adjustments to try being safer with numpy array memory
jlnav May 16, 2024
cfdc077
spellcheck
jlnav May 16, 2024
41c4772
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav May 22, 2024
f4f8d95
rearrange parameters for RandSample
jlnav May 23, 2024
4998094
rename thread attribute to self.thread for clarity
jlnav May 23, 2024
fa87f59
libE now should be able to continue with a "live" gen from a previous…
jlnav May 24, 2024
441cf06
Making new gpCAM gen class
shuds13 May 30, 2024
34e9f4a
Minor fixes to gpCAM class test
shuds13 May 31, 2024
db36ab8
Minor fixes to gpCAM class test
shuds13 May 31, 2024
cfe217a
Make rand sample test both wrapper and asktell
shuds13 May 31, 2024
e999c10
Add gen_classes sampling
shuds13 May 31, 2024
c285920
Make gen_specs generator take precedence over user specs
shuds13 Jun 1, 2024
687ea85
Remove redundant generator redirection
shuds13 Jun 1, 2024
0772deb
Revert original gen funcs
shuds13 Jun 3, 2024
91033be
Fix imports
shuds13 Jun 3, 2024
86e268d
Merge pull request #1316 from Libensemble/experimental/gen_classes
shuds13 Jun 4, 2024
2e3253a
small adjusts, plus add same seed to two aposmm tests (1 classic, 1 a…
jlnav Jun 5, 2024
f0451f7
fix seeds
jlnav Jun 5, 2024
f0769f9
first experiment with creating a RandomSample class that fits the cur…
jlnav Jun 12, 2024
bc458da
wrapper now presumably generic enough for non-x keys?
jlnav Jun 25, 2024
714c177
adds list-to-array conversion to runners.py
jlnav Jun 25, 2024
7df3447
Merge branch 'develop' into feature/asktell_from_standard
jlnav Jun 25, 2024
c791acd
more type checks
jlnav Jun 25, 2024
d4fb064
pair of functions for converting between numpy and list_of_dicts
jlnav Jul 2, 2024
bfd25af
initial changes for APOSMM returning/accepting lists of dicts
jlnav Jul 2, 2024
50a3789
bugfix
jlnav Jul 3, 2024
7581cc0
adjust runner/persistent-wrapper for new datatypes
jlnav Jul 3, 2024
f3b02d0
refactor gen classes to accept/return list-of-dicts
jlnav Jul 5, 2024
0851cad
Merge branch 'develop' into feature/asktell_from_standard
jlnav Jul 5, 2024
4557376
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Jul 10, 2024
1443cee
Merge branch 'experimental/jlnav_plus_shuds_asktell' into feature/ask…
jlnav Jul 10, 2024
815b602
tentatively switching inline conversions to wrapped ask/tells
jlnav Jul 10, 2024
4497ec4
trying out _ask_np, and _tell_np, for more efficient data-transfer in…
jlnav Jul 11, 2024
e83d75a
upon using a LibEnsembleGenInterfacer, talk to that class using _ask_…
jlnav Jul 12, 2024
0fda5db
tentative additional subclass of Generator, with abstractmethods _ask…
jlnav Jul 17, 2024
0750fec
runners.py now interacts with LibensembleGenerator class, makes sure …
jlnav Jul 17, 2024
cf06598
remove leading underscores, _ask_np and _tell_np are now ask_np and t…
jlnav Jul 17, 2024
fe6eedd
remember, the LibensembleGenInterfacer class needs to ask the entire …
jlnav Jul 17, 2024
bc1bf6a
Merge pull request #1328 from Libensemble/feature/asktell_from_standard
jlnav Jul 18, 2024
55011d7
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Jul 18, 2024
3363e4a
rename LibensembleGenInterfacer to LibensembleGenThreadInterfacer
jlnav Jul 18, 2024
25b4d4d
move numpy-> list-of-dicts converters out of generators into libensem…
jlnav Jul 18, 2024
1ca123e
small docstrings for current classes in generators.py, should probabl…
jlnav Jul 18, 2024
838057b
refactor + more comments throughout AskTellGenRunner
jlnav Jul 18, 2024
2638d33
necessary, but currently unfunctional refactoring of the AskTellGenRu…
jlnav Jul 19, 2024
c3c19e1
replacing __new__ magic in Runner superclass with factory function fo…
jlnav Jul 19, 2024
4d48ab9
typo
jlnav Jul 19, 2024
9f7d485
fix Runners unit test
jlnav Jul 22, 2024
30bf2d2
Merge branch 'main' into develop
jlnav Jul 26, 2024
0c3307b
Merge branch 'develop' of https://github.com/Libensemble/libensemble …
jlnav Jul 26, 2024
009f324
Merge branch 'develop' of https://github.com/Libensemble/libensemble …
jlnav Jul 29, 2024
68c9b7c
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Jul 29, 2024
06995d0
type/bug fixes
jlnav Jul 29, 2024
9e6c63c
isort
jmlarson1 Aug 1, 2024
a698385
black
jmlarson1 Aug 1, 2024
9da1ab8
ask_np / tell_np to ask_numpy / tell_numpy
jlnav Aug 1, 2024
c2c7feb
an attempt at some anti-redundancy in runners.py :)
jlnav Aug 1, 2024
9691602
small adjustments from PR, plus first doc-page for ask/tell generator…
jlnav Aug 1, 2024
d5eaddb
simplifications from codeclimate
jlnav Aug 5, 2024
7bad6aa
Update gpCAM class gen
shuds13 Aug 5, 2024
bd996e2
docs fix, plus refactor aposmm_nlopt_asktell reg test to use kwargs'd…
jlnav Aug 6, 2024
7d0bcf8
Trim RNG lines in gpCAM class
shuds13 Aug 7, 2024
136c046
Add and test a sampling gen in standardized interface
shuds13 Aug 7, 2024
c930cde
flake8...?
jlnav Aug 7, 2024
2697af9
move aposmm/surmise asktell classes to gen_classes, a handful of para…
jlnav Aug 7, 2024
a3c09a2
tiny fixes and comments
jlnav Aug 7, 2024
4444a71
gen batch_size and initial_batch_size aren't used. lets remove them
jlnav Aug 7, 2024
4489d42
dont import gpcam classes into gen_classes level
jlnav Aug 7, 2024
c9c4671
presumably fix surmise asktell test?
jlnav Aug 7, 2024
601af44
actually fix surmise test. make sure that when passing around single …
jlnav Aug 7, 2024
d454b5c
similarly exclude gpcam_class test from tests, for now
jlnav Aug 8, 2024
92e22e4
experimenting with batch_size and initial_batch_size gen_specs options
jlnav Aug 8, 2024
d14f4d2
subsequent batch_sizes are either back_size or len(H_in)
jlnav Aug 9, 2024
e27487d
now test in test_sampling_asktell_gen
jlnav Aug 9, 2024
a6feb77
cover asking aposmm for num points
jlnav Aug 9, 2024
12a133b
various coverage adjustments and fixes
jlnav Aug 12, 2024
de1916a
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Aug 16, 2024
ee2508e
initial commit, creating ask/tell gen unit test, base LibensembleGene…
jlnav Aug 16, 2024
070fc6f
add test, arrays become flattened dicts in np_to_list_dicts
jlnav Aug 16, 2024
a969f50
remove debug statement
jlnav Aug 16, 2024
6eb5fe8
additional attempts to unflatten the input dict...
jlnav Aug 16, 2024
1261274
fix index ordering, cleanup/complete tentatively unit test
jlnav Aug 19, 2024
d960b96
passthrough kwargs to superclasses, try to handle empty lists for sin…
jlnav Aug 19, 2024
3ce0ca2
better handling of multi-dim and single-dim output-array item assignm…
jlnav Aug 19, 2024
09cb4a6
comments
jlnav Aug 19, 2024
601f02c
adjust persistent_gen_wrapper, fix UniformSampleDicts
jlnav Aug 19, 2024
6733fe5
fix ordering of parameters in implemented ask/tell classes and parent…
jlnav Aug 21, 2024
7466100
better detecting of combinable names, by stripping out the numeric su…
jlnav Aug 21, 2024
751de5e
deal with keys that end with integers, but aren't similar to any othe…
jlnav Aug 21, 2024
18e7079
keyword assignment of gen_specs to Surmise
jlnav Aug 22, 2024
a34d589
forgot another keyword surmise assignment
jlnav Aug 22, 2024
5f33724
add unit test for awkward H and checking routine from shuds, add case…
jlnav Aug 26, 2024
41c16b7
add optional dtype argument for list_dicts_to_np to preempt "dtype di…
jlnav Aug 26, 2024
4860428
replace _to_array with list_dicts_to_np with dtype parameter. list_di…
jlnav Aug 26, 2024
ced8992
fix
jlnav Aug 26, 2024
cbfdf0b
Merge branch 'develop' into feature/flatten_asktell_dict_values
jlnav Aug 29, 2024
4261ca8
LibensembleGenerator can provide matching dtype for list_dicts_to_np,…
jlnav Aug 29, 2024
460bbe3
fix
jlnav Aug 29, 2024
7fdd8a6
ahhhh, just gen_specs['out']'s dtype isn't sufficient. persis_in, des…
jlnav Aug 29, 2024
69b0584
removing hardcoded gen_specs.out, removing hardcoded persis_info.nwor…
jlnav Sep 12, 2024
8c01ca9
clarify a comment
jlnav Sep 12, 2024
4541d8a
as discussed, currently gen_specs['out'] must be provided to a gen in…
jlnav Sep 12, 2024
345aea3
Merge pull request #1409 from Libensemble/feature/flatten_asktell_dic…
jlnav Sep 12, 2024
fe7629e
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Sep 12, 2024
0d7e1a3
specify gen_specs.out dtype to conversion in independent borehole-call
jlnav Sep 12, 2024
c7d1cb1
dont assert cancelled sims in asktell surmise test (at this time)
jlnav Sep 13, 2024
94de46f
slotting in variables/objectives into Generator abc. changes to subcl…
jlnav Sep 19, 2024
80df25f
try an indexing fix
jlnav Sep 20, 2024
b5d8bcf
dont require an explicit "None" to shut down a threaded generator
jlnav Sep 20, 2024
f52bf92
various internal logics and routines for buffering results passed bac…
jlnav Sep 25, 2024
5434dfa
fixes
jlnav Sep 25, 2024
0ab048d
given that persis_info available to the aposmm thread needs nworkers.…
jlnav Sep 25, 2024
7a9a2d8
fix
jlnav Sep 25, 2024
a68ffb8
tiny fix
jlnav Sep 27, 2024
5228711
tiny fix
jlnav Sep 27, 2024
1ef5898
undo some unneeded changes
jlnav Sep 27, 2024
8371d97
enormously ugly iterating over the buffering, tell_numpy process. got…
jlnav Sep 27, 2024
092be69
Merge branch 'develop' into feature/adjusts_for_optimas
jlnav Oct 4, 2024
3ebc467
making some attributes private
jlnav Oct 4, 2024
1159e74
Merge branch 'develop' into feature/adjusts_for_optimas
jlnav Oct 7, 2024
138c89e
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Oct 7, 2024
2922259
Merge branch 'experimental/jlnav_plus_shuds_asktell' into feature/adj…
jlnav Oct 7, 2024
c2a2802
comments, reorganizing tell_numpy as usual
jlnav Oct 7, 2024
5a2eb09
using gen_specs.batch_size and gen_specs.initial_batch_size to try co…
jlnav Oct 7, 2024
10accde
Merge branch 'develop' into feature/adjusts_for_optimas
jlnav Oct 8, 2024
aa8ad57
use base MPIRunner if detection fails, so KeyError doesnt occur?
jlnav Oct 8, 2024
6712f1e
Merge branch 'bugfix/detect_mpiexec_mpis' into feature/adjusts_for_op…
jlnav Oct 8, 2024
1eec392
various fixes as usual, plus experimenting with running gen-on-proces…
jlnav Oct 10, 2024
c4418fb
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Oct 14, 2024
2b8e537
initial commit - adding variables/objectives to initializer signature…
jlnav Oct 14, 2024
70dde7b
recreate the buffer after the results' final opportunity to send onto…
jlnav Oct 14, 2024
484304b
dont need sim_id sorting
jlnav Oct 14, 2024
b0897d0
the initial sample being done is determined by the total number of re…
jlnav Oct 14, 2024
cdcb2d8
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Oct 15, 2024
57bbfb1
it was long-past time to give up on the super-complicated slot-in-dat…
jlnav Oct 17, 2024
dbd19fd
Merge pull request #1433 from Libensemble/feature/adjusts_for_optimas
jlnav Oct 17, 2024
994b652
enormously critical bugfix; optimas workflow now finds minima
jlnav Oct 17, 2024
64c2cd1
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Oct 18, 2024
3104240
experiment with UniformSampleDicts using variables/objectiveso
jlnav Oct 18, 2024
3d262fb
i wonder if we can determine lb, ub, and n based on the contents of s…
jlnav Oct 21, 2024
847a617
APOSMM can now accept variables and objectives instead of needing ub,…
jlnav Oct 22, 2024
f45ddbe
cleanup the removed validator; since gen_specs['out'] can be absent
jlnav Oct 22, 2024
26f1d73
cleanup/fixes
jlnav Oct 22, 2024
10e96d8
stop kwargs from replacing entire gen_specs.user; try out vars/objs w…
jlnav Oct 22, 2024
0290deb
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Oct 22, 2024
e01e87b
removing ask/tell generator wrapper user function; removing from samp…
jlnav Oct 22, 2024
a1eb450
adjust ask/tell gpcam test
jlnav Oct 23, 2024
23b1549
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Oct 23, 2024
1b4c2c6
we dont need to run multiple tests for asktell surmise
jlnav Oct 24, 2024
5f777c2
additional experiments with vars/objs, including seeing if we can app…
jlnav Oct 25, 2024
a165cdd
tiny changes for slotting in data back from the waket/optimas workflow
jlnav Oct 25, 2024
ac5467b
moving logic for determining lb and ub from variables into parent cla…
jlnav Oct 28, 2024
85507a4
init pair of functions for mapping, slot in where they'll be called
jlnav Oct 28, 2024
fc30284
remove a debugging print
jlnav Oct 28, 2024
98267e3
small fixes, including slotting-in x-on-cube, removing hardcoded -10 …
jlnav Oct 30, 2024
74579d5
simplifications from code-review; need to determine reason for hang i…
jlnav Oct 30, 2024
63ef323
i determined that besides having asked for at least as many points as…
jlnav Oct 30, 2024
1b1cd59
better check: all generated sim_ids have returned to the buffer
jlnav Oct 30, 2024
dcb3486
fix LibensembleGenThreadInterfacer._set_sim_ended to use results' dty…
jlnav Oct 30, 2024
6828fe0
whoops, fix dtype definition in set_sim_ended
jlnav Oct 30, 2024
e443af9
cleanup unused attributes
jlnav Oct 30, 2024
a1937a9
better buffer updating suggestion from shuds
jlnav Oct 31, 2024
dedef4c
fix ask-the-genf condition to accomodate after initial sample has com…
jlnav Oct 31, 2024
4b812d6
fix set_sim_ended new array dtype specification
jlnav Oct 31, 2024
f9e3cba
small fixes, and first tentative implementation of converter for xs t…
jlnav Nov 1, 2024
14c36fa
perhaps the input conversion will be easier on a numpy array?
jlnav Nov 1, 2024
25299e7
tentatively complete converter for vars/objs -> x/f. but those xs and…
jlnav Nov 1, 2024
f0736fb
some cleanup
jlnav Nov 1, 2024
7fa4d1e
fix continue-condition to occur earlier if we're looking at keys we d…
jlnav Nov 4, 2024
14daf3c
test fixes, plus if our gen naturally returns the requested variables…
jlnav Nov 4, 2024
114c7a4
fix asktell_gen functionality test - including removing wrapper tests…
jlnav Nov 4, 2024
507bc0a
just use UniformSample class
jlnav Nov 4, 2024
18a52c9
remove ask/tell surmise and ask/tell surmise test - they were proof-o…
jlnav Nov 4, 2024
231e6f0
fix import
jlnav Nov 4, 2024
eaebbff
remove the other ask/tell surmise test
jlnav Nov 4, 2024
043feeb
renable persistent_aposmm unit test
jlnav Nov 5, 2024
c66f10b
gpCAM class uses returned x
shuds13 Nov 5, 2024
3d7981b
Convert numpy scalar types
shuds13 Nov 5, 2024
c380595
preparing to add variables_mapping to LibensembleGenerator parent cla…
jlnav Nov 6, 2024
fdcfd66
Merge pull request #1453 from Libensemble/experimental/optimas_waket_…
jlnav Nov 7, 2024
1e0abd3
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 7, 2024
c7ea54b
intermediate work on passing mapping into np_to_list_dicts. need to p…
jlnav Nov 7, 2024
c111afd
Call setup on first ask
shuds13 Nov 8, 2024
0ee448c
use mapping to construct list_dicts_to_np dtype when provided
jlnav Nov 8, 2024
bb37f4b
additional work on replacing dict keys with xs and fs
jlnav Nov 8, 2024
38b3967
some cleanup of generators.py in anticipation of the changes to the d…
jlnav Nov 8, 2024
4b49233
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 11, 2024
1d213ef
dont try to determine dtype for fields that aren't actually in the in…
jlnav Nov 11, 2024
f8c5eaf
finalize mapping support within list_dicts_to_np, now need to refacto…
jlnav Nov 11, 2024
dff6bad
refactoring
jlnav Nov 11, 2024
c1ec7f6
tiny fixes; need to figure out why aposmm_nlopt reg test is hanging
jlnav Nov 11, 2024
a5133b9
runners.py no longer calls setup() on gen
jlnav Nov 11, 2024
682daa8
rename a handful of asktell tests to have a test_asktell prefix
jlnav Nov 12, 2024
09ebdbc
remove redundant .setup calls that also cause hangs
jlnav Nov 12, 2024
9f200f0
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 12, 2024
cf5ac63
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Nov 13, 2024
f2ef248
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 13, 2024
2c6a9c4
lock nlopt to 2.8.0?
jlnav Nov 13, 2024
7224de3
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Nov 14, 2024
99a7a2c
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 14, 2024
e8b7052
Feature/spawn with interfacer (#1464)
shuds13 Nov 14, 2024
23e5164
use macOS-supported condition to check if gen_f has enqueued any outb…
jlnav Nov 14, 2024
06c14d7
Merge pull request #1467 from Libensemble/asktell/macos_queue_fixes
jlnav Nov 14, 2024
bc1587e
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 14, 2024
5c2308d
avoid redundant install of nlopt?
jlnav Nov 14, 2024
0d146fc
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Nov 20, 2024
ef906d5
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 20, 2024
9d07e6c
Merge branch 'develop' into experimental/jlnav_plus_shuds_asktell
jlnav Nov 20, 2024
902b7f0
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Nov 20, 2024
64b6401
swap sim_id with _id when data goes out from gen. swap _id with sim_i…
jlnav Dec 3, 2024
ab09b9f
Merge pull request #1480 from Libensemble/asktell/under_id
jlnav Dec 3, 2024
d66dafb
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/var…
jlnav Dec 4, 2024
f4a9691
Merge pull request #1448 from Libensemble/asktell/variables_objectives
jlnav Dec 4, 2024
6fb608e
Merge branch 'experimental/jlnav_plus_shuds_asktell' into asktell/try…
jlnav Dec 4, 2024
f926bfa
Merge pull request #1451 from Libensemble/asktell/try_removing_wrapper
jlnav Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ ignore:
- "libensemble/sim_funcs/executor_hworld.py"
- "libensemble/gen_funcs/persistent_ax_multitask.py"
- "libensemble/gen_funcs/persistent_gpCAM.py"
- "libensemble/gen_classes/gpCAM.py"
21 changes: 21 additions & 0 deletions docs/function_guides/ask_tell_generator.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

Ask/Tell Generators
===================

**BETA - SUBJECT TO CHANGE**

These generators, implementations, methods, and subclasses are in BETA, and
may change in future releases.

The Generator interface is expected to roughly correspond with CAMPA's standard:
https://github.com/campa-consortium/generator_standard

libEnsemble is in the process of supporting generator objects that implement the following interface:

.. automodule:: generators
:members: Generator LibensembleGenerator
:undoc-members:

.. autoclass:: Generator
:member-order: bysource
:members:
1 change: 1 addition & 0 deletions docs/function_guides/function_guide_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ These guides describe common development patterns and optional components:
:caption: Writing User Functions

generator
ask_tell_generator
simulator
allocator
sim_gen_alloc_api
Expand Down
1 change: 1 addition & 0 deletions libensemble/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
from libensemble import logger

from .ensemble import Ensemble
from .generators import Generator
2 changes: 1 addition & 1 deletion libensemble/executors/mpi_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def get_runner(mpi_runner_type, runner_name=None, platform_info=None):
"msmpi": MSMPI_MPIRunner,
"custom": MPIRunner,
}
mpi_runner = mpi_runners[mpi_runner_type]
mpi_runner = mpi_runners.get(mpi_runner_type, MPIRunner)
if runner_name is not None:
runner = mpi_runner(run_command=runner_name, platform_info=platform_info)
else:
Expand Down
3 changes: 3 additions & 0 deletions libensemble/gen_classes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .aposmm import APOSMM # noqa: F401
from .sampling import UniformSample, UniformSampleDicts # noqa: F401
from .surmise import Surmise # noqa: F401
123 changes: 123 additions & 0 deletions libensemble/gen_classes/aposmm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import copy
from typing import List

import numpy as np
from numpy import typing as npt

from libensemble.generators import LibensembleGenThreadInterfacer
from libensemble.message_numbers import EVAL_GEN_TAG, PERSIS_STOP
from libensemble.tools import add_unique_random_streams


class APOSMM(LibensembleGenThreadInterfacer):
"""
Standalone object-oriented APOSMM generator
"""

def __init__(
self, History: npt.NDArray = [], persis_info: dict = {}, gen_specs: dict = {}, libE_info: dict = {}, **kwargs
) -> None:
from libensemble.gen_funcs.persistent_aposmm import aposmm

gen_specs["gen_f"] = aposmm
if not gen_specs.get("out"): # gen_specs never especially changes for aposmm even as the problem varies
n = len(kwargs["lb"]) or len(kwargs["ub"])
gen_specs["out"] = [
("x", float, n),
("x_on_cube", float, n),
("sim_id", int),
("local_min", bool),
("local_pt", bool),
]
gen_specs["persis_in"] = ["x", "f", "local_pt", "sim_id", "sim_ended", "x_on_cube", "local_min"]
if not persis_info:
persis_info = add_unique_random_streams({}, 2, seed=4321)[1]
super().__init__(History, persis_info, gen_specs, libE_info, **kwargs)
if not self.persis_info.get("nworkers"):
self.persis_info["nworkers"] = gen_specs["user"]["max_active_runs"] # ??????????
Copy link
Member

Choose a reason for hiding this comment

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

This is not nworkers. It could be less than nworkers.

Copy link
Member Author

Choose a reason for hiding this comment

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

Right. I'll find a better way to specify nworkers to aposmm

Copy link
Member

Choose a reason for hiding this comment

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

If its not used until the main loop, can it be captured, or atleast checked later?

Copy link
Member

Choose a reason for hiding this comment

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

We also need to review what is happening with gen_specs and esp. gen_specs['out'], which is not SSoT.

self.all_local_minima = []
self._ask_idx = 0
self._last_ask = None
self._tell_buf = None
self._n_buffd_results = 0
self._n_total_results = 0
self._told_initial_sample = False

def _slot_in_data(self, results):
"""Slot in libE_calc_in and trial data into corresponding array fields. *Initial sample only!!*"""
Copy link
Member

Choose a reason for hiding this comment

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

this is what you want:
self._tell_buf[self._n_buffd_results:self._n_buffd_results + len(results)] = results

self._tell_buf["f"][self._n_buffd_results] = results["f"]
self._tell_buf["x"][self._n_buffd_results] = results["x"]
self._tell_buf["sim_id"][self._n_buffd_results] = results["sim_id"]
self._tell_buf["x_on_cube"][self._n_buffd_results] = results["x_on_cube"]
self._tell_buf["local_pt"][self._n_buffd_results] = results["local_pt"]

Check warning on line 52 in libensemble/gen_classes/aposmm.py

View check run for this annotation

Codecov / codecov/patch

libensemble/gen_classes/aposmm.py#L48-L52

Added lines #L48 - L52 were not covered by tests

@property
def _array_size(self):
"""Output array size must match either initial sample or N points to evaluate in parallel."""
user = self.gen_specs["user"]
return user["initial_sample_size"] if not self._told_initial_sample else user["max_active_runs"]

@property
def _enough_initial_sample(self):
"""We're typically happy with at least 90% of the initial sample, or we've already told the initial sample"""
return (
self._n_buffd_results >= self.gen_specs["user"]["initial_sample_size"] - 10
Copy link
Member

Choose a reason for hiding this comment

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

this line looks very dubious. Why is 10 a hardcoded value?

) or self._told_initial_sample

def ask_numpy(self, num_points: int = 0) -> npt.NDArray:
"""Request the next set of points to evaluate, as a NumPy array."""
if (self._last_ask is None) or (
self._ask_idx >= len(self._last_ask)
): # haven't been asked yet, or all previously enqueued points have been "asked"
self._ask_idx = 0
self._last_ask = super().ask_numpy(num_points)
if self._last_ask[
"local_min"
].any(): # filter out local minima rows, but they're cached in self.all_local_minima
min_idxs = self._last_ask["local_min"]
self.all_local_minima.append(self._last_ask[min_idxs])
self._last_ask = self._last_ask[~min_idxs]
if num_points > 0: # we've been asked for a selection of the last ask
results = np.copy(

Check warning on line 81 in libensemble/gen_classes/aposmm.py

View check run for this annotation

Codecov / codecov/patch

libensemble/gen_classes/aposmm.py#L81

Added line #L81 was not covered by tests
self._last_ask[self._ask_idx : self._ask_idx + num_points]
Copy link
Member

@shuds13 shuds13 Oct 29, 2024

Choose a reason for hiding this comment

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

When we are in a situation (perhaps in error) where APOSMM does not give us enough points (e.g. the current ask is for 6, but APOSMM has only supplied one) then this gets filled up with empty points. This should be handled somehow. If it should never arise, then as an error condition.

) # if resetting _last_ask later, results may point to "None"
self._ask_idx += num_points
return results

Check warning on line 85 in libensemble/gen_classes/aposmm.py

View check run for this annotation

Codecov / codecov/patch

libensemble/gen_classes/aposmm.py#L84-L85

Added lines #L84 - L85 were not covered by tests
results = np.copy(self._last_ask)
self.results = results
self._last_ask = None
return results

def tell_numpy(self, results: npt.NDArray, tag: int = EVAL_GEN_TAG) -> None:
if (results is None and tag == PERSIS_STOP) or len(
results
) == self._array_size: # told to stop, by final_tell or libE
self._told_initial_sample = True # we definitely got an initial sample already if one matches
super().tell_numpy(results, tag)
return

if (
self._n_buffd_results == 0 # ONLY NEED TO BUFFER RESULTS FOR INITIAL SAMPLE????
): # Optimas prefers to give back chunks of initial_sample. So we buffer them
self._tell_buf = np.zeros(self._array_size, dtype=self.gen_specs["out"] + [("f", float)])

if not self._enough_initial_sample:
self._slot_in_data(np.copy(results))
self._n_buffd_results += len(results)

Check warning on line 106 in libensemble/gen_classes/aposmm.py

View check run for this annotation

Codecov / codecov/patch

libensemble/gen_classes/aposmm.py#L105-L106

Added lines #L105 - L106 were not covered by tests
self._n_total_results += len(results)

if not self._told_initial_sample and self._enough_initial_sample:
self._tell_buf = self._tell_buf[self._tell_buf["sim_id"] != 0]
Copy link
Member

Choose a reason for hiding this comment

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

Why getting rid of sim_id 0?

super().tell_numpy(self._tell_buf, tag)
self._told_initial_sample = True
self._n_buffd_results = 0

Check warning on line 113 in libensemble/gen_classes/aposmm.py

View check run for this annotation

Codecov / codecov/patch

libensemble/gen_classes/aposmm.py#L110-L113

Added lines #L110 - L113 were not covered by tests

elif self._told_initial_sample: # probably libE: given back smaller selection. but from alloc, so its ok?
super().tell_numpy(results, tag)
self._n_buffd_results = 0 # dont want to send the same point more than once. slotted in earlier

def ask_updates(self) -> List[npt.NDArray]:
"""Request a list of NumPy arrays containing entries that have been identified as minima."""
minima = copy.deepcopy(self.all_local_minima)
self.all_local_minima = []
return minima
155 changes: 155 additions & 0 deletions libensemble/gen_classes/gpCAM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"""Generator class exposing gpCAM functionality"""

import time
from typing import List

import numpy as np
from gpcam import GPOptimizer as GP
from numpy import typing as npt

# While there are class / func duplicates - re-use functions.
from libensemble.gen_funcs.persistent_gpCAM import (
_calculate_grid_distances,
_eval_var,
_find_eligible_points,
_generate_mesh,
_read_testpoints,
)
from libensemble.generators import LibensembleGenerator

__all__ = [
"GP_CAM",
"GP_CAM_Covar",
]


# Note - batch size is set in wrapper currently - and passed to ask as n_trials.
# To support empty ask(), add batch_size back in here.


# Equivalent to function persistent_gpCAM_ask_tell
class GP_CAM(LibensembleGenerator):
"""
This generation function constructs a global surrogate of `f` values.

It is a batched method that produces a first batch uniformly random from
(lb, ub). On subequent iterations, it calls an optimization method to
produce the next batch of points. This optimization might be too slow
(relative to the simulation evaluation time) for some use cases.
"""

def _initialize_gpCAM(self, user_specs):
"""Extract user params"""
# self.b = user_specs["batch_size"]
self.lb = np.array(user_specs["lb"])
self.ub = np.array(user_specs["ub"])
self.n = len(self.lb) # dimension
assert isinstance(self.n, int), "Dimension must be an integer"
assert isinstance(self.lb, np.ndarray), "lb must be a numpy array"
assert isinstance(self.ub, np.ndarray), "ub must be a numpy array"
self.all_x = np.empty((0, self.n))
self.all_y = np.empty((0, 1))
np.random.seed(0)

Copy link
Member

@shuds13 shuds13 Jul 31, 2024

Choose a reason for hiding this comment

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

We need to decide __init__ interface.
We questioned before whether we keep the same interface - which mirrors the current gen_f, or to rearrange, as H is often not given (basically an H0). So it could be gen_specs first. I'm leaning towards keeping the original ordering as it mirrors our user functions, but this should be discussed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fair enough. My opinion/intuition is a user is more likely to prefer either "classical" gens (e.g. Jeff) or ask/tell gens (e.g. other CAMPA folks). With these gens' interfaces and users being so different, I don't think an arguably simpler rearrangement of the input parameters is too confusing.

Similarly to how some people prefer numpy or pandas; they do similar things, but their interfaces being different isn't a point of contention.

I'd also lean towards if someone were to initialize some object, like a gen, themselves, they'd prefer their specifications be provided as early and clearly as possible:

my_gen = Generator(param=1,
     option="two",
)

vs.

my_gen = Generator(None,
     {},
     {"param": 1, "option": "two"},
     {},
)

def __init__(self, H, persis_info, gen_specs, libE_info=None):
Copy link
Member

Choose a reason for hiding this comment

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

I will put above _initialize_gpcAM

Copy link
Member

Choose a reason for hiding this comment

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

and make _initialize_gpcAM _initialize_gpCAM

self.H = H # Currently not used - could be used for an H0
self.persis_info = persis_info
self.gen_specs = gen_specs
self.libE_info = libE_info

self.U = self.gen_specs["user"]
self._initialize_gpCAM(self.U)
self.rng = self.persis_info["rand_stream"]

self.my_gp = None
self.noise = 1e-8 # 1e-12
self.ask_max_iter = self.gen_specs["user"].get("ask_max_iter") or 10

def ask_numpy(self, n_trials: int) -> npt.NDArray:
if self.all_x.shape[0] == 0:
self.x_new = self.rng.uniform(self.lb, self.ub, (n_trials, self.n))
else:
start = time.time()
self.x_new = self.my_gp.ask(
input_set=np.column_stack((self.lb, self.ub)),
n=n_trials,
pop_size=n_trials,
acquisition_function="total correlation",
max_iter=self.ask_max_iter, # Larger takes longer. gpCAM default is 20.
)["x"]
print(f"Ask time:{time.time() - start}")
H_o = np.zeros(n_trials, dtype=self.gen_specs["out"])
H_o["x"] = self.x_new
return H_o

def tell_numpy(self, calc_in: npt.NDArray) -> None:
if calc_in is not None:
self.y_new = np.atleast_2d(calc_in["f"]).T
nan_indices = [i for i, fval in enumerate(self.y_new) if np.isnan(fval[0])]
self.x_new = np.delete(self.x_new, nan_indices, axis=0)
self.y_new = np.delete(self.y_new, nan_indices, axis=0)

self.all_x = np.vstack((self.all_x, self.x_new))
self.all_y = np.vstack((self.all_y, self.y_new))

noise_var = self.noise * np.ones(len(self.all_y))
if self.my_gp is None:
self.my_gp = GP(self.all_x, self.all_y.flatten(), noise_variances=noise_var)
else:
self.my_gp.tell(self.all_x, self.all_y.flatten(), noise_variances=noise_var)
self.my_gp.train()


class GP_CAM_Covar(GP_CAM):
"""
This generation function constructs a global surrogate of `f` values.

It is a batched method that produces a first batch uniformly random from
(lb, ub) and on following iterations samples the GP posterior covariance
function to find sample points.
"""

def __init__(self, H, persis_info, gen_specs, libE_info=None):
super().__init__(H, persis_info, gen_specs, libE_info)
self.test_points = _read_testpoints(self.U)
self.x_for_var = None
self.var_vals = None
if self.U.get("use_grid"):
self.num_points = 10
self.x_for_var = _generate_mesh(self.lb, self.ub, self.num_points)
self.r_low_init, self.r_high_init = _calculate_grid_distances(self.lb, self.ub, self.num_points)

def ask_numpy(self, n_trials: int) -> List[dict]:
if self.all_x.shape[0] == 0:
x_new = self.rng.uniform(self.lb, self.ub, (n_trials, self.n))
else:
if not self.U.get("use_grid"):
x_new = self.x_for_var[np.argsort(self.var_vals)[-n_trials:]]
else:
r_high = self.r_high_init
r_low = self.r_low_init
x_new = []
r_cand = r_high # Let's start with a large radius and stop when we have batchsize points

sorted_indices = np.argsort(-self.var_vals)
while len(x_new) < n_trials:
x_new = _find_eligible_points(self.x_for_var, sorted_indices, r_cand, n_trials)
if len(x_new) < n_trials:
r_high = r_cand
r_cand = (r_high + r_low) / 2.0

self.x_new = x_new
H_o = np.zeros(n_trials, dtype=self.gen_specs["out"])
H_o["x"] = self.x_new
return H_o

def tell_numpy(self, calc_in: npt.NDArray):
if calc_in is not None:
super().tell_numpy(calc_in)
if not self.U.get("use_grid"):
n_trials = len(self.y_new)
self.x_for_var = self.rng.uniform(self.lb, self.ub, (10 * n_trials, self.n))

self.var_vals = _eval_var(
self.my_gp, self.all_x, self.all_y, self.x_for_var, self.test_points, self.persis_info
)
Loading