StaticRelations.cc

Go to the documentation of this file.
00001 
00006 #include "StaticRelations.H"
00007 
00008 CRelation* StaticRelations::GLS[StaticFactorbaseSettings::MaxSize] = {NULL};
00009 int StaticRelations::Filling_GLS = 0;
00010 
00011 filebuf StaticRelations::FileBuffer;
00012 ostream StaticRelations::StaticRelations_to_file(&StaticRelations::FileBuffer);
00013 istream StaticRelations::StaticRelations_from_file(&StaticRelations::FileBuffer);
00014 
00015 
00016 void StaticRelations::Load()
00017 {
00018   // reading static relations from file
00019 #ifdef VERBOSE_NOTICE
00020   cout << "Reading static relations from file..." << endl;
00021 #endif
00022   StaticRelations_from_file.seekg(0,ios::beg);
00023   while (StaticRelations_from_file.peek()=='G' || StaticRelations_from_file.peek()=='U')
00024    {
00025      if (StaticRelations_from_file.peek()=='U')
00026       {
00027 #ifdef VERBOSE_WARN
00028         cerr << "skipping obsolete/invalid relation." << endl;
00029 #endif
00030         StaticRelations_from_file.ignore(1000000,'\n');
00031         continue;
00032       }
00033      CRelation* GL = new CRelation();
00034      GL->combine(StaticRelations_from_file);
00035      GL->optisize(); // Relation optimieren (dense<->sparse, etc.)
00036      GLS[GL->relevant_factor]=GL; ++Filling_GLS; // insert relation into linear system of equations
00037      StaticRelations_from_file.ignore(1,'\n');
00038    }
00039   if (StaticRelations_from_file.peek()!=EOF)
00040    {
00041      cerr << "Static Relations: garbage detected. Giving up. Please validate." << endl;
00042      exit(1);
00043    }
00044   StaticRelations_from_file.clear();
00045 #ifdef VERBOSE_NOTICE
00046   cout << "Recover: " << StaticRelations::Count() << " static relations read." << endl;
00047 #endif
00048 }
00049 
00050 void StaticRelations::insert(CRelation *GL, const bool do_multi_combine_init /* =true */)
00051 {
00052   /* Any new relation is inserted into the linear system of equations.
00053      If the relation is redundant or if it leads to a factorization,
00054      this will be detected automatically. */
00055 
00056 #ifdef IS_CLIENT
00057   // the Client does not manage any system of equations (which is instead handled by the server!)
00058   // so: delete the relation, do stats and return
00059   if (GL->relevant_factor >= 0) ++Filling_GLS;
00060   delete GL;
00061   return;
00062 #else  
00063   if (GL->relevant_factor==CRelation::dynamic_factor || GL->relevant_factor==CRelation::special_factor)
00064     { delete GL; return; } // save it to background storage and delete it in main memory
00065 
00066 #ifdef IS_SERVER
00067   // if this function is called by multiple threads, it is a critical section!
00068   // therefore we have to protect it with a mutex...
00069   static CCriticalSection::Mutex my_read_mutex;
00070   static CCriticalSection::Mutex my_write_mutex;
00071   CCriticalSection CriticalSection_Read(my_read_mutex); // enter Critial Section
00072   CCriticalSection CriticalSection_Write(my_write_mutex,false); // do not enter Additional Critical Section yet
00073 #endif
00074   
00075   if (do_multi_combine_init)
00076    {
00077      CRelation::SMulticombineData *pMD=new(CRelation::SMulticombineData);
00078      GL->set_MulticombineData(pMD);
00079      GL->multi_combine_init();
00080    }
00081    
00082   while (!GL->empty())
00083     {
00084       if (GL->relevant_factor>=StaticFactorbase::Size())
00085        {
00086          MARK;
00087          cerr << "value too big!" << endl;
00088          exit(1);
00089        }
00090       CRelation *pos = GLS[GL->relevant_factor];
00091       if (pos!=NULL)
00092         {
00093           // an entry for this relation already exists -> we can combine it!!
00094 #if 1 /* toggle minimization of relations (1=on/0=off) */
00095           if (
00096                (GL->Relation_sparse) && (pos->Relation_sparse) // both are sparse
00097                && GL->SizeOfRelation()<=pos->SizeOfRelation()
00098                && GL->second_largest_factor_in_Relation()<=pos->second_largest_factor_in_Relation()
00099              )
00100             {
00101               /* weniger Primzahlen in der Relation bedeuten schnelleres Abarbeiten.
00102                  Da beide Relationen äquivalent sind, können sie problemlos so
00103                  getauscht werden, dass die platzsparende im Gleichungssystem verbleibt.
00104                  Andererseits bestimmt das Maximum der zweitgrößten Faktoren zweier
00105                  Relationen die nächste Verknüpfung. Also ist auch dies zu minimieren.
00106                  Beim Zielkonflikt wären beide Kriterien also abzuwägen. Dies geschieht
00107                  hier nicht. Nur wenn beide Kriterien zugleich die Lage nicht
00108                  verschlechtern, werden die Relationen getauscht.
00109 
00110                  Please note, that swapping the two relations does not change the the result of
00111                  the combine operation. But it may help to speed-up later combinations and/or
00112                  and/or reduces memory consumption.
00113               */
00114 
00115 #ifdef IS_SERVER
00116               // if we can retrieve the write lock immediately, then
00117               // we perform the optimization, otherwise we simply continue...
00118               if (!CriticalSection_Write.try_enter())
00119               {
00120 #if defined(VERBOSE_INFO) || 1
00121                 static unsigned int count = 0;
00122                 ++count;
00123                 if ((count&0x1f)==0)
00124                  cout << "Elided optimizations due to write-locked Static Relations: " << count << endl;
00125 #endif                 
00126               }
00127               else
00128               {
00129 #if defined(VERBOSE_INFO) || 1
00130                 static unsigned int count = 0;
00131                 ++count;
00132                 if ((count&0x1f)==0)
00133                  cout << "Performed optimizations due to unlocked Static Relations: " << count << endl;
00134 #endif                 
00135 #endif
00136               GL->multi_combine_exit(); 
00137               GLS[GL->relevant_factor]=GL;
00138               std::swap(pos,GL); // swap relations
00139               GL->use_MulticombineData_from(*pos);
00140               pos->invalidate_MulticombineData();
00141               GL->multi_combine_init();
00142 #ifdef IS_SERVER              
00143               CriticalSection_Write.leave();
00144               }
00145 #endif              
00146             }
00147 #endif
00148           // biggest factor has to be eliminated
00149           GL->multi_combine_main(*pos); 
00150         }
00151       else
00152         {
00153           GL->multi_combine_exit();
00154           GL->dispose_MulticombineData();
00155 
00156 #ifdef IS_SERVER
00157           CriticalSection_Write.enter();
00158 #endif    
00159 
00160           GLS[GL->relevant_factor]=GL; // insert relation into linear system of equations
00161           Filling_GLS++; // one more relation in the system of linear equations
00162 
00163 #ifdef IS_SERVER
00164           CriticalSection_Read.leave();
00165 #endif
00166 
00167           GL->save(StaticRelations_to_file);
00168           // usleep(11000); // only for debugging: simulate slow filesystem
00169           StatusReport();
00170           return;
00171         }
00172     }
00173 
00174   GL->multi_combine_exit();
00175   GL->dispose_MulticombineData();
00176 
00177   // the relation is redundant:
00178   // -> we cannot insert it into the static factorbase,
00179   // -> it can yield a factor instead!
00180   // -> compute quadratic congruency!
00181   const bool complete = GL->ComputeQuadraticCongruence();
00182   delete GL;
00183   if (complete)
00184    {
00185      // Game over, we have won!
00186      // leave the program...
00187      ExitManager::StopFactorization(); // try to stop the program successfully...
00188      exit(0); // this line should not be reached!
00189    }
00190 #endif
00191 }

Generated on Wed Nov 7 23:29:26 2007 for Qsieve by  doxygen 1.5.4