code-loader 1.0.45__py3-none-any.whl → 1.0.47__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- code_loader/experiment_api/api.py +17 -14
- code_loader/experiment_api/epoch.py +74 -12
- code_loader/experiment_api/experiment.py +107 -18
- code_loader/experiment_api/utils.py +52 -2
- code_loader/experiment_api/workingspace_config_utils.py +8 -5
- code_loader/inner_leap_binder/leapbinder.py +1 -0
- code_loader/utils.py +2 -2
- {code_loader-1.0.45.dist-info → code_loader-1.0.47.dist-info}/METADATA +1 -1
- {code_loader-1.0.45.dist-info → code_loader-1.0.47.dist-info}/RECORD +11 -12
- code_loader/code_inegration_processes_manager.py +0 -83
- {code_loader-1.0.45.dist-info → code_loader-1.0.47.dist-info}/LICENSE +0 -0
- {code_loader-1.0.45.dist-info → code_loader-1.0.47.dist-info}/WHEEL +0 -0
@@ -6,18 +6,21 @@ from code_loader.experiment_api.types import ApiMetrics
|
|
6
6
|
|
7
7
|
|
8
8
|
@dataclass
|
9
|
-
class
|
10
|
-
projectId: str
|
9
|
+
class InitExperimentRequest:
|
11
10
|
experimentName: str
|
12
11
|
description: str
|
12
|
+
projectName: Optional[str] = None
|
13
|
+
projectId: Optional[str] = None
|
13
14
|
removeUntaggedUploadedModels: bool = True
|
14
|
-
|
15
|
+
codeIntegrationName: Optional[str] = None
|
16
|
+
codeIntegrationId: Optional[str] = None
|
15
17
|
|
16
18
|
@dataclass
|
17
|
-
class
|
19
|
+
class InitExperimentResponse:
|
18
20
|
projectId: str
|
19
21
|
versionId: str
|
20
22
|
experimentId: str
|
23
|
+
isCreatedProject: bool
|
21
24
|
|
22
25
|
@dataclass
|
23
26
|
class GetUploadModelSignedUrlRequest:
|
@@ -34,7 +37,7 @@ class GetUploadModelSignedUrlResponse:
|
|
34
37
|
fileName: str
|
35
38
|
|
36
39
|
@dataclass
|
37
|
-
class
|
40
|
+
class LogExternalEpochDataRequest:
|
38
41
|
projectId: str
|
39
42
|
experimentId: str
|
40
43
|
epoch: int
|
@@ -49,33 +52,33 @@ class TagModelRequest:
|
|
49
52
|
tags: List[str]
|
50
53
|
|
51
54
|
@dataclass
|
52
|
-
class
|
55
|
+
class SetExperimentPropertiesRequest:
|
53
56
|
projectId: str
|
54
57
|
experimentId: str
|
55
|
-
|
58
|
+
properties: Dict[str, Any]
|
56
59
|
|
57
60
|
class Api:
|
58
61
|
def __init__(self, client: Client):
|
59
62
|
self.client = client
|
60
63
|
|
61
|
-
def
|
62
|
-
response = self.client.post('/versions/
|
64
|
+
def init_experiment(self, data: InitExperimentRequest) -> InitExperimentResponse:
|
65
|
+
response = self.client.post('/versions/initExperiment', data)
|
63
66
|
self.client.check_response(response)
|
64
|
-
return
|
67
|
+
return InitExperimentResponse(**response.json())
|
65
68
|
|
66
69
|
def get_uploaded_model_signed_url(self, data: GetUploadModelSignedUrlRequest)-> GetUploadModelSignedUrlResponse:
|
67
70
|
response = self.client.post('/versions/getUploadModelSignedUrl', data)
|
68
71
|
self.client.check_response(response)
|
69
72
|
return GetUploadModelSignedUrlResponse(**response.json())
|
70
73
|
|
71
|
-
def
|
72
|
-
response = self.client.post('/externalepochdata/
|
74
|
+
def log_external_epoch_data(self, data: LogExternalEpochDataRequest)-> None:
|
75
|
+
response = self.client.post('/externalepochdata/logExternalEpochData', data)
|
73
76
|
self.client.check_response(response)
|
74
77
|
|
75
78
|
def tag_model(self, data: TagModelRequest)-> None:
|
76
79
|
response = self.client.post('/versions/tagModel', data)
|
77
80
|
self.client.check_response(response)
|
78
81
|
|
79
|
-
def
|
80
|
-
response = self.client.post('/versions/
|
82
|
+
def set_experiment_properties(self, data: SetExperimentPropertiesRequest)-> None:
|
83
|
+
response = self.client.post('/versions/setExperimentProperties', data)
|
81
84
|
self.client.check_response(response)
|
@@ -1,25 +1,66 @@
|
|
1
|
-
|
2
1
|
from typing import List, Optional
|
3
2
|
from code_loader.experiment_api.experiment_context import ExperimentContext
|
4
3
|
from code_loader.experiment_api.types import Metrics
|
5
4
|
from code_loader.experiment_api.utils import to_api_metric_value, upload_file
|
6
|
-
from code_loader.experiment_api.api import
|
5
|
+
from code_loader.experiment_api.api import LogExternalEpochDataRequest, GetUploadModelSignedUrlRequest, TagModelRequest
|
7
6
|
|
8
7
|
|
9
8
|
class Epoch:
|
10
|
-
|
9
|
+
"""
|
10
|
+
Represents an epoch in an experiment.
|
11
|
+
|
12
|
+
Attributes:
|
13
|
+
experiment (ExperimentContext): The context of the experiment.
|
14
|
+
epoch (int): The epoch number.
|
15
|
+
metrics (Metrics): The metrics associated with the epoch.
|
16
|
+
default_tag (str): The default tag for the epoch.
|
17
|
+
ctx (ExperimentContext): The context of the experiment.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(self, ctx: ExperimentContext, epoch: int, default_tag: str = 'latest'):
|
21
|
+
"""
|
22
|
+
Initializes the Epoch instance.
|
23
|
+
|
24
|
+
Args:
|
25
|
+
ctx (ExperimentContext): The context of the experiment.
|
26
|
+
epoch (int): The epoch number.
|
27
|
+
default_tag (str): The default tag for the epoch. Defaults to 'latest', set to '' for no default tag.
|
28
|
+
"""
|
11
29
|
self.experiment = ExperimentContext
|
12
30
|
self.epoch = epoch
|
13
31
|
self.metrics: Metrics = {}
|
32
|
+
self.default_tag = default_tag
|
14
33
|
self.ctx = ctx
|
15
34
|
|
16
|
-
def add_metric(self, name: str, value: float)-> None:
|
35
|
+
def add_metric(self, name: str, value: float) -> None:
|
36
|
+
"""
|
37
|
+
Adds a metric to the epoch.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
name (str): The name of the metric.
|
41
|
+
value (float): The value of the metric.
|
42
|
+
"""
|
17
43
|
self.metrics[name] = value
|
18
44
|
|
19
|
-
def set_metrics(self, metrics: Metrics)-> None:
|
45
|
+
def set_metrics(self, metrics: Metrics) -> None:
|
46
|
+
"""
|
47
|
+
Sets the metrics for the epoch.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
metrics (Metrics): The metrics to set for the epoch.
|
51
|
+
"""
|
20
52
|
self.metrics = metrics
|
21
53
|
|
22
|
-
def _upload_model(self, modelFilePath: str)-> None:
|
54
|
+
def _upload_model(self, modelFilePath: str) -> None:
|
55
|
+
"""
|
56
|
+
Uploads the model file for the epoch.
|
57
|
+
|
58
|
+
Args:
|
59
|
+
modelFilePath (str): The path to the model file.
|
60
|
+
|
61
|
+
Raises:
|
62
|
+
Exception: If the model file extension is not allowed.
|
63
|
+
"""
|
23
64
|
allowed_extensions = ["h5", "onnx"]
|
24
65
|
modelExtension = modelFilePath.split(".")[-1]
|
25
66
|
if modelExtension not in allowed_extensions:
|
@@ -35,7 +76,13 @@ class Epoch:
|
|
35
76
|
upload_file(url.url, modelFilePath)
|
36
77
|
print("Model file uploaded")
|
37
78
|
|
38
|
-
def _tag_model(self, tags: List[str])-> None:
|
79
|
+
def _tag_model(self, tags: List[str]) -> None:
|
80
|
+
"""
|
81
|
+
Tags the model file for the epoch.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
tags (List[str]): The tags to associate with the model file.
|
85
|
+
"""
|
39
86
|
print(f"Tagging epoch({self.epoch}) model")
|
40
87
|
self.ctx.api.tag_model(TagModelRequest(
|
41
88
|
experimentId=self.ctx.experiment_id,
|
@@ -44,20 +91,35 @@ class Epoch:
|
|
44
91
|
tags=tags
|
45
92
|
))
|
46
93
|
|
47
|
-
def log(self, modelFilePath: Optional[str] = None, tags: List[str] =
|
94
|
+
def log(self, modelFilePath: Optional[str] = None, tags: Optional[List[str]] = None) -> None:
|
95
|
+
"""
|
96
|
+
Logs the epoch with optional model file and tags.
|
97
|
+
|
98
|
+
Args:
|
99
|
+
modelFilePath (Optional[str]): The path to the model file. Defaults to None.
|
100
|
+
tags (Optional[List[str]]): A list of tags to associate with the epoch model. Will always include the default tag. Unless the default tag is set to '', all previous epoch model with the same tag will be removed
|
101
|
+
"""
|
102
|
+
if tags is None:
|
103
|
+
tags = []
|
104
|
+
|
48
105
|
if modelFilePath is not None:
|
49
106
|
self._upload_model(modelFilePath)
|
107
|
+
|
108
|
+
if len(self.default_tag) > 0 and self.default_tag not in tags:
|
109
|
+
tags.append(self.default_tag)
|
110
|
+
|
111
|
+
if len(tags) == 0 and modelFilePath is not None:
|
112
|
+
raise Exception("No tags provided for the epoch model. Either provide tags or use default_tag")
|
50
113
|
|
51
114
|
print(f"Add metrics for epoch({self.epoch}) model")
|
52
|
-
api_metrics ={
|
115
|
+
api_metrics = {
|
53
116
|
key: to_api_metric_value(value) for key, value in self.metrics.items()
|
54
117
|
}
|
55
|
-
self.ctx.api.
|
118
|
+
self.ctx.api.log_external_epoch_data(LogExternalEpochDataRequest(
|
56
119
|
experimentId=self.ctx.experiment_id,
|
57
120
|
projectId=self.ctx.project_id,
|
58
121
|
epoch=self.epoch,
|
59
122
|
metrics=api_metrics
|
60
123
|
))
|
61
124
|
if modelFilePath is not None and len(tags) > 0:
|
62
|
-
self._tag_model(tags)
|
63
|
-
|
125
|
+
self._tag_model(tags)
|
@@ -1,49 +1,138 @@
|
|
1
1
|
|
2
2
|
from typing import Any, Dict, List, Optional
|
3
3
|
from code_loader.experiment_api.epoch import Epoch
|
4
|
-
from code_loader.experiment_api.api import Api,
|
4
|
+
from code_loader.experiment_api.api import Api, SetExperimentPropertiesRequest, InitExperimentRequest
|
5
5
|
from code_loader.experiment_api.experiment_context import ExperimentContext
|
6
6
|
from code_loader.experiment_api.types import Metrics
|
7
7
|
from code_loader.experiment_api.workingspace_config_utils import load_workspace_config
|
8
|
+
from code_loader.experiment_api.utils import generate_experiment_name
|
8
9
|
from code_loader.experiment_api.client import Client
|
9
10
|
|
10
11
|
|
11
12
|
class Experiment:
|
12
|
-
|
13
|
+
"""
|
14
|
+
Represents an experiment in the system.
|
15
|
+
|
16
|
+
Attributes:
|
17
|
+
ctx (ExperimentContext): The context of the experiment, including API client and identifiers.
|
18
|
+
default_epoch_tag (str): The default tag for epochs. Defaults to 'latest'.
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self, ctx: ExperimentContext, default_epoch_tag: str = 'latest'):
|
22
|
+
"""
|
23
|
+
Initializes the Experiment instance.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
ctx (ExperimentContext): The context of the experiment.
|
27
|
+
default_epoch_tag (str): The default tag for epochs. Defaults to 'latest'.
|
28
|
+
"""
|
13
29
|
self.ctx = ctx
|
30
|
+
self.default_epoch_tag = default_epoch_tag
|
14
31
|
|
15
32
|
def init_epoch(self, epoch: int) -> Epoch:
|
16
|
-
|
33
|
+
"""
|
34
|
+
Initializes a new epoch for the experiment.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
epoch (int): The epoch number to initialize.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
Epoch: An instance of the Epoch class.
|
41
|
+
"""
|
42
|
+
return Epoch(self.ctx, epoch, self.default_epoch_tag)
|
17
43
|
|
18
|
-
def log_epoch(self, epoch: int, metrics: Optional[Metrics] = None, model_path: Optional[str] = None, tags: List[str] =
|
44
|
+
def log_epoch(self, epoch: int, metrics: Optional[Metrics] = None, model_path: Optional[str] = None, tags: Optional[List[str]] = None) -> None:
|
45
|
+
"""
|
46
|
+
Logs an epoch with optional metrics, model path, and tags.
|
47
|
+
|
48
|
+
Args:
|
49
|
+
epoch (int): The epoch number to log.
|
50
|
+
metrics (Optional[Metrics]): The metrics to log for the epoch. Defaults to None.
|
51
|
+
model_path (Optional[str]): The path to the model file. Defaults to None.
|
52
|
+
tags (Optional[List[str]]): A list of tags to associate with the epoch model. Will always include the default tag. Unless the default tag is set to '', all previous epoch model with the same tag will be removed.
|
53
|
+
"""
|
19
54
|
epoch_o = self.init_epoch(epoch)
|
20
55
|
if metrics is not None:
|
21
56
|
epoch_o.set_metrics(metrics)
|
22
57
|
epoch_o.log(model_path, tags)
|
23
58
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
59
|
+
def set_properties(self, properties: Dict[str, Any]) -> None:
|
60
|
+
"""
|
61
|
+
Sets properties for the experiment.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
properties (Dict[str, Any]): A dictionary of properties to set for the experiment.
|
65
|
+
"""
|
66
|
+
print(f"Setting experiment({self.ctx.experiment_id}) properties")
|
67
|
+
self.ctx.api.set_experiment_properties(SetExperimentPropertiesRequest(
|
27
68
|
experimentId=self.ctx.experiment_id,
|
28
69
|
projectId=self.ctx.project_id,
|
29
|
-
|
70
|
+
properties=properties
|
30
71
|
))
|
31
72
|
|
32
|
-
def init_experiment(
|
73
|
+
def init_experiment(
|
74
|
+
experiment_name: Optional[str] = None,
|
75
|
+
description: str = "",
|
76
|
+
project_name: Optional[str] = None,
|
77
|
+
code_integration_name: Optional[str] = None,
|
78
|
+
working_dir: Optional[str] = None,
|
79
|
+
client: Optional[Client] = None,
|
80
|
+
default_epoch_tag: str = 'latest',
|
81
|
+
) -> 'Experiment':
|
82
|
+
"""
|
83
|
+
Initializes and starts a new experiment.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
experiment_name (Optional[str]): The name of the experiment. If not provided, a name will be generated.
|
87
|
+
Example generated names:
|
88
|
+
- Bold Crimson Serpent
|
89
|
+
- Brave Sun Raven
|
90
|
+
- Griffin of the Pearl Wings
|
91
|
+
description (str): A description of the experiment.
|
92
|
+
project_name (Optional[str]): The name of the project. If it does not exist, a new project will be created. If not provided, the project ID is loaded from the workspace config.
|
93
|
+
code_integration_name (Optional[str]): The name of the code integration.
|
94
|
+
working_dir (Optional[str]): The working directory. If not provided, the current directory is used.
|
95
|
+
The working directory should contain a leap.yaml file with the project ID and optionally the code integration ID.
|
96
|
+
This configuration is used if the project name is not provided.
|
97
|
+
client (Optional[Client]): The client to use for the experiment. If not provided, the client will be taken from the leap CLI configuration.
|
98
|
+
Ensure that the user has initialized the authentication by running `leap auth [url] [token]`.
|
99
|
+
default_epoch_tag (str): The default tag to use for epoch model. Default is 'latest', set to '' for no default tag.
|
100
|
+
|
101
|
+
Returns:
|
102
|
+
Experiment: An instance of the Experiment class.
|
103
|
+
|
104
|
+
Raises:
|
105
|
+
Exception: If the project name is not supplied and no workspace config is found or the project ID is missing from the leap.yaml file.
|
106
|
+
Exception: If the client is not supplied and the user has not initialized the authentication by running `leap auth [url] [token]`.
|
107
|
+
"""
|
33
108
|
if client is None:
|
34
109
|
client = Client()
|
110
|
+
|
111
|
+
if experiment_name is None:
|
112
|
+
experiment_name = generate_experiment_name()
|
113
|
+
print(f"Experiment name not provided, generated name: {experiment_name}")
|
114
|
+
|
35
115
|
|
36
116
|
api = Api(client)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
117
|
+
project_id: Optional[str] = None
|
118
|
+
code_integration_id: Optional[str] = None
|
119
|
+
|
120
|
+
if not project_name:
|
121
|
+
workspace_config = load_workspace_config(working_dir)
|
122
|
+
if workspace_config is None or workspace_config.projectId is None:
|
123
|
+
raise Exception("No leap workspace config found or projectId is missing, make sure you are in a leap workspace directory or provide a working_dir")
|
124
|
+
project_id = workspace_config.projectId
|
125
|
+
code_integration_id = workspace_config.codeIntegrationId
|
41
126
|
|
42
|
-
result = api.
|
43
|
-
projectId=
|
44
|
-
experimentName=
|
127
|
+
result = api.init_experiment(InitExperimentRequest(
|
128
|
+
projectId=project_id,
|
129
|
+
experimentName=experiment_name,
|
45
130
|
description=description,
|
46
|
-
|
131
|
+
codeIntegrationId=code_integration_id,
|
132
|
+
codeIntegrationName=code_integration_name,
|
133
|
+
projectName=project_name
|
47
134
|
))
|
135
|
+
if result.isCreatedProject:
|
136
|
+
print(f"Project name: {project_name} not found, created a new one with id: {result.projectId}")
|
48
137
|
ctx = ExperimentContext(api, result.projectId, result.versionId, result.experimentId)
|
49
|
-
return Experiment(ctx)
|
138
|
+
return Experiment(ctx, default_epoch_tag)
|
@@ -1,8 +1,9 @@
|
|
1
1
|
from dataclasses import asdict, is_dataclass
|
2
|
+
import random
|
3
|
+
import requests
|
2
4
|
from typing import Any, Dict, Union
|
3
5
|
from urllib.parse import urljoin
|
4
6
|
from code_loader.experiment_api.types import ApiMetricValue, MetricValue, NumericMetricValue, StringMetricValue
|
5
|
-
import requests
|
6
7
|
|
7
8
|
|
8
9
|
def upload_file(url: str, file_path: str)-> None:
|
@@ -32,4 +33,53 @@ def to_api_metric_value(value: MetricValue) -> ApiMetricValue:
|
|
32
33
|
elif isinstance(value, str):
|
33
34
|
return StringMetricValue(value=value)
|
34
35
|
else:
|
35
|
-
raise Exception(f"Unsupported metric value type: {type(value)}")
|
36
|
+
raise Exception(f"Unsupported metric value type: {type(value)}")
|
37
|
+
|
38
|
+
|
39
|
+
def generate_experiment_name() -> str:
|
40
|
+
words = {
|
41
|
+
"adjectives": [
|
42
|
+
"Brave", "Clever", "Fierce", "Mysterious", "Swift", "Ancient", "Luminous",
|
43
|
+
"Bold", "Majestic", "Noble", "Silent", "Vibrant", "Eternal", "Mystic",
|
44
|
+
"Radiant", "Whimsical", "Serene", "Fabled", "Shadowy", "Enigmatic", "Fearless"
|
45
|
+
],
|
46
|
+
"animals": [
|
47
|
+
"Tiger", "Phoenix", "Dragon", "Griffin", "Falcon", "Wolf", "Eagle",
|
48
|
+
"Lion", "Panther", "Hawk", "Unicorn", "Bear", "Raven", "Fox", "Cobra",
|
49
|
+
"Leopard", "Serpent", "Shark", "Owl", "Stag", "Hound", "Basilisk"
|
50
|
+
],
|
51
|
+
"colors": [
|
52
|
+
"Crimson", "Azure", "Emerald", "Golden", "Silver", "Midnight", "Scarlet",
|
53
|
+
"Ivory", "Obsidian", "Sapphire", "Ruby", "Onyx", "Amber", "Copper",
|
54
|
+
"Pearl", "Amethyst", "Topaz", "Jade", "Bronze", "Verdant", "Indigo"
|
55
|
+
],
|
56
|
+
"elements": [
|
57
|
+
"Fire", "Water", "Earth", "Air", "Lightning", "Shadow", "Ice",
|
58
|
+
"Storm", "Light", "Darkness", "Sun", "Moon", "Void", "Spirit",
|
59
|
+
"Flame", "Ocean", "Wind", "Frost", "Thunder", "Blaze", "Mist"
|
60
|
+
],
|
61
|
+
"objects": [
|
62
|
+
"Blade", "Crown", "Shield", "Spear", "Wings", "Orb", "Heart",
|
63
|
+
"Soul", "Flame", "Key", "Ring", "Sword", "Chalice", "Banner",
|
64
|
+
"Gem", "Mirror", "Scroll", "Stone", "Throne", "Helm", "Talisman"
|
65
|
+
]
|
66
|
+
}
|
67
|
+
|
68
|
+
pattern = random.choice([
|
69
|
+
"{adjectives} {animals}",
|
70
|
+
"{colors} {animals}",
|
71
|
+
"{elements} {animals}",
|
72
|
+
"{adjectives} {objects}",
|
73
|
+
"{colors} {objects}",
|
74
|
+
"{elements} {objects}",
|
75
|
+
"{adjectives} {elements}",
|
76
|
+
"{adjectives} {colors}"
|
77
|
+
])
|
78
|
+
|
79
|
+
return pattern.format(
|
80
|
+
adjectives=random.choice(words["adjectives"]),
|
81
|
+
animals=random.choice(words["animals"]),
|
82
|
+
colors=random.choice(words["colors"]),
|
83
|
+
elements=random.choice(words["elements"]),
|
84
|
+
objects=random.choice(words["objects"])
|
85
|
+
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from os import path
|
3
3
|
import os
|
4
|
-
from typing import
|
4
|
+
from typing import Optional
|
5
5
|
import yaml
|
6
6
|
|
7
7
|
|
@@ -10,9 +10,7 @@ class LocalProjectConfig:
|
|
10
10
|
codeIntegrationId: Optional[str] = None
|
11
11
|
projectId: Optional[str] = None
|
12
12
|
secretId: Optional[str] = None
|
13
|
-
secretManagerId: Optional[str] = None
|
14
13
|
entryFile: Optional[str] = None
|
15
|
-
includePatterns: Optional[List[str]] = None
|
16
14
|
|
17
15
|
# Loading workspace configuration from leap.yaml
|
18
16
|
def load_workspace_config(workspace_dir: Optional[str] = None) -> Optional[LocalProjectConfig]:
|
@@ -23,5 +21,10 @@ def load_workspace_config(workspace_dir: Optional[str] = None) -> Optional[Local
|
|
23
21
|
|
24
22
|
file_path = path.join(workspace_dir, "leap.yaml")
|
25
23
|
with open(file_path) as f:
|
26
|
-
|
27
|
-
return LocalProjectConfig(
|
24
|
+
leap_yaml = yaml.safe_load(f)
|
25
|
+
return LocalProjectConfig(
|
26
|
+
codeIntegrationId=leap_yaml.get("codeIntegrationId"),
|
27
|
+
projectId=leap_yaml.get("projectId"),
|
28
|
+
secretId=leap_yaml.get("secretId"),
|
29
|
+
entryFile=leap_yaml.get("entryFile"),
|
30
|
+
)
|
@@ -420,6 +420,7 @@ class LeapBinder:
|
|
420
420
|
]
|
421
421
|
for i, (single_metadata_name, single_metadata_result) in enumerate(raw_result.items()):
|
422
422
|
metadata_test_result = metadata_test_result_payloads[i]
|
423
|
+
|
423
424
|
result_shape = get_shape(single_metadata_result)
|
424
425
|
metadata_test_result.shape = result_shape
|
425
426
|
metadata_test_result.raw_result = single_metadata_result
|
code_loader/utils.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import sys
|
2
2
|
from pathlib import Path
|
3
3
|
from types import TracebackType
|
4
|
-
from typing import List, Union, Tuple
|
4
|
+
from typing import List, Union, Tuple, Any
|
5
5
|
import traceback
|
6
6
|
import numpy as np
|
7
7
|
import numpy.typing as npt
|
@@ -43,7 +43,7 @@ def get_root_exception_file_and_line_number() -> Tuple[int, str, str]:
|
|
43
43
|
return root_exception_line_number, root_exception_file_name, traceback_as_string
|
44
44
|
|
45
45
|
|
46
|
-
def get_shape(result:
|
46
|
+
def get_shape(result: Any) -> List[int]:
|
47
47
|
if not isinstance(result, np.ndarray):
|
48
48
|
return [1]
|
49
49
|
np_shape = result.shape
|
@@ -1,6 +1,5 @@
|
|
1
1
|
LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
|
2
2
|
code_loader/__init__.py,sha256=6MMWr0ObOU7hkqQKgOqp4Zp3I28L7joGC9iCbQYtAJg,241
|
3
|
-
code_loader/code_inegration_processes_manager.py,sha256=XslWOPeNQk4RAFJ_f3tP5Oe3EgcIR7BE7Y8r9Ty73-o,3261
|
4
3
|
code_loader/contract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
4
|
code_loader/contract/datasetclasses.py,sha256=81TmCcVol7768lzKUp70MatLLipR3ftcR9jgE1r8Yqo,5698
|
6
5
|
code_loader/contract/enums.py,sha256=6Lo7p5CUog68Fd31bCozIuOgIp_IhSiPqWWph2k3OGU,1602
|
@@ -8,22 +7,22 @@ code_loader/contract/exceptions.py,sha256=jWqu5i7t-0IG0jGRsKF4DjJdrsdpJjIYpUkN1F
|
|
8
7
|
code_loader/contract/responsedataclasses.py,sha256=w7xVOv2S8Hyb5lqyomMGiKAWXDTSOG-FX1YW39bXD3A,3969
|
9
8
|
code_loader/contract/visualizer_classes.py,sha256=Ka8fJSVKrOeZ12Eg8-dOBGMW0UswYCIkuhnNMd-7z9s,22948
|
10
9
|
code_loader/experiment_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
code_loader/experiment_api/api.py,sha256=
|
10
|
+
code_loader/experiment_api/api.py,sha256=p_III5t9WCpvd1REq9L-pF3r1RhjDlxMCBBK-Sn0B1I,2490
|
12
11
|
code_loader/experiment_api/cli_config_utils.py,sha256=n6JMyNrquxql3KKxHhAP8jAzezlRT-PV2KWI95kKsm0,1140
|
13
12
|
code_loader/experiment_api/client.py,sha256=8kqLWh2Zg7mNA5E9Q0v0qRuPm3OE3Rs7lfGAcXOucU4,1428
|
14
|
-
code_loader/experiment_api/epoch.py,sha256=
|
15
|
-
code_loader/experiment_api/experiment.py,sha256=
|
13
|
+
code_loader/experiment_api/epoch.py,sha256=q46cxVfpautynKL-ju0YS83vYhpuZuscLA0nff748y0,4700
|
14
|
+
code_loader/experiment_api/experiment.py,sha256=oVi6GAJ1e1kOygnOquTvb6SgepMhTlrpH0uVqCwviYM,6349
|
16
15
|
code_loader/experiment_api/experiment_context.py,sha256=kdzUbuzXo1pMVslOC3TKeJwW8sx_qWkxDVrswjduH0A,194
|
17
16
|
code_loader/experiment_api/types.py,sha256=MY8xFARHwdVA7p4dxyhD60ShmttgTvb4qdp1oEB_NPg,485
|
18
|
-
code_loader/experiment_api/utils.py,sha256=
|
19
|
-
code_loader/experiment_api/workingspace_config_utils.py,sha256=
|
17
|
+
code_loader/experiment_api/utils.py,sha256=XZHtxge12TS4H4-8PjV3sKuhp8Ud6ojAiIzTZJEqBqc,3304
|
18
|
+
code_loader/experiment_api/workingspace_config_utils.py,sha256=DLzXQCg4dgTV_YgaSbeTVzq-2ja_SQw4zi7LXwKL9cY,990
|
20
19
|
code_loader/inner_leap_binder/__init__.py,sha256=koOlJyMNYzGbEsoIbXathSmQ-L38N_pEXH_HvL7beXU,99
|
21
|
-
code_loader/inner_leap_binder/leapbinder.py,sha256=
|
20
|
+
code_loader/inner_leap_binder/leapbinder.py,sha256=CDiz8AWgNW-TgSPspllUUxy2Q-9V2JcavPJ0CZOAUnU,23888
|
22
21
|
code_loader/leaploader.py,sha256=E1DHtRDzz0hyb3kAMl6S_JDbjGxJPR_bZHU77Af4rR4,17521
|
23
|
-
code_loader/utils.py,sha256=
|
22
|
+
code_loader/utils.py,sha256=TZAoUbA2pE8eK3Le3s5Xr4eRaYdeDMQtxotx6rh-5oE,2185
|
24
23
|
code_loader/visualizers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
24
|
code_loader/visualizers/default_visualizers.py,sha256=VoqO9FN84yXyMjRjHjUTOt2GdTkJRMbHbXJ1cJkREkk,2230
|
26
|
-
code_loader-1.0.
|
27
|
-
code_loader-1.0.
|
28
|
-
code_loader-1.0.
|
29
|
-
code_loader-1.0.
|
25
|
+
code_loader-1.0.47.dist-info/LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
|
26
|
+
code_loader-1.0.47.dist-info/METADATA,sha256=bDWLdxS53o7nfne8b-M9OOGy5Rf-AqnKshHY6XtNYTM,888
|
27
|
+
code_loader-1.0.47.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
28
|
+
code_loader-1.0.47.dist-info/RECORD,,
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# mypy: ignore-errors
|
2
|
-
import traceback
|
3
|
-
from dataclasses import dataclass
|
4
|
-
|
5
|
-
from typing import List, Tuple, Optional
|
6
|
-
|
7
|
-
from multiprocessing import Process, Queue
|
8
|
-
|
9
|
-
from code_loader.leap_loader_parallelized_base import LeapLoaderParallelizedBase
|
10
|
-
from code_loader.leaploader import LeapLoader
|
11
|
-
from code_loader.contract.enums import DataStateEnum
|
12
|
-
from code_loader.metric_calculator_parallelized import MetricCalculatorParallelized
|
13
|
-
from code_loader.samples_generator_parallelized import SamplesGeneratorParallelized
|
14
|
-
|
15
|
-
|
16
|
-
@dataclass
|
17
|
-
class SampleSerializableError:
|
18
|
-
state: DataStateEnum
|
19
|
-
index: int
|
20
|
-
leap_script_trace: str
|
21
|
-
exception_as_str: str
|
22
|
-
|
23
|
-
|
24
|
-
class CodeIntegrationProcessesManager:
|
25
|
-
def __init__(self, code_path: str, code_entry_name: str, n_workers: Optional[int] = 2,
|
26
|
-
max_samples_in_queue: int = 128) -> None:
|
27
|
-
self.metric_calculator_parallelized = MetricCalculatorParallelized(code_path, code_entry_name)
|
28
|
-
self.samples_generator_parallelized = SamplesGeneratorParallelized(code_path, code_entry_name)
|
29
|
-
|
30
|
-
def _create_and_start_process(self) -> Process:
|
31
|
-
process = self.multiprocessing_context.Process(
|
32
|
-
target=CodeIntegrationProcessesManager._process_func,
|
33
|
-
args=(self.code_path, self.code_entry_name, self._inputs_waiting_to_be_process,
|
34
|
-
self._ready_processed_results))
|
35
|
-
process.daemon = True
|
36
|
-
process.start()
|
37
|
-
return process
|
38
|
-
|
39
|
-
def _run_and_warm_first_process(self):
|
40
|
-
process = self._create_and_start_process()
|
41
|
-
self.processes = [process]
|
42
|
-
|
43
|
-
# needed in order to make sure the preprocess func runs once in nonparallel
|
44
|
-
self._start_process_inputs([(DataStateEnum.training, 0)])
|
45
|
-
self._get_next_ready_processed_result()
|
46
|
-
|
47
|
-
def _operation_decider(self):
|
48
|
-
if self.metric_calculator_parallelized._ready_processed_results.empty() and not \
|
49
|
-
self.metric_calculator_parallelized._inputs_waiting_to_be_process.empty():
|
50
|
-
return 'metric'
|
51
|
-
|
52
|
-
if self.samples_generator_parallelized._ready_processed_results.empty() and not \
|
53
|
-
self.samples_generator_parallelized._inputs_waiting_to_be_process.empty():
|
54
|
-
return 'dataset'
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@staticmethod
|
60
|
-
def _process_func(code_path: str, code_entry_name: str,
|
61
|
-
samples_to_process: Queue, ready_samples: Queue,
|
62
|
-
metrics_to_process: Queue, ready_metrics: Queue) -> None:
|
63
|
-
import os
|
64
|
-
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
|
65
|
-
|
66
|
-
leap_loader = LeapLoader(code_path, code_entry_name)
|
67
|
-
while True:
|
68
|
-
|
69
|
-
# decide on sample or metric to process
|
70
|
-
state, idx = samples_to_process.get(block=True)
|
71
|
-
leap_loader._preprocess_result()
|
72
|
-
try:
|
73
|
-
sample = leap_loader.get_sample(state, idx)
|
74
|
-
except Exception as e:
|
75
|
-
leap_script_trace = traceback.format_exc().split('File "<string>"')[-1]
|
76
|
-
ready_samples.put(SampleSerializableError(state, idx, leap_script_trace, str(e)))
|
77
|
-
continue
|
78
|
-
|
79
|
-
ready_samples.put(sample)
|
80
|
-
|
81
|
-
def generate_samples(self, sample_identities: List[Tuple[DataStateEnum, int]]):
|
82
|
-
return self.start_process_inputs(sample_identities)
|
83
|
-
|
File without changes
|
File without changes
|