I thought that the fortran object stuff had been mostly resolved with better support for blas libraries on Mac via conda-forge installations. The fortran object thing had already popped up some time ago, and I had gotten in touch with people over at scipy/numpy to see if this was something that they thought they should handle on their end or not. The responses were very clear, fortran objects wont be pickleable because fortran objects can store very weird stuff, not only function pointers.
The root cause of the problem is that at some point in pytensor we are trying to grab a fortran object and serialize it in order to send it to another process that should run it. At the time I first tried to deal with this, I had no idea how to track down what was going on nor how to truly fix it. Some weeks ago, I had to poke around the codebase again to try to understand blas linkage better and I think that I might have found what is causing the fortran objects to get “pickled”. In these lines, pytensor stores the raw fortran objects in a dictionary that is keyed by the tensor dtype. Later on, the Gemv Op tries to access the dictionary in its perform method. Since we are using cloudpickle, the object’s method is pickled by value and not by reference. I think that this means that cloudpickle looks at the objects that are actually referenced by the perform method, and tries to pickle them as well in order to get a serialized version of the method that would run identically to the original one regardless of where the method got called (i.e. another process on another machine, using a different OS, etc). And at that point, pickling fails because fortran objects cannot be pickled. I think that the solution will be to use a higher level interface to actually get the underlying fortran function pointers instead of actually storing their values in a dictionary. I’ll try to open a draft PR to do this, using scipy.linalg.blas.get_blas_funcs.