openCL Kernel to calculate Pi is not correct value
up vote
0
down vote
favorite
Good day,
I have an openCL kernel that is using the Leibniz formula to calculate pi. Currently my issue is that the value I get back isn't pi, but instead just 4.
__kernel void calculatePi(int numIterations, __global float *outputPi,
__local float* local_result, int numWorkers)
{
__private const uint gid = get_global_id(0);
__private const uint lid = get_local_id(0);
__private const uint offset = numIterations*gid*2;
__private float sum = 0.0f;
// Have the first worker initialize local_result
if (gid == 0)
{
for (int i = 0; i < numWorkers; i++)
{
local_result[i] = 0.0f;
}
}
// Have all workers wait until this is completed
barrier(CLK_GLOBAL_MEM_FENCE);
// Have each worker calculate their portion of pi
// This is a private value
for (int i=0; i<numIterations; i++)
{
if (i % 2 == 0)
{
sum += 1 / (1 + 2*i + offset);
}
else
{
sum -= 1 / (1 + 2*i + offset);
}
}
// Have each worker move their value to the appropriate
// local_result slot so that the first worker can see it
// when reducing next
local_result[gid] = sum;
// Make sure all workers complete this task before continuing
barrier(CLK_LOCAL_MEM_FENCE);
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = 0;
for (int i = 0; i < numWorkers; i++)
{
outputPi[0] += local_result[i];
}
outputPi[0] *= 4;
}
}
I've steered all of my inputs to my output to verify that they are what I expect. numIterations is 16 and numWorkers is also 16.
When sum is calculated then for the first worker, I would expect the sum to be
1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + 1/17 - 1/19 + 1/21 - 1/23 + 1/25 - 1/27 + 1/29 - 1/31
Using this calculator for the first 16 times, I expect the result to be around 3.2 : https://scratch.mit.edu/projects/19546118/
If I modify my last bit of code to be this so that I can look at a worker's calculated value of "sum":
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = sum * 4;
}
Then the value returned for the first worker is 4 instead of the expected 3.2
Modifying to any other number except lid == 0, all other workers are reporting their sum as 0. So my question is why is that the calculated value? Am I doing something wrong with my sum variable? This should be a private variable and the for loop should be sequential from my understanding for each worker but numerous loops are executed in parallel based on the number of workers.
Here's a link to my github that has the kernel and main code uploaded.
https://github.com/TreverWagenhals/TreverWagenhals/tree/master/School/Heterogeneous%20Computing/Lab2
Thanks
c for-loop kernel opencl pi
add a comment |
up vote
0
down vote
favorite
Good day,
I have an openCL kernel that is using the Leibniz formula to calculate pi. Currently my issue is that the value I get back isn't pi, but instead just 4.
__kernel void calculatePi(int numIterations, __global float *outputPi,
__local float* local_result, int numWorkers)
{
__private const uint gid = get_global_id(0);
__private const uint lid = get_local_id(0);
__private const uint offset = numIterations*gid*2;
__private float sum = 0.0f;
// Have the first worker initialize local_result
if (gid == 0)
{
for (int i = 0; i < numWorkers; i++)
{
local_result[i] = 0.0f;
}
}
// Have all workers wait until this is completed
barrier(CLK_GLOBAL_MEM_FENCE);
// Have each worker calculate their portion of pi
// This is a private value
for (int i=0; i<numIterations; i++)
{
if (i % 2 == 0)
{
sum += 1 / (1 + 2*i + offset);
}
else
{
sum -= 1 / (1 + 2*i + offset);
}
}
// Have each worker move their value to the appropriate
// local_result slot so that the first worker can see it
// when reducing next
local_result[gid] = sum;
// Make sure all workers complete this task before continuing
barrier(CLK_LOCAL_MEM_FENCE);
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = 0;
for (int i = 0; i < numWorkers; i++)
{
outputPi[0] += local_result[i];
}
outputPi[0] *= 4;
}
}
I've steered all of my inputs to my output to verify that they are what I expect. numIterations is 16 and numWorkers is also 16.
When sum is calculated then for the first worker, I would expect the sum to be
1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + 1/17 - 1/19 + 1/21 - 1/23 + 1/25 - 1/27 + 1/29 - 1/31
Using this calculator for the first 16 times, I expect the result to be around 3.2 : https://scratch.mit.edu/projects/19546118/
If I modify my last bit of code to be this so that I can look at a worker's calculated value of "sum":
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = sum * 4;
}
Then the value returned for the first worker is 4 instead of the expected 3.2
Modifying to any other number except lid == 0, all other workers are reporting their sum as 0. So my question is why is that the calculated value? Am I doing something wrong with my sum variable? This should be a private variable and the for loop should be sequential from my understanding for each worker but numerous loops are executed in parallel based on the number of workers.
Here's a link to my github that has the kernel and main code uploaded.
https://github.com/TreverWagenhals/TreverWagenhals/tree/master/School/Heterogeneous%20Computing/Lab2
Thanks
c for-loop kernel opencl pi
I would expect offset = numIterations / (gid*2); or am i wrong?
– OznOg
11 hours ago
No I don't think so. The next term for the next worker (gid==1) should start at 1/33 (I showed the first 16 terms above). So, the offset is 16*1*2 = 32. For the first loop of the for-loop, the calculation would then be + 1/(1 +2(0) + 32) = + 1/33, which is what is expected. Just for sanity, I tried what you said too and it results in a floating point exception (16/(15*2) = 16/30, which is not an integer anymore, so that makes sense that it isn't correct.
– Trever Wagenhals
11 hours ago
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Good day,
I have an openCL kernel that is using the Leibniz formula to calculate pi. Currently my issue is that the value I get back isn't pi, but instead just 4.
__kernel void calculatePi(int numIterations, __global float *outputPi,
__local float* local_result, int numWorkers)
{
__private const uint gid = get_global_id(0);
__private const uint lid = get_local_id(0);
__private const uint offset = numIterations*gid*2;
__private float sum = 0.0f;
// Have the first worker initialize local_result
if (gid == 0)
{
for (int i = 0; i < numWorkers; i++)
{
local_result[i] = 0.0f;
}
}
// Have all workers wait until this is completed
barrier(CLK_GLOBAL_MEM_FENCE);
// Have each worker calculate their portion of pi
// This is a private value
for (int i=0; i<numIterations; i++)
{
if (i % 2 == 0)
{
sum += 1 / (1 + 2*i + offset);
}
else
{
sum -= 1 / (1 + 2*i + offset);
}
}
// Have each worker move their value to the appropriate
// local_result slot so that the first worker can see it
// when reducing next
local_result[gid] = sum;
// Make sure all workers complete this task before continuing
barrier(CLK_LOCAL_MEM_FENCE);
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = 0;
for (int i = 0; i < numWorkers; i++)
{
outputPi[0] += local_result[i];
}
outputPi[0] *= 4;
}
}
I've steered all of my inputs to my output to verify that they are what I expect. numIterations is 16 and numWorkers is also 16.
When sum is calculated then for the first worker, I would expect the sum to be
1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + 1/17 - 1/19 + 1/21 - 1/23 + 1/25 - 1/27 + 1/29 - 1/31
Using this calculator for the first 16 times, I expect the result to be around 3.2 : https://scratch.mit.edu/projects/19546118/
If I modify my last bit of code to be this so that I can look at a worker's calculated value of "sum":
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = sum * 4;
}
Then the value returned for the first worker is 4 instead of the expected 3.2
Modifying to any other number except lid == 0, all other workers are reporting their sum as 0. So my question is why is that the calculated value? Am I doing something wrong with my sum variable? This should be a private variable and the for loop should be sequential from my understanding for each worker but numerous loops are executed in parallel based on the number of workers.
Here's a link to my github that has the kernel and main code uploaded.
https://github.com/TreverWagenhals/TreverWagenhals/tree/master/School/Heterogeneous%20Computing/Lab2
Thanks
c for-loop kernel opencl pi
Good day,
I have an openCL kernel that is using the Leibniz formula to calculate pi. Currently my issue is that the value I get back isn't pi, but instead just 4.
__kernel void calculatePi(int numIterations, __global float *outputPi,
__local float* local_result, int numWorkers)
{
__private const uint gid = get_global_id(0);
__private const uint lid = get_local_id(0);
__private const uint offset = numIterations*gid*2;
__private float sum = 0.0f;
// Have the first worker initialize local_result
if (gid == 0)
{
for (int i = 0; i < numWorkers; i++)
{
local_result[i] = 0.0f;
}
}
// Have all workers wait until this is completed
barrier(CLK_GLOBAL_MEM_FENCE);
// Have each worker calculate their portion of pi
// This is a private value
for (int i=0; i<numIterations; i++)
{
if (i % 2 == 0)
{
sum += 1 / (1 + 2*i + offset);
}
else
{
sum -= 1 / (1 + 2*i + offset);
}
}
// Have each worker move their value to the appropriate
// local_result slot so that the first worker can see it
// when reducing next
local_result[gid] = sum;
// Make sure all workers complete this task before continuing
barrier(CLK_LOCAL_MEM_FENCE);
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = 0;
for (int i = 0; i < numWorkers; i++)
{
outputPi[0] += local_result[i];
}
outputPi[0] *= 4;
}
}
I've steered all of my inputs to my output to verify that they are what I expect. numIterations is 16 and numWorkers is also 16.
When sum is calculated then for the first worker, I would expect the sum to be
1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + 1/17 - 1/19 + 1/21 - 1/23 + 1/25 - 1/27 + 1/29 - 1/31
Using this calculator for the first 16 times, I expect the result to be around 3.2 : https://scratch.mit.edu/projects/19546118/
If I modify my last bit of code to be this so that I can look at a worker's calculated value of "sum":
// Have the first worker add up all of the other worker's values
// to get the final value
if (lid == 0)
{
outputPi[0] = sum * 4;
}
Then the value returned for the first worker is 4 instead of the expected 3.2
Modifying to any other number except lid == 0, all other workers are reporting their sum as 0. So my question is why is that the calculated value? Am I doing something wrong with my sum variable? This should be a private variable and the for loop should be sequential from my understanding for each worker but numerous loops are executed in parallel based on the number of workers.
Here's a link to my github that has the kernel and main code uploaded.
https://github.com/TreverWagenhals/TreverWagenhals/tree/master/School/Heterogeneous%20Computing/Lab2
Thanks
c for-loop kernel opencl pi
c for-loop kernel opencl pi
edited 11 hours ago
OznOg
2,22711324
2,22711324
asked 11 hours ago
Trever Wagenhals
9210
9210
I would expect offset = numIterations / (gid*2); or am i wrong?
– OznOg
11 hours ago
No I don't think so. The next term for the next worker (gid==1) should start at 1/33 (I showed the first 16 terms above). So, the offset is 16*1*2 = 32. For the first loop of the for-loop, the calculation would then be + 1/(1 +2(0) + 32) = + 1/33, which is what is expected. Just for sanity, I tried what you said too and it results in a floating point exception (16/(15*2) = 16/30, which is not an integer anymore, so that makes sense that it isn't correct.
– Trever Wagenhals
11 hours ago
add a comment |
I would expect offset = numIterations / (gid*2); or am i wrong?
– OznOg
11 hours ago
No I don't think so. The next term for the next worker (gid==1) should start at 1/33 (I showed the first 16 terms above). So, the offset is 16*1*2 = 32. For the first loop of the for-loop, the calculation would then be + 1/(1 +2(0) + 32) = + 1/33, which is what is expected. Just for sanity, I tried what you said too and it results in a floating point exception (16/(15*2) = 16/30, which is not an integer anymore, so that makes sense that it isn't correct.
– Trever Wagenhals
11 hours ago
I would expect offset = numIterations / (gid*2); or am i wrong?
– OznOg
11 hours ago
I would expect offset = numIterations / (gid*2); or am i wrong?
– OznOg
11 hours ago
No I don't think so. The next term for the next worker (gid==1) should start at 1/33 (I showed the first 16 terms above). So, the offset is 16*1*2 = 32. For the first loop of the for-loop, the calculation would then be + 1/(1 +2(0) + 32) = + 1/33, which is what is expected. Just for sanity, I tried what you said too and it results in a floating point exception (16/(15*2) = 16/30, which is not an integer anymore, so that makes sense that it isn't correct.
– Trever Wagenhals
11 hours ago
No I don't think so. The next term for the next worker (gid==1) should start at 1/33 (I showed the first 16 terms above). So, the offset is 16*1*2 = 32. For the first loop of the for-loop, the calculation would then be + 1/(1 +2(0) + 32) = + 1/33, which is what is expected. Just for sanity, I tried what you said too and it results in a floating point exception (16/(15*2) = 16/30, which is not an integer anymore, so that makes sense that it isn't correct.
– Trever Wagenhals
11 hours ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
you are performing integral divisions in your code, should be floats:
if (i % 2 == 0)
{
sum += 1. / (1 + 2*i + offset); // notice the 1.
}
else
{
sum -= 1. / (1 + 2*i + offset);
}
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
you are performing integral divisions in your code, should be floats:
if (i % 2 == 0)
{
sum += 1. / (1 + 2*i + offset); // notice the 1.
}
else
{
sum -= 1. / (1 + 2*i + offset);
}
add a comment |
up vote
0
down vote
you are performing integral divisions in your code, should be floats:
if (i % 2 == 0)
{
sum += 1. / (1 + 2*i + offset); // notice the 1.
}
else
{
sum -= 1. / (1 + 2*i + offset);
}
add a comment |
up vote
0
down vote
up vote
0
down vote
you are performing integral divisions in your code, should be floats:
if (i % 2 == 0)
{
sum += 1. / (1 + 2*i + offset); // notice the 1.
}
else
{
sum -= 1. / (1 + 2*i + offset);
}
you are performing integral divisions in your code, should be floats:
if (i % 2 == 0)
{
sum += 1. / (1 + 2*i + offset); // notice the 1.
}
else
{
sum -= 1. / (1 + 2*i + offset);
}
answered 9 hours ago
OznOg
2,22711324
2,22711324
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398186%2fopencl-kernel-to-calculate-pi-is-not-correct-value%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I would expect offset = numIterations / (gid*2); or am i wrong?
– OznOg
11 hours ago
No I don't think so. The next term for the next worker (gid==1) should start at 1/33 (I showed the first 16 terms above). So, the offset is 16*1*2 = 32. For the first loop of the for-loop, the calculation would then be + 1/(1 +2(0) + 32) = + 1/33, which is what is expected. Just for sanity, I tried what you said too and it results in a floating point exception (16/(15*2) = 16/30, which is not an integer anymore, so that makes sense that it isn't correct.
– Trever Wagenhals
11 hours ago