Build NCrystal from Source for OpenMC#3304
Build NCrystal from Source for OpenMC#3304ahnaf-tahmid-chowdhury wants to merge 8 commits intoopenmc-dev:developfrom
Conversation
|
Many thanks for making this PR @ahnaf-tahmid-chowdhury This would be very enabling for the sci kit core wheel building. @tkittel perhaps has some comments on this |
|
Yes, I have some comments. On vacation and busy with kids right now, but will try to find time a bit later :-) |
|
It seems that ncrystal-python requires ncrystal-core to be installed; otherwise, it is broken. We need to install the full ncrystal package. How would you like to proceed? We can either make ncrystal a runtime dependency, or create a fallback so users can install ncrystal when it's called but not installed, also add an optional dependency on pyproject.toml file. |
|
Sorry for not being able to respond sooner, but let me try to catch up now. First of all, I am a bit confused about the context of all of this, and additionally there are now comments both here, on shimwell#67, and mctools/ncrystal#227. Not to forget the already merged #3274 which was needed not only to make OpenMC work with NCrystal4, but also to ensure that you are not using NCrystal without actually having a self-consistent environment. So maybe it is just me now having enough coffee, but please forgive me if I am misinterpreting some intensions, plans, or oversaw some comments :-) I most assuredly have misunderstood something actually, since some of what I see here doesn't really make sense to me. I have written some comments below, but perhaps rather than responding to them here and risking further mutual misunderstanding, you would be interested in having a zoom call and discuss this? If yes, what time zones are you in? I am CET, but could have a late-evening call if you are interested. Anyway, here are my comments, take them with a grain of salt and a smilie of course :-) First of all, I would like to point out that I am not very keen to see downstream projects trying to put the pieces of NCrystal together manually if it can be avoided, since that will inevitably become very fragile and need constant attention and maintenance overhead in both projects (and as you can tell, it is not easy without first understanding a bit more about NCrystal packaging and deployment). Instead, we have invested quite a lot of effort in trying to make sure that it is easy to install NCrystal in various channels (notably both PyPI and Conda), and I would like to understand if there actually any reason for not using such channels? In particular if you plan to add openmc to the PyPI ecosystem, it seems contradictory to not want to be able to work with the packages your dependencies provide there already. Personally I would think it would be desirable if people can simply "pip install openmc ncrystal" and get the latest and greatest of both openmc and ncrystal working together. We did some tutorials using cloud-based jupyter notebooks in the last few years, and we had to constrain ourselves and only add a single example with openmc since the need to rebuild openmc from scratch was a bit complicated and slow. Anyway, I am a bit horrified to find that this PR tries to revert some of the "recommended NCrystal practices" that I just added. Some of these might seem a bit weird to you perhaps, but they are needed because we 1) want to support windows, 2) want to work whether installed from Python wheels or manual CMake builds (by experts!), 3) Want to make sure that our python layer (which is noarch) is completely separate from the underlying core layer. We ran into a lot of trouble: There are no cross-platform places to put libraries, no CMake-based way to properly install python modules (absent cmake being called from scikit-build-core of course), no Python-wheel supported places to put CMake config files or libraries, etc. The primary solution to all of this comes from the fact that the one thing you CAN provide in a manner which works on all platforms and environment is a command line utility. Hence we base everything around So please do NOT remove the call to I do not understand the sentence:
What subprocess, what inefficiencies? Surely you are not advocating against shared libraries? I can guarantee you that neither a call to Also, I really don't like that you resurrect Next, the call to Finally, I understand of course that you want to keep the dependency on NCrystal optional, but I am curious how on earth you plan to do that in the context of scikit-build-core and prebuilt wheels on PyPI ? On that note, I should mention that I have previously agreed with @paulromano to add a PR for the openmc conda feedstock to enable NCrystal there (always). The reason I have not done so yet, is simply that I want to clarify a bit how ABI compatibility issues works on conda first -- and I have been overloaded with other tasks (in the meantime I have reached the conclusion that it will be simpler and better to simply provide a dedicated ultra-stable header with NCrystal, which can be used by OpenMC to completely avoid such ABI concerns, but that is getting to another topic). In case you are interested in ncrystal-core vs. ncrystal-python, you can read more here: https://github.com/mctools/ncrystal/blob/main/INSTALL.md#package-structure But in general we actually recommend that downstream packages and users simply depend on the package named Anyway, that's all I could remember right now. As I wrote, I would recommend discussing this in a call (perhaps @paulromano wants to join as well?), since there are a lot of moving parts and opinions :-) |
|
Hi @tkittel , I sincerely apologize for any confusion caused. As I am relatively new to OpenMC development, I wasn’t fully aware that the latest version of NCrystal was designed with OpenMC’s build process in mind. What I have observed is that when OpenMC is built with NCrystal, Since The reason I removed That said, I found calling Another reason I initially proposed building from source was to ensure compatibility for forks that install OpenMC from source with different compilers and versions. Ensuring compatibility across various setups seemed beneficial. However, given what I’ve learned about the updated NCrystal, I’d love to hear your thoughts. Do you think building from source still offers advantages, or should we refine the PyPI based workflow instead? As I’m still getting up to speed with OpenMC development, I may not be fully aware of all existing discussions and decisions. Please forgive any oversight on my part. I’d be happy to discuss this further perhaps we could schedule a Zoom meeting? I also believe we have a Slack channel for OpenMC wheel builds, and @shimwell might be able to invite you there. |
|
If we can find a solution that allows us to make the OpenMC wheel using the scikit core like we could before PR #3274 was merged in then that would be great. Unfortunately I don't think adding ncrystal as build time dependency and run time dependency to the pyproject.toml is a good solution as that forces a dependency on people who may not want it and makes the environment harder to solve. This is different to the conda package where I assume/hope ncrystal would be added as build variety to the openmc conda package like mpi and dagmc which are also added as build options and are not mandatory dependencies for every build variety. I would be keen to keep it non mandatory for the same reasons as it makes the environment harder to solve and forces a dependency which not all users want. Perhaps we can make some changes in ncrystal to improve the packaging that @ahnaf-tahmid-chowdhury suggested a while back? |
| #=============================================================================== | ||
|
|
||
| if(OPENMC_USE_NCRYSTAL) | ||
| if(NOT DEFINED "NCrystal_DIR") |
There was a problem hiding this comment.
I have removed this as it forces the definition of NCrystal_DIR, which would break the standard method of defining other CMake variables for NCrystal. However, if this is recommended, please let me know.
| execute_process( | ||
| COMMAND "ncrystal-config" "--show" "cmakedir" | ||
| OUTPUT_VARIABLE "NCrystal_DIR" OUTPUT_STRIP_TRAILING_WHITESPACE | ||
| ) |
There was a problem hiding this comment.
I think we can make it available with a different fallback, right?
| endif() | ||
|
|
||
| if(@OPENMC_USE_NCRYSTAL@) | ||
| if(NOT DEFINED "NCrystal_DIR") |
There was a problem hiding this comment.
I think this is broken. We should set NCrystal_DIR to @NCrystal_DIR@ at the top of OpenMC's config file. The current version can break OpenMC, as the installed version of NCrystal might be different. For example, OpenMC could have been built with NCrystal 4.0.0, while the latest version of NCrystal from PyPI might be 4.1.0.
| chmod +x ./tools/ci/gha-install-ncrystal.sh | ||
| ./tools/ci/gha-install-ncrystal.sh |
There was a problem hiding this comment.
I don't understand why I need to chmod this from the action. I have tried multiple times on my system, and the file is always executable. Maybe someone else can give this a try.
|
Hi @ahnaf-tahmid-chowdhury and @shimwell . Thanks a lot for your feedback. Especially the explanations concerning auditwheel etc. makes it more clear to me what you are doing, and why you might have made the changes you have. I also agree, it is all needlessly complicated, with build flags, optional dependencies, etc. However, while mulling it over this afternoon, I think I came up with something that would be a much better way forward. I hope I can sell you on that idea, so here is my elevator pitch. Let us first hear about the advantages:
The disadvantage is that I have to do some work :-) The technology to make this work would be that the openmc binary upon realising it needs NCrystal will have to query Let me know what you think, if you are positive then I could try to put that up my priority list since it would solve a whole bunch of headaches for me (and hopefully also for you) :-) |
|
Sounds good to me, appreciated. There is some effort to get openmc working on windows. #2919 |
|
Ok @shimwell. I will have a go at it. It will be a bit of work though, and the next days are a bit busy for me. So it might take 1-2 weeks before it is ready. Is that compatible with your plans? |
Many thanks that would be great |
|
I think the current PR already supports building NCrystal from source, as the latest version of NCrystal still supports CMake builds. On the Python side, I found that only two files ( This approach should cover all the scenarios you mentioned, ensuring flexibility while keeping the build process straightforward. Is there anything I might be missing? Or would you like me to look into something specific on the NCrystal side? |
|
I am not sure I 100% get your point @ahnaf-tahmid-chowdhury ? Are we talking about what you will do in the ~2 weeks time until I finish the promised PR, or something else? |
|
I assume there is no need to create an additional PR if we can fix the issue here, as everything seems to be working fine. Would you like me to cover anything else specific to test? |
|
Hi @ahnaf-tahmid-chowdhury @shimwell Just a small update from my side! I was pretty busy this last week, but managed to more or less finish up all the new infrastructure on the NCrystal side, including new CI tests etc., and a preliminary modification to openmc sources to see that everything will work. It seems so! :-) So the next step is for me to release NCrystal 4.1.0 with the new infrastructure needed there, and after that I will open a new PR for OpenMC with the required changes. I hope we are talking 1-2 days more in total, pending issues in CI etc. And I much prefer a separate PR, since nothing in the new PR will depend on this existing PR, and it will get too complicated to intertwine everything. Cheers, |
|
Super, thanks for the update, sounds like great progress |
|
So I have now created #3328 as promised :-) |
|
Closing in favor of #3328 |
Description
This PR modifies the OpenMC build process to compile NCrystal from source instead of relying on the manylinux-provided package. The motivation behind this change is to ensure a more streamlined integration, avoiding unnecessary dependencies and improving compatibility.
Motivation
Using the manylinux version results in a dependency on
libNCrystal.so, which is dynamically loaded viasubprocess, adding inefficiencies.Setting
LD_LIBRARY_PATHis an option, but it introduces complexity.Reference
This PR follows up on discussions in another PR (shimwell/openmc/pull/67), where the issue of dependency management was raised. As suggested, this change is being made separately to integrate source-built NCrystal before addressing packaging concerns.