On Mon, Oct 5, 2009 at 2:41 PM, Ondrej Certik <[email protected]> wrote: > On Mon, Oct 5, 2009 at 2:36 PM, Ondrej Certik <[email protected]> wrote: >> On Mon, Oct 5, 2009 at 1:37 PM, Luke Olson <[email protected]> wrote: >>> >>> >>> On Mon, Oct 5, 2009 at 11:54 AM, Ondrej Certik <[email protected]> wrote: >>>> >>>> On Mon, Oct 5, 2009 at 5:03 AM, Luke <[email protected]> wrote: >>>> > >>>> > AS, >>>> > >>>> > Thanks for you comments. Glad you've liked the package so far. >>>> > >>>> > As for your Fortran code, we're working on a pure C-branch >>>> > specifically for this reason. It's a ways off, however. I've tried >>>> > both of your solutions: >>>> > >>>> > Solution1: >>>> > For me this worked very well. I was impressed with F2Py. I had to do >>>> > very little coding to interface Python with Fortran and did not notice >>>> > a performance drop. This is an easy first pass that's worth trying. >>>> > >>>> > Solution 2: >>>> > I've never been able to do this :) Embedding the interpreter works >>>> > (for me) for very small python examples, but nothing with SciPy/NumPy/ >>>> > PyAMG. You may be a little more savvy, however; I didn't spend too >>>> > much time investigating. >>>> >>>> The example how to do embed python (and numpy+scipy works!) into a C >>>> (resp. C++) app is here: >>>> >>>> http://hpfem.org/hermes1d/ >>>> >>>> e.g. do: >>>> >>>> git clone http://hpfem.math.unr.edu/git/hermes1d.git >>>> cd hermes1d >>>> python -c 'print "set(WITH_PYTHON yes)\n"' > CMake.vars >>>> cmake . >>>> make >>>> cd examples/schroedinger >>>> ./schroedinger >>>> >>>> >>>> and a matplotlib window will popup, I use numpy for solving the >>>> eigenproblem an this is all done from *within* a C++ app, see the >>>> main.cpp (see the line 86). Here is an example of how it looks like if >>>> you run it: >>>> >>>> >>>> http://groups.google.com/group/hermes1d/browse_thread/thread/3f73e5bde7ebe527 >>>> >>>> the hermes2d is a very young code, so you will almost surely discover >>>> some bugs, but the python <-> C interface works great and without any >>>> problems, I use it in other projects too. >>>> >>>> Ondrej >>>> >>> >>> Ondrej, >>> >>> Nice example. One difficulty, however, is that the data is passed by >>> writing to a file and then rereading in the python script. In the other >> >> That is just a quick hack. You can ignore that. >> >>> example, a full copy is performed. The real challenge for PyAMG would be to >>> pass a reference to the data as data to a numpy object. If you have any >>> example of this, that would be helpful. >> >> It's super easy to pass a reference to the data, *without* copying >> anything. See below how to do it. >> >> In the other example, this Cython code is responsible for converting >> C++ array into a numpy array: >> >> cdef ndarray array_double_c2numpy(double *A, int len): >> from numpy import empty >> cdef ndarray vec = empty([len], dtype="double") >> cdef double *pvec = <double *>vec.data >> memcpy(pvec, A, len*sizeof(double)) >> return vec >> >> (see python/hermes1d/_hermes1d.pyx, line 94), so currently the data is >> copied, because that is the safest approach (you never know if the >> C++/Python code doesn't free the memory if the other one needs it). In >> my case the memcopy is really fast and not the bottleneck. >> >> If however, you know that you can safely use the exact same memory >> from both C++ and Python, or the memcpy is really killing you, just >> use this patch: >> >> diff --git a/python/hermes1d/_hermes1d.pyx b/python/hermes1d/_hermes1d.pyx >> index c1d8cdd..3586069 100644 >> --- a/python/hermes1d/_hermes1d.pyx >> +++ b/python/hermes1d/_hermes1d.pyx >> @@ -94,8 +94,9 @@ cdef ndarray array_int_c2numpy(int *A, int len): >> cdef ndarray array_double_c2numpy(double *A, int len): >> from numpy import empty >> cdef ndarray vec = empty([len], dtype="double") >> - cdef double *pvec = <double *>vec.data >> - memcpy(pvec, A, len*sizeof(double)) >> + vec.data = <char *>A >> + #cdef double *pvec = <double *>vec.data >> + #memcpy(pvec, A, len*sizeof(double)) >> return vec > > One problem that I can see with this is that the "vec.data" is first > allocated, and then I should free it myself in the above function, and > then numpy will free the new "vec.data". This also takes care of: > >> then it works. But as I said, it's a major pain to handle this memory by >> hand. > > ^^^ numpy actually frees it for me I think. > > The remaining problem is how to make numpy not to allocate the memory > at all. But in any case, that imho is a minor problem, it should not > slow things down and if you free it yourself in the above function, it > should get you started. > > Please ping me if you figure out how to force numpy not to allocate > the "vec.data" in the first place.
Ok, I have fixed that now, the solution is to use the numpy C/API. So if you do now: git clone http://hpfem.math.unr.edu/git/hermes1d.git cd hermes1d python -c 'print "set(WITH_PYTHON yes)\n"' > CMake.vars cmake . make cd examples/schroedinger ./schroedinger it will be copying the data using memcpy. If you apply this patch: diff --git a/examples/schroedinger/main.cpp b/examples/schroedinger/main.cpp index 4800440..5d3be6e 100644 --- a/examples/schroedinger/main.cpp +++ b/examples/schroedinger/main.cpp @@ -36,12 +36,12 @@ double rhs(int num, double *x, double *weights, void insert_matrix(DenseMatrix *mat, int len) { - double _mat[len*len]; + double *_mat = new double[len*len]; for(int i=0; i<len; i++) for(int j=0; j<len; j++) _mat[i*len+j] = mat->get(i, j); insert_object("len", c2py_int(len)); - insert_object("mat", c2numpy_double(_mat, len*len)); + insert_object("mat", c2numpy_double_inplace(_mat, len*len)); cmd("_ = mat.reshape((len, len))"); cmd("del len"); cmd("del mat"); it will not be copying anything, nor allocating any memory in vain during the conversion. Ondrej _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
