1 | //--------------------------------------------------------------------------------
|
---|
2 | // Programme d'exemple multi-threads de FFT par paquet
|
---|
3 | // Test BAO-Radio/Acq
|
---|
4 | // R. Ansari - C. Magneville , Decembre 2007
|
---|
5 | // Exemples de commandes pour test (dans l'ordre ci-dessous :
|
---|
6 | // csh> tmtfft VSZ NTH NbFFT [PaqSz=4096]
|
---|
7 | // csh> tmtfft 1310720 1 10000 16384
|
---|
8 | // csh> tmtfft 1310720 1 10000 8192
|
---|
9 | // csh> tmtfft 1310720 2 10000 8192
|
---|
10 | //--------------------------------------------------------------------------------
|
---|
11 |
|
---|
12 | #include "sopnamsp.h"
|
---|
13 | #include "zthread.h"
|
---|
14 | #include "resusage.h"
|
---|
15 | #include "ctimer.h"
|
---|
16 | #include "timing.h"
|
---|
17 |
|
---|
18 | #include <stdlib.h>
|
---|
19 | #include <stdio.h>
|
---|
20 | #include <unistd.h>
|
---|
21 | #include <string>
|
---|
22 | #include <iostream>
|
---|
23 |
|
---|
24 | #include "tvector.h"
|
---|
25 | #include "fioarr.h"
|
---|
26 | #include "matharr.h"
|
---|
27 | #include "tarrinit.h"
|
---|
28 |
|
---|
29 | #include "randfmt.h"
|
---|
30 | #include "fftpserver.h"
|
---|
31 | #include "fftwserver.h"
|
---|
32 |
|
---|
33 | #include "FFTW/fftw3.h"
|
---|
34 |
|
---|
35 |
|
---|
36 | //---------------------------------------------------------------------------------
|
---|
37 | // Definition d'une classe heritant de ZThread, pour remplir un vecteur avec
|
---|
38 | // des aleatoires
|
---|
39 |
|
---|
40 | class MTDoFFT : public ZThread {
|
---|
41 | public:
|
---|
42 | MTDoFFT(TVector<r_4>& v, sa_size_t nfft=10, sa_size_t paqsz=4096);
|
---|
43 | virtual void run();
|
---|
44 | inline TVector<r_4>& getSpectre() { return spectre_; }
|
---|
45 | protected:
|
---|
46 | string nom_;
|
---|
47 | TVector<r_4> vv_;
|
---|
48 | sa_size_t nbfft_; // Nb de FFT a faire
|
---|
49 | sa_size_t paqsz_; // taille des paquets pour FFT
|
---|
50 | TVector<r_4> spectre_; // spectre moyenne
|
---|
51 | TVector< complex<r_4> > cfour_; // composant TF
|
---|
52 | FFTPackServer ffts_; // serveur FFT
|
---|
53 | };
|
---|
54 |
|
---|
55 | static int mtrandId = 0; // Pour donner un identificateur a chaque thread
|
---|
56 | ZMutex* pmtx_=NULL; // pour synchroniser creation de plan_fftw;
|
---|
57 |
|
---|
58 | MTDoFFT::MTDoFFT(TVector<r_4>& v, sa_size_t nfft, sa_size_t paqsz)
|
---|
59 | : vv_(v,true), // Partage de reference du vecteur
|
---|
60 | nbfft_(nfft), paqsz_(paqsz), ffts_(true) // preserve input=true
|
---|
61 | {
|
---|
62 | if (pmtx_==NULL) pmtx_ = new ZMutex;
|
---|
63 | char buff[32];
|
---|
64 | sprintf(buff, "MTDoFFT-Id=%d", mtrandId);
|
---|
65 | mtrandId++;
|
---|
66 | nom_ = buff;
|
---|
67 | // Initialisation taille vecteurs
|
---|
68 | TVector<r_4> vx(paqsz_);
|
---|
69 | vx = RegularSequence();
|
---|
70 | ffts_.FFTForward(vx, cfour_);
|
---|
71 | spectre_.ReSize(cfour_.Size());
|
---|
72 | cout << " Thread MTDoFFT(" << nom_ << ", PaqSz=" << paqsz_ << " ) Created ... " << endl;
|
---|
73 | }
|
---|
74 |
|
---|
75 | inline r_4 Zmod2(complex<r_4> z)
|
---|
76 | { return (z.real()*z.real()+z.imag()*z.imag()); }
|
---|
77 |
|
---|
78 | // Le travail fait dans chaque thread (appele par start())
|
---|
79 | void MTDoFFT::run()
|
---|
80 | {
|
---|
81 | Timer tm(nom_.c_str());
|
---|
82 | cout << "MTDoFFT::run() - Nom= " << nom_ << " vv.Size()= " << vv_.Size()
|
---|
83 | << " PaqSz=" << paqsz_ << " NbFFT= " << nbfft_ << endl;
|
---|
84 | FMTRandGen rgen;
|
---|
85 | TVector<r_4> vx(paqsz_);
|
---|
86 |
|
---|
87 | pmtx_->lock();
|
---|
88 | fftwf_plan plan = fftwf_plan_dft_r2c_1d(paqsz_, vx.Data(),
|
---|
89 | (fftwf_complex *)cfour_.Data(), FFTW_ESTIMATE);
|
---|
90 | pmtx_->unlock();
|
---|
91 |
|
---|
92 | sa_size_t prm = nbfft_/10;
|
---|
93 | for(sa_size_t i=0; i<nbfft_; i++) {
|
---|
94 | sa_size_t first = rgen.Flat01()*(vv_.Size()-paqsz_-10);
|
---|
95 | sa_size_t last = first+paqsz_-1;
|
---|
96 | TVector<r_4> vx = vv_(Range(first,last));
|
---|
97 | fftwf_execute(plan);
|
---|
98 |
|
---|
99 | // ffts_.FFTForward(vx, cfour_);
|
---|
100 | // for(sa_size_t j=0; j<spectre_.Size(); j++)
|
---|
101 | // spectre_(j) += Zmod2(cfour_(j));
|
---|
102 | if (i%prm == 0)
|
---|
103 | cout << "MTDoFFT::run() - Nom= " << nom_ << " Done i= " << i << endl;
|
---|
104 | }
|
---|
105 | }
|
---|
106 | // ----- Fin de la definition de la classe MTDoFFT ----
|
---|
107 | //---------------------------------------------------------------------------------
|
---|
108 |
|
---|
109 | //----------------- Les fonction de test -----------------
|
---|
110 |
|
---|
111 | //------- f3_tmtfft()
|
---|
112 | int f3_tmtfft(sa_size_t VSZ, int NTH, sa_size_t nfft=10, sa_size_t paqsz=4096)
|
---|
113 | {
|
---|
114 | cout << "[1] f3_tmtfft/starting, VSZ= " << VSZ << " NTH= " << NTH << endl;
|
---|
115 | cout << " ... NbFFT=" << nfft << " PaqSz=" << paqsz << endl;
|
---|
116 | ResourceUsage res(ResourceUsage::RU_All);
|
---|
117 | Timer tm("f3_tmtfft");
|
---|
118 | vector<MTDoFFT *> vth;
|
---|
119 | FMTRandGen rg;
|
---|
120 | TVector<r_4> DATA(VSZ);
|
---|
121 | for(sa_size_t i=0; i<VSZ; i++)
|
---|
122 | DATA(i) = sin(i*M_PI*0.08654)+2*cos(i*M_PI*0.27591)+rg.Flatpm1();
|
---|
123 | tm.Split("DATA-OK");
|
---|
124 | cout << "[2] f3_tmtfft/creating threads " << endl;
|
---|
125 | for(int kt=0; kt<NTH; kt++) {
|
---|
126 | vth.push_back(new MTDoFFT(DATA, nfft, paqsz) );
|
---|
127 | }
|
---|
128 | tm.Split("Thread-Created");
|
---|
129 | cout << "[3] f3_tmtfft/starting threads " << endl;
|
---|
130 | for(int kt=0; kt<NTH; kt++) vth[kt]->start();
|
---|
131 |
|
---|
132 | cout << "[4] f3_tmtfft/waiting for all threads to finish " << endl;
|
---|
133 | sleep(1);
|
---|
134 | for(int kt=0; kt<NTH; kt++) vth[kt]->join();
|
---|
135 | tm.Split("Threads-Finished");
|
---|
136 |
|
---|
137 | cout << "[5] f3_tmtfft/saving spectra to file mtspectra.ppf " << endl;
|
---|
138 | POutPersist po("mtspectra.ppf");
|
---|
139 | for(int kt=0; kt<NTH; kt++)
|
---|
140 | po << vth[kt]->getSpectre();
|
---|
141 |
|
---|
142 | cout << "[6] f3_tmtfft/deleting thread objects " << endl;
|
---|
143 | for(int kt=0; kt<NTH; kt++) delete vth[kt];
|
---|
144 |
|
---|
145 | cout << res;
|
---|
146 | return 0;
|
---|
147 | }
|
---|
148 | //----------------- FIN des fonctions de test -----------------
|
---|
149 |
|
---|
150 | //-------------------------------------------------------------
|
---|
151 | //---------------------- MAIN MAIN MAIN -----------------------
|
---|
152 | //-------------------------------------------------------------
|
---|
153 |
|
---|
154 | int main(int narg, char *arg[])
|
---|
155 |
|
---|
156 | {
|
---|
157 | InitTim();
|
---|
158 | SophyaInit();
|
---|
159 |
|
---|
160 | int rc = 0;
|
---|
161 | if (narg < 4) {
|
---|
162 | cout << " tmtfft/Error args - Usage: tmtfft VSZ NTH NbFFT [PaqSz=4096]" << endl;
|
---|
163 | return 1;
|
---|
164 | }
|
---|
165 | sa_size_t VSZ = atoi(arg[1]);
|
---|
166 | int NTH = atoi(arg[2]);
|
---|
167 | sa_size_t nfft = atoi(arg[3]);
|
---|
168 | sa_size_t paqsz = 4096;
|
---|
169 | if (narg > 4) paqsz = atoi(arg[4]);
|
---|
170 | try {
|
---|
171 | f3_tmtfft(VSZ, NTH, nfft, paqsz);
|
---|
172 | }
|
---|
173 | catch (PThrowable exc) {
|
---|
174 | cerr << "tmtfft: catched Exception " << exc.Msg() << endl;
|
---|
175 | rc = 77;
|
---|
176 | }
|
---|
177 | catch (...) {
|
---|
178 | cerr << " catched unknown (...) exception (tmtfft.cc) " << endl;
|
---|
179 | rc = 78;
|
---|
180 | }
|
---|
181 | cout << "----------- tmtfft/END ------- " << endl;
|
---|
182 | PrtTim("---END tmtfft---");
|
---|
183 | return(rc);
|
---|
184 |
|
---|
185 | }
|
---|