[CppAD] Multithreading

Dominik Skanda Dominik.Skanda at biologie.uni-freiburg.de
Fri Mar 16 14:05:26 EDT 2012


Hello,

I have played a little bit more with threading and CppAD and found out
that one can use the Forward routine of an ADFun object with
posix-threads, if  one copies for each thread an ADFUN object and before
going parallel ensure that one executes for each ADFun object the
function capacity_taylor such that the memory for the needed degree of
taylor polynomials is available to the ADFun object and compile the
program with DNDEBUG, i.e.


the program main.cpp works compiled with "g++ main.cpp -I./ -DNDEBUG -g
-lpthread" where main,cpp is given by:


#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=10;
	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);
		}


	for (i=0;i<loop;i++)
		{
			y=((THREAD_DATA*)data)->fun.Forward(1,x);
		}
	return NULL; 
}
 

 
int main (int argc, char *argv[])
{
	
  // TAPING THE FUNCTION 	
	
  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;
  fun.Dependent(x,y);
  fun.optimize();
 
  fun.capacity_taylor(2);
  
  // creating data for posix threads
    
  struct THREAD_DATA dataThread1, dataThread2;
  
  dataThread1.fun=fun;
  dataThread1.threadNumber=1;
  dataThread2.fun=fun;
  dataThread2.threadNumber=2;
  
  // creating threads
  
  pthread_t executionThread[2];
 
  int status;
  
  // executing threads
  
  status=pthread_create
(&(executionThread[0]),NULL,start_CppAD,&dataThread1); 
  status=pthread_create
(&(executionThread[1]),NULL,start_CppAD,&dataThread2);
 
  // joining threads
  
  status=pthread_join((executionThread[0]),NULL);
  status=pthread_join((executionThread[1]),NULL);
  
  return 0;
}





BUT if I want to do the same for the reverse functions valgrind
--tool=helgrind complains! This is following program doesn't work
without complaining:

main.cpp:


#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=10;
	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);
		}


	for (i=0;i<loop;i++)
		{
			y=((THREAD_DATA*)data)->fun.Forward(1,x);
		}
    
    	for (i=0;i<loop;i++)
		{
			vector< double > w(1);
			w[0]=1;
			((THREAD_DATA*)data)->fun.Reverse(1,w);
		}
	return NULL; 
}
 

 
int main (int argc, char *argv[])
{
	
  // TAPING THE FUNCTION 	
	
  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;
  fun.Dependent(x,y);
  fun.optimize();
 
  fun.capacity_taylor(2);
  
  // creating data for posix threads
    
  struct THREAD_DATA dataThread1, dataThread2;
  
  dataThread1.fun=fun;
  dataThread1.threadNumber=1;
  dataThread2.fun=fun;
  dataThread2.threadNumber=2;
  
  // creating threads
  
  pthread_t executionThread[2];
 
  int status;
  
  // executing threads
  
  status=pthread_create
(&(executionThread[0]),NULL,start_CppAD,&dataThread1); 
  status=pthread_create
(&(executionThread[1]),NULL,start_CppAD,&dataThread2);
 
  // joining threads
  
  status=pthread_join((executionThread[0]),NULL);
  status=pthread_join((executionThread[1]),NULL);
  
  return 0;
}

It would be great if the reverse mode would work the same way, since
this would totally fit my needs!

Many thanks ...


Dominik




More information about the CppAD mailing list