I'm trying to emulate baremetal Microblaze code using QEMU but don't get any output from the "print" function. The microblaze is produced from a xilinx project, this produces a .dts file which is used to make a .dtb for use with QEMU. I'm using Xilinx's fork of QEMU
I run QEMU with the following command
~/.local/bin/qemu-system-microblazeel -M microblaze-fdt -dtb system-top.dtb -m 256 -serial mon:stdio -display none -kernel ./workspace/app_0/Debug/app_0.elf -s -S -nographic
I can connect with gdb, and step through the code, it clearly writes to address 0x40600004 which is the UART TX data FIFO, but still nothing is seen at the QEMU terminal. I even added some debug inside the QEMU xilinx UART model, it was registered but never called when the code ran.
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
int main()
{
init_platform();
print("Hello World\n\r");
cleanup_platform();
return 0;
}
This is the UART node from the .dts file
top_axi_uartlite_0: serial#40600000 {
clock-frequency = <294999169>;
clocks = <&clk_bus_0>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <115200>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&top_axi_intc_0>;
interrupts = <1 0>;
port-number = <0>;
reg = <0x40600000 0x10000>;
xlnx,baudrate = <0x1c200>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "294.999169";
xlnx,use-parity = <0x0>;
};
QEMU monitor shows the following memory space
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): memory#0
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-000000000fffffff (prio 0, ram): memory#0
Related
I am in cuda-gdb, I can use ((#global float *)array)[0]
but how to use constant memory in gdb ?
I try ((#parameter float *)const_array)
I declared const_array like this :
__constant__ float const_array[1 << 14]
I tried with 1 << 5, and it's the same problem.
I don't seem to have any trouble with it. In order to print device memory, you must be stopped at a breakpoint in device code.
Example:
$ cat t1973.cu
const int cs = 1 << 14;
__constant__ int cdata[cs];
__global__ void k(int *gdata){
gdata[0] = cdata[0];
}
int main(){
int *hdata = new int[cs];
for (int i = 0; i < cs; i++) hdata[i] = i+1;
cudaMemcpyToSymbol(cdata, hdata, cs*sizeof(cdata[0]));
int *gdata;
cudaMalloc(&gdata, sizeof(gdata[0]));
cudaMemset(gdata, 0, sizeof(gdata[0]));
k<<<1,1>>>(gdata);
cudaDeviceSynchronize();
}
$ nvcc -o t1973 t1973.cu -g -G -arch=sm_70
$ cuda-gdb ./t1973
sh: python3: command not found
Unable to determine python3 interpreter version. Python integration disabled.
NVIDIA (R) CUDA Debugger
11.4 release
Portions Copyright (C) 2007-2021 NVIDIA Corporation
GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./t1973...
(cuda-gdb) b 5
Breakpoint 1 at 0x403b0c: file t1973.cu, line 6.
(cuda-gdb) run
Starting program: /home/user2/misc/t1973
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[Detaching after fork from child process 22872]
[New Thread 0x7fffef475700 (LWP 22879)]
[New Thread 0x7fffeec74700 (LWP 22880)]
[Switching focus to CUDA kernel 0, grid 1, block (0,0,0), thread (0,0,0), device 0, sm 0, warp 0, lane 0]
Thread 1 "t1973" hit Breakpoint 1, k<<<(1,1,1),(1,1,1)>>> (
gdata=0x7fffcdc00000) at t1973.cu:5
5 gdata[0] = cdata[0];
(cuda-gdb) print gdata[0]
$1 = 0
(cuda-gdb) print cdata[0]
$2 = 1
(cuda-gdb) s
6 }
(cuda-gdb) print gdata[0]
$3 = 1
(cuda-gdb) print cdata[0]
$4 = 1
(cuda-gdb) print cdata[1]
$5 = 2
(cuda-gdb)
Try putting you __constant__ into .cuh, then use as a classic C global variable.
I have recently installed Cuda on my arch-Linux machine through the system's package manager, and I have been trying to test whether or not it is working by running a simple vector addition program.
I simply copy-paste the code from this tutorial (Both the one using one and more kernels) into a file titled cuda_test.cu and run
> nvcc cuda_test.cu -o cuda_test
In either case, the program can run, and I get no errors (both as in the program doesn't crash and the output is that there were no errors). But when I try to run the Cuda profiler on the program:
> sudo nvprof ./cuda_test
I get result:
==3201== NVPROF is profiling process 3201, command: ./cuda_test
Max error: 0
==3201== Profiling application: ./cuda_test
==3201== Profiling result:
No kernels were profiled.
No API activities were profiled.
==3201== Warning: Some profiling data are not recorded. Make sure cudaProfilerStop() or cuProfilerStop() is called before application exit to flush profile data.
The latter warning is not my main problem or the topic of my question, my problem is the message saying that No Kernels were profiled and no API activities were profiled.
Does this mean that the program was run entirely on my CPU? or is it an error in nvprof?
I have found a discussion about the same error here, but there the answer was that the wrong version of Cuda was installed, and in my case, the version installed is the latest version installed through the systems package manager (Version 10.1.243-1)
Is there any way I can get either nvprof to display the expected output?
Edit
Trying to adhere to the warning at the end does not solve the problem:
Adding call to cudaProfilerStop() (or cuProfilerStop()), and also adding cudaDeviceReset(); at end as suggested and linking the appropriate library (cuda_profiler_api.h or cudaProfiler.h) and compiling with
> nvcc cuda_test.cu -o cuda_test -lcuda
Yields a program which can still run, but which, when uppon which nvprof is run, returns:
==12558== NVPROF is profiling process 12558, command: ./cuda_test
Max error: 0
==12558== Profiling application: ./cuda_test
==12558== Profiling result:
No kernels were profiled.
No API activities were profiled.
==12558== Warning: Some profiling data are not recorded. Make sure cudaProfilerStop() or cuProfilerStop() is called before application exit to flush profile data.
======== Error: Application received signal 139
This has not solved the original problem, and has in fact created a new error; the same happens when cudaProfilerStop() is used on its own or alongside cuProfilerStop() and cudaDeviceReset();
The code
The code is, as mentioned copied from a tutorial to test if Cuda is working, though I also have included calls to cudaProfilerStop() and cudaDeviceReset(); for clarity, it is here included:
#include <iostream>
#include <math.h>
#include <cuda_profiler_api.h>
// Kernel function to add the elements of two arrays
__global__
void add(int n, float *x, float *y)
{
int index = threadIdx.x;
int stride = blockDim.x;
for (int i = index; i < n; i += stride)
y[i] = x[i] + y[i];
}
int main(void)
{
int N = 1<<20;
float *x, *y;
cudaProfilerStart();
// Allocate Unified Memory – accessible from CPU or GPU
cudaMallocManaged(&x, N*sizeof(float));
cudaMallocManaged(&y, N*sizeof(float));
// initialize x and y arrays on the host
for (int i = 0; i < N; i++) {
x[i] = 1.0f;
y[i] = 2.0f;
}
// Run kernel on 1M elements on the GPU
add<<<1, 1>>>(N, x, y);
// Wait for GPU to finish before accessing on host
cudaDeviceSynchronize();
// Check for errors (all values should be 3.0f)
float maxError = 0.0f;
for (int i = 0; i < N; i++)
maxError = fmax(maxError, fabs(y[i]-3.0f));
std::cout << "Max error: " << maxError << std::endl;
// Free memory
cudaFree(x);
cudaFree(y);
cudaDeviceReset();
cudaProfilerStop();
return 0;
}
This problem was apparently somewhat well known, after some searching I found this thread about the error-code in the edited version; the solution as discussed there is to call nvprof with the flag --unified-memory-profiling off:
> sudo nvprof --unified-memory-profiling off ./cuda_test
This makes nvprof work as expected-- even without the call to cudaProfileStop.
You can solve the problem by using
sudo nvprof --unified-memory-profiling per-process-device <your program>
I'm using CMake as a build system for my code, which involves CUDA. I was thinking of automating the task of deciding which compute_XX and arch_XX I need to to pass to my nvcc in order to compile for the GPU(s) on my current machine.
Is there a way to do this:
With the NVIDIA GPU deployment kit?
Without the NVIDIA GPU deployment kit?
Does CMake's FindCUDA help you in determining the values for these switches?
My strategy has been to compile and run a bash script that probes the card and returns the gencode for cmake. Inspiration came from University of Chicago's SLURM. To handle errors or multiple gpus or other circumstances, modify as necessary.
In your project folder create a file cudaComputeVersion.bash and ensure it is executable from the shell. Into this file put:
#!/bin/bash
# create a 'here document' that is code we compile and use to probe the card
cat << EOF > /tmp/cudaComputeVersion.cu
#include <stdio.h>
int main()
{
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop,0);
int v = prop.major * 10 + prop.minor;
printf("-gencode arch=compute_%d,code=sm_%d\n",v,v);
}
EOF
# probe the card and cleanup
/usr/local/cuda/bin/nvcc /tmp/cudaComputeVersion.cu -o /tmp/cudaComputeVersion
/tmp/cudaComputeVersion
rm /tmp/cudaComputeVersion.cu
rm /tmp/cudaComputeVersion
And in your CMakeLists.txt put:
# at cmake-build-time, probe the card and set a cmake variable
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cudaComputeVersion.bash OUTPUT_VARIABLE GENCODE)
# at project-compile-time, include the gencode into the compile options
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; "${GENCODE}")
# this makes CMake all chatty and allows you to see that GENCODE was set correctly
set(CMAKE_VERBOSE_MAKEFILE TRUE)
cheers
You can use the cuda_select_nvcc_arch_flags() macro in the FindCUDA module for this without any additional scripts when using CMake 3.7 or newer.
include(FindCUDA)
set(CUDA_ARCH_LIST Auto CACHE STRING
"List of CUDA architectures (e.g. Pascal, Volta, etc) or \
compute capability versions (6.1, 7.0, etc) to generate code for. \
Set to Auto for automatic detection (default)."
)
cuda_select_nvcc_arch_flags(CUDA_ARCH_FLAGS ${CUDA_ARCH_LIST})
list(APPEND CUDA_NVCC_FLAGS ${CUDA_ARCH_FLAGS})
The above sets CUDA_ARCH_FLAGS to -gencode arch=compute_61,code=sm_61 on my machine, for example.
The CUDA_ARCH_LIST cache variable can be configured by the user to generate code for specific compute capabilites instead of automatic detection.
Note: the FindCUDA module has been deprecated since CMake 3.10. However, no equivalent alternative to the cuda_select_nvcc_arch_flags() macro appears to be provided yet in the latest CMake release (v3.14). See this relevant issue at the CMake issue tracker for further details.
A slight improvement over #orthopteroid's answer, which pretty much ensures a unique temporary file is generated, and only requires one instead of two temporary files.
The following goes into scripts/get_cuda_sm.sh:
#!/bin/bash
#
# Prints the compute capability of the first CUDA device installed
# on the system, or alternatively the device whose index is the
# first command-line argument
device_index=${1:-0}
timestamp=$(date +%s.%N)
gcc_binary=$(which g++)
gcc_binary=${gcc_binary:-g++}
cuda_root=${CUDA_DIR:-/usr/local/cuda}
CUDA_INCLUDE_DIRS=${CUDA_INCLUDE_DIRS:-${cuda_root}/include}
CUDA_CUDART_LIBRARY=${CUDA_CUDART_LIBRARY:-${cuda_root}/lib64/libcudart.so}
generated_binary="/tmp/cuda-compute-version-helper-$$-$timestamp"
# create a 'here document' that is code we compile and use to probe the card
source_code="$(cat << EOF
#include <stdio.h>
#include <cuda_runtime_api.h>
int main()
{
cudaDeviceProp prop;
cudaError_t status;
int device_count;
status = cudaGetDeviceCount(&device_count);
if (status != cudaSuccess) {
fprintf(stderr,"cudaGetDeviceCount() failed: %s\n", cudaGetErrorString(status));
return -1;
}
if (${device_index} >= device_count) {
fprintf(stderr, "Specified device index %d exceeds the maximum (the device count on this system is %d)\n", ${device_index}, device_count);
return -1;
}
status = cudaGetDeviceProperties(&prop, ${device_index});
if (status != cudaSuccess) {
fprintf(stderr,"cudaGetDeviceProperties() for device ${device_index} failed: %s\n", cudaGetErrorString(status));
return -1;
}
int v = prop.major * 10 + prop.minor;
printf("%d\\n", v);
}
EOF
)"
echo "$source_code" | $gcc_binary -x c++ -I"$CUDA_INCLUDE_DIRS" -o "$generated_binary" - -x none "$CUDA_CUDART_LIBRARY"
# probe the card and cleanup
$generated_binary
rm $generated_binary
and the following goes into CMakeLists.txt or a CMake module:
if (NOT CUDA_TARGET_COMPUTE_CAPABILITY)
if("$ENV{CUDA_SM}" STREQUAL "")
set(ENV{CUDA_INCLUDE_DIRS} "${CUDA_INCLUDE_DIRS}")
set(ENV{CUDA_CUDART_LIBRARY} "${CUDA_CUDART_LIBRARY}")
set(ENV{CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER}")
execute_process(COMMAND
bash -c "${CMAKE_CURRENT_SOURCE_DIR}/scripts/get_cuda_sm.sh"
OUTPUT_VARIABLE CUDA_TARGET_COMPUTE_CAPABILITY_)
else()
set(CUDA_TARGET_COMPUTE_CAPABILITY_ $ENV{CUDA_SM})
endif()
set(CUDA_TARGET_COMPUTE_CAPABILITY "${CUDA_TARGET_COMPUTE_CAPABILITY_}"
CACHE STRING "CUDA compute capability of the (first) CUDA device on \
the system, in XY format (like the X.Y format but no dot); see table \
of features and capabilities by capability X.Y value at \
https://en.wikipedia.org/wiki/CUDA#Version_features_and_specifications")
execute_process(COMMAND
bash -c "echo -n $(echo ${CUDA_TARGET_COMPUTE_CAPABILITY})"
OUTPUT_VARIABLE CUDA_TARGET_COMPUTE_CAPABILITY)
execute_process(COMMAND
bash -c "echo ${CUDA_TARGET_COMPUTE_CAPABILITY} | sed 's/^\\([0-9]\\)\\([0-9]\\)/\\1.\\2/;' | xargs echo -n"
OUTPUT_VARIABLE FORMATTED_COMPUTE_CAPABILITY)
message(STATUS
"CUDA device-side code will assume compute capability \
${FORMATTED_COMPUTE_CAPABILITY}")
endif()
set(CUDA_GENCODE
"arch=compute_${CUDA_TARGET_COMPUTE_CAPABILITY}, code=compute_${CUDA_TARGET_COMPUTE_CAPABILITY}")
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -gencode ${CUDA_GENCODE} )
I am trying to get CUDA code to work with Qt on Ubuntu 12.04
My cuda_interface.cu
// CUDA-C includes
#include <cuda.h>
extern "C"
void runCudaPart();
// Main cuda function
void runCudaPart() {
// all your cuda code here *smile*
}
My main.cpp
#include
extern "C"
void runCudaPart();
int main(int argc, char *argv[])
{
runCudaPart();
}
My .pro file
#-------------------------------------------------
#
# Project created by QtCreator 2013-04-17T10:50:37
#
#-------------------------------------------------
QT += core
QT -= gui
TARGET = QtCuda
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
# This makes the .cu files appear in your project
OTHER_FILES += ./cuda_interface.cu
# CUDA settings <-- may change depending on your system
CUDA_SOURCES += ./cuda_interface.cu
CUDA_SDK = "/usr/local/cuda-5.0/" # Path to cuda SDK install
CUDA_DIR = "/usr/local/cuda-5.0/" # Path to cuda toolkit install
SYSTEM_NAME = unix # Depending on your system either 'Win32', 'x64', or 'Win64'
SYSTEM_TYPE = 32 # '32' or '64', depending on your system
CUDA_ARCH = sm_21 # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
NVCC_OPTIONS = --use_fast_math
# include paths
INCLUDEPATH += $$CUDA_DIR/include
# library directories
QMAKE_LIBDIR += $$CUDA_DIR/lib/
CUDA_OBJECTS_DIR = ./
# The following library conflicts with something in Cuda
#QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
#QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:msvcrtd.lib
# Add the necessary libraries
CUDA_LIBS = libcuda libcudart
# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
NVCC_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
LIBS += $$join(CUDA_LIBS,'.so ', '', '.so')
# Configuration of the Cuda compiler
CONFIG(debug, debug|release) {
# Debug mode
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
cuda_d.commands = $$CUDA_DIR/bin/nvcc -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
}
else {
# Release mode
cuda.input = CUDA_SOURCES
cuda.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
cuda.commands = $$CUDA_DIR/bin/nvcc $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda
}
I am trying to adopt this .pro file from Compiling Cuda code in Qt Creator on Windows
Which is a similar question but seeks a solution for windows.
At the moment the compiler shows the following errors :
make: Entering directory `/home/swaroop/Work/ai-junkies/cuda/uc_davis/opencv2.x/QtCuda'
g++ -Wl,-O1 -o QtCuda cuda_interface_cuda.o main.o -L/usr/local/cuda-5.0//lib/ -L/usr/lib/i386-linux-gnu libcuda.so libcudart.so -lQtCore -lpthread
g++: error: libcuda.so: No such file or directory
g++: error: libcudart.so: No such file or directory
make: *** [QtCuda] Error 1
Please help me fix these problems.
I can finally run CUDA code with Qt Creator on Ubuntu 12.04. I assume that you can run cuda independently on your system. Here is an excellent quide to setup cuda on ubuntu 12.04
http://sn0v.wordpress.com/2012/05/11/installing-cuda-on-ubuntu-12-04/
I started off an a Qt console application from Qt-Creator.
Here is my main.cpp
#include <QtCore/QCoreApplication>
extern "C"
void runCudaPart();
int main(int argc, char *argv[])
{
runCudaPart();
}
Here is cuda_interface.cu
// CUDA-C includes
#include <cuda.h>
#include <cuda_runtime.h>
#include <stdio.h>
extern "C"
//Adds two arrays
void runCudaPart();
__global__ void addAry( int * ary1, int * ary2 )
{
int indx = threadIdx.x;
ary1[ indx ] += ary2[ indx ];
}
// Main cuda function
void runCudaPart() {
int ary1[32];
int ary2[32];
int res[32];
for( int i=0 ; i<32 ; i++ )
{
ary1[i] = i;
ary2[i] = 2*i;
res[i]=0;
}
int * d_ary1, *d_ary2;
cudaMalloc((void**)&d_ary1, 32*sizeof(int));
cudaMalloc((void**)&d_ary2, 32*sizeof(int));
cudaMemcpy((void*)d_ary1, (void*)ary1, 32*sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy((void*)d_ary2, (void*)ary2, 32*sizeof(int), cudaMemcpyHostToDevice);
addAry<<<1,32>>>(d_ary1,d_ary2);
cudaMemcpy((void*)res, (void*)d_ary1, 32*sizeof(int), cudaMemcpyDeviceToHost);
for( int i=0 ; i<32 ; i++ )
printf( "result[%d] = %d\n", i, res[i]);
cudaFree(d_ary1);
cudaFree(d_ary2);
}
Here is my .pro file.
#-------------------------------------------------
#
# Project created by QtCreator 2013-04-17T16:30:33
#
#-------------------------------------------------
QT += core
QT -= gui
TARGET = QtCuda
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
# This makes the .cu files appear in your project
OTHER_FILES += ./cuda_interface.cu
# CUDA settings <-- may change depending on your system
CUDA_SOURCES += ./cuda_interface.cu
CUDA_SDK = "/usr/local/cuda-5.0/" # Path to cuda SDK install
CUDA_DIR = "/usr/local/cuda-5.0/" # Path to cuda toolkit install
# DO NOT EDIT BEYOND THIS UNLESS YOU KNOW WHAT YOU ARE DOING....
SYSTEM_NAME = unix # Depending on your system either 'Win32', 'x64', or 'Win64'
SYSTEM_TYPE = 32 # '32' or '64', depending on your system
CUDA_ARCH = sm_21 # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
NVCC_OPTIONS = --use_fast_math
# include paths
INCLUDEPATH += $$CUDA_DIR/include
# library directories
QMAKE_LIBDIR += $$CUDA_DIR/lib/
CUDA_OBJECTS_DIR = ./
# Add the necessary libraries
CUDA_LIBS = -lcuda -lcudart
# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
#LIBS += $$join(CUDA_LIBS,'.so ', '', '.so')
LIBS += $$CUDA_LIBS
# Configuration of the Cuda compiler
CONFIG(debug, debug|release) {
# Debug mode
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
cuda_d.commands = $$CUDA_DIR/bin/nvcc -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
}
else {
# Release mode
cuda.input = CUDA_SOURCES
cuda.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
cuda.commands = $$CUDA_DIR/bin/nvcc $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda
}
libcuda.so and libcudart.so are missing the -l flag in front of them in the g++ call. You have an appropriate join command to add them for the NVCC, so use the same logic for g++:
CUDA_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
LIBS += $$join(CUDA_LIBS,'.so ', '', '.so')
Or just change to this:
CUDA_LIBS = -llibcuda -llibcudart
And get rid of the NVCC_LIBS variable.
I can't comment in the mkuse's answer but I wanted to add that...
I had to add -L/usr/local/cuda-6.5/lib64 to the CUDA_LIBS:
# Add the necessary libraries
CUDA_LIBS = -lcuda -lcudart -L/usr/local/cuda-6.5/lib64
Otherwise I get the error "cannot find -lcudart", even when I can run cuda independently. Just in case.
EDIT: I realized that this is not necessary, I just had to check the path for QMAKE_LIBDIR since I have a 64 bit system.
We have a C code as below. This is how we have compiled it gcc -o get1Receive $(mysql_config --cflags) get1ReceiveSource.c $(mysql_config --libs) -lrt. I works fine when we run from the terminal. Then we tried to run it using cron job and when we review this two line printf("\nNumf of fields : %d",num_fields); and printf("\nNof of row : %lu",mysql_num_rows(localRes1));. The first line shows 4 as the value and second line never give any values and is always 0. We have took the same select query and run on the db and confirm there is value but it is just not delivering when running via cron job.The script is given executable permission too.
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <mysql.h>
#include <string.h>
int flag = 0;
int main () {
MYSQL *localConn;
MYSQL_RES *localRes1;
MYSQL_ROW localRow1;
char *server = "localhost";
char *user = "user1";
char *password = "*****";
char *database = "test1";
localConn = mysql_init(NULL);
if (!mysql_real_connect(localConn, server,
user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(localConn));
exit(1);
}
struct timeval tv;
char queryBuf1[500],queryBuf2[500];
char buff1[20] = {0};
char buff2[20] = {0};
gettimeofday (&tv, NULL);
//fprintf (stderr, "[%d.%06d] Flag set to 1 on ", tv.tv_sec, tv.tv_usec);
//tv.tv_sec -= 5;
strftime(buff1, 20, "%Y-%m-%d %H:%M:00", localtime(&tv.tv_sec));
strftime(buff2, 20, "%Y-%m-%d %H:%M:59", localtime(&tv.tv_sec));
printf("\nTime from %s", buff1);
printf("\nTime to %s", buff2);
sprintf(queryBuf1,"SELECT ipDest, macDest,portDest, sum(totalBits) FROM dataReceive WHERE timeStampID between '%s' And '%s' GROUP BY ipDest, macDest, portDest ",buff1,buff2);
printf("\nQuery receive %s",queryBuf1);
if(mysql_query(localConn, queryBuf1))
{
printf("Error in first query of select %s\n",mysql_error(localConn));
exit(1);
}
localRes1 = mysql_store_result(localConn);
int num_fields = mysql_num_fields(localRes1);
printf("\nNumf of fields : %d",num_fields);
printf("\nNof of row : %lu",mysql_num_rows(localRes1));
while((localRow1 = mysql_fetch_row(localRes1)) !=NULL)
{
int totalBits = atoi(localRow1[3]);
printf("totalBits %d\n", totalBits);
printf("RECEIVE %s,%s\n", localRow1[0], localRow1[1]);
if(totalBits>5000)
{
sprintf(queryBuf1,"INSERT INTO alertReceive1 (timeStampID,ipDest, macDest, portDest, totalBits)VALUES ('%s','%s','%s','%s',%s)",buff1, localRow1[0],localRow1[1],localRow1[2],localRow1[3]);
printf("Query 1 before executing %s\n",queryBuf1);
if (mysql_real_query(localConn,queryBuf1,strlen(queryBuf1))) {
printf("Error in first insert %s\n",mysql_error(localConn));
fprintf(stderr, "%s\n", mysql_error(localConn));
exit(1);
}
//printf("Query 1 after executing %s\n",queryBuf1);*/
}
}
mysql_free_result(localRes1);
mysql_close(localConn);
}
We have run this command file get1Receive and resulting to
file get1Receive
get1Receive.c: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
We have also run this command * * * * * set > /tmp/myvars and below is the results.
GROUPS=()
HOME=/root
HOSTNAME=capture
HOSTTYPE=x86_64
IFS='
'
LOGNAME=root
MACHTYPE=x86_64-redhat-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/bin:/bin
POSIXLY_CORRECT=y
PPID=11086
PS4='+ '
PWD=/root
SHELL=/bin/sh
SHELLOPTS=braceexpand:hashall:interactive-comments:posix
SHLVL=1
TERM=dumb
UID=0
USER=root
_=/bin/sh
Generic hints (see also my comments):
Take time to read documentation notably from Advanced Linux Programming, man pages (which you can also get by typing man man or man 2 intro on the terminal, etc etc...), and MySQL 5.5 reference. Be sure to understand what GIYF or STFW means.
Put the \n at the end of printf format strings, not the beginning.
Also, call fflush(NULL) if appropriate, notably before any MySQL queries e.g. before your mysql_real_query calls, and at the end of your while loops
Compile with gcc -Wall -g e.g. with the following command in your terminal
gcc -Wall -g $(mysql_config --cflags) get1ReceiveSource.c \
$(mysql_config --libs) -lrt -o get1Receive
Improve the code till no warnings are given. (You may even want to have -Wall -Wextra instead of just -Wall). Don't forget to use a version control system like git.
use the gdb debugger (you need to learn how to use it).
(only once you are sure there is no more bugs in your code replace -g by -O2 -g in your compilation command)
use sizeof; most occurrences of 20 should be a sizeof, or at the very least use #define SMALLSIZE 20 and then only SMALLSIZE not 20.
Use snprintf not sprintf (and test its result size, which should fit!). snprintf(3) takes an extra size argument, e.g.
if (snprintf(querybuf, sizeof querybuf,
"SELECT ipDest, macDest, portDest, sum(totalBits)"
" FROM dataReceive"
" WHERE timeStampID between '%s' And '%s' "
" GROUP BY ipDest, macDest, portDest ",
buff1, buff2) >= (int) (sizeof querybuf))
abort();
consider using syslog(3) with openlog, and look into your system logs.
I don't see how is queryBuf1 declared. (Your code, as posted, probably don't even compile!). You might want something like char querybuf[512]; ...
And most importantly, calling mysql_real_query inside a mysql_fetch_row loop is wrong: you should have fetched all the rows before issuing the next MySQL query. Read more about MySQL C API.
You also forgot to test the result localRes1 of mysql_store_result(localConn); show somehow (perhaps thru syslog) the mysql_error(localConn) when localRes1 is NULL ....