code: def main():
      parser = argparse.ArgumentParser(
          description="Chainer example: seq2seq"
      )
      parser.add_argument(
          "--batchsize",
          "-b",
          type=int,
          default=64,
          help="Number of images in each mini-batch",
      )
      parser.add_argument(
          "--bleu",
          action="store_true",
          default=False,
          help="Report BLEU score",
      )
      parser.add_argument(
          "--gpu", "-g", action="store_true", help="Use GPU"
      )
      parser.add_argument(
          "--cache",
          "-c",
          default=None,
          help="Directory to cache pre-processed dataset",
      )
      parser.add_argument(
          "--resume",
          "-r",
          default="",
          help="Resume the training from snapshot",
      )
      parser.add_argument(
          "--unit", "-u", type=int, default=1024, help="Number of units"
      )
      parser.add_argument(
          "--communicator",
          default="pure_nccl",
          help="Type of communicator",
      )
      parser.add_argument(
          "--stop",
          "-s",
          type=str,
          default="15e",
          help='Stop trigger (ex. "500i", "15e")',
      )
      parser.add_argument(
          "--input",
          "-i",
          type=str,
          default="wmt",
          help="Input directory",
      )
      parser.add_argument(
          "--optimizer",
          type=str,
          default="adam()",
          help="Optimizer and its argument",
      )
      parser.add_argument(
          "--out",
          "-o",
          default="result",
          help="Directory to output the result",
      )
      args = parser.parse_args()
  
      # Prepare ChainerMN communicator
      if args.gpu:
          comm = chainermn.create_communicator(args.communicator)
          dev = comm.intra_rank
      else:
          comm = chainermn.create_communicator("naive")
          dev = -1
  
      if comm.rank == 0:
          print("==========================================")
          print("Num process (COMM_WORLD): {}".format(comm.size))
          if args.gpu:
              print("Using GPUs")
          print("Using {} communicator".format(args.communicator))
          print("Num unit: {}".format(args.unit))
          print("Num Minibatch-size: {}".format(args.batchsize))
          print("==========================================")
  
      # Rank 0 prepares all data
      if comm.rank == 0:
          if args.cache and not os.path.exists(args.cache):
              os.mkdir(args.cache)
  
          # Read source data
          bt = time.time()
          if args.cache:
              cache_file = os.path.join(args.cache, "source.pickle")
              source_vocab, source_data = cached_call(
                  cache_file, read_source, args.input, args.cache
              )
          else:
              source_vocab, source_data = read_source(
                  args.input, args.cache
              )
          et = time.time()
          print("RD source done. {:.3f} [s]".format(et - bt))
          sys.stdout.flush()
  
          # Read target data
          bt = time.time()
          if args.cache:
              cache_file = os.path.join(args.cache, "target.pickle")
              target_vocab, target_data = cached_call(
                  cache_file, read_target, args.input, args.cache
              )
          else:
              target_vocab, target_data = read_target(
                  args.input, args.cache
              )
          et = time.time()
          print("RD target done. {:.3f} [s]".format(et - bt))
          sys.stdout.flush()
  
          print("Original training data size: %d" % len(source_data))
          train_data = [
              (s, t)
              for s, t in six.moves.zip(source_data, target_data)
              if 0 < len(s) < 50 and 0 < len(t) < 50
          ]
          print("Filtered training data size: %d" % len(train_data))
  
          en_path = os.path.join(args.input, "dev", "newstest2013.en")
          source_data = europal.make_dataset(en_path, source_vocab)
          fr_path = os.path.join(args.input, "dev", "newstest2013.fr")
          target_data = europal.make_dataset(fr_path, target_vocab)
          assert len(source_data) == len(target_data)
          test_data = [
              (s, t)
              for s, t in six.moves.zip(source_data, target_data)
              if 0 < len(s) and 0 < len(t)
          ]
  
          source_ids = {
              word: index for index, word in enumerate(source_vocab)
          }
          target_ids = {
              word: index for index, word in enumerate(target_vocab)
          }
      else:
          # target_data, source_data = None, None
          train_data, test_data = None, None
          target_ids, source_ids = None, None
  
      # Print GPU id
      for i in range(0, comm.size):
          if comm.rank == i:
              print("Rank {} GPU: {}".format(comm.rank, dev))
          sys.stdout.flush()
          comm.mpi_comm.Barrier()
  
      # broadcast id- > word dictionary
      source_ids = comm.bcast_obj(source_ids, root=0)
      target_ids = comm.bcast_obj(target_ids, root=0)
  
      target_words = {i: w for w, i in target_ids.items()}
      source_words = {i: w for w, i in source_ids.items()}
  
      if comm.rank == 0:
          print("target_words : {}".format(len(target_words)))
          print("source_words : {}".format(len(source_words)))
  
      model = Seq2seq(3, len(source_ids), len(target_ids), args.unit)
  
      if dev >= 0:
          chainer.cuda.get_device_from_id(dev).use()
          model.to_gpu(dev)
  
      # determine the stop trigger
      m = re.match(r"^(\d+)e$", args.stop)
      if m:
          trigger = (int(m.group(1)), "epoch")
      else:
          m = re.match(r"^(\d+)i$", args.stop)
          if m:
              trigger = (int(m.group(1)), "iteration")
          else:
              if comm.rank == 0:
                  sys.stderr.write(
                      "Error: unknown stop trigger: {}".format(
                          args.stop
                      )
                  )
              exit(-1)
  
      if comm.rank == 0:
          print("Trigger: {}".format(trigger))
  
      optimizer = chainermn.create_multi_node_optimizer(
          create_optimizer(args.optimizer), comm
      )
      optimizer.setup(model)
  
      # Broadcast dataset
      # Sanity check of train_data
      train_data = chainermn.scatter_dataset(train_data, comm)
  
      test_data = chainermn.scatter_dataset(test_data, comm)
  
      train_iter = chainer.iterators.SerialIterator(
          train_data, args.batchsize, shuffle=False
      )
      updater = training.StandardUpdater(
          train_iter, optimizer, converter=convert, device=dev
      )
      trainer = training.Trainer(updater, trigger, out=args.out)
  
      trainer.extend(
          chainermn.create_multi_node_evaluator(
              BleuEvaluator(model, test_data, device=dev, comm=comm),
              comm,
          )
      )
  
      def translate_one(source, target):
          words = europal.split_sentence(source)
          print("# source : " + " ".join(words))
          x = model.xp.array(
              [source_ids.get(w, 1) for w in words], numpy.int32
          )
          ys = model.translate([x])[0]
          words = [target_words[y] for y in ys]
          print("#  result : " + " ".join(words))
          print("#  expect : " + target)
  
      # @chainer.training.make_extension(trigger=(200, 'iteration'))
      def translate(trainer):
          translate_one("Who are we ?", "Qui sommes-nous?")
          translate_one(
              "And it often costs over a hundred dollars "
              + "to obtain the required identity card .",
              "Or, il en coûte souvent plus de cent dollars "
              + "pour obtenir la carte d'identité requise.",
          )
  
          source, target = test_data[
              numpy.random.choice(len(test_data))
          ]
          source = " ".join([source_words.get(i, "") for i in source])
          target = " ".join([target_words.get(i, "") for i in target])
          translate_one(source, target)
  
      if comm.rank == 0:
          trainer.extend(
              extensions.LogReport(trigger=(1, "epoch")),
              trigger=(1, "epoch"),
          )
  
          report = extensions.PrintReport(
              [
                  "epoch",
                  "iteration",
                  "main/loss",
                  "main/perp",
                  "validation/main/bleu",
                  "elapsed_time",
              ]
          )
          trainer.extend(report, trigger=(1, "epoch"))
  
      comm.mpi_comm.Barrier()
      if comm.rank == 0:
          print("start training")
          sys.stdout.flush()
  
      trainer.run()
  
imports: import argparse
  import math
  import os.path
  import pickle
  import re
  import sys
  import time
  from nltk.translate import bleu_score
  import numpy
  import six
  import chainer
  from chainer import cuda
  import chainer.functions
  import chainer.links
  from chainer import reporter
  from chainer import training
  from chainer.training import extensions
  import chainermn
  import europal
label_desc: Use image node_id 9 for calling a global function with example usage: main() without return types