Skip to content

Commit

Permalink
Start adding interfaces for various actions
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyhunt committed Dec 7, 2023
1 parent c78fd28 commit 163e90e
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/smartmultiprocessing/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from ctypes import Union
from dataclasses import dataclass
from pathlib import Path
from typing import Optional
import psutil
from smartmultiprocessing.gui.base import SmartMultiprocessingGui

from smartmultiprocessing.gui.printer import PrintGUI


def usable_physical_cpu_count():
physical_cpu_count = psutil.cpu_count(logical=False)
usable_cpu_fraction = psutil.cpu_count(logical=True) / len(
psutil.Process().cpu_affinity()
)
usable_cpu_count = int(physical_cpu_count * usable_cpu_fraction)
if usable_cpu_count < 1:
raise RuntimeError("CPU count could not be automatically estimated.")
return usable_cpu_count


def total_system_memory():
return psutil.virtual_memory().total


PHYSICAL_CORE_COUNT = usable_physical_cpu_count()
TOTAL_PHYSICAL_MEMORY = total_system_memory()
DEFAULT_MEMORY_PER_PROCESS = int(TOTAL_PHYSICAL_MEMORY / PHYSICAL_CORE_COUNT * 0.7)


@dataclass
class Config:
# Metadata
name: str = "Untitled_SmartMultiprocessing_Run"
gui: Optional[SmartMultiprocessingGui] = PrintGUI

# How processes are handled
process_count: int = PHYSICAL_CORE_COUNT
memory: int = int(0.6 * TOTAL_PHYSICAL_MEMORY)
max_memory: int = int(0.8 * TOTAL_PHYSICAL_MEMORY)
error_on_overmemory: bool = False
stop_all_on_error: bool = True
failed_task_repeats: int = 0

# Logging information
log_main_thread: bool = False
logging_directory: Union[str, Path] = Path("./logs")
log_every_process: bool = False
1 change: 1 addition & 0 deletions src/smartmultiprocessing/gui/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .printer import PrintGUI
26 changes: 26 additions & 0 deletions src/smartmultiprocessing/gui/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from abc import ABCMeta, abstractmethod
from typing import Iterable, Optional
from smartmultiprocessing.gui.commands import SmartMultiprocessingCommand
from smartmultiprocessing.gui.updates import SmartMultiprocessingGuiUpdate

class SmartMultiprocessingGui(metaclass=ABCMeta):
@abstractmethod
def start(self):
"""Starts the GUI."""
pass

@abstractmethod
def stop(self):
"""Stops the GUI."""
pass

@abstractmethod
def update(self, updates: Iterable[SmartMultiprocessingGuiUpdate]):
"""Updates the current state of the GUI."""
pass

@abstractmethod
def get_commands(self) -> Optional[Iterable[SmartMultiprocessingCommand]]:
"""Checks to see if there is any current user input. If yes, returns an iterable
list of commands; if no, returns None."""
pass
34 changes: 34 additions & 0 deletions src/smartmultiprocessing/gui/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from abc import ABC
from typing import Any, Mapping


class SmartMultiprocessingCommand(ABC):
pass


class StopCommand(SmartMultiprocessingCommand):
def __init__(self) -> None:
"""Asks a system to stop after execution of all current processes."""
raise NotImplementedError("Command not implemented.")


class TerminateCommand(SmartMultiprocessingCommand):
def __init__(self) -> None:
"""Politely terminates a system (SIGTERM)."""
raise NotImplementedError("Command not implemented.")


class KillCommand(SmartMultiprocessingCommand):
def __init__(self) -> None:
"""Ask a system to stop immediately (SIGKILL)."""
raise NotImplementedError("Command not implemented.")


class UpdateCommand(SmartMultiprocessingCommand):
def __init__(self) -> None:
"""Updates some arbitrary aspect of the configuration of the system."""
raise NotImplementedError("Command not implemented.")

def get_update(self) -> Mapping[str, Any]:
"""Get the update to be applied to the system."""
pass
6 changes: 6 additions & 0 deletions src/smartmultiprocessing/gui/interactive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from smartmultiprocessing.gui.base import SmartMultiprocessingGui


class InteractiveModeGUI(SmartMultiprocessingGui):
def __init__(self) -> None:
raise NotImplementedError("GUI type not implemented.")
29 changes: 29 additions & 0 deletions src/smartmultiprocessing/gui/printer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import Iterable
from smartmultiprocessing import utilities
from smartmultiprocessing.gui.base import SmartMultiprocessingGui
from smartmultiprocessing.gui.updates import SmartMultiprocessingGuiUpdate


class PrintGUI(SmartMultiprocessingGui):
def __init__(self) -> None:
"""The most basic possible SmartMultiprocessing GUI! It simply prints to
console.
You should probably check out the more advanced GUIs implemented in the library;
this one is only really intended for testing purposes, or systems with very
limited resources.
"""
pass

def start(self):
pass

def stop(self):
pass

def update(self, updates: Iterable[SmartMultiprocessingGuiUpdate]):
for update in updates:
print(utilities.timestamp() + update.to_string())

def get_commands(self):
return None
6 changes: 6 additions & 0 deletions src/smartmultiprocessing/gui/terminal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from smartmultiprocessing.gui.base import SmartMultiprocessingGui


class TerminalGUI(SmartMultiprocessingGui):
def __init__(self) -> None:
raise NotImplementedError("GUI type not implemented.")
8 changes: 8 additions & 0 deletions src/smartmultiprocessing/gui/updates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from abc import ABC, abstractmethod


class SmartMultiprocessingGuiUpdate(ABC):
@abstractmethod
def to_string(self):
"""Converts a GUI update to a string."""
pass
6 changes: 6 additions & 0 deletions src/smartmultiprocessing/manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ProcessManager:
def __init__(self, config) -> None:
"""Basic process manager shared amongst all high-level APIs. Not intended for
use by users; instead, please use SmartQueue and SmartPool objects.
"""
pass

0 comments on commit 163e90e

Please sign in to comment.