Commit b7bb3c2a authored by David Trudgian's avatar David Trudgian
Browse files

Packaging

parent 1ef11e50
......@@ -26,9 +26,9 @@ import subprocess
import colorlog
from docopt import docopt
from runner import __version__
from runner import executors
from runner import param
from param_runner import __version__
from param_runner import executors
from param_runner import param
def main():
......
import os
from setuptools import setup
# Utility function to read the README file.
# Used for the long_description. It's nice, because now 1) we have a top level
# README file and 2) it's easier to type in the README file than to put a raw
# string in below ...
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
setup(
name = "param_runner",
version = "1.0.0a0",
author = "David Trudgian",
author_email = "david.trudgian@utsouthwestern.edu",
description = ("Parameter exploration on SLURM clusters."),
license = "",
keywords = "hpc computing",
url = "https://git.biohpc.swmed.edu/biohpc/param_runner",
packages=['param_runner'],
package_data={ 'param_runner': ['schema/*', 'test/*']},
long_description=read('README.md'),
classifiers=[
"Development Status :: 3 - Alpha",
"Topic :: Utilities",
],
install_requires=[
'anyconfig',
'jsonschema',
'docopt',
'colorlog',
'pyyaml',
'yamllint',
'pathos'
],
scripts=['bin/param_runner'],
setup_requires=['pytest-runner'],
tests_require=['pytest', 'pytest-cov'],
zip_safe=False,
)
# The command to run, including any arguments that will not be explored by
# the runner.
command: echo train_ann --input train.set --crossk 10 TPF=0.01 FPF=0.13
# The standard output from a command will be collected into a file named:
# out_<param1 val>_<param2 val>_<param3_val>.....out
# The standard error from a command will be collected into a file named:
# out_<param1 val>_<param2 val>_<param3_val>.....err
summary:
- id: True_Pos_Fraction
regex: 'TPF=([-+]?[0-9]*\.?[0-9]*)'
- id: False_pos_Fraction
regex: 'FPF=([-+]?[0-9]*\.?[0-9]*)'
# Cluster partition to use
partition: 256GB
# Total number of nodes to use
nodes: 4
# Number of CPUs required by each task
cpus_per_task: 4
# Time limit
time_limit: 3-00:00:00
# The list of parameters to explore
#
# For each parameter the following properties are required:
#
# type: 'int_range' A range of integers -or-
# 'real_range' A range of real numbers -or-
# 'choice' A list of string options
#
#
# The following properties are optional:
#
# flag: '--example' A flag which should proceed the value of the paremeter
# optional: true If true, we consider combinations excluding the parameter
#
# int_range and real_range types take paremeters:
#
# min: 10 Minimum value for the parameter
# max: 1e4 Maximum value for the parameter
# step: 20 Amount to add at each step through the range
# multiply: Amount to multiply value at each step through the range
#
# e.g. for an arithmetic progression of 10 - 100 in steps of 5:
# min: 10
# max: 100
# step: 5
#
# e.g. for a geometric progression of 1, 10, 100, 1,000, 10,000 (scale factor 10)
# min: 1
# max: 10000
# scale: 10
parameters:
- id: 'hidden'
type: "int_range"
flag: '--hidden'
min: 0
max: 32
step: 2
description: "Number of hidden nodes"
- id: 'beta'
type: real_range
flag: '-b'
optional: true
min: 0.1
max: 100
scale: 10
description: Regularization beta parameter
- id: 'activation'
type: choice
flag: '--activation'
values:
- step
- sigmoid
description: Activation function
# The command to run, including any arguments that will not be explored by
# the runner.
command: train_ann --input train.set --crossk 10
# The standard output from a command will be collected into a file named:
# out_<param1 val>_<param2 val>_<param3_val>.....out
# The standard error from a command will be collected into a file named:
# out_<param1 val>_<param2 val>_<param3_val>.....err
# If summary is specified, we will create a summary.txt file listing in tabular
# format, the value of each parameter, the standard output of the task.
# To extract only part of the standard output specify a regular expression here.
# Any capture groups in parentheses will be collected as columns in the summary
# file.
summary:
- id: True_Pos_Fraction
regex: 'TPF: ([-+]?[0-9]*\.?[0-9])'
- id: False_pos_Fraction
regex: 'FPF: ([-+]?[0-9]*\.?[0-9])'
# Cluster partition to use
partition: 256GB
# Total number of nodes to use
nodes: 4
# Number of CPUs required by each task
cpus_per_task: 4
# Time limit
time_limit: 3d:00:00:00
# The list of parameters to explore
#
# For each parameter the following properties are required:
#
# type: 'int_range' A range of integers -or-
# 'real_range' A range of real numbers -or-
# 'choice' A list of string options
#
#
# The following properties are optional:
#
# flag: '--example' A flag which should proceed the value of the paremeter
# position: 1 The position of the parameter in the command line
# optional: true If true, we consider combinations excluding the parameter
#
# int_range and real_range types take paremeters:
#
# min: 10 Minimum value for the parameter
# max: 1e4 Maximum value for the parameter
# step: 20 Amount to add at each step through the range
# multiply: Amount to multiply value at each step through the range
#
# e.g. for an arithmetic progression of 10 - 100 in steps of 5:
# min: 10
# max: 100
# step: 5
#
# e.g. for a geometric progression of 1, 10, 100, 1,000, 10,000 (scale factor 10)
# min: 1
# max: 10000
# scale: 10
parameters:
- id: 'hidden'
type: "int_range"
flag: '--hidden'
position: 1
max: 32
step: 2
description: "Number of hidden nodes"
- id: 'beta'
type: real_range
flag: '-b'
position: 2
optional: true
min: 1.3
max: 1.4
step: 0.001
description: Regularization beta parameter
- type: choice
flag: '--activation'
values:
- step
- sigmoid
description: Activation function
import os
import pytest
from runner.param import ParamFile, ParamFileException, IntRange, RealRange, \
ChoiceRange
class TestParams:
def test_validate(self):
md = ParamFile(os.path.dirname(
os.path.abspath(__file__)) + '/test_data/test_params.yaml')
assert md.validate()
def test_validate_exception(self):
md = ParamFile(os.path.dirname(
os.path.abspath(__file__)) + '/test_data/test_params_invalid.yaml')
with pytest.raises(ParamFileException):
md.validate()
def test_load(self):
md = ParamFile(os.path.dirname(
os.path.abspath(__file__)) + '/test_data/test_params.yaml')
md.load()
assert md.vals
# IMPLICIT md.compute_param_ranges()
# min: 0
# max: 32
# step: 2
assert md.vals['parameters'][0]['range'] == range(0, 32 + 1, 2)
# optional: true
# min: 0.1
# max: 100
# scale: 10
assert md.vals['parameters'][1]['range'] == [None, 0.1, 1.0, 10.0,
100.0]
# values:
# - step
# - sigmoid
assert md.vals['parameters'][2]['range'] == ['step', 'sigmoid']
def test_int_range_single(self):
ir = IntRange({'id': 'test', 'min': 0, 'max': 5})
assert ir.to_list() == [0, 1, 2, 3, 4, 5]
def test_int_range_step(self):
ir = IntRange({'id': 'test', 'min': 0, 'max': 10, 'step': 2})
assert ir.to_list() == [0, 2, 4, 6, 8, 10]
def test_int_range_scale(self):
ir = IntRange({'id': 'test', 'min': 1, 'max': 10000, 'scale': 10})
assert ir.to_list() == [1, 10, 100, 1000, 10000]
def test_int_range_step_scale(self):
ir = IntRange(
{'id': 'test', 'min': 0, 'max': 10000, 'scale': 10, 'step': 9})
assert ir.to_list() == [0, 9, 99, 999, 9999]
def test_int_range_optional(self):
ir = IntRange({'id': 'test', 'min': 0, 'max': 5, 'optional': True})
assert ir.to_list() == [None, 0, 1, 2, 3, 4, 5]
def test_real_range_single(self):
rr = RealRange({'id': 'test', 'min': 0.1, 'max': 5.1})
assert rr.to_list() == pytest.approx([0.1, 1.1, 2.1, 3.1, 4.1, 5.1])
def test_real_range_step(self):
rr = RealRange({'id': 'test', 'min': 0.1, 'max': 4.9, 'step': 1.2})
assert rr.to_list() == pytest.approx([0.1, 1.3, 2.5, 3.7, 4.9])
def test_real_range_scale(self):
rr = RealRange({'id': 'test', 'min': 0.001, 'max': 10.0, 'scale': 10})
assert rr.to_list() == pytest.approx([0.001, 0.01, 0.1, 1.0, 10.0])
def test_real_range_step_scale(self):
rr = RealRange({'id': 'test', 'min': 0.001, 'max': 1000.0, 'scale': 10,
'step': 0.2})
assert rr.to_list() == pytest.approx([0.001, 0.21, 2.3, 23.2, 232.2])
def test_real_range_optional(self):
rr = RealRange({'id': 'test', 'min': 0.001, 'max': 10.0, 'scale': 10,
'optional': True})
assert rr.to_list() == pytest.approx(
[None, 0.001, 0.01, 0.1, 1.0, 10.0])
def test_choice(self):
cr = ChoiceRange({'id': 'test', 'values': ['One', 'Two', 'Three']})
assert cr.to_list() == ['One', 'Two', 'Three']
def test_choice_optional(self):
cr = ChoiceRange({'id': 'test', 'values': ['One', 'Two', 'Three'],
'optional': 'true'})
assert cr.to_list() == [None, 'One', 'Two', 'Three']
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment