I want to program something python like:
import os
ROOT = os.path.dirname(__file__)
but in Julia?
So far println(__FILE__) did not work.
Julia's docs on file system tell to use the macro:
ROOT = dirname(#__FILE__)
Related
I am trying to use Derived Datatype more specifically struct in mpi4py but there is not much documentation on how to implement it, the only place I could find it was in the original mpi4py documentation this. I tried to write the code but it had many errors.
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.size
rank = comm.Get_rank()
class mpi4py.MPI.Datatype(datatype=Struct)
classmethod Create_struct(blocklengths, displacements, datatypes)
Any possible documentation I can refer or any suggestions will be helpful
I would like to retrieve the path of the currently running Julia interpreter from Julia. In Python, this can be achieved with sys.executable.
Base.julia_cmd() is probably what you need. It returns the full command line that was used to invoke the current julia process, with the default options spelled out. Base.julia_exename() returns the name of the executable.
julia> Base.julia_cmd()
/Users/aviks/dev/julia/julia5/usr/bin/julia -Cnative -J/usr/lib/julia/sys.dylib --compile=yes --depwarn=yes
julia> Base.julia_exename()
"julia"
If you just want the location of the julia executable, try one of these:
julia> julia_bin_exe = joinpath(Base.Sys.BINDIR,Base.julia_exename())
"/home/mkitti/src/julia/usr/bin/julia"
julia> Base.julia_cmd()
`/home/mkitti/src/julia/usr/bin/julia -Cnative -J/home/mkitti/src/julia/usr/lib/julia/sys.so -g1`
julia> typeof(Base.julia_cmd())
Cmd
julia> Base.julia_cmd()[1]
"/home/mkitti/src/julia/usr/bin/julia"
julia> julia_bin_exe == Base.julia_cmd()[1]
true
How do you find out where a macro is from in Julia. I'm looking at someone's code and they're using an #debug("string") macro. There are no using statements in the particular file that would tell me where it's loaded from, so I assume it's loaded form somewhere else in the code.
I might guess at the debug module for Julia, but it doesn't seem like it's being used that way, it seems like it's being used more for logging, so I'm a bit unsure of how to track it down through the code.
A macro location can be obtained using the #which macro, this is a feature introduced in 0.5.
julia> #which #printf("%0.2f", 1/3)
#printf(args...) at printf.jl:1178
Similar to #which, you can use #edit to open the source file and #functionloc to get the function location programmatically.
You can go to help mode in the Julia repl by keyboard shortcut shfit+?
help?> #debug
No documentation found.
#debug is a macro.
# 1 method for macro "#debug":
#debug(msg...) at /home/guo/.julia/v0.5/Logging/src/logging_macros.jl:11
I guess the marco #debug is probably from the package Logging.jl.
Does Julia have an equivalent of Python's with? Maybe as a macro? This is very useful, for example, to automatically close opened files.
Use a do block. Docs on do blocks are here.
And here is an example of how to do the usual with open(filename) as my_file of Python in Julia:
open("sherlock-holmes.txt") do filehandle
for line in eachline(filehandle)
println(line)
end
end
The above example is from the Julia wikibooks too.
Although the do block syntax does have certain similarities to Python's with statement, there is no exact equivalent. This is discussed in further detail in the GitHub issue "with for deterministic destruction". The issue concludes that this structure should be added to Julia, although no syntax or plan for such is established.
Both R and Rust can interface with C code, so I think it is very possible. I am a bit unclear about how to proceed, however.
I have read these sections looking for answers:
R-extensions System-and-foreign-language-interfaces
The Rust foreign function interface guide
But while I am well-versed in R I am not a systems programmer and confused by what the build-chain looks like for such an endeavor.
Using Rinternals.h would be ideal, but I would settle for the simpler .C interface as well.
I have been struggling on this for a while as well, but once you know how I'ts actually not that difficult.
First create a Rust library following these instructions: rust-inside-other-languages.
Here is an example Rust library:
//src/lib.rs
#[no_mangle]
pub fn kelvin_to_fahrenheit(n: f64) -> f64 {
n * 9.0/5.0 - 459.67
}
If you follow the instructions in rust-inside-other-languages, then you should be able to generate a *.so (or *.dll or .dylib, depending on your system). Let's presume this compiled file is called libtempr.so.
Now create a C++ file which will pass the functions you need to R:
//embed.cpp
extern "C" {
double kelvin_to_fahrenheit(double);
}
// [[Rcpp::export]]
double cpp_kelvin_to_fahrenheit(double k) {
double f = kelvin_to_fahrenheit(k);
return(f);
}
Now before starting R, make sure the environment variable LD_LIBRARY_PATH contains the directory where the shared object generated previously (libtempr.so) is stored. In the shell do:
$ export LD_LIBRARY_PATH=/home/sam/path/to/shared/object:$LD_LIBRARY_PATH
$ rstudio # I highly recommend using Rstudio for your R coding
Finally in Rstudo, write this file:
library(Rcpp)
Sys.setenv("PKG_LIBS"="-L/home/sam/path/to/shared/object -ltempr")
sourceCpp("/home/sam/path/to/embed.cpp", verbose = T, rebuild = T)
cpp_kelvin_to_fahrenheit(300)
Be careful that in Sys.setenv the -L option points to the directory containing your Rust shared object.
Also be careful that -l option is the name of your shared object without the lib prefix and without the .so (or whatever it is on your system) postfix.
Using Sys.setenv in R to set the LD_LIBRARY_PATH variable DOES NOT WORK. Export the variable before starting R.
The verbose option is there so that you can see what Rcpp does to compile your C++ file. Notice how the options in PKG_LIBS above are used for compiling your C++ file.
The rebuild options is there to force a rebuild of the C++ file every time you run this line of R code.
If you did everything well, then run the R file above in the interactive console and it should output 80.33 when you reach the last line.
If anything is not clear, ask in the comments, and I'll try to improve my answer.
Hope it helped :)
Final note, the base functions dyn.load and .C can be used as an alternative approach. But this requires writing a lot more boilerplate wrapper code than this approach.
If R can interface with C code, so it is no problem at all to compile shared library from Rust code which exposes C-style functions.
Then you can easily use your library as it was written in C or C++. Of course, you will not able to use Rust object and libraries directly from R, you will have to make appropriate C interface for converting their functions.
Here is how can I do that for SBCL, and I suppose it would be very similar for R:
On Rust side
Some code:
% cat experiment.rs
extern crate libc;
use libc::{c_int, c_char};
use std::{ffi, str};
#[no_mangle]
pub extern fn rust_code_string_to_int(s: *const c_char, r: *mut c_int) -> c_int {
let string = String::from_utf8_lossy(unsafe { ffi::CStr::from_ptr(s).to_bytes() });
match <isize as str::FromStr>::from_str(&*string) {
Ok(value) => { unsafe { *r = value as c_int }; 0 },
Err(_) => -1,
}
}
Then I'm making shared lib:
% rustc --crate-type dylib experiment.rs
% nm -a libexperiment.dylib | grep rust_code_string_to_int
0000000000001630 t __ZN23rust_code_string_to_int10__rust_abiE
00000000000015e0 T _rust_code_string_to_int
Next, on SBCL side
Now I'm just loading my shared lib and then I have access to my rust_code_string_to_int function:
RUST> (sb-alien:load-shared-object "libexperiment.dylib")
#P"libexperiment.dylib"
RUST> (sb-alien:with-alien ((result sb-alien:int 0))
(values (sb-alien:alien-funcall (sb-alien:extern-alien "rust_code_string_to_int"
(sb-alien:function sb-alien:int
(sb-alien:c-string :external-format :utf-8)
(sb-alien:* sb-alien:int)))
(sb-alien:make-alien-string "42")
(sb-alien:addr result))
result))
0
42