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

Engineering Design Interface (EDI) Contrib Package #2937

Open
wants to merge 78 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
b354844
initial commit for EDI
Jul 27, 2023
3377110
adding coloring to the readme
Jul 27, 2023
604b0a1
correcting the readme example
Jul 27, 2023
eed941f
fixing readme again
Jul 27, 2023
f5a3232
fixing readme again again
Jul 27, 2023
d2696b6
fixing readme again again again
Jul 27, 2023
eba2990
updating readme, I really should read...
Jul 27, 2023
f625ef2
updating some legal stuff
Jul 27, 2023
b8dd90e
fixing the readme
Jul 27, 2023
4603e40
adding Michaels help:
Jul 27, 2023
39ea960
working on unit tests
Jul 27, 2023
b818da7
Merge remote-tracking branch 'upstream/main' into edi_dev
Jul 27, 2023
fe2821f
minor fixes
Jul 27, 2023
550fb70
still writing tests
Jul 28, 2023
f3d306f
working on documentation
Jul 31, 2023
ab02aba
still documenting
Jul 31, 2023
4e3f1d1
formulation unit testing finished
Jul 31, 2023
d62b011
variable docs done i think
Aug 1, 2023
39a5211
fixing the unit tests
Aug 1, 2023
09064b4
updating with an init file
Aug 1, 2023
df6336b
trying a testing fix
Aug 1, 2023
b369e68
working on runtime constraint docs
Aug 2, 2023
e594986
Merge remote-tracking branch 'upstream/main' into edi_dev
Aug 2, 2023
3a7918b
black box constraint docs good enough
Aug 2, 2023
a1049a8
docs done I think
Aug 2, 2023
816a022
more testing
Aug 3, 2023
871014c
finalizing for PR
Aug 3, 2023
6c4ef32
adding black
Aug 3, 2023
a6cde71
typos in docs
Aug 3, 2023
f76f497
addressing concerns in PR
Aug 8, 2023
7542063
adding black, part 2
Aug 8, 2023
b75d75f
undoing black
Aug 8, 2023
e5fbc0e
fixing imports
Aug 8, 2023
10d6845
fixing headers and staging for PR
Aug 8, 2023
6df90fd
applying black 3
Aug 8, 2023
cc683cb
fixing the aircraft GP example
Aug 8, 2023
2acc63e
trying to fix the import error
Aug 8, 2023
fd0c45b
adding a conditional wrapper to the pynumero import
Aug 8, 2023
7a58723
forgot an import statement, fixing
Aug 8, 2023
e769553
trying another import fix
Aug 9, 2023
4ebe52a
forgot to add black
Aug 9, 2023
48abb03
still updating imports
Aug 9, 2023
ca94021
Merge remote-tracking branch 'upstream/main' into edi_dev
Aug 9, 2023
085e729
Merge remote-tracking branch 'upstream/main' into edi_dev
Aug 29, 2023
36b99f9
changed the init file, not sure what I did
Aug 29, 2023
4381d3b
Merge remote-tracking branch 'upstream/main' into edi_dev
Aug 31, 2023
98c3ef6
Merge branch 'Pyomo:main' into edi_dev
codykarcher Aug 31, 2023
7635017
adding black to the init file
Sep 5, 2023
2d4a0ed
Merge branch 'Pyomo:main' into edi_dev
codykarcher Sep 5, 2023
2c48406
Merge branch 'Pyomo:main' into edi_dev
codykarcher Sep 18, 2023
29dd11b
fixing a unit test
Sep 18, 2023
871c8ed
Merge branch 'Pyomo:main' into edi_dev
codykarcher Oct 18, 2023
13c58af
Merge branch 'main' into edi_dev
blnicho Oct 31, 2023
ba8c1f3
Merge branch 'Pyomo:main' into edi_dev
codykarcher Nov 8, 2023
ae6c1be
Merge branch 'Pyomo:main' into edi_dev
codykarcher Nov 8, 2023
f186d89
Merge branch 'Pyomo:main' into edi_dev
codykarcher Nov 15, 2023
7acdac4
Merge branch 'Pyomo:main' into edi_dev
codykarcher Dec 6, 2023
f18548d
encountered sierra bug, caching work
Dec 11, 2023
1237116
updating the black box tests to pass
Dec 11, 2023
782696f
figuring out what Im doing
Mar 7, 2024
13bc460
Merge branch 'Pyomo:main' into edi_dev
codykarcher Mar 7, 2024
e07dce3
needed to pip upgrade black
Mar 7, 2024
1850267
adding a todo list
Mar 7, 2024
54d50eb
Merge branch 'Pyomo:main' into edi_dev
codykarcher Aug 20, 2024
7def60b
finally updating EDI
Aug 20, 2024
28df353
fixing documentation and typos
Aug 20, 2024
e255302
had an outdated version of black
Aug 20, 2024
65f23dd
removing broken links from the readme
Aug 20, 2024
d3b8dcd
Merge branch 'main' into edi_dev
codykarcher Aug 20, 2024
ef135d1
actualy removing links this time
Aug 20, 2024
1fb0c8d
should be ready for reveiw?
Sep 27, 2024
3a2ea94
Merge branch 'Pyomo:main' into edi_dev
codykarcher Sep 27, 2024
ac487b8
fixing dependency issue
Sep 27, 2024
808483f
adding black
Sep 27, 2024
2342baa
updating a python 3.8 compatibilty issue
Sep 27, 2024
42d2357
Merge branch 'main' into edi_dev
mrmundt Oct 4, 2024
b101ab4
Merge branch 'Pyomo:main' into edi_dev
codykarcher Oct 19, 2024
0ef183f
Merge branch 'Pyomo:main' into edi_dev
codykarcher Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ gurobi.log

# Jupyterhub/Jupyterlab checkpoints
.ipynb_checkpoints
cplex.log
cplex.log

# Mac tracking files
*.DS_Store*
37 changes: 37 additions & 0 deletions doc/OnlineDocs/contributed_packages/edi/additionaltips.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Additional Tips
---------------

* Developers may need to install the following additional packages:

::

pip install pytest
pip install pytest-cov
pip install sphinx
pip install sphinx_rtd_theme
pip install sphinx_copybutton


* If you wish to build the documentation locally, use:

::

cd <path_to_pyomo>/pyomo/doc/OnlineDocs
make html

then open the file ``<path_to_pyomo/doc/OnlineDocs/_build/html/index.html>``

Comment on lines +1 to +23
Copy link
Member

Choose a reason for hiding this comment

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

Most of this seems generic and not specific to EDI. Should this get moved to the "contribution" section of Pyomo's documentation?

There are also some build options that can be specified when pip installing Pyomo that will grab the packages needed to run tests or build documentation. Maybe we should point the users to those rather than manually listing packages? I'm mainly concerned that this list could become out of sync with the requirements specified in setup.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

setup.py does not include pytest-cov
https://github.com/Pyomo/pyomo/blob/main/setup.py#L232

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Current documentation only lists:

pip install 'pyomo[optional]'

but it is not clear if a developer would also have to run the following

pip install 'pyomo[tests]'
pip install 'pyomo[docs]'


* Unit tests and coverage can be run locally using:

::

cd <path_to_pyomo>/pyomo/pyomo/contrib/edi
pytest --cov-report term-missing --cov=pyomo.contrib.edi -v ./tests/

or generating html output:

::

cd <path_to_pyomo>/pyomo/pyomo/contrib/edi
pytest --cov-report html --cov=pyomo.contrib.edi -v ./tests/
Comment on lines +25 to +37
Copy link
Member

Choose a reason for hiding this comment

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

Similar to my previous comment, maybe it would be more beneficial to add a section to the contribution guide on how to run tests for a specific subset of the repo.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with this - and it shows a miss in our documentation. We should table this for after the doc-reorg.

115 changes: 115 additions & 0 deletions doc/OnlineDocs/contributed_packages/edi/advancedruntimeconstraints.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
Advanced Runtime Constraints
============================


Automated unpacking for multi-use black-boxes
Copy link
Member

Choose a reason for hiding this comment

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

We should have a design discussion about the functionality described in this section. There has to be a better way to support both scalar and vectorized operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file has been removed from the doc tree

---------------------------------------------

Coding a black-box model often represents a significant effort, and it is therefore desirable to have the black-box work in many situations. A common case is to have a black-box model with a scalar input variable perform vectorized operations, ie, take in a vector and return a vector. In the more general case, this can be thought of as passing in multiple run-cases as input to the black-box model.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Coding a black-box model often represents a significant effort, and it is therefore desirable to have the black-box work in many situations. A common case is to have a black-box model with a scalar input variable perform vectorized operations, ie, take in a vector and return a vector. In the more general case, this can be thought of as passing in multiple run-cases as input to the black-box model.
Coding a black-box model often represents a significant effort, and it is therefore desirable to have the black-box work in many situations. A common case is to have a black-box model with a scalar input variable perform vectorized operations, i.e., take in a vector and return a vector. In the more general case, this can be thought of as passing in multiple run-cases as input to the black-box model.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file has been removed from the documentation


The ``parseInputs()`` method enables this batch-like capability in a variety of forms:

.. py:function:: BlackBoxFunctionModel.parseInputs(self, *args, **kwargs)

Parses the inputs to a black-box model into a list of run-cases

:param args: The self attribute in all python methods
:type self: black-box model
:param args: index passed arguments
Comment on lines +16 to +18
Copy link
Member

Choose a reason for hiding this comment

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

args argument listed twice here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this file has been removed from the doc tree

:type args: list or tuple
:param kwargs: keyword passed arguments
:type kwargs: dict

:return: runcases
:rtype: list
:return: returnMode
:rtype: int
:return: extras
:rtype: list
Comment on lines +12 to +28
Copy link
Member

Choose a reason for hiding this comment

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

Make this a docstring instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed above



The function definition is not particularly helpful, so let's dive in a bit. For the typical user, we recommend that the top of all ``BlackBox()`` methods appear as follows:

.. literalinclude:: ../../../../pyomo/contrib/edi/tests/test_docSnippets.py
:language: python
:dedent: 12
:start-after: # BEGIN: AdvancedRTC_Snippet_02
:end-before: # END: AdvancedRTC_Snippet_02


Essentially, ``parseInputs()`` is a pre-processor that directly takes the inputs of the black-box. The ``parseInputs()`` method will check all of the inputs, ensure that size and units are correct, split into run cases as appropriate, and return a run-cases list that is ready to operate on.

The ``runCases`` return (which can be named as any valid python name) is a list of dicts, where the keys to the dict are the names of the inputs declared in the ``__init__()`` method. Ex: ``runCases[0]['x']`` will give the ``'x'`` input (in units specified in the ``__init__()`` method) in the first run-case.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
The ``runCases`` return (which can be named as any valid python name) is a list of dicts, where the keys to the dict are the names of the inputs declared in the ``__init__()`` method. Ex: ``runCases[0]['x']`` will give the ``'x'`` input (in units specified in the ``__init__()`` method) in the first run-case.
The ``runCases`` return (which can be named as any valid Python name) is a list of dicts, where the keys to the dict are the names of the inputs declared in the ``__init__()`` method. Ex: ``runCases[0]['x']`` will give the ``'x'`` input (in units specified in the ``__init__()`` method) in the first run-case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file has been removed from the doc tree


The ``returnMode`` return (which can be named as any valid python name) is an integer that indicates how the return should be processed. If ``returnMode`` is passed as a ``kwarg``, then the passed in value will be cast to this output. If it is not passed in, then ``returnMode`` will be either ``-1*self.availableDerivative``, indicating that there is only a single run case, or ``self.availableDerivative`` which indicated multiple run cases. A negative value for ``returnMode`` indicates that there will be one less layer of indexing in the output.

The ``extras`` return (which can be named as any valid python name) is a dict that will include all of the additional passed in values not expected by the black-box model. The extra ``kwargs`` will appear as normal, and extra ``args`` get put in a list in ``extras['remainingArgs']``. If you pass in a ``kwarg`` with key name ``'remainingArgs'``, it will be overwritten. The extras dict is the place to find options that may affect the code (ex: tolerances, run modes, etc) that are not expected inputs to the black-box model.

Note that when using run case input, the output will always take the following unpacking structure:

::

output[<run_case_index>][0] = <list_of_outputs_for_specified_runcase>
output[<run_case_index>][0][<index_of_output>] = <output_for_specified_runcase>

output[<run_case_index>][1] = <list_of_jacobians_for_specified_runcase>
output[<run_case_index>][1][<index_of_output>][<index_of_input>] = <d(output_of_specified_index)/d(input_of_specified_index)>


There is **not** a shortcut for single scalar output black boxes as is the case when not using run cases, the final index to output 0 must be included.



An Example
++++++++++

There are many ways this functionality can be used, we provide an example here to get new users started

.. literalinclude:: ../../../../pyomo/contrib/edi/tests/test_docSnippets.py
:language: python
:dedent: 8
:start-after: # BEGIN: AdvancedRTC_Snippet_01
:end-before: # END: AdvancedRTC_Snippet_01


Check outputs
-------------

There is a ``checkOutputs()`` method that is not supported in the current version. Contact the developers if you desire this functionality, but the following the practices described in this documentation should render the need for this moot.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
There is a ``checkOutputs()`` method that is not supported in the current version. Contact the developers if you desire this functionality, but the following the practices described in this documentation should render the need for this moot.
There is a ``checkOutputs()`` method that is not supported in the current version. Contact the developers if you desire this functionality, but following the practices described in this documentation should render the need for this moot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file has been removed from the doc tree



Cases of non-scalar inputs or outputs
-------------------------------------

Indexing can get somewhat complicated when inputs and outputs are not scalars. Users should be warned this feature is supported, but not well tested, so please contact the developers if you encounter any unusual behavior.

The following unpacking remains the same:

::

output[0] = <list_of_outputs>
output[0][<index_of_output>] = <output>

output[1] = <list_of_jacobians>
output[1][<index_of_output>][<index_of_input>] = <d(output_of_specified_index)/d(input_of_specified_index)>

However, for outputs, the result will be an array with dimensions equal to the size of the output. For Jacobians, it breaks down as the following:

::

jacobian_list_entry[(output_dim_1_ix, output_dim_2_ix, ..., input_dim_1_ix, input_dim_2_ix, ...)] = <scalar_d(output_of_specified_index)/d(input_of_specified_index)>

For example, with an output that is 2x2 and an input that is also 2x2

::

output[1][<index_of_output>][<index_of_input>][(0,0,1,1)]

is the derivative of ``output[0,0]`` with respect to ``input[1,1]``



Tips
----

* A model summary can be printed by calling ``print(model_instance.summary)``
Loading