CMake support RelWithDebInfo build_type that enables upcxx runtime assertions

Issue #418 new
Rob Egan created an issue

So on Dan’s advice to build with -g and -O3 I ran into a few snags while attempting to bludgeon CMake to properly do this for which I’ll document my issues and workaround here. I think that supporting this standard-but-mostly-unused RelWithDebInfo CMAKE_BUILD_TYPE is something achievable and relatively easy to do.

So first off just adding “-g” to a Release build options breaks because upcxx complains that you cannot set -g and -O at the same time without UPCXX_CODEMODE set or adding the -codemode={opt|debug} option. Similarly adding -O3 to a Debug build breaks. Nor is adding either really sustainable because an environmental variable is not necessarily propagated to the subsequent make calls and adding “-codemode=..” to the CMAKE_CXX_FLAGS variable breaks any normal code.

In my (pretty new server Mar 2020) with an arguable old cmake version (3.10) from a not-very old linux install (Ubuntu 18.04.05 LTS), I found that I could not even see UPCXX_OPTIONS to modify it. Nor would setting ENV{UPCXX_CODEMODE} (which is what “share/cmake/UPCXX/UPCXXConfig.cmake” does) hold over to the make step. Note that this does seem to work for cmake > 3.12 though, and that is my temporary workaround (i.e. use a custom build of cmake 3.18 on my dev machine and add “set(ENV{UPCXX_CODEMODE} debug)” in the CMakeLists.txt )

Note, that I also found that in 3.10 the CMAKE_CXX_FLAGS were not set at all in RelWithDebInfo whereas Release and Debug set those flags just fine… I may file a bug with CMake on this because CMAKE_CXX_FLAGS_RELWITHDEBINFO is fully proper.

The upshot is that I believe that including -codemode=debug in the UPCXX_OPTIONS variable is a better solution than setting the ENV{UPCXX_CODEMODE} variable.

So, I think that changing share/cmake/UPCXX/UPCXXConfig.cmake from:

  if ((NOT DEFINED ENV{UPCXX_CODEMODE}) OR ("$ENV{UPCXX_CODEMODE}" STREQUAL "unset"))
    string(TOUPPER "${CMAKE_BUILD_TYPE}" uc_CMAKE_BUILD_TYPE)
    if (uc_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
      set(ENV{UPCXX_CODEMODE} "debug" )
    else()
      set(ENV{UPCXX_CODEMODE} "O3" ) # O3 is compatible with any version
    endif()
    unset(uc_CMAKE_BUILD_TYPE)
  endif()

To this

    string(TOUPPER "${CMAKE_BUILD_TYPE}" uc_CMAKE_BUILD_TYPE)
    if (uc_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
      list(APPEND UPCXX_OPTIONS "-codemode=debug" )
    elseif(uc_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
      list(APPEND UPCXX_OPTIONS "-codemode=debug" )
    else()
      list(APPEND UPCXX_OPTIONS "-codemode=opt" )
    endif()
    unset(uc_CMAKE_BUILD_TYPE)

is all that is needed to make this stick in all CMake versions and enable this standard but new-to-upcxx build_mode.

And for backwards compatibility, this code can be protected with some new upcxx cmake option (with documentation) which one can set before the call to find_package(upcxx)

as motivation for this change here are the timing differences for a toy dataset of mhmxx on my single desktop, and I confirmed that both the Debug and RelWithDebInfo versions throw assertion errors from upcxx.

53.57s  Release (-O3)
77.60s  RelWithDebInfo (-O2 -g)
244.19s Debug (-g)

Comments (9)

  1. Rob Egan reporter

    Following up on a slack session we had about how RelWithDebInfo is not a great fit for this build mode… I like the recommendation from stackoverflow to add a new “non-standard” RelWithDebug build type:

    https://stackoverflow.com/questions/48754619/what-are-cmake-build-type-debug-release-relwithdebinfo-and-minsizerel

    So essentially as fast as -O2 (from the compile options of RelWithDebInfo) but also with assertions enabled which is what we wanted and what is necessary in order to also support gasnet statistic collection.

  2. Log in to comment