# why ParallelDo do not do right?

I encountered a problem with ParallelDo. The code below is part of my program. It won't give the right answer. But as soon as I change ParallelDo to ordinary Do, the result is right.

I tried somethings like DistributeDefinitions, but it didn't work.

So what is wrong?

Clear[spinmat];
spinmat[{\[DoubleStruckI]1_, \[DoubleStruckJ]1_,
site1_}, {\[DoubleStruckI]2_, \[DoubleStruckJ]2_, site2_}] :=
Table[h[[label[\[DoubleStruckI]1, \[DoubleStruckJ]1, site1, mm],
label[\[DoubleStruckI]2, \[DoubleStruckJ]2, site2, nn]]], {mm, 1,
2}, {nn, 1, 2}];

Clear[tableassign];
func_[tableassign[expr_, tobeheld__], arg___] ^:=
Block[{tobeheld, Part}, Hold @@ {expr}] /. Hold[x_] :> func[x, arg];

Clear[hop];
hop[i_, j_, ii_, jj_, val_, di_: 0, dj_: 0] :=
tableassign[spinmat[{i + di, j + dj, ii}, {i, j, jj}], h] += val;

σ = PauliMatrix[Range[4]];

t1 = 1;

ParallelDo[
hop[i, j, 1, 2, -t1*σ[[4]]];
hop[i, j, 2, 1, -t1*σ[[4]]];
hop[i, j, 2, 3, -t1*σ[[4]]];
hop[i, j, 3, 2, -t1*σ[[4]]];
hop[i, j, 3, 4, -t1*σ[[4]]];
hop[i, j, 4, 3, -t1*σ[[4]]];
, {i, 0, m + 1}, {j, 0, n + 1}];

-
You seem to be using Global symbols jdj and idi which you probably don't intent to, or didn't think through regarding parallel evaluation. –  Mr.Wizard May 29 at 6:25
@Mr.Wizard you mean jdj and idi should be contained in a block? –  matheorem May 29 at 6:27
Please consider the result of x = 0; DistributeDefinitions[x]; ParallelTable[x += i, {i, 50}] versus Table. –  Mr.Wizard May 29 at 6:51
Do can't be arbitrarily changed to ParallelDo. Think about what's happening within the loop: you're trying to change the same data structure from several parallel threads. Allowing this introduces all kinds of complications such as ensuring that two threads are not writing the same variable at the same time. So it's simply not allowed in Mathematica. In Mma each parallel thread will have it private copy of each symbol/variable, and any change you make to them will be local to that thread. You can use SetSharedVariable to make a variable writable from multiple threads ... –  Szabolcs May 29 at 15:13
... but that will effectively destroy parallelization here. Mathematica doesn't actually use threads but separate processes that can't access the same memory, so SetSharedVariable forces that variable to be accessed through the main kernel only. Your code would not run in parallel. Generally, I'd say that in this particular case if your program can't be reformulated to avoid constantly using a mutable variable then don't do it in Mathematica. If you want to make it fast, write it in C++. You seem to be coding in a low-level style anyway. –  Szabolcs May 29 at 15:14