Embedded Julia: Backslash hangs thread

dotnet
embedding

#1

I’m not entirely sure where the best place to put this question as I am new to this place and Julia in general. I’ve tried stack overflow but I think this is too specific for that.

I’ve embedded Julia into C# using the public C API. When I run the backslash command, execution stalls, and the process keeps consuming processor power. I’ve tried it both by running functions from imported modules and just running statements with jl_eval_string

Here are two examples of I can do that get’s it to hang.
Julia Module
function doStuff()
a = [1 2;3 4];
b = [4;6];
c = a\b;
end

In C# main function
jl_eval_string(“a=[1 2;3 4];”);
jl_eval_string(“b = [4;6];”);
jl_eval_string(“c=a\b;”);

I tried running it in a try/catch block to see if that would help, but it didn’t. Running the statements in the REPL or with a script executed from the command line work just fine. I’m not entirely sure what the differences are between running Julia from the command line and from C#.

Does anyone have an idea about what is going on here? I’ve tried using other lin alg functions and they work just fine.


#2

Just a guess, but do you need to escape the backslash in \b ? That’s a valid escape sequence for C / C++ strings.

Try, perhaps, "c=a\\b" instead?

Ref: https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences


#3

Oops, I wrote that in wrong. I’ve been using jl_eval_string("c=a\\b;"). I know that works because I’ve been able to change directories using the the double backslash.

Still doesn’t explain why it stops working in the Julia module though.


#4

I can’t reproduce this on 0.6-rc3:

julia> include("mod1.jl")
Foo

julia> Foo.doStuff()
2-element Array{Float64,1}:
 -2.0
  3.0

mod1.jl is just your code wrapped with module Foo ... end.


#5

I can’t reproduce from C on a tip-of-trunk build (on a mac). Please try from C. If you have a local build, comment out everything in examples/embedding/embedding.c between jl_init(); and int ret = 0; replace with:

    jl_eval_string("a=[1 2;3 4];");
    jl_eval_string("b = [4;6];");
    jl_eval_string("c=a\\b;");
    jl_eval_string("@show c");

Then in the examples dir run:

make
embedding/embedding


#6

It works when run in the REPL. However, it happens when it’s run from C#.

Here is a more complete version of my code that has been heavily cut (I have a lot of testing code, and some rewritten stuff from julia.h for the garbage collector)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace TestCInCSharp{
    class Program{
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool SetDllDirectory(string lpPathName);

        [DllImport("libjulia.dll", SetLastError = true)]
        public static extern void jl_init(string path);

        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr jl_eval_string(string input);
        //other dll imports here....
        //
        static unsafe void Main(string[] args){
            string p;
            string julia_path = @"C:\Users\schulk4\AppData\Local\Julia-0.5.2\bin";
            IntPtr module;
            SetDllDirectory(julia_path);
            jl_init(julia_path);
            //
            p = @"C:\\Users\\schulk4\\Documents\\Programming\\TestJuliaSim\\Assets\\test_julia.jl";
            p = "include(\"" + p + "\")";
            module = jl_eval_string(p); //holds module pointer? it appears to be so
            
            jl_eval_string("a=[1 2;3 4];");
            jl_eval_string("b=[4;6];");
            jl_eval_string("c=a\\b;");
         
            jl_atexit_hook(0); //tell Julia to shut down
            Console.ReadLine(); //pause so that output stays up
        }
    }
}

#7

I assume you are talking about this, which is almost certainly not going to work as-written, and is most likely the cause of the problem:

https://stackoverflow.com/questions/44442654/embedding-julia-into-c-garbage-collector-rewrite-into-c-sharp-issues-and-quest


#8

As I said in my comment there, it is probably possible in principle but hooking in to pgc_stack like that is asking for trouble and probably provides no benefit (especially not if as-written you are allocating on the managed heap rather than using alloca).


#9

Yes, but I stopped using the functions I wrote to try and see what was going wrong. That shouldn’t influence the code in the Julia function in the module though?


#10

I’ve decided that I’ll try and do it the way that Ipython does it with the global array of references, and see if that works


#11

Ok, if you are not doing the GC manipulation right now then that’s fine, I wasn’t sure based on how the intro to your example was worded.

Console.ReadLine(); //pause so that output stays up

Are you sure that work is actually happening? Try adding jl_eval_string("@show c"); – maybe it’s actually finished.


#12

I just tried both C and C# (Visual Studio 2015) on Windows 10 against 0.5.2 release binary and it worked fine.


#13

I made an entirely new project and copied only the things that I needed. I guess I’ll just work with this now. Thanks for your help


#14

If there’s still an issue, please try some of the suggestions and report back – I’m happy to help debug further if I can find a way to reproduce it.