Bastien Sevajol 6 years ago
parent
commit
a6ec348b2b

+ 3 - 0
DATA_100 View File

@@ -0,0 +1,3 @@
1
+# (COMPLEXITY 100) SUBJECTS CORES_1 CORES_2
2
+500 0.24411559104919434 0.9702152252197266
3
+100 0.04988713264465332 0.1922530174255371

+ 3 - 0
DATA_2000 View File

@@ -0,0 +1,3 @@
1
+# (COMPLEXITY 2000) SUBJECTS CORES_1 CORES_2
2
+500 0.9194584846496582 1.1027130842208863
3
+100 0.1884233236312866 0.21506776809692382

+ 5 - 3
perf.py View File

@@ -9,6 +9,7 @@ import os
9 9
 
10 10
 import time
11 11
 from collections import OrderedDict
12
+from random import randint
12 13
 
13 14
 from sandbox.perf.simulation import ComputeSubject
14 15
 from synergine2.config import Config
@@ -18,7 +19,7 @@ from synergine2.simulation import Simulation, Subjects
18 19
 
19 20
 
20 21
 def simulate(complexity, subject_count, cycle_count, cores):
21
-    config = Config(dict(complexity=complexity, use_x_cores=cores))
22
+    config = Config(dict(complexity=complexity, core=dict(use_x_cores=cores)))
22 23
     simulation = Simulation(config)
23 24
 
24 25
     subjects = Subjects(simulation=simulation)
@@ -26,6 +27,7 @@ def simulate(complexity, subject_count, cycle_count, cores):
26 27
         subjects.append(ComputeSubject(
27 28
             config=config,
28 29
             simulation=simulation,
30
+            data=[randint(0, 1000) for i in range(1000)]
29 31
         ))
30 32
 
31 33
     simulation.subjects = subjects
@@ -53,8 +55,8 @@ def main():
53 55
 
54 56
     host_cores = multiprocessing.cpu_count()
55 57
     retry = 3
56
-    cycles = 200
57
-    subject_counts = [1, 10, 100, 1000, 5000]
58
+    cycles = 10
59
+    subject_counts = [100, 500]
58 60
     complexities = [100, 2000]
59 61
     max_cores = args.max_cores or host_cores
60 62
 

+ 10 - 0
sandbox/perf/simulation.py View File

@@ -1,5 +1,6 @@
1 1
 import random
2 2
 
3
+from synergine2.config import Config
3 4
 from synergine2.simulation import SubjectMechanism, SubjectBehaviour, Event, Subject
4 5
 
5 6
 
@@ -53,3 +54,12 @@ class ComputeBehaviour(SubjectBehaviour):
53 54
 
54 55
 class ComputeSubject(Subject):
55 56
     behaviours_classes = [ComputeBehaviour]
57
+
58
+    def __init__(
59
+        self,
60
+        config: Config,
61
+        simulation: 'Simulation',
62
+        data,
63
+    ):
64
+        super().__init__(config, simulation)
65
+        self.data = data

+ 5 - 0
sandbox/tile/config.yaml View File

@@ -0,0 +1,5 @@
1
+core:
2
+    cycle_duration: 0.125
3
+    use_x_cores: 1
4
+terminals:
5
+    sync: True

+ 3 - 4
sandbox/tile/run.py View File

@@ -5,11 +5,10 @@ import sys
5 5
 import logging
6 6
 from random import seed
7 7
 
8
-from sandbox.tile.simulation.subject import Man
9
-
10 8
 synergine2_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
11 9
 sys.path.append(synergine2_path)
12 10
 
11
+from sandbox.tile.simulation.subject import Man
13 12
 from sandbox.tile.simulation.base import TileStrategySimulation
14 13
 from sandbox.tile.simulation.base import TileStrategySubjects
15 14
 from synergine2.log import get_default_logger
@@ -24,8 +23,8 @@ def main(map_dir_path: str, seed_value: int=42):
24 23
     seed(seed_value)
25 24
 
26 25
     config = Config()
27
-    config.load_files(['sandbox/engulf/config.yaml'])  # TODO: heu ... engulf ??
28
-    logger = get_default_logger(level=logging.ERROR)
26
+    config.load_files(['sandbox/tile/config.yaml'])
27
+    logger = get_default_logger(level=logging.DEBUG)
29 28
 
30 29
     map_file_path = 'sandbox/tile/{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))
31 30
 

+ 7 - 1
synergine2/core.py View File

@@ -8,6 +8,7 @@ from synergine2.log import SynergineLogger
8 8
 from synergine2.simulation import Simulation
9 9
 from synergine2.terminals import TerminalManager
10 10
 from synergine2.terminals import TerminalPackage
11
+from synergine2.utils import time_it
11 12
 
12 13
 
13 14
 class Core(BaseObject):
@@ -50,7 +51,12 @@ class Core(BaseObject):
50 51
                         subject_actions=package.subject_actions,
51 52
                     ))
52 53
 
53
-                events.extend(self.cycle_manager.next())
54
+                with time_it() as elapsed_time:
55
+                    events.extend(self.cycle_manager.next())
56
+                # TODO: There is a problem with logger: when "pickled" we remove it's handler
57
+                self.logger.info('Cycle duration: {}s'.format(elapsed_time.get_final_time()))
58
+                print('Cycle duration: {}s'.format(elapsed_time.get_final_time()))
59
+
54 60
                 cycle_package = TerminalPackage(
55 61
                     events=events,
56 62
                     add_subjects=self.simulation.subjects.adds,

+ 18 - 8
synergine2/cycle.py View File

@@ -11,7 +11,7 @@ from synergine2.simulation import Simulation
11 11
 from synergine2.simulation import SubjectBehaviour
12 12
 from synergine2.simulation import SubjectMechanism
13 13
 from synergine2.simulation import Event
14
-from synergine2.utils import ChunkManager
14
+from synergine2.utils import ChunkManager, time_it
15 15
 
16 16
 
17 17
 class CycleManager(BaseObject):
@@ -24,7 +24,8 @@ class CycleManager(BaseObject):
24 24
     ):
25 25
         if process_manager is None:
26 26
             process_manager = ProcessManager(
27
-                process_count=config.get('use_x_cores', multiprocessing.cpu_count()),
27
+                # TODO: Changer de config de merde (core.use_x_cores)
28
+                process_count=config.get('core', {}).get('use_x_cores', multiprocessing.cpu_count()),
28 29
                 chunk_manager=ChunkManager(multiprocessing.cpu_count()),
29 30
             )
30 31
 
@@ -47,8 +48,13 @@ class CycleManager(BaseObject):
47 48
         events = []
48 49
         # TODO: gestion des behaviours non parallelisables
49 50
         # TODO: Proposer des ordres d'execution
50
-        events.extend(self._get_subjects_events())
51
-        events.extend(self._get_simulation_events())
51
+        with time_it() as elapsed_time:
52
+            events.extend(self._get_subjects_events())
53
+        print('Cycle subjects events duration: {}s'.format(elapsed_time.get_final_time()))
54
+
55
+        with time_it() as elapsed_time:
56
+            events.extend(self._get_simulation_events())
57
+        print('Cycle simulation events duration: {}s'.format(elapsed_time.get_final_time()))
52 58
 
53 59
         self.logger.info('Cycle {} generate {} events'.format(
54 60
             str(self.current_cycle),
@@ -221,12 +227,14 @@ class CycleManager(BaseObject):
221 227
             behaviours_data = {}
222 228
 
223 229
             for mechanism in mechanisms:
224
-                mechanism_data = mechanism.run()
230
+                with time_it() as elapsed_time:
231
+                    mechanism_data = mechanism.run()
225 232
                 if self.logger.is_debug:
226
-                    self.logger.info('Subject {}: {} mechanisms produce data: {}'.format(
233
+                    self.logger.debug('Subject {}: {} mechanisms produce data: {} in {}s'.format(
227 234
                         str(subject.id),
228 235
                         type(mechanism).__name__,
229 236
                         str(mechanism_data),
237
+                        elapsed_time.get_final_time(),
230 238
                     ))
231 239
 
232 240
                 mechanisms_data[type(mechanism)] = mechanism_data
@@ -254,13 +262,15 @@ class CycleManager(BaseObject):
254 262
                 ))
255 263
 
256 264
                 # We identify behaviour data with it's class to be able to intersect it after subprocess data collect
257
-                behaviour_data = behaviour.run(mechanisms_data)  # TODO: Behaviours dependencies
265
+                with time_it() as elapsed_time:
266
+                    behaviour_data = behaviour.run(mechanisms_data)  # TODO: Behaviours dependencies
258 267
 
259 268
                 if self.logger.is_debug:
260
-                    self.logger.debug('Subject {}: behaviour {} produce data: {}'.format(
269
+                    self.logger.debug('Subject {}: behaviour {} produce data: {} in {}s'.format(
261 270
                         str(type(behaviour)),
262 271
                         str(subject.id),
263 272
                         str(behaviour_data),
273
+                        elapsed_time.get_final_time(),
264 274
                     ))
265 275
 
266 276
                 if behaviour_data:

+ 2 - 0
synergine2/processing.py View File

@@ -25,8 +25,10 @@ class ProcessManager(BaseObject):
25 25
         chunks = self._chunk_manager.make_chunks(data)
26 26
 
27 27
         if self._process_count > 1:
28
+            print('USE POOL')
28 29
             results = self.pool.starmap(job_maker, [(chunk, i, self._process_count) for i, chunk in enumerate(chunks)])
29 30
         else:
31
+            print('USE MONO')
30 32
             results = [job_maker(data, 0, 1)]
31 33
 
32 34
         return results

+ 27 - 0
synergine2/utils.py View File

@@ -1,3 +1,8 @@
1
+import typing
2
+from contextlib import contextmanager
3
+
4
+import time
5
+
1 6
 from synergine2.base import BaseObject
2 7
 
3 8
 
@@ -21,3 +26,25 @@ def get_mechanisms_classes(mechanized) -> ['Mechanisms']:
21 26
     for behaviour_class in mechanized.behaviours_classes:
22 27
         mechanisms_classes.extend(behaviour_class.use)
23 28
     return list(set(mechanisms_classes))  # Remove duplicates
29
+
30
+
31
+class ElapsedTime(object):
32
+    def __init__(self, start_time: float) -> None:
33
+        self.start_time = start_time
34
+        self.end_time = None
35
+
36
+    def get_final_time(self) -> float:
37
+        assert self.end_time
38
+        return self.end_time - self.start_time
39
+
40
+    def get_time(self) -> float:
41
+        return time.time() - self.start_time
42
+
43
+
44
+@contextmanager
45
+def time_it() -> typing.Generator[ElapsedTime, None, None]:
46
+    elapsed_time = ElapsedTime(time.time())
47
+    try:
48
+        yield elapsed_time
49
+    finally:
50
+        elapsed_time.end_time = time.time()

+ 3 - 2
synergine2_xyz/move.py View File

@@ -112,10 +112,11 @@ class MoveEvent(Event):
112 112
         self.to_position = to_position
113 113
 
114 114
     def repr_debug(self) -> str:
115
-        return '{}: subject_id:{}, position:{}'.format(
115
+        return '{}: subject_id:{}, from_position:{} to_position: {}'.format(
116 116
             type(self).__name__,
117 117
             self.subject_id,
118
-            self.position,
118
+            self.from_position,
119
+            self.to_position,
119 120
         )
120 121
 
121 122