User Tools

Site Tools


accounting_troubleshooting

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
accounting_troubleshooting [2026/02/04 14:21] – QOS de prueba bbruzzoaccounting_troubleshooting [2026/02/06 17:15] (current) bbruzzo
Line 48: Line 48:
     print(stdout)     print(stdout)
  
-if __name__ == '__main__':+if __name__ == '__main__':file> syntax as above, you might want to make the shown code available for download as well. You can 
     accounts = get_accounts()     accounts = get_accounts()
  
Line 245: Line 245:
 </code> </code>
  
-To be continued...+El job terminó de correr, osea usó más tiempo del que podía: 
 + 
 +<code>[root@mmgt02 admin]# sacct -Xu root --format=jobid,jobname,partition,account,state,exitcode,elapsedraw,ncpus 
 +JobID           JobName  Partition    Account      State ExitCode ElapsedRaw      NCPUS  
 +------------ ---------- ---------- ---------- ---------- -------- ---------- ----------  
 +281155            sleep    gpunode       root    TIMEOUT      0:0      12024         12  
 +</code> 
 + 
 + 
 +<code>[root@mmgt02 admin]# scontrol show assoc_mgr | grep "QOS=qosprueba" -A 21 
 +QOS=qosprueba(32) 
 +    UsageRaw=144288.000000 
 +    GrpJobs=N(0) GrpJobsAccrue=N(0) GrpSubmitJobs=N(0) GrpWall=N(200.40) 
 +    GrpTRES=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    GrpTRESMins=cpu=3000(2404),mem=N(0),energy=N(0),node=N(200),billing=N(2404),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=2000(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    GrpTRESRunMins=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    MaxWallPJ= 
 +    MaxTRESPJ= 
 +    MaxTRESPN= 
 +    MaxTRESMinsPJ= 
 +    MinPrioThresh=  
 +    MinTRESPJ= 
 +    PreemptMode=OFF 
 +    Priority=0 
 +    Account Limits 
 +      root 
 +        MaxJobsPA=N(0) MaxJobsAccruePA=N(0) MaxSubmitJobsPA=N(0) 
 +        MaxTRESPA=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    User Limits 
 +      root(0) 
 +        MaxJobsPU=N(0) MaxJobsAccruePU=N(0) MaxSubmitJobsPU=N(0) 
 +        MaxTRESPU=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +</code> 
 + 
 +Ahora muestra que la qos tiene 3000 horas disponibles pero usó 3500. 
 + 
 +<code>sacct -X -a -q qosprueba --starttime=2025-01-01 --parsable2 --noheader --format=elapsedraw,ncpus | awk -F'|' '{sum+=$1*$2} END {print sum/60}' 
 +3505.48 
 +</code> 
 + 
 +<code> 
 +    UsageRaw=144288.000000 
 +    GrpJobs=N(0) GrpJobsAccrue=N(0) GrpSubmitJobs=N(0) GrpWall=N(200.40) 
 +    GrpTRES=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    GrpTRESMins=cpu=3000(2404),mem=N(0),energy=N(0),node=N(200),billing=N(2404),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=2000(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    GrpTRESRunMins=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +</code> 
 + 
 +¿Vuelve a entrar el mismo job? 
 + 
 +Si, vuelve a correr: 
 + 
 +<code>[root@mmgt02 ~]# sacct -X -a -q qosprueba --starttime=2026-02-04 --format=JobID,JobName,Account,QOS,AllocCPUS,State,Elapsed 
 +JobID           JobName    Account        QOS  AllocCPUS      State    Elapsed  
 +------------ ---------- ---------- ---------- ---------- ---------- ----------  
 +281155            sleep       root  qosprueba         12    TIMEOUT   03:20:24  
 +282169            sleep       root  qosprueba         12    TIMEOUT   00:52:59  
 +</code> 
 + 
 +<code>[root@mmgt02 ~]# sacct -X -a -q qosprueba --starttime=2025-01-01 --parsable2 --noheader --format=elapsedraw,ncpus | awk -F'|' '{sum+=$1*$2} END {print sum/60}' 
 +4141.28 
 +</code> 
 + 
 +Vemos que la qos tiene consumidos 4141 minutos. 
 + 
 +Cree que corrió 3040 minutos: 
 + 
 +<code># scontrol show assoc_mgr | grep -A 7 "QOS=qosprueba(" 
 +QOS=qosprueba(32) 
 +    UsageRaw=182436.000000 
 +    GrpJobs=N(0) GrpJobsAccrue=N(0) GrpSubmitJobs=N(0) GrpWall=N(253.38) 
 +    GrpTRES=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    GrpTRESMins=cpu=3000(3040),mem=N(0),energy=N(0),node=N(253),billing=N(3040),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=2000(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    GrpTRESRunMins=cpu=N(0),mem=N(0),energy=N(0),node=N(0),billing=N(0),fs/disk=N(0),vmem=N(0),pages=N(0),gres/gpu=N(0),gres/gpu:v100=N(0),gres/gpumem=N(0),gres/gpuutil=N(0) 
 +    MaxWallPJ= 
 +    MaxTRESPJ= 
 +</code> 
 + 
 + 
 +====== DefaultQOS ====== 
 + 
 +Previo al update las accounts tenían una QOS por default (o no?).  
 + 
 +Hay que actualizarlo para que contabilice las horas correctamente: 
 + 
 +<code>$ sacctmgr modify account set defaultqos=qos_pisca_73 where account=pisca_73</code> 
 + 
 + 
 +====== FIX ====== 
 + 
 +Utilicé este script para actualizar las qos a los valores restantes y setear las qos default: 
 + 
 +<code python fix_qos.py>#!/usr/bin/env python3.10 
 + 
 +import subprocess 
 + 
 +def get_accounts(): 
 +    command = ['sacctmgr', '--noheader', 'list', 'account', 'format=account'
 +    output = subprocess.run(command,capture_output=True,encoding='utf-8'
 +    accounts = output.stdout.split()  
 +    return accounts 
 + 
 +def get_hours(account): 
 +    command = ['sacct', '-X', '-a', '-A', str(account),  
 +            '--starttime=2025-01-01', '--parsable2', '--noheader',  
 +            '--format=elapsedraw,ncpus'
 +    cpu_hours_command = ['sreport', 'cluster', 'userutilizationbyaccount',  
 +            '--noheader', '--parsable2', '--tres=cpu',  
 +            'accounts='+str(account), 'format=used',  
 +            'start=2025-05-01T00:00:00'
 +    gpu_hours_command = ['sreport', 'cluster', 'userutilizationbyaccount',  
 +            '--noheader', '--parsable2', '--tres=gres/gpu',  
 +            'accounts='+str(account), 'format=used',  
 +            'start=2025-05-01T00:00:00'
 + 
 +    cpu_hours = subprocess.run( 
 +            cpu_hours_command, 
 +            capture_output=True, 
 +            encoding='utf-8').stdout.split() 
 +     
 +    cpu_hours = [int(i) for i in cpu_hours] 
 +    cpu_hours = sum(cpu_hours) 
 + 
 +    gpu_hours = subprocess.run( 
 +            gpu_hours_command, 
 +            capture_output=True, 
 +            encoding='utf-8').stdout.split() 
 + 
 +    gpu_hours = [int(i) for i in gpu_hours] 
 +    gpu_hours = sum(gpu_hours) 
 +     
 +    return cpu_hours, gpu_hours  
 + 
 +def update_qos(account): 
 +    match account: 
 +        case a if a.startswith('pad'): 
 +            default_cpu, default_gpu = 240000000,15000000  
 +        case a if a.startswith('pci'): 
 +            default_cpu, default_gpu = 60000000,3600000 
 +        case a if a.startswith('pisca'): 
 +            default_cpu, default_gpu = 6000000,60000  
 + 
 +    spent_cpu, spent_gpu = get_hours(account) 
 + 
 +    new_cpu = max(0,default_cpu-spent_cpu) 
 +    new_gpu = max(0,default_gpu-spent_gpu) 
 +     
 +    update_command = ['sacctmgr', 'modify', 'qos', 'qos_'+str(account), 'set',  
 +            'GrpTRESMins=cpu='+str(new_cpu)+',gres/gpu='+str(new_gpu)] 
 + 
 +    print(update_command) 
 +    subprocess.run(update_command) 
 + 
 +def update_defqos(account): 
 +    ''' 
 +    Sets Default QOS to IPAC project in case of misconfiguration. 
 +    ''' 
 +    command =  ['sacctmgr', 'modify', 'account', 'set',  
 +            'defaultqos=qos_'+str(account), 'where', 'account='+str(account)] 
 +    subprocess.run(command) 
 + 
 +def action(accounts,func=get_hours): 
 +    for account in accounts: 
 +        if account.startswith(('pad','pci','pisca')): 
 +            func(account) 
 + 
 +actions = { 
 +        '1': get_hours, 
 +        '2': update_defqos, 
 +        '3': update_qos, 
 +
 + 
 +if __name__ == '__main__': 
 +    print("Elegir que acción ejecutar en slurm:\n","1) get_hours\n", 
 +            "2) update_defqos\n","3) update_qos\n"
 +    choice = input("Elegir:"
 +    func = actions.get(choice) 
 + 
 +    accounts = get_accounts() 
 +    if func: 
 +        action(accounts,func) 
 +    else: 
 +        print("Operación invalida"
 +</code>
  
accounting_troubleshooting.1770214875.txt.gz · Last modified: by bbruzzo