Changeset 3041 for trunk/GSASIImpsubs.py


Ignore:
Timestamp:
Sep 3, 2017 11:18:33 AM (4 years ago)
Author:
toby
Message:

Fully implement multiprocessing on reflection loops, but currently disabled, when enabled default is still not to use unless turned on in config; add timing code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIImpsubs.py

    r3000 r3041  
    4444
    4545def InitMP(allowMP=True):
    46     '''Called in routines to initialize use of Multiprocessing
     46    '''Called to initialize use of Multiprocessing
    4747    '''
    4848    global useMP,ncores
    49     if ncores is not None: return
     49    if ncores is not None: return useMP,ncores
    5050    useMP = False
    5151    if not allowMP:
    5252        print('Multiprocessing disabled')
    5353        ncores = 0
    54         return
    55     ncores = GSASIIpath.GetConfigValue('Multiprocessing_cores',-1)
    56     if ncores < 0: ncores = mp.cpu_count()
     54        return useMP,ncores
     55    ncores = GSASIIpath.GetConfigValue('Multiprocessing_cores',0)
     56    if ncores < 0: ncores = mp.cpu_count()/2
    5757    if ncores > 1:
    5858        useMP = True
    59     #if GSASIIpath.GetConfigValue('debug'):
    60     if True:
     59    #if GSASIIpath.GetConfigValue('debug') and useMP:
     60    if useMP:
    6161        print('Multiprocessing with {} cores enabled'.format(ncores))
    62 
    63 ################################################################################
    64 # derivative computation
    65 ################################################################################       
    66 def InitDerivGlobals(im1,calcControls1,SGMT1,hfx1,phfx1,pfx1,G1,GB1,g1,SGData1,
    67                      parmDict1,wave1,shl1,x1,cw1,Ka21,A1,varylist1,dependentVars1,
    68                      dFdvDict1,lamRatio1,kRatio1,doPawley1,pawleyLookup1):
    69     '''Initialize for the computation of derivatives. Puts lots of junk into the global
    70     namespace in this module, including the arrays for derivatives (when needed.)
    71     '''
    72     global im,calcControls,SGMT,hfx,phfx,pfx,G,GB,g,SGData,parmDict,wave,shl,x,cw,Ka2,A
    73     global varylist,dependentVars,dFdvDict,lamRatio,kRatio,doPawley,pawleyLookup
    74     im = im1
    75     calcControls = calcControls1
    76     SGMT = SGMT1
    77     hfx = hfx1
    78     phfx = phfx1
    79     pfx = pfx1
    80     G = G1
    81     GB = GB1
    82     g = g1
    83     SGData = SGData1
    84     parmDict = parmDict1
    85     wave = wave1
    86     shl = shl1
    87     x = ma.getdata(x1)
    88     cw = cw1
    89     Ka2 = Ka21
    90     A = A1
    91     varylist = varylist1
    92     dependentVars = dependentVars1
    93     dFdvDict = dFdvDict1
    94     lamRatio = lamRatio1
    95     kRatio = kRatio1
    96     doPawley = doPawley1
    97     pawleyLookup = pawleyLookup1
    98     # determine the parameters that will have derivatives computed only at end
    99     global nonatomvarylist
    100     nonatomvarylist = []
    101     for name in varylist:
    102         if '::RBV;' not in name:
    103             try:
    104                 aname = name.split(pfx)[1][:2]
    105                 if aname not in ['Af','dA','AU','RB','AM','Xs','Xc','Ys','Yc','Zs','Zc',    \
    106                     'Tm','Xm','Ym','Zm','U1','U2','U3']: continue # skip anything not an atom or rigid body param
    107             except IndexError:
    108                 continue
    109         nonatomvarylist.append(name)
    110     global nonatomdependentVars
    111     nonatomdependentVars = []
    112     for name in dependentVars:
    113         if '::RBV;' not in name:
    114             try:
    115                 aname = name.split(pfx)[1][:2]
    116                 if aname not in ['Af','dA','AU','RB','AM','Xs','Xc','Ys','Yc','Zs','Zc',    \
    117                     'Tm','Xm','Ym','Zm','U1','U2','U3']: continue # skip anything not an atom or rigid body param
    118             except IndexError:
    119                 continue
    120         nonatomdependentVars.append(name)
    121     # create local copies of derivative arrays, if multiprocessing will be used
    122     if useMP:
    123         global dMdv
    124         dMdv = np.zeros(shape=(len(varylist),len(x)))
    125         global depDerivDict
    126         depDerivDict = {j:np.zeros(shape=len(x)) for j in dependentVars}
    127            
    128 
    129 def cellVaryDerv(pfx,SGData,dpdA):
    130     if SGData['SGLaue'] in ['-1',]:
    131         return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],
    132             [pfx+'A3',dpdA[3]],[pfx+'A4',dpdA[4]],[pfx+'A5',dpdA[5]]]
    133     elif SGData['SGLaue'] in ['2/m',]:
    134         if SGData['SGUniq'] == 'a':
    135             return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A5',dpdA[5]]]
    136         elif SGData['SGUniq'] == 'b':
    137             return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A4',dpdA[4]]]
    138         else:
    139             return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A3',dpdA[3]]]
    140     elif SGData['SGLaue'] in ['mmm',]:
    141         return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]]]
    142     elif SGData['SGLaue'] in ['4/m','4/mmm']:
    143         return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]]
    144     elif SGData['SGLaue'] in ['6/m','6/mmm','3m1', '31m', '3']:
    145         return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]]
    146     elif SGData['SGLaue'] in ['3R', '3mR']:
    147         return [[pfx+'A0',dpdA[0]+dpdA[1]+dpdA[2]],[pfx+'A3',dpdA[3]+dpdA[4]+dpdA[5]]]                       
    148     elif SGData['SGLaue'] in ['m3m','m3']:
    149         return [[pfx+'A0',dpdA[0]]]
    150 
    151 def ComputeDerivMPbatch(reflsList):
    152     '''Computes a the derivatives for a batch of reflections and sums the them into
    153     global arrays dMdv & depDerivDict. These arrays are returned once the computation
    154     is completed.
    155     '''
    156     for refl,iref,fmin,fmax,iBeg,iFin in reflsList:
    157         if ComputeDeriv(refl,iref,fmin,fmax,iBeg,iFin,dMdv,depDerivDict): break
    158     return dMdv,depDerivDict
    159 
    160 def ComputeDeriv(refl,iref,fmin,fmax,iBeg,iFin,dMdv,depDerivDict):
    161     '''Compute the parameter derivatives for a single reflection and add the results
    162     into either array dMdv or depDerivDict
    163     '''
    164     global wave
    165     if im:
    166         h,k,l,m = refl[:4]
    167     else:
    168         h,k,l = refl[:3]
    169     Uniq = np.inner(refl[:3],SGMT)
    170     if 'T' in calcControls[hfx+'histType']:
    171         wave = refl[14+im]
    172     dIdsh,dIdsp,dIdpola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx = G2stMth.GetIntensityDerv(refl,im,wave,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
    173     pos = refl[5+im]
    174     calcKa2 = False
    175     if 'C' in calcControls[hfx+'histType']:
    176         tanth = tand(pos/2.0)
    177         costh = cosd(pos/2.0)
    178         if Ka2:
    179             pos2 = refl[5+im]+lamRatio*tanth       # + 360/pi * Dlam/lam * tan(th)
    180             iBeg2 = np.searchsorted(x,pos2-fmin)
    181             iFin2 = np.searchsorted(x,pos2+fmax)
    182             if iBeg2-iFin2:
    183                 calcKa2 = True
    184                 iFin = iFin2       
    185         lenBF = iFin-iBeg
    186         dMdpk = np.zeros(shape=(6,lenBF))
    187         dMdipk = G2pwd.getdFCJVoigt3(refl[5+im],refl[6+im],refl[7+im],shl,x[iBeg:iFin])
    188         for i in range(5):
    189             dMdpk[i] += 100.*cw[iBeg:iFin]*refl[11+im]*refl[9+im]*dMdipk[i]
    190         dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'sig':dMdpk[2],'gam':dMdpk[3],'shl':dMdpk[4],'L1/L2':np.zeros_like(dMdpk[0])}
    191         if calcKa2:
    192             dMdpk2 = np.zeros(shape=(6,lenBF))
    193             dMdipk2 = G2pwd.getdFCJVoigt3(pos2,refl[6+im],refl[7+im],shl,x[iBeg:iFin])
    194             for i in range(5):
    195                 dMdpk2[i] = 100.*cw[iBeg:iFin]*refl[11+im]*refl[9+im]*kRatio*dMdipk2[i]
    196             dMdpk2[5] = 100.*cw[iBeg:iFin]*refl[11+im]*dMdipk2[0]
    197             dervDict2 = {'int':dMdpk2[0],'pos':dMdpk2[1],'sig':dMdpk2[2],'gam':dMdpk2[3],'shl':dMdpk2[4],'L1/L2':dMdpk2[5]*refl[9]}
    198     else:   #'T'OF
    199         lenBF = iFin-iBeg
    200         if lenBF < 0: return True  #bad peak coeff
    201         dMdpk = np.zeros(shape=(6,lenBF))
    202         dMdipk = G2pwd.getdEpsVoigt(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im],x[iBeg:iFin])
    203         for i in range(6):
    204             dMdpk[i] += refl[11+im]*refl[9+im]*dMdipk[i]      #cw[iBeg:iFin]*
    205         dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'alp':dMdpk[2],'bet':dMdpk[3],'sig':dMdpk[4],'gam':dMdpk[5]}           
    206     if doPawley:
    207         try:
    208             if im:
    209                 pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
    210             else:
    211                 pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
    212             idx = varylist.index(pIdx)
    213             dMdv[idx][iBeg:iFin] = dervDict['int']/refl[9+im]
    214             if Ka2: #not for TOF either
    215                 dMdv[idx][iBeg:iFin] += dervDict2['int']/refl[9+im]
    216         except: # ValueError:
    217             pass
    218     if 'C' in calcControls[hfx+'histType']:
    219         dpdA,dpdw,dpdZ,dpdSh,dpdTr,dpdX,dpdY,dpdV = G2stMth.GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict)
    220         names = {hfx+'Scale':[dIdsh,'int'],hfx+'Polariz.':[dIdpola,'int'],phfx+'Scale':[dIdsp,'int'],
    221             hfx+'U':[tanth**2,'sig'],hfx+'V':[tanth,'sig'],hfx+'W':[1.0,'sig'],
    222             hfx+'X':[1.0/costh,'gam'],hfx+'Y':[tanth,'gam'],hfx+'SH/L':[1.0,'shl'],
    223             hfx+'I(L2)/I(L1)':[1.0,'L1/L2'],hfx+'Zero':[dpdZ,'pos'],hfx+'Lam':[dpdw,'pos'],
    224             hfx+'Shift':[dpdSh,'pos'],hfx+'Transparency':[dpdTr,'pos'],hfx+'DisplaceX':[dpdX,'pos'],
    225             hfx+'DisplaceY':[dpdY,'pos'],}
    226         if 'Bragg' in calcControls[hfx+'instType']:
    227             names.update({hfx+'SurfRoughA':[dFdAb[0],'int'],
    228                 hfx+'SurfRoughB':[dFdAb[1],'int'],})
    229         else:
    230             names.update({hfx+'Absorption':[dFdAb,'int'],})
    231     else:   #'T'OF
    232         dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV = G2stMth.GetReflPosDerv(refl,im,0.0,A,pfx,hfx,calcControls,parmDict)
    233         names = {hfx+'Scale':[dIdsh,'int'],phfx+'Scale':[dIdsp,'int'],
    234             hfx+'difC':[dpdDC,'pos'],hfx+'difA':[dpdDA,'pos'],hfx+'difB':[dpdDB,'pos'],
    235             hfx+'Zero':[dpdZ,'pos'],hfx+'X':[refl[4+im],'gam'],hfx+'Y':[refl[4+im]**2,'gam'],
    236             hfx+'alpha':[1./refl[4+im],'alp'],hfx+'beta-0':[1.0,'bet'],hfx+'beta-1':[1./refl[4+im]**4,'bet'],
    237             hfx+'beta-q':[1./refl[4+im]**2,'bet'],hfx+'sig-0':[1.0,'sig'],hfx+'sig-1':[refl[4+im]**2,'sig'],
    238             hfx+'sig-2':[refl[4+im]**4,'sig'],hfx+'sig-q':[1./refl[4+im]**2,'sig'],
    239             hfx+'Absorption':[dFdAb,'int'],phfx+'Extinction':[dFdEx,'int'],}
    240     for name in names:
    241         item = names[name]
    242         if name in varylist:
    243             dMdv[varylist.index(name)][iBeg:iFin] += item[0]*dervDict[item[1]]
    244             if calcKa2:
    245                 dMdv[varylist.index(name)][iBeg:iFin] += item[0]*dervDict2[item[1]]
    246         elif name in dependentVars:
    247             depDerivDict[name][iBeg:iFin] += item[0]*dervDict[item[1]]
    248             if calcKa2:
    249                 depDerivDict[name][iBeg:iFin] += item[0]*dervDict2[item[1]]
    250     for iPO in dIdPO:
    251         if iPO in varylist:
    252             dMdv[varylist.index(iPO)][iBeg:iFin] += dIdPO[iPO]*dervDict['int']
    253             if calcKa2:
    254                 dMdv[varylist.index(iPO)][iBeg:iFin] += dIdPO[iPO]*dervDict2['int']
    255         elif iPO in dependentVars:
    256             depDerivDict[iPO][iBeg:iFin] += dIdPO[iPO]*dervDict['int']
    257             if calcKa2:
    258                 depDerivDict[iPO][iBeg:iFin] += dIdPO[iPO]*dervDict2['int']
    259     for i,name in enumerate(['omega','chi','phi']):
    260         aname = pfx+'SH '+name
    261         if aname in varylist:
    262             dMdv[varylist.index(aname)][iBeg:iFin] += dFdSA[i]*dervDict['int']
    263             if calcKa2:
    264                 dMdv[varylist.index(aname)][iBeg:iFin] += dFdSA[i]*dervDict2['int']
    265         elif aname in dependentVars:
    266             depDerivDict[aname][iBeg:iFin] += dFdSA[i]*dervDict['int']
    267             if calcKa2:
    268                 depDerivDict[aname][iBeg:iFin] += dFdSA[i]*dervDict2['int']
    269     for iSH in dFdODF:
    270         if iSH in varylist:
    271             dMdv[varylist.index(iSH)][iBeg:iFin] += dFdODF[iSH]*dervDict['int']
    272             if calcKa2:
    273                 dMdv[varylist.index(iSH)][iBeg:iFin] += dFdODF[iSH]*dervDict2['int']
    274         elif iSH in dependentVars:
    275             depDerivDict[iSH][iBeg:iFin] += dFdODF[iSH]*dervDict['int']
    276             if calcKa2:
    277                 depDerivDict[iSH][iBeg:iFin] += dFdODF[iSH]*dervDict2['int']
    278     cellDervNames = cellVaryDerv(pfx,SGData,dpdA)
    279     for name,dpdA in cellDervNames:
    280         if name in varylist:
    281             dMdv[varylist.index(name)][iBeg:iFin] += dpdA*dervDict['pos']
    282             if calcKa2:
    283                 dMdv[varylist.index(name)][iBeg:iFin] += dpdA*dervDict2['pos']
    284         elif name in dependentVars: #need to scale for mixed phase constraints?
    285             depDerivDict[name][iBeg:iFin] += dpdA*dervDict['pos']
    286             if calcKa2:
    287                 depDerivDict[name][iBeg:iFin] += dpdA*dervDict2['pos']
    288     dDijDict = G2stMth.GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict)
    289     for name in dDijDict:
    290         if name in varylist:
    291             dMdv[varylist.index(name)][iBeg:iFin] += dDijDict[name]*dervDict['pos']
    292             if calcKa2:
    293                 dMdv[varylist.index(name)][iBeg:iFin] += dDijDict[name]*dervDict2['pos']
    294         elif name in dependentVars:
    295             depDerivDict[name][iBeg:iFin] += dDijDict[name]*dervDict['pos']
    296             if calcKa2:
    297                 depDerivDict[name][iBeg:iFin] += dDijDict[name]*dervDict2['pos']
    298     for i,name in enumerate([pfx+'mV0',pfx+'mV1',pfx+'mV2']):
    299         if name in varylist:
    300             dMdv[varylist.index(name)][iBeg:iFin] += dpdV[i]*dervDict['pos']
    301             if calcKa2:
    302                 dMdv[varylist.index(name)][iBeg:iFin] += dpdV[i]*dervDict2['pos']
    303         elif name in dependentVars:
    304             depDerivDict[name][iBeg:iFin] += dpdV[i]*dervDict['pos']
    305             if calcKa2:
    306                 depDerivDict[name][iBeg:iFin] += dpdV[i]*dervDict2['pos']
    307     if 'C' in calcControls[hfx+'histType']:
    308         sigDict,gamDict = G2stMth.GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict)
    309     else:   #'T'OF
    310         sigDict,gamDict = G2stMth.GetSampleSigGamDerv(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict)
    311     for name in gamDict:
    312         if name in varylist:
    313             dMdv[varylist.index(name)][iBeg:iFin] += gamDict[name]*dervDict['gam']
    314             if calcKa2:
    315                 dMdv[varylist.index(name)][iBeg:iFin] += gamDict[name]*dervDict2['gam']
    316         elif name in dependentVars:
    317             depDerivDict[name][iBeg:iFin] += gamDict[name]*dervDict['gam']
    318             if calcKa2:
    319                 depDerivDict[name][iBeg:iFin] += gamDict[name]*dervDict2['gam']
    320     for name in sigDict:
    321         if name in varylist:
    322             dMdv[varylist.index(name)][iBeg:iFin] += sigDict[name]*dervDict['sig']
    323             if calcKa2:
    324                 dMdv[varylist.index(name)][iBeg:iFin] += sigDict[name]*dervDict2['sig']
    325         elif name in dependentVars:
    326             depDerivDict[name][iBeg:iFin] += sigDict[name]*dervDict['sig']
    327             if calcKa2:
    328                 depDerivDict[name][iBeg:iFin] += sigDict[name]*dervDict2['sig']
    329     for name in ['BabA','BabU']:
    330         if refl[9+im]:
    331             if phfx+name in varylist:
    332                 dMdv[varylist.index(phfx+name)][iBeg:iFin] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict['int']/refl[9+im]
    333                 if calcKa2:
    334                     dMdv[varylist.index(phfx+name)][iBeg:iFin] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict2['int']/refl[9+im]
    335             elif phfx+name in dependentVars:                   
    336                 depDerivDict[phfx+name][iBeg:iFin] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict['int']/refl[9+im]
    337                 if calcKa2:
    338                     depDerivDict[phfx+name][iBeg:iFin] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict2['int']/refl[9+im]                 
    339     if not doPawley and not parmDict[phfx+'LeBail']:
    340         #do atom derivatives -  for RB,F,X & U so far - how do I scale mixed phase constraints?
    341         corr = 0.
    342         #corr2 = 0.
    343         if refl[9+im]:             
    344             corr = dervDict['int']/refl[9+im]
    345             #if calcKa2:  # commented out in Bob's code. Why?
    346             #    corr2 = dervDict2['int']/refl[9+im]
    347         for name in nonatomvarylist:
    348             dMdv[varylist.index(name)][iBeg:iFin] += dFdvDict[name][iref]*corr
    349             #if calcKa2:
    350             #   dMdv[varylist.index(name)][iBeg:iFin] += dFdvDict[name][iref]*corr2 # unneeded w/o above
    351         for name in nonatomdependentVars:
    352            depDerivDict[name][iBeg:iFin] += dFdvDict[name][iref]*corr
    353            #if calcKa2:
    354            #    depDerivDict[name][iBeg:iFin] += dFdvDict[name][iref]*corr2
     62    return useMP,ncores
    35563
    35664################################################################################
    35765# Fobs Squared computation
    35866################################################################################       
    359 #x,ratio,shl,xB,xF,im,lamRatio,kRatio,xMask,Ka2
    36067def InitFobsSqGlobals(x1,ratio1,shl1,xB1,xF1,im1,lamRatio1,kRatio1,xMask1,Ka21):
    36168    '''Initialize for the computation of Fobs Squared for powder histograms.
     
    464171    cw = np.append(cw,cw[-1])
    465172    # create local copies of ycalc array
    466     if useMP:
    467         global yc
    468         yc = np.zeros_like(x1)
     173    global yc
     174    yc = np.zeros_like(x)
    469175
    470176
Note: See TracChangeset for help on using the changeset viewer.