Without root access, run R with tuned BLAS when it is linked with reference BLAS

前端 未结 3 1155
温柔的废话
温柔的废话 2020-12-10 17:11

Can any one tell me why I can not successfully test OpenBLAS\'s dgemm performance (in GFLOPs) in R via the following way?

  1. link R
3条回答
  •  隐瞒了意图╮
    2020-12-10 18:15

    *********************

    Solution 2:

    *********************

    Here we offer another solution, by exploiting environment variable LD_PRELOAD mentioned in our solution 1. The use of LD_PRELOAD is more "brutal", as it forces loading a given library into the program before any other program, even before the C library libc.so! This is often used for urgent patching in Linux development.

    As shown in the part 2 of the original post, the shared BLAS library libopenblas.so has SONAME libopenblas.so.0. An SONAME is an internal name that dynamic library loader would seek at run time, so we need to make a symbolic link to libopenblas.so with this SONAME:

    ~/Desktop/dgemm$ ln -sf libopenblas.so libopenblas.so.0
    

    then we export it:

    ~/Desktop/dgemm$ export LD_PRELOAD=$(pwd)/libopenblas.so.0
    

    Note that a full path to libopenblas.so.0 needs be fed to LD_PRELOAD for a successful load, even if libopenblas.so.0 is under $(pwd).

    Now we launch Rscript and check what happens by LD_DEBUG:

    ~/Desktop/dgemm$ LD_DEBUG=libs Rscript --default-packages=base --vanilla /dev/null |& grep blas
      4860: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4860: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4865: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4868: calling fini: /home/zheyuan/Desktop/dgemm/libopenblas.so [0]
      4870: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4869: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4867: calling fini: /home/zheyuan/Desktop/dgemm/libopenblas.so [0]
      4860: find library=libblas.so.3 [0]; searching
      4860:   trying file=/usr/lib/R/lib/libblas.so.3
      4860:   trying file=/usr/lib/i386-linux-gnu/i686/sse2/libblas.so.3
      4860:   trying file=/usr/lib/i386-linux-gnu/i686/cmov/libblas.so.3
      4860:   trying file=/usr/lib/i386-linux-gnu/i686/libblas.so.3
      4860:   trying file=/usr/lib/i386-linux-gnu/sse2/libblas.so.3
      4860:   trying file=/usr/lib/i386-linux-gnu/libblas.so.3
      4860:   trying file=/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libblas.so.3
      4860:   trying file=/usr/lib/libblas.so.3
      4860: calling init: /usr/lib/libblas.so.3
      4860: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4874: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4876: calling init: /home/zheyuan/Desktop/dgemm/libopenblas.so
      4860: calling fini: /home/zheyuan/Desktop/dgemm/libopenblas.so [0]
      4860: calling fini: /usr/lib/libblas.so.3 [0]
    

    Comparing with what we saw in solution 1 by cheating R with our own version of libblas.so.3, we can see that

    • libopenblas.so.0 is loaded first, hence found first by Rscript;
    • after libopenblas.so.0 is found, Rscript goes on searching and loading libblas.so.3. However, this will play no effect by the "first come, first serve" rule, explained in the original answer.

    Good, everything works, so we test our mmperf.c program:

    ~/Desktop/dgemm$ Rscript --default-packages=base --vanilla mmperf.R
    GFLOPs = 9.62
    

    The outcome 9.62 is bigger than 8.77 we saw in the earlier solution merely by chance. As a test for using OpenBLAS we don't run the experiment many times for preciser result.

    Then as usual, we unset environment variable in the end:

    ~/Desktop/dgemm$ unset LD_PRELOAD
    

提交回复
热议问题