Shared Memory Managers for F-Symbol Attributes#

This module provides an implementation for shared dictionary like state attributes required by the orthogonal F-matrix solver.

Currently, the attributes only work when the base field of the FMatrix factory is a cyclotomic field.

class sage.algebras.fusion_rings.shm_managers.FvarsHandler#

Bases: object

A shared memory backed dict-like structure to manage the _fvars attribute of an F-matrix.

This structure implements a representation of the F-symbols dictionary using a structured NumPy array backed by a contiguous shared memory object.

The monomial data is stored in the exp_data structure. Monomial exponent data is stored contiguously and ticks are used to indicate different monomials.

Coefficient data is stored in the coeff_nums and coeff_denom arrays. The coeff_denom array stores the value d = coeff.denominator() for each cyclotomic coefficient. The coeff_nums array stores the values c.numerator() * d for c in coeff._coefficients(), the abridged list representation of the cyclotomic coefficient coeff.

Each entry also has a boolean modified attribute, indicating whether it has been modified by the parent process. Entry retrieval is cached in each process, so each process must check whether entries have been modified before attempting retrieval.

The parent process should construct this object without a name attribute. Children processes use the name attribute, accessed via self.shm.name to attach to the shared memory block.

INPUT:

  • n_slots – number of generators of the underlying polynomial ring

  • field – base field for polynomial ring

  • idx_to_sextuple – map relating a single integer index to a sextuple of FusionRing elements

  • init_data – a dictionary or FvarsHandler object containing known squares for initialization, e.g., from a solver checkpoint

  • use_mp – an integer indicating the number of child processes used for multiprocessing; if running serially, use 0.

  • pids_name – the name of a ShareableList contaning the process pid’s for every process in the pool (including the parent process)

  • name – the name of a shared memory object (used by child processes for attaching)

  • max_terms – maximum number of terms in each entry; since we use contiguous C-style memory blocks, the size of the block must be known in advance

  • n_bytes – the number of bytes that should be allocated for each numerator and each denominator stored by the structure

Note

To properly dispose of shared memory resources, self.shm.unlink() must be called before exiting.

Note

If you ever encounter an OverflowError when running the FMatrix.find_orthogonal_solution() solver, consider increasing the parameter n_bytes.

Warning

The current data structure supports up to \(2^16\) entries, with each monomial in each entry having at most 254 nonzero terms. On average, each of the max_terms monomials can have at most 30 terms.

EXAMPLES:

sage: from sage.algebras.fusion_rings.shm_managers import FvarsHandler
sage: # Create shared data structure
sage: f = FusionRing("A2", 1).get_fmatrix(inject_variables=True, new=True)
creating variables fx1..fx8
Defining fx0, fx1, fx2, fx3, fx4, fx5, fx6, fx7
sage: f.start_worker_pool()
sage: n_proc = f.pool._processes
sage: pids_name = f._pid_list.shm.name
sage: fvars = FvarsHandler(8, f._field, f._idx_to_sextuple, use_mp=n_proc, pids_name=pids_name)
sage: # In the same shell or in a different shell, attach to fvars
sage: name = fvars.shm.name
sage: fvars2 = FvarsHandler(8, f._field, f._idx_to_sextuple, name=name , use_mp=n_proc, pids_name=pids_name)
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: rhs = tuple((exp, tuple(c._coefficients())) for exp, c in poly_to_tup(fx5**5))
sage: fvars[f2, f1, f2, f2, f0, f0] = rhs
sage: f._tup_to_fpoly(fvars2[f2, f1, f2, f2, f0, f0])
fx5^5
sage: fvars.shm.unlink()
sage: f.shutdown_worker_pool()
items()#

Iterates through key-value pairs in the data structure as if it were a Python dict.

As in a Python dict, the key-value pairs are yielded in no particular order.

EXAMPLES:

sage: f = FusionRing("G2", 1).get_fmatrix(inject_variables=True, new=True)
creating variables fx1..fx5
Defining fx0, fx1, fx2, fx3, fx4
sage: from sage.algebras.fusion_rings.shm_managers import FvarsHandler
sage: shared_fvars = FvarsHandler(5, f._field, f._idx_to_sextuple, init_data=f._fvars)
sage: for sextuple, fvar in shared_fvars.items():
....:     if sextuple == (f1, f1, f1, f1, f1, f1):
....:         f._tup_to_fpoly(fvar)
....:
fx4
shm#
class sage.algebras.fusion_rings.shm_managers.KSHandler#

Bases: object

A shared memory backed dict-like structure to manage the _ks attribute of an F-matrix.

This structure implements a representation of the known squares dictionary using a structured NumPy array backed by a contiguous shared memory object.

The structure mimics a dictionary of (idx, known_sq) pairs. Each integer index corresponds to a variable and each known_sq is an element of the F-matrix factory’s base cyclotomic field.

Each cyclotomic coefficient is stored as a list of numerators and a list of denominators representing the rational coefficients. The structured array also maintains known attribute that indicates whether the structure contains an entry corresponding to the given index.

The parent process should construct this object without a name attribute. Children processes use the name attribute, accessed via self.shm.name to attach to the shared memory block.

INPUT:

  • n_slots – the total number of F-symbols

  • field – F-matrix’s base cyclotomic field

  • use_mp – a boolean indicating whether to construct a shared memory block to back self.

  • init_data – a dictionary or KSHandler object containing known squares for initialization, e.g., from a solver checkpoint

  • name – the name of a shared memory object (used by child processes

    for attaching)

Note

To properly dispose of shared memory resources, self.shm.unlink() must be called before exiting.

Warning

This structure cannot modify an entry that has already been set.

EXAMPLES:

sage: from sage.algebras.fusion_rings.shm_managers import KSHandler
sage: # Create shared data structure
sage: f = FusionRing("A1", 2).get_fmatrix(inject_variables=True, new=True)
creating variables fx1..fx14
Defining fx0, fx1, fx2, fx3, fx4, fx5, fx6, fx7, fx8, fx9, fx10, fx11, fx12, fx13
sage: n = f._poly_ring.ngens()
sage: f.start_worker_pool()
sage: ks = KSHandler(n, f._field, use_mp=True)
sage: # In the same shell or in a different shell, attach to fvars
sage: name = ks.shm.name
sage: ks2 = KSHandler(n, f._field, name=name, use_mp=True)
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: eqns = [fx1**2 - 4, fx3**2 + f._field.gen()**4 - 1/19*f._field.gen()**2]
sage: ks.update([poly_to_tup(p) for p in eqns])
sage: for idx, sq in ks.items():
....:     print("Index: {}, square: {}".format(idx, sq))
....:
Index: 1, square: 4
Index: 3, square: -zeta32^4 + 1/19*zeta32^2
sage: ks.shm.unlink()
sage: f.shutdown_worker_pool()
items()#

Iterate through existing entries using Python dict-style syntax.

EXAMPLES:

sage: f = FusionRing("A3", 1).get_fmatrix()
sage: f._reset_solver_state()
sage: f.get_orthogonality_constraints(output=False)
sage: f._ks.update(f.ideal_basis)
sage: for idx, sq in f._ks.items():
....:     print("Index: {}, sq: {}".format(idx, sq))
....:
Index: 0, sq: 1
Index: 1, sq: 1
Index: 2, sq: 1
Index: 3, sq: 1
Index: 4, sq: 1
...
Index: 25, sq: 1
Index: 26, sq: 1
shm#
update(eqns)#

Update `self’s shared_memory-backed dictionary of known squares. Keys are variable indices and corresponding values are the squares.

EXAMPLES:

sage: f = FusionRing("B5", 1).get_fmatrix()
sage: f._reset_solver_state()
sage: for idx, sq in f._ks.items():
....:     k
....:
sage: f.get_orthogonality_constraints()
[fx0^2 - 1,
 fx1^2 - 1,
 fx2^2 - 1,
 fx3^2 - 1,
 fx4^2 - 1,
 fx5^2 - 1,
 fx6^2 - 1,
 fx7^2 - 1,
 fx8^2 - 1,
 fx9^2 - 1,
 fx10^2 + fx12^2 - 1,
 fx10*fx11 + fx12*fx13,
 fx10*fx11 + fx12*fx13,
 fx11^2 + fx13^2 - 1]
 sage: f.get_orthogonality_constraints(output=False)
 sage: f._ks.update(f.ideal_basis)
 sage: for idx, sq in f._ks.items():
 ....:     print(idx, "-->", sq)
 ....:
 0 --> 1
 1 --> 1
 2 --> 1
 3 --> 1
 4 --> 1
 5 --> 1
 6 --> 1
 7 --> 1
 8 --> 1
 9 --> 1

Warning

This method assumes every polynomial in eqns is monic.

sage.algebras.fusion_rings.shm_managers.make_FvarsHandler(n, field, idx_map, init_data)#

Provide pickling / unpickling support for FvarsHandler.

sage.algebras.fusion_rings.shm_managers.make_KSHandler(n_slots, field, init_data)#

Provide pickling / unpickling support for KSHandler.