"deleted constructor" compiler error when using constant memory

Hey everyone,

I must run a kernel that has excessively many parameters. So I decided to put them all in constant memory rather than passing them during kernel invocation. It happens that the struct I created contains const pointers (which are device pointers) like

struct A
{
float const* data;
};

When I try to declare a constant variable like

constant A a[ 1 ];

The compiler refuses with an error that I attempted to access a deleted constructor. While that makes perfect sense for normal C++ it is rather annoying in Cuda because I will use cudaMemcpyToSymbol to initialize the data. And even if I intended I could not use a constructor, deleted or not.

Has anybody an idea how to deal with that?

Thanks a lot!

PS I propose that constructor invocation be ignored for constant declarations.

I don’t have any trouble compiling the code you have posted here.

It’s true that you can’t use constructors with device or constant variables, but the code you have shown here doesn’t involve any of that.

Thank you for your quick response. In fact, you are right. I figured out that the problem of my original post was shortened a little too much and it was not the pointers I initially suspected. My apologies for not posting a good example.

This code reproduces my error in VS 2017 / Cuda 10.1

struct A
{
int a;
};

struct B
{
const A a;
};

constant B b[ 1 ];

“error : the default constructor of “B” cannot be referenced – it is a deleted function”

I think the workarounds here seem pretty obvious. I wouldn’t be able to debate it.

If you’d like to report a bug or request a change to CUDA behavior, you can do so using the instructions for bug filing linked to a sticky post at the top of this forum.

Just for completeness for anyone who comes across:

Since

struct A
{
const int a;
};

struct B
{
A a;
};

constant B b[ 1 ];

fails all the same, the options are

  1. flatten out the structs into one big struct
  2. remove the const qualifier

Decide whether you want to maintain readability or programming safety.

Uninitialized const-qualified members in struct or class seem quite odd to me when there is no constructor.

https://stackoverflow.com/questions/8092670/uninitialized-const

but if it makes sense to you, great. I’m not sure that code is portable to linux. Yes, I acknowledge you can’t provide a constructor, but that is after all a stated limitation of CUDA device and constant usage.

To be clear: I do not want to use a constructor. I am forced to live with a default constructor which is created by the compiler and deleted because of the const.

So this is what the compiler makes of my struct B

struct B
{
B() = deleted;
const A a;
};

I would rather like nvcc to detect that

constant B b[ 1 ];

is constant, just allocate the device memory needed to hold the data and suppress the constructor altogether. Further down the pipeline, cudaMemcpyToSymbol will overwrite the content anyways.

Thanks alot for your time!