Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS stand-alone client fails #13

Closed
max3-2 opened this issue Feb 9, 2021 · 12 comments
Closed

macOS stand-alone client fails #13

max3-2 opened this issue Feb 9, 2021 · 12 comments
Labels
can't fix Issue cannot be resolved.

Comments

@max3-2
Copy link
Contributor

max3-2 commented Feb 9, 2021

With PR #11 initializing a Server object and connecting a client to this server works. However, when trying to build the Client as standalone, an exception is raised. Strangely, the path should be added (see client.py) and the file libiomp5.dylib is in the folder.

Exception                                 Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ModelUtil.initStandalone()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ServerModelUtil.initStandalone()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ServerModelUtil.initStandalone()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.security.AccessController.doPrivileged()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ServerModelUtil$17.run()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.System.load()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.Runtime.load0()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.ClassLoader.loadLibrary()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.ClassLoader.loadLibrary0()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.ClassLoader$NativeLibrary.load()

Exception: Java Exception

The above exception was the direct cause of the following exception:

java.lang.UnsatisfiedLinkError            Traceback (most recent call last)
<ipython-input-3-23d2b50bf9f8> in <module>
----> 1 c = mph.Client()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mph/client.py in __init__(self, cores, version, port, host)
    147             logger.info('Initializing stand-alone client.')
    148             graphics = True
--> 149             java.initStandalone(graphics)
    150             logger.info('Stand-alone client initialized.')
    151         # Otherwise skip stand-alone initialization and connect to server.

java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: /Applications/COMSOL55/Multiphysics/lib/maci64/libcssystemutil.dylib: dlopen(/Applications/COMSOL55/Multiphysics/lib/maci64/libcssystemutil.dylib, 1): Library not loaded: @rpath/libiomp5.dylib
  Referenced from: /Applications/COMSOL55/Multiphysics/lib/maci64/libcssystemutil.dylib
  Reason: image not found
@john-hen
Copy link
Collaborator

john-hen commented Feb 9, 2021

This is the exact same strange behavior I encountered on Ubuntu. See issue #8 and chapter Limitations in the documentation. Have you tried whatever the indicated work-around on macOS would be? You have to somehow export the environment variable DYLD_LIBRARY_PATH with the correct paths to the shared-library folders.

@max3-2
Copy link
Contributor Author

max3-2 commented Feb 9, 2021

Resolves the issue. Checked os.environ which is correct. Seems to be not respected by the JVM.

@max3-2
Copy link
Contributor Author

max3-2 commented Feb 9, 2021

Edit: I just tried to use a script based on Matplotlib (and then pillow) which gives me

ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PIL/_imaging.cpython-37m-darwin.so, 2): Library not loaded: @loader_path/.dylibs/libtiff.5.dylib
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PIL/_imaging.cpython-37m-darwin.so
  Reason: Incompatible library version: _imaging.cpython-37m-darwin.so requires version 11.0.0 or later, but libtiff.5.dylib provides version 8.0.0

due to libtiff being in /Applications/COMSOL55/Multiphysics/ext/graphicsmagick/maci64

Maybe the env works but there are ambiguous libs? However I have to idea how to resolve that....Is running without the graphics path an option?

@john-hen
Copy link
Collaborator

john-hen commented Feb 9, 2021

Hm, yeah, I have no idea either. Running without the graphics path is not an option though. Otherwise things will break. Not just graphics-related things, such as loading an external image, even just solving the model, according to tests I've made on Linux.

@john-hen john-hen mentioned this issue Feb 10, 2021
@john-hen john-hen added the bug Something isn't working. label Feb 15, 2021
@john-hen
Copy link
Collaborator

So, yes, the issue is ambiguity in install locations when dlopen() loads external libraries, as explained in more detail in #8. It occurs because we rely on the DYLD_LIBRARY_PATH environment variable (LD_LIBRARY_PATH on Linux) to help Comsol's stand-alone client find its external dependencies. There is no solution to that problem that I'm aware of.

It may help to preload PILlow's newer version of libtiff.5.dylib by calling ctypes.CDLL() with the absolute path of that file, before starting the Comsol client. But I can't test that. And it may break Comsol behavior further down the line.

@max3-2
Copy link
Contributor Author

max3-2 commented Feb 15, 2021

So just to go one level up - what would be the disadvantage with running in server / client mode all the time? I mean if this is too much of an issue, the other way works quite good (I know this is not really a satisfying solution). Thus removing standalone would make it more concise is terms of code.

To reduce start stop, one could track the server status and only open once and connect / disconnect clients as needed.

@john-hen
Copy link
Collaborator

Well, I haven't given that much thought yet. If anything, I would have removed support for client-server mode. Because I've never really needed that. Fair point though. Maybe that's the way to go.

@max3-2
Copy link
Contributor Author

max3-2 commented Feb 16, 2021

Client-Server mode is a great feature actually. When models get large (in terms of RAM during calculation), you can have a local client handling file IO with local pathes and still have the mesh generation and computation on a cluster. This is very valuable, at least during my daily work where models easily ramp up to 100GB of RAM. So please keep this :)

@john-hen
Copy link
Collaborator

But then you started the server manually on the remote machine(s), right? It's already running so you can connect to it remotely. And not automated by the same Python script. Just trying to understand this use case.

I use a file share to achieve what I think is the same. All "cluster" nodes (Comsol workstations) access the same shared network folder for I/O and job scheduling. Having access to a shared folder is a given, I think. But in this scenario, I don't need client-server mode. On each machine, I just start as many stand-alone clients ("workers") as I want (or as the machine has cores) and they all work on the same job queue. This approach works even without a network license. It basically lets the network file system fill in the blanks.

No worries, though, we're not gonna scrap client-server mode, especially now.

Come to think of it, the Matlab LiveLink also only ever uses client-server mode, not the stand-alone client. Maybe for the same reason, who knows? I did run into one issue with that though, back when I still had to use Matlab. Like when you start, say, 8 server instances on an 8-core machine, some of those would crash on start-up. I think that's because they're getting in each other's way when opening the communication port.

@max3-2
Copy link
Contributor Author

max3-2 commented Feb 16, 2021

But then you started the server manually on the remote machine(s), right? It's already running so you can connect to it remotely. And not automated by the same Python script. Just trying to understand this use case.

Sure, starting remote is too much of a hassle with different protocols etc.
I do see the use of your way, in my case the remote server with local client is easier to realize and in the end better to use for someone else.

Come to think of it, the Matlab LiveLink also only ever uses client-server mode, not the stand-alone client.

My thought, too. They tell you to always build a server, even on local.

@john-hen john-hen added can't fix Issue cannot be resolved. and removed bug Something isn't working. labels Feb 24, 2021
@john-hen john-hen changed the title macOS Standalone Client fails macOS stand-alone client fails Apr 23, 2021
@shomikverma
Copy link

shomikverma commented May 1, 2022

I may have found solution to this - setting DYLD_FALLBACK_LIBRARY_PATH instead of DYLD_LIBRARY_PATH. As discussed here, macos only checks in the fallback path if the library isn't found in the default path. This ensures nothing breaks when adding the COMSOL paths necessary. Setting:

export DYLD_FALLBACK_LIBRARY_PATH=/Applications/COMSOL56/Multiphysics/lib/maci64:/Applications/COMSOL56/Multiphysics/ext/graphicsmagick/maci64:/Applications/COMSOL56/Multiphysics/ext/cadimport/maci64

allows me to do:

In [1]: import mph

In [2]: import matplotlib.pyplot as plt

In [3]: mph.option('session','stand-alone')

In [4]: client = mph.start(1)

with no issues! I also had to change line 481 in client.py to DYLD_FALLBACK_LIBRARY_PATH instead of DYLD_LIBRARY_PATH so the script would check the right environment variable.

@john-hen
Copy link
Collaborator

john-hen commented May 1, 2022

Thanks for looking into this and reporting back. Good to know, I was not aware of that. This may help people who want to use stand-alone mode on macOS, but run into compatibility problems with other graphics libraries.

Strange though that there seems to be no Linux equivalent, like LD_FALLBACK_LIBRARY_PATH. At least a cursory web search did not turn up anything.

I'll fix the checks of the environment variables in the next release. They are not necessary anyway, but certainly shouldn't get in the way of doing things right.

@john-hen john-hen reopened this May 1, 2022
john-hen added a commit that referenced this issue Jun 30, 2022
As pointed out by @shomikverma, this check gets in the way when
setting `DYLD_FALLBACK_LIBRARY_PATH` instead of `DYLD_LIBRARY_PATH`,
which may be the better setup. It is the user's reponsibiliy to
correctly configure the environment, we should not interfere with
that as long as we're unsure if we have the best solution. The
sanity check of environment variables was therefore removed.
TermeHansen pushed a commit to resolventdk/MPh that referenced this issue Aug 3, 2023
As pointed out by @shomikverma, this check gets in the way when
setting `DYLD_FALLBACK_LIBRARY_PATH` instead of `DYLD_LIBRARY_PATH`,
which may be the better setup. It is the user's reponsibiliy to
correctly configure the environment, we should not interfere with
that as long as we're unsure if we have the best solution. The
sanity check of environment variables was therefore removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
can't fix Issue cannot be resolved.
Projects
None yet
Development

No branches or pull requests

3 participants