def _make_jit_function(f: cs.Function): """ Compiles casadi function into a shared object and return it :return: """ import filecmp import os gen_code_path = 'ilqr_generated_{}.c'.format(f.name()) f.generate(gen_code_path) gen_lib_path = 'ilqr_generated_{}.so'.format(f.name()) gcc_cmd = 'gcc {} -shared -fPIC -O3 -o {}'.format( gen_code_path, gen_lib_path) if os.system(gcc_cmd) != 0: raise SystemError('Unable to compile function "{}"'.format( f.name())) jit_f = cs.external(f.name(), './' + gen_lib_path) os.remove(gen_code_path) os.remove(gen_lib_path) return jit_f
def create_function(name, inp, out, options): codegen = options['codegen'] if options['verbose'] >= 1: print('Building function %s ... ' % name, end=' ') t0 = time.time() fun = Function(name, inp, out).expand() if codegen['build'] == 'jit': if options['verbose'] >= 1: print(('[jit compilation with flags %s]' % (codegen['flags'])), end=' ') fun.generate(name) compiler = Compiler(name + '.c', 'clang', {'flags': codegen['flags']}) fun = external(name, compiler) os.remove(name + '.c') elif codegen['build'] == 'shared': if os.name == 'nt': raise ValueError('Build option is not supported for Windows!') directory = os.path.join(os.getcwd(), 'build') if not os.path.isdir(directory): os.makedirs(directory) path = os.path.join(directory, name) if options['verbose'] >= 1: print(('[compile to .so with flags %s]' % (codegen['flags'])), end=' ') if os.path.isfile(path + '.so'): os.remove(path + '.so') fun.generate(name + '.c') shutil.move(name + '.c', path + '.c') os.system('gcc -fPIC -shared %s %s.c -o %s.so' % (codegen['flags'], path, path)) fun = external(name, path + '.so') os.remove(path + '.c') elif codegen['build'] == 'existing': if os.name == 'nt': raise ValueError('Build option is not supported for Windows!') directory = os.path.join(os.getcwd(), 'build') path = os.path.join(directory, name) if not os.path.isfile(path + '.so'): raise ValueError('%s.so does not exist!', path) if options['verbose'] >= 1: print(('[using shared object %s.so]' % path), end=' ') fun = external(name, path + '.so') elif codegen['build'] is None: fun = fun else: raise ValueError('Invalid build option.') t1 = time.time() if options['verbose'] >= 1: print('in %5f s' % (t1 - t0)) return fun, (t1 - t0)
def generate_c_code_external_cost(model, is_terminal): casadi_version = CasadiMeta.version() casadi_opts = dict(mex=False, casadi_int="int", casadi_real="double") if casadi_version not in (ALLOWED_CASADI_VERSIONS): casadi_version_warning(casadi_version) x = model.x p = model.p if isinstance(x, MX): symbol = MX.sym else: symbol = SX.sym if is_terminal: suffix_name = "_cost_ext_cost_e_fun" suffix_name_hess = "_cost_ext_cost_e_fun_jac_hess" suffix_name_jac = "_cost_ext_cost_e_fun_jac" u = symbol("u", 0, 0) ext_cost = model.cost_expr_ext_cost_e else: suffix_name = "_cost_ext_cost_fun" suffix_name_hess = "_cost_ext_cost_fun_jac_hess" suffix_name_jac = "_cost_ext_cost_fun_jac" u = model.u ext_cost = model.cost_expr_ext_cost # set up functions to be exported fun_name = model.name + suffix_name fun_name_hess = model.name + suffix_name_hess fun_name_jac = model.name + suffix_name_jac # generate expression for full gradient and Hessian full_hess, grad = hessian(ext_cost, vertcat(u, x)) ext_cost_fun = Function(fun_name, [x, u, p], [ext_cost]) ext_cost_fun_jac_hess = Function( fun_name_hess, [x, u, p], [ext_cost, grad, full_hess] ) ext_cost_fun_jac = Function( fun_name_jac, [x, u, p], [ext_cost, grad] ) # generate C code if not os.path.exists("c_generated_code"): os.mkdir("c_generated_code") os.chdir("c_generated_code") gen_dir = model.name + '_cost' if not os.path.exists(gen_dir): os.mkdir(gen_dir) gen_dir_location = "./" + gen_dir os.chdir(gen_dir_location) ext_cost_fun.generate(fun_name, casadi_opts) ext_cost_fun_jac_hess.generate(fun_name_hess, casadi_opts) ext_cost_fun_jac.generate(fun_name_jac, casadi_opts) os.chdir("../..") return
def generate_c_code_external_cost(model, is_terminal): casadi_version = CasadiMeta.version() casadi_opts = dict(mex=False, casadi_int="int", casadi_real="double") if casadi_version not in (ALLOWED_CASADI_VERSIONS): msg = "Please download and install CasADi {} ".format( " or ".join(ALLOWED_CASADI_VERSIONS)) msg += "to ensure compatibility with acados.\n" msg += "Version {} currently in use.".format(casadi_version) raise Exception(msg) if is_terminal: suffix_name = "_ext_cost_e_fun" suffix_name_hess = "_ext_cost_e_fun_jac_hess" u = SX.sym("u", 0, 0) ext_cost = model.cost_expr_ext_cost_e else: suffix_name = "_ext_cost_fun" suffix_name_hess = "_ext_cost_fun_jac_hess" u = model.u ext_cost = model.cost_expr_ext_cost x = model.x p = model.p # set up functions to be exported fun_name = model.name + suffix_name fun_name_hess = model.name + suffix_name_hess # generate jacobians jac_x = jacobian(ext_cost, x) jac_u = jacobian(ext_cost, u) # generate hessians hess_uu = jacobian(jac_u.T, u) hess_xu = jacobian(jac_u.T, x) hess_ux = jacobian(jac_x.T, u) hess_xx = jacobian(jac_x.T, x) full_hess = vertcat(horzcat(hess_uu, hess_xu), horzcat(hess_ux, hess_xx)) ext_cost_fun = Function(fun_name, [x, u, p], [ext_cost]) ext_cost_fun_jac_hess = Function( fun_name_hess, [x, u, p], [ext_cost, vertcat(jac_u.T, jac_x.T), full_hess]) # generate C code if not os.path.exists("c_generated_code"): os.mkdir("c_generated_code") os.chdir("c_generated_code") gen_dir = model.name + '_cost' if not os.path.exists(gen_dir): os.mkdir(gen_dir) gen_dir_location = "./" + gen_dir os.chdir(gen_dir_location) ext_cost_fun.generate(fun_name, casadi_opts) ext_cost_fun_jac_hess.generate(fun_name_hess, casadi_opts) os.chdir("../..") return
def generate_c_code_external_cost(model, stage_type, opts): casadi_version = CasadiMeta.version() casadi_opts = dict(mex=False, casadi_int="int", casadi_real="double") if casadi_version not in (ALLOWED_CASADI_VERSIONS): casadi_version_warning(casadi_version) x = model.x p = model.p if isinstance(x, MX): symbol = MX.sym else: symbol = SX.sym if stage_type == 'terminal': suffix_name = "_cost_ext_cost_e_fun" suffix_name_hess = "_cost_ext_cost_e_fun_jac_hess" suffix_name_jac = "_cost_ext_cost_e_fun_jac" u = symbol("u", 0, 0) ext_cost = model.cost_expr_ext_cost_e custom_hess = model.cost_expr_ext_cost_custom_hess_e elif stage_type == 'path': suffix_name = "_cost_ext_cost_fun" suffix_name_hess = "_cost_ext_cost_fun_jac_hess" suffix_name_jac = "_cost_ext_cost_fun_jac" u = model.u ext_cost = model.cost_expr_ext_cost custom_hess = model.cost_expr_ext_cost_custom_hess elif stage_type == 'initial': suffix_name = "_cost_ext_cost_0_fun" suffix_name_hess = "_cost_ext_cost_0_fun_jac_hess" suffix_name_jac = "_cost_ext_cost_0_fun_jac" u = model.u ext_cost = model.cost_expr_ext_cost_0 custom_hess = model.cost_expr_ext_cost_custom_hess_0 # set up functions to be exported fun_name = model.name + suffix_name fun_name_hess = model.name + suffix_name_hess fun_name_jac = model.name + suffix_name_jac # generate expression for full gradient and Hessian full_hess, grad = hessian(ext_cost, vertcat(u, x)) if custom_hess is not None: full_hess = custom_hess ext_cost_fun = Function(fun_name, [x, u, p], [ext_cost]) ext_cost_fun_jac_hess = Function(fun_name_hess, [x, u, p], [ext_cost, grad, full_hess]) ext_cost_fun_jac = Function(fun_name_jac, [x, u, p], [ext_cost, grad]) # generate C code code_export_dir = opts["code_export_directory"] if not os.path.exists(code_export_dir): os.makedirs(code_export_dir) cwd = os.getcwd() os.chdir(code_export_dir) gen_dir = model.name + '_cost' if not os.path.exists(gen_dir): os.mkdir(gen_dir) gen_dir_location = "./" + gen_dir os.chdir(gen_dir_location) ext_cost_fun.generate(fun_name, casadi_opts) ext_cost_fun_jac_hess.generate(fun_name_hess, casadi_opts) ext_cost_fun_jac.generate(fun_name_jac, casadi_opts) os.chdir(cwd) return