Saturday, 5 May 2012

FizzBuzz - in CUDA

FizzBuzz has been around for a while, as an exercise to weed out candidates who say they can program, but can't; I think this is the origin of using it for that purpose http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
I wanted just a blatant excuse to play with some CUDA one evening, so I implemented FizzBuzz in CUDA - simply by unrolling the loop.

The code for this is available here http://hg.ryant.org/fizzbuzz-cuda/ and requires the Nvidia CUDA toolkit.

The kernel and main function for this are very simple
#define FB_MAX 100

#define FIZZ 0x01
#define BUZZ 0x02

__global__ void fizzbuzz(unsigned char *fbValues) {
        int tid = blockIdx.x;
        if (tid < FB_MAX) {
                fbValues[tid] = 0;
                fbValues[tid] = fbValues[tid] | (tid % 3 == 0 ? FIZZ : 0);
                fbValues[tid] = fbValues[tid] | (tid % 5 == 0 ? BUZZ : 0);
        }
}
int main() {
        cudaEvent_t start, stop;
        float elapsedTime;

        cudaEventCreate(&start);
        cudaEventCreate(&stop);

        unsigned char fbValues[FB_MAX];
        unsigned char* devFbValues;

        cudaEventRecord(start, 0);
        cudaMalloc((void**) &devFbValues, FB_MAX * sizeof(unsigned char));
        fizzbuzz<<<FB_MAX,1>>>(devFbValues);
        cudaMemcpy(&fbValues, devFbValues, FB_MAX * sizeof(unsigned char), cudaMemcpyDeviceToHost);
        cudaEventRecord(stop, 0);
        cudaEventSynchronize(stop);
        cudaEventElapsedTime(&elapsedTime, start, stop);

        // clean up
        cudaFree(devFbValues);
        cudaEventDestroy(start);
        cudaEventDestroy(stop);

        // Print out the results
        int i;
        for (i = 0; i < FB_MAX; i++) {
                std::stringstream s;
                s << i << " ";
                
                if (fbValues[i] & FIZZ) {
                        s << "Fizz ";
                }
                if (fbValues[i] & BUZZ) {
                        s << "Buzz";
                }

                std::cout << s.str() << std::endl;
        }

        std::cout << "Device Time: " << std::setprecision(5) << elapsedTime << " ms" << std::endl;

        return 0;
}



No comments:

Post a Comment