how to deal with bit fields in Julia when writing a wrapper of C - julia

typedef struct {
uint32_t is_bin:1, is_write:1, is_be:1, is_cram:1, dummy:28;
int64_t lineno;
kstring_t line;
char *fn, *fn_aux;
union {
BGZF *bgzf;
struct cram_fd *cram;
struct hFILE *hfile;
void *voidp;
} fp;
htsFormat format;
} htsFile;
how to deal with the bit fields part of htsFile in Julia?
If I am not care about the specific value uint32_t is_bin:1, is_write:1, is_be:1, is_cram:1, dummy:28;, can I just use a Cuint variable to repalce it in julia?

can I just use a Cuint variable to replace it in julia?
Yes, the alignment will be the same. If you do need the values, you can use bitmasks to select the required bit(s).
As a side note, the StrPack package may be of interest for dealing with complicated struct [de]serialization (although I don't think it has built-in bitfield support).

You can extract the individual bits using julia'a bitwise manipulation functions (&, >>, etc.) You could define convenience functions like is_bin(x) = (x & 0x01) > 0.

Related

OpenCL Write __global variable

I would like to have a Variable with Read-Access to all kernels/functions inside a CL Program. For this i have created a variable at the top of the File and prefixed it with __global.
typedef struct{
/* whatever */
} GlobalParameters;
__global GlobalParameters params;
how can i set the Values inside that Struct from the Host code now? Is that even Possible, or how can i edit it else? Or do i have to pass it as Parameter to the kernel every time i need it?
Program scope variables are meant to be constants and need to be initialized.
So, this works like:
typedef struct{
float whatever;
} GlobalParameters;
__constant GlobalParameters params=(GlobalParameters){3.14f};
then you can use it anywhere. But if opencl-compile-time is ok for it, you can alter it with string replacement after preaparing the host-side constant buffer:
typedef struct{
float whatever;
} GlobalParameters;
__constant GlobalParameters params=(GlobalParameters){##replace_0##};
if this is used for minutes per change, you can re-compile it using new string replacement before device-kernel-compiling. If there are non-changing sets, you can compile N times for different kernel programs and switch between them using different contexts.

Using async_work_group_copy with a custom data type

I need to copy some data from __global to __local in openCL using async_work_group_copy. The issue is, I'm not using a built-in data type.
The code snip of what I have tried is as follows:
typedef struct Y
{
...
} Y;
typedef struct X
{
Y y[MAXSIZE];
} X;
kernel void krnl(global X* restrict x){
global const Y* l = x[a].y;
local Y* l2;
size_t sol2 = sizeof(l);
async_work_group_copy(l2, l, sol2, 0);
}
where 'a' is just a vector of int. This code does not work, specifically because the gen_type is not a built-in one. The specs (1.2) says:
We use the generic type name gentype to indicate the built-in data
types ... as the type for the arguments unless otherwise stated.
so how do I otherwisely state this data type?
OpenCL async_work_group_copy() is designed to copy N elements of a basic data type. However it does not really know what is being copied. So you can tell it to copy N bytes, containing any type inside (including structs). Similar to memcpy().
You can do:
kernel void krnl(global X* restrict x){
global const Y* l = x[a].y;
local Y l2;
size_t sol2 = sizeof(Y);
async_work_group_copy((local char *)&l2, (global char *)l, sol2, 0);
}
However, remember that you need to declare local memory explicitly in side the kernel, or dinamically from the API side and pass a pointer to local memory.
You can't just create a local pointer without any initialization and copy there. (see my code)

Casting void pointer

I have a struct
struct GROUP_POINTS
{
unsigned char number_of_points;
void *points;
};
struct GROUP_POINTS group_points;
The reason for points being a void pointer is that I want to keep the groups as general as possible, and setting the "link" to the correct struct at runtime.
One of the other structs is:
struct POINT_A
{
unsigned char something;
};
I can make another pointer that points to the *points to get access to the struct like :
struct POINT_A *point_a = (struct POINT_A *)group_points.points;
and then access the points by doing :
(*point_a).number_of_points = 5;
But I would really like to be able to use it like this:
group_points.points.number_of_points
So not needing the second pointer just to point to the void pointer. Is there any way to do this ?
Assuming the language is C++, you may want to consider template solution like that:
template <class T>
struct GROUP_POINTS
{
unsigned char number_of_points;
T *points;
};
typedef GROUP_POINTS<unsigned char> POINT_A;
//another typedefs for another points.
Also, you probably would be fine with just std::vector<T> instead of whole points structs, but just to illustrate general approach this is how it can be done.
Since all you need is to avoid using another pointer, you can use it like this:
((struct POINT_A *)group_points).points.number_of_points = 5;
Note that the type cast has a lower precedence than that of the . operator, the parenthesis is necessary.

OpenCL void pointer arithmetic - strange behavior

I have wrote an OpenCL kernel that is using the opencl-opengl interoperability to read vertices and indices, but probably this is not even important because I am just doing simple pointer addition in order to get a specific vertex by index.
uint pos = (index + base)*stride;
Here i am calculating the absolute position in bytes, in my example pos is 28,643,328 with a stride of 28, index = 0 and base = 1,022,976. Well, that seems correct.
Unfortunately, I cant use vload3 directly because the offset parameter isn't calculated as an absolute address in bytes. So I just add pos to the pointer void* vertices_gl
void* new_addr = vertices_gl+pos;
new_addr is in my example = 0x2f90000 and this is where the strange part begins,
vertices_gl = 0x303f000
The result (new_addr) should be 0x4B90000 (0x303f000 + 28,643,328)
I dont understand why the address vertices_gl is getting decreased by 716,800 (0xAF000)
I'm targeting the GPU: AMD Radeon HD5830
Ps: for those wondering, I am using a printf to get these values :) ( couldn't get CodeXL working)
There is no pointer arithmetic for void* pointers. Use char* pointers to perform byte-wise pointer computations.
Or a lot better than that: Use the real type the pointer is pointing to, and don't multiply offsets. Simply write vertex[index+base] assuming vertex points to your type containing 28 bytes of data.
Performance consideration: Align your vertex attributes to a power of two for coalesced memory access. This means, add 4 bytes of padding after each vertex entry. To automatically do this, use float8 as the vertex type if your attributes are all floating point values. I assume you work with position and normal data or something similar, so it might be a good idea to write a custom struct which encapsulates both vectors in a convenient and self-explaining way:
// Defining a type for the vertex data. This is 32 bytes large.
// You can share this code in a header for inclusion in both OpenCL and C / C++!
typedef struct {
float4 pos;
float4 normal;
} VertexData;
// Example kernel
__kernel void computeNormalKernel(__global VertexData *vertex, uint base) {
uint index = get_global_id(0);
VertexData thisVertex = vertex[index+base]; // It can't be simpler!
thisVertex.normal = computeNormal(...); // Like you'd do it in C / C++!
vertex[index+base] = thisVertex; // Of couse also when writing
}
Note: This code doesn't work with your stride of 28 if you just change one of the float4s to a float3, since float3 also consumes 4 floats of memory. But you can write it like this, which will not add padding (but note that this will penalize memory access bandwidth):
typedef struct {
float pos[4];
float normal[3]; // Assuming you want 3 floats here
} VertexData;

go tour when to not use pointer to struct literal in a variable

Per the Go tour page 28 and page 53
They show a variable that is a pointer to a struct literal. Why is this not the default behavior? I'm unfamiliar with C, so it's hard to wrap my head around it. The only time I can see when it might not be more beneficial to use a pointer is when the struct literal is unique, and won't be in use for the rest program and so you would want it to be garbage collected as soon as possible. I'm not even sure if a modern language like Go even works that way.
My question is this. When should I assign a pointer to a struct literal to a variable, and when should I assign the struct literal itself?
Thanks.
Using a pointer instead of just a struct literal is helpful when
the struct is big and you pass it around
you want to share it, that is that all modifications affect your struct instead of affecting a copy
In other cases, it's fine to simply use the struct literal. For a small struct, you can think about the question just as using an int or an *int : most of the times the int is fine but sometimes you pass a pointer so that the receiver can modify your int variable.
In the Go tour exercises you link to, the Vertex struct is small and has about the same semantic than any number. In my opinion it would have been fine to use it as struct directly and to define the Scaled function in #53 like this :
func (v Vertex) Scaled(f float64) Vertex {
v.X = v.X * f
v.Y = v.Y * f
return v
}
because having
v2 := v1.Scaled(5)
would create a new vertex just like
var f2 float32 = f1 * 5
creates a new float.
This is similar to how is handled the standard Time struct (defined here), which is usually kept in variables of type Time and not *Time.
But there is no definite rule and, depending on the use, I could very well have kept both Scale and Scaled.
You're probably right that most of the time you want pointers, but personally I find the need for an explicit pointer refreshing. It makes it so there's no difference between int and MyStruct. They behave the same way.
If you compare this to C# - a language which implements what you are suggesting - I find it confusing that the semantics of this:
static void SomeFunction(Point p)
{
p.x = 1;
}
static void Main()
{
Point p = new Point();
SomeFunction(p);
// what is p.x?
}
Depend on whether or not Point is defined as a class or a struct.

Resources