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

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

ただいまの
回答率

90.84%

  • C

    3333questions

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

  • 並列処理

    32questions

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

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

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 468

carnage0216

score 104

<環境>

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

#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を定義している部分なのではないのでしょうか?
どうかエラーを解決するためにお力を貸していただけないでしょうか。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

なんの問題もないねー。

#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 / omp_get_num_threads();
    int thread_part_min = num * thread_id;
    int thread_part_max =
          (omp_get_thread_num() + 1) == omp_get_num_threads() ? N : thread_part_min + num;

        add(a,b,c,thread_part_min,thread_part_max);
        mul(a,b,d,thread_part_min,thread_part_max);
    add_add(a,b,e,thread_part_min,thread_part_max);
    mul_mul(a,b,f,thread_part_min,thread_part_max);
  }

  for(i=0; i < N; i++){
    printf("%4d %4d %4d %4d\n",c[i],d[i],e[i],f[i]);
  }

  return 0;
}

void add(int *a, int *b, int *c, int min, int max){
  int i;
  for(i=min; i < max; i++){
    c[i] = a[i] + b[i];
  }
}

void mul(int *a, int *b, int *d, int min, int max){
  int i;
  for(i=min; i < max; i++){
    d[i] = a[i] * b[i];
  }
}

void add_add(int *a, int *b, int *e, int min,int max){
  int i;
  for(i=min; i < max; i++){
    e[i] = a[i] + b[i] + b[i];
  }
}

void mul_mul(int *a, int *b, int *f, int min, int max){
  int i;
  for(i=min; i < max; i++){
    f[i] = a[i] * b[i] * b[i];
  }
}

/* cl -openmp Workload_Improvement.c
  実行結果:

   1    0    2    0
   2    1    3    1
   3    2    4    2
   ...
 998  997  999  997
 999  998 1000  998
1000  999 1001  999
*/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/15 20:23 編集

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

    キャンセル

  • 2018/05/16 21:09

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

    キャンセル

0

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/14 22:24

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

    キャンセル

  • 2018/05/14 22: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を得ました。
    そのライブラリを設定したのですがエラーが消えませんでした。他に何のライブラリが必要なのでしょうか?

    キャンセル

  • 2018/05/15 03:44

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

    キャンセル

  • 2018/05/15 04:08

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

    キャンセル

  • 2018/05/15 09: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];
    }
    }

    キャンセル

  • 2018/05/15 18:57

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

    キャンセル

  • 2018/05/15 19:16

    なにやってんだ...

    キャンセル

  • 2018/05/15 20:24

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

    キャンセル

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

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3333questions

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

  • 並列処理

    32questions

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