Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1810 fix #1825

Merged
merged 80 commits into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
c6aba65
Better logging
devclinton Aug 25, 2022
42d3893
Added back changes made to 1810 original branch
emilydriano Aug 25, 2022
b9745a9
Make test platform compatible with id generators
devclinton Aug 30, 2022
a1ae14c
updated platform in test_item_sequence to 'Test' and added tests base…
emilydriano Aug 31, 2022
0908d9d
* Fix name of dummy suite method
devclinton Aug 31, 2022
ea96c12
Merge remote-tracking branch 'origin/1810-fix' into 1810-fix
devclinton Aug 31, 2022
d2925c5
* Add configuration caching to item sequence
devclinton Aug 31, 2022
33b50ef
Add cache clearing to tests
devclinton Aug 31, 2022
073df66
Fix tests
devclinton Aug 31, 2022
e3ac2b6
Update slurm tests to be UUID agnostic
devclinton Aug 31, 2022
cee87fd
Make test valid
devclinton Aug 31, 2022
c0f6eed
Mark test serial to prevent being ran with other tests because of con…
devclinton Aug 31, 2022
6b8ee82
Rest id on close
devclinton Sep 2, 2022
269f789
Updated documentation for item_sequence plugin, cleaned up test_item_…
emilydriano Sep 2, 2022
c12b778
Added methods to clear configuration before persistence_services and …
emilydriano Sep 6, 2022
ce414fa
Added documentation for new functions related to id generation.
emilydriano Sep 6, 2022
7d42595
Change order to ensure file is locked during write
devclinton Sep 7, 2022
05b6b6d
Add file locking
devclinton Sep 7, 2022
ea70b0b
Relay error if it occurs too much
devclinton Sep 7, 2022
c62bad8
Update tests
devclinton Sep 7, 2022
8000098
* Fix locking on item sequence
devclinton Sep 7, 2022
b20fef3
* Update performance test to add asserts
devclinton Sep 7, 2022
9b2451b
Update nechmark
devclinton Sep 7, 2022
200d457
* Fix linting
devclinton Sep 7, 2022
b2ad98e
* Replace with lru cache to be work with 3.7
devclinton Sep 7, 2022
68c0408
Clear other cache
devclinton Sep 7, 2022
20d67a5
Merge branch 'dev' into 1810-fix
devclinton Sep 8, 2022
7bbccf6
#1930 - New hook spec
devclinton Nov 1, 2022
86362ca
Merge remote-tracking branch 'origin/dev' into 1810-fix
devclinton Nov 1, 2022
fda3fdf
* Fix uid issue
devclinton Nov 2, 2022
a23b40c
* Document uid copy for manual case
devclinton Nov 2, 2022
21ea7c3
Updated default item sequence file to be $HOME/.idmtools/item_sequenc…
emilydriano Nov 3, 2022
40a8c0d
Merge branch '1810-fix' of https://github.com/InstituteforDiseaseMode…
emilydriano Nov 3, 2022
b756f8c
Updated item sequence file load Json error, & added logic to idmtools…
emilydriano Nov 7, 2022
bb621c3
Created test to verify existence and correctness of .bak file (backup…
emilydriano Nov 7, 2022
813af5d
* #1936 - Add constant for IDMTOOLS home path
devclinton Nov 7, 2022
585ac18
* Add post create hook at all different types of objects
devclinton Nov 7, 2022
5f1972a
Fix commit issue
devclinton Nov 7, 2022
118a3d5
* Fix linting
devclinton Nov 7, 2022
92d5059
# 1938 - Add post run hook
devclinton Nov 7, 2022
41650a0
Updated item_sequence plugin from post_create_item to post_run
emilydriano Nov 7, 2022
a0b4e64
Added logic to make slurm fail if directory exists
emilydriano Nov 8, 2022
c238580
Removed duplicate creation of simulation items in test_item_sequence
emilydriano Nov 8, 2022
0a9997d
Updated item_sequence documentation
emilydriano Nov 9, 2022
4d7a49c
- corrected logic to allow user to override exist_ok directory option…
emilydriano Nov 9, 2022
61441a0
Expanded on item_sequence plugin documentation.
emilydriano Nov 11, 2022
53f33eb
added 'performance' pytest mark, applied to test_id_generation
emilydriano Nov 11, 2022
9935564
https://github.com/InstituteforDiseaseModeling/idmtools/issues/1954
devclinton Nov 17, 2022
80a180d
#1954 - Move to strings for ids within core
devclinton Nov 17, 2022
e911817
#1954 - implementation of using str, not uuid
emilydriano Nov 22, 2022
758855d
#1954 - implementation of using str, not uuid
emilydriano Nov 22, 2022
86f05ef
#1954 - restored line in slurm item operations to set uid when conver…
emilydriano Nov 23, 2022
ea79ee0
#1954 - restored line in analyze_manager.py
emilydriano Nov 23, 2022
74d4eee
Merge branch 'dev' into 1810-fix
emilydriano Nov 30, 2022
6efc658
removed redundant Union expressions
emilydriano Nov 30, 2022
611b5f6
fixed linting issues
emilydriano Nov 30, 2022
28cb52f
changed UUID to str in slurm create_sim_dir_map functions
emilydriano Nov 30, 2022
032cdfc
final UUID > str changes, updated sequential_id_example
emilydriano Nov 30, 2022
414524d
excluded performance tests from test-all and test-smoke
emilydriano Nov 30, 2022
1b535d0
added jinja2 (used in item_sequence plugin) to requirements.txt files
emilydriano Nov 30, 2022
4dc93f1
updated pytest-html to 3.1.1
emilydriano Dec 2, 2022
948b128
Including target dir in error message to specify which dir already ex…
emilydriano Dec 5, 2022
197e012
modified experiment result to avoid causing the sims to be iterated u…
emilydriano Dec 12, 2022
71f732a
modified experiment result to avoid causing the sims to be iterated u…
emilydriano Dec 12, 2022
d338808
modified tests to exclude slurm experiment simulation data
emilydriano Dec 12, 2022
1e90f8b
modified create_sim_dir_map test to account for metadata change
emilydriano Dec 13, 2022
600f084
Merge branch 'dev' into 1810-fix
emilydriano Dec 13, 2022
5fdc8b0
changed named 'slurm_experiment' to 'experiment' in test_create_sim_d…
emilydriano Dec 13, 2022
56f26d7
Merge branch '1810-fix' of https://github.com/InstituteforDiseaseMode…
emilydriano Dec 13, 2022
a3899a3
used experiment post create in test execute platform to save simulati…
emilydriano Dec 15, 2022
6b89439
included missing package
emilydriano Dec 15, 2022
8e81982
added backup sequence file process to post-run hook for test-execute …
emilydriano Dec 15, 2022
e3ec545
Merge branch 'dev' into 1810-fix
emilydriano Dec 15, 2022
965a7e6
simplified code with super function
emilydriano Dec 16, 2022
ea7ba8c
added kwargs to post_run_item call
emilydriano Dec 16, 2022
99463d3
Merge branch 'dev' into 1810-fix
emilydriano Feb 9, 2023
14e6c2f
Update item_sequence.py
devclinton Feb 9, 2023
6b9a9aa
Update item_sequence.py
shchen-idmod Feb 9, 2023
32ffb5f
added changes defining 'meta' var in idmtools_platform_slurm platform…
emilydriano Feb 16, 2023
557b1fe
Merge remote-tracking branch 'origin/1810-fix' into 1810-fix
emilydriano Feb 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 85 additions & 0 deletions docs/cookbook/plugins/idmtools_item_sequence_example.ini
@@ -0,0 +1,85 @@
[COMMON]
# Number of threads idmtools will use for analysis and other multi-threaded activities
max_threads = 16

# How many simulations per threads during simulation creation
sims_per_thread = 20

# Maximum number of LOCAL simulation ran simultaneously
max_local_sims = 6

# Maxium number of workers processing in parallel
max_workers = 16

# Maxium batch size to retrieve simulations
batch_size = 10

id_generator = item_sequence

[COMPS]
type = COMPS
endpoint = https://comps.idmod.org
environment = Belegost
priority = Lowest
simulation_root = $COMPS_PATH(USER)\output
node_group = emod_abcd
num_retries = 0
num_cores = 1
max_workers = 16
batch_size = 10
exclusive = False

[COMPS2]
type = COMPS
endpoint = https://comps2.idmod.org
environment = Bayesian
priority = Lowest
simulation_root = $COMPS_PATH(USER)\output
node_group = emod_abcd
num_retries = 0
num_cores = 1
max_workers = 16
batch_size = 10
exclusive = False
test1 = 1
test2 = 2

[SSMT]
type = SSMT
endpoint = https://comps2.idmod.org
environment = Bayesian
priority = Lowest
simulation_root = $COMPS_PATH(USER)\output
node_group = emod_abcd
num_retries = 0
num_cores = 1
max_workers = 16
batch_size = 10
exclusive = False

[Local]
type = Local

# Path to the model executable
exe_path = \\internal.idm.ctr\IDM-Test\home\mafisher\bin\Eradication.exe

[Logging]
level = DEBUG
console = on


# This is a test we used to validate loading local from section block
[Custom_Local]
type = Local

[Test]
type = Test

[BADTYPE]
type = Bad

[NOTYPE]

[item_sequence]
sequence_file = item_ids.json
id_format_str = '{item_name}{data[item_name]:07d}'
52 changes: 52 additions & 0 deletions docs/cookbook/plugins/sequential_id_example.py
@@ -0,0 +1,52 @@
import os
import sys
from functools import partial
from typing import Any, Dict
from pathlib import Path
from idmtools import IdmConfigParser
from idmtools.builders import SimulationBuilder
from idmtools.core.platform_factory import Platform
from idmtools.entities.experiment import Experiment
from idmtools.entities.simulation import Simulation
from idmtools.entities.templated_simulation import TemplatedSimulations
from idmtools_models.python.json_python_task import JSONConfiguredPythonTask

# NOTE TO USER
# You need to define your own SlurmNative configuration block before running this example
# Please update examples/idmtools.ini accordingly
platform = Platform('SlurmNative')

with platform:
parser = IdmConfigParser()
parser._load_config_file(file_name='idmtools_item_sequence_example.ini')
parser.ensure_init(file_name='idmtools_item_sequence_example.ini', force=True)
sequence_file = Path(
IdmConfigParser.get_option("item_sequence", "sequence_file", 'item_sequences.json')).expanduser()
if sequence_file.exists():
sequence_file.unlink()

task = JSONConfiguredPythonTask(script_path=os.path.join("..", "..", "python_model", "inputs", "python_model_with_deps", "Assets", "model.py"),
parameters=(dict(c=0)))
ts = TemplatedSimulations(base_task=task)
builder = SimulationBuilder()

def param_update(simulation: Simulation, param: str, value: Any) -> Dict[str, Any]:
simulation.task.set_parameter(param, value)
return {param: value}

setA = partial(param_update, param="a")
setB = partial(param_update, param='b')
builder.add_sweep_definition(setA, range(2))
builder.add_sweep_definition(setB, range(3))

ts.add_builder(builder)

experiment = Experiment.from_template(ts)
experiment.tags['id'] = experiment.id

experiment.simulations = list(experiment.simulations)
for sim in list(experiment.simulations):
sim.tags['id'] = sim.id

experiment.run(True)
sys.exit(0 if experiment.succeeded else -1)
4 changes: 4 additions & 0 deletions docs/idmtools.ini
Expand Up @@ -16,6 +16,10 @@ max_local_sims = 6
# Maximum number of workers processing in parallel
max_workers = 16

# What type of ids should idmtools use internally
# use idmtools info plugins id_generators
id_generator = uuid

# You can also set number of workers per CPU
# If you had 16 cpus and set to 2, 32 workers would be created
# workers_per_cpu = 2
Expand Down
64 changes: 64 additions & 0 deletions docs/plugin_documentation/id-generator-plugins.rst
@@ -0,0 +1,64 @@
=====================
ID Generation Plugins
=====================

**1. Create a file to host the plugin callback for generator (under idmtools_core/idmtools/plugins). The plugin must have the following format**::

from idmtools.core.interfaces.ientity import IEntity

from idmtools.registry.hook_specs import function_hook_impl

@function_hook_impl

def idmtools_generate_id(item: IEntity) -> str:
Args:
item: Item for which ID is being generated
Returns:
return <your id implementation here>


The key things in this file are::

@function_hook_impl
def idmtools_generate_id(item: 'IEntity') -> str:

This registers the plugin type with idmtools. By using the name idmtools_generate_id, we know you are defining a callback for ids.
The callback must match the expected signature.


**2. Modify setup.py 'idmtools_hooks' to include the new id generation plugin**::

entry_points=dict(
idmtools_hooks=[
"idmtools_id_generate_<name> = <path to plugin>"
]
),

The *label* of the id plugin must start with **idmtools_id_generate_**
The letters after **idmtools_id_generate_** will be used to select generator in the config.

**3. Modify .ini config file to specify the desired id generator.**

In the .ini configuration file under the 'COMMON' section, use the 'id_generator' option to specify the desired id plugin.

For example, if you want to use the uuid generation plugin ('idmtools_id_generate_uuid'), in the .ini file, you would set the following::

[COMMON]
id_generator = uuid

Similarly, if you want to use the item_sequence plugin ('idmtools_id_generate_item_sequence'), you would specify the following in the .ini file::

[COMMON]
id_generator = item_sequence

The item_sequence plugin allows you to use sequential ids for items in your experiment (experiments themselves as well as simulations, etc).
You can customize use of this plugin by defining an 'item_sequence' section in the .ini file and using the variables:

* *sequence_file*: Json file that is used to store the last-used numbers for item ids. For example, if we have one experiment that was defined with two simulations, this file would keep track of the most recently used ids with the following: {"Simulation": 2, "Experiment": 1}. The default for this value is item_sequences.json, and this file will be created in the user's home directory. To note: the sequences start at 0. Also, to note: if an item is generated that does not have the item_type attribute (i.e. Platform), its sequence will be stored under the 'Unknown' key in this json file.
* *id_format_str*: This defines the desired format of the item ids (using the sequential id numbers stored in the sequence_file). In this string, one may access the sequential ids by using 'data[item_name]' (which would resolve to the next id #) as well as the 'item_name' (i.e. 'Simulation', 'Experiment'). The default for this value is '{item_name}{data[item_name]:07d}' (which would yield ids of 'Simulation0000000', 'Simulation0000001', etc).

Configuration format::

[item_sequence]
sequence_file = <custom file name>.json
id_format_str = '<custom string format>'
9 changes: 9 additions & 0 deletions docs/plugin_documentation/index.rst
@@ -0,0 +1,9 @@
=========================
Plugin Documentation
=========================

.. toctree::
:maxdepth: 3
:titlesonly:

id-generator-plugins
24 changes: 14 additions & 10 deletions docs/reference.rst
Expand Up @@ -13,6 +13,20 @@ Packages overview
.. uml:: /diagrams/packages_overview.puml


API and Plugin Documentation
============================
.. toctree::
:maxdepth: 2
:titlesonly:



idmtools_index
idmtools_models_index
idmtools_platform_comps_index
idmtools_platform_local_index
plugin_documentation/index

Packages and APIs
=================

Expand Down Expand Up @@ -60,13 +74,3 @@ API class specifications

.. uml:: /diagrams/apis-emod.puml

.. toctree::
:maxdepth: 2
:titlesonly:



idmtools_index
idmtools_models_index
idmtools_platform_comps_index
idmtools_platform_local_index
30 changes: 28 additions & 2 deletions idmtools_core/idmtools/core/interfaces/iitem.py
Expand Up @@ -4,10 +4,14 @@
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
"""
from dataclasses import dataclass, field, fields
from functools import cache
from inspect import signature
from logging import getLogger, DEBUG
from typing import List, Callable, TYPE_CHECKING, Any, Dict
from uuid import UUID, uuid4
from uuid import UUID

from idmtools import IdmConfigParser
from idmtools.registry.functions import FunctionPluginManager
from idmtools.utils.hashing import ignore_fields_in_dataclass_on_pickle

if TYPE_CHECKING: # pragma: no cover
Expand All @@ -18,6 +22,21 @@
PRE_POST_CREATION_HOOK = Callable[['IItem', 'IPlatform'], None]


@cache
def get_id_generator():
"""
Retrieves the type of id generator specified in .ini config as well as corresponding plugin.

Returns:
id_gen: specified id generation plugin in .ini config (uuid, item_sequence, etc)
plugin: id generation plugin that is used to determine ids for items. See setup.py > entry_points > idmtools_hooks for full names of plugin options
"""
fpm = FunctionPluginManager.instance()
id_gen = IdmConfigParser.get_option(None, "id_generator", "uuid")
plugin = fpm.get_plugin(f"idmtools_id_generate_{id_gen}")
return id_gen, plugin


@dataclass(repr=False)
class IItem:
"""
Expand All @@ -41,7 +60,14 @@ def uid(self):
ID
"""
if self._uid is None:
self._uid = str(uuid4())
id_gen, plugin = get_id_generator()
if plugin:
self._uid = plugin.idmtools_generate_id(self)
else:
fpm = FunctionPluginManager.instance()
id_plugins = sorted([x[0] for x in fpm.list_name_plugin() if x[0].startswith("idmtools_id_generate_")])
raise RuntimeError(f"Could not find the id plugin idmtools_id_generate_{id_gen} defined by id_generator in your idmtools.ini."
f"Please use one of the following plugins: {', '.join(id_plugins)}")
return self._uid

@uid.setter
Expand Down