Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor for Codegen Routine #8082

Merged
merged 8 commits into from Oct 16, 2014
Merged

refactor for Codegen Routine #8082

merged 8 commits into from Oct 16, 2014

Conversation

cbm755
Copy link
Contributor

@cbm755 cbm755 commented Sep 23, 2014

For OctaveCodeGen (pr #7824), I need some refactoring of Routine.

  • add Fortran matrix tests
  • add C matrix tests
  • move language specific stuff out of Routine.__new__
  • rework docstrings
  • rework Result, added NamedResult.
  • clear-up FIXMEs on name versus result_var in docstrings.

see this comment #7824 (comment)

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 23, 2014

@jcrist: is this the right approach? I guess you rather mean a standard alone function, not part of the code_gen class.

Lots of tests call Routine() directly: how would all of those know what language? I suspect the main user interface should be "name_expr" into "code_gen" rather than calling Routine...

I'll play with having a standalone routine factory some more later.

@jcrist
Copy link
Member

jcrist commented Sep 23, 2014

I guess you rather mean a standard alone function, not part of the code_gen class.

I think that would be best. Instances of Routine are structural, they define how the generated function should look. The init in Routine itself shouldn't do anything more than ensure that the input is valid. Having a standalone routine function that has a nicer interface (implicit creation of Argument and Result instances as befitting the language of choice, etc...) would allow users to still create routines easily using what Sympy thinks are the best options, while not preventing expert users from initializing Routines directly. Tieing it into the codegen class enforces that the class instance be created by the user just to create a Routine. However, if you were to define one for each CodeGen class, then have a function routine that took in a language, initialized the class inside the function, then called codegen.routine, that would be fine. Actually, I think that's probably the best method - keeps it easily extensible to new languages.

@jcrist
Copy link
Member

jcrist commented Sep 23, 2014

Thanks for taking care of this, the codegen stuff is a bit messy and needs more cleanup than I did in my first pass.

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 24, 2014

@jcrist How about this? In the other pr, OctaveCodeGen has its own .routine

It looks like a big change, but its just a copy-paste of the existing Routine.__init__ code.

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 24, 2014

Ok, please review. I can rebase commits a bit before merging (if wanted).

@cbm755 cbm755 changed the title [WIP] refactor for Codegen Routine refactor for Codegen Routine Sep 29, 2014
CodeGenArgumentListError, Result, ResultBase, CCodeGen
)
from sympy.utilities.codegen import routine as Routine
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be explicit with this change. Disguising the function as a class doesn't seem like a good idea to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On 30/09/14 03:38, Jim Crist wrote:

I think we should be explicit with this change.

Agree, done.

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 30, 2014

Perhaps rout or something else? the_routine doesn't sound quite right.

rout looks rather like "R Out". Is this a good enough reason to call the friendly function something else? assemble_routine(), make_routine()? This might be nicer:

routines = []
routine = assemble_routine(name, expr, ...)
routines.append(routine)
...
for routine in routines:
     ...

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 30, 2014

Why can't these all be in the same import? Not super important though.

Should be fixed.

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 30, 2014

I've looked at Result a bit more and it seems there are indeed language-specific assumptions made there. For example, it is not possible to give one a name, rather it automatically generates a hash name. This is fine for C/Fortran but not good for Octave which doesn't have return (blah) but rather has named return values.

Currently I'm (ab)using OutputArguments for Octave return values. I assume the "proper" thing is to fix Result? firstly by subclassing from Variable.

I assume OutputArguments should be only used for "rhs-like" stuff, stuff that should be an argument but for pointers.

@cbm755
Copy link
Contributor Author

cbm755 commented Sep 30, 2014

I've added input checking for Routine init in 4dcaa33. @jcrist does that look about right?

@jcrist
Copy link
Member

jcrist commented Sep 30, 2014

rout looks rather like "R Out". Is this a good enough reason to call the friendly function something else? assemble_routine(), make_routine()?

Two options then, leaving it up to you. Either name the routine function something else (I like make_routine best), or just import it as make_routine to the autowrap file, and leave the name the same. Although I suppose that wouldn't work in codegen. However, having a variable in a function called routine is fine if the function doesn't call the routine function. Scoped variables and all.

I assume OutputArguments should be only used for "rhs-like" stuff, stuff that should be an argument but for pointers.

In my mind the distinction is this: Result should be things that are returned. func(x, y) -> (x + y) returns x + y. This means that it can be used in a larger expression as a representation of this calculation, and still have everything work. OutputArguments can't, because they are modified inplace. So using them for everything in Octave may work, but it's not the best.

I assume the "proper" thing is to fix Result? firstly by subclassing from Variable.

That could maybe work. Ideally Result could have an optional name, and an expression that is being returned. That way it could work with C or Octave. Or you could just give it a junk name. Something like "return".

@cbm755
Copy link
Contributor Author

cbm755 commented Oct 1, 2014

@jcrist commit 1014510 has my attempt at Result changes. Codegen will need a way to tell the difference between auto-named and user-named, so I subclassed a NamedResult. This works well for Octave.

C/Fortran are not effected. If you give them a NamedResult, they should treat it same as Result, although I didn't add a test for that (should I?)

@cbm755
Copy link
Contributor Author

cbm755 commented Oct 1, 2014

Rebased, hopefully easier to understand. No overall changes.

# Check that all symbols in the expressions are covered by
# InputArguments/InOutArguments---subset because user could
# specify additional (unused) InputArguments or local_vars.
assert symbols.issubset(input_symbols.union(local_vars))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do better than an assert for this, and throw an actual error message that will be more meaningful to the users.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do better than an assert for this

done.

@cbm755
Copy link
Contributor Author

cbm755 commented Oct 10, 2014

Ok, I have removed NamedResult.

After a previous discussion with @moorepants, I'm unsure whether I should merge or rebase for the merge conflict. @jcrist: Preference? if not, I will rebase.

@jcrist
Copy link
Member

jcrist commented Oct 14, 2014

Looks good to me. It would be nice to squash some of these commits together (specifically to remove the unused NamedResult history). Squashing will lose some of the line comments on github, which is why it should be avoided if possible. In this case I think it should be done though. For future cases, simply merging to fix the conflict is preferred.

@cbm755
Copy link
Contributor Author

cbm755 commented Oct 14, 2014

rebase done, no changes, just some squashing.

@jcrist
Copy link
Member

jcrist commented Oct 14, 2014

Will merge in 24 hours if no dissents.

precision -- FIXME
"""Return a new variable.

name : Symbol or MatrixSymbol
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this missing:

Parameters
==========

?

@jcrist
Copy link
Member

jcrist commented Oct 14, 2014

@moorepants (since you're looking at it right now), and others: I'm +1 on this, but have one nagging thought. The old Routine class did a lot of magic beforehand that will be taken out and moved to a separate function in this PR. This is good. However, anyone that was relying on this magic being in the class Routine will have broken code after this PR.

In general I think this is unavoidable. Further, I don't think anyone uses this functionality anyway. codegen, autowrap, and ufuncify (the major user interfaces to this submodule) won't change, but "expert" users will have a different interface than they did before this PR. I don't think we need (and am actually against) a deprecation warning on this. Something in the release notes would be good though.

@moorepants
Copy link
Member

I fine with a nice big release note warning. The advanced users would be likely to be using the master branch and would notice this. I have no good idea about how much use of Routine is in the wild.

@bjodah What do you think of this? No deprecation cycle?

@bjodah
Copy link
Member

bjodah commented Oct 15, 2014

👍 I'm fine with just a warning. It's nice to see the codegen stuff moving forward - good job!

@jcrist
Copy link
Member

jcrist commented Oct 15, 2014

There are merge conflicts (I assume from the PR that Jason just merged). Please fix them (could also take this time to squash your last 3 fix-it commits together, but only if you feel like it). I'll merge once that's done.

Put the existing Fortran/C `Routine.__init__` into Codegen class.
Essentially unchanged.  Codegen will now make appropriate instances
of Routine.  Routine is still essentially language agnostic, although
a particular instance might be more appropriate for a particular
Codegen.
Lines to 75 chars, follow numpy style.  Some pylint fixes.
Slightly simplify Argument and its subclasses.
1.  Result subclasses Variable so it has a name.  By default, name
    and result_var get the dummy "result_" symbol.  This was already
    the case for result_var.

2.  Add name and result_var kwargs: name defaults to None and
    result_var defaults to name.

3.  Result can work with Matrix class.  Result can take dimensions
    kwarg.  Maybe not allowed in C/Fortran but others languages might
    allow this.

4.  Document the difference between name and result_var.  Perhaps
    these could/should be refactored, but for now, document that they
    are usually the same thing.
@cbm755
Copy link
Contributor Author

cbm755 commented Oct 15, 2014

Ok, rebased. Please wait for tests to complete (the other merge meant more Routine->make_routine changes, want to make sure I caught them all).

@jcrist
Copy link
Member

jcrist commented Oct 16, 2014

Merging. @cbm755, please add something in the release notes about this change. Thanks for your work!

jcrist added a commit that referenced this pull request Oct 16, 2014
@jcrist jcrist merged commit 1868312 into sympy:master Oct 16, 2014
@cbm755 cbm755 deleted the routine_refactor branch October 16, 2014 21:27
@cbm755
Copy link
Contributor Author

cbm755 commented Oct 16, 2014

please add something in the release notes about this change.

Ok, done, although might be a bit verbose for what is likely a minor issue! Feel free to edit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants