math functions

20 views
Skip to first unread message

jori...@gmail.com

unread,
Apr 4, 2019, 12:39:32 AM4/4/19
to reikna
Hello, Bogdan!

I am trying to work with Reikna. Thanks for the library, I can't imaging your efforts spent here...
But I have a few questions. Want to start just with one very simple.
I would like to calculate complex exponent, which is used intensively in DSP.
I want to calculate exp(1j*k), where 1j is complex sqrt(-1). That means I have a float as input (k) and want to get complex output equal to cos(k)+1j*sin(k)
Numpy of course does the same. But when I use Reikna I have another result: exp(1j*k) -> exp(0) + 1j*exp(k)
Is there any chance to get a complex exponent other than writing a new Module?
And the second short question. Can I use OpenCL's math functions (the same exp, sin, cos exist there)? Suppose no, since Reikna is supposed to be CUDA/OpenCL independent.

Thanks
Dmitry

jori...@gmail.com

unread,
Apr 4, 2019, 12:45:23 AM4/4/19
to reikna
That's how I calculate exp in my transformation:
${indata.ctype} coeff = exp(COMPLEX_CTR(${indata.ctype})(0.0, 1.0));

Bogdan Opanchuk

unread,
Apr 4, 2019, 3:46:58 AM4/4/19
to reikna
Hi Dmitry,

You can use `functions.polar_unit()` (http://reikna.publicfields.net/en/latest/api/cluda.html#reikna.cluda.functions.polar_unit) for that, it takes a floating-point argument and returns a complex result. Of course you can use `functions.exp()` too, and construct a complex argument manually, but it may be slower (if the compiler doesn't figure out that the real part is zero, I am not sure how well constant folding works in different backends). Note though that you need to use `functions.exp()`, not the OpenCL built-in `exp()` as you do in your example. The built-in `exp()` is not a complex-valued exponent, it just exponentiates both components separately (as you noticed). (if I'm not mistaken, it's the same for all functions and operators acting on vector types in OpenCL - they are just applied to all components separately) So you need to do something like

    ${indata.ctype} coeff = ${exp}(COMPLEX_CTR(${indata.ctype})(0.0, k));

passing `exp = functions.exp(indata.dtype)` to `render_kwds`.

> And the second short question. Can I use OpenCL's math functions (the same exp, sin, cos exist there)? Suppose no, since Reikna is supposed to be CUDA/OpenCL independent.

Reikna can be backend-independent, but it doesn't have to be. If you need OpenCL functions, you can use them, of course (as you actually did in your example), it just may not compile for a CUDA backend. Conversely, you can wrap some template-heavy CUDA code in a Reikna `Program` (I encountered problems where I needed to do that). The templating engine just helps you generate the code that is passed to the compiler, you can put there whatever your target compiler can handle. 


Reply all
Reply to author
Forward
0 new messages