<commit_before>#include "subcomm.h"
#include "remotes.h"
#include "basics.h"

void switch_comm(mpi* m)
{
  comm_finalize();
  comm_init(m);
}

static void mesh_regroup(mesh* m, int newgroup, int newrank)
{
  rpeer rp;
  int rrank;
  int othergroup;
  int otherrank;
  for (rp = rpeer_f(m); rpeer_ok(rp); rp = rpeer_n(m, rp)) {
    rrank = rpeer_rank(m, rp);
    COMM_PACK(newgroup, rrank);
    COMM_PACK(newrank, rrank);
  }
  comm_exch();
  while (comm_recv()) {
    COMM_UNPACK(othergroup);
    ASSERT(othergroup == newgroup);
    COMM_UNPACK(otherrank);
    rpeer_set_rank(m, rpeer_by_rank(m, comm_from()), otherrank);
  }
}

mpi* enter_groups(int newgroup, int newrank)
{
  mpi* oldcomm;
  mpi* subcomm;
  oldcomm = mpi_copy(comm_mpi());
  subcomm = mpi_split(oldcomm, newgroup, newrank);
  switch_comm(subcomm);
  return oldcomm;
}

void exit_groups(mpi* oldcomm)
{
  switch_comm(oldcomm);
  mpi_free(oldcomm);
}

mpi* mesh_enter_groups(mesh* m, int newgroup, int newrank)
{
  mpi* oldcomm;
  mesh_regroup(m, newgroup, newrank);
  oldcomm = enter_groups(newgroup, newrank);
  remotes_decide_owners(m);
  return oldcomm;
}

void mesh_exit_groups(mesh* m, mpi* oldcomm)
{
  mesh_regroup(m, 0, mpi_rank(oldcomm));
  exit_groups(oldcomm);<commit_msg>fix communicator leak in subcomm.c<commit_after>#include "subcomm.h"
#include "remotes.h"
#include "basics.h"

void switch_comm(mpi* m)
{
  comm_finalize();
  comm_init(m);
}

static void mesh_regroup(mesh* m, int newgroup, int newrank)
{
  rpeer rp;
  int rrank;
  int othergroup;
  int otherrank;
  for (rp = rpeer_f(m); rpeer_ok(rp); rp = rpeer_n(m, rp)) {
    rrank = rpeer_rank(m, rp);
    COMM_PACK(newgroup, rrank);
    COMM_PACK(newrank, rrank);
  }
  comm_exch();
  while (comm_recv()) {
    COMM_UNPACK(othergroup);
    ASSERT(othergroup == newgroup);
    COMM_UNPACK(otherrank);
    rpeer_set_rank(m, rpeer_by_rank(m, comm_from()), otherrank);
  }
}

mpi* enter_groups(int newgroup, int newrank)
{
  mpi* oldcomm;
  mpi* subcomm;
  oldcomm = mpi_copy(comm_mpi());
  subcomm = mpi_split(oldcomm, newgroup, newrank);
  switch_comm(subcomm);
  mpi_free(subcomm);
  return oldcomm;
}

void exit_groups(mpi* oldcomm)
{
  switch_comm(oldcomm);
  mpi_free(oldcomm);
}

mpi* mesh_enter_groups(mesh* m, int newgroup, int newrank)
{
  mpi* oldcomm;
  mesh_regroup(m, newgroup, newrank);
  oldcomm = enter_groups(newgroup, newrank);
  remotes_decide_owners(m);
  return oldcomm;
}

void mesh_exit_groups(mesh* m, mpi* oldcomm)
{
  mesh_regroup(m, 0, mpi_rank(oldcomm));
  exit_groups(oldcomm);
{'fraction_non_alphanumeric': 0.13679245283018868, 'fraction_numerical': 0.0007861635220125787, 'mean_word_length': 4.877598152424942, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7162889', 'n_tokens_mistral': 1071, 'n_tokens_neox': 1041, 'n_words': 208}