def test_repeatable(): """Check that executions of walk with identical parameters yield the same results.""" for path in ('.', None): git_data_1 = reproducible.Context(cpuinfo=False).data #time.sleep(0.01) git_data_2 = reproducible.Context(cpuinfo=False).data timestamp_1 = git_data_1.pop('timestamp') timestamp_2 = git_data_2.pop('timestamp') #_scrub_cpu_info(git_data_1) #_scrub_cpu_info(git_data_2) assert timestamp_1 != timestamp_2 assert git_data_1 == git_data_2
import random import pickle import reproducible def walk(n): """A simple random walk generator""" steps = [0] for i in range(n): steps.append(steps[-1] + random.choice([-1, 1])) return steps if __name__ == '__main__': # create a reproducible.Context instance, that will hold all the # tracked data. context = reproducible.Context() # recording git repository state # here we are okay with running our code with uncommitted changes, but # we record a diff of the changes in the tracked data. context.add_repo(path='.', allow_dirty=True, diff=True) # recording parameters; this is not necessarily needed, as the code state # is recorded, but it is convenient. seed = 1 random.seed(seed) context.add_data('seed', seed) # add_data return the provided value (here 10), so you can do this: n = reproducible.add_data('n', 10) results = walk(n)
def test_msgpack(): context = reproducible.Context(cpuinfo=True) save_msgpack_xz(context.data, os.path.join(here, 'data.msgpack.xz'))
def run(seed, T, dim, limit, adapt_on, d=None, motor_ratio=None, α=None, τ=0.02, window=None, force_run=False, verbose=True): """ Run the algorithm and save the results. Will opportunistically load a previous run if a matching file is found. :param force_run: will not load saved result, recompute instead. """ if adapt_on: filepath = 'runs/run_{}_adapt_{}_{}_{}_s{}'.format( d, α, τ, window, seed) else: filepath = 'runs/run_{}_fixed_{}_s{}'.format(d, motor_ratio, seed) os.makedirs('runs', exist_ok=True) try: with open(filepath + '.pickle', 'rb') as fd: data = pickle.load(fd) if verbose: print('loaded {}'.format(filepath)) return data except (FileNotFoundError, EOFError): context = reproducible.Context(repo_path='.', allow_dirty=True) try: cmd = ['geos-config', '--version'] geos_version = subprocess.run( cmd, stdout=subprocess.PIPE).stdout.decode('utf-8') except FileNotFoundError: # geos-config not available geos_version = 'could not be retrieved' context.add_data('geos_version', geos_version) params = context.function_args() results = just_run(seed, T, dim, limit, d, adapt_on, motor_ratio=motor_ratio, τ=τ, α=α, window=window) if verbose: print('saving {}'.format(filepath)) data = {'params': params, 'results': results} with open(filepath + '.pickle', 'wb') as fd: pickle.dump(data, fd) context.add_file(filepath + '.pickle', category='output') context.export_yaml(filepath + '.context.yaml') return data
def __init__(self, params, checkpoint=None, resume=True, verbose=True, configpath=None): self.verbose = verbose self.beginning = time.time() self.context = reproducible.Context(repo_path=None) if params['computation']['num_thread'] is not None: torch.set_num_threads(params['computation']['num_thread']) if resume: checkpoint = self.load_checkpoint(params['checkpoints']['filepath'], must_exist=False) # if checkpoint is not None: # # network parametrization *must* be the same # for key in ['classname', 'layers']: # ensure(params['network'][key]).equals(checkpoint['params']['network'][key]) # even when loading from a checkpoint, the new parameters are used. self.params = params log_keys = params.get('logs', ['loss', 'error_CL_train']) if checkpoint is None: # start from scratch self.batch_done = 0 # number of batches that have been computed. self.epoch_done = 0 # number of epoch that have been computed. self.logs = logs.Logs(self, log_keys, []) assert (params['seeds']['torch_seed'] < params['seeds']['python_seed'] < params['seeds']['dataset_seed'] ) torch.random.manual_seed(params['seeds']['torch_seed']) self.configpath = configpath else: self.batch_done = checkpoint['batch_done'] self.epoch_done = checkpoint['epoch_done'] self.logs = logs.Logs(self, log_keys, checkpoint.get('logs', [])) torch.random.set_rng_state(checkpoint['rng_states']['torch']) if verbose: print('Configuration:\n{}'.format(utils.yaml_pprint(self.params))) # device self.device = self.params['computation']['device'] if self.device is None: self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') self.context.add_data('device', str(self.device)) # dataset & network datashape_in, datashape_out = self._create_datasets( self.params['seeds']['dataset_seed'], checkpoint=checkpoint) self._create_network(datashape_in, datashape_out, checkpoint=checkpoint) if verbose: print('Model loaded on {}.'.format(self.network.device)) # task self.task = Task(self.network, w=params['loss']['w'], grad_clip=params['training'].get('grad_clip', 1.0), grad_clip_norm_type=params['training'].get('grad_clip_norm_type', 'inf'), loss_fun=params['loss']['loss_fun'], learning_rate=params['training']['learning_rate'], logs=self.logs) if checkpoint is not None: self.task.optimizer.load_state_dict(checkpoint['optimizer']) self.context.add_repo('.', allow_dirty=True) self.context.add_data('parameters', self.params)