Commit 88da958d authored by Johannes Blaschke's avatar Johannes Blaschke
Browse files

interactive mode can now execute arbitrary python scripts

** ensure that $PYTHONPATH is set properly
** executing python/pyro/expose_pyroclasses.py now does the same as the old pyro mode
++ scons correctly parses input arguments now
++ vs code project settings improved
parent ec59f5bb
......@@ -4,7 +4,8 @@
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include/"
"/usr/local/include",
"/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Headers"
],
"browse" : {
"limitSymbolsToIncludedHeaders" : true,
......
// Place your settings in this file to overwrite default and user settings.
{
"search.exclude": {
"**/build": true
"**/build": true,
"**/build/**": true
},
"files.exclude": {
"**/build": true,
......@@ -10,25 +11,10 @@
"**/.hg": true,
"**/.DS_Store": true
},
"projectManager.showProjectNameInStatusBar": true,
"files.associations": {
"*h*h*h*h*hmemory": "cpp",
"*h*h*h*h*h*h*hfunctional": "cpp",
"istream": "cpp",
"functional": "cpp",
"*hutility": "cpp",
"utility": "cpp",
"*h*h*h*h*h*h*h*harray": "cpp",
"array": "cpp",
"*harray": "cpp",
"tuple": "cpp",
"*h*htuple": "cpp",
"*h*h*h*htype_traits": "cpp",
"type_traits": "cpp",
"*hpp*hpp*h*h*h*h*h*h*h*h*h*h*h*h*hppistream": "cpp",
"memory": "cpp",
"*h*hlimits": "cpp",
"limits": "cpp",
"*h*h*hpp*hpplimits": "cpp"
}
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/node_modules/**": true,
"**/build/**": true
},
"projectManager.showProjectNameInStatusBar": true
}
\ No newline at end of file
......@@ -4,6 +4,6 @@
"version": "0.1.0",
"command": "scons",
"isShellCommand": true,
"args": ["--enable-interactive=True"],
"args": ["--enable-interactive=True", "--debug-compile=True"],
"showOutput": "always"
}
\ No newline at end of file
......@@ -3,25 +3,29 @@ import os.path
AddOption("--enable-interactive",
dest = "interactive_mode",
default = False,
nargs = 1, type = "string",
default = "False",
help = "compile with Pyro4 console option")
AddOption("--debug-compile",
dest = "debug_mode",
default = False,
nargs = 1, type = "string",
default = "False",
help = "compile with DDEBUG")
AddOption("--debug-information",
dest = "debug_info",
default = True,
nargs = 1, type = "string",
default = "True",
help = "compile with -g3 flag")
AddOption("--allow-inline",
dest = "allow_inline",
default = True,
nargs = 1, type = "string",
default = "True",
help = "compile allowing inline functions")
interactive_mode = GetOption("interactive_mode")
debug_mode = GetOption("debug_mode")
debug_info = GetOption("debug_info")
allow_inline = GetOption("allow_inline")
interactive_mode = GetOption("interactive_mode") == "True"
debug_mode = GetOption("debug_mode") == "True"
debug_info = GetOption("debug_info") == "True"
allow_inline = GetOption("allow_inline") == "True"
......
......@@ -460,9 +460,10 @@ main(int argc, char * argv[])
}
#ifdef ENABLEINTERACTIVE
if(argc == 3 && strncmp(argv[2],"--interactive",13) == 0)
if(argc == 4 && strncmp(argv[2], "--interactive", 13) == 0)
{
activate_pyro(& world, argv);
// activate_pyro(& world, argv);
run_pyscript(& world, argv);
//TODO: implement shutdown via pyro...
}
#endif
......
......@@ -624,6 +624,22 @@ py_run_str(const char * str_cmd)
PyRun_SimpleString(str_cmd);
}
char *
construct_execfile_cmd(const char * str_name)
{
char * format = "execfile(\"%s\")\n";
char * s = malloc(snprintf(NULL, 0, format, str_name) + 1);
sprintf(s, format, str_name);
return s;
}
void
py_execfile(const char * str_name)
{
char * str_execfile_cmd = construct_execfile_cmd(str_name);
py_run_str(str_execfile_cmd);
free(str_execfile_cmd);
}
char *
construct_import_cmd(const char * str_module, const char * str_name)
{
......@@ -649,12 +665,12 @@ void
py_import_as(PyMethodDef defs[], const char * str_module_name, const char * str_import_name)
{
Py_InitModule(str_module_name, defs);
py_import_sys(str_module_name,str_import_name);
py_import_sys(str_module_name, str_import_name);
}
void
py_import_from(const char * str_module_name, const char * str_function_name)
{
char * str_import_cmd = construct_import_from_cmd(str_module_name,str_function_name);
char * str_import_cmd = construct_import_from_cmd(str_module_name, str_function_name);
py_run_str(str_import_cmd);
free(str_import_cmd);
}
......@@ -685,7 +701,7 @@ py_import_IPyEmbed(int verbose)
{
if(verbose)
fprintf(stdout,"(cpu.%d) * Loading IPython.embed...\n",cpu.rank);
py_import_from("IPython","embed");//TODO: get to work with mpirun!
py_import_from("IPython", "embed");//TODO: get to work with mpirun!
if(verbose)
{
fprintf(stdout,"(cpu.%d) done! Call embed() for an embedded IPython. Note: this works badly with mpirun!\n",cpu.rank);
......@@ -699,7 +715,7 @@ pyro_init(int verbose)
if(verbose)
fprintf(stdout,"(cpu.%d) * Loading Pyro4.Daemon...\n",cpu.rank);
py_import_from("Pyro4","Daemon");
py_import_from("Pyro4", "Daemon");
if(verbose)
fprintf(stdout,"(cpu.%d) done! Pyro4.Daemon is functions are available Daemon\n",cpu.rank);
......@@ -720,7 +736,7 @@ construct_server_dictstr(const char * proxy_name)
{
const char * const pyrodict_assign_str = "pyro_server_dict[proxy_%s_instance] = 'cpu.%d.%s';\n";
char * s = malloc(snprintf(NULL, 0, pyrodict_assign_str , proxy_name, cpu.rank, proxy_name) + 1);
sprintf(s, pyrodict_assign_str , proxy_name, cpu.rank, proxy_name);
sprintf(s, pyrodict_assign_str, proxy_name, cpu.rank, proxy_name);
return s;
}
......@@ -728,7 +744,7 @@ void
pyro_expose_proxyclass(const char * str_class_name)
{
const char * const instance_format_str = "proxy_%s_instance = proxy_%s();\n";
char * classinst = construct_proxy_defstr(str_class_name,instance_format_str);
char * classinst = construct_proxy_defstr(str_class_name, instance_format_str);
py_run_str(classinst);
free(classinst);
......
......@@ -53,6 +53,7 @@ extern world_state * world_ptr;
void init_python(char * interpreter_name);
void py_run_str(const char * str_cmd);
void py_execfile(const char * str_name);
void py_import_as(PyMethodDef defs[], const char * str_module_name, const char * str_import_name);
void py_import_sys(const char * str_module_name, const char * str_import_name);
......
......@@ -6,7 +6,7 @@
#include "py_backend.h"
#include "trypanosome_PyAPI.h"
#define N_BUFFER 1024 //Console input buffer size
// #define N_BUFFER 1024 //Console input buffer size
// ***** GIT merge old versions *******************************
// const char * const proxy_debug_trypanosome_str =
......@@ -59,90 +59,155 @@ PyMethodDef EmbeddedControl[]={
};
//Basic wee function to read whole lines from the terminal
char *
stdin_getline(void)
{
char * line = malloc(N_BUFFER), * linep = line;
size_t lenmax = N_BUFFER, len = lenmax;
int c;
if(line == NULL)
return NULL;
for(;;) {
c = fgetc(stdin);
if(c == EOF)
break;
if(--len == 0) {
len = lenmax;
char * linen = realloc(linep, lenmax *= 2);
if(linen == NULL) {
free(linep);
return NULL;
}
line = linen + (line - linep);
linep = linen;
}
if((*line++ = c) == '\n')
break;
}
*line = '\0';
return linep;
}
// char *
// stdin_getline(void)
// {
// char * line = malloc(N_BUFFER), * linep = line;
// size_t lenmax = N_BUFFER, len = lenmax;
// int c;
// if(line == NULL)
// return NULL;
// for(;;) {
// c = fgetc(stdin);
// if(c == EOF)
// break;
// if(--len == 0) {
// len = lenmax;
// char * linen = realloc(linep, lenmax *= 2);
// if(linen == NULL) {
// free(linep);
// return NULL;
// }
// line = linen + (line - linep);
// linep = linen;
// }
// if((*line++ = c) == '\n')
// break;
// }
// *line = '\0';
// return linep;
// }
//basic python console
// void
// enter_console(world_state * world, char * argv[])
// {
// world_ptr = world; //TODO HAXOR: OH SO IMPORTANT
// printf("Welcome to interactive mode\n");
// printf("This simple console allows you to execute Python code.\n");
// printf(" * Initializing the Python interpreter ...");
// init_python(argv[0]);
// printf("done!\n");
// py_import_basics(1);
// py_import_IPyEmbed(1);
// printf(" -> Embedding system configurations...");
// py_import_as(EmbeddedConfigurations, "EmbeddedConfigurations", "embed_config");
// PyRun_SimpleString("global_config=embed_config.get()");
// printf("done! Configurations are available in the global global_config dict\n");
// printf(" -> Embedding world state...");
// py_import_as(EmbeddedWorld, "EmbeddedWorld", "sim_world");
// printf("done! World struct available using sim_world.get()\n");
// printf("Ready to go!\n");
// char * line;
// for(;;)
// {
// fputs(" >>> ", stdout);
// fflush(stdout);
// line = stdin_getline();
// PyRun_SimpleString(line);
// //TODO: print error output
// //TODO: readline() support?
// printf("\n");
// free(line);
// }
// Py_Finalize();
// }
void
enter_console(world_state * world, char * argv[])
py_import_mpicd_environment(world_state * world, char * argv[], int verbose)
{
if(verbose == 1){
fprintf(stdout, "[core: %d] Entering python mode!\n", cpu.rank);
fprintf(stdout, "[core: %d] ** Initializing the Python interpreter ...\n", cpu.rank);
}
world_ptr = world; //TODO HAXOR: OH SO IMPORTANT
printf("Welcome to interactive mode\n");
printf("This simple console allows you to execute Python code.\n");
printf(" * Initializing the Python interpreter ...");
init_python(argv[0]);
printf("done!\n");
py_import_basics(1);
py_import_IPyEmbed(1);
if(verbose == 1){
fprintf(stdout, "[core: %d] ... done!\n", cpu.rank);
fprintf(stdout, "[core: %d] => Embedding system configurations...\n", cpu.rank);
}
printf(" -> Embedding system configurations...");
py_import_as(EmbeddedConfigurations, "EmbeddedConfigurations", "embed_config");
PyRun_SimpleString("global_config=embed_config.get()");
printf("done! Configurations are available in the global global_config dict\n");
py_import_as(EmbeddedConfigurations, "EmbeddedConfigurations", "global_config");
if(verbose == 1){
fprintf(stdout, "[core: %d] ... done! Configurations are available using global_config.get()\n", cpu.rank);
fprintf(stdout, "[core: %d] => Embedding world state...\n", cpu.rank);
}
printf(" -> Embedding world state...");
py_import_as(EmbeddedWorld, "EmbeddedWorld", "sim_world");
printf("done! World struct available using sim_world.get()\n");
py_import_as(EmbeddedWorld, "EmbeddedWorld", "sim_world");
if(verbose == 1){
fprintf(stdout, "[core: %d] ... done! World struct available using sim_world.get()\n", cpu.rank);
fprintf(stdout, "[core: %d] -> VParticles can be genereated using sim_world.debug_generate_vparticles()\n", cpu.rank);
fprintf(stdout, "[core: %d] -> Grid shift can be genereated using sim_world.debug_initialize_gridshift()\n", cpu.rank);
fprintf(stdout, "[core: %d] => Embedding cpu configurations...\n", cpu.rank);
}
printf("Ready to go!\n");
py_import_as(EmbeddedCPU, "EmbeddedCPU", "cpu_config");
char * line;
for(;;)
{
fputs(" >>> ", stdout);
fflush(stdout);
if(verbose == 1){
fprintf(stdout, "[core: %d] ... done! CPU Configurations are available using cpu_config.get()\n", cpu.rank);
fprintf(stdout, "[core: %d] => Embedding control system...\n", cpu.rank);
}
line = stdin_getline();
PyRun_SimpleString(line);
//TODO: print error output
//TODO: readline() support?
py_import_as(EmbeddedControl, "EmbeddedControl", "sim_control");
if(verbose == 1){
fprintf(stdout, "[core: %d] ... done! Control available using the sim_control class.\n", cpu.rank);
fprintf(stdout, "[core: %d] -> Control running core simultation for n steps using sim_control.run(n)\n", cpu.rank);
fprintf(stdout, "[core: %d] => Embedding trypanosome debug methods...\n", cpu.rank);
}
printf("\n");
py_import_as(DebugTrypanosomeMethods, "DebugTrypanosomeMethods", "debug_trypanosome");
free(line);
if(verbose == 1){
fprintf(stdout, "[core: %d] ... done! Trypanosome Debug Functions are available using the debug_trypanosome class.\n", cpu.rank);
}
Py_Finalize();
}
void
run_pyscript(world_state * world, char * argv[])
{
py_import_mpicd_environment(world, argv, 1);
char * pyscript_path = argv[3];
py_execfile(pyscript_path);
}
void
activate_pyro(world_state * world, char * argv[])
{
world_ptr = world; //TODO HAXOR: OH SO IMPORTANT
fprintf(stdout, "(cpu.%d) Welcome to interactive mode\n", cpu.rank);
fprintf(stdout, "(cpu.%d) This node (%d) will share Pyro4 objects for inspection and control.\n", cpu.rank, cpu.rank);
......
......@@ -13,7 +13,8 @@
void enter_console(world_state *, char * []);
// void enter_console(world_state *, char * []);
void run_pyscript(world_state * world, char * argv[]);
void activate_pyro(world_state * world, char * argv[]);
......
"""
Script invoking a PyRO4 proxy, exposing internal variables/conrol:
* Requires: PyRO4 installed, running a pyro4-ns instance
-> exposes 1 pyro daemon per core (N) serving 2 objects:
- cpu.{N}.global : global variables and conrol
- cpu.{N}.debug_trypanosome : trypansome debug and control
"""
from Pyro4 import Daemon
from pyro_gears import ProxyGlobal, ProxyDebugTrypanosome
def get_rank():
"""returns cpu rank (ATTN: requests _entire_ cpu config dict!)"""
cpu_pydict = cpu_config.get()
return cpu_pydict["rank"]
# expose pyro classes to the pyro4 server
# using pyro4-ns running on client-side network
PROXY_GLOBAL_INST = ProxyGlobal(global_config, cpu_config, sim_world, sim_control)
PROXY_DEBUG_TRYP_INST = ProxyDebugTrypanosome(debug_trypanosome)
# determin cpu rank
RANK = get_rank()
# start pyro server
PYRO_SRV_DICT = {
PROXY_GLOBAL_INST:"cpu.{0}.global".format(RANK),
PROXY_DEBUG_TRYP_INST:"cpu.{0}.debug_trypanosome".format(RANK)
}
Daemon.serveSimple(PYRO_SRV_DICT, ns=True)
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
init-hook='import sys; sys.path.append(".")'
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
jobs=1
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no
# Tells whether to display a full report or only the messages
reports=yes
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$