def getProjects(self): """Get projects REST: GET /projects.xml Returns all accessible projects. This includes active, inactive, and archived projects. """ path = '/projects.xml' rootElement = self.fromXML(self.get(path).contents) # TODO: use special Array attribute projects = [] for data in rootElement.getElementsByTagName('project'): projects.append(Project.load(data)) return projects
def getProjectById(self, project_id): """Get project REST: GET /projects/#{project_id}.xml Returns a single project identified by its integer ID """ # ensure that we got numerical project id assert isinstance(project_id, int) path = '/projects/%d.xml' % project_id response = self.get(path) if response.status == 404: raise NotFoundError, 'Project with %d id is not found!' % project_id rootElement = self.fromXML(response.contents) return Project.load(rootElement)
def save(self, *args, **kwargs): super(Task, self).save(*args, **kwargs) self.project_set = [Project.get(p) for p in self.projects]
def save(self, *args, **kwargs): super(Task, self).save(*args, **kwargs) self.project_set = [ Project.get(p) for p in self.projects ]
def get_jobs(self, project=None, allocation=None, account=None, host=None): """ Check the calculation module specified by the `Task`, and returns a list of :class:`Job` objects accordingly. Calls the task's entry's "do" method with the `Task.module` as the first argument, and passing `Task.kwargs` as keyword arguments. Returns: List of Job objects. When nothing is left to do for the task, returns empty. Raises: ResourceUnavailableError: Raise if for the specified project, allocation, account and/or host there are no available cores. """ if host != None: if not project: projects = self.project_set.filter(allocations__host=host, state=1) project = random.choice(list(projects)) if not allocation: allocations = project.allocations.filter(host=host, state=1) allocation = random.choice(list(allocations)) elif project != None: allocation = project.get_allocation() if not allocation: raise ResourceUnavailableError else: project = self.get_project() if account is None: if project is None: account = allocation.get_account() elif not allocation is None: account = allocation.get_account( users=list(project.users.all())) calc = self.entry.do(self.module, **self.kwargs) # Special case: Adjustments for certain clusters if not allocation is None: if host.name == 'quest': # Special MPI call for quest Slurm calc.instructions['mpi'] = 'mpirun -np $NPROCS' if allocation.name == 'b1004': # Can only run parallel VASP on b1004 allocation calc.instructions['serial'] = False calc.instructions['binary'] = 'vasp_53' calc.instructions[ 'queuetype'] = 'buyin' # queue type for b1004 is 'buyin' elif allocation.name == 'd20829': # Sheel doesn't have access to b1004 binaries calc.instructions['binary'] = '~/vasp_53' calc.instructions['queuetype'] = 'normal' elif allocation.name == 'p30919': calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 4 calc.instructions['walltime'] = 3600 * 4 #calc.instructions['binary'] = 'vasp_53' elif allocation.name == 'p31151': calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 4 calc.instructions['walltime'] = 3600 * 4 elif allocation.name == 'p30475': calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 16 calc.instructions['walltime'] = 3600 * 4 elif allocation.name == 'p30649': calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 16 calc.instructions['walltime'] = 3600 * 4 elif allocation.name == 'p31102': calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 16 calc.instructions['walltime'] = 3600 * 4 elif calc.entry.natoms < 9: calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 4 calc.instructions['walltime'] = 3600 * 4 elif calc.entry.natoms < 13: calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 16 calc.instructions['walltime'] = 3600 * 4 elif Project.get('pyrochlore') in calc.entry.projects: calc.instructions['queuetype'] = 'short' calc.instructions['serial'] = False calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 16 calc.instructions['walltime'] = 3600 * 4 elif calc.entry.natoms > 19: calc.instructions['queuetype'] = 'normal' calc.instructions['nodes'] = 1 calc.instructions['ntasks'] = 16 else: calc.instructions['queuetype'] = 'normal' if allocation.name == 'bebop': # Special MPI call for bebop calc.instructions['mpi'] = 'mpirun -psm2 -np $NPROCS' if allocation.name == 'xsede': # Special MPI call for xsede calc.instructions['mpi'] = 'mpirun -np $NPROCS' if allocation.name == 'babbage': # Check if calculation is parallel if 'serial' in calc.instructions and not calc.instructions[ 'serial']: # Different MPI call on Babbage calc.instructions[ 'mpi'] = 'mpirun -np $NPROCS -machinefile $PBS_NODEFILE -tmpdir /scratch' jobs = [] if calc.instructions: self.state = 1 new_job = Job.create(task=self, allocation=allocation, account=account, entry=self.entry, **calc.instructions) jobs.append(new_job) calc.save() elif calc.converged: self.complete() else: self.state = -1 return jobs