Implicit constructor in CUDA kernel call

后端 未结 2 1237
执念已碎
执念已碎 2021-01-21 13:24

I\'m trying to pass some POD to a kernel which has as parameters some non-POD, and has non explicit constructors. Idea behind that is: allocate some memory on the host, pass the

相关标签:
2条回答
  • 2021-01-21 13:40

    Ok, I found it works (constructors are called) if I add both __host__ and __device__ qualifiers to the constructors. The constructor of the objects happened at host side, and then they were copied to device (stack?). This is why the constructors weren't called: they were device code (but what was called on the host side?!?)

    Using both __host__ and __device__ in the constructors allowed to use the class without problems.

    EDIT: Still, I'm not sure if the construction always happens before the copy to device.

    0 讨论(0)
  • 2021-01-21 13:47

    You have to see a constructor just like a normal method. If you qualify it with __host__, then you'll be able to call it host-side. If you qualify it with __device__, you'll be able to call it device-side. If you qualify it with both, you'll be able to call it on both sides.

    What happens when you do dosome<<<1, 2>>>(2, 3); is that the two objects are implictly constructed (because your constructor is not explicit, so maybe that's confusing you too) host side and then memcpy'd to the device. There is no copy-constructor involved in the process.

    Let's illustrate this:

        __global__ void dosome(Test a, Test b) {
            a.calc();
            b.calc();
        }
    
        int main(int argc, char **argv) {
            dosome<<<1, 2>>>(2, 3); // Constructors must be at least __host__
            return 0;
        }
    
    // Outputs:
    Construct 2 (from the host side)
    Construct 3 (from the host side)
    

    Now if you change your kernel to take ints instead of Test:

    __global__ void dosome(int arga, int argb) {
        // Constructors must be at least __device__
        Test a(arga);
        Test b(argb);
        a.calc();
        b.calc();
    }
    
    int main(int argc, char **argv) {
        dosome<<<1, 2>>>(2, 3);
        return 0;
    }
    
    // Outputs:
    Construct 2 (from the device side)
    Construct 3 (from the device side)
    
    0 讨论(0)
提交回复
热议问题