So I have an openCL program where some of the variables are in float2 and some are in double2. And I would like to either upcast or downcast these variables but I am not sure how to do it. I tried to explicitly casting it like how I would normally do for float and double but it didn't work.
float2 a,b;
double2 c,d;
a = (float2)(c+d); //didnt work
a = float2(c+d); //didnt work
Maybe I am not understanding the type "float2" and "double2", could someone tell me how to cast them in order to work properly?
Thanks in advance.
The floatn and doublen type families represent vectors of values (in your case they have 2 members). A C-style conversion does not work on them.
There is a family of conversion functions that work for vectors that look like this:
convert_float2(vec2)
However, reading the documentation here it looks like conversion from/to double2 is not supported. That leaves you with the option of performing the conversions manually:
a.x = float(c.x + d.x);
a.y = float(c.y + d.y);
Related
I'm having a problem initializing an arrayfire array from host data.
The following code will not link for me:
constexp int mNumEigenInfos = 100;
std::complex<float> mEigenVectors[mNumEigenInfos][6];
af::array mEigenVectorsArray = af::array((dim_t)6,(dim_t)(mNumEigenInfos),reinterpret_cast<float2*>(mEigenVectors));
Giving me an error of:
undefined reference to `af::array::array<float2>(long long, long long, float2 const*, af_source)'
Now if i change the reinterpret_cast from float2* to float*:
constexp int mNumEigenInfos = 100;
std::complex<float> mEigenVectors[mNumEigenInfos][6];
af::array mEigenVectorsArray = af::array((dim_t)6,(dim_t)(mNumEigenInfos),reinterpret_cast<float*>(mEigenVectors));
It links fine. From reading online, i thought i was supposed to treat complex data as a cuComplex (which casting to float2 or cuComplex gives the exact same error since they are the same thing).
I feel like i'm making a stupid mistake here but can't seem to figure it out.
How am i supposed to initialize an arrayfire array from std::complex host data?
Thank you for your Help
This is kind of similar to the question af::array::device doesn't work with complex arrays please have a look - the only difference is the direction in which complex data is passed.
The following should work fine as std::complex should be ABI compatible with af::cfloat.
af::array mEigenVectorsArray =
af::array((dim_t)6, (dim_t)(mNumEigenInfos),
reinterpret_cast<af::cfloat>(mEigenVectors));
ArrayFire API won't have a symbol for function with float2 type, however it will have the symbol for function with type af::cfloat. Even cuFloatComplext or float2 should also be ABI compatible with af::cfloat I think. So, reinterpret-cast to af::cfloat is what should be done.
I am working on c++, I have a structure with all most 100 float variables within it, and i am going to initialize them with value 0 in no argument constructor ,so which way it is faster?
Type 1:
struct info
{
//no argument constructor
info();
float x1;
float x2;
.
.
.
float x100;
}Info;
info::info()
{
float x1 = 0;
float x2 =0;
.
.
.
.
.
float x100 = 0;
}
//creation
Info* info1 = new Info();
Type2 :
typedef struct info
{
float x1;
float x2;
.
.
.
.
float x100;
}Info;
Info* infoIns = new Info;
memset(infoIns,0,sizeof(Info));
One hundred variables called x1 .. x100 just CALLS out to be an array (or if the number varies, perhaps using a vector)
In which case std::fill(x, x+100, 0.0f) would probably beat all of the choices above.
A better solution is probably to just initialize the whole object:
Info* infoIns = new Info();
or
Info infoIns = {}; // C++11
or
Info infoIns = Info();
Whenever it's a question of performance, the ONLY answer that applies is "what you can measure". I can sit here and explain exactly why in my experience, on my machine (or my machines) method A is faster than method B or method C. But if you are using a different compiler, or have a different processor, that may not apply at all, because the compiler you use is doing something different.
Regardless of which is "faster", you should use a constructor to set the values to zero. If you want to use memset, then by all means do so, but inside the constructor. That way, you won't find some place in the code where you FORGOT to set one of your structures to zero before trying to use it. Bear in mind that setting a struct/class to zero using memset is very dangerous. If the class or struct has virtual member functions (or contain some object that does), this will most likely overwrite the VPTR, which describes the virtual functions. That is a bad thing. So if you want to use memset, use it with x1 and a size of 100 *sizeof(float) (but using an array is probably a better choice again).
In the absence of measurement, clearing will likely be faster but much much nastier, and, if the code you've written is what you actually implemented, the clearing will actually work a lot better. The 2nd way you have is not particularly good style in any case, and you should use member initialisation.
I'd be more inclined to use a std::array (C++11) or a std::vector or even a plain array in any case.
2nd version, apart from already mentioned flaws, actually doesn't guarantee that float values will be 0.0 after memset.
3.9.1 Fundamental types [basic.fundamental]
8
...
The value representation of floating-point types is implementation-defined.
...
Thus you can end up with non zero values in your floating points in case of weird float representation.
As strange as it may seems, I can't find how to cleanly convert a float to an int.
This technique
int int_value = (int)(float_value + 0.5);
triggers a
warning: use of old-style cast
in gcc.
So, what is the modern-style, simple way to convert a float to an int ? (I accept the loss of precision of course)
As Josh pointed out in the comments, + 0.5 is not very reliable. For extra security you could combine a static_cast with std::round like so:
int int_value = static_cast<int>(std::round(float_value));
For the casting part, see this excellent post for an explanation.
try:
int int_value = static_cast<int>(float_value + 0.5);
FYI: different casts in C++ gave a very good explanation about those 4 casts introduced in C++.
You could also consider
int int_value = boost::lexical_cast<int>(float_value);
lexical_cast has the benefit of working for all primitive types, and stl strings etc. It also means you don't have to do the (float_value + 0.5) stuff.
I'm often using the wrong literals in expressions, e.g. dividing a float by an int, like this:
float f = read_f();
float g = f / 2;
I believe that the compiler will in this case first convert the int literal (2) to float, and then apply the division operator. GCC and Clang have always let stuff like that pass, but Visual C++ warns about an implicit conversion. So I have to write it like this:
float f = read_f();
float g = f / 2.0f;
That got me wondering: Should I always use the appropriate literals for float, double, long etc.? I normally use int literals whenever I can get away with it, but I'm not sure if that's actually a good idea.
Is this a likely cause of subtle errors?
Is this only an issue for expressions or also for function parameters?
Are there warning levels for GCC or Clang that warn about such implicit conversions?
How about unsigned int, long int etc?
You should always explicitly indicate the type of literal that you intend to use. This will prevent problems when for example this sort of code:
float foo = 9.0f;
float bar = foo / 2;
changes to the following, truncating the result:
int foo = 9;
float bar = foo / 2;
It's a concern with function parameters as well when you have overloading and templates involved.
I know gcc has -Wconversion but I can't recall everything that it covers.
For integer values that fit in int I usually don't qualify those for long or unsigned as there is usually much less chance there for subtle bugs.
There's pretty much never an absolutely correct answer to a "should" question. Who's going to use this code, and for what? That's relevant here. But also, particularly for anything to do with floats, it's good to get into the habit of specifying exactly the operations you require. float*float is done in single-precision. anything with a double is done double-precision, 2 gets converted to a double so you're specifying different operations here.
The best answer here is What Every Computer Scientist Should Know About Floating-Point Arithmetic. I'd say don't tl;dr it, there are no simple answers with floating point.
I have a class called PointF and it has a constructor that takes a Point, and I keep getting "possible loss of data warnings". How can I show that my intention is in fact to make a float value into an int, among other tings? I tried static_cast and (float) but they did not fix the warning.
For example:
int curPos = ceil(float(newMouseY / font.getLineHeight())) ; //float to int
And
outputChars[0] = uc; //converting from size_t to char
A cast should do the trick; that says "explicitly make this type into that type", which is generally pretty silly for a compiler to warn for:
int curPos = static_cast<int>(ceil(float(newMouseY / font.getLineHeight())));
Or:
outputChars[0] = static_cast<char>(uc);
Make sure the casts you tried were akin to that. You say "I tried ...(float)" which leads me to believe you tried something like this:
int curPos = (float)(ceil(float(newMouseY / font.getLineHeight())));
Which does nothing. The type of the expression is already a float, what would casting it to the same type do? You need to cast it to the destination type.
Keep in mind casts are generally to be avoided. In your first snippet, the cast is sensible because when you quantize something you necessarily need to drop information.
But your second cast is not. Why is uc a size_t in the first place? What happens when the cast does drop information? Is that really a good idea?
You need to cast the result of ceil, preferably with a static_cast.
you may have to use an explicit cast, i.e.
int curPos = int(ceil(...));
You must cast your variable to normally good way change type of her. And if you trying convert size_t to char, then you trying save 4 bytes into 1 byte, data lost is a normal thing in this way.