0

everyone! I am starting to study CUDA programming and I noticed one thing when studying the 1D stencil problem implementation.

To run the function at the device one must write fun_name<<<blocks,threads>>>(arguments). I wrote a test code to print the vector values considering the global index:

#include<stdio.h>
#include<stdlib.h>

    #define size  6
    #define num_threads 3

__global__ void test(int *d_v){
    int gidx = threadIdx.x + blockIdx.x * blockDim.x;
    printf("gidx = %d; v[gidx] = %d \n", gidx, d_v[gidx]);
}

int main(){
    // defining a pointer in host
    int *v;
    // defining a pointer in device
    int *d_v;

    v = (int*)malloc(size*sizeof(int));

    cudaMalloc((void**) &d_v, sizeof(int)*size);
    
    for(int i = 0; i < size; i++){
        v[i] = (size - i);
        printf("%d ", v[i]);
    }
    printf("\n");

    cudaMemcpy(d_v, v, size*sizeof(int), cudaMemcpyHostToDevice);

    test<<<size/num_threads,num_threads>>>(d_v);
    cudaDeviceSynchronize();

    free(v);
    cudaFree(d_v);
    
}

My question is: If I run the test function as test<<<size/num_threads,num_threads>>>(d_v + number); the values in vector d_v will shift by the same amount of number. Why?

In Python and MATLAB, when we add a constant to an array, the value is summed to the array elements. Thus, my intuition says, at first, that calling d_v + number it would add the value number to the elements of d_v (I know that d_v is a pointer and things may work differently).

edit: I gave the example of adding a constant to an array in Python and MATLAB just to ilustrate. I do not want to sum a constant to the array defined as a pointer, just to know why the indexes changed. Thus, the suggested reply concerning pointers arithmetics does not offer a answer to my question.

Felipe_SC
  • 1
  • 3
  • 1
    I guess you are not familiar with c or c++ programming and pointer arithmetic. That would be the starting point. This is not python. – Robert Crovella Nov 11 '22 at 13:24
  • Look at it from this angle: Adding a constant to all values in a big array is itself an operation that one would put in a kernel in this context. C is a systems programming language where arithmetic operations like `+` only operate on primitive types like `int` or `double`. A pointer is just an address, i.e. an unsigned integer type. Adding to it gives you a different, higher address. In C++ one can overload operators for classes, but even there this kind of vector operator overload is only done in specialized linear algebra libraries. – paleonix Nov 11 '22 at 13:49
  • Hi @RobertCrovella. Thanks for your answer! I am also new to C/C++ programming :) I have read a bit about pointers... My question was not about how add a value to all elements, but why passing the pointer + value to the global function shifted the array values. – Felipe_SC Nov 11 '22 at 14:47
  • Hi @paleonix. Thanks for your answer!! I revisited the way for deferencing values stored in the memory as ```*(d_v + index)``` to access the data stored at the i-th position. So, when passing ```d_v + number``` to the global function would be equivalent to say to the program: "Take the values in ```d_v``` and shift all addresses by the amount specified in ````number````"? That makes sense to me... and would explain why, after displacing to the left, the values are accessed by negative indexes. – Felipe_SC Nov 11 '22 at 14:58
  • Yes, I understood that your question was not about how to add a value to all elements. The reason adding a value to the pointer "shifts" array elements has to do with pointer arithmetic and its effects. Your question is really about C or C++, not anything unique or specific to CUDA. The answer to your question will become evident to you once you have a solid grasp of pointers and how pointer arithmetic works. – Robert Crovella Nov 11 '22 at 15:16
  • Thanks, @RobertCrovella! I will read more about pointers in C/C++. Did you read the comment citing paleonix? Does that makes sense? What confused me was performing this pointer arithmetics while passing it to a function – Felipe_SC Nov 11 '22 at 16:25
  • Yes, I read the comments by paleonix. I believe paleonix is a smart individual and very knowledgeable in these areas. I don't see any issues. It's helpful commentary. A pointer is an address, and adding a value to it adjusts the address. The perhaps slightly unusual thing about pointer arithmetic is that even though a pointer ultimately has a granularity of a byte, doing pointer arithmetic on a pointer is "automatically" adjusted to index by *elements*, whatever element type the pointer refers to. So in most cases, adding 1 to a pointer does not access the next byte, but the next element. – Robert Crovella Nov 11 '22 at 16:33
  • I meant my comment citing paleonix XD You mentioned that adding to the pointer will access the next element. How does it explain the shitf in the indexes in the example I posted? I would expec the function recieving the values of ```idx + number``` instead of shifting those values to the left or right – Felipe_SC Nov 11 '22 at 16:39
  • I am asking because when I call the function, for example, as ```test<<>>(d_v + 1);```. The value prevously allocated in ```d_v[0] ``` goes to ```d_v[-1]```. I understood accessing the next value by adding 1, but not yet hot it assigns those values to ```index-1``` – Felipe_SC Nov 11 '22 at 16:49
  • I think now I understood... Considering a simple example with two pointer ```v``` and ```v_n```: When it is declared ```int *v_n = v+1;``` the index ```-1``` in ```v_n``` will be ```-1 + 1 = 0``` in ```v```; index ```0``` in ```v_n``` will be ```0 + 1 = 1``` in ```v``` and so on. – Felipe_SC Nov 11 '22 at 17:36

0 Answers0