255 lines
6.8 KiB
C++
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
|