Commit 1cbe03ae authored by Alexandre Boyer's avatar Alexandre Boyer
Browse files

changes in docstring

parent e6819a68
Pipeline #124083 passed with stage
in 54 seconds
......@@ -5,7 +5,7 @@ This module implements the Module class, which monitors the execution
of a running process
Attributes:
logger (logging.logger): Logger of the current module
logger (:obj:`logging.logger`): Logger of the current module
"""
......@@ -26,9 +26,11 @@ logger = logging.getLogger('MONITOR')
class Monitor():
""" Class that implements a monitor: a Monitor object contains a python function
"""Class that implements a monitor
A Monitor object contains a python function
that will be run in parallel with a monitor process.
Once the `main_function` terminates, the monitoring thread terminates.
Once the `main_function` terminates, the monitoring thread terminates.
Attributes:
main_function (function): Python function that will be run as a subprocess and monitored
......@@ -42,16 +44,16 @@ class Monitor():
def __init__(self, main_function, args, command_name='default_command', interval=5):
"""
Args:
main_function (function): Python function that will be run as a subprocess and monitored
args (Namespace): Arguments given when executing the `main_function`
command_name (str, optional): Name of the command that will be monitored
interval (int, optional): Interval (in *s*) to poll the system resources
"""
self.command_name = command_name
self.main_function = main_function
self.args = args
self.interval = interval
self.interval = interval
log_file_path = os.path.dirname(__file__)
self.log_file = os.path.join(log_file_path, './resources_monitoring.json')
......@@ -61,8 +63,11 @@ class Monitor():
def run_monitor(self):
"""Runs the monitoring process: the `main_function` in a process and the
"""Runs the monitoring process
The `main_function` in a process and the
`monitoring_process()` function in another.
"""
self.main_process = Process(target=self.main_function, kwargs=self.args.__dict__)
......@@ -76,10 +81,11 @@ class Monitor():
"""Increment the file pointed by the `log_file` attribute with a new dict
Note:
The existing `log_file` will be overwritten it it fails to load using JSON.load()
The existing `log_file` will be overwritten it it fails to load using JSON.load()
Args:
log_dict (:obj:dict) A new dictionary to increment the existing log_file
log_dict (:obj:`dict`) A new dictionary to increment the existing log_file
"""
with open(self.log_file, 'a') as f:
......@@ -117,7 +123,7 @@ class Monitor():
# Increment the logs file
self.increment_log_file(resources_use)
time.sleep(self.interval)
except Exception as e:
......
# -*- coding: utf-8 -*-
'''NVML Handler module
"""NVML Handler module
This module implements the NvmlHandler class, which interacts with the NVML
module to monitor the status of the NVIDIA GPU hardware
Attributes:
logger (:logging.logger): Logger of the current module
logger (:obj: `logging.logger`): Logger of the current module
'''
"""
from pynvml import *
......@@ -18,23 +18,25 @@ import logging
logger = logging.getLogger('MONITOR')
class NvmlHandler():
'''
Class to wrap the function to monitor NVIDIA GPUs using the pynvml package.
This class is instanciated using a context manager to ensure that the NVML
pointers are destroyed.
"""Class to wrap the function to monitor NVIDIA GPUs using the pynvml package.
Attributes:
devices (:obj:`dict` of :obj:`NvmlObjects`): references pointers to the NVIDIA devices
This class is instanciated using a context manager to ensure that the NVML
pointers are destroyed.
Example:
with NvmlHandler() as nvml_handler:
nvml_handler.get_devices_status()
'''
Attributes:
devices (:obj:`dict` of :obj:`NvmlObjects`): references pointers to the NVIDIA devices
Example:
with NvmlHandler() as nvml_handler:
nvml_handler.get_devices_status()
"""
def __init__(self):
'''Init the connection with NVML,
"""Init the connection with NVML,
And stores the device handlers in a dictionary
'''
"""
nvmlInit()
n_devices = nvmlDeviceGetCount()
devices_handlers_list = [nvmlDeviceGetHandleByIndex(i) for i in range(n_devices)]
......@@ -45,23 +47,26 @@ class NvmlHandler():
}
def __enter__(self):
'''Called when instanciating the Object using a with: block
'''
"""Called when instanciating the Object using a with: block
"""
return self
def __exit__(self, exc_type, exc_value, traceback):
'''Called to destroy the pointer to NVML
'''
"""Called to destroy the pointer to NVML
"""
nvmlShutdown()
def get_devices_status(self):
'''Get the status of the devices referenced in `devices`
Returns:
{"device_name": {"key":"value", ...}, ...} with some relevant information from NVML
'''
"""Get the status of the devices referenced in `devices`
Returns:
{"device_name": {"key":"value", ...}, ...} with some relevant information from NVML
"""
return {
dev_name:{
......@@ -76,10 +81,10 @@ class NvmlHandler():
}
def get_running_processes(self, dev_handler):
'''Use the NVML's nvmlDeviceGetComputeRunningProcesses to get processes using the GPU,
"""Use the NVML's nvmlDeviceGetComputeRunningProcesses to get processes using the GPU,
And get some information about these processes using the psutil module
'''
"""
# Get the list of running processes on each device
running_processes = NvmlHandler.exec_nvml_function(nvmlDeviceGetComputeRunningProcesses,dev_handler)
......@@ -114,15 +119,15 @@ class NvmlHandler():
@staticmethod
def exec_nvml_function(nvml_func, dev_handler, attr=None):
'''Wrapper arount the NVML functions: they will send exceptions
"""Wrapper arount the NVML functions: they will send exceptions
if an attribute is unavailable
Args:
nvml_func (:`function`): NVML function to execute
dev_handler (:obj:`NvmlObjects`): Pointer to a device
attr (str, optional): Attribute to get from the object returned from `nvml_func`
'''
attr (str, optional): Attribute to get from the object returned from `nvml_func`
"""
try:
obj = nvml_func(dev_handler)
if attr:
......
"""Utils module for resource monitoring
"""
import psutil
def psutil_snapshot():
'''
'''
""" Take a snapshot of cpu and memory usage
"""
snapshot_dict = {}
snapshot_dict = {
......@@ -23,28 +24,32 @@ def psutil_snapshot():
psutil.disk_io_counters(perdisk=False, nowrap=True).write_bytes
)
}
return snapshot_dict
def psutil_snapshot_process(pid, snap_children=True):
'''
Return the psutil.Process attribute in a dictionnary
Monitor the children too if desc_children
Args:
pid (int): Pid to monitor
snap_children (boolean): Whether to recurse the function on the process' children
Returns:
If snap_children:
{'command':'some_command', ...}
else:
{'command':'some_command', ... {'children': [
{'command':'some_command', ... {'children': {} }}},
... ]
}}
'''
"""
Return the psutil.Process attribute in a dictionnary
Monitor the children too if desc_children
Args:
pid (int): Pid to monitor
snap_children (boolean): Whether to recurse the function on the process' children
Returns:
dict: resources usage for a given pid and its children
if snap_children::
{'command':'some_command', ...}
else::
{'command':'some_command', ... {'children': [
{'command':'some_command', ... {'children': {} }}},
... ]
}}
"""
proc = psutil.Process(pid)
pic = {}
......@@ -73,18 +78,21 @@ def psutil_snapshot_process(pid, snap_children=True):
def psutil_parse_readable_bytes(n_bytes):
'''Parse a number of byte in a human readable format
"""Parse a number of byte in a human readable format
Args:
n_bytes (:obj:) Number of bytes, castable to an int
Returns:
Human readable abount of bytes in the best memory unit possible
Examples:
>>> psutil_parse_readable_bytes(10000)
'9.8K'
>>> psutil_parse_readable_bytes(100001221)
'95.4M'
'''
"""
n = int(n_bytes)
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
......@@ -94,4 +102,4 @@ def psutil_parse_readable_bytes(n_bytes):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sB" % n
\ No newline at end of file
return "%sB" % n
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment