math functions

23 views

jori...@gmail.com

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

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

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.