LCOV - code coverage report
Current view: top level - imp - query_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 912 2139 42.6 %
Date: 2025-04-20 06:26:44 Functions: 25 95 26.3 %

          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             : }

Generated by: LCOV version 1.14