Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 78 additions & 76 deletions src/CovidSim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ param P;
person* Hosts;
household* Households;
popvar State, StateT[MAX_NUM_THREADS];
cell* Cells; // Cells[i] is the i'th cell
cell ** CellLookup; // CellLookup[i] is a pointer to the i'th populated cell
microcell* Mcells, ** McellLookup;
std::vector<cell> Cells(P.NC); // Cells.at(i) is the i'th cell
std::vector<cell*> CellLookup(P.NCP); // CellLookup[i] is a pointer to the i'th populated cell
std::vector<microcell> Mcells(P.NMC);
std::vector<microcell*> McellLookup(P.NMCP);
Comment on lines +74 to +77

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are trying to initialise these at program start up time when P.NC is 0 - so this will fail - I think need to have something like:

std::vector<cell> Cells;

// Whereever the calloc was
Cells.resize(P.NC);

etc.

place** Places;
adminunit AdUnits[MAX_ADUNITS];
//// Time Series defs:
Expand Down Expand Up @@ -2567,25 +2568,25 @@ void InitModel(int run) // passing run number so we can save run number in the i
{
for (i = tn; i < P.NC; i+=P.NumThreads)
{
if ((Cells[i].tot_treat != 0) || (Cells[i].tot_vacc != 0) || (Cells[i].S != Cells[i].n) || (Cells[i].D > 0) || (Cells[i].R > 0))
if ((Cells.at(i).tot_treat != 0) || (Cells.at(i).tot_vacc != 0) || (Cells.at(i).S != Cells.at(i).n) || (Cells.at(i).D > 0) || (Cells.at(i).R > 0))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::vector::at() will throw an exception on a bad access. Not a bad thing per se - however, the code isn't exception aware and I think there will be problems with exceptions crossing thread boundaries.

There are two solutions to this:

The easy one: Just use [] access everywhere. (Why do you use it in some places and not others?).

The harder one, put try/catch blocks everywhere that is appropriate.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to expand on the uncaught exceptions issue flagged here, the OpenMP specification mandates that an exception thrown within the omp parallel for region must cause the thread to resume within the same region (ie. no uncaught exceptions within omp parallel for loops).

I second the suggestion to prefer the use of operator[], rather than wrapping inner loops in try catch blocks, since I don't think there's much that can be done about an invalid index in either case, plus a segmentation fault raised by an invalid index is more obviously wrong.

{
for (j = 0; j < Cells[i].n; j++)
for (j = 0; j < Cells.at(i).n; j++)
{
k = Cells[i].members[j];
Cells[i].susceptible[j] = k; //added this in here instead
k = Cells.at(i).members[j];
Cells.at(i).susceptible[j] = k; //added this in here instead
Hosts[k].listpos = j;
}
Cells[i].S = Cells[i].n;
Cells[i].L = Cells[i].I = Cells[i].R = Cells[i].cumTC = Cells[i].D = 0;
Cells[i].infected = Cells[i].latent = Cells[i].susceptible + Cells[i].S;
Cells[i].tot_treat = Cells[i].tot_vacc = 0;
for (l = 0; l < MAX_INTERVENTION_TYPES; l++) Cells[i].CurInterv[l] = -1;
Cells.at(i).S = Cells.at(i).n;
Cells.at(i).L = Cells.at(i).I = Cells.at(i).R = Cells.at(i).cumTC = Cells.at(i).D = 0;
Cells.at(i).infected = Cells.at(i).latent = Cells.at(i).susceptible + Cells.at(i).S;
Cells.at(i).tot_treat = Cells.at(i).tot_vacc = 0;
for (l = 0; l < MAX_INTERVENTION_TYPES; l++) Cells.at(i).CurInterv[l] = -1;

// Next loop needs to count down for DoImmune host list reordering to work
if(!P.DoPartialImmunity)
for (j = Cells[i].n - 1; j >= 0; j--)
for (j = Cells.at(i).n - 1; j >= 0; j--)
{
k = Cells[i].members[j];
k = Cells.at(i).members[j];
if (P.DoWholeHouseholdImmunity)
{
// note that this breaks determinism of runs if executed due to reordering of Cell members list each realisation
Expand Down Expand Up @@ -2618,15 +2619,15 @@ void InitModel(int run) // passing run number so we can save run number in the i
#pragma omp parallel for private(i,j,k,l) schedule(static,500)
for (l = 0; l < P.NMCP; l++)
{
i = (int)(McellLookup[l] - Mcells);
Mcells[i].vacc_start_time = Mcells[i].treat_start_time = USHRT_MAX - 1;
Mcells[i].treat_end_time = 0;
Mcells[i].treat_trig = Mcells[i].vacc_trig = Mcells[i].vacc = Mcells[i].treat = 0;
Mcells[i].place_trig = Mcells[i].move_trig = Mcells[i].socdist_trig = Mcells[i].keyworkerproph_trig =
Mcells[i].placeclose = Mcells[i].moverest = Mcells[i].socdist = Mcells[i].keyworkerproph = 0;
Mcells[i].move_start_time = USHRT_MAX - 1;
Mcells[i].place_end_time = Mcells[i].move_end_time =
Mcells[i].socdist_end_time = Mcells[i].keyworkerproph_end_time = 0;
i = (int)(McellLookup.at(l) - &Mcells[0]);
Mcells.at(i).vacc_start_time = Mcells.at(i).treat_start_time = USHRT_MAX - 1;
Mcells.at(i).treat_end_time = 0;
Mcells.at(i).treat_trig = Mcells.at(i).vacc_trig = Mcells.at(i).vacc = Mcells.at(i).treat = 0;
Mcells.at(i).place_trig = Mcells.at(i).move_trig = Mcells.at(i).socdist_trig = Mcells.at(i).keyworkerproph_trig =
Mcells.at(i).placeclose = Mcells.at(i).moverest = Mcells.at(i).socdist = Mcells.at(i).keyworkerproph = 0;
Mcells.at(i).move_start_time = USHRT_MAX - 1;
Mcells.at(i).place_end_time = Mcells.at(i).move_end_time =
Mcells.at(i).socdist_end_time = Mcells.at(i).keyworkerproph_end_time = 0;
}
if (P.DoPlaces)
#pragma omp parallel for private(m,l) schedule(static,1)
Expand Down Expand Up @@ -2771,7 +2772,7 @@ void SeedInfection(double t, int* nsi, int rf, int run) //adding run number to p
m = 0;
for (k = 0; (k < nsi[i]) && (m < 10000); k++)
{
l = Mcells[j].members[(int)(ranf() * ((double)Mcells[j].n))]; //// randomly choose member of microcell j. Name this member l
l = Mcells.at(j).members[(int)(ranf() * ((double)Mcells.at(j).n))]; //// randomly choose member of microcell j. Name this member l
if (Hosts[l].inf == InfStat_Susceptible) //// If Host l is uninfected.
{
if (CalcPersonSusc(l, 0, 0, 0) > 0)
Expand Down Expand Up @@ -2801,13 +2802,13 @@ void SeedInfection(double t, int* nsi, int rf, int run) //adding run number to p
{
l = (int)(ranf() * ((double)P.PopSize));
j = Hosts[l].mcell;
//fprintf(stderr,"%i ",AdUnits[Mcells[j].adunit].id);
} while ((Mcells[j].n < nsi[i]) || (Mcells[j].n > P.MaxPopDensForInitialInfection)
|| (Mcells[j].n < P.MinPopDensForInitialInfection)
|| ((P.InitialInfectionsAdminUnit[i] > 0) && ((AdUnits[Mcells[j].adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor != (P.InitialInfectionsAdminUnit[i] % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor)));
//fprintf(stderr,"%i ",AdUnits[Mcells.at(j).adunit].id);
} while ((Mcells.at(j).n < nsi[i]) || (Mcells.at(j).n > P.MaxPopDensForInitialInfection)
|| (Mcells.at(j).n < P.MinPopDensForInitialInfection)
|| ((P.InitialInfectionsAdminUnit[i] > 0) && ((AdUnits[Mcells.at(j).adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor != (P.InitialInfectionsAdminUnit[i] % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor)));
for (k = 0; (k < nsi[i]) && (m < 10000); k++)
{
l = Mcells[j].members[(int)(ranf() * ((double)Mcells[j].n))];
l = Mcells.at(j).members[(int)(ranf() * ((double)Mcells.at(j).n))];
if (Hosts[l].inf == InfStat_Susceptible)
{
if (CalcPersonSusc(l, 0, 0, 0) > 0)
Expand Down Expand Up @@ -2839,11 +2840,11 @@ void SeedInfection(double t, int* nsi, int rf, int run) //adding run number to p
{
l = (int)(ranf() * ((double)P.PopSize));
j = Hosts[l].mcell;
//fprintf(stderr,"@@ %i %i ",AdUnits[Mcells[j].adunit].id, (int)(AdUnits[Mcells[j].adunit].id / P.CountryDivisor));
} while ((Mcells[j].n == 0) || (Mcells[j].n > P.MaxPopDensForInitialInfection)
|| (Mcells[j].n < P.MinPopDensForInitialInfection)
|| ((P.InitialInfectionsAdminUnit[i] > 0) && ((AdUnits[Mcells[j].adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor != (P.InitialInfectionsAdminUnit[i] % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor)));
l = Mcells[j].members[(int)(ranf() * ((double)Mcells[j].n))];
//fprintf(stderr,"@@ %i %i ",AdUnits[Mcells.at(j).adunit].id, (int)(AdUnits[Mcells.at(j).adunit].id / P.CountryDivisor));
} while ((Mcells.at(j).n == 0) || (Mcells.at(j).n > P.MaxPopDensForInitialInfection)
|| (Mcells.at(j).n < P.MinPopDensForInitialInfection)
|| ((P.InitialInfectionsAdminUnit[i] > 0) && ((AdUnits[Mcells.at(j).adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor != (P.InitialInfectionsAdminUnit[i] % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor)));
l = Mcells.at(j).members[(int)(ranf() * ((double)Mcells.at(j).n))];
if (Hosts[l].inf == InfStat_Susceptible)
{
if (CalcPersonSusc(l, 0, 0, 0) > 0)
Expand Down Expand Up @@ -3997,10 +3998,10 @@ void LoadSnapshot(void)
if (!(Array_tot_prob = (float*)malloc(P.NCP * sizeof(float)))) ERR_CRITICAL("Unable to temp allocate cell storage\n");
for (i = 0; i < P.NCP; i++)
{
Array_InvCDF[i] = Cells[i].InvCDF;
Array_max_trans[i] = Cells[i].max_trans;
Array_cum_trans[i] = Cells[i].cum_trans;
Array_tot_prob[i] = Cells[i].tot_prob;
Array_InvCDF[i] = Cells.at(i).InvCDF;
Array_max_trans[i] = Cells.at(i).max_trans;
Array_cum_trans[i] = Cells.at(i).cum_trans;
Array_tot_prob[i] = Cells.at(i).tot_prob;
}

fread_big((void*)& i, sizeof(int), 1, dat); if (i != P.PopSize) ERR_CRITICAL_FMT("Incorrect N (%i %i) in snapshot file.\n", P.PopSize, i);
Expand All @@ -4026,35 +4027,35 @@ void LoadSnapshot(void)
fprintf(stderr, ".");
zfread_big((void*)Households, sizeof(household), (size_t)P.NH, dat);
fprintf(stderr, ".");
zfread_big((void*)Cells, sizeof(cell), (size_t)P.NC, dat);
zfread_big((void*)&Cells.front(), sizeof(cell), (size_t)P.NC, dat);
fprintf(stderr, ".");
zfread_big((void*)Mcells, sizeof(microcell), (size_t)P.NMC, dat);
zfread_big((void*)&Mcells.front(), sizeof(microcell), (size_t)P.NMC, dat);
fprintf(stderr, ".");
zfread_big((void*)State.CellMemberArray, sizeof(int), (size_t)P.PopSize, dat);
fprintf(stderr, ".");
zfread_big((void*)State.CellSuscMemberArray, sizeof(int), (size_t)P.PopSize, dat);
fprintf(stderr, ".");
for (i = 0; i < P.NC; i++)
{
if (Cells[i].n > 0)
if (Cells.at(i).n > 0)
{
Cells[i].members += CM_offset;
Cells[i].susceptible += CSM_offset;
Cells[i].latent += CSM_offset;
Cells[i].infected += CSM_offset;
Cells.at(i).members += CM_offset;
Cells.at(i).susceptible += CSM_offset;
Cells.at(i).latent += CSM_offset;
Cells.at(i).infected += CSM_offset;
}
for (j = 0; j < MAX_INTERVENTION_TYPES; j++) Cells[i].CurInterv[j] = -1; // turn interventions off in loaded image
for (j = 0; j < MAX_INTERVENTION_TYPES; j++) Cells.at(i).CurInterv[j] = -1; // turn interventions off in loaded image
}
for (i = 0; i < P.NMC; i++)
if (Mcells[i].n > 0)
Mcells[i].members += CM_offset;
if (Mcells.at(i).n > 0)
Mcells.at(i).members += CM_offset;

for (i = 0; i < P.NCP; i++)
{
Cells[i].InvCDF = Array_InvCDF[i];
Cells[i].max_trans = Array_max_trans[i];
Cells[i].cum_trans = Array_cum_trans[i];
Cells[i].tot_prob = Array_tot_prob[i];
Cells.at(i).InvCDF = Array_InvCDF[i];
Cells.at(i).max_trans = Array_max_trans[i];
Cells.at(i).cum_trans = Array_cum_trans[i];
Cells.at(i).tot_prob = Array_tot_prob[i];
}
free(Array_tot_prob);
free(Array_cum_trans);
Expand Down Expand Up @@ -4101,9 +4102,9 @@ void SaveSnapshot(void)
fprintf(stderr, "## %i\n", i++);
zfwrite_big((void*)Households, sizeof(household), (size_t)P.NH, dat);
fprintf(stderr, "## %i\n", i++);
zfwrite_big((void*)Cells, sizeof(cell), (size_t)P.NC, dat);
zfwrite_big((void*)&Cells.front(), sizeof(cell), (size_t)P.NC, dat);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zfwrite_big((void*)&Cells.front(), sizeof(cell), (size_t)P.NC, dat);
zfwrite_big((void*)Cells.data(), sizeof(cell), (size_t)P.NC, dat);

Calling front results in undefined behaviour in the case where Cells is empty. C++11 introduced std::vector<T,Allocator>::data, which will simply return a null pointer in the case of an empty vector. We should use that here.

fprintf(stderr, "## %i\n", i++);
zfwrite_big((void*)Mcells, sizeof(microcell), (size_t)P.NMC, dat);
zfwrite_big((void*)&Mcells.front(), sizeof(microcell), (size_t)P.NMC, dat);
fprintf(stderr, "## %i\n", i++);

zfwrite_big((void*)State.CellMemberArray, sizeof(int), (size_t)P.PopSize, dat);
Expand All @@ -4123,12 +4124,12 @@ void UpdateProbs(int DoPlace)
#pragma omp parallel for private(j) schedule(static,500)
for (j = 0; j < P.NCP; j++)
{
CellLookup[j]->tot_prob = 0;
CellLookup[j]->S0 = CellLookup[j]->S + CellLookup[j]->L + CellLookup[j]->I;
Cells.at(j).tot_prob = 0;
Cells.at(j).S0 = Cells.at(j).S + Cells.at(j).L + Cells.at(j).I;
if (P.DoDeath)
{
CellLookup[j]->S0 += CellLookup[j]->n / 5;
if ((CellLookup[j]->n < 100) || (CellLookup[j]->S0 > CellLookup[j]->n)) CellLookup[j]->S0 = CellLookup[j]->n;
Cells.at(j).S0 += Cells.at(j).n / 5;
if ((Cells.at(j).n < 100) || (Cells.at(j).S0 > Cells.at(j).n)) Cells.at(j).S0 = Cells.at(j).n;
}
}
}
Expand All @@ -4137,30 +4138,30 @@ void UpdateProbs(int DoPlace)
#pragma omp parallel for private(j) schedule(static,500)
for (j = 0; j < P.NCP; j++)
{
CellLookup[j]->S0 = CellLookup[j]->S;
CellLookup[j]->tot_prob = 0;
Cells.at(j).S0 = Cells.at(j).S;
Cells.at(j).tot_prob = 0;
}
}
#pragma omp parallel for private(j) schedule(static,500)
for (j = 0; j < P.NCP; j++)
{
int m, k;
float t;
CellLookup[j]->cum_trans[0] = ((float)(CellLookup[0]->S0)) * CellLookup[j]->max_trans[0];
t = ((float)CellLookup[0]->n) * CellLookup[j]->max_trans[0];
Cells.at(j).cum_trans[0] = ((float)(Cells.front().S0)) * Cells.at(j).max_trans[0];
t = ((float)Cells.front().n) * Cells.at(j).max_trans[0];
for (m = 1; m < P.NCP; m++)
{
CellLookup[j]->cum_trans[m] = CellLookup[j]->cum_trans[m - 1] + ((float)(CellLookup[m]->S0)) * CellLookup[j]->max_trans[m];
t += ((float)CellLookup[m]->n) * CellLookup[j]->max_trans[m];
Cells.at(j).cum_trans[m] = Cells.at(j).cum_trans[m - 1] + ((float)(Cells.at(m).S0)) * Cells.at(j).max_trans[m];
t += ((float)Cells.at(m).n) * Cells.at(j).max_trans[m];
}
CellLookup[j]->tot_prob = CellLookup[j]->cum_trans[P.NCP - 1];
Cells.at(j).tot_prob = Cells.at(j).cum_trans[P.NCP - 1];
for (m = 0; m < P.NCP; m++)
CellLookup[j]->cum_trans[m] /= CellLookup[j]->tot_prob;
CellLookup[j]->tot_prob /= t;
Cells.at(j).cum_trans[m] /= Cells.at(j).tot_prob;
Cells.at(j).tot_prob /= t;
for (k = m = 0; k <= 1024; k++)
{
while (CellLookup[j]->cum_trans[m] * 1024 < ((float)k)) m++;
CellLookup[j]->InvCDF[k] = m;
while (Cells.at(j).cum_trans[m] * 1024 < ((float)k)) m++;
Cells.at(j).InvCDF[k] = m;
}
}
}
Expand Down Expand Up @@ -4658,7 +4659,7 @@ void RecordSample(double t, int n)
State.NumPlacesClosed[i] = numPC;
TimeSeries[n].PropPlacesClosed[i] = ((double)numPC) / ((double)P.Nplace[i]);
}
for (i = k = 0; i < P.NMC; i++) if (Mcells[i].socdist == 2) k++;
for (i = k = 0; i < P.NMC; i++) if (Mcells.at(i).socdist == 2) k++;
TimeSeries[n].PropSocDist=((double)k)/((double)P.NMC);

//update contact number distribution in State
Expand Down Expand Up @@ -5061,13 +5062,14 @@ void CalcOriginDestMatrix_adunit()
#pragma omp parallel for private(tn,i,j,k,l,m,p,total_flow,mcl_from,mcl_to,cl_from,cl_to,cl_from_mcl,cl_to_mcl,flow) schedule(static) //reduction(+:s,t2)
for (tn = 0; tn < P.NumThreads; tn++)
{
auto Cells_front = &Cells.front();
for (i = tn; i < P.NCP; i += P.NumThreads)
{
//reset pop density matrix to zero
double pop_dens_from[MAX_ADUNITS] = {};

//find index of cell from which flow travels
cl_from = CellLookup[i] - Cells;
cl_from = CellLookup[i] - Cells_front;
cl_from_mcl = (cl_from / P.nch) * P.NMCL * P.nmch + (cl_from % P.nch) * P.NMCL;

//loop over microcells in these cells to find populations in each admin unit and so flows
Expand All @@ -5091,17 +5093,17 @@ void CalcOriginDestMatrix_adunit()
double pop_dens_to[MAX_ADUNITS] = {};

//find index of cell which flow travels to
cl_to = CellLookup[j] - Cells;
cl_to = CellLookup[j] - Cells_front;
cl_to_mcl = (cl_to / P.nch) * P.NMCL * P.nmch + (cl_to % P.nch) * P.NMCL;
//calculate distance and kernel between the cells
//total_flow=Cells[cl_from].max_trans[j]*Cells[cl_from].n*Cells[cl_to].n;
if (j == 0)
{
total_flow = Cells[cl_from].cum_trans[j] * Cells[cl_from].n;
total_flow = Cells.at(cl_from).cum_trans[j] * Cells.at(cl_from).n;
}
else
{
total_flow = (Cells[cl_from].cum_trans[j] - Cells[cl_from].cum_trans[j - 1]) * Cells[cl_from].n;
total_flow = (Cells.at(cl_from).cum_trans[j] - Cells.at(cl_from).cum_trans[j - 1]) * Cells.at(cl_from).n;
}

//loop over microcells within destination cell
Expand All @@ -5111,10 +5113,10 @@ void CalcOriginDestMatrix_adunit()
{
//get index of microcell
mcl_to = cl_to_mcl + p + m * P.nmch;
if (Mcells[mcl_to].n > 0)
if (Mcells.at(mcl_to).n > 0)
{
//get proportion of each population of cell that exists in each admin unit
pop_dens_to[Mcells[mcl_to].adunit] += (((double)Mcells[mcl_to].n) / ((double)Cells[cl_to].n));
pop_dens_to[Mcells.at(mcl_to).adunit] += (((double)Mcells.at(mcl_to).n) / ((double)Cells.at(cl_to).n));
}
}
}
Expand Down
15 changes: 9 additions & 6 deletions src/Dist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ double dist2_cc(cell* a, cell* b)
double x, y;
int l, m;

l = (int)(a - Cells);
m = (int)(b - Cells);
auto Cells_front = &Cells.front();
l = (int)(a - Cells_front);
m = (int)(b - Cells_front);
if (P.DoUTM_coords)
return dist2UTM(P.cwidth * fabs((double)(l / P.nch)), P.cheight * fabs((double)(l % P.nch)),
P.cwidth * fabs((double)(m / P.nch)), P.cheight * fabs((double)(m % P.nch)));
Expand All @@ -84,8 +85,9 @@ double dist2_cc_min(cell* a, cell* b)
double x, y;
int l, m, i, j;

l = (int)(a - Cells);
m = (int)(b - Cells);
auto Cells_front = &Cells.front();
l = (int)(a - Cells_front);
m = (int)(b - Cells_front);
i = l; j = m;
if (P.DoUTM_coords)
{
Expand Down Expand Up @@ -155,8 +157,9 @@ double dist2_mm(microcell* a, microcell* b)
double x, y;
int l, m;

l = (int)(a - Mcells);
m = (int)(b - Mcells);
auto Mcells_front = &Mcells.front();
l = (int)(a - Mcells_front);
m = (int)(b - Mcells_front);
if (P.DoUTM_coords)
return dist2UTM(P.mcwidth * fabs((double)(l / P.nmch)), P.mcheight * fabs((double)(l % P.nmch)),
P.mcwidth * fabs((double)(m / P.nmch)), P.mcheight * fabs((double)(m % P.nmch)));
Expand Down
8 changes: 6 additions & 2 deletions src/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifndef COVIDSIM_MODEL_H_INCLUDED_
#define COVIDSIM_MODEL_H_INCLUDED_

#include <vector>

#include "Country.h"
#include "MachineDefines.h"
#include "Constants.h"
Expand Down Expand Up @@ -334,8 +336,10 @@ typedef struct ADMINUNIT {
extern person* Hosts;
extern household* Households;
extern popvar State, StateT[MAX_NUM_THREADS];
extern cell* Cells, ** CellLookup;
extern microcell* Mcells, ** McellLookup;
extern std::vector<cell> Cells;
extern std::vector<cell*> CellLookup;
extern std::vector<microcell> Mcells;
extern std::vector<microcell*> McellLookup;
extern place** Places;
extern adminunit AdUnits[MAX_ADUNITS];

Expand Down
Loading