galois icon indicating copy to clipboard operation
galois copied to clipboard

Project Structure

Open varun19299 opened this issue 3 years ago • 5 comments

Hi @mhostetter, I'm opening this issue to better understand the structure of the galois package. In case this should be redirected / moved to another issue, please let me know.

Unused classes

  1. Are the base classes in galois/array.py such as {Field|Group|Ring}ArrayBase being used?

varun19299 avatar Jun 13 '21 06:06 varun19299

@varun19299 thanks for opening this issue.

I'm working on a PR now to hopefully simply, clarify, and restructure the class hierarchy some. But until that is done and sensible, we can discuss what is on master. At the conclusion of this issue, I'll add a section to the development guide summarizing the project structure. For the time being, I can clarify the project via question and answer here.

As to your first question, yes they're used as mix-in classes in the class factories when creating new Galois field array classes. For example, here. Then they are used when checking if an object is a Galois field array class or Galois field array, like here.

As a heads up, I'm planning on removing the group arrays for the time being (that would remove the necessity for those base classes you mentioned). They're minimally supported and I don't think anyone uses them. I haven't yet pushed any ring arrays, but I think they'll wait too. Finite fields are the most important. Once they are very stable and the code base is stable, I might add group and ring arrays back in. But for now I think they're just making things more confusing that they have to be.

mhostetter avatar Jun 13 '21 12:06 mhostetter

@varun19299 Do you have any more questions regarding the project structure?

Or rather, from your perspective as a new developer to this library, what would be helpful in making the code structure / layout more understandable? I'd like to incorporate your feedback into either the docs or the docstrings / comments in the code. Appreciate the feedback.

mhostetter avatar Jun 18 '21 18:06 mhostetter

Hi @mhostetter,

Here are a few questions:

  1. A brief explanation (or redirect if need be) on the numpy method overriding done here. This would be required, for instance, to extend Galois to CuPy arrays.
  2. galois/field/factory vs galois/field/factory_prime vs galois/field/factory_extension. Aren't prime + extension the only two possibilities for finite fields?
  3. Extending functionality: if I have a new function for the FieldArray class (with python and Numba implementations), where should they be added?

varun19299 avatar Jun 19 '21 13:06 varun19299

@varun19299 Good questions.

A brief explanation (or redirect if need be) on the numpy method overriding done here. This would be required, for instance, to extend Galois to CuPy arrays.

The main reference I used for determining which methods to override to replace numpy features was https://numpy.org/doc/1.20/user/basics.subclassing.html.

galois/field/factory vs galois/field/factory_prime vs galois/field/factory_extension. Aren't prime + extension the only two possibilities for finite fields?

Yes. Unfortunately I've had a difficult time with circular dependencies, especially with Poly and the rest of the field array classes. This is because Poly imports GF2 as its default field. The complication is extension fields need to import Poly for their irreducible polynomials, etc. The best way I found to avoid the circular imports was to break up the files. It's been a while since I wrestled with it though, and the code has changed, so maybe I could consolidate some of the files without the circular imports. I'd have to look at it again.

Extending functionality: if I have a new function for the FieldArray class (with python and Numba implementations), where should they be added?

If it's a public method for FieldArray instances, it should go here like vector() or row_reduce(). This function could call a private implementation.

If it's a private method that calls a JIT function under-the-hood, it should go here like _poly_divmod(). _poly_divmod() is the python wrapper function that invokes a JIT routine, whose python code is included here. _poly_divmod() is used by Poly for performing division, here. It's also used for BCH decoding of non-systematic codewords, here.

If you need to add a numpy ufunc, those are implemented in galois/field/meta_ufunc.py.

mhostetter avatar Jun 19 '21 15:06 mhostetter

To-dos to improve description of the project structure for new users. Probably should add sections to the development page.

  • [ ] Add a basic description outline of the repository folder structure and contents
  • [ ] Add a description of how the key classes interact -- FieldClass, FieldArray, and the UfuncMeta/FunctionMeta/GF{2,2m,p,pm}Meta mixins
  • [ ] Add UML charts of relevant class hierarchies
  • [ ] Describe the functions used to compile/retrieve JIT-compiled or pure-Python ufuncs and normal functions (as needed in other classes/functions, e.g. BCH and berlekamp_massey()).

mhostetter avatar Aug 31 '21 22:08 mhostetter

I have restructured the code a lot since this issue was opened. I'm hoping it is more clear. I will continue to update module docstrings to help developers navigate the codebase. Closing for now. Feel free to re-open if you have more questions.

mhostetter avatar Nov 09 '22 12:11 mhostetter