Skip to content

Commit 9a5a13d

Browse files
authored
Merge pull request #23 from Clonkk/devel
Devel
2 parents fa12e1b + d383bf1 commit 9a5a13d

24 files changed

Lines changed: 469 additions & 317 deletions

changelog.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
Changelog for Nimjl. Date in format YYYY_MM_DD
22

3+
Release v0.5.3 - 2021_06_24
4+
===========================
5+
* Improve file layout
6+
* Added object <=> struct conversions
7+
38
Release v0.5.2 - 2021_05_25
49
===========================
510
* Split tests into multiple files
@@ -26,7 +31,7 @@ Release v0.4.5 - 2021_04_02
2631

2732
Release v0.4.4 - 2021_03_25
2833
===========================
29-
* Add support for Option
34+
* Add support for Option
3035
* Fix boxing bool and voidpointer types
3136
* Improve test coverage
3237
* Add examples to ci
@@ -46,7 +51,7 @@ Release v0.4.1 - 2021_03_10
4651
* Add seq support when converting types
4752
* Add Tensor support when converting types
4853
* Improved dispatch using generic proc instead of ``when T is ...``
49-
* Format code using nimpretty
54+
* Format code using nimpretty
5055
* Add changelog
5156
* Improve readme
5257
* Improve examples

nimjl.nim

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
1-
import nimjl/arrays
1+
import ./nimjl/arrays
22
export arrays
33

4-
import nimjl/cores
4+
import ./nimjl/cores
55
export cores
66

7-
import nimjl/types
7+
import ./nimjl/types
88
export types
99

10-
import nimjl/gc
10+
import ./nimjl/gc
1111
export gc
1212

13-
import nimjl/functions
13+
import ./nimjl/functions
1414
export functions
1515

16-
import nimjl/glucose
16+
import ./nimjl/glucose
1717
export glucose
1818

19-
import nimjl/sugar/converttypes
20-
export converttypes
19+
import ./nimjl/conversions
20+
export conversions
2121

22-
import nimjl/sugar/valindexing
23-
export valindexing
22+
import ./nimjl/config
2423

25-
import nimjl/config
2624
static:
2725
debugEcho "Nimjl> Using Julia install: ", JuliaPath

nimjl.nimble

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Nimjl
22
# Licensed and distributed under MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
3-
version = "0.5.2"
3+
version = "0.5.3"
44
author = "Regis Caillaud"
55
description = "Nim Julia bridge"
66
license = "MIT"
77
# installDirs = @["third_party", "install"]
88

99
# Dependencies
1010
requires "nim >= 1.2.0"
11-
requires "arraymancer"
11+
requires "arraymancer >= 0.6.3"
1212

1313
# TODO finish auto installation of Julia
1414
task installjulia, "Install Julia":

nimjl/arrays.nim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import ./functions
55

66
import arraymancer
77

8-
import std/typetraits
98
import std/sequtils
109

1110
proc toJlArray*[T](x: JlValue): JlArray[T] {.inline.} =
@@ -46,8 +45,11 @@ proc jlArrayFromBuffer*[T](data: openArray[T]): JlArray[T] =
4645
result = jlArrayFromBuffer(uncheckedDataPtr, [data.len()])
4746

4847
proc jlArrayFromBuffer*[T](data: Tensor[T]): JlArray[T] =
48+
if not data.is_contiguous:
49+
raise newException(ValueError, "Error using non-contiguous Tensor as buffer")
50+
4951
## Create an Array from existing buffer
50-
let uncheckedDataPtr = data.unsafe_raw_offset().distinctBase()
52+
let uncheckedDataPtr = data.toUnsafeView()
5153
result = jlArrayFromBuffer(uncheckedDataPtr, data.shape.toSeq)
5254

5355
# Julia allocated array

nimjl/arrays/indexing.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ proc makerange[T](x: JlArray[T], start, stop: int): JlValue =
2424

2525
# This comes from arraymancer
2626
# |2 syntax is parsed but not used for now
27-
macro desugar*[T](x: JlArray[T], args: untyped): void =
27+
macro desugar[T](x: JlArray[T], args: untyped): void =
2828
## Transform all syntactic sugar in arguments to integer or slices
2929

3030
# echo "\n------------------\nOriginal tree"

nimjl/arrays/interop.nim

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,10 @@ proc toJlArray*[T: seq|array](oa: openarray[T]): auto =
9797
inc(i)
9898

9999
# Utility
100-
proc firstindex*[T](val: JlArray[T], dim: int) : int =
100+
proc firstindex*[T](val: JlArray[T], dim: int): int =
101101
jlCall("firstindex", val, dim).to(int)
102102

103-
proc lastindex*[T](val: JlArray[T], dim: int) : int =
103+
proc lastindex*[T](val: JlArray[T], dim: int): int =
104104
jlCall("lastindex", val, dim).to(int)
105105

106106
proc iterate*[T](val: JlArray[T]): JlValue =
@@ -111,32 +111,32 @@ proc iterate*[T](val: JlArray[T]): JlValue =
111111
proc iterate*[T](val: JlArray[T], state: JlValue): JlValue =
112112
result = jlCall("iterate", val, state)
113113

114-
proc transpose*[T](x: JlArray[T]) : JlArray[T] =
114+
proc transpose*[T](x: JlArray[T]): JlArray[T] =
115115
result = jlCall("transpose", x).toJlArray(T)
116116

117-
proc reshape*[T](x: JlArray[T], dims: JlArray[int]) : JlArray[T] =
117+
proc reshape*[T](x: JlArray[T], dims: JlArray[int]): JlArray[T] =
118118
result = jlCall("reshape", x, dims).toJlArray(T)
119119

120-
proc reshape*[T](x: JlArray[T], dims: openarray[int]) : JlArray[T] =
120+
proc reshape*[T](x: JlArray[T], dims: openarray[int]): JlArray[T] =
121121
result = jlCall("reshape", x, dims).toJlArray(T)
122122

123-
proc reverse*[T](x: JlArray[T]) : JlArray[T] =
123+
proc reverse*[T](x: JlArray[T]): JlArray[T] =
124124
result = jlCall("reverse", x).toJlArray(T)
125125

126-
proc fill*[T](x: T, dims: varargs[int]) : JlArray[T] =
126+
proc fill*[T](x: T, dims: varargs[int]): JlArray[T] =
127127
if dims.len > 0:
128128
result = jlCall("fill", x, dims).toJlArray(T)
129129
else:
130130
result = jlCall("fill", x).toJlArray(T)
131131

132132
# TODO map typedesc to Julia type
133-
proc asType*[T](x: JlArray[T], U: typedesc) : JlArray[U] =
133+
proc asType*[T](x: JlArray[T], U: typedesc): JlArray[U] =
134134
let tmp = newSeq[U](1).toJlArray()
135135
result = jlCall("convert", jltypeof(tmp), x).toJlArray(U)
136136

137-
proc swapMemoryOrder*[T](x: JlArray[T]) : JlArray[T] =
137+
proc swapMemoryOrder*[T](x: JlArray[T]): JlArray[T] =
138138
let revshape = reverse(size(x))
139-
var invdim : seq[int]
139+
var invdim: seq[int]
140140
for i in countdown(ndims(x), 1):
141141
invdim.add i
142142
let tmp = reshape(x, revshape)

nimjl/config.nim

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ const JuliaLibPath* = JuliaPath / "lib"
1313
const JuliaDepPath* = JuliaPath / "lib" / "julia"
1414

1515
const JlVersionCmd = JuliaPath / "bin" / "julia" & " -E VERSION"
16-
const JuliaVersion = gorge(JlVersionCmd).split("\"")[1].split(".")
16+
const (cmdOutput, exitCode) = gorgeEx(JlVersionCmd)
17+
const JuliaVersion = cmdOutput.split("\"")[1].split(".")
18+
static: doAssert(exitCode == 0, "Julia executable could not be found")
19+
1720
# For release : result has the form ["v", "1.6.0", ""] -> splitting [1] yiels ["1", "6, "0"]
1821
# For dev: result has the form ["v", "1.7.0-DEV", "667"] -> splitting [1] yiels ["1", "7, "0-DEV", "667"]
1922
const JuliaMajorVersion* = JuliaVersion[0].parseInt
@@ -32,9 +35,9 @@ const JuliaLibName* = JuliaLibPath / libPrefix & "julia" & libSuffix
3235
{.passL: "-Wl,-rpath," & JuliaDepPath.}
3336
{.passL: "-ljulia".}
3437

35-
# Workaround for Julia 1.6.0 and 1.6.1
38+
# Workaround for Julia 1.6.0
3639
# See https://github.com/JuliaLang/julia/issues/40524
37-
when (JuliaMajorVersion, JuliaMinorVersion) == (1, 6) and (JuliaPatchVersion == 0 or JuliaPatchVersion == 1):
38-
const internalJuliaLibName* = JuliaDepPath / libPrefix & "Julia-internal" & libSuffix
40+
when (JuliaMajorVersion, JuliaMinorVersion) == (1, 6):
41+
const internalJuliaLibName* = JuliaDepPath / libPrefix & "julia-internal" & libSuffix
3942
{.passL: "-ljulia-internal".}
4043

nimjl/conversions.nim

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import conversions/fromjl
2+
import conversions/unbox
3+
4+
import conversions/tojl
5+
import conversions/box
6+
7+
import conversions/dict_tuples
8+
import conversions/obj_structs
9+
10+
export fromjl
11+
export unbox
12+
13+
export tojl
14+
export box
15+
16+
export dict_tuples
17+
export obj_structs
18+

nimjl/conversions/box.nim

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import ../private/jlcores
2+
import ../private/jlboxunbox
3+
4+
import ../types
5+
6+
{.push inline.}
7+
8+
## Box
9+
proc julia_box(x: int8): JlValue = jl_box_int8(x)
10+
proc julia_box(x: int16): JlValue = jl_box_int16(x)
11+
proc julia_box(x: int32): JlValue = jl_box_int32(x)
12+
proc julia_box(x: int64): JlValue = jl_box_int64(x)
13+
proc julia_box(x: uint8): JlValue = jl_box_uint8(x)
14+
proc julia_box(x: uint16): JlValue = jl_box_uint16(x)
15+
proc julia_box(x: uint32): JlValue = jl_box_uint32(x)
16+
proc julia_box(x: uint64): JlValue = jl_box_uint64(x)
17+
proc julia_box(x: float32): JlValue = jl_box_float32(x)
18+
proc julia_box(x: float64): JlValue = jl_box_float64(x)
19+
20+
proc julia_box(x: int): JlValue =
21+
when sizeof(int) == sizeof(int64):
22+
jl_box_int64(x)
23+
else:
24+
jl_box_int32(x)
25+
26+
proc julia_box(x: uint): JlValue =
27+
when sizeof(uint) == sizeof(uint64):
28+
jl_box_uint64(x)
29+
else:
30+
jl_box_uint32(x)
31+
32+
proc julia_box(x: bool): JlValue = jl_box_bool(x)
33+
proc julia_box(x: pointer): JlValue = jl_box_voidpointer(x)
34+
35+
{.pop.}
36+
37+
proc jlBox*[T](val: T): JlValue =
38+
julia_box(val)
39+
40+
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import ../cores
21
import ../types
32
import ../functions
3+
import ../cores
44

55
import std/tables
66
import std/strutils
77
import std/strformat
88

99
proc jlTupleToNim*(val: JlValue, tup: var tuple) =
10-
# collect(keys(val))
10+
# julia> collect(keys(val))
1111
var keys = jlCall("keys", val)
1212
keys = jlCall("collect", keys)
13+
1314
# Tuple of JlSymbol
14-
# length(collect(keys(val)))
15+
# julia> length(collect(keys(val)))
1516
var show = getJlFunc("show")
1617
var sprint = getJlFunc("sprint")
1718
var nkeys = jlCall("length", keys).to(int)
19+
1820
var i = 0
1921
for name, field in tup.fieldPairs:
2022
inc(i)
@@ -33,31 +35,28 @@ proc jlTupleToNim*(val: JlValue, tup: var tuple) =
3335
raise newException(JlError, "Tuple conversion from Julia to Nim failed ! Fields must identical")
3436

3537
proc jlDictToNim*[U, V: string|SomeNumber|bool](val: JlValue, tab: var Table[U, V]) =
36-
# collect(keys(val))
38+
# julia> collect(keys(val))
3739
var keys = jlCall("keys", val)
3840
keys = jlCall("collect", keys)
41+
3942
# Tuple of JlSymbol
40-
# length(collect(keys(val)))
43+
# julia> length(collect(keys(val)))
4144
var nkeys = jlCall("length", keys).to(int)
4245
for i in 1..nkeys:
4346
var key = jlCall("getindex", keys, i)
4447
var val = jlCall("getindex", val, key)
4548
tab[key.to(U)] = val.to(V)
4649

47-
# Recursive import strategy
48-
import ./converttypes
49-
# Tuple helpers -> result is memory managed by Julia's GC
50-
# Convert object as tuple ?
5150
proc nimToUnnamedJlTuple(v: tuple): JlValue =
5251
var tupStr = $v
5352
result = jlEval(tupStr)
5453

55-
proc nimToNamedJlTuple(v: tuple|object): JlValue =
54+
proc nimToNamedJlTuple*(v: tuple|object): JlValue =
5655
result = jlEval("NamedTuple()")
5756
for name, field in v.fieldPairs:
58-
result = jlCall(JlBase, "setindex", result, toJlVal(field), jlSym(name))
57+
result = jlCall(JlBase, "setindex", result, field, jlSym(name))
5958

60-
proc isNamedTuple(v: tuple) : bool =
59+
proc isNamedTuple(v: tuple): bool =
6160
var i = 0
6261
for name, field in v.fieldPairs:
6362
if name != &"Field{i}":
@@ -71,11 +70,7 @@ proc nimToJlTuple*(v: tuple): JlValue =
7170
else:
7271
nimToUnnamedJlTuple(v)
7372

74-
proc nimToJlTuple*(v: object): JlValue =
75-
nimToNamedJlTuple(v)
76-
7773
proc nimTableToJlDict*[U, V: string|SomeNumber](tab: Table[U, V]): JlValue =
7874
result = jlEval("Dict()")
7975
for name, field in tab:
80-
discard jlCall(JlBase, "setindex!", result, toJlVal(field), name)
81-
76+
discard jlCall(JlBase, "setindex!", result, field, name)

0 commit comments

Comments
 (0)