[CppAD] Posix Threads with CppAD
Dominik Skanda
Dominik.Skanda at biologie.uni-freiburg.de
Thu Aug 11 14:17:07 EDT 2011
Hello,
I have also the needs to use CppAD utilizing Posix Threads.
On the first view it seems to work for me and I don't get any
segmentation faults but if I use "valgrind --tool=drd ./a.out" a tool
for detecting errors in multithreaded C and C++ programs, valgrind
complains sometimes.
In summery I think that the memory assignment operations within a ADFun
object are not thread save but if no memory gets allocated it seems
running fine using Posix Threads.
I have made a small as possible example and appended it further below. I
compiled the example with "g++ -g main.cpp -I./ -lpthread".
It would be gorgeous if the ADFun Object itself would be thread safe
this specially means I think that extending the Taylor Capacity should
be thread safe and the Copy operator, too.
Many thanks and kind regards
Dominik
CODE:
#include <pthread.h>
#include <iostream>
#include <vector>
#include <cppad/cppad.hpp>
using namespace std;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
struct THREAD_DATA{
CppAD::ADFun<double> fun;
int threadNumber;
};
void *start_CppAD(void *data)
{
int loop=1000;
vector< double > x(2);
x[0]=3.78;
x[1]=7.33;
int i;
vector< double > y(1);
y[0]=0.0;
for (i=0;i<loop;i++)
{
y=((THREAD_DATA*)data)->fun.Forward(0,x);
pthread_mutex_lock(&mutex);
cout << i<< " THREAD: " << ((THREAD_DATA*)data)-> threadNumber << "
RESULT FORWARD 0: " << y[0] << endl;
pthread_mutex_unlock(&mutex);
}
for (i=0;i<loop;i++)
{
y=((THREAD_DATA*)data)->fun.Forward(1,x);
((THREAD_DATA*)data)->fun.capacity_taylor(1);
pthread_mutex_lock(&mutex);
cout << i << "THREAD: " << ((THREAD_DATA*)data)-> threadNumber << "
RESULT FORWARD 1: " << y[0] << endl;
pthread_mutex_unlock(&mutex);
}
CppAD::ADFun<double> copyFun;
copyFun=((THREAD_DATA*)data)->fun;
y=copyFun.Forward(0,x);
pthread_mutex_lock(&mutex);
cout << "THREAD: " << ((THREAD_DATA*)data)-> threadNumber << "
RESULT COPY FUN FORWARD 0: " << y[0] << endl;
pthread_mutex_unlock(&mutex);
y=copyFun.Forward(1,x);
pthread_mutex_lock(&mutex);
cout << "THREAD: " << ((THREAD_DATA*)data)-> threadNumber << "
RESULT COPY FUN FORWARD 1: " << y[0] << endl;
pthread_mutex_unlock(&mutex);
return NULL;
}
int main (int argc, char *argv[])
{
vector< CppAD::AD<double> > x(2);
x[0]=3.78;
x[1]=7.33;
CppAD::Independent(x);
vector< CppAD::AD<double> > y(1);
y[0]=sin(x[0])+cos(x[1]);
CppAD::ADFun<double> fun(x, y);
fun.optimize();
vector< double > y_eval_1(1);
vector< double > x_eval_1(2);
x_eval_1[0]=3.78;
x_eval_1[1]=7.33;
y_eval_1=fun.Forward(0,x_eval_1);
fun.Forward(1,x_eval_1);
cout << "MAIN FUNCTION: "<< "RESULT FORWARD 0: " << y_eval_1[0] <<
endl;
struct THREAD_DATA dataThread1, dataThread2;
dataThread1.fun=fun;
dataThread1.threadNumber=1;
dataThread2.fun=fun;
dataThread2.threadNumber=2;
pthread_t executionThread[2];
int status;
status=pthread_create
(&(executionThread[0]),NULL,start_CppAD,&dataThread1);
status=pthread_create
(&(executionThread[1]),NULL,start_CppAD,&dataThread2);
status=pthread_join((executionThread[0]),NULL);
status=pthread_join((executionThread[1]),NULL);
return 0;
}
More information about the CppAD
mailing list