Make my C function call from my CUDA code - c

I have cuda code which makes a call to a function present in a .c file whose header file I have included in my cuda code. So, in all I have a header file, a C file for that header file, and a CUDA code. When I am compiling my CUDA code using nvcc and specifying my cuda code name and c file name, then I am getting undefined reference to the functions I called in my CUDA code which are actually present in my C file. Please help me understand what am I doing wrong and how can I fix my mistake.
Ok I am pasting my code below... I did not post it initially because I thought its a linker error or something.
#include "dbConnection.h"
#include "error.h"
#include "libpq-fe.h"
#include <stdio.h>
#include <stdlib.h>
#include "appCompileSwitches.h"
int makeConnection(PGconn** conn,const char* connInfo);
void executeQuery(PGconn* conn,PGresult** res,char* statement,int* rows,int* columns);
/***************************************
* main(), enough said
****************************************/
int main(int argc, char **argv)
{
PGconn *conn = NULL;
PGresult *res= NULL;
float** result;
char* statement = "select visit_no,brand_name from visit_sample limit 3";
int rows=0,columns=0; // WILL BE USED TO CUDAMALLOC gpu memory
const char* connInfo = "dbname = moxy";
if(!makeConnection(&conn,connInfo))
{
printf("failed to connect to Database!\n");
return FAILURE;
}
}
The dbConnection.c file has :
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
#include <string.h>
#include "dbConnection.h"
#include "error.h"
#include "appCompileSwitches.h"
/****************************************************
* close database connection, given connecton info
****************************************************/
static void closeConnection(PGconn *conn)
{
/* close the connection to the database and cleanup */
PQfinish(conn);
}
/****************************************************
* connect to the database
* given the connInfo
****************************************************/
extern int makeConnection(PGconn** conn,const char* connInfo)
{
/* Make a connection to the database */
*conn = PQconnectdb(connInfo);
if (PQstatus(*conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",PQerrorMessage(*conn));
PQfinish(*conn);
return FAILURE;
}
return SUCCESS;
}
So when I am doing:
nvcc DB.cu dbConnection.c -o DB
I am getting undefined reference to make connection.
Also, I will be transferring the data I get from DB to GPGPU later and that is the whole point of this exercise so please do not say I have no CUDA calls here. This is a code still under development.

Your external function is in a .c file, so the host compiler compiles it using the C language naming/calling convention. nvcc, on the other hand, is a C++ compiler by default, so it defaults to C++ naming/calling convention. You need to tell the C++ compiler to look for an external "C" function for makeConnection, by declaring it as such in your header and/or forward declaration in the .cu file.
extern "C"
int makeConnection(PGconn** conn,const char* connInfo);

Related

C error: conflicting types for function and previous declaration was here (not duplicate)

Apologies for the dumb question. I checked all similar questions for the same error on stackoverflow, but it didn't help me understand why this error is happening in the following code.
I have one additional header file and a source file, which is included in the main file, and when I compile, I am getting the following error. I am trying to pass the char** argv from the main() to another function defined in another header file.
#include "include/Process.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc < 2) {
printf("Please provide a path to file\n");
return (EXIT_FAILURE);
}
Process(argv);
Process.h:
#pragma once
extern void Process(char** path);
Process.c:
#include <stdio.h>
#include "../include/Process.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <syslog.h>
#include <sys/types.h>
#include <unistd.h>
void Process(char** path) {
printf("%s\n", path[1]);
}
It gets compiled but the warning is
./src/Process.c:22:6: error: conflicting types for ‘Process’
void Process(char** path) {
^
./include/Process.h:17:6: note: previous declaration of ‘Process’ was here
extern void Process(char** path);
^
However, the warning disappears when I change the type of path from char** to char* and pass argv[1] instead of argv.
I am clueless why this is happening like this, and according to
this similar post, I tried adding a forward declaration for char** path above extern void Process(char** path); in the Process.h file, but it didn't help either.
Why is this error thrown when using char** path?
Why it disappears when I use char* path?
So far, I am able to see the program running, even with this warning. Is it safe to ignore this warning? If not, what could be the possible effects it can have during runtime?
Using gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13)
Thanks.
Try putting your custom includes after the system includes.
It might be possible that the custom include defines a macro which interferes with the system includes. To minimize the risk of this, I always put the Standard C includes first, then any OS includes, and then third party libraries, and then my own ones
In theory the custom include shouldn't do this, and the system includes should only use reserved names, but in practice this doesn't always happen.

expected ')' before '*' token, can't seem to find error

So whenever I try to run my Makefile on my server, it always gives me the error is "Memory.c: 9 error: expected ')' before '*' token. But when I try to run it on my own computer, it works just fine. I've been trying to figure out what is wrong but can't seem to find it.
I've attached the 3 files that are used in this part of my program. Memory.c, Memory.h and ProcessInput.h.
This is Memory.c
/* Initializes memory */
#include <stdio.h>
#include <stdlib.h>
#include "memory.h"
void initializeMemory(memory** memArray, int memSize)
{
// Allocating space for memory array
*memArray = malloc(memSize * sizeof(memory));
if(*memArray == NULL)
{
fprintf(stderr, "Error allocating space for array of memory" );
exit(1); // exit(1) = Unsuccessful exit
}
// Initializing the contents within memory array
int i = 0;
for(i = 0; i < memSize; i ++)
{
((*memArray)[i]).occupied = false;
}
}
and this is Memory.h
// Definitions for Memory.c
#define bool int
#define true 1
#define false 0
#include "ProcessInput.h"
// Include guards to prevent redefinition of struct
#ifndef MEMORY_H
#define MEMORY_H
typedef struct memoryDetail
{
process process;
bool occupied;
} memory;
#endif
// Function declaration for memory.c
void initializeMemory(memory** memArray, int memSize);
the only thing used from ProcessInput.h is the process structure defined in ProcessInput.h
This is ProcessInput.h
// Include guards to prevent redefinition of struct
#ifndef PROCESSDETAIL_H
#define PROCESSDETAIL_H
typedef struct processDetail
{
int timeCreated;
int processID;
int memorySize;
int jobTime;
} process;
#endif
// function declarations for ProcessInput.c
void processInput(int* maxSize, int* count, process** processes, char* fileName);
I'm not too sure why it's giving me the error. I don't know where I'm supposed to be putting a missing right brace. Any advice is much appreciated!
edit: As informed, these are the following questions that I looked at but to not avail.
error: expected ‘)’ before ‘*’ token
Multiple of same error while compiling "error: expected ')' before '*' token
http://www.dreamincode.net/forums/topic/288956-error-expected-before-token/
thanks everyone for the help!
#include "memory.h" is different to #include "Memory.h" (i.e. C is case sensitive)
If you tried #include "myfile.h" instead of #include "MyFile.h" the error may be more obvious. In this case it just happens that the compiler finds the system memory.h.
<memory.h> is a header from C library of pre-standard era. It is quite possible that your standard library still provides it and the compiler takes that one instead of yours.
Try renaming your header file and see if it changes anything.

Setting Immutable Flag using ioctl() in C

I have attempted to make a script that creates a file and then sets it as immutable similar to the chattr +i command for linux. The script compiles (with gcc), runs and the file is created. However the file itself is not immutable and can be removed with a simple rm -f. I have attempted to stacktrace where chattr is called and I found a function called ioctl. I then used what little information I could gather and came up with what I have below. I narrowed it down from ext2_fs.h but it just doesn't seem to work. I've clearly overlooked something.
Updates to previous entry: Compiles but returns -1 on ioctl() function. Bad address shown with perror().
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
int main()
{
FILE *fp;
char shovel[16] = "I have a shovel!";
fp = fopen("/shovel.txt", "w+");
fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
ioctl(fileno(fp), FS_IOC_SETFLAGS, 0x00000010);
fclose(fp);
}
Any help appreciated.
You are using the right ioctl command, but you're passing it the wrong arguments.
The manpage for ioctl_list(2) shows that FS_IOC_SETFLAGS expects to receive a pointer to int (an int *), yet you're passing it an integer literal (hence the Bad Address error).
The fact that you don't to any error checking whatsoever is also not helping.
The correct flag to pass to FS_IOC_SETFLAGS is a pointer holding the value EXT2_IMMUTABLE_FL, which is defined in ext2fs/ext2_fs.h (some older / different Linux distributions seem to have it under linux/ext2_fs.h), so you'll need to #include <ext2fs/etx2_fs.h>. Make sure to install e2fslibs-dev (and probably you'll need linux-headers too).
This code is working:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <ext2fs/ext2_fs.h>
int main()
{
FILE *fp;
char shovel[16] = "I have a shovel!";
if ((fp = fopen("shovel.txt", "w+")) == NULL) {
perror("fopen(3) error");
exit(EXIT_FAILURE);
}
fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
int val = EXT2_IMMUTABLE_FL;
if (ioctl(fileno(fp), FS_IOC_SETFLAGS, &val) < 0)
perror("ioctl(2) error");
fclose(fp);
return 0;
}
Remember to run this as root.
UPDATE:
As Giuseppe Guerrini suggests in his answer, you might want to use FS_IMMUTABLE_FL instead, and you won't need to include ext2_fs.h:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
int main()
{
FILE *fp;
char shovel[16] = "I have a shovel!";
if ((fp = fopen("shovel.txt", "w+")) == NULL) {
perror("fopen(3) error");
exit(EXIT_FAILURE);
}
fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
int val = FS_IMMUTABLE_FL;
if (ioctl(fileno(fp), FS_IOC_SETFLAGS, &val) < 0)
perror("ioctl(2) error");
fclose(fp);
return 0;
}
The main problem is that the ioctl wants a pointer to the mask, not a direct constant. You have to define a int variable, store the mask (0x10) in it and pass its address as third argument of ioctl.
Also, I'd add some hints:
other programs to change attributes are used to use low-level I/O directly (open, close...). Also, the file is usually opened with O_RDONLY.
Use FS_IMMUTABLE_FL istead the raw constant.
Get the current attribute mask first (FS_IOC_SETFLAGS) and mask it with the new flag, so other settings are not lost by the service.

Login simulator in c, dereferencing incomplete types errors

As a preporatory task for a computer lab in school, we are asked to write a c program that simulates the login process in UNIX. The program should read username and password from a terminal, compare it to hashed values in a local file that is supposed to resemble /etc/passwd.
Here's what I've got:
/*
* Program mylogin.c
*
* This program prompts the user for a login name and password
*
*/
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <string.h>
/* define some error constants */
#define NOUSER -1
/* define max size of a username */
#define USERNAME_SIZE 32
#define PASSWORD_SIZE 32
#define HASH_SIZE 32
#define FAILED_LIMIT 5
#define AGE_LIMIT 10
int read_username(char *username)
{
printf("login: ");
fgets(username,USERNAME_SIZE,stdin);
/* remove the CR included by getline() */
username[strlen(username)-1]='\0';
return(0);
}
int read_password(char *password)
{
printf("password: ");
fgets(password,PASSWORD_SIZE,stdin);
//getpass(password);
/* remove the CR included by getline() */
password[strlen(password)-1]='\0';
return(0);
}
int user_exists(const char *username)
{
struct pwdb_passwd *pw_entry;
pw_entry=getpwnam(username);
return((pw_entry)!=NULL);
}
int main(int argc,char **argv)
{
char username[USERNAME_SIZE];
char* password;
/* write "login:" and read user input */
read_username(username);
read_password(password);
if (!user_exists(username))
{
printf("Unknown user or authentication\n");
main(argc, argv);
}
struct pwdb_passwd *pw_entry = getpwnam(username);
char* hashed_password = crypt(password,pw_entry->pw_passwd);
if(strcmp(hashed_password, pw_entry->pw_passwd)==0)
{
if((pw_entry->pw_failed)<FAILED_LIMIT)
{
printf("User authenticated successfully\n");
pw_entry->pw_age++;
pw_entry->pw_failed = 0;
pwdb_update_user(pw_entry);
}else{
printf("User account locked\n");
main(argc, argv);
}
}
else
{
printf("Unknown user or authentication\n");
pw_entry->pw_failed++;
if(pw_entry->pw_failed>5){
printf("Too many failed attempts. Username now locked\n");
}
pwdb_update_user(pw_entry);
main(argc, argv);
}
return(0);
}
The struct pwdb_passwd is defined in the files pwdb_lib.c and pwdb_lib.h, which are already written.
When I compile the program, I get a couple of errors. For example on line 73, I get: "error: dereferencing pointer to incomplete type"
I don't understand why. It doesn't seem to like pw_entry->pw_passwd and things like that. More to the point, I get different errors when compiling under Windows with Code::Blocks (using gcc) than under Ubuntu with gcc. I find this pretty strange. I suspect it could be because I import pwd.h and that it only exists on Linux and not Windows. Could this be right? I tried creating my own pwd.h file and save it in the same directory, but it still didn't work. Moving to an ubuntu computer, I dont get errors from the pwd.h thing, but instead get errors on: "dereferencing pointer to incomplete type"
What's wrong with my code?
I also suspect memory leak in the user_exists function, but I'm not sure if it affects the overall program.
Even though pwdb_lib.c is already written, you need to include it in your source file.
Add
#include "pwdb_lib.h"
to your source and make sure you compile/link against pwdb_lib.c
By #includeing this file, you let your source file know about the definitions within it without providing it the implementation. At the end, when you compile your program with pwdb_lib.c (or link its object file, if that's what you're doing), you let any source which included these definitions know where they are implemented (and thus, give them the ability to use them).
If the header is named pwdb_lib.h, then why isn't your program doing an #include of it? It seems to include a different header (pwd.h), which is it?
The error you're getting is the one you'd expect if the declarations were missing.

How can I use Matlab engine in a mex function called from Matlab

I want to make a mex program that can be called from Matlab, where the user can register a Matlab function to be used for processing. The program will then use this function to process data coming from another program in the background. The communication between the mex program and the external program is trough a shared global buffer, which I keep track of with mutex locks. That part actually seems to work. The problem is that Matlab is single-threaded and I want to process data in the background, so that the user can keep working with Matlab. Since Matlab is single-threaded my solution is to create a new thread and start Matlab engine from it. For this I need to call Matlab engine from a mex file called from Matlab. When I try to do this the program builds ok, but when I try to open a new engine Matlab crashes. Using the test example below, if I call the program (from inside Matlab) with test('process2') Matlab stalls, and when I use ctrl-c Matlab crashes. Using test('process') sometimes seems to work but crashes Matlab in maybe one of ten calls.
#include "mex.h"
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <matrix.h>
#include <unistd.h>
#include "engine.h"
void* local_process(void *arg) {
Engine *engine;
engine = engOpen(NULL);
engClose(engine);
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
if ( (nrhs<1) || (! mxIsChar(prhs[0])) ) {
mexErrMsgTxt("First argument should be a command (string)");
return;
}
/* Read command string */
int buflen = mxGetNumberOfElements(prhs[0])+1;
char* buf = mxCalloc(buflen, sizeof(char));
if (mxGetString(prhs[0], buf, buflen) != 0)
mexErrMsgTxt("Could not read command string");
mexPrintf("Command: %s\n",buf);
if (strcmp(buf,"process")==0) {
pthread_t thread;
pthread_create(&thread,NULL,local_process,NULL);
}
else if (strcmp(buf,"process2")==0) {
Engine *engine;
engine = engOpen(NULL);
engClose(engine);
}
}
If it still is of a concern, I compiled your code without the thread part (only "process2" case) with no error, no stalling, no problem.
i.e.
#include <mex.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <matrix.h>
#include <engine.h>
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
if ( (nrhs<1) || (! mxIsChar(prhs[0])) )
{
mexErrMsgTxt("First argument should be a command (string)");
return;
}
/* Read command string */
int buflen = mxGetNumberOfElements(prhs[0])+1;
char* buf = (char*)mxCalloc(buflen, sizeof(char));
if (mxGetString(prhs[0], buf, buflen) != 0)
mexErrMsgTxt("Could not read command string");
mexPrintf("Command: %s\n",buf);
Engine *engine;
engine = engOpen(NULL);
engClose(engine);
}
ran well. I am on a windows machine, with Visual Studio 2010.
Nevertheless, there are apparently peculiarities dealing with Matlab engine through mex. On this link you can find a recent similar case that I had, and a workaround:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/327157#898916

Resources