質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

1回答

1653閲覧

bindgenを用いてCUDAファイルをバインドできない問題について

BoKuToTuZenU

総合スコア51

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2021/09/13 07:21

編集2021/09/13 07:26

前提・実現したいこと

CUDAのコードをRustから呼び出すため、ccでCUDAファイルをコンパイルし、昨日をまとめたヘッダファイルをbindgenを用いてバインドを試みました。そこで以下のようなエラーを受け取りました。

発生している問題・エラーメッセージ

error: linking with `cc` failed: exit status: 1 | [中略] /usr/bin/ld: /home/bokutotu/curs/target/debug/deps/libcurs-453523e706acde45.rlib(curs-453523e706acde45.46yo270hd3f29kpq.rcgu.o): in function `curs::kernel::array_scalar_add::float_array_add_scalar': /home/bokutotu/curs/src/kernel/array_scalar_add.rs:9: undefined reference to `floatArrayScalarAdd' collect2: error: ld returned 1 exit status = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified = note: use the `-l` flag to specify native libraries to link = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

該当のソースコード

多くのCUDAファイルをしようしていますが、全てを記載することはできないのでひとつのCUDAファイルについてのみ記載させていただきます。

array_scalar_add.cu

cuda

1#include "array_scalar_add.cuh" 2 3#define BLOCKDIM 256 4 5template<typename T> 6__global__ void arrayAddScalar(T *array, T *resArray, T scalar, int size) { 7 unsigned int idx = threadIdx.x + blockIdx.x * blockDim.x; 8 if (idx >= size) { return; } 9 resArray[idx] = array[idx] + scalar; 10} 11 12void floatArrayScalarAdd(float *array, float *resArray, float scalar, int size) { 13 dim3 blockDim(BLOCKDIM); 14 dim3 gridDim((size + blockDim.x - 1) / blockDim.x); 15 arrayAddScalar<<< gridDim, blockDim >>> (array, resArray, scalar, size); 16} 17 18void doubleArrayScalarAdd(double *array, double *resArray, double scalar, int size) { 19 dim3 blockDim(BLOCKDIM); 20 dim3 gridDim((size + blockDim.x - 1) / blockDim.x); 21 arrayAddScalar<<< gridDim, blockDim >>> (array, resArray, scalar, size); 22}

array_scalar_add.cuh

cuda

1#pragma once 2 3void floatArrayScalarAdd(float *array, float *resArray, float scalar, int size); 4void doubleArrayScalarAdd(double *array, double *resArray, double scalar, int size);

build.rs

rust

1extern crate cc; 2 3use cuda_find_path::find_cuda; 4use std::{env, path::PathBuf}; 5 6fn main() { 7 let cuda_files = vec![ 8 "kernel/compare.cu",  // 他のCUDAファイル 9 "kernel/element_wise_operator.cu",  // 他のCUDAファイル 10 "kernel/transpose.cu", // 他のCUDAファイル 11 "kernel/array_scalar_add.cu", 12 ]; 13 14 for cuda_file in cuda_files.iter() { 15 println!("{}", format!("cargo:rerun-if-changed={}", cuda_file)); 16 } 17 println!("cargo:rerun-if-changed=kernel/kernel.h"); 18 println!("cargo:rerun-if-changed=build.rs"); 19 20 cc::Build::new() 21 .cuda(true) 22 .flag("-gencode") 23 .flag("arch=compute_75,code=sm_75") // for (RTX 2080Ti). 24 .files(&cuda_files) 25 .include("kernel/") 26 .compile("libkernel.a"); 27 28 for path in find_cuda() { 29 println!("cargo:rustc-link-search=native={}", path.display()); 30 } 31 32 println!("cargo:rustc-link-lib=cudart"); 33 println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64/stub"); 34 println!("cargo:rustc-link-lib=cuda"); 35 36 let bindings = bindgen::Builder::default() 37 .ctypes_prefix("::libc") 38 .size_t_is_usize(true) 39 .clang_arg("-I") 40 .clang_arg("/usr/local/cuda/include".to_string()) 41 .header("kernel/kernel.h") 42 .default_alias_style(bindgen::AliasVariation::TypeAlias) 43 .rustfmt_bindings(true) 44 .derive_default(true) 45 .derive_eq(true) 46 .derive_hash(true) 47 .derive_ord(true) 48 .parse_callbacks(Box::new(bindgen::CargoCallbacks)) 49 .generate() 50 .expect("Unable to generate bindings"); 51 52 let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 53 bindings 54 .write_to_file(out_path.join("bindings.rs")) 55 .expect("Unable to write"); 56}

試したこと

ccでコンパイルしたファイルをリンクするようにprintln!("cargo:rustc-link-lib=kernel");を追加しましたが同じエラーを受け取りました。

補足情報(FW/ツールのバージョンなど)

rustc : 1.55.0
bindgen 0.59.1
cc: 1.0.70

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

CUDAについて知識がないので誤ったことを言っていたらご容赦ください


array_scalar_add.cuを見ると、テンプレートを使っているので、おそらくC++ファイルとしてコンパイルされているものと推察できます。
この場合、関数floatArrayScalarAdddoubleArrayScalarAddは、デフォルトではC++リンケージでコンパイルされることになります。
C++リンケージでは関数名のマングルが行われるのでオブジェクトファイルに含まれる関数名が異なったものになります。

解決方法としては、extern "C"を関数の実装に追加してコンパイルするとCリンケージになるので、これでうまく行くと思います。

投稿2021/09/13 07:48

equal-l2

総合スコア172

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BoKuToTuZenU

2021/09/13 09:34

``` #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif ``` でextern "C" したら無事にコンパイルすることができました。ご回答いただきありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問