Source code for boolean_cayley_graphs.classify_in_mpi_parallel

r"""
Classification in parallel using MPI
====================================

The ``classify_in_mpi_parallel`` module defines functions that
use MPI to save Cayley graph classifications or partial classifications in parallel.

AUTHORS:

- Paul Leopardi (2017-10-13)

"""
#*****************************************************************************
#       Copyright (C) 2016 Paul Leopardi paul.leopardi@gmail.com
#
#  Distributed under the terms of the GNU General Public License (GPL)
#  as published by the Free Software Foundation; either version 2 of
#  the License, or (at your option) any later version.
#                  http://www.gnu.org/licenses/
#*****************************************************************************

from math import log
from sage.crypto.boolean_function import BooleanFunction
from sage.functions.other import Function_ceil

from boolean_cayley_graphs.bent_function import BentFunction
from boolean_cayley_graphs.classify_in_parallel import save_one_classification
from boolean_cayley_graphs.classify_in_parallel import save_one_class_part


[docs]def save_classifications_in_parallel( comm, name_prefix, list_of_f, start=0, stop=None, directory=None): r""" Using MPI, construct and save a number of Cayley graph classifications corresponding to a list of bent functions. INPUT: - ``comm`` -- MPI communicator. - ``name_prefix`` -- String. Name prefix to use with ``save_mangled`` to save each classification. - ``list_of_f`` -- List of forms or bent functions. - ``start`` -- Integer. Default=0. Index of start position in the list. - ``stop`` -- Integer. Default=None. Index after end position, or ``None`` if whole remaining list. - ``directory`` -- string, optional. The directory where the object is to be saved. Default is None, meaning the current directory. OUTPUT: None. EFFECT: Uses ``name`` to save the classifications corresponding to ``list_of_f``. """ rank = comm.Get_rank() size = comm.Get_size() if stop == None: stop = len(list_of_f) for n in range(start + rank, stop, size): name = name_prefix + '_' + str(n) form = BooleanFunction(list_of_f[n]).truth_table(format='hex') save_one_classification( name, form, directory=directory)
[docs]def save_class_parts_in_parallel( comm, name_prefix, form, c_len=1, directory=None): r""" Using MPI, construct a complete list of the partial Cayley graph classifications corresponding to a given bent function or algebraic normal form. INPUT: - ``comm`` -- MPI communicator. - ``name_prefix`` -- String. Name prefix to use with ``save_mangled`` to save each class part. - ``form`` -- A bent function or an algebraic normal form. - ``c_len`` -- Integer. Default=1. The number of values of `c` to use in each class part. - ``directory`` -- string, optional. The directory where the object is to be saved. Default is None, meaning the current directory. OUTPUT: None. EFFECT: Uses ``name_prefix`` to save all partial classifications corresponding to ``bentf``. """ rank = comm.Get_rank() size = comm.Get_size() bentf = BentFunction(form) dim = bentf.nvariables() v = 2 ** dim ceil = Function_ceil() nbr_parts = ceil(v * 1.0 / c_len) # Include the case where size > nbr_parts and therefore # this function is being applied to many bent functions in parallel. if size > nbr_parts: beg_n = rank % nbr_parts end_n = beg_n + 1 else: beg_n = rank end_n = nbr_parts nbr_digits = ceil(log(nbr_parts, 10)) for n in range(beg_n, end_n, size): n_str = '{0:0={width}}'.format(n, width=nbr_digits) save_one_class_part( name=name_prefix + '_' + n_str, bentf=bentf, c_start=c_len * n, c_stop=c_len * (n + 1), directory=directory)