C/C++ API
Re: C/C++ API
There is not yet a formal API for NEURON but one can use the nrn/src/nrnpython cpp files for examples of how
python uses NEURON functions and data. Python loads NEURON as an extension and gets it initialized via
inithoc.cpp
After that you can execute any hoc statement (e.g. load_file) with hoc_valid_stmt(stmt, 0) as done by
nrnexec in nrnpy_hoc.cpp. The beginning of the file lists many NEURON functions used to retrieve information.
Section, Mechanism, Range Variable interaction is handled in nrnpy_nrn.cpp.
Also, many useful functions are listed in nrn/src/ivoc/oc2iv.h and nrn/src/nrniv/nrnoc2iv.h
python uses NEURON functions and data. Python loads NEURON as an extension and gets it initialized via
inithoc.cpp
After that you can execute any hoc statement (e.g. load_file) with hoc_valid_stmt(stmt, 0) as done by
nrnexec in nrnpy_hoc.cpp. The beginning of the file lists many NEURON functions used to retrieve information.
Section, Mechanism, Range Variable interaction is handled in nrnpy_nrn.cpp.
Also, many useful functions are listed in nrn/src/ivoc/oc2iv.h and nrn/src/nrniv/nrnoc2iv.h
Re: C/C++ API
Hi there Hines,
i've build NEURON with PYTHON support, therefore using:
import neuron
...
additional python NEURON code.
I'm using Python's functionality for embedding it into it with the high level Python API into C++: http://docs.python.org/extending/embedding.html
Example is:
extern "C" {
#include <Python.h>
}
Py_Initialize();
PyRun_SimpleString("from neuron import h\n");
Py_Finalize();
But this fails with:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/stephan/local/lib/python2.7/site-packages/neuron/__init__.py", line 81, in <module>
import neuron.hoc
ImportError: /home/stephan/neuron/nrn/x86_64/lib/libnrnpython.so.0: undefined symbol: PyExc_ImportError
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 64, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 1, in <module>
from apport.report import Report
File "/usr/lib/python2.7/dist-packages/apport/report.py", line 16, in <module>
from xml.parsers.expat import ExpatError
File "/usr/lib/python2.7/xml/parsers/expat.py", line 4, in <module>
from pyexpat import *
ImportError: /usr/lib/python2.7/lib-dynload/pyexpat.so: undefined symbol: _Py_ZeroStruct
Original exception was:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/stephan/local/lib/python2.7/site-packages/neuron/__init__.py", line 81, in <module>
import neuron.hoc
ImportError: /home/stephan/neuron/nrn/x86_64/lib/libnrnpython.so.0: undefined symbol: PyExc_ImportError
terminate called without an active exception
Aborted (core dumped)
Please note: invoking the Python interpreter in a Bash shell, and import neuron module works.
Let me know if you can suggest anything.
All the best,
Stephan
i've build NEURON with PYTHON support, therefore using:
import neuron
...
additional python NEURON code.
I'm using Python's functionality for embedding it into it with the high level Python API into C++: http://docs.python.org/extending/embedding.html
Example is:
extern "C" {
#include <Python.h>
}
Py_Initialize();
PyRun_SimpleString("from neuron import h\n");
Py_Finalize();
But this fails with:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/stephan/local/lib/python2.7/site-packages/neuron/__init__.py", line 81, in <module>
import neuron.hoc
ImportError: /home/stephan/neuron/nrn/x86_64/lib/libnrnpython.so.0: undefined symbol: PyExc_ImportError
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 64, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 1, in <module>
from apport.report import Report
File "/usr/lib/python2.7/dist-packages/apport/report.py", line 16, in <module>
from xml.parsers.expat import ExpatError
File "/usr/lib/python2.7/xml/parsers/expat.py", line 4, in <module>
from pyexpat import *
ImportError: /usr/lib/python2.7/lib-dynload/pyexpat.so: undefined symbol: _Py_ZeroStruct
Original exception was:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/stephan/local/lib/python2.7/site-packages/neuron/__init__.py", line 81, in <module>
import neuron.hoc
ImportError: /home/stephan/neuron/nrn/x86_64/lib/libnrnpython.so.0: undefined symbol: PyExc_ImportError
terminate called without an active exception
Aborted (core dumped)
Please note: invoking the Python interpreter in a Bash shell, and import neuron module works.
Let me know if you can suggest anything.
All the best,
Stephan
Re: C/C++ API
I'd start by leaving out the import neuron line and instead compare
import sys
sys.path
It may be that launching python sets up a bit more environment than what you are getting with Py_Initialize.
import sys
sys.path
It may be that launching python sets up a bit more environment than what you are getting with Py_Initialize.
Re: C/C++ API
Thank you again.
Is there a possibility to use only C/C++ code to control NEURON from within an C/C++ application? (I don't want to bother with Python)
All the best,
Stephan
Is there a possibility to use only C/C++ code to control NEURON from within an C/C++ application? (I don't want to bother with Python)
All the best,
Stephan
Re: C/C++ API
Yes. My best hint is the above 05 Jul 2012 post. You can dynamically load or link your executable against the installed libnrniv.so just like a launch of
python loads nrniv as a module using src/nrnpython/inithoc.cpp . The first test is to execute a hoc statement from your c++ program.
python loads nrniv as a module using src/nrnpython/inithoc.cpp . The first test is to execute a hoc statement from your c++ program.
Re: C/C++ API
Ah okay,
just to be sure if I'm doing things correct:
I've built NEURON without IV and have those .so files. Now I need to include in analogy to your example, NEURON in my own C++ application, then building and linking against the NEURON libs.
Am I right?
All the best and sorry for bothering you again,
Stephan
just to be sure if I'm doing things correct:
I've built NEURON without IV and have those .so files. Now I need to include in analogy to your example, NEURON in my own C++ application, then building and linking against the NEURON libs.
Am I right?
All the best and sorry for bothering you again,
Stephan
Re: C/C++ API
Thank you very much. I figured it out. It's still failing while linking because linking order matters... i'm currently figuring out the correct linkage order:
g++ -L nrn-7.3/x86_64/lib/ example.c -lnrnoc -livoc -loc -livos -lnrniv -lmeschach -lscopmath -lsparse13 -lneuron_gnu -lnrnmpi -lmemacs -lsundials
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `rl_deprep_terminal'
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `rl_event_hook'
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `readline'
nrn-7.3/x86_64/lib//libnrnoc.so: undefined reference to `modl_reg'
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `add_history'
some suggestions? :)
All the best,
Stephan
g++ -L nrn-7.3/x86_64/lib/ example.c -lnrnoc -livoc -loc -livos -lnrniv -lmeschach -lscopmath -lsparse13 -lneuron_gnu -lnrnmpi -lmemacs -lsundials
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `rl_deprep_terminal'
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `rl_event_hook'
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `readline'
nrn-7.3/x86_64/lib//libnrnoc.so: undefined reference to `modl_reg'
nrn-7.3/x86_64/lib//liboc.so: undefined reference to `add_history'
some suggestions? :)
All the best,
Stephan
Re: C/C++ API
I created a static version configured using
../nrn/configure --prefix=`pwd` --without-x --disable-shared --enable-static linux_nrnmech=no
and then nrnivmodl gives a link line of
libtool: link: g++ -g -O2 -pthread -o special /home/hines/neuron/nrnstatic/x86_64/lib/nrnmain.o /home/hines/neuron/nrnstatic/x86_64/lib/ivocmain.o /home/hines/neuron/nrnstatic/x86_64/lib/nvkludge.o temp.o mod_func.o -L/home/hines/neuron/nrnstatic/x86_64/lib /home/hines/neuron/nrnstatic/x86_64/lib/libnrnoc.a /home/hines/neuron/nrnstatic/x86_64/lib/libnrniv.a /home/hines/neuron/nrnstatic/x86_64/lib/libivoc.a /home/hines/neuron/nrnstatic/x86_64/lib/liboc.a /home/hines/neuron/nrnstatic/x86_64/lib/libneuron_gnu.a /home/hines/neuron/nrnstatic/x86_64/lib/libscopmath.a /home/hines/neuron/nrnstatic/x86_64/lib/libsparse13.a /home/hines/neuron/nrnstatic/x86_64/lib/libsundials.a /home/hines/neuron/nrnstatic/x86_64/lib/libnrnmpi.a /home/hines/neuron/nrnstatic/x86_64/lib/libmemacs.a /home/hines/neuron/nrnstatic/x86_64/lib/libmeschach.a /home/hines/neuron/nrnstatic/x86_64/lib/libivos.a /home/hines/neuron/nrnstatic/x86_64/lib/libreadline.a -lncurses -lm -ldl -pthread
from that I infer
-lnrnoc -lnrniv -livoc -loc-lneuron_gnu -lscopmath -lsparse13 -lsundials -lnrnmpi -lmemacs -lmeschach -livos -lreadline -lncurses -lm
might work.
../nrn/configure --prefix=`pwd` --without-x --disable-shared --enable-static linux_nrnmech=no
and then nrnivmodl gives a link line of
libtool: link: g++ -g -O2 -pthread -o special /home/hines/neuron/nrnstatic/x86_64/lib/nrnmain.o /home/hines/neuron/nrnstatic/x86_64/lib/ivocmain.o /home/hines/neuron/nrnstatic/x86_64/lib/nvkludge.o temp.o mod_func.o -L/home/hines/neuron/nrnstatic/x86_64/lib /home/hines/neuron/nrnstatic/x86_64/lib/libnrnoc.a /home/hines/neuron/nrnstatic/x86_64/lib/libnrniv.a /home/hines/neuron/nrnstatic/x86_64/lib/libivoc.a /home/hines/neuron/nrnstatic/x86_64/lib/liboc.a /home/hines/neuron/nrnstatic/x86_64/lib/libneuron_gnu.a /home/hines/neuron/nrnstatic/x86_64/lib/libscopmath.a /home/hines/neuron/nrnstatic/x86_64/lib/libsparse13.a /home/hines/neuron/nrnstatic/x86_64/lib/libsundials.a /home/hines/neuron/nrnstatic/x86_64/lib/libnrnmpi.a /home/hines/neuron/nrnstatic/x86_64/lib/libmemacs.a /home/hines/neuron/nrnstatic/x86_64/lib/libmeschach.a /home/hines/neuron/nrnstatic/x86_64/lib/libivos.a /home/hines/neuron/nrnstatic/x86_64/lib/libreadline.a -lncurses -lm -ldl -pthread
from that I infer
-lnrnoc -lnrniv -livoc -loc-lneuron_gnu -lscopmath -lsparse13 -lsundials -lnrnmpi -lmemacs -lmeschach -livos -lreadline -lncurses -lm
might work.
Re: C/C++ API
forgot to mention that
ivocmain.o nvkludge.o
may be needed to ensure some names in the libraries get linked (perhaps because used in later libraries)
ivocmain.o nvkludge.o
may be needed to ensure some names in the libraries get linked (perhaps because used in later libraries)
Re: C/C++ API
Using this linkage i arrive at that error, mh:
nrn-7.3/x86_64/lib//libnrnoc.so: undefined reference to `modl_reg'
I will try to figure out this, i will update my post if I could figure out for other people.
My example code is (also i defined nil to be NULL since nil is otherwise undefined somehow):
My compile line is:
And I build NEURON with that line:
Maybe you see where I fail.
Addentum: I added nrn-7.3/x86_64/src/oc/modlreg.o and now it compiles, but when running:
I guess I need to change my LD_LIBRARY_PATH variable?
=> Changed it, but now it results in an Segmentation Fault. Is this to be expected in my (buggy?) example code? And is adding modlreg.o from src folder correct?
Best regards,
Stephan
nrn-7.3/x86_64/lib//libnrnoc.so: undefined reference to `modl_reg'
I will try to figure out this, i will update my post if I could figure out for other people.
My example code is (also i defined nil to be NULL since nil is otherwise undefined somehow):
Code: Select all
#define nil NULL
#include "nrn-7.3/src/ivoc/oc2iv.h"
int main(int argc, char** argv) {
int i = 10;
bool test = hoc_is_double_arg(i);
return 1;
}
Code: Select all
g++ -L nrn-7.3/x86_64/lib/ example.cpp nrn-7.3/x86_64/lib/nvkludge.o nrn-7.3/x86_64/lib/ivocmain.o -lnrnoc -lnrniv -livoc -loc -lneuron_gnu -lscopmath -lsparse13 -lsundials -lnrnmpi -lmemacs -lmeschach -livos -lreadline -lncurses -lm -locxt
Code: Select all
./configure --prefix=`pwd` --without-iv; make; make install
Addentum: I added nrn-7.3/x86_64/src/oc/modlreg.o and now it compiles, but when running:
./a.out: error while loading shared libraries: libnrnoc.so.0: cannot open shared object file: No such file or directory
I guess I need to change my LD_LIBRARY_PATH variable?
=> Changed it, but now it results in an Segmentation Fault. Is this to be expected in my (buggy?) example code? And is adding modlreg.o from src folder correct?
Best regards,
Stephan
Re: C/C++ API
Code: Select all
bool test = hoc_is_double_arg(i);
But the interpreter was never started. You would need to follow the initialization process used in nrniv/nrnmain.cpp which calls
ivocmain in ivoc/ivocmain.cpp
Re: C/C++ API
Thank you again hines! :)hines wrote:is out of context since it assumes the interpreter has called your main function. It looks at the argument the interpreter put on its stack.Code: Select all
bool test = hoc_is_double_arg(i);
But the interpreter was never started. You would need to follow the initialization process used in nrniv/nrnmain.cpp which calls
ivocmain in ivoc/ivocmain.cpp
I must have been over-reading this. Sorry.
All the best,
Stephan
Re: C/C++ API
Update:
I managed to compile the code below (which executes valid hoc statements as expected now, yeah!).
I compiled it with the line:
And ran it by:
Outputting:
Nevertheless I need to ask two minor questions:
1) How can i retrieve for example the membrane potential or the value of a variable through execution of hoc_valid_stmt? In fact I need to access a variable defined by a hoc expression like my_val = v(i).
2) How can i get rid of the #define nil NULL - which i guess is quite non-optimal?
I struggled a while for compiling and linking an C++ app with NEURON, as for that i will provide in future (as a post in this forum) a CMakeLists.txt file for custom projects using the hoc interpreter, as I'm going to do for now manually... maybe someone will find this useful (if something like a CMakeLists already exists I'm sorry I did not find it in the www).
All the best,
Stephan
I managed to compile the code below (which executes valid hoc statements as expected now, yeah!).
I compiled it with the line:
Code: Select all
g++ -L nrn-7.3/x86_64/lib/ nrn-7.3/src/oc/modlreg.o example.cpp nrn-7.3/x86_64/lib/nvkludge.o -lnrnoc -lnrniv -livoc -loc -lneuron_gnu -lscopmath -lsparse13 -lsundials -lnrnmpi -lmemacs -lmeschach -livos -lreadline -lncurses -lm -locxt
Code: Select all
LD_LIBRARY_PATH=nrn-7.3/x86_64/lib/ ./a.out
In case of someone finds this useful, i reported it.NEURON -- Release 7.3 (849:5be3d097b917) 2013-04-11
Duke, Yale, and the BlueBrain Project -- Copyright 1984-2013
See http://www.neuron.yale.edu/neuron/credits
Executing hoc statement (t = 0) succeded? Yes.
Code: Select all
// define nil (how to circumvent that define?)
#define nil NULL
// necessary includes
#include "nrn-7.3/src/ivoc/oc2iv.h"
#include "nrn-7.3/src/ivoc/ivocmain.cpp"
#include "nrn-7.3/src/ivoc/ocjump.cpp"
// extern C functions
extern bool hoc_valid_stmt(const char* stmt, Object* ob);
extern int ivocmain(int, char**, char**);
// oc environment
static char* env[] = {0};
// main
int main(int argc, char** argv) {
const int init = 0;
ivocmain(init, argv, env);
const char* stmt = "t = 0";
const bool ret = hoc_valid_stmt(stmt, 0);
std::cout << "Executing hoc statement (" << stmt << ") succeded? " << (ret ? "Yes." : "No.") << std::endl;
return 1;
}
1) How can i retrieve for example the membrane potential or the value of a variable through execution of hoc_valid_stmt? In fact I need to access a variable defined by a hoc expression like my_val = v(i).
2) How can i get rid of the #define nil NULL - which i guess is quite non-optimal?
I struggled a while for compiling and linking an C++ app with NEURON, as for that i will provide in future (as a post in this forum) a CMakeLists.txt file for custom projects using the hoc interpreter, as I'm going to do for now manually... maybe someone will find this useful (if something like a CMakeLists already exists I'm sorry I did not find it in the www).
All the best,
Stephan
Re: C/C++ API
extern double hoc_ac_
is known to the interpreter. So you can execute
hoc_valid_stmt("hoc_ac_ = expr...", 0);
and then look at hoc_ac_
I think
#define nil NULL
is fine.
is known to the interpreter. So you can execute
hoc_valid_stmt("hoc_ac_ = expr...", 0);
and then look at hoc_ac_
I think
#define nil NULL
is fine.