Line data Source code
1 : #include "../inc/header.h"
2 : #include "../inc/param_manager.h"
3 : #include "../inc/save_manager.h"
4 : #include "../inc/utils.h"
5 : #include "../inc/global_param.h"
6 : #include "../inc/divergence.h"
7 : #include <iostream>
8 : #include <fstream>
9 : #include <type_traits> // for std::is_same
10 : #include <string> // for std::stof
11 :
12 : #ifndef ONLY_CPU
13 : #include "../inc/kmeans.h"
14 : #endif
15 :
16 : /** dDsSqacrReiECmlkzgpPeof
17 : * Listes plus complètes mais non utilisées : list char query_type
18 : * Liste des types de query
19 : * a query advenced interprete tout une commande query avec le type le dossier, la limite, le offset.
20 : * m moyenne
21 : * l load
22 : * C commitInsert
23 : * k kmeans
24 : * F Retourne une liste de photos
25 : * v delete dynamic descripters
26 : * A requete vide a supprimer
27 : * q -> r (query sur GPU)
28 : * c -> R (query sur CPU)
29 : * s / S : query Stat
30 : * r / R : query Random prends une photo au hazard
31 : * d / D : get descrpter of type ...
32 : * i insert descripters
33 : * p /P partial distance search
34 : * z simule un descripters aleatoirement de type ...
35 : * g return specific dimension of all desc of type ...
36 : * e / E delete datas and exit
37 : * u / U query unload
38 : **/
39 :
40 :
41 :
42 : #ifndef ONLY_CPU
43 : #define testCUDA(error){testCUDA(error, __FILE__, __LINE__);}
44 : #endif
45 :
46 : #define NTPB 1024
47 : #define NTPBPDS 512
48 :
49 0 : void displayTime(clock_t & begin_end, const std::string & message)
50 : {
51 0 : if (message.compare("") != 0)
52 : {
53 0 : clock_t end = clock();
54 0 : double elaps_time = (double) (end - begin_end) / CLOCKS_PER_SEC;
55 0 : std::cout << "detailed time ms " << message << " " << elaps_time << std::endl;
56 : }
57 0 : begin_end = clock();
58 0 : }
59 :
60 0 : int32_t getiddesc(const int t,const std::vector<int> & list, const int size)
61 : {
62 0 : int32_t index = 0;
63 0 : while (index < size && list[index] != t ) ++index;
64 0 : return (index == size ? -1 : index );
65 : }
66 :
67 0 : int get_max_data(std::vector<types_datas_t> &read_cache)
68 : {
69 0 : int max = 0;
70 0 : for (int i = 0; i < read_cache.size(); ++i)
71 : {
72 0 : if(read_cache.at(i).nb_data > max)
73 0 : max = read_cache.at(i).nb_data;
74 : }
75 0 : return max;
76 : }
77 :
78 0 : void query(std::vector<uint32_t> & result, int id_desc, int nb_data,
79 : int dimension, std::vector<data> & mat_data, std::vector<uint32_t> & ids,
80 : int limit_return, std::vector<VDInt> & distances, std::vector<data> &query_desc, int verbose)
81 : {
82 : // Fais le calcul de distance entre un vecteur et tous une liste de vecteur (mat_data). Puis tri le point le plus proche de ce vecteur.
83 : // VR 18-9-17 : je me demande bien qui a mis ce test ici, on a l'air de dupliquer beaucoup de code a cause de cela, et sans doute de ne pas le tester du coup,
84 : // ce sont sans doute les memes fonctions qui font le jobs, mais cela me parait vraiment inquietant,
85 : // car les arguments pourrait changer quand meme
86 0 : if (id_desc > nb_data)
87 : {
88 0 : printf("Wrong id_query : %d, nb_data : %d \n", id_desc, nb_data);
89 0 : return;
90 : }
91 :
92 0 : if (id_desc >= 0)
93 : {
94 0 : uint64_t address = (uint64_t) id_desc * (uint64_t) dimension;
95 0 : std::cout << " address " << address <<" = id_desc " << id_desc <<" * dimension " << dimension << std::endl;
96 0 : for (int i = 0; i < dimension; i++)
97 0 : query_desc[i] = mat_data[address + i];
98 : }
99 0 : char divergence = 'E';
100 0 : compute_distance(distances, mat_data, nb_data, query_desc, dimension, divergence);
101 :
102 0 : quick_sort<VDInt>(ids, distances, nb_data, verbose);
103 :
104 0 : result.resize(std::min<int>(limit_return, nb_data));
105 :
106 0 : for (int i = 0; i < limit_return && i < nb_data; i++)
107 0 : result[i] = ids[i];
108 : }
109 :
110 : // 27-2-16 : VR to MG : je crains qu'il n'y ait une erreur de conception dans notre communication client serveur, ils se retrouvent qu'ils sont parfois tous les deux bloqué sur recv
111 0 : int FindSamePidDataTypeAndSetPidToNull(std::vector<to_insert_t>& to_insert, int indexCurrent, int pid, int data_type)
112 : {
113 0 : for (int i = 0; i < indexCurrent; i++)
114 : {
115 0 : if (to_insert[i].id == pid && to_insert[i].type_data == data_type)
116 : {
117 0 : to_insert[i].id = 0;
118 0 : return 0;
119 : }
120 : }
121 : return 0;
122 : }
123 :
124 0 : float_t compute_KL(const std::vector<data> &a, const std::vector<data> &b){
125 0 : float_t result=0;
126 0 : for(int i=0; i<a.size();i++){
127 0 : result += (float_t) a[i]*log((double)(a[i]/b[i]));
128 : }
129 0 : return result;
130 : }
131 :
132 :
133 :
134 : /**
135 : * main.cu
136 : **/
137 :
138 : // La ce sont des données en photo_ids => il faut changer en ids et pour cela faire les find_index en dehors et passer vec et vvec (a changer en vecteur plutot que pointeur ! youpla boum)
139 0 : void query_pds_from_cpu(std::vector<uint32_t> & result,
140 : std::vector<VDInt> & distances,
141 : int & limit_return,
142 : uint32_t* vec, // liste_ids_as_ids
143 : int m, // number query ?ca veut rien dire ! c'est le nb de data a traiter
144 : uint32_t* vecc, // candidats_grille_as_ids
145 : int nbc, // number candidats
146 : int n, // number data total (m + nbc)
147 : int d, // dimension (a renommer)
148 : const datag *pointeurGPU,
149 : int verbose
150 : )
151 : // ReadCacheCPU[lp.index_type_query].ids_vec
152 : // ReadCacheCPU[lp.index_type_query].dataGPU
153 : {
154 :
155 0 : uint32_t *vecteursDev, *argminDev;
156 0 : VDInt *distDev;
157 0 : uint32_t* candidatsDev;
158 :
159 0 : std::cout<<"print m (number query) : "<<m<<std::endl;
160 :
161 0 : std::vector<uint32_t> argmin_ids(m);
162 0 : std::vector<VDInt> dist(m);
163 :
164 : #ifndef ONLY_CPU
165 : testCUDA(cudaMalloc(&vecteursDev, m * sizeof(uint32_t)));
166 : testCUDA(cudaMalloc(&argminDev, m * sizeof(uint32_t)));
167 : testCUDA(cudaMalloc(&distDev, m * sizeof(VDInt)));
168 : testCUDA(cudaMalloc(&candidatsDev, nbc * sizeof(uint32_t)));
169 : #endif
170 :
171 : // MG 12/9/17 pourquoi ne pas utiliser des vrais vecteurs ?
172 : // VR 17-9-18 : je suis tout a fait d'accord, il faut le changer, surtout si c'est testé
173 0 : uint32_t* argminHost = new uint32_t[m];
174 0 : VDInt* distHost = new VDInt[m];
175 :
176 : #ifndef ONLY_CPU
177 : testCUDA(cudaMemcpy(vecteursDev, vec, m * sizeof(uint32_t), cudaMemcpyHostToDevice));
178 : testCUDA(cudaMemcpy(candidatsDev, vecc, nbc * sizeof(uint32_t), cudaMemcpyHostToDevice));
179 : #endif
180 :
181 : //query_kernel_vide(m,m);
182 :
183 0 : printf("nbc = %u\n", nbc);
184 0 : puts("\n");
185 0 : datag* donneesGPU = (datag*)pointeurGPU;
186 :
187 : //cudaProfilerStart();
188 : // MG 12/9/17 : removed duplicated/unused params
189 : // VR 19-9-17 : bon c'est pas genial de faire comme cela mais bon !
190 : #ifndef ONLY_CPU
191 : // query_pds_gpu(m, nbc, 0, d, vecteursDev, candidatsDev, argminDev, distDev, (datag*)donneesGPU, 0);
192 : #endif
193 :
194 : //cudaDeviceSynchronize();
195 : //cudaProfilerStop();
196 : //cudaDeviceSynchronize();
197 : // delete[] pointeurHost;
198 : //testCUDA(cudaMemcpy(argminDev,vec,m*sizeof(uint32_t),cudaMemcpyHostToDevice));
199 :
200 : #ifndef ONLY_CPU
201 : testCUDA(cudaMemcpy(argminHost,argminDev,sizeof(uint32_t)*m,cudaMemcpyDeviceToHost));
202 : testCUDA(cudaMemcpy(distHost,distDev,sizeof(VDInt)*m,cudaMemcpyDeviceToHost));
203 : //cudaFree(pointeurGPU2);
204 : #endif
205 :
206 0 : printf("nbc = %u\n", nbc);
207 0 : puts("\n");
208 0 : for (int i = 0; i != m; ++i)
209 : {
210 0 : dist[i] = distHost[i];
211 :
212 0 : uint32_t j = argminHost[i];
213 :
214 : // uint32_t z = candidats_grille[j];//ReadCacheCPU[lp.index_type_query].ids_vec[j];
215 :
216 0 : argmin_ids[i] = j;//ReadCacheCPU[lp.index_type_query].ids_vec[j];
217 : }
218 :
219 0 : printf("là\n");
220 :
221 :
222 0 : delete[] argminHost;
223 0 : delete[] distHost;
224 0 : printf("là aussi\n");
225 :
226 :
227 : #ifndef ONLY_CPU
228 : cudaFree(vecteursDev);
229 : cudaFree(argminDev);
230 : cudaFree(distDev);
231 : cudaFree(candidatsDev);
232 : //cudaProfilerStop();
233 : #endif
234 :
235 0 : result.resize(m);
236 0 : distances.resize(m);
237 :
238 0 : result = argmin_ids;
239 0 : distances = dist;
240 0 : limit_return = argmin_ids.size();
241 0 : }
242 :
243 0 : int initPDSdynamic(LocalParam & lp, int nb_clusters, const std::vector<std::vector<uint32_t>> list_photo_ids_per_cluster, int32_t type)
244 : {
245 0 : std::cout<<"on veut creer les pds dynamiques"<<std::endl;
246 0 : int nb_desc_dyn_before=lp.ReadCacheCpuDyn.size();
247 0 : std::cout<<"taille desc dyn : "<<nb_desc_dyn_before<<std::endl;
248 0 : lp.ReadCacheCpuDyn.resize(nb_clusters+nb_desc_dyn_before);
249 : //lp.list_dyn_desc_type.resize(nb_clusters+lp.list_dyn_desc_type.size());
250 0 : types_datas_t & ReadCache = lp.ReadCacheCPU[lp.index_type_query];
251 0 : int new_type=-100-nb_desc_dyn_before;
252 : //std::cout<<"new type "<<new_type<<std::endl;
253 0 : uint32_t size=ReadCache.size;
254 0 : uint32_t taille_data;
255 0 : for(int i=0; i<nb_clusters; i++){
256 : //TODO si plusieurs photo_desc de depart
257 0 : taille_data=list_photo_ids_per_cluster[i].size();
258 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].datas_vec.resize(0);
259 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].ids_vec.resize(0);
260 : //lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].size=size;
261 : //std::cout<<"size du ReadCache : "<<ReadCache.size<<std::endl;
262 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].size=ReadCache.size;
263 0 : std::cout<<"avant push_back , taille de laliste"<<lp.list_dyn_desc_type.size()<<std::endl;
264 0 : lp.list_dyn_desc_type.push_back(new_type);
265 0 : lp.list_pere_desc_dyn.push_back(type);
266 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].type = new_type;
267 0 : std::cout<<"apres push, taille de la liste "<<lp.list_dyn_desc_type.size()<<std::endl;
268 0 : std::cout<<"list_new_desc_dyn["<<i+nb_desc_dyn_before<<"] : "<<lp.list_dyn_desc_type[i+nb_desc_dyn_before]<<std::endl;
269 0 : std::cout<<"list_pere_desc_dyn["<<i+nb_desc_dyn_before<<"] : "<<lp.list_pere_desc_dyn[i+nb_desc_dyn_before]<<std::endl;
270 :
271 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].nb_data=taille_data;
272 0 : std::cout<<"nb data : "<<lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].nb_data<<std::endl;
273 0 : for(int j=0; j<taille_data; j++){
274 :
275 0 : uint32_t id=FindPidsIndex(ReadCache.ids_vec, list_photo_ids_per_cluster[i][j]);
276 0 : for(int d=0; d<size; d++){
277 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].datas_vec.push_back(ReadCache.datas_vec[id*size+d]);
278 : }
279 0 : lp.ReadCacheCpuDyn[i+nb_desc_dyn_before].ids_vec.push_back(list_photo_ids_per_cluster[i][j]);
280 :
281 : }
282 0 : std::cout<<"new type : "<<new_type<<std::endl;
283 0 : new_type-=1;
284 : //std::cout<<"new type à la derniere etape du for"<<new_type<<std::endl;
285 : }
286 0 : std::cout<<"nb dyn desc after init : "<<lp.ReadCacheCpuDyn.size()<<std::endl;
287 0 : for(int i = 0; i<lp.ReadCacheCpuDyn.size(); i++){
288 0 : std::cout<<lp.ReadCacheCpuDyn[i].type<<","<<lp.ReadCacheCpuDyn[i].nb_data<<std::endl;
289 : }
290 :
291 0 : return 0;
292 : }
293 :
294 :
295 : /**
296 : * query.cu
297 : **/
298 0 : void query_pds(uint32_t idx_v, unsigned id_photo, std::vector<uint32_t>& res, std::vector<VDInt>& dist,std::vector<types_datas_t>& ReadCacheCPU, LocalParam& lp, Query& cur_query, const std::vector<uint32_t>& candidats_grille)
299 : {
300 0 : auto & ReadCache = ReadCacheCPU[lp.index_type_query];
301 0 : unsigned d = lp.dimension;
302 0 : unsigned nbc = (unsigned) candidats_grille.size();
303 0 : unsigned int n = (unsigned int) ReadCache.ids_vec.size();
304 0 : cur_query.set_query_id(id_photo);
305 0 : auto qi = FindPidsIndex(ReadCache.ids_vec, id_photo);
306 0 : size_t address_desc = (size_t) d * (size_t) qi;
307 0 : uint32_t id;
308 0 : VDInt dist_min = (VDInt)-1;
309 0 : VDInt dcumul = 0;
310 0 : uint32_t argmin = 0;
311 0 : short z;
312 :
313 0 : for(int i=0; i!=nbc; ++i) {
314 0 : id = candidats_grille[i];
315 0 : if (id == id_photo) continue;
316 0 : dcumul = 0;
317 0 : uint32_t offset_grille = FindPidsIndex(ReadCache.ids_vec,id)*d;
318 0 : for(int j=0; j!=d; ++j) {
319 0 : z = ReadCache.datas_vec[address_desc+j]-ReadCache.datas_vec[offset_grille + j];
320 0 : dcumul += z*z;
321 :
322 0 : if(dcumul>dist_min)
323 : break;
324 : }
325 0 : if (dcumul <= dist_min && dcumul != 0) {
326 0 : dist_min = dcumul;
327 0 : argmin = id;
328 : }
329 : }
330 0 : res[idx_v] = argmin;
331 0 : dist[idx_v] = dist_min;
332 0 : }
333 :
334 0 : void query_pds2(unsigned id_photo, std::vector<uint32_t>& res, std::vector<VDInt>& dist, LocalParam& lp, Query& cur_query, const std::vector<uint32_t>& candidats_grille)
335 : {
336 :
337 0 : auto & ReadCache = lp.ReadCacheCPU[lp.index_type_query];
338 0 : unsigned d = lp.dimension;
339 :
340 0 : unsigned nbc = (unsigned) candidats_grille.size();
341 0 : unsigned int n = (unsigned int) ReadCache.ids_vec.size();
342 0 : cur_query.set_query_id(id_photo);
343 0 : auto qi = FindPidsIndex(ReadCache.ids_vec, id_photo);
344 0 : size_t address_desc = (size_t) d * (size_t) qi;
345 :
346 0 : uint32_t id;
347 0 : VDInt dist_min = (VDInt)-1;
348 0 : VDInt dcumul = 0;
349 0 : uint32_t argmin = 0;
350 0 : short z;
351 0 : uint32_t echecs = 0;
352 0 : unsigned nb_voisins = 5;
353 0 : uint32_t limite_echecs = nbc;
354 0 : std::list<std::pair<uint32_t, VDInt> > candidats;
355 0 : uint32_t dist_max = (VDInt)-1;
356 :
357 0 : for(unsigned int k=0; k<nbc; ++k) {
358 :
359 0 : id = candidats_grille[k];//ReadCache.ids_vec[k];
360 :
361 0 : if(/*id == 0 || */id == id_photo) continue;
362 0 : dcumul = 0;
363 0 : uint32_t offset_grille = FindPidsIndex(ReadCache.ids_vec,id)*d;
364 :
365 0 : for(unsigned int j=0; j<d; ++j) {
366 : // TM : 01/08/17 : Il y a probablement une erreur juste en dessus. En effet, ReadCache.datas_vec[address_desc+j] et ReadCache.datas_vec[k*d + j] sont des unsigned int donc si l'on fait la soustraction des deux, on obtiendra jamais un nombre négatif (par example 3-4 donnera 255 et non -1), pour avoir un nombre négatif il faut écrire : (short)ReadCache.datas_vec[address_desc+j]-(short)ReadCache.datas_vec[k*d + j].
367 0 : z = /*vecteur[j]*/ReadCache.datas_vec[address_desc+j]-ReadCache.datas_vec[offset_grille + j];
368 0 : dcumul += z*z;
369 0 : if(dcumul > dist_max) {
370 : //calculs_economises += d-j-1; // (d-1)-(j+1) + 1 = d-j -1-1+1 = d-j-1
371 : break;
372 : }
373 : }
374 :
375 0 : if(dcumul == 0) continue;
376 :
377 0 : if(dcumul <= dist_min) {
378 : //printf("dist_min=%lu devient %lu pour le candidat %lu (%lu)\n", dist_min,dcumul,(uint32_t)k, id);
379 0 : dist_min = dcumul;
380 0 : argmin = id;
381 0 : echecs = 0;
382 0 : if(candidats.size()>nb_voisins) {
383 0 : candidats.pop_front();
384 : }
385 0 : dist_max = candidats.front().second;
386 0 : candidats.push_back(std::pair<uint32_t, VDInt>(argmin,dist_min));
387 : }
388 0 : else if(dcumul <= dist_max) {
389 :
390 0 : if(dcumul == dist_max)
391 0 : candidats.push_front(std::pair<uint32_t, VDInt>(id,dcumul));
392 :
393 : else {
394 :
395 0 : std::list<std::pair<uint32_t, VDInt> >::iterator it=candidats.begin();
396 : //unsigned long long position = 0;
397 0 : for(; it!=candidats.end(); ++it) {
398 0 : if(it->second<dcumul)
399 : break;
400 : // ++position;
401 : }
402 0 : if(it!=candidats.begin())
403 0 : --it;
404 0 : candidats.insert(it,std::pair<uint32_t, VDInt>(id,dcumul));
405 0 : if(candidats.size()>nb_voisins)
406 0 : candidats.pop_front();
407 0 : dist_max = candidats.front().second;
408 0 : echecs = 0;
409 : }
410 : //printf("%u\n", dist_max);
411 : }
412 : else{
413 0 : if(++echecs == limite_echecs) {
414 : break;
415 : }
416 : }
417 :
418 : }
419 : /// T468 Afvs_conf_468.ini
420 :
421 0 : candidats.sort([](std::pair<uint32_t,VDInt>& X,std::pair<uint32_t,VDInt>& Y)
422 : { if(X.second>Y.second) return false; if(X.second == Y.second) return X.first > Y.first; return true; });
423 :
424 :
425 0 : candidats.push_front(std::pair<uint32_t,VDInt>(id_photo,0));
426 0 : n = (unsigned int) candidats.size();
427 0 : if(n > nb_voisins) n=nb_voisins, candidats.resize(n);
428 :
429 0 : auto it = candidats.begin();
430 0 : for(auto u : candidats)
431 0 : printf("%u:%u\n",u.first,u.second);
432 0 : ++it; ++it;
433 0 : res.push_back(it->first);
434 0 : dist.push_back(it->second);
435 0 : }
436 :
437 0 : static void query_moyenne_cpu(const std::vector<data> & datas_vec, std::vector<uint32_t> &photo_id_int,size_t nb_pic, uint32_t size, std::vector<VDInt> &result)
438 : {
439 0 : for (int i = 0; i < size; ++i)
440 : {
441 0 : for (int j = 0; j < nb_pic; ++j)
442 0 : result[i] += datas_vec[i + photo_id_int[j] * size];
443 0 : result[i] /= nb_pic;
444 : }
445 0 : }
446 :
447 : // VR 2-8-16 : est-ce que query_moyenne est testé ?
448 0 : void query_moyenne(types_datas_t ReadCacheCPUOneData, std::vector<uint32_t> &list_id, int cs, int notgpu, size_t limit)
449 : {
450 0 : std::vector<uint32_t> list_id_int(list_id.size());
451 0 : int64_t index;
452 0 : int it;
453 0 : int length = 0;
454 0 : for (size_t i = 0; i < list_id.size(); ++i)
455 : {
456 0 : it = FindPidsIndex(ReadCacheCPUOneData.ids_vec, list_id[i]);
457 0 : if (it != ReadCacheCPUOneData.ids_vec.size())
458 : {
459 0 : index = it;
460 0 : if (index >= 0 && index < ReadCacheCPUOneData.nb_data)
461 0 : list_id_int[length++] = (uint32_t) index;
462 : }
463 : }
464 : // VR 10-9-23 Faudrait-il plutot avoir datag ? ou data ici, il y avait avant uint32_t
465 0 : std::vector<VDInt> result(ReadCacheCPUOneData.size);
466 0 : if (notgpu)
467 0 : query_moyenne_cpu(ReadCacheCPUOneData.datas_vec, list_id_int, length, ReadCacheCPUOneData.size, result);
468 0 : if (result.size()) {
469 0 : std::string result_str;
470 0 : for (int i = 0; i < ReadCacheCPUOneData.size; ++i)
471 : {
472 0 : if(i>0)
473 0 : result_str += ",";
474 0 : result_str += boost::lexical_cast<std::string>(result[i]);
475 :
476 : }
477 0 : result_str+="eof";
478 0 : send(cs, &(result_str.at(0)), result_str.size(), 0);
479 : } else
480 0 : send(cs, "need to implement GPU moyenneeof", 32,0);
481 0 : close(cs);
482 0 : }
483 :
484 : // VR 10-1-17 : pourquoi est-ce declaré deux fois ?
485 : // void fromCPUKmeanOneStep(std::vector<uint32_t> &clusters, types_datas_t &ReadCacheCPUPointerOneDescriptorType, int verbose);
486 :
487 0 : void auxKmeanOnCPU(std::vector<VDInt> &new_clusters,
488 : std::vector<std::pair<int, VDInt> > & size_and_inertia,
489 : std::vector<std::vector<uint32_t> > & list_photo_ids_per_cluster,
490 : std::vector<std::vector<uint32_t> > & list_ids_per_clusters,
491 : std::vector<std::vector<VDInt> > & list_minimum_distances_photo_ids_per_clusters,
492 : const std::vector<VDInt> &clusters,
493 : const types_datas_t &ReadCacheCPUPointerOneDescriptorType,
494 : char divergence,
495 : int verbose,
496 : int methodChoice = -1)
497 : {
498 0 : if (clusters.size() == 0)
499 : {
500 0 : std::cout << "Empty clusters ! " << std::endl;
501 0 : new_clusters.resize(0);
502 0 : return;
503 : }
504 :
505 0 : const uint32_t nbrPhoto = ReadCacheCPUPointerOneDescriptorType.nb_data;
506 0 : const uint32_t dimension = ReadCacheCPUPointerOneDescriptorType.size;
507 0 : const unsigned long nbrCentroids = (int) clusters.size() / dimension;
508 0 : std::vector<uint32_t> centroidIds(nbrCentroids);
509 0 : std::vector<data> tempCluster(clusters.size());
510 :
511 0 : data min_elem = *std::min_element(ReadCacheCPUPointerOneDescriptorType.datas_vec.begin(),ReadCacheCPUPointerOneDescriptorType.datas_vec.end());
512 0 : data max_elem = *std::max_element(ReadCacheCPUPointerOneDescriptorType.datas_vec.begin(),ReadCacheCPUPointerOneDescriptorType.datas_vec.end());
513 0 : std::cout<<"min element : "<<min_elem<<", max_elem : "<<max_elem<<std::endl;
514 0 : data scope = max_elem-min_elem;
515 0 : std::cout<<"scope : "<<scope<<std::endl;
516 : int sign_elem;
517 0 : if(min_elem < (data) 0 ? sign_elem=-1 : sign_elem=1);
518 :
519 0 : for (int i = 0 ; i < nbrCentroids ; i++)
520 0 : centroidIds[i] = i;
521 :
522 0 : for (int i = 0 ; i < clusters.size(); i++)
523 0 : tempCluster[i] = (clusters[i]+sign_elem*min_elem+1);//scope*16;
524 :
525 0 : if (nbrPhoto == 0)
526 : {
527 0 : std::cout << "Empty clusters we can't update them with Lloyds algorithm (and in gpu mode it would crash ERROR PROBLEM !) VR 23-1-17 " << std::endl;
528 0 : return;
529 : }
530 :
531 0 : if (list_ids_per_clusters.size() >0){
532 0 : for(int i =0; i<list_ids_per_clusters.size();i++){
533 0 : std::cout<<"nb data in "<<i<<" : "<<list_ids_per_clusters[i].size()<<", ";
534 : }
535 0 : std::cout<<std::endl;
536 : }
537 :
538 0 : list_photo_ids_per_cluster.clear();
539 0 : list_photo_ids_per_cluster.resize(nbrCentroids, std::vector<uint32_t>());
540 :
541 :
542 0 : list_ids_per_clusters.clear();
543 0 : list_ids_per_clusters.resize(nbrCentroids, std::vector<uint32_t>());
544 :
545 :
546 0 : list_minimum_distances_photo_ids_per_clusters.resize(0);
547 0 : list_minimum_distances_photo_ids_per_clusters.resize(nbrCentroids, std::vector<VDInt>());
548 :
549 0 : const int id_query = -1;
550 0 : const int limit_return = 1;
551 :
552 0 : std::vector<data> query_desc(dimension);
553 0 : std::vector<uint32_t> ids;
554 0 : std::vector<uint32_t> result;
555 0 : std::vector<VDInt> distances;
556 0 : std::cout<<" Methode Choice : "<<methodChoice<<std::endl;
557 0 : std::cout<<"divergence : "<<divergence<<std::endl;
558 :
559 :
560 0 : if (methodChoice == -1 || methodChoice == 2)
561 : {
562 : #ifndef ONLY_CPU
563 : // VR 6-11-16 : ne pourrait-on pas utiliser le vecteur de query ?
564 :
565 : std::vector<types_datas_t> ReadCacheCPU(1);
566 : ReadCacheCPU[0].size = dimension; // VR 18-9-17 : petit doute !
567 : ReadCacheCPU[0].datas_vec = tempCluster;
568 : ReadCacheCPU[0].nb_data = clusters.size() / dimension;
569 :
570 : size_t sizemalloc = tempCluster.size() * sizeof(data);
571 : testCUDA(cudaMalloc(&(ReadCacheCPU[0].dataGPU), sizemalloc));
572 : testCUDA(cudaMemcpy(ReadCacheCPU[0].dataGPU, &(tempCluster.front()), sizemalloc, cudaMemcpyHostToDevice));
573 :
574 : #endif
575 :
576 0 : for (int i = 0; i < ReadCacheCPUPointerOneDescriptorType.nb_data; i++)
577 : {
578 0 : ids = centroidIds;
579 :
580 0 : for (int k = 0; k < dimension; k++)
581 0 : query_desc[k] = (ReadCacheCPUPointerOneDescriptorType.datas_vec[i * ReadCacheCPUPointerOneDescriptorType.size + k]+sign_elem*min_elem+1);//scope*16;
582 :
583 0 : if (i % 1000 == 0)
584 0 : std::cout << ",";
585 :
586 0 : if (verbose)
587 : {
588 0 : std::cout << " ids.size() : " << ids.size() << std::endl;
589 0 : for (int i = 0; i < ids.size(); i++)
590 : {
591 0 : std::cout << " ids[" << i << "] : " << ids[i] << std::endl;
592 : }
593 0 : std::cout << " limit_return : " << limit_return << std::endl;
594 : }
595 :
596 : #ifndef ONLY_CPU
597 : if (methodChoice == 2)
598 : {
599 : int type_query = -1; // esperons que ce soit inutile !?!?!?!
600 : int index_type_query = 0;
601 : // int verbose_local = 0; // VR 20-9-17 : quand on aura debuggue
602 : fromCPU(result, id_query, ReadCacheCPU, type_query, ids, limit_return, distances, query_desc, verbose, index_type_query);
603 : }
604 : else
605 : #endif
606 0 : {
607 0 : NNeighbors(result, id_query, (int) nbrCentroids, dimension,
608 : tempCluster, ids, limit_return, distances, query_desc, divergence,verbose);
609 : }
610 :
611 : // Il faut utiliser ici fromCPU !?!?! comment-est ce que je veux l'interfacer ?
612 :
613 : // VR 17-1-17 : il faut faire la liste avec les id et pas les photo_id pour rendre plus rapide la seconde partie qunad on fait la moyenne du cluster
614 0 : if (result.size() == 0)
615 : {
616 0 : std::cout << "Empty result for one photos, maybe there are no cluster, we cannot assign the photo to a cluster ! " << std::endl;
617 0 : continue;
618 : }
619 :
620 0 : if (result.size() > 0 && distances.size() > 0)
621 : {
622 0 : int id_result = result[0];
623 0 : if (verbose)
624 0 : std::cout << " id_result : " << id_result << std::endl;
625 0 : list_ids_per_clusters[id_result].push_back(i);
626 0 : list_photo_ids_per_cluster[id_result].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[i]);
627 0 : list_minimum_distances_photo_ids_per_clusters[id_result].push_back(distances[0]);
628 : }
629 : else
630 : {
631 0 : std::cout << " Empty result for id : " << ReadCacheCPUPointerOneDescriptorType.ids_vec[i] << std::endl;
632 : }
633 : }
634 0 : for(int j=0; j<nbrCentroids; j++){
635 0 : int sizeclt = list_ids_per_clusters[j].size();
636 0 : std::cout<<"size cluster "<<j<<" : "<<sizeclt<<std::endl;
637 0 : std::cout<<"size list per cluster : "<<list_photo_ids_per_cluster[j].size()<<std::endl;
638 : }
639 : }
640 0 : else if (methodChoice == 1) // VR 18-9-17 : we would like to link pds's MC methods
641 : {
642 : // VR 18-9-17 Ici les recherches vont etre fais de maniere vectoriels, donc sans doute la signature de la fonction va changer, et il va y avoir des ajustements entre les ids et photo_ids
643 0 : std::vector<uint32_t> liste_ids, candidats_grille;
644 0 : std::vector<data> dataCPU;
645 : // VR 18-9-17 : cela aurait ete plus facile de mettre ceux-ci apres plutot qu'avant !
646 0 : for (int i = 0; i < ReadCacheCPUPointerOneDescriptorType.nb_data; i++)
647 : {
648 0 : liste_ids.push_back(i);
649 0 : for (int d = 0; d < dimension; d++)
650 : {
651 : // VR 19-9-17 : il doit y avoir une maniere de copier plus rapide !
652 0 : dataCPU.push_back(ReadCacheCPUPointerOneDescriptorType.datas_vec[i * dimension + d]);
653 : }
654 : }
655 :
656 0 : for (int i = 0; i < nbrCentroids; i++)
657 0 : candidats_grille.push_back(liste_ids.size() + i);
658 :
659 0 : for (int i = 0; i < clusters.size(); i++)
660 : {
661 0 : dataCPU.push_back(clusters[i]);
662 : }
663 :
664 0 : datag * pointeurGPU;
665 :
666 : #ifndef ONLY_CPU
667 : size_t sizemalloc = dataCPU.size() * sizeof(data);
668 : testCUDA(cudaMalloc(&pointeurGPU, sizemalloc));
669 : testCUDA(cudaMemcpy(pointeurGPU, &(dataCPU.front()), sizemalloc, cudaMemcpyHostToDevice));
670 : #endif
671 :
672 0 : if (verbose)
673 : {
674 0 : std::cout << "Entering query_pds_from_cpu !" << std::endl;
675 : }
676 :
677 0 : int current_limit = 0;
678 0 : query_pds_from_cpu(result, distances,
679 : current_limit,
680 0 : &(liste_ids.front()), // sans doute la liste des queries, sauf le premier qui en est la taille
681 0 : liste_ids.size(), // number query
682 0 : &(candidats_grille.front()),// std::vector<uint32_t> & candidats,
683 0 : candidats_grille.size(), // number candidats
684 0 : liste_ids.size() + candidats_grille.size(), // number data total (m + nbc)
685 : dimension,
686 : pointeurGPU,
687 : verbose
688 : );
689 :
690 :
691 : // Post traitement a faire VR 19-9-17
692 0 : for (int i = 0; i < ReadCacheCPUPointerOneDescriptorType.nb_data; i++)
693 : {
694 : // MC : il fallait mettre candidats_grille[result[i]] - liste_ids.size(), ou plus simplement encore result[i]
695 :
696 0 : int cluster_id = result[i];//candidats_grille[result[i]] - liste_ids.size();
697 : // VR 18-9-17 si ca crashe il faudra afficher cluster_id
698 0 : list_ids_per_clusters[cluster_id].push_back(i);
699 0 : list_photo_ids_per_cluster[cluster_id].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[i]);
700 0 : list_minimum_distances_photo_ids_per_clusters[cluster_id].push_back(distances[i]);
701 : }
702 : }
703 :
704 :
705 0 : std::cout << std::endl << std::endl;
706 :
707 0 : clock_t startClockQuery = clock();
708 :
709 0 : new_clusters.resize(clusters.size());
710 : int idx;
711 : unsigned long cellSize;
712 0 : for (int i = 0 ; i < nbrCentroids ; i++)
713 : {
714 0 : cellSize = list_photo_ids_per_cluster[i].size();
715 0 : for (int k = 0; k < cellSize ; k++)
716 : {
717 : // int idx = FindIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, ReadCacheCPUPointerOneDescriptorType.ids_vec.size(), list_photo_ids_per_clusters[i][k]);
718 0 : idx = list_ids_per_clusters[i][k];
719 :
720 0 : for (int l = 0 ; l < dimension; l++)
721 0 : new_clusters[i * dimension + l] += ReadCacheCPUPointerOneDescriptorType.datas_vec[idx * dimension + l];
722 : }
723 :
724 0 : if ( cellSize > 0 )
725 : {
726 0 : for (int l = 0 ; l < dimension; l++)
727 0 : new_clusters[i * dimension + l] /= cellSize;
728 : }
729 : }
730 :
731 0 : if(0){
732 : std::cout<<"in kmeanoid"<<std::endl<<std::endl;
733 : std::vector<data> center_mean(dimension);
734 :
735 : for(int i=0; i< nbrCentroids ; i++){
736 : cellSize = list_photo_ids_per_cluster[i].size();
737 : std::vector<data> data_cluster(dimension*cellSize);
738 : for(int k=0; k<dimension; k++){
739 : center_mean[k] = new_clusters[i*dimension +k];
740 : }
741 : for(int l=0; l<cellSize; l++){
742 : idx = list_ids_per_clusters[i][l];
743 : for(int m=0; m<dimension; m++){
744 : data_cluster[l*dimension+m] = ReadCacheCPUPointerOneDescriptorType.datas_vec[idx * dimension + m];
745 : }
746 : }
747 : //NNeighbors();
748 : }
749 : }
750 :
751 0 : clock_t endClockQuery = clock();
752 0 : std::cout << "Computing new clusters took " << (endClockQuery - startClockQuery) << " micro seconds " << std::endl;
753 :
754 0 : printf("avant le resize\n");
755 :
756 0 : printf("nbrCentroids=%lu\n", nbrCentroids);
757 :
758 :
759 0 : size_and_inertia.clear();
760 0 : size_and_inertia.resize(nbrCentroids);
761 0 : VDInt inertia;
762 0 : int size;
763 :
764 :
765 0 : printf("avant la boucle ! \n");
766 :
767 0 : for (int i = 0 ; i < nbrCentroids ; i++)
768 : {
769 :
770 0 : printf("avant\n");
771 :
772 0 : size = (int) list_minimum_distances_photo_ids_per_clusters[i].size();
773 0 : inertia = 0;
774 :
775 0 : printf("i=%d, size=%d\n", i, size);
776 :
777 :
778 0 : for (int k = 0; k < size; k++)
779 0 : inertia += list_minimum_distances_photo_ids_per_clusters[i][k];
780 :
781 0 : size_and_inertia[i] = std::pair<int, VDInt>(size, inertia/ReadCacheCPUPointerOneDescriptorType.nb_data);
782 : }
783 0 : std::cout << " about to leave auxKmeanOnCPU " << std::endl;
784 : }
785 :
786 0 : VDInt computeDistanceSquare(const std::vector<VDInt> & a, const std::vector<VDInt> & b)
787 : {
788 0 : VDInt dist = 0;
789 0 : long int temp;
790 0 : unsigned long dim = std::min<unsigned long>(a.size(), b.size());
791 0 : for (int i = 0; i < dim ; i++)
792 : {
793 0 : temp = (int)a[i] - (int)b[i];
794 0 : dist += temp * temp;
795 : }
796 0 : return dist;
797 : }
798 :
799 : // VR 11-1-17 : faire une fonction aux ! => je pense que c'est fait VR 2-4-17
800 0 : void onCPUKmeanOneStepSplitAndStick(std::vector<VDInt> &clusters,
801 : std::vector<std::pair<int, VDInt> > & size_and_inertia,
802 : types_datas_t &ReadCacheCPUPointerOneDescriptorType,
803 : char divergence,
804 : int verbose,
805 : SplitAndStickParam param_split_stick)
806 : {
807 0 : std::vector<VDInt> new_clusters;
808 0 : std::vector<std::vector<uint32_t> > list_photo_ids_per_cluster;
809 0 : std::vector<std::vector<uint32_t> > list_ids_per_clusters;
810 0 : std::vector<std::vector<VDInt> > list_minimum_distances_photo_ids_per_clusters;
811 :
812 0 : auxKmeanOnCPU(new_clusters, size_and_inertia, list_photo_ids_per_cluster, list_ids_per_clusters, list_minimum_distances_photo_ids_per_clusters, clusters, ReadCacheCPUPointerOneDescriptorType, divergence, verbose);
813 :
814 0 : std::vector<std::vector<uint32_t> > list_photo_ids_per_clusters_before_split_and_stick = list_ids_per_clusters;
815 0 : std::cout << " Before split and stick clusters.size() " << clusters.size() << " new_clusters.size() " << new_clusters.size() << std::endl;
816 :
817 0 : int nb_clusters = (int) clusters.size() / ReadCacheCPUPointerOneDescriptorType.size;
818 :
819 0 : std::vector<VDInt> local_inertia(nb_clusters);
820 : // should be of size list_minimum_distances_photo_ids_per_clusters
821 0 : for (int i = 0; i < nb_clusters ; i++)
822 : {
823 0 : local_inertia[i] = 0;
824 :
825 0 : for (int k = 0; k < list_minimum_distances_photo_ids_per_clusters[i].size(); k++)
826 0 : local_inertia[i] += list_minimum_distances_photo_ids_per_clusters[i][k];
827 : }
828 :
829 0 : std::vector<uint32_t> id(nb_clusters);
830 0 : for (int i = 0; i < nb_clusters ; i++) id[i] = i;
831 :
832 : // order map (a construire)
833 : // parametre qui doivent venir
834 0 : quick_sort<VDInt>(id, local_inertia, nb_clusters, verbose);
835 :
836 0 : int nb_to_remove = nb_clusters / param_split_stick.fraction_stick;
837 0 : if (nb_to_remove == 0) nb_to_remove = 1;
838 :
839 0 : int nb_to_add = nb_clusters / param_split_stick.fraction_split;
840 0 : if (nb_to_add == 0) nb_to_add = 1;
841 :
842 : // VR 14-1-2017 : la il faut maintenant rajouter et splitter les clusters
843 0 : if (nb_clusters < nb_to_add + nb_to_remove)
844 : {
845 0 : clusters = new_clusters;
846 0 : std::cout << " Il y a un problème ! " << std::endl;
847 : }
848 : else
849 : {
850 : // VR 9-2-17 : je ne sais pas comment tout ceci est numéroté
851 : // std::vector<std::vector<uint32_t> > list_photo_ids_per_clusters_after_sns(nb_clusters - nb_to_remove + nb_to_add);
852 : // std::vector<std::vector<uint32_t> > list_ids_per_clusters_after_sns(nb_clusters - nb_to_remove + nb_to_add);
853 :
854 0 : std::vector<std::pair<int, VDInt> > new_size_and_inertia(nb_clusters - (nb_to_add + nb_to_remove));
855 0 : new_size_and_inertia.reserve(nb_clusters);
856 :
857 : // Ceux qui reste tel quel :
858 0 : std::vector<VDInt> clusters_split_and_stick;
859 0 : int id_cluster;
860 0 : for (int i = 0; i < nb_clusters - (nb_to_add + nb_to_remove); i++)
861 : {
862 0 : id_cluster = id[i + nb_to_remove];
863 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
864 0 : clusters_split_and_stick.push_back(new_clusters[ReadCacheCPUPointerOneDescriptorType.size * (id_cluster) + k]);
865 :
866 0 : new_size_and_inertia[i] = size_and_inertia[id_cluster];
867 : }
868 :
869 0 : int nb_elem, this_data ,this_data_idx;
870 0 : VDInt first_inertia = 0, second_inertia = 0;
871 0 : std::vector<VDInt> b(ReadCacheCPUPointerOneDescriptorType.size);
872 :
873 0 : for (int i = 0; i < nb_to_add; i++)
874 : {
875 0 : id_cluster = id[nb_clusters - nb_to_add + i];
876 :
877 : // the main one, to be commented
878 :
879 0 : nb_elem = (int)list_photo_ids_per_cluster[id_cluster].size();
880 0 : if (nb_elem < 2)
881 : {
882 0 : std::cout << " On perds un cluster ! " << std::endl;
883 :
884 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
885 0 : clusters_split_and_stick.push_back(new_clusters[ReadCacheCPUPointerOneDescriptorType.size * (id_cluster) + k]);
886 :
887 0 : new_size_and_inertia.push_back(size_and_inertia[id_cluster]);
888 : }
889 : else
890 : {
891 0 : std::vector<VDInt> first_half_cluster(ReadCacheCPUPointerOneDescriptorType.size), second_half_cluster(ReadCacheCPUPointerOneDescriptorType.size);
892 0 : for (int l = 0; l < nb_elem / 2; l++)
893 : {
894 0 : this_data = list_photo_ids_per_cluster[id_cluster][l];
895 0 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
896 :
897 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
898 0 : first_half_cluster[k] += ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
899 : }
900 0 : for (int l = nb_elem / 2; l < nb_elem; l++)
901 : {
902 0 : this_data = list_photo_ids_per_cluster[id_cluster][l];
903 0 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
904 :
905 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
906 0 : second_half_cluster[k] += ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
907 : }
908 :
909 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
910 : {
911 0 : first_half_cluster[k] /= (nb_elem / 2);
912 0 : second_half_cluster[k] /= (nb_elem - nb_elem / 2);
913 : }
914 :
915 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
916 0 : clusters_split_and_stick.push_back(first_half_cluster[k]);
917 :
918 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
919 0 : clusters_split_and_stick.push_back(second_half_cluster[k]);
920 :
921 : first_inertia = 0;
922 0 : for (int l = 0; l < nb_elem / 2; l++)
923 : {
924 0 : this_data = list_photo_ids_per_cluster[id_cluster][l];
925 0 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
926 :
927 : // ca me parait assez dangereux ! VR 15-1-17
928 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
929 0 : b[k] = ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
930 :
931 0 : first_inertia += computeDistanceSquare(first_half_cluster, b);
932 : }
933 0 : new_size_and_inertia.push_back(std::pair<int, VDInt>(nb_elem / 2, first_inertia));
934 :
935 0 : second_inertia = 0;
936 0 : for (int l = nb_elem / 2; l < nb_elem; l++)
937 : {
938 0 : this_data = list_photo_ids_per_cluster[id_cluster][l];
939 0 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
940 :
941 : // ca me parait assez dangereux ! VR 15-1-17
942 : // std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin());
943 0 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
944 0 : b[k] = ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
945 :
946 0 : second_inertia += computeDistanceSquare(second_half_cluster, b);
947 : }
948 0 : new_size_and_inertia.push_back(std::pair<int, VDInt>(nb_elem - nb_elem / 2, second_inertia));
949 : }
950 : }
951 :
952 : // Ceux qu'on a enleve et qu'on met au bon endroit :
953 : // On va devoir chercher des plus proche voisin, donc on rajoute cette affaire la
954 0 : types_datas_t SearchCluster = ReadCacheCPUPointerOneDescriptorType;
955 0 : SearchCluster.size = ReadCacheCPUPointerOneDescriptorType.size;
956 0 : SearchCluster.nb_data = (int) clusters_split_and_stick.size() / SearchCluster.size;
957 0 : if (SearchCluster.nb_data == 0)
958 : {
959 0 : std::cout << "Empty clusters we can't update them with Lloyds algorithm (and in gpu mode it would crash ERROR PROBLEM !) VR 23-1-17 " << std::endl;
960 0 : return;
961 : }
962 :
963 0 : SearchCluster.ids_vec.resize(SearchCluster.nb_data);
964 0 : for (int i = 0; i < SearchCluster.ids_vec.size(); i++)
965 0 : SearchCluster.ids_vec[i] = i;
966 :
967 0 : SearchCluster.datas_vec.resize(clusters_split_and_stick.size());
968 0 : for (int i = 0; i < clusters_split_and_stick.size(); i++)
969 0 : SearchCluster.datas_vec[i] = clusters_split_and_stick[i];
970 :
971 0 : const int id_query = -1;
972 0 : const int limit_return = 1;
973 :
974 0 : std::vector<data> query_desc(SearchCluster.size);
975 0 : std::vector<uint32_t> ids;
976 0 : std::vector<uint32_t> result;
977 0 : std::vector<VDInt> distances;
978 :
979 0 : for (int i = 0; i < nb_to_remove; i++)
980 : {
981 : // id ils sont trié comme il faut par inertie croissante, on peut imaginer qu'il y a du coup peu de donnée la dedans
982 0 : id_cluster = id[i];
983 :
984 0 : for (int l = 0; l < list_photo_ids_per_clusters_before_split_and_stick[id_cluster].size(); l++)
985 : {
986 0 : ids = SearchCluster.ids_vec;
987 0 : for (int k = 0; k < SearchCluster.size; k++)
988 0 : query_desc[k] = ReadCacheCPUPointerOneDescriptorType.datas_vec[list_photo_ids_per_clusters_before_split_and_stick[id_cluster][l] * ReadCacheCPUPointerOneDescriptorType.size + k];
989 :
990 0 : std::cout << ",";
991 0 : query(result, id_query, SearchCluster.nb_data, SearchCluster.size, SearchCluster.datas_vec, ids, limit_return, distances, query_desc, verbose);
992 :
993 : // VR 17-1-17 : il faut faire la liste avec les id et pas les photo_id pour rendre plus rapide la seconde partie qunad on fait la moyenne du cluster
994 0 : list_ids_per_clusters[result[0]].push_back(i);
995 0 : list_photo_ids_per_cluster[result[0]].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[i]);
996 0 : list_minimum_distances_photo_ids_per_clusters[result[0]].push_back(distances[0]);
997 :
998 0 : new_size_and_inertia[result[0]].first += 1;
999 0 : new_size_and_inertia[result[0]].second += distances[0];
1000 :
1001 : // new_size_and_inertia.push_back(size_and_inertia[id_cluster]);
1002 :
1003 : // int this_data = list_photo_ids_per_clusters[id_cluster][l];
1004 : // for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
1005 : // {
1006 : // clusters_split_and_stick.push_back(new_clusters[ReadCacheCPUPointerOneDescriptorType.size * (id_cluster) + k]);
1007 : // }
1008 : }
1009 0 : std::cout << std::endl << std::endl;
1010 : }
1011 :
1012 0 : std::cout << " After split and stick clusters.size() " << clusters.size() << " clusters_split_and_stick.size() " << clusters_split_and_stick.size() << std::endl;
1013 :
1014 0 : size_and_inertia = new_size_and_inertia;
1015 0 : clusters = clusters_split_and_stick;
1016 : }
1017 : }
1018 :
1019 :
1020 : //20-08-18 fonction des kmeans actuelle sans doute
1021 0 : void onCPUKmeanOneStep( std::vector<VDInt> &clusters,
1022 : std::vector<std::pair<int, VDInt> > & size_and_inertia,
1023 : types_datas_t &ReadCacheCPUPointerOneDescriptorType,
1024 : std::vector<std::vector<uint32_t> > & list_photo_ids_per_cluster, char divergence,
1025 : int verbose, int methodChoice)
1026 : {
1027 0 : std::vector<VDInt> new_clusters;
1028 :
1029 0 : std::vector<std::vector<uint32_t> > list_ids_per_clusters;
1030 0 : std::vector<std::vector<VDInt> > list_minimum_distances_photo_ids_per_clusters; // VR 15-1-17 : it is the distance square, we could change the name
1031 :
1032 0 : if (methodChoice == 0)
1033 : {
1034 0 : std::cout << "\n---- Choose method 2 ----\n" << std::endl;
1035 0 : std::cout << "\n---- Original Method ----\n" << std::endl;
1036 : }
1037 : else
1038 : {
1039 0 : for(int i=0; i<size_and_inertia.size(); i++){
1040 0 : if(size_and_inertia[i].first == 0){
1041 0 : std::cout<<"cluster vide n : "<<i<<std::endl;
1042 0 : uint32_t dim = ReadCacheCPUPointerOneDescriptorType.size;
1043 0 : int ind = rand()%(ReadCacheCPUPointerOneDescriptorType.datas_vec.size()/dim);
1044 0 : std::cout<<"id : "<<ind<<std::endl;
1045 0 : for(int j=0; j<dim; j++){
1046 0 : clusters[i*dim+j] = ReadCacheCPUPointerOneDescriptorType.datas_vec[ind*dim+j];
1047 : }
1048 : }
1049 : }
1050 : //list_photo_ids_per_cluster.clear();
1051 : //list_photo_ids_per_cluster.resize(clusters.size()/ReadCacheCPUPointerOneDescriptorType.size);
1052 : //std::cout <<list_photo_ids_per_cluster.size()<<std::endl;
1053 0 : if(methodChoice == 3){
1054 0 : auxKmeanOnCPU(new_clusters, size_and_inertia, list_photo_ids_per_cluster, list_ids_per_clusters, list_minimum_distances_photo_ids_per_clusters, clusters, ReadCacheCPUPointerOneDescriptorType,
1055 : divergence, verbose, -1);
1056 : }
1057 : else
1058 : {
1059 0 : auxKmeanOnCPU(new_clusters, size_and_inertia, list_photo_ids_per_cluster, list_ids_per_clusters, list_minimum_distances_photo_ids_per_clusters, clusters, ReadCacheCPUPointerOneDescriptorType,
1060 : divergence, verbose, methodChoice);
1061 : }
1062 : //std::cout << " Outside auxKmeanOnCPU : " << std::endl;
1063 : }
1064 0 : std::cout << " After cpu step clusters.size() " << clusters.size() << " new_clusters.size() " << new_clusters.size() << std::endl;
1065 0 : if(methodChoice == 3){
1066 0 : clusters = new_clusters;
1067 : }
1068 :
1069 0 : }
1070 :
1071 :
1072 :
1073 : #ifndef ONLY_CPU
1074 :
1075 : //MC-21-08-18 ajout de la fonction appelee par le gpu
1076 : __global__ void selectcentroid(datag * data, VDInt * centroid, int *count, int dim, int nb_cluster, VDInt * mean, int size,
1077 : int * centroidselec, VDInt * distanceg){
1078 : //32*rep dimensions calculees
1079 : //id = photo sur laquelle on travaille
1080 : //dim_local = dimension sur laquelle on fait les calculs
1081 : //warp = n° du warp sur lequel on est
1082 : //lane = n° d'un thread a l'interieur d'un warp
1083 :
1084 : int rep=0;
1085 : int warpsize=32;
1086 : int warp=threadIdx.x/warpsize;
1087 : int nb_warp=blockDim.x/warpsize;
1088 : int lane=threadIdx.x % warpsize;
1089 : int idx=threadIdx.x+blockIdx.x*blockDim.x;
1090 :
1091 : __shared__ VDInt distance_max[32];
1092 : __shared__ VDInt distance[32];
1093 : __shared__ int censelecsha[32];
1094 : __shared__ VDInt dist[1024];
1095 :
1096 :
1097 : while(idx<size*32){
1098 : rep=0;
1099 : int id=blockIdx.x*nb_warp+warp;
1100 : int dim_loc=threadIdx.x%32;
1101 :
1102 : if (dim_loc<dim){
1103 :
1104 : if (rep==0)
1105 : distance_max[warp]=LONG_MAX;
1106 : VDInt dist_loc;
1107 : //pour une etape des kmean
1108 : for(int c=0; c<nb_cluster; c++){
1109 : //if(idx==0)
1110 : //printf("cluster %d \n",c);
1111 : rep=0;
1112 : dim_loc=threadIdx.x%32;
1113 : distance[warp]=0;
1114 : //on continue tant qu'on a pas calculé toutes les dimensions
1115 : while (dim_loc<dim){
1116 : dist_loc=0;
1117 :
1118 : //dist l2
1119 : dist_loc=(data[id*dim+dim_loc]-centroid[c*dim+dim_loc])*(data[id*dim+dim_loc]-centroid[c*dim+dim_loc]);
1120 : //dist l1
1121 : int i=32/2;
1122 : dist[threadIdx.x]=dist_loc;
1123 : while (i!=0){
1124 : //somme de la moitie des threads du warp a chaque boucle
1125 : if(lane<i){
1126 : dist[threadIdx.x]+= dist[threadIdx.x+i];
1127 : }
1128 : //fonction pas connue
1129 : i/=2;
1130 : }
1131 : if (lane==0){
1132 : distance[warp]+=dist[threadIdx.x];
1133 : __syncthreads();
1134 : }
1135 :
1136 : dim_loc+=32;
1137 : dist_loc=0;
1138 : dist[threadIdx.x]=0;
1139 : rep+=1;
1140 : }
1141 : //maj des donnees a la fin du calcul de distance
1142 : if(lane==0){
1143 : if (distance[warp] < distance_max[warp]){
1144 : distance_max[warp]=distance[warp];
1145 : censelecsha[warp]=c;
1146 : }
1147 : }
1148 : }
1149 :
1150 : if(lane==0){
1151 : centroidselec[id]=censelecsha[warp];
1152 : distanceg[id]=distance_max[warp];
1153 : atomicAdd(&count[centroidselec[id]], 1);
1154 : }
1155 : __syncthreads();
1156 :
1157 : //ajout de la donnee pour calculer le nouveau centroid
1158 : dim_loc=threadIdx.x%32;
1159 : while (dim_loc<dim){
1160 :
1161 : atomicAdd(&mean[censelecsha[warp]*dim+dim_loc],data[id*dim+dim_loc]);
1162 :
1163 : dim_loc+=32;
1164 : }
1165 : }
1166 : idx+=blockDim.x*gridDim.x;
1167 : id+=nb_warp*gridDim.x;
1168 :
1169 : }
1170 :
1171 :
1172 : }
1173 : #endif
1174 :
1175 :
1176 :
1177 : #ifndef ONLY_CPU
1178 : //MC-20-08-18 ajout de la fonction gpu des kmean
1179 : void onCPUKmeanOneStepMCgpu( std::vector<VDInt> &clusters,
1180 : std::vector<std::pair<int, VDInt> > & size_and_inertia,
1181 : types_datas_t &ReadCacheCPUPointerOneDescriptorType,
1182 : int verbose,std::vector<std::vector<uint32_t> > & list_photo_ids_per_cluster){
1183 :
1184 : //ajouter les parametres pour le size and inertia
1185 : std::vector<VDInt> new_clusters;
1186 :
1187 : std::vector<std::vector<uint32_t> > list_ids_per_clusters;
1188 : std::vector<std::vector<VDInt> > list_minimum_distances_photo_ids_per_clusters;
1189 :
1190 : //recup des info a verifier
1191 : const uint32_t nbrPhoto = ReadCacheCPUPointerOneDescriptorType.nb_data;
1192 : const uint32_t dimension = ReadCacheCPUPointerOneDescriptorType.size;
1193 : //voir si on deplace ou non cette partie dans une autre fonction
1194 : VDInt * clustergpu;
1195 : int * cluster_selec_gpu;
1196 : int * cluster_selec;
1197 : const unsigned long nbrCluster= clusters.size()/dimension;
1198 : testCUDA(cudaMalloc(&clustergpu, clusters.size()*sizeof(VDInt)));
1199 : testCUDA(cudaMemcpy(clustergpu, clusters.data(), clusters.size()*sizeof(VDInt), cudaMemcpyHostToDevice));
1200 : testCUDA(cudaMalloc(&cluster_selec_gpu, nbrPhoto*sizeof(int)));
1201 : testCUDA(cudaMemset(cluster_selec_gpu,0, nbrPhoto*sizeof(int)));
1202 : cluster_selec=(int*)calloc(nbrPhoto, sizeof(int));
1203 : VDInt * meangpu;
1204 : VDInt * mean;
1205 : mean=(VDInt*)calloc(clusters.size(), sizeof(VDInt));
1206 : testCUDA(cudaMalloc(&meangpu, clusters.size()*sizeof(VDInt)));
1207 : testCUDA(cudaMemset(meangpu, 0, clusters.size()*sizeof(VDInt)));
1208 : int * countgpu;
1209 : int * count;
1210 : std::cout<<"taille countgpu : "<<nbrCluster<<std::endl;
1211 : testCUDA(cudaMalloc(&countgpu, nbrCluster*sizeof(int)));
1212 : testCUDA(cudaMemset(countgpu, 0, nbrCluster*sizeof(int)));
1213 : count=(int*)calloc(nbrCluster, sizeof(int));
1214 : VDInt * distance;
1215 : VDInt * distancegpu;
1216 : testCUDA(cudaMalloc(&distancegpu, nbrPhoto*sizeof(VDInt)));
1217 : testCUDA(cudaMemset(distancegpu, 0, nbrPhoto*sizeof(VDInt)));
1218 : distance=(VDInt*)calloc(nbrPhoto, sizeof(VDInt));
1219 :
1220 : std::cout<<"avant l'appel au kernel"<<std::endl;
1221 : selectcentroid<<<(nbrPhoto*32+NTPB-1)/NTPB,NTPB>>>(ReadCacheCPUPointerOneDescriptorType.dataGPU, clustergpu,\
1222 : countgpu, dimension, nbrCluster, meangpu,nbrPhoto,cluster_selec_gpu, distancegpu);
1223 : std::cout<<"apres l'appel au kernel"<<std::endl;
1224 :
1225 :
1226 : //recupreation des donnees et calcul de size and inertie
1227 : testCUDA(cudaMemcpy(cluster_selec, cluster_selec_gpu, nbrPhoto*sizeof(int), cudaMemcpyDeviceToHost));
1228 : testCUDA(cudaMemcpy(mean, meangpu, clusters.size()*sizeof(VDInt), cudaMemcpyDeviceToHost));
1229 : testCUDA(cudaMemcpy(count, countgpu, nbrCluster*sizeof(int), cudaMemcpyDeviceToHost));
1230 : testCUDA(cudaMemcpy(distance, distancegpu, nbrPhoto*sizeof(VDInt), cudaMemcpyDeviceToHost));
1231 :
1232 : size_and_inertia.clear();
1233 : size_and_inertia.resize(nbrCluster);
1234 : list_photo_ids_per_cluster.clear();
1235 : list_photo_ids_per_cluster.resize(nbrCluster);
1236 : std::vector<VDInt> inertia(nbrCluster, 0);
1237 : int size_cluster;
1238 :
1239 : for(int j=0; j<nbrPhoto; j++){
1240 :
1241 : inertia[cluster_selec[j]]+=distance[j];
1242 : list_photo_ids_per_cluster[cluster_selec[j]].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[j]);
1243 : }
1244 :
1245 : for(int i =0; i<nbrCluster; i++){
1246 : size_cluster=count[i];
1247 : std::cout<<"nb de donnees pour le "<<i<<"e cluster : "<<size_cluster<<" (count)"<<std::endl;
1248 : for (int j=0; j< dimension; j++){
1249 : if(size_cluster!=0){
1250 : new_clusters.push_back(mean[i*dimension+j]/size_cluster);
1251 : }else{
1252 : new_clusters.push_back(clusters[i*dimension+j]);
1253 : }
1254 : }
1255 : size_and_inertia[i]=std::pair<int, VDInt> (size_cluster, inertia[i]);
1256 : }
1257 :
1258 : clusters=new_clusters;
1259 :
1260 : free(mean);
1261 : free(count);
1262 : free(distance);
1263 : free(cluster_selec);
1264 : testCUDA(cudaFree(meangpu));
1265 : testCUDA(cudaFree(countgpu));
1266 : testCUDA(cudaFree(clustergpu));
1267 : testCUDA(cudaFree(cluster_selec_gpu));
1268 : testCUDA(cudaFree(distancegpu));
1269 : }
1270 : #endif
1271 :
1272 :
1273 :
1274 :
1275 : #ifndef CUDA7
1276 : #ifndef ONLY_CPU
1277 : __global__ void selectcentroidpds(datag * data, VDInt * centroid, int *count, int dim, int nb_cluster, VDInt * mean, int size,
1278 : int * centroidselec, VDInt * distanceg){
1279 : //32*rep dimensions calculees
1280 : //id = photo sur laquelle on travaille
1281 : //dim_local = dimension sur laquelle on fait les calculs
1282 : //warp = n° du warp sur lequel on est
1283 : //lane = n° d'un thread a l'interieur d'un warp
1284 : int rep=0;
1285 : int warpsize=32;
1286 : int warp=threadIdx.x/warpsize;
1287 : int nb_warp=blockDim.x/warpsize;
1288 : int lane=threadIdx.x % warpsize;
1289 : int idx=threadIdx.x+blockIdx.x*blockDim.x;
1290 : int flag;
1291 :
1292 : __shared__ VDInt distance_max[32];
1293 : __shared__ VDInt distance[32];
1294 : __shared__ int censelecsha[32];
1295 : __shared__ VDInt dist[1024];
1296 :
1297 : while(idx<size*warpsize){
1298 : rep=0;
1299 : int id=blockIdx.x*nb_warp+warp;
1300 : int dim_loc=threadIdx.x%warpsize;
1301 :
1302 : if (dim_loc<dim){
1303 :
1304 : if (rep==0)
1305 : distance_max[warp]=LONG_MAX;
1306 : VDInt dist_loc;
1307 :
1308 : //pour une etape des kmean
1309 : for(int c=0; c<nb_cluster; c++){
1310 : flag=0;
1311 : rep=0;
1312 : dim_loc=threadIdx.x%warpsize;
1313 : distance[warp]=0;
1314 : //on continue tant qu'on a pas calculé toutes les dimensions
1315 : while(dim_loc<128){
1316 : dist_loc=(data[id*dim+dim_loc]-centroid[c*dim+dim_loc])*(data[id*dim+dim_loc]-centroid[c*dim+dim_loc]);
1317 : if(dim_loc<dim && id>10900){
1318 : printf("id: %d, data: %u, centroid: %u, dist_loc %u, \n",id,data[id*dim+dim_loc],centroid[c*dim+dim_loc],dist_loc);
1319 : }
1320 : int i=warpsize/2;
1321 : dist[threadIdx.x]=dist_loc;
1322 : while(i!=0){
1323 : if(lane<i){
1324 : dist[threadIdx.x]+=dist[threadIdx.x+i];
1325 : }
1326 : i/=2;
1327 : }
1328 : if(lane==0){
1329 : distance[warp]+=dist[threadIdx.x+i];
1330 : __syncwarp();
1331 : }
1332 : dim_loc+=warpsize;
1333 : rep+=1;
1334 : dist_loc=0;
1335 : }
1336 : if(distance[warp]>distance_max[warp]){
1337 : flag=1;
1338 : }else{
1339 : dim_loc+=warpsize;
1340 : rep+=1;
1341 : while (dim_loc<dim){
1342 : dist_loc=0;
1343 : //dist l2
1344 : dist_loc=(data[id*dim+dim_loc]-centroid[c*dim+dim_loc])*(data[id*dim+dim_loc]-centroid[c*dim+dim_loc]);
1345 : //dist l1
1346 : int i=warpsize/2;
1347 : dist[threadIdx.x]=dist_loc;
1348 : while (i!=0){
1349 : //somme de la moitie des threads du warp a chaque boucle
1350 : if(threadIdx.x%warpsize<i){
1351 : dist[threadIdx.x]+= dist[threadIdx.x+i];
1352 : }
1353 : i/=2;
1354 : }
1355 : if (lane==0){
1356 : distance[warp]+=dist[threadIdx.x];
1357 : __syncwarp();
1358 : }
1359 : dim_loc+=warpsize;
1360 : rep+=1;
1361 : }
1362 : }
1363 : //maj des donnees a la fin du calcul de distance
1364 : if(lane==0){
1365 : //distance[warp]=sqrt(distance[warp]);
1366 : if (distance[warp] < distance_max[warp] && flag!=1){
1367 : distance_max[warp]=distance[warp];
1368 : censelecsha[warp]=c;
1369 : }
1370 : }
1371 : }
1372 : if(lane==0){
1373 : centroidselec[id]=censelecsha[warp];
1374 : distanceg[id]=distance_max[warp];
1375 : //ajout de 1 dans le nombre de donnees pour ce cluster
1376 : atomicAdd(&count[censelecsha[warp]], 1);
1377 : }
1378 : __syncwarp();
1379 : //ajout de la donnee pour calculer le nouveau centroid
1380 : dim_loc=threadIdx.x%warpsize;
1381 : while (dim_loc<dim){
1382 : atomicAdd(&mean[censelecsha[warp]*dim+dim_loc],data[id*dim+dim_loc]);
1383 : dim_loc+=warpsize;
1384 : }
1385 : }
1386 :
1387 : idx+=blockDim.x*gridDim.x;
1388 : id+=nb_warp*gridDim.x;
1389 :
1390 : }
1391 :
1392 :
1393 : }
1394 : #endif
1395 : #endif
1396 :
1397 :
1398 :
1399 : #ifndef ONLY_CPU
1400 : void onCPUKmeanOneStepPdsgpub( std::vector<VDInt> &clusters,
1401 : std::vector<std::pair<int, VDInt> > & size_and_inertia,
1402 : types_datas_t &ReadCacheCPUPointerOneDescriptorType,
1403 : int verbose,std::vector<std::vector<uint32_t> > & list_photo_ids_per_cluster, int nb_iter, int desc_dyn){
1404 :
1405 :
1406 : std::cout<<"on souhaite faire : "<<nb_iter<<" itérations"<<std::endl;
1407 : cudaEvent_t start, stop;
1408 : float elapstime;
1409 : //ajouter les parametres pour le size and inertia
1410 : std::vector<VDInt> new_clusters;
1411 :
1412 : std::vector<std::vector<uint32_t> > list_ids_per_clusters;
1413 : std::vector<std::vector<VDInt> > list_minimum_distances_photo_ids_per_clusters;
1414 :
1415 : //recup des info a verifier
1416 : const uint32_t nbrPhoto = ReadCacheCPUPointerOneDescriptorType.nb_data;
1417 : const uint32_t dimension = ReadCacheCPUPointerOneDescriptorType.size;
1418 : //voir si on deplace ou non cette partie dans une autre fonction
1419 : VDInt * clustergpu;
1420 : int * cluster_selec_gpu;
1421 : int * cluster_selec;
1422 : printf("avant alloc cluster et selc \n");
1423 : const unsigned long nbrCluster= clusters.size()/dimension;
1424 : testCUDA(cudaMalloc(&clustergpu, clusters.size()*sizeof(VDInt)));
1425 : testCUDA(cudaMemcpy(clustergpu, clusters.data(), clusters.size()*sizeof(VDInt), cudaMemcpyHostToDevice));
1426 : testCUDA(cudaMalloc(&cluster_selec_gpu, nbrPhoto*sizeof(int)));
1427 : testCUDA(cudaMemset(cluster_selec_gpu,0, nbrPhoto*sizeof(int)));
1428 : cluster_selec=(int*)calloc(nbrPhoto, sizeof(int));
1429 : VDInt * meangpu;
1430 : VDInt * mean;
1431 : printf("avant alloc mean \n");
1432 : mean=(VDInt*)calloc(clusters.size(), sizeof(VDInt));
1433 : testCUDA(cudaMalloc(&meangpu, clusters.size()*sizeof(VDInt)));
1434 : testCUDA(cudaMemset(meangpu, 0, clusters.size()*sizeof(VDInt)));
1435 : int * countgpu;
1436 : int * count;
1437 : testCUDA(cudaMalloc(&countgpu, nbrCluster*sizeof(int)));
1438 : testCUDA(cudaMemset(countgpu, 0, nbrCluster*sizeof(int)));
1439 : count=(int*)calloc(nbrCluster, sizeof(int));
1440 : VDInt * distance;
1441 : VDInt * distancegpu;
1442 : testCUDA(cudaMalloc(&distancegpu, nbrPhoto*sizeof(VDInt)));
1443 : testCUDA(cudaMemset(distancegpu, 0, nbrPhoto*sizeof(VDInt)));
1444 : distance=(VDInt*)calloc(nbrPhoto, sizeof(VDInt));
1445 : cudaEventCreate(&start);
1446 : cudaEventCreate(&stop);
1447 : cudaEventRecord(start,0);
1448 : for(int k=0; k<nb_iter-1; k++){
1449 :
1450 : if(desc_dyn==0){
1451 :
1452 : selectcentroidpds<<<(nbrPhoto*32+NTPBPDS-1)/NTPBPDS,NTPBPDS>>>(ReadCacheCPUPointerOneDescriptorType.dataGPU, clustergpu,\
1453 : countgpu, dimension, nbrCluster, meangpu,nbrPhoto,cluster_selec_gpu, distancegpu);
1454 : }else{
1455 : selectcentroidpds<<<(nbrPhoto*32+NTPBPDS-1)/NTPBPDS,NTPBPDS>>>(ReadCacheCPUPointerOneDescriptorType.dataGPUdyn,clustergpu,\
1456 : countgpu, dimension, nbrCluster, meangpu,nbrPhoto,cluster_selec_gpu, distancegpu);
1457 : }
1458 :
1459 : testCUDA(cudaMemcpy(count, countgpu, nbrCluster*sizeof(int), cudaMemcpyDeviceToHost));
1460 : testCUDA(cudaMemcpy(mean, meangpu, clusters.size()*sizeof(VDInt), cudaMemcpyDeviceToHost));
1461 : for(int i=0; i<nbrCluster; i++){
1462 : for(int j=0; j<dimension; j++){
1463 : if(count[i]!=0)
1464 : clusters[i*dimension+j]=mean[i*dimension+j]/count[i];
1465 : }
1466 : }
1467 : testCUDA(cudaMemset(meangpu, 0, clusters.size()*sizeof(VDInt)));
1468 : testCUDA(cudaMemset(countgpu, 0, nbrCluster*sizeof(int)));
1469 : testCUDA(cudaMemset(distancegpu, 0, nbrPhoto*sizeof(VDInt)));
1470 : }
1471 : if(desc_dyn==0)
1472 : selectcentroidpds<<<(nbrPhoto*32+NTPBPDS-1)/NTPBPDS,NTPBPDS>>>(ReadCacheCPUPointerOneDescriptorType.dataGPU, clustergpu,\
1473 : countgpu, dimension, nbrCluster, meangpu,nbrPhoto,cluster_selec_gpu, distancegpu);
1474 : else
1475 : selectcentroidpds<<<(nbrPhoto*32+NTPBPDS-1)/NTPBPDS,NTPBPDS>>>(ReadCacheCPUPointerOneDescriptorType.dataGPUdyn, clustergpu,\
1476 : countgpu, dimension, nbrCluster, meangpu,nbrPhoto,cluster_selec_gpu, distancegpu);
1477 : cudaEventRecord(stop,0);
1478 : cudaEventSynchronize(stop);
1479 : //recupreation des donnees et calcul de size and inertie
1480 : testCUDA(cudaMemcpy(cluster_selec, cluster_selec_gpu, nbrPhoto*sizeof(int), cudaMemcpyDeviceToHost));
1481 : testCUDA(cudaMemcpy(mean, meangpu, clusters.size()*sizeof(VDInt), cudaMemcpyDeviceToHost));
1482 : testCUDA(cudaMemcpy(count, countgpu, nbrCluster*sizeof(int), cudaMemcpyDeviceToHost));
1483 : testCUDA(cudaMemcpy(distance, distancegpu, nbrPhoto*sizeof(VDInt), cudaMemcpyDeviceToHost));
1484 :
1485 :
1486 : cudaEventElapsedTime(&elapstime, start,stop);
1487 : std::cout<<"temps ecoule : "<<elapstime<<std::endl;
1488 :
1489 : size_and_inertia.clear();
1490 : size_and_inertia.resize(nbrCluster);
1491 : list_photo_ids_per_cluster.clear();
1492 : list_photo_ids_per_cluster.resize(nbrCluster);
1493 : std::vector<VDInt> inertia(nbrCluster, 0);
1494 : int size_cluster;
1495 :
1496 : for(int j=0; j<nbrPhoto; j++){
1497 : inertia[cluster_selec[j]]+=distance[j];
1498 : list_photo_ids_per_cluster[cluster_selec[j]].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[j]);
1499 : }
1500 :
1501 : for(int i =0; i<nbrCluster; i++){
1502 : size_cluster=count[i];
1503 : std::cout<<"nb de donnees pour le "<<i<<"e cluster : "<<size_cluster<<" (count)"<<std::endl;
1504 : for (int j=0; j< dimension; j++){
1505 : if(size_cluster!=0){
1506 : std::cout<<mean[i*dimension+j]/size_cluster<<", ";
1507 : new_clusters.push_back(mean[i*dimension+j]/size_cluster);
1508 : }else{
1509 : new_clusters.push_back(clusters[i*dimension+j]);
1510 : }
1511 : }
1512 : size_and_inertia[i]=std::pair<int, VDInt> (size_cluster, inertia[i]);
1513 : }
1514 :
1515 :
1516 : clusters=new_clusters;
1517 :
1518 : free(mean);
1519 : free(count);
1520 : free(distance);
1521 : free(cluster_selec);
1522 : testCUDA(cudaFree(meangpu));
1523 : testCUDA(cudaFree(countgpu));
1524 : testCUDA(cudaFree(clustergpu));
1525 : testCUDA(cudaFree(cluster_selec_gpu));
1526 : testCUDA(cudaFree(distancegpu));
1527 :
1528 :
1529 :
1530 : }
1531 :
1532 : // lp, desc_type, divergence, list_photo_ids_per_cluster, desc_dyn
1533 :
1534 : #ifdef FLOAT_TYPE
1535 : void onGPUKmeanOneStepThrust(std::vector<VDInt> &clusters,
1536 : std::vector<std::pair<int, VDInt> > & size_and_inertia,
1537 : types_datas_t &ReadCacheCPUPointerOneDescriptorType,
1538 : std::vector<std::vector<uint32_t> > & list_photo_ids_per_cluster, char divergence, int verbose)
1539 : {
1540 : if(verbose){
1541 : std::cout<<"Begin kmeans with thrust"<<std::endl;
1542 : }
1543 : std::cout<<"Begin kmeans with thrust"<<std::endl;
1544 : const int nbphoto = ReadCacheCPUPointerOneDescriptorType.nb_data;
1545 : const int dimension = ReadCacheCPUPointerOneDescriptorType.size;
1546 : const int nbcluster = clusters.size()/dimension;
1547 :
1548 :
1549 : std::cout<<"n: "<<nbphoto<<", d: "<<dimension<<", k: "<<nbcluster<<std::endl;
1550 :
1551 : thrust::device_vector<data> device_data(nbphoto*dimension);
1552 : thrust::device_vector<data> device_clusters(nbcluster*dimension);
1553 : //std::cout<<"before vector to thrust device "<<std::endl;
1554 :
1555 : vector_to_thrust_device(ReadCacheCPUPointerOneDescriptorType.datas_vec, nbphoto, dimension, device_data);
1556 : vector_to_thrust_device(clusters, nbcluster, dimension, device_clusters);
1557 :
1558 : thrust::device_vector<int> device_label(nbphoto);
1559 : thrust::device_vector<VDInt> device_distance(nbphoto);
1560 :
1561 : //std::cout<<"before kmeans with thrust "<<std::endl;
1562 :
1563 : //thrust::copy(device_clusters.begin(), device_clusters.begin()+nbcluster*dimension, std::ostream_iterator<data>(std::cout, " "));
1564 : std::cout<<std::endl;
1565 :
1566 : kmeans(nbphoto, dimension, nbcluster, device_data, device_clusters, device_label, device_distance, 100, divergence);
1567 :
1568 :
1569 : std::cout<<"test label "<<device_label[0]<<std::endl;
1570 : std::cout<<"divergence "<<divergence<<std::endl;
1571 :
1572 : size_and_inertia.clear();
1573 : size_and_inertia.resize(nbcluster);
1574 : list_photo_ids_per_cluster.clear();
1575 : list_photo_ids_per_cluster.resize(nbcluster);
1576 :
1577 : std::vector<VDInt> inertia(nbcluster, 0);
1578 : int size_cluster;
1579 :
1580 : for(int i=0; i<nbphoto; i++){
1581 : inertia[device_label[i]]+=device_distance[i];
1582 : list_photo_ids_per_cluster[device_label[i]].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[i]);
1583 : }
1584 :
1585 : for(int j=0; j<nbcluster; j++){
1586 : size_cluster = thrust::count(device_label.begin(),device_label.end(),j);
1587 : size_and_inertia[j]=std::pair<int, VDInt> (size_cluster, inertia[j]);
1588 : }
1589 : std::cout<<std::endl;
1590 : for(int i =0; i<nbcluster; i++){
1591 : std::cout<<"cluster : "<<i<<std::endl;
1592 : for(int j=0; j<100 && j<list_photo_ids_per_cluster[i].size();j++){
1593 : std::cout<<list_photo_ids_per_cluster[i][j]<<",";
1594 : }
1595 : std::cout<<std::endl;
1596 : std::cout<<"nb data : "<<list_photo_ids_per_cluster[i].size()<<std::endl;
1597 : }
1598 :
1599 :
1600 : std::cout<<"Fin gpub !"<<std::endl;
1601 :
1602 : }
1603 : #endif
1604 : #endif
1605 :
1606 :
1607 :
1608 :
1609 :
1610 0 : uint32_t l2_dist(std::vector<data> & p, std::vector<VDInt> & c,int dim, int dim2, int photo_id, int cluster_id, int pds)
1611 : {
1612 : //p vec photos, c vec clusters, dim taille des photos, dim2 dim de calcul, photo_id n° de la photo, cluster_id
1613 : // n° du cluster, pds decalage selon pds ou non
1614 0 : VDInt distance=0;
1615 0 : for (int i=0;i<dim2; i++){
1616 0 : distance += (p[photo_id*dim+pds+i]-c[cluster_id*dim+pds+i]) * (p[photo_id*dim+pds+i]-c[cluster_id*dim+pds+i]);
1617 : }
1618 0 : return distance;
1619 :
1620 :
1621 : }
1622 :
1623 :
1624 0 : void onCPUKmeanOneStepPdscpu(std::vector<VDInt> &clusters, std::vector<std::pair<int, VDInt> > & size_and_inertia,
1625 : types_datas_t &ReadCacheCPUPointerOneDescriptorType, int verbose,
1626 : std::vector<std::vector<uint32_t> > & list_photo_ids_per_cluster){
1627 :
1628 0 : std::vector<VDInt> new_clusters;
1629 0 : time_t debut, fin;
1630 :
1631 0 : std::vector<std::vector<VDInt> > list_minimum_distances_photo_ids_per_clusters;
1632 0 : const uint32_t nbrPhoto = ReadCacheCPUPointerOneDescriptorType.nb_data;
1633 0 : const uint32_t dimension = ReadCacheCPUPointerOneDescriptorType.size;
1634 :
1635 0 : const unsigned long nbrCluster= clusters.size()/dimension;
1636 :
1637 0 : list_photo_ids_per_cluster.clear();
1638 0 : list_photo_ids_per_cluster.resize(nbrCluster);
1639 0 : list_minimum_distances_photo_ids_per_clusters.clear();
1640 0 : list_minimum_distances_photo_ids_per_clusters.resize(nbrCluster);
1641 :
1642 :
1643 :
1644 0 : int pds=1;
1645 0 : VDInt * mean;
1646 0 : int * centroid_selec, * count;
1647 0 : mean=(VDInt*)calloc(nbrCluster*dimension, sizeof(VDInt));
1648 0 : count=(int*)calloc(nbrCluster, sizeof(int));
1649 0 : VDInt best_dist;
1650 0 : int cents;
1651 0 : int cpt_break;
1652 0 : int pds_break=32;
1653 0 : std::cout<<"avant appel des kmeans"<<std::endl;
1654 0 : VDInt distancepart;
1655 0 : VDInt dist_totale;
1656 0 : time(&debut);
1657 0 : cpt_break=0;
1658 0 : for(int photo_id=0; photo_id<nbrPhoto; photo_id++){
1659 0 : best_dist=LONG_MAX;
1660 0 : for (int c=0; c<nbrCluster; c++){
1661 0 : if(pds){
1662 0 : distancepart=l2_dist(ReadCacheCPUPointerOneDescriptorType.datas_vec, clusters,dimension, pds_break, photo_id, c, 0);
1663 0 : if(distancepart>best_dist){
1664 0 : dist_totale=distancepart;
1665 0 : cpt_break+=1;
1666 : }
1667 : else{
1668 0 : dist_totale=distancepart+l2_dist(ReadCacheCPUPointerOneDescriptorType.datas_vec, clusters,dimension, \
1669 0 : dimension-pds_break, photo_id, c, pds_break);
1670 0 : if(dist_totale<best_dist){
1671 0 : best_dist=dist_totale;
1672 0 : cents=c;
1673 : }
1674 : }
1675 :
1676 : }
1677 : else{
1678 : dist_totale=l2_dist(ReadCacheCPUPointerOneDescriptorType.datas_vec,clusters,dimension,dimension, photo_id, c, 0);
1679 : if(dist_totale<best_dist){
1680 : best_dist=dist_totale;
1681 : cents=c;
1682 : }
1683 : }
1684 : }
1685 :
1686 0 : list_photo_ids_per_cluster[cents].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[photo_id]);
1687 0 : list_minimum_distances_photo_ids_per_clusters[cents].push_back(best_dist);
1688 :
1689 0 : for(int d=0; d<dimension; d++){
1690 0 : mean[cents*dimension+d]+=ReadCacheCPUPointerOneDescriptorType.datas_vec[photo_id*dimension+d];
1691 : }
1692 0 : count[cents]+=1;
1693 : }
1694 :
1695 0 : size_and_inertia.clear();
1696 0 : size_and_inertia.resize(nbrCluster);
1697 0 : std::vector<VDInt> inertia(nbrCluster, 0);
1698 :
1699 0 : for(int c=0; c<nbrCluster; c++){
1700 0 : if(count[c]!=0){
1701 0 : for(int d=0; d<dimension; d++){
1702 0 : new_clusters.push_back(mean[c*dimension+d]/count[c]);
1703 : }
1704 : }else
1705 : {
1706 0 : for(int d=0; d<dimension; d++)
1707 0 : new_clusters.push_back(clusters[c*dimension+d]);
1708 : }
1709 0 : inertia[c]=std::accumulate(list_minimum_distances_photo_ids_per_clusters[c].begin(),\
1710 0 : list_minimum_distances_photo_ids_per_clusters[c].end(), 0);
1711 0 : size_and_inertia[c]=std::pair<int, VDInt> (count[c], inertia[c]);
1712 : }
1713 :
1714 0 : clusters=new_clusters;
1715 :
1716 0 : std::cout<<"apres calcul des kmeans"<<std::endl;
1717 :
1718 0 : time(&fin);
1719 :
1720 0 : if(verbose)
1721 0 : for(int i=0; i<nbrCluster; i++){
1722 0 : std::cout << "count : " << count[i] << " pour le cluster " << i << std::endl;
1723 : }
1724 0 : long double elaps_time=difftime(fin,debut);
1725 0 : if(verbose)
1726 : {
1727 0 : std::cout << "temps ecoulé : " << elaps_time << std::endl;
1728 0 : std::cout << "nb de break : " << cpt_break << " sur " << nbrPhoto*nbrCluster << std::endl;
1729 : }
1730 :
1731 :
1732 0 : }
1733 :
1734 :
1735 0 : static void stats(const std::vector<VDInt> & ordered_distances, uint32_t nb_data, std::vector<double> &result, uint32_t sizeResult, int verbose, const std::vector<data> & datas_vec)
1736 : {
1737 0 : int nb_equal = 0;
1738 :
1739 0 : double m1 = 0.;
1740 0 : double m2 = 0.;
1741 :
1742 0 : for (uint32_t i = 0 ; i < std::max<int>(nb_data - 1, 0); i++)
1743 : {
1744 0 : if (ordered_distances[i] > ordered_distances[i + 1])
1745 : {
1746 0 : printf("Result not ordered ! : INTERNAL BUG \n");
1747 : }
1748 0 : if (ordered_distances[i] == ordered_distances[i + 1])
1749 0 : nb_equal++;
1750 :
1751 0 : double val = ordered_distances[i];
1752 0 : double m0 = i + 1;
1753 0 : m1 += (val - m1) / m0;
1754 0 : m2 += (val * val - m2) / m0;
1755 : }
1756 :
1757 0 : double mean = m1;
1758 0 : double var = m2 - m1 * m1;
1759 0 : double stddev = sqrt(var);
1760 :
1761 0 : size_t dimension = (nb_data > 0) ? datas_vec.size() / nb_data : 0;
1762 0 : std::cout << "Dimension : " << dimension << std::endl;
1763 0 : std::cout << "Size Result : " << sizeResult << std::endl;
1764 0 : std::vector<double> m1v(dimension, 0.), m2v(dimension, 0.);
1765 0 : std::vector<double> varv(dimension, 0.), stddevv(dimension, 0.);
1766 :
1767 0 : double m1d = 0.;
1768 0 : double m2d = 0.;
1769 :
1770 0 : for (uint32_t i = 0 ; i < nb_data; i++)
1771 : {
1772 0 : double m0v = i + 1;
1773 0 : for (uint32_t j = 0 ; j < dimension; j++)
1774 : {
1775 0 : double val = datas_vec[i * dimension + j];
1776 0 : m1v[j] += (val - m1v[j]) / m0v;
1777 0 : m2v[j] += (val * val - m2v[j]) / m0v;
1778 :
1779 0 : double m0d = i * dimension + j + 1;
1780 0 : m1d += (val - m1d) / m0d;
1781 0 : m2d += (val * val - m2d) / m0d;
1782 : }
1783 : }
1784 :
1785 0 : for (uint32_t j = 0; j < dimension; j++)
1786 : {
1787 0 : varv[j] = m2v[j] - m1v[j] * m1v[j];
1788 0 : if (varv[j] > 0)
1789 0 : stddevv[j] = sqrt(varv[j]);
1790 : }
1791 :
1792 0 : double vard = m2d - m1d * m1d;
1793 0 : double stddevd = vard > 0 ? sqrt(vard) : 0;
1794 :
1795 0 : if (verbose)
1796 : {
1797 0 : printf("mean : %f\n", mean);
1798 0 : printf("stddev : %f\n", stddev);
1799 0 : printf("nb_equal : %d\n", nb_equal);
1800 0 : printf("ordered_distances : %u\n", ordered_distances[0]);
1801 0 : printf("max : %u\n", ordered_distances[nb_data - 1]);
1802 0 : printf("median : %u\n", ordered_distances[nb_data/2]);
1803 : }
1804 :
1805 0 : result.resize(0);
1806 0 : if (sizeResult > 20)
1807 : {
1808 0 : if (verbose)
1809 0 : printf("mean to set");
1810 0 : result.push_back(mean);
1811 0 : if (verbose)
1812 0 : printf("set mean");
1813 0 : result.push_back(stddev);
1814 0 : result.push_back(nb_equal);
1815 0 : std::cout << " mean : " << mean<<std::endl;
1816 0 : std::cout << " std dev : "<<stddev<<std::endl;
1817 0 : std::cout << " nb_equal : "<<nb_equal<<std::endl;
1818 0 : std::cout << " ordered distances distance : "<<ordered_distances[0]<<std::endl;
1819 0 : std::cout << " ordered ordered_distances size : "<<ordered_distances.size()<<std::endl;
1820 0 : if (ordered_distances.size() > 0 && nb_data > 0)
1821 : {
1822 0 : result.push_back(ordered_distances[0]);
1823 0 : std::cout << " 0 : " << 0 << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1824 :
1825 0 : result.push_back(ordered_distances[nb_data - 1]);
1826 0 : std::cout << " nb_data - 1 : " << (nb_data - 1) << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1827 :
1828 0 : result.push_back(ordered_distances[nb_data / 2]);
1829 0 : std::cout << " nb_data / 2 : " << (nb_data / 2) << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1830 :
1831 : }
1832 0 : if (verbose)
1833 0 : printf("Loop over the quantile :");
1834 0 : for (int i = 0; i < 10; i++)
1835 : {
1836 0 : size_t id_decile = i * nb_data/10;
1837 0 : result.push_back(ordered_distances[id_decile]);
1838 0 : std::cout << " id_decile : " << id_decile << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1839 0 : if (verbose)
1840 0 : printf(" id_decile %lu , value : %lf \n", id_decile, result[6 + i]);
1841 : }
1842 : int decile = 100;
1843 0 : while (nb_data >= decile)
1844 : {
1845 0 : result.push_back(decile);
1846 0 : size_t id_decile = nb_data / decile;
1847 0 : result.push_back(ordered_distances[id_decile]);
1848 0 : std::cout << " id_decile : " << id_decile << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1849 0 : result.push_back(ordered_distances[nb_data - 1 - id_decile]);
1850 0 : std::cout << " nb_data - 1 - id_decile : " << (nb_data - 1 - id_decile) << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1851 0 : decile *= 10;
1852 : }
1853 : }
1854 0 : if (verbose)
1855 : {
1856 0 : std::cout << "#Moyenne de tous les descripteurs : " << m1d << ", stddev : " << stddevd << std::endl;
1857 0 : std::cout << "#gnuplot moyenne stddev par dimension" << std::endl;
1858 0 : for (uint32_t j = 0; j < dimension; j++)
1859 : {
1860 0 : std::cout << j << " " << m1v[j] << " " << stddevv[j] << std::endl;
1861 : }
1862 : }
1863 0 : if (verbose)
1864 0 : puts("Stats computed !");
1865 0 : }
1866 :
1867 0 : void query_stat(uint32_t nb_data_in_file, int dimension, int limit_return,
1868 : const std::vector<VDInt> & distances,
1869 : std::vector<uint32_t> & result,
1870 : // VR 22-9-16 : je crois que ce sont les datas_vec plutot que les ids_data, du coup je rajoute les datas_vec en vector a la fin et on verra si on peut enlever cet argument
1871 : std::vector<uint32_t> &ids_data,
1872 : std::string &result_str, int verbose,
1873 : const std::vector<data> & datas_vec,
1874 : LocalParam & lp)
1875 : {
1876 0 : if (verbose)
1877 0 : printf(" We will output some stats, result size : %ld, nb_data_in_file : %d !\n", result.size(), nb_data_in_file);
1878 0 : uint32_t sizeResult = 2048;
1879 :
1880 0 : std::cout<<" query stat : nb_data : "<<lp.ReadCacheCPU[0].nb_data<<std::endl;
1881 :
1882 0 : int min_limit_nb_data = limit_return - 2;
1883 0 : if (min_limit_nb_data > nb_data_in_file)
1884 0 : min_limit_nb_data = nb_data_in_file;
1885 0 : if (min_limit_nb_data > ids_data.size())
1886 0 : min_limit_nb_data = (int) ids_data.size();
1887 :
1888 0 : result.resize(min_limit_nb_data + 3);
1889 0 : result[0] = nb_data_in_file;
1890 0 : result[1] = dimension;
1891 : // VR 27-11-16 : je voudrais decommenter cela pour rajouter cette info en cas de query stat, en fait surtout changer le 2 en 3 ci-dessous !
1892 0 : result[2] = (lp.descriptor_type == -1 ? lp.type_query : lp.descriptor_type);
1893 :
1894 0 : if (verbose)
1895 0 : printf(" min_limit_nb_data : %d, result : %ld \n", min_limit_nb_data, result.size());
1896 :
1897 0 : for (int i = 0; i < std::min<size_t>(min_limit_nb_data, ids_data.size()); i++)
1898 0 : result[i + 3] = ids_data[i];
1899 :
1900 0 : if (verbose)
1901 : {
1902 0 : puts("Copying result in result as string");
1903 0 : printf(" limit_return : %d\n", limit_return);
1904 : }
1905 0 : for (int i = 0; i < std::max(3, limit_return + 1); i++)
1906 : {
1907 0 : result_str += boost::lexical_cast<std::string>(result[i]);
1908 0 : result_str += ",";
1909 : }
1910 :
1911 0 : std::vector<double> other_result(sizeResult);
1912 0 : stats(distances, nb_data_in_file, other_result, sizeResult, verbose, datas_vec);
1913 0 : if (verbose)
1914 0 : printf(" sizeResult : %d\n", sizeResult);
1915 0 : for (int i = 0; i < sizeResult; i++)
1916 : {
1917 0 : result_str += boost::lexical_cast<std::string>(other_result[i]);
1918 0 : if (i != sizeResult - 1) {
1919 0 : result_str += ",";
1920 : }
1921 : }
1922 0 : if (verbose)
1923 0 : printf("End of stat computation !");
1924 0 : }
1925 :
1926 0 : void query_load(LocalParam & lp, std::vector<types_datas_t> & ReadCacheCPU,int cs,int verbose, int limit_data, int type, int index)
1927 : {
1928 0 : std::string tmp_file;
1929 :
1930 : // VR 4-11-16 : je ne teste pas car cette fonction n'est pas teste car ele ne marche pas
1931 0 : tmp_file = ReadCacheCPU[index].dir + GlobalParam::Instance().filename_photo_id_list_str_;
1932 :
1933 0 : types_datas_t & cache = ReadCacheCPU[index];
1934 0 : std::vector<data> datas_vec;
1935 0 : cache.ids_vec.resize(0);
1936 0 : cache.index_vec.resize(0);
1937 0 : cache.datas_vec.resize(0);
1938 0 : cache.nb_data = 0;
1939 : #ifndef ONLY_CPU
1940 : testCUDA(cudaFree(cache.dataGPU));
1941 : cache.dataGPU = NULL;
1942 : #endif
1943 :
1944 0 : char rootDirectory_loc[100];
1945 0 : std::string local = cache.dir;
1946 0 : strcpy(rootDirectory_loc, local.c_str());
1947 0 : std::vector<std::vector<to_insert_t> > dummy2;
1948 0 : uint32_t nb_data_in_file = 0;
1949 0 : GlobalParam & gp = GlobalParam::Instance();
1950 0 : lp.reload = 1;
1951 : /*ret = setCacheParamDeuxiemeMoitieAndLoadDataCPUAndGPU(gp, lp, cache.type, verbose, nb_data_in_file,
1952 : ReadCacheCPU,
1953 : std::string(rootDirectory_loc),
1954 : dummy2,
1955 : 1,
1956 : 0);
1957 : * a remplacer par LoadDtdesc
1958 : */
1959 0 : int ret = LoadDataInCache(gp,lp,type,verbose,std::string(rootDirectory_loc),1,0);
1960 0 : if (ret == 0)
1961 0 : send(cs, "load doneeof", 12,0);
1962 : else {
1963 : #ifndef ONLY_CPU
1964 : testCUDA(cudaMalloc(&ReadCacheCPU[index].dataGPU, 1 * (size_t)ReadCacheCPU[index].size * sizeof(datag)));
1965 : #endif
1966 0 : send(cs, "no data to loadeof", 18, 0);
1967 : }
1968 0 : close(cs);
1969 0 : }
1970 :
1971 :
1972 0 : int query_unload(Query cur_query,LocalParam lp)
1973 : {
1974 0 : const std::vector<uint32_t> list_index = cur_query.getIndexList();
1975 0 : for (int i = 0; i < list_index.size(); ++i)
1976 : {
1977 : // MG : need to do something for number of data.
1978 0 : printf("freeing");
1979 : #ifndef ONLY_CPU
1980 : if (cur_query.get_query_char() == 'U')
1981 : {
1982 : cudaFree(lp.ReadCacheCPU[i].dataGPU);
1983 : }
1984 : else
1985 : #endif
1986 0 : {
1987 0 : lp.ReadCacheCPU[i].datas_vec.resize(0);
1988 : }
1989 : }
1990 0 : send(lp.cs,"unload doneeof",14,0);
1991 0 : close(lp.cs);
1992 0 : cur_query.reset_query();
1993 0 : return 0;
1994 : }
1995 :
1996 0 : void delete_desc_dyn(LocalParam & lp, int desc){
1997 0 : std::vector<int>::iterator it;
1998 0 : std::cout<<"on supprime le desc : "<<desc<<std::endl;
1999 0 : int id=getiddesc(desc, lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
2000 0 : int id2;
2001 0 : if(id==-1){
2002 0 : std::cout<<"le photo desc n existe pas ou a deja ete supprime"<<std::endl;
2003 0 : return;
2004 : }
2005 : else
2006 : {
2007 :
2008 0 : std::vector<int>::iterator it2;
2009 0 : it2=lp.list_dyn_desc_type.begin();
2010 0 : it2+=id;
2011 0 : lp.list_dyn_desc_type.erase(it2);
2012 0 : it2=lp.list_pere_desc_dyn.begin();
2013 0 : it2+=id;
2014 0 : lp.list_pere_desc_dyn.erase(it2);
2015 0 : std::vector<types_datas_t>::iterator iter2;
2016 0 : iter2=lp.ReadCacheCpuDyn.begin();
2017 0 : iter2+=id;
2018 0 : lp.ReadCacheCpuDyn.erase(iter2);
2019 0 : it=find(lp.list_pere_desc_dyn.begin(),lp.list_pere_desc_dyn.end(), desc);
2020 :
2021 0 : std::cout<<std::endl;
2022 0 : while(it!=lp.list_pere_desc_dyn.end()){
2023 0 : id2=it-lp.list_pere_desc_dyn.begin();
2024 0 : std::cout<<"id2 : "<<id2<<std::endl;
2025 0 : delete_desc_dyn(lp, lp.list_dyn_desc_type[id2]);
2026 0 : it=find(it,lp.list_pere_desc_dyn.end(), desc);
2027 : }
2028 0 : if(*it==desc)
2029 0 : delete_desc_dyn(lp, lp.list_dyn_desc_type[-1]);
2030 : }
2031 : return;
2032 : }
2033 :
2034 :
2035 :
2036 :
2037 : /**
2038 : * get_query.cu
2039 : **/
2040 :
2041 : // VR 2-12 : on veut changer le nom de l'objet, VR 15-1-17 : ah ouais lequel ?
2042 :
2043 : // VR 15-1-17 : ca c'est proscrit !
2044 : using namespace boost;
2045 : using namespace std;
2046 : /*
2047 :
2048 : // list char query_type
2049 : char query_type_gpudesc = 'd';
2050 : char query_type_cpudesc = 'D';
2051 : char query_type_stat = 's';
2052 : char query_type_statgpu = 'S';
2053 : char query_type_query = 'q';
2054 : char query_type_advquery = 'a';
2055 : char query_type_cpu = 'c';
2056 : char query_type_rand = 'r';
2057 : char query_type_randgpu = 'R';
2058 : char query_type_delete = 'e';
2059 : char query_type_insert = 'i';
2060 : char query_type_exit = 'E';
2061 : char query_type_commit_insert = 'C';
2062 : char query_type_moyenne = 'm';
2063 : char query_type_load = 'l';
2064 : char query_type_multitype_cpu = 't';
2065 : char query_type_multitype_gpu = 'T';
2066 : char query_type_multi_insert = 'I';
2067 : char query_type_kmeangpu = 'G';
2068 : char query_type_kmean = 'k';
2069 : char query_type_partial_distance_serach = 'P';
2070 : char query_type_return_photo = 'F';
2071 : char query_type_arbre = 'A';
2072 : char query_type_vider = 'v';
2073 : */
2074 :
2075 :
2076 1 : Query::Query() : verbose_query(-1), id(0), input(""), query_char('.'), limit(0), index_type(-1), type(0), size(0), nb_clusters(0), iter_max(1), crea_photo_desc(0),
2077 1 : return_centroid(1), return_list_photo(0)
2078 : {
2079 1 : query_desc.resize(1);
2080 1 : list_ids.resize(1);
2081 1 : }
2082 :
2083 : // VR 6-11-16 : je croyais que le server_type etait dans le input_arg
2084 0 : Query::Query(std::string & input_arg, uint32_t server_type)
2085 0 : : verbose_query(-1), input(input_arg)
2086 : {
2087 0 : if (input_arg.length() > 0)
2088 0 : query_char = input_arg[0];
2089 0 : LocalParam lp = LocalParam();
2090 0 : set_query(server_type, lp);
2091 0 : }
2092 :
2093 0 : Query::~Query()
2094 : {
2095 0 : puts("query object destruction");
2096 0 : }
2097 :
2098 : //si pas fonctionnel on passe pas au test suivant dans test.py
2099 0 : void Query::reset_query()
2100 : {
2101 0 : std::cout<<"reset query"<<std::endl;
2102 0 : id = 0;
2103 0 : input = "";
2104 0 : query_char = '.';
2105 0 : query_desc.resize(0);
2106 0 : list_ids.resize(0);
2107 0 : limit = 0;
2108 0 : index_type = -1;
2109 0 : type = 0;
2110 0 : id = 0;
2111 0 : size = 0;
2112 0 : data_to_insert.resize(0);
2113 0 : type_list.resize(0);
2114 0 : index_type_list.resize(0);
2115 0 : list_size.resize(0);
2116 0 : crea_photo_desc=0;
2117 0 : return_centroid=1;
2118 0 : return_list_photo=0;
2119 0 : }
2120 :
2121 : //teste avec la requete m dans les tests
2122 0 : void Query::set_limit(char *str)
2123 : {
2124 0 : if (str)
2125 : {
2126 0 : if (str[0] >= '0' && str[0] <= '9')
2127 0 : limit = atoi(str);
2128 : else
2129 0 : limit = atoi(str + 1);
2130 : }
2131 : else
2132 0 : limit = LIMIT_RETURN;
2133 0 : if (limit > MAX_LIMIT_RETURN)
2134 0 : limit = MAX_LIMIT_RETURN;
2135 0 : if (limit == 0)
2136 0 : limit = LIMIT_RETURN;
2137 0 : }
2138 :
2139 :
2140 : //dans query advanced a verifier si teste, pour l'instant 2query type advanced
2141 0 : void Query::set_offset(char *str)
2142 : {
2143 0 : if (str)
2144 : {
2145 0 : if (str[0] >= '0' && str[0] <= '9')
2146 0 : offset = atoi(str);
2147 : else
2148 0 : offset = atoi(str + 1);
2149 : }
2150 : else
2151 0 : offset = 0;
2152 0 : }
2153 :
2154 :
2155 : //dans set_query_coordinate, pas teste
2156 0 : void Query::set_indice_coordinate(const char *str)
2157 : {
2158 0 : if (str)
2159 : {
2160 0 : if (str[0] >= '0' && str[0] <= '9')
2161 0 : indice_coordinate = atoi(str);
2162 : else
2163 0 : indice_coordinate = atoi(str + 1);
2164 : }
2165 : else
2166 0 : indice_coordinate = 0;
2167 0 : }
2168 :
2169 : //teste avec les requete de kmean simples
2170 0 : void Query::set_type(const char *str, int32_t server_type, LocalParam& lp)
2171 : {
2172 0 : if (str)
2173 : {
2174 0 : if (str[0] >= '0' && str[0] <= '9')
2175 0 : type = atoi(str);
2176 : else
2177 0 : type = atoi(str + 1); // str = TXXXX ou XXXX est le desc type, str+1 pour retirer le Ts
2178 : }
2179 : else
2180 0 : type = server_type;
2181 0 : index_type = FindDescIndex(lp.ReadCacheCPU, (uint32_t)type);
2182 0 : }
2183 :
2184 : //teste dans les fonctions de kmeans ou on passe le nombre de cluster
2185 0 : void Query::set_nb_clusters(int nb)
2186 : {
2187 0 : nb_clusters=nb;
2188 0 : }
2189 :
2190 :
2191 : //a verififer
2192 0 : void Query::set_limit(uint32_t lim)
2193 : {
2194 0 : limit = lim;
2195 0 : }
2196 :
2197 :
2198 : //avec le query_char p, dans les tests
2199 0 : int Query::set_query_multiarg(uint32_t server_type, LocalParam & lp) {
2200 :
2201 0 : if(input.find(',') != std::string::npos) {
2202 :
2203 0 : set_query_generic(server_type, lp);
2204 :
2205 :
2206 0 : std::vector<std::string> ids_str;
2207 :
2208 0 : char * tmp_str = &(input.at(0));
2209 0 : char * tmp_str2 = NULL;
2210 :
2211 :
2212 0 : Query::set_type(tmp_str2, server_type, lp);
2213 0 : if (index_type == -1)
2214 0 : return 2;
2215 0 : size = lp.ReadCacheCPU[index_type].size;
2216 0 : tmp_str2 = strchr(tmp_str, 'L');
2217 0 : Query::set_limit(tmp_str2);
2218 :
2219 0 : split(ids_str, input, is_any_of(","));
2220 0 : list_ids.resize(ids_str.size());
2221 0 : list_ids[0] = (uint32_t)atoi(&(ids_str[0].at(1)));
2222 :
2223 0 : for (int i = 1; i < ids_str.size(); ++i)
2224 0 : list_ids[i] = (uint32_t)atoi(&(ids_str[i].at(0)));
2225 : }
2226 : else {
2227 0 : list_ids.resize(0);
2228 0 : return set_query_generic(server_type, lp);
2229 : }
2230 : //limit = size;
2231 0 : return 0;
2232 : }
2233 :
2234 : //avec query_char m, dans les tests
2235 :
2236 0 : int Query::set_query_list_ids(uint32_t server_type,LocalParam & lp)
2237 : {
2238 : // remove pointer et mettre juste un char ! VR 13-10-16
2239 0 : char * tmp_str = &(input.at(0));
2240 0 : char * tmp_str2;
2241 0 : std::vector<std::string> lines;
2242 0 : std::vector<std::string> ids_str;
2243 :
2244 0 : tmp_str2 = strchr(tmp_str, 'T');
2245 0 : Query::set_type(tmp_str2, server_type, lp);
2246 0 : if (index_type == -1)
2247 : return 2;
2248 0 : size = lp.ReadCacheCPU[index_type].nb_data;
2249 0 : split(lines, input, is_any_of("."));
2250 0 : if (lines.size() == 2)
2251 : {
2252 0 : split(ids_str, lines.at(1), is_any_of(","));
2253 0 : list_ids.resize(ids_str.size());
2254 0 : for (int i = 0; i < ids_str.size(); ++i)
2255 : {
2256 0 : list_ids[i] = (uint32_t)atoi(&(ids_str[i].at(0)));
2257 : }
2258 : } else {
2259 : return 1;
2260 : }
2261 0 : limit = size;
2262 0 : return 0;
2263 : }
2264 :
2265 :
2266 : //utilise si query char, a quel moment on teste si 'l'?
2267 0 : int Query::set_query_load(uint32_t server_type, LocalParam & lp)
2268 : {
2269 0 : char * tmp_str = &(input.at(0));
2270 0 : char * tmp_str2;
2271 0 : tmp_str2 = strchr(tmp_str, 'T');
2272 0 : Query::set_type(tmp_str2, server_type, lp);
2273 0 : if (index_type == -1)
2274 0 : return 2;
2275 : return 0;
2276 : }
2277 :
2278 : //dans les test avec requete de kmean
2279 : //pas de tests avec substring g
2280 0 : int Query::set_query_kmean(uint32_t server_type, LocalParam & lp, int verbose)
2281 : {
2282 : /////////////////////////////// Fonction appelé pour lancer les kmeans ///////////////////////////
2283 0 : std::vector<std::string> clusters_as_csv, lines, clusters_csv;
2284 0 : std::string input_less = "";
2285 :
2286 0 : if (input.length() > 2)
2287 0 : input_less = input.substr(1, input.length() - 2);
2288 0 : split(lines, input_less, is_any_of("|"));
2289 0 : verbose_query = -1;
2290 :
2291 0 : std::cout<<" loop to create desc dyn "<<lines.size()<<std::endl;
2292 0 : for (int l = 0; l < lines.size(); l++)
2293 : {
2294 0 : std::cout<<" start loop : " << l << " content : " << lines[l] << std::endl;
2295 0 : int taille=lines[l].size();
2296 0 : if (lines[l].substr(0, 1) == std::string("S"))
2297 : {
2298 0 : std::cout<<" setting param with prefix S " << std::endl;
2299 0 : std::vector<std::string> option;
2300 0 : split(option, lines[l], is_any_of(":"));
2301 :
2302 0 : special_kmean = option[1];
2303 0 : iter_max = atoi(option[2].c_str());
2304 0 : crea_photo_desc = atoi(option[3].c_str());
2305 0 : return_centroid = atoi(option[4].c_str());
2306 0 : return_list_photo = atoi(option[5].c_str());
2307 0 : if (option.size() > 6)
2308 : {
2309 0 : std::cout << " we should get rid of eof, I am not sure that [0] is the first char of a string ! " << std::endl;
2310 0 : divergence = option[6][0];
2311 : }
2312 : else
2313 : {
2314 0 : std::cout << " forcing divergence euclidean " << std::endl;
2315 0 : std::cout << " et voila " << std::endl;
2316 0 : divergence = 'E';
2317 : }
2318 0 : if (option.size() > 7)
2319 : {
2320 0 : nb_iteration = atoi(option[7].c_str());
2321 : }
2322 : }
2323 0 : else if (lines[l].substr(0, 1) == std::string("P"))
2324 : {
2325 0 : kmean_param = lines[l].substr(2, taille-4-2-1);
2326 0 : iter_max = atoi(lines[l].substr(taille-4,2).c_str());
2327 0 : crea_photo_desc = atoi(lines[l].substr(taille-1,1).c_str());
2328 0 : std::cout << "Special kmean Param :" << kmean_param << "|" << std::endl;
2329 : }
2330 0 : else if (lines[l].substr(0, 1) == std::string("T"))
2331 : {
2332 0 : std::cout << "Type : " << lines[l] << std::endl;
2333 0 : std::size_t found=lines[l].find(',');
2334 : //si , kmean sur plusieurs clusters
2335 0 : if(found!=std::string::npos){
2336 0 : Query::set_types(lines[l], server_type, lp);
2337 : }
2338 : else{
2339 0 : std::string to_set_type = lines[l].substr(1);
2340 0 : Query::set_type(to_set_type.c_str(), server_type, lp);
2341 : }
2342 : }
2343 0 : else if (lines[l].substr(0,1) == std::string("G"))
2344 : {
2345 : //MC-23-08-18 servira pour utiliser pds ou non
2346 : //param_gpu = lines[l].substr(2);
2347 : //std::cout << "Kmean pds gpu param : "<< param << "|" << std::endl;
2348 0 : std::cout << "Kmean pds gpu " << std::endl;
2349 : }
2350 0 : else if (lines[l].substr(0, 1) == std::string("V"))
2351 : {
2352 0 : if (lines[l].length() >= 3)
2353 : {
2354 : // VR 3-4-17 : on a initialisé a un tout a l'heure
2355 0 : verbose_query = (uint32_t)atoi(lines[l].substr(2).c_str());
2356 0 : std::cout << "verbose_query kmean query :" << verbose_query << "|" << std::endl;
2357 : }
2358 : else
2359 0 : verbose_query = -1;
2360 : }
2361 0 : else if (lines[l].substr(0,1) == std::string("C"))
2362 : {
2363 0 : std::cout<<"on met a jour le nb de clusters demandés"<<std::endl;
2364 0 : std::vector<std::string> option;
2365 0 : split(option, lines[l], is_any_of(":"));
2366 0 : nb_clusters=atoi(lines[l].substr(2).c_str());
2367 0 : if(option.size() > 2){
2368 0 : k_min = atoi(option[1].c_str());
2369 0 : k_max = atoi(option[2].c_str());
2370 0 : if(k_min > k_max){
2371 0 : k_max = atoi(option[1].c_str());
2372 0 : k_min = atoi(option[2].c_str());
2373 : }
2374 : }
2375 : }
2376 : else
2377 : {
2378 0 : std::cout << " split cluster_csv " << clusters_csv.size() << std::endl;
2379 :
2380 0 : split(clusters_csv, lines[l], is_any_of(";"));
2381 :
2382 0 : Query::set_type(NULL, server_type, lp);
2383 0 : if (verbose)
2384 : {
2385 0 : for (int i = 0; i < clusters_csv.size(); i++)
2386 0 : std::cout << "clusters_csv[" << i << "] = " << clusters_csv[i] << std::endl;
2387 : }
2388 0 : clusters.resize(0);
2389 0 : clusters.resize(clusters_csv.size(), std::vector<VDInt>(0));
2390 :
2391 0 : std::cout << " after resize cluster " << clusters.size() << std::endl;
2392 :
2393 0 : for (int i = 0; i < clusters_csv.size(); i++)
2394 : {
2395 0 : if (clusters_csv[i] == "")
2396 : {
2397 0 : clusters.pop_back();
2398 0 : continue;
2399 : }
2400 :
2401 0 : std::vector<std::string> one_desc;
2402 0 : split(one_desc, clusters_csv[i], is_any_of(","));
2403 :
2404 0 : for (int k = 0; k < one_desc.size(); k++)
2405 : {
2406 : // VDInt val = (data)atoi(&(one_desc[k].at(0)));
2407 : // clusters[i].push_back(val);
2408 0 : if (std::is_same<VDInt, uint32_t>::value) // si VDInt est un uint32_t
2409 : {
2410 0 : VDInt val = (data)atoi(&(one_desc[k].at(0)));
2411 0 : clusters[i].push_back(val);
2412 : }
2413 : else if (std::is_same<VDInt, float>::value) // si VDInt est un float
2414 : {
2415 : VDInt val = std::stof(one_desc[k]);
2416 : clusters[i].push_back(val);
2417 : }
2418 : }
2419 : }
2420 : }
2421 0 : std::cout<<"crea desc dyn "<<crea_photo_desc<<std::endl;
2422 : }
2423 :
2424 0 : char * tmp_str = &(input.at(0));
2425 0 : char *tmp_str2 = strchr(tmp_str, 'T');
2426 0 : Query::set_type(tmp_str2, server_type, lp);
2427 : // VR 2-12-16 : on pourrait compléter ou tronquer si ce n'est pas de la bonne taille
2428 :
2429 0 : clusters_as_line.resize(0);
2430 0 : std::cout<<"et clusters.size "<<clusters.size()<<std::endl;
2431 0 : for (int i = 0; i < clusters.size(); i++)
2432 : {
2433 0 : for (int k = 0; k < clusters[i].size(); k++)
2434 : {
2435 0 : clusters_as_line.push_back(clusters[i][k]);
2436 : }
2437 : }
2438 :
2439 0 : return 0;
2440 : }
2441 :
2442 0 : int Query::set_query_prediction(uint32_t server_type, LocalParam & lp, int verbose)
2443 : {
2444 : /////////////////////////////// Fonction appelé pour lancer les kmeans ///////////////////////////
2445 0 : std::vector<std::string> path, lines, options;
2446 0 : std::string input_less = "", temp;
2447 :
2448 0 : if (input.length() > 2)
2449 0 : input_less = input.substr(1, input.length()-4);
2450 0 : split(lines, input_less, is_any_of("|"));
2451 0 : verbose_query = -1;
2452 :
2453 0 : std::cout<<" loop to create desc dyn "<<lines.size()<<std::endl;
2454 0 : for (int l = 0; l < lines.size(); l++)
2455 : {
2456 0 : std::cout<<" start loop : " << l << " content : " << lines[l] << std::endl;
2457 0 : int taille=lines[l].size();
2458 0 : if (lines[l].substr(0, 5) == std::string("/home"))
2459 : {
2460 0 : std::cout<<lines[l].substr(0, 5)<<std::endl;
2461 0 : split(path, lines[l], is_any_of("/"));
2462 0 : for(int j=0 ; j<path.size() ;j++){
2463 0 : if (path[j].substr(0, 5) == std::string("grid_"))
2464 : {
2465 0 : split(options, path[j], is_any_of("_"));
2466 0 : std::cout<<"type of grid : "<<options[1]<<std::endl;
2467 0 : std::cout<<"nb cluster of grid : "<<options[2]<<std::endl;
2468 0 : temp = options[3].substr(0, 1);
2469 0 : std::cout<<"divergence of grid : "<<temp<<std::endl;
2470 0 : divergence = temp[0];
2471 : }
2472 : }
2473 0 : grid_filename = lines[l];
2474 : }
2475 0 : std::cout<<"path to grid : "<<grid_filename<<std::endl;
2476 : }
2477 0 : char * tmp_str = &(input.at(0));
2478 0 : char *tmp_str2 = strchr(tmp_str, 'T');
2479 0 : Query::set_type(tmp_str2, server_type, lp);
2480 :
2481 0 : return 0;
2482 : }
2483 :
2484 : //appele si requete g, pas encore teste
2485 0 : int Query::set_query_coordinate(uint32_t server_type, LocalParam & lp, int verbose)
2486 : {
2487 : // if (input.length() > 2)
2488 : // input_less = input.substr(1, input.length() - 2);
2489 :
2490 0 : std::string to_set_indice_coordinate = input.substr(1);
2491 0 : set_indice_coordinate(to_set_indice_coordinate.c_str());
2492 :
2493 0 : return set_query_generic(server_type, lp);
2494 : }
2495 :
2496 :
2497 : //teste avec toutes les requetes de kmeans, maj des cluster pour renvoie
2498 0 : void Query::get_data_kmean(int dimension)
2499 : {
2500 0 : uint32_t nb_clusters = (int) clusters_as_line.size() / dimension;
2501 :
2502 0 : clusters.resize(nb_clusters);
2503 0 : for (int i = 0 ; i < nb_clusters; i++)
2504 : {
2505 0 : clusters[i].resize(dimension);
2506 0 : for (int k = 0; k < dimension; k ++)
2507 : {
2508 0 : clusters[i][k] = clusters_as_line[i * dimension + k];
2509 : }
2510 : }
2511 0 : }
2512 :
2513 :
2514 : //teste avec la requete d dans les tests
2515 0 : int Query::set_query_desc(uint32_t server_type, LocalParam & lp)
2516 : {
2517 0 : int ret = Query::set_query_generic(server_type,lp);
2518 0 : if (ret)
2519 : return ret;
2520 0 : limit = lp.ReadCacheCPU[index_type].size;
2521 0 : if (index_type == -1)
2522 0 : return 2;
2523 0 : limit = lp.ReadCacheCPU[index_type].size;
2524 : return 0;
2525 : }
2526 :
2527 :
2528 : //pas appele dans les .cu a voir si dans les .h
2529 0 : int Query::set_query_commit(uint32_t server_type, LocalParam & lp)
2530 : {
2531 0 : Query::set_type(NULL, server_type, lp);
2532 0 : return 0;
2533 : }
2534 : /*
2535 : grammaire advanced query :
2536 : addesc.desc.desc|Ttype,type,type|Llimit|Ooffset
2537 :
2538 : si le vecteur retourné par get_query_types ou par get_query_index_type_list a une taille de 0
2539 : on est en monotype en query
2540 : sinon les types et index associes sont dans ces 2 variables
2541 :
2542 : */
2543 :
2544 :
2545 : //a tester : les requetes sur plusieurs descripteurs
2546 0 : const std::vector<int32_t> &Query::get_query_types() const
2547 : {
2548 0 : return type_list;
2549 : }
2550 :
2551 :
2552 : //a voir si teste dans les requetes d'insertion
2553 0 : const std::vector<uint32_t> &Query::get_query_index_type_list() const
2554 : {
2555 0 : return index_type_list;
2556 : }
2557 :
2558 :
2559 :
2560 : //pas testé, doit faire un tests avec plusieurs types sur les kmeans
2561 0 : void Query::set_types(std::string str, int32_t server_type, LocalParam & lp)
2562 : {
2563 0 : std::vector<std::string> types;
2564 0 : std::string tmp = str.substr(1);
2565 0 : split(types, tmp, is_any_of(","));
2566 0 : type_list.resize(types.size());
2567 0 : index_type_list.resize(types.size());
2568 0 : for (int i = 0; i < types.size(); i++)
2569 : {
2570 0 : type_list[i] = atoi(&(types[i].at(0)));
2571 0 : if(type_list[i]<-99){
2572 :
2573 :
2574 : }else{
2575 0 : int it;
2576 0 : it = FindDescIndex(lp.ReadCacheCPU,(int32_t) type_list[i]);
2577 0 : if (it == -1)
2578 : {
2579 0 : index_type = -1;
2580 0 : printf("type %d not in conf file\n", atoi(&(types[i].at(0))));
2581 0 : return;
2582 : }
2583 : else {
2584 0 : index_type = (int) it;
2585 0 : index_type_list[i] = index_type;
2586 : }
2587 : }
2588 : }
2589 : }
2590 :
2591 :
2592 : //pas utilise dans .cu mais a regarder dans .h
2593 0 : const std::string & Query::get_special_kmean() const
2594 : {
2595 0 : return special_kmean;
2596 : }
2597 :
2598 :
2599 : //pas teste, dans le cas de la query g
2600 0 : size_t Query::get_indice_coordinate() const
2601 : {
2602 0 : return indice_coordinate;
2603 : }
2604 :
2605 :
2606 : //teste avec les query en a
2607 : //a verifier : les différentes options de la fonction+--
2608 0 : int Query::set_query_advanced(uint32_t server_type, LocalParam & lp)
2609 : {
2610 0 : std::vector<std::string> lines;
2611 0 : size_t pos;
2612 0 : std::vector<std::string> desc_str;
2613 :
2614 0 : id = uint32_t(-1);
2615 0 : std::string input_query_data = input.substr(1);
2616 0 : split(lines, input_query_data, is_any_of("|"));
2617 :
2618 : // VR 29-11-16 : MG, des que la limit n'etait pas le dernier argument il etait ignore !
2619 : // VR 29-11-16 : non mais je pense que la c'est lpus solide :
2620 0 : query_desc.resize(0);
2621 0 : limit = LIMIT_RETURN;
2622 0 : offset = 0;
2623 :
2624 0 : for (int i = 0; i < lines.size(); ++i)
2625 : {
2626 0 : pos = lines[i].find("d");
2627 0 : if (pos != string::npos)
2628 : {
2629 0 : std::string desc_str_inline(&(lines[i].at(1)));
2630 0 : split(desc_str, desc_str_inline, is_any_of("."));
2631 0 : size = desc_str.size();
2632 0 : query_desc.resize(size);
2633 0 : for (int i = 0; i < query_desc.size(); ++i)
2634 : {
2635 0 : query_desc[i] = (data)atoi(&(desc_str[i].at(0)));
2636 : }
2637 0 : continue;
2638 : }
2639 0 : pos = lines[i].find("T");
2640 0 : if (pos != string::npos)
2641 : {
2642 0 : size_t del = lines[i].find(",");
2643 0 : if (del == string::npos)
2644 : {
2645 0 : Query::set_type(&(lines[i].at(pos)), server_type, lp);
2646 0 : if (index_type == -1) {
2647 0 : puts("type not in conf");
2648 : return 2;
2649 : }
2650 0 : type_list.resize(0);
2651 0 : index_type_list.resize(0);
2652 : } else {
2653 0 : Query::set_types(lines[i], server_type, lp);
2654 0 : if (index_type == -1) {
2655 0 : puts("type not in conf");
2656 : return 2;
2657 : }
2658 : }
2659 0 : continue;
2660 : }
2661 0 : pos = lines[i].find("L");
2662 0 : if (pos != string::npos)
2663 : {
2664 0 : Query::set_limit(&(lines[i].at(pos)));
2665 0 : continue;
2666 : }
2667 0 : pos = lines[i].find("O");
2668 0 : if (pos != string::npos)
2669 : {
2670 0 : Query::set_offset(&(lines[i].at(pos)));
2671 0 : continue;
2672 : }
2673 : }
2674 : // VR 29-11-16 : je veux des query limit offset sans tri ! Il y a peut etre mieux a faire que cela !
2675 0 : if (query_desc.size() != lp.ReadCacheCPU[index_type].size && query_desc.size() != 0)
2676 : {
2677 0 : std::cout<<"query desc size : "<<query_desc.size()<<", desc size : "<<lp.ReadCacheCPU[index_type].size<<std::endl;
2678 0 : puts("error in type length");
2679 : return 2;
2680 : }
2681 : return 0;
2682 : }
2683 :
2684 :
2685 :
2686 :
2687 : //I776902586,4096,2.227.143.106|776902586,4096,2.227,143,106|776902586,4096,2.227,143,106
2688 : //teste avec la requete en i dans les fichiers de test
2689 0 : int Query::set_query_multi_insert(LocalParam & lp)
2690 : {
2691 0 : std::vector<std::string> photos;
2692 0 : std::vector<std::string> lines;
2693 0 : std::vector<std::string> info;
2694 0 : std::vector<std::string> options;
2695 0 : std::vector<std::string> input_less;
2696 0 : std::string in = input.substr(1);
2697 :
2698 0 : if (input.compare("ieof") == 0)
2699 : {
2700 0 : puts("Just ieof !");
2701 0 : lp.index_type_query = 0; // VR is this a hack ?
2702 0 : Query::set_type(0, lp.descriptor_type, lp);
2703 0 : return 0;
2704 : }
2705 0 : split(photos, input.erase(0,1), is_any_of("|"));// le erase(0,1) c'est pour retirer le 'i' de la query !
2706 0 : std::cout<<" nb photo to insert : "<<photos.size()<<std::endl;
2707 0 : data_to_insert.resize(photos.size());
2708 0 : list_ids.resize(photos.size());
2709 0 : list_size.resize(photos.size());
2710 0 : type_list.resize(photos.size());
2711 0 : index_type_list.resize(photos.size());
2712 0 : for (int i = 0; i < photos.size(); i++)
2713 : {
2714 0 : split(lines, photos[i], is_any_of(";"));
2715 0 : split(info, lines[0], is_any_of(","));
2716 :
2717 0 : list_ids[i] = (uint32_t)atoi(&(info[0].at(0)));
2718 0 : list_size[i] = (uint32_t)atoi(&(info[1].at(0)));
2719 0 : Query::set_type(&(info[2].at(0)), 0, lp);
2720 0 : if (index_type == -1) {
2721 0 : puts("type not in conf");
2722 : return 2;
2723 : }
2724 0 : type_list[i] = type;
2725 0 : index_type_list[i] = index_type;
2726 0 : data_to_insert[i].resize(lines.size()-1);
2727 0 : if (data_to_insert[i].size() != atoi(&(info[1].at(0))))
2728 : {
2729 0 : puts("error in type length");
2730 : return 2;
2731 : }
2732 0 : for (int j = 1; j < lines.size(); ++j)
2733 : {
2734 : #ifdef FLOAT_TYPE
2735 : data_to_insert[i][j-1] = (data)atof(&(lines[j].at(0)));
2736 : #else
2737 0 : data_to_insert[i][j-1] = (data)atoi(&(lines[j].at(0)));
2738 : #endif
2739 : }
2740 : }
2741 : return 0;
2742 : }
2743 :
2744 :
2745 :
2746 : //a tester : requete des kmeans sans clusters initiaux pour un pds dynamique
2747 0 : void Query::set_cluster_init_dyn(const std::vector<data> & data_vec, const int dim){
2748 0 : clusters_as_line.resize(0);
2749 0 : std::cout<<"on charge les nouveaux centroids"<<std::endl;
2750 0 : std::cout<<"dimension : "<<dim<<" nb_clusters : "<<nb_clusters<<std::endl;
2751 0 : for(int cpt=0; cpt<nb_clusters*dim; cpt++){
2752 0 : clusters_as_line.push_back(data_vec[cpt]);
2753 : }
2754 0 : std::cout<<"taille cluster apres init : "<<clusters_as_line.size()<<std::endl;
2755 0 : }
2756 :
2757 :
2758 :
2759 : //a tester : requete des kmeans sans clusters initiaux
2760 0 : void Query::set_cluster_init(const int nb_clusters, const std::vector<data> & data_vec, const int dim){
2761 0 : int index;
2762 0 : std::cout<<"la liste des centroids est incomplete, on va la completer"<<std::endl;
2763 0 : for(int i=clusters_as_line.size(); i<nb_clusters; i++){
2764 0 : index = rand()%(data_vec.size()/dim);
2765 0 : std::cout<<index<<",";
2766 0 : for(int j=0; j<dim; j++){
2767 0 : clusters_as_line.push_back(data_vec[index+j]);
2768 : }
2769 : }
2770 0 : std::cout<<std::endl;
2771 0 : }
2772 :
2773 0 : void Query::reset_clusters(const int nb_clusters, const std::vector<data> & data_vec, const int dim){
2774 0 : clusters_as_line.resize(0);
2775 0 : set_cluster_init(nb_clusters, data_vec, dim);
2776 0 : std::cout<<"cluster size"<<clusters_as_line.size()<<std::endl;
2777 0 : }
2778 :
2779 :
2780 : //teste avec la requete i
2781 0 : const std::vector<std::vector<data> > & Query::getDataInsert() const
2782 : {
2783 0 : return data_to_insert;
2784 : }
2785 : //teste avec la requete i
2786 0 : const std::vector<uint32_t> & Query::getListIds() const
2787 : {
2788 0 : return list_ids;
2789 : }
2790 : //teste avec la requete i
2791 0 : const std::vector<int32_t> & Query::getTypeList() const
2792 : {
2793 0 : return type_list;
2794 : }
2795 : //teste avec la requete i
2796 0 : const std::vector<uint32_t> & Query::getIndexList() const
2797 : {
2798 0 : return index_type_list;
2799 : }
2800 :
2801 :
2802 :
2803 : //i776902586,4096,2,227.143.106
2804 : //pas utilise dans les .cu a verifier dans les .h
2805 0 : int Query::set_query_insert(LocalParam & lp)
2806 : {
2807 0 : std::vector<std::string> lines;
2808 0 : std::vector<std::string> info;
2809 :
2810 0 : split(lines, input, is_any_of("."));
2811 0 : split(info, lines[0], is_any_of(","));
2812 0 : id = (uint32_t)atoi(&(info[0].at(1)));
2813 0 : size = (uint32_t)atoi(&(info[1].at(0)));
2814 0 : Query::set_type(&(info[2].at(0)), 0, lp);
2815 0 : if (index_type == -1) {
2816 0 : puts("type not in conf");
2817 : return 2;
2818 : }
2819 : // VR 27-11-16 : avec 8 dimensions, j'ai bien lines.size() == info[1], mais pas lines.size() - 1 == info[1], comment-est ce possible que l'on soit dans ce cas de figure et surtout que cela marche pour 2 par exemple ?
2820 : // VR 27-11-16 : ok, je comprends mais je ne trouve cela vraiment pas intuitif !
2821 0 : query_desc.resize(lines.size() - 1);
2822 0 : int query_size = (int)query_desc.size();
2823 0 : if (query_size != atoi(&(info[1].at(0))))
2824 : {
2825 0 : printf("size desc are not the same : query size = %d, received : %d\n", query_size,atoi(&(info[1].at(0))));
2826 : return 2;
2827 : }
2828 0 : for (int i = 1; i < lines.size(); ++i)
2829 : {
2830 0 : query_desc[i- 1] = (data)atoi(&(lines[i].at(0)));
2831 : }
2832 : return 0;
2833 : }
2834 :
2835 :
2836 :
2837 : //teste avec les requete e
2838 : //fait de maniere automatique
2839 0 : int Query::set_query_delete(uint32_t server_type, LocalParam & lp)
2840 : {
2841 0 : std::string ids_str = input.substr (1, string::npos);
2842 0 : std::vector<std::string> ids_vec_str;
2843 0 : char * tmp_str = &(input.at(0));
2844 0 : char *tmp_str2 = strchr(tmp_str, 'T');
2845 0 : Query::set_type(tmp_str2, server_type, lp);
2846 0 : split(ids_vec_str, ids_str, is_any_of(","));
2847 0 : list_ids.resize(ids_vec_str.size());
2848 0 : if (ids_vec_str.size() == 0) {
2849 0 : puts("no id to delete");
2850 : return 1;
2851 : }
2852 0 : for (int i = 0; i < ids_vec_str.size(); ++i)
2853 : {
2854 : // VR 13-10-16 TODO bug d'apres mon compilo, et oui cela veut dire que le delete ne marche plus (et n'est sans doute pas testé !)
2855 0 : list_ids[i] == (uint32_t)atoi(&(ids_vec_str[i].at(0)));
2856 : }
2857 :
2858 : return 0;
2859 : }
2860 :
2861 :
2862 : //a verifier si teste, appele dans le cas de multi arg ou si pas de query char particulier ou set_coordinate
2863 0 : int Query::set_query_generic(uint32_t server_type, LocalParam & lp)
2864 : {
2865 0 : char * tmp_str = &(input.at(0));
2866 0 : char * tmp_str2;
2867 0 : id = atoi(tmp_str + 1);
2868 0 : tmp_str2 = strchr(tmp_str, 'T');
2869 0 : Query::set_type(tmp_str2, server_type, lp);
2870 0 : if (index_type == -1)
2871 : return 2;
2872 0 : size = lp.ReadCacheCPU[index_type].size;
2873 0 : tmp_str2 = strchr(tmp_str, 'L');
2874 0 : Query::set_limit(tmp_str2);
2875 0 : if (query_char == 'r' || query_char == 'R' || query_char == 'n' )
2876 0 : id = 0;
2877 : return 0;
2878 : }
2879 :
2880 :
2881 :
2882 : //a tester avec la requete u
2883 0 : int Query::set_query_unload(LocalParam & lp, int verbose)
2884 : {
2885 0 : std::cout<<"query unload "<<std::endl;
2886 0 : std::string types_csv = input.substr (1, string::npos);
2887 0 : set_types(types_csv,0, lp);
2888 0 : return 0;
2889 : }
2890 :
2891 :
2892 : //teste a chaque query envoyée
2893 0 : int Query::set_query(uint32_t server_type, LocalParam & lp, int verbose)
2894 : {
2895 : // var hors set_query : query_char (1ere char), input (list des char du message, query string
2896 : //
2897 0 : std::string querys = "dDsSqacrReiECmlkzgpPuUFAvnt";
2898 : // VR 4-11-16 : on pourrait mettre cela dans une autre fonction appelé par le constructeur qui prend juste un input string
2899 0 : std::string query_string(1, query_char);
2900 :
2901 0 : std::cout << " query_char : " << query_char << " input[0] " << input[0] << ", query_string : " << query_string << std::endl;
2902 :
2903 0 : query_string = input[0];
2904 :
2905 0 : std::cout << " query_string : " << query_string << std::endl;
2906 :
2907 0 : std::size_t found = querys.find(query_string);
2908 0 : if (found == std::string::npos)
2909 : {
2910 0 : puts("first char not in list");
2911 : return -3;
2912 : }
2913 0 : limit = LIMIT_RETURN;
2914 : // VR 17-8-16 : c'est quoi ce E ?
2915 0 : if (query_char == 'C' || query_char == 'E')
2916 : ;
2917 : // return Query::set_query_commit(server_type);
2918 0 : else if (query_char == 'l')
2919 0 : return Query::set_query_load(server_type, lp);
2920 0 : else if (query_char == 'a')
2921 0 : return Query::set_query_advanced(server_type, lp);
2922 0 : else if (query_char == 'd' || query_char == 'D')
2923 0 : return Query::set_query_desc(server_type, lp);
2924 0 : else if (query_char == 'i')
2925 0 : return Query::set_query_multi_insert(lp);
2926 0 : else if (query_char == 'e')
2927 0 : return Query::set_query_delete(server_type, lp);
2928 0 : else if (query_char == 'm')
2929 0 : return Query::set_query_list_ids(server_type,lp);
2930 0 : else if (query_char == 'k')
2931 0 : return Query::set_query_kmean(server_type, lp, verbose);
2932 0 : else if (query_char == 't')
2933 0 : return Query::set_query_prediction(server_type, lp, verbose);
2934 0 : else if (query_char == 'g')
2935 0 : return Query::set_query_coordinate(server_type, lp, verbose);
2936 0 : else if (query_char == 'p' || query_char == 'P')
2937 0 : return Query::set_query_multiarg(server_type, lp);
2938 0 : else if (query_char == 'u' || query_char == 'U')
2939 0 : return Query::set_query_unload(lp, verbose);
2940 : else
2941 0 : return Query::set_query_generic(server_type, lp);
2942 :
2943 : return 0;
2944 : }
2945 :
2946 :
2947 :
2948 :
2949 : //Lecture des requetes client-server
2950 0 : int Query::load_query(int cs, uint32_t server_type,LocalParam & lp, int verbose)
2951 : {
2952 : //////// GB Debut de l'interpretation du message en requete fvs //////
2953 : /*
2954 : size_t r = read(cs, &query_char, 1);
2955 : int taille_buffer = 512;
2956 :
2957 : bool allocDynamique = (query_char == 'p' || query_char == 'P');
2958 :
2959 : if(allocDynamique)
2960 : taille_buffer = 20000000; // 20Mo
2961 :
2962 : char * buff = new char[taille_buffer+1];
2963 : bzero(&buff[0], taille_buffer);
2964 : printf("query_char = %c, ", query_char);
2965 : buff[0] = query_char;
2966 : printf("buff[0] = %c\n", buff[0]);
2967 : r += read(cs, &buff[1], taille_buffer);
2968 :
2969 :
2970 :
2971 : //*/
2972 :
2973 : //*
2974 0 : char * buff = new char[512];
2975 0 : bzero(&buff[0], 512);
2976 0 : size_t r = read(cs,&buff[0],512);
2977 0 : buff[r] = '\0';
2978 : //*/
2979 :
2980 0 : buff[r] = '\0';
2981 :
2982 0 : int desc_dyn=0;
2983 :
2984 0 : size_t tmp = 0;
2985 0 : if (r > 0)
2986 : {
2987 0 : tmp += r;
2988 0 : query_char = buff[0];
2989 0 : input += std::string(&buff[0]);
2990 0 : int count_same_size = 0;
2991 0 : int last_size = 0;
2992 0 : if (query_char == 'p' || query_char == 'P' || query_char == 'i' || query_char == 'a' || query_char == 'm' || query_char == 'k')
2993 : {
2994 : // VR 29-11-16 : on a des boucles infinies ici
2995 0 : while (std::strcmp(&input[tmp - 3], "eof") != 0)
2996 : {
2997 0 : bzero(&buff[0], 512);
2998 0 : r = read(cs, &buff[0], 512);
2999 0 : buff[r] = '\0';
3000 0 : tmp += r;
3001 0 : if (r > 0)
3002 0 : input += std::string(&buff[0]);
3003 : else
3004 : return -5;
3005 :
3006 0 : if (last_size == input.length())
3007 : {
3008 0 : count_same_size++;
3009 0 : if (count_same_size > 3)
3010 : break;
3011 : }
3012 : else
3013 : {
3014 0 : last_size = (int) input.length();
3015 0 : count_same_size = 0;
3016 : }
3017 : }
3018 0 : size_t it = input.find(std::string("T"));
3019 : // std::cout << " input : " << input << std::endl;
3020 0 : std::cout << " it : " << it << std::endl;
3021 0 : if (it != std::string::npos)
3022 : {
3023 0 : std::cout << "T found!" << '\n';
3024 0 : int ind=0;
3025 0 : while (input[ind]!='T')
3026 0 : ind+=1;
3027 : // VR 27-10-18 : a mon avis ind = (int) (it - input.begin());
3028 0 : std::string desc = input.substr(ind, 20);
3029 0 : desc_dyn=atoi(desc.c_str());
3030 : }
3031 : else
3032 : {
3033 0 : std::cout << " If we need desc_dyn, maybe we should set it to the value of default_desc_type " << desc_dyn << std::endl;
3034 : }
3035 :
3036 :
3037 : }
3038 0 : else if(query_char=='F' || query_char=='v')
3039 : return 0;
3040 0 : if (verbose)
3041 : {
3042 0 : std::cout << " input : " << input << std::endl;
3043 : }
3044 :
3045 0 : delete[] buff;
3046 0 : if(desc_dyn<-1)
3047 0 : return set_query(desc_dyn, lp, verbose);
3048 0 : return set_query(server_type, lp, verbose);
3049 :
3050 : } else {
3051 0 : if (r == 0) {
3052 0 : puts("empty message");
3053 0 : delete[] buff;
3054 0 : return -1;
3055 : } else {
3056 : puts("error while reading");
3057 : delete[] buff;
3058 : return -2;
3059 : }
3060 : }
3061 : puts("exit load query");
3062 : /*puts("return after set");
3063 : return 0;*/
3064 :
3065 : }
3066 :
3067 :
3068 0 : void Query::set_query_char(char c)
3069 : {
3070 0 : query_char = c;
3071 0 : }
3072 :
3073 :
3074 0 : void Query::set_query_id(uint32_t newid)
3075 : {
3076 0 : id = newid;
3077 0 : }
3078 :
3079 :
3080 0 : char Query::get_query_char()
3081 : {
3082 0 : return query_char;
3083 : }
3084 :
3085 0 : std::vector<data> & Query::get_query_desc()
3086 : {
3087 0 : return query_desc;
3088 : }
3089 :
3090 0 : std::vector<uint32_t> &Query::get_query_list_ids()
3091 : {
3092 0 : return list_ids;
3093 : }
3094 :
3095 :
3096 0 : size_t Query::get_query_limit()
3097 : {
3098 0 : return limit;
3099 : }
3100 :
3101 :
3102 0 : size_t Query::get_query_offset()
3103 : {
3104 0 : return offset;
3105 : }
3106 :
3107 :
3108 0 : int Query::get_query_iter_max()
3109 : {
3110 0 : return iter_max;
3111 : }
3112 :
3113 :
3114 0 : int Query::get_query_crea_photo_desc()
3115 : {
3116 0 : return crea_photo_desc;
3117 : }
3118 :
3119 :
3120 0 : int Query::get_query_return_centroid(){
3121 0 : return return_centroid;
3122 : }
3123 :
3124 :
3125 0 : int Query::get_query_return_list_photo(){
3126 0 : return return_list_photo;
3127 : }
3128 :
3129 :
3130 0 : int Query::get_query_nb_clusters()
3131 : {
3132 0 : return nb_clusters;
3133 : }
3134 :
3135 :
3136 0 : int Query::get_query_index_type()
3137 : {
3138 0 : return index_type;
3139 : }
3140 :
3141 0 : int Query::get_query_list_index_type(int i)
3142 : {
3143 0 : if (i < index_type_list.size())
3144 0 : return index_type_list[i];
3145 : return -1;
3146 : }
3147 :
3148 0 : int32_t Query::get_query_type()
3149 : {
3150 0 : return type;
3151 : }
3152 :
3153 0 : uint32_t Query::get_query_id()
3154 : {
3155 0 : return id;
3156 : }
3157 :
3158 0 : uint32_t Query::get_query_size()
3159 : {
3160 0 : return (uint32_t) size;
3161 : }
3162 :
3163 0 : std::string Query::get_query_input()
3164 : {
3165 0 : return input;
3166 : }
3167 :
3168 0 : const std::vector<VDInt> & Query::getClustersForGPU() const
3169 : {
3170 0 : return clusters_as_line;
3171 : }
3172 :
3173 0 : const std::vector<std::vector<VDInt> > & Query::getClustersForOutput() const
3174 : {
3175 0 : return clusters;
3176 : }
3177 :
3178 0 : const std::vector<std::pair<int, VDInt> > & Query::getSizeAndInertieClustersForOutput() const
3179 : {
3180 0 : return size_and_inertia;
3181 : }
3182 :
3183 0 : const std::vector<std::vector<uint32_t>> & Query::getListPhotoIdsPerCluster() const
3184 : {
3185 0 : return list_photo_ids_per_cluster;
3186 : }
3187 :
3188 0 : int Query::exit()
3189 : {
3190 0 : int r = input.compare("EXIT MERCI PASSE");
3191 0 : return r;
3192 : }
3193 :
3194 0 : int Query::get_kmax(){
3195 0 : return k_max;
3196 : }
3197 :
3198 0 : void Query::get_cluster(){
3199 0 : for(int i=0; i<list_photo_ids_per_cluster.size();i++){
3200 0 : std::cout<<"cluster "<<i<<" nb photos : "<<list_photo_ids_per_cluster[i].size()<<std::endl;
3201 0 : for(int j=0; j<list_photo_ids_per_cluster[i].size() && j<100; j++){
3202 0 : std::cout<<list_photo_ids_per_cluster[i][j]<<",";
3203 : }
3204 0 : std::cout<<std::endl;
3205 : }
3206 0 : }
3207 :
3208 0 : void Query::cluster_to_csv(LocalParam lp,int index_type,
3209 : const std::vector<types_datas_t> & read_cache_cpu){
3210 0 : std::string csv_filename;
3211 0 : int type = read_cache_cpu[index_type].type;
3212 0 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3213 0 : csv_filename = read_cache_cpu[index_type].dir + "cluster_" + std::to_string(type) +"_"+std::to_string(list_photo_ids_per_cluster.size())+"_"+divergence+".csv";
3214 0 : std::cout<<"filename csv : "<<csv_filename<<std::endl;
3215 : // std::ofstream myfile;
3216 : // myfile.open (csv_filename);
3217 0 : std::ofstream myfile(csv_filename, std::ios::binary);
3218 0 : myfile << "cluster;photo_id\n";
3219 : int photo_idx;
3220 : size_t address_desc;
3221 :
3222 0 : for(int i=0; i<list_photo_ids_per_cluster.size();i++){
3223 0 : for(int j=0; j<list_photo_ids_per_cluster[i].size();j++){
3224 0 : photo_idx = FindPidsIndex(read_cache_cpu[0].ids_vec,list_photo_ids_per_cluster[i][j]);
3225 0 : address_desc = (size_t) read_cache_cpu[0].size * (size_t) photo_idx;
3226 0 : myfile <<i<<";"<<list_photo_ids_per_cluster[i][j];
3227 : //for( int d=0; d<read_cache_cpu[0].size; d++){
3228 : // if (typeid(read_cache_cpu[0].datas_vec[address_desc+ d]) == typeid(float) || typeid(read_cache_cpu[0].datas_vec[address_desc+ d]) == typeid(double)) {
3229 : // std::stringstream stream;
3230 : // stream << std::fixed << std::setprecision(5) << read_cache_cpu[0].datas_vec[address_desc+ d];
3231 : // std::string s = stream.str();
3232 : // myfile << s ;
3233 : // }
3234 : // else {
3235 : // myfile << std::to_string(read_cache_cpu[0].datas_vec[address_desc+ d]);
3236 : // }
3237 : //myfile << std::to_string(read_cache_cpu[0].datas_vec[address_desc+ d]);
3238 : // myfile << read_cache_cpu[0].datas_vec[address_desc+ d];
3239 : //if(d<read_cache_cpu[0].size-1)
3240 : //myfile <<",";
3241 : //}
3242 0 : myfile <<"\n";
3243 : }
3244 : }
3245 0 : std::cout<<"lp dimension "<<read_cache_cpu[index_type].size<<std::endl;
3246 0 : myfile.close();
3247 0 : }
3248 :
3249 :
3250 0 : void Query::data_to_csv(LocalParam lp,int index_type,
3251 : const std::vector<types_datas_t> & read_cache_cpu){
3252 0 : std::string csv_filename;
3253 0 : int type = read_cache_cpu[index_type].type;
3254 0 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3255 0 : csv_filename = read_cache_cpu[index_type].dir + "data_" + std::to_string(type)+".csv";
3256 0 : std::cout<<"filename data desc : "<<csv_filename<<std::endl;
3257 : // std::ofstream myfile;
3258 : // myfile.open (csv_filename);
3259 0 : std::ofstream myfile(csv_filename, std::ios::binary);
3260 0 : myfile << "photo_id;descriptors\n";
3261 : int photo_idx;
3262 : size_t address_desc;
3263 :
3264 0 : for(int i=0; i<list_photo_ids_per_cluster.size();i++){
3265 0 : for(int j=0; j<list_photo_ids_per_cluster[i].size();j++){
3266 0 : photo_idx = FindPidsIndex(read_cache_cpu[0].ids_vec,list_photo_ids_per_cluster[i][j]);
3267 0 : address_desc = (size_t) read_cache_cpu[0].size * (size_t) photo_idx;
3268 0 : myfile <<list_photo_ids_per_cluster[i][j]<<";";
3269 0 : for( int d=0; d<read_cache_cpu[0].size; d++){
3270 0 : myfile << std::to_string(read_cache_cpu[0].datas_vec[address_desc+ d]);
3271 0 : if(d<read_cache_cpu[0].size-1)
3272 0 : myfile <<",";
3273 : }
3274 0 : myfile <<"\n";
3275 : }
3276 : }
3277 0 : myfile.close();
3278 0 : }
3279 :
3280 0 : void Query::prediction_to_csv(LocalParam lp,int index_type,
3281 : const std::vector<types_datas_t> & read_cache_cpu){
3282 0 : std::string csv_filename;
3283 0 : int type = read_cache_cpu[index_type].type;
3284 0 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3285 0 : csv_filename = read_cache_cpu[index_type].dir + "predictions_" + std::to_string(type) +"_"+std::to_string(list_photo_ids_per_cluster.size())+"_"+divergence+".csv";
3286 0 : std::cout<<"filename csv : "<<csv_filename<<std::endl;
3287 : // std::ofstream myfile;
3288 : // myfile.open (csv_filename);
3289 0 : std::ofstream myfile(csv_filename, std::ios::binary);
3290 0 : myfile << "cluster;photo_id\n";
3291 : int photo_idx;
3292 : size_t address_desc;
3293 :
3294 0 : for(int i=0; i<list_photo_ids_per_cluster.size();i++){
3295 0 : for(int j=0; j<list_photo_ids_per_cluster[i].size();j++){
3296 0 : photo_idx = FindPidsIndex(read_cache_cpu[index_type].ids_vec,list_photo_ids_per_cluster[i][j]);
3297 0 : address_desc = (size_t) read_cache_cpu[index_type].size * (size_t) photo_idx;
3298 0 : myfile <<i<<";"<<list_photo_ids_per_cluster[i][j];
3299 0 : myfile <<"\n";
3300 : }
3301 : }
3302 0 : myfile.close();
3303 0 : }
3304 :
3305 0 : void Query::grid_to_csv(LocalParam lp,int index_type){
3306 0 : std::string csv_filename;
3307 0 : int type = lp.ReadCacheCPU[index_type].type;
3308 0 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3309 0 : std::cout<<"size : "<<clusters_as_line.size()<<","<<lp.ReadCacheCPU[index_type].size<<std::endl;
3310 0 : int nbclusters = clusters_as_line.size()/lp.ReadCacheCPU[index_type].size;
3311 0 : int dimension = lp.ReadCacheCPU[index_type].size;
3312 0 : csv_filename = lp.ReadCacheCPU[index_type].dir + "grid_" + std::to_string(type) +"_"+std::to_string(nbclusters)+"_"+divergence+".csv";
3313 0 : std::cout<<"filename csv : "<<csv_filename<<std::endl;
3314 : // std::ofstream myfile;
3315 : // myfile.open (csv_filename);
3316 0 : std::ofstream myfile(csv_filename, std::ios::binary);
3317 0 : myfile << "cluster;photo_id\n";
3318 :
3319 0 : for(int i=0; i<nbclusters;i++){
3320 0 : myfile <<i<<";";
3321 0 : for(int j=0; j<dimension;j++){
3322 0 : myfile <<clusters_as_line[i*dimension+j]<<",";
3323 : }
3324 0 : myfile <<"\n";
3325 : }
3326 0 : std::cout<<"lp dimension "<<lp.ReadCacheCPU[index_type].size<<std::endl;
3327 0 : myfile.close();
3328 0 : }
3329 :
3330 0 : void Query::load_grid_csv(LocalParam lp,int index_type){
3331 0 : int type = lp.ReadCacheCPU[index_type].type;
3332 0 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3333 0 : int dimension = lp.ReadCacheCPU[index_type].size;
3334 0 : std::cout<<"grid filename : "<<grid_filename<<std::endl;
3335 0 : fstream myfile;
3336 0 : myfile.open(grid_filename, ios::in);
3337 :
3338 0 : string line, word;
3339 0 : std::vector<string> temp, row;
3340 0 : std::vector<VDInt> centroid_buffer;
3341 0 : int id =0;
3342 0 : clusters.clear();
3343 0 : clusters_as_line.clear();
3344 0 : while (myfile >> line){
3345 0 : id++;
3346 0 : temp.clear();
3347 0 : row.clear();
3348 0 : stringstream s(line);
3349 0 : while(getline(s,word,';')){
3350 0 : temp.push_back(word);
3351 : }
3352 0 : split(row,temp[1],is_any_of(","));
3353 0 : int sizetemp;
3354 0 : sizetemp = row.size();
3355 0 : std::cout<<"size temp "<<sizetemp<<std::endl;
3356 0 : if(id==1)
3357 : {
3358 0 : continue;// le header du csv
3359 : }
3360 0 : else if ((sizetemp == 0 || sizetemp-1 != dimension))
3361 : {
3362 0 : std::cout<<"Pb de dimension dans le chargement du cluster"<<std::endl;
3363 0 : break;
3364 : }
3365 : else
3366 : {
3367 0 : std::cout<<"centroid vector has correct dimension : "<<sizetemp-1<<std::endl;
3368 0 : centroid_buffer.resize(dimension);
3369 0 : for(int i=0; i<dimension;i++){
3370 : #ifdef FLOAT_TYPE
3371 : centroid_buffer[i] = (VDInt)atof(&(row[i].at(0)));
3372 : #else
3373 0 : centroid_buffer[i] = (VDInt)atoi(&(row[i].at(0)));
3374 : #endif
3375 0 : clusters_as_line.push_back(centroid_buffer[i]);
3376 : }
3377 0 : clusters.push_back(centroid_buffer);
3378 : }
3379 : }
3380 0 : std::cout<<"end load grid, nb cluster : "<<clusters.size()<<std::endl;
3381 0 : myfile.close();
3382 0 : }
3383 :
3384 0 : int Query::executeElbowKmean(LocalParam & lp, int methodChoice){
3385 0 : int nb_kmeans = k_max - k_min;
3386 0 : std::cout<<"k min : "<<k_min<<", k max : "<<k_max<<std::endl;
3387 0 : std::vector<VDInt> list_distortion;
3388 0 : list_distortion.resize(nb_kmeans+1);
3389 0 : if (k_min == 0 || k_max == 0){
3390 0 : std::cout<<"minimal or maximal k is not initialized properly for Elbow kmeans"<<std::endl;
3391 : return -1;
3392 : }
3393 0 : for(int k=k_min ; k<k_max+1 ; k++){
3394 0 : nb_clusters = k;
3395 0 : std::cout<<"nb clusters : "<<nb_clusters<<std::endl;
3396 0 : executeQueryOneStepKmean(lp, methodChoice);
3397 0 : list_distortion[k-k_min] = distortion;
3398 0 : reset_clusters(nb_clusters, lp.ReadCacheCPU[lp.index_type_query].datas_vec,lp.ReadCacheCPU[lp.index_type_query].size);
3399 : }
3400 0 : std::cout<<"list of distortion"<<std::endl;
3401 0 : for(int i=0 ; i<list_distortion.size() ; i++){
3402 0 : std::cout<<list_distortion[i]<<",";
3403 : }
3404 0 : std::cout<<std::endl;
3405 : return 0;
3406 : }
3407 :
3408 :
3409 0 : int Query::executeQueryOneStepKmean(LocalParam & lp, int methodChoice)
3410 : {
3411 0 : int new_type=0;
3412 : #ifndef ONLY_CPU
3413 : std::cout<<"on est dans le execute query kmean OC"<<std::endl;
3414 : #endif
3415 :
3416 0 : if (lp.verbose)
3417 0 : std::cout << " In executeQueryOneStepKmean with special_kmean : " << special_kmean << " and index_type : " << index_type << std::endl;
3418 :
3419 0 : int verbose = verbose_query >= 0 ? verbose_query : lp.verbose;
3420 :
3421 0 : if (index_type == -1)
3422 0 : index_type = 0;
3423 0 : int n = lp.ReadCacheCPU[index_type].nb_data;
3424 0 : distortion = 0;
3425 :
3426 0 : std::cout<<" input : "<<input<<std::endl;
3427 :
3428 0 : if (methodChoice == 3){
3429 0 : nb_iteration = 1;
3430 0 : prediction = true;
3431 0 : onCPUKmeanOneStep(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], list_photo_ids_per_cluster, divergence, verbose, methodChoice);
3432 : }else{
3433 0 : nb_iteration = 20; //valeur par défaut
3434 0 : prediction = false;
3435 : }
3436 :
3437 :
3438 0 : std::cout<<"execute query one step kmean, special_kmean : "<<special_kmean<<std::endl;
3439 :
3440 0 : if (special_kmean == "cpu" || special_kmean == "fromcpu" || special_kmean == "pds" || special_kmean == "pdsgpu")
3441 : {
3442 0 : int methodChoiceUsed = -1;
3443 0 : if (special_kmean == "pds")
3444 : methodChoiceUsed = 0;
3445 0 : else if (special_kmean == "pdsgpu")
3446 : methodChoiceUsed = 1;
3447 0 : else if (special_kmean == "fromcpu")
3448 0 : methodChoiceUsed = 2;
3449 :
3450 0 : if (verbose)
3451 0 : std::cout << " In executeQueryOneStepKmean with special_kmean cpu : " << special_kmean << std::endl;
3452 :
3453 :
3454 0 : if(type < -1 ){
3455 0 : std::cout<<"type : "<<type<<std::endl;
3456 0 : index_type = FindDescIndex(lp.ReadCacheCpuDyn,type);
3457 0 : std::cout<<"index type : "<<index_type<<std::endl;
3458 0 : for(int k=0; k<nb_iteration; k++){
3459 0 : onCPUKmeanOneStep(clusters_as_line, size_and_inertia, lp.ReadCacheCpuDyn[index_type], list_photo_ids_per_cluster, divergence, verbose, methodChoiceUsed);
3460 0 : std::cout<<"iteration test : "<<k<<std::endl;
3461 : }
3462 0 : cluster_to_csv(lp, index_type, lp.ReadCacheCpuDyn);
3463 0 : grid_to_csv(lp, index_type);
3464 : }else{
3465 0 : std::cout<<"test read csv"<<std::endl;
3466 :
3467 0 : for(int k=0; k<nb_iteration; k++){
3468 0 : onCPUKmeanOneStep(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], list_photo_ids_per_cluster, divergence, verbose, methodChoiceUsed);
3469 0 : std::cout<<clusters_as_line[0]<<std::endl;
3470 0 : std::cout<<"fin iteration kmeans cpu :"<<k<<std::endl;
3471 : }
3472 0 : cluster_to_csv(lp, index_type, lp.ReadCacheCPU);
3473 0 : data_to_csv(lp, index_type, lp.ReadCacheCPU);
3474 0 : grid_to_csv(lp, index_type);
3475 : }
3476 0 : for(int i =0; i<list_photo_ids_per_cluster.size(); i++){
3477 0 : std::cout<<"cluster : "<<i<<std::endl;
3478 0 : for(int j=0; j<100 && j<list_photo_ids_per_cluster[i].size();j++){
3479 0 : std::cout<<list_photo_ids_per_cluster[i][j]<<",";
3480 : }
3481 0 : std::cout<<std::endl;
3482 0 : std::cout<<"nb data : "<<list_photo_ids_per_cluster[i].size()<<std::endl;
3483 :
3484 : }
3485 :
3486 : }
3487 0 : else if (special_kmean == "splitandstick")
3488 : {
3489 0 : if (verbose)
3490 0 : std::cout << " In executeQueryOneStepKmean with special_kmean splitandstick : " << special_kmean << std::endl;
3491 0 : onCPUKmeanOneStepSplitAndStick(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], divergence, verbose, SplitAndStickParam(kmean_param));
3492 : }
3493 : #ifndef ONLY_CPU
3494 : //MC-17-08-18 insertion code cuda
3495 : else if (special_kmean == "MCgpu")
3496 : {
3497 : if (verbose)
3498 : std::cout << " In executeQueryOneStepKmean with special_kmean : " << special_kmean << std::endl;
3499 : //fonction a creer dans query.cu
3500 : onCPUKmeanOneStepMCgpu(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], verbose, list_photo_ids_per_cluster); //ajout d'un parametre pour la methode
3501 : //a voir
3502 :
3503 : }
3504 : //fin insertion
3505 :
3506 : #ifndef CUDA7
3507 : else if(special_kmean == "pdsgpub")
3508 : {
3509 : if(verbose)
3510 : std::cout << " In executeQueryOneStepKmean with special_kmean : " << special_kmean << std::endl;
3511 : if(type_list.size()!=0){
3512 : std::cout<<"On est dans le cas des kmeans sur plusieurs clusters, descripteurs"<<std::endl;
3513 : //on suppose qu'on ne demande de merger que des photo_desc temp, sinon on lance un server double
3514 : //pas encore pris en charge
3515 : int nb_desc_dyn_before=lp.ReadCacheCpuDyn.size();
3516 : new_type=lp.list_dyn_desc_type.back() - 1;
3517 : std::vector<data>::iterator it;
3518 : std::vector<uint32_t>::iterator it2;
3519 : //uint32_t ind1, ind2;
3520 : uint32_t ind;
3521 : uint32_t ind2;
3522 : ind=getiddesc(type_list[0], lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3523 : ind2=getiddesc(type_list[type_list.size()-1], lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3524 : std::cout<<"type recherche : "<<type_list[type_list.size()-1]<<std::endl;
3525 : std::cout<<"indice du dernier desc : "<<ind2<<std::endl;
3526 : //ind2=getididesc(type_list[1], lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3527 : //if(lp.ReadCacheCpuDyn[ind2].size != lp.ReadCacheCpuDyn[ind1].size)
3528 : // std::cout<<"Les deux types n'ont pas la meme dimension"<<std::endl;
3529 : if(ind==-1){
3530 : send(lp.cs, "le type n'existe pas!eof",24,0);
3531 : return -1;
3532 : }
3533 : int test=-1;
3534 : while(ind2==-1){
3535 : test-=1;
3536 : ind2=getiddesc(type_list[-1], lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3537 : }
3538 : lp.ReadCacheCpuDyn.resize(nb_desc_dyn_before+1);
3539 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].type=new_type;
3540 : lp.list_dyn_desc_type.push_back(new_type);
3541 : std::cout<<"new type : "<<new_type<<std::endl;
3542 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].size=lp.ReadCacheCpuDyn[ind].size;
3543 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].nb_data=0;
3544 : lp.list_pere_desc_dyn.push_back(lp.list_pere_desc_dyn[ind2]);
3545 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].datas_vec.resize(0);
3546 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].ids_vec.resize(0);
3547 :
3548 : for(int i=0; i<type_list.size(); i++){
3549 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].nb_data+=lp.ReadCacheCpuDyn[ind].nb_data;
3550 : it=lp.ReadCacheCpuDyn[nb_desc_dyn_before].datas_vec.end();
3551 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].datas_vec.insert(it, lp.ReadCacheCpuDyn[ind].datas_vec.begin(), lp.ReadCacheCpuDyn[ind].datas_vec.end());
3552 : it2=lp.ReadCacheCpuDyn[nb_desc_dyn_before].ids_vec.end();
3553 : lp.ReadCacheCpuDyn[nb_desc_dyn_before].ids_vec.insert(it2, lp.ReadCacheCpuDyn[ind].ids_vec.begin(), lp.ReadCacheCpuDyn[ind].ids_vec.end());
3554 :
3555 : if(i<type_list.size()-1){
3556 : ind=getiddesc(type_list[i+1], lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3557 : if(ind==-1){
3558 : send(lp.cs, "le type n'existe pas!eof",24,0);
3559 : return -1;
3560 : }
3561 : }
3562 : }
3563 :
3564 : //insertion sur le gpu
3565 : testCUDA(cudaMalloc(&lp.ReadCacheCpuDyn[nb_desc_dyn_before].dataGPUdyn, lp.ReadCacheCpuDyn[nb_desc_dyn_before].datas_vec.size()*sizeof(datag)));
3566 : testCUDA(cudaMemcpy(lp.ReadCacheCpuDyn[nb_desc_dyn_before].dataGPUdyn, lp.ReadCacheCpuDyn[nb_desc_dyn_before].datas_vec.data(), lp.ReadCacheCpuDyn[nb_desc_dyn_before].datas_vec.size()*sizeof(datag), cudaMemcpyHostToDevice));
3567 : onCPUKmeanOneStepPdsgpub(clusters_as_line, size_and_inertia, lp.ReadCacheCpuDyn[nb_desc_dyn_before], verbose, list_photo_ids_per_cluster, iter_max,1);
3568 : testCUDA(cudaFree(lp.ReadCacheCpuDyn[nb_desc_dyn_before].dataGPUdyn));
3569 : }else{
3570 : if(type<-1){
3571 : int id=getiddesc(type, lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3572 : testCUDA(cudaMalloc(&lp.ReadCacheCpuDyn[id].dataGPUdyn, lp.ReadCacheCpuDyn[id].nb_data*lp.ReadCacheCpuDyn[id].size*sizeof(datag)));
3573 : testCUDA(cudaMemcpy(lp.ReadCacheCpuDyn[id].dataGPUdyn, lp.ReadCacheCpuDyn[id].datas_vec.data(), lp.ReadCacheCpuDyn[id].nb_data*lp.ReadCacheCpuDyn[id].size*sizeof(datag), cudaMemcpyHostToDevice));
3574 : onCPUKmeanOneStepPdsgpub(clusters_as_line, size_and_inertia, lp.ReadCacheCpuDyn[id], verbose, list_photo_ids_per_cluster, iter_max,1);
3575 : testCUDA(cudaFree(lp.ReadCacheCpuDyn[id].dataGPUdyn));
3576 :
3577 : }else{
3578 : onCPUKmeanOneStepPdsgpub(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], verbose, list_photo_ids_per_cluster, iter_max,0);
3579 : }
3580 : }
3581 :
3582 : }
3583 : #endif
3584 : #else
3585 0 : else if (special_kmean == "pdscpu")
3586 : {
3587 0 : if(verbose)
3588 0 : std::cout << "In executeQueryOneStepKmean with special kmean : " << special_kmean << std::endl;
3589 0 : onCPUKmeanOneStepPdscpu(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], verbose, list_photo_ids_per_cluster);
3590 :
3591 :
3592 : }
3593 : #endif
3594 0 : else if (special_kmean == "gpub")
3595 : {
3596 0 : std::cout<<"In gpub"<<std::endl;
3597 : #ifndef ONLY_CPU
3598 : std::cout<<"GPU mode"<<std::endl;
3599 : #ifdef FLOAT_TYPE
3600 : std::cout<<"in gpub !"<<std::endl;
3601 : if(type<-1){
3602 : std::cout<<"type : "<<type<<std::endl;
3603 : index_type = FindDescIndex(lp.ReadCacheCpuDyn,type);
3604 : std::cout<<"index type : "<<index_type<<std::endl;
3605 : onGPUKmeanOneStepThrust(clusters_as_line, size_and_inertia, lp.ReadCacheCpuDyn[index_type], list_photo_ids_per_cluster, divergence, verbose);
3606 : get_cluster();
3607 : cluster_to_csv(lp, index_type, lp.ReadCacheCpuDyn);
3608 : grid_to_csv(lp, index_type);
3609 : }else{
3610 : std::cout<<"type : "<<type<<std::endl;
3611 : onGPUKmeanOneStepThrust(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], list_photo_ids_per_cluster, divergence, verbose);
3612 : get_cluster();
3613 : cluster_to_csv(lp, index_type, lp.ReadCacheCPU);
3614 : grid_to_csv(lp, index_type);
3615 : }
3616 : #endif
3617 : #endif
3618 : }
3619 : else
3620 : {
3621 0 : if (verbose)
3622 0 : std::cout << " In executeQueryOneStepKmean with special_kmean GPU : " << special_kmean << std::endl;
3623 : #ifndef ONLY_CPU
3624 : fromCPUKmeanOneStep(clusters_as_line, lp.ReadCacheCPU[index_type], verbose);
3625 : //appel a la fonction de gpu.cu
3626 : #else
3627 0 : onCPUKmeanOneStep(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], list_photo_ids_per_cluster, divergence, verbose, methodChoice);
3628 : #endif
3629 : }
3630 :
3631 0 : if (verbose)
3632 : {
3633 0 : std::cout << " After fromCPUKmeanOneStep or onCPUKmeanOneStep : list_photo_ids_per_clusters if only_cpu " << std::endl;
3634 :
3635 0 : std::cout << " clusters_as_line : " << clusters_as_line.size() << std::endl;
3636 : // for (unsigned int i = 0; i < clusters_as_line.size(); i++)
3637 : // {
3638 : // std::cout << ", " << clusters_as_line[i]; // << std::endl;
3639 : // }
3640 : }
3641 :
3642 0 : std::cout<<"Computing distortion"<<std::endl;
3643 0 : for (int i = 0; i < size_and_inertia.size(); i++) {
3644 0 : distortion += (VDInt) size_and_inertia[i].second;
3645 : }
3646 0 : std::cout<<"nb data : "<<n<<", Distortion : "<<distortion<<std::endl;
3647 :
3648 : // VR 9-11-23 : et voilà, il faut rajouter ce test
3649 : // if (index_type > lp.ReadCacheCPU.size())
3650 0 : if(type < -1 )
3651 : {
3652 0 : std::cout << " We should probably get the lp.ReadCacheCpuDyn instead of lp.ReadCacheCPU but VR 9-11-23 doesn't know how to check ! " << std::endl;
3653 0 : get_data_kmean(lp.ReadCacheCpuDyn[index_type].size);
3654 : }
3655 : else
3656 : {
3657 0 : get_data_kmean(lp.ReadCacheCPU[index_type].size);
3658 : }
3659 0 : return new_type;
3660 : }
3661 :
3662 : /* query_char options
3663 : * a query advenced interprete tout une commande query avec le type le dossier, la limite, le offset.
3664 : * m moyenne
3665 : * l load
3666 : * C commitInsert
3667 : * k kmeans
3668 : * F Retourne une liste de photos
3669 : * v delete dynamic descripters
3670 : * A requete vide a supprimer
3671 : * q -> query compute distance on data
3672 : * c -> query compute distance on centers
3673 : * s / S : query Stat
3674 : * r / R : query Random prends une photo au hazard
3675 : * d / D : get descrpter of type ...
3676 : * i insert descripters
3677 : * p /P partial distance search
3678 : * z simule un descripters aleatoirement de type ...
3679 : * g return specific dimension of all desc of type ...
3680 : * e / E delete datas and exit
3681 : * u / U query unload
3682 : */
3683 :
3684 0 : int executeQuery(Query & cur_query, LocalParam & lp, GlobalParam & gp)
3685 : {
3686 : ///////////// Execution de la query apres lecture du message ///////////////////
3687 0 : std::cout<<"debut de execute query"<<std::endl;
3688 :
3689 0 : std::vector<types_datas_t> & ReadCacheCPU = lp.ReadCacheCPU;
3690 :
3691 0 : lp.dimension = cur_query.get_query_size();
3692 0 : lp.counter++;
3693 0 : char query_char = cur_query.get_query_char();
3694 0 : std::cout<<"\nCounter request : "<< lp.counter<<std::endl;
3695 0 : if (query_char != 'd' && query_char != 'D' && query_char != 'm')
3696 : {
3697 0 : if (cur_query.get_query_limit() > ReadCacheCPU[cur_query.get_query_index_type()].nb_data)
3698 0 : cur_query.set_limit(ReadCacheCPU[cur_query.get_query_index_type()].nb_data);
3699 : }
3700 0 : std::cout<<" query_type : "<<query_char<<std::endl;
3701 0 : if (query_char == 'E')
3702 : {
3703 0 : lp.retval_set_query = cur_query.exit();
3704 0 : if (lp.retval_set_query == 0)
3705 : {
3706 0 : send(lp.cs, "exitingeof", 10, 0);
3707 0 : close(lp.cs);
3708 0 : return 100;
3709 : }
3710 : else
3711 : {
3712 0 : send(lp.cs, "incorrect queryeof", 18, 0);
3713 0 : close(lp.cs);
3714 0 : return 101;
3715 : }
3716 : }
3717 :
3718 0 : if (query_char == 'n')
3719 : {
3720 0 : std::cout<<"In reset cluster ! "<<std::endl;
3721 0 : cur_query.reset_clusters(cur_query.get_query_nb_clusters(), lp.ReadCacheCPU[lp.index_type_query].datas_vec, ReadCacheCPU[lp.index_type_query].size);
3722 : }
3723 :
3724 0 : if (query_char == 'm')
3725 : {
3726 0 : query_moyenne(ReadCacheCPU[lp.index_type_query], cur_query.get_query_list_ids(), lp.cs, 1, cur_query.get_query_limit());
3727 0 : cur_query.reset_query();
3728 : //clock_t endClockQuery = clock();
3729 : //printf("Querying took %ld micro seconds\n", (endClockQuery - startClockQuery));
3730 : //startClockQuery = clock();
3731 0 : return 101;
3732 : }
3733 0 : if (query_char == 'l')
3734 : {
3735 0 : query_load(lp, ReadCacheCPU, lp.cs, lp.verbose, lp.limit_data, (int) cur_query.get_query_type(), cur_query.get_query_index_type());
3736 : //clock_t endClockQuery = clock();
3737 0 : cur_query.reset_query();
3738 : //printf("Querying took %ld micro seconds\n", (endClockQuery - startClockQuery));
3739 0 : return 101;
3740 : }
3741 0 : if (query_char == 'C')
3742 : {
3743 0 : if (lp.verbose)
3744 0 : puts("commit insert");
3745 0 : for (int i = 0; i < gp.nbtype_; ++i)
3746 : {
3747 0 : commitInsert(gp.WriteCache.at(i), lp.indexCurrent.at(i), ReadCacheCPU.at(i), lp.verbose, gp.dontCheckDuplicateIdObject_,lp.insert_save_file, lp.insert_sync_cache);
3748 0 : if (ReadCacheCPU[i].nb_data)
3749 : {
3750 0 : ReadCacheCPU[i].resizeDatas(ReadCacheCPU[i].datas_vec.size() / ReadCacheCPU[i].size);
3751 : }
3752 : }
3753 0 : if (lp.cleanCPU)
3754 : {
3755 0 : for (int i = 0; i < gp.nbtype_; ++i)
3756 : {
3757 0 : ReadCacheCPU[i].resizeDatas(ReadCacheCPU[i].nb_data);
3758 : }
3759 : }
3760 :
3761 : // VR 3-11-16 : je pense qu'il faut faire cela avant de remplir distances_vec, VR 4-11-16 : j pense l'avoir fait, on peut commenter ces deux lignes et tester
3762 0 : int max_data_loc = get_max_data(ReadCacheCPU);
3763 0 : lp.distances_vec.resize(max_data_loc);
3764 :
3765 0 : send(lp.cs, "commit doneeof", 14, 0);
3766 0 : close(lp.cs);
3767 0 : cur_query.reset_query();
3768 : //clock_t endClockQuery = clock();
3769 : //std::cout<<"Querying took %ld micro seconds\n"<< (endClockQuery - startClockQuery)<<std::endl;
3770 : //startClockQuery = clock();
3771 : // continue;
3772 0 : return 101;
3773 : }
3774 :
3775 0 : if (query_char == 't')
3776 : {
3777 :
3778 0 : int index_type = cur_query.get_query_index_type();
3779 0 : int temp_type = lp.ReadCacheCPU[index_type].type;
3780 0 : int nbclusters = cur_query.get_query_nb_clusters();
3781 0 : int dimension = lp.ReadCacheCPU[index_type].size;
3782 0 : char divergence = 'E';
3783 0 : int merge = 0;
3784 0 : std::cout<<"In prediction step :"<<std::endl;
3785 0 : std::cout<<"Type :"<<temp_type<<" and index : "<<index_type<<std::endl;
3786 0 : std::cout<<"Dimension : "<<dimension<<std::endl;
3787 0 : std::cout<<"NB Clusters : "<<nbclusters<<std::endl;
3788 0 : std::cout<<"Divergence : "<<divergence<<std::endl;
3789 0 : std::string filename;
3790 0 : filename = lp.ReadCacheCPU[index_type].dir + "grid_" + std::to_string(temp_type) +"_11_"+divergence+".csv";
3791 0 : std::cout<<"filename cluster to load "<<filename<<std::endl;
3792 0 : cur_query.load_grid_csv(lp, index_type);
3793 0 : merge=cur_query.executeQueryOneStepKmean(lp, 3);
3794 0 : cur_query.prediction_to_csv(lp, index_type, lp.ReadCacheCPU);
3795 0 : std::cout<<"fin de la prediction"<<std::endl;
3796 : }
3797 :
3798 : //MC 1ere fois query_char=='k'
3799 0 : if (query_char == 'k')
3800 : {
3801 0 : int merge=0;
3802 0 : int id=0;
3803 : //if (lp.verbose)
3804 : //TODO : parametre a modifer si liste de photo_desc
3805 : //19-10-18 peut etre modifié après ou insérer dans le if suivant
3806 : //pour l'instant permet de tester le code
3807 0 : if(cur_query.get_query_types().size()!=0)
3808 0 : std::cout<<"on est dans le cas des kmeans multiples"<<std::endl;
3809 0 : if(cur_query.get_query_nb_clusters()==0){
3810 0 : if(cur_query.getClustersForGPU().size()==0){
3811 0 : cur_query.set_nb_clusters(32);
3812 : }else{
3813 0 : int nb;
3814 0 : if(lp.dimension)
3815 0 : nb=cur_query.getClustersForGPU().size()/lp.dimension;
3816 : else
3817 0 : nb=cur_query.getClustersForGPU().size()/lp.ReadCacheCPU[lp.index_type_query].size;
3818 0 : cur_query.set_nb_clusters(nb);
3819 : }
3820 : }
3821 0 : if (int(cur_query.get_query_type())<(-99)){
3822 0 : std::cout<<"dans le if , type : "<<int(cur_query.get_query_type())<<std::endl;
3823 0 : int nbclusters=cur_query.getClustersForOutput().size();
3824 0 : if (cur_query.get_query_types().size()!=0){
3825 0 : id=getiddesc(cur_query.get_query_types()[0], lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3826 : }else{
3827 0 : id=getiddesc(cur_query.get_query_type(), lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3828 : }
3829 0 : int dim=lp.ReadCacheCpuDyn[id].size;
3830 0 : cur_query.set_cluster_init_dyn(lp.ReadCacheCpuDyn[id].datas_vec, dim);
3831 : }
3832 : else{
3833 : //si le nombre de centroids envoyé ne correspond pas au nombre de cluster demandé
3834 : //on complete la liste
3835 0 : int dimension=ReadCacheCPU[lp.index_type_query].size;
3836 0 : if (cur_query.get_query_nb_clusters()*dimension> cur_query.getClustersForGPU().size() && cur_query.get_query_nb_clusters()!=0)
3837 : {
3838 0 : cur_query.set_cluster_init(cur_query.get_query_nb_clusters(), lp.ReadCacheCPU[lp.index_type_query].datas_vec, dimension);
3839 : }
3840 : }
3841 :
3842 : //MC-17-08-18 ajout d'une methode speciale aux kmeans dans la methode suivante
3843 0 : if (cur_query.get_kmax() != 0){
3844 0 : merge = cur_query.executeElbowKmean(lp);
3845 : } else {
3846 0 : merge=cur_query.executeQueryOneStepKmean(lp);
3847 : }
3848 :
3849 :
3850 0 : if(merge==-1){
3851 0 : close(lp.cs);
3852 0 : cur_query.reset_query();
3853 0 : return 101;
3854 : }
3855 :
3856 0 : if (merge){
3857 0 : int desc;
3858 0 : std::vector<int32_t> descriptors=cur_query.get_query_types();
3859 0 : for(int i=0; i<descriptors.size(); i++){
3860 : //desc=atoi(descriptors[i].c_str());
3861 0 : desc=descriptors[i];
3862 0 : if(desc<-99){
3863 0 : delete_desc_dyn(lp, desc);
3864 : }
3865 : else
3866 0 : std::cout<<"le photo desc demande n'existe pas"<<std::endl;
3867 :
3868 : }
3869 0 : std::cout<<"tous les descripteurs ont ete supprime"<<std::endl;
3870 :
3871 : }
3872 :
3873 :
3874 0 : int id_merge=getiddesc(merge, lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3875 0 : if (lp.verbose)
3876 0 : std::cout << " After executeQueryOneStepKmean " << std::endl;
3877 : // cur_query.get_data_kmean(9216);
3878 0 : std::string result("");
3879 0 : const std::vector<std::vector<uint32_t>> list_photo_ids_per_cluster=cur_query.getListPhotoIdsPerCluster();
3880 0 : if(list_photo_ids_per_cluster.size()==0){
3881 0 : std::cout<<"la liste des photos est vide"<<std::endl;
3882 0 : const std::vector<std::vector<VDInt> > clusters = cur_query.getClustersForOutput();
3883 : //ajout des nouveaux clusters dans le retour des kmeans
3884 0 : if(cur_query.get_query_return_centroid())
3885 0 : for (int i = 0; i < clusters.size(); i++)
3886 : {
3887 0 : if (i > 0)
3888 0 : result += ";";
3889 0 : for (int j = 0; j < clusters[i].size(); j++)
3890 : {
3891 0 : if (j > 0)
3892 0 : result += ",";
3893 0 : result += boost::lexical_cast<std::string>(clusters[i][j]);
3894 : }
3895 : }
3896 : else
3897 0 : std::cout<<"on ne retourne pas la liste des nouveaux centroids"<<std::endl;
3898 : //etape refaite plus bas peut etre a supprimer
3899 :
3900 : // VR 15-1-17 : pour faire du split and stick efficace
3901 0 : result += "|";
3902 : //ajout de la taille et de l'inertie dans le retour des kmeans
3903 0 : const std::vector<std::pair<int, VDInt> > & size_and_inertia = cur_query.getSizeAndInertieClustersForOutput();
3904 0 : for (int i = 0; i < size_and_inertia.size(); i++)
3905 : {
3906 0 : if (i > 0)
3907 0 : result += ";";
3908 0 : result += boost::lexical_cast<std::string>(size_and_inertia[i].first);
3909 0 : result += ":";
3910 0 : result += boost::lexical_cast<std::string>(size_and_inertia[i].second);
3911 : }
3912 0 : if(merge){
3913 0 : result += ';';
3914 0 : result += boost::lexical_cast<std::string>(lp.ReadCacheCpuDyn[id_merge].nb_data);
3915 0 : result += ":0";
3916 :
3917 : }
3918 :
3919 0 : result += "|";
3920 : //renvoie du resume des clusters (1photo par cluster)
3921 : //pour l'instant la premiere photo du cluster, après la plus proche du centroid surement
3922 0 : for( int i=0; i< clusters.size(); i++){
3923 0 : if (i>0)
3924 0 : result += ",";
3925 : //else
3926 0 : result += '0';
3927 :
3928 : }
3929 0 : if(merge)
3930 0 : result += ",0";
3931 : //renvoie de la liste des photo desc temporaires
3932 0 : result += "|";
3933 0 : if(cur_query.get_query_crea_photo_desc()==1){
3934 0 : for ( int i=lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters(); i< lp.list_dyn_desc_type.size(); i++){
3935 0 : std::cout<<"i de debut : "<<lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters()<<std::endl;
3936 0 : std::cout<<"i de fin : "<<lp.list_dyn_desc_type.size()<<std::endl;
3937 0 : if (i>lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters())
3938 0 : result+= ",";
3939 0 : result += boost::lexical_cast<std::string>(lp.list_dyn_desc_type[i]);
3940 : }
3941 : }
3942 : else{
3943 0 : for ( int i=lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters(); i< lp.list_dyn_desc_type.size(); i++){
3944 0 : if (i>lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters())
3945 0 : result+= ",";
3946 0 : result +="0";
3947 : }
3948 : }
3949 0 : if(merge){
3950 0 : result += ',';
3951 0 : if (id_merge!=-1)
3952 0 : result += boost::lexical_cast<std::string>(lp.list_dyn_desc_type[id_merge]);
3953 : else
3954 0 : result+='0';
3955 : }
3956 :
3957 :
3958 :
3959 : //dans le cas ou on veut retourner la liste des photos
3960 : }else{
3961 :
3962 0 : std::cout<<"la liste des photos n'est pas vide"<<std::endl;
3963 0 : const std::vector<std::vector<VDInt> > clusters = cur_query.getClustersForOutput();
3964 :
3965 : //appel de la fonction qui va créer les nouveaux photo_desc
3966 0 : if(cur_query.get_query_crea_photo_desc())
3967 0 : initPDSdynamic(lp, clusters.size(), list_photo_ids_per_cluster, cur_query.get_query_type());
3968 : //renvoie la liste des nouveaux clusters
3969 :
3970 0 : std::cout << " after init pds dynamic " << std::endl;
3971 0 : if(cur_query.get_query_return_centroid())
3972 0 : for (int i = 0; i < clusters.size(); i++)
3973 : {
3974 0 : if (i > 0)
3975 0 : result += ";";
3976 0 : for (int j = 0; j < clusters[i].size(); j++)
3977 : {
3978 0 : if (j > 0)
3979 0 : result += ",";
3980 0 : result += boost::lexical_cast<std::string>(clusters[i][j]);
3981 : }
3982 : }
3983 : else
3984 0 : std::cout<<"on ne retourne pas la liste des nouveaux centroids"<<std::endl;
3985 0 : result += "|";
3986 0 : std::cout << " About to get inertia and size ! " << std::endl;
3987 : //renvoie la taille et l'inertie de chaque cluster
3988 0 : const std::vector<std::pair<int, VDInt> > & size_and_inertia = cur_query.getSizeAndInertieClustersForOutput();
3989 0 : for (int i = 0; i < size_and_inertia.size(); i++)
3990 : {
3991 0 : if (i > 0)
3992 0 : result += ";";
3993 0 : result += boost::lexical_cast<std::string>(size_and_inertia[i].first);
3994 0 : result += ":";
3995 0 : result += boost::lexical_cast<std::string>(size_and_inertia[i].second);
3996 : }
3997 :
3998 0 : if(merge){
3999 0 : result += ';';
4000 0 : result += boost::lexical_cast<std::string>(lp.ReadCacheCpuDyn[id_merge].nb_data);
4001 0 : result += ":0";
4002 :
4003 : }
4004 :
4005 0 : result += "|";
4006 : //renvoie du resume des clusters (1photo par cluster)
4007 : //pour l'instant la premiere photo du cluster, après la plus proche du centroid surement
4008 0 : for( int i=0; i< clusters.size(); i++){
4009 : //if (list_photo_ids_per_clusters[i].size() == 0)
4010 :
4011 0 : if (i>0)
4012 0 : result += ",";
4013 0 : if(size_and_inertia[i].first ==0)
4014 0 : result += '0';
4015 : else
4016 0 : result += boost::lexical_cast<std::string>(list_photo_ids_per_cluster[i][0]);
4017 :
4018 : }
4019 0 : if(merge){
4020 0 : result += ",";
4021 0 : result += boost::lexical_cast<std::string>(lp.ReadCacheCpuDyn[id_merge].ids_vec[0]);
4022 : }
4023 : //renvoie de la liste des photo desc temporaires
4024 0 : result += "|";
4025 0 : if(cur_query.get_query_crea_photo_desc()==1){
4026 0 : for ( int i=lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters(); i< lp.list_dyn_desc_type.size(); i++){
4027 0 : if (i>lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters())
4028 0 : result+= ",";
4029 0 : result += boost::lexical_cast<std::string>(lp.list_dyn_desc_type[i]);
4030 : }
4031 : }
4032 : else{
4033 0 : for ( int i=lp.list_dyn_desc_type.size()-cur_query.get_query_nb_clusters(); i< lp.list_dyn_desc_type.size(); i++){
4034 0 : if (i>0)
4035 0 : result+= ",";
4036 0 : result += "0";
4037 : }
4038 : }
4039 0 : if(merge){
4040 0 : result += ',';
4041 0 : if (id_merge!=-1)
4042 0 : result += boost::lexical_cast<std::string>(lp.list_dyn_desc_type[id_merge]);
4043 : else
4044 0 : result+='0';
4045 : }
4046 :
4047 0 : result+="|";
4048 : //Renvoie la liste des photos par clusters, pour la sauvegarde dans des portfolios
4049 0 : if(cur_query.get_query_return_list_photo()){
4050 0 : for(int i=0; i<list_photo_ids_per_cluster.size(); i++){
4051 0 : if(i>0)
4052 0 : result+=";";
4053 0 : for(int j=0; j<list_photo_ids_per_cluster[i].size(); j++){
4054 0 : if(j>0)
4055 0 : result+=",";
4056 0 : result+=boost::lexical_cast<std::string>(list_photo_ids_per_cluster[i][j]);
4057 :
4058 : }
4059 : }
4060 0 : std::cout<<"on renvoie la liste complete des photos"<<std::endl;
4061 : }else{
4062 0 : for(int i=0; i<list_photo_ids_per_cluster.size(); i++){
4063 0 : if(i>0)
4064 0 : result+=";";
4065 0 : for(int j=0; j<std::min(20,(int)list_photo_ids_per_cluster[i].size()); j++){
4066 0 : if(j>0)
4067 0 : result+=",";
4068 0 : result+=boost::lexical_cast<std::string>(list_photo_ids_per_cluster[i][j]);
4069 :
4070 : }
4071 : }
4072 0 : std::cout<<"on renvoie la mosaique de photos"<<std::endl;
4073 : }
4074 0 : result+="|p";
4075 :
4076 :
4077 : }
4078 :
4079 : // VR 7-12-16: pourquoi y avait t-il ce result.size()-1
4080 0 : if (result.size() > 1){
4081 0 : result+="eof";
4082 0 : std::cout<<"result"<<std::endl<<result<<std::endl<<std::endl<<std::endl;
4083 0 : send(lp.cs,&(result.at(0)), result.size(), 0);
4084 : }else{
4085 0 : send(lp.cs, "Empty Resulteof", 15, 0);
4086 : }
4087 0 : close(lp.cs);
4088 0 : cur_query.reset_query();
4089 0 : return 101;
4090 : }
4091 : //F pour retourner la liste de fotos
4092 : //ajouter des tests si le photo desc n'est pas chargé
4093 0 : else if (query_char == 'F')
4094 : {
4095 0 : std::cout<<"dans le query_char f"<<std::endl;
4096 0 : std::string result("");
4097 0 : std::string input=cur_query.get_query_input();
4098 0 : std::string input_less=input.substr(1);
4099 0 : std::vector<std::string> descriptors;
4100 0 : split(descriptors, input_less, boost::is_any_of(","));
4101 0 : int desc;
4102 0 : for(int i=0; i<descriptors.size(); i++){
4103 0 : desc=atoi(descriptors[i].c_str());
4104 0 : std::cout<<"main desc : "<<lp.ReadCacheCPU[0].type<<std::endl;
4105 0 : std::cout<<"desc : "<<desc<<std::endl;
4106 :
4107 0 : if(desc<-99){
4108 0 : std::cout<<"le desc est negatif"<<std::endl;
4109 0 : int id=getiddesc(desc, lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
4110 0 : if(id==-1){
4111 0 : std::cout<<"l'id "<<id<<" demande n'existe pas"<<std::endl;
4112 0 : send(lp.cs, "Id inexistanteof", 16, 0);
4113 0 : cur_query.reset_query();
4114 : return 101;
4115 : }
4116 0 : std::cout<<"id : "<<id<<std::endl;
4117 0 : if(lp.ReadCacheCpuDyn[id].nb_data==0){
4118 0 : std::cout<<"le descripteur : "<<desc<<" n'a pas de photos"<<std::endl;
4119 : //std::cout<<"liste vide"<<std::endl;
4120 : //result+="Liste videeof";
4121 : //send(lp.cs,&(result.at(0)), result.size(), 0);
4122 : }
4123 : else{
4124 0 : if (result.size()>0)
4125 0 : result+=",";
4126 0 : std::cout<<"la liste des photos n'est pas vide, on a "<<lp.ReadCacheCpuDyn[id].nb_data<<" photos"<<std::endl;
4127 0 : for(int i=0; i<lp.ReadCacheCpuDyn[id].nb_data; i++){
4128 0 : if(i>0)
4129 0 : result+=",";
4130 0 : result+=boost::lexical_cast<std::string>(lp.ReadCacheCpuDyn[id].ids_vec[i]);
4131 : }
4132 : }
4133 : }
4134 : else{
4135 : //int id=getididesc(desc, lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
4136 : //if(id==-1){
4137 0 : std::cout<<"on est dans pas dans le cas du dynamic"<<std::endl;
4138 0 : if(lp.ReadCacheCPU[0].type!=desc){
4139 0 : std::cout<<"le desc lance est : "<<lp.ReadCacheCPU[0].type<<" le desc demande est : "<<desc<<std::endl;
4140 0 : std::cout<<"id demande n'existe pas"<<std::endl;
4141 0 : send(lp.cs, "Id inexistanteof", 16, 0);
4142 : return 101;
4143 : }
4144 0 : if(lp.ReadCacheCPU[0].nb_data==0){
4145 0 : std::cout<<"la liste des photos est vide pour le descripteur : "<<desc<<std::endl;
4146 : //result+="Liste vide";
4147 : //send(lp.cs, "Liste videeof", 13,0);
4148 : }
4149 : else{
4150 0 : if(result.size()>0)
4151 0 : result+=",";
4152 0 : std::cout<<"la liste des photos n'est pas vide, on a nbdata : "<<lp.ReadCacheCPU[0].nb_data<<std::endl;
4153 0 : for(int i=0; i<lp.ReadCacheCPU[0].nb_data; i++){
4154 0 : if(i>0)
4155 0 : result+=",";
4156 0 : result+=boost::lexical_cast<std::string>(lp.ReadCacheCPU[0].ids_vec[i]);
4157 : }
4158 : }
4159 : }
4160 : }
4161 0 : if(lp.verbose)
4162 0 : std::cout<<"result : "<<std::endl<<result<<std::endl;
4163 0 : if (result.size() > 1){
4164 0 : result+="eof";
4165 0 : send(lp.cs,&(result.at(0)), result.size(), 0);
4166 : }else{
4167 0 : send(lp.cs, "Empty Resulteof", 15, 0);
4168 : }
4169 : //std::cout<<"result"<<std::endl<<result<<std::endl
4170 0 : cur_query.reset_query();
4171 : return 101;
4172 : }
4173 0 : else if(query_char=='v'){
4174 0 : std::cout<<"dans le query char v"<<std::endl;
4175 0 : std::cout<<"input : "<<cur_query.get_query_input()<<std::endl;
4176 0 : std::string input=cur_query.get_query_input();
4177 0 : std::string input_less=input.substr(1);
4178 0 : std::vector<std::string> descriptors;
4179 0 : split(descriptors, input_less, boost::is_any_of(","));
4180 0 : int desc;
4181 0 : for(int i=0; i<descriptors.size(); i++){
4182 0 : desc=atoi(descriptors[i].c_str());
4183 0 : if(desc==lp.ReadCacheCPU[0].type){
4184 0 : std::cout<<"on va supprimer tous les descripteurs dynamiques"<<std::endl;
4185 0 : lp.ReadCacheCpuDyn.clear();
4186 0 : lp.list_dyn_desc_type.clear();
4187 0 : lp.list_pere_desc_dyn.clear();
4188 0 : lp.list_photo_per_desc_dyn.clear();
4189 0 : send(lp.cs, "Allcleaneof", 11, 0);
4190 0 : cur_query.reset_query();
4191 : return 101;
4192 : }
4193 0 : if(desc<-99){
4194 0 : delete_desc_dyn(lp, desc);
4195 : }
4196 : else
4197 0 : std::cout<<"le photo desc demande n'existe pas"<<std::endl;
4198 :
4199 : }
4200 0 : std::cout<<"tous les descripteurs ont ete supprime"<<std::endl;
4201 0 : send(lp.cs, "cleandoneeof", 12, 0);
4202 0 : cur_query.reset_query();
4203 : return 101;
4204 :
4205 : }
4206 : //recupere le type
4207 0 : lp.type_query = (int) cur_query.get_query_type();
4208 0 : lp.index_type_query = cur_query.get_query_index_type();
4209 : // VR 29-11-16 : pourquoi est-ce que lp.index_type_query == -1 ?
4210 0 : if (lp.index_type_query == -1)
4211 : {
4212 0 : std::cout << " Unexpected value ! lp.index_type_query : " << lp.index_type_query << " " << __FUNCTION__ << " " << __LINE__ << std::endl;
4213 0 : std::cout << "TODO VR 7-2-23 : we should save the data in the writingcache ! " << std::endl;
4214 0 : exit(1);
4215 : }
4216 : //verification de la taille des donnees
4217 0 : std::cout<<"size Read cache before : "<<ReadCacheCPU[lp.index_type_query].datas_vec.size()<<std::endl;
4218 0 : size_t new_size = (ReadCacheCPU[lp.index_type_query].size == 0 ? 0 : (ReadCacheCPU[lp.index_type_query].datas_vec.size() / ReadCacheCPU[lp.index_type_query].size));
4219 0 : ReadCacheCPU[lp.index_type_query].resizeDatas(new_size);
4220 0 : std::cout<<"size Read cache after : "<<new_size<<std::endl;
4221 0 : std::vector<uint32_t>::iterator query_id_it;
4222 : //recherche de la requete dans les requetes dans le cache
4223 0 : printf("Searching %d in : %lu\n", cur_query.get_query_id(), ReadCacheCPU[lp.index_type_query].ids_vec.size());
4224 0 : query_id_it = std::find(ReadCacheCPU[lp.index_type_query].ids_vec.begin(), ReadCacheCPU[lp.index_type_query].ids_vec.end(), cur_query.get_query_id());
4225 : //placement du curseur au debut de la requete
4226 : // GB mon pb est ici lp.query_index est = -1 qu a cause de cette condition
4227 : // je dois faire de print ici
4228 : // std::cout<<"pb ici : ids vec end "<< lp.ReadCacheCPU[lp.index_type_query].ids_vec.end()<<std::endl;
4229 0 : if (query_id_it == ReadCacheCPU[lp.index_type_query].ids_vec.end())
4230 0 : lp.query_index = -1;
4231 : else
4232 0 : lp.query_index = (int) (query_id_it - ReadCacheCPU[lp.index_type_query].ids_vec.begin());
4233 :
4234 : /// useless si on fait la copie ci-dessous
4235 0 : lp.idc_vec = ReadCacheCPU[lp.index_type_query].ids_vec;
4236 0 : lp.current_limit = (int) cur_query.get_query_limit();
4237 0 : if (lp.verbose)
4238 0 : printf("\ncurrent_limit = %d, allocatin result \n", lp.current_limit);
4239 0 : lp.result_vec.resize(ReadCacheCPU[lp.index_type_query].nb_data);
4240 0 : std::fill(lp.result_vec.begin(), lp.result_vec.end(), 0);
4241 :
4242 : // VR 3-11-16 : proposition : cur_query.is_query_type() or stat_type()
4243 : // VR 26-9-16 : passera dans set_query avec l'utilisation de RadCacheCPU en arguments de set_query
4244 0 : if (query_char == 'q' || query_char == 'c' || query_char == 's' || query_char == 'S' )
4245 : {
4246 0 : if (lp.query_index == -1)
4247 : {
4248 0 : if (query_char == 'q')
4249 : {
4250 : // if lp.query_index == -1, then the given photo id is not part of the index, so we don't do the search
4251 0 : printf("query photo id %d not present in index\n", cur_query.get_query_id());
4252 0 : send(lp.cs, "query pid not indexedeof", 24, 0);
4253 0 : cur_query.reset_query();
4254 0 : close(lp.cs);
4255 0 : return 101;
4256 : }
4257 0 : if (query_char == 'c')
4258 0 : cur_query.set_query_char('R');
4259 0 : if (query_char == 's' || query_char == 'S')
4260 : {
4261 0 : lp.query_index = rand();
4262 0 : if (lp.verbose)
4263 : {
4264 0 : std::cout << " query_index : " << lp.query_index << ", nb_data : " << ReadCacheCPU[lp.index_type_query].nb_data << std::endl;
4265 : }
4266 :
4267 0 : if (ReadCacheCPU[lp.index_type_query].nb_data > 0)
4268 : {
4269 0 : lp.query_index %= ReadCacheCPU[lp.index_type_query].nb_data;
4270 0 : cur_query.set_query_id(ReadCacheCPU[lp.index_type_query].ids_vec[lp.query_index]);
4271 : }
4272 : }
4273 : else
4274 0 : cur_query.set_query_id(0);
4275 : }
4276 0 : query_char = cur_query.get_query_char();
4277 : }
4278 :
4279 : // VR 3-11-16 : proposition : cur_query.is_random_type()
4280 0 : if (query_char == 'r' || query_char == 'R')
4281 : {
4282 0 : if (ReadCacheCPU[lp.index_type_query].nb_data > 0)
4283 : {
4284 : int counter_break = 0;
4285 : // en cas de rand avec qqs données nulles, on peut essayer plusieurs fois
4286 0 : while (cur_query.get_query_id() == 0 && counter_break < 100)
4287 : {
4288 0 : lp.query_index = rand();
4289 0 : lp.query_index %= ReadCacheCPU[lp.index_type_query].nb_data;
4290 0 : printf(" query_index : %d, nb_data : %d \n", lp.query_index, ReadCacheCPU[lp.index_type_query].nb_data);
4291 0 : cur_query.set_query_id(ReadCacheCPU[lp.index_type_query].ids_vec[lp.query_index]);
4292 0 : counter_break++;
4293 : }
4294 : }
4295 : else
4296 : {
4297 0 : printf("no data for type %d\n", lp.type_query);
4298 0 : send(lp.cs, "no data to rand oneof", 21,0);
4299 0 : cur_query.reset_query();
4300 0 : close(lp.cs);
4301 0 : return 101;
4302 : }
4303 0 : printf("rand index chosen : %d", lp.query_index);
4304 : }
4305 :
4306 : // VR 26-9-16 : proposition : cur_query. get_query_type() == Query::query_type_insert
4307 : // VR 3-11-16 : proposition : cur_query.is_insert_type()
4308 0 : if (query_char == 'i')
4309 : {
4310 0 : clock_t timer;
4311 0 : displayTime(timer);
4312 :
4313 : //MG 5/1/17 : boucle for a itérer sur photos.size()
4314 : //quel est la meilleur facon?
4315 : //renvoyer la size? renvoyer une référence du vector?
4316 : //renvoyer des reference de tous les vectors?
4317 : //
4318 0 : int testvar = 0;
4319 0 : const std::vector<std::vector<data> > & datas = cur_query.getDataInsert();
4320 0 : const std::vector<uint32_t> & ids = cur_query.getListIds();
4321 0 : const std::vector<int32_t> & types = cur_query.getTypeList();
4322 0 : const std::vector<uint32_t> & indexes = cur_query.getIndexList();
4323 :
4324 0 : std::cout<<" taille data from insert query : "<<datas.size()<<std::endl;
4325 :
4326 0 : displayTime(timer, "init query i");
4327 0 : std::cout<<"data size : "<<datas.size()<<std::endl;
4328 0 : for (int i = 0; i < datas.size(); i++)
4329 : {
4330 0 : uint32_t photo_id = ids[i];
4331 0 : uint32_t nb_datas = (uint32_t) datas[i].size();
4332 0 : testvar = indexes[i];
4333 0 : if (!gp.dontCheckDuplicateIdObject_)
4334 : {
4335 0 : FindSamePidDataTypeAndSetPidToNull(gp.WriteCache[testvar], lp.indexCurrent.at(testvar), photo_id, types[i]);
4336 : }
4337 0 : if (lp.verbose)
4338 : {
4339 0 : printf("index = %d\n", lp.indexCurrent.at(testvar));
4340 0 : printf("id = %d, type_data = %d, length = %d\n", photo_id, lp.type_query, nb_datas);
4341 0 : printf("gp.WriteCache size : %ld\n", gp.WriteCache.size());
4342 0 : printf("gp.WriteCache index current id : %p\n", &(gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].id));
4343 : }
4344 :
4345 0 : gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].id = photo_id;
4346 0 : gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].type_data = types[i];
4347 0 : gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].length = nb_datas;
4348 0 : gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].datas_vec = datas[i];
4349 :
4350 : // first.insert(first.end(), datas.begin(), datas.end());
4351 :
4352 0 : if (lp.verbose)
4353 0 : printf("id = %d, type_data = %d, length = %d\n", gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].id, gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].type_data, gp.WriteCache[testvar][lp.indexCurrent.at(testvar)].length);
4354 0 : lp.indexCurrent.at(testvar)++;
4355 : }
4356 0 : displayTime(timer, " load data in write cache ");
4357 0 : std::cout<<" insert data "<<std::endl;
4358 0 : std::cout<<" lp.indexCurrent : "<<lp.indexCurrent.at(testvar)<<std::endl;
4359 0 : int nb_data_init = ReadCacheCPU[testvar].nb_data;
4360 0 : if (lp.insert_save_file || lp.insert_sync_cache)
4361 : {
4362 0 : puts("inserting");
4363 0 : if (lp.verbose)
4364 0 : printf("length[0] = %d, length[1] = %d\n", gp.WriteCache[testvar][0].length, gp.WriteCache[testvar][1].length);
4365 0 : commitInsert(gp.WriteCache[testvar], lp.indexCurrent.at(testvar), ReadCacheCPU[testvar], lp.verbose, gp.dontCheckDuplicateIdObject_, lp.insert_save_file, lp.insert_sync_cache);
4366 0 : displayTime(timer, " insert data in cache ");
4367 :
4368 0 : lp.indexCurrent.at(testvar) = 0;
4369 : }
4370 :
4371 :
4372 : // VR 3-11-16 : j'ai l'impression que cela n'est pas utilisé
4373 : // MG 9/11/17 : si ce n est pas la ca fait foiré les tests pour Stat, stat devrait prendre les parametre de cur_query plutot que les localparam
4374 : //
4375 0 : lp.descriptor_type = (lp.descriptor_type == -1 ? lp.type_query : lp.descriptor_type);
4376 :
4377 0 : std::string inserted_photos_str = boost::lexical_cast<std::string>(ReadCacheCPU[testvar].nb_data - nb_data_init) + " photos inserted: ";
4378 0 : for (int i = nb_data_init; i < ReadCacheCPU[testvar].nb_data; ++i)
4379 : {
4380 0 : inserted_photos_str += boost::lexical_cast<std::string>(ReadCacheCPU[testvar].ids_vec[i]);
4381 0 : if (i < ReadCacheCPU[testvar].nb_data - 1)
4382 0 : inserted_photos_str += ",";
4383 : }
4384 0 : inserted_photos_str += "eof";
4385 0 : send(lp.cs, &(inserted_photos_str.at(0)), inserted_photos_str.size(), 0);
4386 0 : cur_query.reset_query();
4387 0 : close(lp.cs);
4388 : //clock_t endClockQuery = clock();
4389 : //printf("Querying took %ld micro seconds\n", (endClockQuery - startClockQuery));
4390 : //startClockQuery = clock();
4391 0 : displayTime(timer, " end query ");
4392 0 : return 101;
4393 : }
4394 0 : else if (query_char == 'D' || query_char == 'd')
4395 : {
4396 0 : if (lp.verbose)
4397 0 : printf(" We will output the descriptors : %d with dimension : %d!\n", lp.query_index, lp.dimension);
4398 0 : std::vector<data> desc_to_copy_vec(lp.dimension);
4399 :
4400 0 : lp.result_vec.resize(lp.dimension);
4401 :
4402 0 : lp.result_data_vec.resize(lp.dimension);
4403 0 : size_t address_desc;
4404 : #ifdef FLOAT_TYPE
4405 : std::cout<<"float type"<<std::endl;
4406 : #else
4407 0 : std::cout<<"int type"<<std::endl;
4408 : #endif
4409 : #ifndef ONLY_CPU
4410 : if (query_char == 'D')
4411 : {
4412 : address_desc = ((size_t) lp.dimension * (size_t) lp.query_index);
4413 : testCUDA(cudaMemcpy(&(lp.result_vec.front()), &ReadCacheCPU[lp.index_type_query].dataGPU[address_desc], lp.dimension * sizeof(datag), cudaMemcpyDeviceToHost));
4414 : }
4415 : #endif
4416 0 : if (query_char == 'd')
4417 : {
4418 0 : address_desc = (size_t) lp.dimension * (size_t) lp.query_index;
4419 0 : for (int i = 0; i < lp.dimension; ++i)
4420 : {
4421 0 : lp.result_data_vec[i] = ReadCacheCPU[lp.index_type_query].datas_vec[address_desc + i];
4422 : }
4423 : }
4424 : }
4425 : // VR 31-12-16 independent simulation for each dimension
4426 0 : else if (query_char == 'z')
4427 : {
4428 0 : if (lp.verbose)
4429 0 : printf(" We take descriptor simulated : %d with dimension : %d!\n", lp.query_index, lp.dimension);
4430 :
4431 0 : std::vector<data> desc_to_copy_vec(lp.dimension);
4432 0 : lp.result_vec.resize(lp.dimension);
4433 : size_t address_desc;
4434 0 : for (int i = 0; i < lp.dimension; ++i)
4435 : {
4436 0 : lp.query_index = rand();
4437 0 : lp.query_index %= ReadCacheCPU[lp.index_type_query].nb_data;
4438 :
4439 0 : address_desc = (size_t) lp.dimension * (size_t) lp.query_index;
4440 :
4441 0 : lp.result_vec[i] = ReadCacheCPU[lp.index_type_query].datas_vec[address_desc + i];
4442 : }
4443 : }
4444 : // VR 1-1-17 : marginal distribution for each dimension
4445 0 : else if (query_char == 'g')
4446 : {
4447 0 : int indice_data = (int) lp.query.get_indice_coordinate();
4448 0 : if (lp.verbose)
4449 0 : std::cout << " We want one dimension of data " << lp.limit_data << " for dimension (ca va pas ! VR 1-1-17) " << indice_data << std::endl;
4450 :
4451 0 : lp.result_vec.resize(lp.limit_data);
4452 : size_t address_desc;
4453 : // VR 15-1-17 : il ne faut pas faire en fonction de limit_data mais seulement des données dans le resultat
4454 0 : for (int i = 0; i < std::min(lp.limit_data, (int) ReadCacheCPU[lp.index_type_query].nb_data); ++i)
4455 : {
4456 0 : address_desc = (size_t) lp.dimension * (size_t) i;
4457 :
4458 0 : lp.result_vec[i] = ReadCacheCPU[lp.index_type_query].datas_vec[address_desc + indice_data];
4459 : }
4460 : }
4461 0 : else if (query_char == 'e')
4462 : {
4463 : int ret = 1;
4464 0 : for (int i = 0; i < gp.nbtype_; ++i)
4465 : {
4466 0 : std::string completeFileNameStr = ReadCacheCPU[i].dir + gp.filename_photo_id_list_str_;
4467 0 : std::string list_pid (&(cur_query.get_query_input().at(1)));
4468 0 : std::string local = ReadCacheCPU[i].dir;
4469 0 : ret = deleteWithTokenManagement(gp.pid_, local, completeFileNameStr, list_pid, ReadCacheCPU[i].nb_data, ReadCacheCPU[i].ids_vec, lp.ReadCacheCPU[i].type, lp.verbose);
4470 : }
4471 0 : if (ret == 0)
4472 0 : send(lp.cs, "delete done!eof", 15, 0);
4473 : else
4474 0 : send(lp.cs, "problem with delete!eof", 23, 0);
4475 0 : close(lp.cs);
4476 0 : cur_query.reset_query();
4477 0 : return 101;
4478 : }
4479 0 : else if (query_char == 'u' || query_char == 'U')
4480 : {
4481 0 : return query_unload(cur_query, lp);
4482 : }
4483 0 : else if (query_char == 'p' || query_char == 'P')
4484 : {
4485 : // result_vec : les ids de retours et distances_vec : les distances aux ids en question
4486 :
4487 : // recherche partial distance search : 1 seul voisin (cpu)
4488 0 : if (lp.verbose)
4489 0 : puts("We are doing a partial distance search query !\n");
4490 :
4491 0 : types_datas_t & ReadCache = ReadCacheCPU[lp.index_type_query];
4492 0 : unsigned d = lp.dimension;
4493 0 : unsigned n = (unsigned) ReadCache.ids_vec.size();
4494 :
4495 : // cur_query.set_query_id(ReadCacheCPU[lp.index_type_query].ids_vec[lp.query_index]);
4496 : // VR 19-9-17 la liste des queries, sauf le premier qui en est la taille
4497 0 : std::vector<uint32_t> liste_ids = cur_query.get_query_list_ids();
4498 :
4499 : // le premier argument
4500 0 : int commandnum = liste_ids[0];
4501 0 : unsigned m = 0;
4502 :
4503 0 : std::cout << " commandnum : is this negative ? " << commandnum << std::endl;
4504 :
4505 0 : bool duplication = (commandnum < 0);
4506 0 : if (duplication)
4507 0 : m = -liste_ids[0];
4508 : else
4509 0 : m = liste_ids[0];
4510 :
4511 : // à remplacer par une lecture de requete après
4512 : // VR 18-9-17 : je crois que ce sont les ids supplémentaires qu'on veut mettre dans les données, cela me parait inutile ! => A moins que cela permettent d'utiliser des query by desc comme on fait dans les autres tests des kmeans et comme il serait utile de le faire pour de l'insertion multiple ou on ne veut pas inserer les données dans la couche qui définit les clusters
4513 0 : uint32_t nbc = liste_ids.size() - (m + 1);
4514 0 : std::vector<uint32_t> candidats_grille(nbc);
4515 :
4516 0 : for (int i = 0; i != nbc; ++i)
4517 0 : candidats_grille[i] = liste_ids[m + 1 + i];//ReadCacheCPU[lp.index_type_query].ids_vec[m+1+i];
4518 :
4519 0 : if (nbc > n)
4520 0 : nbc = 10;
4521 :
4522 0 : if (m + nbc > n)
4523 0 : m = n - nbc;
4524 :
4525 :
4526 : // je suuprime le cas m == 0
4527 :
4528 0 : if (m >= 1)
4529 : {
4530 0 : if (query_char == 'P')
4531 : {
4532 : #ifndef ONLY_CPU
4533 : printf("GPU multi P\n");
4534 :
4535 : if (duplication)
4536 : {
4537 :
4538 : uint32_t *vecteursDev, *argminDev;
4539 : VDInt *distDev;
4540 : uint32_t* candidatsDev;
4541 : datag* grilleDev; ////////////////////////ICI
4542 : const datag *pointeurGPU = ReadCacheCPU[lp.index_type_query].dataGPU;
4543 : std::vector<uint32_t> argmin(m);
4544 : std::vector<VDInt> dist(m);
4545 :
4546 : testCUDA(cudaMalloc(&vecteursDev,m*sizeof(uint32_t)));
4547 : if (duplication)
4548 : testCUDA(cudaMalloc(&grilleDev,m*n*d*sizeof(datag))); /////////////////ICI
4549 : testCUDA(cudaMalloc(&argminDev,m*sizeof(uint32_t)));
4550 : testCUDA(cudaMalloc(&distDev,m*sizeof(uint32_t)));
4551 : testCUDA(cudaMalloc(&candidatsDev,nbc*sizeof(uint32_t)));
4552 :
4553 : // MG 12/9/17 pourquoi ne pas utiliser des vrais vecteurs ?
4554 : // VR 17-9-18 : je suis tout a fait d'accord, il faut le changer, surtout si c'est testé
4555 : uint32_t* argminHost = new uint32_t[m];
4556 : uint32_t* distHost = new uint32_t[m];
4557 : uint32_t* vec = new uint32_t[m];
4558 : uint32_t* vecc = new uint32_t[nbc];
4559 :
4560 : for (int i = 0; i != m; ++i)
4561 : {
4562 : vec[i] = FindPidsIndex(ReadCacheCPU[lp.index_type_query].ids_vec, liste_ids[i + 1]);
4563 : }
4564 :
4565 : for (int i = 0; i != nbc; ++i)
4566 : {
4567 : vecc[i] = FindPidsIndex(ReadCacheCPU[lp.index_type_query].ids_vec, candidats_grille[i]);
4568 : }
4569 :
4570 : testCUDA(cudaMemcpy(vecteursDev, vec, m * sizeof(uint32_t), cudaMemcpyHostToDevice));
4571 : testCUDA(cudaMemcpy(candidatsDev, vecc, nbc * sizeof(uint32_t), cudaMemcpyHostToDevice));
4572 : if (duplication)
4573 : {
4574 : std::vector<data> dats(m*n*d);
4575 : for (int i = 0; i != n; ++i)
4576 : for(int j = 0; j != d; ++j)
4577 : dats[i * d + j] = ReadCacheCPU[lp.index_type_query].datas_vec[i * d + j];
4578 :
4579 : for (int k = 1; k < m; ++k)
4580 : for (int i = 0; i != n; ++i)
4581 : for (int j = 0; j != d; ++j)
4582 : dats[k*n*d+i*d+j] = dats[i*d+j];
4583 : //for(int i=0; i!=m; ++i)
4584 : testCUDA(cudaMemcpy((void**)grilleDev,dats.data(),m*n*d,cudaMemcpyHostToDevice)); //////ICI
4585 : }
4586 :
4587 : //query_kernel_vide(m,m);
4588 :
4589 : printf("nbc = %u\n", nbc);
4590 : puts("\n");
4591 : datag* donneesGPU = (datag*)pointeurGPU;
4592 : if (duplication)
4593 : donneesGPU = grilleDev;
4594 :
4595 : //cudaProfilerStart();
4596 : // MG 12/9/17 : removed duplicated/unused params
4597 : // VR 18-9-17 : n est utilisé dans le cas de duplication, mais je ne vois pas ou il est defini
4598 : query_pds_gpu(m, nbc, n, d, vecteursDev, candidatsDev, argminDev, distDev, (uint32_t*)donneesGPU, duplication); /////////ICI
4599 : delete[] vec;
4600 : delete[] vecc;
4601 : // delete[] pointeurHost;
4602 : //testCUDA(cudaMemcpy(argminDev,vec,m*sizeof(uint32_t),cudaMemcpyHostToDevice));
4603 : lp.result_vec.resize(m);
4604 : lp.distances_vec.resize(m);
4605 : testCUDA(cudaMemcpy(argminHost,argminDev,sizeof(uint32_t)*m,cudaMemcpyDeviceToHost));
4606 : testCUDA(cudaMemcpy(distHost,distDev,sizeof(uint32_t)*m,cudaMemcpyDeviceToHost));
4607 : //cudaFree(pointeurGPU2);
4608 : printf("nbc = %u\n", nbc);
4609 : puts("\n");
4610 : for (int i = 0; i != m; ++i)
4611 : {
4612 : dist[i] = distHost[i];
4613 : uint32_t j = argminHost[i];
4614 : uint32_t z = candidats_grille[j];
4615 : argmin[i] = z;
4616 : }
4617 :
4618 : lp.result_vec = argmin;
4619 : lp.distances_vec = dist;
4620 : lp.current_limit = argmin.size();
4621 :
4622 : delete[] argminHost;
4623 : delete[] distHost;
4624 : cudaFree(vecteursDev);
4625 : if (duplication)
4626 : cudaFree(grilleDev); /////////////////////ICI
4627 : cudaFree(argminDev);
4628 : cudaFree(distDev);
4629 : cudaFree(candidatsDev);
4630 : //cudaProfilerStop();
4631 : }
4632 : else
4633 : {
4634 : uint32_t* vec = new uint32_t[m];
4635 : uint32_t* vecc = new uint32_t[nbc];
4636 :
4637 : for (int i = 0; i != m; ++i)
4638 : {
4639 : vec[i] = FindPidsIndex(ReadCacheCPU[lp.index_type_query].ids_vec, liste_ids[i + 1]);
4640 : }
4641 :
4642 : for (int i = 0; i != nbc; ++i)
4643 : {
4644 : vecc[i] = FindPidsIndex(ReadCacheCPU[lp.index_type_query].ids_vec, candidats_grille[i]);
4645 : }
4646 :
4647 : const datag *pointeurGPU = ReadCacheCPU[lp.index_type_query].dataGPU;
4648 :
4649 : // VR 19-9-17 : il faudrait enlever pas mal de truc comme lp en arguments et peut etre aussi ReadCacheCPU dont on utilise les données gpu
4650 : query_pds_from_cpu(lp.result_vec,
4651 : lp.distances_vec,
4652 : lp.current_limit,
4653 : vec, // VR 19-9-17 : a renommer
4654 : m, // number query, a supprimer quand on aura mis en vecteur la dessus
4655 : vecc, // VR 19-9-17 : a renommer
4656 : nbc, // number candidats, a supprimer quand on aura mis en vecteur la dessus
4657 : n, // number data total (m + nbc)
4658 : d,
4659 : pointeurGPU,
4660 : lp.verbose
4661 : );
4662 :
4663 : delete[] vec;
4664 : delete[] vecc;
4665 : // transformation en photo_ids
4666 : for (int i = 0; i < lp.result_vec.size(); i++)
4667 : {
4668 : lp.result_vec[i] = candidats_grille[lp.result_vec[i]];
4669 : }
4670 : }
4671 : #else
4672 : // MG 12/9/17 j'ai l'impression d'avoir du code dupliqué entre ici et 20 lignes en dessous
4673 0 : printf("CPU multi P\n");
4674 0 : std::cout << liste_ids.size() << std::endl;
4675 : //cur_query.set_query_moyenne(cur_query.get_query_type());
4676 0 : std::vector<uint32_t> res(m);
4677 0 : std::vector<VDInt> dist(m);
4678 0 : lp.current_limit = m;
4679 0 : for (int i = 0; i != m; ++i)
4680 : {
4681 : //printf("%u\n", u);
4682 0 : uint32_t u = liste_ids[i+1];
4683 0 : query_pds(i, u, res, dist, ReadCacheCPU, lp, cur_query, candidats_grille);
4684 : }
4685 :
4686 0 : lp.result_vec.resize(res.size());
4687 0 : lp.distances_vec.resize(dist.size());
4688 0 : lp.result_vec = res;
4689 0 : lp.distances_vec = dist;
4690 :
4691 : #endif // ONLY_CPU
4692 : }
4693 : else
4694 : {
4695 0 : printf("CPU multi p\n");
4696 0 : std::cout << liste_ids.size() << std::endl;
4697 : //cur_query.set_query_moyenne(cur_query.get_query_type());
4698 0 : std::vector<uint32_t> res(m);
4699 0 : std::vector<VDInt> dist(m);
4700 0 : lp.current_limit = m;
4701 0 : for (int i = 0; i != m; ++i)
4702 : {
4703 0 : uint32_t u = liste_ids[i+1];
4704 0 : query_pds(i, u, res, dist,ReadCacheCPU, lp, cur_query, candidats_grille);
4705 : }
4706 0 : lp.result_vec.resize(res.size());
4707 0 : lp.distances_vec.resize(dist.size());
4708 0 : lp.result_vec = res;
4709 0 : lp.distances_vec = dist;
4710 : }
4711 : }
4712 : else
4713 0 : std::cout << "p received an ill-formed list\n" << std::endl;
4714 :
4715 : }
4716 0 : else if (query_char != 'i' && query_char != 'k')
4717 : // by query_type_is_query or query_type_is_statgpu or query_type_is_advanced_query or query_type_is_stat query_type_is_randgpu
4718 : {
4719 0 : if (lp.verbose)
4720 0 : puts("We are doing a classical query !\n");
4721 0 : std::vector<data> desc_to_query_vec(lp.dimension);
4722 0 : if (query_char == 'a')
4723 : {
4724 0 : desc_to_query_vec = cur_query.get_query_desc();
4725 : }
4726 0 : if (query_char == 'a' && cur_query.get_query_desc().size() == 0)
4727 : {
4728 0 : lp.result_vec.resize(cur_query.get_query_limit());
4729 0 : std::vector<uint32_t> & data_local = ReadCacheCPU[cur_query.get_query_index_type()].ids_vec;
4730 0 : for (size_t l = 0; l < std::min(data_local.size(), cur_query.get_query_limit()); l++)
4731 : {
4732 0 : lp.result_vec[l] = data_local[l + cur_query.get_query_offset()];
4733 : }
4734 : }
4735 : else
4736 : {
4737 0 : std::vector<uint32_t> index_type_list = cur_query.get_query_index_type_list();
4738 0 : if (index_type_list.size() == 0)
4739 0 : index_type_list.push_back(cur_query.get_query_index_type());
4740 :
4741 0 : std::vector<uint32_t> result_vec;
4742 0 : std::vector<VDInt> distances_vec;
4743 : // lp.query_index
4744 : // cur_query.get_query_index_type()
4745 0 : for (int k = 0; k < index_type_list.size(); k++)
4746 : {
4747 0 : lp.index_type_query = index_type_list[k];
4748 : // lp.query_index = lp.index_type_query;
4749 0 : lp.type_query = ReadCacheCPU[lp.index_type_query].type;
4750 : // VR 1-1-17 : ca c'est fait deux fois, donc pas vraiment au bon endroit !
4751 0 : lp.idc_vec = ReadCacheCPU[lp.index_type_query].ids_vec;
4752 0 : lp.current_limit = (int) cur_query.get_query_limit();
4753 :
4754 : // ici on est dans le petrain !
4755 0 : if (!lp.current_limit)
4756 : {
4757 0 : lp.current_limit = LIMIT_RETURN;
4758 0 : puts("on a eu un probleme ici current limit ne devrait pas etre null");
4759 : }
4760 :
4761 0 : if (lp.verbose)
4762 0 : printf("\ncurrent_limit = %d, allocatin result \n", lp.current_limit);
4763 0 : lp.result_vec.resize(ReadCacheCPU[lp.index_type_query].nb_data);
4764 :
4765 : #ifndef ONLY_CPU
4766 : // VR 13-10-16 : il faudrait passer dans l'autre boucle du if en cas de lettre petite signifiant cpu, ou le contraire
4767 : if (query_char == 'q' || query_char == 'S' || query_char == 's'|| query_char == 'r' || query_char == 'a')
4768 : {
4769 : if (lp.verbose)
4770 : puts("GPU search mode\n");
4771 : //fromCPU(lp.result_vec, lp.query_index, ReadCacheCPU, lp.type_query, lp.idc_vec, lp.current_limit, lp.distances_vec, desc_to_query_vec, lp.verbose, lp.index_type_query);//cur_query.get_query_index_type());
4772 : NNeighbors(lp.result_vec, lp.query_index, (int) ReadCacheCPU[lp.index_type_query].nb_data, ReadCacheCPU[0].size,
4773 : ReadCacheCPU[lp.index_type_query].datas_vec, lp.idc_vec, lp.current_limit, lp.distances_vec, desc_to_query_vec, 'E', 0);
4774 : }
4775 : else
4776 : #endif
4777 0 : {
4778 0 : if (lp.verbose)
4779 0 : puts("CPU search mode\n");
4780 0 : NNeighbors(lp.result_vec, lp.query_index, (int) ReadCacheCPU[lp.index_type_query].nb_data, ReadCacheCPU[lp.index_type_query].size,
4781 0 : ReadCacheCPU[lp.index_type_query].datas_vec, lp.idc_vec, lp.current_limit, lp.distances_vec, desc_to_query_vec, 'E', 0);
4782 : }
4783 0 : for (int l = 0; l < lp.result_vec.size(); l++)
4784 0 : result_vec.push_back(lp.result_vec[l]);
4785 0 : for (int l = 0; l < lp.distances_vec.size(); l++)
4786 0 : distances_vec.push_back(lp.distances_vec[l]);
4787 :
4788 : }
4789 0 : if (index_type_list.size() > 1)
4790 : {
4791 0 : quick_sort<VDInt>(result_vec, distances_vec, (int) result_vec.size(), lp.verbose);
4792 0 : result_vec.resize(lp.result_vec.size());
4793 0 : distances_vec.resize(lp.distances_vec.size());
4794 0 : lp.result_vec = result_vec;
4795 0 : lp.distances_vec = distances_vec;
4796 : }
4797 : }
4798 : }
4799 :
4800 : //hors des type des requetes => fait dans tous les cas
4801 : //clock_t endClockQuery = clock();
4802 : //printf("Querying took %ld micro seconds\n", (endClockQuery - startClockQuery));
4803 : //startClockQuery = clock();
4804 0 : if (lp.verbose)
4805 0 : printf("result size : %ld\n", lp.result_vec.size());
4806 0 : printf("result size : %ld\n", lp.result_vec.size());
4807 0 : std::string result_str = "";
4808 0 : if (lp.verbose)
4809 0 : puts("query_type_is_stat query_type_is_statgpu or not \n");
4810 :
4811 : //retour aux tests des requetes (stats)
4812 0 : if (query_char == 's' || query_char == 'S')
4813 : {
4814 0 : std::cout<<" start query stat "<<std::endl;
4815 : // VR TODO replace ReadCacheCPU[index_type_query].ids_vec by idc_vec 12-10-16 : but this will makes test change !
4816 0 : query_stat(ReadCacheCPU[lp.index_type_query].nb_data, lp.dimension, lp.current_limit, lp.distances_vec, lp.result_vec, ReadCacheCPU[lp.index_type_query].ids_vec, result_str, lp.verbose, ReadCacheCPU[lp.index_type_query].datas_vec, lp);
4817 : }
4818 :
4819 : //MC 2e query_char=='k' => pourquoi 2 appels ? => surement obselete
4820 0 : else if (query_char == 'k')
4821 : {
4822 : // VR 15-1-17 : pourquoi y a t-il deux appels a clusters for output
4823 0 : const std::vector<std::vector<VDInt> > & clusters_ret = lp.query.getClustersForOutput();
4824 0 : std::ostringstream oss;
4825 0 : for (unsigned int i = 0; i < clusters_ret.size(); i++)
4826 : {
4827 0 : if (i > 0) oss << ";";
4828 0 : for (unsigned int k = 0; k < clusters_ret[i].size(); k++)
4829 : {
4830 0 : if (k > 0) oss << ",";
4831 0 : oss << clusters_ret[i][k];
4832 : }
4833 : }
4834 0 : result_str = ""; // oss.str();
4835 :
4836 :
4837 : // VR 15-1-17 : pour faire du split and stick efficace
4838 0 : result_str += "|";
4839 0 : const std::vector<std::pair<int, VDInt> > & size_and_inertia = cur_query.getSizeAndInertieClustersForOutput();
4840 0 : std::cout<<" inertia : ";
4841 0 : for (int i = 0; i < size_and_inertia.size(); i++)
4842 : {
4843 0 : if (i > 0) result_str += ";";
4844 0 : std::cout<<size_and_inertia[i].first<<":"<<size_and_inertia[i].second;
4845 0 : result_str += boost::lexical_cast<std::string>(size_and_inertia[i].first);
4846 0 : result_str += ":";
4847 0 : result_str += boost::lexical_cast<std::string>(size_and_inertia[i].second);
4848 : }
4849 0 : std::cout<<std::endl;
4850 :
4851 : }
4852 0 : else if (query_char == 'z' || query_char == 'g')
4853 : {
4854 0 : std::ostringstream oss;
4855 0 : for (unsigned int i = 0; i < lp.result_vec.size(); i++)
4856 : {
4857 0 : if (i > 0) oss << ",";
4858 0 : oss << lp.result_vec[i];
4859 : }
4860 0 : result_str = ""; //oss.str();
4861 : }
4862 0 : else if (query_char == 'd' || query_char == 'D'){
4863 0 : for (int i = 0; i < std::min<size_t>(lp.current_limit, lp.result_data_vec.size()); i++)
4864 : {
4865 : #ifdef FLOAT_TYPE
4866 : result_str += boost::lexical_cast<std::string>(lp.result_data_vec[i]);
4867 : #else
4868 0 : result_str += boost::lexical_cast<std::string>(unsigned(lp.result_data_vec[i]));
4869 : #endif
4870 0 : if (i != lp.current_limit - 1)
4871 0 : result_str += ",";
4872 : }
4873 : }
4874 : else
4875 : {
4876 0 : std::cout<<" current limit "<<lp.current_limit<<std::endl;
4877 0 : if (!lp.current_limit)
4878 : {
4879 0 : lp.current_limit = LIMIT_RETURN;
4880 0 : puts("on a eu un probleme ici current limit ne devrait pas etre null");
4881 : }
4882 0 : if (lp.current_limit)
4883 : {
4884 0 : for (int i = 0; i < std::min<size_t>(lp.current_limit, lp.result_vec.size()); i++)
4885 : {
4886 0 : result_str += boost::lexical_cast<std::string>(lp.result_vec[i]);
4887 0 : if (query_char != 'd' && query_char != 'D' && i < lp.distances_vec.size())
4888 : {
4889 0 : result_str += ":";
4890 0 : result_str += boost::lexical_cast<std::string>(lp.distances_vec[i]);
4891 : }
4892 0 : if (i != lp.current_limit - 1)
4893 0 : result_str += ",";
4894 : }
4895 : }
4896 : else
4897 : {
4898 0 : puts("current_limit NULL no answer to send sending dummy result");
4899 0 : result_str = "0,0,0,0";
4900 : }
4901 : }
4902 :
4903 0 : if (lp.verbose)
4904 0 : puts("About to send result !");
4905 0 : if (result_str.length() > 0){
4906 0 : std::cout<<"result query : "<<result_str<<std::endl;
4907 0 : result_str+="eof";
4908 0 : send(lp.cs, &(result_str.at(0)), result_str.size(), 0);
4909 : }else{
4910 0 : send(lp.cs, "eof", result_str.size()+3, 0);
4911 : }
4912 0 : return 0;
4913 : }
|