# Revision history [back]

### @parallel decorator makes elements of a custom monoid incompatible

I experience a weird effect of @parallel decorator.

Let's consider an example of FiniteMonoidFromMultiplicationTable defined in https://ask.sagemath.org/question/32064/ I define this monoid and a list of three its elements and compute their product as follows:

F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
E1 = [ F(0), F(1), F(2) ]
print('product1:', prod(E1) )


It prints product1: 0. So far good.

Now let's define the parallel id function that simply returns its argument, and apply it (in parallel fashion) to E1 to obtain list E2 as follows:

@parallel
def id(x):
return x

E2 = [ e for _,e in id(E1) ]
print('product2:', prod(E2) )


However, prod(E2) here results in the error

TypeError: unsupported operand parent(s) for *: 'Finite monoid on 3 elements given by its multiplication table' and 'Finite monoid on 3 elements given by its multiplication table'

which is rather weird. While E2[0].parent() == E2[1].parent() evaluates to True here, E2[0].parent() is E2[1].parent() evaluates to False and that's probably the cause for the error above.

So, my questions are: why elements of E2 have different parents and what needs to be changed to avoid the described issue?

PS. Just in case, here is the full code at Sagecell illustrating the issue.

### @parallel decorator makes elements of a custom monoid incompatible

I experience a weird effect of @parallel decorator.

Let's consider an example of FiniteMonoidFromMultiplicationTable defined in https://ask.sagemath.org/question/32064/ I define this monoid and a list of three its elements and compute their product as follows:

F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
E1 = [ F(0), F(1), F(2) ]
print('product1:', prod(E1) )


It prints product1: 0. So - so far so good.

Now let's define the parallel id function that simply returns its argument, and apply it (in parallel fashion) to E1 to obtain list E2 as follows:

@parallel
def id(x):
return x

E2 = [ e for _,e in id(E1) ]
print('product2:', prod(E2) )


However, prod(E2) here results in the error

TypeError: unsupported operand parent(s) for *: 'Finite monoid on 3 elements given by its multiplication table' and 'Finite monoid on 3 elements given by its multiplication table'

which is rather weird. While E2[0].parent() == E2[1].parent() evaluates to True here, E2[0].parent() is E2[1].parent() evaluates to False and that's probably the cause for the error above.

So, my questions are: why elements of E2 have different parents and what needs to be changed to avoid the described issue?

PS. Just in case, here is the full code at Sagecell illustrating the issue.

### @parallel decorator makes elements of a custom monoid incompatible

I experience a weird effect of @parallel decorator.

Let's consider an example of FiniteMonoidFromMultiplicationTable defined in https://ask.sagemath.org/question/32064/ I define this monoid and a list of three its elements and compute their product as follows:

F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
E1 = [ F(0), F(1), F(2) ]
print('product1:', prod(E1) )


It prints product1: 0 - so far so good.

Now let's define the parallel id function that simply returns its argument, and apply it (in parallel fashion) to E1 to obtain list E2 as follows:

@parallel
def id(x):
return x

E2 = [ e for _,e in id(E1) ]
print('product2:', prod(E2) )


However, prod(E2) here results in the error

TypeError: unsupported operand parent(s) for *: 'Finite monoid on 3 elements given by its multiplication table' and 'Finite monoid on 3 elements given by its multiplication table'

which is rather weird. While E2[0].parent() == E2[1].parent() evaluates to True here, E2[0].parent() is E2[1].parent() evaluates to False and that's probably the cause for the error above.

So, my questions are: why elements of E2 have different parents and what needs to be changed to avoid the described issue?

PS. Just in case, here is the full code at Sagecell illustrating the issue.

### @parallel decorator makes elements of a custom monoid incompatible

I experience a weird effect of UPD. In fact, this issue appears with any multiprocessing of monoid's elements and it's not specific to @parallel decorator.

Let's consider an example of FiniteMonoidFromMultiplicationTable defined in https://ask.sagemath.org/question/32064/ I define this monoid and a list of three its elements and compute their product as follows:

F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
E1 = [ F(0), F(1), F(2) ]
print('product1:', prod(E1) )


It prints product1: 0 - so far so good.

Now let's define the parallel id function that simply returns its argument, and apply it (in parallel fashion) to E1 to obtain list E2 as follows:

@parallel
def id(x):
return x

E2 = [ e for _,e in id(E1) ]
print('product2:', prod(E2) )


However, prod(E2) here results in the error

TypeError: unsupported operand parent(s) for *: 'Finite monoid on 3 elements given by its multiplication table' and 'Finite monoid on 3 elements given by its multiplication table'

which is rather weird. While E2[0].parent() == E2[1].parent() evaluates to True here, E2[0].parent() is E2[1].parent() evaluates to False and that's probably the cause for the error above.

So, my questions are: why elements of E2 have different parents and what needs to be changed to avoid the described issue?

PS. Just in case, here is the full code at Sagecell illustrating the issue.

### @parallel decorator makes elements of a custom monoid incompatible

UPD. In fact, this issue appears with any multiprocessing of monoid's elements and it's not specific to @parallel decorator.

Let's consider an example of FiniteMonoidFromMultiplicationTable defined in https://ask.sagemath.org/question/32064/ I define this monoid and a list of three its elements and compute their product as follows:

F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
E1 = [ F(0), F(1), F(2) ]
print('product1:', prod(E1) )


It prints product1: 0 - so far so good.

Now let's define the parallel id function that simply returns its argument, and apply it (in parallel fashion) to E1 to obtain list E2 as follows:

@parallel
def id(x):
return x

E2 = [ e for _,e in id(E1) ]
print('product2:', prod(E2) )


However, prod(E2) here results in the error

TypeError: unsupported operand parent(s) for *: 'Finite monoid on 3 elements given by its multiplication table' and 'Finite monoid on 3 elements given by its multiplication table'

which is rather weird. While E2[0].parent() == E2[1].parent() evaluates to True here, E2[0].parent() is E2[1].parent() evaluates to False and that's probably the cause for the error above.

So, my questions are: why elements of E2 have different parents and what needs to be changed to avoid the described issue?

PS. Just in case, here is the full code at Sagecell illustrating the issue.

### @parallel decorator makes elements of a custom monoid incompatible

UPD. In fact, this issue appears with any multiprocessing of monoid's elements and it's not specific to @parallel decorator.

Let's consider an example of FiniteMonoidFromMultiplicationTable defined in https://ask.sagemath.org/question/32064/ I define this monoid and a list of three its elements and compute their product as follows:

F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
E1 = [ F(0), F(1), F(2) ]
print('product1:', prod(E1) )


It prints product1: 0 - so far so good.

Now let's define the parallel id function that simply returns its argument, and apply it (in parallel fashion) to E1 to obtain list E2 as follows:

@parallel
def id(x):
return x

E2 = [ e for _,e in id(E1) ]
print('product2:', prod(E2) )


However, prod(E2) here results in the error

TypeError: unsupported operand parent(s) for *: 'Finite monoid on 3 elements given by its multiplication table' and 'Finite monoid on 3 elements given by its multiplication table'

which is rather weird. While E2[0].parent() == E2[1].parent() evaluates to True here, E2[0].parent() is E2[1].parent() evaluates to False and that's probably the cause for the error above.

So, my questions are: why elements of E2 have different parents and what needs to be changed to avoid the described issue?

PS. Just in case, here is the full code at Sagecell illustrating the issue.