Non-deterministic compilation when anonymous namespaces are used

Hi,

Consider the following example code, foo.cu:

namespace
{
  constexpr int MyVariable = 1;
}

Compiling this file with NVCC repeated times leads to an object file with different checksums:

$ nvcc --keep -c foo.cu -o foo.o && sha256sum foo.o
1427f8aa6ed432d8d13286f4668a968f761dace6416a3794a63b04c58e5a6ddd foo.o
$ nvcc --keep -c foo.cu -o foo.o && sha256sum foo.o
b9638413cb4169f21362c6877cbf63824dce1cf8586b890fbe7a9b96183af9a6 foo.o

Please note the --keep flag to avoid random paths from entering into the binary.

Inspecting the symbols of the object file, we clearly see that the name mangling of the variable in the anonymous namespace changes for every compilation:

$ nm foo.o | grep MyVariable
0000000000000000 r _ZN44_GLOBAL__N__432e6cba_6_foo_cu_a222da5b_37308L10MyVariableE

Recompile...

$ nm foo.o | grep MyVariable
0000000000000000 r _ZN44_GLOBAL__N__432e6cba_6_foo_cu_a222da5b_37378L10MyVariableE

This is a problem for build systems based on reproducible builds, like Bazel, which expect every recompilation to generate a file with the exact same checksum if nothing has changed. However, NVCC does generate a file with different checksum even if nothing changes.

Why is this? Is there a flag we can pass to prevent this behavior and ensure a fully deterministic build?

If I remove the anonymous namespace, the build is fully deterministic.

Note: this is tested on cuda_12.6.r12.6/compiler.34431801_0, Ubuntu 24.04.

Thanks!

my suggestion would be to file a bug

Thanks, I’ve just done that. Hopefully it’s gets addressed, I have like 5 open bugs from 2+ years ago without feedback :(