Files
rocm-systems/script/hipap.py
T
2018-05-10 13:19:10 -05:00

190 строки
5.8 KiB
Python
Исполняемый файл

#!/usr/bin/python
import os, sys, re
HEADER = "hip_cbstr.h"
REC_MAX_LEN = 1024
def fill_api_map(out, api_name, args_str):
args_list = []
args_str = re.sub(r'^\s*', r'', args_str);
args_str = re.sub(r'\s*$', r'', args_str);
args_str = re.sub(r'\s*,\s*', r',', args_str);
args_str = re.sub(r'\s+', r' ', args_str);
for arg_pair in args_str.split(','):
arg_pair = re.sub(r'\s+=\s+\S+$', '', arg_pair);
m = re.match("^(.*)\s(\S+)$", arg_pair);
if m: args_list.append((m.group(1), m.group(2)))
out[api_name] = args_list;
# hipError_t hipSetupArgument(const void* arg, size_t size, size_t offset);
def parse_api(inp, out):
end_pattern = re.compile("Texture");
beg_pattern = re.compile("^hipError_t");
api_pattern = re.compile("^hipError_t\s+([^\(]+)\(([^\)]*)\)");
found = 0
record = ""
line_num = -1
for line in inp.readlines():
record += re.sub(r'^\s+', r' ', line[:-1])
line_num += 1
if len(record) > REC_MAX_LEN:
print "Error: bad record \"" + record + "\"\nfile '" + hfile + ", line (" + str(line_num) + ")"
break;
if beg_pattern.match(record): found = 1
if found:
m = api_pattern.match(record)
if m:
found = 0
if end_pattern.search(record): break
fill_api_map(out, m.group(1), m.group(2))
else: continue
record = ""
#############################################################
if (len(sys.argv) != 2):
print >>sys.stderr, "Usage:", sys.argv[0], " <input HIP API .h file>"
sys.exit(1)
hfile = sys.argv[1]
if not os.path.isfile(hfile):
print >>sys.stderr, "Error: input file '" + hfile + "' not found"
sys.exit(1)
inp = open(hfile, 'r')
api_map = {}
parse_api(inp, api_map)
api_map['hipLaunchKernel'] = [('void*', 'kernel'), ('hipStream_t', 'stream')]
f = open(HEADER, 'w')
f.write('// automatically generated sources\n')
f.write('#ifndef HIP__CBSTR_H__\n');
f.write('#define HIP__CBSTR_H__\n');
# Generating the callbacks function type
f.write('\n// HIP API callbacks function type\n\
struct hip_cb_data_t;\n\
typedef void (*hip_cb_fun_t)(const hip_cb_data_t* data, void* arg);\n\
')
# Generating the callbacks ID enumaration
f.write('\n// HIP API callbacks ID enumaration\n')
f.write('enum hip_cb_id_t {\n')
cb_id = 0
for name in api_map.keys():
f.write(' HIP_API_ID_' + name + ' = ' + str(cb_id) + ',\n')
cb_id += 1
f.write(' HIP_API_ID_NUMBER = ' + str(cb_id) + ',\n')
f.write('};\n')
# Generating the callbacks data structure
f.write('\n// HIP API callbacks data structure\n')
f.write(
'struct hip_cb_data_t {\n' +
' const char* name;\n' +
' hip_cb_id_t id;\n' +
' uint32_t correlation_id;\n' +
' bool on_enter;\n' +
' union {\n'
)
for name, args in api_map.items():
if len(args) != 0:
f.write(' struct {\n')
for arg_tuple in args:
f.write(' ' + arg_tuple[0] + ' ' + arg_tuple[1] + ';\n')
f.write(' } ' + name + ';\n')
f.write(
' } args;\n' +
'};\n'
)
# Generating the callbacks args data filling macros
f.write('\n// HIP API callbacks args data filling macros\n')
for name, args in api_map.items():
f.write('#define INIT_' + name + '_CB_ARGS_DATA(cb_data) { \\\n')
for arg_tuple in args:
arg_type = arg_tuple[0];
arg_name = arg_tuple[1];
f.write(' cb_data.args.' + name + '.' + arg_name + ' = (' + arg_type + ')' + arg_name + '; \\\n');
f.write('};\n')
f.write('#define INIT_CB_ARGS_DATA(cb_id, cb_data) INIT_##cb_id##_CB_ARGS_DATA(cb_data)\n')
# Generating the callbacks table
f.write('\n// HIP API callbacks table\n')
f.write('\
struct hip_cb_table_t {\n\
struct { hip_cb_fun_t act; hip_cb_fun_t fun; void* arg; } arr[HIP_API_ID_NUMBER];\n\
};\n\
#define HIP_CALLBACKS_TABLE hip_cb_table_t HIP_API_callbacks_table{};\n\
')
f.write('\
inline bool HIP_SET_ACTIVITY(uint32_t id, hip_cb_fun_t fun, void* arg = NULL) {\n\
(void)arg;\n\
extern hip_cb_table_t HIP_API_callbacks_table;\n\
if (id < HIP_API_ID_NUMBER) {\n\
HIP_API_callbacks_table.arr[id].act = fun;\n\
return true;\n\
}\n\
return false;\n\
}\n')
f.write('\
inline bool HIP_SET_CALLBACK(uint32_t id, hip_cb_fun_t fun, void* arg) {\n\
extern hip_cb_table_t HIP_API_callbacks_table; \n\
if (id < HIP_API_ID_NUMBER) {\n\
HIP_API_callbacks_table.arr[id].fun = fun;\n\
HIP_API_callbacks_table.arr[id].arg = arg;\n\
return true;\n\
}\n\
return false;\n\
}\n')
# Generating the callback spawning class
f.write('\n// HIP API callbacks spawning class macro\n\
#define CB_SPAWNER_OBJECT(cb_id) \\\n\
class api_callbacks_spawner_t { \\\n\
public: \\\n\
api_callbacks_spawner_t(hip_cb_data_t& cb_data) : cb_data_(cb_data) { \\\n\
hip_cb_id_t id = HIP_API_ID_##cb_id; \\\n\
cb_data_.id = id; \\\n\
cb_data_.correlation_id = UINT_MAX; \\\n\
cb_data_.name = #cb_id; \\\n\
extern const hip_cb_table_t* getApiCallbackTabel(); \\\n\
const hip_cb_table_t* cb_table = getApiCallbackTabel(); \\\n\
cb_act_ = cb_table->arr[id].act; \\\n\
cb_fun_ = cb_table->arr[id].fun; \\\n\
cb_arg_ = cb_table->arr[id].arg; \\\n\
cb_data_.on_enter = true; \\\n\
if (cb_act_ != NULL) cb_act_(&cb_data_, NULL); \\\n\
if (cb_fun_ != NULL) cb_fun_(&cb_data_, cb_arg_); \\\n\
} \\\n\
~api_callbacks_spawner_t() { \\\n\
cb_data_.on_enter = false; \\\n\
if (cb_act_ != NULL) cb_act_(&cb_data_, NULL); \\\n\
if (cb_fun_ != NULL) cb_fun_(&cb_data_, cb_arg_); \\\n\
} \\\n\
private: \\\n\
hip_cb_data_t& cb_data_; \\\n\
hip_cb_fun_t cb_act_; \\\n\
hip_cb_fun_t cb_fun_; \\\n\
void* cb_arg_; \\\n\
}; \\\n\
hip_cb_data_t cb_data{}; \\\n\
INIT_CB_ARGS_DATA(cb_id, cb_data); \\\n\
api_callbacks_spawner_t api_callbacks_spawner(cb_data); \n\
')
f.write('#endif // HIP__CBSTR__');
print "Header '" + HEADER + "' is generated"
#############################################################