0

CUDAとCを使用して基本的な行列乗算プログラムを作成しようとしています。コード自体は現在何も実行していませんが、少なくともコンパイルする必要があります。この問題について調査した結果、問題はCUDAヘッダーファイルのインクルードの失敗であり、Makefileに問題があることを示していると判断しました。私はCUDA(そしてそのことについてはC)に非常に不慣れなので、どんな助けでも大歓迎です。

コマンドの出力:make matrixMult1

c99    -I. -I/usr/local/cuda/include -c matrixMult1.c -o matrixMult1.o
matrixMult1.c: In function 'main':
matrixMult1.c:77: warning: implicit declaration of function 'cudaMalloc'
matrixMult1.c:82: warning: implicit declaration of function 'cudaMemcpy'
matrixMult1.c:83: error: 'cudaMemcpyHostToDevice' undeclared (first use in this
function)
matrixMult1.c:83: error: (Each undeclared identifier is reported only once
matrixMult1.c:83: error: for each function it appears in.)
matrixMult1.c:106: warning: implicit declaration of function 'cudaFree'
make: *** [matrixMult1.o] Error 1

Makefile:

GCC = c99
CUDA_INSTALL_PATH := /usr/local/cuda
INCLUDES := -I. -I$(CUDA_INSTALL_PATH)/include
CUDA_LIBS := -L$(CUDA_INSTALL_PATH)/lib -lcudart

matrixMult1.o:          matrixMult1.c
                $(GCC)  $(INCLUDES) -c matrixMult1.c -o $@

matrixMult1:            matrixMult1.o
                $(GCC)  -o $@ matrixMult1.o $(CUDA_LIBS)

Cプログラム:

//********************************************************************
// matrixMult1.c
//
// A basic matrix multiplication program.
//********************************************************************

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "cuda.h"

#define WA 3
#define HA 3
#define WB 3
#define HB WA
#define WC WB
#define HC HA

void initMatrix(float * matrix, int numIndices);

//*************
// Main Program
//*************
int main(int argc, char** argv) {

    /* Set random seed */
    srand(2013);

    /* Compute memory sizes for matrices A, B, and C */
    unsigned int sizeA = WA * HA;
    unsigned int sizeB = WB * HB;
    unsigned int sizeC = WC * HC;
    unsigned int memoryA = sizeof(float) * sizeA;
    unsigned int memoryB = sizeof(float) * sizeB;
    unsigned int memoryC = sizeof(float) * sizeC;

    /* Allocate memory for matrices A, B, and C */
    float * matrixA = (float *) malloc(memoryA);
    float * matrixB = (float *) malloc(memoryB);
    float * matrixC = (float *) malloc(memoryC);

    /* Initialize matrices A and B */
    initMatrix(matrixA, sizeA);
    initMatrix(matrixB, sizeB);

    /* Print matrix A */
    printf("\nMatrix A:\n");
    for (int i = 0; i < sizeA; i++) {
        printf("%f ", matrixA[i]);

    if (((i + 1) % WA) == 0) {
        printf("\n");
    } else {
        printf(" | ");
    }
    }

    /* Print matrix B */
    printf("\nMatrix B:\n");
    for (int i = 0; i < sizeB; i++) {
    printf("%f ", matrixB[i]);

    if (((i + 1) % WA) == 0) {
        printf("\n");
    } else {
        printf(" | ");
    }
    }

    /* Allocate device memory */
    float* deviceMemA;
    float* deviceMemB;
    float* deviceMemC;
    cudaMalloc((void**) &deviceMemA, memoryA);
    cudaMalloc((void**) &deviceMemB, memoryB);
    cudaMalloc((void**) &deviceMemC, memoryC);

    /* Copy host memory to device */
    cudaMemcpy(deviceMemA, matrixA, memoryA,
           cudaMemcpyHostToDevice);
    cudaMemcpy(deviceMemB, matrixB, memoryB,
               cudaMemcpyHostToDevice);
    cudaMemcpy(deviceMemC, matrixC, memoryC,
           cudaMemcpyHostToDevice);

    /* Print matrix C */
    printf("\nMatrix C:\n");
    for (int i = 0; i < sizeC; i++) {
    printf("%f ", matrixC[i]);

    if (((i + 1) % WC) == 0) {
        printf("\n");
    } else {
        printf(" | ");
    }
    }
    printf("\n");

    /* Free up memory */
    free(matrixA);
    free(matrixB);
    free(matrixC);
    cudaFree(deviceMemA);
    cudaFree(deviceMemB);
    cudaFree(deviceMemC);
}

//--------------------------------------------------------------------
// initMatrix - Assigns a random float value to each indice of the
//              matrix.
//
// PRE:  matrix is a pointer to a block of bytes in memory; numIndices
//       is the number of indicies in the matrix being instantiated.
// POST: Each index of the matrix has been instantiated with a random
//       float value.
//--------------------------------------------------------------------
void initMatrix(float * matrix, int numIndices) {

    /*
    Loop through the block of bytes, assigning a random float
    for each index of the matrix
    */
    for (int i = 0; i < numIndices; ++i) {

    /* Assign a random float between 0 and 1 at this byte */
    matrix[i] = rand() / (float)RAND_MAX;
    }
}
4

2 に答える 2

1

ここで 2 つの問題:

  1. コードに適切なヘッダーを含めていませんでした(修正しました)
  2. 実際、あなたの Makefile は壊れています。次のようになります。
GCC = c99
CUDA_INSTALL_PATH := /usr/local/cuda
INCLUDES := -I. -I$(CUDA_INSTALL_PATH)/include
CUDA_LIBS := -L$(CUDA_INSTALL_PATH)/lib -lcudart

matrixMult1.o:          matrixMult1.c
                $(GCC) $(INCLUDES) -c matrixMult1.c -o $@

matrixMult1:            matrixMult1.o
                $(GCC) -o $@ matrixMult1.o  $(CUDA_LIBS)

[免責事項:テストされていません。自己責任で使用してください]

現在の問題は、インクルード パスがビルドのリンケージ フェーズでのみ指定されていたことです。

これらの変更により、CUDA ランタイム ライブラリとリンクしていないためにリンク中に発生するシンボルの欠落エラーも回避されることに注意してください。32 ビットまたは 64 ビットのホスト OS を使用しているかどうかに応じて$(CUDA_INSTALL_PATH)/lib64、リンケージを正しく機能させるためにライブラリ パスを に変更する必要がある場合があることに注意してください。

于 2013-03-20T09:38:06.490 に答える
1

CUDA プログラムは でコンパイルする必要がありますnvcc。あなたのプログラムにはまだ CUDA カーネルが含まれていませんが、それはあなたが達成したいことだと思います。

ファイルの名前を からmatrixMult1.cに変更しmatrixMult1.cu、その行を削除し#include "cuda.h"( でコンパイルされたプログラムはnvccCUDA 固有のインクルードを必要としません)、nvcc代わりに でコンパイルしますgcc(たとえばGCC = nvcc、Makefile の先頭に設定することにより)。

于 2013-03-20T11:01:37.787 に答える