EDIT: Check the UPDATE at the bottom please.
Hi guys,
Please shed some light into a problem that I’m struggling for a couple of days now.
I receive this error when I compile my project: expected primary-expression before ‘,’ token, on the line pointed below (it seems to not know the argument types?!).
#include "operator.h"
#include "qustate.h"
#include "gpu.h"
#define ROUTINE(n) int n(const sRoutDef *def,const SymTable *loc,int inv)
#define EXTERR(s) throw tError(errEXT,s)
#define PAR_QUSTATE(v,s) quState* v; { GETVAL(s); if(!value->isQuExpr()) EXTERR("quantum expression expected"); v=value->qustate(); }
ROUTINE(ext_bit) {
int i;
quState *qbit;
PAR_QUSTATE(q,"q");
opBit *op;
...
// The next line raises the error
gpucaller(opBit, q); // expected primary-expression before ',' token
//gpucaller(1, 3);
qcl_delete(op);
return 0;
}
where opBit and quState are classes defined in “qc/operator.h” and in “qc/qustate.h”, and gpu.h has the following content:
#ifndef _GPU_H_
#define _GPU_H_
#include "operator.h"
#include "qustates.h"
void gpucaller(opBit* op, quBaseState* q);
//void gpucaller(int a, int b);
#endif // #ifndef _GPU_H_
My .cu file includes gpu.h and is compiled with nvcc as commented below:
/*
compile with:
nvcc -arch sm_11 -c -I"/home/[user_name]/NVIDIA_GPU_Computing_SDK/C/common/inc" -I"qc" -I"/usr/local/cuda/include" -o cuda_kernel.o cuda_kernel.cu
*/
#ifndef _CUDA_KERNEL_H_
#define _CUDA_KERNEL_H_
// includes
#include <cutil_inline.h>
#include "gpu.h"
__constant__ float devOpBit[2][2];
// kernel function
__global__ void qcl1(cuFloatComplex *a, int N, int qbCount, int blockGrpSize, int k)
{
...
}
void gpucaller(opBit* op, quBaseState* q) {
float** myOpBit = (float**)op->getDeviceReadyOpBit();
...
// execute the kernel
qcl1<<< dimGrid, dimBlock >>>(a_d, N, gates, blockGrpSize, k);
...
}
/*
void gpucaller(int a, int b) {
int c = a+b;
return;
}
*/
#endif // #ifndef _CUDA_KERNEL_H_
So I generate my .o file and add it in my project’s Makefile, also adding the -lcudart flag to the compiler:
# Makefile for QCL
VERSION=0.6.3
# Directory for Standard .qcl files
QCLDIR = /usr/local/lib/qcl
# Directory for CUDA libraries
CUDALIB = /usr/local/cuda/lib
# 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$(CUDALIB) -lcudart
FILESCC = $(wildcard *.cc)
FILESH = $(wildcard *.h)
SOURCE = $(FILESCC) $(FILESH) qcl.lex qcl.y Makefile
OBJECTS = cuda_kernel.o 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
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
If I change the gpucaller's function definition to
void gpucaller(int a, int b);
it compiles just fine.
Any help will be appreciated.
UPDATE: I found the answer, I was passing a type as a parameter. Now I get the following error while compiling my project with g++:
tmpxft_00001aba_0000000000-1_cuda_kernel.cudafe1.cpp:(.text+0xe): undefined reference to `opBit::getDeviceReadyOpBit()'
while this method (getDeviceReadyOpBit) is defined in “qc/operator.h” and have included the header.