Articles on demvessias's Bloghttps://blogs.python-gsoc.orgUpdates on different articles published on demvessias's BlogenMon, 23 Aug 2021 19:45:51 +0000Google Summer of Code Final Work Producthttps://blogs.python-gsoc.org/en/demvessiass-blog/google-summer-of-code-final-work-product-3/<a href="https://summerofcode.withgoogle.com/projects/#6653942668197888"><img alt="gsoc" height="50" src="https://developers.google.com/open-source/gsoc/resources/downloads/GSoC-logo-horizontal.svg"></a> <a href="https://summerofcode.withgoogle.com/projects/#6653942668197888"><img height="45" src="https://www.python.org/static/community_logos/python-logo.png"></a> <a href="https://fury.gl/latest/community.html"><img alt="fury" height="45" src="https://python-gsoc.org/logos/FURY.png"></a> <h1>Google Summer of Code 2021 Final Work Product</h1> <ul> <li><strong>Name:</strong> Bruno Messias</li> <li><strong>Organisation:</strong> Python Software Foundation</li> <li><strong>Sub-Organisation:</strong> FURY</li> <li><strong>Project:</strong> A system for collaborative visualization of large network layouts using FURY</li> </ul> <h2>Abstract</h2> <p>We have changed some points of my project in the first meeting. Specifically, we focused the efforts into developing a streaming system using the WebRTC protocol that could be used in more generic scenarios than just the network visualization. In addition to that, we have opted to develop the network visualization for fury as a separated repository and package available <a href="https://github.com/fury-gl/helios">here</a>. The name Helios was selected for this new network visualization system based on the Fury rendering pipeline.</p> <h2>Proposed Objectives</h2> <ul> <li>Create a streaming system (stadia-like) for FURY <ul> <li>Should work in a low-bandwidth scenario</li> <li>Should allow user interactions and collaboration across the Internet using a web-browser</li> </ul></li> <li>Helios Network System objectives: <ul> <li>Implement the Force-Directed Algorithm with examples</li> <li>Implement the ForceAtlas2 algorithm using cugraph with examples</li> <li>Implement Minimum-Distortion Embeddings algorithm (PyMDE) and examples</li> <li>Non-blocking network algorithms computation avoiding the GIL using the Shared Memory approach</li> <li>Create the documentation and the actions for the CI</li> </ul></li> <li>Stretch Goals: <ul> <li>Create an actor in FURY to draw text efficiently using shaders</li> <li>Add support to draw millions of nodes using FURY</li> <li>Add support to control the opengl state on FURY</li> </ul></li> </ul> <h2>Objectives Completed</h2> <ul> <li><h3>Create a streaming system (stadia-like) for FURY</h3> <p>There are several reasons to have a streaming system for data visualization. Because I am doing my Ph.D. in a developing country I always need to think of the less expensive solutions to use the computational resources available. For example, with the GPU’s prices increasing, it is necessary to share the a single machine with GPU with other users at different locations.</p> <p>To construct the streaming system for my project we have opted to follow three main properties and behaviors:</p> <ol> <li>avoid blocking the code execution in the main thread (where the vtk/fury instance resides)</li> <li>work inside of a low bandwidth environment</li> <li>make it easy and cheap to share the rendering result. For example, using the free version of <code>ngrok</code></li> </ol> <p>To achieve the first property we need to circumvent the GIL and allow python code to execute in parallel. Using the threading module alone is not good enough to attain real pralellism as Python calls in the same process can not execute concurrently. In addition to that, to achieve better organization it is desirable to define the server system as an uncoupled module from the rendering pipeline. Therefore, I have chosen to employ the multiprocessing approach for that. The second and third property can be only achieved choosing a suitable protocol for transfering the rendered results to the client. We have opted to implement two streaming protocols: the MJPEG and the WebRTC. The latter is more suitable for low-bandwidth scenarios [1].</p> <p>The image below shows a simple representation of the streaming system.</p> <p><img alt="..." height="400" src="https://user-images.githubusercontent.com/6979335/121934889-33ff1480-cd1e-11eb-89a4-562fbb953ba4.png"></p> <p>The video below shows how our streaming system works smottly and can be easily integrated inside of a Jupyter notebook.</p></li> </ul> <p><a href="https://user-images.githubusercontent.com/6979335/130284952-2ffbf117-7119-4048-b7aa-428e0162fb7a.mp4">Video: WebRTC Streaming + Ngrok</a></p> <p><a href="https://user-images.githubusercontent.com/6979335/130284261-20e84622-427e-4a59-a46f-6a33f5473025.mp4">Video: WebRTC Streaming + Jupyter</a></p> <p><em>Pull Requests:</em> * https://github.com/fury-gl/fury/pull/480</p> <ul> <li><h3>2D and 3D marker actor</h3> <p>This feature gave FURY the ability to efficiently draw millions of markers and impostor 3D spheres. This feature was essential for the development of Helios. This feature work with signed distance fields (SDFs) you can get more information about how SDFs works here [4] .</p> <p>The image bellow shows 1 million of markers rendered using an Intel HD graphics 3000.</p></li> </ul> <p><img src="https://user-images.githubusercontent.com/6979335/116004971-70927780-a5db-11eb-8363-8c0757574eb4.png"></p> <ul> <li><h3>Fine-Tunning the OpenGl State</h3> <p>Sometimes users may need to have finer control on how OpenGL will render the actors. This can be useful when they need to create specialized visualization effects or to improve the performance.</p> <p>In this PR I have worked in a feature that allows FURY to control the OpenGL context created by VTK</p> <p><em>Pull Request:</em></p> <ul> <li>https://github.com/fury-gl/fury/pull/432</li> </ul></li> <li><h3>Helios Network Visualization Lib: Network Layout Algorithms</h3> <p><strong>Case 1:</strong> Suppose that you need to monitor a hashtag and build a social graph. You want to interact with the graph and at the same time get insights about the structure of the user interactions. To get those insights you can perform a node embedding using any kind of network layout algorithm, such as force-directed or minimum distortion embeddings.</p> <p><strong>Case 2:</strong> Suppose that you are modelling a network dynamic such as an epidemic spreading or a Kuramoto model. In some of those network dynamics a node can change the state and the edges related to the node must be deleted. For example, in an epidemic model a node can represent a person who died due to a disease. Consequently, the layout of the network must be recomputed to give better insights.</p> <p>In the described cases, if we want a better (UX) and at the same time a more practical and insightful application of Helios, the employed layout algorithms should not block any kind of computation in the main thread.</p> <p>In Helios we already have a lib written in C (with a python wrapper) which performs the force-directed layout algorithm using separated threads avoiding the GIL problem and consequently avoiding blocking the main thread. But what about the other open-source network layout libs available on the internet? Unfortunately, most of those libs have not been implemented like Helios force-directed methods and consequently, if we want to update the network layout the Python interpreter will block the computation and user interaction in your network visualization.</p> <p>My solution for having PyMDE and CuGraph-ForceAtlas not blocking the main thread was to break the network layout method into two different types of processes: A and B and communicate both process using the Shared Memory approach. You can more information about this PR through my following posts [2], [3].</p></li> </ul> <p>The image bellow show an example that I made and is available at https://github.com/fury-gl/helios/blob/main/docs/examples/viz_mde.py</p> <p><img src="https://user-images.githubusercontent.com/6979335/125310065-a3a9f480-e308-11eb-98d9-0ff5406a0e96.gif"> <em>Pull Requests:</em></p> <ul> <li><p><strong>MDE Layout:</strong> https://github.com/fury-gl/helios/pull/6</p></li> <li><p><strong>CuGraph ForceAtlas2</strong> https://github.com/fury-gl/helios/pull/13</p></li> <li><p><strong>Force-Directed and MDE improvements</strong> https://github.com/fury-gl/helios/pull/14</p></li> <li><h3>Helios Network Visualization Lib: Visual Aspects</h3></li> </ul> <p>I’ve made several stuffs to give Helios a better visual aspects. One of them was to give a smooth real-time network layout animations. Because the layout computations happens into a different process that the process responsible to render the network was necessary to record the positions and communicate the state of layout between both process.</p> <p>The GIF bellow shows how the network layout through IPC behaved before these modification</p> <img alt="..." height="300" src="https://user-images.githubusercontent.com/6979335/126175596-e6e2b415-bd79-4d99-82e7-53e10548be8c.gif"> <p>Bellow, you can see how after those modifications the visual aspect is better.</p> <img alt="..." height="300" src="https://user-images.githubusercontent.com/6979335/126175583-c7d85f0a-3d0c-400e-bbdd-4cbcd2a36fed.gif"> <p><em>Pull Requests:</em></p> <ul> <li><p><strong>OpenGL SuperActors:</strong> https://github.com/fury-gl/helios/pull/1</p></li> <li><p><strong>Fixed the flickering effect</strong> https://github.com/fury-gl/helios/pull/10</p></li> <li><p><strong>Improvements in the network node visual aspects</strong> https://github.com/fury-gl/helios/pull/15</p></li> <li><p><strong>Smooth animations when using IPC layouts</strong> https://github.com/fury-gl/helios/pull/17</p></li> <li><h3>Helios Network Visualization Lib: CI and Documentation</h3></li> </ul> <p>Because Helios was a project that begins in my GSoC project It was necessary to create the documentation, hosting and more. Now we have a online documentation available at https://heliosnetwork.io/ altough the documentation still need some improvements.</p> Below is presented the Helios Logo which was developed by my mentor Filipi Nascimento. <img alt="Helios Network Logo" height="100" src="https://fury-gl.github.io/helios-website/_images/logo.png"> <p><em>Pull Requests:</em></p> <ul> <li><p><strong>CI and pytests:</strong> https://github.com/fury-gl/helios/pull/5, https://github.com/fury-gl/helios/pull/20</p></li> <li><p><strong>Helios Logo, Sphinx Gallery and API documentation</strong> https://github.com/fury-gl/helios/pull/18</p></li> <li><p><strong>Documentation improvements:</strong> https://github.com/fury-gl/helios/pull/8</p></li> <li><h3>Objectives in Progress</h3></li> <li><h3>Draw texts on FURY and Helios</h3> <p>This two PRs allows FURY and Helios to draw millions of characters in VTK windows instance with low computational resources consumptions. I still working on that, finishing the SDF font rendering which the theory behinds was developed here [5].</p> <p><em>Pull Requests:</em></p> <ul> <li><p>https://github.com/fury-gl/helios/pull/24</p></li> <li><p>https://github.com/fury-gl/fury/pull/489</p> <p><img alt="..." height="400" src="https://user-images.githubusercontent.com/6979335/129643743-6cb12c06-3415-4a02-ba43-ccc97003b02d.png"></p> </li> </ul></li> <li><h3>GSoC weekly Blogs</h3> <p>Weekly blogs were added to the FURY Website.</p> <p><em>Pull Requests:</em></p> <ul> <li><strong>First Evaluation:</strong> https://github.com/fury-gl/fury/pull/476</li> <li><strong>Second Evaluation:</strong> TBD</li> </ul></li> </ul> <h2>Timeline</h2> <table> <tbody><tr class="header"> <th>Date</th> <th>Description</th> <th>Blog Link</th> </tr> </tbody><tbody> <tr class="odd"> <td>Week 1<br>(08-06-2021)</td> <td>Welcome to my weekly Blogs!</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-1-21/">Weekly Check-in #1</a></td> </tr> <tr class="even"> <td>Week 2<br>(14-06-2021)</td> <td>Post #1: A Stadia-like system for data visualization</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/post-1-a-stadia-like-system-for-data-visualization/">Weekly Check-in #2</a></td> </tr> <tr class="odd"> <td>Week 3<br>(21-06-2021)</td> <td>2d and 3d fake impostors marker; fine-tunning open-gl state; Shared Memory support for the streaming system; first-version of helios: the network visualization lib for helios</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-3-15/">Weekly Check-in #3</a></td> </tr> <tr class="even"> <td>Week 4<br>(28-06-2020)</td> <td>Post #2: SOLID, monkey patching a python issue and network layouts through WebRTC</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/post-2-solid-monkey-patching-a-python-issue-and-network-layouts-through-webrtc/">Weekly Check-in #4</a></td> </tr> <tr class="odd"> <td>Week 5<br>(05-07-2021)</td> <td>Code refactoring; 2d network layouts for Helios; Implemented the Minimum distortion embedding algorithm using the IPC approach</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-5-14/">Weekly Check-in #5</a></td> </tr> <tr class="even"> <td>Week 6<br>(12-07-2020)</td> <td>Post #3: Network layout algorithms using IPC</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/post-3-network-layout-algorithms-using-ipc/">Weekly Check-in #6</a></td> </tr> <tr class="odd"> <td>Week 7<br>(19-07-2020)</td> <td>Helios IPC network layout algorithms support for MacOs; Smooth animations for IPC layouts; ForceAtlas2 network layout using cugraph/cuda</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-7-14/">eekly Check-in #7</a></td> </tr> <tr class="even"> <td>Week 8<br>(26-07-2020)</td> <td>Helios CI, Helios documentation</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-8-9/">Weekly Check-in #8</a></td> </tr> <tr class="odd"> <td>Week 9<br>(02-08-2020)</td> <td>Helios documentation; improved the examples and documentation of the WebRTC streaming system and made some improvements in the compatibility removing some dependencies</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-9-16/">Weekly Check-in #9</a></td> </tr> <tr class="even"> <td>Week 10<br>(09-08-2020)</td> <td>Helios documentation improvements; found and fixed a bug in fury w.r.t. the time management system; improved the memory management system for the network layout algorithms using IPC</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-10-12/">Weekly Check-in #10</a></td> </tr> <tr class="odd"> <td>Week 11<br>(16-08-2020)</td> <td>Created a PR that allows FURY to draw hundred of thousands of characters without any expensive GPU; fixed the flickering effect on the streaming system; helios node labels feature; finalizing remaining PRs</td> <td><a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-11-13/">Weekly Check-in #11</a></td> </tr> </tbody> </table> <p>Detailed weekly tasks, progress and work done can be found <a href="https://blogs.python-gsoc.org/en/demvessiass-blog/">here</a>.</p> <h3>References</h3> <p>[1] ( Python GSoC - Post #1 - A Stadia-like system for data visualization - demvessias s Blog, n.d.; https://blogs.python-gsoc.org/en/demvessiass-blog/post-1-a-stadia-like-system-for-data-visualization/</p> <p>[2] Python GSoC - Post #2: SOLID, monkey patching a python issue and network layouts through WebRTC - demvessias s Blog, n.d.; https://blogs.python-gsoc.org/en/demvessiass-blog/post-2-solid-monkey-patching-a-python-issue-and-network-layouts-through-webrtc/</p> <p>[3] Python GSoC - Post #3: Network layout algorithms using IPC - demvessias s Blog, n.d.)https://blogs.python-gsoc.org/en/demvessiass-blog/post-3-network-layout-algorithms-using-ipc/</p> <p>[4] Rougier, N.P., 2018. An open access book on Python, OpenGL and Scientific Visualization [WWW Document]. An open access book on Python, OpenGL and Scientific Visualization. URL https://github.com/rougier/python-opengl (accessed 8.21.21).</p> <p>[5] Green, C., 2007. Improved alpha-tested magnification for vector textures and special effects, in: ACM SIGGRAPH 2007 Courses on - SIGGRAPH ’07. Presented at the ACM SIGGRAPH 2007 courses, ACM Press, San Diego, California, p. 9. https://doi.org/10.1145/1281500.1281665</p>messias.physics@gmail.com (demvessias)Mon, 23 Aug 2021 19:45:51 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/google-summer-of-code-final-work-product-3/Weekly Check-in #11https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-11-13/Hi everyone! My name is Bruno Messias. Currently I'm a Ph.D student at USP/Brazil. This summer I'll develop new tools and features for FURY-GL Specifically, I'll focus on developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did I do this week?</h2> <h4> FURY </h4> <ul> <li> <a href="https://github.com/fury-gl/fury/pull/489"> PR fury-gl/fury#489: </a> <p> I've created the PR that will allow FURY to draw hundreds thousands of labels using texture maps. By default, this PR give to FURY three pre-built texture maps using different fonts. However, is quite easy to create new fonts to be used in a visualization. It's was quite hard to develop the shader code and find the correct positions of the texture maps to be used in the shader. Because we used the freetype-py to generate the texture and packing the glyps. However, the lib has some examples with bugs. But fortunelly, now everthing is woking on FURY. I've also created two different examples to show how this PR works. </p><ul> <li> <p> The first example, viz_huge_amount_of_labels.py, shows that feature has a realy good performance. The user can draw hundreds of thounsands of characters in a regular computer. </p> <img src="https://user-images.githubusercontent.com/6979335/129643743-6cb12c06-3415-4a02-ba43-ccc97003b02d.png"> </li> <li> The second example, viz_billboad_labels.py, shows the different behaviors of the label actor. In addition, presents to the user how to create a new texture atlas font to be used across different visualizations. </li> </ul> <p></p> </li> <li> <a href="https://github.com/fury-gl/fury/pull/437"> PR fury-gl/fury#437: </a> <ul> <li> <h5>Fix: avoid multiple OpenGl context on windows using asyncio</h5> The streaming system must be generic, but opengl and vtk behaves in uniques ways in each Operating System. Thus, can be tricky to have the same behavior acrros different OS. One hard stuff that we founded is that was not possible to use my TimeIntervals objects (implemented with threading module) with vtk. The reason for this impossibility is because we can't use vtk in windows in different threads. But fortunely, moving from the threading (multithreading) to the asyncio approcach (concurrency) have fixed this issue and now the streaming system is ready to be used anywhere. </li> <li> <h5>Flickering</h5> Finally, I could found the cause of the flickering effect on the streaming system. This flickering was appearing only when the streaming was created using the Widget object. The cause seems to be a bug or a strange behavior from vtk. Calling <pre>iren.MouseWheelForwardEvent()</pre> or <pre>iren.MouseWheelBackwardEvent()</pre> inside of a thread without invoking the Start method from a vtk instance produces a memory corruption. Fortunately, I could fix this behavior and now the streaming system is working without this glitch effect. </li> </ul> </li> </ul> <h4> FURY/Helios </h4> <ul> <li> <a href="https://github.com/fury-gl/helios/pull/24"> PR fury-gl/helios#24 :</a> <p>This uses the <a href="https://github.com/fury-gl/fury/pull/489"> PRfury-gl/fury#489: </a> to give the network label feature to helios. Is possible to draw node labels, update the colors, change the positions at runtime. In addition, when a network layout algorithm is running this will automatically update the node labels positions to follow the nodes across the screen. </p> <img src="https://user-images.githubusercontent.com/6979335/129642582-fc6785d8-0e4f-4fdd-81f4-b2552e1ff7c7.png"> </li> <li> <a href="https://github.com/fury-gl/helios/pull/23"> PR fury-gl/helios#23: Merged. </a> This PR granted compatibility between IPC Layouts and Windows. Besides that , now is quite easier to create new network layouts using inter process communication </li> </ul> <h2>Did I get stuck anywhere?</h2> I did not get stuck this week. <h2>What is coming up next?</h2> I’ll discuss that with my mentors tomorrow.messias.physics@gmail.com (demvessias)Mon, 16 Aug 2021 23:26:34 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-11-13/Weekly Check-in #10https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-10-12/Hi everyone! My name is Bruno Messias. Currently I'm a Ph.D student at USP/Brazil. This summer I'll develop new tools and features for FURY-GL Specifically, I'll focus on developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did I do this week?</h2> <h4> FURY/Helios </h4> <ul> <li> <a href="https://github.com/fury-gl/helios/pull/22"> PR fury-gl/helios#22 :</a> Helios Documentation Improvements. </li> <li> <a href="https://github.com/fury-gl/helios/pull/23"> PR fury-gl/helios#23: </a> A PR that makes helios IPCLayout system compatible with Windows. </li> </ul> <h4> FURY </h4> <ul> <li> <a href="https://github.com/fury-gl/fury/pull/484"> PR fury-gl/fury#484: I've found and fixed a bug in FURY time managment system </a> </li> <li> <a href="https://github.com/fury-gl/fury/pull/437"> PR fury-gl/fury#437: </a> <ul> <li> Fixed the tests on Windows </li> <li> Improve the streaming memory managment system for IPC communication </li> </ul> </li> <li> <p> I've developing a feature that will allows FURY to draw hundreds thousands of labels using texture maps and signed distance functions. Until now I've a sketch that at least is able to draw the labels using the markers billboards and bitmap fonts. </p> <img src="https://user-images.githubusercontent.com/6979335/128761833-53f53e2c-5bc0-4ff3-93c4-0ad01dc7d8eb.png" style="width: 80%;"> </li> <li> <a href="https://github.com/fury-gl/fury/pull/432"> PR fury-gl/fury#432: </a> minor improvements </li> <li> <a href="https://github.com/fury-gl/fury/pull/474">PR #474</a> Helped to review this PR </li> </ul> <h2>Did I get stuck anywhere?</h2> I did not get stuck this week. <h2>What is coming up next?</h2> I’ll discuss that with my mentors tomorrow.messias.physics@gmail.com (demvessias)Mon, 09 Aug 2021 19:20:16 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-10-12/Weekly Check-in #9https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-9-16/Hi everyone! My name is Bruno Messias. Currently I'm a Ph.D student at USP/Brazil. This summer I'll develop new tools and features for FURY-GL Specifically, I'll focus on developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did I do this week?</h2> <h4> FURY/Helios </h4> <ul> <li> <a href="https://github.com/fury-gl/helios/pull/22"> PR fury-gl/helios#22 :</a> Helios Documentation Improvements. I’ve spent some time studying sphinx in order to discover how I could create a custom summary inside of a template module. </li> </ul> <h4> FURY </h4> <ul> <li> Added my GSoC blogs to the FURY blogs as requested by my mentors. </li> <li> <a href="https://github.com/fury-gl/fury/pull/437"> PR fury-gl/fury#43: </a> <ul> <li> Docstrings improvements </li> <li> Covered more tests </li> <li> Covered tests using optional dependencies. </li> <li> Aiortc now it’s not a mandatory dependency </li> <li> improvements in memory management </li> </ul> </li> <li> <a href="https://github.com/fury-gl/fury/pull/432">PR #432</a> Fixed some typos, improved the tests and docstrings </li> <li> Helped to review and made some suggestions to the <a href="https://github.com/fury-gl/fury/pull/474">PR #474</a> made by @mehabhalodiya. </li> </ul> <h2>Did I get stuck anywhere?</h2> I did not get stuck this week. <h2>What is coming up next?</h2> I’ll discuss that with my mentors tomorrow.messias.physics@gmail.com (demvessias)Mon, 02 Aug 2021 23:06:11 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-9-16/Weekly Check-In #8https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-8-9/Hi everyone! My name is Bruno Messias. Currently I'm a Ph.D student at USP/Brazil. This summer I'll develop new tools and features for FURY-GL Specifically, I'll focus on developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did I do this week?</h2> <ul> <li> <a href="https://github.com/fury-gl/helios/pull/18"> PR fury-gl/helios#18 (merged): </a>Helios Documentation <p> I’ve been working in the Helios documentation. Now it’s available online at <a href="https://fury-gl.github.io/helios-website">https://fury-gl.github.io/helios-website</a><a> <img src="https://fury-gl.github.io/helios-website/_images/logo.png" style="width: 100%;"> </a></p><a> </a></li><a> </a><li><a> </a><a href="https://github.com/fury-gl/helios/pull/17"> PR fury-gl/helios#17 (merged): </a>Helios CI for tests and code coverage </li> </ul> <h2>Did I get stuck anywhere?</h2> I did not get stuck this week. <h2>What is coming up next?</h2> I’ll discuss that with my mentors tomorrow.messias.physics@gmail.com (demvessias)Mon, 26 Jul 2021 14:10:44 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-8-9/Weekly Check-In #7https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-7-14/Hi everyone! My name is Bruno Messias currently I'm a Ph.D student at USP/Brazil. In this summer I'll develop new tools and features for FURY-GL Specifically, I'll focus into developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did I do this week?</h2> <ul> <li> <a href="https://github.com/fury-gl/helios/pull/16"> PR fury-gl/helios#16 (merged): </a>Helios IPC network layout support for MacOs </li> <li> <a href="https://github.com/fury-gl/helios/pull/17"> PR fury-gl/helios#17 (merged): </a>Smooth animations for IPC network layout algorithms <p> Before this commit was not possible to record the positions to have a smooth animations with IPCLayout approach. See the animation bellow</p> <img src="https://user-images.githubusercontent.com/6979335/126175596-e6e2b415-bd79-4d99-82e7-53e10548be8c.gif"> <p> After this PR now it's possible to tell Helios to store the evolution of the network positions using the record_positions parameter. This parameter should be passed on the start method. Notice in the image bellow how this gives to us a better visualization</p> <img src="https://user-images.githubusercontent.com/6979335/126175583-c7d85f0a-3d0c-400e-bbdd-4cbcd2a36fed.gif"> </li> <li> <a href="https://github.com/fury-gl/helios/pull/13"> PR fury-gl/helios#13 (merged) </a>Merged the forceatlas2 cugraph layout algorithm </li> </ul> <h2>Did I get stuck anywhere?</h2> I did not get stuck this week. <h2>What is coming up next?</h2> Probably, I'll work more on Helios. Specifically I want to improve the memory management system. It seems that some shared memory resources are not been released when using the IPCLayout approach.messias.physics@gmail.com (demvessias)Mon, 19 Jul 2021 13:18:00 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-7-14/Post #3: Network layout algorithms using IPChttps://blogs.python-gsoc.org/en/demvessiass-blog/post-3-network-layout-algorithms-using-ipc/<p> Hi all. In the past weeks, I’ve been focusing on developing Helios; the network visualization library for FURY. I improved the visual aspects of the network rendering as well as implemented the most relevant network layout methods. </p> <p> In this post I will discuss the most challenging task that I faced to implement those new network layout methods and how I solved it. </p> <h3>The problem: network layout algorithm implementations with a blocking behavior </h3> <p> <strong>Case 1:</strong> Suppose that you need to monitor a hashtag and build a social graph. You want to interact with the graph and at the same time get insights about the structure of the user interactions. To get those insights you can perform a node embedding using any kind of network layout algorithm, such as force-directed or minimum distortion embeddings. </p> <p> <strong>Case 2:</strong> Suppose that you are modelling a network dynamic such as an epidemic spreading or a Kuramoto model. In some of those network dynamics a node can change the state and the edges related to the node must be deleted. For example, in an epidemic model a node can represent a person who died due to a disease. Consequently, the layout of the network must be recomputed to give better insights. </p> <p> In described cases if we want a better (UX) and at the same time a more practical and insightful application of Helios layouts algorithms shouldn’t block any kind of computation in the main thread. </p> <p> In Helios we already have a lib written in C (with a python wrapper) which performs the force-directed layout algorithm using separated threads avoiding the GIL problem and consequently avoiding the blocking. But and the other open-source network layout libs available on the internet? Unfortunately, most of those libs have not been implemented like Helios force-directed methods and consequently, if we want to update the network layout the python interpreter will block the computation and user interaction in your network visualization. How to solve this problem? </p> <h3> Why is using the python threading is not a good solution? </h3> <p> One solution to remove the blocking behavior of the network layout libs like PyMDE is to use the threading module from python. However, remember the GIL problem: only one thread can execute python code at once. Therefore, this solution will be unfeasible for networks with more than some hundreds of nodes or even less! Ok, then how to solve it well? </p> <h3>IPC using python</h3> <p> As I said in my previous posts I’ve created a streaming system for data visualization for FURY using webrtc. The streaming system is already working and an important piece in this system was implemented using the python SharedMemory from multiprocessing. We can get the same ideas from the streaming system to remove the blocking behavior of the network layout libs. </p> <p> My solution to have PyMDE and CuGraph-ForceAtlas without blocking was to break the network layout method into two different types of processes: A and B. The list below describes the most important behaviors and responsibilities for each process </p> <p> <strong>Process A:</strong> </p><ul> <li> Where the visualization (NetworkDraw) will happen </li> <li> Create the shared memory resources: edges, weights, positions, info.. </li> <li> Check if the process B has updated the shared memory resource which stores the positions using the timestamp stored in the info_buffer </li> <li> Update the positions inside of NetworkDraw instance </li> </ul> <p> <strong> Process B: </strong> </p><ul> <li> Read the network information stored in the shared memory resources: edges , weights, positions </li> <li> Execute the network layout algorithm </li> <li> Update the positions values inside of the shared memory resource </li> <li> Update the timestamp inside of the shared memory resource </li></ul> <p> I used the timestamp information to avoid unnecessary updates in the FURY/VTK window instance, which can consume a lot of computational resources. </p> <h4> How have I implemented the code for A and B? </h4> <p> Because we need to deal with a lot of different data and share them between different processes I’ve created a set of tools to deal with that, take a look for example in the <a href="https://github.com/fury-gl/helios/blob/main/helios/layouts/ipc_tools.py#L111"> ShmManagerMultiArrays Object </a>, which makes the memory management less painful. </p> <p> I'm breaking the layout method into two different processes. Thus I’ve created two abstract objects to deal with any kind of network layout algorithm which must be performed using inter-process-communication (IPC). Those objects are: <a href="https://github.com/devmessias/helios/blob/a0a24525697ec932a398db6413899495fb5633dd/helios/layouts/base.py#L65"> NetworkLayoutIPCServerCalc </a>; used by processes of type B and <a href="https://github.com/devmessias/helios/blob/a0a24525697ec932a398db6413899495fb5633dd/helios/layouts/base.py#L135"> NetworkLayoutIPCRender </a>; which should be used by processes of type A. </p> <p> I’ll not bore you with the details of the implementation. But let’s take a look into some important points. As I’ve said saving the timestamp after each step of the network layout algorithm. Take a look into the method _check_and_sync from NetworkLayoutIPCRender <a href="https://github.com/fury-gl/helios/blob/a0a24525697ec932a398db6413899495fb5633dd/helios/layouts/base.py#L266"> here</a>. Notice that the update happens only if the stored timestamp has been changed. Also, look at this line <a href="https://github.com/fury-gl/helios/blob/a0a24525697ec932a398db6413899495fb5633dd/helios/layouts/mde.py#L180">helios/layouts/mde.py#L180</a>, the IPC-PyMDE implementation This line writes a value 1 into the second element of the info_buffer. This value is used to inform the process A that everything worked well. I used that info for example in the tests for the network layout method, see the link <a href="https://github.com/fury-gl/helios/blob/a0a24525697ec932a398db6413899495fb5633dd/helios/tests/test_mde_layouts.py#L43"> helios/tests/test_mde_layouts.py#L43 </a> </p> <h3>Results</h3> <p> Until now Helios has three network layout methods implemented: Force Directed , Minimum Distortion Embeddings and Force Atlas 2. Here <a href="https://github.com/fury-gl/helios/blob/a0a24525697ec932a398db6413899495fb5633dd/docs/examples/viz_helios_mde.ipynb"> docs/examples/viz_helios_mde.ipynb </a> you can get a jupyter notebook that I’ve a created showing how to use MDE with IPC in Helios. </p> <p> In the animation below we can see the result of the Helios-MDE application into a network with a set of anchored nodes. </p> <img src="https://user-images.githubusercontent.com/6979335/125310065-a3a9f480-e308-11eb-98d9-0ff5406a0e96.gif"> <h3>Next steps </h3> <p> I’ll probably focus on the Helios network visualization system. Improving the documentation and testing the ForceAtlas2 in a computer with cuda installed. See the list of opened <a href="https://github.com/fury-gl/helios/issues">issues</a> </p> <h3>Summary of most important pull-requests: </h3> <ul> <li> IPC tools for network layout methods (helios issue #7) <a href="https://github.com/fury-gl/helios/pull/6"> fury-gl/helios/pull/6 </a> </li> <li> New network layout methods for fury (helios issue #7) <a href="https://github.com/fury-gl/helios/pull/9">fury-gl/helios/pull/9</a> <a href="https://github.com/fury-gl/helios/pull/14">fury-gl/helios/pull/14</a> <a href="https://github.com/fury-gl/helios/pull/13">fury-gl/helios/pull/13</a> </li> <li> Improved the visual aspects and configurations of the network rendering(helios issue #12) <a href="https://github.com/devmessias/helios/tree/fury_network_actors_improvements"> https://github.com/devmessias/helios/tree/fury_network_actors_improvements </a> </li> <li> Tests, examples and documentation for Helios (helios issues #3 and #4) <a href="https://github.com/fury-gl/helios/pull/5">fury-gl/helios/pull/5</a> </li> <li> Reduced the flickering effect on the FURY/Helios streaming system <a href="https://github.com/fury-gl/helios/pull/10">fury-gl/helios/pull/10</a> <a href="https://github.com/fury-gl/fury/pull/437/commits/a94e22dbc2854ec87b8c934f6cabdf48931dc279">fury-gl/fury/pull/437/commits/a94e22dbc2854ec87b8c934f6cabdf48931dc279</a> </li></ul>messias.physics@gmail.com (demvessias)Mon, 12 Jul 2021 15:11:52 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/post-3-network-layout-algorithms-using-ipc/Weekly Check-In #5https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-5-14/<h2>What did you do this week?</h2> <h3> <a href="https://github.com/fury-gl/fury/pull/427"> fury-gl/fury PR#437: WebRTC streaming system for FURY </a> </h3> <ul> <li> Before the <a href="https://github.com/fury-gl/fury/pull/437/commits/8c670c284368029cdb5b54c178a792ec615e4d4d"> 8c670c2 </a> commit, for some versions of MacOs the streaming system was falling in a silent bug. I’ve spent a lot of time researching to find a cause for this. Fortunately, I could found the cause and the solution. This troublesome MacOs was falling in a silent bug because the SharedMemory Object was creating a memory resource with at least 4086 bytes indepedent if I've requested less than that. If we look into the MultiDimensionalBuffer Object (stream/tools.py) before the 8c670c2 commit we can see that Object has max_size parameter which needs to be updated if the SharedMemory was created with a "wrong" size. </li> </ul> <h3> <a href="https://github.com/fury-gl/helios/pull/1"> fury-gl/helios PR 1: Network Layout and SuperActors </a> </h3> <p> In the past week I've made a lot of improvements in this PR, from performance improvements to visual effects. Bellow are the list of the tasks related with this PR: </p> <ul> <li> - Code refactoring. </li> <li> - Visual improvements: Using the UniformTools from my pull request <a href="https://github.com/fury-gl/fury/pull/424">#424</a> now is possible to control all the visual characteristics at runtime. </li> <li> - 2D Layout: Meanwhile 3d network representations are very usefully for exploring a dataset is hard to convice a group of network scientists to use a visualization system which dosen't allow 2d representations. Because of that I started to coding the 2d behavior in the network visualization system. </li> <li> - Minimum Distortion Embeddings examples: I've created some examples which shows how integrate pymde (Python Minimum Distortion Embeddings) with fury/helios. The image bellow shows the result of this integration: a "perfect" graph embedding </li> </ul> <img src="https://user-images.githubusercontent.com/6979335/124524052-da937e00-ddcf-11eb-83ca-9b58ca692c2e.png"> <h2> What is coming up next week? </h2> <p> I'll probably focus on the <a href="">heliosPR#1</a>. Specifically, writing tests and improving the minimum distortion embedding layout. </p> <h2> Did you get stuck anywhere? </h2> I did not get stuck this week.messias.physics@gmail.com (demvessias)Mon, 05 Jul 2021 21:51:45 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-5-14/Post #2: SOLID, monkey patching a python issue and network layouts through WebRTChttps://blogs.python-gsoc.org/en/demvessiass-blog/post-2-solid-monkey-patching-a-python-issue-and-network-layouts-through-webrtc/<p>Hi everyone! My name is Bruno Messias and I'm a PhD student working with graphs and networks. This summer I'll develop new tools and features for FURY-GL Specifically, I'll focus on developing a system for collaborative visualization of large network layouts using FURY and VTK.</p> <p>These past two weeks I’ve spent most of my time in the <a href="https://github.com/fury-gl/fury/pull/437">Streaming System PR</a> and the <a href="https://github.com/fury-gl/helios/pull/1/">Network Layout PR</a> In this post I’ll focus on the most relevant things I’ve made for those PRs</p> <h2>Streaming System</h2> <p><strong>Pull request <a href="https://github.com/fury-gl/fury/pull/437/"> fury-gl/fury/pull/437</a></strong></p> <h3>Code Refactoring</h3> <h4>Abstract class and SOLID</h4> <p> The past weeks I've spent some time refactoring the code to see what I’ve done let’ s take a look into this <a href="https://github.com/devmessias/fury/blob/b1e985bd6a0088acb4a116684577c4733395c9b3/fury/stream/client.py#L20">fury/blob/b1e985.../fury/stream/client.py#L20</a>, the FuryStreamClient Object before the refactoring. </p> <p> The code is a mess. To see why this code is not good according to SOLID principles let’s just list all the responsibilities of FuryStreamClient </p><ul> <li>Creates a RawArray or SharedMemory to store the n-buffers</li> <li>Creates a RawArray or SharedMemory to store the information about each buffer</li> <li>Cleanup the shared memory resources if the SharedMemory was used</li> <li>Write the vtk buffer into the shared memory resource</li> <li>Creates the vtk callbacks to update the vtk-buffer</li> </ul> <p> That’s a lot and those responsibilities are not even related to each other. How can we be more SOLID[1]? An obvious solution is to create a specific object to deal with the shared memory resources. But it's not good enough because we still have a poor generalization since this new object still needs to deal with different memory management systems: rawarray or shared memory (maybe sockets in the future). Fortunately, we can use the python Abstract Classes[2] to organize the code.</p> <p>To use the ABC from python I first listed all the behaviors that should be mandatory in the new abstract class. If we are using SharedMemory or RawArrays we need first to create the memory resource in a proper way. Therefore, the GenericImageBufferManager must have a abstract method create_mem_resource. Now take a look into the ImageBufferManager inside of <a href="https://github.com/devmessias/fury/blob/c196cf43c0135dada4e2c5d59d68bcc009542a6c/fury/stream/server/server.py#L40">stream/server/server.py</a>, sometimes it is necessary to load the memory resource in a proper way. Because of that, the GenericImageBufferManager needs to have a load_mem_resource abstract method. Finally, each type of ImageBufferManager should have a different cleanup method. The code below presents the sketch of the abstract class </p> <pre><code> from abc import ABC, abstractmethod GenericImageBufferManager(ABC): def __init__( self, max_window_size=None, num_buffers=2, use_shared_mem=False): … #... @abstractmethod def load_mem_resource(self): pass @abstractmethod def create_mem_resource(self): pass @abstractmethod def cleanup(self): pass </code> </pre> <p> Now we can look for those behaviors inside of FuryStreamClient.py and ImageBufferManger.py that does not depend if we are using the SharedMemory or RawArrays. These behaviors should be methods inside of the new GenericImageBufferManager. </p> <code> </code><pre><code># code at: https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/tools.py#L491 class GenericImageBufferManager(ABC): def __init__( self, max_window_size=None, num_buffers=2, use_shared_mem=False) self.max_window_size = max_window_size self.num_buffers = num_buffers self.info_buffer_size = num_buffers*2 + 2 self._use_shared_mem = use_shared_mem # omitted code @property def next_buffer_index(self): index = int((self.info_buffer_repr[1]+1) % self.num_buffers) return index @property def buffer_index(self): index = int(self.info_buffer_repr[1]) return index def write_into(self, w, h, np_arr): buffer_size = buffer_size = int(h*w) next_buffer_index = self.next_buffer_index # omitted code def get_current_frame(self): if not self._use_shared_mem: # omitted code return self.width, self.height, self.image_buffer_repr def get_jpeg(self): width, height, image = self.get_current_frame() if self._use_shared_mem: # omitted code return image_encoded.tobytes() async def async_get_jpeg(self, ms=33): # omitted code @abstractmethod def load_mem_resource(self): pass @abstractmethod def create_mem_resource(self): pass @abstractmethod def cleanup(self): Pass </code> </pre> <p> With the <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/tools.py#L491"> GenericImageBufferManager</a> the <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/tools.py#L609"> RawArrayImageBufferManager</a> and <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/tools.py#L681">SharedMemImageBufferManager</a> is now implemented with less duplication of code (DRY principle). This makes the code more readable and easier to find bugs. In addition, later we can implement other memory management systems in the streaming system without modifying the behavior of FuryStreamClient or the code inside of server.py. </p> <p> I’ve also applied the same SOLID principles to improve the CircularQueue object. Although the CircularQueue and FuryStreamInteraction was not violating the S from SOLID the head-tail buffer from the CircularQueue must have a way to lock the write/read if the memory resource is busy. Meanwhile the <a href="https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Array">multiprocessing.Arrays</a> already has a context which allows lock (.get_lock()) SharedMemory dosen’t[2]. The use of abstract class allowed me to deal with those peculiarities. <a href="https://github.com/fury-gl/fury/pull/437/commits/358402ea2f06833f66f45f3818ccc3448b2da9cd"> commit 358402e</a> </p> <h4>Using namedtuples to grant immutability and to avoid silent bugs</h4> The circular queue and the user interaction are implemented in the streaming system using numbers to identify the type of event (mouse click, mouse weel, ...) and where to store the specific values associated with the event , for example if the ctrl key is pressed or not. Therefore, those numbers appear in different files and locations: tests/test_stream.py, stream/client.py, steam/server/app_async.py. This can be problematic because a typo can create a silent bug. One possibility to mitigate this is to use a python dictionary to store the constant values, for example <pre><code> EVENT_IDS = { “ mouse_move” : 2, “mouse_weel”: 1, …. }</code> </pre> But this solution has another issue, anywhere in the code we can change the values of EVENT_IDS and this will produce a new silent bug. To avoid this I chose to use <a href="https://docs.python.org/3/library/collections.html#collections.namedtuple">namedtuples</a> to create an immutable object which holds all the constant values associated with the user interactions. <a href="https://github.com/devmessias/fury/blob/b1e985bd6a0088acb4a116684577c4733395c9b3/fury/stream/constants.py#L59"> stream/constants.py</a> <p> The namedtuple has several advantages when compared to dictionaries for this specific situation. In addition, it has a better performance. A good tutorial about namedtuples it’s available here <a href="https://realpython.com/python-namedtuple/">https://realpython.com/python-namedtuple/</a> </p><h3>Testing</h3> <p>My mentors asked me to write tests for this PR. Therefore, this past week I’ve implemented the most important tests for the streaming system: <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/tests/test_stream.py">/fury/tests/test_stream.py</a> </p><h3>Most relevant bugs</h3> As I discussed in my <a href="https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-3-15/">third week</a> check-in there is an open issue related to SharedMemory in python. This"bug" happens in the streaming system through the following scenario <pre><code> 1-Process A creates a shared memory X 2-Process A creates a subprocess B using popen (shell=False) 3-Process B reads X 4-Process B closes X 5-Process A kills B 4-Process A closes X 5-Process A unlink() the shared memory resource </code></pre><code> </code> In python, this scenario translates to <pre><code> from multiprocessing import shared_memory as sh import time import subprocess import sys shm_a = sh.SharedMemory(create=True, size=10000) command_string = f"from multiprocessing import shared_memory as sh;import time;shm_b = sh.SharedMemory('{shm_a.name}');shm_b.close();" time.sleep(2) p = subprocess.Popen( [sys.executable, '-c', command_string], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) p.wait() print("\nSTDOUT") print("=======\n") print(p.stdout.read()) print("\nSTDERR") print("=======\n") print(p.stderr.read()) print("========\n") time.sleep(2) shm_a.close() shm_a.unlink() </code> </pre> Fortunately, I could use a monkey-patching[3] solution to fix that; meanwhile we're waiting for the python-core team to fix the resource_tracker (38119) issue [4]. <h2>Network Layout (Helios-FURY)</h2> <p><strong>Pull request <a href="https://github.com/fury-gl/helios/pull/1/"> fury-gl/helios/pull/1</a></strong></p> <p>Finally, the first version of FURY network layout is working as can you see in the video below</p> <iframe height="315" src="https://www.youtube.com/embed/aN1mUPRHoqM" width="560"></iframe> <p>In addition, this already can be used with the streaming system allowing user interactions across the internet with WebRTC protocol.</p> <p>One of the issues that I had to solve to achieve the result presented in the video above was to find a way to update the positions of the vtk objects without blocking the main thread and at the same time allowing the vtk events calls. My solution was to define an interval timer using the python threading module: <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/tools.py#L776">/fury/stream/tools.py#L776</a>, <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/client.py#L112">/fury/stream/client.py#L112</a> <a href="https://github.com/devmessias/fury/blob/440a39d427822096679ba384c7d1d9a362dab061/fury/stream/client.py#L296">/fury/stream/client.py#L296</a> </p> <h2>Refs:</h2> <ul> <li>[1] A. Souly,"5 Principles to write SOLID Code (examples in Python)," Medium, Apr. 26, 2021. https://towardsdatascience.com/5-principles-to-write-solid-code-examples-in-python-9062272e6bdc (accessed Jun. 28, 2021).</li> <li>[2]"[Python-ideas] Re: How to prevent shared memory from being corrupted ?" https://www.mail-archive.com/python-ideas@python.org/msg22935.html (accessed Jun. 28, 2021).</li> <li>[3]“Message 388287 - Python tracker." https://bugs.python.org/msg388287 (accessed Jun. 28, 2021). </li> <li>[4]“bpo-38119: Fix shmem resource tracking by vinay0410 · Pull Request #21516 · python/cpython," GitHub. https://github.com/python/cpython/pull/21516 (accessed Jun. 28, 2021). </li> </ul>messias.physics@gmail.com (demvessias)Mon, 28 Jun 2021 13:28:18 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/post-2-solid-monkey-patching-a-python-issue-and-network-layouts-through-webrtc/Weekly Check-In #3https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-3-15/Hi everyone! My name is Bruno Messias. In this summer I'll develop new tools and features for FURY-GL Specifically, I'll focus into developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did you do this week?</h2> <iframe height="315" src="https://www.youtube.com/embed/aN1mUPRHoqM" width="560"></iframe> <ul> <li> <a href="https://github.com/fury-gl/fury/pull/422/commits/8a0012b66b95987bafdb71367a64897b25c89368"> PR fury-gl/fury#422 (merged): </a>Integrated the 3d impostor spheres with the marker actor </li> <li> <a href="https://github.com/fury-gl/fury/pull/422"> PR fury-gl/fury#422 (merged): </a>Fixed some issues with my maker PR which now it's merged on fury </li> <li> <a href="https://github.com/fury-gl/fury/pull/432"> PR fury-gl/fury#432 </a>I've made some improvements in my PR which can be used to fine tuning the opengl state on VTK </li> <li> <a href="https://github.com/fury-gl/fury/pull/437"> PR fury-gl/fury#437 </a>I've made several improvements in my streamer proposal for FURY. most of those improvements it's related with memory management. Using the SharedMemory from python 3.8 now it's possible to use the streamer direct on a jupyter without blocking </li> <li> <a href="https://github.com/fury-gl/helios/pull/1"> PR fury-gl/helios#1 </a> First version of async network layout using force-directed. </li> </ul> <h2>Did I get stuck anywhere?</h2> <h3>A python-core issue</h3> <p> I've spent some hours trying to discover this issue. But now it's solved through the commit <a href="https://github.com/devmessias/fury/commit/071dab85a86ec4f97eba36721b247ca9233fd59e">devmessias/fury/commit/071dab85</a> </p> <p> The <a href="https://docs.python.org/3/library/multiprocessing.shared_memory.html">SharedMemory</a> from python&gt;=3.8 offers new a way to share memory resources between unrelated process. One of the advantages of using the SharedMemory instead of the RawArray from multiprocessing it’s that the SharedMemory allows to share memory blocks without those processes be related with a fork or spawm method. The SharedMemory behavior allowed to achieve our jupyter integration and <a href="https://github.com/fury-gl/fury/pull/437/files#diff-7680a28c3a88a93b8dae7b777c5db5805e1157365805eeaf2e58fd12a00df046"> simplifies the use of the streaming system</a>. However, I saw a issue in the shared memory implementation. </p> Let’s see the following scenario: <pre><code> 1-Process A creates a shared memory X 2-Process A creates a subprocess B using popen (shell=False) 3-Process B reads X 4-Process B closes X 5-Process A kills B 4-Process A closes X 5-Process A unlink() the shared memory resource X </code></pre> This scenario should work well. unlink() X in it's the right way as discussed in the python official documentation. However, there is a open issue which a think it's related with the above scenario. <ul> <li> <a href="https://bugs.python.org/issue38119">Issue: https://bugs.python.org/issue38119</a> </li> <li> <a href="https://github.com/python/cpython/pull/21516"> PR python/cpython/pull/21516</a> </li> </ul> Fortunately, I could use a <a href="https://bugs.python.org/msg388287">monkey-patching</a> solution to fix that meanwhile we wait to the python-core team to fix the resource_tracker (38119) issue. <h2>What is coming up next?</h2> I'm planning to work in the <a href="https://github.com/fury-gl/fury/pull/432">fury-gl/fury#432</a> and <a href="https://github.com/fury-gl/helios/pull/1">fury-gl/helios#1</a>.messias.physics@gmail.com (demvessias)Mon, 21 Jun 2021 11:28:09 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-3-15/Post #1 - A Stadia-like system for data visualizationhttps://blogs.python-gsoc.org/en/demvessiass-blog/post-1-a-stadia-like-system-for-data-visualization/<p> Hi all! In this post I'll talk about the PR <a href="https://github.com/fury-gl/fury/pull/437">#437</a>. </p> <p> There are several reasons to have a streaming system for data visualization. Because I’m doing a PhD in a developing country I always need to think of the cheapest way to use the computational resources available. For example, with the GPU’s prices increasing, it’s necessary to share a machine with a GPU with different users in different locations. Therefore, to convince my Brazilian friends to use FURY I need to code thinking inside of the (a) low-budget scenario. </p> <p> To construct the streaming system for my project I’m thinking about the following properties and behaviors: </p> <ol> <li>I want to avoid blocking the code execution in the main thread (where the vtk/fury instance resides)</li> <li>The streaming should work inside of a low bandwidth environment</li> <li>II need an easy way to share the rendering result. For example, using the free version of ngrok</li> </ol> <p> To achieve the property <strong>1.</strong> we need to circumvent the GIL problem. Using the threading module alone it’s not good enough because we can’t use the python-threading for parallel CPU computation. In addition, to achieve a better organization it’s better to define the server system as an uncoupled module. Therefore, I believe that multiprocessing-lib in python will fit very well for our proposes. </p> <p> For the streaming system to work smoothly in a low-bandwidth scenario we need to choose the protocol wisely. In the recent years the WebRTC protocol has been used in a myriad of applications like google hangouts and Google Stadia aiming low latency behavior. Therefore, I choose the webrtc as my first protocol to be available in the streaming system proposal. </p> <p> To achieve the third property, we must be economical in adding requirements and dependencies. </p> <p> Currently, the system has some issues, but it's already working. You can see some tutorials about how to use this streaming system <a href="https://github.com/devmessias/fury/tree/feature_fury_stream_client/docs/tutorials/04_stream">here</a>. After running one of these examples you can easily share the results and interact with other users. For example, using the ngrok For example, using the ngrok </p><pre><code> ./ngrok http 8000 </code> </pre> <p></p> <br> <h2>How does it works?</h2> <p> The image bellow it's a simple representation of the streaming system. </p> <img alt="" src="https://user-images.githubusercontent.com/6979335/121934889-33ff1480-cd1e-11eb-89a4-562fbb953ba4.png"> <p> As you can see, the streaming system is made up of different processes that share some memory blocks with each other. One of the hardest part of this PR was to code this sharing between different objects like VTK, numpy and the webserver. I'll discuss next some of technical issues that I had to learn/circunvent. </p> <h3>Sharing data between process</h3> We want to avoid any kind of unnecessary duplication of data or expensive copy/write actions. We can achieve this economy of computational resources using the multiprocessing module from python. <h4>multiprocessing RawArray </h4> <p> The <a href="https://docs.python.org/3/library/multiprocessing.html#multiprocessing.sharedctypes.RawArray"> RawArray </a> from multiprocessing allows to share resources between different processes. However, there are some tricks to get a better performance when we are dealing with RawArray's. For example, <a href="https://github.com/devmessias/fury/tree/6ae82fd239dbde6a577f9cccaa001275dcb58229"> take a look at my PR in a older stage. </a> In this older stage my streaming system was working well. However, one of my mentors (Filipi Nascimento) saw a huge latency for high-resolutions examples. My first thought was that latency was caused by the GPU-CPU copy from the opengl context. However, I discovered that I've been using RawArray's wrong in my entire life! <br> See for example this line of code <a href="https://github.com/devmessias/fury/blob/6ae82fd239dbde6a577f9cccaa001275dcb58229/fury/stream/client.py#L101"> fury/stream/client.py#L101 </a> The code bellow shows how I've been updating the raw arrays </p> <pre><code> raw_arr_buffer[:] = new_data </code> </pre> <p>This works fine for small and medium sized arrays, but for large ones it takes a large amount of time, more than GPU-CPU copy. The explanation for this bad performance is available here : <a href="https://stackoverflow.com/questions/33853543/demystifying-sharedctypes-performance"> Demystifying sharedctypes performance. </a> The solution which gives a stupendous performance improvement is quite simple. RawArrays implements the buffer protocol. Therefore, we just need to use the memoryview: </p> <pre><code> memview(arr_buffer)[:] = new_data </code> </pre> <p> The memview is really good, but there it's a litle issue when we are dealing with uint8 RawArrays. The following code will cause an exception </p> <pre><code> memview(arr_buffer_uint8)[:] = new_data_uint8 </code> </pre> <p> There is a solution for uint8 rawarrays using just memview and cast methods. However, numpy comes to rescue and offers a simple and a more a generic solution. You just need to convert the rawarray to a np representation in the following way </p> <pre><code> arr_uint8_repr = np.ctypeslib.as_array(arr_buffer_uint8) arr_uint8_repr[:] = new_data_uint8 </code> </pre> <p> You can navigate to my repository in this specific <a href="https://github.com/devmessias/fury/commit/b1b0caf30db762cc018fc99dd4e77ba0390b2f9e"> commit position </a> and test the streaming examples to see how this little modification improves the performance. </p> <h3>Multiprocessing inside of different Operating Systems</h3> <p> Serge Koudoro, who is one of my mentors, has pointed out an issue of the streaming system running in MacOs. I don't know many things about MacOs, and as pointed out by Filipi the way that MacOs deals with multiprocessing is very different than the Linux approach. Although we solved the issue discovered by Serge, I need to be more carefully to assume that different operating systems will behave in the same way. If you want to know more,I recommend that you read this post <a href="https://britishgeologicalsurvey.github.io/science/python-forking-vs-spawn/">Python: Forking vs Spawm</a>. And it's also important to read the official documentation from python. It can save you a lot of time. Take a look what the official python documentation says about the multiprocessing method Take a look what the official python documentation says about the multiprocessing method </p> <img src="https://user-images.githubusercontent.com/6979335/121958121-b0ebb780-cd39-11eb-862a-37244f7f635b.png"> &lt;small&gt;Source: <a href="https://docs.python.org/3/library/multiprocessing.html">https://docs.python.org/3/library/multiprocessing.html</a>&lt;/small&gt;messias.physics@gmail.com (demvessias)Mon, 14 Jun 2021 18:21:03 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/post-1-a-stadia-like-system-for-data-visualization/Weekly Check-In #1https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-1-21/Hi everyone! My name is Bruno Messias currently I'm a Ph.D student at USP/Brazil. In this summer I'll develop new tools and features for FURY-GL Specifically, I'll focus into developing a system for collaborative visualization of large network layouts using FURY and VTK. <h2>What did I do this week?</h2> In my first meeting the mentors explained the rules and the code of conduct inside the FURY organization. We also made some modifications in the timeline and discussed the next steps of my project. I started coding during the community bonding period. The next paragraph shows my contributions in the past weeks <ul> <li><a href="’https://github.com/fury-gl/fury/pull/437’">A FURY/VTK webrtc stream system proposal:</a> to the second part of my GSoC project I need to have a efficiently and easy to use streaming system to send the graph visualizations across the Internet. In addition, I also need this to my Ph.D. Therefore, I’ve been working a lot in this PR. This PR it’s also help me to achieve the first part of my project. Because I don’t have a computer with good specs in my house and I need to access a external computer to test the examples for large graphs. </li> <li>Minor improvements into the <a href="https://github.com/fury-gl/fury/pull/422’">shader markers PR</a> and <a href="’https://github.com/fury-gl/fury/pull/432/"> fine tunning open-gl state PR</a>. </li> </ul> <h2>Did I get stuck anywhere?</h2> I’ve been stuck into a performance issue (copying the opengl framebuffer to a python rawarray) which caused a lot of lag in the webrtc streamer. Fortunately, I discovered that I’ve been using rawarrays in the wrong way. My <a href=" https://github.com/fury-gl/fury/pull/437/commits/b1b0caf30db762cc018fc99dd4e77ba0390b2f9e ">commit</a> solved this performance issue. <h2>What is coming up next?</h2> In this week I'll focus on finish the #432 and #422 pull-requests.messias.physics@gmail.com (demvessias)Tue, 08 Jun 2021 14:46:11 +0000https://blogs.python-gsoc.org/en/demvessiass-blog/weekly-check-in-1-21/