0
$\begingroup$

Consider the following code:

Unprotect[NonCommutativeMultiply];

ClearAll[NonCommutativeMultiply]

NonCommutativeMultiply[] := 1
NonCommutativeMultiply[l___, 0, r___] := 0
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[a___, Times[-1, b_], c___] := -a ** b ** c
NonCommutativeMultiply[a_] := a


SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]

Protect[NonCommutativeMultiply];

Unprotect[NonCommutativeMultiply];


left___ ** HoldPattern[Times[z_, p : (a[x_] | ad[x_])]] ** right___ := z*left ** p ** right
left___ ** HoldPattern[Times[u_[x_], p : (a[x_] | ad[x_])]] ** right___ := u[x]*left ** p ** right
left___ ** HoldPattern[Times[z__, p : (a[x_] | ad[x_])]] ** right___ :=z*left ** p ** right
left___ ** Times[z___, y__NonCommutativeMultiply, x___] ** right___ := z*x*left ** y ** right

x___ ** y__Real ** z___ := y x ** z
x___ ** y__Integer ** z___ := y x ** z
l___ ** y__Power ** r___ := y l ** r
l___ ** Times[x__, y__] ** r___ := Times[x, y] l ** r

a[x_] ** a[x_] := 1
ad[x_] ** ad[x_] := 1

Protect[NonCommutativeMultiply];

xval[x___] := NonCommutativeMultiply[x];

xval[] := 1
xval[___ ** 0 ** ___] := 0

xval[x__Plus] := Map[ExpVal, x]   

xval[Times[x__, y_NonCommutativeMultiply, z___]] := x z ExpVal[y]  
xval[Times[x___, y_NonCommutativeMultiply, z__]] := x z ExpVal[y]
xval[___ ** a[x_]] := 0;

Now let's evaluate the matrix whose elements are given by: $ad(i)**\Big(2 |\cos(\pi i)| ad(j)**a(j)+2 |\sin(\pi j/2)|ad(j)**a(j)\Big)**a(i)$:

sind = 10;
Clear[f, i, j]
f[i_, j_] := xval[Distribute[ad[i] ** (2 Abs[Cos[Pi i]] ad[j] ** a[j] + 2 Abs[Sin[Pi j/2]] ad[j] ** a[j]) ** a[i]]]
mat = Array[f, {sind, sind}];
mat

The output is the diagonal matrix:

{{4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 
 0, 4, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 2, 0, 0, 0, 0, 0, 0}, {0, 0, 
 0, 0, 4, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 0, 0, 0}, {0, 0, 0, 
 0, 0, 0, 4, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, {0, 0, 0, 0, 
 0, 0, 0, 0, 4, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 2}}

So far so good. Now let's try to compute the same matrix using parallel features. I try:

Clear[fp, i, j, matp]
LaunchKernels[2]
fp[i_, j_] := xval[Distribute[ad[i] ** (2 Abs[Cos[Pi i]] ad[j] ** a[j] + 2 Abs[Sin[Pi j/2]] ad[j] ** a[j]) ** a[i]]]
matp = ParallelArray[fp, {sind, sind}, DistributedContexts -> Automatic];
MatrixForm[matp]

The output is the zero matrix, which is wrong

Let's try:

LaunchKernels[2]
Parallelize[Table[f[i, j], {i, 1, sind}, {j, 1, sind}]]

The output is again the zero matrix.

As I see it the problem is that I don't use the ParallelArray or Parallelize properly. What am I doing wrong?

MMA's manual states " Functions defined interactively can immediately be used in parallel"

EDIT

Based on the answer by @Sjoerd Smit let's check the following:

Quiet@LaunchKernels[];
DistributeDefinitions[NonCommutativeMultiply, xval]; (* can be omitted *)
ParallelEvaluate[a[x] ** a[x]]
ParallelEvaluate[Distribute[ad[1] ** (2 Abs[Cos[Pi 1]] ad[1] ** a[1] + 2 Abs[Sin[Pi 1/2]] ad[1] ** a[1]) ** a[1]]]
ParallelEvaluate[xval[Distribute[ad[1] ** (2 Abs[Cos[Pi 1]] ad[1] ** a[1]+ 2 Abs[Sin[Pi 1/2]] ad[1] ** a[1]) ** a[1]]]]
ParallelEvaluate[xval[a[x] ** a[x]]]

(* output *)
{1, 1, 1, 1}  (* correct *)
{4, 4, 4, 4}  (* correct *)
{0, 0, 0, 0}  (* WRONG *)
{0, 0, 0, 0}  (* WRONG *)

which suggests that xval does not work properly in parallel. Specifically, ParallelEvaluate[xval[a[x] ** a[x]]] gives 0 in all kernels which shows that xval doesn't recognize that a[x]**a[x]==1 when it works in parallel. I can't see the reason though

$\endgroup$
2
  • $\begingroup$ You might want to either use explicit Print, or Trace, to see where it goes wrong in the parallel case. $\endgroup$ Commented Jan 13, 2021 at 14:18
  • $\begingroup$ This obviously needs running code to troubleshoot, but you did not include the definitions of sind and ExpVal. $\endgroup$
    – MarcoB
    Commented Jan 13, 2021 at 15:06

1 Answer 1

1
$\begingroup$

It looks like the definitions for NonCommutativeMultiply don't make it to the parallel kernels. You can test this as follows:

CloseKernels[];
Unprotect[NonCommutativeMultiply];
NonCommutativeMultiply[args___] := f[args];
Protect[NonCommutativeMultiply];
Quiet @ LaunchKernels[];
DistributeDefinitions[NonCommutativeMultiply];
ParallelEvaluate[Hold[Evaluate[3 ** 2]], DistributedContexts -> Automatic]

{Hold[3 ** 2], Hold[3 ** 2], Hold[3 ** 2], Hold[3 ** 2]}

The Hold[Evaluate[...]] trick is very useful for figuring out if something evaluates on the parallel kernels or only on the main kernel. If you'd just use

ParallelEvaluate[3 ** 2, DistributedContexts -> Automatic]

{f[3, 2], f[3, 2], f[3, 2], f[3, 2]}

it looks like it works because the main kernel applies the definition of NonCommutativeMultiply.

I suspect that the Protected attribute is interfering with the distribution of the definitions. You can do this instead to circumvent the problem:

CloseKernels[];
Quiet @ LaunchKernels[];
ParallelEvaluate[
  Unprotect[NonCommutativeMultiply];
  NonCommutativeMultiply[args___] := f[args];
  Protect[NonCommutativeMultiply]
];
ParallelEvaluate[Hold[Evaluate[3 ** 2]]]

{Hold[f[3, 2]], Hold[f[3, 2]], Hold[f[3, 2]], Hold[f[3, 2]]}

$\endgroup$
2
  • $\begingroup$ Thanks for the reply. I don't think NonCommutativeMultiply is the problem. Consider g[i_, j_] := Distribute[ad[i] ** (2 Abs[Cos[Pi i]] ad[j] ** a[j] + 2 Abs[Sin[Pi j/2]] ad[j] **a[j]) ** a[i]] s1=Sum[g[i, j], {i, sind}, {j, sind}] Then evaluate the sum parallel LaunchKernels[4]; s2 = ParallelSum[g[i, j], {i, sind}, {j, sind}] You see that s1==s2 I think something goes wrong with xval in parallel $\endgroup$
    – geom
    Commented Jan 13, 2021 at 15:51
  • 1
    $\begingroup$ Fair point. I recommend you try all the functions you defined in isolation using the Hold[Evaluate[...]] trick to see which functions are behaving differently when evaluated in parallel. Or try putting all of your definitions inside of ParallelEvaluate like I did to make sure the definitions land on the kernels correctly. $\endgroup$ Commented Jan 13, 2021 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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