Skip to content

Commit 69740f8

Browse files
committed
Remove value convertibility exclusion from Cell
This was done because the old impl of iota() used to be non-convertible, but there's no reason to handle this differently from other exprs. * ra/expr (Cell): As stated.
1 parent e9b03f3 commit 69740f8

File tree

8 files changed

+32
-55
lines changed

8 files changed

+32
-55
lines changed

TODO

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ checkbox [C-ct] flip TODO
1313
Match isn't even involved. See checks.cc.
1414
- [ ] const issues in View vs Container
1515
- [ ] conversion to const & op in ViewBig uses reinterpret_const
16-
- [X] ra::Small<real, 3, 3, 3>() benchmark in bench-dot.cc has op 10x worse than indexed
17-
- Fixed in ca20c1678bb7aa43ccf6b4fe1b93ee9c742b1630. Yay!
18-
- Appears to have regressed in 65076211eeeeecd8623877e3e3b5cc0a87af302c, although by a smaller factor. Bummer.
19-
- Looks good in v20 in g++-11, but bad in 12/13. Bummer.
20-
- Investigated & resolved in e297ee0561a647065fb5b92880fe0f994340595c ss.
2116
- [ ] Small/Big unification
2217
- [ ] Forbid initialization from higher rank
2318
- Cf 'Initialization of nested types' in the manual.
@@ -32,26 +27,25 @@ checkbox [C-ct] flip TODO
3227
- [-] Features [0/15]
3328
- [ ] generalize cat
3429
- [-] support std::format
35-
- [X] basic support
36-
- [X] ways to use the formatter without parsing, like ra::format_t { .option = value ... }.
3730
- [ ] ellipsis feature, e.g. max width/max length.
3831
- [ ] formatting options for the shape (needed?)
32+
- [X] ways to use the formatter without parsing, like ra::format_t { .option = value ... }.
33+
- [X] basic support
3934
- [ ] compatibility with OpenMP, even if only for trivially parallel cases
4035
The way ply() works atm, with iterators, more or press precludes it.
4136
- [ ] support expr = braces for any expr, not just views.
4237
- [ ] make iter work with w/rank.
4338
- [ ] make iter work with foreign vectors.
4439
- [ ] Can choose iteration order in plyers. Order is already explicit, just need to expose it.
4540
- [-] Deduction guides, e.g. ra::Small a = {{1, 2}, {3, 4}} ?! maybe rank 1 first
46-
- [X] rank 1 SmallArray <2023-06-23 Fri 13:24> (not very useful)
4741
- [ ] rank >1 SmallArray
4842
- [ ] Small
4943
- [ ] Big
44+
- [X] rank 1 SmallArray <2023-06-23 Fri 13:24> (not very useful)
5045
- [ ] Support ra::len in x in o.len(x).
5146
- [ ] Shape returns Small not std::array (for static rank expr).
5247
- [ ] Remove inheritance relationship of Container on ViewBig
53-
- [ ] Should be able to turn ravel iterators (e.g. ViewBig::begin()) into array iterators. Ptr()
54-
doesn't work for that.
48+
- [ ] Should be able to turn ravel iterators (e.g. ViewBig::begin()) into array iterators.
5549
- This has become more feasible after changing the iterator interface from flat to saveload,
5650
main obstacle atm seems to be the need to support copy. <2023-11-20 Mon 12:45>
5751
- One can now create a ravel iterator from an Iterator <2023-11-28 Tue 16:37>
@@ -61,12 +55,12 @@ checkbox [C-ct] flip TODO
6155
it's just a one time op. Propagating ops down Map into leaf Views (a kind of beating) would
6256
be better.
6357
- [-] Magic subscript len
58+
- [ ] Optimize iota(len...) + iota(len...)
6459
- [X] For Big/View in beatable subscripts <2023-07-04 Tue 18:20>
6560
- [X] For Big/View in unbeatable subscripts <2023-07-05 Wed 12:34>
6661
- [X] For Small/ViewSmall
6762
- [X] Scalar / unbeatable <2023-08-04 Fri 14:18>
6863
- [X] iota. But iota args need to integral constants for this to work.
69-
- [ ] Optimize iota(len...) + iota(len...)
7064
- [-] Performance [0/2]
7165
- [ ] bench/bench-stencil* is weird.
7266
- [ ] Bigd cases in bench-at.
@@ -76,7 +70,7 @@ checkbox [C-ct] flip TODO
7670
- [X] Support RA_USE_BLAS with cmake (mac) <2018-12-07 Fri 16:33>
7771
- [X] TestRecorder.test_eq with mismatched shapes aborts. Should just fail the test. <2023-07-10 Mon 13:14>
7872
- We have had agree() for a while.
79-
- [ ] Make cmake tests respect dependences and able to be run independently.
73+
- [ ] Make cmake tests respect dependencies and able to be run independently.
8074
- [ ] Test for expected compilation errors (static_assert, etc) [ra42].
8175
- One idea (libc++?) is to fork() and check that child breaks.
8276
- [ ] Documentation [0/3]
@@ -225,3 +219,8 @@ Some of these aren't bugs in the sense that I expect to solve them, but more lik
225219
- <2025-07-24 Thu 11:35> was caused by auto && x constructor interfereing.
226220
Fixed in 85653fd786c78e339f730699021ebdac39877012
227221
- [X] Merge Ptr and Iota. Why need more than one rank 1 Iterator adaptor.
222+
- [X] ra::Small<real, 3, 3, 3>() benchmark in bench-dot.cc has op 10x worse than indexed
223+
- Fixed in ca20c1678bb7aa43ccf6b4fe1b93ee9c742b1630. Yay!
224+
- Appears to have regressed in 65076211eeeeecd8623877e3e3b5cc0a87af302c, although by a smaller factor. Bummer.
225+
- Looks good in v20 in g++-11, but bad in 12/13. Bummer.
226+
- Investigated & resolved in e297ee0561a647065fb5b92880fe0f994340595c ss.

box/SConstruct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ env.Prepend(CPPPATH=['..', '.'],
5050
LINKFLAGS=raflags['LINKFLAGS'])
5151

5252
[ra.to_test_ra(env, variant_dir)(example)
53-
for example in ['tuple-construct', 'iterator-as-ravel', 'cellptr']]
53+
for example in ['tuple-construct', 'iterator-as-ravel']]
5454

5555
if not top['skip_summary']:
5656
atexit.register(lambda: ra.print_summary(GetBuildFailures, 'ra/box'))

ra/expr.hh

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -319,17 +319,16 @@ struct Cell: public std::conditional_t<is_constant<Dimv>, CellSmall<P, Dimv, Cr>
319319
using Base::Base, Base::cellr, Base::framer, Base::c, Base::step, Base::len, Base::len_s, Base::rank;
320320
using View = decltype(std::declval<Base>().c);
321321
static_assert((cellr>=0 || cellr==ANY) && (framer>=0 || framer==ANY), "Bad cell/frame ranks.");
322-
constexpr auto data() const { return c.cp; }
323322
RA_ASSIGNOPS_ITER(Cell)
324-
// FIXME only for the sake of iota(), which needs to be both iterator and slice.
323+
// for the sake of iota(), which needs to be both iterator and slice. FIXME make iota() View not Cell.
325324
template <rank_t c=0> constexpr auto iter() const requires (0==cellr && 1==framer) { static_assert(0==c); return *this; }
325+
constexpr auto data() const { return c.cp; }
326326
constexpr void adv(rank_t k, dim_t d) { mov(step(k)*d); }
327327
constexpr decltype(*c.cp) at(auto const & i) const requires (0==cellr) { return *indexer(*this, c.cp, ra::iter(i)); }
328328
constexpr View at(auto const & i) const requires (0!=cellr) { View d(c); d.cp=indexer(*this, d.cp, ra::iter(i)); return d; }
329329
constexpr decltype(*c.cp) operator*() const requires (0==cellr) { return *(c.cp); }
330330
constexpr View const & operator*() const requires (0!=cellr) { return c; }
331-
constexpr static bool static_1 = framer>=0 && std::apply([](auto ... i){ return ((1==len_s(i)) && ...); }, mp::iota<(framer<0)?0:framer> {});
332-
constexpr operator decltype(*c.cp) () const requires (0==cellr && static_1) /* [ra45 */ { return to_scalar(*this); }
331+
constexpr operator decltype(*c.cp) () const { return to_scalar(*this); } /* [ra45] */
333332
constexpr auto save() const { return c.cp; }
334333
constexpr void load(P p) { c.cp=p; }
335334
#pragma GCC diagnostic push
@@ -348,25 +347,20 @@ constexpr auto
348347
ptr(P && p, N && n=N {}, S && s=S(maybe_step<S>))
349348
{
350349
if constexpr (std::ranges::bidirectional_range<std::remove_reference_t<P>>) {
351-
static_assert(std::is_same_v<ic_t<dim_t(UNB)>, N>, "Object has own length.");
352-
static_assert(std::is_same_v<ic_t<dim_t(1)>, S>, "No step with deduced size.");
353-
if constexpr (ANY==size_s(p)) {
354-
return ptr(std::begin(RA_FW(p)), std::ssize(p), RA_FW(s));
355-
} else {
356-
return ptr(std::begin(RA_FW(p)), ic<size_s(p)>, RA_FW(s));
357-
}
350+
static_assert(std::is_same_v<ic_t<dim_t(UNB)>, N>, "Conflict with own length.");
351+
static_assert(std::is_same_v<ic_t<dim_t(1)>, S>, "Deduced size means unit step.");
352+
return ptr(std::begin(RA_FW(p)), [&p](){ if constexpr (ANY==size_s(p)) return ra::size(p); else return ic<size_s(p)>; }(), RA_FW(s));
358353
} else {
359354
if constexpr (std::is_integral_v<N>) { RA_CK(n>=0, "Bad Ptr length ", n, "."); }
360-
using Dim = ra::SDim<sarg<N>, sarg<S>>;
361-
return Ptr<std::decay_t<P>, sarg<N>, sarg<S>> { p, {Dim {.len=RA_FW(n), .step=RA_FW(s) }}};
355+
return Ptr<std::decay_t<P>, sarg<N>, sarg<S>> { p, {ra::SDim<sarg<N>, sarg<S>> {.len=RA_FW(n), .step=RA_FW(s) }}};
362356
}
363357
}
364358

365359
template <class I, class N, class S, class K=ic_t<dim_t(0)>>
366360
constexpr auto
367361
reverse(Ptr<Seq<I>, N, S> const & i, K k = {})
368362
{
369-
static_assert(UNB!=i.len_s(0), "Bad arguments to reverse(iota).");
363+
static_assert(UNB!=i.len_s(0), "Bad arguments to reverse.");
370364
return ptr(Seq { i.data().i+(i.dimv[0].len-1)*i.dimv[0].step }, i.dimv[0].len, csub(ic<0>, i.dimv[0].step));
371365
}
372366

ra/ply.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ fromb(auto pl, auto ds, auto && bv, int bk, auto && a, int ak)
538538
#pragma GCC diagnostic push // gcc14/15 -DRA_CHECK=0 --no-sanitize -O2 -O3 [ra03]
539539
#pragma GCC diagnostic warning "-Warray-bounds"
540540
#pragma GCC diagnostic warning "-Wstringop-overflow"
541-
bv[bk] = { a.dimv[ak].len, a.dimv[ak].step }; // support Ptr
541+
bv[bk] = { a.dimv[ak].len, a.dimv[ak].step };
542542
#pragma GCC diagnostic pop
543543
}
544544
}

test/SConstruct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ env.Prepend(CPPPATH=['..', '.'],
5252
tester = ra.to_test_ra(env, variant_dir)
5353

5454
[tester(test)
55-
for test in ['at', 'bench', 'big-0', 'big-1', 'bug83', 'bug10', 'cellrank', 'checks', 'compatibility',
55+
for test in ['at', 'bench', 'big-0', 'big-1', 'bug83', 'bug10', 'cellptr', 'cellrank', 'checks', 'compatibility',
5656
'concrete', 'const', 'constexpr', 'dual', 'early', 'explode-0', 'foreign', 'frame-new',
5757
'frame-old', 'fromb', 'fromu', 'genfrom', 'headers', 'io', 'iota', 'iterator-small', 'len',
5858
'list9', 'macros', 'mem-fn', 'ndebug', 'nested-0', 'operators', 'optimize',

test/big-0.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int main(int argc, char * * argv)
7878
static_assert(!ctest3<int>);
7979
static_assert(!ctest4<int>);
8080

81-
// FIXME these errors depend on static_assert so cannot be checked with requires.
81+
// FIXME these errors depend on static_assert so cannot be checked with requires.
8282
// ra::Big<T, 2> {3, 4}; // Invalid shape for rank
8383
// ra::Big<int, 2> (2, ra::none); // shape arg must have rank 1 for array rank>1
8484
// ra::Big<T, 2> {1, 2, 3, 4, 5, 6}; // bad deduced shape from content arg
@@ -198,13 +198,12 @@ int main(int argc, char * * argv)
198198
ra::Small<ra::Big<int, 1>, 1> d = { {1, 2, 3} }; // ok
199199
tr.test_eq(ra::iota(3, 1), d(0));
200200

201-
// requires that x NOT be convertible to int, but expressions generally are convertible to their val type.
202-
// his is hacked away in Cell's conversion operator. FIXME probably not worth it.
203-
auto x = ra::iota(3, 1);
204-
ra::Small<ra::Big<int, 1>, 1> f = { {x} }; // ok; broken with { x }
205-
tr.test_eq(ra::iota(3, 1), f(0));
201+
// these fail because x/w is convertible to int. This used not to be the case for old Ptr / iota (so the 1st one worked), but if anything, it is the second that shouldn't be convertible, because the size is static and we exclude size_s!=1 from convertibility (maybe FIXME).
202+
203+
// auto x = ra::iota(3, 1);
204+
// ra::Small<ra::Big<int, 1>, 1> f = { {x} }; // broken with { x }, rt error with { {x} }
205+
// tr.test_eq(ra::iota(3, 1), f(0));
206206

207-
// fails for the same reason.
208207
// ra::Small<int, 3> w = { 1, 2, 3 };
209208
// ra::Small<ra::Big<int, 1>, 1> e = { {w} }; // broken with { w }, ct error with { {w} }
210209
// tr.test_eq(ra::iota(3, 1), e(0));

test/cellptr.cc

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// -*- mode: c++; coding: utf-8 -*-
2-
// ra-ra/box - Special Dimv to let Cell<> replace Ptr
2+
// ra-ra/box - Replacement sandbox of Oldptr (old ptr/iota) by Cell (current)
33

4-
// (c) Daniel Llorens - 2025
4+
// (c) Daniel Llorens - 2025-2026
55
// This library is free software; you can redistribute it and/or modify it under
66
// the terms of the GNU Lesser General Public License as published by the Free
77
// Software Foundation; either version 3 of the License, or (at your option) any
@@ -219,20 +219,5 @@ int main()
219219
tr.test(ra::Slice<decltype(ra::iota2(10))>);
220220
tr.test(ra::Slice<decltype(ra::iota3(10))>);
221221
}
222-
// 1st goes to constexpr SmallArray(T const & t) { std::ranges::fill(cp, t); }, the other idk :-/
223-
tr.section("regression from test/big-0");
224-
{
225-
auto x = ra::iota1(3, 1);
226-
cout << "conv1 " << std::is_convertible_v<decltype(x), int> << endl;
227-
ra::Small<ra::Big<int, 1>, 1> f = { {x} }; // ok; broken with { x }
228-
tr.test_eq(ra::iota(3, 1), f(0));
229-
}
230-
{
231-
auto x = ra::iota3(3, 1);
232-
cout << "conv1 " << std::is_convertible_v<decltype(x), int> << endl;
233-
cout << "static_1 " << decltype(x)::static_1 << endl;
234-
ra::Small<ra::Big<int, 1>, 1> f = { {x} }; // ok; broken with { x }
235-
tr.test_eq(ra::iota(3, 1), f(0));
236-
}
237222
return tr.summary();
238223
}

test/iota.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ int main()
7474
{
7575
tr.test_eq(sizeof(ra::iota().data()), sizeof(ra::dim_t));
7676
tr.test_eq(sizeof(ra::iota(4, 0, 2).data()), sizeof(0));
77-
tr.info("not true when Ptr is slice").skip().test_eq(sizeof(ra::iota().data()), sizeof(ra::iota()));
78-
tr.info("not true when Ptr is slice").skip().test_eq(sizeof(ra::iota().data()), sizeof(ra::iota(ra::dim_c<4> {})));
77+
tr.info("not when Ptr is Cell").skip().test_eq(sizeof(ra::iota().data()), sizeof(ra::iota()));
78+
tr.info("not when Ptr is Cell").skip().test_eq(sizeof(ra::iota().data()), sizeof(ra::iota(ra::dim_c<4> {})));
7979
// sizeof might still be > sizeof(i) + sizeof(n) because of alignment
8080
tr.test_eq(1, decltype(ra::iota(4).dimv[0].step)::value);
8181
tr.test_eq(sizeof(ra::iota(4, 0, 2)), sizeof(ra::iota(4, 0, 2).data()) + sizeof(ra::iota(4, 0, 2).dimv[0].len) + sizeof(ra::iota(4, 0, 2).dimv[0].step));

0 commit comments

Comments
 (0)