Cannot parallelize class-based code with SubDomain child class as member

Hi everyone,

I hop this is not too similar to this thread, but since it’s about SubDomain child classes, I opened a new one.

I try to parallelize the execution of code somewhat in the manner of below code.

from fenics import *
import multiprocessing


class PeriodicBoundary:#(SubDomain):
    def map(self, x, y):
        y[0] = x[0] - 1.  # L

class aClass:

  def __init__(self, i):
    self.aBoundary = PeriodicBoundary()

  def hello(self):
    print("hello ")



if __name__ == "__main__":

    number_of_threads = 10

    class_list = [aClass(i) for i in range(number_of_threads)]

    def hello_function(instance:aClass):
      instance.hello()

    pool = multiprocessing.Pool(processes=number_of_threads)
    pool.map(hello_function, class_list)
    pool.close()

This code works if you leave out the inheritance of SubDomain, but once you put it in, multiprocessing.Pool cannot run, because the PeriodicBoundary class cannot be pickled.

TypeError: can't pickle PeriodicBoundary objects

While the solution in this thread will work perfectly well in the real case I use, it will be very clunky and not modular at all. So I am wondering if anyone knows why this problem happens and how to circumvent it.

Best,

David

The easy way I found around this is to load the offending class only after spawning a new process:

from fenics import *
import multiprocessing


class PeriodicBoundary(SubDomain):
  def map(self, x, y):
    y[0] = x[0] - 1.  # L

class aClass:

  def __init__(self, i):
    self.aBoundary = None

  def hello(self):
    print("hello ")



if __name__ == "__main__":

  number_of_threads = 10

  class_list = [aClass(i) for i in range(number_of_threads)]

  def hello_function(instance:aClass):
    self.aBoundary = PeriodicBoundary()
    instance.hello()

  pool = multiprocessing.Pool(processes=number_of_threads)
  pool.map(hello_function, class_list)
  pool.close()

This is not extremely elegant, but works