Wow. That's a lot of work. It's very entwined in the core Julia code. Is there hope that it could be separated into a package?
Or, are you hoping to get it merged into Julia?
Yes, this can be a possible usage.
So far, the concept is: the user specifies 1 Julia function to be translated into native C; then in the Julia code generation phase, we recursively compile this function and all its direct and indirect callees into C; that is, the whole call graph is translated. Then a C compiler is invoked to translate the C code into a shared library, and the original call to the user Julia function is replaced by a call to this shared library.
If the user specifies the main function to be translated into C, he/she should get a standalone executable as you imagined.
There are two main parts of the code:
(1) traverse the AST tree of a function. This is embedded into codegen.cpp and a few other files to minimize our coding efforts. But a (much) better way would be to make it a self-contained module.
(2) map Julia types and AST nodes to C types and statements. This is in j2c.cpp.
Since the code works at Julia code generation phase, it seems more
appropriate to merge it into Julia, instead of as an external package.
We hope that this initial version will give the community a starting point for Julia to C translation, and people can re-shape it to be better.
First of all - a big thanks to Intel for this contribution. Large organisations are not easy to convince on open source, and this is huge.
A question for everyone is if we should open have j2c as a PR? How should we integrate it? There is a fair amount of work to do before it is complete.
There is a case for embedded deployments where a certified C compiler is required to compile and this gives a way to deploy Julia in such cases if we can make the support first class.
From the output, it seems that out.cpp is not successfully generated. If so, libout.so.1.0 will contain a function called sumOfThree_.To figure out why, try this:1. Make sure sumOfThree function is indeed processed by j2c.In codegen.cpp, line 3209,bool prev_in_j2c = in_j2c;bool should_j2c_cur_func = J2C_FLAG_J2C(lam->j2cflag) || should_j2c(ctx.funcName.c_str());Check if should_j2c_cur_func is true. If not, force it to be true, and see if out.cpp is generated.
This is a good step toward figuring out the issue. In setting that var in gdb, you are turning on J2C translation for all the functions that get into emit_function(). That will expose some unimplemented features of J2C. In j2c.jl, J2C is on explicitly only for function sumofThree() and all its callees.
At this place
bool should_j2c_cur_func = J2C_FLAG_J2C(lam->j2cflag) || should_j2c(ctx.funcName.c_str());
Can you add
JL_PRINTF(JL_STDOUT, “j2c flag is %d for function %s\n", J2C_FLAG_J2C(lam->j2cflag), ctx.funcName.c_str())
make again, and run again?
Let’s see if J2C_FLAG_J2C(lam->j2cflag) is always false, or should_j2c(ctx.funcName.c_str()) is always false.
Thanks,
Hongbo
This is a good step toward figuring out the issue. In setting that var in gdb, you are turning on J2C translation for all the functions that get into emit_function(). That will expose some unimplemented features of J2C. In j2c.jl, J2C is on explicitly only for function sumofThree() and all its callees.
At this place
bool should_j2c_cur_func = J2C_FLAG_J2C(lam->j2cflag) || should_j2c(ctx.funcName.c_str());
Can you add
JL_PRINTF(JL_STDOUT, “j2c flag is %d for function %s\n", J2C_FLAG_J2C(lam->j2cflag), ctx.funcName.c_str())
make again, and run again?
Let’s see if J2C_FLAG_J2C(lam->j2cflag) is always false, or should_j2c(ctx.funcName.c_str()) is always false.
Can you confirm that with that JL_PRINTF, the output contains something like "j2c flag is X for function sumOfThree"?It is wrong that J2C_FLAG_J2C(lam->j2cflag) is always false. You should expect the X above is 1 for function sumOfThree
great. this is the right output. So j2c is indeed enabled for sumofThree.Now set a breakpoint at src/j2c.cpp line 2130 in function j2c_dump_all_funcs() and step through. This is the final phase to dump out the cpp file. It first dumps to a file called temporary. After line 2145, you should be able to see if that temporary (a text file) is there or empty.
The bug is fixed and checked in. Here is the info from Paul:
There is a typo at line 64 of test/j2c.jl, and instead of zeros(Cint, 1), it should be zeros(Cint, 2).
The 2 here means it expects the return result to be a 2D array, and the length of each dimension will be stored in this ret_out_dims array.
The bug is fixed and checked in. Here is the info from Paul:
This is to announce the release of Julia2C, a source-to-source translator from Julia to C. This initial version converts basic Julia types and expressions into the corresponding C types and statements. It is open sourced at https://github.com/IntelLabs/julia/tree/j2c. You can download and start playing with the code.Enjoy!Hongbo
1. How would you handle multi dimensional julia areas
2. Would all the underlying c math libraries that Julia uses be also available in the code
that Julia2c uses. In other words, what things in Julia are not going to be supported in Julia2C?3. Is this (in this form or some other form) going to be supported by the core devs...
not strictly required to call Julia from Go.