A simple MPI code to catch the SIGUSR1, SIGTERM signals with signalfd unix system call
#include <assert.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/signalfd.h>
#include <unistd.h>
#include <mpi.h>
/*Simple MPI Code*/
int main(int argc, char* argv[]){
MPI_Init(&argc, &argv);
int err, nbProcs, rank;
sigset_t sigset;
int fd;
MPI_Comm_size(MPI_COMM_WORLD, &nbProcs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
****
Setup SIGALRM to be delivered via SignalFD
****
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGUSR1);
/* */
if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
printf("Failed to signalmask\n");
return -1;
}
fd = signalfd(-1, &mask, 0);
if (fd < 0)
return -1;
while (1) {
struct signalfd_siginfo si;
int ret;
ret = read(fd, &si, sizeof(si));// here the MPI process doesn't
return when I send SIGTERM or SIGUSR1
if (ret < 0)
return -1;
if (ret != sizeof(si))
return -1;
if (si.ssi_signo == SIGTERM)
printf("receive SIGTERM \\\n");
else if (si.ssi_signo == SIGUSR1)
printf("receive SIGUSR1\n");
}
MPI_Finalize();
return 0;
}
In this code, I am using signalfd to catch SIGUSR1, SIGTERM. At
ret = read(fd, &si, sizeof(si));
read() system call it doesn't return and the program dies at this point. When I use the same code without MPI simple C code it works perfect.Can anyone explain me how does signalfd works inside MPI???
I'm trying to read from Arduino (who's sending char '4' constantly) with XBee.
I have tried writing from the PC to Arduino, and it works, so the connection is correct.
When I execute de following code, the terminal doesn't show anything and don't finish the program, so it gets stuck on reading.
#include <stdio.h> // Standard input / output functions
#include <stdlib.h>
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
int tty_fd = open(XBEE , O_RDWR| O_NOCTTY);
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // Baudrate is declared above
tcsetattr(tty_fd,TCSANOW,&tio);
// for(i;i<5;i++){
// write(tty_fd,&c,1); //If new data is available on the console, send it to the serial port
// write(tty_fd,&o,1); //If new data is available on the console, send it to the serial port
// }
int n=0;
char buf = '\0';
/* Whole response*/
do
{
n = read( tty_fd, &buf, sizeof(char) );
}
while( n > 0);
if (n < 0)
{
printf("ERROR READING");
}
else if (n == 0)
{
printf("Read nothing!");
}
else
{
printf("Response: %c",buf);
}
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
How do I solve this?
UPDATE
I tried this other code and receive a warning: turning off output flushing and then the terminal froze.
#include <stdio.h> // Standard input / output functions
#include <stdlib.h>
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
struct termios options;
int tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY);
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // Baudrate is declared above
tcsetattr(tty_fd,TCSANOW,&tio);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// for(i;i<5;i++){
// write(tty_fd,&c,1);//if new data is available on the console, send it to serial port
// write(tty_fd,&o,1);//if new data is available on the console, send it to serial port
// }
int n=0;
char buf = '1';
int i = 1;
/* Whole response*/
while(i==1){
n = read( tty_fd, &buf, sizeof(char) );
if (n < 0)
{
printf("ERROR READING");
}
else if (n == 0)
{
printf("Read nothing!");
}
else
{
printf("Response: %c",buf);
close(tty_fd);
break;
}
}
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
If you're going to be using C to communicate with XBee modules, you might want to check out this Open Source XBee Host library. You could just use the serial driver from it in your code, or take a look at the xbee_term sample program as a simple terminal.
If you are printing data, why are you using printf? You must use the Serial.print() syntax w.r.t the Arduino IDE.
I'm dying a little inside. I've been working on this all day to no avail. I was having issues running some code that previously ran fine, so I wrote a short "toy" OpenCL program to try and figure out what was going on, but my toy program has me baffled and incredibly frustrated.
I'm working with an Nvidia 780i with 3Gb of global memory. It has a maximum allocation of ~780 Mb. At first, it wouldn't error out when I was intentionally over-allocating. Solved that (it was typographical, but the compiler/analyzer wasn't catching it). Now, even when trying to allocate WAY below what the device should be able to handle, I get an error code of -6 (CL_OUT_OF_HOST_MEMORY) on the second big buffer allocation.
I've been researching this error and I just can't track how it applies in this case. I have 32 gb of ram in the machine I'm using so there's certainly not a shortage there. I figure there's something that I just don't understand going on here.
It will allocate the first buffer alright, but then choke on the second. I basically just cannot allocate nearly the amount of global memory I both want and need to.
Any help is much appreciated. If you can help me with this and you're near LA I'll take you out for drinks. That's how frustrated I am.
Code and output is below for my machine.
Thanks,
John
Main program:
#define _CRT_SECURE_NO_WARNINGS
#define PROGRAM_FILE "kernels.cl"
#define KERNEL_NAME "test"
#include <CL/cl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#define N_PROJ 4000
#define N_CHANNELS 736
#define N_ROWS 32
/* Find a GPU or CPU associated with the first available platform */
cl_device_id create_device() {
cl_platform_id platform;
cl_device_id dev;
int err;
/* Identify a platform */
err = clGetPlatformIDs(1, &platform, NULL);
if(err < 0) {
perror("Couldn't identify a platform");
exit(1);
}
/* Access a device */
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &dev, NULL);
if(err == CL_DEVICE_NOT_FOUND) {
perror("Just a heads up: I'm not going to run on the GPU");
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &dev, NULL);
}
if(err < 0) {
perror("Couldn't access any devices");
exit(1);
}
cl_ulong16 alloc_size,mem_size;
char name[40];
clGetDeviceInfo(dev,CL_DEVICE_MAX_MEM_ALLOC_SIZE,sizeof(cl_ulong16),&alloc_size,NULL);
clGetDeviceInfo(dev,CL_DEVICE_NAME,sizeof(name),name,NULL);
clGetDeviceInfo(dev,CL_DEVICE_GLOBAL_MEM_SIZE,sizeof(cl_ulong16),&mem_size,NULL);
printf("Using device: %s\n",name);
printf("Global memory size: %lu\n",mem_size);
printf("Max. allocation: %lu\n",alloc_size);
return dev;
}
/* Create program from a file and compile it */
cl_program build_program(cl_context ctx, cl_device_id dev, const char* filename) {
cl_program program;
FILE *program_handle;
char *program_buffer, *program_log;
size_t program_size, log_size;
int err;
/* Read program file and place content into buffer */
program_handle = fopen(filename, "r");
if(program_handle == NULL) {
perror("Couldn't find the program file");
exit(1);
}
fseek(program_handle, 0, SEEK_END);
program_size = ftell(program_handle)-13;
rewind(program_handle);
program_buffer = (char*)malloc(program_size + 1);
program_buffer[program_size] = '\0';
fread(program_buffer, sizeof(char), program_size, program_handle);
fclose(program_handle);
/* Create program from file */
program = clCreateProgramWithSource(ctx, 1,
(const char**)&program_buffer, &program_size, &err);
if(err < 0) {
perror("Couldn't create the program");
exit(1);
}
free(program_buffer);
/* Build program */
err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
if(err < 0) {
/* Find size of log and print to std output */
clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG,
0, NULL, &log_size);
program_log = (char*) malloc(log_size + 1);
program_log[log_size] = '\0';
clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG,
log_size + 1, program_log, NULL);
printf("%s\n", program_log);
free(program_log);
exit(1);
}
return program;
}
int main(int argc, const char * argv[])
{
/* This file serves as a backbone for OpenCL programs. */
/* All the user needs to do is enter their OpenCL data */
/* structures, set kernel args, and kernel dispatches. */
/* Standard OCL structures */
cl_device_id device;
cl_context context;
cl_program program;
cl_kernel kernel;
cl_command_queue queue;
device=create_device();
context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
program = build_program(context, device, PROGRAM_FILE);
queue = clCreateCommandQueue(context, device,0, NULL);
kernel = clCreateKernel(program, KERNEL_NAME, NULL);
/* User code goes here */
cl_int err;
/* Declare and set data */
int a[]={1,2,3};
float *rebin;
rebin =(float*) calloc(N_PROJ*N_CHANNELS*N_ROWS,sizeof(float));
float *mat;
mat =(float*) calloc(N_PROJ*N_CHANNELS*N_ROWS,sizeof(float));
printf("\nAllocation size: %lu\n",N_PROJ*N_CHANNELS*N_ROWS*sizeof(float));
/* Declare and set buffer objects */
cl_mem a_buff,rebin_buff,mat_buff;
printf("Total memory to be allocated: %lu\n",2*N_PROJ*N_CHANNELS*N_ROWS*sizeof(float)+sizeof(a) );
a_buff =clCreateBuffer(context,CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE,sizeof(a),a,NULL);
rebin_buff =clCreateBuffer(context,CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE,N_PROJ*N_CHANNELS*N_ROWS*sizeof(float),rebin,&err);
if (err<0){
printf("Error: %i\n",err);
perror("Couldn't create buffer 1");
exit(1);
}
mat_buff =clCreateBuffer(context,CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE,N_PROJ*N_CHANNELS*N_ROWS*sizeof(float),mat ,&err);
if (err<0){
printf("Error: %i\n",err);
perror("Couldn't create buffer 2");
exit(1);
}
/* Copy data over to the device */
err=clSetKernelArg(kernel,0,sizeof(cl_mem),&mat_buff);
if (err<0){
perror("Couldn't set kernel argument");
exit(1);
}
err=clSetKernelArg(kernel,1,sizeof(cl_mem),&rebin_buff);
err=clSetKernelArg(kernel,2,sizeof(cl_mem),&a_buff);
clEnqueueTask(queue,kernel,0,NULL,NULL);
clEnqueueReadBuffer(queue,mat_buff ,CL_TRUE,0,N_PROJ*N_CHANNELS*N_ROWS*sizeof(float),mat ,0,NULL,NULL);
clEnqueueReadBuffer(queue,rebin_buff,CL_TRUE,0,N_PROJ*N_CHANNELS*N_ROWS*sizeof(float),rebin,0,NULL,NULL);
clEnqueueReadBuffer(queue,a_buff, CL_TRUE,0,sizeof(a),a,0,NULL,NULL);
printf("%f %f %f\n",mat[1],mat[2],mat[3]);
printf("%f %f %f\n",rebin[1],rebin[2],rebin[3]);
printf("%i %i %i",a[0],a[1],a[2]);
/***********************/
clReleaseKernel(kernel);
clReleaseCommandQueue(queue);
clReleaseProgram(program);
clReleaseContext(context);
//clReleaseDevice(device);
printf("\n\nProgram apparently executed fully. \n");
return 0;
}
Kernel:
__kernel void test(__global float *mat,__global float *rebin,__global int *a){
a[0]=3;
a[1]=2;
a[2]=1;
rebin[1]=1.0f;
rebin[2]=2.0f;
rebin[3]=3.0f;
mat[1]=3.0f;
mat[2]=2.0f;
mat[3]=1.0f;
}
Console output for my machine:
Using device: GeForce GTX 780
Global memory size: 3221225472
Max. allocation: 805306368
Allocation size: 376832000
Total memory to be allocated: 753664012
Error: -6
Couldn't create buffer 2: No error
Process returned 1 (0x1) execution time : 0.435 s
Press any key to continue.
I have a simple program written in C which uses termios to send a basic string to the Raspberry Pi UART and attempts to read and output the response. The Rx and Tx pins on the Raspberry Pi are connected with a jumper so whatever is sent should be immediately received.
Despite the program outputting that it successfully sent and received 5 characters for the chosen string ('Hello'), trying to print the contents of the buffer just produces one or two garbage characters.
The program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(int argc, char* argv[]) {
struct termios serial;
char* str = "Hello";
char buffer[10];
if (argc == 1) {
printf("Usage: %s [device]\n\n", argv[0]);
return -1;
}
printf("Opening %s\n", argv[1]);
int fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror(argv[1]);
return -1;
}
if (tcgetattr(fd, &serial) < 0) {
perror("Getting configuration");
return -1;
}
// Set up Serial Configuration
serial.c_iflag = 0;
serial.c_oflag = 0;
serial.c_lflag = 0;
serial.c_cflag = 0;
serial.c_cc[VMIN] = 0;
serial.c_cc[VTIME] = 0;
serial.c_cflag = B115200 | CS8 | CREAD;
tcsetattr(fd, TCSANOW, &serial); // Apply configuration
// Attempt to send and receive
printf("Sending: %s\n", str);
int wcount = write(fd, &str, strlen(str));
if (wcount < 0) {
perror("Write");
return -1;
}
else {
printf("Sent %d characters\n", wcount);
}
int rcount = read(fd, &buffer, sizeof(buffer));
if (rcount < 0) {
perror("Read");
return -1;
}
else {
printf("Received %d characters\n", rcount);
}
buffer[rcount] = '\0';
printf("Received: %s\n", buffer);
close(fd);
}
Outputs:
Opening /dev/ttyAMA0
Sending: Hello
Sent 5 characters
Received 5 characters
Received: [garbage]
I can't see any major problem with the code myself, but I might be wrong. I can successfully send and receive characters using PuTTY connected with the same settings, so it can't really be a hardware problem. Although I haven't tried it in PuTTY, trying to connect with anything less than 115200 baud with this program will result in nothing being received.
Where am I going wrong?
int wcount = write(fd, &str, strlen(str));
int rcount = read(fd, &buffer, sizeof(buffer));
In these lines, buffer/str are already pointers. You are passing a pointer to a pointer.
The lines should be:
int wcount = write(fd, str, strlen(str));
int rcount = read(fd, buffer, sizeof(buffer));
The output of the following program on my machine with ATI Firepro V8750 is as follows:
"Couldn't find any devices:No error"
(this happens at the call of first clGetDeviceIDs). the error code returned is -30. What does that mean?
I am not able to understand why it is unable to find the device. I have checked that CLinfo.exe lists my GPU along with the Intel CPU I am having. Can some one give my some pointers as to what is wrong here?
Additional info:
AMD APP SK 2.4
Firepro Driver: 8.911.3.3_VistaWin7_X32X64_135673
12-4_vista_win7_32_dd_ccc
Windows 7
Also I must mention that the firePro Driver's some componenets failed to get install.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef MAC
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif
int main() {
/* Host/device data structures */
cl_platform_id platform;
cl_device_id *devices;
cl_uint num_devices, addr_data;
cl_int i, err;
/* Extension data */
char name_data[48], ext_data[4096];
/* Identify a platform */
err = clGetPlatformIDs(1, &platform, NULL);
if(err < 0) {
perror("Couldn't find any platforms");
exit(1);
}
/* Determine number of connected devices */
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, NULL, &num_devices);
if(err < 0) {
perror("Couldn't find any devices");
exit(1);
}
/* Access connected devices */
devices = (cl_device_id*)
malloc(sizeof(cl_device_id) * num_devices);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU,
num_devices, devices, NULL);
/* Obtain data for each connected device */
for(i=0; i<num_devices; i++) {
err = clGetDeviceInfo(devices[i], CL_DEVICE_NAME,
sizeof(name_data), name_data, NULL);
if(err < 0) {
perror("Couldn't read extension data");
exit(1);
}
clGetDeviceInfo(devices[i], CL_DEVICE_ADDRESS_BITS,
sizeof(ext_data), &addr_data, NULL);
clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS,
sizeof(ext_data), ext_data, NULL);
printf("NAME: %s\nADDRESS_WIDTH: %u\nEXTENSIONS: %s",
name_data, addr_data, ext_data);
}
free(devices);
return 0;
}
Here is CLINFO output:
GPU:
CPU:
Why are the two highlighted versions different?
Could it be that you have multiple OpenCL platforms installed on your system? So, perhaps your first platform is a CPU-only playform, so the query for a GPU device fails.
EDIT:
Here's the problem: The first call to clGetDeviceIDs passes 1 for num_entries, but NULL for the devices pointer. I think you want to pass in 0 for num_entries.