I think, but I didn’t test, that the error is because the compiler doesn’t know where “int a” is located, in global memory, shared memory, local (private) memory, etc. Something like device void atomic_test(shared int *a) should work.
You cannot do atomics on local variables. In both of the examples you have posted, your variable i or a is local. (I think there would be no reason to have local atomics; there is no possibility for parallel access to a specific local variable; it can only be accessed by one CUDA thread.) atomic operations are possible on global or shared variables. Here are two examples using global variables:
This should work (compile):
__device__ int a;
__global__ void atomic_test()
{
atomicAdd(&a, 1);
}
I think it should be fairly obvious that your second example using i is clearly a local variable.
In your first example, any variable passed by value to a function:
__device__ void atomic_test(int a)
has local scope within that function. Changes to that variable within the function cannot show up in the calling environment, or be visible to other threads that may use that function. Therefore atomics don’t apply here (and wouldn’t make sense anyway).