Xgboost: Create a binary wheel for Mac OSX

Created on 23 Apr 2020  路  19Comments  路  Source: dmlc/xgboost

Request to submit XGBoost 1.0.0 to Homebrew (https://github.com/Homebrew/homebrew-core/pull/50467) is still ongoing. In the meanwhile, we should create a Homebrew tap so that Mac users can install XGBoost easily.

Example:

# Load recipe xgboost.rb from GitHub repo hcho3/homebrew-repo
brew install hcho3/repo/xgboost
brew install hcho3/repo/py-xgboost  # Install Python package

cc @ankane

Most helpful comment

Was planning to make coffee while it installed, but it installed immediately. Please revert!

In all seriousness, works great on Mojave. Ruby version is also out and submitted a version bump to Homebrew for the CLI. https://github.com/Homebrew/homebrew-core/pull/54882

All 19 comments

Hey @hcho3, my suggestion would be to try and use the official Homebrew tap again before starting your own, since formula are precompiled, which makes installation much faster. I'd recommend breaking it into two steps:

  1. Add support for OpenMP
  2. Add support for the Python library. It looks like there is demand for the Python library to be included as part of Homebrew (https://github.com/dmlc/xgboost/issues/4949#issuecomment-542333666 and https://github.com/dmlc/xgboost/issues/5411), so I think there's a case to be made. Looking at the formula for other Python packages (like NumPy), I think the code needs to be a bit different than what was proposed in the earlier PR.

We can build pre-built bottles in a tap.

I proposed making a tap as an interim measure. Yes, we should submit a pull request again to homebrew-core, but it may take a while to get the pull request approved.

Sounds good. I just submitted a PR for the first one.

@ankane Interesting, so XGBoost recipe has been already upgraded to 1.0.2? I thought the recipe was still stuck to 0.9. In that case, users already have access to 1.0.2, albeit without OpenMP and without Python wrapper.

Yeah, was updated a few days ago in a different PR.

Got it. Let's see if we can get OpenMP and Python wrapper in this time. Thanks for the pull request!

I just tested NumPy on Homebrew. Homebrew has updated many packages (like NumPy) to Python 3.8, but the default Python (brew install python) is still 3.7, so users need to change their path to use Python 3.8. I have a feeling many users will confused by this.

Essentially, brew install xgboost won't be enough to make things "just work" with Python in the current state.

I personally think including shared libraries in the Python wheels is a better way to go. Then users can do pip/pip3 install xgboost in any Python environment.

So something like what LightGBM is doing? The LightGBM wheel includes a shared lib for OSX. That might be a better way to go. Since Homebrew requires macOS High Sierra nowadays, we can build a shared lib using macOS High Sierra and include it in the wheel.

Yeah, LightGBM takes that approach, but still requires brew install libomp. I just downloaded PyTorch to see how it works, and it looks like they include a copy of libiomp5.dylib in the Mac wheels in the .dylibs directory, so that may be a possibility (would be good to confirm licensing).

cc @StrikerRUS

fwiw, we should be able to use GitHub Actions or similar to build the shared libraries without Homebrew. GitHub Actions uses the latest macOS, but setting MACOSX_DEPLOYMENT_TARGET should allow it work on previous versions.

Example: https://github.com/ankane/ml-builds/blob/master/.github/workflows/xgboost-mac.yml

@ankane Thanks a lot for the ping!

I personally against of including any copy of libomp.dylib into wheels. I think that making libomp as a dependency and allowing users to install it in their favorite way is more appropriate way and brings less maintenance burden for us. One of the main reason is that there shouldn't be more than one copy of it in user's environment. Refer to https://github.com/dmlc/xgboost/issues/1715 and https://github.com/microsoft/LightGBM/blob/master/docs/FAQ.rst#10-lightgbm-crashes-randomly-with-the-error-like-initializing-libiomp5dylib-but-found-libompdylib-already-initialized. I believe that ideally all packages should rely on one system wide copy of libomp and do not produce additional copies.

Linking also https://github.com/microsoft/LightGBM/issues/2435 here as a one possible solution.

In addition, if I'm not mistaken, GitHub Actions and Azure Pipelines share the same containers and their policy of deprecating images is quite aggressive. Refer to https://github.com/microsoft/LightGBM/pull/2822. So it won't be easy to build artifacts inside non-latest environments.

@ankane @StrikerRUS Travis CI supports High Sierra. I'm currently testing XGBoost inside High Sierra environment: https://travis-ci.org/github/hcho3/xgboost/builds/679300818

@StrikerRUS Thanks for the info and links!

Agree including OpenMP adds more complexity for maintainers, so may not be worth it. PyTorch might have a way to avoid the already initialized error, as I was able to train a simple neural net in PyTorch and XGBoost model (with OpenMP) in the same script (but there are a few reports of it). Here's a note about the specific error fwiw: https://github.com/pytorch/pytorch/blob/47c4dca1ab3fedfde7b1ce383e779454e7903e86/cmake/Modules/FindOpenMP.cmake#L198-L237

@hcho3 re High Sierra: great!

Also, the OpenMP PR for Homebrew has been merged 馃帀

5597 will create binary wheels targeted for Mac High Sierra, Mojave, and Catalina.

Hey @hcho3, just tried it and works great! I think it'd be helpful to give instructions for brew install libomp when it's not installed (I imagine you can check if the error message contains libomp.dylib). Here's the current one:

xgboost.core.XGBoostError: XGBoost Library (libxgboost.dylib) could not be loaded.
Likely causes:
  * OpenMP runtime is not installed (vcomp140.dll or libgomp-1.dll for Windows, libgomp.so for UNIX-like OSes)
  * You are running 32-bit Python on a 64-bit OS
Error message(s): ['dlopen(/Users/runner/hostedtoolcache/Python/3.8.2/x64/lib/python3.8/site-packages/xgboost/lib/libxgboost.dylib, 6): Library not loaded: /usr/local/opt/libomp/lib/libomp.dylib\n  Referenced from: /Users/runner/hostedtoolcache/Python/3.8.2/x64/lib/python3.8/site-packages/xgboost/lib/libxgboost.dylib\n  Reason: image not found']

Edit: Just pushed this for Ruby. https://github.com/ankane/xgboost/commit/b2af20328262c9fc911546dec95500b3c29ae552

@ankane 1.1.0 is just released with the mac wheel: https://pypi.org/project/xgboost/1.1.0/#files

Was planning to make coffee while it installed, but it installed immediately. Please revert!

In all seriousness, works great on Mojave. Ruby version is also out and submitted a version bump to Homebrew for the CLI. https://github.com/Homebrew/homebrew-core/pull/54882

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pplonski picture pplonski  路  3Comments

XiaoxiaoWang87 picture XiaoxiaoWang87  路  3Comments

uasthana15 picture uasthana15  路  4Comments

lizsz picture lizsz  路  3Comments

nicoJiang picture nicoJiang  路  4Comments