79 std::vector<filedesc> filelist;
86 for (
auto it = filelist.begin(); it != filelist.end(); ++it) {
93 void add_opened_module(
void* module,
const std::string& name,
bool clean_up)
98 fd.clean_up = clean_up;
99 filelist.push_back(fd);
104 void clean_up(
const std::vector<filedesc>::const_iterator it)
108 remove(it->name.c_str());
115 void create_src_file(std::string& filename, std::ofstream& ofs)
117 if (filename.empty()) {
119 const char* filename_pattern =
"./GiNaCXXXXXX";
120 char* new_filename =
new char[strlen(filename_pattern)+1];
121 strcpy(new_filename, filename_pattern);
122 int fd = mkstemp(new_filename);
124 delete[] new_filename;
125 throw std::runtime_error(
"mkstemp failed");
127 filename = std::string(new_filename);
128 ofs.open(new_filename, std::ios::out);
130 delete[] new_filename;
133 ofs.open(filename.c_str(), std::ios::out);
137 throw std::runtime_error(
"could not create source code file for compilation");
140 ofs <<
"#include <stddef.h> " << std::endl;
141 ofs <<
"#include <stdlib.h> " << std::endl;
142 ofs <<
"#include <math.h> " << std::endl;
150 void compile_src_file(
const std::string filename,
bool clean_up)
152 std::string strcompile = LIBEXECDIR
"ginac-excompiler " + filename;
153 if (system(strcompile.c_str())) {
154 throw std::runtime_error(
"excompiler::compile_src_file: error compiling source file!");
157 remove(filename.c_str());
163 void* link_so_file(
const std::string filename,
bool clean_up)
165 void*
module = nullptr;
166 module = dlopen(filename.c_str(), RTLD_NOW);
167 if (module ==
nullptr) {
168 throw std::runtime_error(
"excompiler::link_so_file: could not open compiled module!");
171 add_opened_module(module, filename, clean_up);
173 return dlsym(module,
"compiled_ex");
179 void unlink(
const std::string filename)
181 for (
auto it = filelist.begin(); it != filelist.end();) {
182 if (it->name == filename) {
184 it = filelist.erase(it);
202static excompiler global_excompiler;
204void compile_ex(
const ex& expr,
const symbol& sym,
FUNCP_1P& fp,
const std::string filename)
207 ex expr_with_x = expr.subs(
lst{sym==
x});
210 std::string unique_filename = filename;
211 global_excompiler.create_src_file(unique_filename, ofs);
213 ofs <<
"double compiled_ex(double x)" << std::endl;
214 ofs <<
"{" << std::endl;
215 ofs <<
"double res = ";
217 ofs <<
";" << std::endl;
218 ofs <<
"return(res); " << std::endl;
219 ofs <<
"}" << std::endl;
223 global_excompiler.compile_src_file(unique_filename, filename.empty());
226 fp = (
FUNCP_1P) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
229void compile_ex(
const ex& expr,
const symbol& sym1,
const symbol& sym2,
FUNCP_2P& fp,
const std::string filename)
231 symbol
x(
"x"), y(
"y");
232 ex expr_with_xy = expr.subs(
lst{sym1==
x, sym2==y});
235 std::string unique_filename = filename;
236 global_excompiler.create_src_file(unique_filename, ofs);
238 ofs <<
"double compiled_ex(double x, double y)" << std::endl;
239 ofs <<
"{" << std::endl;
240 ofs <<
"double res = ";
242 ofs <<
";" << std::endl;
243 ofs <<
"return(res); " << std::endl;
244 ofs <<
"}" << std::endl;
248 global_excompiler.compile_src_file(unique_filename, filename.empty());
251 fp = (
FUNCP_2P) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
257 for (std::size_t count=0; count<
syms.nops(); ++count) {
258 std::ostringstream s;
259 s <<
"a[" << count <<
"]";
260 replacements.append(
syms.op(count) == symbol(s.str()));
263 std::vector<ex> expr_with_cname;
264 for (std::size_t count=0; count<exprs.nops(); ++count) {
265 expr_with_cname.push_back(exprs.op(count).subs(replacements));
269 std::string unique_filename = filename;
270 global_excompiler.create_src_file(unique_filename, ofs);
272 ofs <<
"void compiled_ex(const int* an, const double a[], const int* fn, double f[])" << std::endl;
273 ofs <<
"{" << std::endl;
274 for (std::size_t count=0; count<exprs.nops(); ++count) {
275 ofs <<
"f[" << count <<
"] = ";
277 ofs <<
";" << std::endl;
279 ofs <<
"}" << std::endl;
283 global_excompiler.compile_src_file(unique_filename, filename.empty());
286 fp = (
FUNCP_CUBA) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
293 fp = (
FUNCP_1P) global_excompiler.link_so_file(filename,
false);
300 fp = (
FUNCP_2P) global_excompiler.link_so_file(filename,
false);
307 fp = (
FUNCP_CUBA) global_excompiler.link_so_file(filename,
false);
310void unlink_ex(
const std::string filename)
312 global_excompiler.unlink(filename);
324 throw std::runtime_error(
"compile_ex has been disabled because of missing libdl!");
329 throw std::runtime_error(
"compile_ex has been disabled because of missing libdl!");
334 throw std::runtime_error(
"compile_ex has been disabled because of missing libdl!");
339 throw std::runtime_error(
"link_ex has been disabled because of missing libdl!");
344 throw std::runtime_error(
"link_ex has been disabled because of missing libdl!");
349 throw std::runtime_error(
"link_ex has been disabled because of missing libdl!");
354 throw std::runtime_error(
"unlink_ex has been disabled because of missing libdl!");
Wrapper template for making GiNaC classes out of STL containers.
Lightweight wrapper for GiNaC's symbolic objects.
Context for C source output using double precision.
Interface to GiNaC's light-weight expression handles.
Functions to facilitate the conversion of a ex to a function pointer suited for fast numerical integr...
Definition of GiNaC's lst.
container< std::list > lst
void compile_ex(const ex &expr, const symbol &sym, FUNCP_1P &fp, const std::string filename)
Takes an expression and produces a function pointer to the compiled and linked C code equivalent in d...
void(* FUNCP_CUBA)(const int *, const double[], const int *, double[])
Function pointer for use with the CUBA library (http://www.feynarts.de/cuba).
void link_ex(const std::string filename, FUNCP_1P &fp)
Opens an existing so-file and returns a function pointer of type FUNCP_1P to the contained function.
double(* FUNCP_1P)(double)
Function pointer with one function parameter.
void unlink_ex(const std::string filename)
Closes all linked .so files that have the supplied filename.
double(* FUNCP_2P)(double, double)
Function pointer with two function parameters.
Interface to GiNaC's overloaded operators.
Interface to relations between expressions.
Interface to GiNaC's symbolic objects.