1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
import glob
import os
import re
import sys
import numpy as np
my_path = os.path.dirname(os.path.realpath(__file__))
cppy_files = glob.glob(my_path + '/cppy_source/*.cppy')
dtype_map = {
'bool': 'bool',
'float32': 'float',
'float64': 'double',
'int32': 'int',
'int64': 'long',
'uint32': 'unsigned int',
'uint64': 'unsigned long',
'complex64': 'std::complex<float>',
'complex128': 'std::complex<double>',
}
def get_xtype(arr, xtensor=False):
if isinstance(arr, (int)):
return "int"
elif isinstance(arr, float):
return "double"
if xtensor:
s = "xtensor<" + dtype_map[str(arr.dtype)] + ", " + str(arr.ndim) + ">"
else:
s = "xarray<" + dtype_map[str(arr.dtype)] + ">"
return s
def get_cpp_initlist(arr, name):
if isinstance(arr, (int, str, float)):
return get_xtype(arr) + " " + name + " = " + str(arr) + ';'
name = get_xtype(arr) + " " + name
s = np.array2string(arr, separator=',', precision=16)
s = s.replace('[', '{')
s = s.replace(']', '}')
s = s.replace('j', 'i')
s += ';'
s = s.replace("\n", "\n" + " " * (len(name) + 3))
s = name + " = " + s
return s
def translate_file(contents, f):
current_vars = {}
matches = re.findall(r"\/\*py.*?\*\/", contents, re.MULTILINE | re.DOTALL)
def exec_comment(txt, upper_level=False):
lines = txt.split('\n')
if upper_level:
txt = '\n'.join(["import numpy as np"] + [x.strip() for x in lines[1:-1]])
locals_before = list(locals().keys())
exec(txt, globals(), current_vars)
current_vars.update(
{x: val for x, val in locals().items() if x not in locals_before}
)
result_file = ""
idx = 0
lidx = 0
for line in contents.split('\n'):
if lidx == 8:
f = os.path.split(f)[1]
result_file += "// This file is generated from test/files/cppy_source/{} by preprocess.py!\n".format(f)
result_file += "// Warning: This file should not be modified directly! " \
"Instead, modify the `*.cppy` file.\n\n"
lstrip = line.lstrip()
if lstrip.startswith("/*py"):
exec_comment(matches[idx], True)
idx += 1
if lstrip.startswith("// py_"):
indent_n = len(line) - len(lstrip)
if '=' in lstrip:
exec_comment(lstrip[6:])
var = line.strip()[6:lstrip.index('=')].strip()
else:
var = line.strip()[6:]
indent = line[:indent_n]
init_list = get_cpp_initlist(current_vars[var], 'py_' + var)
init_list = '\n'.join([indent + x for x in init_list.split('\n')])
result_file += line + '\n'
result_file += init_list + '\n'
else:
result_file += line + '\n'
lidx += 1
return result_file
print("::: PREPROCESSING :::\n")
for f in cppy_files:
print(" - PROCESSING {}".format(f))
global current_vars
current_vars = {} # reset
with open(f) as fi:
contents = fi.read()
# reset global seed
np.random.seed(42)
result = translate_file(contents, f)
f_result = os.path.split(f)[1]
with open(my_path + "/../" + f_result[:-1], 'w+') as fo:
fo.write(result)
print("::: DONE :::")
# print(result)
|