Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/cuda/src/fi/json_to_python.py
ViewVC logotype

View of /branches/cuda/src/fi/json_to_python.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5597 - (download) (as text) (annotate)
Mon Jun 21 17:51:35 2021 UTC (10 months, 3 weeks ago) by jhr
File size: 19126 byte(s)
  populate new CUDA branch with Adrian's code
#! /usr/bin/python

# version 1.6 put pass by reference wrapper class into the program class
# AND added nrrd functions to wrapper
import json, os, sys
from pprint import pprint

global program_FFI 
global lib_program
global json_found
global brackets
json_found = False

brackets = ""

#allows the file to be run from command line
os.system("chmod +x json_to_python.py")

#path to the directory with json
path = os.path.dirname(os.path.abspath(__file__))

#looks for json and opens it if exits
for file in os.listdir(path):
	if file.endswith(".json"):
		with open(file) as data_file:
			json_found = True
			data = json.load(data_file)
		
			
program_FFI = data["program"]+"FFI"
lib_program = "lib" + data["program"]


#this parses the type of a C-type variable from the JSON file
def parse_type(obj):
	global brackets
	if "kind" in obj:
		#if the "kind" is a pointer, then put to end of type
		if obj["kind"] == "const" or obj["kind"] == "extern":
			return obj["kind"] + " " + parse_type(obj["arg"])
		#any other "kind" goes in front, such as "const" or "extern"
		elif obj["kind"] == "[]":
			if "size" in obj:
				brackets = "[" + str(obj["size"]) + "]"
			else:
				brackets = "[]"
			return obj["arg"]
		else:
			return parse_type(obj["arg"]) + obj["kind"]
	else:
		return obj


##################### START OF CDEF USING CFFI ########################

#returns a string that is the parameters of the function returned in
#"create_proto"
def create_params_proto(obj):
	#obj = data[purpose][index][func]
	global brackets
	length  = len(obj["params"])
	params = ""
	for i in range(length):
		if i != length-1:
			params += (parse_type(obj["params"][i]["param-ty"]) + " " + 
				obj["params"][i]["name"] + brackets + ", ")
			brackets = ""
		else:
			params += (parse_type(obj["params"][i]["param-ty"]) + " " + 
				obj["params"][i]["name"] + brackets)
			brackets = ""
	return params


#creates the c-prototype functions that typically go inside a ".h" file
def create_proto(purpose, index, func):
	global brackets
	if purpose == "strand":
		obj = data[purpose]["state-vars"][index][func]
	else:
		obj = data[purpose][index][func]
	proto = (parse_type(obj["return-ty"]) + " " + obj["name"] 
		+ "(" + create_params_proto(obj) + ");")
	brackets = ""
	return proto

#returns a string that is the parameters of the function returned in
#"create_proto" for arrays
def create_params_proto_array(obj):
	global brackets
	#obj = data[purpose][index][func][func_index]
	length  = len(obj["params"])
	params = ""
	for i in range(length):
		if i != length-1:
			params += (parse_type(obj["params"][i]["param-ty"]) + " " + 
				obj["params"][i]["name"] + brackets + ", ")
			brackets = ""
		else:
			params += (parse_type(obj["params"][i]["param-ty"]) + " " + 
				obj["params"][i]["name"] + brackets)
			brackets = ""
	return params


#creates the c-prototype functions that go inside a ".h" file for arrays
def create_proto_array(purpose, index, func, func_index):
	global brackets
	obj = data[purpose][index][func][func_index]
	proto = (parse_type(obj["return-ty"]) + " " + obj["name"] 
		+ "(" + create_params_proto_array(obj) + ");")
	brackets = ""
	return proto

#prints all prototype functions in a cdef for CFFI's "inline ABI mode"
def print_cdef(file):
	file.write("  " + program_FFI + " = FFI()\n  " + program_FFI + 
		".include(teemFFI)\n""  " + program_FFI + ".cdef(\n    \"\"\"\n")
	#all possible purposes
	obj_array = ["inputs", "runtime", "outputs"]
	len1 = len(obj_array)

	#len3 = len(extern_const_array)
	file.write("    typedef struct Diderot_struct_world Diderot_world_t;\n")
	'''for k in range(len3):
		file.write("    " + "extern const char *Diderot_input_desc_" 
			+ extern_const_array[k] + ";\n")'''
	#loop through the array of purposes
	for j in range(len1):
		obj = data[obj_array[j]]
		len2 = len(obj)
		for i in range(len2):
			#each "if" checks if there exists a "func", "set", or "get" 
			#function(s) in the object
			if "func" in obj[i]:
				# this inner "if-else" checks whether there are 
				# multiple func functions in the object 
				#(that is there exists an array)
				if isinstance(obj[i]["func"], list):
					len4 = len(obj[i]["func"])
					for l in range(len4):
						file.write("    " + 
							create_proto_array(obj_array[j], 
								i, "func", l) + "\n")
				else:
					file.write("    " + create_proto(obj_array[j],
						i,"func") + "\n")
			if "set" in obj[i]:
				# this inner "if-else" checks whether there are 
				# multiple set functions in the object 
				#(that is there exists an array)
				if isinstance(obj[i]["set"], list):
					len4 = len(obj[i]["set"])
					for l in range(len4):
						file.write("    " + create_proto_array(obj_array[j], 
							i, "set", l) + "\n")
				else:
					file.write("    " + create_proto(obj_array[j],
						i,"set") + "\n")
			if "get" in obj[i]:
				# this inner "if-else" checks whether there are 
				# multiple get functions in the object 
				#(that is there exists an array)
				if isinstance(obj[i]["get"], list):
					len4 = len(obj[i]["get"])
					for l in range(len4):
						file.write("    " + create_proto_array(obj_array[j], 
							i, "get", l) + "\n")
				else:
					file.write("    " + create_proto(obj_array[j],
						i,"get") + "\n")
	#####################################################
	obj = data["strand"]["state-vars"]
	len2 = len(obj)
	for i in range(len2):
		#each "if" checks if there exists a "func", "set", or "get" 
		#function(s) in the object
		if "func" in obj[i]:
			# this inner "if-else" checks whether there are 
			# multiple func functions in the object 
			#(that is there exists an array)
			if isinstance(obj[i]["func"], list):
				len4 = len(obj[i]["func"])
				for l in range(len4):
					file.write("    " + 
						create_proto_array("strand", 
							i, "func", l) + "\n")
			else:
				file.write("    " + create_proto("strand",
					i,"func") + "\n")
		if "set" in obj[i]:
			# this inner "if-else" checks whether there are 
			# multiple set functions in the object 
			#(that is there exists an array)
			if isinstance(obj[i]["set"], list):
				len4 = len(obj[i]["set"])
				for l in range(len4):
					file.write("    " + create_proto_array("strand", 
						i, "set", l) + "\n")
			else:
				file.write("    " + create_proto("strand",
					i,"set") + "\n")
		if "get" in obj[i]:
			# this inner "if-else" checks whether there are 
			# multiple get functions in the object 
			#(that is there exists an array)
			if isinstance(obj[i]["get"], list):
				len4 = len(obj[i]["get"])
				for l in range(len4):
					file.write("    " + create_proto_array("strand", 
						i, "get", l) + "\n")
			else:
				file.write("    " + create_proto("strand",
					i,"get") + "\n")
	file.write("    \"\"\")\n")

##################### END OF CDEF USING CFFI ############################

#################### START OF PYTHON CLASS SCRIPT ########################
#returns a string that is the parameters of the function returned in
#"create_func"
def create_params(obj):
	#obj = data[purpose][index][func]
	length  = len(obj["params"])
	params = ""
	for i in range(length):
		if i != length-1:
			if "*" in parse_type(obj["params"][i]["param-ty"]) and parse_type(obj["params"][i]["param-ty"]) != "Diderot_world_t*":
				params += (obj["params"][i]["name"] + ".var, ")
			else:
				params += (obj["params"][i]["name"] + ", ")
		else:
			if "*" in parse_type(obj["params"][i]["param-ty"]) and parse_type(obj["params"][i]["param-ty"]) != "Diderot_world_t*":
				params += (obj["params"][i]["name"] + ".var")
			else:
				params += (obj["params"][i]["name"])
		brackets = ""
	return params

#returns a string that is the parameters of the function returned in
#"create_func"
def create_params_array(obj):
	#obj = data[purpose][index][func][func_index]
	length  = len(obj["params"])
	params = ""
	for i in range(length):
		if i != length-1:
			if "*" in parse_type(obj["params"][i]["param-ty"]) and parse_type(obj["params"][i]["param-ty"]) != "Diderot_world_t*":
				params += (obj["params"][i]["name"] + ".var, ")
			else:
				params += (obj["params"][i]["name"] + ", ")
		else:
			if "*" in parse_type(obj["params"][i]["param-ty"]) and parse_type(obj["params"][i]["param-ty"]) != "Diderot_world_t*":
				params += (obj["params"][i]["name"] + ".var")
			else:
				params += (obj["params"][i]["name"])
		brackets = ""
	return params

#creates the call to the diderot function in question
#this call is to be wrapped by a python equivalent function call
#ex: self.lib
def create_func(obj):
	#obj = data[purpose][index][func]
	proto = ("self." + lib_program +"." + obj["name"] 
		+ "(" + create_params(obj) + ")")
	return proto

def create_func_array(obj):
	#obj = data[purpose][index][func][func_index]
	proto = ("self." + lib_program +"." + obj["name"] 
		+ "(" + create_params_array(obj) + ")")
	return proto

def create_wrapper(purpose, index, func):
	global brackets
	params = ""
	middle = ""
	if purpose == "strand":
		obj = data[purpose]["state-vars"][index][func]
		num_params = len(obj["params"])
		for i in range(num_params):
			ty = parse_type(obj["params"][i]["param-ty"])
			if (ty != "Diderot_world_t*") and (ty != "Nrrd*"):
				if "*" in ty:
					middle += ("    " + obj["params"][i]["name"] + 
						".var = teemFFI.new(\"" + ty + "\")\n")
				params += ("," + obj["params"][i]["name"])
			elif (ty == "Nrrd*"):
				middle += ("    " + obj["params"][i]["name"] + 
					".var = self.libTeem.nrrdNew()\n")
				params += ("," + obj["params"][i]["name"])
			brackets = ""
		if (func == "get") or (func == "set"):
			firstline = ("  def " + func + "_" + 
				data[purpose]["state-vars"][index]["name"] + "(self" + params + "):\n")
		else:
			firstline = ("  def " + 
				data[purpose]["state-vars"][index]["name"] + "(self" + params + "):\n")
		if obj["return-ty"] != "void":
			lastline = "    return " + create_func(obj) + "\n"
		else:
			lastline = "    " + create_func(obj) + "\n"

		#if(obj["name"] = "Diderot_output_get_vrie")
		return firstline + middle + lastline
	else:
		obj = data[purpose][index][func]
		num_params = len(obj["params"])
		for i in range(num_params):
			ty = parse_type(obj["params"][i]["param-ty"])
			if (ty != "Diderot_world_t*") and (ty != "Nrrd*"):
				if "*" in ty:
					middle += ("    " + obj["params"][i]["name"] + 
						".var = teemFFI.new(\"" + ty + "\")\n")
				params += ("," + obj["params"][i]["name"])
			elif (ty == "Nrrd*"):
				middle += ("    " + obj["params"][i]["name"] + 
					".var = self.libTeem.nrrdNew()\n")
				params += ("," + obj["params"][i]["name"])
			brackets = ""
		if (func == "get") or (func == "set"):
			firstline = ("  def " + func + "_" + 
				data[purpose][index]["name"] + "(self" + params + "):\n")
		else:
			firstline = ("  def " + 
				data[purpose][index]["name"] + "(self" + params + "):\n")
		if obj["return-ty"] != "void":
			lastline = "    return " + create_func(obj) + "\n"
		else:
			lastline = "    " + create_func(obj) + "\n"

		#if(obj["name"] = "Diderot_output_get_vrie")
		return firstline + middle + lastline

def create_wrapper_array(purpose, index, func, func_index):
	global brackets
	params = ""
	middle = ""
	if purpose == "strand":
		obj = data[purpose]["state-vars"][index][func][func_index]
		num_params = len(obj["params"])
		for i in range(num_params):
			ty = parse_type(obj["params"][i]["param-ty"])
			if (ty != "Diderot_world_t*") and (ty != "Nrrd*"):
				if "*" in ty:
					middle += ("    " + obj["params"][i]["name"] + 
						".var = teemFFI.new(\"" + ty + "\")\n")
				params += ("," + obj["params"][i]["name"])
			elif (ty == "Nrrd*"):
				middle += ("    " + obj["params"][i]["name"] + 
					".var = self.libTeem.nrrdNew()\n")
				params += ("," + obj["params"][i]["name"])
			brackets = ""
		if (func == "get") or (func == "set"):
			firstline = ("  def " + func + "_" + data[purpose]["state-vars"][index]["name"] + 
				"_" + str(func_index) + "(self" + params + "):\n")
		else:
			firstline = ("  def " + data[purpose]["state-vars"][index]["name"] + 
				"_" + str(func_index) + "(self" + params + "):\n")
		if obj["return-ty"] != "void":
			secondline = "    return " + create_func_array(obj) + "\n"
		else:
			secondline = "    " + create_func_array(obj) + "\n"
		return firstline + secondline
	else:
		obj = data[purpose][index][func][func_index]
		num_params = len(obj["params"])
		for i in range(num_params):
			ty = parse_type(obj["params"][i]["param-ty"])
			if (ty != "Diderot_world_t*") and (ty != "Nrrd*"):
				if "*" in ty:
					middle += ("    " + obj["params"][i]["name"] + 
						".var = teemFFI.new(\"" + ty + "\")\n")
				params += ("," + obj["params"][i]["name"])
			elif (ty == "Nrrd*"):
				middle += ("    " + obj["params"][i]["name"] + 
					".var = self.libTeem.nrrdNew()\n")
				params += ("," + obj["params"][i]["name"])
			brackets = ""
		if (func == "get") or (func == "set"):
			firstline = ("  def " + func + "_" + data[purpose][index]["name"] + 
				"_" + str(func_index) + "(self" + params + "):\n")
		else:
			firstline = ("  def " + data[purpose][index]["name"] + 
				"_" + str(func_index) + "(self" + params + "):\n")
		if obj["return-ty"] != "void":
			secondline = "    return " + create_func_array(obj) + "\n"
		else:
			secondline = "    " + create_func_array(obj) + "\n"
		return firstline + secondline

# writes all of the equivalent python functions into _class.py
def print_wrapper(file):
	file.write("  def __init__(self):\n" + 
		"    self.libTeem = teemFFI.dlopen(\"/usr/local/lib/libteem.so\")\n" + 
		"    self." + lib_program + " = " + program_FFI + ".dlopen(\"" + path + 
		"/" + data["program"] + ".so\")\n" + 
		"    global wrld\n" + 
		"    wrld = self." + lib_program + ".Diderot_new_world()\n\n")
	# obj_array: an array of all the JSON purposes possible
	obj_array = ["inputs", "runtime", "outputs"] 
	len1 = len(obj_array)
	# loop through the possible purposes
	for j in range(len1):
		obj = data[obj_array[j]]
		len2 = len(obj)
		for i in range(len2):
			# each outer "if-else" checks if the object has a "get", 
			# "set", or "func" function(s)
			if "func" in obj[i]:
				# this inner "if-else" checks whether there are 
				# multiple func functions in the object 
				# (that is there exists an array)
				if isinstance(obj[i]["func"], list):
					len4 = len(obj[i]["func"])
					for l in range(len4):
						file.write(create_wrapper_array(obj_array[j], 
							i, "func", l) + "\n")
				else:
					file.write(create_wrapper(obj_array[j],i,"func") + "\n")
			if "set" in obj[i]:
				# this inner "if-else" checks whether there are 
				# multiple set functions in the object 
				# (that is there exists an array)
				if isinstance(obj[i]["set"], list):
					len4 = len(obj[i]["set"])
					for l in range(len4):
						file.write(create_wrapper_array(obj_array[j], 
							i, "set", l) + "\n")
				else:
					file.write(create_wrapper(obj_array[j],i,"set") + "\n")
			if "get" in obj[i]:
				# this inner "if-else" checks whether there are 
				# multiple get functions in the object 
				# (that is there exists an array)
				if isinstance(obj[i]["get"], list):
					len4 = len(obj[i]["get"])
					for l in range(len4):
						file.write(create_wrapper_array(obj_array[j], 
							i, "get", l) + "\n")
				else:
					file.write(create_wrapper(obj_array[j],i,"get") + "\n")
	########################################################################
	obj = data["strand"]["state-vars"]
	len2 = len(obj)
	for i in range(len2):
		# each outer "if-else" checks if the object has a "get", 
		# "set", or "func" function(s)
		if "func" in obj[i]:
			# this inner "if-else" checks whether there are 
			# multiple func functions in the object 
			# (that is there exists an array)
			if isinstance(obj[i]["func"], list):
				len4 = len(obj[i]["func"])
				for l in range(len4):
					file.write(create_wrapper_array("strand", 
						i, "func", l) + "\n")
			else:
				file.write(create_wrapper("strand",i,"func") + "\n")
		if "set" in obj[i]:
			# this inner "if-else" checks whether there are 
			# multiple set functions in the object 
			# (that is there exists an array)
			if isinstance(obj[i]["set"], list):
				len4 = len(obj[i]["set"])
				for l in range(len4):
					file.write(create_wrapper_array("strand", 
						i, "set", l) + "\n")
			else:
				file.write(create_wrapper("strand",i,"set") + "\n")
		if "get" in obj[i]:
			# this inner "if-else" checks whether there are 
			# multiple get functions in the object 
			# (that is there exists an array)
			if isinstance(obj[i]["get"], list):
				len4 = len(obj[i]["get"])
				for l in range(len4):
					file.write(create_wrapper_array("strand", 
						i, "get", l) + "\n")
			else:
				file.write(create_wrapper("strand",i,"get") + "\n")

######################## END OF PYTHON CLASS SCRIPT ###########################

######################## NRRD FUNCTIONS ######################################


######################## NRRD FUNCTIONS END #################################
def print_nrrd(file):
	file.write("""  def nrrdNew(self):
	return self.libTeem.nrrdNew()

  def nrrdNix(self, nrrd):
	return self.libTeem.nrrdNix(nrrd)
  
  def nrrdEmpty(self, nrrd):
	return self.libTeem.nrrdEmpty(nrrd)
  
  def nrrdNuke(self, nrrd):
	return self.libTeem.nrrdEmpty(nrrd)  

  def nrrdSave(self, nrrd, filename):
	return self.libTeem.nrrdSave(filename, nrrd, teemFFI.NULL)

  def nrrdLoad(self, nrrd, filename):
	return self.libTeem.nrrdLoad(nrrd,filename,teemFFI.NULL)\n  
""")
######################## EXECUTION OF SCRIPT #################################

#checks if the JSON file is found or not
if not json_found:
	print("Error: JSON file:" + " not found")
	sys.exit()

pass_reference_class = """class data_wrapper:
  def __init__(self):
	c_type = teemFFI.cast("void*", 0)
	self.var = c_type\n\n"""

file = open(data["program"] + "_class.py", "w+")
file.write("from cffi import FFI\n" + "import os\n\n" + pass_reference_class + "class " + data["program"] 
	+ ":\n  global libTeem\n" + "  global teemFFI\n" + "  global " + program_FFI
	+ "\n  global " + lib_program + "\n" + 
  """  
  teemFFI = FFI()
  teemFFI.cdef(
	\"\"\"
	#define NRRD_DIM_MAX 16
	#define NRRD_SPACE_DIM_MAX 8
	typedef struct {
	  size_t size;
	  double spacing;
	  double thickness;
	  double min, max;
	  double spaceDirection[NRRD_SPACE_DIM_MAX];
	  int center;
	  int kind;
	  char *label,*units;
	} NrrdAxisInfo;
	typedef struct {
	  void *data;
	  int type;
	  unsigned int dim;
	  NrrdAxisInfo axis[NRRD_DIM_MAX];
	  char *content;
	  char *sampleUnits;
	  int space;
	  unsigned int spaceDim;
	  char *spaceUnits[NRRD_SPACE_DIM_MAX];
	  double spaceOrigin[NRRD_SPACE_DIM_MAX];
	  double measurementFrame[NRRD_SPACE_DIM_MAX][NRRD_SPACE_DIM_MAX];
	  size_t blockSize;
	  double oldMin, oldMax;
	  void *ptr;
	  char **cmt;
	  void *cmtArr;
	  char **kvp;
	  void *kvpArr;
	} Nrrd;
	Nrrd *nrrdNew(void);
	Nrrd *nrrdNix(Nrrd *nrrd);
	Nrrd *nrrdEmpty(Nrrd *nrrd);
	Nrrd *nrrdNuke(Nrrd *nrrd);
	int nrrdSave(const char *filename, const Nrrd *nrrd,
						 void *nio);
	int nrrdLoad(Nrrd *nrrd, const char *filename, void *nio);
	\"\"\")\n""")

print_cdef(file)
print_wrapper(file)
print_nrrd(file)
file.close()

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0