UnreachableCode
UnreachableCode

Reputation: 1791

Need to convert global variables into local variables in C

Basically, I sloppily coded an OpenCL program for an assignment using these global variables:

int devType = CL_DEVICE_TYPE_GPU;

cl_int err;         /* Error code returned from api calls.  */
size_t global;      /* Global domain size for our calculation.  */
size_t local;           /* Local domain size for our calculation.  */

cl_platform_id cpPlatform;  /* openCL platform.  */
cl_device_id device_id; /* Compute device id.  */
cl_context context;     /* Compute context.  */
cl_command_queue commands;  /* Compute command queue.  */
cl_program program;     /* Compute program.  */
cl_kernel kernel;       /* Compute kernel.  */

/* Create data for the run.  */
float *data = NULL;     /* Original data set given to device.  */
float *results = NULL;  /* Results returned from device.  */
unsigned int correct;       /* Number of correct results returned.  */
cl_mem input;           /* Device memory used for the input array.  */
cl_mem output;      /* Device memory used for the output SUM.  */

int rc = EXIT_FAILURE;

Now I'm trying to make them all local in order to tidy the program up.

I converted a global variable N by just moving it away from the variables above into the main() function. I then updated every function header that used N to have 'int N' as a parameter, and passed N into any function calls that needed it as an argument. The program worked as expected.

So I suppose what I'm asking is, for the rest of these variables, will it be that simple? I understand the concepts of passing by reference and value and realise some functions may change variables, so I'll need to use pointer referencing/dereferencing. My concern is that my pointer theory is a little rough and I'm worried I'll run into problems. I also am unsure whether my defined functions can take all of these cl variables.

Also, is there anything wrong with using the same variable names within the functions?

EDIT:

As I feared, a problem does occur in the following functions when trying to localise device_id:

void deviceSetup(int devType) {
    cl_platform_id cpPlatform;  /* openCL platform.  */

    /* Connect to a compute device.  */
    if (CL_SUCCESS != clGetPlatformIDs (1, &cpPlatform, NULL))
        die ("Error: Failed to find a platform!");

    /* Get a device of the appropriate type.  */
    if (CL_SUCCESS != clGetDeviceIDs (cpPlatform, devType, 1, &device_id, NULL))
        die ("Error: Failed to create a device group!");
}

/* Create a compute context.  */
void createContext(cl_int err){
    context = clCreateContext (0, 1, &device_id, NULL, NULL, &err);
    if (!context || err != CL_SUCCESS)
        die ("Error: Failed to create a compute context!");
}

/* Create a command commands.  */
void createCommandQueue(cl_int err) {
    commands = clCreateCommandQueue (context, device_id, 0, &err);
    if (!commands || err != CL_SUCCESS)
        die ("Error: Failed to create a command commands!");
}       

void createAndCompile(cl_int err){
    /* Create the compute program from the source buffer.  */
    program = clCreateProgramWithSource (context, 1,
                                         (const char **) &KernelSource,
                                         NULL, &err);
    if (!program || err != CL_SUCCESS)
        die ("Error: Failed to create compute program!");

    /* Build the program executable.  */
    err = clBuildProgram (program, 0, NULL, NULL, NULL, NULL);
    if (err != CL_SUCCESS)
    {
        size_t len;
        char buffer[2048];

        clGetProgramBuildInfo (program, device_id, CL_PROGRAM_BUILD_LOG,
                               sizeof (buffer), buffer, &len);
        die ("Error: Failed to build program executable!\n%s", buffer);
    }
}

Upvotes: 2

Views: 2183

Answers (1)

Joe
Joe

Reputation: 7798

You've answered your own question really. Yes, that really is all there is to it. You may want to consider combining a large number of related variables into a struct and pass just a pointer to that struct if you find you've generated massive parameter lists for your functions but that's about it. (There is a tiny degree of performance consideration relating to the number of parameters you pass to any function, but I think for now that's an unnecessary level of complication you could do without!)

There's no getting away from understanding pointers in C though (the only way to pass by reference) so a small project like this might well be an ideal time to strengthen that knowledge!

OK, let's have an example, life's always better explained that way.

We have:

int cheddar;
int montereyjack;
int brie;

void print_cheeses(void)
{
    printf("I have %d cheddar %d montereyjack and %d brie\n", cheddar, montereyjack, brie);
}

void add_cheeses(void)
{
   cheddar = cheddar + 1;
   montereyjack = montereyjack + 1;
   brie = brie + 1;
   print_cheeses();
}

int main(int argc, char *argv[])
{
    add_cheeses();
    printf ("Now I have %d cheddars %d jacks %d bries\n", cheddar, montereyjack, brie);
}

What we need to get to is:

// By value here because we're not changing anything
void print_cheeses(int cheds, int jacks, int bries)
{
    printf("I have %d cheddar %d montereyjack and %d brie\n", cheds, jacks, bries);
}

// Pointers here because we need to change the values in main
void add_cheeses(int *cheese_one, int *cheese_two, int *cheese_three)
{
   *cheese_one = *cheese_one + 1; // We're following the pointer to get to the data we want to change
   *cheese_two = *cheese_two + 1;
   *cheese_three = *cheese_three + 1;
   print_cheeses(*cheese_one, *cheese_two, *cheese_three); // We're following the pointer to get to the data we want to print
}

int main(int argc, char *argv[])
{
    int cheddar = 0;
    int montereyjack = 0;
    int brie = 0;

    add_cheeses(&cheddar, &montereyjack, &brie);

    printf ("Now I have %d cheddars %d jacks %d bries\n", cheddar, montereyjack, brie);
}

But it can be a pain passing all three values each time, and since they're related you could bundle them together in one struct and just pass a pointer to that struct about.

Upvotes: 5

Related Questions