Thursday, November 29, 2012

OpenCL/CUDA: How to resolve "Arguments mismatch for instruction 'mov' "

The following OpenCL kernel fails on my MacBook, CUDA 5.0/OpenCL framework:

__kernel void scalMov(const int N, __global float *x, __global float *y)
{
    const int idx = get_global_id(0);
 if (idx < N)
 {
  x[idx] = 0.1*y[idx];
 }
}

And puts out the error message

ptxas application ptx input, line 38; error : Arguments mismatch for instruction 'mov'
ptxas fatal : Ptx assembly aborted due to errors

There is one easy way to remove that:
__kernel void scalMov(const int N, __global float *x, __global float *y)
{
    const int idx = get_global_id(0);
 if (idx < N)
 {
  float beta = 0.1;
  float alpha = beta*y[idx];
  x[idx] = alpha;
 }
}

The reason for this seems to be the = operation above, which is given some wrong parameters. Funny thing is, this kernel works:

__kernel void scalMov(const int N, __global float *x, float alpha, __global float *y)
{
    const int idx = get_global_id(0);
 if (idx < N)
 {
  x[idx] = alpha*y[idx];
 }
}

So the "mov" instruction only has problems when you are using constants in it.
So if you're having the same problems, try to comment out all your assignments so you can find out which assignment is making problems, then split the assignment up. Note that you have to split it up several times otherwise the OpenCL compiler will "optimize" it back again for you.

Monday, November 26, 2012

Mimicking cout and Java strings in Julia

If you're coming from C++, perhaps you're going to miss cout or some of those fancing ostream stuff in fstream. In Julia, you have print and println, but you have to enclose everything in brackets and the ',' seperation is not really what you're used to when you're coming from C++. I also always enjoyed how easy it is in Java to compose strings. Luckily, it is very easy to incorporate the ostream and String behaviour into Julia, and it also shows some of the nice features of Julia.

cout << "Hello, Julia!\n";

First, we're going to create a singleton named cout. There is a special syntax for singletons in Julia (see here): a type without members.
Next, we'll need a function which handles the operator <<. This works much like in C++, since operators are functions. The function will just take the other argument, and print it:

# our coutType singleton
type coutType
end
cout = coutType()

# the operator <<
function << (c::coutType, t)
    print(t)
    return cout
end

Here we have to apply the same mechanism as in C++: The operator << returns the output object so that chained <<'s are possible. Now we can try our code:

julia> cout << "Hello, Julia! It is " << 
       time()/3600/24/365 << " years since epoch.\n";
Hello, Julia! It is 42.93542962147783 years since epoch.

If you omit the ; at the end, you still have valid julia code, but in the julia shell you will get an output like coutType(XXXX) after your output (in loaded files you won't). That's because the julia shell automatically displays the return values of the last statement. ; is the chained expressions operator , so by inserting a ; at the end you are inserting an empty instruction, which has no return type.
Note that you have to enclose temporary calculations in brackets like for cout << (1+2) << " is " << 3 << "\n"; .

"composing " + "Strings"

Next we want to have something to use strings as in Java: a = "it's the year " + 2012 + "!". For this, we need to specify a function for +:
# + for strings with variable number of arguments
function +(a::ASCIIString, tArgs...)
    for t in tArgs
        a = strcat(a,t)
    end
    return a
end

Here we used Julias nice vargs ability combined with the fact that something like "a"+2+"c" is translated in + ("a", 2, "b").

fstream

Of course you can apply the cout idea to other streams, here's for files:
# << operator for files
function << (out::IOStream, t)
   write(out, t)
   return out
end
# .<< operator for files for writing data stringified (e.g. 2 as "2")
function .<< (out::IOStream, t)
    write(out, string(t))
    return out
end

And again an example:

myFile=open("year.txt", "w")
year = 2012
myFile << "It is the year " .<<  year << ".\n"
close(myFile)

Notice the use of the .<< operator here so 2012 is translated to the string "2012" before being written to the file (otherwise it will write 2012 as binary).

split ostreams

Another idea is to create objects that stream into the console and into a file, which is useful for logging and similar tasks:

type loggerType
    file::IOStream
end
logger = loggerType(open("log.txt", "w"))

function << (out::loggerType, t)
    out.file .<< t
    cout << t
    return out    
end

year = 2012
logger << "Still the year " << 2012 << "!\n"

close(logger.file)