Eliminate mdlib/mdrun.h
[alexxy/gromacs.git] / src / gromacs / mdlib / broadcaststructs.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 /* This file is completely threadsafe - keep it that way! */
38 #include "gmxpre.h"
39
40 #include "broadcaststructs.h"
41
42 #include <cstring>
43
44 #include <memory>
45
46 #include "gromacs/gmxlib/network.h"
47 #include "gromacs/math/vec.h"
48 #include "gromacs/mdlib/tgroup.h"
49 #include "gromacs/mdtypes/awh_params.h"
50 #include "gromacs/mdtypes/commrec.h"
51 #include "gromacs/mdtypes/inputrec.h"
52 #include "gromacs/mdtypes/md_enums.h"
53 #include "gromacs/mdtypes/pull_params.h"
54 #include "gromacs/mdtypes/state.h"
55 #include "gromacs/topology/mtop_util.h"
56 #include "gromacs/topology/symtab.h"
57 #include "gromacs/topology/topology.h"
58 #include "gromacs/utility/fatalerror.h"
59 #include "gromacs/utility/inmemoryserializer.h"
60 #include "gromacs/utility/keyvaluetree.h"
61 #include "gromacs/utility/keyvaluetreeserializer.h"
62 #include "gromacs/utility/smalloc.h"
63
64 static void bc_cstring(const t_commrec *cr, char **s)
65 {
66     int size = 0;
67
68     if (MASTER(cr) && *s != nullptr)
69     {
70         /* Size of the char buffer is string length + 1 for '\0' */
71         size = strlen(*s) + 1;
72     }
73     block_bc(cr, size);
74     if (size > 0)
75     {
76         if (!MASTER(cr))
77         {
78             srenew(*s, size);
79         }
80         nblock_bc(cr, size, *s);
81     }
82     else if (!MASTER(cr) && *s != nullptr)
83     {
84         sfree(*s);
85         *s = nullptr;
86     }
87 }
88
89 static void bc_string(const t_commrec *cr, t_symtab *symtab, char ***s)
90 {
91     int handle;
92
93     if (MASTER(cr))
94     {
95         handle = lookup_symtab(symtab, *s);
96     }
97     block_bc(cr, handle);
98     if (!MASTER(cr))
99     {
100         *s = get_symtab_handle(symtab, handle);
101     }
102 }
103
104 static void bc_strings(const t_commrec *cr, t_symtab *symtab, int nr, char ****nm)
105 {
106     int     i;
107     int    *handle;
108
109     snew(handle, nr);
110     if (MASTER(cr))
111     {
112         for (i = 0; (i < nr); i++)
113         {
114             handle[i] = lookup_symtab(symtab, (*nm)[i]);
115         }
116     }
117     nblock_bc(cr, nr, handle);
118
119     if (!MASTER(cr))
120     {
121         snew_bc(cr, *nm, nr);
122         for (i = 0; (i < nr); i++)
123         {
124             (*nm)[i] = get_symtab_handle(symtab, handle[i]);
125         }
126     }
127     sfree(handle);
128 }
129
130 static void bc_strings_resinfo(const t_commrec *cr, t_symtab *symtab,
131                                int nr, t_resinfo *resinfo)
132 {
133     int   i;
134     int  *handle;
135
136     snew(handle, nr);
137     if (MASTER(cr))
138     {
139         for (i = 0; (i < nr); i++)
140         {
141             handle[i] = lookup_symtab(symtab, resinfo[i].name);
142         }
143     }
144     nblock_bc(cr, nr, handle);
145
146     if (!MASTER(cr))
147     {
148         for (i = 0; (i < nr); i++)
149         {
150             resinfo[i].name = get_symtab_handle(symtab, handle[i]);
151         }
152     }
153     sfree(handle);
154 }
155
156 static void bc_symtab(const t_commrec *cr, t_symtab *symtab)
157 {
158     int       i, nr, len;
159     t_symbuf *symbuf;
160
161     block_bc(cr, symtab->nr);
162     nr = symtab->nr;
163     snew_bc(cr, symtab->symbuf, 1);
164     symbuf          = symtab->symbuf;
165     symbuf->bufsize = nr;
166     snew_bc(cr, symbuf->buf, nr);
167     for (i = 0; i < nr; i++)
168     {
169         if (MASTER(cr))
170         {
171             len = strlen(symbuf->buf[i]) + 1;
172         }
173         block_bc(cr, len);
174         snew_bc(cr, symbuf->buf[i], len);
175         nblock_bc(cr, len, symbuf->buf[i]);
176     }
177 }
178
179 static void bc_block(const t_commrec *cr, t_block *block)
180 {
181     block_bc(cr, block->nr);
182     snew_bc(cr, block->index, block->nr+1);
183     nblock_bc(cr, block->nr+1, block->index);
184 }
185
186 static void bc_blocka(const t_commrec *cr, t_blocka *block)
187 {
188     block_bc(cr, block->nr);
189     snew_bc(cr, block->index, block->nr+1);
190     nblock_bc(cr, block->nr+1, block->index);
191     block_bc(cr, block->nra);
192     if (block->nra)
193     {
194         snew_bc(cr, block->a, block->nra);
195         nblock_bc(cr, block->nra, block->a);
196     }
197 }
198
199 static void bc_grps(const t_commrec *cr, t_grps grps[])
200 {
201     int i;
202
203     for (i = 0; (i < egcNR); i++)
204     {
205         block_bc(cr, grps[i].nr);
206         snew_bc(cr, grps[i].nm_ind, grps[i].nr);
207         nblock_bc(cr, grps[i].nr, grps[i].nm_ind);
208     }
209 }
210
211 static void bc_atoms(const t_commrec *cr, t_symtab *symtab, t_atoms *atoms)
212 {
213     block_bc(cr, atoms->nr);
214     snew_bc(cr, atoms->atom, atoms->nr);
215     nblock_bc(cr, atoms->nr, atoms->atom);
216     bc_strings(cr, symtab, atoms->nr, &atoms->atomname);
217     block_bc(cr, atoms->nres);
218     snew_bc(cr, atoms->resinfo, atoms->nres);
219     nblock_bc(cr, atoms->nres, atoms->resinfo);
220     bc_strings_resinfo(cr, symtab, atoms->nres, atoms->resinfo);
221     /* QMMM requires atomtypes to be known on all nodes as well */
222     bc_strings(cr, symtab, atoms->nr, &atoms->atomtype);
223     bc_strings(cr, symtab, atoms->nr, &atoms->atomtypeB);
224 }
225
226 static void bc_groups(const t_commrec *cr, t_symtab *symtab,
227                       int natoms, gmx_groups_t *groups)
228 {
229     int g, n;
230
231     bc_grps(cr, groups->grps);
232     block_bc(cr, groups->ngrpname);
233     bc_strings(cr, symtab, groups->ngrpname, &groups->grpname);
234     for (g = 0; g < egcNR; g++)
235     {
236         if (MASTER(cr))
237         {
238             if (groups->grpnr[g])
239             {
240                 n = natoms;
241             }
242             else
243             {
244                 n = 0;
245             }
246         }
247         block_bc(cr, n);
248         if (n == 0)
249         {
250             groups->grpnr[g] = nullptr;
251         }
252         else
253         {
254             snew_bc(cr, groups->grpnr[g], n);
255             nblock_bc(cr, n, groups->grpnr[g]);
256         }
257     }
258     if (debug)
259     {
260         fprintf(debug, "after bc_groups\n");
261     }
262 }
263
264 template <typename AllocatorType>
265 static void bcastPaddedRVecVector(const t_commrec *cr, gmx::PaddedVector<gmx::RVec, AllocatorType> *v, int numAtoms)
266 {
267     v->resizeWithPadding(numAtoms);
268     nblock_bc(cr, makeArrayRef(*v));
269 }
270
271 void broadcastStateWithoutDynamics(const t_commrec *cr, t_state *state)
272 {
273     GMX_RELEASE_ASSERT(!DOMAINDECOMP(cr), "broadcastStateWithoutDynamics should only be used for special cases without domain decomposition");
274
275     if (!PAR(cr))
276     {
277         return;
278     }
279
280     /* Broadcasts the state sizes and flags from the master to all ranks
281      * in cr->mpi_comm_mygroup.
282      */
283     block_bc(cr, state->natoms);
284     block_bc(cr, state->flags);
285
286     for (int i = 0; i < estNR; i++)
287     {
288         if (state->flags & (1 << i))
289         {
290             switch (i)
291             {
292                 case estLAMBDA:
293                     nblock_bc(cr, efptNR, state->lambda.data());
294                     break;
295                 case estFEPSTATE:
296                     block_bc(cr, state->fep_state);
297                     break;
298                 case estBOX:
299                     block_bc(cr, state->box);
300                     break;
301                 case estX:
302                     bcastPaddedRVecVector(cr, &state->x, state->natoms);
303                     break;
304                 default:
305                     GMX_RELEASE_ASSERT(false, "The state has a dynamic entry, while no dynamic entries should be present");
306                     break;
307             }
308         }
309     }
310 }
311
312 static void bc_ilists(const t_commrec *cr, InteractionLists *ilist)
313 {
314     int ftype;
315
316     /* Here we only communicate the non-zero length ilists */
317     if (MASTER(cr))
318     {
319         for (ftype = 0; ftype < F_NRE; ftype++)
320         {
321             if ((*ilist)[ftype].size() > 0)
322             {
323                 block_bc(cr, ftype);
324                 int nr = (*ilist)[ftype].size();
325                 block_bc(cr, nr);
326                 nblock_bc(cr, nr, (*ilist)[ftype].iatoms.data());
327             }
328         }
329         ftype = -1;
330         block_bc(cr, ftype);
331     }
332     else
333     {
334         for (ftype = 0; ftype < F_NRE; ftype++)
335         {
336             (*ilist)[ftype].iatoms.clear();
337         }
338         do
339         {
340             block_bc(cr, ftype);
341             if (ftype >= 0)
342             {
343                 int nr;
344                 block_bc(cr, nr);
345                 (*ilist)[ftype].iatoms.resize(nr);
346                 nblock_bc(cr, nr, (*ilist)[ftype].iatoms.data());
347             }
348         }
349         while (ftype >= 0);
350     }
351
352     if (debug)
353     {
354         fprintf(debug, "after bc_ilists\n");
355     }
356 }
357
358 static void bc_cmap(const t_commrec *cr, gmx_cmap_t *cmap_grid)
359 {
360     int ngrid = cmap_grid->cmapdata.size();
361     block_bc(cr, ngrid);
362     block_bc(cr, cmap_grid->grid_spacing);
363
364     int nelem = cmap_grid->grid_spacing * cmap_grid->grid_spacing;
365
366     if (ngrid > 0)
367     {
368         if (!MASTER(cr))
369         {
370             cmap_grid->cmapdata.resize(ngrid);
371         }
372
373         for (int i = 0; i < ngrid; i++)
374         {
375             nblock_abc(cr, 4*nelem, &cmap_grid->cmapdata[i].cmap);
376         }
377     }
378 }
379
380 static void bc_ffparams(const t_commrec *cr, gmx_ffparams_t *ffp)
381 {
382     int numTypes = ffp->numTypes();
383     block_bc(cr, numTypes);
384     block_bc(cr, ffp->atnr);
385     nblock_abc(cr, numTypes, &ffp->functype);
386     nblock_abc(cr, numTypes, &ffp->iparams);
387     block_bc(cr, ffp->reppow);
388     block_bc(cr, ffp->fudgeQQ);
389     bc_cmap(cr, &ffp->cmap_grid);
390 }
391
392 static void bc_grpopts(const t_commrec *cr, t_grpopts *g)
393 {
394     int i, n;
395
396     block_bc(cr, g->ngtc);
397     block_bc(cr, g->ngacc);
398     block_bc(cr, g->ngfrz);
399     block_bc(cr, g->ngener);
400     snew_bc(cr, g->nrdf, g->ngtc);
401     snew_bc(cr, g->tau_t, g->ngtc);
402     snew_bc(cr, g->ref_t, g->ngtc);
403     snew_bc(cr, g->acc, g->ngacc);
404     snew_bc(cr, g->nFreeze, g->ngfrz);
405     snew_bc(cr, g->egp_flags, g->ngener*g->ngener);
406
407     nblock_bc(cr, g->ngtc, g->nrdf);
408     nblock_bc(cr, g->ngtc, g->tau_t);
409     nblock_bc(cr, g->ngtc, g->ref_t);
410     nblock_bc(cr, g->ngacc, g->acc);
411     nblock_bc(cr, g->ngfrz, g->nFreeze);
412     nblock_bc(cr, g->ngener*g->ngener, g->egp_flags);
413     snew_bc(cr, g->annealing, g->ngtc);
414     snew_bc(cr, g->anneal_npoints, g->ngtc);
415     snew_bc(cr, g->anneal_time, g->ngtc);
416     snew_bc(cr, g->anneal_temp, g->ngtc);
417     nblock_bc(cr, g->ngtc, g->annealing);
418     nblock_bc(cr, g->ngtc, g->anneal_npoints);
419     for (i = 0; (i < g->ngtc); i++)
420     {
421         n = g->anneal_npoints[i];
422         if (n > 0)
423         {
424             snew_bc(cr, g->anneal_time[i], n);
425             snew_bc(cr, g->anneal_temp[i], n);
426             nblock_bc(cr, n, g->anneal_time[i]);
427             nblock_bc(cr, n, g->anneal_temp[i]);
428         }
429     }
430
431     /* QMMM stuff, see inputrec */
432     block_bc(cr, g->ngQM);
433     snew_bc(cr, g->QMmethod, g->ngQM);
434     snew_bc(cr, g->QMbasis, g->ngQM);
435     snew_bc(cr, g->QMcharge, g->ngQM);
436     snew_bc(cr, g->QMmult, g->ngQM);
437     snew_bc(cr, g->bSH, g->ngQM);
438     snew_bc(cr, g->CASorbitals, g->ngQM);
439     snew_bc(cr, g->CASelectrons, g->ngQM);
440     snew_bc(cr, g->SAon, g->ngQM);
441     snew_bc(cr, g->SAoff, g->ngQM);
442     snew_bc(cr, g->SAsteps, g->ngQM);
443
444     if (g->ngQM)
445     {
446         nblock_bc(cr, g->ngQM, g->QMmethod);
447         nblock_bc(cr, g->ngQM, g->QMbasis);
448         nblock_bc(cr, g->ngQM, g->QMcharge);
449         nblock_bc(cr, g->ngQM, g->QMmult);
450         nblock_bc(cr, g->ngQM, g->bSH);
451         nblock_bc(cr, g->ngQM, g->CASorbitals);
452         nblock_bc(cr, g->ngQM, g->CASelectrons);
453         nblock_bc(cr, g->ngQM, g->SAon);
454         nblock_bc(cr, g->ngQM, g->SAoff);
455         nblock_bc(cr, g->ngQM, g->SAsteps);
456         /* end of QMMM stuff */
457     }
458 }
459
460 static void bc_awhBias(const t_commrec *cr, gmx::AwhBiasParams *awhBiasParams)
461 {
462     block_bc(cr, *awhBiasParams);
463
464     snew_bc(cr, awhBiasParams->dimParams, awhBiasParams->ndim);
465     nblock_bc(cr, awhBiasParams->ndim, awhBiasParams->dimParams);
466 }
467
468 static void bc_awh(const t_commrec *cr, gmx::AwhParams *awhParams)
469 {
470     int k;
471
472     block_bc(cr, *awhParams);
473     snew_bc(cr, awhParams->awhBiasParams, awhParams->numBias);
474     for (k = 0; k < awhParams->numBias; k++)
475     {
476         bc_awhBias(cr, &awhParams->awhBiasParams[k]);
477     }
478 }
479
480 static void bc_pull_group(const t_commrec *cr, t_pull_group *pgrp)
481 {
482     block_bc(cr, *pgrp);
483     if (pgrp->nat > 0)
484     {
485         snew_bc(cr, pgrp->ind, pgrp->nat);
486         nblock_bc(cr, pgrp->nat, pgrp->ind);
487     }
488     if (pgrp->nweight > 0)
489     {
490         snew_bc(cr, pgrp->weight, pgrp->nweight);
491         nblock_bc(cr, pgrp->nweight, pgrp->weight);
492     }
493 }
494
495 static void bc_pull(const t_commrec *cr, pull_params_t *pull)
496 {
497     int g;
498
499     block_bc(cr, *pull);
500     snew_bc(cr, pull->group, pull->ngroup);
501     for (g = 0; g < pull->ngroup; g++)
502     {
503         bc_pull_group(cr, &pull->group[g]);
504     }
505     snew_bc(cr, pull->coord, pull->ncoord);
506     nblock_bc(cr, pull->ncoord, pull->coord);
507     for (int c = 0; c < pull->ncoord; c++)
508     {
509         if (!MASTER(cr))
510         {
511             pull->coord[c].externalPotentialProvider = nullptr;
512         }
513         if (pull->coord[c].eType == epullEXTERNAL)
514         {
515             bc_cstring(cr, &pull->coord[c].externalPotentialProvider);
516         }
517     }
518 }
519
520 static void bc_rotgrp(const t_commrec *cr, t_rotgrp *rotg)
521 {
522     block_bc(cr, *rotg);
523     if (rotg->nat > 0)
524     {
525         snew_bc(cr, rotg->ind, rotg->nat);
526         nblock_bc(cr, rotg->nat, rotg->ind);
527         snew_bc(cr, rotg->x_ref, rotg->nat);
528         nblock_bc(cr, rotg->nat, rotg->x_ref);
529     }
530 }
531
532 static void bc_rot(const t_commrec *cr, t_rot *rot)
533 {
534     int g;
535
536     block_bc(cr, *rot);
537     snew_bc(cr, rot->grp, rot->ngrp);
538     for (g = 0; g < rot->ngrp; g++)
539     {
540         bc_rotgrp(cr, &rot->grp[g]);
541     }
542 }
543
544 static void bc_imd(const t_commrec *cr, t_IMD *imd)
545 {
546     block_bc(cr, *imd);
547     snew_bc(cr, imd->ind, imd->nat);
548     nblock_bc(cr, imd->nat, imd->ind);
549 }
550
551 static void bc_fepvals(const t_commrec *cr, t_lambda *fep)
552 {
553     int      i;
554
555     block_bc(cr, fep->nstdhdl);
556     block_bc(cr, fep->init_lambda);
557     block_bc(cr, fep->init_fep_state);
558     block_bc(cr, fep->delta_lambda);
559     block_bc(cr, fep->edHdLPrintEnergy);
560     block_bc(cr, fep->n_lambda);
561     if (fep->n_lambda > 0)
562     {
563         snew_bc(cr, fep->all_lambda, efptNR);
564         nblock_bc(cr, efptNR, fep->all_lambda);
565         for (i = 0; i < efptNR; i++)
566         {
567             snew_bc(cr, fep->all_lambda[i], fep->n_lambda);
568             nblock_bc(cr, fep->n_lambda, fep->all_lambda[i]);
569         }
570     }
571     block_bc(cr, fep->sc_alpha);
572     block_bc(cr, fep->sc_power);
573     block_bc(cr, fep->sc_r_power);
574     block_bc(cr, fep->sc_sigma);
575     block_bc(cr, fep->sc_sigma_min);
576     block_bc(cr, fep->bScCoul);
577     nblock_bc(cr, efptNR, &(fep->separate_dvdl[0]));
578     block_bc(cr, fep->dhdl_derivatives);
579     block_bc(cr, fep->dh_hist_size);
580     block_bc(cr, fep->dh_hist_spacing);
581     if (debug)
582     {
583         fprintf(debug, "after bc_fepvals\n");
584     }
585 }
586
587 static void bc_expandedvals(const t_commrec *cr, t_expanded *expand, int n_lambda)
588 {
589     block_bc(cr, expand->nstexpanded);
590     block_bc(cr, expand->elamstats);
591     block_bc(cr, expand->elmcmove);
592     block_bc(cr, expand->elmceq);
593     block_bc(cr, expand->equil_n_at_lam);
594     block_bc(cr, expand->equil_wl_delta);
595     block_bc(cr, expand->equil_ratio);
596     block_bc(cr, expand->equil_steps);
597     block_bc(cr, expand->equil_samples);
598     block_bc(cr, expand->lmc_seed);
599     block_bc(cr, expand->minvar);
600     block_bc(cr, expand->minvar_const);
601     block_bc(cr, expand->c_range);
602     block_bc(cr, expand->bSymmetrizedTMatrix);
603     block_bc(cr, expand->nstTij);
604     block_bc(cr, expand->lmc_repeats);
605     block_bc(cr, expand->lmc_forced_nstart);
606     block_bc(cr, expand->gibbsdeltalam);
607     block_bc(cr, expand->wl_scale);
608     block_bc(cr, expand->wl_ratio);
609     block_bc(cr, expand->init_wl_delta);
610     block_bc(cr, expand->bInit_weights);
611     snew_bc(cr, expand->init_lambda_weights, n_lambda);
612     nblock_bc(cr, n_lambda, expand->init_lambda_weights);
613     block_bc(cr, expand->mc_temp);
614     if (debug)
615     {
616         fprintf(debug, "after bc_expandedvals\n");
617     }
618 }
619
620 static void bc_simtempvals(const t_commrec *cr, t_simtemp *simtemp, int n_lambda)
621 {
622     block_bc(cr, simtemp->simtemp_low);
623     block_bc(cr, simtemp->simtemp_high);
624     block_bc(cr, simtemp->eSimTempScale);
625     snew_bc(cr, simtemp->temperatures, n_lambda);
626     nblock_bc(cr, n_lambda, simtemp->temperatures);
627     if (debug)
628     {
629         fprintf(debug, "after bc_simtempvals\n");
630     }
631 }
632
633
634 static void bc_swapions(const t_commrec *cr, t_swapcoords *swap)
635 {
636     block_bc(cr, *swap);
637
638     /* Broadcast atom indices for split groups, solvent group, and for all user-defined swap groups */
639     snew_bc(cr, swap->grp, swap->ngrp);
640     for (int i = 0; i < swap->ngrp; i++)
641     {
642         t_swapGroup *g = &swap->grp[i];
643
644         block_bc(cr, *g);
645         snew_bc(cr, g->ind, g->nat);
646         nblock_bc(cr, g->nat, g->ind);
647
648         int len = 0;
649         if (MASTER(cr))
650         {
651             len = strlen(g->molname);
652         }
653         block_bc(cr, len);
654         snew_bc(cr, g->molname, len);
655         nblock_bc(cr, len, g->molname);
656     }
657 }
658
659
660 static void bc_inputrec(const t_commrec *cr, t_inputrec *inputrec)
661 {
662     // Note that this overwrites pointers in inputrec, so all pointer fields
663     // Must be initialized separately below.
664     block_bc(cr, *inputrec);
665     if (SIMMASTER(cr))
666     {
667         gmx::InMemorySerializer serializer;
668         gmx::serializeKeyValueTree(*inputrec->params, &serializer);
669         std::vector<char>       buffer = serializer.finishAndGetBuffer();
670         size_t                  size   = buffer.size();
671         block_bc(cr, size);
672         nblock_bc(cr, size, buffer.data());
673     }
674     else
675     {
676         // block_bc() above overwrites the old pointer, so set it to a
677         // reasonable value in case code below throws.
678         inputrec->params = nullptr;
679         std::vector<char> buffer;
680         size_t            size;
681         block_bc(cr, size);
682         nblock_abc(cr, size, &buffer);
683         gmx::InMemoryDeserializer serializer(buffer);
684         inputrec->params = new gmx::KeyValueTreeObject(
685                     gmx::deserializeKeyValueTree(&serializer));
686     }
687
688     bc_grpopts(cr, &(inputrec->opts));
689
690     /* even if efep is efepNO, we need to initialize to make sure that
691      * n_lambda is set to zero */
692
693     snew_bc(cr, inputrec->fepvals, 1);
694     if (inputrec->efep != efepNO || inputrec->bSimTemp)
695     {
696         bc_fepvals(cr, inputrec->fepvals);
697     }
698     /* need to initialize this as well because of data checked for in the logic */
699     snew_bc(cr, inputrec->expandedvals, 1);
700     if (inputrec->bExpanded)
701     {
702         bc_expandedvals(cr, inputrec->expandedvals, inputrec->fepvals->n_lambda);
703     }
704     snew_bc(cr, inputrec->simtempvals, 1);
705     if (inputrec->bSimTemp)
706     {
707         bc_simtempvals(cr, inputrec->simtempvals, inputrec->fepvals->n_lambda);
708     }
709     if (inputrec->bPull)
710     {
711         snew_bc(cr, inputrec->pull, 1);
712         bc_pull(cr, inputrec->pull);
713     }
714     if (inputrec->bDoAwh)
715     {
716         snew_bc(cr, inputrec->awhParams, 1);
717         bc_awh(cr, inputrec->awhParams);
718     }
719
720     if (inputrec->bRot)
721     {
722         snew_bc(cr, inputrec->rot, 1);
723         bc_rot(cr, inputrec->rot);
724     }
725     if (inputrec->bIMD)
726     {
727         snew_bc(cr, inputrec->imd, 1);
728         bc_imd(cr, inputrec->imd);
729     }
730     if (inputrec->eSwapCoords != eswapNO)
731     {
732         snew_bc(cr, inputrec->swap, 1);
733         bc_swapions(cr, inputrec->swap);
734     }
735 }
736
737 static void bc_moltype(const t_commrec *cr, t_symtab *symtab,
738                        gmx_moltype_t *moltype)
739 {
740     bc_string(cr, symtab, &moltype->name);
741     bc_atoms(cr, symtab, &moltype->atoms);
742     if (debug)
743     {
744         fprintf(debug, "after bc_atoms\n");
745     }
746
747     bc_ilists(cr, &moltype->ilist);
748     bc_block(cr, &moltype->cgs);
749     bc_blocka(cr, &moltype->excls);
750 }
751
752 static void bc_vector_of_rvec(const t_commrec *cr, std::vector<gmx::RVec> *vec)
753 {
754     int numElements = vec->size();
755     block_bc(cr, numElements);
756     if (!MASTER(cr))
757     {
758         vec->resize(numElements);
759     }
760     if (numElements > 0)
761     {
762         nblock_bc(cr, numElements, as_rvec_array(vec->data()));
763     }
764 }
765
766 static void bc_molblock(const t_commrec *cr, gmx_molblock_t *molb)
767 {
768     block_bc(cr, molb->type);
769     block_bc(cr, molb->nmol);
770     bc_vector_of_rvec(cr, &molb->posres_xA);
771     bc_vector_of_rvec(cr, &molb->posres_xB);
772     if (debug)
773     {
774         fprintf(debug, "after bc_molblock\n");
775     }
776 }
777
778 static void bc_atomtypes(const t_commrec *cr, t_atomtypes *atomtypes)
779 {
780     block_bc(cr, atomtypes->nr);
781 }
782
783 /*! \brief Broadcasts ir and mtop from the master to all nodes in
784  * cr->mpi_comm_mygroup. */
785 static
786 void bcast_ir_mtop(const t_commrec *cr, t_inputrec *inputrec, gmx_mtop_t *mtop)
787 {
788     if (debug)
789     {
790         fprintf(debug, "in bc_data\n");
791     }
792     bc_inputrec(cr, inputrec);
793     if (debug)
794     {
795         fprintf(debug, "after bc_inputrec\n");
796     }
797     bc_symtab(cr, &mtop->symtab);
798     if (debug)
799     {
800         fprintf(debug, "after bc_symtab\n");
801     }
802     bc_string(cr, &mtop->symtab, &mtop->name);
803     if (debug)
804     {
805         fprintf(debug, "after bc_name\n");
806     }
807
808     bc_ffparams(cr, &mtop->ffparams);
809
810     int nmoltype = mtop->moltype.size();
811     block_bc(cr, nmoltype);
812     mtop->moltype.resize(nmoltype);
813     for (gmx_moltype_t &moltype : mtop->moltype)
814     {
815         bc_moltype(cr, &mtop->symtab, &moltype);
816     }
817
818     block_bc(cr, mtop->bIntermolecularInteractions);
819     if (mtop->bIntermolecularInteractions)
820     {
821         mtop->intermolecular_ilist = std::make_unique<InteractionLists>();
822         bc_ilists(cr, mtop->intermolecular_ilist.get());
823     }
824
825     int nmolblock = mtop->molblock.size();
826     block_bc(cr, nmolblock);
827     mtop->molblock.resize(nmolblock);
828     for (gmx_molblock_t &molblock : mtop->molblock)
829     {
830         bc_molblock(cr, &molblock);
831     }
832
833     block_bc(cr, mtop->natoms);
834
835     bc_atomtypes(cr, &mtop->atomtypes);
836
837     bc_groups(cr, &mtop->symtab, mtop->natoms, &mtop->groups);
838
839     GMX_RELEASE_ASSERT(!MASTER(cr) || mtop->haveMoleculeIndices, "mtop should have valid molecule indices");
840     if (!MASTER(cr))
841     {
842         mtop->haveMoleculeIndices = true;
843
844         gmx_mtop_finalize(mtop);
845     }
846 }
847
848 void init_parallel(t_commrec *cr, t_inputrec *inputrec,
849                    gmx_mtop_t *mtop)
850 {
851     bcast_ir_mtop(cr, inputrec, mtop);
852 }