Commit eb0a6968 authored by David Hendriks's avatar David Hendriks
Browse files

made first logging function

parent a558d566
Loading
Loading
Loading
Loading

#TODO.org#

deleted100644 → 0
+0 −18
Original line number Diff line number Diff line
* Todo list for the binary_c-python
** Logging functionality:
Idea is to be able to give a string via python that will be used in the through the libbinary_c.so so that log_every_timestep.c 

** General:
*** DONE Get a more reliable way of loading the default values (running a ./tbse echo or something?)
    CLOSED: [2019-10-29 Tue 17:44]
*** DONE make routine that reads out all the lines, splits them into pieces and reads out the correct key
    CLOSED: [2019-10-29 Tue 17:43]
*** TODO Put header and other source files in a dedicated directory
*** TODO Use sphinx or read the docs for auto generation of documentation
*** TODO Have the compiled files put into a build directory
*** TODO add pythonpath thing to readme
*** TODO make script that will set up binaryc automatically so that this can become an out of the box thing
*** TODO Test the importing of this code from different places
** Population ideas
*** TODO Queuing system and some multiprocessing to run many systems
*** TODO Consider rewriting the work that perl does

.#TODO.org

deleted120000 → 0
+0 −1
Original line number Diff line number Diff line
david@david-Lenovo-IdeaPad-S340-14IWL.21326:1572369068
 No newline at end of file
+132 −1
Original line number Diff line number Diff line
* Todo list for the binary_c-python
** Logging functionality:
Idea is to be able to give a string via python that will be used in the 
*** Idea
Idea is to be able to give a string via python that will be used in the through the libbinary_c.so so that log_every_timestep.c 
The code below is the piece in log_every_timestep that uses it.

    if(stardata->preferences->custom_output_function != NULL)
    {
        Dprint("calling custom output function %p\n",
               stardata->preferences->custom_output_function);
        stardata->preferences->custom_output_function(stardata);
    }

So the function should recieve 'stardata' as input.

We can do that with providing a logging string alltogether, or generate a logging function

In either way, this should be passed to stardata->preferences->custom_output_function as a pointer to that function


*** Provide string for logging
In perl this is done in the following way:

sub binary_c_log_code
{
    my ($code) = @_;
    return "
#pragma push_macro(\"MAX\")
#pragma push_macro(\"MIN\")
#undef MAX
#undef MIN
#include \"binary_c.h\"

void custom_output_function(SV * x);
SV * custom_output_function_pointer(void);

SV * custom_output_function_pointer()
{
    /*
     * use PTR2UV to convert the function pointer 
     * &custom_output_function to an unsigned int,
     * which is then converted to a Perl SV
     */
    return (SV*)newSVuv(PTR2UV(&custom_output_function));
}

void custom_output_function(SV * x)
{
    struct stardata_t * stardata = (struct stardata_t *)x;
    $code;
}
#undef MAX 
#undef MIN
#pragma pop_macro(\"MIN\")
#pragma pop_macro(\"MAX\")
";
}

And then to use it via 
    $population->set(
        C_logging_code => '
             PRINTF("MY_STELLAR_DATA %g %g %g %g\n",
                 stardata->model.time,
                 stardata->star[0].mass,
                 stardata->model.probability,
                 stardata->model.dt);
                       '
    );

Or use it via:

*** auto logging
We should also try to be able to have the code autogenerate some logging function via the following:

$population->set(    C_auto_logging => {
        'MY_STELLAR_DATA' =>
            [
             'model.time',
             'star[0].mass',
             'model.probability',
             'model.dt'
            ]
    });


Which is handled in perl via (see binary_grid2.pm
sub autogen_C_logging_code
{
    # given a hash of arrays of variable names, where the hash
    # key is the header, autogenerate PRINTF statements
    my ($self) = @_;
    my $code = undef;
    if(defined $self->{_grid_options}->{C_auto_logging} &&
       ref $self->{_grid_options}->{C_auto_logging} eq 'HASH'
        )
    {
        $code = '';

        foreach my $header (keys %{$self->{_grid_options}->{C_auto_logging}})
        {
            if(ref $self->{_grid_options}->{C_auto_logging}->{$header} eq 'ARRAY')
            {
                $code .= 'PRINTF("'.$header.' ';
                foreach my $x (@{$self->{_grid_options}->{C_auto_logging}->{$header}})
                {
                    $code .= '%g ';
                }
                $code .= '\n"';

                foreach my $x (@{$self->{_grid_options}->{C_auto_logging}->{$header}})
                {
                    $code .= ',((double)stardata->'.$x.')';
                }
                $code .= ');'
            }
        }
    }
    print "MADE AUTO CODE \n\n************************************************************\n\n$code\n\n************************************************************\n";

    return $code;
}




*** TODO Make function in python that puts code into c function
*** TODO Make function in python that generates c-function from a list of arguments
*** TODO Resolve current issue malloc
➜  binary_c-python git:(master) ✗ python python_API_test.py 
Traceback (most recent call last):
  File "python_API_test.py", line 3, in <module>
    import binary_c
ImportError: /home/david/projects/binary_c_root/binary_c-python/libbinary_c_api.so: undefined symbol: MALLOC

I get this error when I am using the master version of binary_c with either branches of the python wrapper

** General:
*** DONE Get a more reliable way of loading the default values (running a ./tbse echo or something?)
+105 −0
Original line number Diff line number Diff line
# Functions for the automatic logging of stuff

# Perl code for autogeneration
# sub autogen_C_logging_code
# {
#     # given a hash of arrays of variable names, where the hash
#     # key is the header, autogenerate PRINTF statements
#     my ($self) = @_;
#     my $code = undef;
#     if(defined $self->{_grid_options}->{C_auto_logging} &&
#        ref $self->{_grid_options}->{C_auto_logging} eq 'HASH'
#         )
#     {
#         $code = '';

#         foreach my $header (keys %{$self->{_grid_options}->{C_auto_logging}})
#         {
#             if(ref $self->{_grid_options}->{C_auto_logging}->{$header} eq 'ARRAY')
#             {
#                 $code .= 'PRINTF("'.$header.' ';
#                 foreach my $x (@{$self->{_grid_options}->{C_auto_logging}->{$header}})
#                 {
#                     $code .= '%g ';
#                 }
#                 $code .= '\n"';

#                 foreach my $x (@{$self->{_grid_options}->{C_auto_logging}->{$header}})
#                 {
#                     $code .= ',((double)stardata->'.$x.')';
#                 }
#                 $code .= ');'
#             }
#         }
#     }
#     print "MADE AUTO CODE \n\n************************************************************\n\n$code\n\n************************************************************\n";

#     return $code;
# }

# Which is used in flexi-grid via this:
# $population->set(    C_auto_logging => {
#         'MY_STELLAR_DATA' =>
#             [
#              'model.time',
#              'star[0].mass',
#              'model.probability',
#              'model.dt'
#             ]
#     });



def autogen_C_logging_code(logging_dict):
    """
    Function that autogenerates PRINTF statements for binaryc

    Input:
        dictionary where the key is the header of that logging line and items which are lists of parameters that will be put in that logging line

        example: {'MY_STELLAR_DATA': 
        [
            'model.time',
            'star[0].mass',
            'model.probability',
            'model.dt'
        ']}
    """

    # Check if the input is of the correct form 
    if not type(logging_dict)==dict:
        print("Error: please use a dictionary as input")

    #
    code = ''

    # Loop over dict keys
    for key in logging_dict:
        print('{}'.format(key))

        logging_dict_entry = logging_dict[key]

        # Check if item is of correct type:
        if type(logging_dict_entry)==list:
            print(logging_dict_entry)

            # Construct print statement
            code += 'PRINTF("{}'.format(key)
            code += ' {}'.format('%g '*len(logging_dict_entry))
            code = code.strip()
            code += '\n"'

            # Add format keys
            for param in logging_dict_entry:
                code += ',((double)stardata->{})'.format(param)
            code += ');'

        else:
            print('Error: please use a list for the list of parameters that you want to have logged')


    print(repr(code))

autogen_C_logging_code({'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 'my_sss2': ['model.time', 'star[1].mass']})