Commit 61eb8c84 authored by David Hendriks's avatar David Hendriks
Browse files

Added functionalities around grid code generation, like accepting custom...

Added functionalities around grid code generation, like accepting custom defined functions, exporting it to a file and saving it to grid_options
parent 6904c611
Loading
Loading
Loading
Loading
+25 −11
Original line number Diff line number Diff line
@@ -471,30 +471,28 @@ class Population(object):
        # TODO: make a generator for this.  
        # TODO: Add correct logging everywhere
        # TODO: add different types of grid. 
        # TODO: Load the generated file and execute.
        # TODO: add part to handle separation if orbital_period is added
        """


        # Some local values
        code_string = ""
        depth = 0
        indent = '    '

        # Set some values in the generated code:

        # TODO: add imports
        # TODO: 

        #
        # Import packages
        code_string += "from binarycpython.utils.probability_distributions import *\n"  
        code_string += "import math\n"
        code_string += "import numpy as np\n"
        code_string += "\n\n"

        # Make the function
        code_string += "def grid_code(self):\n"

        code_string += "def grid_code():\n"

        # Increase depth 
        depth += 1

        # 
        # Set some values in the generated code:
        code_string += indent*depth + "starcount = 0\n"
        code_string += indent*depth + "probabilities = {}\n"
        code_string += indent*depth + "parameter_dict = {}\n"
@@ -510,6 +508,15 @@ class Population(object):
            print("Constructing/adding: {}".format(el[0]))
            grid_variable = el[1]

            # If the grid variable has a condition, write the check and the action
            if grid_variable['condition']:
                # Add condition check
                code_string += indent * depth + 'if not {}:'.format(grid_variable['condition']) + '\n'

                # Add condition failed action: #TODO: add correct exception error
                code_string += indent * (depth + 1) + 'print("Condition not met!")'.format(grid_variable['condition']) + '\n'            
                code_string += indent * (depth + 1) + 'raise ValueError'.format(grid_variable['condition']) + '\n'

            # Adding for loop structure
            code_string += indent * depth + 'for {} in {}:'.format(grid_variable['name'], grid_variable['spacingfunc']) + '\n'

@@ -539,8 +546,13 @@ class Population(object):
        code_string += indent * (depth) + 'print("starcount: ", starcount)\n'
        code_string += indent * (depth) + 'yield(parameter_dict)\n'

        # Save the gridcode to the grid_options
        self.grid_options['code_string'] = code_string

        # Write to file
        gridcode_filename = os.path.join(temp_custom_logging_dir(), 'example_grid.py')
        self.grid_options['gridcode_filename'] = gridcode_filename

        with open(gridcode_filename, 'w') as f:
            f.write(code_string)

@@ -548,11 +560,13 @@ class Population(object):
        """
        Test function to run grid stuff. mostly to test the import
        """

        # Code to load the 
        import importlib.util
        spec = importlib.util.spec_from_file_location("binary_c_python_grid", os.path.join(temp_custom_logging_dir(), 'example_grid.py'))
        grid_file = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(grid_file)
        generator = grid_file.grid_code()
        generator = grid_file.grid_code(self)


        print(next(generator))
+474 −0
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@ grid_options_defaults_dict = {
    "log_args_dir": "/tmp/",
    # Grid variables: instructions to generate the values of the parameters
    "grid_variables": {},
    "grid_code": None,
    "gridcode_filename": None,
    # binary
    "binary": 0,
    ##
    # return_array_refs=>1, # quicker data parsing mode
    # sort_args=>1,
@@ -23,4 +27,474 @@ grid_options_defaults_dict = {
    # timeout=>15, # seconds until timeout
    # log_filename=>"/scratch/davidh/results_simulations/tmp/log.txt",
    # # current_log_filename=>"/scratch/davidh/results_simulations/tmp/grid_errors.log",





#     my $self = shift;

    ############################################################
    # Set default grid properties (in %self->{_grid_options}} 
    # and %{$self->{_bse_options}})
    # This is the first thing that should be called by the user!
    ############################################################

    # # set signal handlers for timeout
    # $self->set_class_signal_handlers();

    # # set operating system
    # my $os = rob_misc::operating_system();
    
    # # set tmp dir
    # my $tmp = $self->tmpdir($os);
     
    # %{$self->{_grid_options}}=(

    #     # save operating system
    # operating_system=>$os,

    #     # process name
    #     process_name => 'binary_grid'.$VERSION,
        
    # # temp directory: 
    # tmp=>$tmp,

    # grid_defaults_set=>1, # so we know the grid_defaults function has been called

    # # grid suspend files: assume binary_c by default
    # suspend_files=>[$tmp.'/force_binary_c_suspend',
    #         './force_binary_c_suspend'],

    # snapshot_file=>$tmp.'/binary_c-snapshot',
    

    # ########################################
    # # infomration about the running grid script
    # ########################################
    # working_directory=>cwd(), # the starting directory
    # perlscript=>$0, # the name of the perlscript
    # perlscript_arguments=>join(' ',@ARGV), # arguments as a string
    # perl_executable=>$^X, # the perl executable
    # command_line=>join(' ',$0,@ARGV), # full command line
    # process_ID=>$$, # process ID of the main perl script

    # ########################################
    # # GRID
    # ########################################

    #     # if undef, generate gridcode, otherwise load the gridcode
    #     # from this file. useful for debugging
    #     gridcode_from_file => undef,
        
    #     # assume binary_grid perl backend by default
    #     backend => 
    #     $self->{_grid_options}->{backend} // 
    #     $binary_grid2::backend //
    #     'binary_grid::Perl',

    #     # custom C function for output : this automatically
    #     # binds if a function is available.
    #     C_logging_code => undef,
    #     C_auto_logging => undef,
    #     custom_output_C_function_pointer => binary_c_function_bind(), 
        
    # # control flow
    # rungrid=>1, # usually run the grid, but can be 0
    # # to skip it (e.g. for condor/slurm runs)
    # merge_datafiles=>'',
    # merge_datafiles_filelist=>'',

    # # parameter space options
    # weight=>1.0, # weighting for the probability

    # repeat=>1, # number of times to repeat each system (probability is adjusted to be 1/repeat)

    # binary=>0, # set to 0 for single stars, 1 for binaries     

    #     # if use_full_resolution is 1, then run a dummy grid to
    #     # calculate the resolution. this could be slow...
    #     use_full_resolution => 1,
        
    # # the probability in any distribution must be within
    # # this tolerance of 1.0, ignored if undef (if you want
    # # to run *part* of the parameter space then this *must* be undef)
    # probability_tolerance=>undef,

    # # how to deal with a failure of the probability tolerance:
    # # 0 = nothing
    # # 1 = warning
    # # 2 = stop
    # probability_tolerance_failmode=>1,

    # # add up and log system error count and probability
    # add_up_system_errors=>1,
    # log_system_errors=>1,

    # # codes, paths, executables etc.
    
    # # assume binary_c by default, and set its defaults
    # code=>'binary_c',
    # arg_prefix=>'--',
    # prog=>'binary_c', # executable 
    # nice=>'nice -n +0', # nice command
    # ionice=>'',
        
    # # compress output?
    # binary_c_compression=>0,

    #     # get output as array of pre-split array refs
    #     return_array_refs=>1,

    # # environment
    # shell_environment=>undef,
    # libpath=>undef, # for backwards compatibility

    # # where is binary_c? need this to get the values of some counters
    # rootpath=>$self->okdir($ENV{BINARY_C_ROOTPATH}) // 
    # $self->okdir($ENV{HOME}.'/progs/stars/binary_c') //
    # '.' , # last option is a fallback ... will fail if it doesn't exist

    # srcpath=>$self->okdir($ENV{BINARY_C_SRCPATH}) // 
    # $self->okdir($ENV{BINARY_C_ROOTPATH}.'/src') // 
    # $self->okdir($ENV{HOME}.'/progs/stars/binary_c/src') //
    # './src' , # last option is fallback... will fail if it doesn't exist

    # # stack size per thread in megabytes
    # threads_stack_size=>50, 

    # # thread sleep time between starting the evolution code and starting 
    # # the grid
    # thread_presleep=>0,

    # # threads
    # # Max time a thread can sit looping (with calls to tbse_line)
    # # before a warning is issued : NB this does not catch real freezes,
    # # just infinite loops (which still output)
    # thread_max_freeze_time_before_warning=>10,
    
    # # run all models by default: modulo=1, offset=0
    # modulo=>1,
    # offset=>0,      

    #     # max number of stars on the queue
    #     maxq_per_thread => 100,
        
    # # data dump file : undef by default (do nothing)
    # results_hash_dumpfile => '',

    # # compress files with bzip2 by default
    # compress_results_hash => 1,

    # ########################################
    # # Condor stuff
    # ########################################    
    # condor=>0, # 1 to use condor, 0 otherwise
    #     condor_command=>'',# condor command e.g. "run_flexigrid", 
    # # "join_datafiles"
    # condor_dir=>'', # working directory containing e.g.
    # # scripts, output, logs (e.g. should be NFS available to all)
    # condor_njobs=>'', # number of scripts
    # condor_jobid=>'', # condor job id
    # condor_postpone_join=>0, # if 1, data is not joined, e.g. if you
    # # want to do it off the condor grid (e.g. with more RAM)
    # condor_join_machine=>undef, # if defined then this is the machine on which the join command should be launched (must be sshable and not postponed)
    # condor_join_pwd=>undef, # directory the join should be in
    # # (defaults to $ENV{PWD} if undef)
    # condor_memory=>1024, # in MB, the memory use (ImageSize) of the job
    # condor_universe=>'vanilla', # usually vanilla universe
    # condor_snapshot_on_kill=>0, # if 1 snapshot on SIGKILL before exit
    # condor_load_from_snapshot=>0, # if 1 check for snapshot .sv file and load it if found
    # condor_checkpoint_interval=>0, # checkpoint interval (seconds) 
    # condor_checkpoint_stamp_times=>0, # if 1 then files are given timestamped names (warning: lots of files!), otherwise just store the lates
    # condor_streams=>0, # stream stderr/stdout by default (warning: might cause heavy network load)
    # condor_save_joined_file=>0, # if 1 then results/joined contains the results (useful for debugging, otherwise a lot of work)
    # condor_requirements=>'', # used?

    #     # resubmit options : if the status of a condor script is
    #     # either 'finished','submitted','running' or 'crashed',
    #     # decide whether to resubmit it.
    #     # NB Normally the status is empty, e.g. on the first run.
    #     # These are for restarting runs.
    #     condor_resubmit_finished=>0,
    # condor_resubmit_submitted=>0,
    # condor_resubmit_running=>0,
    # condor_resubmit_crashed=>0,


    # ########################################
    # # Slurm stuff
    # ########################################    
    #     slurm=>0, # don't use slurm by default
    # slurm_command=>'',# slurm command e.g. "run_flexigrid", 
    # # "join_datafiles"
    # slurm_dir=>'', # working directory containing e.g.
    # # scripts, output, logs (e.g. should be NFS available to all)
    # slurm_njobs=>'', # number of scripts
    # slurm_jobid=>'', # slurm job id (%A)
    # slurm_jobarrayindex=>'', # slurm job array index (%a)
    #     slurm_jobname=>'binary_grid', # set to binary_grid
    #     slurm_postpone_join=>0, # if 1, data is not joined, e.g. if you
    # # want to do it off the slurm grid (e.g. with more RAM)
    #     slurm_postpone_sbatch=>0, # if 1, don't submit, just make the script
    
    # # (defaults to $ENV{PWD} if undef)
    # slurm_memory=>512, # in MB, the memory use of the job
    #     slurm_warn_max_memory=>1024, # in MB : warn if mem req. > this
    #     slurm_partition=>undef,
    #     slurm_ntasks=>1, # 1 CPU required per array job: usually only need this
    #     slurm_time=>0, # 0 = infinite time
    # slurm_use_all_node_CPUs=>0, # 1 = use all of a node's CPUs (0)
    # # you will want to use this if your Slurm SelectType is e.g. linear
    # # which means it allocates all the CPUs in a node to the job
    # slurm_control_CPUs=>0, # if so, leave this many for Perl control (0)
    #     slurm_array=>undef,# override for --array, useful for rerunning jobs
        
    # ########################################
    # # CPU 
    # ########################################
    # cpu_cap=>0, # if 1, limits to one CPU
    # cpu_affinity => 0, # do not bind to a CPU by default

    # ########################################
    # # Code, Timeouts, Signals
    # ########################################
    # binary_grid_code_filtering=>1, #  you want this, it's (MUCH!) faster
    # pre_filter_file=>undef, # dump pre filtered code to this file
    # post_filter_file=>undef,  # dump post filtered code to this file

    # timeout=>30, # timeout in seconds
    # timeout_vb=>0, # no timeout logging
    # tvb=>0, # no thread logging
    # nfs_sleep=>1, # time to wait for NFS to catch up with file accesses

    # # flexigrid checks the timeouts every 
    # # flexigrid_timeout_check_interval seconds
    # flexigrid_timeout_check_interval=>0.01, 

    # # this is set to 1 when the grid is finished
    # flexigrid_finished=>0,

    # # allow signals by default
    # 'no signals'=>0,

    # # but perhaps disable specific signals?
    # 'disable signal'=>{INT=>0,ALRM=>0,CONT=>0,USR1=>0,STOP=>0},

    # # dummy variables
    # single_star_period=>1e50,  # orbital period of a single star

    # #### timers : set timers to 0 (or empty list) to ignore, 
    # #### NB these must be given context (e.g. main::xyz) 
    # #### for functions not in binary_grid
    # timers=>0,
    # timer_subroutines=>[
    #     # this is a suggested default list
    #     'flexigrid',
    #         'set_next_alarm',
    #     'vbout',
    #         'vbout_fast',
    #     'run_flexigrid_thread',
    #         'thread_vb'
    # ],

    # ########################################
    # # INPUT/OUTPUT
    # ########################################
    # blocking=>undef, # not yet set
    
    # # prepend command with stdbuf to stop buffering (if available)
    # stdbuf_command=>`stdbuf --version`=~/stdbuf \(GNU/ ? ' stdbuf -i0 -o0 -e0 ' : undef,

    # vb=>("@ARGV"=~/\Wvb=(\d+)\W/)[0] // 0, # set to 1 (or more) for verbose output to the screen
    # log_dt_secs=>1, # log output to stdout~every log_dt_secs seconds
    # nmod=>10, # every nmod models there is output to the screen,
    # # if log_dt_secs has been exceeded also (ignored if 0)

    # colour=>1, # set to 1 to use the ANSIColor module for colour output
    # log_args=>0, # do not log args in files
    # log_fins=>0, # log end of runs too
    #     sort_args=>0, # do not sort args
    # save_args=>0, # do not save args in a string
    # log_args_dir=>$tmp, # where to output the args files
    # always_reopen_arg_files=>0, # if 1 then arg files are always closed and reopened (may cause a lot of disk I/O)

    # lazy_arg_sending=>1, # if 1, the previous args are remembered and
    # # only args that changed are sent (except M1, M2 etc. which always
    # # need sending)
 
    # # force output files to open on a local disk (not an NFS partion)
    # # not sure how to do this on another OS
    # force_local_hdd_use=>($os eq 'unix'), 

    # # for verbose output, define the newline
    # # For terminals use "\x0d", for files use "\n", in the 
    # # case of multiple threads this will be set to \n
    # newline=> "\x0d",

    #     # use reset_stars_defaults
    #     reset_stars_defaults=>1,

    # # set signal captures: argument determines behaviour when the code locks up
    # # 0: exit
    # # 1: reset and try the next star (does this work?!)
    # alarm_procedure=>1,

    # # exit on eval failure?
    # exit_on_eval_failure=>1,

    # ## functions: these should be set by perl lexical name
    # ## (they are automatically converted to function pointers
    # ## at runtime)

    # # function to be called just before a thread is created
    # thread_precreate_function=>undef,
    #     thread_precreate_function_pointer=>undef,
    
    # # function to be called just after a thread is created
    # # (from inside the thread just before *grid () call)
    # threads_entry_function=>undef,
    #     threads_entry_function_pointer=>undef,

    # # function to be called just after a thread is finished
    # # (from inside the thread just after *grid () call)
    # threads_flush_function=>undef,
    # threads_flush_function_pointer=>undef,

    # # function to be called just after a thread is created
    # # (but external to the thread)
    # thread_postrun_function=>undef,
    # thread_postrun_function_pointer=>undef,

    # # function to be called just before a thread join
    # # (external to the thread)
    # thread_prejoin_function=>undef,
    # thread_prejoin_function_pointer=>undef,

    # # default to using the internal join_flexigrid_thread function
    # threads_join_function=>'binary_grid2::join_flexigrid_thread',
    # threads_join_function_pointer=>sub{return $self->join_flexigrid_thread(@_)},
    
    # # function to be called just after a thread join
    # # (external to the thread)
    # thread_postjoin_function=>undef,
    # thread_postjoin_function_pointer=>undef,

    # # usually, parse_bse in the main script is called
    # parse_bse_function=>'main::parse_bse',
    #     parse_bse_function_pointer=>undef,

    # # if starting_snapshot_file is defined, load initial
    # # values for the grid from the snapshot file rather 
    # # than a normal initiation: this enables you to 
    # # stop and start a grid
    # starting_snapshot_file=>undef,
    
    # # flexigrid options
    # flexigrid=>{
    #         # there are several types of flexigrid:
    #         #
    #         # 'grid' is the traditional N-dimensional grid
    #         # 'monte carlo' is a Monte Carlo simulation (may not work!)
    #         # 'list' takes a list of systems from 
    #         #
    #         # $self->{_grid_options}->{flexigrid}->{'list filename'}
    #         #
    #         # (which is a file containing list strings on each line)
    #         #
    #         # or from 
    #         # 
    #         # $self->{_grid_options}->{flexigrid}->{'list reference'}
    #         #
    #         # (which is a reference to a perl list)
    #     'grid type'=>'grid',
    #         'list filename'=>undef,  # undef unless 'grid type' is 'list'
    #         'list reference'=>undef, # ditto
    #         'listFP'=>undef, # file pointer : keep undef here (set automatically) 

    #     },

    #     # start at this model number: handy during debugging 
    #     # to skip large parts of the grid
    #     start_at => 0
    # );
    # );

    # # if available, use the evcode's defaults
    # if(1)
    # {
    #     my $evcode_args = $self->evcode_args_list();
        
    #     if(defined $evcode_args && 
    #        $evcode_args &&
    #        ref $evcode_args eq 'ARRAY' &&
    #        $#{$evcode_args} > 1)
    #     {
    #         foreach my $arg (grep {
    #             !(
    #                  # some args should be ignored
    #                  /=\s*$/ ||
    #                  /Function$/ ||
    #                  /NULL$/ ||
    #                  /\(?null\)?$/i ||
    #                  /^M_[12]/ ||
    #                  /^eccentricity/ ||
    #                  /^orbital_period/ ||
    #                  /^phasevol/ ||
    #                  /^separation/ ||
    #                  /^probability/ ||
    #                  /^stellar_type/ ||
    #                  /^_/||
    #                  /^batchmode/  ||
    #                  /^initial_abunds_only/ ||
    #                  /^monte_carlo_kicks/
    #                 )
    #                          }@$evcode_args)
    #         {
    #             if($arg=~/(\S+) = (\S+)/)
    #             {
    #                 if(!defined $self->{_bse_options}->{$1})
    #                 {
    #                     #print "NEW set $1 to $2\n";
    #                 }
    #                 $self->{_bse_options}->{$1} = 
    #                     $2 eq 'TRUE' ? 1 :
    #                     $2 eq 'FALSE' ? 0 :
    #                     $2;
    #                 #print "Set $1 -> $2 = $self->{_bse_options}->{$1}\n";
    #             }
    #         }
    #     }
    # }
   
    # $self->{_flexigrid} = {
    # count         => 0,
    #     error         => 0,
    #     failed_count  => 0,
    #     failed_prob   => 0.0,
    #     global_error_string => undef,

    #     # random string to ID the flexigrid
    #     id            => rob_misc::random_string(8),
    #     modulo        => 1, # run modulo n
    #     monitor_files => [],
    #     nextlogtime   => 0,
    #     nthreads      => 1, # number of threads
    #     # start at model offset (0-based, so first model is zero)
    #     offset        => 0, 
    #     probtot       => 0.0,
    #     resolution=>{
    #         shift   =>0,
    #         previous=>0,
    #         n       =>{} # per-variable resolution
    #     },
    #     results_hash  => $self->{_results},
    #     thread_q      => undef,
    #     threads       => undef, # array of threads objects
    #     tstart        => [gettimeofday], # flexigrid start time     
    #     __nvar        => 0, # number of grid variables
    #     _varstub      => undef,
    #     _lock         => undef,
    #     _evcode_pids  => [],
    # }; 
}
+255 −1

File changed.

Preview size limit exceeded, changes collapsed.

+8 −6
Original line number Diff line number Diff line
@@ -11,8 +11,6 @@ from binarycpython.utils.grid import Population
from binarycpython.utils.functions import get_help_all, get_help

## Script is intended for some testing of grid functionality. Its a bit random, not really structured tbh


test_pop = Population()

## Setting values
@@ -202,6 +200,10 @@ test_pop.set(
# plt.savefig('sizes_for_commands.png')
# plt.show()

# def ding(val):
#     return val
# test_pop.set(extra_prob_function=ding)

### Grid generating testing
test_pop.add_grid_variable(
    name='lnm1',
@@ -211,6 +213,7 @@ test_pop.add_grid_variable(
    spacingfunc='np.linspace(0.213, 10.2, 10)',
    precode='M_1=math.exp(lnm1)',
    probdist='flat(M_1)',
    # probdist='self.custom_options["extra_prob_function"](M_1)',
    dphasevol='',
    parameter_name='M_1',
    condition='',
@@ -227,12 +230,11 @@ test_pop.add_grid_variable(
    probdist='flat(orbital_period)',
    parameter_name='orbital_period',
    dphasevol='',
    condition='',
    condition='self.grid_options["binary"]==0',
)

test_pop.generate_grid_code()
test_pop.load_grid_function()


# test_pop.run_grid()

test_pop.load_grid_function()
 No newline at end of file
print(test_pop.grid_options['code_string'])
 No newline at end of file