Package multi :: Module uni_processor
[hide private]
[frames] | no frames]

Source Code for Module multi.uni_processor

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2007 Gary S Thompson                                          # 
  4  # Copyright (C) 2008,2010,2012,2014 Edward d'Auvergne                         # 
  5  #                                                                             # 
  6  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  7  #                                                                             # 
  8  # This program is free software: you can redistribute it and/or modify        # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation, either version 3 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # This program is distributed in the hope that it will be useful,             # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """The uni-processor fabric for running on a single CPU.""" 
 25   
 26   
 27  # Python module imports. 
 28  import sys, os 
 29   
 30  # multi module imports. 
 31  from multi.misc import Result_string 
 32  from multi.processor import Processor 
 33  from multi.result_commands import Result_command 
 34   
 35   
36 -class Uni_processor(Processor):
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
57 - def add_to_queue(self, command, memo=None):
58 self.command_queue.append(command) 59 if memo != None: 60 command.set_memo_id(memo) 61 self.memo_map[memo.memo_id()] = memo
62 63
64 - def assert_on_master(self):
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
71 - def get_intro_string(self):
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 # Return the string. 79 return "Uni-processor."
80 81
82 - def get_name(self):
83 # FIXME may need system dependent changes 84 return '%s-%s' % (os.getenv('HOSTNAME'), os.getpid())
85 86
87 - def on_master(self):
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 # Always master. 95 return True
96 97
98 - def master_queue_command(self, command, dest):
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 # Hold the result command so that the matching self.master_receive_result() can return it. 111 self._result_command_queue = command
112 113
114 - def master_receive_result(self):
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 # Remove the command from the class namespace. 125 command = self._result_command_queue 126 del self._result_command_queue 127 128 # Return the command 129 return command
130 131
132 - def post_run(self):
133 """Dummy function for preventing the printing of the run time."""
134 135
136 - def processor_size(self):
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
146 - def rank(self):
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
156 - def return_object(self, result):
157 158 if isinstance(result, Exception): 159 #FIXME: clear command queue 160 # and finalise mpi (or restart it if we can! 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
177 - def run_queue(self):
178 """Safely run each command in the queue, cleaning up after failures.""" 179 180 # Run each command in the queue. 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 # Clear the queue, even if a failure occurs. 189 finally: 190 #TODO: add cheques for empty queues and maps if now warn 191 del self.command_queue[:] 192 self.memo_map.clear()
193