Public API for Julia functionality. Initialize! must be called before any other functions and there are a choice of garbgage collection mechanisms (see topic in docs). is probably a bad idea to call Julia from multiple threads so access to julia should be from one thread or protected via a mutex.


user> (require '[libjulia-clj.julia :as julia])
user> (julia/initialize!)
user> (def ones-fn (julia/jl "Base.ones"))
Nov 27, 2020 12:39:39 PM$eval6611$fn__6614 invoke
INFO: Rooting address  0x00007F3E092D6E40
user> (def jl-ary (ones-fn 3 4))

Nov 27, 2020 12:40:02 PM$eval6611$fn__6614 invoke
INFO: Rooting address  0x00007F3DFF9C92A0
user> jl-ary
[1.0 1.0 1.0 1.0; 1.0 1.0 1.0 1.0; 1.0 1.0 1.0 1.0]
user> (type jl-ary)
user> (require '[tech.v3.tensor :as dtt])
user> ;;zero-copy
user> (def tens (dtt/as-tensor jl-ary))
user> tens
#tech.v3.tensor<float64>[3 4]
[[1.000 1.000 1.000 1.000]
 [1.000 1.000 1.000 1.000]
 [1.000 1.000 1.000 1.000]]
user> (dtt/mset! tens 0 25)
#tech.v3.tensor<float64>[3 4]
[[25.00 25.00 25.00 25.00]
 [1.000 1.000 1.000 1.000]
 [1.000 1.000 1.000 1.000]]
user> jl-ary
[25.0 25.0 25.0 25.0; 1.0 1.0 1.0 1.0; 1.0 1.0 1.0 1.0]


(->array tens)

Create a new dense julia array that is the 'transpose' of the input tensor. Transposing ensures the memory alignment matches as Julia is column-major while datatype is row-major.


(apply-tuple-type & args)

Create a new Julia tuple type from a sequence of types.


(apply-type jl-type & args)

Create a new Julia type from an existing type and a sequence of other types.


Resolves to the base julia array datatype


(call-function fn-handle args options)(call-function fn-handle args)

Call a function. The result will be marshalled back to the jvm and if necessary, rooted. This method is normally not necessary but useful if you would like to use keywords in your argument list or specify to avoid rooting the result.


(call-function-kw fn-handle args kw-args options)(call-function-kw fn-handle args kw-args)(call-function-kw fn-handle args)

Call a julia function and pass in keyword arguments. This is useful if you would like to specify the arglist and kw-argmap. Normally this is done for you.



Call periodically to release rooted Julia objects. We root return values if they aren't primitives and then hook them to the jvm GC such that they get put in a queue once they aren't reachable by the program. This call clears that queue and unroots them thus notifying the Julia GC that they aren't reachable any more.

In the future point this may be done for you.


(initialize! {:keys [julia-library-path], :as options})(initialize!)

Initialize julia optionally providing an explicit path which will override the julia library search mechanism.

Currently the search mechanism is:


Returns :ok on success else exception.


  • :julia-home - Explicitly declare the env var julia-home.
  • :n-threads - Set to -1 to set to n-cpus. Defaults to nil which means single threaded unless the JULIA_NUM_THREADS environment variable is set. Note that this has implications for application stability - see the topic.
  • :signals-enabled? - Users do not usually need to set this. This allows users to disable all of Julia's signal handling most likely leading to a crash. See the topic.


(jl str-data options)(jl str-data)

Eval a string in julia returning the result. If the result is callable in Julia, the result will be callable in Clojure.


Resolves to the julia undef type


(named-tuple value-map)(named-tuple)

Create a julia named tuple from a map of values. The keys of the map must be keywords or symbols. A new named tuple type will be created and instantiated.


(new-array shape datatype)(new-array shape)

Create a new, uninitialized dense julia array. Because Julia is column major while tech.v3.datatype is row major, the returned array's size will be the reverse of dtype/shape as that keeps the same in memory alignment of data.


(set-julia-gc-root-log-level! log-level)

Set the log level to use when rooting/unrooting julia objects. We automatically root julia objects in a julia id dictionary that we expose to JVM objects. This code isn't yet perfect, so sometimes it is worthwhile to log all root/unroot operations.

Valid log levels are valid log levels for clojure/tools.logging.


(struct struct-type & args)

Instantiate a Julia struct type (tuple, NamedTuple, etc). Use this after apply-tuple-type in order to create an instance of your new type.


(tuple & args)

Create a julia tuple from a set of arguments. The tuple type will be the same datatype as the argument types.

This function converts the arguments to julia, calls apply-tuple-type on the resulting argument types, and then instantiates an instance of the given newly created tuple type.


(typeof item)

Get the julia type of an item.



(with-stack-context & body)

Run code in which all objects created within this context will be released once the stack unwinds where released means unrooted and thus potentially available to the next julia garbage collection run.