From eb0a6968448e06c694c47e9b991fc3fbe1202f30 Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Tue, 29 Oct 2019 20:08:12 +0000 Subject: [PATCH] made first logging function --- #TODO.org# | 18 --- .#TODO.org | 1 - TODO.org | 133 +++++++++++++++++++++- binaryc_python_utils/logging_functions.py | 105 +++++++++++++++++ 4 files changed, 237 insertions(+), 20 deletions(-) delete mode 100644 #TODO.org# delete mode 120000 .#TODO.org create mode 100644 binaryc_python_utils/logging_functions.py diff --git a/#TODO.org# b/#TODO.org# deleted file mode 100644 index 807bc566c..000000000 --- a/#TODO.org# +++ /dev/null @@ -1,18 +0,0 @@ -* 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 diff --git a/.#TODO.org b/.#TODO.org deleted file mode 120000 index a749651ea..000000000 --- a/.#TODO.org +++ /dev/null @@ -1 +0,0 @@ -david@david-Lenovo-IdeaPad-S340-14IWL.21326:1572369068 \ No newline at end of file diff --git a/TODO.org b/TODO.org index 3294b1e80..42fa47440 100644 --- a/TODO.org +++ b/TODO.org @@ -1,7 +1,138 @@ * 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?) diff --git a/binaryc_python_utils/logging_functions.py b/binaryc_python_utils/logging_functions.py new file mode 100644 index 000000000..1d4aa71c3 --- /dev/null +++ b/binaryc_python_utils/logging_functions.py @@ -0,0 +1,105 @@ +# 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']}) + + -- GitLab