0
$\begingroup$

Why does CUDAFunctionLoad not accept character types (strings)? I want to load equations defined in an array (a list of equations) which is written in Mathematica and call them using CUDAFunctionLoad. It is very difficult to define the whole equation in cuda c/c++. Can anyone please explain. Is there is any other way to fix it?

 __device__ float f (float t, float x)
     { return (sin (x) + sin (t));} 

 __global __ void secondKernel (float out[2][5], float x[], float t, 
      float h, float end, int listSize) 
    {
     int index = threadIdx.x + blockIdx.x * blockDim.x;
     float k1, k2, k3, k4;
     int i = 0;
     do {
            k1 = h*f (t, x[index]);
            k2 = h*f (t + h/2.0, (x[index] + k1*h/2.0));
            k3 = h*f (t + h/2.0, (x[index] + k2*h/2.0));
            k4 = h*f (t + h, (x[index] + k3*h));
            x[index] = (k1 + 2.0*k2 + 2.0*k3 + k4)/6.0;
            out[index][i] = x[index];
            t = t + h;
            i++;
        } while (t <= end);
     }
    ";
start = 0.0; end = 4.0; h = 1.0; nsteps = (end - start)/h;

xarr = {4.0, 5.0}; listSize = Length[xarr];

secondKernel = CUDAFunctionLoad[secondKernelCode, "secondKernel",{{"Float"},{"Float"}, "Float", "Float", "Float", _Integer}, {2, 5}];

output = CUDAMemoryAllocate["Float", {2, 5}];

secondKernel[output, xarr, start, h, end, listSize];

outputarray = CUDAMemoryGet[output][[ ;; ]]
{{-0.16506, 1.28052, 1.36264, 0.622622, -0.539732}, {-0.522478, 
  0.740226, 1.47266, 0.598251, -0.575384}}

the above code is the Rungekutta 4 solution for the given differential equation f'(x,t)=sin(x)+sin(t). To find the the solution we have to give the equation inside the c Code . Its fine if the equation is simple and only one. When there are multiple equations and the equations are complex it is difficult to redefine every variable inside the c code again because CUDAFunctionLoad doesnot accept this kind of input.It only accepts the list of numeric.

$\endgroup$
  • 4
    $\begingroup$ It is not quite clear to me what you are asking. What relationship do strings and equations have? Also, "Byte" is a valid argument type, which provides a way to encode strings. $\endgroup$ – Szabolcs Sep 27 '18 at 7:57
  • 1
    $\begingroup$ Thanks for your consideration and reply @Szabolcs. Actually the general equations in mathematica contains mainy variables , so it requires for me to input the array of equations into the c code, rather defining again in c. I have tried with "Byte" type i am not sure whether its working. $\endgroup$ – revanth roy Sep 27 '18 at 8:28
  • 2
    $\begingroup$ What would you do with a string of a Mathematica expression in C? $\endgroup$ – Szabolcs Sep 27 '18 at 8:30
  • $\begingroup$ @Szabolcs Sir, I want to input the above equation using CUDAFunctionLoad and the equation contains variables in which the return type to it must be character or strings $\endgroup$ – revanth roy Sep 28 '18 at 1:58
1
$\begingroup$

The way to do this is to construct C code as a string. CForm is a useful tool for simple expressions, but more complicated programming needs help. Here's an example of translating a StateSpaceModel into C:

Helpers to extract the parts of a discrete time state space model.

a[m_[{a_, b_, c_, d_}, p__Rule]] := a /; m === StateSpaceModel
b[m_[{a_, b_, c_, d_}, p__Rule]] := b /; m === StateSpaceModel
c[m_[{a_, b_, c_, d_}, p__Rule]] := c /; m === StateSpaceModel
d[m_[{a_, b_, c_, d_}, p__Rule]] := d /; m === StateSpaceModel
tsamp[m_[{a_, b_, c_, d_}, p__Rule]] := 
 SamplingPeriod /. p /; m === StateSpaceModel

A function to construct a list of C assignment statements.

assign[lhs_String, rhs_] := lhs <> " = " <> ToString[CForm[N[rhs]]] <> ";"
assign[lhs_Symbol, rhs_] := assign[ToString[lhs], rhs]
SetAttributes[assign, Listable]

Make a list of variables like {x1, x2, ...}. Omit the number if only one.

mkvars[root_String, n_Integer] := (root <> #) & /@ (ToString /@ Range[n]) // 
  ToExpression
mkvars[root_String, 1] := {ToExpression[root]}

Make a list of variable declarations.

varDecls[init_, decls__] := 
 "float " <> 
  stringRiffle[Map[initstring[init, #] &, Flatten[{decls}]], ", "] <> ";\n"
initstring[init_, s_] := ToString[s] <> init

Construct C code to implement a discrete time state space model, with input "u", output "y", state variables "x", temporaries "xt".

stateCode[m_StateSpaceModel] := 
 With[{
   a = a[m] /. {0. -> 0, 1. -> 1},
   b = b[m] /. {0. -> 0, 1. -> 1},
   c = c[m],
   d = d[m]},
  With[{
    x = mkvars["x", Length[a]],
    xt = mkvars["xt", Length[a]],
    y = mkvars["y", Length[c]],
    u = mkvars["u", Length[d[[1]]]]},
   varDecls["=0", x] <>
    varDecls["", xt, y, u] <>
    stringRiffle[
     Join[
      assign[y, c.x + d.u],
      assign[xt, a.x + b.u],
      assign[x, xt]],
     "\n"]]]

Given a model (not included here), you may then generate code as follows:

stateCode[someStateSpaceModel[...]]

Yielding, as a string:

 "float x1=0, x2=0, x3=0, x4=0, x5=0, x6=0;
 float xt1, xt2, xt3, xt4, xt5, xt6, y, u;
 y = 0.031127973531929903*u - 0.02101524984082605*x1 -
 0.035188225051206584*x2 - 0.1213134928462274*x3 + 
 0.3160616000095401*x4 + 0.010488819711376657*x5 + 
 0.2621918599112481*x6;
 xt1 = x2;
 xt2 = x3;
 xt3 = x4;
 xt4 = x5;
 xt5 = x6;
 xt6 = u - 0.08803437213024824*x1 + 0.805012011701874*x2 - 
 3.0263511390065165*x3 + 6.024518327556238*x4 - 6.727592601453252*x5 + 
 4.010120040702665*x6;
 x1 = xt1;
 x2 = xt2;
 x3 = xt3;
 x4 = xt4;
 x5 = xt5;
 x6 = xt6;"

You may then concatenate this string to other strings to make a complete definition for CUDALink.

| improve this answer | |
$\endgroup$
  • $\begingroup$ The "SymbolicC`" package might be useful too $\endgroup$ – b3m2a1 Sep 28 '18 at 17:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.