Skip to content

Commit acf4f65

Browse files
committed
add rcfuse
1 parent dc278e5 commit acf4f65

File tree

5 files changed

+98
-80
lines changed

5 files changed

+98
-80
lines changed

meson.build

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ mir_algorithm_src = [
3131
'source/mir/interpolate/constant.d',
3232
'source/mir/interpolate/linear.d',
3333
'source/mir/interpolate/package.d',
34-
'source/mir/interpolate/pchip.d',
3534
'source/mir/interpolate/spline.d',
3635
'source/mir/interpolate/utility.d',
3736
'source/mir/math/func/expdigamma.d',

source/mir/interpolate/package.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Returns:
101101
Lazy input range.
102102
See_also:
103103
$(SUBREF linear, linear),
104-
$(SUBREF pchip, pchip).
104+
$(SUBREF spline, spline).
105105
+/
106106
auto interp1(Range, Interpolant)(Range range, Interpolant interpolant, size_t interval = 0)
107107
{

source/mir/interpolate/pchip.d

Lines changed: 0 additions & 56 deletions
This file was deleted.

source/mir/ndslice/allocation.d

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,36 @@ version(mir_test)
171171
static assert(is(typeof(tensor) == Slice!(RCI!ptrdiff_t, 2)));
172172
}
173173

174+
/++
175+
Allocates an n-dimensional reference-counted (thread-safe) slice without memory initialisation.
176+
Params:
177+
lengths = List of lengths for each dimension.
178+
init = Value to initialize with (optional).
179+
slice = Slice to copy shape and data from (optional).
180+
Returns:
181+
n-dimensional slice
182+
+/
183+
Slice!(RCI!T, N)
184+
uninitRCslice(T, size_t N)(size_t[N] lengths...)
185+
{
186+
immutable len = lengths.lengthsProduct;
187+
auto _lengths = lengths;
188+
return typeof(return)(_lengths, RCI!T(RCArray!T(len, false)));
189+
}
190+
191+
///
192+
version(mir_test)
193+
@safe pure nothrow @nogc unittest
194+
{
195+
import mir.ndslice.slice: Slice;
196+
import mir.rc.array: RCI;
197+
auto tensor = uninitRCslice!int(5, 6, 7);
198+
tensor[] = 1;
199+
assert(tensor.length == 5);
200+
assert(tensor.elementCount == 5 * 6 * 7);
201+
static assert(is(typeof(tensor) == Slice!(RCI!int, 3)));
202+
}
203+
174204
/++
175205
Allocates a bitwise packed n-dimensional reference-counted (thread-safe) boolean slice.
176206
Params:

source/mir/ndslice/fuse.d

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,29 @@ import mir.math.common: optmath;
2828
@optmath:
2929

3030
/++
31-
Fuses ndrange `r` into GC-allocated ndslice. Can be used to join rows or columns into a matrix.
31+
Fuses ndrange `r` into GC-allocated (`fuse`) or RC-allocated (`rcfuse`) ndslice. Can be used to join rows or columns into a matrix.
3232
3333
Params:
3434
Dimensions = (optional) indexes of dimensions to be brought to the first position
3535
Returns:
3636
ndslice
3737
+/
38-
template fuse(Dimensions...)
38+
///
39+
alias fuse(Dimensions...) = fuseImpl!(false, Dimensions);
40+
///
41+
alias rcfuse(Dimensions...) = fuseImpl!(true, Dimensions);
42+
/// ditto
43+
template fuseImpl(bool RC, Dimensions...)
3944
{
4045
import mir.ndslice.internal: isSize_t, toSize_t;
4146
static if (!allSatisfy!(isSize_t, Dimensions))
42-
alias fuse = .fuse!(staticMap!(toSize_t, Dimensions));
47+
alias fuseImpl = .fuseImpl!(RC, staticMap!(toSize_t, Dimensions));
4348
else
4449
/++
4550
Params:
4651
r = parallelotope (ndrange) with length/shape and input range primitives.
4752
+/
48-
@optmath Slice!(FuseElementType!NDRange*, fuseDimensionCount!NDRange) fuse(NDRange)(NDRange r)
53+
@optmath auto fuseImpl(NDRange)(NDRange r)
4954
if (hasShape!NDRange)
5055
{
5156
import mir.conv: emplaceRef;
@@ -54,8 +59,17 @@ template fuse(Dimensions...)
5459
auto shape = fuseShape(r);
5560
alias T = FuseElementType!NDRange;
5661
alias UT = Unqual!T;
57-
alias R = typeof(return);
58-
Slice!(UT*, fuseDimensionCount!NDRange) ret;
62+
static if (RC)
63+
{
64+
import mir.rc.array: RCI;
65+
alias R = Slice!(RCI!T, fuseDimensionCount!NDRange);
66+
Slice!(RCI!UT, fuseDimensionCount!NDRange) ret;
67+
}
68+
else
69+
{
70+
alias R = Slice!(T*, fuseDimensionCount!NDRange);
71+
Slice!(UT*, fuseDimensionCount!NDRange) ret;
72+
}
5973
static if (Dimensions.length)
6074
{
6175
import mir.ndslice.topology: iota;
@@ -72,40 +86,66 @@ template fuse(Dimensions...)
7286
return ar;
7387
}(perm)
7488
);
75-
if (__ctfe)
89+
static if (RC)
7690
{
77-
ret = shapep.slice!UT;
78-
ret.transposed!InverseDimensions.each!"a = b"(r);
91+
ret = shapep.uninitRcslice!UT;
92+
ret.lightScope.transposed!InverseDimensions.each!(emplaceRef!T)(r);
7993
}
8094
else
8195
{
82-
ret = shapep.uninitSlice!UT;
83-
ret.transposed!InverseDimensions.each!(emplaceRef!T)(r);
96+
if (__ctfe)
97+
{
98+
ret = shapep.slice!UT;
99+
ret.transposed!InverseDimensions.each!"a = b"(r);
100+
}
101+
else
102+
{
103+
ret = shapep.uninitSlice!UT;
104+
ret.transposed!InverseDimensions.each!(emplaceRef!T)(r);
105+
}
106+
84107
}
85108
}
86109
else
87110
{
88-
if (__ctfe)
111+
static if (RC)
89112
{
90-
ret = shape.slice!UT;
91-
ret.each!"a = b"(r);
113+
ret = shape.uninitRCslice!UT;
114+
ret.lightScope.each!(emplaceRef!T)(r);
92115
}
93116
else
94117
{
95-
ret = shape.uninitSlice!UT;
96-
ret.each!(emplaceRef!T)(r);
118+
if (__ctfe)
119+
{
120+
ret = shape.slice!UT;
121+
ret.each!"a = b"(r);
122+
}
123+
else
124+
{
125+
ret = shape.uninitSlice!UT;
126+
ret.each!(emplaceRef!T)(r);
127+
}
97128
}
98129
}
99-
return R(ret._structure, (() @trusted => cast(T*)ret._iterator)());
130+
static if (RC)
131+
{
132+
import core.lifetime: move;
133+
return move(*(() @trusted => cast(R*)&ret)());
134+
}
135+
else
136+
{
137+
return *(() @trusted => cast(R*)&ret)();
138+
}
100139
}
101140
}
102141

103142
///
104-
unittest
143+
@safe pure nothrow version(mir_test) unittest
105144
{
106145
import mir.ndslice.fuse;
107-
import mir.ndslice.topology: iota;
108146
import mir.ndslice.slice : Contiguous, Slice;
147+
import mir.ndslice.topology: iota;
148+
import mir.rc.array: RCI;
109149

110150
enum ror = [
111151
[0, 1, 2, 3],
@@ -117,14 +157,19 @@ unittest
117157
// 8 9 10 11
118158
auto matrix = ror.fuse;
119159

160+
auto rcmatrix = ror.rcfuse; // nogc version
161+
120162
assert(matrix == [3, 4].iota);
163+
assert(rcmatrix == [3, 4].iota);
121164
static assert(ror.fuse == [3, 4].iota); // CTFE-able
165+
122166
// matrix is contiguos
123167
static assert(is(typeof(matrix) == Slice!(int*, 2)));
168+
static assert(is(typeof(rcmatrix) == Slice!(RCI!int, 2)));
124169
}
125170

126171
/// Transposed
127-
unittest
172+
@safe pure nothrow version(mir_test) unittest
128173
{
129174
import mir.ndslice.fuse;
130175
import mir.ndslice.topology: iota;
@@ -153,7 +198,7 @@ unittest
153198

154199

155200
/// 3D
156-
unittest
201+
@safe pure nothrow version(mir_test) unittest
157202
{
158203
import mir.ndslice.fuse;
159204
import mir.ndslice.topology: iota;
@@ -174,7 +219,7 @@ unittest
174219
}
175220

176221
/// Work with RC Arrays of RC Arrays
177-
unittest
222+
@safe pure nothrow version(mir_test) unittest
178223
{
179224
import mir.ndslice.fuse;
180225
import mir.ndslice.slice;

0 commit comments

Comments
 (0)