1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """The uni-processor fabric for running on a single CPU."""
25
26
27
28 import sys, os
29
30
31 from multi.misc import Result_string
32 from multi.processor import Processor
33 from multi.result_commands import Result_command
34
35
37 """The uni-processor class."""
38
39 - def __init__(self, processor_size, callback):
40 """Initialise the class.
41
42 @param processor_size: The number of processors.
43 @type processor_size: int
44 @param callback: The callback object.
45 @type callback: ?
46 """
47 super(Uni_processor, self).__init__(processor_size=1, callback=callback)
48
49 if processor_size > 1:
50 print('warning: uniprocessor can only support 1 processor you requested %d' % processor_size)
51 print('continuing...\n')
52
53 self.command_queue = []
54 self.memo_map = {}
55
56
62
63
65 """Make sure that this is the master processor and not a slave.
66
67 As this is the Uni-processor, the processor is always the master. Hence this method does nothing.
68 """
69
70
72 """Return the string to append to the end of the relax introduction string.
73
74 @return: The string describing this Processor fabric.
75 @rtype: str
76 """
77
78
79 return "Uni-processor."
80
81
83
84 return '%s-%s' % (os.getenv('HOSTNAME'), os.getpid())
85
86
88 """For the uni-processor fabric, we are always on the master.
89
90 @return: The flag specifying if we are on the master or slave processors.
91 @rtype: bool
92 """
93
94
95 return True
96
97
99 """Slave to master processor data transfer - send the result command from the slave.
100
101 This mimics a slave to master data transfer initiated by a slave by holding the result command so that the matching self.master_receive_result(), which is called by the master processor, can return it. As the master and slave processors are one and the same, the command is just held as a private class variable.
102
103
104 @param command: The results command to send to the master.
105 @type command: Results_command instance
106 @param dest: The destination processor's rank.
107 @type dest: int
108 """
109
110
111 self._result_command_queue = command
112
113
115 """Slave to master processor data transfer - receive the result command from the slave.
116
117 This mimics a slave to master data transfer initiated by a slave by holding the result command so that the matching self.master_receive_result(), which is called by the master processor, can return it. As the master and slave processors are one and the same, the command is just held as a private class variable.
118
119
120 @return: The result command sent by the slave.
121 @rtype: Result_command instance
122 """
123
124
125 command = self._result_command_queue
126 del self._result_command_queue
127
128
129 return command
130
131
132 - def post_run(self):
133 """Dummy function for preventing the printing of the run time."""
134
135
137 """Return 1 as this is the uni-processor.
138
139 @return: The number of processors.
140 @rtype: int
141 """
142
143 return 1
144
145
147 """The uni-processor is always of rank 0.
148
149 @return: The processor rank.
150 @rtype: int
151 """
152
153 return 0
154
155
157
158 if isinstance(result, Exception):
159
160
161 raise result
162 elif isinstance(result, Result_command):
163 memo = None
164 if result.memo_id != None:
165 memo = self.memo_map[result.memo_id]
166 result.run(self, memo)
167 if result.memo_id != None and result.completed:
168 del self.memo_map[result.memo_id]
169
170 elif isinstance(result, Result_string):
171 sys.stdout.write(result.string)
172 else:
173 message = 'Unexpected result type \n%s \nvalue%s' %(result.__class__.__name__, result)
174 raise Exception(message)
175
176
178 """Safely run each command in the queue, cleaning up after failures."""
179
180
181 try:
182 last_command = len(self.command_queue)-1
183 for i, command in enumerate(self.command_queue):
184 completed = (i == last_command)
185
186 command.run(self, completed)
187
188
189 finally:
190
191 del self.command_queue[:]
192 self.memo_map.clear()
193