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 56 : void displayTime(clock_t & begin_end, const std::string & message)
50 : {
51 56 : if (message.compare("") != 0)
52 : {
53 42 : clock_t end = clock();
54 42 : double elaps_time = (double) (end - begin_end) / CLOCKS_PER_SEC;
55 42 : std::cout << "detailed time ms " << message << " " << elaps_time << std::endl;
56 : }
57 56 : begin_end = clock();
58 56 : }
59 :
60 8 : int32_t getiddesc(const int t,const std::vector<int> & list, const int size)
61 : {
62 0 : int32_t index = 0;
63 8 : while (index < size && list[index] != t ) ++index;
64 8 : 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 8 : 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 8 : auto & ReadCache = ReadCacheCPU[lp.index_type_query];
301 8 : unsigned d = lp.dimension;
302 8 : unsigned nbc = (unsigned) candidats_grille.size();
303 8 : unsigned int n = (unsigned int) ReadCache.ids_vec.size();
304 8 : cur_query.set_query_id(id_photo);
305 16 : auto qi = FindPidsIndex(ReadCache.ids_vec, id_photo);
306 8 : size_t address_desc = (size_t) d * (size_t) qi;
307 8 : uint32_t id;
308 8 : VDInt dist_min = (VDInt)-1;
309 8 : VDInt dcumul = 0;
310 8 : uint32_t argmin = 0;
311 8 : short z;
312 :
313 24 : for(int i=0; i!=nbc; ++i) {
314 16 : id = candidats_grille[i];
315 16 : if (id == id_photo) continue;
316 16 : dcumul = 0;
317 16 : uint32_t offset_grille = FindPidsIndex(ReadCache.ids_vec,id)*d;
318 76 : for(int j=0; j!=d; ++j) {
319 64 : z = ReadCache.datas_vec[address_desc+j]-ReadCache.datas_vec[offset_grille + j];
320 64 : dcumul += z*z;
321 :
322 64 : if(dcumul>dist_min)
323 : break;
324 : }
325 16 : if (dcumul <= dist_min && dcumul != 0) {
326 12 : dist_min = dcumul;
327 12 : argmin = id;
328 : }
329 : }
330 8 : res[idx_v] = argmin;
331 8 : dist[idx_v] = dist_min;
332 8 : }
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 65 : 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 65 : 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 65 : const uint32_t nbrPhoto = ReadCacheCPUPointerOneDescriptorType.nb_data;
506 65 : const uint32_t dimension = ReadCacheCPUPointerOneDescriptorType.size;
507 65 : const unsigned long nbrCentroids = (int) clusters.size() / dimension;
508 130 : std::vector<uint32_t> centroidIds(nbrCentroids);
509 130 : std::vector<data> tempCluster(clusters.size());
510 :
511 130 : data min_elem = *std::min_element(ReadCacheCPUPointerOneDescriptorType.datas_vec.begin(),ReadCacheCPUPointerOneDescriptorType.datas_vec.end());
512 130 : data max_elem = *std::max_element(ReadCacheCPUPointerOneDescriptorType.datas_vec.begin(),ReadCacheCPUPointerOneDescriptorType.datas_vec.end());
513 65 : std::cout<<"min element : "<<min_elem<<", max_elem : "<<max_elem<<std::endl;
514 65 : data scope = max_elem-min_elem;
515 65 : std::cout<<"scope : "<<scope<<std::endl;
516 : int sign_elem;
517 173 : if(min_elem < (data) 0 ? sign_elem=-1 : sign_elem=1);
518 :
519 173 : for (int i = 0 ; i < nbrCentroids ; i++)
520 108 : centroidIds[i] = i;
521 :
522 498 : for (int i = 0 ; i < clusters.size(); i++)
523 433 : tempCluster[i] = (clusters[i]+sign_elem*min_elem+1);//scope*16;
524 :
525 65 : 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 65 : 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 65 : list_photo_ids_per_cluster.clear();
539 65 : list_photo_ids_per_cluster.resize(nbrCentroids, std::vector<uint32_t>());
540 :
541 :
542 65 : list_ids_per_clusters.clear();
543 65 : list_ids_per_clusters.resize(nbrCentroids, std::vector<uint32_t>());
544 :
545 :
546 65 : list_minimum_distances_photo_ids_per_clusters.resize(0);
547 65 : list_minimum_distances_photo_ids_per_clusters.resize(nbrCentroids, std::vector<VDInt>());
548 :
549 65 : const int id_query = -1;
550 65 : const int limit_return = 1;
551 :
552 130 : std::vector<data> query_desc(dimension);
553 130 : std::vector<uint32_t> ids;
554 65 : std::vector<uint32_t> result;
555 65 : std::vector<VDInt> distances;
556 65 : std::cout<<" Methode Choice : "<<methodChoice<<std::endl;
557 65 : std::cout<<"divergence : "<<divergence<<std::endl;
558 :
559 :
560 65 : 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 715065 : for (int i = 0; i < ReadCacheCPUPointerOneDescriptorType.nb_data; i++)
577 : {
578 715000 : ids = centroidIds;
579 :
580 3575000 : for (int k = 0; k < dimension; k++)
581 2860000 : query_desc[k] = (ReadCacheCPUPointerOneDescriptorType.datas_vec[i * ReadCacheCPUPointerOneDescriptorType.size + k]+sign_elem*min_elem+1);//scope*16;
582 :
583 715000 : if (i % 1000 == 0)
584 715 : std::cout << ",";
585 :
586 715000 : 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 715000 : {
607 715000 : 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 715000 : 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 715000 : if (result.size() > 0 && distances.size() > 0)
621 : {
622 715000 : int id_result = result[0];
623 715000 : if (verbose)
624 0 : std::cout << " id_result : " << id_result << std::endl;
625 715000 : list_ids_per_clusters[id_result].push_back(i);
626 715000 : list_photo_ids_per_cluster[id_result].push_back(ReadCacheCPUPointerOneDescriptorType.ids_vec[i]);
627 715000 : list_minimum_distances_photo_ids_per_clusters[id_result].push_back(distances[0]);
628 : }
629 : else
630 : {
631 715000 : std::cout << " Empty result for id : " << ReadCacheCPUPointerOneDescriptorType.ids_vec[i] << std::endl;
632 : }
633 : }
634 173 : for(int j=0; j<nbrCentroids; j++){
635 108 : int sizeclt = list_ids_per_clusters[j].size();
636 108 : std::cout<<"size cluster "<<j<<" : "<<sizeclt<<std::endl;
637 108 : 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 65 : std::cout << std::endl << std::endl;
706 :
707 65 : clock_t startClockQuery = clock();
708 :
709 65 : new_clusters.resize(clusters.size());
710 : int idx;
711 : unsigned long cellSize;
712 173 : for (int i = 0 ; i < nbrCentroids ; i++)
713 : {
714 108 : cellSize = list_photo_ids_per_cluster[i].size();
715 715108 : 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 715000 : idx = list_ids_per_clusters[i][k];
719 :
720 3575000 : for (int l = 0 ; l < dimension; l++)
721 2860000 : new_clusters[i * dimension + l] += ReadCacheCPUPointerOneDescriptorType.datas_vec[idx * dimension + l];
722 : }
723 :
724 108 : if ( cellSize > 0 )
725 : {
726 520 : for (int l = 0 ; l < dimension; l++)
727 416 : new_clusters[i * dimension + l] /= cellSize;
728 : }
729 : }
730 :
731 65 : 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 65 : clock_t endClockQuery = clock();
752 65 : std::cout << "Computing new clusters took " << (endClockQuery - startClockQuery) << " micro seconds " << std::endl;
753 :
754 65 : printf("avant le resize\n");
755 :
756 65 : printf("nbrCentroids=%lu\n", nbrCentroids);
757 :
758 :
759 65 : size_and_inertia.clear();
760 65 : size_and_inertia.resize(nbrCentroids);
761 65 : VDInt inertia;
762 65 : int size;
763 :
764 :
765 65 : printf("avant la boucle ! \n");
766 :
767 173 : for (int i = 0 ; i < nbrCentroids ; i++)
768 : {
769 :
770 108 : printf("avant\n");
771 :
772 108 : size = (int) list_minimum_distances_photo_ids_per_clusters[i].size();
773 108 : inertia = 0;
774 :
775 108 : printf("i=%d, size=%d\n", i, size);
776 :
777 :
778 715108 : for (int k = 0; k < size; k++)
779 715000 : inertia += list_minimum_distances_photo_ids_per_clusters[i][k];
780 :
781 108 : size_and_inertia[i] = std::pair<int, VDInt>(size, inertia/ReadCacheCPUPointerOneDescriptorType.nb_data);
782 : }
783 65 : std::cout << " about to leave auxKmeanOnCPU " << std::endl;
784 : }
785 :
786 11000 : VDInt computeDistanceSquare(const std::vector<VDInt> & a, const std::vector<VDInt> & b)
787 : {
788 11000 : VDInt dist = 0;
789 11000 : long int temp;
790 11000 : unsigned long dim = std::min<unsigned long>(a.size(), b.size());
791 55000 : for (int i = 0; i < dim ; i++)
792 : {
793 44000 : temp = (int)a[i] - (int)b[i];
794 44000 : dist += temp * temp;
795 : }
796 11000 : return dist;
797 : }
798 :
799 : // VR 11-1-17 : faire une fonction aux ! => je pense que c'est fait VR 2-4-17
800 1 : 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 2 : std::vector<VDInt> new_clusters;
808 1 : std::vector<std::vector<uint32_t> > list_photo_ids_per_cluster;
809 1 : std::vector<std::vector<uint32_t> > list_ids_per_clusters;
810 1 : std::vector<std::vector<VDInt> > list_minimum_distances_photo_ids_per_clusters;
811 :
812 1 : 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 1 : std::vector<std::vector<uint32_t> > list_photo_ids_per_clusters_before_split_and_stick = list_ids_per_clusters;
815 1 : std::cout << " Before split and stick clusters.size() " << clusters.size() << " new_clusters.size() " << new_clusters.size() << std::endl;
816 :
817 1 : int nb_clusters = (int) clusters.size() / ReadCacheCPUPointerOneDescriptorType.size;
818 :
819 2 : std::vector<VDInt> local_inertia(nb_clusters);
820 : // should be of size list_minimum_distances_photo_ids_per_clusters
821 3 : for (int i = 0; i < nb_clusters ; i++)
822 : {
823 2 : local_inertia[i] = 0;
824 :
825 11002 : for (int k = 0; k < list_minimum_distances_photo_ids_per_clusters[i].size(); k++)
826 11000 : local_inertia[i] += list_minimum_distances_photo_ids_per_clusters[i][k];
827 : }
828 :
829 2 : std::vector<uint32_t> id(nb_clusters);
830 3 : for (int i = 0; i < nb_clusters ; i++) id[i] = i;
831 :
832 : // order map (a construire)
833 : // parametre qui doivent venir
834 1 : quick_sort<VDInt>(id, local_inertia, nb_clusters, verbose);
835 :
836 1 : int nb_to_remove = nb_clusters / param_split_stick.fraction_stick;
837 1 : if (nb_to_remove == 0) nb_to_remove = 1;
838 :
839 1 : int nb_to_add = nb_clusters / param_split_stick.fraction_split;
840 1 : 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 1 : if (nb_clusters < nb_to_add + nb_to_remove)
844 : {
845 0 : clusters = new_clusters;
846 1 : 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 2 : std::vector<std::pair<int, VDInt> > new_size_and_inertia(nb_clusters - (nb_to_add + nb_to_remove));
855 1 : new_size_and_inertia.reserve(nb_clusters);
856 :
857 : // Ceux qui reste tel quel :
858 2 : std::vector<VDInt> clusters_split_and_stick;
859 1 : int id_cluster;
860 1 : 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 1 : int nb_elem, this_data ,this_data_idx;
870 1 : VDInt first_inertia = 0, second_inertia = 0;
871 2 : std::vector<VDInt> b(ReadCacheCPUPointerOneDescriptorType.size);
872 :
873 2 : for (int i = 0; i < nb_to_add; i++)
874 : {
875 1 : id_cluster = id[nb_clusters - nb_to_add + i];
876 :
877 : // the main one, to be commented
878 :
879 1 : nb_elem = (int)list_photo_ids_per_cluster[id_cluster].size();
880 1 : 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 3 : std::vector<VDInt> first_half_cluster(ReadCacheCPUPointerOneDescriptorType.size), second_half_cluster(ReadCacheCPUPointerOneDescriptorType.size);
892 5501 : for (int l = 0; l < nb_elem / 2; l++)
893 : {
894 5500 : this_data = list_photo_ids_per_cluster[id_cluster][l];
895 5500 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
896 :
897 27500 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
898 22000 : first_half_cluster[k] += ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
899 : }
900 5501 : for (int l = nb_elem / 2; l < nb_elem; l++)
901 : {
902 5500 : this_data = list_photo_ids_per_cluster[id_cluster][l];
903 5500 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
904 :
905 27500 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
906 22000 : second_half_cluster[k] += ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
907 : }
908 :
909 5 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
910 : {
911 4 : first_half_cluster[k] /= (nb_elem / 2);
912 4 : second_half_cluster[k] /= (nb_elem - nb_elem / 2);
913 : }
914 :
915 5 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
916 4 : clusters_split_and_stick.push_back(first_half_cluster[k]);
917 :
918 5 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
919 4 : clusters_split_and_stick.push_back(second_half_cluster[k]);
920 :
921 : first_inertia = 0;
922 5501 : for (int l = 0; l < nb_elem / 2; l++)
923 : {
924 5500 : this_data = list_photo_ids_per_cluster[id_cluster][l];
925 5500 : this_data_idx = FindPidsIndex(ReadCacheCPUPointerOneDescriptorType.ids_vec, this_data);
926 :
927 : // ca me parait assez dangereux ! VR 15-1-17
928 27500 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
929 22000 : b[k] = ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
930 :
931 5500 : first_inertia += computeDistanceSquare(first_half_cluster, b);
932 : }
933 1 : new_size_and_inertia.push_back(std::pair<int, VDInt>(nb_elem / 2, first_inertia));
934 :
935 1 : second_inertia = 0;
936 5501 : for (int l = nb_elem / 2; l < nb_elem; l++)
937 : {
938 5500 : this_data = list_photo_ids_per_cluster[id_cluster][l];
939 5500 : 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 27500 : for (int k = 0; k < ReadCacheCPUPointerOneDescriptorType.size; k++)
944 22000 : b[k] = ReadCacheCPUPointerOneDescriptorType.datas_vec[this_data_idx * ReadCacheCPUPointerOneDescriptorType.size + k];
945 :
946 5500 : second_inertia += computeDistanceSquare(second_half_cluster, b);
947 : }
948 1 : 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 2 : types_datas_t SearchCluster = ReadCacheCPUPointerOneDescriptorType;
955 1 : SearchCluster.size = ReadCacheCPUPointerOneDescriptorType.size;
956 1 : SearchCluster.nb_data = (int) clusters_split_and_stick.size() / SearchCluster.size;
957 1 : 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 1 : SearchCluster.ids_vec.resize(SearchCluster.nb_data);
964 3 : for (int i = 0; i < SearchCluster.ids_vec.size(); i++)
965 2 : SearchCluster.ids_vec[i] = i;
966 :
967 1 : SearchCluster.datas_vec.resize(clusters_split_and_stick.size());
968 9 : for (int i = 0; i < clusters_split_and_stick.size(); i++)
969 8 : SearchCluster.datas_vec[i] = clusters_split_and_stick[i];
970 :
971 1 : const int id_query = -1;
972 1 : const int limit_return = 1;
973 :
974 2 : std::vector<data> query_desc(SearchCluster.size);
975 2 : std::vector<uint32_t> ids;
976 1 : std::vector<uint32_t> result;
977 1 : std::vector<VDInt> distances;
978 :
979 2 : 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 1 : id_cluster = id[i];
983 :
984 1 : 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 1 : std::cout << std::endl << std::endl;
1010 : }
1011 :
1012 1 : std::cout << " After split and stick clusters.size() " << clusters.size() << " clusters_split_and_stick.size() " << clusters_split_and_stick.size() << std::endl;
1013 :
1014 1 : size_and_inertia = new_size_and_inertia;
1015 1 : clusters = clusters_split_and_stick;
1016 : }
1017 : }
1018 :
1019 :
1020 : //20-08-18 fonction des kmeans actuelle sans doute
1021 64 : 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 64 : std::vector<VDInt> new_clusters;
1028 :
1029 64 : std::vector<std::vector<uint32_t> > list_ids_per_clusters;
1030 64 : 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 64 : 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 169 : for(int i=0; i<size_and_inertia.size(); i++){
1040 105 : if(size_and_inertia[i].first == 0){
1041 3 : std::cout<<"cluster vide n : "<<i<<std::endl;
1042 3 : uint32_t dim = ReadCacheCPUPointerOneDescriptorType.size;
1043 3 : int ind = rand()%(ReadCacheCPUPointerOneDescriptorType.datas_vec.size()/dim);
1044 3 : std::cout<<"id : "<<ind<<std::endl;
1045 15 : for(int j=0; j<dim; j++){
1046 12 : 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 64 : 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 64 : 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 64 : std::cout << " After cpu step clusters.size() " << clusters.size() << " new_clusters.size() " << new_clusters.size() << std::endl;
1065 64 : if(methodChoice == 3){
1066 0 : clusters = new_clusters;
1067 : }
1068 :
1069 64 : }
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 1 : 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 1 : int nb_equal = 0;
1738 :
1739 1 : double m1 = 0.;
1740 1 : double m2 = 0.;
1741 :
1742 11000 : for (uint32_t i = 0 ; i < std::max<int>(nb_data - 1, 0); i++)
1743 : {
1744 10999 : if (ordered_distances[i] > ordered_distances[i + 1])
1745 : {
1746 0 : printf("Result not ordered ! : INTERNAL BUG \n");
1747 : }
1748 10999 : if (ordered_distances[i] == ordered_distances[i + 1])
1749 10285 : nb_equal++;
1750 :
1751 10999 : double val = ordered_distances[i];
1752 10999 : double m0 = i + 1;
1753 10999 : m1 += (val - m1) / m0;
1754 10999 : m2 += (val * val - m2) / m0;
1755 : }
1756 :
1757 1 : double mean = m1;
1758 1 : double var = m2 - m1 * m1;
1759 1 : double stddev = sqrt(var);
1760 :
1761 1 : size_t dimension = (nb_data > 0) ? datas_vec.size() / nb_data : 0;
1762 1 : std::cout << "Dimension : " << dimension << std::endl;
1763 1 : std::cout << "Size Result : " << sizeResult << std::endl;
1764 2 : std::vector<double> m1v(dimension, 0.), m2v(dimension, 0.);
1765 3 : std::vector<double> varv(dimension, 0.), stddevv(dimension, 0.);
1766 :
1767 1 : double m1d = 0.;
1768 1 : double m2d = 0.;
1769 :
1770 11001 : for (uint32_t i = 0 ; i < nb_data; i++)
1771 : {
1772 11000 : double m0v = i + 1;
1773 55000 : for (uint32_t j = 0 ; j < dimension; j++)
1774 : {
1775 44000 : double val = datas_vec[i * dimension + j];
1776 44000 : m1v[j] += (val - m1v[j]) / m0v;
1777 44000 : m2v[j] += (val * val - m2v[j]) / m0v;
1778 :
1779 44000 : double m0d = i * dimension + j + 1;
1780 44000 : m1d += (val - m1d) / m0d;
1781 44000 : m2d += (val * val - m2d) / m0d;
1782 : }
1783 : }
1784 :
1785 5 : for (uint32_t j = 0; j < dimension; j++)
1786 : {
1787 4 : varv[j] = m2v[j] - m1v[j] * m1v[j];
1788 4 : if (varv[j] > 0)
1789 4 : stddevv[j] = sqrt(varv[j]);
1790 : }
1791 :
1792 1 : double vard = m2d - m1d * m1d;
1793 1 : double stddevd = vard > 0 ? sqrt(vard) : 0;
1794 :
1795 1 : 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 1 : result.resize(0);
1806 1 : if (sizeResult > 20)
1807 : {
1808 1 : if (verbose)
1809 0 : printf("mean to set");
1810 1 : result.push_back(mean);
1811 1 : if (verbose)
1812 0 : printf("set mean");
1813 1 : result.push_back(stddev);
1814 1 : result.push_back(nb_equal);
1815 1 : std::cout << " mean : " << mean<<std::endl;
1816 1 : std::cout << " std dev : "<<stddev<<std::endl;
1817 1 : std::cout << " nb_equal : "<<nb_equal<<std::endl;
1818 1 : std::cout << " ordered distances distance : "<<ordered_distances[0]<<std::endl;
1819 1 : std::cout << " ordered ordered_distances size : "<<ordered_distances.size()<<std::endl;
1820 1 : if (ordered_distances.size() > 0 && nb_data > 0)
1821 : {
1822 1 : result.push_back(ordered_distances[0]);
1823 1 : std::cout << " 0 : " << 0 << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1824 :
1825 1 : result.push_back(ordered_distances[nb_data - 1]);
1826 1 : std::cout << " nb_data - 1 : " << (nb_data - 1) << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1827 :
1828 1 : result.push_back(ordered_distances[nb_data / 2]);
1829 1 : std::cout << " nb_data / 2 : " << (nb_data / 2) << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1830 :
1831 : }
1832 1 : if (verbose)
1833 0 : printf("Loop over the quantile :");
1834 11 : for (int i = 0; i < 10; i++)
1835 : {
1836 10 : size_t id_decile = i * nb_data/10;
1837 10 : result.push_back(ordered_distances[id_decile]);
1838 10 : std::cout << " id_decile : " << id_decile << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1839 10 : if (verbose)
1840 10 : printf(" id_decile %lu , value : %lf \n", id_decile, result[6 + i]);
1841 : }
1842 : int decile = 100;
1843 4 : while (nb_data >= decile)
1844 : {
1845 3 : result.push_back(decile);
1846 3 : size_t id_decile = nb_data / decile;
1847 3 : result.push_back(ordered_distances[id_decile]);
1848 3 : std::cout << " id_decile : " << id_decile << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1849 3 : result.push_back(ordered_distances[nb_data - 1 - id_decile]);
1850 3 : std::cout << " nb_data - 1 - id_decile : " << (nb_data - 1 - id_decile) << " result[result.size() - 1] " << result[result.size() - 1] << std::endl;
1851 3 : decile *= 10;
1852 : }
1853 : }
1854 1 : 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 1 : if (verbose)
1864 0 : puts("Stats computed !");
1865 1 : }
1866 :
1867 1 : 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 1 : 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 1 : uint32_t sizeResult = 2048;
1879 :
1880 1 : std::cout<<" query stat : nb_data : "<<lp.ReadCacheCPU[0].nb_data<<std::endl;
1881 :
1882 1 : int min_limit_nb_data = limit_return - 2;
1883 1 : if (min_limit_nb_data > nb_data_in_file)
1884 0 : min_limit_nb_data = nb_data_in_file;
1885 1 : if (min_limit_nb_data > ids_data.size())
1886 0 : min_limit_nb_data = (int) ids_data.size();
1887 :
1888 1 : result.resize(min_limit_nb_data + 3);
1889 1 : result[0] = nb_data_in_file;
1890 1 : 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 1 : result[2] = (lp.descriptor_type == -1 ? lp.type_query : lp.descriptor_type);
1893 :
1894 1 : if (verbose)
1895 0 : printf(" min_limit_nb_data : %d, result : %ld \n", min_limit_nb_data, result.size());
1896 :
1897 49 : for (int i = 0; i < std::min<size_t>(min_limit_nb_data, ids_data.size()); i++)
1898 48 : result[i + 3] = ids_data[i];
1899 :
1900 1 : if (verbose)
1901 : {
1902 0 : puts("Copying result in result as string");
1903 0 : printf(" limit_return : %d\n", limit_return);
1904 : }
1905 104 : for (int i = 0; i < std::max(3, limit_return + 1); i++)
1906 : {
1907 102 : result_str += boost::lexical_cast<std::string>(result[i]);
1908 51 : result_str += ",";
1909 : }
1910 :
1911 1 : std::vector<double> other_result(sizeResult);
1912 1 : stats(distances, nb_data_in_file, other_result, sizeResult, verbose, datas_vec);
1913 1 : if (verbose)
1914 0 : printf(" sizeResult : %d\n", sizeResult);
1915 2049 : for (int i = 0; i < sizeResult; i++)
1916 : {
1917 4096 : result_str += boost::lexical_cast<std::string>(other_result[i]);
1918 2048 : if (i != sizeResult - 1) {
1919 2048 : result_str += ",";
1920 : }
1921 : }
1922 1 : if (verbose)
1923 1 : printf("End of stat computation !");
1924 1 : }
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 2 : 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 2 : return_centroid(1), return_list_photo(0)
2078 : {
2079 2 : query_desc.resize(1);
2080 2 : list_ids.resize(1);
2081 2 : }
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 32 : Query::~Query()
2094 : {
2095 10 : puts("query object destruction");
2096 10 : }
2097 :
2098 : //si pas fonctionnel on passe pas au test suivant dans test.py
2099 13 : void Query::reset_query()
2100 : {
2101 13 : std::cout<<"reset query"<<std::endl;
2102 13 : id = 0;
2103 13 : input = "";
2104 13 : query_char = '.';
2105 13 : query_desc.resize(0);
2106 13 : list_ids.resize(0);
2107 13 : limit = 0;
2108 13 : index_type = -1;
2109 13 : type = 0;
2110 13 : id = 0;
2111 13 : size = 0;
2112 13 : data_to_insert.resize(0);
2113 13 : type_list.resize(0);
2114 13 : index_type_list.resize(0);
2115 13 : list_size.resize(0);
2116 13 : crea_photo_desc=0;
2117 13 : return_centroid=1;
2118 13 : return_list_photo=0;
2119 13 : }
2120 :
2121 : //teste avec la requete m dans les tests
2122 9 : void Query::set_limit(char *str)
2123 : {
2124 9 : 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 9 : limit = LIMIT_RETURN;
2133 9 : if (limit > MAX_LIMIT_RETURN)
2134 0 : limit = MAX_LIMIT_RETURN;
2135 9 : if (limit == 0)
2136 0 : limit = LIMIT_RETURN;
2137 9 : }
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 26 : void Query::set_type(const char *str, int32_t server_type, LocalParam& lp)
2171 : {
2172 17 : 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 17 : type = server_type;
2181 17 : index_type = FindDescIndex(lp.ReadCacheCPU, (uint32_t)type);
2182 17 : }
2183 :
2184 : //teste dans les fonctions de kmeans ou on passe le nombre de cluster
2185 1 : void Query::set_nb_clusters(int nb)
2186 : {
2187 1 : nb_clusters=nb;
2188 1 : }
2189 :
2190 :
2191 : //a verififer
2192 1 : void Query::set_limit(uint32_t lim)
2193 : {
2194 1 : limit = lim;
2195 1 : }
2196 :
2197 :
2198 : //avec le query_char p, dans les tests
2199 4 : int Query::set_query_multiarg(uint32_t server_type, LocalParam & lp) {
2200 :
2201 4 : if(input.find(',') != std::string::npos) {
2202 :
2203 4 : set_query_generic(server_type, lp);
2204 :
2205 :
2206 8 : std::vector<std::string> ids_str;
2207 :
2208 4 : char * tmp_str = &(input.at(0));
2209 4 : char * tmp_str2 = NULL;
2210 :
2211 :
2212 4 : Query::set_type(tmp_str2, server_type, lp);
2213 4 : if (index_type == -1)
2214 0 : return 2;
2215 4 : size = lp.ReadCacheCPU[index_type].size;
2216 4 : tmp_str2 = strchr(tmp_str, 'L');
2217 4 : Query::set_limit(tmp_str2);
2218 :
2219 4 : split(ids_str, input, is_any_of(","));
2220 4 : list_ids.resize(ids_str.size());
2221 4 : list_ids[0] = (uint32_t)atoi(&(ids_str[0].at(1)));
2222 :
2223 20 : for (int i = 1; i < ids_str.size(); ++i)
2224 16 : 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 4 : 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 8 : int Query::set_query_kmean(uint32_t server_type, LocalParam & lp, int verbose)
2281 : {
2282 : /////////////////////////////// Fonction appelé pour lancer les kmeans ///////////////////////////
2283 16 : std::vector<std::string> clusters_as_csv, lines, clusters_csv;
2284 16 : std::string input_less = "";
2285 :
2286 8 : if (input.length() > 2)
2287 8 : input_less = input.substr(1, input.length() - 2);
2288 8 : split(lines, input_less, is_any_of("|"));
2289 8 : verbose_query = -1;
2290 :
2291 8 : std::cout<<" loop to create desc dyn "<<lines.size()<<std::endl;
2292 24 : for (int l = 0; l < lines.size(); l++)
2293 : {
2294 16 : std::cout<<" start loop : " << l << " content : " << lines[l] << std::endl;
2295 16 : int taille=lines[l].size();
2296 16 : if (lines[l].substr(0, 1) == std::string("S"))
2297 : {
2298 6 : std::cout<<" setting param with prefix S " << std::endl;
2299 12 : std::vector<std::string> option;
2300 6 : split(option, lines[l], is_any_of(":"));
2301 :
2302 6 : special_kmean = option[1];
2303 6 : iter_max = atoi(option[2].c_str());
2304 6 : crea_photo_desc = atoi(option[3].c_str());
2305 6 : return_centroid = atoi(option[4].c_str());
2306 6 : return_list_photo = atoi(option[5].c_str());
2307 6 : 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 6 : std::cout << " forcing divergence euclidean " << std::endl;
2315 6 : std::cout << " et voila " << std::endl;
2316 6 : divergence = 'E';
2317 : }
2318 6 : if (option.size() > 7)
2319 : {
2320 0 : nb_iteration = atoi(option[7].c_str());
2321 : }
2322 : }
2323 10 : 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 10 : 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 10 : 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 10 : 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 10 : else if (lines[l].substr(0,1) == std::string("C"))
2362 : {
2363 1 : std::cout<<"on met a jour le nb de clusters demandés"<<std::endl;
2364 2 : std::vector<std::string> option;
2365 1 : split(option, lines[l], is_any_of(":"));
2366 1 : nb_clusters=atoi(lines[l].substr(2).c_str());
2367 1 : 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 9 : std::cout << " split cluster_csv " << clusters_csv.size() << std::endl;
2379 :
2380 9 : split(clusters_csv, lines[l], is_any_of(";"));
2381 :
2382 9 : Query::set_type(NULL, server_type, lp);
2383 9 : 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 9 : clusters.resize(0);
2389 9 : clusters.resize(clusters_csv.size(), std::vector<VDInt>(0));
2390 :
2391 9 : std::cout << " after resize cluster " << clusters.size() << std::endl;
2392 :
2393 24 : for (int i = 0; i < clusters_csv.size(); i++)
2394 : {
2395 15 : if (clusters_csv[i] == "")
2396 : {
2397 0 : clusters.pop_back();
2398 0 : continue;
2399 : }
2400 :
2401 30 : std::vector<std::string> one_desc;
2402 15 : split(one_desc, clusters_csv[i], is_any_of(","));
2403 :
2404 72 : 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 57 : if (std::is_same<VDInt, uint32_t>::value) // si VDInt est un uint32_t
2409 : {
2410 57 : VDInt val = (data)atoi(&(one_desc[k].at(0)));
2411 57 : 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 16 : std::cout<<"crea desc dyn "<<crea_photo_desc<<std::endl;
2422 : }
2423 :
2424 8 : char * tmp_str = &(input.at(0));
2425 8 : char *tmp_str2 = strchr(tmp_str, 'T');
2426 8 : 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 8 : clusters_as_line.resize(0);
2430 8 : std::cout<<"et clusters.size "<<clusters.size()<<std::endl;
2431 21 : for (int i = 0; i < clusters.size(); i++)
2432 : {
2433 62 : for (int k = 0; k < clusters[i].size(); k++)
2434 : {
2435 49 : clusters_as_line.push_back(clusters[i][k]);
2436 : }
2437 : }
2438 :
2439 16 : 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 8 : void Query::get_data_kmean(int dimension)
2499 : {
2500 8 : uint32_t nb_clusters = (int) clusters_as_line.size() / dimension;
2501 :
2502 8 : clusters.resize(nb_clusters);
2503 21 : for (int i = 0 ; i < nb_clusters; i++)
2504 : {
2505 13 : clusters[i].resize(dimension);
2506 65 : for (int k = 0; k < dimension; k ++)
2507 : {
2508 52 : clusters[i][k] = clusters_as_line[i * dimension + k];
2509 : }
2510 : }
2511 8 : }
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 8 : 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 1 : const std::vector<uint32_t> &Query::get_query_index_type_list() const
2554 : {
2555 1 : 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 1 : void Query::set_cluster_init(const int nb_clusters, const std::vector<data> & data_vec, const int dim){
2761 1 : int index;
2762 1 : std::cout<<"la liste des centroids est incomplete, on va la completer"<<std::endl;
2763 2 : for(int i=clusters_as_line.size(); i<nb_clusters; i++){
2764 1 : index = rand()%(data_vec.size()/dim);
2765 1 : std::cout<<index<<",";
2766 5 : for(int j=0; j<dim; j++){
2767 4 : clusters_as_line.push_back(data_vec[index+j]);
2768 : }
2769 : }
2770 1 : std::cout<<std::endl;
2771 1 : }
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 5 : int Query::set_query_generic(uint32_t server_type, LocalParam & lp)
2864 : {
2865 5 : char * tmp_str = &(input.at(0));
2866 5 : char * tmp_str2;
2867 5 : id = atoi(tmp_str + 1);
2868 5 : tmp_str2 = strchr(tmp_str, 'T');
2869 5 : Query::set_type(tmp_str2, server_type, lp);
2870 5 : if (index_type == -1)
2871 : return 2;
2872 5 : size = lp.ReadCacheCPU[index_type].size;
2873 5 : tmp_str2 = strchr(tmp_str, 'L');
2874 5 : Query::set_limit(tmp_str2);
2875 5 : 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 14 : 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 28 : 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 28 : std::string query_string(1, query_char);
2900 :
2901 14 : std::cout << " query_char : " << query_char << " input[0] " << input[0] << ", query_string : " << query_string << std::endl;
2902 :
2903 14 : query_string = input[0];
2904 :
2905 14 : std::cout << " query_string : " << query_string << std::endl;
2906 :
2907 14 : std::size_t found = querys.find(query_string);
2908 14 : if (found == std::string::npos)
2909 : {
2910 0 : puts("first char not in list");
2911 : return -3;
2912 : }
2913 14 : limit = LIMIT_RETURN;
2914 : // VR 17-8-16 : c'est quoi ce E ?
2915 14 : if (query_char == 'C' || query_char == 'E')
2916 : ;
2917 : // return Query::set_query_commit(server_type);
2918 13 : else if (query_char == 'l')
2919 0 : return Query::set_query_load(server_type, lp);
2920 13 : else if (query_char == 'a')
2921 0 : return Query::set_query_advanced(server_type, lp);
2922 13 : else if (query_char == 'd' || query_char == 'D')
2923 0 : return Query::set_query_desc(server_type, lp);
2924 13 : else if (query_char == 'i')
2925 0 : return Query::set_query_multi_insert(lp);
2926 13 : else if (query_char == 'e')
2927 0 : return Query::set_query_delete(server_type, lp);
2928 13 : else if (query_char == 'm')
2929 0 : return Query::set_query_list_ids(server_type,lp);
2930 13 : else if (query_char == 'k')
2931 8 : return Query::set_query_kmean(server_type, lp, verbose);
2932 5 : else if (query_char == 't')
2933 0 : return Query::set_query_prediction(server_type, lp, verbose);
2934 5 : else if (query_char == 'g')
2935 0 : return Query::set_query_coordinate(server_type, lp, verbose);
2936 5 : else if (query_char == 'p' || query_char == 'P')
2937 4 : return Query::set_query_multiarg(server_type, lp);
2938 1 : else if (query_char == 'u' || query_char == 'U')
2939 0 : return Query::set_query_unload(lp, verbose);
2940 : else
2941 1 : return Query::set_query_generic(server_type, lp);
2942 :
2943 : return 0;
2944 : }
2945 :
2946 :
2947 :
2948 :
2949 : //Lecture des requetes client-server
2950 14 : 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 14 : char * buff = new char[512];
2975 14 : bzero(&buff[0], 512);
2976 14 : size_t r = read(cs,&buff[0],512);
2977 14 : buff[r] = '\0';
2978 : //*/
2979 :
2980 14 : buff[r] = '\0';
2981 :
2982 14 : int desc_dyn=0;
2983 :
2984 14 : size_t tmp = 0;
2985 14 : if (r > 0)
2986 : {
2987 14 : tmp += r;
2988 14 : query_char = buff[0];
2989 14 : input += std::string(&buff[0]);
2990 14 : int count_same_size = 0;
2991 14 : int last_size = 0;
2992 14 : 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 12 : 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 24 : size_t it = input.find(std::string("T"));
3019 : // std::cout << " input : " << input << std::endl;
3020 12 : std::cout << " it : " << it << std::endl;
3021 12 : 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 12 : 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 2 : else if(query_char=='F' || query_char=='v')
3039 : return 0;
3040 14 : if (verbose)
3041 : {
3042 0 : std::cout << " input : " << input << std::endl;
3043 : }
3044 :
3045 14 : delete[] buff;
3046 14 : if(desc_dyn<-1)
3047 0 : return set_query(desc_dyn, lp, verbose);
3048 14 : 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 8 : void Query::set_query_id(uint32_t newid)
3075 : {
3076 8 : id = newid;
3077 0 : }
3078 :
3079 :
3080 15 : char Query::get_query_char()
3081 : {
3082 15 : return query_char;
3083 : }
3084 :
3085 0 : std::vector<data> & Query::get_query_desc()
3086 : {
3087 0 : return query_desc;
3088 : }
3089 :
3090 4 : std::vector<uint32_t> &Query::get_query_list_ids()
3091 : {
3092 4 : return list_ids;
3093 : }
3094 :
3095 :
3096 20 : size_t Query::get_query_limit()
3097 : {
3098 20 : 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 16 : int Query::get_query_crea_photo_desc()
3115 : {
3116 16 : return crea_photo_desc;
3117 : }
3118 :
3119 :
3120 8 : int Query::get_query_return_centroid(){
3121 8 : return return_centroid;
3122 : }
3123 :
3124 :
3125 8 : int Query::get_query_return_list_photo(){
3126 8 : return return_list_photo;
3127 : }
3128 :
3129 :
3130 26 : int Query::get_query_nb_clusters()
3131 : {
3132 9 : return nb_clusters;
3133 : }
3134 :
3135 :
3136 21 : int Query::get_query_index_type()
3137 : {
3138 21 : 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 13 : int32_t Query::get_query_type()
3149 : {
3150 0 : return type;
3151 : }
3152 :
3153 10 : uint32_t Query::get_query_id()
3154 : {
3155 5 : return id;
3156 : }
3157 :
3158 14 : uint32_t Query::get_query_size()
3159 : {
3160 14 : return (uint32_t) size;
3161 : }
3162 :
3163 0 : std::string Query::get_query_input()
3164 : {
3165 0 : return input;
3166 : }
3167 :
3168 10 : const std::vector<VDInt> & Query::getClustersForGPU() const
3169 : {
3170 10 : return clusters_as_line;
3171 : }
3172 :
3173 8 : const std::vector<std::vector<VDInt> > & Query::getClustersForOutput() const
3174 : {
3175 8 : 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 8 : const std::vector<std::vector<uint32_t>> & Query::getListPhotoIdsPerCluster() const
3184 : {
3185 8 : return list_photo_ids_per_cluster;
3186 : }
3187 :
3188 1 : int Query::exit()
3189 : {
3190 0 : int r = input.compare("EXIT MERCI PASSE");
3191 1 : return r;
3192 : }
3193 :
3194 8 : int Query::get_kmax(){
3195 8 : 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 3 : void Query::cluster_to_csv(LocalParam lp,int index_type,
3209 : const std::vector<types_datas_t> & read_cache_cpu){
3210 3 : std::string csv_filename;
3211 3 : int type = read_cache_cpu[index_type].type;
3212 3 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3213 3 : 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 3 : std::cout<<"filename csv : "<<csv_filename<<std::endl;
3215 : // std::ofstream myfile;
3216 : // myfile.open (csv_filename);
3217 6 : std::ofstream myfile(csv_filename, std::ios::binary);
3218 3 : myfile << "cluster;photo_id\n";
3219 : int photo_idx;
3220 : size_t address_desc;
3221 :
3222 8 : for(int i=0; i<list_photo_ids_per_cluster.size();i++){
3223 33005 : for(int j=0; j<list_photo_ids_per_cluster[i].size();j++){
3224 33000 : photo_idx = FindPidsIndex(read_cache_cpu[0].ids_vec,list_photo_ids_per_cluster[i][j]);
3225 33000 : address_desc = (size_t) read_cache_cpu[0].size * (size_t) photo_idx;
3226 33000 : 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 33000 : myfile <<"\n";
3243 : }
3244 : }
3245 3 : std::cout<<"lp dimension "<<read_cache_cpu[index_type].size<<std::endl;
3246 3 : myfile.close();
3247 3 : }
3248 :
3249 :
3250 3 : void Query::data_to_csv(LocalParam lp,int index_type,
3251 : const std::vector<types_datas_t> & read_cache_cpu){
3252 3 : std::string csv_filename;
3253 3 : int type = read_cache_cpu[index_type].type;
3254 3 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3255 3 : csv_filename = read_cache_cpu[index_type].dir + "data_" + std::to_string(type)+".csv";
3256 3 : std::cout<<"filename data desc : "<<csv_filename<<std::endl;
3257 : // std::ofstream myfile;
3258 : // myfile.open (csv_filename);
3259 6 : std::ofstream myfile(csv_filename, std::ios::binary);
3260 3 : myfile << "photo_id;descriptors\n";
3261 : int photo_idx;
3262 : size_t address_desc;
3263 :
3264 8 : for(int i=0; i<list_photo_ids_per_cluster.size();i++){
3265 33005 : for(int j=0; j<list_photo_ids_per_cluster[i].size();j++){
3266 33000 : photo_idx = FindPidsIndex(read_cache_cpu[0].ids_vec,list_photo_ids_per_cluster[i][j]);
3267 33000 : address_desc = (size_t) read_cache_cpu[0].size * (size_t) photo_idx;
3268 33000 : myfile <<list_photo_ids_per_cluster[i][j]<<";";
3269 165000 : for( int d=0; d<read_cache_cpu[0].size; d++){
3270 132000 : myfile << std::to_string(read_cache_cpu[0].datas_vec[address_desc+ d]);
3271 132000 : if(d<read_cache_cpu[0].size-1)
3272 99000 : myfile <<",";
3273 : }
3274 33000 : myfile <<"\n";
3275 : }
3276 : }
3277 3 : myfile.close();
3278 3 : }
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 3 : void Query::grid_to_csv(LocalParam lp,int index_type){
3306 3 : std::string csv_filename;
3307 3 : int type = lp.ReadCacheCPU[index_type].type;
3308 3 : std::cout<<"type and index : "<<type<<","<<index_type<<std::endl;
3309 3 : std::cout<<"size : "<<clusters_as_line.size()<<","<<lp.ReadCacheCPU[index_type].size<<std::endl;
3310 3 : int nbclusters = clusters_as_line.size()/lp.ReadCacheCPU[index_type].size;
3311 3 : int dimension = lp.ReadCacheCPU[index_type].size;
3312 3 : csv_filename = lp.ReadCacheCPU[index_type].dir + "grid_" + std::to_string(type) +"_"+std::to_string(nbclusters)+"_"+divergence+".csv";
3313 3 : std::cout<<"filename csv : "<<csv_filename<<std::endl;
3314 : // std::ofstream myfile;
3315 : // myfile.open (csv_filename);
3316 6 : std::ofstream myfile(csv_filename, std::ios::binary);
3317 3 : myfile << "cluster;photo_id\n";
3318 :
3319 8 : for(int i=0; i<nbclusters;i++){
3320 5 : myfile <<i<<";";
3321 25 : for(int j=0; j<dimension;j++){
3322 20 : myfile <<clusters_as_line[i*dimension+j]<<",";
3323 : }
3324 5 : myfile <<"\n";
3325 : }
3326 3 : std::cout<<"lp dimension "<<lp.ReadCacheCPU[index_type].size<<std::endl;
3327 3 : myfile.close();
3328 3 : }
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 8 : int Query::executeQueryOneStepKmean(LocalParam & lp, int methodChoice)
3410 : {
3411 8 : 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 8 : if (lp.verbose)
3417 0 : std::cout << " In executeQueryOneStepKmean with special_kmean : " << special_kmean << " and index_type : " << index_type << std::endl;
3418 :
3419 8 : int verbose = verbose_query >= 0 ? verbose_query : lp.verbose;
3420 :
3421 8 : if (index_type == -1)
3422 0 : index_type = 0;
3423 8 : int n = lp.ReadCacheCPU[index_type].nb_data;
3424 8 : distortion = 0;
3425 :
3426 8 : std::cout<<" input : "<<input<<std::endl;
3427 :
3428 8 : 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 8 : nb_iteration = 20; //valeur par défaut
3434 8 : prediction = false;
3435 : }
3436 :
3437 :
3438 8 : std::cout<<"execute query one step kmean, special_kmean : "<<special_kmean<<std::endl;
3439 :
3440 8 : if (special_kmean == "cpu" || special_kmean == "fromcpu" || special_kmean == "pds" || special_kmean == "pdsgpu")
3441 : {
3442 3 : int methodChoiceUsed = -1;
3443 3 : if (special_kmean == "pds")
3444 : methodChoiceUsed = 0;
3445 3 : else if (special_kmean == "pdsgpu")
3446 : methodChoiceUsed = 1;
3447 3 : else if (special_kmean == "fromcpu")
3448 1 : methodChoiceUsed = 2;
3449 :
3450 3 : if (verbose)
3451 0 : std::cout << " In executeQueryOneStepKmean with special_kmean cpu : " << special_kmean << std::endl;
3452 :
3453 :
3454 3 : 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 3 : std::cout<<"test read csv"<<std::endl;
3466 :
3467 63 : for(int k=0; k<nb_iteration; k++){
3468 60 : onCPUKmeanOneStep(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], list_photo_ids_per_cluster, divergence, verbose, methodChoiceUsed);
3469 60 : std::cout<<clusters_as_line[0]<<std::endl;
3470 60 : std::cout<<"fin iteration kmeans cpu :"<<k<<std::endl;
3471 : }
3472 3 : cluster_to_csv(lp, index_type, lp.ReadCacheCPU);
3473 3 : data_to_csv(lp, index_type, lp.ReadCacheCPU);
3474 3 : grid_to_csv(lp, index_type);
3475 : }
3476 8 : for(int i =0; i<list_photo_ids_per_cluster.size(); i++){
3477 5 : std::cout<<"cluster : "<<i<<std::endl;
3478 505 : for(int j=0; j<100 && j<list_photo_ids_per_cluster[i].size();j++){
3479 500 : std::cout<<list_photo_ids_per_cluster[i][j]<<",";
3480 : }
3481 5 : std::cout<<std::endl;
3482 5 : std::cout<<"nb data : "<<list_photo_ids_per_cluster[i].size()<<std::endl;
3483 :
3484 : }
3485 :
3486 : }
3487 5 : else if (special_kmean == "splitandstick")
3488 : {
3489 1 : if (verbose)
3490 0 : std::cout << " In executeQueryOneStepKmean with special_kmean splitandstick : " << special_kmean << std::endl;
3491 1 : 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 4 : 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 4 : 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 4 : 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 4 : onCPUKmeanOneStep(clusters_as_line, size_and_inertia, lp.ReadCacheCPU[index_type], list_photo_ids_per_cluster, divergence, verbose, methodChoice);
3628 : #endif
3629 : }
3630 :
3631 8 : 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 8 : std::cout<<"Computing distortion"<<std::endl;
3643 21 : for (int i = 0; i < size_and_inertia.size(); i++) {
3644 13 : distortion += (VDInt) size_and_inertia[i].second;
3645 : }
3646 8 : 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 8 : 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 8 : get_data_kmean(lp.ReadCacheCPU[index_type].size);
3658 : }
3659 8 : 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 14 : int executeQuery(Query & cur_query, LocalParam & lp, GlobalParam & gp)
3685 : {
3686 : ///////////// Execution de la query apres lecture du message ///////////////////
3687 14 : std::cout<<"debut de execute query"<<std::endl;
3688 :
3689 14 : std::vector<types_datas_t> & ReadCacheCPU = lp.ReadCacheCPU;
3690 :
3691 14 : lp.dimension = cur_query.get_query_size();
3692 14 : lp.counter++;
3693 14 : char query_char = cur_query.get_query_char();
3694 14 : std::cout<<"\nCounter request : "<< lp.counter<<std::endl;
3695 14 : if (query_char != 'd' && query_char != 'D' && query_char != 'm')
3696 : {
3697 14 : if (cur_query.get_query_limit() > ReadCacheCPU[cur_query.get_query_index_type()].nb_data)
3698 1 : cur_query.set_limit(ReadCacheCPU[cur_query.get_query_index_type()].nb_data);
3699 : }
3700 14 : std::cout<<" query_type : "<<query_char<<std::endl;
3701 14 : if (query_char == 'E')
3702 : {
3703 1 : lp.retval_set_query = cur_query.exit();
3704 1 : if (lp.retval_set_query == 0)
3705 : {
3706 1 : send(lp.cs, "exitingeof", 10, 0);
3707 1 : close(lp.cs);
3708 1 : 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 13 : 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 13 : 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 13 : 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 13 : 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 13 : 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 13 : if (query_char == 'k')
3800 : {
3801 8 : int merge=0;
3802 8 : 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 8 : if(cur_query.get_query_types().size()!=0)
3808 0 : std::cout<<"on est dans le cas des kmeans multiples"<<std::endl;
3809 8 : if(cur_query.get_query_nb_clusters()==0){
3810 1 : if(cur_query.getClustersForGPU().size()==0){
3811 0 : cur_query.set_nb_clusters(32);
3812 : }else{
3813 1 : int nb;
3814 1 : if(lp.dimension)
3815 0 : nb=cur_query.getClustersForGPU().size()/lp.dimension;
3816 : else
3817 1 : nb=cur_query.getClustersForGPU().size()/lp.ReadCacheCPU[lp.index_type_query].size;
3818 1 : cur_query.set_nb_clusters(nb);
3819 : }
3820 : }
3821 8 : 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 8 : int dimension=ReadCacheCPU[lp.index_type_query].size;
3836 8 : if (cur_query.get_query_nb_clusters()*dimension> cur_query.getClustersForGPU().size() && cur_query.get_query_nb_clusters()!=0)
3837 : {
3838 1 : 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 8 : if (cur_query.get_kmax() != 0){
3844 0 : merge = cur_query.executeElbowKmean(lp);
3845 : } else {
3846 8 : merge=cur_query.executeQueryOneStepKmean(lp);
3847 : }
3848 :
3849 :
3850 8 : if(merge==-1){
3851 0 : close(lp.cs);
3852 0 : cur_query.reset_query();
3853 0 : return 101;
3854 : }
3855 :
3856 8 : 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 8 : int id_merge=getiddesc(merge, lp.list_dyn_desc_type, lp.list_dyn_desc_type.size());
3875 8 : if (lp.verbose)
3876 0 : std::cout << " After executeQueryOneStepKmean " << std::endl;
3877 : // cur_query.get_data_kmean(9216);
3878 16 : std::string result("");
3879 16 : const std::vector<std::vector<uint32_t>> list_photo_ids_per_cluster=cur_query.getListPhotoIdsPerCluster();
3880 8 : 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 8 : std::cout<<"la liste des photos n'est pas vide"<<std::endl;
3963 8 : 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 8 : 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 8 : std::cout << " after init pds dynamic " << std::endl;
3971 8 : if(cur_query.get_query_return_centroid())
3972 19 : for (int i = 0; i < clusters.size(); i++)
3973 : {
3974 12 : if (i > 0)
3975 5 : result += ";";
3976 60 : for (int j = 0; j < clusters[i].size(); j++)
3977 : {
3978 48 : if (j > 0)
3979 36 : result += ",";
3980 96 : result += boost::lexical_cast<std::string>(clusters[i][j]);
3981 : }
3982 : }
3983 : else
3984 1 : std::cout<<"on ne retourne pas la liste des nouveaux centroids"<<std::endl;
3985 8 : result += "|";
3986 8 : std::cout << " About to get inertia and size ! " << std::endl;
3987 : //renvoie la taille et l'inertie de chaque cluster
3988 21 : const std::vector<std::pair<int, VDInt> > & size_and_inertia = cur_query.getSizeAndInertieClustersForOutput();
3989 21 : for (int i = 0; i < size_and_inertia.size(); i++)
3990 : {
3991 13 : if (i > 0)
3992 5 : result += ";";
3993 26 : result += boost::lexical_cast<std::string>(size_and_inertia[i].first);
3994 13 : result += ":";
3995 26 : result += boost::lexical_cast<std::string>(size_and_inertia[i].second);
3996 : }
3997 :
3998 8 : 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 8 : 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 21 : for( int i=0; i< clusters.size(); i++){
4009 : //if (list_photo_ids_per_clusters[i].size() == 0)
4010 :
4011 13 : if (i>0)
4012 5 : result += ",";
4013 13 : if(size_and_inertia[i].first ==0)
4014 13 : result += '0';
4015 : else
4016 22 : result += boost::lexical_cast<std::string>(list_photo_ids_per_cluster[i][0]);
4017 :
4018 : }
4019 8 : 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 8 : result += "|";
4025 8 : 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 8 : 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 8 : 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 8 : result+="|";
4048 : //Renvoie la liste des photos par clusters, pour la sauvegarde dans des portfolios
4049 8 : 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 21 : for(int i=0; i<list_photo_ids_per_cluster.size(); i++){
4063 13 : if(i>0)
4064 5 : result+=";";
4065 235 : for(int j=0; j<std::min(20,(int)list_photo_ids_per_cluster[i].size()); j++){
4066 220 : if(j>0)
4067 209 : result+=",";
4068 440 : result+=boost::lexical_cast<std::string>(list_photo_ids_per_cluster[i][j]);
4069 :
4070 : }
4071 : }
4072 8 : std::cout<<"on renvoie la mosaique de photos"<<std::endl;
4073 : }
4074 8 : result+="|p";
4075 :
4076 :
4077 : }
4078 :
4079 : // VR 7-12-16: pourquoi y avait t-il ce result.size()-1
4080 8 : if (result.size() > 1){
4081 8 : result+="eof";
4082 8 : std::cout<<"result"<<std::endl<<result<<std::endl<<std::endl<<std::endl;
4083 8 : send(lp.cs,&(result.at(0)), result.size(), 0);
4084 : }else{
4085 0 : send(lp.cs, "Empty Resulteof", 15, 0);
4086 : }
4087 8 : close(lp.cs);
4088 8 : cur_query.reset_query();
4089 8 : return 101;
4090 : }
4091 : //F pour retourner la liste de fotos
4092 : //ajouter des tests si le photo desc n'est pas chargé
4093 5 : 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 5 : 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 5 : lp.type_query = (int) cur_query.get_query_type();
4208 5 : 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 5 : 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 5 : std::cout<<"size Read cache before : "<<ReadCacheCPU[lp.index_type_query].datas_vec.size()<<std::endl;
4218 5 : 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 5 : ReadCacheCPU[lp.index_type_query].resizeDatas(new_size);
4220 5 : std::cout<<"size Read cache after : "<<new_size<<std::endl;
4221 5 : std::vector<uint32_t>::iterator query_id_it;
4222 : //recherche de la requete dans les requetes dans le cache
4223 5 : printf("Searching %d in : %lu\n", cur_query.get_query_id(), ReadCacheCPU[lp.index_type_query].ids_vec.size());
4224 5 : 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 5 : if (query_id_it == ReadCacheCPU[lp.index_type_query].ids_vec.end())
4230 4 : lp.query_index = -1;
4231 : else
4232 1 : 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 5 : lp.idc_vec = ReadCacheCPU[lp.index_type_query].ids_vec;
4236 5 : lp.current_limit = (int) cur_query.get_query_limit();
4237 5 : if (lp.verbose)
4238 0 : printf("\ncurrent_limit = %d, allocatin result \n", lp.current_limit);
4239 5 : lp.result_vec.resize(ReadCacheCPU[lp.index_type_query].nb_data);
4240 5 : 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 5 : if (query_char == 'q' || query_char == 'c' || query_char == 's' || query_char == 'S' )
4245 : {
4246 1 : 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 1 : query_char = cur_query.get_query_char();
4277 : }
4278 :
4279 : // VR 3-11-16 : proposition : cur_query.is_random_type()
4280 5 : 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 5 : 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 5 : 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 5 : 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 5 : 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 5 : 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 5 : else if (query_char == 'u' || query_char == 'U')
4480 : {
4481 0 : return query_unload(cur_query, lp);
4482 : }
4483 5 : 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 4 : if (lp.verbose)
4489 0 : puts("We are doing a partial distance search query !\n");
4490 :
4491 4 : types_datas_t & ReadCache = ReadCacheCPU[lp.index_type_query];
4492 4 : unsigned d = lp.dimension;
4493 4 : 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 8 : std::vector<uint32_t> liste_ids = cur_query.get_query_list_ids();
4498 :
4499 : // le premier argument
4500 4 : int commandnum = liste_ids[0];
4501 4 : unsigned m = 0;
4502 :
4503 4 : std::cout << " commandnum : is this negative ? " << commandnum << std::endl;
4504 :
4505 4 : bool duplication = (commandnum < 0);
4506 4 : if (duplication)
4507 2 : m = -liste_ids[0];
4508 : else
4509 2 : 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 4 : uint32_t nbc = liste_ids.size() - (m + 1);
4514 8 : std::vector<uint32_t> candidats_grille(nbc);
4515 :
4516 12 : for (int i = 0; i != nbc; ++i)
4517 8 : candidats_grille[i] = liste_ids[m + 1 + i];//ReadCacheCPU[lp.index_type_query].ids_vec[m+1+i];
4518 :
4519 4 : if (nbc > n)
4520 0 : nbc = 10;
4521 :
4522 4 : if (m + nbc > n)
4523 0 : m = n - nbc;
4524 :
4525 :
4526 : // je suuprime le cas m == 0
4527 :
4528 4 : if (m >= 1)
4529 : {
4530 4 : 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 2 : printf("CPU multi P\n");
4674 2 : std::cout << liste_ids.size() << std::endl;
4675 : //cur_query.set_query_moyenne(cur_query.get_query_type());
4676 4 : std::vector<uint32_t> res(m);
4677 4 : std::vector<VDInt> dist(m);
4678 2 : lp.current_limit = m;
4679 6 : for (int i = 0; i != m; ++i)
4680 : {
4681 : //printf("%u\n", u);
4682 4 : uint32_t u = liste_ids[i+1];
4683 4 : query_pds(i, u, res, dist, ReadCacheCPU, lp, cur_query, candidats_grille);
4684 : }
4685 :
4686 2 : lp.result_vec.resize(res.size());
4687 2 : lp.distances_vec.resize(dist.size());
4688 2 : lp.result_vec = res;
4689 2 : lp.distances_vec = dist;
4690 :
4691 : #endif // ONLY_CPU
4692 : }
4693 : else
4694 : {
4695 2 : printf("CPU multi p\n");
4696 2 : std::cout << liste_ids.size() << std::endl;
4697 : //cur_query.set_query_moyenne(cur_query.get_query_type());
4698 4 : std::vector<uint32_t> res(m);
4699 4 : std::vector<VDInt> dist(m);
4700 2 : lp.current_limit = m;
4701 6 : for (int i = 0; i != m; ++i)
4702 : {
4703 4 : uint32_t u = liste_ids[i+1];
4704 4 : query_pds(i, u, res, dist,ReadCacheCPU, lp, cur_query, candidats_grille);
4705 : }
4706 2 : lp.result_vec.resize(res.size());
4707 2 : lp.distances_vec.resize(dist.size());
4708 2 : lp.result_vec = res;
4709 2 : lp.distances_vec = dist;
4710 : }
4711 : }
4712 : else
4713 4 : std::cout << "p received an ill-formed list\n" << std::endl;
4714 :
4715 : }
4716 1 : 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 1 : if (lp.verbose)
4720 0 : puts("We are doing a classical query !\n");
4721 2 : std::vector<data> desc_to_query_vec(lp.dimension);
4722 1 : if (query_char == 'a')
4723 : {
4724 0 : desc_to_query_vec = cur_query.get_query_desc();
4725 : }
4726 1 : 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 2 : std::vector<uint32_t> index_type_list = cur_query.get_query_index_type_list();
4738 1 : if (index_type_list.size() == 0)
4739 1 : index_type_list.push_back(cur_query.get_query_index_type());
4740 :
4741 2 : std::vector<uint32_t> result_vec;
4742 1 : std::vector<VDInt> distances_vec;
4743 : // lp.query_index
4744 : // cur_query.get_query_index_type()
4745 2 : for (int k = 0; k < index_type_list.size(); k++)
4746 : {
4747 1 : lp.index_type_query = index_type_list[k];
4748 : // lp.query_index = lp.index_type_query;
4749 1 : 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 1 : lp.idc_vec = ReadCacheCPU[lp.index_type_query].ids_vec;
4752 1 : lp.current_limit = (int) cur_query.get_query_limit();
4753 :
4754 : // ici on est dans le petrain !
4755 1 : 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 1 : if (lp.verbose)
4762 0 : printf("\ncurrent_limit = %d, allocatin result \n", lp.current_limit);
4763 1 : 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 1 : {
4778 1 : if (lp.verbose)
4779 0 : puts("CPU search mode\n");
4780 1 : NNeighbors(lp.result_vec, lp.query_index, (int) ReadCacheCPU[lp.index_type_query].nb_data, ReadCacheCPU[lp.index_type_query].size,
4781 1 : ReadCacheCPU[lp.index_type_query].datas_vec, lp.idc_vec, lp.current_limit, lp.distances_vec, desc_to_query_vec, 'E', 0);
4782 : }
4783 51 : for (int l = 0; l < lp.result_vec.size(); l++)
4784 50 : result_vec.push_back(lp.result_vec[l]);
4785 11001 : for (int l = 0; l < lp.distances_vec.size(); l++)
4786 11000 : distances_vec.push_back(lp.distances_vec[l]);
4787 :
4788 : }
4789 1 : 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 5 : if (lp.verbose)
4805 0 : printf("result size : %ld\n", lp.result_vec.size());
4806 5 : printf("result size : %ld\n", lp.result_vec.size());
4807 19 : std::string result_str = "";
4808 5 : 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 5 : if (query_char == 's' || query_char == 'S')
4813 : {
4814 1 : 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 1 : 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 4 : 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 4 : 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 4 : 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 4 : std::cout<<" current limit "<<lp.current_limit<<std::endl;
4877 4 : 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 4 : if (lp.current_limit)
4883 : {
4884 12 : for (int i = 0; i < std::min<size_t>(lp.current_limit, lp.result_vec.size()); i++)
4885 : {
4886 16 : result_str += boost::lexical_cast<std::string>(lp.result_vec[i]);
4887 8 : if (query_char != 'd' && query_char != 'D' && i < lp.distances_vec.size())
4888 : {
4889 8 : result_str += ":";
4890 16 : result_str += boost::lexical_cast<std::string>(lp.distances_vec[i]);
4891 : }
4892 8 : if (i != lp.current_limit - 1)
4893 8 : 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 5 : if (lp.verbose)
4904 0 : puts("About to send result !");
4905 5 : if (result_str.length() > 0){
4906 5 : std::cout<<"result query : "<<result_str<<std::endl;
4907 5 : result_str+="eof";
4908 5 : 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 5 : return 0;
4913 : }
|