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

Load rocSOLVER with dlopen at runtime #903

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

daineAMD
Copy link
Contributor

Don't have access to a windows machine so this hasn't been tested on windows yet.

See #896 for the request. Similar changes for hipSOLVER have been done at hipSOLVER #302

This change allows hipBLAS to build without rocSOLVER available at buildtime. By default, hipBLAS will try to find rocSOLVER at runtime using dlopen(). If rocSOLVER cannot be found, the rocsolver-based functions will return HIPBLAS_STATUS_NOT_IMPLEMENTED.

The -n flags has been changed to mean "don't build rocSOLVER tests".
The --solver-buildtime flags has been added to find rocSOVLER at build time.

Also added some flags for jenkins so will be testing the various flags on CI.

Copy link
Contributor

@TorreZuk TorreZuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the static build without solver_buildtime the default as that creates an invalid static library?

Comment on lines +77 to +79
if(BUILD_SHARED_LIBS)
set(BUILD_WITH_SOLVER_DEFAULT OFF)
else()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just for testing or default to not link? Default to not link may may need to review effect on rpath or package consumption documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default will be to not link. I think it'll be ok but I'll test out consuming the hipblas package now to make sure it find rocsolver.

@cgmb
Copy link
Contributor

cgmb commented Aug 20, 2024

Is the static build without solver_buildtime the default as that creates an invalid static library?

It's valid. It's just unlikely that you'd want a static hipblas and a dynamic rocsolver.

static bool load_rocsolver()
{
#ifdef WIN32
void* handle = LoadLibraryW(L"librocsolver.dll");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's just rocsolver.dll.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing this out on a windows machine now.

library/src/amd_detail/dlopen/load_rocsolver.cpp Outdated Show resolved Hide resolved

// RTLD_NOW to load symbols now to avoid performance hit later
// RTLD_GLOBAL to load geqrf_ptr_batched declared symbols in hipblas.cpp
void* handle = dlopen("librocsolver.so", RTLD_NOW | RTLD_GLOBAL);
Copy link
Contributor

@cgmb cgmb Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please load librocsolver.so.0. librocsolver.so is only provided by the -dev/-devel package on Debian, Ubuntu and Fedora. If you want to fall back to librocsolver.so in the case that loading librocsolver.so.0 fails, that's fine.

The unsuffixed symlink goes in the -dev package on those distros because the maintainers wish to ensure that both librocsolver.so.0 and the hypothetical future librocsolver.so.1 can both be installed at the same time without having a conflict caused by both packages containing a file with the same name. The ability to install the two versions side-by-side makes for a smoother migration during the package update process.

@cgmb
Copy link
Contributor

cgmb commented Aug 20, 2024

You may want to adjust the CMake that defines the package dependencies to recommend and/or suggest the rocsolver package to users that install hipblas.

@TorreZuk
Copy link
Contributor

Is the static build without solver_buildtime the default as that creates an invalid static library?

It's valid. It's just unlikely that you'd want a static hipblas and a dynamic rocsolver.

Invalid in the sense that neither a customer nor developer would want it (we don't want failing tests for bad configs), let alone be default. Maybe a conditional option should be used?

@cgmb
Copy link
Contributor

cgmb commented Aug 21, 2024

Invalid in the sense that neither a customer nor developer would want it (we don't want failing tests for bad configs), let alone be default. Maybe a conditional option should be used?

Keep in mind that we're not distinguishing between 'maybe rocsolver at runtime' and 'no rocsolver'. The configuration of 'static hipblas with no rocsolver' is something that developers may want.

@TorreZuk
Copy link
Contributor

Invalid in the sense that neither a customer nor developer would want it (we don't want failing tests for bad configs), let alone be default. Maybe a conditional option should be used?

Keep in mind that we're not distinguishing between 'maybe rocsolver at runtime' and 'no rocsolver'. The configuration of 'static hipblas with no rocsolver' is something that developers may want.

The flags are confusing me maybe keeping -n --no-solver as never any solver is simpler (both shared and static). What this seems to be is an architeture option to delays .so loading to make it optional. Should discuss an overall roadmap feature request for this change for hip libraries.

@@ -82,6 +82,11 @@ if(HIP_PLATFORM STREQUAL amd)
endif( )
endif( )

if(NOT BUILD_WITH_SOLVER)
target_link_libraries(hipblas PRIVATE $<$<PLATFORM_ID:Linux>:${CMAKE_DL_LIBS}>)
set_property(TARGET hipblas APPEND PROPERTY BUILD_RPATH ${ROCSOLVER_PATH}/lib)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What prompted this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is needed to find the rocsolver library if hipblas is built with the install script --rocsolver-path option

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind that rocsolver might not actually even exist on the system at build-time. Personally, I wouldn't bother mucking around with the RPATH, as it can always be handled after the build by setting the LD_LIBRARY_PATH.

If you prefer to set the RPATH, it should be guarded to only be set when rocsolver exists and --rocsolver-path has been used. The hardcoded lib may be a problem, as the library directory can sometimes have other names in third-party builds, like lib64 or <target-triple>/lib. You could use ${CMAKE_INSTALL_LIBDIR} instead, but I think it would be more robust to extract the path from the target:

if(DEFINED ROCSOLVER_PATH)
  find_package(rocsolver QUIET PATHS "${ROCSOLVER_PATH}" NO_DEFAULT_PATH)
  if(rocsolver_FOUND)
    get_target_property(rocsolver_location roc::rocsolver LOCATION)
    get_filename_component(rocsolver_directory ${rocsolver_location} DIRECTORY)
    set_property(TARGET hipblas APPEND PROPERTY BUILD_RPATH ${rocsolver_directory})
  endif()
endif()

With all that said, I prefer less code to more code. IMO, it's fine to expect users to set LD_LIBRARY_PATH if rocSOLVER is not in a system directory or /opt/rocm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants