From 50bbcde1f31bb08d722b57d25bc4e844e0e5a09a Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Thu, 7 Nov 2019 16:43:24 +0000 Subject: [PATCH] made most code to compile the shared library for binaryc --- binaryc/__pycache__/functions.cpython-36.pyc | Bin 0 -> 3263 bytes binaryc/custom_logging.c | 20 ++ binaryc/functions.py | 238 +++++++++++++++++++ binaryc/main.py | 35 +++ binaryc/readme.md | 2 + 5 files changed, 295 insertions(+) create mode 100644 binaryc/__pycache__/functions.cpython-36.pyc create mode 100644 binaryc/custom_logging.c create mode 100644 binaryc/functions.py create mode 100644 binaryc/main.py create mode 100644 binaryc/readme.md diff --git a/binaryc/__pycache__/functions.cpython-36.pyc b/binaryc/__pycache__/functions.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d94edfad50de7db8a96e18cb3cb9c54647929fad GIT binary patch literal 3263 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 literal 0 HcmV?d00001 diff --git a/binaryc/custom_logging.c b/binaryc/custom_logging.c new file mode 100644 index 0000000..22c19e9 --- /dev/null +++ b/binaryc/custom_logging.c @@ -0,0 +1,20 @@ +#pragma push_macro("MAX") +#pragma push_macro("MIN") +#undef MAX +#undef MIN +#include "binary_c.h" + +void custom_output_function(struct stardata_t * stardata); +void custom_output_function(struct stardata_t * stardata) +{ + // struct stardata_t * stardata = (struct stardata_t *)x; + PRINTF("MY_STELLAR_DATA %g %g +",((double)stardata->model.time),((double)stardata->star[0].mass)); +PRINTF("my_sss2 %g %g +",((double)stardata->model.time),((double)stardata->star[1].mass));; +} + +#undef MAX +#undef MIN +#pragma pop_macro("MIN") +#pragma pop_macro("MAX") \ No newline at end of file diff --git a/binaryc/functions.py b/binaryc/functions.py new file mode 100644 index 0000000..b9d635e --- /dev/null +++ b/binaryc/functions.py @@ -0,0 +1,238 @@ +import os +import textwrap +import subprocess +import socket + +# Functions for the automatic logging of stuff + +def autogen_C_logging_code(logging_dict): + # See example_perl.pm autologging + """ + 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") + return None + + code = '' + # Loop over dict keys + for key in logging_dict: + logging_dict_entry = logging_dict[key] + + # Check if item is of correct type: + if type(logging_dict_entry)==list: + + # 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 += ');\n' + + else: + print('Error: please use a list for the list of parameters that you want to have logged') + code = code.strip() + # print("MADE AUTO CODE\n\n{}\n\n{}\n\n{}\n".format('*'*60, repr(code), '*'*60)) + + return code + +#################################################################################### +def binary_c_log_code(code): + """ + Function to construct the code to construct the custom logging function + # see example_perl.pm binary_c_log_code in perl + """ + custom_logging_function_string = """\ +#pragma push_macro(\"MAX\") +#pragma push_macro(\"MIN\") +#undef MAX +#undef MIN +#include \"binary_c.h\" + +void custom_output_function(struct stardata_t * stardata); +void custom_output_function(struct stardata_t * stardata) +{{ + // struct stardata_t * stardata = (struct stardata_t *)x; + {}; +}} + +#undef MAX +#undef MIN +#pragma pop_macro(\"MIN\") +#pragma pop_macro(\"MAX\")\ + """.format(code) + + # print(repr(textwrap.dedent(custom_logging_function_string))) + return textwrap.dedent(custom_logging_function_string) + +def binary_c_write_log_code(code, filename): + """ + Function to write the generated logging code to a file + """ + + cwd = os.getcwd() + + filePath = os.path.join(cwd, filename) + if os.path.exists(filePath): + try: + os.remove(filePath) + except: + print("Error while deleting file {}".format(filePath)) + + with open(filePath, 'w') as f: + f.write(code) + +def from_binary_c_config(config_file, flag): + """ + Function to run the binaryc_config command with flags + """ + + res = subprocess.check_output('{config_file} {flag}'.format(config_file=config_file, flag=flag), + shell=True, stderr=subprocess.STDOUT) + + # convert and chop off newline + res = res.decode('utf').rstrip() + return res + +def return_compilation_dict(): + """ + Function to build the compile command for the shared library + + inspired by binary_c_inline_config command in perl + + TODO: this function still has some cleaning up to do wrt default values for the compile command + + returns: + - string containing the command to build the shared library + """ + + # use binary_c-config to get necessary flags + BINARY_C_DIR = os.getenv('BINARY_C') + if BINARY_C_DIR: + BINARY_C_CONFIG = os.path.join(BINARY_C_DIR, 'binary_c-config') + BINARY_C_SRC_DIR = os.path.join(BINARY_C_DIR, 'src') + # TODO: build in check to see whether the file exists + else: + raise NameError('Envvar BINARY_C doesnt exist') + return None + + # TODO: make more options for the compiling + cc = from_binary_c_config(BINARY_C_CONFIG, 'cc') + + # Check for binary_c + BINARY_C_EXE = os.path.join(BINARY_C_DIR, 'binary_c') + if not os.path.isfile(BINARY_C_EXE): + print("We require binary_c executable; have you built binary_c?") + raise NameError('BINARY_C executable doesnt exist') + + # TODO: debug + binclibs = from_binary_c_config(BINARY_C_CONFIG, 'libs') + libdirs = "{} -L{}".format(from_binary_c_config(BINARY_C_CONFIG, 'libdirs'), BINARY_C_SRC_DIR) + bincflags = from_binary_c_config(BINARY_C_CONFIG, 'cflags') + bincincdirs = from_binary_c_config(BINARY_C_CONFIG, 'incdirs') + + # combine + binclibs = ' {} {}'.format(libdirs, binclibs) + + # setup defaults: + defaults = { + 'cc': 'gcc', # default compiler + 'ccflags': bincflags, + 'ld': 'ld', # 'ld': $Config{ld}, # default linker + 'debug': 0, + 'inc': '{} -I{}'.format(bincincdirs, BINARY_C_SRC_DIR), + # inc => ' '.($Config{inc}//' ').' '.$bincincdirs." -I$srcdir ", # include the defaults plus # GSL and binary_c + # 'libname': libname, # libname is usually just binary_c corresponding to libbinary_c.so + 'libs': binclibs, + } + + # set values with defaults. TODO: make other input possile. + ld = defaults['ld'] + debug = defaults['debug'] + inc = defaults['inc'] # = ($ENV{BINARY_GRID2_INC} // $defaults{inc}).' '.($ENV{BINARY_GRID2_EXTRAINC} // ''); + libs = defaults['libs'] # = ($ENV{BINARY_GRID2_LIBS} // $defaults{libs}).' '.($ENV{BINARY_GRID2_EXTRALIBS}//''); + ccflags = defaults['ccflags'] # = $ENV{BINARY_GRID2_CCFLAGS} // ($defaults{ccflags}) . ($ENV{BINARY_GRID2_EXTRACCFLAGS} // ''); + + # you must define _SEARCH_H to prevent it being loaded twice + ccflags += ' -D_SEARCH_H' + + # ensure library paths to the front of the libs: + libs_content = libs.split(' ') + library_paths = [el for el in libs_content if el.startswith('-L')] + non_library_paths = [el for el in libs_content if (not el.startswith('-L') and not el=='')] + libs = "{} {}".format(' '.join(library_paths), ' '.join(non_library_paths)) + + print("Building shared library for custom logging with (binary_c.h) at {} on {}\n".format(BINARY_C_SRC_DIR, socket.gethostname())) + print("With options:\n\tcc = {cc}\n\tccflags = {ccflags}\n\tld = {ld}\n\tlibs = {libs}\n\tinc = {inc}\n\n".format( + cc=cc, ccflags=ccflags, ld=ld, libs=libs, inc=inc) + ) + + return { + 'cc': cc, + 'ld': ld, + 'ccflags': ccflags, + 'libs': libs, + 'inc': inc + } + +# compilation_dict = return_compilation_dict('libcustomlogging') +def compile_shared_lib(code, sourcefile_name, outfile_name): + """ + Function to write the custom logging code to a file and then compile it. + """ + + # Write code to file + binary_c_write_log_code(code, sourcefile_name) + + # create compilation command + compilation_dict = return_compilation_dict() + + command = "{cc} {ccflags} {libs} -o {outfile_name} {sourcefile_name} {inc}".format( + cc=compilation_dict['cc'], + ccflags=compilation_dict['ccflags'], + libs=compilation_dict['libs'], + outfile_name=outfile_name, + sourcefile_name=sourcefile_name, + inc=compilation_dict['inc']) + + # remove extra whitespaces: + command = ' '.join(command.split()) + + # Execute compilation + res = subprocess.check_output('{command}'.format(command=command), + shell=True, stderr=subprocess.STDOUT) + print(res) + + + + # return command + +# generate logging lines +logging_line = autogen_C_logging_code( + { + 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], + 'my_sss2': ['model.time', 'star[1].mass'] + } +) + +# Generate code around logging lines +created_code = binary_c_log_code(logging_line) + +compile_shared_lib(created_code, sourcefile_name='custom_logging.c', outfile_name='lib_custom_logging.so') \ No newline at end of file diff --git a/binaryc/main.py b/binaryc/main.py new file mode 100644 index 0000000..ccc28fa --- /dev/null +++ b/binaryc/main.py @@ -0,0 +1,35 @@ +from functions import autogen_C_logging_code, binary_c_log_code, binary_c_write_log_code + +import textwrap + +# generate logging lines +logging_line = autogen_C_logging_code( + { + 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], + 'my_sss2': ['model.time', 'star[1].mass'] + } +) + +# Generate code around logging lines +created_code = binary_c_log_code(logging_line) + +binary_c_write_log_code(created_code) + + + + + + + + + + + + + + + + + + + diff --git a/binaryc/readme.md b/binaryc/readme.md new file mode 100644 index 0000000..9c5fd5f --- /dev/null +++ b/binaryc/readme.md @@ -0,0 +1,2 @@ +# function for binaryc to work + -- GitLab