[Skip-CI] Improvements to mem_counter, suggested by Samuel Poncé

This commit is contained in:
Paolo Giannozzi 2019-04-26 23:02:19 +02:00
parent 15408fedfd
commit 04365f4b1c
4 changed files with 85 additions and 12 deletions

View File

@ -4,17 +4,22 @@ This directory contains several tools that may be useful for developers
- `mem_counter`. A script that tracks all calls to `allocate` and `deallocate`,
appending a call to subroutine `UtilXlib/mem_counter.f90`.
Calls python script `mem_counter.py`, written by Pietro Bonfà (CINECA).
Calls python script `mem_counter.py`, written by Pietro Bonfà (CINECA)
and improved by Samuel Poncé.
`mem_counter -h` gives information on how to use it.
- `mem_analyse.py` is a python script, by Samuel Poncé, locating memory leaks. See the script header for directions on how to use it.
- `src-normal`. A script that "normalizes" the fortran syntax to QE style (see below).
Calls python script `src-normal.py`, written by Norbert Nemec.
Usage: `src-normal file1.f90 [file2.f90 ...]` or `src-normal`
- `calltree.pl`
- Utilities for GPUs (Pietro Bonfà):
* `get_device_props.py`
* `device_props.c`
- (Obsolete?) utilities:
* `calltree.pl`
A perl script, to be run from the root QE directory, producing in the
standard output the tree of called routines
- `callhtml.pl`
* `callhtml.pl`
As above, producing a html page with the tree of called routines
- Utilities for PWgui:
* `check_gui` (called via `Makefile`)
@ -31,7 +36,7 @@ This directory contains several tools that may be useful for developers
* `gen-emacs-mode.tcl`
## Coding style
These are some basic rules to follow when writing Fortran code.
These are some basic rules for Fortran codes enforced by `src_normal`:
* Use spaces for indentation instead of tabs (tab width 8 characters).
* Trailing whitespaces at the end the line should be removed.
* Normalize multiword keywords (e.g. END DO).

0
dev-tools/get_device_props.py Normal file → Executable file
View File

61
dev-tools/mem_analyse.py Executable file
View File

@ -0,0 +1,61 @@
import numpy as np
#1) Run dev-tools/mem_counter inside EPW/src
#2) compile UtilXlib/mem_counter.f90 with -D__DEBUG flag
#3) Run EPW
#4) grep ' allocating' epw1.out > alloc.txt
#5) grep 'deallocating' epw1.out > dealloc.txt
#6) Run this script after having changed the correct allocation lengths
alloc_len = 38817
dealloc_len = 38769
ii = 0
alloc_name = [None] * alloc_len
alloc_size = np.zeros((alloc_len))
alloc_sub = [None] * alloc_len
with open('alloc.txt','r') as R:
for lines in R:
tmp = lines.split()
alloc_name[ii] = str(tmp[4])
alloc_sub[ii] = str(tmp[5])
alloc_size[ii] = np.float(tmp[1])
ii+=1
ii = 0
dealloc_name = [None] * dealloc_len
dealloc_size = np.zeros((dealloc_len))
with open('dealloc.txt','r') as R:
for lines in R:
tmp = lines.split()
dealloc_name[ii] = str(tmp[4])
dealloc_size[ii] = np.float(tmp[1])
ii+=1
deall_found = [ False ] * dealloc_len
for ii in np.arange(alloc_len):
print ii,' / ',alloc_len
name = alloc_name[ii]
found = False
for jj in np.arange(dealloc_len):
if name == dealloc_name[jj]:
if (alloc_size[ii] == dealloc_size[jj] and deall_found[jj]==False ) :
# We found the corresponding all/deall pair
deall_found[jj] = True
found = True
break
if (found == False):
with open('mem_analyse.out','a') as O:
O.write('We did not find a maching pair in '+str(alloc_sub[ii])+'\n')
O.write('Allocate: '+str(name)+' '+str(alloc_size[ii])+'\n')
O.write('Deallocate: '+str(dealloc_name[jj])+' '+str(dealloc_size[jj])+ '\n')
# print 'We did not find a maching pair in ', alloc_sub[ii]
# print 'Allocate: ',name,' ',alloc_size[ii]
# print 'Deallocate: ',dealloc_name[jj],' ',dealloc_size[jj]

View File

@ -27,7 +27,7 @@ for file in *.bkp; do cp $file ${file%.bkp}; done
import os, sys, re
from shutil import copyfile
fmt = """ CALL mem_counter ( SIZEOF({0}), {1}, "{0}" )
fmt = """ CALL mem_counter ( SIZEOF({0}), {1}, "{0}", "{2}" )
"""
if len(sys.argv) < 2:
@ -83,13 +83,13 @@ def get_args_list(line):
return [x.replace('!',',') for x in args.split(',')]
def write_counters(fout, sign, args, tag=[], prepend=""):
def write_counters(fout, sign, args, sub, tag=[], prepend=""):
for a, arg in enumerate(args):
if 'stat' in arg.lower():
continue
if (a == 0) and (tag != []):
fout.write(tag[0] + ' ')
fout.write(prepend + fmt.format(*[arg, sign]))
fout.write(prepend + fmt.format(*[arg, sign, sub]))
with open(fname,'r') as fin:
with open(fname+".new",'w') as fout:
@ -120,6 +120,13 @@ with open(fname,'r') as fin:
if buff[-1] != '\n':
buff += '\n'
# find name of subroutine
str_subroutine = re.findall("subroutine", buff.lower())
if (len(str_subroutine) > 0):
#print 'Treating subroutine ',str_subroutine
sub = buff.split()[1]
# find (de)allocate in strings
str_allocate = re.findall("[\"\'].*?(allocate).*?[\"\']", buff.lower())
@ -147,7 +154,7 @@ with open(fname,'r') as fin:
tag = re.findall(r'^\d+', buff.lower().strip())
write_counters(fout, -1, args, tag, ifcls[0] + ' ')
write_counters(fout, -1, args, sub, tag, ifcls[0] + ' ')
#fout.write(ifcls[0] + ' ' + fmt.format(*[args[0], -1]))
if tag:
@ -168,7 +175,7 @@ with open(fname,'r') as fin:
fout.write(ifcls[0] + ' THEN \n ALLOCATE ' + ifcls[1] + '\n ')
write_counters(fout, +1, args)
write_counters(fout, +1, args, sub)
fout.write( '\n END IF \n')
elif re.findall(r'\bdeallocate\b', buff.lower()):
@ -181,7 +188,7 @@ with open(fname,'r') as fin:
print("WARNING! deallocate with tag! Check (and change?) file " + fname + ".new (original line " + str(i) + ")")
write_counters(fout, -1, args, tag)
write_counters(fout, -1, args, sub, tag)
#for a, arg in enumerate(args):
# if 'stat' in arg.lower():
# continue
@ -203,7 +210,7 @@ with open(fname,'r') as fin:
if tag:
print("WARNING! allocate with tag! Check (and change!) file " + fname + ".new (original line " + str(i) + ")")
write_counters(fout, +1, args)
write_counters(fout, +1, args, sub)
#for arg in args:
# if 'stat' in arg.lower():
# continue