From 3c51cd44ccc809e7399fcf6a79e5a2f3131f460e Mon Sep 17 00:00:00 2001 From: h-aze Date: Mon, 4 Dec 2023 13:00:22 +0000 Subject: [PATCH] Added logo to docs --- .github/workflows/docs.yml | 5 +- .github/workflows/tests_windows.yml | 2 +- README.md | 2 +- docs/.html/search.js | 2 +- docs/.html/src.html | 57 ++++++++++++++--------- docs/.html/src/slune.html | 5 +- docs/.html/src/slune/base.html | 1 + docs/.html/src/slune/loggers.html | 1 + docs/.html/src/slune/loggers/default.html | 1 + docs/.html/src/slune/savers.html | 1 + docs/.html/src/slune/savers/csv.html | 1 + docs/.html/src/slune/searchers.html | 1 + docs/.html/src/slune/searchers/grid.html | 1 + docs/.html/src/slune/slune.html | 45 +++++++++--------- docs/.html/src/slune/utils.html | 1 + 15 files changed, 74 insertions(+), 52 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c92c600..b823f51 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,4 +1,4 @@ -name: website +name: Documentation # build the documentation whenever there are new commits on main on: @@ -28,8 +28,7 @@ jobs: - run: pip install pdoc # ADJUST THIS: build your documentation into docs/. # We use a custom build script for pdoc itself, ideally you just run `pdoc -o docs/ ...` here. - - run: pdoc --docformat google --logo "https://github.com/h-0-0/slune/blob/5ef13e03e671c280d4a7918c3b718cf73930f6ba/slune.jpeg" -o docs/.html src - + - run: pdoc --docformat google --logo "https://raw.githubusercontent.com/h-0-0/slune/main/slune.jpeg" -o docs/.html src - uses: actions/upload-pages-artifact@v2 with: path: docs/.html diff --git a/.github/workflows/tests_windows.yml b/.github/workflows/tests_windows.yml index 1ec6c87..ea228c9 100644 --- a/.github/workflows/tests_windows.yml +++ b/.github/workflows/tests_windows.yml @@ -1,4 +1,4 @@ -name: Tests +name: Tests windows on: push: diff --git a/README.md b/README.md index 626b008..0844717 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![PyPI - Version](https://img.shields.io/pypi/v0.0.2/:slune-lib) +[![PyPI version](https://badge.fury.io/py/slune-lib.svg)](https://badge.fury.io/py/slune-lib) [![license](https://img.shields.io/badge/License-MIT-purple.svg)](LICENSE) ![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/h-0-0/4aa01e058fee448070c587f6967037e4/raw/CodeCovSlune.json) diff --git a/docs/.html/search.js b/docs/.html/search.js index bcd0f25..19641a9 100644 --- a/docs/.html/search.js +++ b/docs/.html/search.js @@ -1,6 +1,6 @@ window.pdocSearch = (function(){ /** elasticlunr - http://weixsong.github.io * Copyright (C) 2017 Oliver Nightingale * Copyright (C) 2017 Wei Song * MIT Licensed */!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o\"PyPI\n\"license\"\n\"badge\"

\n\n

\"badge\"\n\"badge\"\n\"badge\"

\n\n

slune (= slurm + tune!)

\n\n

A super simplistic python package for performing hyperparameter tuning (or more generally launching jobs and saving results) on a cluster using SLURM. Takes advantage of the fact that lots of jobs (including hyperparameter tuning) are embarrassingly parallel! With slune you can divide your compute into lots of separately scheduled jobs meaning that each small job can get running on your cluster more quickly, speeding up your workflow! Often significantly!

\n\n

Slune is super-easy to use! We have helper functions which can execute everything you need done for you. Letting you speed up your work without wasting time.

\n\n

Slune is barebones by design. This means that you can easily write code to integrate with slune if you want to do something a bit different! You can also workout what each function is doing pretty easily.

\n\n

Slune is flexible. In designing this package I've tried to make as few assumptions as possible meaning that it can be used for lots of stuff outside hyperparameter tuning! (or also within!) For example, you can get slune to give you paths for where to save things, submit lots of jobs in parallel for any sort of script and do grid search! and there's more to come!

\n\n

Usage

\n\n

Let's go through a quick example of how we can use slune ... first let's define a model that we want to train:

\n\n
\n
# Simple Regularized Linear Regression without using external libraries\n\n# Function to compute the mean of a list\ndef mean(values):\n    return sum(values) / float(len(values))\n\n# Function to compute the covariance between two lists\ndef covariance(x, mean_x, y, mean_y):\n    covar = 0.0\n    for i in range(len(x)):\n        covar += (x[i] - mean_x) * (y[i] - mean_y)\n    return covar\n\n# Function to compute the variance of a list\ndef variance(values, mean):\n    return sum((x - mean) ** 2 for x in values)\n\n# Function to compute coefficients for a simple regularized linear regression\ndef coefficients_regularized(x, y, alpha):\n    mean_x, mean_y = mean(x), mean(y)\n    var_x = variance(x, mean_x)\n    covar = covariance(x, mean_x, y, mean_y)\n    b1 = (covar + alpha * var_x) / (var_x + alpha)\n    b0 = mean_y - b1 * mean_x\n    return b0, b1\n\n# Function to make predictions with a simple regularized linear regression model\ndef linear_regression_regularized(train_X, train_y, test_X, alpha):\n    b0, b1 = coefficients_regularized(train_X, train_y, alpha)\n    predictions = [b0 + b1 * x for x in test_X]\n    return predictions\n\n# ------------------\n# The above is code for a simple normalized linear regression model that we want to train.\n# Now let's fit the model and use slune to save how well our model performs!\n# ------------------\n\nif __name__ == "__main__":\n    # First let's load in the value for the regularization parameter alpha that has been passed to this script from the command line. We will use the slune helper function lsargs to do this. \n    # lsargs returns a tuple of the python path and a list of arguments passed to the script. We can then use this to get the alpha value.\n    from slune import lsargs\n    python_path, args = lsargs()\n    alpha = float(args[0])\n\n    # Mock training dataset, function is y = 1 + 1 * x\n    X = [1, 2, 3, 4, 5]\n    y = [2, 3, 4, 5, 6]\n\n    # Mock test dataset\n    test_X = [6, 7, 8]\n    test_y = [7, 8, 9]\n    test_predictions = linear_regression_regularized(X, y, test_X, alpha)\n\n    # First let's load in a function that we can use to get a saver object that uses the default method of logging (we call this object a slog = saver + logger). The saving will be coordinated by a csv saver object which saves and reads results from csv files stored in a hierarchy of directories.\n    from slune import get_csv_slog\n    csv_slog = get_csv_slog(params = args)\n\n    # Let's now calculate the mean squared error of our predictions and log it!\n    mse = mean((test_y[i] - test_predictions[i])**2 for i in range(len(test_y)))\n    csv_slog.log({'mse': mse})\n\n    # Let's now save our logged results!\n    slog.save_collated()\n
\n
\n\n

Now let's write some code that will submit some jobs to train our model using different hyperparameters!!

\n\n
\n
# Let's now load in a function that will coordinate our search! We're going to do a grid search.\n# SearcherGrid is the class we can use to coordinate a grid search. We pass it a dictionary of hyperparameters and the values we want to try for each hyperparameter. We also pass it the number of runs we want to do for each combination of hyperparameters.\nfrom slune.searchers import SearcherGrid\ngrid_searcher = SearcherGrid({'alpha' : [0.25, 0.5, 0.75]}, runs = 1)\n\n# Let's now import a function which will submit a job for our model, the script_path specifies the path to the script that contains the model we want to train. The template_path specifies the path to the template script that we want to specify the job with, cargs is a list of constant arguments we want to pass to the script for each tuning. \n# We set slog to None as we don't want to not run jobs if we have already run them before.\nfrom slune import sbatchit\nscript_path = 'model.py'\ntemplate_path = 'template.sh'\nsbatchit(script_path, template_path, grid_searcher, cargs=[], slog=None)\n
\n
\n\n

Now we've submitted our jobs we will wait for them to finish \ud83d\udd5b\ud83d\udd50\ud83d\udd51\ud83d\udd52\ud83d\udd53\ud83d\udd54\ud83d\udd55\ud83d\udd56\ud83d\udd57\ud83d\udd58\ud83d\udd59\ud83d\udd5a\ud83d\udd5b, now that they are finished we can read the results!

\n\n
\n
from slune import get_csv_slog\ncsv_slog = get_csv_slog(params = None)\nparams, value = csv_slog.read(params = [], metric_name = 'mse', select_by ='min')\nprint(f'Best hyperparameters: {params}')\nprint(f'Their MSE: {value}')\n
\n
\n\n

Amazing! \ud83e\udd73 We have successfully used slune to train our model. I hope this gives you a good flavour of how you can use slune and how easy it is to use!

\n\n

Please check out the examples folder for notebooks detailing in more depth some potential ways you can use slune. The docs are not yet up and running \ud83d\ude22 but they are coming soon!

\n\n

Roadmap

\n\n
    \n
  • Make package user friendly:\n
      \n
    • Go through automation settings.
    • \n
    • Code of conduct.
    • \n
    • Contributing guidelines.
    • \n
    • Add to pypi.\nStill in early stages! First thing on the horizon is better integration with SLURM:
    • \n
  • \n
  • Set-up notifications for job completion, failure, etc.
  • \n
  • Auto job naming, job output naming and job output location saving.
  • \n
  • Auto save logged results when finishing a job.
  • \n
  • Automatically re-submit failed jobs.
  • \n
  • Tools for monitoring and cancelling jobs. \nThen it will be looking at adding more savers, loggers and searchers! For example integration with tensorboard, saving to one csv file (as opposed to a hierarchy of csv files in different directories) and different search methods like random search and cross validation. It would perhaps also be beneficial to be able to interface with other languages like R and Julia. Finally, more helper functions!
  • \n
\n\n

However, I am trying to keep this package as bloatless as possible to make it easy for you to tweak and configure to your individual needs. It's written in a simple and compartmentalized manner for this reason. You can of course use the helper functions and let slune handle everything under the hood, but, you can also very quickly and easily write your own classes to work with other savers, loggers and searchers to do as you please.

\n\n

Installation

\n\n

To install latest version use:

\n\n
\n
pip install slune-lib\n
\n
\n\n

To install latest dev version use (CURRENTLY RECOMENDED):

\n\n
\n
# With https\npip install "git+https://github.com/h-aze/slune.git#egg=slune-lib"\n
\n
\n\n

Class Design

\n\n

Here we will outline the different kind of classes that are used in slune and how they interact with each other. There are 3 types:

\n\n
    \n
  • 'Searcher' classes - these are the classes that are used to define and traverse a search space.
  • \n
  • 'Logger' classes - these are the classes that are used to create and read log files.
  • \n
  • 'Saver' classes - these are the classes that are used to save logs to files and read logs from files.
  • \n
\n\n

The base module is where the base classes for each of these types are defined. The base classes are:

\n\n
    \n
  • BaseSearcher
  • \n
  • BaseLogger
  • \n
  • BaseSaver
  • \n
\n\n

To create a new searcher, logger or saver, you must inherit from the appropriate base class and implement the required methods. The required methods will have the '@abc.abstractmethod' decorator above them and will throw errors if they are not implemented. The compulsory methods allow for well-defined interactions between the different classes and should allow for any combination of searcher, logger and saver to be used together.

\n\n

Please read the docs for the base classes to see what methods are required to be implemented and how they should be implemented.

\n"}, {"fullname": "src.slune", "modulename": "src.slune", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.base", "modulename": "src.slune.base", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSearcher", "modulename": "src.slune.base", "qualname": "BaseSearcher", "kind": "class", "doc": "

Base class for all Searchers.

\n\n

This must be subclassed to create different Searcher classes.\nPlease name your searcher class Searcher\nOutlines a protocol for creating a search space and creating configurations from it.\nMethods document what they should do once implemented.

\n"}, {"fullname": "src.slune.base.BaseSearcher.__init__", "modulename": "src.slune.base", "qualname": "BaseSearcher.__init__", "kind": "function", "doc": "

Initialises the searcher.

\n", "signature": "(*args, **kwargs)"}, {"fullname": "src.slune.base.BaseSearcher.next_tune", "modulename": "src.slune.base", "qualname": "BaseSearcher.next_tune", "kind": "function", "doc": "

Returns the next configuration to try.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSearcher.check_existing_runs", "modulename": "src.slune.base", "qualname": "BaseSearcher.check_existing_runs", "kind": "function", "doc": "

Used to tell searcher to check if there are existing runs in storage.

\n\n

If there are existing runs, the searcher should skip them \nbased on the number of runs we would like for each job.\nThis may require a 'runs' attribute to be set in the searcher.\nIt will probably also require access to a Saver object,\nso we can use it's saving protocol to check if there are existing runs.\nIn this case is advised that this function takes a Saver object as an argument,\nand that the searcher is initialized with a 'runs' attribute.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseLogger", "modulename": "src.slune.base", "qualname": "BaseLogger", "kind": "class", "doc": "

Base class for all Loggers.

\n\n

This must be subclassed to implement different Logger classes.\nPlease name your logger class Logger.\nOutlines a protocol for logging metrics and reading from the logs.\nMethods document what they should do once implemented.

\n"}, {"fullname": "src.slune.base.BaseLogger.__init__", "modulename": "src.slune.base", "qualname": "BaseLogger.__init__", "kind": "function", "doc": "

Initialises the logger.

\n", "signature": "(*args, **kwargs)"}, {"fullname": "src.slune.base.BaseLogger.log", "modulename": "src.slune.base", "qualname": "BaseLogger.log", "kind": "function", "doc": "

Logs the metric/s for the current hyperparameter configuration.

\n\n

Should store metrics in some way so we can later save it using a Saver.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseLogger.read_log", "modulename": "src.slune.base", "qualname": "BaseLogger.read_log", "kind": "function", "doc": "

Returns value of a metric from the log based on a selection criteria.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSaver", "modulename": "src.slune.base", "qualname": "BaseSaver", "kind": "class", "doc": "

Base class for all savers.

\n\n

This must be subclassed to implement different Saver classes.\nPlease name your saver class Saver.\nOutlines a protocol for saving and reading results to/from storage.\nMethods document what they should do once implemented.

\n"}, {"fullname": "src.slune.base.BaseSaver.__init__", "modulename": "src.slune.base", "qualname": "BaseSaver.__init__", "kind": "function", "doc": "

Initialises the saver.

\n\n

Assigns the logger instance to self.logger and makes its methods accessible through self.log and self.read_log.

\n\n
Arguments:
\n\n
    \n
  • - logger_instance (BaseLogger): Instance of a logger class that inherits from BaseLogger.
  • \n
\n", "signature": "(logger_instance: src.slune.base.BaseLogger, *args, **kwargs)"}, {"fullname": "src.slune.base.BaseSaver.logger", "modulename": "src.slune.base", "qualname": "BaseSaver.logger", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSaver.log", "modulename": "src.slune.base", "qualname": "BaseSaver.log", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSaver.read_log", "modulename": "src.slune.base", "qualname": "BaseSaver.read_log", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSaver.save_collated", "modulename": "src.slune.base", "qualname": "BaseSaver.save_collated", "kind": "function", "doc": "

Saves the current results in logger to storage.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSaver.read", "modulename": "src.slune.base", "qualname": "BaseSaver.read", "kind": "function", "doc": "

Reads results from storage.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSaver.exists", "modulename": "src.slune.base", "qualname": "BaseSaver.exists", "kind": "function", "doc": "

Checks if results already exist in storage.

\n\n

Should return integer indicating the number of runs that exist in storage for the given parameters.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.loggers", "modulename": "src.slune.loggers", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.loggers.default", "modulename": "src.slune.loggers.default", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.loggers.default.LoggerDefault", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault", "kind": "class", "doc": "

Logs metric/s in a data frame.

\n\n

Stores the metric/s in a data frame that we can later save in storage.\nLogs by creating data frame out of the metrics and then appending it to the current results data frame.

\n\n
Attributes:
\n\n
    \n
  • - results (pd.DataFrame): Data frame containing all the metrics logged so far.\nEach row stores all the metrics that were given in a call to the 'log' method,\neach column title is a metric name.\nThe first column is always the time stamp at which 'log' is called.
  • \n
\n", "bases": "slune.base.BaseLogger"}, {"fullname": "src.slune.loggers.default.LoggerDefault.__init__", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.__init__", "kind": "function", "doc": "

Initialises the logger.

\n", "signature": "(*args, **kwargs)"}, {"fullname": "src.slune.loggers.default.LoggerDefault.results", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.results", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.loggers.default.LoggerDefault.log", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.log", "kind": "function", "doc": "

Logs the metric/s given.

\n\n

Stores them in a data frame that we can later save in storage.\nAll metrics provided will be saved as a row in the results data frame,\nthe first column is always the time stamp at which log is called.

\n\n
Arguments:
\n\n
    \n
  • - metrics (dict): Metrics to be logged, keys are metric names and values are metric values.\nEach metric should only have one value! So please log as soon as you get a metric.
  • \n
\n", "signature": "(self, metrics: dict):", "funcdef": "def"}, {"fullname": "src.slune.loggers.default.LoggerDefault.read_log", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.read_log", "kind": "function", "doc": "

Reads log and returns value according to select_by.

\n\n

Reads the values for given metric for given log and chooses metric value to return based on select_by.

\n\n
Arguments:
\n\n
    \n
  • - data_frame (pd.DataFrame): Data frame containing the metric to be read.
  • \n
  • - metric_name (str): Name of the metric to be read.
  • \n
  • - select_by (str, optional): How to select the 'best' metric, currently can select by 'min' or 'max'.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • value (float): Minimum or maximum value of the metric.
  • \n
\n
\n\n

TODO: \n - Add more options for select_by.\n - Should be able to return other types than float?

\n", "signature": "(\tself,\tdata_frame: pandas.core.frame.DataFrame,\tmetric_name: str,\tselect_by: str = 'max') -> float:", "funcdef": "def"}, {"fullname": "src.slune.savers", "modulename": "src.slune.savers", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.savers.csv", "modulename": "src.slune.savers.csv", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.savers.csv.SaverCsv", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv", "kind": "class", "doc": "

Saves the results of each run in a CSV file in hierarchy of directories.

\n\n

Each directory is named after a parameter - value pair in the form \"--parameter_name=value\".\nThe paths to csv files then define the configuration under which the results were obtained,\nfor example if we only have one parameter \"learning_rate\" with value 0.01 used to obtain the results,\nto save those results we would create a directory named \"--learning_rate=0.01\" and save the results in a csv file in that directory.

\n\n

If we have multiple parameters, for example \"learning_rate\" with value 0.01 and \"batch_size\" with value 32,\nwe would create a directory named \"--learning_rate=0.01\" with a subdirectory named \"--batch_size=32\",\nand save the results in a csv file in that subdirectory.

\n\n

We use this structure to then read the results from the csv files by searching for the directory that matches the parameters we want,\nand then reading the csv file in that directory.

\n\n

The order in which we create the directories is determined by the order in which the parameters are given,\nso if we are given [\"--learning_rate=0.01\", \"--batch_size=32\"] we would create the directories in the following order:\n\"--learning_rate=0.01/--batch_size=32\".

\n\n

The directory structure generated will also depend on existing directories in the root directory,\nif there are existing directories in the root directory that match some subset of the parameters given,\nwe will create the directory tree from the deepest matching directory.

\n\n

For example if we only have the following path in the root directory:\n\"--learning_rate=0.01/--batch_size=32\"\nand we are given the parameters [\"--learning_rate=0.01\", \"--batch_size=32\", \"--num_epochs=10\"],\nwe will create the path:\n\"--learning_rate=0.01/--batch_size=32/--num_epochs=10\".\non the other hand if we are given the parameters [\"--learning_rate=0.02\", \"--num_epochs=10\", \"--batch_size=32\"],\nwe will create the path:\n\"--learning_rate=0.02/--batch_size=32/--num_epochs=10\".

\n\n

Handles parallel runs trying to create the same directories by waiting a random time (under 1 second) before creating the directory.\nShould work pretty well in practice, however, may occasionally fail depending on the number of jobs launched at the same time.

\n\n
Attributes:
\n\n
    \n
  • - root_dir (str): Path to the root directory where we will store the csv files.
  • \n
  • - current_path (str): Path to the csv file where we will store the results for the current run.
  • \n
\n", "bases": "slune.base.BaseSaver"}, {"fullname": "src.slune.savers.csv.SaverCsv.__init__", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.__init__", "kind": "function", "doc": "

Initialises the csv saver.

\n\n
Arguments:
\n\n
    \n
  • - logger_instance (BaseLogger): Instance of a logger class that inherits from BaseLogger.
  • \n
  • - params (list, optional): List of strings containing the parameters used, in form [\"--parameter_name=parameter_value\", ...], default is None.\nIf None, we will create a path using the parameters given in the log.
  • \n
  • - root_dir (str, optional): Path to the root directory where we will store the csv files, default is './tuning_results'.
  • \n
\n", "signature": "(\tlogger_instance: slune.base.BaseLogger,\tparams: List[str] = None,\troot_dir: Optional[str] = './tuning_results')"}, {"fullname": "src.slune.savers.csv.SaverCsv.root_dir", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.root_dir", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.savers.csv.SaverCsv.strip_params", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.strip_params", "kind": "function", "doc": "

Strips the parameter values.

\n\n

Strips the parameter values from the list of parameters given,\nie. [\"--parameter_name=parameter_value\", ...] -> [\"--parameter_name=\", ...]

\n\n

Also gets rid of blank spaces.

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): List of strings containing the parameters used, in form [\"--parameter_name=parameter_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • stripped_params (list of str): List of strings containing the parameters used, in form [\"--parameter_name=\", ...].
  • \n
\n
\n", "signature": "(self, params: List[str]) -> List[str]:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.get_match", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.get_match", "kind": "function", "doc": "

Searches the root directory for a path that matches the parameters given.

\n\n

If only partial matches are found, returns the deepest matching directory with the missing parameters appended.\nBy deepest we mean the directory with the most parameters matching.\nIf no matches are found creates a path using the parameters.\nCreates path using parameters in the order they are given, \nie. [\"--learning_rate=0.01\", \"--batch_size=32\"] -> \"--learning_rate=0.01/--batch_size=32\".

\n\n

If we find a partial match, we add the missing parameters to the end of the path,\nie. if we have the path \"--learning_rate=0.01\" in the root \nand are given the parameters [\"--learning_rate=0.01\", \"--batch_size=32\"],\nwe will create the path \"--learning_rate=0.01/--batch_size=32\".

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): List of strings containing the arguments used, in form [\"--argument_name=argument_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • match (str): Path to the directory that matches the parameters given.
  • \n
\n
\n", "signature": "(self, params: List[str]) -> str:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.get_path", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.get_path", "kind": "function", "doc": "

Creates a path using the parameters.

\n\n

Does this by first checking for existing paths in the root directory that match the parameters given.

\n\n

Check get_match for how we create the path, \nonce we have the path we check if there is already a csv file with results in that path,\nif there is we increment the number of the results file name that we will use.

\n\n

For example if we get back the path \"--learning_rate=0.01/--batch_size=32\",\nand there exists a csv file named \"results_0.csv\" in the final directory,\nwe will name our csv file \"results_1.csv\".

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): List of strings containing the arguments used, in form [\"--argument_name=argument_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • csv_file_path (str): Path to the csv file where we will store the results for the current run.
  • \n
\n
\n", "signature": "(self, params: List[str]) -> str:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.save_collated_from_results", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.save_collated_from_results", "kind": "function", "doc": "

Saves results to csv file.

\n\n

If the csv file already exists, \nwe append the collated results from the logger to the end of the csv file.\nIf the csv file does not exist,\nwe create it and save the results to it.

\n\n
Arguments:
\n\n
    \n
  • - results (pd.DataFrame): Data frame containing the results to be saved.
  • \n
\n\n

TODO: \n - Could be making to many assumptions about the format in which we get the results from the logger,\n should be able to work with any logger.\n We should only be assuming that we are saving results to a csv file.

\n", "signature": "(self, results: pandas.core.frame.DataFrame):", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.save_collated", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.save_collated", "kind": "function", "doc": "

Saves results to csv file.

\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.read", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.read", "kind": "function", "doc": "

Finds the min/max value of a metric from all csv files in the root directory that match the parameters given.

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): Contains the parameters used, in form [\"--parameter_name=parameter_value\", ...].
  • \n
  • - metric_name (string): Name of the metric to be read.
  • \n
  • - select_by (string, optional): How to select the 'best' value for the metric from a log file, currently can select by 'min' or 'max'.
  • \n
  • - avg (bool, optional): Whether to average the metric over all runs, default is True.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • best_params (list of str): Contains the arguments used to get the 'best' value of the metric (determined by select_by).
  • \n
  • best_value (float): Best value of the metric (determined by select_by).
  • \n
\n
\n", "signature": "(\tself,\tparams: List[str],\tmetric_name: str,\tselect_by: str = 'max',\tavg: bool = True) -> (typing.List[str], <class 'float'>):", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.exists", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.exists", "kind": "function", "doc": "

Checks if results already exist in storage.

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): Contains the parameters used, in form [\"--parameter_name=parameter_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • num_runs (int): Number of runs that exist in storage for the given parameters.
  • \n
\n
\n", "signature": "(self, params: List[str]) -> int:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.get_current_path", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.get_current_path", "kind": "function", "doc": "

Getter function for the current_path attribute.

\n\n
Returns:
\n\n
\n
    \n
  • current_path (str): Path to the csv file where we will store the results for the current run.
  • \n
\n
\n", "signature": "(self) -> str:", "funcdef": "def"}, {"fullname": "src.slune.searchers", "modulename": "src.slune.searchers", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid", "modulename": "src.slune.searchers.grid", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid", "kind": "class", "doc": "

Searcher for grid search.

\n\n

Given dictionary of parameters and values to try, creates grid of all possible configurations,\nand returns them one by one for each call to next_tune.

\n\n
Attributes:
\n\n
    \n
  • - configs (dict): Parameters and values to create grid from.\nStructure of dictionary should be: { \"--parameter_name\" : [Value_1, Value_2, ...], ... }
  • \n
  • - runs (int): Controls search based on number of runs we want for each config.\nif runs > 0 -> run each config 'runs' times.\nif runs = 0 -> run each config once even if it already exists.\nThis behavior is modified if we want to (use) check_existing_runs, see methods description.
  • \n
  • - grid (list of dict): List of dictionaries, each containing one combination of argument values.
  • \n
  • - grid_index (int): Index of the current configuration in the grid.
  • \n
  • - saver_exists (function): Pointer to the savers exists method, used to check if there are existing runs.
  • \n
\n", "bases": "slune.base.BaseSearcher"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.__init__", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.__init__", "kind": "function", "doc": "

Initialises the searcher.

\n\n
Arguments:
\n\n
    \n
  • - configs (dict): Dictionary of parameters and values to try.\nStructure of dictionary should be: { \"--parameter_name\" : [Value_1, Value_2, ...], ... }
  • \n
  • - runs (int, optional): Controls search based on number of runs we want for each config.\nif runs > 0 -> run each config 'runs' times.\nif runs = 0 -> run each config once even if it already exists.\nThis behavior is modified if we want to (use) check_existing_runs, see methods description.
  • \n
\n", "signature": "(configs: dict, runs: int = 0)"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.runs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.runs", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.configs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.configs", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.grid", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.grid", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.grid_index", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.grid_index", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.saver_exists", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.saver_exists", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.get_grid", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.get_grid", "kind": "function", "doc": "

Creates search grid.

\n\n

Generates all possible combinations of values for each argument in the given dictionary using recursion.

\n\n
Arguments:
\n\n
    \n
  • - param_dict (dict): A dictionary where keys are argument names and values are lists of values.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • all_combinations (list): A list of dictionaries, each containing one combination of argument values.
  • \n
\n
\n", "signature": "(self, param_dict: dict) -> List:", "funcdef": "def"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.check_existing_runs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.check_existing_runs", "kind": "function", "doc": "

We save a pointer to the savers exists method to check if there are existing runs.

\n\n
If there are n existing runs:
\n\n
\n

n < runs -> run the remaining runs\n n >= runs -> skip all runs

\n
\n\n
Arguments:
\n\n
    \n
  • - saver (BaseSaver): Pointer to the savers exists method, used to check if there are existing runs.
  • \n
\n", "signature": "(self, saver: slune.base.BaseSaver):", "funcdef": "def"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.skip_existing_runs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.skip_existing_runs", "kind": "function", "doc": "

Skips runs if they are in storage already.

\n\n

Will check if there are existing runs for the current configuration,\nif there are existing runs we tally them up \nand skip configs or runs of a config based on the number of runs we want for each config.

\n\n
Arguments:
\n\n
    \n
  • - grid_index (int): Index of the current configuration in the grid.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • grid_index (int): Index of the next configuration in the grid.
  • \n
  • run_index (int): Index of the next run for the current configuration.
  • \n
\n
\n", "signature": "(self, grid_index: int) -> Tuple[int, int]:", "funcdef": "def"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.next_tune", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.next_tune", "kind": "function", "doc": "

Returns the next configuration to try.

\n\n

Will skip existing runs if check_existing_runs has been called.\nFor more information on how this works check the methods descriptions for check_existing_runs and skip_existing_runs.\nWill raise an error if we have reached the end of the grid.\nTo iterate through all configurations, use a for loop like so: \n for config in searcher: ...

\n\n
Returns:
\n\n
\n
    \n
  • next_config (dict): The next configuration to try.
  • \n
\n
\n", "signature": "(self) -> dict:", "funcdef": "def"}, {"fullname": "src.slune.slune", "modulename": "src.slune.slune", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.slune.submit_job", "modulename": "src.slune.slune", "qualname": "submit_job", "kind": "function", "doc": "

Submits a job using specified Bash script

\n\n
Arguments:
\n\n
    \n
  • - sh_path (string): Path to the Bash script to be run.
  • \n
  • - args (list of str): List of strings containing the arguments to be passed to the Bash script.
  • \n
\n", "signature": "(sh_path: str, args: List[str]):", "funcdef": "def"}, {"fullname": "src.slune.slune.sbatchit", "modulename": "src.slune.slune", "qualname": "sbatchit", "kind": "function", "doc": "

Submits jobs based on arguments given by searcher.

\n\n

For each job runs the script stored at script_path with selected parameter values given by searcher\nand the arguments given by cargs.

\n\n

Uses the sbatch script with path sbatch_path to submit each job to the cluster.

\n\n

If given a Saver object, uses it to check if there are existing runs for each job and skips them,\nbased on the number of runs we would like for each job (which is stored in the saver).

\n\n
Arguments:
\n\n
    \n
  • - script_path (str): Path to the script (of the model) to be run for each job.
  • \n
  • - sbatch_path (str): Path to the sbatch script that will be used to submit each job.\nExamples of sbatch scripts can be found in the templates folder.
  • \n
  • - searcher (Searcher): Searcher object used to retrieve changing arguments for each job.
  • \n
  • - cargs (list, optional): Contains arguments to be passed to the script for every job.
  • \n
  • - saver (Saver, optional): Saver object used if we want to check if there are existing runs so we don't rerun.\nCan simply not give a Saver object if you want to rerun all jobs.
  • \n
\n", "signature": "(\tscript_path: str,\tsbatch_path: str,\tsearcher: slune.base.BaseSearcher,\tcargs: Optional[List] = [],\tsaver: Optional[slune.base.BaseSaver] = None):", "funcdef": "def"}, {"fullname": "src.slune.slune.lsargs", "modulename": "src.slune.slune", "qualname": "lsargs", "kind": "function", "doc": "

Returns the script name and a list of the arguments passed to the script.

\n", "signature": "() -> (<class 'str'>, typing.List[str]):", "funcdef": "def"}, {"fullname": "src.slune.slune.garg", "modulename": "src.slune.slune", "qualname": "garg", "kind": "function", "doc": "

Finds the argument/s with name arg_names in the list of arguments args_ls and returns its value/s.

\n\n
Arguments:
\n\n
    \n
  • - args (list of str): List of strings containing the arguments to be searched.
  • \n
  • - arg_names (str or list of str): String or list of strings containing the names of the arguments to be searched for.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • arg_value (str or list of str): String or list of strings containing the values of the arguments found.
  • \n
\n
\n", "signature": "(\targs: List[str],\targ_names: Union[str, List[str]]) -> Union[str, List[str]]:", "funcdef": "def"}, {"fullname": "src.slune.slune.get_csv_slog", "modulename": "src.slune.slune", "qualname": "get_csv_slog", "kind": "function", "doc": "

Returns a SaverCsv object with the given parameters and root directory.

\n\n
Arguments:
\n\n
    \n
  • - params (dict, optional): Dictionary of parameters to be passed to the SaverCsv object, default is None.
  • \n
  • - root_dir (str, optional): Path to the root directory to be used by the SaverCsv object, default is 'slune_results'.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • SaverCsv (Saver): Saver object with the given parameters and root directory.\n Initialized with a LoggerDefault object as its logger.
  • \n
\n
\n", "signature": "(\tparams: Optional[dict] = None,\troot_dir: Optional[str] = 'slune_results') -> slune.base.BaseSaver:", "funcdef": "def"}, {"fullname": "src.slune.utils", "modulename": "src.slune.utils", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.utils.find_directory_path", "modulename": "src.slune.utils", "qualname": "find_directory_path", "kind": "function", "doc": "

Searches the root directory for a path of directories that matches the strings given in any order.\nIf only a partial match is found, returns the deepest matching path.\nIf no matches are found returns root_directory.\nReturns a stripped matching path of directories, ie. where we convert '--string=value' to '--string='.

\n\n
Arguments:
\n\n
    \n
  • - strings (list of str): List of strings to be matched in any order. Each string in list must be in the form '--string='.
  • \n
  • - root_directory (string, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • max_depth (int): Depth of the deepest matching path.
  • \n
  • max_path (string): Path of the deepest matching path.
  • \n
\n
\n", "signature": "(\tstrings: List[str],\troot_directory: Optional[str] = '.') -> Tuple[int, str]:", "funcdef": "def"}, {"fullname": "src.slune.utils.get_numeric_equiv", "modulename": "src.slune.utils", "qualname": "get_numeric_equiv", "kind": "function", "doc": "

Replaces directories in path with existing directories with the same numerical value.

\n\n
Arguments:
\n\n
    \n
  • - og_path (str): Path we want to check against existing paths, must be a subdirectory of root_directory and each directory must have form '--string=value'.
  • \n
  • - root_directory (str, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • equiv (str): Path with values changed to match existing directories if values are numerically equivalent, with root directory at beginning.
  • \n
\n
\n", "signature": "(og_path: str, root_directory: Optional[str] = '.') -> str:", "funcdef": "def"}, {"fullname": "src.slune.utils.dict_to_strings", "modulename": "src.slune.utils", "qualname": "dict_to_strings", "kind": "function", "doc": "

Converts a dictionary into a list of strings in the form of '--key=value'.

\n\n
Arguments:
\n\n
    \n
  • - d (dict): Dictionary to be converted.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • out (list of str): List of strings in the form of '--key=value'.
  • \n
\n
\n", "signature": "(d: dict) -> List[str]:", "funcdef": "def"}, {"fullname": "src.slune.utils.find_csv_files", "modulename": "src.slune.utils", "qualname": "find_csv_files", "kind": "function", "doc": "

Recursively finds all csv files in all subdirectories of the root directory and returns their paths.

\n\n
Arguments:
\n\n
    \n
  • - root_directory (str, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • csv_files (list of str): List of strings containing the paths to all csv files found.
  • \n
\n
\n", "signature": "(root_directory: Optional[str] = '.') -> List[str]:", "funcdef": "def"}, {"fullname": "src.slune.utils.get_all_paths", "modulename": "src.slune.utils", "qualname": "get_all_paths", "kind": "function", "doc": "

Find all possible paths of csv files that have directory matching one of each of all the parameters given.

\n\n

Finds all paths of csv files in all subdirectories of the root directory that have a directory in their path matching one of each of all the parameters given.

\n\n
Arguments:
\n\n
    \n
  • - dirs (list of str): List of directory names we want returned paths to have in their path.
  • \n
  • - root_directory (str, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • matches (list of str): List of strings containing the paths to all csv files found.
  • \n
\n
\n", "signature": "(dirs: List[str], root_directory: Optional[str] = '.') -> List[str]:", "funcdef": "def"}]; + /** pdoc search index */const docs = [{"fullname": "src", "modulename": "src", "kind": "module", "doc": "

\"PyPI\n\"license\"\n\"badge\"

\n\n

\"badge\"\n\"badge\"\n\"badge\"

\n\n

slune (= slurm + tune!)

\n\n

A super simplistic python package for performing hyperparameter tuning (or more generally launching jobs and saving results) on a cluster using SLURM. Takes advantage of the fact that lots of jobs (including hyperparameter tuning) are embarrassingly parallel! With slune you can divide your compute into lots of separately scheduled jobs meaning that each small job can get running on your cluster more quickly, speeding up your workflow! Often significantly!

\n\n

Slune is super-easy to use! We have helper functions which can execute everything you need done for you. Letting you speed up your work without wasting time.

\n\n

Slune is barebones by design. This means that you can easily write code to integrate with slune if you want to do something a bit different! You can also workout what each function is doing pretty easily.

\n\n

Slune is flexible. In designing this package I've tried to make as few assumptions as possible meaning that it can be used for lots of stuff outside hyperparameter tuning! (or also within!) For example, you can get slune to give you paths for where to save things, submit lots of jobs in parallel for any sort of script and do grid search! and there's more to come!

\n\n

The docs are here.

\n\n

Usage

\n\n

Let's go through a quick example of how we can use slune ... first let's define a model that we want to train:

\n\n
\n
# Simple Regularized Linear Regression without using external libraries\n\n# Function to compute the mean of a list\ndef mean(values):\n    return sum(values) / float(len(values))\n\n# Function to compute the covariance between two lists\ndef covariance(x, mean_x, y, mean_y):\n    covar = 0.0\n    for i in range(len(x)):\n        covar += (x[i] - mean_x) * (y[i] - mean_y)\n    return covar\n\n# Function to compute the variance of a list\ndef variance(values, mean):\n    return sum((x - mean) ** 2 for x in values)\n\n# Function to compute coefficients for a simple regularized linear regression\ndef coefficients_regularized(x, y, alpha):\n    mean_x, mean_y = mean(x), mean(y)\n    var_x = variance(x, mean_x)\n    covar = covariance(x, mean_x, y, mean_y)\n    b1 = (covar + alpha * var_x) / (var_x + alpha)\n    b0 = mean_y - b1 * mean_x\n    return b0, b1\n\n# Function to make predictions with a simple regularized linear regression model\ndef linear_regression_regularized(train_X, train_y, test_X, alpha):\n    b0, b1 = coefficients_regularized(train_X, train_y, alpha)\n    predictions = [b0 + b1 * x for x in test_X]\n    return predictions\n\n# ------------------\n# The above is code for a simple normalized linear regression model that we want to train.\n# Now let's fit the model and use slune to save how well our model performs!\n# ------------------\n\nif __name__ == "__main__":\n    # First let's load in the value for the regularization parameter alpha that has been passed to this script from the command line. We will use the slune helper function lsargs to do this. \n    # lsargs returns a tuple of the python path and a list of arguments passed to the script. We can then use this to get the alpha value.\n    from slune import lsargs\n    python_path, args = lsargs()\n    alpha = float(args[0])\n\n    # Mock training dataset, function is y = 1 + 1 * x\n    X = [1, 2, 3, 4, 5]\n    y = [2, 3, 4, 5, 6]\n\n    # Mock test dataset\n    test_X = [6, 7, 8]\n    test_y = [7, 8, 9]\n    test_predictions = linear_regression_regularized(X, y, test_X, alpha)\n\n    # First let's load in a function that we can use to get a saver object that uses the default method of logging. The saving will be coordinated by a csv saver object which saves and reads results from csv files stored in a hierarchy of directories.\n    from slune import get_csv_saver\n    csv_saver = get_csv_saver(params = args)\n\n    # Let's now calculate the mean squared error of our predictions and log it!\n    mse = mean((test_y[i] - test_predictions[i])**2 for i in range(len(test_y)))\n    csv_saver.log({'mse': mse})\n\n    # Let's now save our logged results!\n    csv_saver.save_collated()\n
\n
\n\n

Now let's write some code that will submit some jobs to train our model using different hyperparameters!!

\n\n
\n
# Let's now load in a function that will coordinate our search! We're going to do a grid search.\n# SearcherGrid is the class we can use to coordinate a grid search. We pass it a dictionary of hyperparameters and the values we want to try for each hyperparameter. We also pass it the number of runs we want to do for each combination of hyperparameters.\nfrom slune.searchers import SearcherGrid\ngrid_searcher = SearcherGrid({'alpha' : [0.25, 0.5, 0.75]}, runs = 1)\n\n# Let's now import a function which will submit a job for our model, the script_path specifies the path to the script that contains the model we want to train. The template_path specifies the path to the template script that we want to specify the job with, cargs is a list of constant arguments we want to pass to the script for each tuning. \n# We set saver to None as we don't want to not run jobs if we have already run them before.\nfrom slune import sbatchit\nscript_path = 'model.py'\ntemplate_path = 'template.sh'\nsbatchit(script_path, template_path, grid_searcher, cargs=[], saver=None)\n
\n
\n\n

Now we've submitted our jobs we will wait for them to finish \ud83d\udd5b\ud83d\udd50\ud83d\udd51\ud83d\udd52\ud83d\udd53\ud83d\udd54\ud83d\udd55\ud83d\udd56\ud83d\udd57\ud83d\udd58\ud83d\udd59\ud83d\udd5a\ud83d\udd5b, now that they are finished we can read the results!

\n\n
\n
from slune import get_csv_saver\ncsv_saver = get_csv_saver(params = None)\nparams, value = csv_saver.read(params = [], metric_name = 'mse', select_by ='min')\nprint(f'Best hyperparameters: {params}')\nprint(f'Their MSE: {value}')\n
\n
\n\n

Amazing! \ud83e\udd73 We have successfully used slune to train our model. I hope this gives you a good idea of how you can use slune and how easy it is to use!

\n\n

Please check out the examples folder for notebooks detailing in more depth some potential ways you can use slune and of course please check out the docs!

\n\n

Roadmap

\n\n

Still in early stages! First thing on the horizon is better integration with SLURM:

\n\n
    \n
  • Set-up notifications for job completion, failure, etc.
  • \n
  • Auto job naming, job output naming and job output location saving.
  • \n
  • Auto save logged results when finishing a job.
  • \n
  • Automatically re-submit failed jobs.
  • \n
  • Tools for monitoring and cancelling jobs. \nThen it will be looking at adding more savers, loggers and searchers! For example integration with tensorboard, saving to one csv file (as opposed to a hierarchy of csv files in different directories) and different search methods like random search and cross validation. It would perhaps also be beneficial to be able to interface with other languages like R and Julia. Finally, more helper functions!
  • \n
\n\n

However, I am trying to keep this package as bloatless as possible to make it easy for you to tweak and configure to your individual needs. It's written in a simple and compartmentalized manner for this reason. You can of course use the helper functions and let slune handle everything under the hood, but, you can also very quickly and easily write your own classes to work with other savers, loggers and searchers to do as you please.

\n\n

Installation

\n\n

To install latest version use:

\n\n
\n
pip install slune-lib\n
\n
\n\n

To install latest dev version use (CURRENTLY RECOMENDED):

\n\n
\n
# With https\npip install "git+https://github.com/h-0-0/slune.git#egg=slune-lib"\n
\n
\n\n

Class Design

\n\n

Here we will outline the different kind of classes that are used in slune and how they interact with each other. There are 3 types:

\n\n
    \n
  • 'Searcher' classes - these are the classes that are used to define and traverse a search space.
  • \n
  • 'Logger' classes - these are the classes that are used to create and read log files.
  • \n
  • 'Saver' classes - these are the classes that are used to save logs to files and read logs from files.
  • \n
\n\n

The base module is where the base classes for each of these types are defined. The base classes are:

\n\n
    \n
  • BaseSearcher
  • \n
  • BaseLogger
  • \n
  • BaseSaver
  • \n
\n\n

To create a new searcher, logger or saver, you must inherit from the appropriate base class and implement the required methods. The required methods will have the '@abc.abstractmethod' decorator above them and will throw errors if they are not implemented. The compulsory methods allow for well-defined interactions between the different classes and should allow for any combination of searcher, logger and saver to be used together.

\n\n

Please read the docs for the base classes to see what methods are required to be implemented and how they should be implemented.

\n\n

Contributing

\n\n

If you would like to contribute to slune please first familiarize yourself with the package by taking a look at the docs. In particular please read about the class design, the base classes and take a look at the code for the helper functions in the slune module.

\n\n

To contribute to the package please either submit a pull request for an open issue or open a new issue. If you are unsure about whether to open a new issue or in general have any problems please open a discussion in the discussions tab.

\n\n

Checklist for contributing:

\n\n
    \n
  • Make sure that your code is well documented and that the documentation is clear and concise, use google style docstrings.
  • \n
  • Make sure that your code is well tested and that the tests are clear and concise, want to keep coverage as high as possible! (minimum 90%) and keep tests as simple as possible!
  • \n
  • Make sure that you only solve the issue that you are attempting to close, if you find other issues please open a new issue for them.
  • \n
\n"}, {"fullname": "src.slune", "modulename": "src.slune", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.base", "modulename": "src.slune.base", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSearcher", "modulename": "src.slune.base", "qualname": "BaseSearcher", "kind": "class", "doc": "

Base class for all Searchers.

\n\n

This must be subclassed to create different Searcher classes.\nPlease name your searcher class Searcher\nOutlines a protocol for creating a search space and creating configurations from it.\nMethods document what they should do once implemented.

\n"}, {"fullname": "src.slune.base.BaseSearcher.__init__", "modulename": "src.slune.base", "qualname": "BaseSearcher.__init__", "kind": "function", "doc": "

Initialises the searcher.

\n", "signature": "(*args, **kwargs)"}, {"fullname": "src.slune.base.BaseSearcher.next_tune", "modulename": "src.slune.base", "qualname": "BaseSearcher.next_tune", "kind": "function", "doc": "

Returns the next configuration to try.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSearcher.check_existing_runs", "modulename": "src.slune.base", "qualname": "BaseSearcher.check_existing_runs", "kind": "function", "doc": "

Used to tell searcher to check if there are existing runs in storage.

\n\n

If there are existing runs, the searcher should skip them \nbased on the number of runs we would like for each job.\nThis may require a 'runs' attribute to be set in the searcher.\nIt will probably also require access to a Saver object,\nso we can use it's saving protocol to check if there are existing runs.\nIn this case is advised that this function takes a Saver object as an argument,\nand that the searcher is initialized with a 'runs' attribute.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseLogger", "modulename": "src.slune.base", "qualname": "BaseLogger", "kind": "class", "doc": "

Base class for all Loggers.

\n\n

This must be subclassed to implement different Logger classes.\nPlease name your logger class Logger.\nOutlines a protocol for logging metrics and reading from the logs.\nMethods document what they should do once implemented.

\n"}, {"fullname": "src.slune.base.BaseLogger.__init__", "modulename": "src.slune.base", "qualname": "BaseLogger.__init__", "kind": "function", "doc": "

Initialises the logger.

\n", "signature": "(*args, **kwargs)"}, {"fullname": "src.slune.base.BaseLogger.log", "modulename": "src.slune.base", "qualname": "BaseLogger.log", "kind": "function", "doc": "

Logs the metric/s for the current hyperparameter configuration.

\n\n

Should store metrics in some way so we can later save it using a Saver.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseLogger.read_log", "modulename": "src.slune.base", "qualname": "BaseLogger.read_log", "kind": "function", "doc": "

Returns value of a metric from the log based on a selection criteria.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSaver", "modulename": "src.slune.base", "qualname": "BaseSaver", "kind": "class", "doc": "

Base class for all savers.

\n\n

This must be subclassed to implement different Saver classes.\nPlease name your saver class Saver.\nOutlines a protocol for saving and reading results to/from storage.\nMethods document what they should do once implemented.

\n"}, {"fullname": "src.slune.base.BaseSaver.__init__", "modulename": "src.slune.base", "qualname": "BaseSaver.__init__", "kind": "function", "doc": "

Initialises the saver.

\n\n

Assigns the logger instance to self.logger and makes its methods accessible through self.log and self.read_log.

\n\n
Arguments:
\n\n
    \n
  • - logger_instance (BaseLogger): Instance of a logger class that inherits from BaseLogger.
  • \n
\n", "signature": "(logger_instance: src.slune.base.BaseLogger, *args, **kwargs)"}, {"fullname": "src.slune.base.BaseSaver.logger", "modulename": "src.slune.base", "qualname": "BaseSaver.logger", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSaver.log", "modulename": "src.slune.base", "qualname": "BaseSaver.log", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSaver.read_log", "modulename": "src.slune.base", "qualname": "BaseSaver.read_log", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.base.BaseSaver.save_collated", "modulename": "src.slune.base", "qualname": "BaseSaver.save_collated", "kind": "function", "doc": "

Saves the current results in logger to storage.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSaver.read", "modulename": "src.slune.base", "qualname": "BaseSaver.read", "kind": "function", "doc": "

Reads results from storage.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.base.BaseSaver.exists", "modulename": "src.slune.base", "qualname": "BaseSaver.exists", "kind": "function", "doc": "

Checks if results already exist in storage.

\n\n

Should return integer indicating the number of runs that exist in storage for the given parameters.

\n", "signature": "(self, *args, **kwargs):", "funcdef": "def"}, {"fullname": "src.slune.loggers", "modulename": "src.slune.loggers", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.loggers.default", "modulename": "src.slune.loggers.default", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.loggers.default.LoggerDefault", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault", "kind": "class", "doc": "

Logs metric/s in a data frame.

\n\n

Stores the metric/s in a data frame that we can later save in storage.\nLogs by creating data frame out of the metrics and then appending it to the current results data frame.

\n\n
Attributes:
\n\n
    \n
  • - results (pd.DataFrame): Data frame containing all the metrics logged so far.\nEach row stores all the metrics that were given in a call to the 'log' method,\neach column title is a metric name.\nThe first column is always the time stamp at which 'log' is called.
  • \n
\n", "bases": "slune.base.BaseLogger"}, {"fullname": "src.slune.loggers.default.LoggerDefault.__init__", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.__init__", "kind": "function", "doc": "

Initialises the logger.

\n", "signature": "(*args, **kwargs)"}, {"fullname": "src.slune.loggers.default.LoggerDefault.results", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.results", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.loggers.default.LoggerDefault.log", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.log", "kind": "function", "doc": "

Logs the metric/s given.

\n\n

Stores them in a data frame that we can later save in storage.\nAll metrics provided will be saved as a row in the results data frame,\nthe first column is always the time stamp at which log is called.

\n\n
Arguments:
\n\n
    \n
  • - metrics (dict): Metrics to be logged, keys are metric names and values are metric values.\nEach metric should only have one value! So please log as soon as you get a metric.
  • \n
\n", "signature": "(self, metrics: dict):", "funcdef": "def"}, {"fullname": "src.slune.loggers.default.LoggerDefault.read_log", "modulename": "src.slune.loggers.default", "qualname": "LoggerDefault.read_log", "kind": "function", "doc": "

Reads log and returns value according to select_by.

\n\n

Reads the values for given metric for given log and chooses metric value to return based on select_by.

\n\n
Arguments:
\n\n
    \n
  • - data_frame (pd.DataFrame): Data frame containing the metric to be read.
  • \n
  • - metric_name (str): Name of the metric to be read.
  • \n
  • - select_by (str, optional): How to select the 'best' metric, currently can select by 'min' or 'max'.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • value (float): Minimum or maximum value of the metric.
  • \n
\n
\n\n

TODO: \n - Add more options for select_by.\n - Should be able to return other types than float?

\n", "signature": "(\tself,\tdata_frame: pandas.core.frame.DataFrame,\tmetric_name: str,\tselect_by: str = 'max') -> float:", "funcdef": "def"}, {"fullname": "src.slune.savers", "modulename": "src.slune.savers", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.savers.csv", "modulename": "src.slune.savers.csv", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.savers.csv.SaverCsv", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv", "kind": "class", "doc": "

Saves the results of each run in a CSV file in hierarchy of directories.

\n\n

Each directory is named after a parameter - value pair in the form \"--parameter_name=value\".\nThe paths to csv files then define the configuration under which the results were obtained,\nfor example if we only have one parameter \"learning_rate\" with value 0.01 used to obtain the results,\nto save those results we would create a directory named \"--learning_rate=0.01\" and save the results in a csv file in that directory.

\n\n

If we have multiple parameters, for example \"learning_rate\" with value 0.01 and \"batch_size\" with value 32,\nwe would create a directory named \"--learning_rate=0.01\" with a subdirectory named \"--batch_size=32\",\nand save the results in a csv file in that subdirectory.

\n\n

We use this structure to then read the results from the csv files by searching for the directory that matches the parameters we want,\nand then reading the csv file in that directory.

\n\n

The order in which we create the directories is determined by the order in which the parameters are given,\nso if we are given [\"--learning_rate=0.01\", \"--batch_size=32\"] we would create the directories in the following order:\n\"--learning_rate=0.01/--batch_size=32\".

\n\n

The directory structure generated will also depend on existing directories in the root directory,\nif there are existing directories in the root directory that match some subset of the parameters given,\nwe will create the directory tree from the deepest matching directory.

\n\n

For example if we only have the following path in the root directory:\n\"--learning_rate=0.01/--batch_size=32\"\nand we are given the parameters [\"--learning_rate=0.01\", \"--batch_size=32\", \"--num_epochs=10\"],\nwe will create the path:\n\"--learning_rate=0.01/--batch_size=32/--num_epochs=10\".\non the other hand if we are given the parameters [\"--learning_rate=0.02\", \"--num_epochs=10\", \"--batch_size=32\"],\nwe will create the path:\n\"--learning_rate=0.02/--batch_size=32/--num_epochs=10\".

\n\n

Handles parallel runs trying to create the same directories by waiting a random time (under 1 second) before creating the directory.\nShould work pretty well in practice, however, may occasionally fail depending on the number of jobs launched at the same time.

\n\n
Attributes:
\n\n
    \n
  • - root_dir (str): Path to the root directory where we will store the csv files.
  • \n
  • - current_path (str): Path to the csv file where we will store the results for the current run.
  • \n
\n", "bases": "slune.base.BaseSaver"}, {"fullname": "src.slune.savers.csv.SaverCsv.__init__", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.__init__", "kind": "function", "doc": "

Initialises the csv saver.

\n\n
Arguments:
\n\n
    \n
  • - logger_instance (BaseLogger): Instance of a logger class that inherits from BaseLogger.
  • \n
  • - params (list, optional): List of strings containing the parameters used, in form [\"--parameter_name=parameter_value\", ...], default is None.\nIf None, we will create a path using the parameters given in the log.
  • \n
  • - root_dir (str, optional): Path to the root directory where we will store the csv files, default is './tuning_results'.
  • \n
\n", "signature": "(\tlogger_instance: slune.base.BaseLogger,\tparams: List[str] = None,\troot_dir: Optional[str] = './tuning_results')"}, {"fullname": "src.slune.savers.csv.SaverCsv.root_dir", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.root_dir", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.savers.csv.SaverCsv.strip_params", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.strip_params", "kind": "function", "doc": "

Strips the parameter values.

\n\n

Strips the parameter values from the list of parameters given,\nie. [\"--parameter_name=parameter_value\", ...] -> [\"--parameter_name=\", ...]

\n\n

Also gets rid of blank spaces.

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): List of strings containing the parameters used, in form [\"--parameter_name=parameter_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • stripped_params (list of str): List of strings containing the parameters used, in form [\"--parameter_name=\", ...].
  • \n
\n
\n", "signature": "(self, params: List[str]) -> List[str]:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.get_match", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.get_match", "kind": "function", "doc": "

Searches the root directory for a path that matches the parameters given.

\n\n

If only partial matches are found, returns the deepest matching directory with the missing parameters appended.\nBy deepest we mean the directory with the most parameters matching.\nIf no matches are found creates a path using the parameters.\nCreates path using parameters in the order they are given, \nie. [\"--learning_rate=0.01\", \"--batch_size=32\"] -> \"--learning_rate=0.01/--batch_size=32\".

\n\n

If we find a partial match, we add the missing parameters to the end of the path,\nie. if we have the path \"--learning_rate=0.01\" in the root \nand are given the parameters [\"--learning_rate=0.01\", \"--batch_size=32\"],\nwe will create the path \"--learning_rate=0.01/--batch_size=32\".

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): List of strings containing the arguments used, in form [\"--argument_name=argument_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • match (str): Path to the directory that matches the parameters given.
  • \n
\n
\n", "signature": "(self, params: List[str]) -> str:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.get_path", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.get_path", "kind": "function", "doc": "

Creates a path using the parameters.

\n\n

Does this by first checking for existing paths in the root directory that match the parameters given.

\n\n

Check get_match for how we create the path, \nonce we have the path we check if there is already a csv file with results in that path,\nif there is we increment the number of the results file name that we will use.

\n\n

For example if we get back the path \"--learning_rate=0.01/--batch_size=32\",\nand there exists a csv file named \"results_0.csv\" in the final directory,\nwe will name our csv file \"results_1.csv\".

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): List of strings containing the arguments used, in form [\"--argument_name=argument_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • csv_file_path (str): Path to the csv file where we will store the results for the current run.
  • \n
\n
\n", "signature": "(self, params: List[str]) -> str:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.save_collated_from_results", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.save_collated_from_results", "kind": "function", "doc": "

Saves results to csv file.

\n\n

If the csv file already exists, \nwe append the collated results from the logger to the end of the csv file.\nIf the csv file does not exist,\nwe create it and save the results to it.

\n\n
Arguments:
\n\n
    \n
  • - results (pd.DataFrame): Data frame containing the results to be saved.
  • \n
\n\n

TODO: \n - Could be making to many assumptions about the format in which we get the results from the logger,\n should be able to work with any logger.\n We should only be assuming that we are saving results to a csv file.

\n", "signature": "(self, results: pandas.core.frame.DataFrame):", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.save_collated", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.save_collated", "kind": "function", "doc": "

Saves results to csv file.

\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.read", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.read", "kind": "function", "doc": "

Finds the min/max value of a metric from all csv files in the root directory that match the parameters given.

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): Contains the parameters used, in form [\"--parameter_name=parameter_value\", ...].
  • \n
  • - metric_name (string): Name of the metric to be read.
  • \n
  • - select_by (string, optional): How to select the 'best' value for the metric from a log file, currently can select by 'min' or 'max'.
  • \n
  • - avg (bool, optional): Whether to average the metric over all runs, default is True.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • best_params (list of str): Contains the arguments used to get the 'best' value of the metric (determined by select_by).
  • \n
  • best_value (float): Best value of the metric (determined by select_by).
  • \n
\n
\n", "signature": "(\tself,\tparams: List[str],\tmetric_name: str,\tselect_by: str = 'max',\tavg: bool = True) -> (typing.List[str], <class 'float'>):", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.exists", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.exists", "kind": "function", "doc": "

Checks if results already exist in storage.

\n\n
Arguments:
\n\n
    \n
  • - params (list of str): Contains the parameters used, in form [\"--parameter_name=parameter_value\", ...].
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • num_runs (int): Number of runs that exist in storage for the given parameters.
  • \n
\n
\n", "signature": "(self, params: List[str]) -> int:", "funcdef": "def"}, {"fullname": "src.slune.savers.csv.SaverCsv.get_current_path", "modulename": "src.slune.savers.csv", "qualname": "SaverCsv.get_current_path", "kind": "function", "doc": "

Getter function for the current_path attribute.

\n\n
Returns:
\n\n
\n
    \n
  • current_path (str): Path to the csv file where we will store the results for the current run.
  • \n
\n
\n", "signature": "(self) -> str:", "funcdef": "def"}, {"fullname": "src.slune.searchers", "modulename": "src.slune.searchers", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid", "modulename": "src.slune.searchers.grid", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid", "kind": "class", "doc": "

Searcher for grid search.

\n\n

Given dictionary of parameters and values to try, creates grid of all possible configurations,\nand returns them one by one for each call to next_tune.

\n\n
Attributes:
\n\n
    \n
  • - configs (dict): Parameters and values to create grid from.\nStructure of dictionary should be: { \"--parameter_name\" : [Value_1, Value_2, ...], ... }
  • \n
  • - runs (int): Controls search based on number of runs we want for each config.\nif runs > 0 -> run each config 'runs' times.\nif runs = 0 -> run each config once even if it already exists.\nThis behavior is modified if we want to (use) check_existing_runs, see methods description.
  • \n
  • - grid (list of dict): List of dictionaries, each containing one combination of argument values.
  • \n
  • - grid_index (int): Index of the current configuration in the grid.
  • \n
  • - saver_exists (function): Pointer to the savers exists method, used to check if there are existing runs.
  • \n
\n", "bases": "slune.base.BaseSearcher"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.__init__", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.__init__", "kind": "function", "doc": "

Initialises the searcher.

\n\n
Arguments:
\n\n
    \n
  • - configs (dict): Dictionary of parameters and values to try.\nStructure of dictionary should be: { \"--parameter_name\" : [Value_1, Value_2, ...], ... }
  • \n
  • - runs (int, optional): Controls search based on number of runs we want for each config.\nif runs > 0 -> run each config 'runs' times.\nif runs = 0 -> run each config once even if it already exists.\nThis behavior is modified if we want to (use) check_existing_runs, see methods description.
  • \n
\n", "signature": "(configs: dict, runs: int = 0)"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.runs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.runs", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.configs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.configs", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.grid", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.grid", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.grid_index", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.grid_index", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.saver_exists", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.saver_exists", "kind": "variable", "doc": "

\n"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.get_grid", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.get_grid", "kind": "function", "doc": "

Creates search grid.

\n\n

Generates all possible combinations of values for each argument in the given dictionary using recursion.

\n\n
Arguments:
\n\n
    \n
  • - param_dict (dict): A dictionary where keys are argument names and values are lists of values.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • all_combinations (list): A list of dictionaries, each containing one combination of argument values.
  • \n
\n
\n", "signature": "(self, param_dict: dict) -> List:", "funcdef": "def"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.check_existing_runs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.check_existing_runs", "kind": "function", "doc": "

We save a pointer to the savers exists method to check if there are existing runs.

\n\n
If there are n existing runs:
\n\n
\n

n < runs -> run the remaining runs\n n >= runs -> skip all runs

\n
\n\n
Arguments:
\n\n
    \n
  • - saver (BaseSaver): Pointer to the savers exists method, used to check if there are existing runs.
  • \n
\n", "signature": "(self, saver: slune.base.BaseSaver):", "funcdef": "def"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.skip_existing_runs", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.skip_existing_runs", "kind": "function", "doc": "

Skips runs if they are in storage already.

\n\n

Will check if there are existing runs for the current configuration,\nif there are existing runs we tally them up \nand skip configs or runs of a config based on the number of runs we want for each config.

\n\n
Arguments:
\n\n
    \n
  • - grid_index (int): Index of the current configuration in the grid.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • grid_index (int): Index of the next configuration in the grid.
  • \n
  • run_index (int): Index of the next run for the current configuration.
  • \n
\n
\n", "signature": "(self, grid_index: int) -> Tuple[int, int]:", "funcdef": "def"}, {"fullname": "src.slune.searchers.grid.SearcherGrid.next_tune", "modulename": "src.slune.searchers.grid", "qualname": "SearcherGrid.next_tune", "kind": "function", "doc": "

Returns the next configuration to try.

\n\n

Will skip existing runs if check_existing_runs has been called.\nFor more information on how this works check the methods descriptions for check_existing_runs and skip_existing_runs.\nWill raise an error if we have reached the end of the grid.\nTo iterate through all configurations, use a for loop like so: \n for config in searcher: ...

\n\n
Returns:
\n\n
\n
    \n
  • next_config (dict): The next configuration to try.
  • \n
\n
\n", "signature": "(self) -> dict:", "funcdef": "def"}, {"fullname": "src.slune.slune", "modulename": "src.slune.slune", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.slune.submit_job", "modulename": "src.slune.slune", "qualname": "submit_job", "kind": "function", "doc": "

Submits a job using specified Bash script

\n\n
Arguments:
\n\n
    \n
  • - sh_path (string): Path to the Bash script to be run.
  • \n
  • - args (list of str): List of strings containing the arguments to be passed to the Bash script.
  • \n
\n", "signature": "(sh_path: str, args: List[str]):", "funcdef": "def"}, {"fullname": "src.slune.slune.sbatchit", "modulename": "src.slune.slune", "qualname": "sbatchit", "kind": "function", "doc": "

Submits jobs based on arguments given by searcher.

\n\n

For each job runs the script stored at script_path with selected parameter values given by searcher\nand the arguments given by cargs.

\n\n

Uses the sbatch script with path sbatch_path to submit each job to the cluster.

\n\n

If given a Saver object, uses it to check if there are existing runs for each job and skips them,\nbased on the number of runs we would like for each job (which is stored in the saver).

\n\n
Arguments:
\n\n
    \n
  • - script_path (str): Path to the script (of the model) to be run for each job.
  • \n
  • - sbatch_path (str): Path to the sbatch script that will be used to submit each job.\nExamples of sbatch scripts can be found in the templates folder.
  • \n
  • - searcher (Searcher): Searcher object used to retrieve changing arguments for each job.
  • \n
  • - cargs (list, optional): Contains arguments to be passed to the script for every job.
  • \n
  • - saver (Saver, optional): Saver object used if we want to check if there are existing runs so we don't rerun.\nCan simply not give a Saver object if you want to rerun all jobs.
  • \n
\n", "signature": "(\tscript_path: str,\tsbatch_path: str,\tsearcher: slune.base.BaseSearcher,\tcargs: Optional[List] = [],\tsaver: Optional[slune.base.BaseSaver] = None):", "funcdef": "def"}, {"fullname": "src.slune.slune.lsargs", "modulename": "src.slune.slune", "qualname": "lsargs", "kind": "function", "doc": "

Returns the script name and a list of the arguments passed to the script.

\n", "signature": "() -> (<class 'str'>, typing.List[str]):", "funcdef": "def"}, {"fullname": "src.slune.slune.garg", "modulename": "src.slune.slune", "qualname": "garg", "kind": "function", "doc": "

Finds the argument/s with name arg_names in the list of arguments args_ls and returns its value/s.

\n\n
Arguments:
\n\n
    \n
  • - args (list of str): List of strings containing the arguments to be searched.
  • \n
  • - arg_names (str or list of str): String or list of strings containing the names of the arguments to be searched for.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • arg_value (str or list of str): String or list of strings containing the values of the arguments found.
  • \n
\n
\n", "signature": "(\targs: List[str],\targ_names: Union[str, List[str]]) -> Union[str, List[str]]:", "funcdef": "def"}, {"fullname": "src.slune.slune.get_csv_saver", "modulename": "src.slune.slune", "qualname": "get_csv_saver", "kind": "function", "doc": "

Returns a SaverCsv object with the given parameters and root directory.

\n\n
Arguments:
\n\n
    \n
  • - params (dict, optional): Dictionary of parameters to be passed to the SaverCsv object, default is None.
  • \n
  • - root_dir (str, optional): Path to the root directory to be used by the SaverCsv object, default is 'slune_results'.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • SaverCsv (Saver): Saver object with the given parameters and root directory.\n Initialized with a LoggerDefault object as its logger.
  • \n
\n
\n", "signature": "(\tparams: Optional[dict] = None,\troot_dir: Optional[str] = 'slune_results') -> slune.base.BaseSaver:", "funcdef": "def"}, {"fullname": "src.slune.utils", "modulename": "src.slune.utils", "kind": "module", "doc": "

\n"}, {"fullname": "src.slune.utils.find_directory_path", "modulename": "src.slune.utils", "qualname": "find_directory_path", "kind": "function", "doc": "

Searches the root directory for a path of directories that matches the strings given in any order.\nIf only a partial match is found, returns the deepest matching path.\nIf no matches are found returns root_directory.\nReturns a stripped matching path of directories, ie. where we convert '--string=value' to '--string='.

\n\n
Arguments:
\n\n
    \n
  • - strings (list of str): List of strings to be matched in any order. Each string in list must be in the form '--string='.
  • \n
  • - root_directory (string, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • max_depth (int): Depth of the deepest matching path.
  • \n
  • max_path (string): Path of the deepest matching path.
  • \n
\n
\n", "signature": "(\tstrings: List[str],\troot_directory: Optional[str] = '.') -> Tuple[int, str]:", "funcdef": "def"}, {"fullname": "src.slune.utils.get_numeric_equiv", "modulename": "src.slune.utils", "qualname": "get_numeric_equiv", "kind": "function", "doc": "

Replaces directories in path with existing directories with the same numerical value.

\n\n
Arguments:
\n\n
    \n
  • - og_path (str): Path we want to check against existing paths, must be a subdirectory of root_directory and each directory must have form '--string=value'.
  • \n
  • - root_directory (str, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • equiv (str): Path with values changed to match existing directories if values are numerically equivalent, with root directory at beginning.
  • \n
\n
\n", "signature": "(og_path: str, root_directory: Optional[str] = '.') -> str:", "funcdef": "def"}, {"fullname": "src.slune.utils.dict_to_strings", "modulename": "src.slune.utils", "qualname": "dict_to_strings", "kind": "function", "doc": "

Converts a dictionary into a list of strings in the form of '--key=value'.

\n\n
Arguments:
\n\n
    \n
  • - d (dict): Dictionary to be converted.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • out (list of str): List of strings in the form of '--key=value'.
  • \n
\n
\n", "signature": "(d: dict) -> List[str]:", "funcdef": "def"}, {"fullname": "src.slune.utils.find_csv_files", "modulename": "src.slune.utils", "qualname": "find_csv_files", "kind": "function", "doc": "

Recursively finds all csv files in all subdirectories of the root directory and returns their paths.

\n\n
Arguments:
\n\n
    \n
  • - root_directory (str, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • csv_files (list of str): List of strings containing the paths to all csv files found.
  • \n
\n
\n", "signature": "(root_directory: Optional[str] = '.') -> List[str]:", "funcdef": "def"}, {"fullname": "src.slune.utils.get_all_paths", "modulename": "src.slune.utils", "qualname": "get_all_paths", "kind": "function", "doc": "

Find all possible paths of csv files that have directory matching one of each of all the parameters given.

\n\n

Finds all paths of csv files in all subdirectories of the root directory that have a directory in their path matching one of each of all the parameters given.

\n\n
Arguments:
\n\n
    \n
  • - dirs (list of str): List of directory names we want returned paths to have in their path.
  • \n
  • - root_directory (str, optional): Path to the root directory to be searched, default is current working directory.
  • \n
\n\n
Returns:
\n\n
\n
    \n
  • matches (list of str): List of strings containing the paths to all csv files found.
  • \n
\n
\n", "signature": "(dirs: List[str], root_directory: Optional[str] = '.') -> List[str]:", "funcdef": "def"}]; // mirrored in build-search-index.js (part 1) // Also split on html tags. this is a cheap heuristic, but good enough. diff --git a/docs/.html/src.html b/docs/.html/src.html index 81d7a74..9fd9666 100644 --- a/docs/.html/src.html +++ b/docs/.html/src.html @@ -17,6 +17,7 @@
+ @@ -30,6 +31,7 @@

Contents

  • Installation
  • Class Design
  • +
  • Contributing
  • @@ -70,6 +72,8 @@

    slune (= slurm + tune!)

    Slune is flexible. In designing this package I've tried to make as few assumptions as possible meaning that it can be used for lots of stuff outside hyperparameter tuning! (or also within!) For example, you can get slune to give you paths for where to save things, submit lots of jobs in parallel for any sort of script and do grid search! and there's more to come!

    +

    The docs are here.

    +

    Usage

    Let's go through a quick example of how we can use slune ... first let's define a model that we want to train:

    @@ -128,16 +132,16 @@

    Usage

    test_y = [7, 8, 9] test_predictions = linear_regression_regularized(X, y, test_X, alpha) - # First let's load in a function that we can use to get a saver object that uses the default method of logging (we call this object a slog = saver + logger). The saving will be coordinated by a csv saver object which saves and reads results from csv files stored in a hierarchy of directories. - from slune import get_csv_slog - csv_slog = get_csv_slog(params = args) + # First let's load in a function that we can use to get a saver object that uses the default method of logging. The saving will be coordinated by a csv saver object which saves and reads results from csv files stored in a hierarchy of directories. + from slune import get_csv_saver + csv_saver = get_csv_saver(params = args) # Let's now calculate the mean squared error of our predictions and log it! mse = mean((test_y[i] - test_predictions[i])**2 for i in range(len(test_y))) - csv_slog.log({'mse': mse}) + csv_saver.log({'mse': mse}) # Let's now save our logged results! - slog.save_collated() + csv_saver.save_collated()
    @@ -150,40 +154,34 @@

    Usage

    grid_searcher = SearcherGrid({'alpha' : [0.25, 0.5, 0.75]}, runs = 1) # Let's now import a function which will submit a job for our model, the script_path specifies the path to the script that contains the model we want to train. The template_path specifies the path to the template script that we want to specify the job with, cargs is a list of constant arguments we want to pass to the script for each tuning. -# We set slog to None as we don't want to not run jobs if we have already run them before. +# We set saver to None as we don't want to not run jobs if we have already run them before. from slune import sbatchit script_path = 'model.py' template_path = 'template.sh' -sbatchit(script_path, template_path, grid_searcher, cargs=[], slog=None) +sbatchit(script_path, template_path, grid_searcher, cargs=[], saver=None)

    Now we've submitted our jobs we will wait for them to finish 🕛🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛, now that they are finished we can read the results!

    -
    from slune import get_csv_slog
    -csv_slog = get_csv_slog(params = None)
    -params, value = csv_slog.read(params = [], metric_name = 'mse', select_by ='min')
    +
    from slune import get_csv_saver
    +csv_saver = get_csv_saver(params = None)
    +params, value = csv_saver.read(params = [], metric_name = 'mse', select_by ='min')
     print(f'Best hyperparameters: {params}')
     print(f'Their MSE: {value}')
     
    -

    Amazing! 🥳 We have successfully used slune to train our model. I hope this gives you a good flavour of how you can use slune and how easy it is to use!

    +

    Amazing! 🥳 We have successfully used slune to train our model. I hope this gives you a good idea of how you can use slune and how easy it is to use!

    -

    Please check out the examples folder for notebooks detailing in more depth some potential ways you can use slune. The docs are not yet up and running 😢 but they are coming soon!

    +

    Please check out the examples folder for notebooks detailing in more depth some potential ways you can use slune and of course please check out the docs!

    Roadmap

    +

    Still in early stages! First thing on the horizon is better integration with SLURM:

    +
      -
    • Make package user friendly: -
        -
      • Go through automation settings.
      • -
      • Code of conduct.
      • -
      • Contributing guidelines.
      • -
      • Add to pypi. -Still in early stages! First thing on the horizon is better integration with SLURM:
      • -
    • Set-up notifications for job completion, failure, etc.
    • Auto job naming, job output naming and job output location saving.
    • Auto save logged results when finishing a job.
    • @@ -207,7 +205,7 @@

      Installation

      # With https
      -pip install "git+https://github.com/h-aze/slune.git#egg=slune-lib"
      +pip install "git+https://github.com/h-0-0/slune.git#egg=slune-lib"
       
      @@ -232,6 +230,20 @@

      Class Design

      To create a new searcher, logger or saver, you must inherit from the appropriate base class and implement the required methods. The required methods will have the '@abc.abstractmethod' decorator above them and will throw errors if they are not implemented. The compulsory methods allow for well-defined interactions between the different classes and should allow for any combination of searcher, logger and saver to be used together.

      Please read the docs for the base classes to see what methods are required to be implemented and how they should be implemented.

      + +

      Contributing

      + +

      If you would like to contribute to slune please first familiarize yourself with the package by taking a look at the docs. In particular please read about the class design, the base classes and take a look at the code for the helper functions in the slune module.

      + +

      To contribute to the package please either submit a pull request for an open issue or open a new issue. If you are unsure about whether to open a new issue or in general have any problems please open a discussion in the discussions tab.

      + +

      Checklist for contributing:

      + +
        +
      • Make sure that your code is well documented and that the documentation is clear and concise, use google style docstrings.
      • +
      • Make sure that your code is well tested and that the tests are clear and concise, want to keep coverage as high as possible! (minimum 90%) and keep tests as simple as possible!
      • +
      • Make sure that you only solve the issue that you are attempting to close, if you find other issues please open a new issue for them.
      • +
      @@ -241,7 +253,8 @@

      Class Design

      1"""
       2.. include:: ../README.md
       3.. include:: ../CLASSDESIGN.md
      -4"""
      +4.. include:: ../CONTRIBUTING.md
      +5"""
       
      diff --git a/docs/.html/src/slune.html b/docs/.html/src/slune.html index 43ca94f..071d226 100644 --- a/docs/.html/src/slune.html +++ b/docs/.html/src/slune.html @@ -22,6 +22,7 @@  src + @@ -66,10 +67,10 @@

      4from .searchers import * 5from .savers import * 6from .loggers import * - 7from .slune import submit_job, sbatchit, lsargs, garg, get_csv_slog + 7from .slune import submit_job, sbatchit, lsargs, garg, get_csv_saver 8from . import base, utils 9 -10# __all__ = ['submit_job', 'sbatchit', 'lsargs', 'garg', 'get_csv_slog', +10# __all__ = ['submit_job', 'sbatchit', 'lsargs', 'garg', 'get_csv_saver', 11 # 'base', 'utils', 'default', 'grid', 'csv'] 12 13import importlib.metadata diff --git a/docs/.html/src/slune/base.html b/docs/.html/src/slune/base.html index 43a847e..ad447eb 100644 --- a/docs/.html/src/slune/base.html +++ b/docs/.html/src/slune/base.html @@ -22,6 +22,7 @@  src.slune + diff --git a/docs/.html/src/slune/loggers.html b/docs/.html/src/slune/loggers.html index 455b6c7..8a4f5a2 100644 --- a/docs/.html/src/slune/loggers.html +++ b/docs/.html/src/slune/loggers.html @@ -22,6 +22,7 @@  src.slune + diff --git a/docs/.html/src/slune/loggers/default.html b/docs/.html/src/slune/loggers/default.html index 30be80e..5704745 100644 --- a/docs/.html/src/slune/loggers/default.html +++ b/docs/.html/src/slune/loggers/default.html @@ -22,6 +22,7 @@  src.slune.loggers + diff --git a/docs/.html/src/slune/savers.html b/docs/.html/src/slune/savers.html index 6f8b8fc..b70c9b0 100644 --- a/docs/.html/src/slune/savers.html +++ b/docs/.html/src/slune/savers.html @@ -22,6 +22,7 @@  src.slune + diff --git a/docs/.html/src/slune/savers/csv.html b/docs/.html/src/slune/savers/csv.html index 4393de5..b540608 100644 --- a/docs/.html/src/slune/savers/csv.html +++ b/docs/.html/src/slune/savers/csv.html @@ -22,6 +22,7 @@  src.slune.savers + diff --git a/docs/.html/src/slune/searchers.html b/docs/.html/src/slune/searchers.html index 95b7faf..c7f59da 100644 --- a/docs/.html/src/slune/searchers.html +++ b/docs/.html/src/slune/searchers.html @@ -22,6 +22,7 @@  src.slune + diff --git a/docs/.html/src/slune/searchers/grid.html b/docs/.html/src/slune/searchers/grid.html index f7b4d7d..e8eb90c 100644 --- a/docs/.html/src/slune/searchers/grid.html +++ b/docs/.html/src/slune/searchers/grid.html @@ -22,6 +22,7 @@  src.slune.searchers + diff --git a/docs/.html/src/slune/slune.html b/docs/.html/src/slune/slune.html index 668107c..bf2339b 100644 --- a/docs/.html/src/slune/slune.html +++ b/docs/.html/src/slune/slune.html @@ -22,6 +22,7 @@  src.slune + @@ -43,7 +44,7 @@

      API Documentation

      garg
    • - get_csv_slog + get_csv_saver
    @@ -159,7 +160,7 @@

    91 else: 92 return single_garg(arg_names) 93 - 94def get_csv_slog(params: Optional[dict]= None, root_dir: Optional[str]='slune_results') -> BaseSaver: + 94def get_csv_saver(params: Optional[dict]= None, root_dir: Optional[str]='slune_results') -> BaseSaver: 95 """ Returns a SaverCsv object with the given parameters and root directory. 96 97 Args: @@ -378,32 +379,32 @@
    Returns:
    -
    - +
    +
    def - get_csv_slog( params: Optional[dict] = None, root_dir: Optional[str] = 'slune_results') -> slune.base.BaseSaver: + get_csv_saver( params: Optional[dict] = None, root_dir: Optional[str] = 'slune_results') -> slune.base.BaseSaver: - +
    - -
     95def get_csv_slog(params: Optional[dict]= None, root_dir: Optional[str]='slune_results') -> BaseSaver:
    - 96    """ Returns a SaverCsv object with the given parameters and root directory.
    - 97
    - 98    Args:
    - 99        - params (dict, optional): Dictionary of parameters to be passed to the SaverCsv object, default is None.
    -100
    -101        - root_dir (str, optional): Path to the root directory to be used by the SaverCsv object, default is 'slune_results'.
    -102
    -103    Returns:
    -104        - SaverCsv (Saver): Saver object with the given parameters and root directory.
    -105            Initialized with a LoggerDefault object as its logger.
    -106    
    -107    """
    -108
    -109    return SaverCsv(LoggerDefault(), params = params, root_dir=root_dir)
    +    
    +            
     95def get_csv_saver(params: Optional[dict]= None, root_dir: Optional[str]='slune_results') -> BaseSaver:
    + 96    """ Returns a SaverCsv object with the given parameters and root directory.
    + 97
    + 98    Args:
    + 99        - params (dict, optional): Dictionary of parameters to be passed to the SaverCsv object, default is None.
    +100
    +101        - root_dir (str, optional): Path to the root directory to be used by the SaverCsv object, default is 'slune_results'.
    +102
    +103    Returns:
    +104        - SaverCsv (Saver): Saver object with the given parameters and root directory.
    +105            Initialized with a LoggerDefault object as its logger.
    +106    
    +107    """
    +108
    +109    return SaverCsv(LoggerDefault(), params = params, root_dir=root_dir)
     
    diff --git a/docs/.html/src/slune/utils.html b/docs/.html/src/slune/utils.html index 5a28ba6..ab3cb90 100644 --- a/docs/.html/src/slune/utils.html +++ b/docs/.html/src/slune/utils.html @@ -22,6 +22,7 @@  src.slune +