rmm icon indicating copy to clipboard operation
rmm copied to clipboard

[FEA] Add CMake Option to Disable Exceptions

Open JieRen98 opened this issue 3 months ago • 7 comments

I'm working on a project that requires the use of the C++ compile option -fno-exceptions to optimize my library's performance and reduce binary size.

When compiling RMM with -fno-exceptions, I encountered a compilation error because code paths like RMM_EXPECT explicitly or implicitly use throw (e.g., https://github.com/rapidsai/rmm/blob/507278505eeda79436c1000da6808efa219cf3d2/cpp/include/rmm/detail/error.hpp#L65).

Could the RMM library implement a CMake option (similar to SPDLOG_NO_EXCEPTIONS in spdlog) to conditionally disable exception-throwing behavior and allow for compilation with -fno-exceptions?

JieRen98 avatar Oct 06 '25 14:10 JieRen98

@JieRen98 RMM relies on C++ exceptions to convey problems like out-of-memory errors back to applications using RMM.

What design would you propose for this? A special return value for calls that error? Ignoring errors entirely? Would you be interested in contributing a pull request after we discuss possible designs?

bdice avatar Oct 06 '25 14:10 bdice

My project primarily involves C libraries, where I use an extern "C" wrapper to export a C API that utilizes some RMM features. These C APIs are, in turn, consumed by upstream libraries.

For my specific use case, I only require that the program prints necessary error messages and terminates upon encountering a critical error.

I would like to contribute, but I don't have a definitive proposal. Perhaps a simple approach—such as having functions return a NULL pointer (similar to malloc) on a bad allocation—would be sufficient. I don't know... What do you think?

JieRen98 avatar Oct 06 '25 15:10 JieRen98

I believe that supporting both exception-enabled and exception-disabled builds is a crucial feature. Many libraries (especially C libraries) do not support or require exception handling. By removing exception support, one can achieve a slight performance improvement and a significant reduction in binary size. What do you think?

JieRen98 avatar Oct 06 '25 15:10 JieRen98

I think you can use try { ... } catch (...) { ... } blocks in your extern "C" wrappers to put a firewall around potentially exception-throwing code.

Exceptions are a core part of RMM's C++ design, so I don't expect this to change in our C++ code. Simply ignoring exceptions would not be safe. If we added a C API for RMM, I would probably recommend that we provide error codes as a return value, rather than using null pointers to indicate an allocation failure.

Would you be interested in helping with the design of an official C API? We have had other requests for this, and I'd like to see what you are currently doing to wrap RMM in C. Is this a public project?

bdice avatar Oct 07 '25 14:10 bdice

Yes, I agree that confining the try-catch blocks to the extern "C" wrappers would ensure the program's reliability in the current situation.

Personally, I have a strong preference for binary optimization—I typically disable exceptions and strip symbols in my projects to achieve the smallest possible executable size.

I would be happy to assist with the design and development of official C APIs and the mechanisms required to support an exception-disabled configuration.

My current work involves developing sparse direct solvers and optimizing/hijacking various runtime functions (such as those similar to cudaMalloc). Both of these projects export C APIs but are written in C++. While they are not public, I am certainly open to discussing my specific use cases with you privately.

JieRen98 avatar Oct 07 '25 15:10 JieRen98

I found this C wrapper for RMM, which is Apache-2.0 licensed. It appears to use RMM 21.10, so it's 4 years old, but it might be a good starting point for exploration.

https://github.com/DrTimothyAldenDavis/GraphBLAS/tree/1213aa68551fdfc7e3aefb981ffb91ecd98d3e79/rmm_wrap

bdice avatar Oct 25 '25 18:10 bdice

I found this C wrapper for RMM, which is Apache-2.0 licensed. It appears to use RMM 21.10, so it's 4 years old, but it might be a good starting point for exploration.

https://github.com/DrTimothyAldenDavis/GraphBLAS/tree/1213aa68551fdfc7e3aefb981ffb91ecd98d3e79/rmm_wrap

Thanks. Prof. Tim Davis is a real legend. I am still using his SuiteSparse dataset in my recent paper. :D

After finishing my current project (December deadline), I will spend more time with the C API RMM. But we can discuss before that. GraphBLAS's RMM C API is mostly good, but I think it may be better to maintain an internal map to store the size of allocation instead of passing it to void rmm_wrap_deallocate( void *p, std::size_t size ). From my experience, C APIs like free or cudaFree do not need the size.

JieRen98 avatar Oct 25 '25 19:10 JieRen98