【问题标题】:How to use Julia special functions inside c++如何在 C++ 中使用 Julia 特殊函数
【发布时间】:2021-03-27 01:25:37
【问题描述】:

您好,我想使用 Julia 实现的特殊功能 (https://juliamath.github.io/SpecialFunctions.jl/dev/functions_list/) 在 C++ 中。

按照手册 (https://docs.julialang.org/en/v1/manual/embedding/) 到目前为止我无法实现。

对于像 sqrt 这样的函数,我们有类似的东西

jl_function_t *func1 = jl_get_function(jl_base_module,"sqrt");

以类似的方式,这些特殊功能的module 是什么?

我尝试使用

jl_function_t *func2 = jl_get_function(jl_specialfunctions_module,"polygamma");

显示以下错误:

signal (11): Segmentation fault
in expression starting at none:0
jl_mutex_wait at /buildworker/worker/package_linux64/build/src/locks.h:24 [inlined]
jl_mutex_lock at /buildworker/worker/package_linux64/build/src/locks.h:94 [inlined]
jl_get_binding_ at /buildworker/worker/package_linux64/build/src/module.c:280
jl_get_global at /buildworker/worker/package_linux64/build/src/module.c:561
jl_get_function at ./test (unknown line)
main at ./test (unknown line)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at ./test (unknown line)
Allocations: 2544 (Pool: 2535; Big: 9); GC: 0

从手册中不清楚应该如何在 c++ 中使用这些特殊功能。 任何线索将不胜感激!

我发现 Federico 已经提出了这个问题(尤其是 polygamma):(How to call a julia method defined in an imported package from c++?): 示例如下:

  #include<iostream>
  #include<julia.h>
  JULIA_DEFINE_FAST_TLS() ;

int main(){
   jl_init();
   jl_eval_string("print(sqrt(2.0))"); // see that Julia works

   jl_module_t* jl_specialfunctions_module = (jl_module_t*) 
   jl_get_binding(jl_main_module, jl_symbol("SpecialFunctions"));
   jl_function_t* func2 = jl_get_function(jl_specialfunctions_module,"polygamma");
   jl_value_t *argument1 = jl_box_int64(1);
   jl_value_t *argument2 = jl_box_float64(2.0);
   jl_value_t *arguments[2] = { argument1 , argument2 };
   jl_value_t *ret = jl_call(func2, arguments, 2);

   if (jl_typeis(ret, jl_float64_type)) {
    double ret_unboxed = jl_unbox_float64(ret);
    std::cout << "julia = " << ret_unboxed << std::endl;
    }
   else {
    std::cout << "Error" << std::endl;
   }

   jl_atexit_hook(0);
   return 0;
 }

很遗憾那里没有答案!

当我尝试调整它时会发生类似的情况: https://discourse.julialang.org/t/jl-get-function-throwing-segmentation-fault/37186

注意:特殊功能扩展是通过import Pkg; Pkg.add("SpecialFunctions") 安装的,在julia shell 中可以访问特殊功能。

【问题讨论】:

  • 从表面上看,它看起来像是 Julia 源代码中的一个错误。你能发个minimal reproducible example吗?
  • 看起来你需要告诉 C++ 你是using SpecialFunctions。嵌入文档缺少 jl_module_import 和朋友的文档,但我认为这就是您所缺少的。

标签: c++ julia


【解决方案1】:

我回答了这个问题in the other stackoverflow thread

基本上,最简单的做法是使用 Julia @cfunction 构造让 Julia 将代码编译为 C++ 函数指针,然后您可以正常调用它而无需担心拆箱等。

(对于传递复数,@cfunction 可以利用 C++ std::complex&lt;double&gt; 和 Julia Complex{Float64} 具有相同的内存表示。)

【讨论】:

  • ,感谢您让我知道这种替代方法,并且可能是更好的方法。我也可以用它为polygamma 生成复杂参数的值,从而避免装箱/拆箱等。不幸的是,标准C++ 库不支持(据我所知)polygamma 用于复杂参数。感谢您在 Julia 中努力实现它。如果你愿意(对未来的读者也很好),你可以把它作为一个更好的答案,提供一个完整的例子。 (这也鼓励我接受您的答案作为“已接受的答案”):)
  • 哎呀,你已经在另一个线程中回答了!!
  • Julia 在实现特殊功能方面是一种比 C++ 更好的语言,我发现。 (作为比较,我编写了 C/C++ complex error function used in SciPy 等。)即使是简单的东西,例如同时适用于单/双精度和真实/复杂数据的易于编写的代码,也是一个巨大的胜利,更不用说用于内联的元编程技术多项式评估和其他高级技巧。
【解决方案2】:

感谢@Matt B,我查看了 Julia 代码并了解这些模块是如何存在的。 因此,以下可能是一种可能的解决方案。

#include <julia.h>
#include<iostream>
JULIA_DEFINE_FAST_TLS() 

int main(){
  jl_init();

  jl_eval_string("using SpecialFunctions");
  jl_module_t* SpecialFunctions =(jl_module_t*)jl_eval_string("SpecialFunctions");

  jl_function_t *func2 = jl_get_function(SpecialFunctions, "polygamma");

  // arguments to pass to polygamma
  jl_value_t *argument1 = jl_box_int64(1);
  jl_value_t *argument2 = jl_box_float64(2.0);
  jl_value_t *arguments[2] = { argument1 , argument2 };
  jl_value_t *ret2 = jl_call(func2, arguments, 2);

  if (jl_typeis(ret2, jl_float64_type)){
    double ret_unboxed = jl_unbox_float64(ret2);
    std::cout << "\n julia result = " << ret_unboxed << std::endl;
  }
  else{
    std::cout<<"hello error!!"<<std::endl;
  }

  jl_atexit_hook(0);
  return 0;
 }

现在我需要看看如何将复数传递给polygamma 的参数,这就是所有这些大惊小怪的原因:)!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    相关资源
    最近更新 更多