80 std::vector<filedesc> filelist;
87 for (
auto it = filelist.begin(); it != filelist.end(); ++it) {
94 void add_opened_module(
void* module,
const std::string& name,
bool clean_up)
99 fd.clean_up = clean_up;
100 filelist.push_back(fd);
105 void clean_up(
const std::vector<filedesc>::const_iterator it)
109 remove(it->name.c_str());
116 void create_src_file(std::string& filename, std::ofstream& ofs)
118 if (filename.empty()) {
120 const char* filename_pattern =
"./GiNaCXXXXXX";
121 char* new_filename =
new char[strlen(filename_pattern)+1];
122 strcpy(new_filename, filename_pattern);
123 int fd = mkstemp(new_filename);
125 delete[] new_filename;
126 throw std::runtime_error(
"mkstemp failed");
128 filename = std::string(new_filename);
129 ofs.open(new_filename, std::ios::out);
131 delete[] new_filename;
134 ofs.open(filename.c_str(), std::ios::out);
138 throw std::runtime_error(
"could not create source code file for compilation");
141 ofs <<
"#include <stddef.h> " << std::endl;
142 ofs <<
"#include <stdlib.h> " << std::endl;
143 ofs <<
"#include <math.h> " << std::endl;
151 void compile_src_file(
const std::string filename,
bool clean_up)
153 std::string strcompile = LIBEXECDIR
"ginac-excompiler " + filename;
154 if (system(strcompile.c_str())) {
155 throw std::runtime_error(
"excompiler::compile_src_file: error compiling source file!");
158 remove(filename.c_str());
164 void* link_so_file(
const std::string filename,
bool clean_up)
166 void* module =
nullptr;
167 module = dlopen(filename.c_str(), RTLD_NOW);
168 if (module ==
nullptr) {
169 throw std::runtime_error(
"excompiler::link_so_file: could not open compiled module!");
172 add_opened_module(module, filename, clean_up);
174 return dlsym(module,
"compiled_ex");
180 void unlink(
const std::string filename)
182 for (
auto it = filelist.begin(); it != filelist.end();) {
183 if (it->name == filename) {
185 it = filelist.erase(it);
203static excompiler global_excompiler;
205void compile_ex(
const ex& expr,
const symbol& sym,
FUNCP_1P& fp,
const std::string filename)
208 ex expr_with_x = expr.subs(
lst{sym==
x});
211 std::string unique_filename = filename;
212 global_excompiler.create_src_file(unique_filename, ofs);
214 ofs <<
"double compiled_ex(double x)" << std::endl;
215 ofs <<
"{" << std::endl;
216 ofs <<
"double res = ";
218 ofs <<
";" << std::endl;
219 ofs <<
"return(res); " << std::endl;
220 ofs <<
"}" << std::endl;
224 global_excompiler.compile_src_file(unique_filename, filename.empty());
227 fp = (
FUNCP_1P) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
230void compile_ex(
const ex& expr,
const symbol& sym1,
const symbol& sym2,
FUNCP_2P& fp,
const std::string filename)
232 symbol
x(
"x"), y(
"y");
233 ex expr_with_xy = expr.subs(
lst{sym1==
x, sym2==y});
236 std::string unique_filename = filename;
237 global_excompiler.create_src_file(unique_filename, ofs);
239 ofs <<
"double compiled_ex(double x, double y)" << std::endl;
240 ofs <<
"{" << std::endl;
241 ofs <<
"double res = ";
243 ofs <<
";" << std::endl;
244 ofs <<
"return(res); " << std::endl;
245 ofs <<
"}" << std::endl;
249 global_excompiler.compile_src_file(unique_filename, filename.empty());
252 fp = (
FUNCP_2P) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
258 for (std::size_t count=0; count<
syms.nops(); ++count) {
259 std::ostringstream s;
260 s <<
"a[" << count <<
"]";
261 replacements.append(
syms.op(count) == symbol(s.str()));
264 std::vector<ex> expr_with_cname;
265 for (std::size_t count=0; count<exprs.nops(); ++count) {
266 expr_with_cname.push_back(exprs.op(count).subs(replacements));
270 std::string unique_filename = filename;
271 global_excompiler.create_src_file(unique_filename, ofs);
273 ofs <<
"void compiled_ex(const int* an, const double a[], const int* fn, double f[])" << std::endl;
274 ofs <<
"{" << std::endl;
275 for (std::size_t count=0; count<exprs.nops(); ++count) {
276 ofs <<
"f[" << count <<
"] = ";
278 ofs <<
";" << std::endl;
280 ofs <<
"}" << std::endl;
284 global_excompiler.compile_src_file(unique_filename, filename.empty());
287 fp = (
FUNCP_CUBA) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
294 fp = (
FUNCP_1P) global_excompiler.link_so_file(filename,
false);
301 fp = (
FUNCP_2P) global_excompiler.link_so_file(filename,
false);
308 fp = (
FUNCP_CUBA) global_excompiler.link_so_file(filename,
false);
311void unlink_ex(
const std::string filename)
313 global_excompiler.unlink(filename);
325 throw std::runtime_error(
"compile_ex has been disabled because of missing libdl!");
330 throw std::runtime_error(
"compile_ex has been disabled because of missing libdl!");
335 throw std::runtime_error(
"compile_ex has been disabled because of missing libdl!");
340 throw std::runtime_error(
"link_ex has been disabled because of missing libdl!");
345 throw std::runtime_error(
"link_ex has been disabled because of missing libdl!");
350 throw std::runtime_error(
"link_ex has been disabled because of missing libdl!");
355 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.