Introduction
What is machinable?
machinable is a Python API for research code. It provides an object-oriented skeleton that helps you efficiently develop and experiment in a unified interface while handling tedious housekeeping behind the scenes.
The key idea is to unify the running of code and the retrieval of produced results in one abstraction. A detailed discussion of this approach can be found in the about section, but for now, here is a minimal example that illustrates the idea.
- Write some code in a module class
from dataclasses import dataclass
from random import random
from machinable import Experiment
class EstimatePi(Experiment):
@dataclass
class Config:
samples: int = 100
def on_execute(self):
count = 0
for _ in range(self.config.samples):
x, y = random(), random()
count += int((x**2 + y**2) <= 1)
pi = 4 * count / self.config.samples
self.save_data(
"result.json",
{"count": count, "pi": pi},
)
def summary(self):
if self.is_finished():
print(
f"After {self.config.samples} samples, "
f"PI is approximately {self.load_data('result.json')['pi']}."
)
- Run and inspect it using a unified abstraction
from machinable import get
experiment = get("montecarlo", {"samples": 150})
# Imports experiment in `montecarlo.py` with samples=150;
# if an experiment with this configuration exists, it
# is automatically reloaded.
experiment.launch()
# Executes the experiment unless it's already been computed
experiment.summary()
# >>> After 150 samples, PI is approximately 3.1466666666666665.
>>> from machinable import get
>>> experiment = get("montecarlo", {"samples": 150})
>>> experiment.launch()
Experiment <is51xA>
>>> experiment.summary()
After 150 samples, PI is approximately 3.1466666666666665.
>>> experiment.execution.nickname
'chocolate_mosquito'
>>> experiment.finished_at().humanize()
'finished just now'
>>> experiment.local_directory()
'./storage/is51xA'
$ machinable montecarlo samples=150 --launch --summary
> After 150 samples, PI is approximately 3.1466666666666665.
The above example demonstrates the two core principles of machinable code:
- Enforced modularity The Monte Carlo algorithm is encapsulated in its own module that can be instantiated with different configuration settings.
- Unified representation Running experiments is handled through the same interface that is used to retrieve their results; multiple get-invocations simply reload and display the results without re-running the simulation.
You may already have questions - don't worry. We will cover the details in the rest of the documentation. For now, please read along so you can have a high-level understanding of what machinable offers.
What it is not
Research is extremely diverse so machinable primarily aims to be an API-spec that leaves concrete feature implementation to the user. It does not compete with other frameworks that may provide similar functionality but embraces the integration of other tools within the API. Notably, the machinable ecosystem already provides wrappers and integrations of a variety of tools and it is easy for users to maintain their own.
Where to go from here
If you are interested in learning more, continue with the guide that will quickly introduce the bare minimum of concepts necessary to start using machinable. Along the way, we will provide pointers to sections of the tutorial that discuss concepts in more detail or cover more advanced functionality.
After covering the essentials, feel free to pick a learning path that suits your preference - although we do recommend going over all of the content at some point, of course!
Installation
We recommend installing machinable to try things out while following along.
🧑🎓 Continue with the Tutorial
Designed for beginners to learn the essential things hands-on.
The guide describes every aspect of the framework and available APIs in full detail.
➡️ Check out the How-to guides
Explore real-world examples that demonstrate advanced concepts