Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save insertinterestingnamehere/8f087a99c2ae34f275ac268ff4210f28 to your computer and use it in GitHub Desktop.
Save insertinterestingnamehere/8f087a99c2ae34f275ac268ff4210f28 to your computer and use it in GitHub Desktop.
LAPACK_version_compare_script.py
# Copyright Ian Henriksen 2020
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This script generates the info at
# https://gist.github.com/insertinterestingnamehere/baf36ce759b1712f2dfb
# Continuity of excluded functions must be checked by hand.
# Pass this script a directory containing the LAPACK 3.1 through 3.9
# source downloads with directory names formatted as PASSED_DIRECTORY/lapack-VERSION
from os import walk
from fnmatch import filter
from numpy.f2py import crackfortran
import sys
from os import path
sig_types = {'integer':'int',
'complex':'c',
'double precision':'d',
'real':'s',
'complex*16':'z',
'double complex':'z',
'character':'char',
'logical':'bint'}
def get_type(info, arg):
argtype = sig_types[info['vars'][arg]['typespec']]
if argtype == 'c' and info['vars'][arg].get('kindselector') is not None:
argtype = 'z'
return argtype
def make_signature(filename):
try:
info = crackfortran.crackfortran(filename)[0]
name = info['name']
#if '_' in name:
# info = info['body']
# name = info['name']
if info['block'] == 'subroutine':
return_type = 'void'
else:
return_type = get_type(info, name)
arglist = [' *'.join([get_type(info, arg), arg]) for arg in info['args']]
args = ', '.join(arglist)
# Eliminate strange variable naming that replaces rank with rank_bn.
args = args.replace('rank_bn', 'rank')
return '{} {}({})\n'.format(return_type, name, args)
except:
print('*' * 100)
print("offending file:", filename)
print('*' * 100)
raise
def get_sigs(lapack_dir, exclusions=None):
if exclusions is None:
exclusions = []
sigs = []
for root, dirnames, filenames in walk(lapack_dir):
if 'BLAS' in root or 'TESTING' in root:
continue
for filename in filter(filenames, '*.f'):
if filename[-5:-2] == 'tst' or filename[:3] == 'tst':
continue
fullpath = '/'.join([root, filename])
if 'DEPRECATED' in fullpath:
continue
if filename[1:-2] not in exclusions:
sigs.append(make_signature(fullpath))
print("done processing: {}".format(fullpath))
return sigs
def get_sig_name(line):
return line.split('(')[0].split(' ')[-1]
def get_argtypes(line):
return [arg.split(' *')[0] for arg in line.split('(')[1].split(',')]
def compare_versions(v1, v2, v1sigs, v2sigs):
lines = ["Contained in " + v1 + " but not in " + v2 + ":\n"]
v1names = [get_sig_name(sig) for sig in v1sigs]
v2names = [get_sig_name(sig) for sig in v2sigs]
changed = set(v1names) & set(v2names)
v1_changed_lines = []
for sig in sorted(set(v1sigs) - set(v2sigs), key=get_sig_name):
if get_sig_name(sig) not in changed:
lines.append(sig)
else:
v1_changed_lines.append(sig)
lines.append("\nContained in " + v2 + " but not in " + v1 + ":\n")
v2_changed_lines = []
for sig in sorted(set(v2sigs) - set(v1sigs), key=get_sig_name):
if get_sig_name(sig) not in changed:
lines.append(sig)
else:
v2_changed_lines.append(sig)
argname_changes = []
argtype_changes = []
for v1line, v2line in zip(v1_changed_lines, v2_changed_lines):
v1types = get_argtypes(v1line)
v2types = get_argtypes(v2line)
if v1types == v2types:
argname_changes.append(v1 + ': ' + v1line)
argname_changes.append(v2 + ': ' + v2line)
else:
argtype_changes.append(v1 + ': ' + v1line)
argtype_changes.append(v2 + ': ' + v2line)
ver_diff = v1 + " to " + v2 + ":\n"
changed_lines = (["Changed from " + ver_diff] +
["Changed signature from " + ver_diff] +
argtype_changes +
["Changed argument names from " + ver_diff] +
argname_changes)
lines.append('\n')
lines += changed_lines
lines.append('\n\n')
return lines
def get_dir(version):
return path.join(sys.argv[1], "lapack-{}".format(version))
versions = ['3.1.0', '3.1.1', '3.2.0', '3.2.1', '3.2.2', '3.3.0', '3.3.1',
'3.4.0', '3.4.1', '3.4.2', '3.5.0', '3.5.1', '3.6.0', '3.6.1',
'3.7.0', '3.7.1', '3.8.0',
'3.9.0']
exclusions_310 = ['gees', 'geesx', 'gges', 'ggesx', 'APACK_version']
exclusions_320 = exclusions_310 + ['hla_transtype']
exclusions_341 = exclusions_320 + ['intface']
exclusions_351 = exclusions_341 + ['gges3']
exclusions_370 = exclusions_351 + ['lalsd', 'lamswlq', 'lamtsqr', 'laswlq', 'latsqr']
exclusions_390 = exclusions_370 + ['unhr_col', 'orhr_col']
exclusions = [exclusions_310,
exclusions_310,
exclusions_320,
exclusions_320,
exclusions_320,
exclusions_320,
exclusions_320,
exclusions_320,
exclusions_341,
exclusions_341,
exclusions_341,
exclusions_351,
exclusions_351,
exclusions_351,
exclusions_370,
exclusions_370,
exclusions_370,
exclusions_390]
def compare_all():
old_version = versions[0]
old_sigs = get_sigs(get_dir(versions[0]), exclusions[0])
lines = []
for version, exclusion in zip(versions[1:], exclusions[1:]):
sigs = get_sigs(get_dir(version), exclusion)
lines += compare_versions(old_version, version, old_sigs, sigs)
old_version = version
old_sigs = sigs
with open('lapack_version_compare.txt', 'w') as f:
f.writelines(lines)
if __name__ == '__main__':
compare_all()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment