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

LockableKnob init fix #193

Merged
merged 6 commits into from
Mar 1, 2023
Merged

Conversation

mjaskula
Copy link
Collaborator

@mjaskula mjaskula commented Nov 9, 2022

The range for setting the initial value of a LockableKnob was unclear and hard to use. This PR attempts to alleviate both of these issues. In addition it updates the Turing machine and knob playground to support these changes.

Details:

The internal representation of a LockableKnob's value uses the full AnalogueReader range of 0-MAX_UINT16. This was unclear in the LockableKnob's documentation and api. To fix this we've updated the API to make it clear how the value is being used by giving two possible ways. First is the original full int range, second is a percentage. The int range will be useful when saving and loading a knob value. The percentage will be more useful when hard coding a knobs initial state.

I've again included the 'KnobPlayground' script to aid in PR review and testing. It should be removed before merge.

@mjaskula mjaskula self-assigned this Nov 15, 2022
Copy link
Collaborator

@awonak awonak left a comment

Choose a reason for hiding this comment

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

Overall looks good, nice documentation and examples. The one area I wanted to discuss was to explore improving the API interface for selecting from a list of choices by configuring the knob with the length of choices instead of requiring the user to perform the percentage calculations.

.with_locked_knob("scale", initial_percentage_value=initial_scale_percent)
.with_locked_knob(
"length",
initial_percentage_value=(self.LENGTH_CHOICES.index(initial_length) * 2 + 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

[discussion] I think it would make more sense to take len(CHOICES) and do percent calculations internally. From a user perspective, I think using a percent as an input for selecting a choice from a list is less clear than configuring the lockable knob to choose from value from a range of len(CHOICES).

Why not accept either len(CHOICES) as the configuration input and do the percentage calculations internally?

Perhaps I don't fully understand the problem you encountered that inspired this change, but I do still see value in simplifying the API for usability sake with CHOICE knobs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So I did start going down this road earlier in the development of LockableKnob but I backed off of it because of the flexibility that the Knob api allows. Specifically, the api allows the client to read the knob for any number of choices at any time. So given that, saving the value for 'choice 2' felt weird to me.

That said, thinking about your suggestion more and looking at this code here, I think that you are right and we could make a 'choices' api for lockable knob that would make sense and be way cleaner than this mess.

I think that this change would be an improvement beyond the scope of this PR however, would you be ok with it coming in a followup PR?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I've found knobs to mostly represent "int", "percent", or "choice". If LockableKnob had an interface for each of those, I think that would help with the API clarity and usability.

self.kb2 = (
KnobBank.builder(k2)
.with_disabled_knob()
.with_locked_knob("p4", initial_percentage_value=0.5, threshold_from_choice_count=7)
Copy link
Collaborator

Choose a reason for hiding this comment

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

[optional] nit: If you define choice_p4 as a instance variable and use len(choice_p4) here, that will remove magic numbers and make the example more clear.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The intention is that this file isn't merged into the repo. I'll remove it after approval.

self,
knob: Knob,
initial_percentage_value=None,
initial_uint16_value=None,
Copy link
Collaborator

Choose a reason for hiding this comment

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

[optional] nit: This is Python, just int is fine, since there is no other int type. If the concern is clearly communicating a max value of uint16, that could be in the documentation. That might make the api interface a little more pythonic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The naming of this comes directly from the MAX_UINT16 constant in europi.py. And yes the intention is to describe this parameter as much more constrained than an int. I agree that the name is verbose, however the problem that this PR is trying to resolve is the confusion over exactly what this value represents. Putting it in the parameter name is my way of solving that.

This makes the values used in initial knob setup more clear.
add ability to set the initial value in the TM class. Use this to more clearly setup the inital state of the locked knob.
@mjaskula
Copy link
Collaborator Author

I am workin on resolving these conflicts.

Copy link
Collaborator

@awonak awonak left a comment

Choose a reason for hiding this comment

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

LGTM. I think the knob playground will be helpful to get more folks interested in leveraging that package in their scripts, perhaps move it into the experimental folder or somewhere so it doesn't get lost?

We'd like to make this available, but there seems to be a memory
allocation issue when adding more scripts. This will be addressed in a
different PR.
@mjaskula mjaskula merged commit af789e2 into Allen-Synthesis:main Mar 1, 2023
@mjaskula mjaskula deleted the mjj/knob_init_fix branch March 1, 2023 20:42
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

2 participants