# Unique symbol for parallel kernels

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

• Can you give more background to why do you need them? Maybe you don't.
– Kuba
Feb 10 '21 at 5:21
• @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. Feb 10 '21 at 14:17
• @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 Feb 10 '21 at 14:29
• @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. Feb 10 '21 at 15:36
• @Turgon Still no functioning code though... Alright, we'll keep guessing! Would Indexed be of any help then? Feb 10 '21 at 15:39

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} *)  • 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? Feb 10 '21 at 14:18 • @turgon how many symbols do you expect to need? Feb 10 '21 at 14:31 • A few dozens maybe, so your solution is ok for me. I'm only curious if there's a better way to do this. Feb 10 '21 at 15:30 • @Turgon Would the alternative approach in my edit work better then? Feb 10 '21 at 15:37 • Well how about this ParallelEvaluate[$ModuleNumber = 10000 \$KernelID]? Random doesn't seem safe when you're trying to make it unique. Feb 10 '21 at 15:52