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