ABACUS-v1/src/SCAN/Scan_Thread_Set.cc

255 lines
6.8 KiB
C++

/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: Scan_Thread_Set.cc
Purpose: defines all functions for Scan_Thread_Set class.
***********************************************************/
#include "JSC.h"
using namespace std;
using namespace JSC;
namespace JSC {
Scan_Thread_Set::Scan_Thread_Set()
{
dim = Vect<int> (nlists);
nthreads_tot = Vect<int> (nlists);
nthreads_done = Vect<int> (nlists);
label = Vect<Vect<string> > (nlists);
type = Vect<Vect<int> > (nlists);
isdone = Vect<Vect<bool> > (nlists);
// Give starting values to all:
for (int il = 0; il < nlists; ++il) {
dim[il] = 100;
nthreads_tot[il] = 0;
nthreads_done[il] = 0;
label[il] = Vect<string> (dim[il]);
type[il] = Vect<int> (dim[il]);
isdone[il] = Vect<bool> (false, dim[il]);
}
}
bool Scan_Thread_Set::Increase_Size (int il, int nr_to_add) // resizes the vectors to accommodate up to nr_to_add additional entries
{
if (il < 0 || il > nlists) JSCerror("ilist out of bounds in Scan_Thread_Set::Increase_Size");
dim[il] += nr_to_add;
try {
label[il].Increase_Size (nr_to_add, "");
type[il].Increase_Size (nr_to_add);
isdone[il].Increase_Size (nr_to_add, false);
}
catch (bad_alloc) {
cout << "dim[il] " << dim[il] << "\tnr_to_add " << nr_to_add << endl;
JSCerror("Memory allocation failed in Scan_Thread_Set::Increase_Size.");
}
return(true);
}
void Scan_Thread_Set::Include_Thread (DP abs_data_value_ref, string label_ref, int type_ref)
{
// Determine which ilist index is to be used:
int il = int(-log(abs_data_value_ref)/logscale);
if (il < 0) il = 0;
if (il >= nlists) il = nlists - 1;
if (nthreads_tot[il] > dim[il] - 10) { // Resize the Scan_Thread_Set list, by doubling its size
//cout << "Resizing threads list" << endl;
(*this).Increase_Size (il, dim[il]);
//cout << "Done resizing" << endl;
}
//cout << "Including thread for label " << label_ref << " and type " << type_ref << endl;
label[il][nthreads_tot[il] ] = label_ref;
type[il][nthreads_tot[il] ] = type_ref;
isdone[il][nthreads_tot[il] ] = false;
nthreads_tot[il]++;
}
void Scan_Thread_Set::Merge (const Scan_Thread_Set& refset)
{
if (nlists != refset.nlists) JSCerror("nlists don't match in Scan_Thread_Set::Merge");
for (int il = 0; il < nlists; ++il) {
if (nthreads_tot[il] + refset.nthreads_tot[il] >= dim[il])
(*this).Increase_Size (il, nthreads_tot[il]/10 + refset.nthreads_tot[il]);
for (int i = 0; i < refset.nthreads_tot[il]; ++i) {
label[il][nthreads_tot[il] ] = refset.label[il][i];
type[il][nthreads_tot[il] ] = refset.type[il][i];
isdone[il][nthreads_tot[il] ] = refset.isdone[il][i];
nthreads_tot[il]++;
}
}
}
void Scan_Thread_Set::Remove_Done_Threads (int il)
{
// If isdone[ithread] == true, remove from list
int nr_removed = 0;
for (int i = 0; i < nthreads_tot[il]; ++i) {
if (!isdone[il][i]) {
label[il][i - nr_removed] = label[il][i];
type[il][i - nr_removed] = type[il][i];
isdone[il][i - nr_removed] = isdone[il][i];
}
else nr_removed++;
}
// Zero other entries:
for (int i = nthreads_tot[il] - nr_removed; i < nthreads_tot[il]; ++i) {
label[il][i] = "";
type[il][i] = 0;
isdone[il][i] = false;
}
nthreads_tot[il] -= nr_removed;
if (nthreads_done[il] != nr_removed) {
cout << nthreads_done[il] << "\t" << nr_removed << endl;
JSCerror("Miscount in removing threads during Scan_Thread_Set::Remove_Done_Threads.");
}
nthreads_done[il] = 0;
return;
}
void Scan_Thread_Set::Remove_Done_Threads ()
{
// If isdone[ithread] == true, remove from list
for (int il = 0; il < nlists; ++il)
(*this).Remove_Done_Threads(il);
return;
}
void Scan_Thread_Set::Clear ()
{
for (int il = 0; il < nlists; ++il) {
nthreads_tot[il] = 0;
nthreads_done[il] = 0;
label[il] = Vect<string> (dim[il]);
type[il] = Vect<int> (dim[il]);
isdone[il] = Vect<bool> (false, dim[il]);
}
}
void Scan_Thread_Set::Save(const char* outfile_Cstr)
{
// We save only the undone threads, so after cleanup.
(*this).Remove_Done_Threads();
ofstream outfile;
outfile.open(outfile_Cstr);
if (outfile.fail()) JSCerror("Could not open outfile... ");
outfile.precision(3);
//cout << "Saving threads: nthreads_tot vector is" << endl;
//for (int il = 0; il < nlists; ++il)
//if (nthreads_tot[il] > 0) cout << il << "\t" << nthreads_tot[il] << "\t";
//cout << endl;
bool started = false;
for (int il = 0; il < nlists; ++il) {
if (nthreads_tot[il] > 0) {
if (started) outfile << endl;
outfile << il << "\t" << label[il][0] << "\t" << type[il][0];
started = true;
for (int i = 1; i < nthreads_tot[il]; ++i) {
outfile << endl << il << "\t" << label[il][i] << "\t" << type[il][i];
}
}
}
outfile.close();
return;
}
void Scan_Thread_Set::Load (const char* thrfile_Cstr)
{
ifstream infile;
infile.open(thrfile_Cstr);
if(infile.fail()) {
cout << "Could not open file " << thrfile_Cstr << " in Scan_Thread_Set::Load." << endl;
JSCerror("Terminating.");
}
(*this).Clear();
// First count the number of elements in each list:
Vect<int> nthreads_read(0, nlists);
int il_read;
string label_read;
int type_read;
while (infile.peek() != EOF) {
infile >> il_read;
infile >> label_read;
infile >> type_read;
nthreads_read[il_read]++;
}
infile.close();
//cout << "nthreads_read vector: " << endl;
//for (int il = 0; il < nlists; ++il)
//if (nthreads_read[il] > 0) cout << il << "\t" << nthreads_read[il] << "\t";
//cout << endl;
// Now allocate the proper sizes:
for (int il = 0; il < nlists; ++il) {
(*this).Increase_Size (il, JSC::max(0, nthreads_read[il] - dim[il] + 10));
nthreads_read[il] = 0;
}
// Read threads data in:
ifstream infile2;
infile2.open(thrfile_Cstr);
infile.seekg(0);
while (infile2.peek() != EOF) {
infile2 >> il_read;
infile2 >> label[il_read][nthreads_read[il_read] ];
infile2 >> type[il_read][nthreads_read[il_read] ];
//isdone[il_read][nthreads_read[il_read] ] = false; // no need
nthreads_tot[il_read]++;
nthreads_read[il_read]++;
}
infile2.close();
//cout << "Loading threads: nthreads_tot vector is" << endl;
//for (int il = 0; il < nlists; ++il)
//if (nthreads_tot[il] > 0) cout << il << "\t" << nthreads_tot[il] << "\t";
//cout << endl;
return;
}
} // namespace JSC