Включить ядро ​​cuda в мой проект - PullRequest
0 голосов
/ 16 июня 2011

У меня есть проект c ++, в котором я вызываю ядро ​​cuda с помощью функции-оболочки.

Мой файл c ++ выглядит следующим образом (это extern.cc ):

#include "extern.h"  
#include "qc/operator.h"  
#include "qc/quStates.h"  
#include "gpu.h"  
...  
ROUTINE(ext_bit) {  
    int i;  
    quState *qbit;
    PAR_QUSTATE(q,"q");
    opBit *op;
    tComplex I(0,1);
    tComplex sg= inv ? -1 : 1;
    char c=(def->id())[0];
    if(def->id().length()!=1) c='?';
    switch(c) {
        case 'H': op=new opBit(1,1,1,-1,sqrt(0.5)); break;
        case 'X': op=new opBit(0,1,1,0);        break;
        case 'Y': op=new opBit(0,-I,I,0);       break;
        case 'Z': op=new opBit(1,0,0,-1);       break;
        case 'S': op=new opBit(1,0,0,sg*I);     break;
        case 'T': op=new opBit(1,0,0,sqrt(0.5)+sg*sqrt(0.5)*I); break;
        case '?':
        default: EXTERR("unknown single qubit operator "+def->id());
    } 

    // This is where I call my wrapper function
    // the error that I get is: expected primary-expression before ',' token
    gpucaller(opBit, q);  

    qcl_delete(op);
    return 0;
}

где "gpucaller" - это моя функция-оболочка, которая вызывает ядро, оба определены в cuda_kernel.cu :

/* compiling with:
nvcc -arch sm_11 -c -I"/home/glu/NVIDIA_GPU_Computing_SDK/C/common/inc" -I"." -I"./qc" -I"/usr/local/cuda/include" -o cuda_kernel.o cuda_kernel.cu
*/


#ifndef _CUDA_KERNEL_H_
#define _CUDA_KERNEL_H_


#define MAX_QUBITS 25
#define BLOCKDIM 512
#define MAX_TERMS_PER_BLOCK (2*BLOCKDIM)
#define THREAD_MASK (~0ul << 1)


// includes
#include <cutil_inline.h>

#include "gpu.h"    


__constant__ float devOpBit[2][2];


__global__ void qcl1(cuFloatComplex *a, int N, int qbCount, int blockGrpSize, int k)
{
    //int idx = blockIdx.x * BLOCKDIM + threadIdx.x;
    //int tx = threadIdx.x;

    cuFloatComplex t0_0, t0_1, t1_0, t1_1;
    int x0_idx, x1_idx;
    int i, grpSize, b0_idx, b1_idx;

    __shared__ cuFloatComplex aS[MAX_TERMS_PER_BLOCK];
    ...
}



void gpucaller(opBit* op, quBaseState* q) {
    // make an operator copy
    float** myOpBit = (float**)op->getDeviceReadyOpBit();

    unsigned int timer = 0;
    cuFloatComplex *a_d;
    long int N = 1 << q->mapbits();
    int size = sizeof(cuFloatComplex) * N;

    // start timer
    cutilCheckError( cutCreateTimer( &timer));
    cutilCheckError( cutStartTimer( timer));    
    // allocate device memory
    cudaMalloc((void**)&a_d,size);  
    // copy host memory to device
    cudaMemcpy(a_d, q->termsarray, size, cudaMemcpyHostToDevice);
    // copy quantic operator to constant memory
    cutilSafeCall( cudaMemcpyToSymbol(devOpBit, myOpBit, 2*sizeof(float[2]), 0) );
    printf("Cuda errors: %s\n", cudaGetErrorString( cudaGetLastError() ) );    

    // setup execution parameters
    dim3 dimBlock(BLOCKDIM, 1, 1);    
    int n_blocks = N/MAX_TERMS_PER_BLOCK + (N%MAX_TERMS_PER_BLOCK == 0 ? 0:1);
    dim3 dimGrid(n_blocks, 1, 1);
    ...        

    // execute the kernel
    qcl1<<< dimGrid, dimBlock >>>(a_d, N, gates, blockGrpSize, k);
    // check if kernel execution generated and error
    cutilCheckMsg("Kernel execution failed");
    ...
    // copy result from device to host
    cudaMemcpy(q->termsarray, a_d, size, cudaMemcpyDeviceToHost);   
    // stop timer
    cutilCheckError( cutStopTimer( timer));
    //printf( "GPU Processing time: %f (ms)\n", cutGetTimerValue( timer));    
    cutilCheckError( cutDeleteTimer( timer));
    // cleanup memory on device
    cudaFree(a_d);
    cudaThreadExit();
}


#endif // #ifndef _CUDA_KERNEL_H_

и " gpu.h " имеет следующее содержание:

#ifndef _GPU_H_
#define _GPU_H_

#include "qc/operator.h"
#include "qc/qustates.h"

void gpucaller(opBit* op, quBaseState* q);

#endif // #ifndef _GPU_H_

Я не включаю файл .cu в свой файл c ++, я включаю только файл .h (gpu.h - содержит прототип функции вызова в ядре) как в файлы c ++, так и в файлы .cu.

Я компилирую файл .cu с помощью nvcc и связываю полученный файл .o с файлом Makefile моего проекта. Также я не забыл добавить флаг «-lcudart» в Makefile.

Проблема в том, что когда я компилирую свой основной проект, я получаю эту ошибку:

expected primary-expression before ',' token

и ссылается на строку в extern.cc , где я вызываю функцию "gpucaller".

Кто-нибудь знает, как сделать это правильно?

EDIT: я попытался снова скомпилировать, на этот раз удалив аргументы из определения функции gpucaller (и, очевидно, не передавая никакие аргументы в функцию, что неправильно, потому что мне нужно для передачи аргументов). Скомпилировано просто отлично.

Итак, проблема в том, что gpucaller типы аргументов не распознаются, я понятия не имею, почему (я включил заголовки, в которых объявлены типы аргументов, т.е. "qc / operator. h "и" qc / quStates.h "). У кого-нибудь есть решение этого?

Makefile моего проекта:

VERSION=0.6.3

# Directory for Standard .qcl files

QCLDIR = /usr/local/lib/qcl

# Path for qcl binaries

QCLBIN = /usr/local/bin

ARCH = `g++ -dumpmachine || echo bin`

# Comment out if you want to compile for a different target architecture
# To build libqc.a, you will also have to edit qc/Makefile!

#ARCH = i686-linux
#ARCHOPT = -m32 -march=i686

# Debugging and optimization options

#DEBUG = -g -pg -DQCL_DEBUG -DQC_DEBUG
#DEBUG = -g -DQCL_DEBUG -DQC_DEBUG
DEBUG = -O2 -g -DQCL_DEBUG -DQC_DEBUG
#DEBUG = -O2

# Plotting support 
#
# Comment out if you don't have GNU libplotter and X

PLOPT = -DQCL_PLOT
PLLIB = -L/usr/X11/lib -lplotter

# Readline support
#
# Comment out if you don't have GNU readline on your system
# explicit linking against libtermcap or libncurses may be required

RLOPT = -DQCL_USE_READLINE
#RLLIB = -lreadline
RLLIB = -lreadline -lncurses

# Interrupt support
#
# Comment out if your system doesn't support ANSI C signal handling

IRQOPT = -DQCL_IRQ

# Replace with lex and yacc on non-GNU systems (untested)

LEX = flex
YACC = bison 
INSTALL = install

##### You shouldn't have to edit the stuff below #####

DATE = `date +"%y.%m.%d-%H%M"`

QCDIR = qc
QCLIB = $(QCDIR)/libqc.a
QCLINC = lib

#CXX = g++
#CPP = $(CC) -E
CXXFLAGS = -c $(ARCHOPT) -Wall $(DEBUG) $(PLOPT) $(RLOPT) $(IRQOPT) -I$(QCDIR) -DDEF_INCLUDE_PATH="\"$(QCLDIR)\""
LDFLAGS = $(ARCHOPT) -L$(QCDIR) $(DEBUG) $(PLLIB) -lm -lfl -lqc $(RLLIB) -L"/usr/local/cuda/lib" -lcudart

FILESCC = $(wildcard *.cc)
FILESH = $(wildcard *.h)

SOURCE = $(FILESCC) $(FILESH) qcl.lex qcl.y Makefile

OBJECTS = types.o syntax.o typcheck.o symbols.o error.o \
          lex.o yacc.o print.o quheap.o extern.o eval.o exec.o \
          parse.o options.o debug.o cond.o dump.o plot.o format.o cuda_kernel.o

all: do-it-all

ifeq (.depend,$(wildcard .depend))
include .depend
do-it-all: build
else
do-it-all: dep
    $(MAKE)
endif

#### Rules for depend

dep: lex.cc yacc.cc yacc.h $(QCLIB)
    for i in *.cc; do \
      $(CPP) -I$(QCDIR) -MM $$i; \
    done > .depend

lex.cc: qcl.lex yacc.h
    $(LEX) -olex.cc qcl.lex

yacc.cc: qcl.y
    $(YACC) -t -d -o yacc.cc qcl.y

yacc.h: yacc.cc
    mv yacc.*?h yacc.h

$(QCLIB):
    cd $(QCDIR) && $(MAKE) libqc.a

#### Rules for build

build: qcl $(QCLINC)/default.qcl

qcl: $(OBJECTS) qcl.o $(QCLIB)
    $(CXX) $(OBJECTS) qcl.o $(LDFLAGS) -o qcl

$(QCLINC)/default.qcl: extern.cc
    grep "^//!" extern.cc | cut -c5- > $(QCLINC)/default.qcl

checkinst:
    [ -f ./qcl -a -f $(QCLINC)/default.qcl ] || $(MAKE) build

install: checkinst
    $(INSTALL) -m 0755 -d $(QCLBIN) $(QCLDIR)
    $(INSTALL) -m 0755 ./qcl $(QCLBIN)
    $(INSTALL) -m 0644 ./$(QCLINC)/*.qcl $(QCLDIR)

uninstall:
    -rm -f $(QCLBIN)/qcl
    -rm -f $(QCLDIR)/*.qcl
    -rmdir $(QCLDIR)

#### Other Functions

edit:
    nedit $(SOURCE) &

clean:
    rm -f *.o lex.* yacc.* 
    cd $(QCDIR) && $(MAKE) clean

clear: clean
    rm -f qcl $(QCLINC)/default.qcl .depend
    cd $(QCDIR) && $(MAKE) clear

dist-src: dep
    mkdir qcl-$(VERSION)
    cp README CHANGES COPYING .depend $(SOURCE) qcl-$(VERSION) 
    mkdir qcl-$(VERSION)/qc
    cp qc/Makefile qc/*.h qc/*.cc qcl-$(VERSION)/qc
    cp -r lib qcl-$(VERSION)
    tar czf qcl-$(VERSION).tgz --owner=0 --group=0 qcl-$(VERSION)
    rm -r qcl-$(VERSION)

dist-bin: build
    mkdir qcl-$(VERSION)-$(ARCH)
    cp Makefile README CHANGES COPYING qcl qcl-$(VERSION)-$(ARCH) 
    cp -r lib qcl-$(VERSION)-$(ARCH)
    tar czf qcl-$(VERSION)-$(ARCH).tgz --owner=0 --group=0 qcl-$(VERSION)-$(ARCH)
    rm -r qcl-$(VERSION)-$(ARCH)

upload: dist-src
    scp qcl-$(VERSION)*.tgz oemer@tph.tuwien.ac.at:html/tgz

scp: dist-src
    scp qcl-$(VERSION).tgz oemer@tph.tuwien.ac.at:bak/qcl-$(DATE).tgz

Единственное изменение, которое я добавил в исходный Makefile, - это добавление «cuda_kernel.o» в строку OBJECTS и добавление флага «-lcudart» в LDFLAGS.

ОБНОВЛЕНИЕ: Спасибо Гаррисм за помощь мне. Я передавал тип в качестве параметра.

Ответы [ 3 ]

0 голосов
/ 16 июня 2011

Ваш код проблемы в данный момент довольно большой и сложный. Попытайтесь сократить это до более простого случая отказа и обновите свой вопрос, как только у вас есть это. Это облегчит попытку воспроизведения. Удалите код таймера cuda, switch case, замените детали реализации на ..., где это не имеет значения, и т. Д.

Я компилирую с msvc и nvcc, затем связываю с icl; так что, если вы можете сделать простой пример, я могу увидеть, компилируется ли он с совершенно другой настройкой компилятора. Это должно сузить проблему.


Несмотря на то, что переименование собственного заголовка cuda.h в somethingspecific.h не помогло, я не думаю, что будет хорошей идеей оставить его как cuda.h. Это сбивает с толку и потенциальный источник проблем.

0 голосов
/ 17 июня 2011
gpucaller(opBit, q);  

Вы передаете имя типа (opBit) в качестве параметра функции, который не является допустимым C или C ++.Похоже, вам нужно сделать это вместо:

gpucaller(op, q);  
0 голосов
/ 16 июня 2011

Выглядит ли это буквально так в cuda.h?

void gpucaller(type1 param1, type2 param2);

Объявлены ли где-нибудь type1 и type2, чтобы ваш обычный компилятор C ++ знал, что это за типы?Если нет, то вы получите ошибку, как будто говорите, что получаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...