cars 1.0.0rc2__cp312-cp312-win_amd64.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.

Potentially problematic release.


This version of cars might be problematic. Click here for more details.

Files changed (225) hide show
  1. cars/__init__.py +86 -0
  2. cars/applications/__init__.py +40 -0
  3. cars/applications/application.py +117 -0
  4. cars/applications/application_constants.py +29 -0
  5. cars/applications/application_template.py +146 -0
  6. cars/applications/auxiliary_filling/__init__.py +29 -0
  7. cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
  10. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
  11. cars/applications/dem_generation/__init__.py +30 -0
  12. cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
  13. cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
  14. cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
  15. cars/applications/dem_generation/bulldozer_memory.py +55 -0
  16. cars/applications/dem_generation/dem_generation_algo.py +107 -0
  17. cars/applications/dem_generation/dem_generation_constants.py +32 -0
  18. cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
  19. cars/applications/dense_match_filling/__init__.py +30 -0
  20. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
  21. cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
  22. cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
  23. cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
  24. cars/applications/dense_match_filling/zero_padding_app.py +302 -0
  25. cars/applications/dense_matching/__init__.py +30 -0
  26. cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
  27. cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
  31. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  32. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  33. cars/applications/dense_matching/cpp/meson.build +9 -0
  34. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  35. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  36. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  37. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  38. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  39. cars/applications/dense_matching/disparity_grid_algo.py +597 -0
  40. cars/applications/dense_matching/loaders/__init__.py +23 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  46. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  47. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  48. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  49. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  50. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  51. cars/applications/dsm_filling/__init__.py +32 -0
  52. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  53. cars/applications/dsm_filling/border_interpolation_app.py +278 -0
  54. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  55. cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
  56. cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
  57. cars/applications/dsm_merging/__init__.py +28 -0
  58. cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
  59. cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
  60. cars/applications/grid_correction/__init__.py +30 -0
  61. cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
  62. cars/applications/grid_correction/grid_correction_app.py +557 -0
  63. cars/applications/grid_generation/__init__.py +30 -0
  64. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  65. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  66. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  67. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  68. cars/applications/grid_generation/transform_grid.py +88 -0
  69. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  70. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  71. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  72. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  73. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  74. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  75. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  76. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  77. cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
  78. cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
  79. cars/applications/rasterization/__init__.py +30 -0
  80. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  81. cars/applications/rasterization/rasterization_algo.py +534 -0
  82. cars/applications/rasterization/rasterization_constants.py +38 -0
  83. cars/applications/rasterization/rasterization_wrappers.py +639 -0
  84. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  85. cars/applications/resampling/__init__.py +28 -0
  86. cars/applications/resampling/abstract_resampling_app.py +187 -0
  87. cars/applications/resampling/bicubic_resampling_app.py +760 -0
  88. cars/applications/resampling/resampling_algo.py +590 -0
  89. cars/applications/resampling/resampling_constants.py +36 -0
  90. cars/applications/resampling/resampling_wrappers.py +309 -0
  91. cars/applications/sensors_subsampling/__init__.py +32 -0
  92. cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
  93. cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
  94. cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
  95. cars/applications/sparse_matching/__init__.py +30 -0
  96. cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
  97. cars/applications/sparse_matching/sift_app.py +724 -0
  98. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  99. cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
  100. cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
  101. cars/applications/triangulation/__init__.py +32 -0
  102. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  103. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  104. cars/applications/triangulation/pc_transform.py +552 -0
  105. cars/applications/triangulation/triangulation_algo.py +371 -0
  106. cars/applications/triangulation/triangulation_constants.py +38 -0
  107. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  108. cars/bundleadjustment.py +750 -0
  109. cars/cars.py +179 -0
  110. cars/conf/__init__.py +23 -0
  111. cars/conf/geoid/egm96.grd +0 -0
  112. cars/conf/geoid/egm96.grd.hdr +15 -0
  113. cars/conf/input_parameters.py +156 -0
  114. cars/conf/mask_cst.py +35 -0
  115. cars/core/__init__.py +23 -0
  116. cars/core/cars_logging.py +402 -0
  117. cars/core/constants.py +191 -0
  118. cars/core/constants_disparity.py +50 -0
  119. cars/core/datasets.py +140 -0
  120. cars/core/geometry/__init__.py +27 -0
  121. cars/core/geometry/abstract_geometry.py +1119 -0
  122. cars/core/geometry/shareloc_geometry.py +598 -0
  123. cars/core/inputs.py +568 -0
  124. cars/core/outputs.py +176 -0
  125. cars/core/preprocessing.py +722 -0
  126. cars/core/projection.py +843 -0
  127. cars/core/roi_tools.py +215 -0
  128. cars/core/tiling.py +774 -0
  129. cars/core/utils.py +164 -0
  130. cars/data_structures/__init__.py +23 -0
  131. cars/data_structures/cars_dataset.py +1544 -0
  132. cars/data_structures/cars_dict.py +74 -0
  133. cars/data_structures/corresponding_tiles_tools.py +186 -0
  134. cars/data_structures/dataframe_converter.py +185 -0
  135. cars/data_structures/format_transformation.py +297 -0
  136. cars/devibrate.py +689 -0
  137. cars/extractroi.py +264 -0
  138. cars/orchestrator/__init__.py +23 -0
  139. cars/orchestrator/achievement_tracker.py +125 -0
  140. cars/orchestrator/cluster/__init__.py +37 -0
  141. cars/orchestrator/cluster/abstract_cluster.py +250 -0
  142. cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
  143. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  144. cars/orchestrator/cluster/dask_config/README.md +94 -0
  145. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  146. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  147. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  148. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  149. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  150. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  151. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  152. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  153. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  154. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  155. cars/orchestrator/cluster/log_wrapper.py +728 -0
  156. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  157. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  158. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  159. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  160. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  161. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
  162. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  163. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  164. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  165. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  166. cars/orchestrator/memory_tools.py +47 -0
  167. cars/orchestrator/orchestrator.py +755 -0
  168. cars/orchestrator/orchestrator_constants.py +29 -0
  169. cars/orchestrator/registry/__init__.py +23 -0
  170. cars/orchestrator/registry/abstract_registry.py +143 -0
  171. cars/orchestrator/registry/compute_registry.py +106 -0
  172. cars/orchestrator/registry/id_generator.py +116 -0
  173. cars/orchestrator/registry/replacer_registry.py +213 -0
  174. cars/orchestrator/registry/saver_registry.py +363 -0
  175. cars/orchestrator/registry/unseen_registry.py +118 -0
  176. cars/orchestrator/tiles_profiler.py +279 -0
  177. cars/pipelines/__init__.py +26 -0
  178. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  179. cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
  180. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  181. cars/pipelines/default/__init__.py +26 -0
  182. cars/pipelines/default/default_pipeline.py +1088 -0
  183. cars/pipelines/filling/__init__.py +26 -0
  184. cars/pipelines/filling/filling.py +981 -0
  185. cars/pipelines/formatting/__init__.py +26 -0
  186. cars/pipelines/formatting/formatting.py +186 -0
  187. cars/pipelines/merging/__init__.py +26 -0
  188. cars/pipelines/merging/merging.py +439 -0
  189. cars/pipelines/parameters/__init__.py +0 -0
  190. cars/pipelines/parameters/advanced_parameters.py +256 -0
  191. cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
  192. cars/pipelines/parameters/application_parameters.py +72 -0
  193. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  194. cars/pipelines/parameters/dsm_inputs.py +349 -0
  195. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  196. cars/pipelines/parameters/output_constants.py +52 -0
  197. cars/pipelines/parameters/output_parameters.py +438 -0
  198. cars/pipelines/parameters/sensor_inputs.py +859 -0
  199. cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
  200. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  201. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  202. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  203. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  204. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  205. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  206. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  207. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  208. cars/pipelines/pipeline.py +119 -0
  209. cars/pipelines/pipeline_constants.py +38 -0
  210. cars/pipelines/pipeline_template.py +135 -0
  211. cars/pipelines/subsampling/__init__.py +26 -0
  212. cars/pipelines/subsampling/subsampling.py +358 -0
  213. cars/pipelines/surface_modeling/__init__.py +26 -0
  214. cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
  215. cars/pipelines/tie_points/__init__.py +26 -0
  216. cars/pipelines/tie_points/tie_points.py +536 -0
  217. cars/starter.py +167 -0
  218. cars-1.0.0rc2.dist-info/DELVEWHEEL +2 -0
  219. cars-1.0.0rc2.dist-info/METADATA +289 -0
  220. cars-1.0.0rc2.dist-info/RECORD +225 -0
  221. cars-1.0.0rc2.dist-info/WHEEL +4 -0
  222. cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
  223. cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
  224. cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
  225. cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
@@ -0,0 +1,535 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf8
3
+ #
4
+ # Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
5
+ #
6
+ # This file is part of CARS
7
+ # (see https://github.com/CNES/cars).
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ #
21
+ """
22
+ Contains class objects used by multiprocessing cluster
23
+ """
24
+
25
+ import threading
26
+ import time
27
+
28
+ from cars.orchestrator.cluster.mp_cluster.mp_tools import replace_data_rec
29
+ from cars.orchestrator.cluster.mp_cluster.mp_wrapper import load_args_or_kwargs
30
+
31
+
32
+ class MpJob: # pylint: disable=R0903
33
+ """
34
+ Encapsulation of multiprocessing job Id (internal use for mp_local_cluster)
35
+ """
36
+
37
+ __slots__ = ["task_id", "r_idx"]
38
+
39
+ def __init__(self, idx, return_index):
40
+ self.__class__.__name__ = "MpJob"
41
+ self.task_id = idx
42
+ self.r_idx = return_index
43
+
44
+
45
+ class MpDelayedTask: # pylint: disable=R0903
46
+ """
47
+ Delayed task
48
+ """
49
+
50
+ def __init__(self, func, args, kw_args):
51
+ """
52
+ Init function of MpDelayedTask
53
+
54
+ :param func: function to run
55
+ :param args: args of function
56
+ :param kw_args: kwargs of function
57
+
58
+ """
59
+ self.__class__.__name__ = "MpDelayedTask"
60
+ self.func = func
61
+ self.args = args
62
+ self.kw_args = kw_args
63
+ self.associated_objects = []
64
+
65
+ def __repr__(self):
66
+ """
67
+ Repr function
68
+ :return: printable self CarsDataset
69
+ """
70
+ return self.custom_print()
71
+
72
+ def __str__(self):
73
+ """
74
+ Str function
75
+ :return: printable self CarsDataset
76
+ """
77
+ return self.custom_print()
78
+
79
+ def custom_print(self):
80
+ """
81
+ Return string of self
82
+ :return : printable delayed
83
+ """
84
+
85
+ res = (
86
+ "MpDelayedTask: \n "
87
+ + str(self.func)
88
+ + "\n"
89
+ + "args : "
90
+ + str(self.args)
91
+ + "\n kw_args: \n"
92
+ + str(self.kw_args)
93
+ )
94
+
95
+ return res
96
+
97
+ def modify_delayed_task(self, wrapper):
98
+ """
99
+ Modify delayed to add wrapper (disk, None)
100
+
101
+ :param wrapper: wrapper function
102
+ :type wrapper: fun
103
+ """
104
+ used_func, used_kwargs = wrapper.get_function_and_kwargs(
105
+ self.func, self.kw_args, nout=len(self.associated_objects)
106
+ )
107
+
108
+ self.kw_args = used_kwargs
109
+ self.func = used_func
110
+
111
+
112
+ class MpDelayed: # pylint: disable=R0903
113
+ """
114
+ multiprocessing version of dask.delayed
115
+ """
116
+
117
+ def __init__(self, delayed_task, return_index=0):
118
+ self.__class__.__name__ = "MpDelayed"
119
+ self.delayed_task = delayed_task
120
+ self.return_index = return_index
121
+
122
+ # register to delayed_task
123
+ self.delayed_task.associated_objects.append(self)
124
+
125
+ def __repr__(self):
126
+ """
127
+ Repr function
128
+ :return: printable self CarsDataset
129
+ """
130
+ return self.custom_print()
131
+
132
+ def __str__(self):
133
+ """
134
+ Str function
135
+ :return: printable self CarsDataset
136
+ """
137
+ return self.custom_print()
138
+
139
+ def custom_print(self):
140
+ """
141
+ Return string of self
142
+ :return : printable delayed
143
+ """
144
+ if "log_fun" in self.delayed_task.kw_args:
145
+ name = str(self.delayed_task.kw_args["log_fun"])
146
+ elif isinstance(self.delayed_task.args[0], FactorizedObject):
147
+ # Task is factorized
148
+ name = str(self.delayed_task.args[0])
149
+ else:
150
+ name = str(self.delayed_task.func)
151
+
152
+ res = (
153
+ ("MpDELAYED : " + name) + " return index: " + str(self.return_index)
154
+ )
155
+
156
+ return res
157
+
158
+ def get_depending_delayed(self):
159
+ """
160
+ Get all the delayed that current delayed depends on
161
+
162
+ :return list of depending delayed
163
+ :rtype: list(MpDelayed)
164
+ """
165
+
166
+ def get_depending_delayed_rec(list_or_dict):
167
+ """
168
+ Get all the delayed that current delayed depends on
169
+
170
+ :return list of depending delayed
171
+ :rtype: list(MpDelayed)
172
+ """
173
+
174
+ depending_delayed = []
175
+
176
+ if isinstance(list_or_dict, (list, tuple)):
177
+ for arg in list_or_dict:
178
+ depending_delayed += get_depending_delayed_rec(arg)
179
+
180
+ elif isinstance(list_or_dict, dict):
181
+ for key in list_or_dict:
182
+ depending_delayed += get_depending_delayed_rec(
183
+ list_or_dict[key]
184
+ )
185
+
186
+ elif isinstance(list_or_dict, FactorizedObject):
187
+ depending_delayed += get_depending_delayed_rec(
188
+ list_or_dict.get_args()
189
+ )
190
+ depending_delayed += get_depending_delayed_rec(
191
+ list_or_dict.get_kwargs()
192
+ )
193
+
194
+ elif isinstance(list_or_dict, MpDelayed):
195
+ depending_delayed.append(list_or_dict)
196
+
197
+ return depending_delayed
198
+
199
+ depending_delayed_in_args = get_depending_delayed_rec(
200
+ self.delayed_task.args
201
+ )
202
+ depending_delayed_in_kwargs = get_depending_delayed_rec(
203
+ self.delayed_task.kw_args
204
+ )
205
+
206
+ return depending_delayed_in_args + depending_delayed_in_kwargs
207
+
208
+
209
+ class MpFuture:
210
+ """
211
+ Multiprocessing version of distributed.future
212
+ """
213
+
214
+ def __init__(self, mp_future_task, return_index):
215
+ """
216
+ Init function of SequentialCluster
217
+
218
+ :param mp_future_task: Future task
219
+ :param return_index: index of return object
220
+
221
+ """
222
+ self.__class__.__name__ = "MpFuture"
223
+
224
+ self.mp_future_task = mp_future_task
225
+ # register itself to future_task
226
+ self.mp_future_task.associated_futures.append(self)
227
+
228
+ self.result = None
229
+ self._success = None
230
+ self.return_index = return_index
231
+ self.event = threading.Event()
232
+
233
+ def cleanup(self):
234
+ """
235
+ Cleanup future
236
+ """
237
+ self.event.clear()
238
+
239
+ def ready(self):
240
+ """
241
+ Check if future is ready
242
+
243
+ """
244
+ return self.event.is_set()
245
+
246
+ def successful(self):
247
+ """
248
+ Check if future is successful
249
+
250
+ """
251
+ if not self.ready():
252
+ raise ValueError("mp_future not ready!")
253
+ return self._success
254
+
255
+ def set(self, success, obj):
256
+ """
257
+ Set results to future
258
+
259
+ :param success: success of future
260
+ :type success: bool
261
+ :param obj: result
262
+
263
+ """
264
+ self._success = success
265
+ if self._success:
266
+ if not isinstance(obj, tuple):
267
+ if self.return_index > 0:
268
+ raise ValueError("Asked for index > 0 in a singleton")
269
+ self.result = obj
270
+ else:
271
+ self.result = obj[self.return_index]
272
+ else:
273
+ self.result = obj
274
+ self.event.set()
275
+
276
+ def wait(self, timeout=None):
277
+ """
278
+ Wait
279
+
280
+ :param timeout: timeout to apply
281
+
282
+ """
283
+ self.event.wait(timeout)
284
+
285
+ def get(self, timeout=None):
286
+ """
287
+ Get result
288
+
289
+ :param timeout: timeout to apply
290
+
291
+ """
292
+ self.wait(timeout)
293
+ if not self.ready():
294
+ raise TimeoutError
295
+ if not self._success:
296
+ raise self.result
297
+ return self.result
298
+
299
+
300
+ class MpFutureIterator:
301
+ """
302
+ iterator on multiprocessing.pool.AsyncResult, similar to as_completed
303
+ Only returns the actual results, delete the future after usage
304
+ """
305
+
306
+ def __init__(self, future_list, cluster, timeout=None):
307
+ """
308
+ Init function of MpFutureIterator
309
+
310
+ :param future_list: list of futures
311
+
312
+ """
313
+ self.future_list = future_list
314
+ self.cluster = cluster
315
+ self.was_killed = False
316
+ self.timeout = timeout
317
+ self.past_time = time.time()
318
+
319
+ # update future list for cleaning
320
+ for future in future_list:
321
+ self.cluster.cl_future_list.append(future)
322
+
323
+ def __iter__(self):
324
+ """
325
+ Iterate
326
+
327
+ """
328
+ return self
329
+
330
+ def __next__(self):
331
+ """
332
+ Next
333
+
334
+ """
335
+ if not self.future_list:
336
+ raise StopIteration
337
+ res = None
338
+ while res is None:
339
+ if self.timeout is not None:
340
+ if time.time() - self.past_time > self.timeout:
341
+ raise TimeoutError("No task completed before timeout")
342
+ for item in self.future_list:
343
+ if item.ready():
344
+ if not item.successful():
345
+ raise RuntimeError("Failure in tasks")
346
+ res = item
347
+ self.past_time = time.time()
348
+ break
349
+
350
+ self.future_list.remove(res)
351
+ # transform result (depending on the wrapper)
352
+ transformed_res = self.cluster.wrapper.get_obj(res.get())
353
+
354
+ # update future list for cleaning
355
+ self.cluster.cl_future_list.remove(res)
356
+
357
+ return transformed_res
358
+
359
+
360
+ class PreviousData: # pylint: disable=R0903
361
+ """
362
+ Object used in FactorisedObject for args already computed
363
+ in factorized function
364
+
365
+ """
366
+
367
+ def __init__(self, delayed):
368
+ """
369
+ Init function of PreviousData
370
+
371
+ :param return_index: position of data in output of task
372
+ """
373
+ self.return_index = delayed.return_index
374
+
375
+
376
+ def transform_mp_delayed_to_previous_data(obj):
377
+ """
378
+ Replace MpDelayed by PreviousData object
379
+
380
+ :param data: data to replace if necessary
381
+
382
+ """
383
+
384
+ new_data = obj
385
+ if isinstance(obj, MpDelayed):
386
+ new_data = PreviousData(obj)
387
+ return new_data
388
+
389
+
390
+ def transform_previous_data_to_results(obj, res):
391
+ """
392
+ Replace PreviousData object by real data
393
+
394
+ :param data: data to replace if necessary
395
+
396
+ """
397
+
398
+ new_data = obj
399
+ if isinstance(obj, PreviousData):
400
+ pos = obj.return_index
401
+ if isinstance(res, tuple):
402
+ new_data = res[pos]
403
+ else:
404
+ if pos != 0:
405
+ raise RuntimeError(
406
+ "Waiting multiple output but res is not tuple"
407
+ )
408
+ new_data = res
409
+ return new_data
410
+
411
+
412
+ class FactorizedObject:
413
+ """
414
+ Object used as args of function factorised_func
415
+ It contains several tasks that can be run within a single function
416
+ """
417
+
418
+ def __init__(self, current_task, previous_task):
419
+ """
420
+ Init function of FactorizedObject
421
+
422
+ :param current_task: last task to execute in factorized_func
423
+ (arg of task can be a factorized object)
424
+ :param previous_task: task to add and run before current task
425
+ (arg of task can NOT be a factorized object)
426
+ """
427
+ current_task_is_factorized = False
428
+ current_factorized_object = None
429
+
430
+ current_fun = current_task.func
431
+ current_args = current_task.args
432
+ current_kwargs = current_task.kw_args
433
+
434
+ if isinstance(current_args[0], FactorizedObject):
435
+ current_task_is_factorized = True
436
+ current_factorized_object = current_args[0]
437
+ current_args = current_factorized_object.get_args()
438
+ current_kwargs = current_factorized_object.get_kwargs()
439
+
440
+ # Replace MpDelayed with PreviousData that will be computed
441
+ # in run method of FactorizedObject before the call of current_task
442
+ new_args = replace_data_rec(
443
+ current_args, transform_mp_delayed_to_previous_data
444
+ )
445
+ new_kwargs = replace_data_rec(
446
+ current_kwargs, transform_mp_delayed_to_previous_data
447
+ )
448
+
449
+ if current_task_is_factorized:
450
+ # List of tasks is initialized with all tasks in current
451
+ # factorized task
452
+ current_factorized_object.set_args(new_args)
453
+ current_factorized_object.set_kwargs(new_kwargs)
454
+ self.tasks = current_factorized_object.tasks
455
+ else:
456
+ # List of tasks is initialized with current task
457
+ self.tasks = [
458
+ {
459
+ "func": current_fun,
460
+ "args": new_args,
461
+ "kwargs": new_kwargs,
462
+ }
463
+ ]
464
+
465
+ # Add at the end of the list the first task to be executed
466
+ # (self.tasks is a LIFO queue)
467
+ previous_fun = previous_task.func
468
+ previous_args = previous_task.args
469
+ previous_kwargs = previous_task.kw_args
470
+
471
+ self.tasks.append(
472
+ {
473
+ "func": previous_fun,
474
+ "args": previous_args,
475
+ "kwargs": previous_kwargs,
476
+ }
477
+ )
478
+
479
+ def __str__(self):
480
+ res = "Factorized Object : "
481
+ for task in reversed(self.tasks):
482
+ res += str(task["kwargs"]["log_fun"]) + ", "
483
+ return res
484
+
485
+ def get_args(self):
486
+ """
487
+ Get args of first task to execute
488
+ """
489
+ return self.tasks[-1]["args"]
490
+
491
+ def set_args(self, args):
492
+ """
493
+ Set args of first task to execute
494
+
495
+ :param args: arguments to set
496
+ """
497
+ self.tasks[-1]["args"] = args
498
+
499
+ def get_kwargs(self):
500
+ """
501
+ Get kwargs of first task to execute
502
+ """
503
+ return self.tasks[-1]["kwargs"]
504
+
505
+ def set_kwargs(self, kwargs):
506
+ """
507
+ Set kwargs of first task to execute
508
+
509
+ :param args: keyword arguments to set
510
+ """
511
+ self.tasks[-1]["kwargs"] = kwargs
512
+
513
+ def pop_next_task(self, previous_result=None):
514
+ """
515
+ Run the next task to execute, remove it from the list and
516
+ return the result
517
+
518
+ :param previous_result: output of previous task
519
+ """
520
+ task = self.tasks.pop()
521
+ func = task["func"]
522
+ args = task["args"]
523
+ kwargs = task["kwargs"]
524
+ if previous_result is not None:
525
+ # Replace PreviousData objects with output of previous task
526
+ args = replace_data_rec(
527
+ args, transform_previous_data_to_results, previous_result
528
+ )
529
+ kwargs = replace_data_rec(
530
+ kwargs, transform_previous_data_to_results, previous_result
531
+ )
532
+ # Load remaining args : shared data
533
+ args = load_args_or_kwargs(args)
534
+ kwargs = load_args_or_kwargs(kwargs)
535
+ return func(*args, **kwargs)
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf8
3
+ #
4
+ # Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
5
+ #
6
+ # This file is part of CARS
7
+ # (see https://github.com/CNES/cars).
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ #
21
+ """
22
+ Contains tools for multiprocessing
23
+ """
24
+
25
+
26
+ def replace_data(list_or_dict, func_to_apply, *func_args):
27
+ """
28
+ Replace MpJob in list or dict by their real data
29
+ (can deal with FactorizedObject)
30
+
31
+ :param list_or_dict: list or dict of data or mp_objects.FactorizedObject
32
+ :param func_to_apply: function to apply
33
+ :param func_args: function arguments
34
+
35
+ :return: list or dict with real data
36
+ :rtype: list, tuple, dict, mp_objects.FactorizedObject
37
+ """
38
+ if (
39
+ isinstance(list_or_dict, (list, tuple))
40
+ and len(list_or_dict) == 1
41
+ and type(list_or_dict[0]).__name__ == "FactorizedObject"
42
+ ):
43
+ # list_or_dict is a single FactorizedObject
44
+ factorized_object = list_or_dict[0]
45
+ args = factorized_object.get_args()
46
+ args = replace_data_rec(args, func_to_apply, *func_args)
47
+ kwargs = factorized_object.get_kwargs()
48
+ kwargs = replace_data_rec(kwargs, func_to_apply, *func_args)
49
+
50
+ factorized_object.set_args(args)
51
+ factorized_object.set_kwargs(kwargs)
52
+ return [factorized_object]
53
+
54
+ return replace_data_rec(list_or_dict, func_to_apply, *func_args)
55
+
56
+
57
+ def replace_data_rec(list_or_dict, func_to_apply, *func_args):
58
+ """
59
+ Replace MpJob in list or dict by their real data recursively
60
+
61
+ :param list_or_dict: list or dict of data
62
+ :param func_to_apply: function to apply
63
+ :param func_args: function arguments
64
+
65
+ :return: list or dict with real data
66
+ :rtype: list, tuple, dict
67
+ """
68
+
69
+ if isinstance(list_or_dict, (list, tuple)):
70
+ res = []
71
+ for arg in list_or_dict:
72
+ if isinstance(arg, (list, tuple, dict)):
73
+ res.append(replace_data_rec(arg, func_to_apply, *func_args))
74
+ else:
75
+ res.append(func_to_apply(arg, *func_args))
76
+ if isinstance(list_or_dict, tuple):
77
+ res = tuple(res)
78
+
79
+ elif isinstance(list_or_dict, dict):
80
+ res = {}
81
+ for key, value in list_or_dict.items():
82
+ if isinstance(value, (list, dict, tuple)):
83
+ res[key] = replace_data_rec(value, func_to_apply, *func_args)
84
+ else:
85
+ res[key] = func_to_apply(value, *func_args)
86
+
87
+ else:
88
+ raise TypeError(
89
+ "Function only support list or dict or tuple, "
90
+ "but type is {}".format(list_or_dict)
91
+ )
92
+
93
+ return res