1

Let us assume that we have the following strings that we need to store in a CUDA array.

"hi there"

"this is"

"who is"

How do we declare a array on the GPU to do this. I tried using C++ strings but it does not work.

2
  • Do you really mean "CUDA array" (as in spatially ordered data for use with textures and surfaces) or do you mean "array usable for general global memory access inside a kernel"? Commented Jul 9, 2012 at 7:25
  • @talonmies: I just need to create an array of strings and access it in global memory. Something like char** array in C. How can we do this for the GPU. Moreover, as there are no strcmp function in CUDA, what is the workaround for this Commented Jul 10, 2012 at 5:39

2 Answers 2

2

Probably the best way to do this is to use structure that is similar to common compressed sparse matrix formats. Store the character data packed into a single piece of linear memory, then use a separate integer array to store the starting indices, and perhaps a third array to store the string lengths. The storage overhead of the latter might be more efficient that storing a string termination byte for every entry in the data and trying to parse for the terminator inside the GPU code.

So you might have something like this:

struct gpuStringArray {
    unsigned int * pos; 
    unsigned int * length;  // could be a smaller type if strings are short
    char4 * data; // 32 bit data type will improve memory throughput, could be 8 bit
} 

Note I used a char4 type for the string data; the vector type will give better memory throughput, but it will mean strings need to be aligned/suitably padded to 4 byte boundaries. That may or may not be a problem depending on what a typical real string looks like in your application. Also, the type of the (optional) length parameter should probably be chosen to reflect the maximum admissible string length. If you have a lot of very short strings, it might be worth using an 8 or 16 bit unsigned type for the lengths to save memory.


A really simplistic code to compare strings stored this way in the style of strcmp might look something like this:

__device__ __host__
int cmp4(const char4 & c1, const char4 & c2)
{
    int result;

    result = c1.x - c2.x; if (result !=0) return result; 
    result = c1.y - c2.y; if (result !=0) return result; 
    result = c1.z - c2.z; if (result !=0) return result; 
    result = c1.w - c2.w; if (result !=0) return result; 

    return 0;
}

__device__ __host__
int strncmp4(const char4 * s1, const char4 * s2, const unsigned int nwords)
{
    for(unsigned int i=0; i<nwords; i++) {
        int result = cmp4(s1[i], s2[i]);
        if (result != 0) return result;
    }

    return 0;
}

__global__
void tkernel(const struct gpuStringArray a, const gpuStringArray b, int * result)
{
    int idx = threadIdx.x + blockIdx.x * blockDim.x;

    char4 * s1 = a.data + a.pos[idx];
    char4 * s2 = b.data + b.pos[idx];
    unsigned int slen = min(a.length[idx], b.length[idx]);

    result[idx] = strncmp4(s1, s2, slen);
}

[disclaimer: never compiled, never tested, no warranty real or implied, use at your own risk]

There are some corner cases and assumptions in this which might catch you out depending on exactly what the real strings in your code look like, but I will leave those as an exercise to the reader to resolve. You should be able to adapt and expand this into whatever it is you are trying to do.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot. This looks useful. However, how do I compare two strings on the GPU?
I gave you one up for this much. will be obliged if you could answer the question in my comment
@Programmer: "this much" completely answers the question you asked. I didn't see any reference to string comparison in the original question. But I have made a small edit that might give you a start on whatever it is you are actually trying to acheive.
-1

You have to use C-style character strings char *str. Searching for "CUDA string" on google would have given you this CUDA "Hello World" example as first hit: http://computer-graphics.se/hello-world-for-cuda.html There you can see how to use char*-strings in CUDA. Be aware that standard C-functions like strcpy or strcmp are not available in CUDA!

If you want an array of strings, you just have to use char** (as in C/C++). As for strcmp and similar functions, it highly depends on what you want to do. CUDA is not really well suited for string operations, maybe it would help if you would provide a little more detail about what you want to do.

2 Comments

This doesn't really answer the question - he wants to know how to store and manage an array of strings in the GPU, not a single string.
I thought the main problem were the strings themselves (since Programmer tried to use C++ stings in CUDA!). From there, it should quite simple to create an array of strings. I noticed that this question is very similar to those two: stackoverflow.com/questions/6566910/… and stackoverflow.com/questions/6561005/… .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.