@@ -158,6 +158,19 @@ def _start_generator_loop(self, tag, Work, H_in):
158158 self ._convert_initial_ingest (H_in )
159159 return self ._loop_over_gen (tag , Work , H_in )
160160
161+ def _create_initial_sample (self , sample_method , num_points ):
162+ """Create initial sample points using the specified sampling method."""
163+ from libensemble .gen_classes .sampling import UniformSample
164+
165+ vocs = self .specs .get ("vocs" )
166+ samplers = {
167+ "uniform" : UniformSample ,
168+ }
169+ if sample_method not in samplers :
170+ raise ValueError (f"Unknown initial_sample_method: { sample_method !r} . Supported: { list (samplers .keys ())} " )
171+ sampler = samplers [sample_method ](vocs = vocs )
172+ return sampler .suggest (num_points )
173+
161174 def _persistent_result (self , calc_in , persis_info , libE_info ):
162175 """Setup comms with manager, setup gen, loop gen to completion, return gen's results"""
163176 self .ps = PersistentSupport (libE_info , EVAL_GEN_TAG )
@@ -166,14 +179,32 @@ def _persistent_result(self, calc_in, persis_info, libE_info):
166179 if calc_in is not None and len (calc_in ) > 0 :
167180 self ._convert_initial_ingest (calc_in )
168181
169- # libE gens will hit the following line, but list_dicts_to_np will passthrough if the output is a numpy array
170- H_out = list_dicts_to_np (
171- self ._get_initial_suggest (libE_info ),
172- dtype = self .specs .get ("out" ),
173- mapping = getattr (self .gen , "variables_mapping" , {}),
174- )
175- tag , Work , H_in = self .ps .send_recv (H_out ) # evaluate the initial sample
176- final_H_out = self ._start_generator_loop (tag , Work , H_in )
182+ sample_method = self .specs .get ("initial_sample_method" )
183+ if sample_method is not None :
184+ # libEnsemble produces the initial sample, evaluates it, and
185+ # ingests results into the generator before optimization begins.
186+ initial_batch = self .specs .get ("initial_batch_size" )
187+ if not initial_batch :
188+ raise ValueError ("initial_sample_method requires initial_batch_size to be set in GenSpecs." )
189+ H_sample = list_dicts_to_np (
190+ self ._create_initial_sample (sample_method , initial_batch ),
191+ dtype = self .specs .get ("out" ),
192+ mapping = getattr (self .gen , "variables_mapping" , {}),
193+ )
194+ tag , Work , H_in = self .ps .send_recv (H_sample )
195+ self ._convert_initial_ingest (H_in )
196+ # Generator now has evaluated data — enter the normal loop
197+ final_H_out = self ._loop_over_gen (tag , Work , H_in )
198+ else :
199+ # Generator handles its own initial sampling
200+ H_out = list_dicts_to_np (
201+ self ._get_initial_suggest (libE_info ),
202+ dtype = self .specs .get ("out" ),
203+ mapping = getattr (self .gen , "variables_mapping" , {}),
204+ )
205+ tag , Work , H_in = self .ps .send_recv (H_out ) # evaluate the initial sample
206+ final_H_out = self ._start_generator_loop (tag , Work , H_in )
207+
177208 self .gen .finalize ()
178209 return final_H_out , FINISHED_PERSISTENT_GEN_TAG
179210
0 commit comments