diff --git a/dev-tools/README.md b/dev-tools/README.md index 3fdb901ac..ba2655652 100644 --- a/dev-tools/README.md +++ b/dev-tools/README.md @@ -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). diff --git a/dev-tools/get_device_props.py b/dev-tools/get_device_props.py old mode 100644 new mode 100755 diff --git a/dev-tools/mem_analyse.py b/dev-tools/mem_analyse.py new file mode 100755 index 000000000..71e27c8d1 --- /dev/null +++ b/dev-tools/mem_analyse.py @@ -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] + + + diff --git a/dev-tools/mem_counter.py b/dev-tools/mem_counter.py index fa1b40a8b..855c673b0 100755 --- a/dev-tools/mem_counter.py +++ b/dev-tools/mem_counter.py @@ -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: @@ -119,6 +119,13 @@ with open(fname,'r') as fin: buff += lines[i+j].split('!')[0] 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