Алексей, у меня Ваш код работает (GTX680M, Linux) и с N_block = 1, и с N_block = 2. Пара исправлений:
1) В вызове fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__) не хватает аргумента. Заменил на макрос
2) Размер грида на sm_30 и выше больше, чем диапазон int. Заменил на uint64_t, и, соответственно, тип индекса в ядре. Иначе int переполнится, станет отрицательным, и всё пропало.
Но это скорее косметика. А вот принципиальная проблема состоит в том, что автор кода не до конца разобрался в том, как выбирать конфигурацию грида. В частности:
1) Возможность или невозможность запуска конфигурации ограничена не только размерностями, но и, например, числом регистров. Почитайте об этом в книге или в доках. Скорее всего работающий/не работающий случаи объясняются именно этим.
2) Непонятно, какой смысл запускать ядро с гридом, не зависящим от размера самой задачи. Скажем вот с uint64_t N_block = prop.maxGridSize[0] будет честно запущен миллиард блоков. На свободном GPU это будет считаться очень долго, а на GPU с таймаутом драйвер остановит ядро через небольшое время и выдаст ошибку (как раз упоминаемый Вами "сбой драйвера").
"Глюк CUDA" звучит немного как "мой компьютер захватили инопланетяне". Пожалуйста, разделите разные проблемы на отдельные письма с более конкретными названиями.
- Д.