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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

並列処理

複数の計算が同時に実行される手法

Q&A

解決済

3回答

2732閲覧

並列処理を行うプログラムのコンパイルエラー。

carnage0216

総合スコア194

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

並列処理

複数の計算が同時に実行される手法

0グッド

0クリップ

投稿2018/05/14 10:19

<環境>

こちらのプログラムをコンパイルしたところ以下のエラーが出ました。

#include<stdio.h> #include<omp.h> #define N 1000 void add(int *a, int *b, int *c, int min, int max); void mul(int *a, int *b, int *d, int min, int max); void add_add(int *a, int *b, int *e, int min, int max); void mul_mul(int *a, int *b, int *f, int min, int max); int main(){ int a[N]; int b[N]; int c[N]; int d[N]; int e[N]; int f[N]; int i; #pragma omp parallel for for(i=0; i < N; i++){ a[i] = i; b[i] = 1; } #pragma omp parallel { int thread_id = omp_get_thread_num(); int num = N/4; int thread_part = num * thread_id; add(a,b,c,thread_part,thread_part + num); mul(a,b,d,thread_part,thread_part + num); add_add(a,b,e,thread_part,thread_part + num); mul_mul(a,b,f,thread_part,thread_part + num); } for(i=0; i < N; i++){ printf("c : %d\n",c[i]); printf("d : %d\n",d[i]); printf("e : %d\n",e[i]); printf("f : %d\n",f[i]); } return 0; }

こちらがエラーです。

C:\Users\Daito\AppData\Local\Temp\cc8XCf4f.o:Workload_Improvement.c:(.text+0x61): undefined reference to `omp_get_thread_num' C:\Users\Daito\AppData\Local\Temp\cc8XCf4f.o:Workload_Improvement.c:(.text+0xcd): undefined reference to `add' C:\Users\Daito\AppData\Local\Temp\cc8XCf4f.o:Workload_Improvement.c:(.text+0x111): undefined reference to `mul' C:\Users\Daito\AppData\Local\Temp\cc8XCf4f.o:Workload_Improvement.c:(.text+0x155): undefined reference to `add_add' C:\Users\Daito\AppData\Local\Temp\cc8XCf4f.o:Workload_Improvement.c:(.text+0x196): undefined reference to `mul_mul' collect2.exe: error: ld returned 1 exit status

プログラムを見る限りomp_get_thread_numが必要ないと思い消しました。
そして試しにint thread_id = 0と置きました。
再びコンパイルしたところ以下のエラーが出ました。

C:\Users\Daito\AppData\Local\Temp\cccJAFkb.o:Workload_Improvement.c:(.text+0xcc): undefined reference to `add' C:\Users\Daito\AppData\Local\Temp\cccJAFkb.o:Workload_Improvement.c:(.text+0x110): undefined reference to `mul' C:\Users\Daito\AppData\Local\Temp\cccJAFkb.o:Workload_Improvement.c:(.text+0x154): undefined reference to `add_add' C:\Users\Daito\AppData\Local\Temp\cccJAFkb.o:Workload_Improvement.c:(.text+0x195): undefined reference to `mul_mul' collect2.exe: error: ld returned 1 exit status

関数の定義がされていないとエラーが出ているのですが、

void add(int *a, int *b, int *c, int min, int max); void mul(int *a, int *b, int *d, int min, int max); void add_add(int *a, int *b, int *e, int min, int max); void mul_mul(int *a, int *b, int *f, int min, int max);

こちらが変数add、mul、add_add、mul_mulを定義している部分なのではないのでしょうか?
どうかエラーを解決するためにお力を貸していただけないでしょうか。

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

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

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

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

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

guest

回答3

0

ベストアンサー

なんの問題もないねー。

C

1#include <stdio.h> 2#include <omp.h> 3#define N 1000 4 5void add(int *a, int *b, int *c, int min, int max); 6void mul(int *a, int *b, int *d, int min, int max); 7void add_add(int *a, int *b, int *e, int min, int max); 8void mul_mul(int *a, int *b, int *f, int min, int max); 9 10int main(){ 11 int a[N]; 12 int b[N]; 13 int c[N]; 14 int d[N]; 15 int e[N]; 16 int f[N]; 17 int i; 18 19 #pragma omp parallel for 20 for(i=0; i < N; i++){ 21 a[i] = i; 22 b[i] = 1; 23 } 24 25 #pragma omp parallel 26 { 27 int thread_id = omp_get_thread_num(); 28 int num = N / omp_get_num_threads(); 29 int thread_part_min = num * thread_id; 30 int thread_part_max = 31 (omp_get_thread_num() + 1) == omp_get_num_threads() ? N : thread_part_min + num; 32 33 add(a,b,c,thread_part_min,thread_part_max); 34 mul(a,b,d,thread_part_min,thread_part_max); 35 add_add(a,b,e,thread_part_min,thread_part_max); 36 mul_mul(a,b,f,thread_part_min,thread_part_max); 37 } 38 39 for(i=0; i < N; i++){ 40 printf("%4d %4d %4d %4d\n",c[i],d[i],e[i],f[i]); 41 } 42 43 return 0; 44} 45 46void add(int *a, int *b, int *c, int min, int max){ 47 int i; 48 for(i=min; i < max; i++){ 49 c[i] = a[i] + b[i]; 50 } 51} 52 53void mul(int *a, int *b, int *d, int min, int max){ 54 int i; 55 for(i=min; i < max; i++){ 56 d[i] = a[i] * b[i]; 57 } 58} 59 60void add_add(int *a, int *b, int *e, int min,int max){ 61 int i; 62 for(i=min; i < max; i++){ 63 e[i] = a[i] + b[i] + b[i]; 64 } 65} 66 67void mul_mul(int *a, int *b, int *f, int min, int max){ 68 int i; 69 for(i=min; i < max; i++){ 70 f[i] = a[i] * b[i] * b[i]; 71 } 72} 73 74/* cl -openmp Workload_Improvement.c 75 実行結果: 76 77 1 0 2 0 78 2 1 3 1 79 3 2 4 2 80 ... 81 998 997 999 997 82 999 998 1000 998 831000 999 1001 999 84*/

投稿2018/05/15 10:16

episteme

総合スコア16614

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

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

carnage0216

2018/05/15 11:26 編集

お待たせしました。なんとか解決できました。 TaroToyotomiさんのアドバイスを基にプログラムの編集とrun terminalからコンパイルしたらできました。 どうもありがとうございます。
episteme

2018/05/16 12:09

んじゃ"解決"しといて。
guest

0

コンパイル・オプションは? -fopenmp つけてるか?

こちらが変数add、mul、add_add、mul_mulを定義している部分なのではないのでしょうか?

それは定義じゃない、宣言だ。
「関数部分は冗長になるので省略する。」って書いてあるぞ。

投稿2018/05/14 12:04

編集2018/05/14 12:08
episteme

総合スコア16614

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

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

carnage0216

2018/05/14 13:24

>>-fopenmp つけてるか? 付けていませんでした。 >>それは定義じゃない、宣言だ。 「関数部分は冗長になるので省略する。」って書いてあるぞ。 忘れていました。改めて考えてコンパイルしてみます。
carnage0216

2018/05/14 13:43

VS2017で実行したところ 1>------ ビルド開始: プロジェクト: 並列計算, 構成: Release x64 ------ 1>Source.obj : error LNK2001: 外部シンボル ""void __cdecl mul_mul(int *,int *,int *,int,int)" (?mul_mul@@YAXPEAH00HH@Z)" は未解決です。 1>Source.obj : error LNK2001: 外部シンボル ""void __cdecl add(int *,int *,int *,int,int)" (?add@@YAXPEAH00HH@Z)" は未解決です。 1>Source.obj : error LNK2001: 外部シンボル ""void __cdecl add_add(int *,int *,int *,int,int)" (?add_add@@YAXPEAH00HH@Z)" は未解決です。 1>Source.obj : error LNK2001: 外部シンボル ""void __cdecl mul(int *,int *,int *,int,int)" (?mul@@YAXPEAH00HH@Z)" は未解決です。 1>c:\users\daito\source\repos\Project14\x64\Release\並列計算.exe : fatal error LNK1120: 4 件の未解決の外部参照 1>プロジェクト "Project14.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== と出ました。 ライブラリを持っていなかったのでcmakeでomp.slnを作り、releaseでビルドしてomp.libを得ました。 そのライブラリを設定したのですがエラーが消えませんでした。他に何のライブラリが必要なのでしょうか?
YomogiKOBO

2018/05/14 18:44

なぜにVisual Studioで試行しているのだ。 ”gcc(Mingw)”で実行ファイルを得ようとしていたのではないのか? もしかしてgccで手に負えなくなったからとか・・・ 開発環境を自身の都合で変えてんじゃねよ。回答者が振り回されるだろうが。
episteme

2018/05/14 19:08

起きている問題に対する対処がまるで見当違い。 「関数:mul_mul 等がないからexeが作れない」と言うてるんだが、 あなたはそれに対してどんな対処をしたんだ?
carnage0216

2018/05/15 00:43

勝手に環境を変えて申し訳ありませんでした。 gccに戻します。 プログラムの最後の部分のreturn 0;の後に以下のプログラムを付け足す対処をしました。 void add(int *a, int *b, int *c){ int i; #pragma omp parallel for for(i=0; i < N; i++){ c[i] = a[i] + b[i]; } } void mul(int *a, int *b, int *d){ int i; #pragma omp parallel for for(i=0; i < N; i++){ d[i] = a[i] * b[i]; } } void add_add(int *a, int *b, int *e){ int i; #pragma omp parallel for for(i=0; i < N; i++){ e[i] = a[i] + b[i] + b[i]; } } void mul_mul(int *a, int *b, int *f){ int i; #pragma omp parallel for for(i=0; i < N; i++){ f[i] = a[i] * b[i] * b[i]; } }
TaroToyotomi

2018/05/15 09:57

付け足した関数、プロトタイプと型があってないですよ。
episteme

2018/05/15 10:16

なにやってんだ...
carnage0216

2018/05/15 11:24

どうもありがとうございます。
guest

0

プログラムを見る限りomp_get_thread_numが必要ないと思い消しました。

コンパイルに失敗しているのは、OpenMPをコンパイルオプションで有効にし忘れているからでしょう。そして、「思った」判断もメチャクチャです(並列処理する以上、今「どの部分」を実行するかを知ることは、ほぼ必須です)。

こちらが変数add、mul、add_add、mul_mulを定義している部分なのではないのでしょうか?

いえ、これは関数プロトタイプといって、引数や返り値を決めるためにある宣言だけのものです。実装は別に必要です。

投稿2018/05/14 11:50

maisumakun

総合スコア145123

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問