~ubuntu-branches/ubuntu/maverick/openturns/maverick

« back to all changes in this revision

Viewing changes to lib/test/external_code_threads.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2010-05-10 17:27:55 UTC
  • mfrom: (1.1.4 upstream) (5.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100510172755-cb5ynskknqqi5rhp
Tags: 0.13.2-2ubuntu1
* Merge with Debian testing. No changes left.
* ubuntu_fix-python-2.6.patch: fix detection of python 2.6 libs, to not use
  LOCALMODLIBS. This pulls a dependency on SSL and makes the package FTBFS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *  @file  external_code_threads.cxx
4
4
 *  @brief 
5
5
 *
6
 
 *  (C) Copyright 2005-2007 EDF-EADS-Phimeca
 
6
 *  (C) Copyright 2005-2010 EDF-EADS-Phimeca
7
7
 *
8
8
 *  This library is free software; you can redistribute it and/or
9
9
 *  modify it under the terms of the GNU Lesser General Public
20
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21
21
 *
22
22
 *  @author: $LastChangedBy: dutka $
23
 
 *  @author: $LastChangedBy: dutka $
24
 
 *  @date:   $LastChangedDate: 2009-04-30 12:04:13 +0200 (jeu. 30 avril 2009) $
25
 
 *  Id:      $Id: external_code_threads.cxx 1219 2009-04-30 10:04:13Z dutka $
 
23
 *  @date:   $LastChangedDate: 2010-02-04 16:44:49 +0100 (jeu. 04 févr. 2010) $
 
24
 *  Id:      $Id: external_code_threads.cxx 1473 2010-02-04 15:44:49Z dutka $
26
25
 */
27
 
#include <iostream>
28
 
#include <cmath>
29
 
#include <cstdio>
30
 
#include <cstdlib>
31
 
#include <pthread.h>
 
26
#include "OTconfig.hxx" // Only needed for test wrappers
32
27
#include "WrapperInterface.h"
33
28
#include "WrapperCommon.h"
 
29
#include "WrapperMacros.h"
 
30
 
 
31
 
 
32
/*
 
33
 *  This is the declaration of function named 'smallest' into the wrapper.
 
34
 */
 
35
  
34
36
 
35
37
extern "C" {
36
38
 
37
39
 
38
 
  /*
 
40
/*
39
41
******************************************************************************************
40
42
*                                                                                        *
41
 
*                             external_code function                                 *
 
43
*                                  smallest function                                     *
42
44
*                                                                                        *
43
45
******************************************************************************************
44
46
*/
45
47
 
46
 
 
47
 
 
48
 
  /* The wrapper information informs the NumericalMathFunction object that loads the wrapper of the
49
 
   * signatures of the wrapper functions. In particular, it hold the size of the input NumericalPoint
50
 
   * (inSize_) and of the output NumericalPoint (outSize_).
51
 
   * Those information are also used by the gradient and hessian functions to set the correct size
52
 
   * of the returned matrix and tensor.
53
 
   */
54
 
 
55
 
 
56
 
  /* Wrapper information */
57
 
  static struct WrapperInformation info_external_code = {/* inSize_  = */ 4,
58
 
                                                             /* outSize_ = */ 1};
59
 
 
60
 
  enum WrapperErrorCode func_getInfo_external_code(void * p_state, struct WrapperInformation * p_info)
61
 
  {
62
 
    *p_info = info_external_code;
63
 
    return WRAPPER_OK;
64
 
  }
 
48
#define WRAPPERNAME external_code
65
49
 
66
50
  /**
67
51
   * Execution function
71
55
   * This function has a mathematical meaning. It operates on one vector (aka point) and
72
56
   * returns another vector.
73
57
   */
74
 
  enum WrapperErrorCode func_exec_external_code(void * p_state, const struct point * inPoint, struct point * outPoint)
75
 
  {
76
 
    if ( (inPoint->size_ != info_external_code.inSize_) ||
77
 
         (outPoint->size_ != info_external_code.outSize_) ) return WRAPPER_WRONG_ARGUMENT;
78
 
    // First initialize the output point to the null vector
79
 
    for (long i = 0; i < info_external_code.outSize_; i++)
80
 
      {
81
 
        outPoint->data_[i] = 0.0;
82
 
      }
83
 
    // Search the fixed point of the contraction by a fixed number of iterations
84
58
#define NUM_LOOPS 1000000
85
 
    for (long i = 0; i < NUM_LOOPS; i++)
86
 
      {
87
 
        outPoint->data_[i % info_external_code.outSize_] = inPoint->data_[i % info_external_code.inSize_] + outPoint->data_[(i + 1) % info_external_code.outSize_];
88
 
      }
89
 
 
90
 
    return WRAPPER_OK;
91
 
  }
92
 
 
93
 
  struct job {
94
 
    void * p_state;
95
 
    const struct sample * inSample;
96
 
    struct sample * outSample;
97
 
    int begin;
98
 
    int end;
99
 
  };
100
 
 
101
 
  void* threadExecute(void* arg)
102
 
  {
103
 
    struct job * localJob = (struct job*) arg;
104
 
    int begin(localJob->begin);
105
 
    int end(localJob->end);
106
 
    for (int i = begin; i < end; i++)
107
 
      {
108
 
        func_exec_external_code(localJob->p_state, &(localJob->inSample->data_[i]), &(localJob->outSample->data_[i]));
109
 
      }
110
 
    return NULL;
111
 
  }
112
 
 
113
 
  /**
114
 
   * Execution function over a sample
115
 
   * This function is called by the platform to do the real work of the wrapper. It may be
116
 
   * called concurrently, so be aware of not using shared or global data not protected by
117
 
   * a critical section.
118
 
   * This function has a mathematical meaning. It operates on one vector (aka point) and
119
 
   * returns another vector.
120
 
   */
121
 
  enum WrapperErrorCode func_exec_sample_external_code(void * p_state, const struct sample * inSample, struct sample * outSample)
122
 
  {
123
 
#define NUM_THREADS 4
124
 
    pthread_t thread[NUM_THREADS];
125
 
    struct job jobs[NUM_THREADS];
126
 
    pthread_attr_t attr;
127
 
    int rc, status;
128
 
 
129
 
    /* Initialize and set thread detached attribute */
130
 
    pthread_attr_init(&attr);
131
 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
132
 
 
133
 
    int size(inSample->size_);
134
 
    for(int t = 0; t < NUM_THREADS; t++)
135
 
      {
136
 
        jobs[t].p_state = p_state;
137
 
        jobs[t].inSample = inSample;
138
 
        jobs[t].outSample = outSample ;
139
 
        jobs[t].begin = (t * size) / NUM_THREADS;
140
 
        jobs[t].end = ((t + 1) * size) / NUM_THREADS;
141
 
        rc = pthread_create(&thread[t], &attr, threadExecute, (void *) &jobs[t]); 
142
 
        if (rc)
143
 
          {
144
 
            printf("ERROR; return code from pthread_create() is %d\n", rc);
145
 
            exit(-1);
146
 
          }
147
 
      }
148
 
 
149
 
    /* Free attribute and wait for the other threads */
150
 
    pthread_attr_destroy(&attr);
151
 
    for(int t = 0; t < NUM_THREADS; t++)
152
 
      {
153
 
        rc = pthread_join(thread[t], (void **)&status);
154
 
        if (rc)
155
 
          {
156
 
            printf("ERROR; return code from pthread_join() is %d\n", rc);
157
 
            exit(-1);
158
 
          }
159
 
        std::cerr << "Completed join with thread " << t << " status= " << status << std::endl;
160
 
      }
161
 
 
162
 
    return WRAPPER_OK;
163
 
  }
164
 
 
165
 
 
 
59
  FUNC_EXEC( WRAPPERNAME , 
 
60
             {
 
61
               const long inSize  = getNumberOfVariables(p_exchangedData, WRAPPER_IN);
 
62
               const long outSize = getNumberOfVariables(p_exchangedData, WRAPPER_OUT);
 
63
 
 
64
               // First initialize the output point to the null vector
 
65
               for (long i = 0; i < outSize; i++) outPoint->data_[i] = 0.0;
 
66
 
 
67
               // Search the fixed point of the contraction by a fixed number of iterations
 
68
               for (long i = 0; i < NUM_LOOPS; i++)
 
69
                 outPoint->data_[i % outSize] = inPoint->data_[i % inSize] + outPoint->data_[(i + 1) % outSize];
 
70
             } )
 
71
 
 
72
 
 
73
  FUNC_EXEC_SAMPLE_MULTITHREADED( WRAPPERNAME )
166
74
 
167
75
 
168
76
} /* end extern "C" */