I'm sorry if this is very basic but I'm still learning all that things I can do in C and can't figure out how to do this.
I create pairs of ints in a program and then need to store them. The way I have been doing it so far is by creating a struct:
struct list_el {
short *val; //first value
short *val2; //second value
struct list_el * next;
};
typedef struct list_el item;
I can iterate though the list fine in my normal program but I want to send this to Cuda and am not sure how to transfer the whole struct into Cuda(I know I can make a reference to it). I'm wondering if there's another way I can structure this data so maybe its array? The format I need is in is just simple pairs (something like this 10:5, 20:40, etc..). I thought worst case I can use a char string and have the pairs as characters and then parse them once the main array is in Cuda but I'm wondering if there's a better way create this list of list?
Assuming that you can use two separate arrays, and thinking about how to use/read/write them in CUDA, I will arrange the data in two arrays mainly due to coalesced accesses from global memory wihtin a kernel.
int *h_val1, *h_val2; // allocate arrays in the host and initialize them
Let be N the size of the arrays, allocate the arrays in device memory
int *d_val1, *d_val2;
cudaMalloc( (void**) &d_val1, N * sizeof(int) );
cudaMalloc( (void**) &d_val2, N * sizeof(int) );
and copy data from host to device memory
cudaMemcpy(h_val1, d_val1, N * sizeof(int), cudaMemcpyHostoToDevice);
cudaMemcpy(h_val2, d_val2, N * sizeof(int), cudaMemcpyHostoToDevice);
Configure and launch your kernel to run as much threads as element in the array.
// kernel configuration
dim3 dimBlock = dim3 ( BLK_SIZE, 1, 1 );
dim3 dimGrid = dim3 ( (N / BLK_SIZE) + 1 );
yourKernel<<<dimGrid, dimBlock>>>(d_val1, d_val2);
With this in mind, implement your kernel
__global__ void
yourKernel(int* val1, int* val2, N)
{
// map from threadIdx/BlockIdx to index position
int gid = threadIdx.x + blockIdx.x * blockDim.x;
if (gid < N)
{
int r_val1 = val1[ idx ]; // load from global memory to register
int r_val2 = val2[ idx ]; // load from global memory to register
// do what you need to do with pair val1:val2
}
}
Do not forget to check for errors when calling CUDA functions.
Instead of storing something that references two ints, store something that holds a copy of the ints.
struct list_el {
int val; //first value
int val2; //second value
struct list_el * next;
};
typedef struct list_el item;
Sometimes it is preferable to hold a reference, sometime it is preferable to hold a value. Depending on what you are attempting to do, use the right tool for the job.
By the way, your reference holding struct was only holding references to shorts. To really hold references to ints, you need
struct list_el {
int *val; //reference to first value
int *val2; //reference to second value
struct list_el * next;
};
typedef struct list_el item;
Note that if you hold a reference, the rest of your program should not dispose of the reference's memory before you dispose of the struct reference to prevent accessing memory that is no longer associated with the program (which is an error).
There are other techniques, if you don't want to use list like constructs.
int val[2] = { 1, 2 };
will store two ints, but only two ints.
int val[2][9];
will store nine pairs of two ints, and could easily also be represented as
int val[9][2];
And of course, there is the old standby
int val = 3;
int val2 = 4;
How about just using a two-dimensional array?
int pairs[30][2];
pairs[0][0] = 10;
pairs[0][1] = 5;
// etc.
I'd have to test it, but I think I tested it, and you can even do something like
int pairs[][2] = {{10, 5}, {20, 40}, ...};
for initialization.
NOTE: This method works well if you know how many pairs you will have ahead of time and the number doesn't grow/shrink (in large amounts). If you have a widely variable number of pairs, sticking with a list of structs and using Edwin's answer would probably be better in the long run.
Having a two dimensional array is a good solution, but I am going to answer as if you are keeping your struct solution.
There's nothing wrong with your storing the short ints in a struct, but I would not store the values in short *. To me it is not worth dynamically allocating memory as you need a new structure.
You could have an array of structs to store this data. Here is an example of a fixed size array of item.
#include <stdio.h>
struct list_el {
short val; //first value
short val2; //second value
};
typedef struct list_el item;
item listA[20];
int main()
{
listA[0].val = 1;
listA[0].val2 = 2;
printf("\n%i %i\n", listA[0].val, listA[0].val2);
return 0
}
Even if you make the argument that you won't know in advance how many of these
structs you will have, I would only allocate space for the array like this:
#include <stdio.h>
#include <stdlib.h>
struct list_el {
short val; //first value
short val2; //second value
};
typedef struct list_el item;
item * p_list_el, * pCurStruct;
int main()
{
int idx;
/* p_list_el is the pointer to the array. Don't modify.
pCurStruct can be modified to walk the array. */
p_list_el = malloc(sizeof(item) * 20);
for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
{
pCurStruct[idx].val = idx;
pCurStruct[idx].val2 = idx + 1;
}
for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
{
printf("\n%i %i\n", pCurStruct[idx].val, pCurStruct[idx].val2);
}
free(p_list_el);
}
Related
So, I'm pretty new to the C language and I've been passed a project by my professor to make a game in C. My problem is, I created a structure like so:
typedef struct vector
{
int parts;
int dir;
} Vector;
typedef struct snake
{
Vector* parts;
Vector dir;
} Snake;
I'm trying to initialize the parts pointer within this function:
void init_snake(struct snake *snake, int size, int x, int y)
{
snake->parts = (Vector *)malloc(sizeof(Vector) * size);
for (int i = 0; i < size; i++)
{
//sets the body parts one after the other in a line
snake->parts[i].x = x - i * PIXEL_SIZE;
snake->parts[i].y = y;
}
//sets the snake direction to the left
snake->dir.x = 1;
snake->dir.y = 0;
}
But by doing that the array parts inside the snake pointer is not initialized as expected. By checking its size with sizeof(snake.parts) / sizeof(Vector) it returns 0. Any ideas of how to fix it?
It likely is working, you're just confused about sizeof. This operator measures the size (in bytes) of a type. If you ask for the size of a value, it uses the type of that expression instead.
This is a compile-time evaluation and therefore is not dynamic.
sizeof(snake.parts) is the same as sizeof(Vector*) which will be either 4 or 8 bytes depending on whether you are compiling to a 32-bit or 64-bit target. Therefore, it's not useful to determine the size of an allocation.
Generally, given a pointer, you cannot tell how large the allocation is. Usually this is handled by storing some kind of useful length somewhere else. For example, you could modify struct snake to include an element count for parts:
typedef struct snake
{
Vector* parts;
int parts_size;
Vector dir;
} Snake;
And set this value accordingly:
snake->parts = (Vector *)malloc(sizeof(Vector) * size);
snake->parts_size = size;
I'm developing a driver in C for communication and the messages exchanged don't have a fixed size. The recommendation of communication bus is to use structs for multi-topics, which is also my case.
My 1st problem: I have to keep listening for new messages, and when I get one I have to process message data (it has a delay) and still listening for new messages.
1st solution: using thread when got new messages to process data.
My 2nd problem: Data in message can have multiple data of a struct, and my communicator requires using a struct to organize this multiple values.
2nd solution: using struct hack to allocate memory dynamic size of struct.
My current problem: when I'd pass my struct as argument to the thread, or any function, I'm loosing data structure and getting wrong values.
A short test which a made is:
typedef struct test{
int size;
int value[];
} test;
void allocation(test *v){
test *aux = (test *)malloc(sizeof(test)+3*sizeof(int));
int i;
aux->value[0] = 2;
aux->size = 3;
aux->value[1] = 1;
aux->value[2] = 5;
printf("Teste1 %d\n",aux->size);
for(i=0; i < aux->size; i++){
printf("%d\n", aux->value[i]);
}
*v = *aux;
}
void cleanup(test *v){
free(v);
}
int main(int argc, char *argv[]){
test v;
int i;
allocation(&v);
printf("Teste2 %d\n",v.size);
for(i=0; i < v.size; i++){
printf("%d\n", v.value[i]);
}
//cleanup(&v);
return 0;
}
In this test I got right values in first print and wrong values in second (only v.size is giving a right value).
And my struct is a little more complex than that in test. My struct is like:
typedef struct test1{
double v1;
double v2;
} test1;
typedef struct test2{
int size;
test1 values[];
} test2;
Do you know how to fix my memory struct in that function, once I have all elements necessary to fix? Please, keep in mind that is desirable (not required) that I could also allocate multiple test2 data.
The thing here is that you assign structs with incomplete member int value[]; Though it is in principle OK to copy two structs by value (and this is actually what happens if you write *v = *aux); However, as the compiler does not know which size member value[] will take on at runtime, the "sizeof" of v as well as the size of *aux is always 4, i.e. the known size of the one int member size. Hence, only this is copied, whereas the value[]-array simply gets not copied.
A way out out this situation would be require a pointer to a pointer (i.e. allocation(test **v), such that the memory reserved can be directly assigned to it, using a pointer to struct test in main, i.e. test *vptr, and call allocation(&vptr).
If you cannot avoid passing a reverence to the value (instead of a reference to a pointer to the value), I suppose you'll have to use memcpy to transfer the contents. But this does actually not make sense, because then the receiver must provide enough space to take on the value[]-array in advance (which is not the case if you simple declare a variable of the form test v). An then the malloc and the aux would make no sense; you could directly write into object v passed by reference.
You are declaring v as non-pointer, meaning that the memory is already allocated for v when you declare it in main. Sending the reference to your allocation only copies the size correctly since it is not dynamically allocated. Correct way to do this would be to:
Declare your v as pointer
Make your allocation return test* (test* allocation())
Assign it to v in main. i.e. something like v = allocate()
And use v like a pointer from then on
EDIT: Since OP wants this to work only as arguments, best way to go about it is using double pointer. Check the following code:
typedef struct test{
int size;
int value[];
} test;
void allocation(test **v){
test *aux = (test *)malloc(sizeof(test)+3*sizeof(int));
int i;
aux->value[0] = 2;
aux->size = 3;
aux->value[1] = 1;
aux->value[2] = 5;
printf("Teste1 %d\n",aux->size);
for(i=0; i < aux->size; i++){
printf("%d\n", aux->value[i]);
}
*v = aux;
}
void cleanup(test *v){
free(v);
}
int main(int argc, char *argv[]){
test **v;
v = malloc (sizeof (test*));
int i;
allocation(v);
printf("Teste2 %d\n",(*v)->size);
for(i=0; i < (*v)->size; i++){
printf("%d\n", (*v)->value[i]);
}
//cleanup(&v);
return 0;
}
Please note that your cleanup will change too after this.
How does one build a struct with an array that can be set differently for each struct, ideally by a parameter? The application being a single data type that supports arrays of different, but fixed lengths
My attempt looks somehting like this, which obviously didnt compile:
struct Data_struct(n)
{
int xData[n];
int test;
};
The only method available is to use a flexible array member.
struct Data_struct {
int test;
int xData[];
};
You would then allocate space for this using malloc():
int n = 4;
struct Data_struct *s = malloc(sizeof(struct Data_struct) + n * sizeof(int));
Note that we had to explicitly allocate additional space for the flexible array.
You can dynamically allocate the array
struct Data_struct
{
int * xData;
int test;
};
....
s.xData = calloc(size, sizeof(int))
and remember to free xData when finished
Normally you would define a variable length array at the end of the struct, and then fix up the size at run-time, e.g.
typedef struct
{
int test;
int xData[1];
} Data_struct;
To allocate a struct such as this with a size of n for xData you'd do soemthing like this:
Data_struct * s = malloc(sizeof(Data_struct) + (n - 1) * sizeof(int));
One might call this ugly but here goes. Use a #define
#define foo(n) struct Data_struct##n { int test; int xData[n]; }
foo(20);
struct Data_struct20 abc;
The foo(20) defines a structure with n = 20 characters.
You could use another #define for the allocation of space if you wish.
I'm trying to make a struct that contains another struct with multiple arrays. I need to dynamically allocate those arrays too, so I think I need another pointer still.
int arraysize;
typedef struct Array{
int *size = arraysize;
unsigned int val[*size];
unsigned int x[*size];
unsigned int y[*size];
} Array;
typedef struct Image{
int height;
int width;
int max;
Array *data;
} Image;
OK, so once I finally figure that out, I still need to figure out how to dynamically allocate that memory using malloc. I'm totally lost there too. Any help at all would be greatly appreciated.
EDIT: more clarification:
I'm using the arrays to store three pieces of information that are all connected. Think of a chessboard, you could say knight E4, which tells you that on the 4th column of row E, there is a knight. If you started this process at A1 and ended at K10 you'd have a full chessboard right? The image struct is analogous to the chessboard, the Array is analogous to a list of a bunch of squares that compose the chessboard and the contents of those squares. (E.g. A1 null A2 knight a3 bishop etc...) Unfortunately, I don't know what kind of board will be passed through, it might be a 3x7 board or a 9x2 board etc. So I need to dynamically allocate the memory for those possibilities. Once I have the memory allocated I need to store information about the location and the contents of all of the "squares." Then I need to let a program pass through the height of the board, width of the board and the list of contents and I'd be done the hard part.
What you actually meant was:
typedef struct data {
unsigned int x;
unsigned int y;
unsigned int val;
} Data;
typedef struct image {
int height;
int width;
int max;
Data* data;
} Image;
and somewhere:
Image i;
i.height = 10;
i.width = 20;
i.data = malloc(sizeof(Data) * i.width * i.height);
...
// one of the ways how to access Data at 2nd row, 3rd column:
*(i.data + i.width * 1 + 2).val = 7;
...
free(i.data);
i.data = NULL;
But what you actually need is some good book ;)
Working with this code:
#include <stdlib.h>
#include <stdio.h>
int j_btree_create (int fn_initial_nodes);
typedef struct {
int depth;
int value;
void *item;
void *left_pointer;
void *right_pointer;
} j_btree_node_int;
typedef struct {
int nodes;
int available_nodes;
int btree_extension;
} j_btree_descriptor_int;
int j_btree_create (int fn_initial_nodes) {
int *free_btree_node;
int loop_counter;
j_btree_descriptor_int *btree_start;
btree_start = (j_btree_descriptor_int *) malloc (((sizeof(j_btree_node_int) + sizeof(free_btree_node)) * fn_initial_nodes) + sizeof(j_btree_descriptor_int));
(*btree_start).nodes = fn_initial_nodes;
(*btree_start).available_nodes = fn_initial_nodes;
(*btree_start).extension = NULL; */
for (loop_counter = 0; loop_counter < fn_initial_nodes; loop_counter++) {
printf ("loop_test: %d", loop_counter);
}
}
I want a pointer that points to the location after the binary tree descriptor (basically a struct at btree_start)
Can I do this with by
free_btree_node = btree_start + sizeof(j_btree_descriptor_int);
Or is this liable to go completely wrong? If so how should I do this? I will be doing something similar to initially populate the table of unused binary tree nodes.
If you really want to keep it all in one structure, one approach is to use a 'flexible array member':
typedef struct {
int *value;
j_btree_node_int node;
} j_btree_node;
typedef struct {
j_btree_descriptor_int btree_start;
j_btree_node nodes[0];
} j_btree;
j_btree *btree = malloc(sizeof(j_btree) + fn_initial_nodes * sizeof(j_btree_node));
free_btree_node = &j_btree->nodes[0];
You ask about
free_btree_node = btree_start + sizeof(j_btree_descriptor_int);
Because of the rules of pointer arithmetic, which implicitly multiply an offset by the type's size, that's equivalent to
free_btree_node = &btree_start[sizeof(j_btree_descriptor_int)];
which isn't what you want. What you want is
free_btree_node = (int*)&btree_start[1];
or, equivalently,
free_btree_node = (int*)(btree_start + 1);
Yes, you can do that, since you allocated extra space. But it doesn't really make sense, because you allocated ((sizeof(j_btree_node_int) + sizeof(free_btree_node)) * fn_initial_nodes) extra bytes, which is not a count of ints. It's not clear what you want that to be, but it certainly can't be right because free_btree_node is a pointer and you have no interest in its size ... you probably meant sizeof(*free_btree_node). But your code is impenetrable because there are no comments explaining what things are or why you are doing things. In particular, there should be a comment on your malloc saying exactly what it is you think you are allocing ... maybe even a little diagram. Or you could forego trying to allocate contiguous structures and allocate each sort of thing independently.
(*btree_start).nodes
Please use
btree_start->nodes
It's standard usage, more succinct, more comprehendible ...