I have compiled part of boost – the ibeta_inv function – into a .Net 64 bit assembly and it worked great until I started calling it from multiple threads. Then it occationally return wrong results.
I complied it using this code (C++/CLI):
// Boost.h
#pragma once
#include <boost/math/special_functions/beta.hpp>
using namespace boost::math;
namespace Boost {
public ref class BoostMath
{
public:
double static InverseIncompleteBeta( double a, double b, double x )
{
return ibeta_inv(a,b,x);
}
};
}
Has anyone tried this before?
I have NOT tried this outside .Net, so I don’t know if this is the cause, but I really don’t see why, since it works great single threaded.
Usage (C#):
private void calcBoost(List<Val> vals)
{
//gives WRONG results (sometimes):
vals.AsParallel().ForAll(v => v.BoostResult = BoostMath.InverseIncompleteBeta(v.A, v.B, v.X));
//gives CORRECT results:
vals.ForEach(v => v.BoostResult = BoostMath.InverseIncompleteBeta(v.A, v.B, v.X));
}
UPDATE: As can be seen in my comments below – I’m not sure at all anymore that this is a Boost problem. Maybe it is some weird PLinq to C++/CLI bug??? I’m blaffed and will return with more facts later.
I happen to have encapsulated part of boost in a C++/CLI 64bit project and use it from C# exactly as you do.
So I threw in your C++ class in my own Boost wrapper and added this code to the C# project:
And it just executes “forever”. The parallel results are equal to the sequential results all the time. No thread unsafety here…
May I suggest that you download a fresh copy of Boost and include it in a completely new project and try this out?
I also notice that you called your result “BoostResult”… and mention in the comments something about “our current implementaion”. Exactly what are you comparing your result agains? What is your definition of “correct”?