You are doing nothing wrong, but trying to run
length(Xs,N), domain(Xs,0,N), all_distinct(Xs), labeling([],Xs).
for N up to 1,000,000. The system creates a search tree with depth N and must store intermediate states of variables and a constraint system for each level. It takes up a lot of memory for large N, and it is quite possible that you get memory overflow for one run with large N.
The second problem is that you use your tests in a recursive loop, i.e. effectively create a connection
atest(0,0), ..., atest(1000,1000)
and since every atest / 2 call succeeds with its first solution and retains its search state, this means that you are trying to create a search tree with levels 250500250000 ...
The simplest improvement is to reduce each search after the first solution by changing the code to once(atest(C,R)) . A further improvement is to run tests in a failover cycle.
( between(0,Cm,C), between(0,Cr,R), once(atest(C,R)), fail ; true )
which will free up memory faster and faster and reduce the distortion of your measurements due to garbage collection.