Вы должны начать уделять гораздо больше внимания выводу компилятора.Ваш второй код ядра:
__global__ void setVal(char **word)
{
char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x];
myWord = "Hello\0";
}
компилируется в нулевое ядро, в котором ничего нет:
$ nvcc -arch=sm_20 -c nullkernel.cu
nullkernel.cu(3): warning: variable "myWord" was set but never used
nullkernel.cu(3): warning: variable "myWord" was set but never used
Причина в том, что то, что вы считаете назначением копирования строк, на самом деле простоназначение указателя, и в этом случае компилятор достаточно умен, чтобы знать, что myWord не записывается в память, поэтому он просто удаляет весь код и предупреждает вас, что myWord не используется.
Если бы язадайте риторический вопрос и переписайте код следующим образом:
__global__ void setVal(char **word)
{
char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x];
const char[] mymsg = "Hello\0";
myWord = mymsg;
}
было бы более очевидно как в том, почему код не компилируется, так и в том, почему он никогда не мог "неявно" выполнить присвоение строки, даже если онскомпилировал?