ILP64 name-mangling

Open discussion for MAGMA library (Matrix Algebra on GPU and Multicore Architectures)
Post Reply
staticfloat
Posts: 2
Joined: Fri Aug 09, 2019 3:33 pm

ILP64 name-mangling

Post by staticfloat » Fri Aug 09, 2019 3:47 pm

In the Julia language world, we tend to build Julia against an ILP64 BLAS (OpenBLAS, in the default case), but occasionally users link against dynamic libraries that expect a non-ILP64 BLAS. To avoid potentially fatal symbol name clashes, we mangle the name of all ILP64 BLAS operations (e.g. `dgemv_` becomes `dgemv64_`). What is the proper way to convince MAGMA to mangle its expected BLAS symbol names appropriately so that it can link against these ILP64 symbols? I've tried editing `include/magma_mangling.h` to have preprocessor defines such as `#define FORTRAN_NAME(lcname, UCNAME) lcname##64_`, but that doesn't seem to work. I'm compiling using CMake. I have also tried editing `include/magma_mangling_cmake.h`, but I believe that file is autogenerated (and gets overwritten) and I'm unsure where it is generated from.

mgates3
Posts: 902
Joined: Fri Jan 06, 2012 2:13 pm

Re: ILP64 name-mangling

Post by mgates3 » Fri Aug 09, 2019 4:55 pm

If you compiled without CMake, then editing magma_mangling.h as you describe should work. But as you noticed, CMake #defines its own mangling macro, called MAGMA_GLOBAL, in the file magma_mangling_cmake.h.

The quickest hack to do would be comment out magma_mangling_cmake (or #undef MAGMA_GLOBAL), and then edit FORTRAN_NAME macro as you described. Something like this, in magma_mangling.h:

Code: Select all

// #include "magma_mangling_cmake.h"  // Comment out CMake's mangling macro,
#undef MAGMA_GLOBAL                   // or undef it.

// Define ADD_, NOCHANGE, or UPCASE as appropriate.
// Normally with Makefile this would be defined in CXXFLAGS.
#define ADD_

#ifndef MAGMA_FORTRAN_NAME
    #if defined(MAGMA_GLOBAL)
        #define FORTRAN_NAME(lcname, UCNAME)  MAGMA_GLOBAL( lcname, UCNAME )
    #elif defined(ADD_)
        #define FORTRAN_NAME(lcname, UCNAME)  lcname##64_  // Add "64" as you suggested
...
-mark

staticfloat
Posts: 2
Joined: Fri Aug 09, 2019 3:33 pm

Re: ILP64 name-mangling

Post by staticfloat » Fri Aug 09, 2019 8:43 pm

Thanks, I'll try that. I also haven't found any guidance on how to enable ILP64 with CMake; I'm exporting `CFLAGS=-DMAGMA_ILP64` before running `cmake`, is that the recommended way?

mgates3
Posts: 902
Joined: Fri Jan 06, 2012 2:13 pm

Re: ILP64 name-mangling

Post by mgates3 » Sun Aug 11, 2019 9:13 am

That should work. Ideally, CMake would detect 64-bit BLAS, which we do in some other projects (BLAS++) but not yet in MAGMA.
-mark

mgates3
Posts: 902
Joined: Fri Jan 06, 2012 2:13 pm

Re: ILP64 name-mangling

Post by mgates3 » Mon Aug 12, 2019 12:26 pm

On second glance, it doesn't appear that CFLAGS is propagated to CXXFLAGS by CMake, and it won't propagate to Fortran or NVCC for CUDA. Even worse, it doesn't seem that CMake picks up NVCCFLAGS from the environment, so there doesn't appear to be a way to override or append to it, without editing CMakeLists.txt.

So currently, you may need to edit CMakeLists.txt to add an option something like this:

Code: Select all

# ----------------------------------------
# Ideally, CMake would auto-detect ILP64 in the BLAS/LAPACK library.
# As a work-around, make it an option.
option( ILP64 "BLAS and LAPACK are ILP64 (64-bit int) instead of usual LP64 (32-bit int)." off )
if (ILP64)
    set( CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -DMAGMA_ILP64" )
    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAGMA_ILP64" )
    set( CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-DMAGMA_ILP64" )  # semicolon
    set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-integer-8" )
endif()
Sorry, ILP64 isn't an option we've tried doing through CMake before, and as usual, CMake makes customization difficult.

-mark

JerryChen97
Posts: 2
Joined: Wed Aug 14, 2019 11:45 am

Re: ILP64 name-mangling

Post by JerryChen97 » Sat Jan 04, 2020 4:12 pm

mgates3 wrote:
Fri Aug 09, 2019 4:55 pm
If you compiled without CMake, then editing magma_mangling.h as you describe should work. But as you noticed, CMake #defines its own mangling macro, called MAGMA_GLOBAL, in the file magma_mangling_cmake.h.

The quickest hack to do would be comment out magma_mangling_cmake (or #undef MAGMA_GLOBAL), and then edit FORTRAN_NAME macro as you described. Something like this, in magma_mangling.h:

Code: Select all

// #include "magma_mangling_cmake.h"  // Comment out CMake's mangling macro,
#undef MAGMA_GLOBAL                   // or undef it.

// Define ADD_, NOCHANGE, or UPCASE as appropriate.
// Normally with Makefile this would be defined in CXXFLAGS.
#define ADD_

#ifndef MAGMA_FORTRAN_NAME
    #if defined(MAGMA_GLOBAL)
        #define FORTRAN_NAME(lcname, UCNAME)  MAGMA_GLOBAL( lcname, UCNAME )
    #elif defined(ADD_)
        #define FORTRAN_NAME(lcname, UCNAME)  lcname##64_  // Add "64" as you suggested
...
-mark
I tried this editing but my ld could not find some functions lik qpt01 or something likewise. They seem to be some testing functions only existing in the MAGMA build, but our mangling sort of globally renamed them and eventually the linker could not find these testing functions...

mgates3
Posts: 902
Joined: Fri Jan 06, 2012 2:13 pm

Re: ILP64 name-mangling

Post by mgates3 » Mon Jan 06, 2020 2:43 pm

[sdcz]qpt01 are LAPACK testing functions. They would not be in the LAPACK library, per se, but in LAPACK's testing. MAGMA has its own copy of them:

Code: Select all

>> pfind -i qpt01 lapack
lapack/TESTING/LIN/cqpt01.f
lapack/TESTING/LIN/dqpt01.f
lapack/TESTING/LIN/sqpt01.f
lapack/TESTING/LIN/zqpt01.f
>> pfind -i qpt01 magma
magma/testing/lin/cqpt01.f
magma/testing/lin/dqpt01.f
magma/testing/lin/sqpt01.f
magma/testing/lin/zqpt01.f
They are only needed in the MAGMA testers, not to build the MAGMA library itself:

Code: Select all

thyme ~/Documents/magma> grep -i qpt01 */*.{h,hpp,cu,cuh,cpp}
include/magma_clapack.h:#define lapackf77_cqpt01   FORTRAN_NAME( cqpt01, CQPT01 )
include/magma_clapack.h:float lapackf77_cqpt01( const magma_int_t *m, const magma_int_t *n, const magma_int_t *k,
include/magma_dlapack.h:#define lapackf77_dqpt01   FORTRAN_NAME( dqpt01, DQPT01 )
include/magma_dlapack.h:double lapackf77_dqpt01( const magma_int_t *m, const magma_int_t *n, const magma_int_t *k,
include/magma_slapack.h:#define lapackf77_sqpt01   FORTRAN_NAME( sqpt01, SQPT01 )
include/magma_slapack.h:float lapackf77_sqpt01( const magma_int_t *m, const magma_int_t *n, const magma_int_t *k,
include/magma_zlapack.h:#define lapackf77_zqpt01   FORTRAN_NAME( zqpt01, ZQPT01 )
include/magma_zlapack.h:double lapackf77_zqpt01( const magma_int_t *m, const magma_int_t *n, const magma_int_t *k,
testing/testing_cgeqp3.cpp:                error = lapackf77_cqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_cgeqp3_gpu.cpp:                error = lapackf77_cqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_dgeqp3.cpp:                error = lapackf77_dqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_dgeqp3_gpu.cpp:                error = lapackf77_dqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_sgeqp3.cpp:                error = lapackf77_sqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_sgeqp3_gpu.cpp:                error = lapackf77_sqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_zgeqp3.cpp:                error = lapackf77_zqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
testing/testing_zgeqp3_gpu.cpp:                error = lapackf77_zqpt01( &M, &N, &min_mn, h_A, h_R, &lda,
So `make lib` should work, but `make test` would fail if you change the name mangling.

-mark

JerryChen97
Posts: 2
Joined: Wed Aug 14, 2019 11:45 am

Re: ILP64 name-mangling

Post by JerryChen97 » Mon Jan 06, 2020 9:07 pm

So I think maybe I should try only building the lib separately.

Is there any way to keep the testing module if we want to do the name mangling?

mgates3
Posts: 902
Joined: Fri Jan 06, 2012 2:13 pm

Re: ILP64 name-mangling

Post by mgates3 » Tue Jan 07, 2020 1:37 pm

You can name mangle the functions in magma/testing/lin/
In magma/testing/Makefile.sr, see variable liblapacktest_src for the 36 or so files that are used. The other files in that directory were copied from LAPACK but aren't used.

-mark

Post Reply