I do small operation in opencl using single parameter function as
__kernel void hello(__global int *x){}
While creating program with following code works
ret=clBuildProgram (program,1,&deviceid,Null,Null,Null);
But for code
__kernel void hello(__global int *x,__global int *y){}
The clbulidprogram throws error. What is mistake when loading function more than one parameter.
Related
Im currently working with an UI tool (Qt Creator 9.5.9) to create UI Interfaces. While messing with the tool i came across following problem:
The following code is from an automatically generated cpp file which is generated when creating a new project.
At the top there are a few functions which I assume can be used to access and possibly change data points.
I want to use the function SetWriteDP() to write my data to the data points.
/**
// register ids
bool registerReadIds(const QList<unsigned int> &ids);
bool registerReadIds(const QUintSet &ids);
bool registerReadIds(const QUintSet &ids, void (*func)(void*, const QUintSet &));
bool registerWriteIds(const QList<unsigned int> &ids);
bool registerWriteIds(const QUintSet &ids);
// read data point values
unsigned int GetReadDP(const unsigned int &id) const;
int GetReadDPInt(const unsigned int &id) const;
float GetReadDPFloat(const unsigned int &id) const;
QString GetReadDPString(const unsigned int &id) const;
// write data point values
void SetWriteDP(const unsigned int &id, const unsigned int &value);
void SetWriteDP(const unsigned int &id, const int &value);
void SetWriteDP(const unsigned int &id, const float &value);
void SetWriteDP(const unsigned int &id, const QString &value);
// execute sql statement
QSqlQuery execSqlQuery(const QString &query, bool &success) const;
**/
#include "hmi_api.h"
#include "widget.h"
#include "ui_arbaseform.h"
#include <iostream>
HMI_API::HMI_API(QWidget *parent) :
AbstractAPI(parent), m_ui(NULL)
{
Widget *widget = dynamic_cast<Widget *>(parent);
if(!widget) return;
m_ui = widget->ui;
QUintSet readIdsToRegister, writeIdsToRegister;
writeIdsToRegister.insert(10001);
registerReadIds(readIdsToRegister);
registerWriteIds(writeIdsToRegister);
SetWriteDP(100001, 69);
}
I tried using the function in another cpp file in different ways:
HMI_API.SetWriteDP()
HMI_API.Abstract_API.SetWriteDP()
This resulted in this error: expected unqualified-id before . token
AbstractAPI::SetWriteDP()
which resulted in this error: cannot call member function 'void DPObject::SetWriteDP(const unsigned int&, const int&, unsigned int)' without object AbstractAPI::SetWriteDP();
the i tried making a DPObject which resulted in this error: cannot declare variable 'test' to be of abstract type 'DPObject'
Im really at my wits end now how to access this function. Can someone maybe explain to me what happens after "HMI_API::HMI_API(QWidget *parent) :" and why it is possible to use the function in that block and how i can make it possible for me to use this function.
I tried reading the documentation but nowwhere in the documentation this function is ever mentioned.
The function works in the code snippet i posted but doesnt when i want to use it in another function, i know its because of some stuff regarding classes but im dont understand how to work around this in this case.
Thanks in advance!
how i can make it possible for me to use this function.
I might be wrong but from my understanding of C++ you would first have to create an object of the class, in this case that would be
HMI_API *uiName = new HMI_API(some_parent_obj);
With QWidget being your earlier created QWidget, you can then call the function using a .
uiName.SetWriteDP(x,y);
Can someone maybe explain to me what happens after "HMI_API::HMI_API(QWidget *parent) :
after "HMI_API::HMI_API(QWidget *parent)" the class makes it clear that it inherits base functionality from the classes AbstractAPI and m_ui, you can learn more about inheritance here :https://www.learncpp.com/cpp-tutorial/basic-inheritance-in-c/
Afterwards im not sure but it looks like it just creates some basic functionality so you can call the functions using the class.
I found an answer to my problem which in hindsight might have been obvious but i dont know how i should have known.
I was able to use the functions by declaring a new function like this:
void HMI_API::myFunction(int arg1){
my code with the functions i wanted to use
}
I really hope this will help someone that might had some understanding problems as well.
Suppose some kernel (a __global__ function named foo) is running on a CUDA device. And suppose that kernel calls a __device__ function bar which is sometimes called from other kernels, i.e. the code of bar does not know at compile-time whether the kernel is foo or something else.
Can a thread running foo, within bar, obtain either the name "foo", the signature, or some other identifier of the kernel, preferable a human-readable one?
If necessary, assume the code has been compiled with any of --debug, --device-debug and/or --lineinfo.
The kernel can read the special register %gridid. %gridid is unique per launch. If performance then a simple kernel prolog can have one thread from each kernel launch output the gridid global function map using func and %gridid. Alternatively, the CUPTI SDK Activity API can be used to collect this information. The CUpti_ActivityKernel2 event contains per launch meta-data including the gridId and CUfunction name.
Here is an example reading %gridid.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdint.h>
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
static __device__ __inline__ uint64_t __gridid()
{
uint64_t gridid;
asm volatile("mov.u64 %0, %%gridid;" : "=l"(gridid));
return gridid;
}
__device__ void devPrintName()
{
static const char* name = __func__;
printf("%llu %s\n", __gridid(), name);
}
__global__ void globPrintName()
{
static const char* name = __func__;
printf("%llu %s\n", __gridid(), name);
devPrintName();
}
int main()
{
for (int i = 0; i < 4; ++i)
{
globPrintName<<<1,1,0>>>();
cudaDeviceReset();
}
return 0;
}
This sample outputs
1 globPrintName
1 devPrintName
2 globPrintName
2 devPrintName
3 globPrintName
3 devPrintName
4 globPrintName
4 devPrintName
Since Kernel Code in PyOpenCl needs to be written only in C, I have written few functions that need to be called inside the Kernel code in PyOpenCL.Where should I store these functions? how to pass a global variable to that function.
In PyOpenCl my kernel code looks like this:
program = cl.Program(context, """
__kernel void Kernel_OVERLAP_BETWEEN_N_IP_GPU(__constant int *FBNs_array,__local int *Binary_IP, __local int *cc,__global const int *olp)
{
function1(int *x, int *y,__global const int *olp);
}
""").build()
Where should I write and store the function1 function. should I define it in kernel itself, or in some other file and provide a path. If i need to define it at some other place and provide a path, please provide me some details , I am completely new to C.
Thanks
Like in C, before the kernel.
program = cl.Program(context, """
void function1(int *x, int *y)
{
//function1 code
}
__kernel void kernel_name()
{
function1(int *x, int *y);
}""").build()
program = cl.Program(context, """
void function1(int x, int *y,__global const int *cc)
{
x=10;
}
__kernel void kernel_name(__global const int *cc)
{
int x=1;
int y[1]={10};
function1(x,y,cc); //now x=10
}""").build()
I have instructions to use:
__kernel void myKernel(__global const unsigned int4* data
But I get CL_INVALID_PROGRAM_EXECUTABLE whenever I try to build it. However, both of these build without error:
__kernel void myKernel(__global const int4* data
__kernel void myKernel(__global const unsigned int* data
"unsigned int" is a valid type, but "unsigned int4" is not. I think what you're looking for is "uint4". See section 6.1.2 of the specification ("Built-in Vector Data Types").
Why is the following allowed in gcc :
void **p1, **p2;
p1=*p2;
but this generates an "assignment from incompatible pointer type" error?
char **p1, **p2;
p1=*p2;
Because *p2 is of type void *, which is the generic (data) pointer type. That means, you can assign any data pointer type to a pointer of type void *, and you can also assign a void * to any type of data pointer. So
(some void **) = (some void *);
is valid.
However, char ** and char * are pointers to different types and neither of them is void *, so you can't assign one to another.
You need:
char **p1, **p2;
/* Make sure p2 has a valid value (i.e. points to a valid memory location) before the following statement */
p1=p2;
The reason it works between void** being assigned a void* is because void pointers can point to anything.