1
$\begingroup$

For each kernel, a unique symbol can be generated with Unique[]. However, since it's basically defined by the growing $ModuleNumber, parallel kernels can only generate unique symbols for themselves, but they are the same across kernels.

MWE:

ParallelEvaluate[Unique[i]]

So how can I generate unique symbols across all kernels? Of course I can set the $ModuleNumber for each kernel during the initialization, but that's way too brute force.

EDIT

My use of this unique symbol, for example, is

expr1=q.k l.k;
expr2=expr1/.{q.k->Module[{i},q[i]k[i]],l.k->Module[{i},l[i]k[i]]};
expr3=expr2/.k[i_]k[j_]:>delta[i,j];
result=expr3/.q_[i_]l_[j_]delta[i_,j_]:>q.l
$\endgroup$
6
  • $\begingroup$ Can you give more background to why do you need them? Maybe you don't. $\endgroup$
    – Kuba
    Feb 10, 2021 at 5:21
  • $\begingroup$ @Kuba It's for the dummy indices, i.e. $q.k$ is $q^i k^i$ where i is the dummy index. So in the whole expression i must be unique and can only appear twice. $\endgroup$
    – Turgon
    Feb 10, 2021 at 14:17
  • $\begingroup$ @Turgon please give an example in Mathematica code of an evaluation that requires your dummy indices. The example you gave could obviously be vectorized so I’m not sure it helps much $\endgroup$
    – MarcoB
    Feb 10, 2021 at 14:29
  • $\begingroup$ @MarcoB I'm not sure if you're familiar with this:i.e. I'd have an expression q[i$1]k[i$2]kroneckerdelta[i$1,i$2] and I want to contract those indices such that the result is $q^ik^j\delta^{ij}=q^ik^i$. And the contraction is the last step so before that, I'd have intermediate results with indices I'd like to keep. $\endgroup$
    – Turgon
    Feb 10, 2021 at 15:36
  • $\begingroup$ @Turgon Still no functioning code though... Alright, we'll keep guessing! Would Indexed be of any help then? $\endgroup$
    – MarcoB
    Feb 10, 2021 at 15:39

1 Answer 1

2
$\begingroup$

How about using the $KernelID as a further differentiator?

ParallelEvaluate[Unique["i" <> ToString@$KernelID]]

(* Out: {i110, i210, i310, i410} *)

Of course you could include $ in the string name, or any other symbol. Alternatively, you could perhaps do away with Unique, and simply use a combination of a string and $KernelID, depending on your usage needs.


You could also skip Unique altogether and roll your own. I was thinking of something along the lines of the following:

ParallelEvaluate[
  Symbol[
    "i" <> ToString[1000 $KernelID + RandomInteger[{1, 999}]]
  ]
]

(* Out: {i1569, i2811, i3512, i4076} *)
$\endgroup$
7
  • $\begingroup$ If you're unlucky and the $ModuleNumber you get is 9, then you have {i19,i29...}. At least I've seen $ModuleNumber being 700-ish, so in that case you have 1000 unique symbols. Of course most of the time it's more than enough but is there a better solution? $\endgroup$
    – Turgon
    Feb 10, 2021 at 14:18
  • $\begingroup$ @turgon how many symbols do you expect to need? $\endgroup$
    – MarcoB
    Feb 10, 2021 at 14:31
  • $\begingroup$ A few dozens maybe, so your solution is ok for me. I'm only curious if there's a better way to do this. $\endgroup$
    – Turgon
    Feb 10, 2021 at 15:30
  • $\begingroup$ @Turgon Would the alternative approach in my edit work better then? $\endgroup$
    – MarcoB
    Feb 10, 2021 at 15:37
  • $\begingroup$ Well how about this ParallelEvaluate[$ModuleNumber = 10000 $KernelID]? Random doesn't seem safe when you're trying to make it unique. $\endgroup$
    – Turgon
    Feb 10, 2021 at 15:52

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.