How to run makefile with libssh? - c++

I have a problem with libssh (libssh.org). I need to run a makefile on the remote server. I do it with a command "channel_request_exec":
int SSHExecCmd (void(* MessSender)(char* CurMessage, bool IsError, CWnd* MainWnd),ssh_session session, CString & ShellEcho, char * cmd, CWnd* MainWnd)
{
ssh_channel channel;
int rc;
channel = ssh_channel_new(session);
if (channel == NULL) return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK)
{
ssh_channel_free(channel);
return rc;
}
rc = ssh_channel_request_exec(channel, cmd);
if (rc != SSH_OK)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
char buffer[256];
unsigned int nbytes;
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0)
{
if (fwrite(buffer, 1, nbytes, stdout) != nbytes)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
return SSH_OK;
}
Makefile is located in root:
all: mpi_cuda.o pattern2d.o
mpicc mpi_cuda.o pattern2d.o -o mpi_cuda -lrt -lpthread -L/opt/cuda/lib64 -lcudart -lm
mpi_cuda.o: mpi_cuda.c
mpicc -g -std=c99 -D_GNU_SOURCE -I/opt/cuda/include -c $< -o $#
pattern2d.o: pattern2d.cu
nvcc -g -c $< -o $#
I send a command "make" and receive echo:
mpicc -g -std=c99 -D_GNU_SOURCE -I/opt/cuda/include -c mpi_cuda.c -o mpi_cuda.oda
but nothing happens (compilation is not performed).
If I do make with a putty: everything work. Echo:
make
mpicc -g -std=c99 -D_GNU_SOURCE -I/opt/cuda/include -c mpi_cuda.c -o mpi_cuda.o
mpi_cuda.c: В функции ‘main’:
mpi_cuda.c:148: предупреждение: недостаточно аргументов для указанного формата
nvcc -g -c pattern2d.cu -o pattern2d.o
mpicc mpi_cuda.o pattern2d.o -o mpi_cuda -lrt -lpthread -L/opt/cuda/lib64 -lcudart -lm
How do I solve this?

Not familiar with libssh, but error could be, because environment gets set up differently, so running make through shell explicitly could help.
Try changing the command (make?) to
bash -c make
If that does not work, try
bash -c "export > env.txt ; make > make_out.txt 2> make_err.txt"
Then check if those file appeared, and what they contain, that should give good hints.
If you have a working and a non-working case, then get these files from both cases, and compare them (eg. with diff -u).
And change bash to whatever shell you use (and in that case check if -c is right switch to give command string, and if export is right command to show environment), if you're not using bash.
Based on comments below: Difference in env.txt could be, because some of the environment variables only get set for interactive shells. For example, in my Ubuntu box, start of .bashrc has lines like this:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Now if any of those needed environemnt variables are set in .bashrc after that line, and your ssh connection is non-interactive (without pseudo-tty), these don't get set.
If this is the case, move these env variable sets to ~/.profile, or in ~/.bashrc before such test as above. Also do man bash, and read stuff about initialization files (like that ~/.bashrc).
Other solution would be to make the ssh-session interactive, which I believe is documented at this page for libssh: http://api.libssh.org/master/libssh_tutor_shell.html .

I would suggest to open a non-interactive shell and do it there. See
http://api.libssh.org/master/libssh_tutor_shell.html

Related

Msys2 mingw built libcurl with openssl, but https unsupported

I need to use libcurl with https in my project, so I've built zlib, openssl and libcurl (with mingw32-make mingw32-ssl-zlib) successfully. But after I copied include libcurl.a libcurldll.a libcurl.dll to my project folder, sent a GET request to https://www.google.com it failed with error Unsupported protocol
My OPENSSL_PATH and ZLIB_PATH in my lib/Makefile.m32 src/Makefile.m32 are:
ZLIB_PATH = ../../zlib-1.2.8
OPENSSL_PATH = /c/OpenSSL
and the build log:
Compeador#DESKTOP-QCSNUGN MSYS /e/programming/c/lib/curl-7.74.0
$ mingw32-make mingw32-ssl-zlib
C:/msys64/mingw32/bin/mingw32-make.exe -C lib -f Makefile.m32 CFG=mingw32-ssl-zlib
mingw32-make[1]: Entering directory 'E:/programming/c/lib/curl-7.74.0/lib'
gcc -I. -I../include -I"C:/OpenSSL/include" -I"../../zlib-1.2.8" -g -O2 -Wall -W -fno-strict-aliasing -m32 -DBUILDING_LIBCURL -DUSE_OPENSSL -DHAVE_OPENSSL_PKCS12_H -DOPENSSL_NO_KRB5 -DHAVE_LIBZ -DHAVE_ZLIB_H -c altsvc.c -o altsvc.o
gcc ......
ar cru libcurl.a altsvc.o amigaos.o asyn-ares.o asyn-thread.o base64.o conncache.o connect.o content_encoding.o cookie.o curl_addrinfo.o curl_ctype.o curl_des.o curl_endian.o curl_fnmatch.o curl_get_line.o curl_gethostname.o curl_gssapi.o curl_memrchr.o curl_multibyte.o curl_ntlm_core.o curl_ntlm_wb.o curl_path.o curl_range.o curl_rtmp.o curl_sasl.o curl_sspi.o curl_threads.o dict.o dotdot.o easy.o escape.o file.o fileinfo.o formdata.o ftp.o url.o ftplistparser.o getenv.o getinfo.o gopher.o hash.o hmac.o hostasyn.o hostcheck.o hostip.o hostip4.o hostip6.o hostsyn.o http.o http2.o http_chunks.o http_digest.o http_negotiate.o http_ntlm.o http_proxy.o idn_win32.o if2ip.o imap.o inet_ntop.o inet_pton.o krb5.o ldap.o llist.o md4.o md5.o memdebug.o mime.o mprintf.o mqtt.o multi.o netrc.o non-ascii.o nonblock.o openldap.o parsedate.o pingpong.o pop3.o progress.o psl.o doh.o rand.o rename.o rtsp.o select.o sendf.o setopt.o sha256.o share.o slist.o smb.o smtp.o socketpair.o socks.o socks_gssapi.o socks_sspi.o speedcheck.o splay.o strcase.o strdup.o strerror.o strtok.o strtoofft.o system_win32.o telnet.o tftp.o timeval.o transfer.o urlapi.o version.o warnless.o wildcard.o x509asn1.o dynbuf.o version_win32.o easyoptions.o easygetopt.o hsts.o vauth/cleartext.o vauth/cram.o vauth/digest.o vauth/digest_sspi.o vauth/krb5_gssapi.o vauth/krb5_sspi.o vauth/ntlm.o vauth/ntlm_sspi.o vauth/oauth2.o vauth/spnego_gssapi.o vauth/spnego_sspi.o vauth/vauth.o vtls/bearssl.o vtls/gskit.o vtls/gtls.o vtls/keylog.o vtls/mbedtls.o vtls/mbedtls_threadlock.o vtls/mesalink.o vtls/nss.o vtls/openssl.o vtls/schannel.o vtls/schannel_verify.o vtls/sectransp.o vtls/vtls.o vtls/wolfssl.o vquic/ngtcp2.o vquic/quiche.o vquic/vquic.o vssh/libssh.o vssh/libssh2.o vssh/wolfssh.o
ranlib libcurl.a
strip -g libcurl.a
windres --include-dir=../include -DDEBUGBUILD=0 -O coff -F pe-i386 -i libcurl.rc -o libcurl.res
gcc -s -m32 -shared -o libcurl.dll \
-Wl,--output-def,libcurl.def,--out-implib,libcurldll.a \
altsvc.o amigaos.o asyn-ares.o asyn-thread.o base64.o conncache.o connect.o content_encoding.o cookie.o curl_addrinfo.o curl_ctype.o curl_des.o curl_endian.o curl_fnmatch.o curl_get_line.o curl_gethostname.o curl_gssapi.o curl_memrchr.o curl_multibyte.o curl_ntlm_core.o curl_ntlm_wb.o curl_path.o curl_range.o curl_rtmp.o curl_sasl.o curl_sspi.o curl_threads.o dict.o dotdot.o easy.o escape.o file.o fileinfo.o formdata.o ftp.o url.o ftplistparser.o getenv.o getinfo.o gopher.o hash.o hmac.o hostasyn.o hostcheck.o hostip.o hostip4.o hostip6.o hostsyn.o http.o http2.o http_chunks.o http_digest.o http_negotiate.o http_ntlm.o http_proxy.o idn_win32.o if2ip.o imap.o inet_ntop.o inet_pton.o krb5.o ldap.o llist.o md4.o md5.o memdebug.o mime.o mprintf.o mqtt.o multi.o netrc.o non-ascii.o nonblock.o openldap.o parsedate.o pingpong.o pop3.o progress.o psl.o doh.o rand.o rename.o rtsp.o select.o sendf.o setopt.o sha256.o share.o slist.o smb.o smtp.o socketpair.o socks.o socks_gssapi.o socks_sspi.o speedcheck.o splay.o strcase.o strdup.o strerror.o strtok.o strtoofft.o system_win32.o telnet.o tftp.o timeval.o transfer.o urlapi.o version.o warnless.o wildcard.o x509asn1.o dynbuf.o version_win32.o easyoptions.o easygetopt.o hsts.o vauth/cleartext.o vauth/cram.o vauth/digest.o vauth/digest_sspi.o vauth/krb5_gssapi.o vauth/krb5_sspi.o vauth/ntlm.o vauth/ntlm_sspi.o vauth/oauth2.o vauth/spnego_gssapi.o vauth/spnego_sspi.o vauth/vauth.o vtls/bearssl.o vtls/gskit.o vtls/gtls.o vtls/keylog.o vtls/mbedtls.o vtls/mbedtls_threadlock.o vtls/mesalink.o vtls/nss.o vtls/openssl.o vtls/schannel.o vtls/schannel_verify.o vtls/sectransp.o vtls/vtls.o vtls/wolfssl.o vquic/ngtcp2.o vquic/quiche.o vquic/vquic.o vssh/libssh.o vssh/libssh2.o vssh/wolfssh.o libcurl.res -L"C:/OpenSSL/lib" -lssl -lcrypto -lgdi32 -lcrypt32 -L"../../zlib-1.2.8" -lz -lwldap32 -lws2_32
mingw32-make[1]: Leaving directory 'E:/programming/c/lib/curl-7.74.0/lib'
C:/msys64/mingw32/bin/mingw32-make.exe -C src -f Makefile.m32 CFG=mingw32-ssl-zlib
mingw32-make[1]: Entering directory 'E:/programming/c/lib/curl-7.74.0/src'
windres --include-dir=../include -O coff -DCURL_EMBED_MANIFEST -F pe-i386 -i curl.rc -o curl.res
gcc -I. -I../include -I../lib -I"C:/OpenSSL/include" -I"../../zlib-1.2.8" -g -O2 -Wall -W -fno-strict-aliasing -m32 -DCURL_STATICLIB -DUSE_OPENSSL -DHAVE_LIBZ -DHAVE_ZLIB_H -c slist_wc.c
gcc ......
rm -f curl.exe
gcc -s -m32 -static -o curl.exe curl.res slist_wc.o tool_binmode.o tool_bname.o tool_cb_dbg.o tool_cb_hdr.o tool_cb_prg.o tool_cb_rea.o tool_cb_see.o tool_cb_wrt.o tool_cfgable.o tool_convert.o tool_dirhie.o tool_doswin.o tool_easysrc.o tool_filetime.o tool_formparse.o tool_getparam.o tool_getpass.o tool_help.o tool_helpers.o tool_homedir.o tool_hugehelp.o tool_libinfo.o tool_main.o tool_metalink.o tool_msgs.o tool_operate.o tool_operhlp.o tool_panykey.o tool_paramhlp.o tool_parsecfg.o tool_progress.o tool_strdup.o tool_setopt.o tool_sleep.o tool_urlglob.o tool_util.o tool_vms.o tool_writeout.o tool_writeout_json.o tool_xattr.o strtoofft.o nonblock.o warnless.o curl_ctype.o curl_multibyte.o version_win32.o dynbuf.o -L../lib -lcurl -L"C:/OpenSSL/lib" -lssl -lcrypto -lgdi32 -lcrypt32 -L"../../zlib-1.2.8" -lz -lwldap32 -lws2_32
mingw32-make[1]: Leaving directory 'E:/programming/c/lib/curl-7.74.0/src'
and my code:
#include <iostream>
#include <windows.h>
#include <openssl/ssl.h>
#include <curl/curl.h>
using namespace std;
size_t CurlStrWCallback(char* content, size_t size, size_t nmemb, void *userdata){
auto total = size*nmemb;
((std::string*)userdata)->append((char*)content, total);
return total;
}
int main(){
auto curl = curl_easy_init();
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK){
std::cout << "Fail to init curl\n";
return 0;
}
if(curl){
std::string buffer;
curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlStrWCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
auto res = curl_easy_perform(curl);
if(res != CURLE_OK){
std::cout << "failed to perform request: " << curl_easy_strerror(res) << '\n';
}
else{
std::cout << "Response:\n" << buffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
output: failed to perform request: Unsupported protocol
meanwhlie I also tried to run libcurl/src/curl.exe https://www.google.com -k and it sucessed
Turns out I have to compile all source in the same fashion I use in Linux: ./configure && make && make install
here are the commands I use:
zlib:
./configure
make && make install
openssl:
./configure --prefix=$PWD/dist no-idea no-mdc2 no-rc5 shared mingw (or mingw64 for 64 bits)
make && make install
libcurl:
./configure --prefix=$PWD/dist --with-zlib=PATH_TO_COMPILED_ZLIB --with-ssl=PATH_TO_COMPILED_OPENSSL --host=i686-w64-mingw32 (or x86_64-w64-mingw32 for 64 bits)
make && make install

Can't compile simple SDL program with Dev-C++

Just before you read just know that i'm not english, so hopefully i won't misspell my writing here.
Anyway. I was trying to compile my first SDL program, so i followed online tutorials to install SDL2 libraries. The code (copied from here min 13:00) i used is this :
#include <iostream>
#include <SDL2/SDL.h>
using namespace std;
int main(void){
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "SDL init failed.\n";
return 1;
}
cout << "SDL init succeeded";
SDL_Quit();
return 0;
}
The error i get is this
C:\Users\raffaele.ciotola\Desktop\Marco & Lory\Lorenzo\Dev-Cpp\SDL2-2.0.12\x86_64-w64-mingw32\lib\libSDL2main.a(SDL_windows_main.o) In function `main_getcmdline':
71 s:\rs\valve\release\SDL\SDL2-2.0.12-source\src\main\windows\SDL_windows_main.c undefined reference to `SDL_main'
C:\Users\raffaele.ciotola\Desktop\Marco & Lory\Lorenzo\Dev-Cpp\Programs\SDL_\collect2.exe [Error] ld returned 1 exit status
25 C:\Users\raffaele.ciotola\Desktop\Marco & Lory\Lorenzo\Dev-Cpp\Programs\SDL_\Makefile.win recipe for target 'SDL_.exe' failed
I tried running my Dev-Cpp.exe on administrator, since the installation folder is on the desktop, but that didn't solve the problem.
The Makefile (Whatevere it is, i don't have the minimal idea) is this. If needed ¯_(ツ)_/¯.
# Project: Progetto3
# Makefile created by Dev-C++ 5.11
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
OBJ = SDL_.o
LINKOBJ = SDL_.o
LIBS = -L"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/lib" -L"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -L"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/SDL2-2.0.12/x86_64-w64-mingw32/lib" -static-libgcc -mwindows -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lglu32
INCS = -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/include" -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include"
CXXINCS = -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/include" -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" -I"C:/Users/raffaele.ciotola/Desktop/Marco & Lory/Lorenzo/Dev-Cpp/SDL2-2.0.12/x86_64-w64-mingw32/include"
BIN = SDL_.exe
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
SDL_.o: SDL_.cpp
$(CPP) -c SDL_.cpp -o SDL_.o $(CXXFLAGS)
If you need any other info just ask. Thank You.
SDL hijacks the main function with its own in order to do some initial setup. It then calls whatever you have written as the main function. Because it is calling your main function it expects it to be defined in a specific way.
Try this and it should resolve the errors you are encountering:
int main(int argc, char* args[])
{
// whatever
return 0;
}

How to wait for t32rem DO script to complete?

It seems that doing t32rem localhost DO script.cmm is non-blocking. How can I block in a shell script until the cmm script is done?
Here is an abbreviated example:
$ time t32rem localhost wait 5s
real 0m5.048s
$ cat wait-5s.cmm
WAIT 5s
ENDDO
$ time t32rem localhost do wait-5s
real 0m0.225s
I can try to do some sort of t32rem localhost wait STATE.RUN() based on whatever the exact script is doing but this is not a very good solution.
Reading through api_remote.pdf it does note that T32_Cmd for DO is non-blocking and recommends polling using T32_GetPractice but it's not clear how to translate this to t32rem.
In my opinion you questions is a rather good one.
First the bummer: t32rem is not suitable to wait for the execution of a script. In fact t32rem cancels any running script before executing a command with T32_Stop(). (You can find the source code of t32rem in your TRACE32 installation at "C:\T32\demo\api\capi\test\t32rem.c")
So your suggestion to use t32rem localhost wait STATE.RUN() will definitely not work because it would cancel the running script. Furthermore STATE.RUN()returns the running state of the debugged CPU and not of the PRACTICE interpreter.
So in fact you have to use T32_GetPractice() to wait for the PRACTICE script to terminate. To use T32_GetPractice() you either have to link statically or dynamically the "API for Remote Control and JTAG Access in C" to an application that launches your script.
For dynamic linking (e.g. from a Python script) load "C:\T32\demo\api\capi\dll\t32api.dll". (Depending on your host operation system you might need t32api64.dll, t32api.so, or t32api64.so instead.)
For static linking (e.g. from a binary application written in C) add the files from "C:\T32\demo\api\capi\src" to your project.
And here is the code to write a command line application t32do, which starts a PRACTICE script and waits until the script terminates:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "t32.h"
int main(int argc, char *argv[])
{
int pstate;
const char *script;
if (argc == 4 && !strncmp(argv[2],"port=", 5)) {
if ( T32_Config( "PORT=", argv[2]+5 ) == -1 ) {
printf("Port number %s not accepted\n", argv[2] );
exit(2);
}
script = argv[3];
} else {
if (argc != 3) {
printf( "Usage: t32do <host> [port=<n>] <script>\n" );
exit(2);
}
script = argv[2];
}
if ( T32_Config( "NODE=", argv[1] ) == -1 ) {
printf( "Hostname %s not accepted\n", argv[1] );
exit(2);
}
if ( T32_Init() != 0 || T32_Attach(1) != 0){
printf( "Failed to connect to TRACE32\n" );
exit(2);
}
if ( T32_Cmd_f("DO \"%s\"", script) != 0 ){ // Launch PRACTICE script
printf( "Failed to start PRACTICE script\n" );
T32_Exit();
exit(1);
}
while (T32_GetPracticeState(&pstate) == 0 && pstate != 0){ // Wait until PRACTICE script terminates
usleep(10000);
}
T32_Exit();
return 0;
}
Put the source in a file named t32do.c in "C:\T32\demo\api\capi\src" and build the application with the following makefile, which works on both Windows (by using the MinGW compiler of Cygwin) and Linux:
BIN := t32do
OBJ := t32do.o hremote.o hlinknet.o
OS := $(shell uname -s)
ifneq ($(findstring CYGWIN,$(OS)),)
CC := x86_64-w64-mingw32-gcc
LOPT := -lws2_32
COPT := -DT32HOST_LE
endif
ifneq ($(findstring Linux,$(OS)),)
CC := gcc
COPT := -DT32HOST_LE
endif
all: $(BIN)
$(BIN): $(OBJ)
$(CC) $^ -s -o $# $(LOPT)
%.o: %.c t32.h
$(CC) -c $(COPT) -o $# $<
clean:
-rm $(OBJ) $(BIN)
If it compiles and links fine, you'll get an application t32do.exe.
Use it in the form: t32do <host> [port=<n>] <practice script>
My example code above is licensed under Creative Commons Zero 1.0. Use it any way you wish, in any code you want.

error: 'CFLAGS' does not name a type

This is my makefile:
CFLAGS=-Wall -g -O2
clean:
rm -f ex1
And when I run a script, for example, this one (ex3.c):
#include <stdio.h>
int main()
{
int age = 10;
int height = 72;
printf("I am %d years old.\n", age);
printf("I am %d inches tall.\n", height);
return 0;
}
I get the following error:
$ g++ Makefile.c -o makefile
Makefile.c:1:1: error: 'CFLAGS' does not name a type
CFLAGS=-Wall -g
^g++ ex3.c -o ex3
$
Please don't compile the makefile.
Use the make utility instead.
Synonyms include nmake and gmake.
The makefile should be passed to the make program or build utility.

Include cuda kernel in my project

I have this c++ project in which I call a cuda kernel by means of a wrapper function.
My c++ file looks like this (this is 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;
}
where "gpucaller" is my wrapper function that calls the kernel, both defined in 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_
and "gpu.h" has the following content:
#ifndef _GPU_H_
#define _GPU_H_
#include "qc/operator.h"
#include "qc/qustates.h"
void gpucaller(opBit* op, quBaseState* q);
#endif // #ifndef _GPU_H_
I don't include the .cu file in my c++ file, I only include the .h file (gpu.h - contains the prototype of my kernel caller function) in both the c++ and the .cu files.
I compile the .cu file with nvcc, and link the resulting .o file in my project's Makefile.
Also, I didn't forget to add the "-lcudart" flag to the Makefile.
The problem is that when I compile my main project, I get this error:
expected primary-expression before ',' token
and is referring to the line in extern.cc where I call the "gpucaller" function.
Does anyone know how to get this right?
EDIT: I've tried compiling again, this time removing the arguments from the gpucaller's function definition (and obviously not passing any arguments to the function, which is wrong because I need to pass arguments). It compiled just fine.
So the problem is that gpucaller's argument types aren't recognized, I have no idea why (I've included the headers where the arguments' types are declared, ie "qc/operator.h" and "qc/quStates.h"). Does anyone have a solution to this?
My project's Makefile is this:
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
The only changes that I've added to the original Makefile is adding "cuda_kernel.o" to the OBJECTS' line, and adding the "-lcudart" flag to LDFLAGS.
UPDATE: Thanks harrism for helping me out. I was passing a type as a parameter.
gpucaller(opBit, q);
You are passing a type name (opBit) as a function parameter, which is not valid C or C++. It looks like you need to do this instead:
gpucaller(op, q);
Does it literally look like this in cuda.h?
void gpucaller(type1 param1, type2 param2);
Are type1 and type2 declared anywhere so that your regular C++ compiler know what these types are? If not, then you'd get an error like you're saying you're getting.
Your problem code is pretty big and complex at the moment. Try to strip it down to a more simple failure case and update your question once you have that. It'll make it easier to attempt reproduction. Strip out the cuda timer code, the switch case, replace implementation details with ... where it doesn't matter, etc.
I compile with msvc and nvcc then link with icl; so if you can make a simple example I can see if it compiles with a totally different compiler setup. That should narrow down the problem.
Even though renaming your own header cuda.h to somethingspecific.h didn't help, I don't think it's a good idea to leave it as cuda.h. It's confusing and a potential source of problems.