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

[BUG] Global static variable in inlined function. #826

Closed
trivialfis opened this issue Jul 20, 2021 · 10 comments · Fixed by #833
Closed

[BUG] Global static variable in inlined function. #826

trivialfis opened this issue Jul 20, 2021 · 10 comments · Fixed by #833
Labels
bug Something isn't working

Comments

@trivialfis
Copy link
Member

trivialfis commented Jul 20, 2021

Describe the bug

Hi, I'm trying to get rmm to work in XGBoost across Python and C++ code base. One issue I found is the global variable device_id_to_resource returned by rmm::mr::detail::get_map. The get_map function is inlined, so when XGBoost is compiled with:

    set_target_properties(${target} PROPERTIES
      C_VISIBILITY_PRESET hidden
      CXX_VISIBILITY_PRESET hidden
      CUDA_VISIBILITY_PRESET hidden
    )

different static variables are returned when called in C++ and called in Python. I tried to print out the address of returned map in set_per_device_resource (called in Python reinitialize) and get_per_device_resource(called during construction of device_uvector), and can confirm the returned maps have different addresses. This leads to user configuration not being honored in XGBoost c++ code base. Actually if I use gdb to break the function, the one called in Python is completely ignored.

@trivialfis trivialfis added ? - Needs Triage Need team to review and classify bug Something isn't working labels Jul 20, 2021
@jrhemstad
Copy link
Contributor

I looked into this extensively in the past. I even made a repro with my results: https://github.com/jrhemstad/link_test

I'm not familiar with the CXX_VISIBILITY_PRESET options, but I'm guessing that it counteracts the global symbol used for the function local static. This is also why RMM doesn't support Windows is that the function local statics won't be shared across dynamically linked libraries.

I would say RMM is just not compatible with those build settings.

@jrhemstad jrhemstad removed the ? - Needs Triage Need team to review and classify label Jul 20, 2021
@trivialfis
Copy link
Member Author

Thanks for the reply. The build setting is used to handle c++ symbol conflicts. We ran into some errors that are caused by such conflicts, from both dmlc-core(a submodule used by xgboost and some other libraries) to CUDA libraries (where a corrupted stack gave me an invalid value error). So is there any chance rmm can support such build configuration in the future?

@trivialfis
Copy link
Member Author

trivialfis commented Jul 20, 2021

I also made a suggestion for cuml to adopt hidden symbols rapidsai/cuml#3859. There's an introduction on why it's useful: https://gcc.gnu.org/wiki/Visibility . (the pdf linked on that page might also be worth a read).

@jrhemstad
Copy link
Contributor

The only way to support that build configuration is to make RMM no longer be a header-only library and distribute a binary. That would be a big change.

@jrhemstad
Copy link
Contributor

I was reading through your link and found this:

With -fvisibility=hidden, you are telling GCC that every declaration not explicitly marked with a visibility attribute has a hidden visibility

So it sounds like we should be able to explicitly annotate the get_map symbol with __attribute__ ((visibility ("default"))) to make it explicitly shared.

@trivialfis
Copy link
Member Author

So it sounds like we should be able to explicitly annotate the get_map symbol with attribute ((visibility ("default"))) to make it explicitly shared.

That sounds like a good idea, I will test it tomorrow to see if it solves the problem. ;-)

@robertmaynard
Copy link
Contributor

we should be able to explicitly annotate the get_map symbol with attribute ((visibility ("default")))

Yes that will work. Explicit visibility attributes take priority over -fvisibility=hidden

If we go down this path for rmm we should consider having some form of ALWAYS_EXPORT, and NEVER_EXPORT macros that make it easier to apply these rules.

@trivialfis
Copy link
Member Author

Just tested the solution by @jrhemstad and it works.

@trivialfis
Copy link
Member Author

Hi, I can open a PR for this simple change if it's decided to be useful.

@jrhemstad
Copy link
Contributor

Yeah, we'd be happy to have a PR for this.

@rapids-bot rapids-bot bot closed this as completed in #833 Jul 23, 2021
rapids-bot bot pushed a commit that referenced this issue Jul 23, 2021
Define macros used for specifying symbol visibility and use it on `get_map`.  The macros are only useful for gcc/clang with glibc on Linux.  Sorry I'm not familiar with other platforms.

Close #826 .

> 1. Please ensure that you have written units tests for the changes made and/or features added.

I'm not sure how to test this on CI.

Authors:
  - Jiaming Yuan (https://github.com/trivialfis)

Approvers:
  - Rong Ou (https://github.com/rongou)
  - Jake Hemstad (https://github.com/jrhemstad)

URL: #833
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants