carray-jit 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -4
- data/README.md +1 -1
- data/lib/carray/jit/compiler.rb +20 -1
- data/lib/carray/jit/expression.rb +34 -2
- data/lib/carray/jit/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89d3c3c1c950f938ca30658e4d6586bd305b60e6d83083a33e645ea69168d3e3
|
|
4
|
+
data.tar.gz: 6101247a5b517a6f28ce051016ced3674ce26e4400952a3a69eaf2ab8ea7eb40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6789499fd3fa7bbb2e2342bb48b35cb2eb6c5dbe05a2ef281cc4c9c734c6ef18c37ece9a929623103e5f1c388b656184bcc76e4b457b9c03241ae226c132e49c
|
|
7
|
+
data.tar.gz: 16b2611b901be3ab35fd088309ba4976ac45f3cefd360a472971c95e7f0edcf17e3ebb19abb0bded712012b9b8e3c85cc26aea6787b9caf71741bc7b06b861f5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
Releases are recorded here from 0.1.0, which is the first.
|
|
3
|
+
Releases are recorded here from 0.1.0, which is the first. There is no
|
|
4
|
+
separate NEWS file: this is where to look for what changed between the
|
|
5
|
+
version you have and a newer one.
|
|
4
6
|
|
|
5
7
|
<!-- Newest first, at both levels: a new release section goes above the
|
|
6
8
|
ones below it, and a new entry goes directly under its own release
|
|
@@ -8,6 +10,12 @@ Releases are recorded here from 0.1.0, which is the first.
|
|
|
8
10
|
carried by the `- Fix:` / `- Change:` / `- New:` that opens the
|
|
9
11
|
entry; there are no per-kind subheadings.
|
|
10
12
|
|
|
13
|
+
A section is written newest-first while the release is open, and
|
|
14
|
+
sorted into New, Change, Fix when it closes -- in the same commit
|
|
15
|
+
that drops `(unreleased)`. Within Change, the ones that ask the
|
|
16
|
+
reader to change code come first. It is a reading order rather than
|
|
17
|
+
a classification: where it is not obvious, either place will do.
|
|
18
|
+
|
|
11
19
|
An entry says three things and stops: what changed, what to do about
|
|
12
20
|
it (the migration, the replacement, the condition under which nothing
|
|
13
21
|
changes), and what is excluded. It does not say how the code was
|
|
@@ -15,10 +23,37 @@ Releases are recorded here from 0.1.0, which is the first.
|
|
|
15
23
|
speed came from, or argue the design -- those belong in the commit
|
|
16
24
|
message. Two to six lines.
|
|
17
25
|
|
|
26
|
+
It is written for someone using the library, not someone working on
|
|
27
|
+
it: with no NEWS file, this is what a reader consults before
|
|
28
|
+
upgrading. An entry naming something only a C extension touches says
|
|
29
|
+
so in its opening words.
|
|
30
|
+
|
|
31
|
+
Every entry has to read on its own. Entries are looked at one at a
|
|
32
|
+
time and move about within a section, so none may lean on a
|
|
33
|
+
neighbour ("as well", "the kernel above") or leave unnamed the
|
|
34
|
+
method, class or keyword it is about.
|
|
35
|
+
|
|
18
36
|
The version here is this gem's own and is not CArray's. Which CArray
|
|
19
37
|
a release needs is said in the gemspec, and an entry says so only
|
|
20
38
|
when the answer changes. -->
|
|
21
39
|
|
|
40
|
+
## 0.1.1
|
|
41
|
+
|
|
42
|
+
- Fix: a zero divisor in a `CArray.fuse` expression no longer turns
|
|
43
|
+
compilation off for the rest of the process. `ZeroDivisionError` is raised
|
|
44
|
+
as before; what has gone is the warning that followed it on stderr, and the
|
|
45
|
+
expressions walked rather than compiled from then on. Nothing to do.
|
|
46
|
+
`jit_for`, `jit_each` and `jit_map` were never affected.
|
|
47
|
+
|
|
48
|
+
- Fix: on macOS, a `CArray.fuse` expression holding an integer `/` or `%` is
|
|
49
|
+
compiled rather than walked. The answers were right before and are
|
|
50
|
+
unchanged; this is speed alone. Linux was never affected.
|
|
51
|
+
|
|
52
|
+
- Fix: on Linux, a program that compiles more than one kernel no longer
|
|
53
|
+
crashes -- any two of `jit_for`, `jit_each`, `jit_map`, `jit_stencil`,
|
|
54
|
+
`jit_contract` and `jit_function` reached in the same run. Nothing to do:
|
|
55
|
+
cached kernels are rebuilt on first use. macOS was never affected.
|
|
56
|
+
|
|
22
57
|
## 0.1.0
|
|
23
58
|
|
|
24
59
|
- New: `CArray.jit_for`, `CArray.jit_each` and `CArray.jit_map` compile their
|
|
@@ -73,9 +108,10 @@ Releases are recorded here from 0.1.0, which is the first.
|
|
|
73
108
|
`CARRAY_JIT_NO_CACHE` keeps the cache in a temporary directory that goes
|
|
74
109
|
away with the process, and `CARRAY_JIT_CC` names a different compiler.
|
|
75
110
|
|
|
76
|
-
- New: the `carray-jit` command reports and looks after
|
|
77
|
-
`status`, `list`, `show`, `clear`. It loads the compiler and
|
|
78
|
-
so a cache can be inspected or cleared when CArray itself
|
|
111
|
+
- New: the `carray-jit` command reports and looks after the on-disk kernel
|
|
112
|
+
cache -- `status`, `list`, `show`, `clear`. It loads the compiler and
|
|
113
|
+
nothing else, so a cache can be inspected or cleared when CArray itself
|
|
114
|
+
will not load.
|
|
79
115
|
|
|
80
116
|
- New: needs CArray 3.0.1 or later in the 3.0 series, and Ruby 3.2 or later.
|
|
81
117
|
The floor is where `ca_call_cslab_N`, the expression evaluator hook,
|
data/README.md
CHANGED
|
@@ -8,7 +8,7 @@ The block is read with Prism, translated to C if it falls inside that subset, co
|
|
|
8
8
|
|
|
9
9
|
## Status
|
|
10
10
|
|
|
11
|
-
0.1.
|
|
11
|
+
0.1.1 is the current release, and it still moves: behaviour can change between releases — see [CHANGELOG.md](CHANGELOG.md). A companion gem to CArray, it follows CArray's surface, which is not settled until CArray 3.1.
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
data/lib/carray/jit/compiler.rb
CHANGED
|
@@ -40,7 +40,26 @@ class CArray
|
|
|
40
40
|
# being lower was not a decision -- the flag list is the one the first
|
|
41
41
|
# milestone was scaffolded with, and only the contraction flag beside
|
|
42
42
|
# it was ever argued for.
|
|
43
|
-
|
|
43
|
+
|
|
44
|
+
# Every generated object exports the same fixed names -- carray_jit_kernel,
|
|
45
|
+
# carray_jit_slab, the border and error helpers -- because each one is a
|
|
46
|
+
# module of its own. Fiddle.dlopen passes RTLD_GLOBAL, so on ELF those
|
|
47
|
+
# names all land in one flat namespace and an intra-module call resolves
|
|
48
|
+
# to the first definition loaded: a later kernel's carray_jit_slab calls
|
|
49
|
+
# an earlier kernel's carray_jit_kernel, which takes a different number
|
|
50
|
+
# of operands, reads past the pointers it was given, and the process
|
|
51
|
+
# segfaults. -Wl,-Bsymbolic binds each object's own definitions before
|
|
52
|
+
# the global scope, which is what one object per kernel assumed all
|
|
53
|
+
# along. Nothing else needs saying so: Mach-O binds within each dylib's
|
|
54
|
+
# own two-level namespace and PE within each DLL, so the flag is named
|
|
55
|
+
# only where it means something -- and Apple's linker rejects it
|
|
56
|
+
# outright, which would trade a Linux crash for a macOS build that never
|
|
57
|
+
# compiles at all.
|
|
58
|
+
SYMBOLIC =
|
|
59
|
+
(RbConfig::CONFIG["host_os"] =~ /darwin|mswin|mingw|cygwin/ ?
|
|
60
|
+
[] : ["-Wl,-Bsymbolic"]).freeze
|
|
61
|
+
|
|
62
|
+
FLAGS = ["-O3", "-fPIC", "-shared", "-ffp-contract=off", *SYMBOLIC].freeze
|
|
44
63
|
|
|
45
64
|
# Kernels retained on disk. Each costs about 17 KB, so the default is
|
|
46
65
|
# roughly 9 MB -- far more than any real program compiles, but a bound
|
|
@@ -16,13 +16,24 @@ class CArray
|
|
|
16
16
|
# goes back to CArray, which walks it and arrives at the same answer.
|
|
17
17
|
class Expression
|
|
18
18
|
|
|
19
|
+
# A kernel that can divide by zero calls ca_zerodiv, which the CArray
|
|
20
|
+
# extension defines and this object does not. ELF is content to leave
|
|
21
|
+
# the name undefined and resolve it when the object is loaded, which is
|
|
22
|
+
# what the declaration in #source_for assumes; Mach-O refuses to link at
|
|
23
|
+
# all, so on macOS every expression holding an integer `/` or `%` failed
|
|
24
|
+
# to compile and was silently handed back to CArray to walk. The flag
|
|
25
|
+
# says to look the name up at load time, which is what Ruby builds its
|
|
26
|
+
# own extensions with and the only thing this object leaves undefined.
|
|
27
|
+
DYNAMIC_LOOKUP =
|
|
28
|
+
(RbConfig::CONFIG["host_os"] =~ /darwin/ ? ["-Wl,-undefined,dynamic_lookup"] : []).freeze
|
|
29
|
+
|
|
19
30
|
# Built the way CArray's own kernels were, since that is what the answer
|
|
20
31
|
# is being compared against. The Prism front end wants the opposite of
|
|
21
32
|
# this on one point -- it answers to a Ruby loop, which does not fuse a
|
|
22
33
|
# multiply and an add into one rounding, so it compiles with
|
|
23
34
|
# -ffp-contract=off. Here the reference is the eager kernel, which was
|
|
24
35
|
# built with whatever CArray settled on.
|
|
25
|
-
FLAGS = ["-fPIC", "-shared", *CArray::BUILD_FLAGS.split].freeze
|
|
36
|
+
FLAGS = ["-fPIC", "-shared", *CArray::BUILD_FLAGS.split, *DYNAMIC_LOOKUP].freeze
|
|
26
37
|
|
|
27
38
|
C_TYPES = {
|
|
28
39
|
float64: "double", float32: "float",
|
|
@@ -37,7 +48,9 @@ class CArray
|
|
|
37
48
|
@kernels = {}
|
|
38
49
|
end
|
|
39
50
|
|
|
40
|
-
# Fills `out` and returns true, or
|
|
51
|
+
# Fills `out` and returns true, or returns false and leaves it to
|
|
52
|
+
# CArray. A decline may have written part of `out` first, which is
|
|
53
|
+
# what walking it over again then settles.
|
|
41
54
|
def call (plan, out)
|
|
42
55
|
return false unless C_TYPES.key?(plan.data_type)
|
|
43
56
|
aliased = plan.leaves.any? { |array| array.equal?(out) }
|
|
@@ -51,6 +64,25 @@ class CArray
|
|
|
51
64
|
kernel.call(out.elements, *pointers(plan, bases))
|
|
52
65
|
end
|
|
53
66
|
true
|
|
67
|
+
rescue ZeroDivisionError
|
|
68
|
+
# A zero divisor is an answer, not a fault: it is what ca_zerodiv --
|
|
69
|
+
# the only thing a kernel here calls out to -- reports, and the same
|
|
70
|
+
# expression walked reaches the same place and raises the same error.
|
|
71
|
+
#
|
|
72
|
+
# CArray cannot tell the two apart, though. It catches whatever an
|
|
73
|
+
# evaluator raises, retires it for the rest of the process and says so
|
|
74
|
+
# on stderr, which is right for an evaluator that is broken and wrong
|
|
75
|
+
# for one that has just met a zero. So this declines instead, and
|
|
76
|
+
# CArray walks the expression and raises it there. Anything else
|
|
77
|
+
# still reaches CArray and still retires this, which is what that net
|
|
78
|
+
# is for.
|
|
79
|
+
#
|
|
80
|
+
# What it costs: a kernel that raised where the walk does not -- over
|
|
81
|
+
# a masked zero, say -- now reads as slow rather than as wrong, since
|
|
82
|
+
# the walk answers and nobody sees the difference. The answer is
|
|
83
|
+
# right either way, and the masked-divisor test asks the evaluator
|
|
84
|
+
# directly for that reason.
|
|
85
|
+
false
|
|
54
86
|
end
|
|
55
87
|
|
|
56
88
|
private
|
data/lib/carray/jit/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: carray-jit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- himotoyoshi
|
|
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
133
133
|
- !ruby/object:Gem::Version
|
|
134
134
|
version: '0'
|
|
135
135
|
requirements: []
|
|
136
|
-
rubygems_version: 4.0.
|
|
136
|
+
rubygems_version: 4.0.8
|
|
137
137
|
specification_version: 4
|
|
138
138
|
summary: JIT compilation of CArray kernels written in Ruby
|
|
139
139
|
test_files: []
|