IOS 9, IPhone 6S plus, metal, unable to link to function frexp - ios

New to IOS metal and I am trying to write a kernel. My function needs to link to the frexp function. Unfortunately, my kernel referencing the frexp function will not compile.
float exponent = 0.0;
float mantissa = frexp(value, exponent);
The Metal documentation lists the function protocol as:
T frexp(T x, Ti &exp)
I am able to compile to other similar math functions such as exp, exp2, exp10, ldexp.
Has anyone been able to link to Metal's frexp function? Or know how I can view the metal_math include file to see the frexp protocol the compiler is referencing?
Thanks!

After reading my own question I found my mistake, the corrected code looks as follows.
int exponent = 0.0;
float mantissa = frexp(value, exponent);

Related

Scale a range in Dart

I'm trying to find a function which does the same thing as the Map() function in Arduino IDE.
I have an int variable that's coming from an ADC. In my arduino code, I use a simple int variable = map(variable, 0, 4095 , 0, 100);
to change the input of that adc to a 0 to 100 but i'd like to do that in Dart.
Is there a simple function for doing this in flutter?
You can simply multiply your new upper range bound by the existing range expressed as a fraction of 1, using the lower range bound as an offset.
variable = ((upper - lower) * (variable / 4095)) + lower;
If you require an integer, you can utilise a rounding or truncation function as well.
I found myself frequently being in need of such a function in my own projects, so I developed the num_remap package.
Using that package, you can remap integers like this:
import 'package:num_remap/num_remap.dart';
...
variable = variable.remapInt(0, 4095, 0, 100);

Best way to calculate the square root of any number in ios , Objective C and Swift

I am asking for ways to calculate the square root of any given number in ios, Objective C. I have inserted my way to do it using log. the logic was. ex : find the square root of 5
X = √5
then
log10X = log10(√5)
this means
log10X = log10(5)/2;
then should get the value of log10(5) and divide it from 2 and after that shoud get the antilog of that value to search X.
so my answer is in Objective C is like below (as an ex: I'm searching the square root of 5)
double getlogvalue = log10(5)/2; // in here the get the value of 5 in log10 and divide it from two.
//then get the antilog value for the getlogvalue
double getangilogvalue = pow(10,getlogvalue);
//this will give the square root of any number. and the answer may include for few decimal points. so to print with two decimal point,
NSLog(#"square root of the given number is : %.02f", getantilogvalue);
If anyone have any other way/answers. to get the square root of any given value , add please add and also suggestions for above answer is also accepted.
This is open for swift developers too. please add there answers also, becasue this will help to anyone who want to calculate the square root of any given number.
The sqrt function (and other mathematical functions as well) is
available in the standard libraries on all OS X and iOS platforms.
It can be used from (Objective-)C:
#include "math.h"
double sqrtFive = sqrt(5.0);
and from Swift:
import Darwin // or Foundation, Cocoa, UIKit, ...
let sqrtFive = sqrt(5.0)
In Swift 3,
x = 4.0
y = x.squareRoot()
since the FloatingPoint protocol has a squareRoot method and both Float and Double comply with the FloatingPoint protocol. This should be higher performance than the sqrt() function from either Darwin or Glibc, since the code it generates will be from the LLVM built-in square root, so no function call overhead on systems with hardware square root machine code.

iOS warning message : Incompatible pointer types passing 'CGFloat *' (aka 'double *') to parameter of type 'float *'

This is causing my App to act up. this error is happening on this line modff(floatIndex, &intIndex); What do I need to do to fix this issue?
Edit: it is because of &intIndex
- (BOOL)isFloatIndexBetween:(CGFloat)floatIndex {
CGFloat intIndex, restIndex;
restIndex = modff(floatIndex, &intIndex);
BOOL isBetween = fabsf(restIndex - 0.5f) < EPSILON;
return isBetween;
}
As I recall CGFloat is defined as float on 32 bit devices and double on 64 bit devices. Thus you don't want to use CGFloat in a call to modff(). Instead, declare your parameters using a specific type, and use casting.
Something like this (In this case I am using modf and all float variables.
- (BOOL)isFloatIndexBetween:(CGFloat)floatIndex
{
float restIndex;
float first, second;
first = (float) floatIndex;
restIndex = modf(first, &second);
BOOL isBetween = fabsf(restIndex - 0.5f) < EPSILON;
return isBetween;
}
Learning to speak compiler error/warning is an invaluable skill. In this case, it is telling you that modff is expecting a float (that is, a single-precision floating point number), but you're passing it a CGFloat (which is typedef'd as a double, which is a double-precision floating point number). As NobodyNada says, you can either change which function you're using or the type if intIndex.
You are passing CGFloats (typedef'ed to double on your system) to functions that expect floats.
You can either change modff and fabsf to modf and fabs, respectively (slower but more precise), or change intIndex and restIndex to be floats instead of doubles (faster but less precise).
Perhaps the easiest way to avoid these types of warnings and errors when using an architecture specific types like CGFloat is to put #import <tgmath.h> in your precompiled header or the imports for this file. That way the type-generic versions of the underly C functions are used. In this case it makes your warnings go away without any code changes. Then it's just a matter of making sure the precision is what you want.
If you are using 64-bit architectures (like arm64),then you should use CGFloat because it is defined as double and therefore a 8-byte floating point number, whereas float is a 4-byte floating point number.
So you should use these according to architecture.

GLSL code make app crash on iPhone 6 Plus

I found some special GLSL writing style will make iPhone 6 Plus crash without any log.
For example, if you write GLSL like code below, it would crash at glLinkProgram.
float testFun(float co) {
return co;
}
float a = testFun(0.1);
void main()
{
// your code here
}
But if you move the define of "a" into a function, then it would work correctly.
This wouldn't happen in iPhone5 or 5s.
You could reproduce this bug by download the sample project at
http://www.raywenderlich.com/3664/opengl-tutorial-for-ios-opengl-es-2-0
then replace SimpleFragment.glsl with
varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoordOut; // New
uniform sampler2D Texture; // New
precision highp float;
float testFun(float co) {
return co;
}
float a = testFun(0.1);
void main()
{
gl_FragColor = vec4(0.7, 0.5, 0.3, 1.0);
}
and run it on your iPhone 6 Plus. It would crash immediately.
At first, these 3 iPhone you mentioned have 3 different GPU:
iPhone 5 -> SGX543
iPhone 5s -> A7
iPhone 6/Plus -> A8
That means it probably have different driver in iOS, and the glsl shader compile implement will also may be different, but no one actually knows that except Apple's guy. On your side, that means you really need to run/debug your App on real device, but not soft simulator.
On the other hand, your iPhone 5/5s/6 Plus are on the same iOS version, right? [I assume yes, ;)]
Turn back to your question, I think your should not use a global variable like c in your glsl shader, since there are no stack/heap storage layout in shader, but most variables are register.
That means your float a; will hold a register place, and that's limited resources in GPU! it's not recommended to use global variable in glsl, or more clear, in most program language, I think.
You can try to check the status about your shader using the function call like below for more detail explain about your shader's compile failure:
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
glGetProgramInfoLog(program, length, NULL, &log[0]);
Hope it helps.
Your shader code contains an error. This line is invalid:
float a = testFun(0.1);
In the ES 2.0 GLSL spec, section "4.3 Storage Qualifiers" on page 29 says (emphasis added):
Declarations of globals without a storage qualifier, or with just the const qualifier, may include initializers, in which case they will be initialized before the first line of main() is executed. Such initializers must be a constant expression.
Now the question becomes if testFun(0.1) is a constant expression. Section "5.10 Constant Expressions" on page 49 clarifies that:
The following may not be used in constant expressions:
User-defined functions
The fact that the shader compiler crashes looks like an Apple bug. File it with them.

Timeout in CUDA? / fermi / gtx465

I am using CUDA SDK 3.1 on MS VS2005 with GPU GTX465 1 GB. I have such a kernel function:
__global__ void CRT_GPU_2(float *A, float *X, float *Y, float *Z, float *pIntensity, float *firstTime, float *pointsNumber)
{
int holo_x = blockIdx.x*20 + threadIdx.x;
int holo_y = blockIdx.y*20 + threadIdx.y;
float k=2.0f*3.14f/0.000000054f;
if (firstTime[0]==1.0f)
{
pIntensity[holo_x+holo_y*MAX_FINAL_X]=0.0f;
}
for (int i=0; i<pointsNumber[0]; i++)
{
pIntensity[holo_x+holo_y*MAX_FINAL_X]=pIntensity[holo_x+holo_y*MAX_FINAL_X]+A[i]*cosf(k*sqrtf(pow(holo_x-X[i],2.0f)+pow(holo_y-Y[i],2.0f)+pow(Z[i],2.0f)));
}
__syncthreads();
}
and this is function which calls kernel function:
extern "C" void go2(float *pDATA, float *X, float *Y, float *Z, float *pIntensity, float *firstTime, float *pointsNumber)
{
dim3 blockGridRows(MAX_FINAL_X/20,MAX_FINAL_Y/20);
dim3 threadBlockRows(20, 20);
CRT_GPU_2<<<blockGridRows, threadBlockRows>>>(pDATA, X, Y, Z, pIntensity,firstTime, pointsNumber);
CUT_CHECK_ERROR("multiplyNumbersGPU() execution failed\n");
CUDA_SAFE_CALL( cudaThreadSynchronize() );
}
I am loading in loop all the paramteres to this function (for example 4096 elements for each parameter in one loop iteration). In total I want to make this kernel for 32768 elements for each parameter after all loop iterations.
The MAX_FINAL_X is 1920 and MAX_FINAL_Y is 1080.
When I am starting alghoritm first iteration goes very fast and after one or two iteration more I get information about CUDA timeout error. I used this alghoritm on GPU gtx260 and it was doing better as far as I remember...
Could You help me.. maybe I am doing some mistake according to new Fermi arch in this algorithm?
It will be better to call
CUT_CHECK_ERROR after
cudaThreadSynchronize(). Because
kernel run asynchronous and you must
wait for kernel ending to know about
errors... Maybe in second iteration you receive an error
from first kernel usage.
Be sure
that you have some valid number in the most interesting variable
pointsNumber[0] (it might cause a
long internal loop).
You could also
improve speed of your kernel
function:
Use better blocks. Threads configuration 20x20 will cause very slow memory usage (see Programming Guide and Best Practices). Try to use blocks 16x16.
Do not use pow(..., 2.0) function. It's faster to use SQR macro (#define SQR(x) (x)*(x))
You don't use shared mem, so __syncthreads() is not required.
PS: You could also pass value parameters to CUDA functions, not only pointers. Speed will be the same.
PPS: please improve code's readability... Now you must edit six places to change block configuration... Inside the kernel you could use blockDim variable and you could use constants in go2 function.
You could also use bool firstTime - it will be MUCH better then float.
Is your GPU connected to a display? If so, I believe the default is that kernel execution will be aborted after 5 seconds. You can check whether kernel execution will timeout by using cudaGetDeviceProperties - see reference page
In kernel's cycle you write in the same array, from which you read - for global memory usage it is the worst, because warps from different blocks wait for each other.

Resources