-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #198 from Neurosim-lab/development
PR from development to master - VERSION 0.6.8
- Loading branch information
Showing
12 changed files
with
1,175 additions
and
293 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,6 +75,7 @@ Requires NEURON with Python and MPI support. | |
* **netpyne/utils.py**: utility python methods (eg. to import cell parameters) | ||
|
||
|
||
Please cite as: "Salvador Dura-Bernal, Padraig Gleeson, Cliff C Kerr, Samuel Neymotin, William W Lytton. (2017). Neurosim-lab/NetPyNE: v0.6.7 [Data set]. Zenodo. http://doi.org/10.5281/zenodo.290623" | ||
|
||
For further information please contact: [email protected] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
|
||
__version__ = '0.6.7' | ||
__version__ = '0.6.8' | ||
__gui__ = True # global option to enable/disable graphics |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,10 +8,11 @@ | |
|
||
|
||
import datetime | ||
from itertools import product | ||
from itertools import izip, product | ||
from popen2 import popen2 | ||
from time import sleep | ||
import imp | ||
from netpyne import specs | ||
from neuron import h | ||
pc = h.ParallelContext() # use bulletin board master/slave | ||
if pc.id()==0: pc.master_works_on_jobs(0) | ||
|
@@ -30,15 +31,18 @@ def runJob(script, cfgSavePath): | |
|
||
class Batch(object): | ||
|
||
def __init__(self, cfgFile='cfg.py', netParamsFile='netParams.py'): | ||
def __init__(self, cfgFile='cfg.py', netParamsFile='netParams.py', params=None): | ||
self.batchLabel = 'batch_'+str(datetime.date.today()) | ||
self.cfgFile = cfgFile | ||
self.netParamsFile = netParamsFile | ||
self.params = [] | ||
self.saveFolder = '/'+self.batchLabel | ||
self.method = 'grid' | ||
self.runCfg = {} | ||
|
||
self.params = [] | ||
if params: | ||
for k,v in params.iteritems(): | ||
self.params.append({'label': k, 'values': v}) | ||
|
||
def save(self, filename): | ||
import os | ||
basename = os.path.basename(filename) | ||
|
@@ -55,10 +59,13 @@ def save(self, filename): | |
dataSave = {'batch': self.__dict__} | ||
if ext == 'json': | ||
import json | ||
#from json import encoder | ||
#encoder.FLOAT_REPR = lambda o: format(o, '.12g') | ||
print('Saving batch to %s ... ' % (filename)) | ||
with open(filename, 'w') as fileObj: | ||
json.dump(dataSave, fileObj, indent=4, sort_keys=True) | ||
|
||
|
||
def run(self): | ||
if self.method in ['grid','list']: | ||
# create saveFolder | ||
|
@@ -86,88 +93,171 @@ def run(self): | |
cfgModule = imp.load_source(cfgModuleName, self.cfgFile) | ||
self.cfg = cfgModule.cfg | ||
|
||
# iterate over all param combinations | ||
if self.method == 'grid': | ||
# iterate over all param combinations | ||
labelList, valuesList = zip(*[(p['label'], p['values']) for p in self.params]) | ||
valueCombinations = product(*(valuesList)) | ||
indexCombinations = product(*[range(len(x)) for x in valuesList]) | ||
elif self.method == 'list': | ||
pass | ||
groupedParams = False | ||
for p in self.params: | ||
if 'group' not in p: | ||
p['group'] = False # by default set linear to False | ||
elif 'group' == True: | ||
groupedParams = True | ||
|
||
labelList, valuesList = zip(*[(p['label'], p['values']) for p in self.params if p['group'] == False]) | ||
valueCombinations = list(product(*(valuesList))) | ||
indexCombinations = list(product(*[range(len(x)) for x in valuesList])) | ||
|
||
if groupedParams: | ||
labelListGroup, valuesListGroup = zip(*[(p['label'], p['values']) for p in self.params if p['group'] == True]) | ||
valueCombGroups = izip(*(valuesListGroup)) | ||
indexCombGroups = izip(*[range(len(x)) for x in valuesListGroup]) | ||
else: | ||
valueCombGroups = [(0,)] # this is a hack -- improve! | ||
indexCombGroups = [(0,)] | ||
|
||
# if using pc bulletin board, initialize all workers | ||
if self.runCfg.get('type', None) == 'mpi': | ||
for iworker in range(int(pc.nhost())): | ||
pc.runworker() | ||
|
||
for iComb, pComb in zip(indexCombinations, valueCombinations): | ||
for i, paramVal in enumerate(pComb): | ||
paramLabel = labelList[i] | ||
if isinstance(paramLabel, tuple): | ||
container = getattr(self.cfg, paramLabel[0]) | ||
container[paramLabel[1]] = paramVal | ||
|
||
#if 1: | ||
#for iComb, pComb in zip(indexCombinations, valueCombinations): | ||
|
||
for iCombG, pCombG in zip(indexCombGroups, valueCombGroups): | ||
for iCombNG, pCombNG in zip(indexCombinations, valueCombinations): | ||
if groupedParams: # temporary hack - improve | ||
iComb = iCombG+iCombNG | ||
pComb = pCombG+pCombNG | ||
else: | ||
setattr(self.cfg, paramLabel, paramVal) # set simConfig params | ||
print str(paramLabel)+' = '+str(paramVal) | ||
iComb = iCombNG | ||
pComb = pCombNG | ||
|
||
# save simConfig json to saveFolder | ||
simLabel = self.batchLabel+''.join([''.join('_'+str(i)) for i in iComb]) | ||
self.cfg.simLabel = simLabel | ||
self.cfg.saveFolder = self.saveFolder | ||
cfgSavePath = self.saveFolder+'/'+simLabel+'_cfg.json' | ||
self.cfg.save(cfgSavePath) | ||
|
||
|
||
# skip if output file already exists | ||
jobName = self.saveFolder+'/'+simLabel | ||
if self.runCfg.get('skip', False) and glob.glob(jobName+'.json'): | ||
print 'Skipping job %s since output file already exists...' % (jobName) | ||
else: | ||
# hpc torque job submission | ||
if self.runCfg.get('type',None) == 'hpc_torque': | ||
print iComb, pComb | ||
|
||
# read params or set defaults | ||
sleepInterval = self.runCfg.get('sleepInterval', 1) | ||
sleep(sleepInterval) | ||
|
||
numproc = self.runCfg.get('numproc', 1) | ||
script = self.runCfg.get('script', 'init.py') | ||
walltime = self.runCfg.get('walltime', '00:30:00') | ||
queueName = self.runCfg.get('queueName', 'default') | ||
nodesppn = 'nodes=1:ppn=%d'%(numproc) | ||
for i, paramVal in enumerate(pComb): | ||
paramLabel = labelList[i] | ||
if isinstance(paramLabel, tuple): | ||
container = self.cfg | ||
for ip in range(len(paramLabel)-1): | ||
if isinstance(container, specs.SimConfig): | ||
container = getattr(container, paramLabel[ip]) | ||
else: | ||
container = container[paramLabel[ip]] | ||
container[paramLabel[-1]] = paramVal | ||
else: | ||
setattr(self.cfg, paramLabel, paramVal) # set simConfig params | ||
print str(paramLabel)+' = '+str(paramVal) | ||
|
||
command = 'mpiexec -np %d nrniv -python -mpi %s simConfig=%s' % (numproc, script, cfgSavePath) | ||
|
||
output, input = popen2('qsub') # Open a pipe to the qsub command. | ||
|
||
jobString = """#!/bin/bash | ||
#PBS -N %s | ||
#PBS -l walltime=%s | ||
#PBS -q %s | ||
#PBS -l %s | ||
#PBS -o %s.run | ||
#PBS -e %s.err | ||
cd $PBS_O_WORKDIR | ||
echo $PBS_O_WORKDIR | ||
%s""" % (jobName, walltime, queueName, nodesppn, jobName, jobName, command) | ||
|
||
# Send job_string to qsub | ||
input.write(jobString) | ||
print jobString+'\n' | ||
input.close() | ||
|
||
# pc bulletin board job submission (master/slave) via mpi | ||
# eg. usage: mpiexec -n 4 nrniv -mpi batch.py | ||
elif self.runCfg.get('type',None) == 'mpi': | ||
jobName = self.saveFolder+'/'+simLabel | ||
print 'Submitting job ',jobName | ||
# master/slave bulletin board schedulling of jobs | ||
pc.submit(runJob, self.runCfg.get('script', 'init.py'), cfgSavePath) | ||
# set simLabel and jobName | ||
simLabel = self.batchLabel+''.join([''.join('_'+str(i)) for i in iComb]) | ||
jobName = self.saveFolder+'/'+simLabel | ||
|
||
# skip if output file already exists | ||
if self.runCfg.get('skip', False) and glob.glob(jobName+'.json'): | ||
print 'Skipping job %s since output file already exists...' % (jobName) | ||
elif self.runCfg.get('skipCfg', False) and glob.glob(jobName+'_cfg.json'): | ||
print 'Skipping job %s since cfg file already exists...' % (jobName) | ||
else: | ||
# save simConfig json to saveFolder | ||
self.cfg.simLabel = simLabel | ||
self.cfg.saveFolder = self.saveFolder | ||
cfgSavePath = self.saveFolder+'/'+simLabel+'_cfg.json' | ||
self.cfg.save(cfgSavePath) | ||
|
||
# hpc torque job submission | ||
if self.runCfg.get('type',None) == 'hpc_torque': | ||
|
||
# read params or set defaults | ||
sleepInterval = self.runCfg.get('sleepInterval', 1) | ||
sleep(sleepInterval) | ||
|
||
numproc = self.runCfg.get('numproc', 1) | ||
script = self.runCfg.get('script', 'init.py') | ||
walltime = self.runCfg.get('walltime', '00:30:00') | ||
queueName = self.runCfg.get('queueName', 'default') | ||
nodesppn = 'nodes=1:ppn=%d'%(numproc) | ||
|
||
command = 'mpiexec -np %d nrniv -python -mpi %s simConfig=%s' % (numproc, script, cfgSavePath) | ||
|
||
output, input = popen2('qsub') # Open a pipe to the qsub command. | ||
|
||
jobString = """#!/bin/bash | ||
#PBS -N %s | ||
#PBS -l walltime=%s | ||
#PBS -q %s | ||
#PBS -l %s | ||
#PBS -o %s.run | ||
#PBS -e %s.err | ||
cd $PBS_O_WORKDIR | ||
echo $PBS_O_WORKDIR | ||
%s""" % (jobName, walltime, queueName, nodesppn, jobName, jobName, command) | ||
|
||
# Send job_string to qsub | ||
input.write(jobString) | ||
print jobString+'\n' | ||
input.close() | ||
|
||
# hpc torque job submission | ||
elif self.runCfg.get('type',None) == 'hpc_slurm': | ||
|
||
# read params or set defaults | ||
sleepInterval = self.runCfg.get('sleepInterval', 1) | ||
sleep(sleepInterval) | ||
|
||
allocation = self.runCfg.get('allocation', 'csd403') # NSG account | ||
nodes = self.runCfg.get('nodes', 1) | ||
coresPerNode = self.runCfg.get('coresPerNode', 1) | ||
email = self.runCfg.get('email', '[email protected]') | ||
folder = self.runCfg.get('folder', '.') | ||
script = self.runCfg.get('script', 'init.py') | ||
walltime = self.runCfg.get('walltime', '00:30:00') | ||
numproc = nodes*coresPerNode | ||
command = 'ibrun -np %d nrniv -python -mpi %s simConfig=%s' % (numproc, script, cfgSavePath) | ||
|
||
jobString = """#!/bin/bash | ||
#SBATCH --job-name=%s | ||
#SBATCH -A %s | ||
#SBATCH -t %s | ||
#SBATCH --nodes=%d | ||
#SBATCH --ntasks-per-node=%d | ||
#SBATCH -o %s.run | ||
#SBATCH -e %s.err | ||
#SBATCH --mail-user=%s | ||
#SBATCH --mail-type=end | ||
source ~/.bashrc | ||
cd %s | ||
%s | ||
wait | ||
""" % (jobName, allocation, walltime, nodes, coresPerNode, jobName, jobName, email, folder, command) | ||
|
||
# Send job_string to qsub | ||
# output, input = popen2('sbatch') # Open a pipe to the qsub command. | ||
# input.write(jobString) | ||
print 'Submitting job ',jobName | ||
print jobString+'\n' | ||
# input.close() | ||
|
||
batchfile = '%s.sbatch'%(jobName) | ||
with open(batchfile, 'w') as text_file: | ||
text_file.write("%s" % jobString) | ||
|
||
#subprocess.call | ||
output, pinput = popen2('sbatch '+batchfile) # Open a pipe to the qsub command. | ||
pinput.close() | ||
|
||
# pc bulletin board job submission (master/slave) via mpi | ||
# eg. usage: mpiexec -n 4 nrniv -mpi batch.py | ||
elif self.runCfg.get('type',None) == 'mpi': | ||
jobName = self.saveFolder+'/'+simLabel | ||
print 'Submitting job ',jobName | ||
# master/slave bulletin board schedulling of jobs | ||
pc.submit(runJob, self.runCfg.get('script', 'init.py'), cfgSavePath) | ||
|
||
# wait for pc bulletin board jobs to finish | ||
try: | ||
while pc.working(): | ||
sleep(1) | ||
pc.done() | ||
#pc.done() | ||
except: | ||
pass | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.