I have a C code (io.c) which compiles and runs perfectly. I am trying to call a function of the C code (io.c) from a cuda file (PCA.cu):
io.c
#include <stdio.h>
#include <stdlib.h>
void Read_header(char filename_header[200], int *num_lines, int *num_samples, int *num_bands, int *lines_samples, int *data_type){
FILE *fp;
char line[200];
char *ptr;
int i=0;
if(strstr(filename_header, ".hdr")==NULL){
exit(1);
}
if ((fp=fopen(filename_header,"r"))==NULL){
exit(1);
}
else{
fseek(fp,0L,SEEK_SET);
while(fgets(line, 200, fp)!='\0'){
if(strstr(line, "samples")!=NULL){
ptr=strrchr(line, ' ');
ptr= ptr+1;
*num_samples=atoi(ptr);
}
if(strstr(line, "lines")!=NULL){
ptr=strrchr(line, ' ');
ptr= ptr+1;
*num_lines=atoi(ptr);
}
if(strstr(line, "bands")!=NULL){
ptr=strrchr(line, ' ');
ptr= ptr+1;
*num_bands=atoi(ptr);
}
if(strstr(line, "data type")!=NULL){
ptr=strrchr(line, ' ');
ptr= ptr+1;
*data_type=atoi(ptr);
}
}//while
(*lines_samples)=(*num_lines)*(*num_samples);
fclose(fp);
}//else
}
PCA.cu
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
/*C includes*/
extern "C"{
#include "io.h"
}
#include "cuda.h"
/* Main */
int main(int argc, char** argv){
int num_lines, num_samples, num_bands, lines_samples, data_type;
Read_header(argv[1], &num_lines, &num_samples, &num_bands, &lines_samples, &data_type);
printf("lines = %d\nsamples = %d\nbands = %d\npixels = %d\ndata_type = %d\n", num_lines, num_samples, num_bands, lines_samples, data_type);
// the rest of source code has been removed for simplicity
}
I am using the following Makefile to compile and link io.c and PCA.cu:
MKL =1
CUDA_PATH=/usr/local/cuda-6.0
BUILD_DIR=./build
CUDA_INCLUDE_DIR=-I. -I$(CUDA_PATH)/include
CUDA_LIB_DIR=-L$(CUDA_PATH)/lib64
CUDALIBS=-lcublas -lcudart
utilS= -lpthread -lm
CFLAGS= -Wwrite-strings
CUDAFLAGS= --gpu-architecture sm_20
io.o : io.c
icc $(CFLAGS) -c -O3 io.c -o $(BUILD_DIR)/io.o
PCA.o: PCA.cu
nvcc $(CUDAFLAGS) $(CUDA_INCLUDE_DIR) -c -O3 PCA.cu -o $(BUILD_DIR)/PCA.o
#everything is already compiled, this is just a call to the linker
PCA: io.o PCA.o
icc $(CFLAGS) $(BUILD_DIR)/io.o $(BUILD_DIR)/PCA.o $(CUDA_LIB_DIR) $(utilS) $(CUDALIBS) -o PCA
And I get segmentation fault (core dumped) when I run the generated executable (./PCA)
Any help?
I get segmentation fault (core dumped) when I run the generated executable (./PCA)
This program expects a filename to be specified on the command line.
If you run your program as-is the way you have described in your question (./PCA
) it will seg fault.
This has nothing to do with CUDA. The seg fault is arising because of this call:
Read_header(argv[1], &num_lines, &num_samples, &num_bands, &lines_samples, &data_type);
The argv[1]
is expecting to pull a command line argument as the file name to be used in io.c here:
void Read_header(char filename_header[200], int *num_lines, int *num_samples, int *num_bands, int *lines_samples, int *data_type){
...
if(strstr(filename_header, ".hdr")==NULL){
If the first parameter (filename_header
, which is argv[1]
in main
) is null (because you haven't specified the file name on the command line), the call to strstr
will seg fault.
Again, this is just a coding/usage error, and it has nothing to do with CUDA.
The fix is to specify a filename on the command line (./PCA myfile
), and even better write some code that detects when the user has not provided a valid filename and halt the program with an error message.