here is my code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
main(int argc, char *argv[])
{
struct numbers_struct {
char numbers_array[1000];
};
char Line[300];
FILE *Fp;
int i=0;
long size;
Fp=fopen("input2.txt","r");
fscanf(Fp, "%ld", &size);
struct numbers_struct *numbers = malloc(sizeof(struct numbers_struct) * size);
while(!feof(Fp))
{
if (fgets(Line,1000,Fp)!=NULL)
{
strncpy(numbers[i].numbers_array,Line,1000);
i++;
}
}
int k;
k=i;
for(i=k-1;i>=0;i--)
printf("%s",numbers[i].numbers_array);
free(numbers);
fclose(Fp);
return 0;
}
When I run it, program prints correct output and then this error message:
*** glibc detected *** ./part2: double free or corruption (out): 0x08834170 ***
part2: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted (core dumped)
What did I do wrong?
What did I do wrong?
You have corrupted heap.
The best way to diagnose heap corruption are Valgrind and AddressSanitizer. Either of these should point you directly at the problem.
There are two obvious bugs in your program:
fgets(Line,1000,Fp) -- how big is the Line, and how many characters are you reading into it if presented with a long line?
struct numbers_struct *numbers = malloc(sizeof(struct numbers_struct) * size); -- what happens if the input file starts with 3 but contains 15 lines?
Related
How can an array of structs that has been dynamically allocated on the host be used by a kernel, without passing the array of structs as a kernel argument? This seems like a common procedure with a good amount of documentation online, yet it doesn't work on the following program.
Note: Please note that the following questions have been studied before posting this question:
1) copying host memory to cuda __device__ variable 2) Global variable in CUDA 3) Is there any way to dynamically allocate constant memory? CUDA
So far, unsuccessful attempts have been made to:
Dynamically allocate array of structs with cudaMalloc(), then
Use cudaMemcpyToSymbol() with the pointer returned from cudaMalloc() to copy to a __device__ variable which can be used by the kernel.
Code attempt:
NBody.cu (error checking using cudaStatus has mostly been omitted for better readability, and function to read data from file into dynamic array removed):
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
#define BLOCK 256
struct nbody {
float x, y, vx, vy, m;
};
typedef struct nbody nbody;
// Global declarations
nbody* particle;
// Device variables
__device__ unsigned int d_N; // Kernel can successfully access this
__device__ nbody d_particle; // Update: part of problem was here with (*)
// Aim of kernel: to print contents of array of structs without using kernel argument
__global__ void step_cuda_v1() {
int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < d_N) {
printf("%.f\n", d_particle.x);
}
}
int main() {
unsigned int N = 10;
unsigned int I = 1;
cudaMallocHost((void**)&particle, N * sizeof(nbody)); // Host allocation
cudaError_t cudaStatus;
for (int i = 0; i < N; i++) particle[i].x = i;
nbody* particle_buf; // device buffer
cudaSetDevice(0);
cudaMalloc((void**)&particle_buf, N * sizeof(nbody)); // Allocate device mem
cudaMemcpy(particle_buf, particle, N * sizeof(nbody), cudaMemcpyHostToDevice); // Copy data into device mem
cudaMemcpyToSymbol(d_particle, &particle_buf, sizeof(nbody*)); // Copy pointer to data into __device__ var
cudaMemcpyToSymbol(d_N, &N, sizeof(unsigned int)); // This works fine
int NThreadBlock = (N + BLOCK - 1) / BLOCK;
for (int iteration = 0; iteration <= I; iteration++) {
step_cuda_v1 << <NThreadBlock, BLOCK >> > ();
//step_cuda_v1 << <1, 5 >> > (particle_buf);
cudaDeviceSynchronize();
cudaStatus = cudaGetLastError();
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "ERROR: %s\n", cudaGetErrorString(cudaStatus));
exit(-1);
}
}
return 0;
}
OUTPUT:
"ERROR: kernel launch failed."
Summary:
How can I print the contents of the array of structs from the kernel, without passing it as a kernel argument?
Coding in C using VS2019 with CUDA 10.2
With the help of #Robert Crovella and #talonmies, here is the solution that outputs a sequence that cycles from 0 to 9 repeatedly.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
#define BLOCK 256
//#include "Nbody.h"
struct nbody {
float x, y, vx, vy, m;
};
typedef struct nbody nbody;
// Global declarations
nbody* particle;
// Device variables
__device__ unsigned int d_N; // Kernel can successfully access this
__device__ nbody* d_particle;
//__device__ nbody d_particle; // Update: part of problem was here with (*)
// Aim of kernel: to print contents of array of structs without using kernel argument
__global__ void step_cuda_v1() {
int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < d_N) {
printf("%.f\n", d_particle[i].x);
}
}
int main() {
unsigned int N = 10;
unsigned int I = 1;
cudaMallocHost((void**)&particle, N * sizeof(nbody)); // Host allocation
cudaError_t cudaStatus;
for (int i = 0; i < N; i++) particle[i].x = i;
nbody* particle_buf; // device buffer
cudaSetDevice(0);
cudaMalloc((void**)&particle_buf, N * sizeof(nbody)); // Allocate device mem
cudaMemcpy(particle_buf, particle, N * sizeof(nbody), cudaMemcpyHostToDevice); // Copy data into device mem
cudaMemcpyToSymbol(d_particle, &particle_buf, sizeof(nbody*)); // Copy pointer to data into __device__ var
cudaMemcpyToSymbol(d_N, &N, sizeof(unsigned int)); // This works fine
int NThreadBlock = (N + BLOCK - 1) / BLOCK;
for (int iteration = 0; iteration <= I; iteration++) {
step_cuda_v1 << <NThreadBlock, BLOCK >> > ();
//step_cuda_v1 << <1, 5 >> > (particle_buf);
cudaDeviceSynchronize();
cudaStatus = cudaGetLastError();
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "ERROR: %s\n", cudaGetErrorString(cudaStatus));
exit(-1);
}
}
return 0;
}
I need to get both /dev/random and /dev/urandom within kernel module.
get_random_bytes API provided to get /dev/urandom.
But there is no API for /dev/random so I tried to ioctl and read file in kernel space.
Here is what I have done.
using RNDGETPOOL ioctl
in include/linux/random.h
RNDGETPOOL is declared
/* Get the contents of the entropy pool. (Superuser only.) */
#define RNDGETPOOL _IOR( 'R', 0x02, int [2] )
but, It won't work so I checked driver/char/random.h noticed RNDGETPOOL is gone!!
static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
int size, ent_count;
int __user *p = (int __user *)arg;
int retval;
switch (cmd) {
case RNDGETENTCNT:
/* inherently racy, no point locking */
if (put_user(input_pool.entropy_count, p))
return -EFAULT;
return 0;
case RNDADDTOENTCNT:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (get_user(ent_count, p))
return -EFAULT;
credit_entropy_bits(&input_pool, ent_count);
return 0;
case RNDADDENTROPY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (get_user(ent_count, p++))
return -EFAULT;
if (ent_count < 0)
return -EINVAL;
if (get_user(size, p++))
return -EFAULT;
retval = write_pool(&input_pool, (const char __user *)p,
size);
if (retval < 0)
return retval;
credit_entropy_bits(&input_pool, ent_count);
return 0;
case RNDZAPENTCNT:
case RNDCLEARPOOL:
/* Clear the entropy pool counters. */
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
rand_initialize();
return 0;
default:
return -EINVAL;
}
}
I searched google and find out ioctl RNDGETPOOL is removed. done!
using random_read function from driver/char/random.c:997
static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
here is my kernel module's function accesses to /dev/random.
static void read_file()
{
struct file *file;
loff_t pos = 0;
//ssize_t wc;
unsigned char buf_ent[21]={0,};
int ent_c;
int i;
ssize_t length = 0;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
file = filp_open("/dev/random", O_WRONLY, 0);
file->f_op->unlocked_ioctl(file, RNDGETENTCNT, &ent_c);
if(ent_c < sizeof(char))
{
printk("not enough entropy\n");
}
printk("ent counter : %d\n", ent_c);
//file->f_op->unlocked_ioctl(file, RNDGETPOOL, &ent_st.buf);
length = file->f_op->read(file, buf_ent, ent_c/ 8, &pos);
if(length <0)
{
printk("failed to random_read\n");
}
printk("length : %d\n", length);
printk("ent: ");
for(i=0;i<length; i++)
{
printk("%02x", buf_ent[i]);
}
printk("\n");
filp_close(file,0);
set_fs(old_fs);
}
outputs seems to be random
first try
[1290902.992048] ent_c : 165
[1290902.992060] length : 20
[1290902.992060] ent: d89290f4a5eea8e087a63943ed0129041e80b568
second try
[1290911.493990] ent_c : 33
[1290911.493994] length : 4
[1290911.493994] ent: 7832640a
by the way random_read function argument has __user keyword. Buf buf in code is in kernel space.
Is appropriate using random_read function in kernel space??
The in-kernel interface to get random bytes is get_random_bytes():
static void read_file(void)
{
unsigned char buf_ent[21];
get_random_bytes(buf_ent, 21);
print_hex_dump_bytes("ent: ", DUMP_PREFIX_NONE, buf_ent, 21);
}
I have 4 filepaths in the global_filetable and I am trying to scatter 2 pilepaths to each process.
The process 0 have proper 2 paths, but there is something strange in the process 1 (null)...
EDIT:
Here's the full code:
#include <stdio.h>
#include <limits.h> // PATH_MAX
#include <mpi.h>
int main(int argc, char *argv[])
{
char** global_filetable = (char**)malloc(4 * PATH_MAX * sizeof(char));
for(int i = 0; i < 4; ++i) {
global_filetable[i] = (char*)malloc(PATH_MAX *sizeof(char));
strncpy (filetable[i], "/path/", PATH_MAX);
}
/*for(int i = 0; i < 4; ++i) {
printf("%s\n", global_filetable[i]);
}*/
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
char** local_filetable = (char**)malloc(2 * PATH_MAX * sizeof(char));
MPI_Scatter(global_filetable, 2*PATH_MAX, MPI_CHAR, local_filetable, 2*PATH_MAX , MPI_CHAR, 0, MPI_COMM_WORLD);
{
/* now all processors print their local data: */
for (int p = 0; p < size; ++p) {
if (rank == p) {
printf("Local process on rank %d is:\n", rank);
for (int i = 0; i < 2; i++) {
printf("path: %s\n", local_filetable[i]);
}
}
MPI_Barrier(MPI_COMM_WORLD);
}
}
MPI_Finalize();
return 0;
}
Output:
Local process on rank 0 is:
path: /path/
path: /path/
Local process on rank 1 is:
path: (null)
path: (null)
Do you have any idea why I am having those nulls?
First, your allocation is inconsistent:
char** local_filetable = (char**)malloc(2 * PATH_MAX * sizeof(char));
The type char** indicates an array of char*, but you allocate a contiguous memory block, which would indicate a char*.
The easiest way would be to use the contiguous memory as char* for both global and local filetables. Depending on what get_filetable() actually does, you may have to convert. You can then index it like this:
char* entry = &filetable[i * PATH_MAX]
You can then simply scatter like this:
MPI_Scatter(global_filetable, 2 * PATH_MAX, MPI_CHAR,
local_filetable, 2 * PATH_MAX, MPI_CHAR, 0, MPI_COMM_WORLD);
Note that there is no more displacement, every rank just gets an equal sized chunk of the contiguous memory.
The next step would be to define a C and MPI struct encapsulating PATH_MAX characters so you can get rid of the constant usage of PATH_MAX and crude indexing.
I think this is much nicer (less complex, less memory management) than using actual char**. You would only need that if memory waste or redundant data transfer becomes an issue.
P.S. Make sure to never put in more than PATH_MAX - 1 characters in an filetable entry to keep space for the tailing \0.
Okay, I'm stupid.
char global_filetable[NUMBER_OF_STRINGS][PATH_MAX];
for(int i = 0; i < 4; ++i) {
strcpy (filetable[i], "/path/");
}
char local_filetable[2][PATH_MAX];
Now it works!
I am following a source code on my documents, but I encounter an error when I try to use MPI_Send() and MPI_Recv() from Open MPI library.
I have googled and read some threads in this site but I can not find the solution to resolve my error.
This is my error:
mca_oob_tcp_msg_recv: readv faled : Unknown error (108)
Here is details image:
And this is the code that I'm following:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argv, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0/n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
I commented all of MPI_Send(), and MPI_Recv(), and my program worked. In other hand, I commented either MPI_Send() or MPI_Recv(), and I still got that error. So I think the problem are MPI_Send() and MPI_Recv() functions.
P.S.: I'm using Open MPI v1.6 on Windows 8.1 OS.
You pass in the wrong arguments to MPI_Init (two times argv, instead of argc and argv once each).
The sends and receives actually look fine, I think. But there is also one typo in one of your prints with a /n instead of \n.
Here is what works for me (on MacOSX, though):
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0\n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
If this does not work, I'd guess your OS does not let the processes communicate with each other via the method chosen by OpenMPI.
Set MPI_STATUS_IGNORED instead of &status in MPI_Recv in both places.
I'm learning Pthreads. My code executes the way I want it to, I'm able to use it. But it gives me a warning on compilation.
I compile using:
gcc test.c -o test -pthread
with GCC 4.8.1. And I get the warning
test.c: In function ‘main’:
test.c:39:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
pthread_create(&(tid[i]), &attr, runner, (void *) i);
^
test.c: In function ‘runner’:
test.c:54:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int threadnumber = (int) param;
^
This error comes for the following code:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_THREADS 10
int sum; /* this data is shared by the thread(s) */
void *runner(void * param);
int main(int argc, char *argv[])
{
int num_threads, i;
pthread_t tid[MAX_THREADS]; /* the thread identifiers */
pthread_attr_t attr; /* set of thread attributes */
if (argc != 2) {
fprintf(stderr, "usage: test <integer value>\n");
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) <= 0) {
fprintf(stderr,"%d must be > 0\n", atoi(argv[1]));
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) > MAX_THREADS) {
fprintf(stderr,"%d must be <= %d\n", atoi(argv[1]), MAX_THREADS);
exit(EXIT_FAILURE);
}
num_threads = atoi(argv[1]);
printf("The number of threads is %d\n", num_threads);
/* get the default attributes */
pthread_attr_init(&attr);
/* create the threads */
for (i=0; i<num_threads; i++) {
pthread_create(&(tid[i]), &attr, runner, (void *) i);
printf("Creating thread number %d, tid=%lu \n", i, tid[i]);
}
/* now wait for the threads to exit */
for (i=0; i<num_threads; i++) {
pthread_join(tid[i],NULL);
}
return 0;
}
/* The thread will begin control in this function */
void *runner(void * param)
{
int i;
int threadnumber = (int) param;
for (i=0; i<1000; i++) printf("Thread number=%d, i=%d\n", threadnumber, i);
pthread_exit(0);
}
How can I fix this warning?
A quick hacky fix might just to cast to long instead of int. On a lot of systems, sizeof(long) == sizeof(void *).
A better idea might be to use intptr_t.
int threadnumber = (intptr_t) param;
and
pthread_create(&(tid[i]), &attr, runner, (void *)(intptr_t)i);
pthread_create(&(tid[i]), &attr, runner, (void *) i);
You are passing the local variable i as an argument for runner, sizeof(void*) == 8 and sizeof(int) == 4 (64 bits).
If you want to pass i, you should wrap it as a pointer or something:
void *runner(void * param) {
int id = *((int*)param);
delete param;
}
int tid = new int; *tid = i;
pthread_create(&(tid[i]), &attr, runner, tid);
You may just want i, and in that case, the following should be safe (but far from recommended):
void *runner(void * param) {
int id = (int)param;
}
pthread_create(&(tid[i]), &attr, runner, (void*)(unsigned long long)(i));
I was also getting the same warning. So to resolve my warning I converted int to long and then this warning just vanished. And about the warning "cast to pointer from integer of different size" you can leave this warning because a pointer can hold the value of any variable because pointer in 64x is of 64 bit and in 32x is of 32 bit.
Try passing
pthread_create(&(tid[i]), &attr, runner, (void*)&i);