[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