2
$\begingroup$

This is my first time trying to implement a parallel computation in Mathematica and my question could be very naive. I would like to ask how I can best implement the following:

I have several Do loops that run through a list of matrices checkmat2 in which I evaluate traces based on an If statement and assign the result of each iteration to a list.

e.g.

 Do[tt = (1/(8)) Tr[checkmat2[[a, z]].checkmat2[[b, l]].checkmat2[[m, k]].checkmat2[[b, l]]];
 If[tt != 0, test1[[a]] = test1[[a]] - 2 tt*c[[b]]*c1[[m]]],
 
 {a, 6}, {b, 6}, {m, 6}, {z, Length[checkmat2[[a]]]}, {l, 
  Length[checkmat2[[b]]]}, {k, Length[checkmat2[[m]]]}]
 

For a relatively small list of matrices these loops can be evaluated relatively quickly, but checkmat2 in general contains >100 matrices which are 16x16. There's several of these loops and I would like to compute them in parallel and then combine the final result in test1. I have tried setting up an Evaluator for each loop, but I do not seem to get them running and assigning a separate kernel to each cell doesn't seem to work since the kernel doesn't recognize my variable definitions, for which I have used DistributeDefinitions[checkmat2]. What am I doing wrong?

EDIT: I include the definitions of checkmat2 and c here. One is essentially a collection of matrices and the other is a list containing symbolic constants. I also include a clarification on the problem statement:

What I would like to calculate additional loops provided in the example. And the If clause checks different quantities every time. So for example I would like to evaluate both


Do[tt = (1/(8)) Tr[checkmat2[[a, z]].checkmat2[[b, l]].checkmat2[[m, k]].checkmat2[[b, l]]];
 If[tt != 0, test1[[a]] = test1[[a]] - 2 tt*c[[b]]*c1[[m]]],
 
 {a, 6}, {b, 6}, {m, 6}, {z, Length[checkmat2[[a]]]}, {l, 
  Length[checkmat2[[b]]]}, {k, Length[checkmat2[[m]]]}]

and

Do[tt = (1/(8)) Tr[
    checkmat2[[a, z]].checkmat2[[b, l]].u[[1]].checkmat2[[m, k]].u[[
      1]].checkmat2[[b, l]]];
 If[tt != 0, test1[[a]] = test1[[a]] + 2 tt*c[[b]]*
     c1[[m]]],
 
 {a, 6}, {b, 6}, {m, 6}, {z, Length[checkmat2[[a]]]}, {l, 
  Length[checkmat2[[b]]]}, {k, Length[checkmat2[[m]]]}]`

in parallel.

Tmat = {KroneckerProduct[PauliMatrix[1], IdentityMatrix[2], 
    IdentityMatrix[2]], 
   KroneckerProduct[PauliMatrix[2], IdentityMatrix[2], 
    IdentityMatrix[2]], 
   KroneckerProduct[PauliMatrix[3], IdentityMatrix[4]], 
   KroneckerProduct[IdentityMatrix[2], IdentityMatrix[2], 
    PauliMatrix[3]], 
   KroneckerProduct[PauliMatrix[1], IdentityMatrix[2], 
    PauliMatrix[3]], 
   KroneckerProduct[PauliMatrix[2], IdentityMatrix[2], 
    PauliMatrix[3]], 
   KroneckerProduct[PauliMatrix[3], IdentityMatrix[2], 
    PauliMatrix[3]], 
   KroneckerProduct[IdentityMatrix[2], PauliMatrix[2], 
    PauliMatrix[1]], 
   KroneckerProduct[PauliMatrix[1], PauliMatrix[2], PauliMatrix[1]], 
   KroneckerProduct[PauliMatrix[2], PauliMatrix[2], PauliMatrix[1]], 
   KroneckerProduct[PauliMatrix[3], PauliMatrix[2], 
    PauliMatrix[1]], -KroneckerProduct[IdentityMatrix[2], 
     PauliMatrix[2], PauliMatrix[2]], -KroneckerProduct[
     PauliMatrix[1], PauliMatrix[2], 
     PauliMatrix[2]], -KroneckerProduct[PauliMatrix[2], 
     PauliMatrix[2], PauliMatrix[2]], -KroneckerProduct[
     PauliMatrix[3], PauliMatrix[2], PauliMatrix[2]]};
id = {IdentityMatrix[8]};
term3 = {KroneckerProduct[IdentityMatrix[2], PauliMatrix[3], 
    PauliMatrix[3]]};
term4 = Dot @@@ Tuples[{term3, Tmat}];
u = {KroneckerProduct[IdentityMatrix[2], PauliMatrix[1], 
    PauliMatrix[3]], 
   KroneckerProduct[IdentityMatrix[2], PauliMatrix[2], 
    IdentityMatrix[2]]};
omega = Dot @@@ Tuples[{u, Tmat}];


checkmat2 = {id, Tmat, term3, term4, u, omega};
c = {g1t/Nf, v1t/Nf, g4t/Nf, v4t/Nf, g2t/Nf, v2t/Nf};
c1 = {h1,h2,h3,h4,h5,h6};

Thanks in advance!

$\endgroup$
3
  • $\begingroup$ c is not defined. And what structure does checkmat2 has? $\endgroup$ Commented Sep 9, 2023 at 14:16
  • 2
    $\begingroup$ Have you tried ParallelDo? $\endgroup$
    – MarcoB
    Commented Sep 9, 2023 at 14:20
  • $\begingroup$ @MarcoB Hi Marco! Two things: I don't really know how to implement ParallelDo for nested loops, so any pointers would be appreciated! The Do loops I am trying to implement, while they run through the same array, they calculate different quantities and have different If-clauses, so would a ParallelDo work here? $\endgroup$
    – N P
    Commented Sep 9, 2023 at 15:28

1 Answer 1

3
$\begingroup$

The problem is not clearly stated, but I had the following idea. After working on it, I didn't want it to go to waste and wanted to post it. Hopefully I made correct guesses.

This statement does not seem parallelizable:

test1[[a]] = test1[[a]] - 2 tt*c[[b]]*c1[[m]]

For a given a, the statement has to be evaluated on the same subkernel, or worse, test1 would need to be a shared variable.

SeedRandom[0];
checkmat2 = RandomReal[{-1., 1}, {6, 20, 16, 16}];
c = RandomReal[{-1., 1}, 6];
c1 = RandomReal[{-1, 1}, 6];

ParallelTable[
 Module[{test1 = 0, tt},
  Do[tt = (1/(8)) Tr[
      checkmat2[[a, z]] . checkmat2[[b, l]] . checkmat2[[m, k]] . 
       checkmat2[[b, l]]];
   If[tt != 0, test1 = test1 - 2 tt*c[[b]]*c1[[m]]], {b, 6}, {m, 
    6}, {z, Length[checkmat2[[a]]]}, {l, Length[checkmat2[[b]]]}, {k, 
    Length[checkmat2[[m]]]}];
  test1
  ], {a, 6}]
(*  {-418.983, 6139.44, 3879.43, 3575.22, -4255., 5415.49}  *)

Tangential remark: The If[] condition seems to have no effect except to slow things down, unless c[[b]]*c1[[m]] is the multiplication of large arrays and checkmat2 consists of integer matrices.

Here's a faster refactoring, if you have, say, ten or more kernels:

Table[
 Total[
  ParallelTable[
   Total[
    Table[
     (1/(8)) Tr[
       checkmat2[[a, z]] . checkmat2[[b, l]] . checkmat2[[m, k]] . 
        checkmat2[[b, l]]]*
      -2 *c[[b]]*c1[[m]]
     , {b, 6}, {m, 6}, {l, Length[checkmat2[[b]]]}, {k, 
      Length[checkmat2[[m]]]}],
    All]
   , {z, Length[checkmat2[[a]]]}]
  ]
 , {a, 6}]
(*  {-418.983, 6139.44, 3879.43, 3575.22, -4255., 5415.49}  *)

One goal in the refactoring was to allow more than 6 threads. I assumed that Length[checkmat2[[a]]] is rather large.

$\endgroup$
2
  • $\begingroup$ What I would like to calculate additional loops provided in the example. And the If clause checks different quantities every time. So for example I would like to evaluate both $\endgroup$
    – N P
    Commented Sep 9, 2023 at 16:00
  • $\begingroup$ I had only the code posted to work with. The above codes do all the loops in your original one for the data I made up, and the first one does the If[] statement. $\endgroup$
    – Michael E2
    Commented Sep 9, 2023 at 16:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.