mardi 5 mai 2015

Converting C Program To CUDA (Max Reduction)

I am new to CUDA and trying to get a grasp for the basic so I apologize if something I ask or say sounds overly simple.

EDIT: Using the code provided by Robert Crovella below I am trying to convert the code to use multiple threads rather than one.

I have come up with the following code:

#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <cuda.h>

#define num 100000

#define cudaCheckErrors(msg) \
    do { \
        cudaError_t __err = cudaGetLastError(); \
        if (__err != cudaSuccess) { \
            fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                msg, cudaGetErrorString(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
        } \
    } while (0)


int *arr,my_max = -1;

int getRand() {
    double r1=rand()/(double)RAND_MAX; // Generates value between 0 & 1
    return (r1 * num) + 1;
}
void generateRandom(int M) {
    int i;
    for(i=0;i<M;i++) {
        arr[i] = getRand();
    }
}
__global__ void getMax(int M, int *dArr, int *dMax) {
    int id = threadIdx.x;
    int numberThisThread = M / 32;
    int start = numberThisThread * id;
    int end = numberThisThread * (id + 1);
    for(int i=start;i<end;i++) {
        int a = dArr[i];
        if(a > *dMax)
            *dMax = a;
        }
}

int main(int argc, char *argv[] ){
    if (argc == 2) {
        int M;
        int *devArr, *devMax;
        /* initialize random seed: */
        srand (time(NULL));
        M = atoi(argv[1]);
        //int arr[M];
        arr = (int*)calloc(M,sizeof(int));
        cudaMalloc(&devArr,M*sizeof(int));
        cudaCheckErrors("cudaMalloc 1 fail");
        cudaMalloc(&devMax,sizeof(int));
        cudaCheckErrors("cudaMalloc 2 fail");
        cudaMemset(devMax, 0, sizeof(int));
        cudaCheckErrors("cudaMemset fail");
        //printf("M = %d MAX = %d\n", M, RAND_MAX);

        generateRandom(M);
        cudaMemcpy(devArr, arr, M*sizeof(int), cudaMemcpyHostToDevice);
        cudaCheckErrors("cudaMemcpy 1 fail");
        getMax<<<64,1>>>(M, devArr, devMax);
        cudaMemcpy(&my_max, devMax, sizeof(int), cudaMemcpyDeviceToHost);
        cudaCheckErrors("cudaMemcpy 2/kernel fail");
        printf("Max value: %d \n", my_max);

    }

    else
        printf("Invalid arguments.");

    return 0;
}

My idea in the implementation was to divide the amount of input by the amount of threads and have each thread compute its own section. This code just hangs though and does not produce any output.

Aucun commentaire:

Enregistrer un commentaire