I find myself out of my depth again. I'm playing with complex numbers
using 0.94rc (on Windows XP with CUDA 2.3). I've successfully used
simple operations (addition, multiplication) on complex numbers, that
resulted in the Mandelbrot example in the wiki.

Now I'm trying sin and log and I'm getting errors and one positive
result (see the end). I'm not sure if these functions are supported
yet? If anyone can point me in the right direction (and perhaps
suggest what needs implementing) then I'll have a go at fixing the
problem.

For reference, you can do the following using numpy on the CPU for verification:
In [117]: numpy.sin(numpy.array(numpy.complex64(1-1j)))
Out[117]: (1.2984576-0.63496387j)

Here are two pieces of test code. At first I used multiplication
(rather than sin()) to confirm that the code ran as expected.

Next I tried creating a simple complex64 array, passing it to the GPU
and then asking for pycuda.cumath.sin() - this results in "Error:
External calls are not supported". Here's the code and error:

========
import pycuda.driver as drv
import pycuda.autoinit
import pycuda.gpuarray as gpuarray
import pycuda.cumath
import numpy

a = numpy.array(numpy.complex64(1-1j)) # make list of 1 complex element
a_gpu = gpuarray.to_gpu(a)
pycuda.cumath.sin(a_gpu) # should produce (1.29-0.63j)
print a_gpu.get()
========

In [62]: %run complex_test.py
kernel.cu
tmpxft_00000840_00000000-3_kernel.cudafe1.gpu
tmpxft_00000840_00000000-8_kernel.cudafe2.gpu
./kernel.cu(19): Error: External calls are not supported (found
non-inlined call to _ZN6pycuda3sinERKNS_7complexIfEE)
---------------------------------------------------------------------------
CompileError                              Traceback (most recent call last)

     16 a = numpy.array(numpy.complex64(1-1j)) # make list of 1 complex element
     17 a_gpu = gpuarray.to_gpu(a)
---> 18 pycuda.cumath.sin(a_gpu) # should produce (1.29-0.63j)
========

I replaced:
pycuda.cumath.sin(a_gpu) # should produce (1.29-0.63j)
with:
pycuda.cumath.log(a_gpu) # should produce (0.34-0.78j)
and the code ran without an error...but produced the wrong result. It
generates (1-1j) which looks like a no-op.


Next I tried similar functionality using sin() in an
ElementwiseKernel, this generates the same "Error: External calls are
not supported" problem:

========
import pycuda.driver as drv
import pycuda.autoinit
import pycuda.gpuarray as gpuarray
import pycuda.cumath
import numpy

from pycuda.elementwise import ElementwiseKernel
complex_gpu = ElementwiseKernel (
        "pycuda::complex<float> *z",
        "z[i] = sin(z[i]);",
        "complex_fn",
        "#include <pycuda-complex.hpp>,"
)


a = numpy.array(numpy.complex64(1-1j)) # make list of 1 complex element
a_gpu = gpuarray.to_gpu(a)
#sin((1-1j)) should produce (1.29-0.63j)
#log((1-1j)) should produce (0.34-0.78j)
complex_gpu(a_gpu)
print a_gpu.get()
========

In [56]: %run complex_test.py
*** compiler output in c:\docume~1\parc\locals~1\temp\tmpjqvxpv
kernel.cu
kernel.cudafe1.gpu
kernel.cudafe2.gpu
./kernel.cu(19): Error: External calls are not supported (found
non-inlined call to _ZN6pycuda3sinERKNS_7complexIfEE)
---------------------------------------------------------------------------
CompileError                              Traceback (most recent call last)

C:\Panalytical\pycuda_git\pycuda0.94\pycuda\examples\complex_test.py
in <module>()
     26         "z[i] = sin(z[i]);",
     27         "complex_fn",
---> 28         "#include <pycuda-complex.hpp>,"
     29 )
....
CompileError: nvcc compilation of
c:\docume~1\parc\locals~1\temp\tmpjqvxpv\kernel.cu failed
[command: nvcc --cubin -arch sm_11
-IC:\Python26\lib\site-packages\pycuda-0.94rc-py2.6-win32.egg\pycuda\..\include\pycud
a --keep kernel.cu]
WARNING: Failure executing file: <complex_test.py>
========

*However* if I replace sin() with log():
from pycuda.elementwise import ElementwiseKernel
complex_gpu = ElementwiseKernel (
        "pycuda::complex<float> *z",
        "z[i] = log(z[i]);",
        "complex_fn",
        "#include <pycuda-complex.hpp>,"
)
then I get the correct result!
========
In [126]: %run complex_test.py
(0.346573650837-0.785398185253j)
========

Does anyone know why sin() doesn't work in both cases and log() works
in an ElementwiseKernel but not correctly as a pycuda.cumath call?

Ian.

-- 
Ian Ozsvald (A.I. researcher, screencaster)
i...@ianozsvald.com

http://IanOzsvald.com
http://morconsulting.com/
http://TheScreencastingHandbook.com
http://ProCasts.co.uk/examples.html
http://twitter.com/ianozsvald

_______________________________________________
PyCUDA mailing list
pyc...@host304.hostmonster.com
http://host304.hostmonster.com/mailman/listinfo/pycuda_tiker.net

Reply via email to