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

Add some fixes to the AML Documentation #132

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 11 additions & 14 deletions amlip_docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,30 @@

/rst/getting_started/project_overview


.. _index_demo:
.. _index_user_manual:

.. toctree::
:caption: Demo Examples
:caption: User Manual
:maxdepth: 2
:numbered: 5
:hidden:

/rst/demo/collaborative_learning
/rst/demo/tensor_inference
/rst/demo/rosbot2r_inference
/rst/demo/workload_distribution

Nodes </rst/user_manual/nodes/nodes>
Tools </rst/user_manual/tools/tools>
Scenarios </rst/user_manual/scenarios/scenarios>

.. _index_user_manual:
.. _index_demo:

.. toctree::
:caption: User Manual
:caption: Demo Examples
:maxdepth: 2
:numbered: 5
:hidden:

Scenarios </rst/user_manual/scenarios/scenarios>
Nodes </rst/user_manual/nodes/nodes>
Tools </rst/user_manual/tools/tools>

/rst/demo/collaborative_learning
/rst/demo/tensor_inference
/rst/demo/rosbot2r_inference
/rst/demo/workload_distribution

.. _index_developer_manual:

Expand Down
7 changes: 3 additions & 4 deletions amlip_docs/rst/demo/collaborative_learning.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Let's continue explaining the global variables.
:language: python
:lines: 24

``waiter`` is a ``WaitHandler`` that waits on a boolean value.
``waiter`` is a ``WaitHandler`` , which is an object that allows multiple threads wait, until another thread awakes them. In this case, due to being a ``BoolWaitHandler``, it waits on a boolean value.
Whenever this value is ``True``, threads awake.
Whenever it is ``False``, threads wait.

Expand Down Expand Up @@ -125,8 +125,7 @@ Model Manager Sender Node
-------------------------

This is the Python code for the :ref:`user_manual_nodes_model_sender` application.
It does not use real *AML Models*, but strings.
It does not have a real *AML Engine* but instead the calculation is an *upper-case* conversion of the string received.
It does not use real *AML Models* nor does it have a real *AML Engine* Instead, strings are sent and the calculation is an *upper-case* conversion of the string received.
It is implemented in |python| using :code:`amlip_py` API.

This code can be found `here <https://github.com/eProsima/AML-IP/blob/main/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py>`__.
Expand All @@ -145,7 +144,7 @@ Let's continue explaining the global variables.
:language: python
:lines: 23

``waiter`` is a ``WaitHandler`` that waits on a boolean value.
``waiter`` is a ``WaitHandler`` , which is an object that allows multiple threads wait, until another thread awakes them. In this case, due to being a ``BoolWaitHandler``, it waits on a boolean value.
Whenever this value is ``True``, threads awake.
Whenever it is ``False``, threads wait.

Expand Down
64 changes: 30 additions & 34 deletions amlip_docs/rst/demo/tensor_inference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ TensorFlow Inference
Background
==========

Inference refers to the process of using a trained model to make predictions or draw conclusions based on input data.
It involves applying the learned knowledge and statistical relationships encoded in the model to new, unseen data.
The inference of an image involves passing the image through a trained AI model to obtain a classification based on the learned knowledge and patterns within the model.
Inference is the process of using a trained model to make predictions or draw conclusions from new, unseen data.
It involves applying the learned knowledge and statistical relationships encoded in the model to the input data.
When inferring an image, the image is passed through a trained AI model to classify it based on the patterns and knowledge the model has learned.

This demo shows how to implement 2 types of nodes, :ref:`user_manual_nodes_inference` and :ref:`user_manual_nodes_edge`, to perform TensorFlow inference on a given image.
With these 2 nodes implemented, the user can deploy as many nodes of each kind as desired and check the behavior of a simulated |amlip| network running.
Expand Down Expand Up @@ -44,22 +44,16 @@ The demo requires the following tools to be installed in the system:

sudo apt install -y swig alsa-utils libopencv-dev
pip3 install -U pyttsx3 opencv-python
curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
# For changes to take effect, close and re-open your current shell.
conda create --name tf python=3.9
conda install -c conda-forge cudatoolkit=11.8.0
mkdir -p $CONDA_PREFIX/etc/conda/activate.d
echo 'CUDNN_PATH=$(dirname $(python3 -c "import nvidia.cudnn;print(nvidia.cudnn.__file__)"))' >> $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CONDA_PREFIX/lib/:$CUDNN_PATH/lib' >> $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
source $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
python -m venv aml-ip-venv
source aml-ip-venv/bin/activate

Ensure that you have TensorFlow and TensorFlow Hub installed in your Python environment before proceeding.
You can install them using pip by executing the following commands:
You can install them by executing the following commands:

.. code-block:: bash

pip3 install tensorflow tensorflow-hub tensorflow-object-detection-api nvidia-cudnn-cu11==8.6.0.163 protobuf==3.20.*
python3 -m pip install tensorflow[and-cuda]
pip3 install tensorflow-hub tensorflow-object-detection-api protobuf==3.20

Additionally, it is required to obtain the TensorFlow model from `TensorFlow Hub <https://tfhub.dev/>`_, follow the steps below:

Expand Down Expand Up @@ -106,7 +100,7 @@ The next block includes the Python header files that allow the use of the AML-IP
:lines: 18-19

Let's continue explaining the global variables.
The ``waiter`` allows the node to wait for the inference.
The ``waiter`` object is used to pause the node's execution until the inference result is received.
``DOMAIN_ID`` allows the execution to be isolated because only DomainParticipants with the same Domain Id would be able to communicate to each other.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/edge_node_async.py
Expand All @@ -127,9 +121,11 @@ We define the ``main`` function.

First, we create an instance of ``AsyncEdgeNode``.
The first thing the constructor gets is the given name.
Then a listener, which is an ``InferenceListenerLambda`` object is created with the function ``inference_received`` declared above.
This function is called each we receive an inference.
And also we specified the domain equal to the DOMAIN_ID variable.
Then a `listener <https://fast-dds.docs.eprosima.com/en/stable/fastdds/dds_layer/core/entity/entity.html#listener>`__,
which is an ``InferenceListenerLambda`` object, is created for the function ``inference_received`` declared above.
The listener acts as an asynchronous notification system that allows the entity to notify the application about the Status changes in the entity.
This function is called each time an inference is received.
Lastly, a ``DOMAIN_ID`` is specified, which allows the execution to be isolated.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/edge_node_async.py
:language: python
Expand All @@ -142,7 +138,7 @@ It converts the size information and the image into bytes and combines the two t
:language: python
:lines: 51-65

After that, the ``request_inference`` method is called to request the inference of the image.
Next, the ``request_inference`` method is invoked to send the image for inference.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/edge_node_async.py
:language: python
Expand All @@ -154,7 +150,7 @@ Finally, the program waits for the inference solution using ``waiter.wait``.
:language: python
:lines: 74

Once the solution is received, the execution finish.
Once the solution is received, the execution finishes.

Inference Node
--------------
Expand All @@ -172,14 +168,14 @@ The next block includes the Python header files that allow the use of the AML-IP
:lines: 19-20

Let's continue explaining the global variables.
``DOMAIN_ID`` allows the execution to be isolated because only DomainParticipants with the same Domain Id would be able to communicate to each other.
``tolerance`` sets a limit to ignore detections with a probability less than the tolerance.
The ``DOMAIN_ID`` variable allows the execution to be isolated because only DomainParticipants with the same Domain Id would be able to communicate to each other.
The ``tolerance`` variable sets a threshold to filter out detections with a probability lower than the specified tolerance value.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/inference_node_async.py
:language: python
:lines: 28-32

It loads the model from TensorFlow based on the specified path.
The model is loaded from TensorFlow using the specified path.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/inference_node_async.py
:language: python
Expand All @@ -201,22 +197,22 @@ We define the ``main`` function.

We create an instance of ``AsyncInferenceNode``.
The first thing the constructor gets is the name ``AMLInferenceNode``.
Then the listener which is an ``InferenceReplierLambda(process_inference)``.
This means calling the ``process_inference`` function to perform the inference requests.
And also we specified the domain equal to the DOMAIN_ID variable.
Then a `listener <https://fast-dds.docs.eprosima.com/en/stable/fastdds/dds_layer/core/entity/entity.html#listener>`__,
which is an ``InferenceReplierLambda`` object, is created for the function ``process_inference`` declared above.
This means that the ``process_inference`` function will be called to handle the inference requests.
Additionally, the domain is specified using the DOMAIN_ID variable.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/inference_node_async.py
:language: python
:lines: 84-87

This starts the inference node.
It will start listening for incoming inference requests and call the ``process_inference`` function to handle them.
This initiates the Inference Node, which will listen for incoming inference requests and invoke the ``process_inference`` function to handle them.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/inference_node_async.py
:language: python
:lines: 91

Finally, waits for a SIGINT signal ``Ctrl+C`` to stop the node and close it.
Finally, the node waits for a SIGINT signal (``Ctrl+C``) to stop and close gracefully.

.. literalinclude:: /../amlip_demo_nodes/amlip_tensorflow_inference_demo/amlip_tensorflow_inference_demo/inference_node_async.py
:language: python
Expand All @@ -230,7 +226,7 @@ This demo explains the implemented nodes in `amlip_demo_nodes/amlip_tensorflow_i
Run Edge Node
-------------

In the first terminal, run the Edge Node with the following command:
In one terminal, run the Edge Node with the following command:

.. code-block:: bash

Expand Down Expand Up @@ -265,7 +261,7 @@ The expected output is the following:
Run Inference Node
------------------

In the second terminal, run the following command to process the inference:
In a second terminal, run the following command to process the inference:

.. code-block:: bash

Expand Down Expand Up @@ -313,8 +309,8 @@ The execution expects an output similar to the one shown below:
what(): SWIG director method error. In method 'process_inference': AttributeError: module 'tensorflow' has no attribute 'gfile'
Aborted (core dumped)

Next steps
----------
Results
-------

Based on the information acquired, we have successfully generated the next image:

Expand Down Expand Up @@ -351,7 +347,7 @@ Check following `issue <https://github.com/tensorflow/tensorflow/issues/31315>`_

To update the code, please follow these `steps <https://stackoverflow.com/questions/55591437/attributeerror-module-tensorflow-has-no-attribute-gfile>`_:

1. Locate the file `label_map_util.py`. (default path: ``.local/lib/python3.10/site-packages/object_detection/utils/label_map_util.py``)
1. Locate the file `label_map_util.py`. (default path: ``.local/lib/python3.x/site-packages/object_detection/utils/label_map_util.py``)
2. Navigate to line 132 within the file.
3. Replace `tf.gfile.GFile` with `tf.io.gfile.GFile`.

Expand Down
6 changes: 3 additions & 3 deletions amlip_docs/rst/demo/workload_distribution.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The nodes are implemented in both Python and C++, illustrating how to instantiat
The purpose of this demo is to illustrate how a *Main Node* dispatches jobs to a *Computing Node* and how the *Computing Node* processes them.
The *Main Node* waits until a *Computing Node* is available to handle the job, while the *Computing Node* awaits a job to solve.

In this demo, the actual :term:`AML` Engine is not provided, and it is mocked.
In this demo, the actual :term:`AML` Engine is simulated using a mock implementation.
This *Mock* simulates a difficult calculation by converting a string to uppercase and randomly waiting between
1 and 5 seconds in doing so.

Expand Down Expand Up @@ -75,8 +75,8 @@ Computing Node
--------------

This node simulates a :ref:`user_manual_nodes_computing`.
It does not use real *AML Jobs*, but strings.
It does not have a real *AML Engine* but instead the calculation is an *upper-case* conversion of the string received.
It processes simple string tasks rather than real *AML Jobs*.
Instead of using a real *AML Engine*, it performs a mock computation by converting the received string to uppercase.
It is implemented in |cpp| using :code:`amlip_cpp` API.

The code can be found `here <https://github.com/eProsima/AML-IP/blob/main/amlip_demo_nodes/amlip_workload_distribution_demo/computing_node_sync.cpp>`__.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ If using colcon_, use the following command to source them:

.. code-block:: bash

source <eprosima-dependencies-installation-path>/install/setup.bash
source <eprosima-dependencies-installation-path>/install/setup.bat


Installation methods
Expand Down
4 changes: 2 additions & 2 deletions amlip_docs/rst/getting_started/project_overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Project Overview

|eamlip| is a communications framework in charge of data exchange between :term:`AML` nodes
through local or remote networks.
It is designed to allow non-experts users to create and manage a cluster of AML nodes to exploit the distributed and concurrent learning capabilities of AML.
It is designed to allow non-expert users to create and manage a cluster of AML nodes to exploit the distributed and concurrent learning capabilities of AML.
Thus, AML-IP is a communication framework that abstracts the transport protocols from the user, creating a platform that communicates each node without requiring the user to be concerned about communication issues.
It also allows the creation of complex distributed networks with one or multiple users working on the same problem.

Expand Down Expand Up @@ -69,7 +69,7 @@ The API, implementation and testing of this part of the code can be found mainly
Python
------

This is the programming language though to be used by a final user.
This is the programming language thought to be used by a final user.
|python| has been chosen as it is easier to work with state-of-the-art :term:`ML` projects.

Nodes and classes that the user needs to instantiate in order to implement their own code are parsed from |cpp| by using |swig| tool, giving the user a |python| API.
Expand Down
12 changes: 6 additions & 6 deletions amlip_docs/rst/user_manual/nodes/agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This tool is developed and maintained by `eProsima` which enables the connection
DDS entities such as publishers and subscribers deployed in one geographic location and using a dedicated local network will be able to communicate with other DDS entities deployed in different geographic areas on their own dedicated local networks as if they were all on the same network.

This node is in charge of communicating a local node or AML-IP cluster with the rest of the network in WANs.
It centralizes the WAN discovery and communication, i.e. it is the bridge for all the nodes in their LANs with the rest of the AML-IP components.
It serves as the central hub for WAN discovery and communication, acting as a bridge that connects all nodes within their respective LANs to the broader AML-IP network.

.. figure:: /rst/figures/agent_nodes.png
:align: center
Expand All @@ -32,7 +32,7 @@ Steps
-----

* Create a new :code:`eprosima::ddspipe::participants::types::Address` object with the address port, external address port, :term:`IP` address and transport protocol.
* Instantiate the ``ClientNode`` creating an object of such class with a name, a connection address and a domain.
* Instantiate the ``ClientNode`` creating an object of this class with a name, a connection address and a domain.
* Wait until ``Ctrl+C``.

.. tabs::
Expand Down Expand Up @@ -97,7 +97,7 @@ Steps
-----

* Create a new :code:`eprosima::ddspipe::participants::types::Address` object with the address port, external address port, :term:`IP` address and transport protocol.
* Instantiate the ``ServerNode`` creating an object of such class with a name, a listening address and a domain.
* Instantiate the ``ServerNode`` creating an object of this class with a name, a listening address and a domain.
* Wait until ``Ctrl+C``.

.. tabs::
Expand All @@ -114,7 +114,7 @@ Steps
eprosima::ddspipe::participants::types::TransportProtocol::udp);

// Create Server Node
eprosima::amlip::node::agent::ServerNode Client_node(
eprosima::amlip::node::agent::ServerNode Server_node(
"CppServerNode_Manual",
{ listening_address },
200);
Expand Down Expand Up @@ -152,7 +152,7 @@ Steps
Repeater Node
*************

A Repeater Node can be used to repeat messages between networks, that is, the message will be forwarded using the same network interface. This is useful to communicate across LANs.
A Repeater Node is utilized to forward messages between different networks, effectively repeating the message using the same network interface. This functionality is particularly useful for facilitating communication across multiple LANs.

.. figure:: /rst/figures/agent_nodes_repeater.png
:align: center
Expand All @@ -162,7 +162,7 @@ Steps
-----

* Create a new :code:`eprosima::ddspipe::participants::types::Address` object with the address port, external address port, :term:`IP` address and transport protocol.
* Instantiate the ``RepeaterNode`` creating an object of such class with a name, a listening address and a domain.
* Instantiate the ``RepeaterNode`` creating an object of this class with a name, a listening address and a domain.
* Wait until ``Ctrl+C``.

.. tabs::
Expand Down
Loading
Loading