1

最近、 NVidiaサイト、このサイト、およびこのサイトの指示に従って、64 ビットの Ubuntu 12.04 システムに CUDA 5.0 をインストールしました。(注として、Ubuntu 12.04 は、NVidia サイトで CUDA 5.0 をサポートするものとしてリストされている OS の 1 つではありませんが、他の人がそれをインストールしてシステムで実行していることは明らかです。) ドライバーとパッケージを正しくインストールした後、試してみます。コンパイルして実行する

1) 含まれているサンプルの最初のプログラム (~/NVIDIA_CUDA-5.0_Samples/1_Utilities/deviceQuery/ の実行可能な deviceQuery)、および

2) 最初の GPU 対応プログラム (第 03 章の simple_kernel.cu ) は、 NVidia が発行し たCUDA By Exampleブックのソース コード (ここから入手可能) に含まれています。

実行可能ファイル 1)make対応するディレクトリで実行して取得しました。実行可能 2) で取得しましnvcc simple_kernel.cuた。両方の結果は次の出力でした。

./deviceQuery: error while loading shared libraries: libcudart.so.5.0: cannot open shared object file: No such file or directory

また

./a.out: error while loading shared libraries: libcudart.so.5.0: cannot open shared object file: No such file or directory

明確にするために、はい、PATH変数を include/usr/local/cuda-5.0/binに設定し、変数に と のLD_LIBRARY_PATH両方を含める/usr/local/cuda-5.0/libように設定しました。はい、を指すリンクと を指す/usr/local/cuda-5.0/lib64リンクがありました。しかし、これは私の質問につながります.../usr/local/cuda-5.0/lib/libcudart.so/usr/local/cuda-5.0/lib/libcudart.so.5.0/usr/local/cuda-5.0/lib/libcudart.so/usr/local/cuda-5.0/lib/libcudart.so.5.0

~/.bashrc ファイルに行を追加して、PATH 変数と LD_LIBRARY_PATH 変数を変更しました。

export PATH=${PATH}:/usr/local/cuda-5.0/binexport LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/cuda-5.0/lib:/usr/local/cuda-5.0/lib64

ターミナル ウィンドウを開いて入力するecho $PATHecho $LD_LIBRARY_PATH、両方の変数が正しく設定されていることが示されますが、上記の CUDA 実行可能ファイルの実行に問題がありました。

次に、stackoverflow でこの投稿を見つけ、sivapal ayyappan nadar によって提供された提案を試してみました。PATH変更/etc/environmentLD_LIBRARY_PATH変更による設定です/etc/ld.so.conf.d/cuda50.conf(~/.bashrc の対応する行を同時にコメントアウトしました)。CUDA サンプルをコンパイルして実行すると、動作するようになりました。

では、私の質問: ここで何が起こっているのでしょうか? LD_LIBRARY_PATH が設定されている場合は libcudart ライブラリが正しくリンクされている/etc/ld.so.conf.d/cuda50.confのに、 に設定されている場合はリンクされないのはなぜ~/.bashrcですか? 一方が行い、他方が行わないことは何ですか? それとも、これが私の問題の本当の原因ではありませんか?

返信の際は、私の質問の動機を念頭に置いてください。1) Linux システムの複雑さを理解し、2) 利用可能な他の優れた指示に従った後でも同じ問題に遭遇する可能性のある他の人のために、考えられる解決策を投稿したいと思います。どうもありがとう。

4

1 に答える 1

3

これは少し興味深いトピックなので、説明してみます。したがって、この例では、小さなライブラリjanssonをテスト用にインストールします。非標準のディレクトリにインストールするように構成します。

./configure --prefix=/home/ubuntu/mystuff

これを実行すると、次のmake install警告が表示されます。

Libraries have been installed in:
   /home/ubuntu/mystuff/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.

では、テスト スイート プログラムの 1 つを使用してリンクを試みます。

$ gcc test_dump.c -ljansson 
test_dump.c:8:21: fatal error: jansson.h: No such file or directory

C が何を使用できるかを知るためには、まずインクルード ファイルについて知る必要があります。幸いなことに、これはコンパイル時にのみ行う必要があります。インクルード ファイルの場所を知っている-Iので、インクルード ディレクトリを渡します。gcc

$ gcc test_dump.c -I/home/ubuntu/mystuff/include -ljansson
/usr/bin/ld: cannot find -ljansson

さて、リンクの問題に戻ります。LD_LIBRARY_PATHそれでは、リンクしながら試してみましょう:

$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" gcc test_dump.c -I/home/ubuntu/mystuff/include -ljansson
/usr/bin/ld: cannot find -ljansson

これは機能しません。これの背後にある理由は、次のコマンドを実行すると表示されるように、gcc が別のディレクトリを検索しているためです。

gcc -print-search-dirs

必要なディレクトリで動作するようにgccに指示するには、-L次を使用します。

$ gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson
$

これで、と呼ばれるプログラムを使用して、lddリンク対象を確認できます。

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fc4c872d000)
        libjansson.so.4 => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc4c8366000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc4c872e000)

必要なライブラリが「見つかりません」と表示されていることに気付くでしょう。今、その問題を試してみてください:

$ LD_RUN_PATH="/home/ubuntu/mystuff/lib" gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson

これは を使用する 1 つの方法LD_RUN_PATHです。ライブラリだけにリンクするのではなく、ライブラリへのフル パスにリンクします。もう一度実行lddすると、次のようになります。

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fff481d7000)
        libjansson.so.4 => /home/ubuntu/mystuff/lib/libjansson.so.4 (0x00007fe86b0dd000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe86ad18000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe86b2eb000)

これを関与せずに試してみると、次のLD_RUN_PATHようになります。

$ ./a.out 
./a.out: error while loading shared libraries: libjansson.so.4: cannot open shared object file: No such file or directory

これを解決するにLD_LIBRARY_PATHは、次を使用します。

$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" ./a.out
$

ただし、これはちょっとしたハックであり、眉をひそめています。David Barr は、この問題について素晴らしい記事を書いています。何が起こっているかというとld.so/ld-linux.so、「プログラムに必要な共有ライブラリをロードし、実行するプログラムを準備してから実行する」動的ライブラリ ローダーがあるということです。ld.soマンページを見ると、次のように記載されています。

   The necessary shared libraries needed by the program are searched for in the following order

   o      Using the environment variable LD_LIBRARY_PATH (LD_AOUT_LIBRARY_PATH for a.out programs).  Except if the executable is a setuid/setgid binary, in which case it is ignored.

   o      From the cache file /etc/ld.so.cache which contains a compiled list of candidate libraries previously found in the augmented library path. Libraries installed in hardware capabilities
          directories (see below) are prefered to other libraries.

   o      In the default path /lib, and then /usr/lib.

その/etc/ld.so.cacheパスを入れたい場所です。このキャッシュは をldconfig使用して生成され/etc/ld.so.confます。Ubuntuでそのファイルを見ると:

include /etc/ld.so.conf.d/*.conf

それが言うすべてです。/etc/ld.so.conf.dディレクトリには、デフォルトで、glib、gcc のディレクトリがあり、/usr/local/libデフォルト パスの外にあるためです。必要なディレクトリをキャッシュに追加するには、そのディレクトリにファイルを追加するだけです。

$ sudo vim /etc/ld.so.conf.d/50-jansson.conf
- add /home/ubuntu/mystuff/lib to the file -
$ sudo ldconfig

これにより/etc/ld.so.cache、ローダー用にそのファイルが再生成されます。ldconfigキャッシュされたディレクトリを出力することで、ディレクトリが取得されたことを確認できます。

$ ldconfig -p | grep "mystuff"
        libjansson.so.4 (libc6,x86-64) => /home/ubuntu/mystuff/lib/libjansson.so.4
        libjansson.so (libc6,x86-64) => /home/ubuntu/mystuff/lib/libjansson.so

ここで、lddもう一度実行を試みると、次のようになります。

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fff1e510000)
        libjansson.so.4 => /home/ubuntu/mystuff/lib/libjansson.so.4 (0x00007f529da67000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f529d6a8000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f529dc7b000)

最後にプログラムを実行します。

$ ./a.out
$

それはすべて動作します!これは、リンクを行っているときにバックエンドで何が起こっているかを調べたものです。詳細については、 および を参照することをお勧めしman ld.soますman ldconfig。説明が必要な場合は、遠慮なくお尋ねください。

于 2013-03-03T22:05:50.597 に答える