Compare commits

...

389 commits

Author SHA1 Message Date
b03e35d422 Merge pull request 'update workflows' (#10) from fix into main
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
Reviewed-on: #10
2024-05-17 20:33:15 +02:00
Christian Zimmermann
a1a1448ee6 update workflows 2024-05-17 20:31:37 +02:00
0139fd1192 Merge pull request 'base/utils.h: add algorithm library (seems to be neccessary on newer systems)' (#9) from fix into main
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
Reviewed-on: #9
2024-05-16 18:40:45 +02:00
Christian Zimmermann
ecd279e5b7 base/utils.h: add algorithm library (seems to be neccessary on newer systems) 2024-05-15 18:11:38 +02:00
27c4c59d19 Merge pull request 'correct .github/workflows/main.yml' (#8) from dev into main
Reviewed-on: #8
2024-02-04 18:57:01 +00:00
Christian Zimmermann
a68ed3722f correct .github/workflows/main.yml 2024-02-04 19:56:40 +01:00
1d36fefec4 Merge pull request 'correct .github/workflows/main.yml' (#7) from dev into main
Reviewed-on: #7
2024-02-04 18:53:35 +00:00
Christian Zimmermann
cc332069ad correct .github/workflows/main.yml 2024-02-04 19:53:16 +01:00
38d0258aa4 Merge pull request 'correct .github/workflows/main.yml' (#6) from dev into main
Reviewed-on: #6
2024-02-04 18:34:06 +00:00
Christian Zimmermann
1aa6828e8a correct .github/workflows/main.yml 2024-02-04 19:33:43 +01:00
e0b32d7e25 Merge pull request 'github doxy task: workflow_dispatch' (#5) from dev into main
Reviewed-on: #5
2024-02-04 18:31:34 +00:00
Christian Zimmermann
29913bb350 github doxy task: workflow_dispatch 2024-02-04 19:31:07 +01:00
75b2bde675 Merge pull request 'add github doxygen workflow + add LICENSE + update README' (#4) from dev into main
Reviewed-on: #4
2024-02-04 18:14:48 +00:00
Christian Zimmermann
b802aac2d0 add github doxygen workflow + add LICENSE + update README
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-04 19:05:12 +01:00
e392db5fdc Merge pull request 'dev' (#3) from dev into main
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: chizeta/CNORXZ#3
2024-02-03 23:49:58 +00:00
Christian Zimmermann
9b9a8a596e update TODO
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-02-04 00:39:28 +01:00
Christian Zimmermann
1261435835 correct CMakeLists.txt
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-04 00:26:28 +01:00
Christian Zimmermann
be312c31bb readme minor changes...
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 23:55:54 +01:00
Christian Zimmermann
b20de211ef remove some code that has been already commented out
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 23:35:29 +01:00
Christian Zimmermann
8a0fdf7a7c improve comment notation + add missing briefs
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 23:21:40 +01:00
Christian Zimmermann
c478bf0fae more documentation + clean up
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 22:02:01 +01:00
Christian Zimmermann
5eff4cfe3f improve doxygen setup
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 18:35:13 +01:00
Christian Zimmermann
871910355d cereal documentation
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 16:44:34 +01:00
Christian Zimmermann
b2c52384b0 README: expressions and operations section (WIP)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 01:22:52 +01:00
6793fc1bdb Merge pull request 'dev' (#2) from dev into main
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: chizeta/CNORXZ#2
2024-02-02 19:36:53 +00:00
Christian Zimmermann
1a26f1407f remove deprecated definition in .woodpecker.yml
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-02-02 20:31:50 +01:00
Christian Zimmermann
dc7137f400 hdf5: fix oinfo bug occuring for older hdf5 versions
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-02 20:28:22 +01:00
Christian Zimmermann
2023d64a5f hdf5: clean up + fixes
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-02 19:25:09 +01:00
Christian Zimmermann
190032729a urange: fix bug (seg fault) in getMeta
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-02 16:27:18 +01:00
Christian Zimmermann
27466f6ef1 hdf5: fix doxy errors + remove some unused code
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-02 15:11:03 +01:00
Christian Zimmermann
c46d9b1772 hdf5: virtual function exists() in ContentBase + hdf5 header documentation
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-02 14:51:51 +01:00
Christian Zimmermann
1f7ebae61b WIP: hdf5 documentation
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-02 12:13:54 +01:00
Christian Zimmermann
26831adb94 fix compile error
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-02 11:55:27 +01:00
Christian Zimmermann
be3f5521e8 WIP: hdf5 documentation
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-02 00:36:14 +01:00
Christian Zimmermann
eb3055ddca hdf5: several fixes + yrange: add setSub member function + dindex: add missing operator*(dindex,index)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-01 18:22:08 +01:00
Christian Zimmermann
6f3601daa4 hdf5: dataset
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-01 00:11:20 +01:00
Christian Zimmermann
e2e233b931 im com
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-31 19:09:04 +01:00
Christian Zimmermann
df228d545b WIP: hdf5: Dataset
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-31 00:16:34 +01:00
Christian Zimmermann
84f18e1d5e hdf5: groups: handle paths to access sub-content objects
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-30 19:18:33 +01:00
Christian Zimmermann
39c0a3146f hdf5: table: iterRecords + test
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-30 01:13:58 +01:00
Christian Zimmermann
f7c00eab8c improve table read / readRecord
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-30 00:14:06 +01:00
Christian Zimmermann
e3ad04e56c add table read functions
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-28 23:39:27 +01:00
Christian Zimmermann
b2637802be changes in STable
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-28 16:42:11 +01:00
Christian Zimmermann
30a3c0b756 fixes in to_string + h5 attributes
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-28 01:57:52 +01:00
Christian Zimmermann
035ae78785 h5: simple attribute handling (to be tested)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-25 01:19:26 +01:00
Christian Zimmermann
d5b42c9c00 hdf5: group iterations
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-23 02:17:56 +01:00
Christian Zimmermann
f77132ddfe hdf5: fix group mkCont + improve error handling of urange/yrange at()
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-01-22 00:03:08 +01:00
Christian Zimmermann
0bfee171e0 add POpRoot class + prange: implement xpr()
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-20 22:38:15 +01:00
Christian Zimmermann
91f9a3c957 prange: add missing extend() implementation
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-20 21:33:40 +01:00
Christian Zimmermann
21a11eb4f6 ranges: add remaining doxy comments
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-19 23:32:41 +01:00
Christian Zimmermann
a5031d80b1 prange comments
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-17 22:57:18 +01:00
Christian Zimmermann
ac352206c7 more doc
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-14 23:57:42 +01:00
Christian Zimmermann
4c71fac091 more documentation; WIP: mrange doc
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-13 18:26:28 +01:00
Christian Zimmermann
0eb505f41b yrange: solve lower-dim-reformat issue
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-03 19:18:20 +01:00
Christian Zimmermann
d66164e874 mrange: solve lower-dim-reformat issue
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-03 11:54:06 +01:00
Christian Zimmermann
ab13d97b03 cmake: new version string
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-02 20:43:05 +01:00
Christian Zimmermann
e3f8fa17ba yrange/yindex: comments
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-30 18:10:07 +01:00
f6af00d162 Merge pull request 'dev' (#1) from dev into main
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: chizeta/CNORXZ#1
2023-12-29 23:37:24 +00:00
Christian Zimmermann
671eedf9fe link logo in html docu
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2023-12-30 00:27:54 +01:00
Christian Zimmermann
30a6acf903 readme: include logo
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-30 00:23:06 +01:00
Christian Zimmermann
7376905928 doxy: use readme as main page
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-30 00:09:29 +01:00
Christian Zimmermann
e8db02a6ec more doc
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-29 22:48:28 +01:00
Christian Zimmermann
5a75c7964f remove .gitlab-ci.yml
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-29 15:20:02 +01:00
Christian Zimmermann
6857e3fc7d yindex+mindex: reformat: todo errmsg
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-29 00:36:52 +01:00
Christian Zimmermann
e94bad17fb ... and again...
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-28 23:14:07 +01:00
Christian Zimmermann
2155568864 CI: scalar build
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-28 23:12:04 +01:00
Christian Zimmermann
ab4cb78258 WIP: index format
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-28 21:57:05 +01:00
Christian Zimmermann
c72fbc329d WIP: index format test + fixes...
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-28 00:25:44 +01:00
Christian Zimmermann
bf83c26a12 index reformat: apply format change to same instance (no copy)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-25 22:07:39 +01:00
Christian Zimmermann
62b75c01a0 WIP: reformat tests
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-25 15:08:40 +01:00
Christian Zimmermann
df2a8e5a0b WIP: index reformat: mindex: do not copy single-indices
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-22 01:52:49 +01:00
Christian Zimmermann
4b9c8e94dc WIP: index reformat
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-19 18:43:05 +01:00
Christian Zimmermann
00eb2d2fb1 WIP: reformat
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-19 02:08:15 +01:00
Christian Zimmermann
642381ecc0 YRange: bug fix in deepFormat + add setFormat + array: bug fix in check format
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-11 02:20:02 +01:00
Christian Zimmermann
fb8a44e88b WIP: todos in array operator(), operator[]
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-11 01:11:49 +01:00
Christian Zimmermann
a7c1aad6fc comment memory section
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-10 18:59:09 +01:00
Christian Zimmermann
129c27a28d index: remove xpr() from base type + add trait to check if expression is available
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-12-02 18:02:34 +01:00
Christian Zimmermann
eee1805f88 get intrinsics vector size from environment + compile with avx -> works
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-11-20 00:41:37 +01:00
Christian Zimmermann
886c47bc24 add TODOs
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-19 19:52:46 +01:00
Christian Zimmermann
55ebc2e3d7 finish xpr_base.cc.h
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-19 19:17:55 +01:00
Christian Zimmermann
a5593a04f6 comment-out empty vpos specialization (might have been deprecated before, TDOD: check)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-19 18:43:42 +01:00
Christian Zimmermann
3b7040447c re-implement DIndex ifor (-> template)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-12 23:16:56 +01:00
Christian Zimmermann
0f0a01793c for return value -> None
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-09 22:53:35 +01:00
Christian Zimmermann
43f5e560fa dynamic indices: DXpr<SizeT> -> DXpr<None>
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-08 02:06:16 +01:00
Christian Zimmermann
09f15408b1 for: bug fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-07 02:22:30 +01:00
Christian Zimmermann
3d08dc530e implement missing trivial format checks
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-06 23:21:03 +01:00
Christian Zimmermann
be44541135 more doxy comments + WIP: index member function formatIsTrivial
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-05 22:20:12 +01:00
Christian Zimmermann
7487929bfc add comment header to include/array files
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-05 16:27:36 +01:00
Christian Zimmermann
c055ef39da base+ranges: more docu
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-05 01:25:23 +01:00
Christian Zimmermann
62f83de07b add more docu for range_base / index_base code
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-04 02:12:32 +01:00
Christian Zimmermann
337774cd8f ranges: comment blocks
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-04 00:24:30 +01:00
Christian Zimmermann
c9f7407de8 WIP: doxygen + remove unused code
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-03 02:01:01 +01:00
Christian Zimmermann
17d40add98 rewrite README, wip
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-11-01 18:50:04 +01:00
Christian Zimmermann
fcf6712912 WIP: doxy
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
2023-11-01 02:58:05 +01:00
Christian Zimmermann
636c1d6407 corrections + remove old files + some todos 2023-11-01 01:23:32 +01:00
Christian Zimmermann
0e616f8370 add operator- Index 2023-10-29 22:03:45 +01:00
Christian Zimmermann
04af9ec3e8 remove old code (access.h + access.cc.h) 2023-10-29 19:20:26 +01:00
Christian Zimmermann
cb2db9c80d add first slice tests + corresp fixes 2023-10-24 02:01:29 +02:00
Christian Zimmermann
2a763d67be test prange of prange + corresp fixes 2023-10-22 17:06:30 +02:00
Christian Zimmermann
eb5276c967 tests and fix bugs regarding prange 2023-10-22 01:33:54 +02:00
Christian Zimmermann
cf0e7c5856 implement missing prange member functions 2023-10-21 19:23:38 +02:00
Christian Zimmermann
301967288f index: add prange member function 2023-10-21 18:29:16 +02:00
Christian Zimmermann
db6b0a14ec WIP: slicing + partial ranges
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-09-18 00:01:27 +02:00
Christian Zimmermann
9b706c4ec0 check format compatibility
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-10 14:35:53 +02:00
Christian Zimmermann
bfeda55904 WIP: check format compatibility
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-09 13:20:20 +02:00
Christian Zimmermann
303450d068 WIP: deepFormat + check format compatibility
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-09 12:56:39 +02:00
Christian Zimmermann
7e182ded83 comment out formatFrom/slice ...
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-09 11:29:22 +02:00
Christian Zimmermann
944db31e02 WIP: deepFormat + check format compatibility
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-09 11:14:03 +02:00
Christian Zimmermann
b0a5b1d13f WIP: deepFormat + check format compatibility
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-09-08 19:18:54 +02:00
Christian Zimmermann
1eea0e8a3f fix again .woodpecker.yml
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-06 17:04:05 +02:00
Christian Zimmermann
81a21120ed fix compile errors
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-09-06 17:01:59 +02:00
Christian Zimmermann
5acd80bdcb try to fix CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 13:17:24 +02:00
Christian Zimmermann
425a5524c4 try to fix CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 13:16:56 +02:00
Christian Zimmermann
b0810b80b7 try to fix CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:55:12 +02:00
Christian Zimmermann
28e14e1604 debug CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:51:20 +02:00
Christian Zimmermann
babf17cf6f try to fix CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:50:29 +02:00
Christian Zimmermann
98c168cbf3 debug CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:30:46 +02:00
Christian Zimmermann
44ba32b029 try to fix CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:29:06 +02:00
Christian Zimmermann
defa7c9211 try to fix CMakeLists.txt
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:27:28 +02:00
Christian Zimmermann
b5be793548 remove tabs in .woodpecker.yml
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-08-31 12:15:45 +02:00
Christian Zimmermann
9d9180fdcb add .woodpecker.yml 2023-08-31 12:12:52 +02:00
Christian Zimmermann
cf5fabd04b im com 2023-08-31 12:07:20 +02:00
Christian Zimmermann
f1b1298c69 reformat -> formatTo/formatFrom 2023-06-25 23:35:09 +02:00
Christian Zimmermann
f088ba156b remove special assignment operator in Consecutive (appeared to be unneccesary) 2023-06-18 02:49:43 +02:00
Christian Zimmermann
17b8b79ade various fixes regarding usage of Consecutive 2023-06-17 21:51:37 +02:00
Christian Zimmermann
bd6f15156b WIP: fix test errors... 2023-06-15 00:41:17 +02:00
Christian Zimmermann
717e4a6548 WIP: fix compile errors regarding first extension operation test 2023-06-12 00:00:20 +02:00
Christian Zimmermann
1919d373df indices: fullfill missing iterator requirements 2023-06-11 22:28:10 +02:00
Christian Zimmermann
811e955491 WIP: EIndex tests 2023-06-11 03:06:30 +02:00
Christian Zimmermann
59a9236c04 rename index.format(index) -> index.reformat(index) (because of conflicting member function names) 2023-06-04 23:11:46 +02:00
Christian Zimmermann
ba02601b97 EIndex: new inheritance structure: SIndex<S> -> LIndex<SIndex<S>,L> -> EIndex<S,L> 2023-06-04 22:14:26 +02:00
Christian Zimmermann
52517675a5 EFor: F argument 2023-06-04 17:31:47 +02:00
Christian Zimmermann
e9fde3d900 srange casts + add first eindex implementation 2023-05-29 23:05:47 +02:00
Christian Zimmermann
3f8c7aacc3 srange.cc.h (casts missing...) 2023-05-29 17:41:55 +02:00
Christian Zimmermann
3c98377e2d add srange.h 2023-05-27 20:03:41 +02:00
Christian Zimmermann
1610084abd Merge branch 'dev' of git.f3l.de:chizeta/cnorxz into dev 2023-05-10 01:20:40 +02:00
Christian Zimmermann
0593150651 add cereal write/readFile wrappers 2023-05-10 01:20:31 +02:00
Christian Zimmermann
cceace2ef0 minor change in CMakeLists.txt + fix preprocessor variables to prevent extra semicolon error 2023-05-09 16:22:25 +02:00
Christian Zimmermann
7ea21da81a ranges: add sub() to ranges -> returns MArray of RangePtrs 2023-05-07 21:46:46 +02:00
Christian Zimmermann
862697edef include/base/types.h: include <cstdint> 2023-05-07 17:53:49 +02:00
Christian Zimmermann
ef45d8cbac ranges: add some of the possible casts for URange 2023-05-05 19:29:10 +02:00
Christian Zimmermann
026c7f1a87 add missing operator* for GMIndex + fix various bugs 2023-03-19 01:48:51 +01:00
Christian Zimmermann
4642ebe6d2 various fixes 2023-03-15 17:29:24 +01:00
Christian Zimmermann
c1f92b4685 prange.cc.h: add missing template argument 2023-03-15 13:45:37 +01:00
Christian Zimmermann
40a86441cb add missing PRange / PRangeFactory member implementations 2023-03-15 12:20:48 +01:00
Christian Zimmermann
0e1ec2e95a include prange + fix corresponding compile errors (untested) 2023-03-15 11:46:21 +01:00
Christian Zimmermann
2d4d0b8ee9 change behavior of operator* for RangePtr: preserve sub-range structure 2023-03-14 19:07:05 +01:00
Christian Zimmermann
1d6f8dc52b try to fix pipeline 2023-03-12 16:54:32 +01:00
Christian Zimmermann
bea9add008 mrange: range cast 2023-03-12 04:30:42 +01:00
Christian Zimmermann
abb47cbb06 array base: add using CAB::operator() 2023-03-08 20:03:19 +01:00
Christian Zimmermann
b77955a36e op roots: index pos offset (only valid for non-looped indices) 2023-03-08 02:08:30 +01:00
Christian Zimmermann
2864c10056 various fixes 2023-03-07 20:12:11 +01:00
Christian Zimmermann
e016059ad0 finish first version of cereal extension (more or less tested) 2023-02-28 17:50:56 +01:00
Christian Zimmermann
80ac604089 cxz cereal: more tests 2023-02-28 14:15:16 +01:00
Christian Zimmermann
36a22f51de add first parts of cereal extension 2023-02-27 20:09:06 +01:00
Christian Zimmermann
82fab9f7dc Merge branch 'dev' of git.f3l.de:chizeta/cnorxz into dev 2023-02-26 20:15:14 +01:00
Christian Zimmermann
a2b936c4da add basic_operations + first corresponding test 2023-02-26 20:15:05 +01:00
Christian Zimmermann
fee6d8e895 cmake lists: fix version string bug 2023-02-22 12:06:56 +01:00
Christian Zimmermann
039effb344 add config binary 2023-02-22 02:38:51 +01:00
Christian Zimmermann
229a913bcb move python stuff to separate repo 2023-02-21 19:31:53 +01:00
Christian Zimmermann
9a7daabd24 Merge branch 'dev' of git.f3l.de:chizeta/cnorxz into dev 2023-02-21 16:52:21 +01:00
Christian Zimmermann
b3d1ced728 switch to uuid as range id 2023-02-21 16:52:05 +01:00
Christian Zimmermann
3a7bd9c9e2 fix urange slice() + prange for and pfor expression 2023-01-30 01:13:14 +01:00
Christian Zimmermann
65e7539666 for: replace * by () in position calculation 2023-01-29 23:42:12 +01:00
Christian Zimmermann
792c3bd84e WIP: prange 2023-01-28 18:34:24 +01:00
Christian Zimmermann
f5f66461f7 merge 2023-01-28 02:13:14 +01:00
Christian Zimmermann
32ef2ef921 Merge branch 'dev' of git.f3l.de:chizeta/cnorxz into dev 2023-01-28 02:12:38 +01:00
Christian Zimmermann
62b77921f5 fixes + keep correct ordering in h5 table fields names 2023-01-28 02:05:50 +01:00
Christian Zimmermann
25b5c13608 h5_table: remove mCheckedFile 2023-01-26 19:55:29 +01:00
Christian Zimmermann
2547a450d8 hdf5: type declaration in separate file + some reorgs in table code 2023-01-25 18:31:03 +01:00
Christian Zimmermann
24ea3339f8 hdf5: group/table improvements 2023-01-25 00:30:12 +01:00
Christian Zimmermann
58fa19f514 hdf5: preliminary append (init) table test 2023-01-24 01:39:23 +01:00
Christian Zimmermann
6faaf7ea15 hdf5: include cc.h files + corresp compile fixes 2023-01-24 00:02:32 +01:00
Christian Zimmermann
0db94229bf WIP: more development on h5_table 2023-01-23 19:22:42 +01:00
Christian Zimmermann
59932895e9 add h5_types + class STabel : public Table ( field types known by compile time) 2023-01-22 23:34:30 +01:00
Christian Zimmermann
69a9344790 Merge branch 'restructure-rename' into dev 2023-01-22 15:42:06 +01:00
Christian Zimmermann
1f5843895e h5 table, untested 2023-01-22 15:41:42 +01:00
Christian Zimmermann
07428d1e6d fix install paths 2023-01-20 15:58:52 +01:00
Christian Zimmermann
66d5e5b741 index xpr + h5 table header file 2023-01-20 01:05:24 +01:00
Christian Zimmermann
02174f8371 hdf5: H5Oget_info: distinguish between versions 2023-01-18 19:12:41 +01:00
Christian Zimmermann
835b8e885f various fixes regarding extending ranges/arrays + hdf5 2023-01-18 18:57:17 +01:00
Christian Zimmermann
e6da712482 ranges: extend + array: init + extend + hdf5: adapt 2023-01-18 00:49:11 +01:00
Christian Zimmermann
d72bf23049 further hdf5 test 2023-01-15 03:18:21 +01:00
Christian Zimmermann
e331f6c4e2 first hdf5 test 2023-01-15 01:26:01 +01:00
Christian Zimmermann
b6455049c4 add hdf5 test build files 2023-01-13 15:42:15 +01:00
Christian Zimmermann
5dd114f03f add cmake files for hdf5 part + fix compile errors 2023-01-13 12:26:23 +01:00
Christian Zimmermann
caed6b4469 hdf5: group 2023-01-13 01:40:19 +01:00
Christian Zimmermann
631d187c91 begin hdf5 2023-01-12 19:29:45 +01:00
Christian Zimmermann
e8c8e519dc change operator* for index shared ptrs -> creates index packs instead of m/yindices 2023-01-11 19:02:34 +01:00
Christian Zimmermann
6bd7140ae3 fix pipeline... 2023-01-11 17:36:24 +01:00
Christian Zimmermann
55922490b2 change operator* for indices -> creates index packs instead of m/yindices 2023-01-11 17:32:52 +01:00
Christian Zimmermann
603d03971d replace std integral_constant by corresponding typedef CSizeT 2023-01-04 23:11:51 +01:00
Christian Zimmermann
b74ace2f43 update base/types.h 2023-01-04 23:06:02 +01:00
Christian Zimmermann
8469fa9fb2 yrange: replace index pack type 2023-01-04 11:27:18 +01:00
Christian Zimmermann
346f92f267 yrange: replace blockSizes by yformat 2023-01-04 11:15:51 +01:00
Christian Zimmermann
b1f9a38af7 mindex: replace type of ipack 2023-01-03 21:02:50 +01:00
Christian Zimmermann
8787ec7590 mindex: replace block sizes by format 2023-01-03 18:11:45 +01:00
Christian Zimmermann
53aa87c362 index format 2022-12-31 19:43:06 +01:00
Christian Zimmermann
0980934706 index pack 2022-12-31 15:18:26 +01:00
Christian Zimmermann
1ab0c21667 first array operation test 2022-12-30 13:32:27 +01:00
Christian Zimmermann
a4e32416ad array base: slice + op 2022-12-29 00:35:57 +01:00
Christian Zimmermann
b86ea957ba index format + slice 2022-12-28 21:21:11 +01:00
Christian Zimmermann
16f062b069 im com... 2022-12-21 22:06:17 +01:00
Christian Zimmermann
61cef892f3 ... 2022-12-21 00:06:21 +01:00
Christian Zimmermann
8209f14c71 include lindex 2022-12-20 21:53:59 +01:00
Christian Zimmermann
d25cbda2fc array_base: operator() and op function 2022-12-20 17:21:29 +01:00
Christian Zimmermann
07242a995e minor change 2022-12-20 00:52:23 +01:00
Christian Zimmermann
34c45e3dd9 fix compile errors 2022-12-20 00:07:59 +01:00
Christian Zimmermann
0fbd2d6f5b mrange: zip; todo: for all other index types 2022-12-14 01:48:17 +01:00
Christian Zimmermann
6963dd82cd index utils: index depth/dimension 2022-12-13 19:19:41 +01:00
Christian Zimmermann
79535c496f add get/set block sizes function for gmindex, yindex, xindex and dindex 2022-12-13 00:37:59 +01:00
Christian Zimmermann
f41ada859a im com 2022-12-12 02:15:42 +01:00
Christian Zimmermann
854e1a0533 slices 2022-12-06 19:34:42 +01:00
Christian Zimmermann
9938d43f9c rename darray_base -> carray_base, mdarray_base -> array_base, darray -> marray + rename corresponding files/tests 2022-12-06 14:48:44 +01:00
Christian Zimmermann
9aba24cf01 .gitlab-ci.yml: use my own centos image 2022-12-05 22:36:35 +01:00
Christian Zimmermann
9bfb5f4707 dynamic index multiplication 2022-12-05 00:14:00 +01:00
Christian Zimmermann
13467b800a fix cxz error macro (clang) 2022-12-04 21:57:18 +01:00
Christian Zimmermann
9ef055d9c9 revert ci 2022-12-04 19:21:28 +01:00
Christian Zimmermann
4d6a810704 try to fix pipeline 13 2022-12-04 19:13:21 +01:00
Christian Zimmermann
485dfe36c4 try to fix pipeline 12 2022-12-04 19:09:35 +01:00
Christian Zimmermann
4b6288beaf try to fix pipeline 11 2022-12-04 19:06:21 +01:00
Christian Zimmermann
addd19ca70 try to fix pipeline 10 2022-12-04 19:03:33 +01:00
Christian Zimmermann
0e84e2ffd8 try to fix pipeline 10 2022-12-04 19:03:04 +01:00
Christian Zimmermann
dcd2e4a87f try to fix pipeline 9 2022-12-04 18:59:52 +01:00
Christian Zimmermann
627fa9eb1a try to fix pipeline 8 2022-12-04 18:57:44 +01:00
Christian Zimmermann
5f85f13d66 try to fix pipeline 7 2022-12-04 18:55:49 +01:00
Christian Zimmermann
8025f657d6 try to fix pipeline 6 2022-12-04 18:55:00 +01:00
Christian Zimmermann
3866b603ce try to fix pipeline 5 2022-12-04 18:52:47 +01:00
Christian Zimmermann
a8fad26cfa try to fix pipeline 4 2022-12-04 18:44:35 +01:00
Christian Zimmermann
b1df3e1307 try to fix pipeline 3 2022-12-04 18:42:35 +01:00
Christian Zimmermann
9fad49a2eb try to fix pipeline 2 2022-12-04 17:49:17 +01:00
Christian Zimmermann
9c2b29ac07 try to fix pipeline 1 2022-12-04 17:42:37 +01:00
Christian Zimmermann
9210f59d39 more tests on index multiplication + corresponding fixes 2022-12-04 17:35:22 +01:00
Christian Zimmermann
38e011c979 first tests on index multiplication 2022-12-04 03:17:29 +01:00
Christian Zimmermann
b2fd81b764 add more range tests 2022-12-04 01:12:34 +01:00
Christian Zimmermann
1bd51ee700 shift index multiplication to separate file + extend to Sptr 2022-11-29 01:46:53 +01:00
Christian Zimmermann
a3a25af289 redefine index-index-multiplications 2022-11-27 23:51:15 +01:00
Christian Zimmermann
8513b6dcd3 2d opcont test 2022-11-27 04:28:46 +01:00
Christian Zimmermann
059093241b OpCont: again owns data (can have static size now); use (C)OpRoot for assignment-like operations 2022-11-27 03:38:10 +01:00
Christian Zimmermann
204b726acf minor fix 2022-11-27 01:25:59 +01:00
Christian Zimmermann
4f1ebb9986 1dim operation test + corresponding fixes 2022-11-27 00:27:34 +01:00
Christian Zimmermann
42a8acbc6e remove statics/ utils/ 2022-11-26 17:03:39 +01:00
Christian Zimmermann
3418ec9ee1 remove old test files 2022-11-26 16:28:00 +01:00
Christian Zimmermann
0e71d45a5b minor changes + mindex/yindex: further functionalities 2022-11-25 02:08:43 +01:00
Christian Zimmermann
25abf5e1b0 add src/opt/python/setup.py.in + update cmake project name + remove static cnorxz lib 2022-11-24 02:08:04 +01:00
Christian Zimmermann
7acc5c86ee remove old files 2022-11-23 23:26:27 +01:00
Christian Zimmermann
1f27826aff fixes/more functionalities in MIndex + add 2d Array test 2022-11-23 01:25:59 +01:00
Christian Zimmermann
216bb3f56e aindex: inherit yindex + yrange: specialize RangeCast + corrections in DArray classes + more DArray tests 2022-11-22 19:11:41 +01:00
Christian Zimmermann
a3d3d99c8d add first for tests 2022-11-22 00:58:50 +01:00
Christian Zimmermann
2f5f29f577 mrange: different members for blockSizes and lexBlockSizes 2022-11-20 23:18:58 +01:00
Christian Zimmermann
2745eee0ff src/tests/range_unit_test.cc: again fix signed vs unsigned comp 2022-11-18 19:53:43 +01:00
Christian Zimmermann
31bebecb23 further yrange tests 2022-11-18 19:50:19 +01:00
Christian Zimmermann
99eb72bb76 fix bug in DType + further yrange test 2022-11-17 19:00:58 +01:00
Christian Zimmermann
da4bf39c83 remove old files + first yr_test (to be extended) 2022-11-17 01:26:35 +01:00
Christian Zimmermann
3e54485b12 extend mr_test 2022-11-14 18:47:51 +01:00
Christian Zimmermann
3a6ffc209b change template args of RangeInterface (static polymorphism) + fixes in MRange -> first tests compile 2022-11-14 00:35:05 +01:00
Christian Zimmermann
62a9df39d3 add UR_Test + remove operator-> for index classes where it conflicts with c++ syntax 2022-11-13 02:23:33 +01:00
Christian Zimmermann
4e2244db79 finish mrange/mindex (unchecked) 2022-11-12 03:14:07 +01:00
Christian Zimmermann
113a0e7209 fix compile errors 2022-11-12 00:15:26 +01:00
Christian Zimmermann
fb94a382bb base/isq.h + base/iter.* + functional/fundamental.h + adaptions in mrange (WIP) 2022-11-08 22:36:16 +01:00
Christian Zimmermann
0197e7db6e more on MIndex + operator << for PosTypes 2022-11-06 22:58:46 +01:00
Christian Zimmermann
172110c5de start refactoring MIndex 2022-11-02 18:51:18 +01:00
Christian Zimmermann
6b2bbc3020 OpCont + adapt ifor memeber functions 2022-10-30 22:28:40 +01:00
Christian Zimmermann
c9f69ad25d extensions: finish basic arithmetic implementation for consecutive + avx 2022-10-30 12:12:53 +01:00
Christian Zimmermann
fbfd84f421 more on extensions... 2022-10-29 03:08:34 +02:00
Christian Zimmermann
cf7dcb816b WIP: avx 2022-10-25 23:45:05 +02:00
Christian Zimmermann
1befb14039 fixes + start extension code 2022-10-24 18:34:11 +02:00
Christian Zimmermann
e2405738c1 derive COpInterface : XprInterface; allow return values for Xpr (VXpr+DXpr -> templates) 2022-10-23 18:29:07 +02:00
Christian Zimmermann
fa1ea56d51 op_types: contraction (not finished) 2022-10-22 02:42:18 +02:00
Christian Zimmermann
e3fe04d5da DPos/DPosRef: -> static scalar; replace next() by sub() 2022-10-22 01:11:27 +02:00
Christian Zimmermann
f68c02565d im com (not finished) 2022-10-21 17:35:23 +02:00
Christian Zimmermann
483e3b4286 move xpr/op_xpr.* -> operation/op_xpr.* 2022-10-21 13:52:53 +02:00
Christian Zimmermann
4cb3977fb3 cxz_operation -> op_types 2022-10-21 13:40:12 +02:00
Christian Zimmermann
db623649ee move include/ranges/xpr -> include/xpr 2022-10-21 13:32:27 +02:00
Christian Zimmermann
98f71b874b more on operations 2022-10-21 02:24:30 +02:00
Christian Zimmermann
aafc6f0e2a xpr -> only one pos argument 2022-10-21 00:21:47 +02:00
Christian Zimmermann
477ea8d43d start operation refactoring 2022-10-20 02:58:24 +02:00
Christian Zimmermann
7904d77bd8 EPos + EFor (for extensions, simd vectorization, etc) 2022-10-18 00:30:05 +02:00
Christian Zimmermann
b47000d015 corrections in TFor 2022-10-17 12:20:09 +02:00
Christian Zimmermann
b0d002b7b1 re-enable index ifor 2022-10-16 23:05:48 +02:00
Christian Zimmermann
6fc3a50fa9 index_id 2022-10-16 18:37:14 +02:00
Christian Zimmermann
3eea7f2314 for.h 2022-10-16 00:55:14 +02:00
Christian Zimmermann
e2baceada7 xpr_base 2022-10-13 19:12:23 +02:00
Christian Zimmermann
85059f8024 xpr_unit_test: add more tests -> work 2022-10-13 15:58:17 +02:00
Christian Zimmermann
ade28d5122 rename directory xfor -> xpr 2022-10-13 14:50:15 +02:00
Christian Zimmermann
d555fabf40 remove most of static chains in vpos 2022-10-13 14:39:40 +02:00
Christian Zimmermann
d804f5db7e im com 2022-10-13 00:30:37 +02:00
Christian Zimmermann
c7e66f081c im com 2022-10-12 23:03:44 +02:00
Christian Zimmermann
73ded8c9a8 tests: fix signed vs unsigned again... 2022-10-12 16:53:26 +02:00
Christian Zimmermann
4dc6846845 first DPos test works 2022-10-12 15:28:35 +02:00
Christian Zimmermann
459ea690e5 more on DPos/VPos 2022-10-11 23:01:31 +02:00
Christian Zimmermann
ed6c90b95c new DPos/VPos + further macros 2022-10-11 18:36:23 +02:00
Christian Zimmermann
ee1fe52429 xfor_unit_test: signed vs unsigned 2022-10-10 17:01:37 +02:00
Christian Zimmermann
7e1cfa6b3a PosT: again linear 2022-10-09 16:59:12 +02:00
Christian Zimmermann
a142fdb466 im com 2022-10-06 18:32:56 +02:00
Christian Zimmermann
37dc3bf818 Pos_Test Multi works; change some things in near future 2022-09-28 23:28:07 +02:00
Christian Zimmermann
872d8f0d4a Pos_Test Basics works 2022-09-28 19:09:45 +02:00
Christian Zimmermann
321d6cd8fa more on pos type (not finished/checked/debugged) 2022-09-27 20:32:26 +02:00
Christian Zimmermann
cc52e86526 more on PosT 2022-09-20 23:52:54 +02:00
Christian Zimmermann
d497eb09ae change getStepSize: pass ptr id instead of index number 2022-09-18 22:50:07 +02:00
Christian Zimmermann
a880d1e0db start refactoring mrange + index interface offset (not finished) 2022-09-18 18:53:38 +02:00
Christian Zimmermann
59267fb040 src/tests/CMakeLists.txt: remove test sources (link against testlib instead) 2022-09-18 17:24:19 +02:00
Christian Zimmermann
47b2f3ee31 yrange.cc: fix undefined ref to ::range() 2022-09-18 17:06:51 +02:00
Christian Zimmermann
4c2945b683 range_unit_test: fix signed vs unsigned comparison 2022-09-18 17:04:25 +02:00
Christian Zimmermann
e542a37bf3 add dindex (-> standard index of RangeBase) 2022-09-18 16:19:27 +02:00
Christian Zimmermann
4212ed7ee9 crange.basic test works 2022-09-18 00:49:36 +02:00
Christian Zimmermann
a10770b4f1 container_index -> a/b index 2022-09-17 22:09:01 +02:00
Christian Zimmermann
5a71d00863 container_index -> a/b index 2022-09-17 22:08:01 +02:00
Christian Zimmermann
3044646b6a yrange implementations (part only) 2022-09-15 23:40:23 +02:00
Christian Zimmermann
3764f865e9 rename yindex.* -> yrange.* 2022-09-15 22:32:44 +02:00
Christian Zimmermann
9543342db4 further compile fixes 2022-09-15 16:45:45 +02:00
Christian Zimmermann
0dcf7d3b5a further renaming + fixes 2022-09-14 18:58:06 +02:00
Christian Zimmermann
0ec807c8fa fix some of the recently introduced compile errors 2022-09-13 00:31:12 +02:00
Christian Zimmermann
796bb50118 ext -> pos, expressions... 2022-09-12 16:48:45 +02:00
Christian Zimmermann
10db0908e0 im com 2022-09-12 01:09:51 +02:00
Christian Zimmermann
f6725f5356 rename range files 2022-09-11 17:23:59 +02:00
Christian Zimmermann
72e898606f im com 2022-09-11 17:20:09 +02:00
Christian Zimmermann
bc4ebf317b index_base.cc.h 2022-09-11 15:20:27 +02:00
Christian Zimmermann
3463e6ceea wip... 2022-09-11 02:48:30 +02:00
Christian Zimmermann
ebc0f5a807 wip: dynamic stuff; switched off most of the tests 2022-09-09 19:41:43 +02:00
Christian Zimmermann
5d473ddd8c wip... 2022-09-03 22:11:36 +02:00
Christian Zimmermann
05f4cb0abb wip: dynamic indices 2022-08-31 17:37:20 +02:00
Christian Zimmermann
3dd688bbed DArray (future Array) 2022-08-31 14:58:39 +02:00
Christian Zimmermann
21bd120032 std::iterator is depricated... 2022-08-08 14:55:07 +02:00
Christian Zimmermann
8f6094233a re-enable auto-vectorization 2021-09-21 14:01:04 +02:00
Christian Zimmermann
388531c37f split cxz_operation: move Access and Expression classes to extra files 2021-08-06 11:34:13 +02:00
Christian Zimmermann
7aa4b18d15 remove unused code 2021-08-06 10:54:11 +02:00
Christian Zimmermann
8b64d2c0d5 remove unused code 2021-08-06 10:40:42 +02:00
Christian Zimmermann
b5ec02c7c5 update README 2021-08-03 11:20:09 +02:00
Christian Zimmermann
3c6f9ea025 Merge remote-tracking branch 'origin/restructure-rename' 2021-07-29 19:03:09 +02:00
Christian Zimmermann
7a24e328e7 rename libmultiarray -> libcnorxz 2021-07-28 21:30:21 +02:00
Christian Zimmermann
3975edea20 rename MultiArray + pre-processor variables 2021-07-28 20:59:31 +02:00
Christian Zimmermann
c5e6003fc9 rename namespaces 2021-07-28 20:29:56 +02:00
Christian Zimmermann
e3d4c34962 rename files 2021-07-28 19:55:37 +02:00
Christian Zimmermann
bba1c6944a im com (vectorization (wrong access instance) + parallel not working) 2021-07-18 23:11:05 +02:00
Christian Zimmermann
a841782115 remove some old debug asserts 2021-07-18 18:40:10 +02:00
Christian Zimmermann
8bde2d7250 fix bug from previous commit 2021-07-14 22:01:07 +02:00
Christian Zimmermann
bf4633054d im com (some weird runtime errors -> PointerAccess) 2021-07-09 16:54:30 +02:00
Christian Zimmermann
33b52c1a70 start building in Access classes + add IsArray trait 2021-07-01 18:15:12 +02:00
Christian Zimmermann
bf7853c1b5 operations: AccessTemplate (static base class) 2021-07-01 17:55:46 +02:00
Christian Zimmermann
e80c71aa62 multi_array_operation: member access class for array-type members -> sub operations... 2021-07-01 01:51:10 +02:00
Christian Zimmermann
312074c486 multi_array_operation: remove RootSumN 2021-07-01 00:42:31 +02:00
Christian Zimmermann
24ea3c2c30 im com 2021-06-30 16:55:38 +02:00
Christian Zimmermann
9946a8d416 Merge branch 'restructure-rename' of rqcd.ur.de:czimmermann/multi_array into restructure-rename 2021-06-26 00:41:33 +02:00
Christian Zimmermann
d5e02ba9d2 remove slicecontraction + start hyperoperation (for slicearray) 2021-06-26 00:40:42 +02:00
Christian Zimmermann
ffb8e71dbd multi_array_operation: replace template spec by static if 2021-06-25 17:28:22 +02:00
Christian Zimmermann
c282cf683d Merge branch 'restructure-rename' of rqcd.ur.de:czimmermann/multi_array into restructure-rename 2021-06-24 21:39:52 +02:00
Christian Zimmermann
7cd0c3104f separate lib for high level stuff 2021-06-24 21:39:42 +02:00
Christian Zimmermann
6991742206 remove old code 2021-06-11 18:57:00 +02:00
Christian Zimmermann
49f2c41a95 remove dead code + simplify StaticFunctionBase (less template args) 2021-06-09 17:25:02 +02:00
Christian Zimmermann
f1b44cfd5c sfor: return cond 2021-06-08 17:53:51 +02:00
Christian Zimmermann
c26fb133ae replace/remove static for macros 2021-06-08 16:41:28 +02:00
Christian Zimmermann
53362be499 two container indices (one const) 2021-05-29 00:03:48 +02:00
Christian Zimmermann
01703dec28 container_index: split header -> .h .cc.h 2021-05-28 21:20:07 +02:00
Christian Zimmermann
63df6bbdef ranges/container_range.h -> container_index.h 2021-05-28 20:35:24 +02:00
Christian Zimmermann
98138114f7 remove assignment ContainerIndex -> MultiIndex 2021-05-28 20:17:20 +02:00
Christian Zimmermann
1d882d55c4 ContainerRange typedef: remove template arg T + remove MultiRange Factory constructor for ContainerRange 2021-05-28 20:02:04 +02:00
Christian Zimmermann
34e69cd805 ContainerIndex -> ConstContainerIndex 2021-05-28 17:29:13 +02:00
Christian Zimmermann
c5b9e84486 completely remove rpacknum 2021-05-27 23:29:04 +02:00
Christian Zimmermann
6dc926f234 further packnum replacements 2021-05-27 18:37:15 +02:00
Christian Zimmermann
12c79b595f rpacknum: replace mkfor 2021-05-27 12:15:44 +02:00
Christian Zimmermann
893b2360bc remove rpacknum getMeta, getSize, getTypeNum 2021-05-27 11:02:36 +02:00
Christian Zimmermann
29f4ddc0cd continue... 2021-05-12 17:56:35 +02:00
Christian Zimmermann
43e8486354 bugfix + continue prev com 2021-05-07 17:35:59 +02:00
Christian Zimmermann
482a7a7b4e continue previous commit 2021-05-06 19:04:26 +02:00
Christian Zimmermann
13488b9839 ranges: start replacement of rpack_num 2021-05-05 20:04:13 +02:00
Christian Zimmermann
7fee5aa45d completely remove pack_num 2021-05-04 18:26:17 +02:00
Christian Zimmermann
acda91d792 remove all PackNum stuff from multi_array_operation 2021-05-04 17:11:53 +02:00
Christian Zimmermann
44f6149a23 rewrite Operation::get (not final solution) 2021-04-11 22:11:20 +02:00
Christian Zimmermann
9d85f8df46 remove Application classes 2021-04-11 16:54:46 +02:00
Christian Zimmermann
fe22b1ad80 im com + remove Getter class 2021-04-11 16:34:01 +02:00
Christian Zimmermann
1f663e0b76 start replacement PackNum -> SFOR 2021-04-10 16:06:02 +02:00
Christian Zimmermann
64c5c2b4f3 -> C++17 2021-04-10 13:25:43 +02:00
Christian Zimmermann
48084b2a5e generalize static_for.h 2021-04-10 00:58:30 +02:00
Christian Zimmermann
cf1850923f name mapping suggestions + static cc for implementation 2021-04-04 15:10:15 +02:00
Christian Zimmermann
70c850be2f basic_types 2021-04-04 14:21:09 +02:00
Christian Zimmermann
469a7b4848 Merge branch 'dev' into HEAD 2021-04-04 14:19:02 +02:00
Christian Zimmermann
c608239ced various fixes 2021-02-03 14:30:25 +01:00
Christian Zimmermann
867c20959a auto-vectorization works 2021-01-24 02:10:06 +01:00
Christian Zimmermann
269ff69ec3 automatic vectorization: unit tests work again 2021-01-24 00:10:14 +01:00
Christian Zimmermann
3bacc6c1c4 im com 2021-01-23 19:40:15 +01:00
Christian Zimmermann
15664781f7 further auto vectorization (open issue: static loop reduction) 2021-01-21 00:35:13 +01:00
Christian Zimmermann
64d10867dd finish parts of auto-vectorization 2021-01-18 19:00:12 +01:00
Christian Zimmermann
db92197048 im com (Operation: remove T?) 2021-01-15 01:05:58 +01:00
Christian Zimmermann
68ae7d8428 im com 2021-01-14 23:57:06 +01:00
Christian Zimmermann
29b1502e60 unify AssigmentExpr2 and AddExpr 2021-01-14 19:20:46 +01:00
Christian Zimmermann
fdb1bb6833 xfor: vectrization requirements 2021-01-14 17:40:32 +01:00
Christian Zimmermann
6ecbe5ff27 minor changes 2021-01-14 16:26:53 +01:00
Christian Zimmermann
ec430efcc6 operations: vget 2021-01-14 14:43:09 +01:00
264 changed files with 34856 additions and 20625 deletions

36
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,36 @@
# This file is based on https://github.com/satu0king/Github-Documentation-With-Doxygen/blob/master/main.yml
name: Doxygen Action
# Trigger workflow only on pushed to master branch:
on:
workflow_dispatch:
push:
branches: [ main ]
jobs:
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Doxygen Action
uses: mattnotmitt/doxygen-action@v1.1.0
with:
# Path to Doxyfile
doxyfile-path: "./Doxyfile"
# Working directory
working-directory: "./doc/doxy"
- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doc/doxy/html
permissions:
contents: write

4
.gitignore vendored
View file

@ -4,4 +4,6 @@ build/
install/
*/build/
*/install/
src/lib/hl_ops/*.cc
src/lib/hl_ops/*.cc
doc/doxy/html/
doc/doxy/latex/

View file

@ -1,17 +0,0 @@
before_script:
- export GTEST_ROOT=/opt/gtest-1.8.0
image: docker.io/rqcd/centos-buildtools:7.2.1511
stages:
- build
build-centos:
stage: build
script:
- source /opt/rh/devtoolset-7/enable
- mkdir build
- cd build
- cmake3 ..
- make -j2
- make test

18
.woodpecker.yml Normal file
View file

@ -0,0 +1,18 @@
---
steps:
build:
image: chizeta/centos:8
commands:
- source /opt/rh/gcc-toolset-9/enable
- mkdir build-gcc
- cd build-gcc
- cmake3 -DSCALAR_BUILD=on ..
- make -j2
- make test
- cd ..
- mkdir build-clang
- cd build-clang
- CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake3 -DRUN_PIPELINE=on -DSCALAR_BUILD=on ..
- make -j2
- make test

View file

@ -1,6 +1,38 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5)
project(multi_array)
project(cnorxz)
# LIB VERSION
set(V_MAJOR 0)
set(V_MINOR 0)
set(V_PATCH 0)
set(VERSION "${V_MAJOR}.${V_MINOR}.${V_PATCH}")
# OPTIONS
option(SCALAR_BUILD "" OFF)
# INCLUDES
include(cmake/check_avx.cmake)
# GIT VARIABLES
execute_process(COMMAND bash "-c" "git rev-parse HEAD" OUTPUT_VARIABLE GIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND bash "-c" "git rev-parse --abbrev-ref HEAD" OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE)
# BUILD VERSION STRING
message(STATUS "git hash = ${GIT_HASH}")
message(STATUS "git branch = ${GIT_BRANCH}")
if(NOT ("${GIT_BRANCH}" EQUAL "release"))
string(SUBSTRING ${GIT_HASH} 0 7 GIT_HASH_SHORT)
set(VERSION "${VERSION}-${GIT_BRANCH}-${GIT_HASH_SHORT}")
endif()
message(STATUS "version = ${VERSION}")
# CHECK COMPILER
if(CMAKE_COMPILER_IS_GNUCXX)
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)
@ -10,20 +42,41 @@ else()
message(WARNING "compiler ${CMAKE_CXX_COMPILER_ID} officially not supported")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -Wpedantic -Ofast -march=native -faligned-new -funroll-loops -fopenmp")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -g -Wpedantic -Ofast -march=native -faligned-new -funroll-loops -fopenmp -ftemplate-backtrace-limit=0")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -g -Wpedantic -O0 -march=native -faligned-new -funroll-loops -fopenmp")
# FLAGS
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++17 -Wpedantic -O2 -march=native -faligned-new -funroll-loops -fopenmp")
# TESTING
enable_testing()
# INSTALL PATH
if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
set(INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
else()
#set(INSTALL_PATH ${CMAKE_SOURCE_DIR}/install)
get_filename_component(INSTALL_PATH ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX} ABSOLUTE)
endif()
message(WARNING "found absolute install path '${INSTALL_PATH}'")
message(STATUS "found absolute install path '${INSTALL_PATH}'")
# SCALAR / INTRINSICS
if(NOT ${SCALAR_BUILD})
message(STATUS "check for intrinsics")
check_avx()
if(AVX_AVAIL)
message(STATUS "AVX available")
add_definitions("-DCXZ_HAVE_AVX")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
else()
message(STATUS "AVX not available")
endif()
endif()
# CHECK LIBRARIES : GTest
message(STATUS "check for libraries")
find_package( GTest REQUIRED )
if(GTest_FOUND)
include_directories(${GTEST_INCLUDE_DIRS})
@ -31,6 +84,8 @@ else()
message(FATAL_ERROR "GTest not found")
endif()
# CHECK LIBRARIES : Threads
find_package(Threads REQUIRED)
if(Threads_FOUND)
#include_directories(${Threads_INCLUDE_DIRS})
@ -38,4 +93,42 @@ else()
message(FATAL_ERROR "Threads not found")
endif()
# CHECK LIBRARIES : hdf5
if(DEFINED ENABLE_hdf5)
set(ENABLE_hdf5 ${ENABLE_hdf5} CACHE BOOL "enable hdf5")
else()
set(ENABLE_hdf5 TRUE CACHE BOOL "enable hdf5")
endif()
# CHECK LIBRARIES : cereal
if(DEFINED ENABLE_cereal)
set(ENABLE_cereal ${ENABLE_cereal} CACHE BOOL "enable hdf5")
else()
set(ENABLE_cereal TRUE CACHE BOOL "enable hdf5")
endif()
find_package(cereal QUIET)
if(cereal_FOUND)
message(STATUS "found cereal")
if(ENABLE_cereal)
message(STATUS "enable cereal")
add_definitions(-DHAVE_CEREAL)
endif()
else()
message(STATUS "no cereal")
if(ENABLE_cereal)
message(FATAL_ERROR "cereal has been enabled but the cereal library has not been found")
endif()
endif()
# DEFINES
add_definitions(-DVERSION="${VERSION}")
add_definitions(-DGIT_COMMIT="${GIT_HASH}")
add_definitions(-DCXX_FLAGS="${CMAKE_CXX_FLAGS}")
# CONTINUE WITH SUB-DIRECTORIES
add_subdirectory(src)

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Christian Zimmermann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

226
README.md
View file

@ -1,120 +1,154 @@
# Multi Array Container Library
# Container with Native Operation Routines and Expressions (CNORXZ)
(as always, the name was there before the acronym)
![Image](./cnorxz_logo.png)
## Description
This library provides a framework for handling multi dimensional containers. This includes the basic container class template `MultiArrayBase` and their derivates, the Range class templates on which the containers are defined, as well as some operation class templates, which allow comfortable calling of operations on the containers.
This library provides a framework for handling multi dimensional data containers (arrays or array-like types), their meta data, and several kinds of operations on one or more of them.
## Build instructions
The library can be installed by the following procedure (`gtest` required):
```bash
git clone git@rqcd.ur.de:czimmermann/multi_array.git <SOURCE_DIR>
git clone git@git.f3l.de:chizeta/cnorxz.git <LIBRARY_ROOT_DIR>
mkdir <BUILD_DIR>
cd <BUILD_DIR>
cmake -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> <SOURCE_DIR>
cmake -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> <LIBRARY_ROOT_DIR>
make install
```
## Usage and Examples
To build the doxygen:
To use the features of the libraries one has to include `multi_array_header.h` and link against the `libmultiarray.so`.
The tools of the library are accessible within the namespace `MultiArrayTools`.
### Some Terms
* Ranges: A set of meta data which is mapped onto the linear position. Every container is supposed to be defined on at least one Range. In the simplest case a Range space "containes" the numbers [0,...,rangesize]. Ranges have to be created via the corresponding factory and only exist within a shared pointer. They cannot be copied. The reason is, that every operation performed on the containers, has to identify common sets of ranges, on which the containers are defined. Every range inherits the `RangeBase` class.
* Indices: They can be thought of as iterators of the range space. In the special case of the `ContainerIndex` it is also an iterator over the corresponding container. The index type must be known at compile time (static polymorphism). Indices on a range can be obtained by `getIndex( range )`. For Container Indices call the `begin()` function of a `MultiArray`. Indices are crucial for defining operations.
* `MultiArray<T,Ranges...>`: Contains data of type `T` and is defined on `Ranges...`.
* `[Const]Slice<T,Ranges...>`: Views data of type `T` and acts as a MultiArray defined on `Ranges...`.
* `FunctionalMultiArray`: Additional template argument indicating the funtion. The value at some position is then defined by the function value obtained from the meta data of the indices/ranges.
On each of these types one can perform an operation by calling `operator(...)` where within the braces the corresponding indices have to be specified (see example below).
### Example
```c++
#include "multi_array_header.h"
namespace mat = MultiArrayTools;
typedef mat::SingleRange<double,mat::SpaceType::ANY> DRange;
typedef mat::SingleRangeFactory<double,mat::SpaceType::ANY> DRangeF;
typedef mat::SingleRange<std::string,mat::SpaceType::ANY> SRange;
typedef mat::SingleRangeFactory<std::string,mat::SpaceType::ANY> SRangeF;
typedef mat::SingleRange<size_t,mat::SpaceType::NONE> CRange; // also provided as 'ClassicR'
typedef mat::SingleRangeFactory<size_t,mat::SpaceType::NONE> CRangeF;
/*create ranges*/
std::vector<double> meta1({...});
std::vector<double> meta2({...});
std::vector<std::string> meta3({...});
DRangeF drf1(meta1);
DRangeF drf2(meta2);
SRangeF srf(meta3);
CRangeF crf(10); // specialized in this case; only size needed.
auto dr1 = mat::createExplicit( drf1 );
auto dr2 = mat::createExplicit( drf2 );
auto sr = mat::createExplicit( srf );
auto cr = mat::createExplicit( crf );
mat::MultiArray<double,DRange,DRange,SRange,CRange> ma_a(dr1,dr2,sr,cr,0);
mat::MultiArray<double,SRange,SRange> ma_b(sr,sr,0);
/* assign some values... */
double val = 1.;
for(auto& x: ma_a){
x = val += 1;
}
for(auto& x: ma_b){
x = val /= 2.;
}
mat::FunctionalMultiArray<double,plus<double>,DRange,DRange> fma(dr1,dr2);
mat::MultiArray<double,DRange,DRange> res1(dr1,dr2);
mat::MultiArray<double,DRange,DRange> res2(dr1,dr2);
/* get indices... */
auto i1 = mat::getIndex( dr1 );
auto i2 = mat::getIndex( dr2 );
auto i3 = mat::getIndex( sr );
auto i4 = mat::getIndex( sr );
auto i5 = mat::getIndex( cr );
i3->at(<metaString>);
i5->at(<metaNum>);
/* performs plus operation on each element in hypercube spanned by i1,i2,i4
* and sums up resulting values by iterating over i4. i3 and i5 are fixed to the positions
* given by the meta data above : */
res1(i1,i2) += (ma_a(i1,i2,i4,i5) + ma_b(i4,i3)).c(i4);
/* calculates i2.meta() + i1.meta() and divide res1 at the corresponding entry by the result */
res2(i1,i2) = res1(i1,i2) / fma(i2,i1)
```bash
cd <SOURCE_DIR>/doc/doxy
doxygen Doxyfile
```
Further examples will follow; you can also look in the test executable source files in `./src/test/*.cc`
## Linking
# Multithreading
To use the features of the libraries one has to include `cnorxz.h` and link against the `libcnorxz.so`.
The tools of the library are accessible within the namespace `CNORXZ`.
## Documentation
(Also consider doxygen)
### Basics and Library organization
This library consists of several building blocks. For simple usage, the most important building blocks are [ranges](#sec-ranges), [indices](#sec-indices) and [arrays](#sec-array-types).
#### Ranges {#sec-ranges}
Basically, a *range* defines a meta data space. There are several range class types, which are derived from the abstract base class `RangeBase`. Ranges can only be created by the corresponding factory and exclusively exist within a shared pointer; they cannot be copied. Available range class types are:
* `CRange` : Classic one-dimensional range. The meta data space is simply given by integer numbers running from `0` to `size-1`. The range size is determined at runtime.
* `URange<MetaT>` : Generic One-dimensional range. The meta data space is user defined, the meta data type is passed as template argument. The range size is determined at runtime.
* `SRange<MetaT,S>` : The same as `URange`, but the range length is fixed at compile time by the template integer variable `S`.
* `PRange<RangeT>` : Partial or sub-range, i.e. a user-defined subspace of another range. The type of the range must be known at compile time, the subspace can be specified at runtime.
* `MRange<RangeTs...>` : Multi-dimensional range, spanned by a set of ranges. The number of ranges, as well as their types must be known at compile time.
* `YRange` : The same as `MRange` but the number of ranges and their types can be specified at runtime.
#### Indices {#sec-indices}
For each range type there is a corresponding index type (`CIndex`, `UIndex<MetaT>`, `SIndex<MetaT,S>`, `PIndex<IndexT>`, `MIndex<IndexTs...>`, `YIndex`). They act as const iterators on the ranges and are a crucial component to define operations on containers. In contrast to the ranges, all index types must be known at compile time (static polymorphism, `IndexInterface<Index,MetaT>`).
Apart from range specific indices, there exist also special indices:
* `DIndex` : Dynamic index wrapper, for the case that the index type cannot be determined at compile time.
* `AIndex<T>` : Array index. Const iterators pointing to the data of an array-type object with data type `T`.
* `BIndex<T>` : The same as `AIndex`, but not const.
#### Array types {#sec-array-types}
Arrays or array-like types contain or view datasets and are derived from `CArrayBase<T>` (const) or `ArrayBase<T>` for a given data type `T`. All array types are defined on a range, their data can be accessed or iterated over using suitable indices. The array-type actually containing data is called `MArray<T>`. Moreover, there exist array-types that do not contain data, but view the data of other arrays or at least parts of the data. These are called `CSlice<T>` (const view) or `Slice`.
#### Expressions and Operations
In the context of this library, *expressions* are classes representing an expression that is supposed to be executed at given points during an iteration proceedure that involves one or more indexed quantities. Each expression type must fulfill the following requirements:
* There must be an implementation of `operator()` taking a multi-position argument indicating the position for the current iteration of each involved object according to its indices. The function can have an expression defined return value, which can be further processed.
* There must be an implementation of `rootSteps()` taking an index ID as argument. The function should return jump sizes for each involved object corresponding to the given index.
Each expression `Xpr` should be derived from the class `XprInterface<Xpr>`, where `Xpr` is a recurring template argument (static polymorphism).
There are two important expression types:
* *For* expressions: They represent a for loop over a given index.
* *Operations*: They correspond to one or more indexed array types and given operation on or between them. If an operation handles nothing but the access to one single array, it is called *Operation* *Root*.
Example:
```cpp
#include "cnroxz.h"
using namespace CNORZX;
RangePtr r = CRangeFactory(3).create(); // [0,1,2]
RangePtr s = CRangeFactory(5).create(); // [0,1,2,3,4]
RangePtr t = URangeFactory<Int>(Vector<Int>{4,5,6}).create(); // [4,5,6]
i = std::make_shared<CIndex>(r);
j = std::make_shared<CIndex>(s);
k = std::make_shared<UIndex<Int>>(t);
MArray<Double> a(r*s*t); // 3-dim array, dimensions = [3,5,3], size = 45
MArray<Double> b(r*t); // 2-dim array, dimensions = [3,3], size = 9
MArray<Double> c(s*t); // 2-dim array, dimensions = [3,5], size = 15
// set array element values of a,b,c here...
c(j*k) += ( a(i*j*k) * b(j*k) * xpr(k) ).c(i);
/* Explanation of the above line:
c(j*k), a(i*j*k), b(j*k) and xpr(k) are operation roots, i.e.
they manage access to the arrays c,a,b and the meta data space of index k
The operations between the operation roots are also operations in the
sense of this nomenclature, i.e. a(i*j*k) * b(j*k) is again an operation.
The operation member function c() creates contraction, i.e. a for loop
over the given index (i). If no further functions are specified, the values
returned by the underlying operations are summed up for equivalent index
combinations.
The += invokes a for loop over the indices on the l.h.s.. The values returned
by the expression on the r.h.s. are added to the l.h.s. Something similar could be done
with a = operator. Then the values would just be assigned instead of added.
*/
// Equivalent C-stype for loop (if a,b,c were C-style arrays):
for(size_t j = 0; j < s; ++j){
for(size_t k = 0; k < t; ++k){
int kv = k+4;
double x = 0;
// the contraction part:
for(size_t i = 0; i < r; ++i){
x += a[i*s*t+j*t+k] * b[j*t+k] * kv;
}
c[j*t+k] += x;
}
}
Multithreading can be enabled by the operation class member function `par()`, which will parallelize the top loop. E.g. for the operation in the example above:
```c++
/* Enable multithreading for the loop over i1 */
res1(i1,i2).par() = (ma_a(i1,i2,i4,i5) + ma_b(i4,i3)).c(i4);
```
Caution: If you want to multithread operations over functional multi arrays, you have to make sure by yourself that involved functors are either static or const (const member variables).
# Planned features
More documentation will follow...
Basically the structure of the operation routines allows in some cases (at least in those, where it is possible for simple c++ for loops) vectorization. So far the necessary implamentations are not done, but it is planned to enable these features.
## Acknowledgments
# Known Issues
GitHub Doxygen Task based on work by [satu0king](https://github.com/satu0king/Github-Documentation-With-Doxygen/tree/master).
I didn't care that much about error handling because of missing time. There it might happen that you declare a `MultiArray` or `Slice` and an operation on it yields a segfault because it was forgotten to instancate the underlying container. Of course, there should be some mechanism, that catches such things, but due to the afore mentioned lack of time, it has not been implemented in every case. If you encounter such problems, pleas tell me, but be aware, that I won't fix it very soon.
I want to thank Gesina Schwalbe for creating the logo.
There are unit tests, which cover the all crucial parts of this library, but probably not every special case. Hence, there is no warranty, that, if you do something fancy I didn't consider, everything works fine.

14
TODO Normal file
View file

@ -0,0 +1,14 @@
include/operation/op_types.cc.h@225: "build and execute assign expression forwarding outer index"
include/operation/op_types.cc.h@498: "implement ifor with func arg"
opt/hdf5/include/h5_content_base.h@23: "IO save error handling"
opt/hdf5/lib/h5_dataset.cc@124: "all sub-ranges explicity"
lib/ranges/crange.cc@94: "preliminary solution (TODO: implement xpr that simply returns PosT value)"
include/ranges/srange.cc.h@307: "check for selected static sizes of SRange -> return SRange"
include/xpr/for.cc.h@324: "check for write access"
include/base/dtype.cc.h@23: "for tuple use vector<DType>"
include/ranges/urange.cc.h@384: "else general transform using DType (better than nothing), to be implemented"
include/ranges/urange.cc.h@448: "else general transform using DType (better than nothing), to be implemented"
include/array/array_base.cc.h@184: "check further compatibility of index/range format"
include/array/array_base.cc.h@376: "check further compatibility of index/range format"
include/ranges/index_base.cc.h@109: "if this assert never applies, remove mPtrId (-> Defaults)"

24
cmake/check_avx.cmake Normal file
View file

@ -0,0 +1,24 @@
macro(check_avx)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_FLAGS "-Wall -Werror -Wpedantic -std=c++17 -mavx")
check_cxx_source_compiles("
#include <immintrin.h>
#include <iostream>
int main()
{
const double a[4] = { 0,0,0,0 };
const double b[4] = { 0,0,0,0 };
double o[4] = { 0,0,0,0 };
__m256d av = _mm256_load_pd(a);
__m256d bv = _mm256_load_pd(b);
__m256d ov = _mm256_add_pd(av, bv);
_mm256_store_pd(o, ov);
std::cout << o[0] << std::endl;
return 0;
}
"
AVX_AVAIL
)
endmacro()

BIN
cnorxz_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

2774
doc/doxy/Doxyfile Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

36
doc/doxy/header.html Normal file
View file

@ -0,0 +1,36 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.10.0"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>CNORXZ: Container with Native Operation Routines and Expressions (CNORXZ)</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<link rel="icon" href="$relpath^cnorxz_logo_mini.png" type="image/x-icon" />
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectlogo"><img alt="Logo" src="cnorxz_logo_mini.png"/></td>
<td id="projectalign">
<div id="projectname">CNORXZ
</div>
<div id="projectbrief">Container with Native Operation Routines and Expressions</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->

View file

@ -0,0 +1 @@
../../../cnorxz_logo.png

View file

@ -2,5 +2,14 @@
include_directories(${CMAKE_SOURCE_DIR}/src/include)
add_subdirectory(tests)
add_subdirectory(lib)
add_subdirectory(bin)
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include)
if(ENABLE_hdf5)
add_subdirectory(opt/hdf5)
endif()
if(ENABLE_cereal)
add_subdirectory(opt/cereal)
endif()
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz)

6
src/bin/CMakeLists.txt Normal file
View file

@ -0,0 +1,6 @@
add_executable(cnorxz-config config.cc)
add_dependencies(cnorxz-config cnorxz)
target_link_libraries(cnorxz-config cnorxz)
install(TARGETS cnorxz-config RUNTIME DESTINATION ${INSTALL_PATH}/bin)

62
src/bin/config.cc Normal file
View file

@ -0,0 +1,62 @@
// -*- C++ -*-
/**
@file bin/config.cc
@brief Program for printing cnorxz configurations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include <cstdlib>
#include <iostream>
#include <map>
#include <functional>
#include "base/config.h"
using CNORXZ::String;
using CNORXZ::SizeT;
typedef std::map<String,std::function<String(void)>> CMapT;
auto configMap()
{
CMapT m;
m["--version"] = CNORXZ::Config::version;
m["--commit"] = CNORXZ::Config::commit;
m["--flags"] = CNORXZ::Config::flags;
return m;
}
void printUsage(const String& prog, const CMapT& cm)
{
std::cout << "usage: " << prog << " ";
for(const auto& x: cm){
std::cout << "[" << x.first << "] ";
}
std::cout << std::endl;
}
int main(int argc, char** argv)
{
const String prog(argv[0]);
const auto cm = configMap();
if(argc == 1){
printUsage(prog, cm);
}
try {
for(SizeT i = 1; i != static_cast<SizeT>(argc); ++i){
std::cout << cm.at( String(argv[i]) )() << std::endl;
}
}
catch(const std::out_of_range& e){
std::cerr << "caught exception: " << e.what() << std::endl;
printUsage(prog, cm);
return 1;
}
catch(...){
std::cerr << "caught generic exception" << std::endl;
}
return 0;
}

View file

@ -1,89 +0,0 @@
#ifndef __ma_allocator__
#define __ma_allocator__
#include <cstdlib>
#include <new>
#include <vector>
#include <cstdint>
#include <cassert>
#include <iostream>
#define MIB_SIZE 1024*1024 // 1MiB
#define WARN_SIZE MIB_SIZE*100 // 100 MiB
namespace MultiArrayHelper
{
template <typename T>
struct Allocator
{
typedef T value_type;
static constexpr size_t type_size = sizeof(value_type);
static constexpr size_t N = 32;
struct VX
{
alignas(N) char x[N];
};
Allocator() = default;
template <typename U>
Allocator(const Allocator<U>& x) {}
T* allocate(size_t n)
{
const size_t nn = n*type_size;
if(nn >= WARN_SIZE){
std::cout << __func__ << ": WARNING: allocating " << nn/(MIB_SIZE) << " MiB" << std::endl;
}
const size_t off = nn%N;
const size_t nnx = (off == 0) ? nn : nn + N - off;
const size_t nnd = nnx/N;
VX* vx = new VX[nnd];
return reinterpret_cast<T*>(vx);
}
void deallocate(T* p, size_t n)
{
VX* vx = reinterpret_cast<VX*>(p);
delete [] vx;
}
};
template <class T, class U>
bool operator==(const Allocator<T>& a, const Allocator<U>& b)
{
return true;
}
template <class T, class U>
bool operator!=(const Allocator<T>& a, const Allocator<U>& b)
{
return false;
}
} // namespace MultiArrayHelper
namespace MultiArrayTools
{
template <typename T>
using vector = std::vector<T,MultiArrayHelper::Allocator<T>>;
template <typename T>
inline std::vector<T> toStdVec(const vector<T>& v)
{
return std::vector<T>(v.begin(), v.end());
}
template <typename T>
inline vector<T> toMatVec(const std::vector<T>& v)
{
return vector<T>(v.begin(), v.end());
}
} // namespace MultiArrayTools
#endif

View file

@ -1,299 +0,0 @@
#ifndef __arith_h__
#define __arith_h__
#include <functional>
namespace MultiArrayTools
{
template <size_t N>
struct ArgPack
{
template <class F, class Tuple, typename... As>
static inline auto mk(const Tuple& tp, As... as)
-> decltype(ArgPack<N-1>::template mk<F,Tuple,decltype(std::get<N>(tp)),As...>(tp, std::get<N>(tp), as...))
{
return ArgPack<N-1>::template mk<F,Tuple,decltype(std::get<N>(tp)),As...>(tp, std::get<N>(tp), as...);
}
template <class F, class Tuple, typename... As>
static inline auto mkd(const F& ff, const Tuple& tp, As... as)
-> decltype(ArgPack<N-1>::template mkd<F,Tuple,decltype(std::get<N>(tp)),As...>(ff, tp, std::get<N>(tp), as...))
{
return ArgPack<N-1>::template mkd<F,Tuple,decltype(std::get<N>(tp)),As...>(ff, tp, std::get<N>(tp), as...);
}
};
template <>
struct ArgPack<0>
{
template <class F, class Tuple, typename... As>
static inline auto mk(const Tuple& tp, As... as)
-> decltype(F::apply(std::get<0>(tp), as...))
{
return F::apply(std::get<0>(tp), as...);
}
template <class F, class Tuple, typename... As>
static inline auto mkd(const F& ff, const Tuple& tp, As... as)
-> decltype(ff(std::get<0>(tp), as...))
{
return ff(std::get<0>(tp), as...);
}
};
template <typename T, class F, typename... As>
struct StaticFunctionBase
{
static constexpr bool FISSTATIC = true;
typedef T value_type;
template <class... Ops>
static auto mk(const Ops&... ops)
-> Operation<T,F,Ops...>
{
return Operation<T,F,Ops...>(ops...);
}
static inline T apply(const std::tuple<As...>& arg)
{
return ArgPack<sizeof...(As)-1>::template mk<F,std::tuple<As...> >(arg);
}
};
// OPERATIONS (STATIC)
template <typename T>
struct identity : public StaticFunctionBase<T, identity<T>, T>
{
//static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, identity<T>, T>::apply;
static inline T apply(T a)
{
return a;
}
};
template <typename T, typename U>
using plusv = decltype(std::declval<T>()+std::declval<U>());
template <typename T, typename U>
using minusv = decltype(std::declval<T>()-std::declval<U>());
template <typename T, typename U>
using multipliesv = decltype(std::declval<T>()*std::declval<U>());
template <typename T, typename U>
using dividesv = decltype(std::declval<T>()/std::declval<U>());
template <typename T, typename U>
struct plusx : public StaticFunctionBase<plusv<T,U>, plusx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<plusv<T,U>, plusx<T,U>, T, U>::apply;
static inline plusv<T,U> apply(T a1, U a2)
{
return a1 + a2;
}
static inline T& selfApply(T& a1, const T& a2)
{
return a1 += a2;
}
};
template <typename T, typename U>
struct minusx : public StaticFunctionBase<minusv<T,U>, minusx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<minusv<T,U>, minusx<T,U>, T, U>::apply;
static inline plusv<T,U> apply(T a1, U a2)
{
return a1 - a2;
}
};
template <typename T, typename U>
struct multipliesx : public StaticFunctionBase<multipliesv<T,U>, multipliesx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<multipliesv<T,U>, multipliesx<T,U>, T, U>::apply;
static inline multipliesv<T,U> apply(T a1, U a2)
{
return a1 * a2;
}
};
template <typename T, typename U>
struct dividesx : public StaticFunctionBase<dividesv<T,U>, dividesx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<dividesv<T,U>, dividesx<T,U>, T, U>::apply;
static inline dividesv<T,U> apply(T a1, U a2)
{
return a1 / a2;
}
};
template <typename T>
struct negate : public StaticFunctionBase<T, negate<T>, T>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, negate<T>, T>::apply;
static inline T apply(T a)
{
return -a;
}
};
template <typename T>
using plus = plusx<T,T>;
template <typename T>
using minus = minusx<T,T>;
template <typename T>
using multiplies = multipliesx<T,T>;
template <typename T>
using divides = dividesx<T,T>;
/*
template <typename T>
struct plus : public StaticFunctionBase<T, plus<T>, T, T>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, plus<T>, T, T>::apply;
static inline T apply(T a1, T a2)
{
return a1 + a2;
}
static inline T& selfApply(T& a1, const T& a2)
{
return a1 += a2;
}
};
template <typename T>
struct minus : public StaticFunctionBase<T, minus<T>, T, T>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, minus<T>, T, T>::apply;
static inline T apply(T a1, T a2)
{
return a1 - a2;
}
};
template <typename T>
struct multiplies : public StaticFunctionBase<T, multiplies<T>, T, T>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, multiplies<T>, T, T>::apply;
static inline T apply(T a1, T a2)
{
return a1 * a2;
}
};
template <typename T>
struct divides : public StaticFunctionBase<T, divides<T>, T, T>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, divides<T>, T, T>::apply;
static inline T apply(T a1, T a2)
{
return a1 / a2;
}
};
*/
// OPERATIONS (STATIC)
template <typename R, typename... Args>
class function
{
public:
static constexpr bool FISSTATIC = false;
private:
std::function<R(Args...)> mF;
public:
function() = default;
function(const std::function<R(Args...)>& in) : mF(in) {}
inline R operator()(const Args&... args)
{
return mF(args...);
}
inline R operator()(const std::tuple<Args...>& args)
{
return ArgPack<sizeof...(Args)-1>::template mkd<std::function<R(Args...)>,std::tuple<Args...>>>(mF, args);
}
};
#include <cmath>
#define regFunc1(fff) template <typename T>\
struct x_##fff : public StaticFunctionBase<T, x_##fff<T>, T> {\
static constexpr bool FISSTATIC = true;\
static inline T apply(T a){\
return fff(a); } };
#include "extensions/math.h"
#undef regFunc1
template <size_t N>
struct x_ipow
{
static constexpr bool FISSTATIC = true;
template <typename T>
static inline T apply(T a)
{
return a * x_ipow<N-1>::apply(a);
}
};
template <>
struct x_ipow<0>
{
static constexpr bool FISSTATIC = true;
template <typename T>
static inline T apply(T a)
{
return a;
}
};
/*
template <typename T, class Func>
struct dynamic_function
{
static constexpr bool FISSTATIC = false;
template <typename... Us>
inline T apply(Us... args)
{
return f(args...);
}
};
*/
} // end namespace MultiArrayHelper
#endif

View file

@ -0,0 +1,109 @@
// -*- C++ -*-
/**
@file include/array/aindex.cc.h
@brief Array index template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_aindex_cc_h__
#define __cxz_aindex_cc_h__
#include "aindex.h"
namespace CNORXZ
{
template <typename T>
AIndex<T>::AIndex(const T* data, const RangePtr& range, SizeT lexpos) :
YIndex(range, lexpos),
mCData(data)
{}
template <typename T>
AIndex<T>::AIndex(const T* data, const YIndex& yindex) :
YIndex(yindex),
mCData(data)
{}
template <typename T>
AIndex<T>::AIndex(const T* data, const AIndex<T>& aindex) :
AIndex<T>(aindex)
{
mCData = data;
}
template <typename T>
AIndex<T> AIndex<T>::operator+(Int n) const
{
AIndex<T> o = *this;
o += n;
return o;
}
template <typename T>
AIndex<T> AIndex<T>::operator-(Int n) const
{
AIndex<T> o = *this;
o -= n;
return o;
}
template <typename T>
const T& AIndex<T>::operator*() const
{
return mCData[IB::mPos];
}
template <typename T>
const T* AIndex<T>::operator->() const
{
return mCData + IB::mPos;
}
template <typename T>
BIndex<T>::BIndex(T* data, const RangePtr& range, SizeT lexpos) :
AIndex<T>(data, range, lexpos),
mData(data)
{}
template <typename T>
BIndex<T>::BIndex(T* data, const AIndex<T>& ai) :
AIndex<T>(data, ai),
mData(data)
{}
template <typename T>
BIndex<T> BIndex<T>::operator+(Int n) const
{
BIndex<T> o = *this;
o += n;
return o;
}
template <typename T>
BIndex<T> BIndex<T>::operator-(Int n) const
{
BIndex<T> o = *this;
o -= n;
return o;
}
template <typename T>
T& BIndex<T>::operator*()
{
return mData[IB::mPos];
}
template <typename T>
T* BIndex<T>::operator->()
{
return mData + IB::mPos;
}
}
#endif

View file

@ -0,0 +1,71 @@
// -*- C++ -*-
/**
@file include/array/aindex.h
@brief Array index declaration.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_aindex_h__
#define __cxz_aindex_h__
#include "ranges/range_base.h"
#include "ranges/index_base.h"
#include "ranges/xindex.h"
#include "ranges/yrange.h"
namespace CNORXZ
{
// AIndex (A = Array)
template <typename T>
class AIndex : public YIndex
{
public:
typedef YIndex::IB IB;
using YIndex::operator=;
DEFAULT_MEMBERS(AIndex);
AIndex(const T* data, const RangePtr& range, SizeT lexpos = 0);
AIndex(const T* data, const YIndex& yindex);
AIndex(const T* data, const AIndex<T>& aindex);
AIndex operator+(Int n) const;
AIndex operator-(Int n) const;
const T& operator*() const;
const T* operator->() const;
protected:
const T* mCData = nullptr;
};
// BIndex (because B comes after A...)
template <typename T>
class BIndex : public AIndex<T>
{
public:
typedef AIndex<T> AI;
typedef typename AI::IB IB;
DEFAULT_MEMBERS(BIndex);
BIndex(T* data, const RangePtr& range, SizeT pos = 0);
BIndex(T* data, const AIndex<T>& cci);
BIndex operator+(Int n) const;
BIndex operator-(Int n) const;
T& operator*();
T* operator->();
private:
T* mData = nullptr;
};
}
#endif

View file

@ -0,0 +1,15 @@
// -*- C++ -*-
/**
@file include/array/array.cc.h
@brief Array main header for template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "array_base.cc.h"
#include "marray.cc.h"
#include "aindex.cc.h"
#include "slice.cc.h"

17
src/include/array/array.h Normal file
View file

@ -0,0 +1,17 @@
// -*- C++ -*-
/**
@file include/array/array.h
@brief Array main header.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "array_base.h"
#include "marray.h"
#include "aindex.h"
#include "slice.h"
#include "array.cc.h"

View file

@ -0,0 +1,382 @@
// -*- C++ -*-
/**
@file include/array/array_base.cc.h
@brief Array base class template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_array_base_cc_h__
#define __cxz_array_base_cc_h__
#include "array_base.h"
#include "slice.h"
namespace CNORXZ
{
/*=======================================================+
| Implementations for CArrayBase member functions |
+=======================================================*/
template <typename T>
CArrayBase<T>::CArrayBase(const RangePtr& range) :
mRange(rangeCast<YRange>(range))
{}
template <typename T>
template <typename I, typename M>
const T& CArrayBase<T>::operator[](const IndexInterface<I,M>& i) const
{
if(formatIsTrivial()){
return data()[i.lex()];
}
else {
auto ai = itLex(i);
return *ai;
}
}
template <typename T>
template <typename I, typename M>
const T& CArrayBase<T>::at(const IndexInterface<I,M>& i) const
{
auto ai = itLexSave(i);
return *ai;
}
template <typename T>
template <class... Indices>
const T& CArrayBase<T>::operator[](const SPack<Indices...>& pack) const
{
if(formatIsTrivial()){
return data()[pack.lex()];
}
else {
auto ai = itLex(pack);
return *ai;
}
}
template <typename T>
template <class... Indices>
const T& CArrayBase<T>::at(const SPack<Indices...>& pack) const
{
auto ai = itLexSave(pack);
return *ai;
}
template <typename T>
const T& CArrayBase<T>::operator[](const DPack& pack) const
{
auto ai = itLex(pack);
return *ai;
}
template <typename T>
const T& CArrayBase<T>::at(const DPack& pack) const
{
auto ai = itLexSave(pack);
return *ai;
}
template <typename T>
template <typename I, typename M>
Sptr<CArrayBase<T>> CArrayBase<T>::sl(const IndexInterface<I,M>& begin,
const IndexInterface<I,M>& end) const
{
auto ai = itLexSave(begin);
auto aj = itLexSave(end);
return std::make_shared<CSlice<T>>(ai.prange(aj), this, ai.format(), ai.pos());
}
template <typename T>
SizeT CArrayBase<T>::size() const
{
return mRange->size();
}
template <typename T>
RangePtr CArrayBase<T>::range() const
{
return mRange;
}
template <typename T>
typename CArrayBase<T>::const_iterator CArrayBase<T>::begin() const
{
return this->cbegin();
}
template <typename T>
typename CArrayBase<T>::const_iterator CArrayBase<T>::end() const
{
return this->cend();
}
template <typename T>
template <class Index>
COpRoot<T,Index> CArrayBase<T>::operator()(const Sptr<Index>& i) const
{
if(formatIsTrivial()){
// assert that index format is trivial and has correct extensions
CXZ_ASSERT(i->formatIsTrivial(),
"got non-trivial index for container with trivial format");
this->checkFormatCompatibility(*i);
return coproot(*this, i);
}
else {
if(i->formatIsTrivial()){
// try to apply container format.
// if the reformat changes the index type in any manner
// the format is not applicable:
if constexpr(std::is_same<decltype(i->reformat( Vector<SizeT>(), Vector<SizeT>() )),Index>::value){
auto beg = begin();
auto aformat = beg.deepFormat();
auto amax = beg.deepMax();
auto fi = i->reformat( aformat, amax );
return coproot(*this, moveToPtr( fi ) );
}
else {
this->checkFormatCompatibility(*i);
return coproot(*this, i);
}
}
else {
// check if format is compatible
this->checkFormatCompatibility(*i);
return coproot(*this, i);
}
}
}
template <typename T>
template <class... Indices>
inline decltype(auto) CArrayBase<T>::operator()(const SPack<Indices...>& pack) const
{
return operator()(mindexPtr(pack));
}
template <typename T>
inline decltype(auto) CArrayBase<T>::operator()(const DPack& pack) const
{
return operator()(yindexPtr(pack));
}
/*=================================================================+
| Implementations for protected CArrayBase member functions |
+=================================================================*/
template <typename T>
template <class Acc>
typename CArrayBase<T>::const_iterator CArrayBase<T>::itLex(const Acc& acc) const
{
return begin() + acc.lex();
}
template <typename T>
template <class Acc>
typename CArrayBase<T>::const_iterator CArrayBase<T>::itLexSave(const Acc& acc) const
{
CXZ_ASSERT(acc.lex() < this->size(), "index out of range");
// check further compatibility of index/range format!!!
return begin() + acc.lex();
}
template <typename T>
template <class Acc>
void CArrayBase<T>::checkFormatCompatibility(const Acc& acc) const
{
auto j = begin();
CXZ_ASSERT(acc.lmax().val() == j.lmax().val(),
"got index of iteration space size = " << acc.lmax().val()
<< ", expected size = " << acc.lmax().val());
Vector<SizeT> f1 = toVec(acc.deepFormat());
Vector<SizeT> f2 = j.deepFormat();
std::sort(f1.begin(),f1.end());
std::sort(f2.begin(),f2.end());
SizeT i1 = 0;
SizeT i2 = 0;
CXZ_ASSERT(f1[i1] == f2[i2], "obtained format " << toString(f1)
<< ", which is incompatible to target format " << toString(f2));
++i1;
++i2;
while(i1 < f1.size() and i2 < f2.size()){
if(f1[i1] < f2[i2]) {
if(++i1 == f1.size()) break;
CXZ_ASSERT(f1[i1] <= f2[i2], "obtained format " << toString(f1)
<< ", which is incompatible to target format " << toString(f2));
}
else if(f1[i1] > f2[i2]) {
if(++i2 == f2.size()) break;
CXZ_ASSERT(f1[i1] >= f2[i2], "obtained format " << toString(f1)
<< ", which is incompatible to target format " << toString(f2));
}
else {
++i1;
++i2;
}
}
}
/*======================================================+
| Implementations for ArrayBase member functions |
+======================================================*/
template <typename T>
ArrayBase<T>::ArrayBase(const RangePtr& range) :
CArrayBase<T>(range)
{}
template <typename T>
template <typename I, typename M>
T& ArrayBase<T>::operator[](const IndexInterface<I,M>& i)
{
if(this->formatIsTrivial()){
return data()[i.lex()];
}
else {
auto ai = itLex(i);
return *ai;
}
}
template <typename T>
template <typename I, typename M>
T& ArrayBase<T>::at(const IndexInterface<I,M>& i)
{
auto ai = itLexSave(i);
return *ai;
}
template <typename T>
template <class... Indices>
T& ArrayBase<T>::operator[](const SPack<Indices...>& pack)
{
if(this->formatIsTrivial()){
return data()[pack.lex()];
}
else {
auto ai = itLex(pack);
return *ai;
}
}
template <typename T>
template <class... Indices>
T& ArrayBase<T>::at(const SPack<Indices...>& pack)
{
auto ai = itLexSave(pack);
return *ai;
}
template <typename T>
T& ArrayBase<T>::operator[](const DPack& pack)
{
auto ai = itLex(pack);
return *ai;
}
template <typename T>
T& ArrayBase<T>::at(const DPack& pack)
{
auto ai = itLexSave(pack);
return *ai;
}
template <typename T>
template <typename I, typename M>
Sptr<ArrayBase<T>> ArrayBase<T>::sl(const IndexInterface<I,M>& begin,
const IndexInterface<I,M>& end)
{
auto ai = itLexSave(begin);
auto aj = itLexSave(end);
return std::make_shared<Slice<T>>(ai.prange(aj), this, ai.format(), ai.pos());
}
template <typename T>
typename ArrayBase<T>::iterator ArrayBase<T>::begin()
{
return iterator(this->data(), this->cbegin());
}
template <typename T>
typename ArrayBase<T>::iterator ArrayBase<T>::end()
{
return iterator(this->data(), this->cend());
}
template <typename T>
template <class Index>
OpRoot<T,Index> ArrayBase<T>::operator()(const Sptr<Index>& i)
{
if(this->formatIsTrivial()){
// assert that index format is trivial and has correct extensions
CXZ_ASSERT(i->formatIsTrivial(),
"got non-trivial index for container with trivial format");
this->checkFormatCompatibility(*i);
return oproot(*this, i);
}
else {
if(i->formatIsTrivial()){
// try to apply container format.
// if the reformat changes the index type in any manner
// the format is not applicable:
if constexpr(std::is_same<decltype(i->reformat( Vector<SizeT>(), Vector<SizeT>() )),Index>::value){
auto beg = begin();
auto aformat = beg.deepFormat();
auto amax = beg.deepMax();
auto fi = i->reformat( aformat, amax );
return oproot(*this, moveToPtr( fi ) );
}
else {
this->checkFormatCompatibility(*i);
return oproot(*this, i);
}
}
else {
// check if format is compatible
this->checkFormatCompatibility(*i);
return oproot(*this, i);
}
}
}
template <typename T>
template <class... Indices>
inline decltype(auto) ArrayBase<T>::operator()(const SPack<Indices...>& pack)
{
return operator()(mindexPtr(pack));
}
template <typename T>
inline decltype(auto) ArrayBase<T>::operator()(const DPack& pack)
{
return operator()(yindexPtr(pack));
}
/*================================================================+
| Implementations for protected ArrayBase member functions |
+================================================================*/
template <typename T>
template <class Acc>
typename ArrayBase<T>::iterator ArrayBase<T>::itLex(const Acc& acc)
{
return begin() + acc.lex();
}
template <typename T>
template <class Acc>
typename ArrayBase<T>::iterator ArrayBase<T>::itLexSave(const Acc& acc)
{
CXZ_ASSERT(acc.lex() < this->size(), "index out of range");
// check further compatibility of index/range format!!!
return begin() + acc.lex();
}
}
#endif

View file

@ -0,0 +1,290 @@
// -*- C++ -*-
/**
@file include/array/array_base.h
@brief Array base class declarations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_array_base_h__
#define __cxz_array_base_h__
#include <cstdlib>
#include <vector>
#include <memory>
#include <algorithm>
#include "base/base.h"
#include "aindex.h"
#include "operation/op_types.h"
namespace CNORXZ
{
/** ****
Abstract container base class
only read access to the data
@tparam T data type
*/
template <typename T>
class CArrayBase
{
public:
typedef AIndex<T> const_iterator; /** const iterator type */
DEFAULT_MEMBERS(CArrayBase); /**< default constructors and assignments */
/** construct container on a range
@param range
*/
CArrayBase(const RangePtr& range);
/** default destructor */
virtual ~CArrayBase() = default;
/** const data element access
@tparam I index type
@tparam M meta data type
@param i index
*/
template <typename I, typename M>
const T& operator[](const IndexInterface<I,M>& i) const;
/** const data element access
performs compatibility checks
@tparam I index type
@tparam M meta data type
@param i index
*/
template <typename I, typename M>
const T& at(const IndexInterface<I,M>& i) const;
/** const data element access
@tparam I index type
@tparam M meta data type
@param pack static index pack
*/
template <class... Indices>
const T& operator[](const SPack<Indices...>& pack) const;
/** const data element access
performs compatibility checks
@tparam I index type
@tparam M meta data type
@param i static index pack
*/
template <class... Indices>
const T& at(const SPack<Indices...>& pack) const;
/** const data element access
@param pack index pack
*/
const T& operator[](const DPack& pack) const;
/** const data element access
performs compatibility checks
@param i index pack
*/
const T& at(const DPack& pack) const;
/** create hypercubic slice from this container
@tparam I type of index used to indicate slice edges
@tparam M index meta type
@param begin begin edge
@param end end edge
*/
template <typename I, typename M>
Sptr<CArrayBase<T>> sl(const IndexInterface<I,M>& begin,
const IndexInterface<I,M>& end) const;
/** create operation on this container
@tparam Index type of operation index
@param i operation index
*/
template <class Index>
COpRoot<T,Index> operator()(const Sptr<Index>& i) const;
/** create operation on this container
@tparam Indices types of operation indices
@param pack pack of operation index
*/
template <class... Indices>
inline decltype(auto) operator()(const SPack<Indices...>& pack) const;
/** create operation on this container
@param pack pack of operation index
*/
inline decltype(auto) operator()(const DPack& pack) const;
/** get pointer to container data */
virtual const T* data() const = 0;
/** get number of elements in the container */
virtual SizeT size() const;
/** get container range */
virtual RangePtr range() const;
/** get index pointing to first position */
virtual const_iterator begin() const;
/** get index pointing to position after last position */
virtual const_iterator end() const;
/** get index pointing to first position */
virtual const_iterator cbegin() const = 0;
/** get index pointing to position after last position */
virtual const_iterator cend() const = 0;
/** check if container views the data, i.e. it does not own it */
virtual bool isView() const = 0;
protected:
RangePtr mRange; /**< the container range */
/** Get valid data index.
Create well-formated index from index pack (unformatted)
or index using trivial format.
@tparam Acc index type or index pack type
@param acc index or index pack
*/
template <class Acc>
const_iterator itLex(const Acc& acc) const;
/** Get valid data index.
Create well-formated index from index pack (unformatted)
or index using trivial format.
Perform compatibility checks.
@tparam Acc index type or index pack type
@param acc index or index pack
*/
template <class Acc>
const_iterator itLexSave(const Acc& acc) const;
/** Perform compatibility checks
@tparam Acc index type or index pack type
@param acc index or index pack.
*/
template <class Acc>
void checkFormatCompatibility(const Acc& acc) const;
/** check if format is trivial
@return true if container is data owning array, else return
result of the corresponding container index
*/
virtual bool formatIsTrivial() const = 0;
};
/** ****
Abstract container base class
read and write access to the data
@tparam T data type
*/
template <typename T>
class ArrayBase : public CArrayBase<T>
{
public:
typedef CArrayBase<T> CAB;
typedef typename CAB::const_iterator const_iterator; /**< constant iterator type */
typedef BIndex<T> iterator; /**< read/write iterator type */
using CAB::operator[];
using CAB::operator();
using CAB::at;
using CAB::data;
using CAB::begin;
using CAB::end;
using CAB::cbegin;
using CAB::cend;
using CAB::sl;
DEFAULT_MEMBERS(ArrayBase); /**< default constructors and assignments */
/** construct a container on a range
*/
ArrayBase(const RangePtr& range);
/** @copydoc CArrayBase::operator[]()
*/
template <typename I, typename M>
T& operator[](const IndexInterface<I,M>& i);
/** @copydoc CArrayBase::at()
*/
template <typename I, typename M>
T& at(const IndexInterface<I,M>& i);
/** @copydoc CArrayBase::operator[]()
*/
template <class... Indices>
T& operator[](const SPack<Indices...>& pack);
/** @copydoc CArrayBase::at()
*/
template <class... Indices>
T& at(const SPack<Indices...>& pack);
/** @copydoc CArrayBase::operator[]()
*/
T& operator[](const DPack& pack);
/** @copydoc CArrayBase::at()
*/
T& at(const DPack& pack);
/** @copydoc CArrayBase::operator()()
*/
template <class Index>
OpRoot<T,Index> operator()(const Sptr<Index>& i);
/** @copydoc CArrayBase::operator()()
*/
template <class... Indices>
inline decltype(auto) operator()(const SPack<Indices...>& pack);
/** @copydoc CArrayBase::operator()()
*/
inline decltype(auto) operator()(const DPack& pack);
/** @copydoc CArrayBase::sl()
*/
template <typename I, typename M>
Sptr<ArrayBase<T>> sl(const IndexInterface<I,M>& begin,
const IndexInterface<I,M>& end);
/** @copydoc CArrayBase::data()
read/write access
*/
virtual T* data() = 0;
/** @copydoc CArrayBase::begin()
read/write access
*/
virtual iterator begin();
/** @copydoc CArrayBase::end()
read/write access
*/
virtual iterator end();
protected:
/** @copydoc CArrayBase::itLex()
*/
template <class Acc>
iterator itLex(const Acc& acc);
/** @copydoc CArrayBase::itLexSave()
*/
template <class Acc>
iterator itLexSave(const Acc& acc);
};
}
#endif

View file

@ -0,0 +1,105 @@
// -*- C++ -*-
/**
@file include/array/marray.cc.h
@brief MArray implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_marray_cc_h__
#define __cxz_marray_cc_h__
#include "marray.h"
namespace CNORXZ
{
/*=======================================================+
| Implementation of MArray public member functions |
+=======================================================*/
template <typename T>
MArray<T>::MArray(const RangePtr& range) :
ArrayBase<T>(range), mCont(range->size())
{}
template <typename T>
MArray<T>::MArray(const RangePtr& range, const Vector<T>& vec) :
ArrayBase<T>(range), mCont(vec)
{}
template <typename T>
MArray<T>::MArray(const RangePtr& range, Vector<T>&& vec) :
ArrayBase<T>(range), mCont(vec)
{}
template <typename T>
MArray<T>& MArray<T>::init(const RangePtr& range)
{
AB::mRange = rangeCast<YRange>(range);
mCont.resize(AB::mRange->size());
return *this;
}
template <typename T>
MArray<T>& MArray<T>::extend(const RangePtr& range)
{
if(AB::mRange == nullptr) {
return this->init(range);
}
MArray<T> tmp(AB::mRange->extend(range));
auto ei = this->end();
auto ti = tmp.begin();
// this is not very efficient; remove by sub-index operation once available:
for(auto ii = this->begin(); ii != ei; ++ii){
ti.at(ii.meta());
*ti = *ii;
}
*this = std::move(tmp);
return *this;
}
template <typename T>
const T* MArray<T>::data() const
{
return mCont.data();
}
template <typename T>
T* MArray<T>::data()
{
return mCont.data();
}
template <typename T>
typename MArray<T>::const_iterator MArray<T>::cbegin() const
{
return const_iterator(mCont.data(), AB::mRange);
}
template <typename T>
typename MArray<T>::const_iterator MArray<T>::cend() const
{
return const_iterator(mCont.data(), AB::mRange, mCont.size());
}
template <typename T>
bool MArray<T>::isView() const
{
return false;
}
/*==========================================================+
| Implementation of MArray protected member functions |
+==========================================================*/
template <typename T>
bool MArray<T>::formatIsTrivial() const
{
return true;
}
}
#endif

View file

@ -0,0 +1,58 @@
// -*- C++ -*-
/**
@file include/array/marray.h
@brief MArray declarations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_marray_h__
#define __cxz_marray_h__
#include "array_base.h"
namespace CNORXZ
{
/** ***
Generic multi-dimensional array class
This class owns the data that can be accessed through it
**/
template <typename T>
class MArray : public ArrayBase<T>
{
public:
typedef CArrayBase<T> AB;
typedef typename AB::const_iterator const_iterator;
using CArrayBase<T>::operator[];
using ArrayBase<T>::operator[];
DEFAULT_MEMBERS(MArray);
MArray(const RangePtr& range);
MArray(const RangePtr& range, const Vector<T>& vec);
MArray(const RangePtr& range, Vector<T>&& vec);
MArray& init(const RangePtr& range);
MArray& extend(const RangePtr& range);
virtual const T* data() const override;
virtual T* data() override;
virtual const_iterator cbegin() const override;
virtual const_iterator cend() const override;
virtual bool isView() const override;
SERIALIZATION_FUNCTIONS;
protected:
virtual bool formatIsTrivial() const override final;
private:
Vector<T> mCont;
};
}
#endif

View file

@ -0,0 +1,120 @@
// -*- C++ -*-
/**
@file include/array/slice.cc.h
@brief Slice implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_slice_cc_h__
#define __cxz_slice_cc_h__
#include "slice.h"
namespace CNORXZ
{
/*========================================================+
| Implementation of public CSlice member functions |
+========================================================*/
template <typename T>
CSlice<T>::CSlice(const RangePtr& range, const CArrayBase<T>* parent,
const YFormat& blockSizes, SizeT off) :
CArrayBase<T>(range),
mCParent(parent),
mBlockSizes(blockSizes),
mOff(off)
{}
template <typename T>
const T* CSlice<T>::data() const
{
return mCParent->data() + mOff;
}
template <typename T>
typename CSlice<T>::const_iterator CSlice<T>::cbegin() const
{
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, 0));
}
template <typename T>
typename CSlice<T>::const_iterator CSlice<T>::cend() const
{
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, AB::mRange->size()));
}
template <typename T>
bool CSlice<T>::isView() const
{
return true;
}
/*===========================================================+
| Implementation of protected CSlice member functions |
+===========================================================*/
template <typename T>
bool CSlice<T>::formatIsTrivial() const
{
return cbegin().formatIsTrivial();
}
/*=======================================================+
| Implementation of public Slice member functions |
+=======================================================*/
template <typename T>
Slice<T>::Slice(const RangePtr& range, ArrayBase<T>* parent,
const YFormat& blockSizes, SizeT off) :
ArrayBase<T>(range),
mParent(parent),
mBlockSizes(blockSizes),
mOff(off)
{}
template <typename T>
T* Slice<T>::data()
{
return mParent->data() + mOff;
}
template <typename T>
const T* Slice<T>::data() const
{
return mParent->data() + mOff;
}
template <typename T>
typename Slice<T>::const_iterator Slice<T>::cbegin() const
{
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, 0));
}
template <typename T>
typename Slice<T>::const_iterator Slice<T>::cend() const
{
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, AB::mRange->size()));
}
template <typename T>
bool Slice<T>::isView() const
{
return true;
}
/*==========================================================+
| Implementation of protected Slice member functions |
+==========================================================*/
template <typename T>
bool Slice<T>::formatIsTrivial() const
{
return cbegin().formatIsTrivial();
}
}
#endif

102
src/include/array/slice.h Normal file
View file

@ -0,0 +1,102 @@
// -*- C++ -*-
/**
@file include/array/slice.h
@brief Slice declarations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_slice_h__
#define __cxz_slice_h__
#include "base/base.h"
#include "array_base.h"
namespace CNORXZ
{
/** ****
constant and possibly partial view on the data
of another container
@tparam T data type
*/
template <typename T>
class CSlice : public CArrayBase<T>
{
public:
typedef CArrayBase<T> AB;
typedef typename AB::const_iterator const_iterator;
DEFAULT_MEMBERS(CSlice); /**< default constructors and assignments */
/** create slice from an array
@param range the slice's container range
@param parent the original container
@param blockSizes the format of the slice
@param off the initial pointer position w.r.t. the original initial position
*/
CSlice(const RangePtr& range, const CArrayBase<T>* parent,
const YFormat& blockSizes, SizeT off);
virtual const T* data() const override;
virtual const_iterator cbegin() const override;
virtual const_iterator cend() const override;
virtual bool isView() const override final;
protected:
virtual bool formatIsTrivial() const override final;
const CArrayBase<T>* mCParent = nullptr; /**< pointer to the original container */
YFormat mBlockSizes; /**< the format */
SizeT mOff = 0; /** pointer offset w.r.t. the original pointer */
};
/** ****
possibly partial view on the data
of another container
@tparam T data type
*/
template <typename T>
class Slice : public ArrayBase<T>
{
public:
typedef CArrayBase<T> AB;
typedef typename AB::const_iterator const_iterator;
DEFAULT_MEMBERS(Slice); /**< default constructors and assignments */
/** create slice from an array
@param range the slice's container range
@param parent the original container
@param blockSizes the format of the slice
@param off the initial pointer position w.r.t. the original initial position
*/
Slice(const RangePtr& range, ArrayBase<T>* parent,
const YFormat& blockSizes, SizeT off);
virtual const T* data() const override;
virtual T* data() override;
virtual const_iterator cbegin() const override;
virtual const_iterator cend() const override;
virtual bool isView() const override final;
protected:
virtual bool formatIsTrivial() const override final;
private:
ArrayBase<T>* mParent = nullptr;
YFormat mBlockSizes;
SizeT mOff = 0;
};
}
#endif

40
src/include/base/assert.h Normal file
View file

@ -0,0 +1,40 @@
// -*- C++ -*-
/**
@file include/base/assert.h
@brief warning and error makros
Definition of macros that can be used for convenient error handling and warnings
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include <iostream>
#include <sstream>
/** library error tag */
#define CXZ_ERRTAG __FILE__ << '@' << __LINE__ << '(' << __func__ << "): error"
/** library warning tag */
#define CXZ_WARNTAG __FILE__ << '@' << __LINE__ << ": warning"
/** throw error
@param errmsg error message
*/
#define CXZ_ERROR(errmsg) { \
auto mkerr = [&](){ std::stringstream ss; ss << CXZ_ERRTAG << ": " << errmsg << std::flush; return ss.str(); }; \
throw std::runtime_error(mkerr()); }
/** print warning
@param errmsg warning message
*/
#define CXZ_WARNING(errmsg) {\
std::cerr << CXZ_WARNTAG << ": " << errmsg << std::endl; }
/** throw error if given statement is not fulfilled
@param statement statement to be checked
@param errmsg error message
*/
#define CXZ_ASSERT(statement, errmsg) if(not (statement)) { CXZ_ERROR(errmsg); }

View file

@ -0,0 +1,18 @@
// -*- C++ -*-
/**
@file include/base/base.cc.h
@brief basic cc headers
Include basic cc headers containing defintions and macros
used throughout this library
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "dtype.cc.h"
#include "obj_handle.cc.h"
#include "to_string.cc.h"
#include "iter.cc.h"

38
src/include/base/base.h Normal file
View file

@ -0,0 +1,38 @@
// -*- C++ -*-
/**
@file include/base/base.h
@brief basic headers
Include basic headers containing defintions and macros
used throughout this library
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_base_h__
#define __cxz_base_h__
#include <cstdlib>
#include <iostream>
#include <utility>
#include "macros.h"
#include "assert.h"
#include "types.h"
#include "obj_handle.h"
#include "dtype.h"
#include "isq.h"
#include "iter.h"
#include "uuid.h"
#include "utils.h"
#include "config.h"
#include "intrin.h"
#include "base.cc.h"
#include "memory/memory.h"
#endif

35
src/include/base/config.h Normal file
View file

@ -0,0 +1,35 @@
// -*- C++ -*-
/**
@file include/base/config.h
@brief Runtime config functions declarations.
Declare functions returning version and configuration infos.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_config_h__
#define __cxz_config_h__
#include <cstdlib>
#include "base/types.h"
namespace CNORXZ
{
namespace Config
{
/** return cnorxz version */
String version();
/** return git hash */
String commit();
/** return compile flags */
String flags();
}
}
#endif

View file

@ -0,0 +1,74 @@
// -*- C++ -*-
/**
@file include/base/dtype.cc.h
@brief DType template member function definitions
Definitions of the template member functions of the DType class.
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_dtype_cc_h__
#define __cxz_dtype_cc_h__
#include <sstream>
#include "dtype.h"
#include "to_string.h"
namespace CNORXZ
{
// for tuple use vector<DType> !!!
// (yes DType is slow, thats why one should only use it for debugging)
template <typename T>
DType::DType(const T& d) : mD(d)
{
_mkToStr<T>();
_mkComp<T>();
}
template <typename T>
DType& DType::operator=(const T& d)
{
mD = d;
_mkToStr<T>();
_mkComp<T>();
return *this;
}
template <typename T>
void DType::_mkToStr()
{
mToStr = [](const std::any& d){
return toString(std::any_cast<T>(d));
};
}
template <typename T>
void DType::_mkComp()
{
mComp = [](const std::any& d, const std::any& a){
if(d.type() != a.type()){
return 2;
}
else {
auto& at = std::any_cast<const T&>(a);
auto& dt = std::any_cast<const T&>(d);
if(std::equal_to<T>{}(dt,at)){
return 0;
}
else if(std::less<T>{}(dt,at)){
return -1;
}
else {
return 1;
}
}
};
}
}
#endif

104
src/include/base/dtype.h Normal file
View file

@ -0,0 +1,104 @@
// -*- C++ -*-
/**
@file include/base/dtype.h
@brief DType declaration
DType is a generic type-erasing class that wrapps std::any.
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_dynamic_meta_h__
#define __cxz_dynamic_meta_h__
#include <cstdlib>
#include <utility>
#include <memory>
#include <any>
#include <functional>
#include "macros.h"
#include "types.h"
namespace CNORXZ
{
/** ****
Type erasing class wrapping std::any
*/
class DType
{
private:
std::any mD;
std::function<String(const std::any&)> mToStr;
std::function<Int(const std::any&,const std::any&)> mComp;
template <typename T>
void _mkToStr();
template <typename T>
void _mkComp();
public:
DEFAULT_MEMBERS(DType); /**< default constructors and assignments */
/** Generic constructor template
Constructs a DType from the given argument
@tparam T input data type
@param d input
*/
template <typename T>
DType(const T& d);
/** Generic assignment template
Assigns the given argument to the DType
@tparam T input data type
@param d input
*/
template <typename T>
DType& operator=(const T& d);
/** convert contained data so string */
String str() const { return mToStr(mD); }
/** return reference to type-erased data */
const std::any& get() const { return mD; }
/** check for equality
@param a variable to compare with
*/
bool operator==(const DType& a) const { return mComp(mD,a.mD) == 0; }
/** check for inequality
@param a variable to compare with
*/
bool operator!=(const DType& a) const { return mComp(mD,a.mD) != 0; }
/** check smaller
@param a variable to compare with
*/
bool operator<(const DType& a) const { return mComp(mD,a.mD) == -1; }
/** check greater
@param a variable to compare with
*/
bool operator>(const DType& a) const { return mComp(mD,a.mD) == 1; }
/** check not greater
@param a variable to compare with
*/
bool operator<=(const DType& a) const { auto c = mComp(mD,a.mD); return c <= 0; }
/** check not smaller
@param a variable to compare with
*/
bool operator>=(const DType& a) const { auto c = mComp(mD,a.mD); return c == 1 or c == 0; }
};
} // namespace CNORXZ
#endif

25
src/include/base/intrin.h Normal file
View file

@ -0,0 +1,25 @@
// -*- C++ -*-
/**
@file include/base/intrin.h
@brief Definitions related to intrinsics
**/
#ifndef __cxz_intrin_h__
#define __cxz_intrin_h__
#define MAX_VSIZE 1
// AVX:
#define AVX_BITS 256
#define AVX_VSIZE (AVX_BITS/8)
#ifdef CXZ_HAVE_AVX
#undef MAX_VSIZE
#define MAX_VSIZE AVX_VSIZE
#endif
// ...:
// ...
#endif

48
src/include/base/isq.h Normal file
View file

@ -0,0 +1,48 @@
// -*- C++ -*-
/**
@file include/base/isq.h
@brief Integer sequence range and creation functions
Declaration of integer sequence range and corresponding creating function templates
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_isq_h__
#define __cxz_isq_h__
#include <cstdlib>
#include <utility>
#include "types.h"
namespace CNORXZ
{
/** @cond 0 */
template <SizeT O, SizeT... Is>
std::index_sequence<(Is+O)...> mkIsqAdd(std::index_sequence<Is...> is) { return {}; }
template <SizeT B, SizeT E>
struct MkIsq
{
static auto make()
{
static_assert(B <= E, "begin of sequence must be smaller than end of sequence");
return mkIsqAdd<B>( std::make_index_sequence<E-B>{} );
}
typedef decltype(make()) type;
};
/** @endcond */
/** static consecutive integer sequence
@tparam B begin integer
@tparam E end integer
*/
template <SizeT B, SizeT E>
using Isqr = typename MkIsq<B,E>::type;
}
#endif

View file

@ -0,0 +1,69 @@
// -*- C++ -*-
/**
@file include/base/iter.cc.h
@brief Static for-loops
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_iter_cc_h__
#define __cxz_iter_cc_h__
#include "iter.h"
#include "xpr/func.h"
namespace CNORXZ
{
/** @cond 0 */
template <class G, class F, SizeT... Is>
constexpr decltype(auto) iteri(const G& g, const F& f, Isq<Is...> is)
{
if constexpr(std::is_same<F,NoF>::value){
( g(CSizeT<Is>{}), ... );
}
else {
return f( g(CSizeT<Is>{}) ... );
}
}
/** @endcond */
template <SizeT B, SizeT E, class G, class F>
constexpr decltype(auto) iter(const G& g, const F& f)
{
return iteri(g, f, Isqr<B,E>{});
}
/** @cond 0 */
template <SizeT E, SizeT I, class G, class F, class C, typename... Args>
constexpr decltype(auto) iterIfi(const G& g, const F& f, const C& c, const Args&... args)
{
if constexpr(I >= E){
if constexpr(std::is_same<F,NoF>::value){
return;
}
else {
return f(args...);
}
}
else {
if constexpr(c(CSizeT<I>{})){
return iterIfi<E,I+1>(g, f, c, args..., g(CSizeT<I>{}));
}
else {
return iterIfi<E,I+1>(g, f, c, args...);
}
}
}
/** @endcond */
template <SizeT B, SizeT E, class G, class F, class C>
constexpr decltype(auto) iterIf(const G& g, const F& f, const C& c)
{
return iterIfi<E,B>(g, f, c);
}
}
#endif

57
src/include/base/iter.h Normal file
View file

@ -0,0 +1,57 @@
// -*- C++ -*-
/**
@file include/base/iter.h
@brief Static for-loops
Declaration of function templates that can be used to implement a static for-loop
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_iter_h__
#define __cxz_iter_h__
#include <cstdlib>
#include "types.h"
namespace CNORXZ
{
/** @cond 0 */
template <class G, class F, SizeT... Is>
constexpr decltype(auto) iteri(const G& g, const F& f, Isq<Is...> is);
/** @endcond */
/** static for loop
@tparam B begin index
@tparam E end index
@tparam G type of expression to executed for each element
@tparam F type of accumulating expression collecting result for all elements
@param g expression to executed for each element
@param f accumulating expression collecting result for all elements
*/
template <SizeT B, SizeT E, class G, class F>
constexpr decltype(auto) iter(const G& g, const F& f);
/** @cond 0 */
template <SizeT E, SizeT I, class G, class F, class C, typename... Args>
constexpr decltype(auto) iterIfi(const G& g, const F& f, const C& c, const Args&... args);
/** @endcond */
/** static conditional for loop
@tparam B begin index
@tparam E end index
@tparam G type of expression to executed for each element
@tparam F type of accumulating expression collecting result for all elements
@tparam C type of condition expression
@param g expression to executed for each element
@param f accumulating expression collecting result for all elements
@param c condition expression
*/
template <SizeT B, SizeT E, class G, class F, class C>
constexpr decltype(auto) iterIf(const G& g, const F& f, const C& c);
}
#endif

135
src/include/base/macros.h Normal file
View file

@ -0,0 +1,135 @@
// -*- C++ -*-
/**
@file include/base/macros.h
@brief useful macros
Define useful macros that are used throughout this library for convenience,
briefnes and/or debugging.
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_macros_h__
#define __cxz_macros_h__
#include <iostream>
#ifndef CHECK
#define CHECK std::cout << __FILE__ << ": @" << __LINE__ << " in " << __func__ << std::endl;
#endif
#ifndef VCHECK
#define VCHECK(a) std::cout << __FILE__ << ": @" << __LINE__ \
<< " in " << __func__ << ": " << #a << " = " << a << std::endl;
#endif
/** shortcut for defining default constructor */
#define DEFAULT_C(__class_name__) __class_name__() = default
/** shortcut for defining default copy constructor */
#define DEFAULT_COPY_C(__class_name__) __class_name__(const __class_name__& a) = default
/** shortcut for defining default copy assignment */
#define DEFAULT_COPY_A(__class_name__) __class_name__& operator=(const __class_name__& a) = default
/** shortcut for defining default move constructor */
#define DEFAULT_MOVE_C(__class_name__) __class_name__(__class_name__&& a) = default
/** shortcut for defining default move assignment */
#define DEFAULT_MOVE_A(__class_name__) __class_name__& operator=(__class_name__&& a) = default
/** shortcut for defining default copy constructor and assignment */
#define DEFAULT_COPY(__class_name__) DEFAULT_COPY_C(__class_name__); DEFAULT_COPY_A(__class_name__)
/** shortcut for defining default move constructor and assignment */
#define DEFAULT_MOVE(__class_name__) DEFAULT_MOVE_C(__class_name__); DEFAULT_MOVE_A(__class_name__)
/** shortcut for defining default copy and move constructor and assignment */
#define DEFAULT_MEMBERS_X(__class_name__) DEFAULT_COPY(__class_name__); DEFAULT_MOVE(__class_name__)
/** shortcut for defining default constructor, default copy and move constructor and assignment */
#define DEFAULT_MEMBERS(__class_name__) DEFAULT_C(__class_name__); DEFAULT_MEMBERS_X(__class_name__)
/** shortcut for defining default constructor
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_C(__spec__,__class_name__) __spec__ __class_name__() = default
/** shortcut for defining default copy constructor
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_COPY_C(__spec__,__class_name__) __spec__ __class_name__(const __class_name__& a) = default
/** shortcut for defining default copy assignment
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_COPY_A(__spec__,__class_name__) __spec__ __class_name__& operator=(const __class_name__& a) = default
/** shortcut for defining default move constructor
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_MOVE_C(__spec__,__class_name__) __spec__ __class_name__(__class_name__&& a) = default
/** shortcut for defining default move assignment
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_MOVE_A(__spec__,__class_name__) __spec__ __class_name__& operator=(__class_name__&& a) = default
/** shortcut for defining default copy constructor and assignment
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_COPY(__spec__,__class_name__) SP_DEFAULT_COPY_C(__spec__,__class_name__); SP_DEFAULT_COPY_A(__spec__,__class_name__)
/** shortcut for defining default move constructor and assignment
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_MOVE(__spec__,__class_name__) SP_DEFAULT_MOVE_C(__spec__,__class_name__); SP_DEFAULT_MOVE_A(__spec__,__class_name__)
/** shortcut for defining default copy and move constructor and assignment
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_MEMBERS_X(__spec__,__class_name__) SP_DEFAULT_COPY(__spec__,__class_name__); SP_DEFAULT_MOVE(__spec__,__class_name__)
/** shortcut for defining default constructor, default copy and move constructor and assignment
@param __spec__ specifier
@param __class_name__ class name
*/
#define SP_DEFAULT_MEMBERS(__spec__,__class_name__) SP_DEFAULT_C(__spec__,__class_name__); SP_DEFAULT_MEMBERS_X(__spec__,__class_name__)
/** shortcut for all typedefs needed to use a class as iterator
@param __meta_type__ meta data type
*/
#define INDEX_RANDOM_ACCESS_ITERATOR_DEFS(__meta_type__) typedef std::random_access_iterator_tag iterator_category; \
typedef SizeT difference_type; \
typedef __meta_type__ value_type; \
typedef const __meta_type__* pointer; \
typedef const __meta_type__& reference
#define CXZ_CVAL_FALSE static constexpr bool value = false
#define CXZ_CVAL_TRUE static constexpr bool value = true
#define IS_SAME(a,b) std::is_same<a,b>::value
#define IS_NOT_SAME(a,b) (not std::is_same<a,b>::value)
#ifdef HAVE_CEREAL
#define SERIALIZATION_FUNCTIONS template <class Archive> void save(Archive& ar, const std::uint32_t version) const; \
template <class Archive> void load(Archive& ar, const std::uint32_t version)
#define SERIALIZATION_FUNCTIONS_NOPUB friend class cereal::access; \
template <class Archive> void save(Archive& ar, const std::uint32_t version) const; \
template <class Archive> void load(Archive& ar, const std::uint32_t version)
#else
#define SERIALIZATION_FUNCTIONS static const int v = 0
#define SERIALIZATION_FUNCTIONS_NOPUB static const int v = 0
#endif
#endif

View file

@ -0,0 +1,74 @@
// -*- C++ -*-
/**
@file include/base/obj_handle.cc.h
@brief ObjHandle function definition
Implementation of the member functions of template ObjHandle
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_obj_handle_cc_h__
#define __cxz_obj_handle_cc_h__
#include "obj_handle.h"
namespace CNORXZ
{
template <typename T>
ObjHandle<T>::ObjHandle() {}
template <typename T>
ObjHandle<T>::ObjHandle(Uptr<T>&& a) : mC(std::forward<Uptr<T>>(a)) {}
template <typename T>
ObjHandle<T>::ObjHandle(const ObjHandle& a) : mC(a.mC->copy()) {}
template <typename T>
ObjHandle<T>::ObjHandle(ObjHandle&& a) : mC(a.mC) {}
template <typename T>
ObjHandle<T>& ObjHandle<T>::operator=(const ObjHandle& a)
{
mC = std::make_unique<T>(*a.mC);
return *this;
}
template <typename T>
ObjHandle<T>& ObjHandle<T>::operator=(ObjHandle&& a)
{
mC = a.mC;
return *this;
}
template <typename T>
T& ObjHandle<T>::operator*()
{
return *mC;
}
template <typename T>
T* ObjHandle<T>::operator->()
{
return &*mC;
}
template <typename T>
const T& ObjHandle<T>::operator*() const
{
return *mC;
}
template <typename T>
const T* ObjHandle<T>::operator->() const
{
return &*mC;
}
}
#endif

View file

@ -0,0 +1,84 @@
// -*- C++ -*-
/**
@file include/base/obj_handle.h
@brief ObjHandle template declaration
Pointer wrapper for directly handling objects via abstract base class;
Provides appropriate copy implementation
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_obj_handle_h__
#define __cxz_obj_handle_h__
#include "types.h"
namespace CNORXZ
{
/** ****
unique pointer wrapper
Allows to handle objects accessed through abstract base class pointers
as if they were complete (non-virtual) types.
Each type to be handled is required to have a copy() member function
that returns a copy of itself
@tparam T object type
*/
template <typename T>
class ObjHandle
{
protected:
Uptr<T> mC; /**< pointer to the object data */
public:
/** default constructor */
ObjHandle();
/** construct from unique pointer
@param a unique pointer
*/
ObjHandle(Uptr<T>&& a);
/** copy construct
@param a input
*/
ObjHandle(const ObjHandle& a);
/** move construct
@param a input
*/
ObjHandle(ObjHandle&& a);
/** copy assign
@param a input
*/
ObjHandle& operator=(const ObjHandle& a);
/** move assign
@param a input
*/
ObjHandle& operator=(ObjHandle&& a);
/** access data */
T& operator*();
/** get pointer to data */
T* operator->();
/** access data (const) */
const T& operator*() const;
/** get pointer to data (const) */
const T* operator->() const;
};
}
#endif

View file

@ -0,0 +1,113 @@
// -*- C++ -*-
/**
@file include/base/to_string.cc.h
@brief String converter implementation
Implementation of functions that convert a given object/type to a string
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_to_string_cc_h__
#define __cxz_to_string_cc_h__
#include "to_string.h"
#include "iter.h"
#include <sstream>
namespace CNORXZ
{
template <typename T>
String ToString<T>::func(const T& a)
{
std::stringstream ss;
ss << a;
return ss.str();
}
template <typename T>
String ToString<Vector<T>>::func(const Vector<T>& a)
{
std::stringstream ss;
ss << "[";
if(a.size() == 0){
ss << "]";
}
else {
auto it = a.begin();
for(; it != a.end()-1; ++it){
ss << toString(*it) << ",";
}
ss << toString(*it) << "]";
}
return ss.str();
}
template <typename T, size_t N>
String ToString<Arr<T,N>>::func(const Arr<T,N>& a)
{
std::stringstream ss;
ss << "(";
if constexpr(N == 0){
ss << ")";
}
else {
auto it = a.begin();
for(; it != a.end()-1; ++it){
ss << toString(*it) << ",";
}
ss << toString(*it) << ")";
}
return ss.str();
}
template <typename... Ts>
String ToString<Tuple<Ts...>>::func(const Tuple<Ts...>& t)
{
const String blim = "(";
const String elim = ")";
const String dlim = ",";
return iter<1,sizeof...(Ts)>
( [&](auto i) { return toString(std::get<i>(t)); },
[&](const auto&... xs) {
return blim + toString(std::get<0>(t)) + ( (dlim + xs) + ... ) + elim;
} );
}
template <typename T, typename S>
String ToString<std::pair<T,S>>::func(const std::pair<T,S>& p)
{
return String("(") + toString(p.first) + "," + toString(p.second) + ")";
}
template <typename T, typename S>
String ToString<std::map<T,S>>::func(const std::map<T,S>& p)
{
std::stringstream ss;
ss << "{";
if(p.size() == 0){
ss << "}";
}
else {
auto it = p.begin();
auto e = p.end();
e--;
for(; it != e; ++it){
ss << toString(it->first) << ":" << toString(it->second) << ",";
}
ss << toString(it->first) << ":" << toString(it->second) << "}";
}
return ss.str();
}
template <typename T>
String toString(const T& a)
{
return ToString<T>::func(a);
}
}
#endif

View file

@ -0,0 +1,135 @@
// -*- C++ -*-
/**
@file include/base/to_string.h
@brief String converter declarations.
Declaration of functions that convert a given object/type to a string.
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_to_string_h__
#define __cxz_to_string_h__
#include "types.h"
namespace CNORXZ
{
/** ***
Generic cast to string
@tparam T type to be casted
*/
template <typename T>
struct ToString
{
/** cast to string
@param a object to be casted
*/
static String func(const T& a);
};
/** ***
Specialization of ToString for strings
*/
template <>
struct ToString<String>
{
/** cast to string
@param a string to be casted
*/
static String func(const String& a);
};
/** ***
Specialization of ToString for vectors
@tparam T vector element type
*/
template <typename T>
struct ToString<Vector<T>>
{
/** cast to string
@param a vector to be casted
*/
static String func(const Vector<T>& a);
};
/** ***
Specialization of ToString for arrays
@tparam T array element type
@tparam N array size
*/
template <typename T, SizeT N>
struct ToString<Arr<T,N>>
{
/** cast to string
@param a array to be casted
*/
static String func(const Arr<T,N>& a);
};
/** ***
Specialization of ToString for tuples
@tparam Ts tuple element types
*/
template <typename... Ts>
struct ToString<Tuple<Ts...>>
{
/** cast to string
@param a tuple to be casted
*/
static String func(const Tuple<Ts...>& t);
};
/** ***
Specialization of ToString for pairs
@tparam T first element type
@tparam S second element type
*/
template <typename T, typename S>
struct ToString<std::pair<T,S>>
{
/** cast to string
@param a pair to be casted
*/
static String func(const std::pair<T,S>& t);
};
/** ***
Specialization of ToString for maps
@tparam T key type
@tparam S value type
*/
template <typename T, typename S>
struct ToString<std::map<T,S>>
{
/** cast to string
@param a map to be casted
*/
static String func(const std::map<T,S>& t);
};
/** ***
Specialization of ToString for DType
*/
template <>
struct ToString<DType>
{
/** cast to string
@param a DType to be casted
*/
static String func(const DType& a);
};
/** wrapper function for ToString
@tparam T type to be casted
@param a object to be casted
*/
template <typename T>
String toString(const T& a);
}
#endif

321
src/include/base/types.h Normal file
View file

@ -0,0 +1,321 @@
// -*- C++ -*-
/**
@file include/base/types.h
@brief Declaration of all library types
This file contains the declaration of all library types
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_types_h__
#define __cxz_types_h__
#include <string>
#include <vector>
#include <memory>
#include <tuple>
#include <complex>
#include <array>
#include <map>
#include <typeinfo>
#include <utility>
#include <numeric>
#include <cstdint>
namespace CNORXZ
{
/*====================+
| standard types |
=====================*/
typedef std::intptr_t PtrId;
typedef int32_t Int;
typedef int64_t LInt;
typedef uint64_t SizeT;
typedef double Double;
typedef Double Real;
typedef std::complex<Real> Complex;
typedef std::string String;
template <typename T, size_t N>
using Arr = std::array<T,N>;
template <typename T>
using Sptr = std::shared_ptr<T>;
template <typename T>
using Wptr = std::weak_ptr<T>;
template <typename T>
using Uptr = std::unique_ptr<T>;
template <typename T, typename U>
using Pair = std::pair<T,U>;
template <typename... T>
using Tuple = std::tuple<T...>;
template <SizeT I, typename... T>
using TupleElem = std::tuple_element<I,Tuple<T...>>;
template <typename T>
using RemoveRef = typename std::remove_reference<T>::type;
template <typename K, typename V>
using Map = std::map<K,V>;
typedef std::type_info TypeInfo;
template <SizeT... Is>
using Isq = std::index_sequence<Is...>;
// cxz helper functions/classes: -> isq.h
template <class... T>
using Isqf = std::index_sequence_for<T...>;
template <SizeT N>
using CSizeT = std::integral_constant<SizeT,N>;
/*===================+
| library types |
+===================*/
/*
Naming Prefixes:
D = Y = Dynamic
V = X = Virtual
S = Static
P = Partial = Sub
C = Classic
M = Multi (Index,Ranges) or !const (Container)
U = One(=Uni) dimensional
N = None = Null
E = Extension (SSE,AVX,etc dof)
T = Thread
R = Rank
A = (const) Array
B = (mutable) Array
F = Functional, Map,...
*/
// default template parameter
class None {};
// definition: base/dtype.h
class DType;
// definition: base/obj_handle.h
template <typename T>
class ObjHandle;
// definition: memory/allocator.h
template <typename T>
class Allocator;
// definition: xpr/vpos_type.h
class VPosBase;
// definition: xpr/vpos_type.h
template <class PosT>
class VPos;
// definition: xpr/vpos_type.h
template <class PosT>
class VPosRef;
// definition: xpr/pos_type.h
class UPos;
// definition: xpr/pos_type.h
template <SizeT N>
class SPos;
// definition: xpr/pos_type.h
class FPos;
// definition: xpr/pos_type.h
template <SizeT N, SizeT... Ms>
class SFPos;
// definition: xpr/pos_type.h
class DPos;
// definition: xpr/pos_type.h
class DPosRef;
// definition: xpr/pos_type.h
template <class PosT1, class PosT2>
class MPos;
// definition: ranges/range_base.h
class RangeBase;
typedef Sptr<RangeBase> RangePtr;
// definition: ranges/index_base.h
template <class I, typename MetaType>
class IndexInterface;
template <class I, typename MetaType>
using IndexPtr = Sptr<IndexInterface<I,MetaType>>;
// definition: ranges/nrange.h
class NRange; // null-range (range over none)
// definition: ranges/nrange.h
class NIndex;
// definition: ranges/urange.h
template <typename Meta>
class URange; // generic simple range (uni-dimensional)
// definition: ranges/urange.h
template <typename Meta>
class UIndex;
// definition: ranges/prange.h
template <class Range>
class PRange;
// definition: ranges/prange.h
template <class Index>
class PIndex;
// definition: ranges/crange.h
class CRange; // classic range, trivial meta data
// definition: ranges/crange.h
class CIndex;
// definition: ranges/srange.h
template <typename Meta, SizeT S>
class SRange; // generic static size range
// definition: ranges/srange.h
template <typename Meta, SizeT S>
class SIndex;
// definition: ranges/mrange.h
template <class... Ranges>
class MRange; // multi range
// definition: ranges/mrange.h
template <class BlockType, class... Indices>
class GMIndex;
template <class... Indices>
using MIndex = GMIndex<None,Indices...>;
// definition: ranges/xindex.h
class XIndexBase; // dynamic index wrapper
typedef Sptr<XIndexBase> XIndexPtr;
// definition: ranges/dindex.h
class DIndex;
// definition: ranges/yrange.h
class YRange; // dynamic multi range
// definition: ranges/yrange.h
class YIndex;
typedef Sptr<YIndex> YIndexPtr;
// definition: ranges/pindex.h
template <class Index>
class PIndex; // partial index (index over sub-ranges and permutations)
// there should be also a static analogue
// definition: ranges/lindex.h
template <class Index, SizeT L>
class LIndex;
// definition: ranges/index_pack.h
template <class... Indices>
class SPack;
// definition: ranges/index_pack.h
class DPack;
// definition: ranges/index_format.h
template <SizeT N>
class MFormat;
// definition: ranges/index_format.h
template <class... PosT>
class GMFormat;
// definition: ranges/index_format.h
class YFormat;
// definition: array/array_base.h
template <typename T>
class CArrayBase;
// definition: array/array_base.h
template <typename T>
class ArrayBase;
// definition: array/array.h
template <typename T>
class MArray;
// definition: array/slice.h
template <typename T>
class CSlice;
// definition: array/slice.h
template <typename T>
class Slice;
// definition: operation/op_types.h
template <class OpT>
class COpInterface;
// definition: operation/op_types.h
template <class OpT>
class OpInterface;
// definition: operation/op_types.h
template <typename T, class IndexT>
class COpRoot;
// definition: operation/op_types.h
template <typename T, class IndexT>
class OpCont;
// definition: operation/op_types.h
template <typename T, class IndexT>
class OpRoot;
// definition: operation/op_types.h
template <class F, class... Ops>
class Operation;
// definition: operation/op_types.h
template <class CXpr>
class Contraction;
/*===================+
| derived types |
+===================*/
template <typename T>
using Vector = std::vector<T,Allocator<T>>;
template <typename T, SizeT N, bool Static>
struct Container
{ typedef Vector<T> type; };
template <typename T, SizeT N>
struct Container<T,N,true>
{ typedef Arr<T,N> type; };
}
#endif

147
src/include/base/utils.h Normal file
View file

@ -0,0 +1,147 @@
// -*- C++ -*-
/**
@file include/base/utils.h
@brief utilities
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_utils_h__
#define __cxz_utils_h__
#include <cstdlib>
#include <algorithm>
#include "types.h"
namespace CNORXZ
{
template <typename T, SizeT N>
Vector<T> toVec(const Arr<T,N>& a)
{
return iter<0,N>( [&](auto i) { return std::get<i>(a); },
[](const auto&... e) { return Vector<T> { e... }; } );
}
template <typename T>
Vector<T> toVec(const Vector<T>& a)
{
return a;
}
template <typename T>
Vector<T> toVec(const T& a)
{
return Vector<T> { a };
}
template <typename T, SizeT N1, SizeT N2>
constexpr Arr<T,N1+N2> cat2(const Arr<T,N1>& a1, const Arr<T,N2>& a2)
{
return iter<0,N1+N2>
( [&](auto i) { if constexpr(i < N1) { return std::get<i>(a1); } else { return std::get<i-N1>(a2); } },
[](const auto&... e) { return Arr<T,N1+N2> { e... }; } );
}
template <typename T, SizeT N1>
constexpr Arr<T,N1+1> cat2(const Arr<T,N1>& a1, const T& a2)
{
return iter<0,N1>
( [&](auto i) { return std::get<i>(a1); },
[&](const auto&... e) { return Arr<T,N1+1> { e..., a2 }; } );
}
template <typename T, SizeT N1>
constexpr Arr<T,N1+1> cat2(const T& a1, const Arr<T,N1>& a2)
{
return iter<0,N1>
( [&](auto i) { return std::get<i>(a2); },
[&](const auto&... e) { return Arr<T,N1+1> { a1, e... }; } );
}
template <typename T>
constexpr Arr<T,2> cat2(const T& a1, const T& a2)
{
return Arr<T,2> { a1, a2 };
}
template <typename T, SizeT N2>
Vector<T> cat2(const Vector<T>& a1, const Arr<T,N2>& a2)
{
Vector<T> o(a1.size()+N2);
std::copy(a1.begin(), a1.end(), o.begin());
std::copy(a2.begin(), a2.end(), o.begin()+a1.size());
return o;
}
template <typename T, SizeT N1>
Vector<T> cat2(const Arr<T,N1>& a1, const Vector<T>& a2)
{
Vector<T> o(N1+a2.size());
std::copy(a1.begin(), a1.end(), o.begin());
std::copy(a2.begin(), a2.end(), o.begin()+N1);
return o;
}
template <typename T>
Vector<T> cat2(const Vector<T>& a1, const Vector<T>& a2)
{
Vector<T> o(a1.size()+a2.size());
std::copy(a1.begin(), a1.end(), o.begin());
std::copy(a2.begin(), a2.end(), o.begin()+a1.size());
return o;
}
template <typename T>
Vector<T> cat2(const Vector<T>& a1, const T& a2)
{
Vector<T> o(a1);
o.push_back(a2);
return o;
}
template <typename T, SizeT N1>
Vector<T> cat2(const T& a1, const Vector<T>& a2)
{
Vector<T> o { a1 };
o.insert(o.end(), a2.begin(), a2.end());
return o;
}
template <typename T1, typename T2, typename... Ts>
decltype(auto) concat(const T1& a1, const T2& a2, const Ts&... as)
{
if constexpr(sizeof...(Ts) != 0){
return cat2(a1, concat(a2, as...));
}
else {
return cat2(a1, a2);
}
}
template <typename T, SizeT N>
constexpr Arr<T,N> mul(const Arr<T,N>& a, const T& b)
{
return iter<0,N>( [&](auto i) { return std::get<i>(a) * b; },
[](const auto&... e) { return Arr<T,N> { e... }; } );
}
template <typename T>
Vector<T> mul(const Vector<T>& a, const T& b)
{
Vector<T> o(a.size());
std::transform(a.begin(), a.end(), o.begin(), [&](const auto& x) { return x*b; } );
return o;
}
template <typename T>
constexpr T mul(const T& a, const T& b)
{
return a*b;
}
}
#endif

87
src/include/base/uuid.h Normal file
View file

@ -0,0 +1,87 @@
// -*- C++ -*-
/**
@file include/base/uuid.h
@brief cnorxz uuid declaration.
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_uuid_h__
#define __cxz_uuid_h__
#include <stdint.h>
#include <functional>
namespace CNORXZ
{
/** ***
uuid
*/
struct Uuid
{
uint64_t i1; /**< first 8 bytes */
uint64_t i2; /**< second 8 bytes */
};
/** create new uuid */
Uuid mkUuid();
/** operator equal to
@param a left hand side
@param b right hand side
*/
inline bool operator==(const Uuid& a, const Uuid& b)
{
return a.i1 == b.i1 and a.i2 == b.i2;
}
/** operator not equal to
@param a left hand side
@param b right hand side
*/
inline bool operator!=(const Uuid& a, const Uuid& b)
{
return a.i1 != b.i1 or a.i2 != b.i2;
}
/** operator less than
@param a left hand side
@param b right hand side
*/
inline bool operator<(const Uuid& a, const Uuid& b)
{
return (a.i1 == b.i1) ? a.i2 < b.i2 : a.i1 < b.i1;
}
/** operator greater than
@param a left hand side
@param b right hand side
*/
inline bool operator>(const Uuid& a, const Uuid& b)
{
return (a.i1 == b.i1) ? a.i2 > b.i2 : a.i1 > b.i1;
}
/** operator less or equal
@param a left hand side
@param b right hand side
*/
inline bool operator<=(const Uuid& a, const Uuid& b)
{
return not( (a.i1 == b.i1) ? a.i2 > b.i2 : a.i1 > b.i1 );
}
/** operator greater or equal
@param a left hand side
@param b right hand side
*/
inline bool operator>=(const Uuid& a, const Uuid& b)
{
return not( (a.i1 == b.i1) ? a.i2 < b.i2 : a.i1 < b.i1 );
}
}
#endif

View file

@ -1,39 +0,0 @@
// -*- C++ -*-
#ifndef __base_def_h__
#define __base_def_h__
#include <cassert>
#define DEBUG_MODE_X
#ifdef DEBUG_MODE_X
#include <iostream>
#ifndef CHECK
#define CHECK std::cout << __FILE__ << ": @" << __LINE__ << " in " << __func__ << std::endl;
#endif
#ifndef VCHECK
#define VCHECK(a) std::cout << __FILE__ << ": @" << __LINE__ \
<< " in " << __func__ << ": " << #a << " = " << a << std::endl;
#endif
#else
#define CHECK
#define VCHECK(a)
#endif
#define DEFAULT_MEMBERS(__class_name__) __class_name__() = default; \
__class_name__(const __class_name__& in) = default; \
__class_name__& operator=(const __class_name__& in) = default; \
__class_name__(__class_name__&& in) = default; \
__class_name__& operator=(__class_name__&& in) = default
#define DEFAULT_MEMBERS_X(__class_name__) __class_name__(const __class_name__& in) = default; \
__class_name__& operator=(const __class_name__& in) = default; \
__class_name__(__class_name__&& in) = default; \
__class_name__& operator=(__class_name__&& in) = default
#endif

16
src/include/cnorxz.cc.h Normal file
View file

@ -0,0 +1,16 @@
// -*- C++ -*-
/**
@file include/cnorxz.cc.h
@brief cnorxz main template header
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "base/base.cc.h"
#include "memory/memory.cc.h"
#include "ranges/ranges.cc.h"
#include "array/array.cc.h"
#include "operation/operation.cc.h"

23
src/include/cnorxz.h Normal file
View file

@ -0,0 +1,23 @@
// -*- C++ -*-
/**
@file include/cnorxz.h
@brief cnorxz main header
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_cnorxz_h__
#define __cxz_cnorxz_h__
#include "base/base.h"
#include "memory/memory.h"
#include "ranges/ranges.h"
#include "array/array.h"
#include "operation/operation.h"
#include "cnorxz.cc.h"
#endif

View file

@ -1,122 +0,0 @@
#ifndef __ma_conversions_h__
#define __ma_conversions_h__
#include "multi_array.h"
#include "slice.h"
namespace MultiArrayTools
{
namespace ConversionSizes
{
template <size_t N>
struct OrigSize
{
template <typename C, typename T>
struct FromTo
{
static void check() { static_assert( not N % (sizeof(T) / sizeof(C)), "conversion does not fit" ); }
static constexpr size_t SIZE = N * sizeof(T) / sizeof(C);
};
};
template <>
struct OrigSize<MUI>
{
template <typename C, typename T>
struct FromTo
{
static void check() {}
static constexpr size_t SIZE = MUI;
};
};
}
namespace
{
template <typename C, typename T, size_t N>
using SC = typename ConversionSizes::OrigSize<N>::template FromTo<C,T>;
template <typename C, typename T, class Range>
using SCR = SC<C,T,Range::SIZE>;
template <typename C, typename T, class Range>
using SCRR = GenSingleRange<typename Range::MetaType,SpaceType::NONE,SCR<C,T,Range>::SIZE>;
}
template <size_t N>
struct SubTuple
{
template <class RTP, class... Ranges>
static inline auto mk(const RTP& rtp, const Ranges&... rs)
-> decltype(SubTuple<N-1>::mk(rtp, std::get<N>(rtp), rs...))
{
return SubTuple<N-1>::mk(rtp, std::get<N>(rtp), rs...);
}
};
template <>
struct SubTuple<0>
{
template <class RTP, class... Ranges>
static inline auto mk(const RTP& rtp, const Ranges&... rs)
-> decltype(std::make_tuple(std::get<0>(rtp), rs...))
{
return std::make_tuple(std::get<0>(rtp), rs...);
}
};
template <class... Ranges>
using LastR = typename std::tuple_element<sizeof...(Ranges)-1,std::tuple<Ranges...>>::type;
template <typename C, typename T, class... Ranges>
auto rtcast(const std::tuple<std::shared_ptr<Ranges>...>& rtp)
-> decltype(std::tuple_cat(SubTuple<sizeof...(Ranges)-2>::mk(rtp),
std::make_tuple( std::dynamic_pointer_cast<SCRR<C,T,LastR<Ranges...>>>
( SCRR<C,T,LastR<Ranges...>>::factory().create() ) ) ))
{
return std::tuple_cat(SubTuple<sizeof...(Ranges)-2>::mk(rtp),
std::make_tuple( std::dynamic_pointer_cast<SCRR<C,T,LastR<Ranges...>>>
( SCRR<C,T,LastR<Ranges...>>::factory().create() ) ) );
}
template <typename T, class... Ranges>
inline Slice<T,Ranges...> rangeTpToSlice( const std::tuple<std::shared_ptr<Ranges>...>& rtp, T* data )
{
return Slice<T,Ranges...>(rtp, data);
}
template <typename T, class... Ranges>
inline ConstSlice<T,Ranges...> rangeTpToSlice( const std::tuple<std::shared_ptr<Ranges>...>& rtp, const T* data )
{
return ConstSlice<T,Ranges...>(rtp, data);
}
template <typename C, typename T, class... Ranges>
auto tcast(MultiArray<T,Ranges...>& ma)
-> decltype(rangeTpToSlice
( rtcast<C,T>( ma.range()->space() ),
reinterpret_cast<C*>( ma.data() ) ))
{
// VCHECK(reinterpret_cast<std::intptr_t>(ma.data()) % 32);
//VCHECK(reinterpret_cast<std::intptr_t>(reinterpret_cast<C*>(ma.data())) % 32);
return rangeTpToSlice
( rtcast<C,T>( ma.range()->space() ),
reinterpret_cast<C*>( ma.data() ) );
}
template <typename C, typename T, class... Ranges>
auto tcast(const MultiArray<T,Ranges...>& ma)
-> decltype(rangeTpToSlice
( rtcast<C,T>( ma.range()->space() ),
reinterpret_cast<const C*>( ma.data() ) ))
{
//VCHECK(reinterpret_cast<std::intptr_t>(ma.data()) % 32);
//VCHECK(reinterpret_cast<std::intptr_t>(reinterpret_cast<C*>(ma.data())) % 32);
return rangeTpToSlice
( rtcast<C,T>( ma.range()->space() ),
reinterpret_cast<const C*>( ma.data() ) );
}
}
#endif

View file

@ -1,198 +0,0 @@
#include "dynamic_operation.h"
#include "helper_tools.h"
namespace MultiArrayTools
{
template <typename T, class Operation>
T DynamicOperation<T,Operation>::get(const DExtT& pos) const
{
return mOp.get(pos.expl<ET>());
}
template <typename T, class Operation>
DynamicOperationBase<T>& DynamicOperation<T,Operation>::set(const DExtT& pos)
{
mOp.set(pos.expl<ET>());
return *this;
}
template <typename T, class Operation>
DExtT DynamicOperation<T,Operation>::rootSteps(std::intptr_t iPtrNum) const
{
return DExtT(mkDExt(mkExtT(mOp.rootSteps(iPtrNum))),None(0));
}
template <typename T, class Operation>
DynamicExpression DynamicOperation<T,Operation>::loop(const DynamicExpression& exp) const
{
return mOp.loop(exp);
}
template <typename T, class Operation>
const T* DynamicOperation<T,Operation>::data() const
{
return mOp.data();
}
template <typename T, class Operation>
std::shared_ptr<DynamicOperationBase<T>> DynamicOperation<T,Operation>::deepCopy() const
{
return std::make_shared<DynamicOperation<T,Operation>>(*this);
}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const DynamicOuterOp& in) :
mThreadId(omp_get_thread_num()), mOp(in.mOp),
mIndices(in.mIndices),
mMa((mThreadId != in.mThreadId) ? std::make_shared<MultiArray<T,Ranges...>>(*in.mMa) : in.mMa),
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
mL((mThreadId != in.mThreadId) ?
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
in.mL)
{*mMa = 0;}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(DynamicOuterOp&& in) :
mThreadId(omp_get_thread_num()), mOp(in.mOp),
mIndices(in.mIndices),
mMa((mThreadId != in.mThreadId) ? std::make_shared<MultiArray<T,Ranges...>>(*in.mMa) : in.mMa),
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
mL((mThreadId != in.mThreadId) ?
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
in.mL)
{*mMa = 0;}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>&
DynamicOuterOp<T,Operation,Ranges...>::operator=(const DynamicOuterOp& in)
{
mThreadId = omp_get_thread_num();
mOp = in.mOp;
mIndices = in.mIndices;
if(mThreadId != in.mThreadId){
mMa = std::make_shared<MultiArray<T,Ranges...>>(in.mMa);
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
}
else {
mMa = in.mMa;
mProto = in.mProto;
mL = in.mL;
}
*mMa = 0;
return *this;
}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>&
DynamicOuterOp<T,Operation,Ranges...>::operator=(DynamicOuterOp&& in)
{
mThreadId = omp_get_thread_num();
mOp = in.mOp;
mIndices = in.mIndices;
if(mThreadId != in.mThreadId){
mMa = std::make_shared<MultiArray<T,Ranges...>>(in.mMa);
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
}
else {
mMa = in.mMa;
mProto = in.mProto;
mL = in.mL;
}
*mMa = 0;
return *this;
}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const Operation& op,
const std::shared_ptr<typename Ranges::IndexType>&... inds)
: mThreadId(omp_get_thread_num()), mOp(op),
mIndices(inds...),
mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))),
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}))
{}
/*
DynamicOuterOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
const Operation& op, const std::shared_ptr<Indices>&... inds )
: mThreadId(omp_get_thread_num()),
//mDyn(dyn),
mOp(op), mIndices(inds...),
mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))),
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}))
{}
*/
template <typename T, class Operation, class... Ranges>
OpH<OperationRoot<T,Ranges...>> DynamicOuterOp<T,Operation,Ranges...>::get(const DExtT& pos) const
{
//if(mPrev) mPrev.get(pos.expl<ET>());
mL(0,pos.expl<ET>());
return mProto; // empty
}
template <typename T, class Operation, class... Ranges>
DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>&
DynamicOuterOp<T,Operation,Ranges...>::set(const DExtT& pos)
{
mOp.set(pos.expl<ET>());
return *this;
}
template <typename T, class Operation, class... Ranges>
DExtT DynamicOuterOp<T,Operation,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
{
return DExtT(mkDExt(mkExtT(mL.rootSteps(iPtrNum))),None(0));
}
template <typename T, class Operation, class... Ranges>
DynamicExpression DynamicOuterOp<T,Operation,Ranges...>::loop(const DynamicExpression& exp) const
{
return mOp.loop(exp); // ???!!
}
template <typename T, class Operation, class... Ranges>
const OpH<OperationRoot<T,Ranges...>>* DynamicOuterOp<T,Operation,Ranges...>::data() const
{
return &mProto;
}
/*
template <class Op1, class Op2>
template <class ET>
inline T TwoOp<Op1,Op2>::get(const ET& pos) const
{
return mOp2.get(pos);
}
*/
template <typename T, class Operation, class... Ranges>
std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>>
DynamicOuterOp<T,Operation,Ranges...>::deepCopy() const
{
return std::make_shared<DynamicOuterOp<T,Operation,Ranges...>>(*this);
}
} // namespace MultiArrayTools

View file

@ -1,202 +0,0 @@
#ifndef __dynamic_operation_h__
#define __dynamic_operation_h__
#include "base_def.h"
#include "multi_array_operation.h"
namespace MultiArrayTools
{
template <typename T>
class DynamicOperationBase : public OperationTemplate<T,DynamicOperationBase<T>>
{
public:
typedef T value_type;
typedef OperationBase<T,DynamicOperationBase<T>> OT;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
DynamicOperationBase() = default;
DynamicOperationBase(const DynamicOperationBase& in) = default;
DynamicOperationBase(DynamicOperationBase&& in) = default;
DynamicOperationBase& operator=(const DynamicOperationBase& in) = default;
DynamicOperationBase& operator=(DynamicOperationBase&& in) = default;
virtual T get(const DExtT& pos) const = 0;
virtual DynamicOperationBase& set(const DExtT& pos) = 0;
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const = 0;
virtual DynamicExpression loop(const DynamicExpression& exp) const = 0;
virtual const T* data() const = 0;
virtual std::shared_ptr<DynamicOperationBase<T>> deepCopy() const = 0;
};
template <typename T, class Operation>
class DynamicOperation : public DynamicOperationBase<T>
{
private:
Operation mOp;
public:
typedef decltype(mOp.rootSteps()) ET;
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
DynamicOperation() = default;
DynamicOperation(const DynamicOperation& in) = default;
DynamicOperation(DynamicOperation&& in) = default;
DynamicOperation& operator=(const DynamicOperation& in) = default;
DynamicOperation& operator=(DynamicOperation&& in) = default;
DynamicOperation(const Operation& op) : mOp(op) {}
virtual T get(const DExtT& pos) const override final;
virtual DynamicOperationBase<T>& set(const DExtT& pos) override final;
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const override final;
virtual DynamicExpression loop(const DynamicExpression& exp) const override final;
virtual const T* data() const override final;
virtual std::shared_ptr<DynamicOperationBase<T>> deepCopy() const override final;
};
template <class Op>
struct OpH
{
std::shared_ptr<Op> mOp;
OpH(const Op& op) : mOp(std::make_shared<Op>(op)) {}
// overload all operations here ...
};
template <typename T, class Operation, class... Ranges>
class DynamicOuterOp : public DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>
{
private:
size_t mThreadId;
//std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> mDyn;
Operation mOp;
//OperationRoot<T,Ranges...> mProto;
std::tuple<std::shared_ptr<typename Ranges::IndexType>...> mIndices;
std::shared_ptr<MultiArray<T,Ranges...>> mMa;
OpH<OperationRoot<T,Ranges...>> mProto;
typedef ILoop<std::tuple<OperationRoot<T,Ranges...>,Operation>,
std::tuple<std::shared_ptr<typename Ranges::IndexType>...>,
std::tuple<std::shared_ptr<MultiArray<T,Ranges...>>>,
std::tuple<decltype(mProto.mOp->assign( mOp, mkMIndex(std::shared_ptr<typename Ranges::IndexType>()...) ))>> LoopT;
mutable LoopT mL;
public:
typedef decltype(mL.rootSteps()) ET;
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
DynamicOuterOp() : mThreadId(omp_get_thread_num()) {}
DynamicOuterOp(const DynamicOuterOp& in);
DynamicOuterOp(DynamicOuterOp&& in);
DynamicOuterOp& operator=(const DynamicOuterOp& in);
DynamicOuterOp& operator=(DynamicOuterOp&& in);
DynamicOuterOp(const Operation& op, const std::shared_ptr<typename Ranges::IndexType>&... inds);
/*
DynamicOuterOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
const Operation& op, const std::shared_ptr<Indices>&... inds );
*/
virtual OpH<OperationRoot<T,Ranges...>> get(const DExtT& pos) const override final;
virtual DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>& set(const DExtT& pos) override final;
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const override final;
virtual DynamicExpression loop(const DynamicExpression& exp) const override final;
virtual const OpH<OperationRoot<T,Ranges...>>* data() const override final;
virtual std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> deepCopy() const override final;
};
template <typename T>
class DynamicO : public OperationTemplate<T,DynamicO<T>>
{
private:
// NOT THREAD SAFE!!!
std::shared_ptr<DynamicOperationBase<T>> mOp;
public:
typedef T value_type;
typedef OperationBase<T,DynamicO<T>> OT;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
DynamicO() = default;
DynamicO(const DynamicO& in) : mOp(in.mOp ? in.mOp->deepCopy() : nullptr) {}
DynamicO(DynamicO&& in) : mOp(in.mOp ? in.mOp->deepCopy() : nullptr) {}
DynamicO& operator=(const DynamicO& in)
{ mOp = in.mOp ? in.mOp->deepCopy() : nullptr; return *this; }
DynamicO& operator=(DynamicO&& in)
{ mOp = in.mOp ? in.mOp->deepCopy() : nullptr; return *this; }
bool init() const { return mOp != nullptr; }
template <class Op>
DynamicO(const Op& op) : mOp(std::make_shared<DynamicOperation<T,Op>>(op)) {}
DynamicO(const std::shared_ptr<DynamicOperationBase<T>>& op) :
mOp(op) {}
template <class X>
inline T get(const DExtTX<X>& pos) const { return mOp->get(pos.reduce()); }
template <class X>
inline DynamicO& set(const DExtTX<X>& pos) { mOp->set(pos.reduce()); return *this; }
inline DExtT rootSteps(std::intptr_t iPtrNum = 0) const { return mOp->rootSteps(iPtrNum); }
inline DynamicExpression loop(const DynamicExpression& exp) const { return mOp->loop(exp); }
inline const T* data() const { return mOp->data(); }
};
/*
template <class Op1>
class TwoOp : public OperationTemplate<typename Op2::value_type,TwoOp<Op1>>
{
private:
Op1 mOp1;
typename Op1::value_type mOp2; // mOp1.data()->mOp
public:
typedef typename Op2::value_type value_type;
typedef value_type T;
TwoOp(const Op1& op1);
template <class ET>
inline T get(const ET& pos) const;
};
*/
template <class Operation, class... Indices>
auto mkDynOutOp(const Operation& op, const std::shared_ptr<Indices>&... inds)
{
return DynamicO<OpH<OperationRoot<typename Operation::value_type,
typename Indices::RangeType...>>>
(DynamicOuterOp<typename Operation::value_type,Operation,
typename Indices::RangeType...>(op, inds...));
}
/*
template <class Operation, class... Indices>
auto mkDynOutOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
const Operation& op, const std::shared_ptr<Indices>&... inds)
{
return DynamicO<OpH<OperationRoot<typename Operation::value_type,
typename Indices::RangeType...>>>
(DynamicOuterOp<typename Operation::value_type,Operation,
typename Indices::RangeType...>(dyn, op, inds...));
}
*/
// Build plan
/*
template <class Operation>
class OperationBuilder
{
};
*/
} // namespace MultiArrayTools
#endif

View file

@ -1,30 +0,0 @@
#ifdef regFunc1
regFunc1(exp)
regFunc1(exp2)
regFunc1(expm1)
regFunc1(log)
regFunc1(log10)
regFunc1(log2)
regFunc1(log1p)
regFunc1(sqrt)
regFunc1(cbrt)
regFunc1(sin)
regFunc1(cos)
regFunc1(tan)
regFunc1(asin)
regFunc1(acos)
regFunc1(atan)
regFunc1(sinh)
regFunc1(cosh)
regFunc1(tanh)
regFunc1(asinh)
regFunc1(acosh)
regFunc1(atanh)
regFunc1(erf)
regFunc1(erfc)
regFunc1(tgamma)
regFunc1(lgamma)
#endif

View file

@ -1,109 +0,0 @@
#include "functional_multi_array.h"
namespace MultiArrayTools
{
/****************************
* FunctionalMultiArray *
****************************/
template <bool FISSTATIC>
struct Application
{
template <typename T, class Function, typename Meta>
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
{
return (*f)(m);
}
};
template <>
struct Application<true>
{
template <typename T, class Function, typename Meta>
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
{
return Function::apply(m);
}
};
template <typename T, class Function, class... SRanges>
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges,
const std::shared_ptr<Function>& func) :
MultiArrayBase<T,SRanges...>(ranges...), mFunc(func) {}
template <typename T, class Function, class... SRanges>
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges) :
MultiArrayBase<T,SRanges...>(ranges...) {}
template <typename T, class Function, class... SRanges>
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space) :
MultiArrayBase<T,SRanges...>(space) {}
template <typename T, class Function, class... SRanges>
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space,
const std::shared_ptr<Function>& func) :
MultiArrayBase<T,SRanges...>(space), mFunc(func) {}
template <typename T, class Function, class... SRanges>
const T& FunctionalMultiArray<T,Function,SRanges...>::operator[](const IndexType& i) const
{
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc, i.meta());
return mVal;
}
template <typename T, class Function, class... SRanges>
const T& FunctionalMultiArray<T,Function,SRanges...>::at(const typename CRange::IndexType::MetaType& meta) const
{
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc,meta);
return mVal;
}
template <typename T, class Function, class... SRanges>
const T* FunctionalMultiArray<T,Function,SRanges...>::data() const
{
return &mVal;
}
template <typename T, class Function, class... SRanges>
bool FunctionalMultiArray<T,Function,SRanges...>::isConst() const
{
return true;
}
template <typename T, class Function, class... SRanges>
bool FunctionalMultiArray<T,Function,SRanges...>::isSlice() const
{
return false;
}
template <typename T, class Function, class... SRanges>
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > FunctionalMultiArray<T,Function,SRanges...>::anonymous(bool slice) const
{
assert(0); // think about it carefully
return nullptr;
}
template <typename T, class Function, class... SRanges>
ConstOperationRoot<T,SRanges...> FunctionalMultiArray<T,Function,SRanges...>::
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
{
if(not mMaPtr){
mMaPtr = std::make_shared<MAType>( MAB::mRange->space() );
(*mMaPtr)(inds...) = exec(inds...);
}
return ConstOperationRoot<T,SRanges...>( *mMaPtr, inds... );
}
template <typename T, class Function, class... SRanges>
auto FunctionalMultiArray<T,Function,SRanges...>::
exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
-> Operation<T,Function,MetaOperationRoot<SRanges>...>
{
return mkOperation( mFunc, MetaOperationRoot<SRanges>( inds ) ... );
}
} // namespace MultiArrayTools

View file

@ -1,127 +0,0 @@
#ifndef __functional_multi_array__
#define __functional_multi_array__
#include "multi_array_base.h"
#include "slice.h"
namespace MultiArrayTools
{
template <bool HASMETACONT>
struct ToMAObject
{
template <class Index>
static auto mk(const std::shared_ptr<Index>& i)
-> MultiArray<typename Index::MetaType, typename Index::RangeType>
{
assert(0); // deprecated
vector<typename Index::MetaType> vv(i->range()->size());
for(Index j = (*i); j.pos() != j.max(); ++j){
vv[j.pos()] = j.meta();
}
return MultiArray<typename Index::MetaType, typename Index::RangeType>( i->range(), vv );
}
};
template <>
struct ToMAObject<true>
{
template <class Index>
static auto mk(const std::shared_ptr<Index>& i)
-> ConstSlice<typename Index::MetaType, typename Index::RangeType>
{
return ConstSlice<typename Index::MetaType, typename Index::RangeType>( i->range(), i->metaPtr() );
}
};
template <class Index>
auto mkMAObject(const std::shared_ptr<Index>& i)
-> std::shared_ptr<decltype(ToMAObject<Index::RangeType::HASMETACONT>::mk(i))>
{
return std::make_shared<decltype(ToMAObject<Index::RangeType::HASMETACONT>::mk(i))>
(ToMAObject<Index::RangeType::HASMETACONT>::mk(i));
}
template <bool HASMETACONT>
struct ToOpObject
{
template <class Index>
static auto mk(const std::shared_ptr<Index>& ind)
-> ConstOperationRoot<typename Index::MetaType,
typename Index::RangeType>
{
return ConstOperationRoot<typename Index::MetaType,
typename Index::RangeType>( mkMAObject(ind), ind);
}
};
template <>
struct ToOpObject<false>
{
template <class Index>
static auto mk(const std::shared_ptr<Index>& ind)
-> MetaOperationRoot<typename Index::RangeType>
{
return MetaOperationRoot<typename Index::RangeType>( ind );
}
};
template <class Index>
auto mkOpObject(const std::shared_ptr<Index>& i)
-> decltype(ToOpObject<Index::RangeType::HASMETACONT>::mk(i))
{
return ToOpObject<Index::RangeType::HASMETACONT>::mk(i);
}
template <typename T, class Function, class... SRanges>
class FunctionalMultiArray : public MultiArrayBase<T,SRanges...>
{
public:
typedef ContainerRange<T,SRanges...> CRange;
typedef MultiArrayBase<T,SRanges...> MAB;
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
typedef MultiArray<T,SRanges...> MAType;
typedef T value_type;
private:
mutable T mVal;
std::shared_ptr<Function> mFunc;
mutable std::shared_ptr<MAType> mMaPtr;
public:
DEFAULT_MEMBERS(FunctionalMultiArray);
FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges, const std::shared_ptr<Function>& func);
FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges);
FunctionalMultiArray(const typename CRange::Space& space);
FunctionalMultiArray(const typename CRange::Space& space, const std::shared_ptr<Function>& func);
virtual const T& operator[](const IndexType& i) const override;
virtual const T& at(const typename CRange::IndexType::MetaType& meta) const override;
virtual const T* data() const override;
virtual bool isConst() const override;
virtual bool isSlice() const override;
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const override;
auto exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
-> Operation<T,Function,MetaOperationRoot<SRanges>...>;
virtual ConstOperationRoot<T,SRanges...>
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const override;
};
} // namespace MultiArrayTools
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
#endif

View file

@ -1,398 +0,0 @@
#include "helper_tools.h"
namespace MultiArrayTools
{
template <typename... T>
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp)
{
PackNum<sizeof...(T)-1>::printTuple(out, tp);
return out;
}
template <class RangeType>
auto getIndex(std::shared_ptr<RangeType> range)
-> std::shared_ptr<typename RangeType::IndexType>
{
return std::make_shared<typename RangeType::IndexType>(range);
}
template <class RangeType>
auto getIndex()
-> std::shared_ptr<typename RangeType::IndexType>
{
static_assert( RangeType::defaultable,
/*typeid(typename RangeType).name() + */" is not defaultable" );
static auto f = RangeType::factory();
static auto r = std::dynamic_pointer_cast<RangeType>( f.create() );
return std::make_shared<typename RangeType::IndexType>(r);
}
template <class... RangeTypes>
auto mkMulti(std::shared_ptr<RangeTypes>... ranges)
-> std::shared_ptr<MultiRange<RangeTypes...> >
{
MultiRangeFactory<RangeTypes...> mrf( ranges... );
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
}
namespace
{
template <size_t N>
struct IndexToRangeTuple
{
template <class... IndexTypes>
static inline void set(std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>& out,
const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
{
std::get<N>(out) = std::get<N>(indices)->range();
IndexToRangeTuple<N-1>::set(out,indices);
}
};
template <>
struct IndexToRangeTuple<0>
{
template <class... IndexTypes>
static inline void set(std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>& out,
const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
{
std::get<0>(out) = std::get<0>(indices)->range();
}
};
}
template <class... IndexTypes>
auto indexToRangeTuple(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
-> std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>
{
std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...> out;
IndexToRangeTuple<sizeof...(IndexTypes)-1>::set(out, indices);
return out;
}
template <class... IndexTypes>
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
-> decltype( getIndex( mkMulti( indices->range()... ) ) )
{
auto mi = getIndex( mkMulti( indices->range()... ) );
(*mi)( indices... );
return mi;
}
template <class... IndexTypes>
auto mkMIndex(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
-> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) )
{
auto mi = getIndex( mkMulti( indexToRangeTuple(indices) ) );
(*mi)( indices );
return mi;
}
template <class Index>
auto mkIndexW(const std::shared_ptr<Index>& ind)
-> std::shared_ptr<IndexW>
{
return std::make_shared<IndexWrapper<Index>>(ind);
}
template <SpaceType STYPE, class Op, class MA, class... RangeTypes>
auto mkGenMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
-> std::shared_ptr<GenMapRange<MapORType<Op,STYPE>,Op,STYPE,RangeTypes...> >
{
GenMapRangeFactory<MapORType<Op,STYPE>,Op,STYPE,RangeTypes...> mrf(f, ranges... );
return createExplicit( mrf );
}
template <SpaceType STYPE, class ORType, class Op, class MA, class... RangeTypes>
auto mkGenMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f,
std::shared_ptr<RangeTypes>... ranges)
-> std::shared_ptr<GenMapRange<ORType,Op,STYPE,RangeTypes...> >
{
GenMapRangeFactory<ORType,Op,STYPE,RangeTypes...> mrf(outr, f, ranges... );
return createExplicit( mrf );
}
template <SpaceType STYPE, class Op, class MA, class... IndexTypes>
auto mkGenMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
-> decltype( getIndex( mkGenMapR<STYPE>( f, indices->range()... ) ) )
{
auto mi = getIndex( mkGenMapR<STYPE>( f, indices->range()... ) );
(*mi)(indices...);
return mi;
}
template <class Op, class MA, class... RangeTypes>
auto mkMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
-> decltype( mkGenMapR<SpaceType::ANY>(f, ranges... ) )
{
return mkGenMapR<SpaceType::ANY>(f, ranges... );
}
template <class ORType, class Op, class MA, class... RangeTypes>
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f,
std::shared_ptr<RangeTypes>... ranges)
-> decltype( mkGenMapRwith<SpaceType::ANY>(outr, f, ranges... ) )
{
return mkGenMapRwith<SpaceType::ANY>(outr, f, ranges... );
}
template <class Func, class... Indices>
auto mkMapR(const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
-> decltype( mkMapR( mkMapOp( func, is... ), is->range()... ) )
{
return mkMapR( mkMapOp( func, is... ), is->range()... );
}
template <class ORType, class Func, class... Indices>
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
-> decltype( mkMapRwith(outr, mkMapOp( func, is... ), is->range()... ) )
{
return mkMapRwith(outr, mkMapOp( func, is... ), is->range()... );
}
template <class Op, class MA, class... IndexTypes>
auto mkMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
-> decltype( mkGenMapI<SpaceType::ANY>(f, indices... ) )
{
return mkGenMapI<SpaceType::ANY>(f, indices... );
}
template <class... RangeTypes>
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
-> std::shared_ptr<MultiRange<RangeTypes...>>
{
MultiRangeFactory<RangeTypes...> mrf( rangesTuple );
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
}
template <class RangeFactory>
auto createExplicit(RangeFactory& rf)
-> std::shared_ptr<typename RangeFactory::oType>
{
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rf.create() );
}
template <class RangeFactory>
auto createExplicit(std::shared_ptr<RangeFactory> rfp)
-> std::shared_ptr<typename RangeFactory::oType>
{
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rfp->create() );
}
template <class Range>
auto createRange(const vector<char>& cvec)
-> std::shared_ptr<Range>
{
const char* dp = cvec.data();
auto ff = createRangeFactory(&dp);
auto rbptr = ff->create();
assert(rbptr->spaceType() == Range::STYPE);
// CATCH CAST ERROR HERE !!!
return std::dynamic_pointer_cast<Range>( rbptr );
}
inline auto createRange(const vector<char>* cvec, int metaType, size_t size)
-> std::shared_ptr<RangeBase>
{
auto f = createSingleRangeFactory(cvec, metaType, size);
return f->create();
}
inline auto createRangeA(const vector<char>* cvec, int metaType, size_t size)
-> std::shared_ptr<AnonymousRange>
{
AnonymousRangeFactory arf(createRange(cvec, metaType, size));
return createExplicit(arf);
}
inline auto cvecMetaCast(const std::shared_ptr<SingleRange<vector<char>,SpaceType::ANY>>& r, int metaType)
-> std::shared_ptr<RangeBase>
{
return createRange(&r->get(0), metaType, r->size());
}
inline auto cvecMetaCastA(const std::shared_ptr<SingleRange<vector<char>,SpaceType::ANY>>& r, int metaType)
-> std::shared_ptr<AnonymousRange>
{
return createRangeA(&r->get(0), metaType, r->size());
}
template <class Range, typename... Args>
auto createRangeE(Args&&... args)
-> std::shared_ptr<Range>
{
typename Range::FType f(args...);
return createExplicit(f);
}
template <size_t N, class MArray>
auto rptr(const MArray& ma)
-> decltype(ma.template getRangePtr<N>())
{
return ma.template getRangePtr<N>();
}
template <class MArray>
auto dynamic(const MArray& ma, bool slice)
-> std::shared_ptr<MultiArrayBase<typename MArray::value_type,DynamicRange>>
{
DynamicRangeFactory drf(ma.range()->space());
if(slice){
return std::make_shared<ConstSlice<typename MArray::value_type,DynamicRange>>
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
ma.data() );
}
else {
return std::make_shared<MultiArray<typename MArray::value_type,DynamicRange>>
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
ma.vdata() );
}
}
template <class MArray>
auto mdynamic(MArray& ma, bool slice)
-> std::shared_ptr<MutableMultiArrayBase<typename MArray::value_type,DynamicRange>>
{
DynamicRangeFactory drf(ma.range()->space());
if(slice){
return std::make_shared<Slice<typename MArray::value_type,DynamicRange>>
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
ma.data() );
}
else {
return std::make_shared<MultiArray<typename MArray::value_type,DynamicRange>>
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
ma.vdata() );
}
}
namespace
{
template <size_t N>
struct CopyRanges
{
template <class Space1, class Space2>
static inline void exec(const Space1& space1, Space2& space2)
{
std::get<N>(space2) = std::get<N>(space1);
CopyRanges<N-1>::exec(space1,space2);
}
};
template <>
struct CopyRanges<0>
{
template <class Space1, class Space2>
static inline void exec(const Space1& space1, Space2& space2)
{
std::get<0>(space2) = std::get<0>(space1);
}
};
}
template <typename T, class Range1, class... RangeTypes>
auto anonToDynView(const MultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
-> ConstSlice<T,Range1,RangeTypes...,DynamicRange>
{
constexpr size_t LAST = sizeof...(RangeTypes)+1;
DynamicRangeFactory drf(rptr<LAST>(ma)->orig());
std::tuple<std::shared_ptr<Range1>,std::shared_ptr<RangeTypes>...,
std::shared_ptr<DynamicRange>> mNSpace;
CopyRanges<LAST-1>::exec(ma.range()->space(),mNSpace);
std::get<LAST>(mNSpace) = createExplicit( drf );
return ConstSlice<T,Range1,RangeTypes...,DynamicRange>(mNSpace, ma.data());
}
template <typename T, class Range1, class... RangeTypes>
auto anonToDynView(MutableMultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
-> Slice<T,Range1,RangeTypes...,DynamicRange>
{
constexpr size_t LAST = sizeof...(RangeTypes)+1;
DynamicRangeFactory drf(rptr<LAST>(ma)->orig());
std::tuple<std::shared_ptr<Range1>,std::shared_ptr<RangeTypes>...,
std::shared_ptr<DynamicRange>> mNSpace;
CopyRanges<LAST-1>::exec(ma.range()->space(),mNSpace);
std::get<LAST>(mNSpace) = createExplicit( drf );
return Slice<T,Range1,RangeTypes...,DynamicRange>(mNSpace, ma.data());
}
template <typename T, class Range1, class... RangeTypes>
auto dynToAnonMove(MultiArray<T,Range1,RangeTypes...,DynamicRange>&& ma)
-> MultiArray<T,Range1,RangeTypes...,AnonymousRange>
{
constexpr size_t LAST = sizeof...(RangeTypes)+1;
AnonymousRangeFactory arf(rptr<LAST>(ma)->orig());
std::tuple<std::shared_ptr<Range1>,std::shared_ptr<RangeTypes>...,
std::shared_ptr<AnonymousRange>> mNSpace;
CopyRanges<LAST-1>::exec(ma.range()->space(),mNSpace);
std::get<LAST>(mNSpace) = createExplicit( arf );
return ma.format(mNSpace);
}
template <typename T>
auto anonToDynView(const MultiArrayBase<T,AnonymousRange>& ma)
-> ConstSlice<T,DynamicRange>
{
DynamicRangeFactory drf(rptr<0>(ma)->orig());
auto mNSpace = std::make_tuple( createExplicit( drf ) );
return ConstSlice<T,DynamicRange>(mNSpace, ma.data());
}
template <typename T>
auto anonToDynView(MutableMultiArrayBase<T,AnonymousRange>& ma)
-> Slice<T,DynamicRange>
{
DynamicRangeFactory drf(rptr<0>(ma)->orig());
auto mNSpace = std::make_tuple( createExplicit( drf ) );
return Slice<T,DynamicRange>(mNSpace, ma.data());
}
template <typename T>
auto dynToAnonMove(MultiArray<T,DynamicRange>&& ma)
-> MultiArray<T,AnonymousRange>
{
AnonymousRangeFactory arf(rptr<0>(ma)->orig());
auto mNSpace = std::make_tuple( createExplicit( arf ) );
return ma.format(mNSpace);
}
template <class Range>
auto metaSlice(const std::shared_ptr<Range>& r)
-> ConstSlice<typename Range::MetaType,ClassicRange>
{
ClassicRF crf(r->size());
return ConstSlice<typename Range::MetaType,ClassicRange>( createExplicit(crf), &r->get(0) );
}
template <class Range, class ORange>
auto metaSlice(const std::shared_ptr<Range>& r, const std::shared_ptr<ORange>& ro)
-> ConstSlice<typename Range::MetaType,ORange>
{
return ConstSlice<typename Range::MetaType,ORange>( ro, &r->get(0) );
}
template <typename T, class... Ranges>
auto mkArray(const std::shared_ptr<Ranges>&... rs)
-> MultiArray<T,Ranges...>
{
return MultiArray<T,Ranges...>(rs...);
}
template <typename T, class... Ranges>
auto mkArray(const std::shared_ptr<Ranges>&... rs, const T& val)
-> MultiArray<T,Ranges...>
{
return MultiArray<T,Ranges...>(rs..., val);
}
template <typename T, class... Ranges>
auto mkArrayPtr(const std::shared_ptr<Ranges>&... rs)
-> std::shared_ptr<MultiArray<T,Ranges...>>
{
return std::make_shared<MultiArray<T,Ranges...>>(rs...);
}
}

View file

@ -1,239 +0,0 @@
#ifndef __helper_tools_h__
#define __helper_tools_h__
#include "base_def.h"
#include "slice.h"
#include <ostream>
#include "pack_num.h"
#include "map_range.h"
#include <functional>
#include "xfor/iloop.h"
namespace MultiArrayTools
{
template <typename... T>
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp);
template <class RangeType>
auto getIndex(std::shared_ptr<RangeType> range)
-> std::shared_ptr<typename RangeType::IndexType>;
// only if 'RangeType' is defaultable and unique (Singleton)
template <class RangeType>
auto getIndex() -> std::shared_ptr<typename RangeType::IndexType>;
template <class... RangeTypes>
auto mkMulti(std::shared_ptr<RangeTypes>... ranges)
-> std::shared_ptr<MultiRange<RangeTypes...> >;
template <class Op, SpaceType XSTYPE>
using MapORType = SingleRange<typename Op::value_type,XSTYPE>;
template <SpaceType STYPE, class Op, class MA, class... RangeTypes>
auto mkGenMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
-> std::shared_ptr<GenMapRange<MapORType<Op,STYPE>,Op,STYPE,RangeTypes...> >;
template <SpaceType STYPE, class ORType, class Op, class MA, class... RangeTypes>
auto mkGenMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f,
std::shared_ptr<RangeTypes>... ranges)
-> std::shared_ptr<GenMapRange<ORType,Op,STYPE,RangeTypes...> >;
template <SpaceType STYPE, class Op, class MA, class... IndexTypes>
auto mkGenMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
-> decltype( getIndex( mkGenMapR<STYPE>( f, indices->range()... ) ) );
template <class Op, class MA, class... RangeTypes>
auto mkMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
-> decltype( mkGenMapR<SpaceType::ANY>(f, ranges... ) );
template <class ORType, class Op, class MA, class... RangeTypes>
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
-> decltype( mkGenMapRwith<SpaceType::ANY>(outr, f, ranges... ) );
template <class Func, class... Indices>
auto mkMapR(const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
-> decltype( mkMapR( mkMapOp( func, is... ), is->range()... ) );
template <class ORType, class Func, class... Indices>
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
-> decltype( mkMapRwith(outr, mkMapOp( func, is... ), is->range()... ) );
template <class Op, class MA, class... IndexTypes>
auto mkMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
-> decltype( mkGenMapI<SpaceType::ANY>(f, indices... ) );
template <class... IndexTypes>
auto indexToRangeTuple(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
-> std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>;
template <class... RangeTypes>
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
-> std::shared_ptr<MultiRange<RangeTypes...>>;
template <class... IndexTypes>
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
-> decltype( getIndex( mkMulti( indices.range()... ) ) );
template <class... IndexTypes>
auto mkMIndex(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
-> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) );
template <class Index>
auto mkIndexW(const std::shared_ptr<Index>& ind)
-> std::shared_ptr<IndexW>;
template <class RangeFactory>
auto createExplicit(RangeFactory& rf)
-> std::shared_ptr<typename RangeFactory::oType>;
template <class RangeFactory>
auto createExplicit(std::shared_ptr<RangeFactory> rfp)
-> std::shared_ptr<typename RangeFactory::oType>;
template <class Range>
auto createRange(const vector<char>& cvec)
-> std::shared_ptr<Range>;
inline auto createRange(const vector<char>* cvec, int metaType, size_t size)
-> std::shared_ptr<RangeBase>;
inline auto createRangeA(const vector<char>* cvec, int metaType, size_t size)
-> std::shared_ptr<AnonymousRange>;
template <class Range, typename... Args>
auto createRangeE(Args&&... args)
-> std::shared_ptr<Range>;
template <size_t N, class MArray>
auto rptr(const MArray& ma)
-> decltype(ma.template getRangePtr<N>());
template <size_t I, class MIndex>
auto get(const std::shared_ptr<MIndex>& i)
-> decltype(i->template getPtr<I>())
{
return i->template getPtr<I>();
}
template <class MArray>
auto dynamic(const MArray& ma, bool slice = false)
-> std::shared_ptr<MultiArrayBase<typename MArray::value_type,DynamicRange>>;
template <class MArray>
auto mdynamic(MArray& ma, bool slice)
-> std::shared_ptr<MutableMultiArrayBase<typename MArray::value_type,DynamicRange>>;
template <typename T, class Range1, class... RangeTypes>
auto anonToDynView(const MultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
-> ConstSlice<T,Range1,RangeTypes...,DynamicRange>;
template <typename T, class Range1, class... RangeTypes>
auto anonToDynView(MutableMultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
-> Slice<T,Range1,RangeTypes...,DynamicRange>;
template <typename T, class Range1, class... RangeTypes>
auto dynToAnonMove(MultiArray<T,Range1,RangeTypes...,DynamicRange>&& ma)
-> MultiArray<T,Range1,RangeTypes...,AnonymousRange>;
template <typename T>
auto anonToDynView(const MultiArrayBase<T,AnonymousRange>& ma)
-> ConstSlice<T,DynamicRange>;
template <typename T>
auto anonToDynView(MutableMultiArrayBase<T,AnonymousRange>& ma)
-> Slice<T,DynamicRange>;
template <typename T>
auto dynToAnonMove(MultiArray<T,DynamicRange>&& ma)
-> MultiArray<T,AnonymousRange>;
template <class Range>
auto metaSlice(const std::shared_ptr<Range>& r)
-> ConstSlice<typename Range::MetaType,ClassicRange>;
template <class Range, class ORange>
auto metaSlice(const std::shared_ptr<Range>& r, const std::shared_ptr<ORange>& ro)
-> ConstSlice<typename Range::MetaType,ORange>;
template <typename T, class... Ranges>
auto mkArray(const std::shared_ptr<Ranges>&... rs)
-> MultiArray<T,Ranges...>;
template <typename T, class... Ranges>
auto mkArrayPtr(const std::shared_ptr<Ranges>&... rs)
-> std::shared_ptr<MultiArray<T,Ranges...>>;
template <typename T, class... Ranges>
auto mkArray(const std::shared_ptr<Ranges>&... rs, const T& val)
-> MultiArray<T,Ranges...>;
template <class OpTp, class IndTp, class VarTp, class LTp>
auto mkILoop(const OpTp& opTp, const IndTp& indTp, const VarTp& varTp, const LTp& lTp,
const std::array<size_t,std::tuple_size<LTp>::value>& umpos,
const std::array<size_t,std::tuple_size<VarTp>::value>& setzero)
-> MultiArrayHelper::ILoop<OpTp,IndTp,VarTp,LTp>
{
return MultiArrayHelper::ILoop<OpTp,IndTp,VarTp,LTp>(opTp, indTp, varTp, lTp, umpos, setzero);
}
template <class CF>
auto mkPILoop(const CF& cf)
-> MultiArrayHelper::PILoop<CF>
{
return MultiArrayHelper::PILoop<CF>(cf);
}
template <class IndexType>
inline void For(const std::shared_ptr<IndexType>& ind, const std::function<void(void)>& ll)
{
for((*ind) = 0; ind->pos() != ind->max(); ++(*ind)){
ll();
}
}
// parallel:
template <class IndexType>
inline void PFor(const std::shared_ptr<IndexType>& ind,
const std::function<void(const std::shared_ptr<IndexType>&)>& ll)
{
const int max = static_cast<int>(ind->max());
int i = 0;
#pragma omp parallel shared(ind,ll) private(i)
{
#pragma omp for nowait
for(i = 0; i < max; i++) {
auto ii = getIndex( ind->range() );
((*ii) = i)();
ll(ii);
}
}
}
template <class Index>
inline auto mkOp(const std::shared_ptr<Index>& i)
-> decltype(std::declval<FunctionalMultiArray<typename Index::MetaType,
identity<typename Index::MetaType>,typename Index::RangeType> >
().exec(i))
{
FunctionalMultiArray<typename Index::MetaType,
identity<typename Index::MetaType>,
typename Index::RangeType> fma(i->range());
return fma.exec(i);
}
template <typename R, typename... Ts>
struct Func
{
static inline std::shared_ptr<function<R,Ts...>> mk(const std::function<R(Ts...)>& ll)
{
return std::make_shared<function<R,Ts...>>(ll);
}
};
}
#endif

View file

@ -1,476 +0,0 @@
#include "high_level_operation.h"
namespace MultiArrayTools
{
template <typename T, class Op>
DynamicO<T> mkDynOp1(const Op& op)
{
return DynamicO<T>(op);
}
template <class ROP>
template <class... Indices>
template <class Op, class... Ops>
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuterM(const Op& op, const Ops&... ops)
{
// does not check anything regarding input !!!
if(outer.init()){
outer = mkDynOp1<size_t>(mkMOp<size_t>(outer,op,ops...));
}
else {
outer = mkDynOp1<size_t>(mkMOp<size_t>(op,ops...));
}
}
template <class ROP>
template <class... Indices>
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuterM()
{}
template <class ROP>
template <class... Indices>
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuter(const DynamicO<size_t>& in)
{
if(in.init()){
if(outer.init()){
outer = mkDynOp1<size_t>(mkMOp<size_t>(outer,in));
}
else {
outer = in;
}
}
}
template <class ROP>
template <class... Indices>
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuter(const RetT& in)
{
appendOuter(in.outer);
}
template <class ROP>
HighLevelOpRoot<ROP>::HighLevelOpRoot(const ROP& op) : mOp(op) {}
template <class ROP>
bool HighLevelOpRoot<ROP>::root() const
{
return true;
}
template <class ROP>
template <class... Inds>
auto HighLevelOpRoot<ROP>::xcreate(const std::shared_ptr<Inds>&... inds)
-> typename B::template RetT<Inds...>
{
assert(0);
return typename B::template RetT<Inds...>();
}
template <class ROP>
ROP* HighLevelOpRoot<ROP>::get()
{
return &mOp;
}
template <class ROP>
auto HighLevelOpRoot<ROP>::vget()
-> VOP*
{
return nullptr;
}
template <class ROP>
HighLevelOpValue<ROP>::HighLevelOpValue(const VOP& op) : mOp(op) {}
template <class ROP>
bool HighLevelOpValue<ROP>::root() const
{
return true;
}
template <class ROP>
template <class... Inds>
auto HighLevelOpValue<ROP>::xcreate(const std::shared_ptr<Inds>&... inds)
-> typename B::template RetT<Inds...>
{
assert(0);
return typename B::template RetT<Inds...>();
}
template <class ROP>
ROP* HighLevelOpValue<ROP>::get()
{
return nullptr;
}
template <class ROP>
auto HighLevelOpValue<ROP>::vget()
-> VOP*
{
return &mOp;
}
namespace
{
template <size_t N>
struct Create
{
template <class... Indices>
struct cx
{
template <class ROP, class OpF, class... OPs>
struct ccx
{
template <size_t M, class... DOPs>
static inline void
cccx(typename HighLevelOpBase<ROP>::template RetT<Indices...>& res,
const std::array<std::shared_ptr<HighLevelOpBase<ROP>>,M>& in,
const std::shared_ptr<Indices>&... inds,
const OPs&... ops,
const DOPs&... dops)
{
static_assert(N > 0, "N > 0 failed");
auto& inn = std::get<N>(in);
if(not inn->root()){
auto dop = inn->create(inds...);
auto op = *dop.op.data()->mOp;
typedef decltype(op) OP;
res.appendOuter(dop);
assert(dop.op.init());
Create<N-1>::template cx<Indices...>::template ccx<ROP,OpF,OP,OPs...>::template cccx<M>
(res, in, inds..., op, ops..., dop, dops...);
}
else {
auto op = inn->get();
auto vop = inn->vget();
typedef typename std::remove_reference<decltype(*op)>::type OP;
typedef typename std::remove_reference<decltype(*vop)>::type VOP;
if(op != nullptr){
Create<N-1>::template cx<Indices...>::template ccx<ROP,OpF,OP,OPs...>::template cccx<M>
(res, in, inds..., *op, ops..., dops...);
}
else {
Create<N-1>::template cx<Indices...>::template ccx<ROP,OpF,VOP,OPs...>::template cccx<M>
(res, in, inds..., *vop, ops..., dops...);
}
}
}
};
};
};
template <>
struct Create<0>
{
template <class... Indices>
struct cx
{
template <class ROP, class OpF, class... OPs>
struct ccx
{
template <size_t M, class... DOPs>
static inline void
cccx(typename HighLevelOpBase<ROP>::template RetT<Indices...>& res,
const std::array<std::shared_ptr<HighLevelOpBase<ROP>>,M>& in,
const std::shared_ptr<Indices>&... inds,
const OPs&... ops,
const DOPs&... dops)
{
auto& inn = std::get<0>(in);
if(not inn->root()){
auto dop = inn->create(inds...);
auto op = *dop.op.data()->mOp;
res.appendOuter(dop);
res.op = mkDynOutOp(mkFOp<OpF>(op,ops...), inds...);
assert(dop.op.init());
res.appendOuterM(dop.op,dops.op...);
}
else {
auto op = inn->get();
auto vop = inn->vget();
if(op != nullptr){
res.op = mkDynOutOp(mkFOp<OpF>(*op,ops...), inds...);
}
else {
res.op = mkDynOutOp(mkFOp<OpF>(*vop,ops...), inds...);
}
res.appendOuterM(dops.op...);
}
}
};
};
};
}
template <class ROP, class OpF, size_t N>
HighLevelOp<ROP,OpF,N>::HighLevelOp(std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N> in) : mIn(in) {}
template <class ROP, class OpF, size_t N>
bool HighLevelOp<ROP,OpF,N>::root() const
{
return false;
}
template <class ROP, class OpF, size_t N>
ROP* HighLevelOp<ROP,OpF,N>::get()
{
assert(0);
return nullptr;
}
template <class ROP, class OpF, size_t N>
auto HighLevelOp<ROP,OpF,N>::vget()
-> VOP*
{
assert(0);
return nullptr;
}
template <class ROP, class OpF, size_t N>
template <class... Inds>
auto HighLevelOp<ROP,OpF,N>::xcreate(const std::shared_ptr<Inds>&... inds)
-> typename B::template RetT<Inds...>
{
typename B::template RetT<Inds...> res;
Create<N-1>::template cx<Inds...>::template ccx<ROP,OpF>::template cccx<N>
(res,mIn,inds...);
return res;
}
template <class ROP>
HighLevelOpHolder<ROP>::HighLevelOpHolder(const std::shared_ptr<HighLevelOpBase<ROP>>& op) : mOp(op) {}
template <class ROP>
bool HighLevelOpHolder<ROP>::root() const
{
return mOp->root();
}
template <class ROP>
template <class... Inds>
auto HighLevelOpHolder<ROP>::create(const std::shared_ptr<Inds>&... inds) const
-> decltype(mOp->create(inds...))
{
return mOp->create(inds...);
}
template <class ROP>
auto HighLevelOpHolder<ROP>::get()
-> decltype(mOp->get())
{
return mOp->get();
}
template <class ROP>
std::shared_ptr<HighLevelOpBase<ROP>> HighLevelOpHolder<ROP>::op() const
{
return mOp;
}
template <class ROP>
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator*(const HighLevelOpHolder& in) const
{
return HighLevelOpHolder<ROP>
( std::make_shared<HighLevelOp<ROP,multipliesx<double,double>,2>>
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
}
template <class ROP>
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator+(const HighLevelOpHolder& in) const
{
return HighLevelOpHolder<ROP>
( std::make_shared<HighLevelOp<ROP,plusx<double,double>,2>>
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
}
template <class ROP>
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator-(const HighLevelOpHolder& in) const
{
return HighLevelOpHolder<ROP>
( std::make_shared<HighLevelOp<ROP,minusx<double,double>,2>>
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
}
template <class ROP>
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator/(const HighLevelOpHolder& in) const
{
return HighLevelOpHolder<ROP>
( std::make_shared<HighLevelOp<ROP,dividesx<double,double>,2>>
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
}
template <class F, class ROP, class... ROPs>
HighLevelOpHolder<ROP> mkSFunc(const HighLevelOpHolder<ROP>& a, const HighLevelOpHolder<ROPs>&... as)
{
constexpr size_t N = sizeof...(ROPs)+1;
return HighLevelOpHolder<ROP>
( std::make_shared<HighLevelOp<ROP,F,N>>
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N>({a.op(), as.op()...}) ) );
}
template <class ROP>
template <class... Indices>
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::xassign(const HighLevelOpHolder& in,
const std::shared_ptr<DynamicIndex>& di,
const std::shared_ptr<Indices>&... is)
{
const size_t dim = di->dim();
if(dim > 2){
auto ci1 = di->getP(dim-2)->reduced();
auto ci2 = di->getP(dim-1)->reduced();
assert(ci1 != nullptr);
assert(ci2 != nullptr);
auto odi = mkSubSpaceX(di, dim-2);
auto mi = mkMIndex(is..., odi);
this->assign(in, mi, ci1, ci2);
}
else {
assert(dim == 2 or dim == 1);
auto ci1 = di->getP(dim-1)->reduced();
assert(ci1 != nullptr);
auto odi = mkSubSpaceX(di, dim-1);
auto mi = mkMIndex(is..., odi);
this->assign(in, mi, ci1);
}
return *this;
}
template <class ROP>
template <class... Indices>
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::xplus(const HighLevelOpHolder& in,
const std::shared_ptr<DynamicIndex>& di,
const std::shared_ptr<Indices>&... is)
{
const size_t dim = di->dim();
if(dim > 2){
auto ci1 = di->getP(dim-2)->reduced();
auto ci2 = di->getP(dim-1)->reduced();
assert(ci1 != nullptr);
assert(ci2 != nullptr);
auto odi = mkSubSpaceX(di, dim-2);
auto mi = mkMIndex(is..., odi);
this->plus(in, mi, ci1, ci2);
}
else {
assert(dim == 2 or dim == 1);
auto ci1 = di->getP(dim-1)->reduced();
assert(ci1 != nullptr);
auto odi = mkSubSpaceX(di, dim-1);
auto mi = mkMIndex(is..., odi);
this->plus(in, mi, ci1);
}
return *this;
}
template <class Ind1, class Ind2, class... Inds>
std::string printInd(const std::shared_ptr<Ind1>& ind1, const std::shared_ptr<Ind2>& ind2,
const std::shared_ptr<Inds>&... inds)
{
return std::to_string(reinterpret_cast<std::intptr_t>(ind1.get())) + "(" +
std::to_string(ind1->max()) + "), " + printInd(ind2, inds...);
}
template <class Ind1>
std::string printInd(const std::shared_ptr<Ind1>& ind1)
{
return std::to_string(reinterpret_cast<std::intptr_t>(ind1.get())) + "(" + std::to_string(ind1->max()) + ")";
}
template <class ROP>
template <class MIndex, class... Indices>
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::assign(const HighLevelOpHolder& in,
const std::shared_ptr<MIndex>& mi,
const std::shared_ptr<Indices>&... inds)
{
auto xx = mkArrayPtr<double>(nullr());
ROP& opr = *mOp->get();
if(in.root()){
auto inx = in;
opr.par().assign( *inx.get(), mkMIndex(mi,inds...) )();
return *this;
}
auto loop = mkPILoop
( [&opr,&in,&xx,&inds...,this](){
auto inx = in;
auto dop = inx.create(inds...);
DynamicO<size_t> gexp;
if(dop.outer.init()){
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.outer,dop.op));
}
else {
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.op));
}
auto xloop = mkILoop(std::make_tuple(*dop.op.data()->mOp),
std::make_tuple(inds...),
std::make_tuple(xx),
std::make_tuple(opr.assign( *dop.op.data()->mOp,
mkMIndex(inds...) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
return mkGetExpr(gexp, xloop); });
mi->pifor(1,loop)();
return *this;
}
template <class ROP>
template <class MIndex, class... Indices>
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::plus(const HighLevelOpHolder& in,
const std::shared_ptr<MIndex>& mi,
const std::shared_ptr<Indices>&... inds)
{
auto xx = mkArrayPtr<double>(nullr());
ROP& opr = *mOp->get();
if(in.root()){
auto inx = in;
opr.par().plus( *inx.get(), mkMIndex(mi,inds...) )();
return *this;
}
auto loop = mkPILoop
( [&opr,&in,&xx,&inds...,this](){
auto inx = in;
auto dop = inx.create(inds...);
DynamicO<size_t> gexp;
if(dop.outer.init()){
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.outer,dop.op));
}
else {
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.op));
}
auto xloop = mkILoop(std::make_tuple(*dop.op.data()->mOp),
std::make_tuple(inds...),
std::make_tuple(xx),
std::make_tuple(opr.plus( *dop.op.data()->mOp,
mkMIndex(inds...) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
return mkGetExpr(gexp, xloop); });
mi->pifor(1,loop)();
return *this;
}
template <class ROP>
HighLevelOpHolder<ROP> mkHLO(const ROP& op)
{
return HighLevelOpHolder<ROP>(std::make_shared<HighLevelOpRoot<ROP>>( op ) );
}
template <class ROP>
HighLevelOpHolder<ROP> mkHLOV(double val)
{
return HighLevelOpHolder<ROP>(std::make_shared<HighLevelOpValue<ROP>>
( OperationValue<double>(val) ) );
}
#define SP " "
#define regFunc1(fff) template <class ROP> \
HighLevelOpHolder<ROP> hl_##fff (const HighLevelOpHolder<ROP>& in) \
{ return HighLevelOpHolder<ROP>( std::make_shared<HighLevelOp<ROP,x_##fff <double>,1>> \
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,1>( {in.op()} ) ) ); } \
#include "extensions/math.h"
#undef regFunc1
#undef SP
}

View file

@ -1,267 +0,0 @@
#ifndef __high_level_operation_h__
#define __high_level_operation_h__
#include "base_def.h"
#include "ranges/rheader.h"
#include "dynamic_operation.h"
namespace MultiArrayTools
{
typedef ClassicRange CR;
typedef CR::IndexType CI;
typedef std::shared_ptr<CI> CIP;
typedef OperationRoot<double,CR,DynamicRange> OpCD;
typedef OperationRoot<double,DynamicRange> OpD;
extern template class OperationRoot<double,CR,DynamicRange>;
extern template class OperationRoot<double,DynamicRange>;
template <typename T, class Op>
DynamicO<T> mkDynOp1(const Op& op);
std::shared_ptr<DynamicIndex> mkSubSpaceX(const std::shared_ptr<DynamicIndex>& di, size_t max);
template <class ROP>
class HighLevelOpBase
{
public:
typedef OperationValue<double> VOP;
template <class... Indices>
struct RetT
{
DynamicO<OpH<OperationRoot<double,typename Indices::RangeType...>>> op;
DynamicO<size_t> outer;
template <class Op, class... Ops>
void appendOuterM(const Op& op, const Ops&... ops);
void appendOuterM();
void appendOuter(const DynamicO<size_t>& in);
void appendOuter(const RetT& in);
};
virtual bool root() const = 0;
#define reg_ind1(I1) virtual RetT<I1> create \
(const std::shared_ptr<I1>& ind1) = 0
#define reg_ind2(I1,I2) virtual RetT<I1,I2> create \
(const std::shared_ptr<I1>& ind1,const std::shared_ptr<I2>& ind2) = 0
#define reg_ind3(I1,I2,I3) virtual RetT<I1,I2,I3> create \
(const std::shared_ptr<I1>& ind1,const std::shared_ptr<I2>& ind2,const std::shared_ptr<I3>& ind3) = 0
#include "hl_reg_ind.h"
#undef reg_ind1
#undef reg_ind2
#undef reg_ind3
virtual ROP* get() = 0;
virtual VOP* vget() = 0;
};
template <class ROP>
class HighLevelOpRoot : public HighLevelOpBase<ROP>
{
private:
typedef HighLevelOpBase<ROP> B;
typedef typename B::VOP VOP;
template <class... Inds>
typename B::template RetT<Inds...> xcreate(const std::shared_ptr<Inds>&... inds);
ROP mOp;
public:
HighLevelOpRoot(const ROP& op);
virtual bool root() const override final;
#define reg_ind1(I1) virtual typename B::template RetT<I1> create \
(const std::shared_ptr<I1>& ind1) \
override final { return xcreate(ind1); }
#define reg_ind2(I1,I2) virtual typename B::template RetT<I1,I2> create \
(const std::shared_ptr<I1>& ind1, const std::shared_ptr<I2>& ind2) \
override final { return xcreate(ind1,ind2); }
#define reg_ind3(I1,I2,I3) virtual typename B::template RetT<I1,I2,I3> create \
(const std::shared_ptr<I1>& ind1, const std::shared_ptr<I2>& ind2, const std::shared_ptr<I3>& ind3) \
override final { return xcreate(ind1,ind2,ind3); }
#include "hl_reg_ind.h"
virtual ROP* get() override final;
virtual VOP* vget() override final;
};
extern template class HighLevelOpBase<OpCD>;
extern template class HighLevelOpBase<OpD>;
extern template class HighLevelOpRoot<OpCD>;
extern template class HighLevelOpRoot<OpD>;
template <class ROP>
class HighLevelOpValue : public HighLevelOpBase<ROP>
{
private:
typedef HighLevelOpBase<ROP> B;
typedef typename B::VOP VOP;
template <class... Inds>
typename B::template RetT<Inds...> xcreate(const std::shared_ptr<Inds>&... inds);
VOP mOp;
public:
HighLevelOpValue(const VOP& vop);
virtual bool root() const override final;
#include "hl_reg_ind.h"
virtual ROP* get() override final;
virtual VOP* vget() override final;
};
template <class OpF, class... Ops>
auto mkFOp(const Ops&... ops)
{
return Operation<double,OpF,Ops...>(ops...);
}
template <class ROP, class OpF, size_t N>
class HighLevelOp : public HighLevelOpBase<ROP>
{
public:
typedef HighLevelOpBase<ROP> B;
typedef typename B::VOP VOP;
private:
std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N> mIn;
template <class... Inds>
auto xcreate(const std::shared_ptr<Inds>&... inds)
-> typename B::template RetT<Inds...>;
public:
HighLevelOp(std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N> in);
virtual bool root() const override final;
virtual ROP* get() override final;
virtual VOP* vget() override final;
#include "hl_reg_ind.h"
#undef reg_ind1
#undef reg_ind2
#undef reg_ind3
};
extern template class HighLevelOp<OpCD,plusx<double,double>,2>;
extern template class HighLevelOp<OpCD,minusx<double,double>,2>;
extern template class HighLevelOp<OpCD,multipliesx<double,double>,2>;
extern template class HighLevelOp<OpCD,dividesx<double,double>,2>;
extern template class HighLevelOp<OpD,plusx<double,double>,2>;
extern template class HighLevelOp<OpD,minusx<double,double>,2>;
extern template class HighLevelOp<OpD,multipliesx<double,double>,2>;
extern template class HighLevelOp<OpD,dividesx<double,double>,2>;
#define regFunc1(fff) \
extern template class HighLevelOp<OpCD,x_##fff<double>,1>; \
extern template class HighLevelOp<OpD,x_##fff<double>,1>;
#include "extensions/math.h"
#undef regFunc1
template <class ROP>
class HighLevelOpHolder
{
private:
std::shared_ptr<HighLevelOpBase<ROP>> mOp;
public:
HighLevelOpHolder() = default;
HighLevelOpHolder(const HighLevelOpHolder& in) = default;
HighLevelOpHolder(HighLevelOpHolder&& in) = default;
HighLevelOpHolder& operator=(const HighLevelOpHolder& in) = default;
HighLevelOpHolder& operator=(HighLevelOpHolder&& in) = default;
HighLevelOpHolder(const std::shared_ptr<HighLevelOpBase<ROP>>& op);
bool root() const;
template <class... Inds>
auto create(const std::shared_ptr<Inds>&... inds) const
-> decltype(mOp->create(inds...));
auto get() -> decltype(mOp->get());
std::shared_ptr<HighLevelOpBase<ROP>> op() const;
HighLevelOpHolder operator*(const HighLevelOpHolder& in) const;
HighLevelOpHolder operator+(const HighLevelOpHolder& in) const;
HighLevelOpHolder operator-(const HighLevelOpHolder& in) const;
HighLevelOpHolder operator/(const HighLevelOpHolder& in) const;
template <class... Indices>
HighLevelOpHolder& xassign(const HighLevelOpHolder& in,
const std::shared_ptr<DynamicIndex>& di,
const std::shared_ptr<Indices>&... is);
template <class... Indices>
HighLevelOpHolder& xplus(const HighLevelOpHolder& in,
const std::shared_ptr<DynamicIndex>& di,
const std::shared_ptr<Indices>&... is);
template <class MIndex, class... Indices>
HighLevelOpHolder& assign(const HighLevelOpHolder& in,
const std::shared_ptr<MIndex>& mi,
const std::shared_ptr<Indices>&... inds);
template <class MIndex, class... Indices>
HighLevelOpHolder& plus(const HighLevelOpHolder& in,
const std::shared_ptr<MIndex>& mi,
const std::shared_ptr<Indices>&... inds);
};
extern template class HighLevelOpHolder<OpCD>;
extern template class HighLevelOpHolder<OpD>;
template <class F, class ROP, class... ROPs>
HighLevelOpHolder<ROP> mkSFunc(const HighLevelOpHolder<ROP>& a, const HighLevelOpHolder<ROPs>&... as);
template <class ROP>
HighLevelOpHolder<ROP> mkHLO(const ROP& op);
template <class ROP>
HighLevelOpHolder<ROP> mkHLOV(double val);
extern template HighLevelOpHolder<OpCD> mkHLO(const OpCD& op);
extern template HighLevelOpHolder<OpD> mkHLO(const OpD& op);
extern template HighLevelOpHolder<OpCD> mkHLOV(double val);
extern template HighLevelOpHolder<OpD> mkHLOV(double val);
#define regFunc1(fff) template <class ROP> \
HighLevelOpHolder<ROP> hl_##fff (const HighLevelOpHolder<ROP>& in);
#include "extensions/math.h"
#undef regFunc1
#define regFunc1(fff) template <class ROP> \
HighLevelOpHolder<ROP> hl_##fff (const HighLevelOpHolder<ROP>& in); \
extern template HighLevelOpHolder<OpCD> hl_##fff (const HighLevelOpHolder<OpCD>& in); \
extern template HighLevelOpHolder<OpD> hl_##fff (const HighLevelOpHolder<OpD>& in);
#include "extensions/math.h"
#undef regFunc1
}
#endif

View file

@ -1,52 +0,0 @@
#ifndef __hl_reg_ind_h__
#define __hl_reg_ind_h__
#include "ranges/rheader.h"
namespace MultiArrayTools
{
template <class Index>
struct RegIndNum
{
static constexpr size_t VALUE = -1;
static constexpr size_t DEPTH = 0;
};
template <>
struct RegIndNum<ClassicRange::IndexType>
{
static constexpr size_t VALUE = 0;
static constexpr size_t DEPTH = 3;
};
// to be returned by IndexWrapper
struct RegIndInfo
{
size_t type;
size_t depth;
template <class Index>
RegIndInfo& set(const std::shared_ptr<Index>& i)
{
type = RegIndNum<Index>::VALUE;
depth = RegIndNum<Index>::DEPTH;
return *this;
}
};
}
#endif
#ifdef reg_ind1
#ifdef reg_ind2
#ifdef reg_ind3
reg_ind1(ClassicRange::IndexType);
reg_ind2(ClassicRange::IndexType,ClassicRange::IndexType);
reg_ind3(ClassicRange::IndexType,ClassicRange::IndexType,ClassicRange::IndexType);
#endif
#endif
#endif

View file

@ -1,15 +0,0 @@
#include <iostream>
#include <sstream>
#define MA_ERRTAG __FILE__ << '@' << __LINE__ << '(' << __func__ << "): error"
#define MA_WARNTAG __FILE__ << '@' << __LINE__ << ": warning"
#define MA_ERROR(errmsg) {\
std::stringstream ss;\
ss << MA_ERRTAG << ": " << errmsg << std::flush;\
throw std::runtime_error(ss.str()); }
#define MA_WARNING(errmsg) {\
std::cerr << MA_WARNTAG << ": " << errmsg << std::endl; }
#define MA_ASSERT(statement, errmsg) if(not (statement)) { MA_ERROR(errmsg); }

View file

@ -1,696 +0,0 @@
#include "map_range.h"
#include <type_traits>
namespace MultiArrayTools
{
namespace
{
using namespace MultiArrayHelper;
}
/**************
* OpExpr *
**************/
template <class Op, class Index, class Expr, SpaceType STYPE>
OpExpr<Op,Index,Expr,STYPE>::OpExpr(const Op& mapf, const Index* ind,
size_t step, Expr ex) :
mIndPtr(ind), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
mStep(step), mExpr( ex ),
mOp(mapf),
//mExt(ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
mExt( mOp.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ).extend
( ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ) ) )
{
assert(mIndPtr != nullptr);
}
template <class Op, class Index, class Expr, SpaceType STYPE>
inline void OpExpr<Op,Index,Expr,STYPE>::operator()(size_t mlast,
ExtType last)
{
constexpr size_t NEXT = Op::SIZE;
const ExtType nxpos = last;
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
if(pos != mIndPtr->max()){
const ExtType npos = last + mExt*pos;
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ) );
}
}
template <class Op, class Index, class Expr, SpaceType STYPE>
inline void OpExpr<Op,Index,Expr,STYPE>::operator()(size_t mlast)
{
const ExtType last;
constexpr size_t NEXT = Op::SIZE;
const ExtType nxpos = last;
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
if(pos != mIndPtr->max()){
const ExtType npos = last + mExt*pos;
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ));
}
}
template <class Op, class Index, class Expr, SpaceType STYPE>
auto OpExpr<Op,Index,Expr,STYPE>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType
{
return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) );
//return mExpr.rootSteps(iPtrNum).extend( mOp.rootSteps(iPtrNum) );
}
// -> define in range_base.cc
//std::shared_ptr<RangeFactoryBase> mkMULTI(const char** dp);
/******************
* MapIndex *
******************/
/*
template <class MapF, class... Indices>
MapIndex<MapF,Indices...>::MapIndex(const MapIndex<MapF,Indices...>& in) :
IndexInterface<std::tuple<typename Indices::MetaType...> >(in)
{
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
template <class MapF, class... Indices>
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator=(const MapIndex<MapF,Indices...>& in)
{
IndexI::operator=(in);
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
return *this;
}
*/
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <class MRange>
GenMapIndex<OIType,Op,XSTYPE,Indices...>::GenMapIndex(const std::shared_ptr<MRange>& range) :
IndexInterface<GenMapIndex<OIType,Op,XSTYPE,Indices...>,typename Op::value_type>(range, 0)
{
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); // has one more element!
mOutIndex = std::make_shared<OIType>
( std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->outRange()->begin() );
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <size_t DIR>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::up()
{
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
IB::mPos += RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
RPackNum<DIR>::pp( mIPack );
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <size_t DIR>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::down()
{
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
IB::mPos -= RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
RPackNum<DIR>::mm( mIPack );
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <size_t N>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
{
return *std::get<N>(mIPack);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <size_t N>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>(mIPack);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::outIndex() const -> std::shared_ptr<OIType>
{
return mOutIndex;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator()(const std::shared_ptr<Indices>&... indices)
{
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices...);
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos);
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
IndexType GenMapIndex<OIType,Op,XSTYPE,Indices...>::type() const
{
return IndexType::MULTI;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator=(size_t pos)
{
(*mOutIndex) = pos;
IB::mPos = mOutIndex->pos();
//RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator++()
{
//RPackNum<sizeof...(Indices)-1>::pp( mIPack );
++(*mOutIndex);
IB::mPos = mOutIndex->pos();
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator--()
{
//RPackNum<sizeof...(Indices)-1>::mm( mIPack );
--(*mOutIndex);
IB::mPos = mOutIndex->pos();
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
int GenMapIndex<OIType,Op,XSTYPE,Indices...>::pp(std::intptr_t idxPtrNum)
{
//int tmp = RPackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtrNum);
mOutIndex->pp(idxPtrNum);
IB::mPos = mOutIndex->pos();
//IB::mPos += tmp;
return 1;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
int GenMapIndex<OIType,Op,XSTYPE,Indices...>::mm(std::intptr_t idxPtrNum)
{
//int tmp = RPackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtrNum);
mOutIndex->mm(idxPtrNum);
IB::mPos = mOutIndex->pos();
//IB::mPos -= tmp;
return 1;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
std::string GenMapIndex<OIType,Op,XSTYPE,Indices...>::stringMeta() const
{
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->stringMeta(IB::mPos);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
typename GenMapIndex<OIType,Op,XSTYPE,Indices...>::MetaType GenMapIndex<OIType,Op,XSTYPE,Indices...>::meta() const
{
//MetaType metaTuple;
//RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
//assert(0);
return mOutIndex->meta();
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::at(const MetaType& metaPos)
{
//RPackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
//IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
mOutIndex->at(metaPos);
IB::mPos = mOutIndex->pos();
return *this;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
size_t GenMapIndex<OIType,Op,XSTYPE,Indices...>::posAt(const MetaType& metaPos) const
{
return range()->outRange()->getMeta(metaPos);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
size_t GenMapIndex<OIType,Op,XSTYPE,Indices...>::dim() const
{
return sizeof...(Indices);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
bool GenMapIndex<OIType,Op,XSTYPE,Indices...>::first() const
{
return IB::mPos == 0;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
bool GenMapIndex<OIType,Op,XSTYPE,Indices...>::last() const
{
return IB::mPos == IB::mMax - 1;
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
std::shared_ptr<typename GenMapIndex<OIType,Op,XSTYPE,Indices...>::RangeType>
GenMapIndex<OIType,Op,XSTYPE,Indices...>::range() const
{
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <size_t N>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::getPtr() -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>(mIPack);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
size_t GenMapIndex<OIType,Op,XSTYPE,Indices...>::getStepSize(size_t n) const
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
return mBlockSizes[n+1];
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
std::string GenMapIndex<OIType,Op,XSTYPE,Indices...>::id() const
{
return std::string("mul") + std::to_string(IB::mId);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
void GenMapIndex<OIType,Op,XSTYPE,Indices...>::print(size_t offset) const
{
if(offset == 0){
std::cout << " === " << std::endl;
}
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this)
<< "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl;
RPackNum<sizeof...(Indices)-1>::printIndex(mIPack, offset+1);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <class Exprs>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::ifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
(step, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex<OIType,Op,XSTYPE,Indices...>,Exprs,XSTYPE>
( range()->map(), this, step, exs ) ) )
{
return RPackNum<sizeof...(Indices)-1>::mkForh
(0, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex<OIType,Op,XSTYPE,Indices...>,Exprs,XSTYPE>
( range()->map(), this, step, exs ) );
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <class Exprs>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::pifor(size_t step, Exprs exs) const
-> decltype(ifor(step, exs))
{
return ifor(step, exs);
}
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
template <class Exprs>
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::iforh(size_t step, Exprs exs) const
-> decltype(ifor(step, exs))
{
return ifor(step, exs);
}
/*************************
* MapRangeFactory *
*************************/
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::shared_ptr<ORType>& outr,
const std::tuple<Op,MA>& mapf,
const std::shared_ptr<Ranges>&... rs)
{
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( outr, mapf, rs... ) );
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::shared_ptr<ORType>& outr,
const std::tuple<Op,MA>& mapf,
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& st)
{
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( outr, mapf, st ) );
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::tuple<Op,MA>& mapf,
const std::shared_ptr<Ranges>&... rs)
{
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( mapf, rs... ) );
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::tuple<Op,MA>& mapf,
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& st)
{
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( mapf, st ) );
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
std::shared_ptr<RangeBase> GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::create()
{
mProd = checkIfCreated( std::dynamic_pointer_cast<oType>( mProd )->mSpace );
setSelf();
return mProd;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
std::shared_ptr<RangeBase> GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::checkIfCreated(const std::tuple<std::shared_ptr<Ranges>...>& ptp)
{
std::shared_ptr<RangeBase> out;
bool check = false;
for(auto& x: MapRangeFactoryProductMap::mAleadyCreated){
if(x.second.size() == sizeof...(Ranges)){
check = RPackNum<sizeof...(Ranges)-1>::checkIfCreated(ptp, x.second);
if(check){
out = x.first;
break;
}
}
}
if(not check){
vector<std::intptr_t> pv(sizeof...(Ranges));
RPackNum<sizeof...(Ranges)-1>::RangesToVec(ptp, pv);
pv.push_back( reinterpret_cast<std::intptr_t>
( &std::dynamic_pointer_cast<oType>( mProd )->mMapf ) );
MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv;
out = mProd;
}
return out;
}
/******************
* MapRange *
******************/
template <SpaceType XSTYPE>
struct OutRangeMaker
{};
template <>
struct OutRangeMaker<SpaceType::ANY>
{
template <class MapF, class ORType>
static void mk(std::shared_ptr<ORType>& outRange, MultiArray<size_t,ORType>& mapMult, const MapF& mapf)
{
std::map<typename MapF::value_type,size_t> mult;
for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) {
mult[mapf[ii]]++;
}
vector<typename MapF::value_type> outmeta(mult.size());
vector<size_t> outmult(mult.size());
size_t cnt = 0;
for(auto& x: mult){
outmeta[cnt] = x.first;
outmult[cnt] = x.second;
++cnt;
}
typename ORType::FType orf(outmeta);
outRange = std::dynamic_pointer_cast<ORType>( orf.create() );
mapMult = MultiArray<size_t,ORType>( outRange, outmult );
}
};
template <>
struct OutRangeMaker<SpaceType::NONE>
{
template <class MapF, class ORType>
static void mk(std::shared_ptr<ORType>& outRange, MultiArray<size_t,ORType>& mapMult, const MapF& mapf)
{
static_assert( std::is_same<size_t,typename MapF::value_type>::value,
"out range value type for NONE must be size_t" );
size_t max = 0;
for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) {
max = mapf[ii]+1 > max ? mapf[ii]+1 : max;
}
vector<size_t> mult(max,0);
for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) {
mult[mapf[ii]]++;
}
vector<size_t> outmult(mult.size());
size_t cnt = 0;
for(auto& x: mult){
outmult[cnt++] = x;
}
typename ORType::FType orf(max);
outRange = std::dynamic_pointer_cast<ORType>( orf.create() );
mapMult = MultiArray<size_t,ORType>( outRange, outmult );
}
};
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
void GenMapRange<ORType,Op,XSTYPE,Ranges...>::mkOutRange(const MA& mapf)
{
//FunctionalMultiArray<typename MapF::value_type,MapF,Ranges...> fma(mSpace, mMapf);
OutRangeMaker<XSTYPE>::mk(mOutRange,mMapMult,mapf);
auto i = mapf.begin();
mMapPos.resize(i.max());
for(; i.pos() != i.max(); ++i){
mMapPos[i.pos()] = mOutRange->getMeta( mapf[i] );
}
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
const std::shared_ptr<Ranges>&... rs) :
mSpace(std::make_tuple(rs...)),
mMapf(std::get<0>(mapf)),
mOutRange(outr),
mMapMult(mOutRange,0),
mMapPos(std::get<1>(mapf).size(),mOutRange->size())
{
auto& ma = std::get<1>(mapf);
auto jj = mMapMult.begin();
for(auto ii = ma.begin(); ii.pos() != ii.max(); ++ii){
++mMapMult[jj.at(ma[ii])];
mMapPos[ii.pos()] = jj.pos();
}
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
const Space& space) :
mSpace(space),
mMapf(std::get<0>(mapf)),
mOutRange(outr),
mMapMult(mOutRange,0),
mMapPos(std::get<1>(mapf).size(),mOutRange->size())
{
auto& ma = std::get<1>(mapf);
auto jj = mMapMult.begin();
for(auto ii = ma.begin(); ii.pos() != ii.max(); ++ii){
++mMapMult[jj.at(ma[ii])];
mMapPos[ii.pos()] = jj.pos();
}
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::tuple<Op,MA>& mapf,
const std::shared_ptr<Ranges>&... rs) :
mSpace(std::make_tuple(rs...)),
mMapf(std::get<0>(mapf))
{
mkOutRange(std::get<1>(mapf));
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class MA>
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::tuple<Op,MA>& mapf, const Space& space) :
mSpace( space ),
mMapf(std::get<0>(mapf))
{
mkOutRange(std::get<1>(mapf));
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <size_t N>
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::get() const -> decltype( *std::get<N>( mSpace ) )&
{
return *std::get<N>(mSpace);
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <size_t N>
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::getPtr() const -> decltype( std::get<N>( mSpace ) )&
{
return std::get<N>(mSpace);
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::outRange() const -> std::shared_ptr<ORType>
{
return mOutRange;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
const Op& GenMapRange<ORType,Op,XSTYPE,Ranges...>::map() const
{
return mMapf;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::dim() const
{
return sdim;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::size() const
{
return mOutRange->size();
//return RPackNum<sizeof...(Ranges)-1>::getSize(mSpace);
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
SpaceType GenMapRange<ORType,Op,XSTYPE,Ranges...>::spaceType() const
{
return SpaceType::ANY;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& GenMapRange<ORType,Op,XSTYPE,Ranges...>::space() const
{
return mSpace;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
vector<size_t> GenMapRange<ORType,Op,XSTYPE,Ranges...>::typeNum() const
{
vector<size_t> o;
RPackNum<sizeof...(Ranges)-1>::getTypeNum(o,mSpace);
return o;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::cmeta(char* target, size_t pos) const
{
//MetaType* xtarget = reinterpret_cast<MetaType*>(target);
assert(0);
return 0;
//return RPackNum<sizeof...(Ranges)-1>::getCMeta(xtarget,pos,mSpace,cmetaSize());
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::cmetaSize() const
{
return RPackNum<sizeof...(Ranges)-1>::getCMetaSize(mSpace);
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
std::string GenMapRange<ORType,Op,XSTYPE,Ranges...>::stringMeta(size_t pos) const
{
auto i = begin();
i = pos;
return "[ " + RPackNum<sizeof...(Ranges)-1>::getStringMeta(i) + " ]";
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
vector<char> GenMapRange<ORType,Op,XSTYPE,Ranges...>::data() const
{
DataHeader h = dataHeader();
vector<char> out;
//out.reserve(h.metaSize + sizeof(DataHeader));
char* hcp = reinterpret_cast<char*>(&h);
out.insert(out.end(), hcp, hcp + sizeof(DataHeader));
RPackNum<sizeof...(Ranges)-1>::fillRangeDataVec(out, mSpace);
return out;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
DataHeader GenMapRange<ORType,Op,XSTYPE,Ranges...>::dataHeader() const
{
DataHeader h;
h.spaceType = static_cast<int>( SpaceType::ANY );
h.metaSize = sizeof...(Ranges);
h.multiple = 1;
return h;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::IndexType GenMapRange<ORType,Op,XSTYPE,Ranges...>::begin() const
{
GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...>
i( std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
i = 0;
return i;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::IndexType GenMapRange<ORType,Op,XSTYPE,Ranges...>::end() const
{
GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...>
i( std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis )) );
i = size();
return i;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::mapMultiplicity() const
-> const MultiArray<size_t,ORType>&
{
return mMapMult;
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::explMapMultiplicity() const
-> ConstSlice<size_t,GenMapRange>
{
/*
auto tmp = mMapMult;
return tmp.format( std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis )) );
*/
return mMapMult.slformat(std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis )));
}
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
vector<size_t> GenMapRange<ORType,Op,XSTYPE,Ranges...>::mapPos() const
{
return mMapPos;
}
/*
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
template <class... ERanges>
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::cat(const std::shared_ptr<MapRange<ERanges...> >& erange)
-> std::shared_ptr<GenMapRange<Ranges...,ERanges...> >
{
auto crange = std::tuple_cat(mSpace, erange->space());
MapRangeFactory<Ranges...,ERanges...> rf(crange);
return std::dynamic_pointer_cast<MapRange<Ranges...,ERanges...> >(rf.create());
}
*/
}

View file

@ -1,357 +0,0 @@
// -*- C++ -*-
#ifndef __map_range_h__
#define __map_range_h__
#include <cstdlib>
#include <tuple>
#include <memory>
#include <map>
#include "mbase_def.h"
#include "ranges/range_base.h"
#include "ranges/index_base.h"
#include "ranges/rpack_num.h"
#include "map_range_factory_product_map.h"
#include "ranges/x_to_string.h"
#include "ranges/type_map.h"
#include "xfor/xfor.h"
namespace MultiArrayTools
{
namespace
{
using namespace MultiArrayHelper;
}
template <class Func, class... Indices>
auto mkMapOp(const std::shared_ptr<Func>& func,
const std::shared_ptr<Indices>&... is)
-> decltype(std::make_tuple(FunctionalMultiArray<typename Func::value_type,Func,
typename Indices::RangeType...>().exec(is...),
FunctionalMultiArray<typename Func::value_type,Func,
typename Indices::RangeType...>()))
{
typedef FunctionalMultiArray<typename Func::value_type,Func,typename Indices::RangeType...> FMA;
if(Func::FISSTATIC){
FMA fma(is->range()...);
return std::make_tuple(fma.exec(is...),fma);
}
else {
FMA fma(is->range()...,func);
return std::make_tuple(fma.exec(is...),fma);
}
}
template <class Op, class Index, class Expr, SpaceType STYPE = SpaceType::ANY>
//template <class MapF, class IndexPack, class Expr, SpaceType STYPE = SpaceType::ANY>
class OpExpr
{
public:
//typedef typename Index::OIType OIType;
//typedef SingleIndex<typename Op::value_type,STYPE> OIType;
static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE + Op::SIZE;
private:
OpExpr() = default;
const Index* mIndPtr;
//const OIType* mIndPtr;
size_t mSPos;
size_t mMax;
size_t mStep;
Expr mExpr;
Op mOp;
typedef decltype(mOp.rootSteps(std::declval<intptr_t>()).extend( mExpr.rootSteps(std::declval<intptr_t>()) )) ExtType;
ExtType mExt;
public:
OpExpr(const OpExpr& in) = default;
OpExpr(OpExpr&& in) = default;
OpExpr& operator=(const OpExpr& in) = default;
OpExpr& operator=(OpExpr&& in) = default;
OpExpr(const Op& mapf, const Index* ind, size_t step, Expr ex);
inline void operator()(size_t mlast, ExtType last);
inline void operator()(size_t mlast = 0);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
};
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
class GenMapIndex : public IndexInterface<GenMapIndex<OIType,Op,XSTYPE,Indices...>,
typename Op::value_type>
//std::tuple<typename Indices::MetaType...> >
{
public:
typedef IndexInterface<GenMapIndex<OIType,Op,XSTYPE,Indices...>,
typename Op::value_type> IB;
//std::tuple<typename Indices::MetaType...> > IB;
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
//typedef std::tuple<typename Indices::MetaType...> MetaType;
typedef typename Op::value_type MetaType;
typedef GenMapRange<typename OIType::RangeType,Op,XSTYPE,typename Indices::RangeType...> RangeType;
typedef GenMapIndex IType;
//typedef SingleIndex<typename Op::value_type,XSTYPE> OIType;
static constexpr IndexType sType() { return IndexType::SINGLE; }
static constexpr size_t sDim() { return sizeof...(Indices); }
static constexpr size_t totalDim() { return mkTotalDim<Indices...>(); }
static void check_type() { static_assert( std::is_same<typename OIType::MetaType,typename Op::value_type>::value, "inconsitent value types" ); }
static constexpr SpaceType STYPE = XSTYPE;
static constexpr bool PARALLEL = false;
private:
IndexPack mIPack;
std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
std::shared_ptr<OIType> mOutIndex;
public:
const IndexPack& pack() const { return mIPack; }
GenMapIndex() = delete;
// NO DEFAULT HERE !!!
// ( have to assign sub-indices (ptr!) correctly )
//MapIndex(const MapIndex& in);
//MapIndex& operator=(const MapIndex& in);
template <class MRange>
GenMapIndex(const std::shared_ptr<MRange>& range);
template <size_t DIR>
GenMapIndex& up();
template <size_t DIR>
GenMapIndex& down();
template <size_t N>
auto get() const -> decltype( *std::get<N>( mIPack ) )&;
template <size_t N>
auto getPtr() const -> decltype( std::get<N>( mIPack ) )&;
template <size_t N>
size_t getBlockSize() const { return std::get<N>(mBlockSizes); }
std::shared_ptr<OIType> outIndex() const;
// raplace instances (in contrast to its analogon in ContainerIndex
// MultiIndices CANNOT be influences be its subindices, so there is
// NO foreign/external controll)
// Do NOT share index instances between two or more MapIndex instances
GenMapIndex& operator()(const std::shared_ptr<Indices>&... indices);
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
IndexType type() const;
GenMapIndex& operator=(size_t pos);
GenMapIndex& operator++();
GenMapIndex& operator--();
int pp(std::intptr_t idxPtrNum);
int mm(std::intptr_t idxPtrNum);
std::string stringMeta() const;
MetaType meta() const;
GenMapIndex& at(const MetaType& metaPos);
size_t posAt(const MetaType& metaPos) const;
size_t dim() const;
bool first() const;
bool last() const;
std::shared_ptr<RangeType> range() const;
template <size_t N>
auto getPtr() -> decltype( std::get<N>( mIPack ) )&;
size_t getStepSize(size_t n) const;
std::string id() const;
void print(size_t offset) const;
template <class Exprs>
auto ifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
(step, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex,Exprs,XSTYPE>( range()->map(), this, step, exs ) ) );
// first step arg not used!
template <class Exprs>
auto pifor(size_t step, Exprs exs) const
-> decltype(ifor(step, exs)); // NO MULTITHREADING
template <class Exprs>
auto iforh(size_t step, Exprs exs) const
-> decltype(ifor(step, exs));
};
/*************************
* MapRangeFactory *
*************************/
// NOT THREAD SAVE
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
class GenMapRangeFactory : public RangeFactoryBase
{
public:
//typedef SingleRange<typename Op::value_type,XSTYPE> ORType;
typedef GenMapRange<ORType,Op,XSTYPE,Ranges...> oType;
GenMapRangeFactory() = delete;
template <class MA>
GenMapRangeFactory(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
const std::shared_ptr<Ranges>&... rs);
template <class MA>
GenMapRangeFactory(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& st);
template <class MA>
GenMapRangeFactory(const std::tuple<Op,MA>& mapf, const std::shared_ptr<Ranges>&... rs);
template <class MA>
GenMapRangeFactory(const std::tuple<Op,MA>& mapf,
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& space);
virtual std::shared_ptr<RangeBase> create() override;
private:
std::shared_ptr<RangeBase> checkIfCreated(const std::tuple<std::shared_ptr<Ranges>...>& ptp);
};
/******************
* MapRange *
******************/
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
class GenMapRange : public RangeInterface<GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...> >
{
public:
typedef RangeBase RB;
typedef std::tuple<std::shared_ptr<Ranges>...> Space;
typedef GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...> IndexType;
//typedef GenMapRange RangeType;
//typedef SingleRange<typename Op::value_type,XSTYPE> ORType;
//typedef SingleRangeFactory<typename Op::value_type,XSTYPE> ORFType;
typedef typename Op::value_type MetaType;
//typedef typename RangeInterface<MapIndex<typename Ranges::IndexType...> >::IndexType IndexType;
protected:
GenMapRange() = delete;
GenMapRange(const GenMapRange& in) = delete;
GenMapRange& operator=(const GenMapRange& in) = delete;
template <class MA>
GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
const std::shared_ptr<Ranges>&... rs);
template <class MA>
GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
const Space& space);
template <class MA>
GenMapRange(const std::tuple<Op,MA>& mapf, const Space& space);
template <class MA>
GenMapRange(const std::tuple<Op,MA>& mapf, const std::shared_ptr<Ranges>&... rs);
Space mSpace;
Op mMapf;
//Op mMapf;
std::shared_ptr<ORType> mOutRange;
MultiArray<size_t,ORType> mMapMult;
vector<size_t> mMapPos;
private:
template <class MA>
void mkOutRange(const MA& mapf);
public:
static constexpr size_t sdim = sizeof...(Ranges);
template <size_t N>
auto get() const -> decltype( *std::get<N>( mSpace ) )&;
template <size_t N>
auto getPtr() const -> decltype( std::get<N>( mSpace ) )&;
std::shared_ptr<ORType> outRange() const;
const Op& map() const;
virtual size_t dim() const final;
virtual size_t size() const final;
virtual SpaceType spaceType() const final;
virtual DataHeader dataHeader() const final;
virtual vector<size_t> typeNum() const final;
virtual size_t cmeta(char* target, size_t pos) const final;
virtual size_t cmetaSize() const final;
virtual std::string stringMeta(size_t pos) const final;
virtual vector<char> data() const final;
const Space& space() const;
virtual IndexType begin() const final;
virtual IndexType end() const final;
const MultiArray<size_t,ORType>& mapMultiplicity() const;
ConstSlice<size_t,GenMapRange> explMapMultiplicity() const;
vector<size_t> mapPos() const;
/*
template <class... ERanges>
auto cat(const std::shared_ptr<GenMapRange<ERanges...> >& erange)
-> std::shared_ptr<GenMapRange<Ranges...,ERanges...> >;
*/
friend GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>;
static constexpr bool HASMETACONT = false;
static constexpr bool defaultable = false;
static constexpr size_t ISSTATIC = SubProp<Op,Ranges...>::ISSTATIC;
static constexpr size_t SIZE = SubProp<Op,Ranges...>::SIZE;
};
// for legacy
template <class OIType, class Op, class... Indices>
using MapIndex = GenMapIndex<OIType,Op,SpaceType::ANY,Indices...>;
template <class ORType, class Op, class... Ranges>
using MapRangeFactory = GenMapRangeFactory<ORType,Op,SpaceType::ANY,Ranges...>;
template <class ORType, class Op, class... Ranges>
using MapRange = GenMapRange<ORType,Op,SpaceType::ANY,Ranges...>;
template <class OIType, class Op, class... Indices>
auto mapResult/*<MapIndex<Op,Indices...> >*/(const std::shared_ptr<MapIndex<OIType,Op,Indices...> >& ind)
-> decltype(ind->outIndex())
{
return ind->outIndex();
}
}
#endif

View file

@ -1,26 +0,0 @@
#ifndef __map_range_factory_product_map_h__
#define __map_range_factory_product_map_h__
#include <memory>
#include <vector>
#include <map>
#include "ranges/rbase_def.h"
#include "mbase_def.h"
namespace MultiArrayTools
{
class MapRangeFactoryProductMap
{
public:
template <class ORType, class MapF, SpaceType XSTYPE, class... Ranges>
friend class GenMapRangeFactory;
private:
static std::map<std::shared_ptr<RangeBase>,vector<std::intptr_t> > mAleadyCreated;
};
}
#endif

View file

@ -1,98 +0,0 @@
#ifndef __mbase_def_h__
#define __mbase_def_h__
#include "ranges/rbase_def.h"
#include "allocator.h"
namespace MultiArrayTools
{
/***********************
* Provided Types *
***********************/
// multi_array.h
template <typename T, class... SRanges>
class MultiArrayBase;
// multi_array.h
template <typename T, class... SRanges>
class MutableMultiArrayBase;
// multi_array.h
template <typename T, class... SRanges>
class MultiArray;
// multi_array_operation.h
template <typename T, class OperationClass>
class OperationBase;
// multi_array_operation.h
//template <typename T>
//class MutableOperationBase;
// multi_array_operation.h
template <typename T, class OperationClass>
class OperationTemplate;
// multi_array_operation.h
template <typename T, class... Ranges>
class OperationRoot;
// multi_array_operation.h
template <typename T, class... Ranges>
class ParallelOperationRoot;
// multi_array_operation.h
template <typename T>
class OperationValue;
// multi_array_operation.h
template <typename T, class... Ranges>
class ConstOperationRoot;
// multi_array_operation.h
template <typename T, class Op>
class OperationPointer;
// multi_array_operation.h
template <typename T, class OpFunction, class... Ops>
class Operation;
// multi_array_operation.h
template <typename T, class Op, class IndexType>
class Contraction;
// multi_array_operation.h
template <typename T, class Op, class... Indices>
class SliceContraction;
// slice.h
template <typename T, class... SRanges>
class Slice;
template <typename T, class... SRanges>
class ConstSlice;
// slice.h
template <typename T, class... SRanges>
class SliceDef;
// slice.h
template <typename T, class... SRanges>
class ConstSliceDef;
// map_range.h
template <class OITpye, class MapF, SpaceType XSTYPE, class... Indices>
class GenMapIndex;
// map_range.h
template <class ORType, class MapF, SpaceType XSTYPE, class... Ranges>
class GenMapRangeFactory;
// map_range.h
template <class ORType, class MapF, SpaceType XSTYPE, class... Ranges>
class GenMapRange;
}
#endif

View file

@ -0,0 +1,56 @@
// -*- C++ -*-
/**
@file include/memory/allocator.cc.h
@brief Allocator template member function implementation
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_allocator_cc_h__
#define __cxz_allocator_cc_h__
#include "allocator.h"
#include "memcount.h"
namespace CNORXZ
{
template <typename T>
T* Allocator<T>::allocate(SizeT n)
{
const SizeT nn = n*type_size;
MemCount::add(nn);
const SizeT off = nn%N;
const SizeT nnx = (off == 0) ? nn : nn + N - off;
const SizeT nnd = nnx/N;
VX* vx = new VX[nnd];
return reinterpret_cast<T*>(vx);
}
template <typename T>
void Allocator<T>::deallocate(T* p, SizeT n)
{
const SizeT nn = n*type_size;
MemCount::sub(nn);
VX* vx = reinterpret_cast<VX*>(p);
delete [] vx;
}
template <class T, class U>
bool operator==(const Allocator<T>& a, const Allocator<U>& b)
{
return true;
}
template <class T, class U>
bool operator!=(const Allocator<T>& a, const Allocator<U>& b)
{
return false;
}
}
#endif

View file

@ -0,0 +1,85 @@
// -*- C++ -*-
/**
@file include/memory/allocator.h
@brief Allocator declaration
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_allocator__
#define __cxz_allocator__
#include <cstdlib>
#include <new>
#include <vector>
#include <cstdint>
#include <cassert>
#include <iostream>
#include "base/types.h"
#include "base/intrin.h"
#define MIB_SIZE 1024*1024 // 1MiB
#define WARN_SIZE MIB_SIZE*100 // 100 MiB
namespace CNORXZ
{
/** *****
Allocator implementation
Takes care of proper alignment
*/
template <typename T>
class Allocator
{
public:
typedef T value_type;
static constexpr SizeT type_size = sizeof(T); /** < type size */
static constexpr SizeT N = MAX_VSIZE; /** < size of the larges available intrinsics vector */
/** ***
Aligned data block type
The size equals the maximal intrinsics vectors size
*/
struct VX
{
alignas(N) char x[N];
};
/** default constructor */
Allocator() = default;
/** (copy) construct from allocator for different data type
@tparam U input data type
@param x input allocator
*/
template <typename U>
Allocator(const Allocator<U>& x) {}
/** allocate n element of type T
@param n number of elements
*/
T* allocate(SizeT n);
/** deallocate n elements
@param p pointer to first element
@param n number of elements
*/
void deallocate(T* p, SizeT n);
};
/** compare two cnorxz allocators; equality check returns always true */
template <class T, class U>
bool operator==(const Allocator<T>& a, const Allocator<U>& b);
/** compare two cnorxz allocators; unequality check returns always false */
template <class T, class U>
bool operator!=(const Allocator<T>& a, const Allocator<U>& b);
} // namespace CNORXZ
#endif

View file

@ -0,0 +1,53 @@
// -*- C++ -*-
/**
@file include/memory/memcount.h
@brief MemCount declaration.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_memcount_h__
#define __cxz_memcount_h__
#include "base/types.h"
namespace CNORXZ
{
/** *****
Static class to track memory usage by cnorxz types
The usage variable can be changed only be an Allocator instance
@see Allocator
**/
class MemCount
{
private:
static SizeT sMemUsage; /**< current memory usage (bytes) */
/** increas memory usage
@param x number of bytes
*/
static void add(SizeT x);// { sMemUsage += x; }
/** decreas memory usage
@param x number of bytes
*/
static void sub(SizeT x);// { sMemUsage -= x; }
public:
/** no instance construction (static) */
MemCount() = delete;
/** return current memory usage (bytes) */
static SizeT usage();
template <typename T>
friend class Allocator;
};
} // namespace CNORXZ
#endif

View file

@ -0,0 +1,12 @@
// -*- C++ -*-
/**
@file include/memory/memory.cc.h
@brief Memory template implementations main header.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "allocator.cc.h"

View file

@ -0,0 +1,15 @@
// -*- C++ -*-
/**
@file include/memory/memory.h
@brief Memory main heade.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "allocator.h"
#include "memcount.h"
#include "memory.cc.h"

View file

@ -1,307 +0,0 @@
#include "multi_array.h"
namespace MultiArrayTools
{
template <typename T>
Scalar<T> scalar(const T& in)
{
NullRF nrf;
return Scalar<T>( std::dynamic_pointer_cast<NullRange>( nrf.create() ), vector<T>( { in } ) );
}
/*******************
* MultiArray *
*******************/
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space) :
MutableMultiArrayBase<T,SRanges...>(space),
mCont(MAB::mRange->size())
{
MAB::mInit = true;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space,
const vector<T>& vec) :
MutableMultiArrayBase<T,SRanges...>(space),
mCont(vec)
{
MAB::mInit = true;
if(mCont.size() > MAB::mRange->size()){
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
}
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges) :
MutableMultiArrayBase<T,SRanges...>(ranges...),
mCont(MAB::mRange->size())
{
MAB::mInit = true;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const T& val) :
MutableMultiArrayBase<T,SRanges...>(ranges...),
mCont(MAB::mRange->size(), val)
{
MAB::mInit = true;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const vector<T>& vec) :
MutableMultiArrayBase<T,SRanges...>(ranges...),
mCont(vec)
{
MAB::mInit = true;
if(mCont.size() > MAB::mRange->size()){
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
}
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, vector<T>&& vec) :
MutableMultiArrayBase<T,SRanges...>(ranges...),
mCont(std::forward<vector<T>>(vec))
{
MAB::mInit = true;
if(mCont.size() > MAB::mRange->size()){
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
}
}
template <typename T, class... SRanges>
template <class... Ranges>
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, MultiArray<T,Ranges...>&& in) :
MutableMultiArrayBase<T,SRanges...>(ranges...),
mCont( std::move( in.mCont ) )
{
// maybe some checks here in the future...
assert(mCont.size() == MAB::mRange->size());
MAB::mInit = true;
in.mInit = false;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(MultiArray<T,AnonymousRange>&& ama, SIZET<SRanges>... sizes) :
MutableMultiArrayBase<T,SRanges...>
( ama.range()->template get<0>().template scast<SRanges...>(sizes...)->space() ),
mCont( std::move( ama.mCont ) )
{
MAB::mInit = true;
ama.mInit = false;
}
/*
template <typename T, class... SRanges>
template <class Range2, class Range3>
MultiArray<T,SRanges...>::MultiArray(const MultiArray<MultiArray<T,Range2>,Range3> in) :
MutableMultiArrayBase<T,SRanges...>(merge(in.range(), in[ in.beginIndex() ].range()))
// assert that Range2 has always same extension
{
MAB::mInit = true;
mCont.clear();
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
}
assert(mCont.size() == MAB::mRange->size());
}
*/
/*
template <typename T, class... SRanges>
template <class Range2, class Range3>
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const MultiArray<MultiArray<T,Range2>,Range3> in)
{
MAB::mRange.reset(new Range(merge(in.range(), in[ in.beginIndex() ].range())));
// assert that Range2 has always same extension
mCont.clear();
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
}
assert(mCont.size() == MAB::mRange->size());
return *this;
} */
template <typename T, class... SRanges>
T& MultiArray<T,SRanges...>::operator[](const IndexType& i)
{
return mCont[ i.pos() ];
}
template <typename T, class... SRanges>
const T& MultiArray<T,SRanges...>::operator[](const IndexType& i) const
{
return mCont[ i.pos() ];
}
template <typename T, class... SRanges>
T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta)
{
return mCont[ MAB::beginIndex().at(meta).pos() ];
}
template <typename T, class... SRanges>
const T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta) const
{
return mCont[ MAB::beginIndex().at(meta).pos() ];
}
template <typename T, class... SRanges>
bool MultiArray<T,SRanges...>::isConst() const
{
return false;
}
template <typename T, class... SRanges>
bool MultiArray<T,SRanges...>::isSlice() const
{
return false;
}
template <typename T, class... SRanges>
template <class... SRanges2>
MultiArray<T,SRanges2...> MultiArray<T,SRanges...>::format(const std::shared_ptr<SRanges2>&... nrs)
{
//MAB::mInit = false;
return MultiArray<T,SRanges2...>( nrs... , mCont );
}
template <typename T, class... SRanges>
template <class... SRanges2>
MultiArray<T,SRanges2...> MultiArray<T,SRanges...>::format(const std::tuple<std::shared_ptr<SRanges2>...>& nrs)
{
//MAB::mInit = false;
return MultiArray<T,SRanges2...>( nrs , mCont );
}
template <typename T, class... SRanges>
template <class... SRanges2>
Slice<T,SRanges2...> MultiArray<T,SRanges...>::slformat(const std::shared_ptr<SRanges2>&... nrs)
{
return Slice<T,SRanges2...>( nrs..., mCont.data() );
}
template <typename T, class... SRanges>
template <class... SRanges2>
ConstSlice<T,SRanges2...> MultiArray<T,SRanges...>::slformat(const std::shared_ptr<SRanges2>&... nrs) const
{
return ConstSlice<T,SRanges2...>( nrs..., mCont.data() );
}
template <typename T, class... SRanges>
const T* MultiArray<T,SRanges...>::data() const
{
return mCont.data();
}
template <typename T, class... SRanges>
T* MultiArray<T,SRanges...>::data()
{
return mCont.data();
}
template <typename T, class... SRanges>
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymous(bool slice) const
{
AnonymousRangeFactory arf(MAB::mRange->space());
if(slice){
return std::make_shared<ConstSlice<T,AnonymousRange> >
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
data() );
}
else {
return std::make_shared<MultiArray<T,AnonymousRange> >
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
mCont );
}
}
/*
template <typename T, class... SRanges>
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymousMove()
{
AnonymousRangeFactory arf(MAB::mRange->space());
MAB::mInit = false;
return std::make_shared<MultiArray<T,AnonymousRange> >
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
std::move(mCont) );
}
*/
template <typename T, class... SRanges>
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const T& in)
{
for(auto& x: mCont){
x = in;
}
return *this;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator+=(const MultiArray& in)
{
if(not MAB::mInit){ // not initialized by default constructor !!
(*this) = in;
}
else {
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
for(size_t i = 0; i != mCont.size(); ++i){
mCont[i] += in.mCont[i];
}
//std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::plus<T>());
}
return *this;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator-=(const MultiArray& in)
{
if(not MAB::mInit){ // not initialized by default constructor !!
(*this) = in;
}
else {
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
for(size_t i = 0; i != mCont.size(); ++i){
mCont[i] -= in.mCont[i];
}
//std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::minus<T>());
}
return *this;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator*=(const T& in)
{
for(auto& x: mCont){
x *= in;
}
return *this;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator/=(const T& in)
{
for(auto& x: mCont){
x /= in;
}
return *this;
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::operator T() const
{
//static_assert( sizeof...(SRanges) == 1, "try to cast non-scalar type into scalar" );
// TODO: check that SIZE is statically = 1 !!!
return mCont[0];
}
template <typename T, class... SRanges>
auto MultiArray<T,SRanges...>::cat() const
-> decltype(ArrayCatter<T>::cat(*this))
{
return ArrayCatter<T>::cat(*this);
}
}

View file

@ -1,151 +0,0 @@
// -*- C++ -*-
#ifndef __multi_array_h__
#define __multi_array_h__
#include <algorithm>
#include "multi_array_base.h"
#include "ranges/anonymous_range.h"
namespace MultiArrayTools
{
template <typename T>
struct ArrayCatter;
template <typename T>
struct ArrayCatter
{
template <class... Ranges>
static auto cat(const MultiArray<T,Ranges...>& ma)
-> MultiArray<T,Ranges...>
{
return ma;
}
};
template <typename T, class... SRanges>
class MultiArray : public MutableMultiArrayBase<T,SRanges...>
{
public:
typedef ContainerRange<T,SRanges...> CRange;
typedef MultiArrayBase<T,SRanges...> MAB;
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
using MultiArrayBase<T,SRanges...>::operator[];
using MutableMultiArrayBase<T,SRanges...>::operator[];
DEFAULT_MEMBERS(MultiArray);
MultiArray(const std::shared_ptr<SRanges>&... ranges);
MultiArray(const std::shared_ptr<SRanges>&... ranges, const T& val);
MultiArray(const std::shared_ptr<SRanges>&... ranges, const vector<T>& vec);
MultiArray(const std::shared_ptr<SRanges>&... ranges, vector<T>&& vec);
template <class... Ranges>
MultiArray(const std::shared_ptr<SRanges>&... ranges, MultiArray<T,Ranges...>&& in); // same effect as format
MultiArray(const typename CRange::Space& space);
MultiArray(const typename CRange::Space& space, const vector<T>& vec);
MultiArray(MultiArray<T,AnonymousRange>&& ama, SIZET<SRanges>... sizes);
// Only if ALL ranges have default extensions:
//MultiArray(const vector<T>& vec);
//MultiArray(vector<T>&& vec);
// template <class Range2, class Range3>
// MultiArray(const MultiArray<MultiArray<T,Range2>,Range3> in);
// implement contstructor using FunctionalMultiArray as Input !!!
//template <class Range2, class Range3>
//MultiArray& operator=(const MultiArray<MultiArray<T,Range2>,Range3> in);
virtual T& operator[](const IndexType& i) final;
virtual const T& operator[](const IndexType& i) const final;
virtual T& at(const typename IndexType::MetaType& meta) override;
virtual const T& at(const typename IndexType::MetaType& meta) const override;
virtual bool isConst() const override;
virtual bool isSlice() const override;
template <class... SRanges2>
MultiArray<T,SRanges2...> format(const std::shared_ptr<SRanges2>&... nrs); // reformat array using 'nr' which in
// total must have the same size as mRange
template <class... SRanges2>
MultiArray<T,SRanges2...> format(const std::tuple<std::shared_ptr<SRanges2>...>& nrs);
template <class... SRanges2>
Slice<T,SRanges2...> slformat(const std::shared_ptr<SRanges2>&... nrs);
template <class... SRanges2>
ConstSlice<T,SRanges2...> slformat(const std::shared_ptr<SRanges2>&... nrs) const;
virtual const T* data() const override;
virtual T* data() override;
virtual vector<T>& vdata() { return mCont; }
virtual const vector<T>& vdata() const { return mCont; }
vector<T>&& vmove() { MAB::mInit = false; return std::move(mCont); }
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const override;
//virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymousMove() override;
auto cat() const
-> decltype(ArrayCatter<T>::cat(*this));
operator T() const;
MultiArray& operator=(const T& in);
MultiArray& operator+=(const MultiArray& in);
MultiArray& operator-=(const MultiArray& in);
MultiArray& operator*=(const T& in);
MultiArray& operator/=(const T& in);
template <typename U, class... SRanges2>
friend class MultiArray;
private:
vector<T> mCont;
};
template <typename T>
using Scalar = MultiArray<T,NullRange>;
template <typename T>
Scalar<T> scalar(const T& in);
template <typename T, class... ERanges>
struct ArrayCatter<MultiArray<T,ERanges...> >
{
template <class... Ranges>
static auto cat(const MultiArray<MultiArray<T,ERanges...>,Ranges...>& ma)
-> MultiArray<T,Ranges...,ERanges...>
{
auto sma = *ma.begin();
const size_t smas = sma.size();
const size_t mas = ma.size();
auto cr = ma.range()->cat(sma.range());
vector<T> ov;
ov.reserve(mas * smas);
for(auto& x: ma){
assert(x.size() == smas);
ov.insert(ov.end(), x.vdata().begin(), x.vdata().end());
}
return MultiArray<T,Ranges...,ERanges...>(cr->space(), std::move(ov));
}
};
}
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
#endif

View file

@ -1,281 +0,0 @@
#include "multi_array_base.h"
namespace MultiArrayTools
{
/**********************
* MultiArrayBase *
**********************/
template <typename T, class... SRanges>
MultiArrayBase<T,SRanges...>::MultiArrayBase(const MultiArrayBase& in) :
mInit(in.mInit),
mRange(in.mRange)
{
if(mRange){
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
}
}
template <typename T, class... SRanges>
MultiArrayBase<T,SRanges...>::MultiArrayBase(MultiArrayBase&& in) :
mInit(in.mInit),
mRange(in.mRange)
{
if(mRange){
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
}
}
template <typename T, class... SRanges>
MultiArrayBase<T,SRanges...>& MultiArrayBase<T,SRanges...>::operator=(const MultiArrayBase& in)
{
mInit = in.mInit;
mRange = in.mRange;
if(mRange){
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
}
return *this;
}
template <typename T, class... SRanges>
MultiArrayBase<T,SRanges...>& MultiArrayBase<T,SRanges...>::operator=(MultiArrayBase&& in)
{
mInit = in.mInit;
mRange = in.mRange;
if(mRange){
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
}
return *this;
}
template <typename T, class... SRanges>
MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges)
{
ContainerRangeFactory<T,SRanges...> crf(ranges...);
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
}
template <typename T, class... SRanges>
MultiArrayBase<T,SRanges...>::MultiArrayBase(const typename CRange::Space& space)
{
ContainerRangeFactory<T,SRanges...> crf(space);
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
}
template <typename T, class... SRanges>
template <typename X>
const T& MultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
{
IndexType ii(*mProtoI);
ii = i;
return (*this)[ii];
}
template <typename T, class... SRanges>
const T& MultiArrayBase<T,SRanges...>::operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is) const
{
IndexType ii(*mProtoI);
ii(is);
return (*this)[ii];
}
template <typename T, class... SRanges>
size_t MultiArrayBase<T,SRanges...>::size() const
{
return mRange->size();
}
template <typename T, class... SRanges>
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const
{
IndexType i(*mProtoI,true);
i = 0;
return i.setData(data());
}
template <typename T, class... SRanges>
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const
{
IndexType i(*mProtoI,true);
i = i.max();
//i = mRange->size();
return i.setData(data());
}
template <typename T, class... SRanges>
typename MultiArrayBase<T,SRanges...>::IndexType
MultiArrayBase<T,SRanges...>::beginIndex() const
{
IndexType i(*mProtoI,true);
i = 0;
return i.setData(data());
}
template <typename T, class... SRanges>
typename MultiArrayBase<T,SRanges...>::IndexType
MultiArrayBase<T,SRanges...>::endIndex() const
{
IndexType i(*mProtoI,true);
i = i.max();
//i = mRange->size();
return i.setData(data());
}
template <typename T, class... SRanges>
const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>&
MultiArrayBase<T,SRanges...>::range() const
{
return mRange;
}
template <typename T, class... SRanges>
bool MultiArrayBase<T,SRanges...>::isConst() const
{
return true;
}
template <typename T, class... SRanges>
ConstOperationRoot<T,SRanges...>
MultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
{
return ConstOperationRoot<T,SRanges...>(*this, inds...);
}
template <typename T, class... SRanges>
ConstOperationRoot<T,SRanges...>
MultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
{
return ConstOperationRoot<T,SRanges...>(data(), *ind);
}
template <typename T, class... SRanges>
template <class... MappedRanges>
ConstOperationRoot<T,MappedRanges...>
MultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
{
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
"number of mapped ranges must be equal to number of original ranges");
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
}
template <typename T, class... SRanges>
bool MultiArrayBase<T,SRanges...>::isInit() const
{
return mInit;
}
template <typename T, class... SRanges>
template <size_t N>
auto MultiArrayBase<T,SRanges...>::getRangePtr() const
-> decltype(mRange->template getPtr<N>())
{
return mRange->template getPtr<N>();
}
/******************************
* MutableMultiArrayBase *
******************************/
template <typename T, class... SRanges>
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) :
MultiArrayBase<T,SRanges...>(ranges...) {}
template <typename T, class... SRanges>
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const typename CRange::Space& space) :
MultiArrayBase<T,SRanges...>(space) {}
/*
template <typename T, class... SRanges>
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin()
{
auto i = mRange->begin();
return i.setData(data());
}
template <typename T, class... SRanges>
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end()
{
auto i = mRange->end();
return i.setData(data());
}
*/
template <typename T, class... SRanges>
template <typename X>
T& MutableMultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
{
IndexType ii(*MAB::mProtoI);
ii = i;
return (*this)[ii];
}
template <typename T, class... SRanges>
T& MutableMultiArrayBase<T,SRanges...>::operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is)
{
IndexType ii(*MAB::mProtoI);
ii(is);
return (*this)[ii];
}
template <typename T, class... SRanges>
bool MutableMultiArrayBase<T,SRanges...>::isConst() const
{
return false;
}
template <typename T, class... SRanges>
OperationRoot<T,SRanges...>
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds)
{
return OperationRoot<T,SRanges...>(*this, inds...);
}
template <typename T, class... SRanges>
OperationRoot<T,SRanges...>
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind)
{
return OperationRoot<T,SRanges...>(data(), *ind);
}
template <typename T, class... SRanges>
ConstOperationRoot<T,SRanges...>
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
{
return ConstOperationRoot<T,SRanges...>(*this, inds...);
}
template <typename T, class... SRanges>
ConstOperationRoot<T,SRanges...>
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
{
return ConstOperationRoot<T,SRanges...>(data(), *ind);
}
template <typename T, class... SRanges>
template <class... MappedRanges>
OperationRoot<T,MappedRanges...>
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds)
{
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
"number of mapped ranges must be equal to number of original ranges");
return OperationRoot<T,MappedRanges...>(*this, inds...);
}
template <typename T, class... SRanges>
template <class... MappedRanges>
ConstOperationRoot<T,MappedRanges...>
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
{
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
"number of mapped ranges must be equal to number of original ranges");
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
}
} // end namespace MultiArrayTools

View file

@ -1,187 +0,0 @@
#ifndef __multi_array_base_h__
#define __multi_array_base_h__
#include <cstdlib>
#include <vector>
#include <memory>
#include <iterator>
#include <algorithm>
#include "base_def.h"
#include "mbase_def.h"
#include "ranges/rheader.h"
namespace MultiArrayTools
{
template <class IndexType>
using IPTR = std::shared_ptr<IndexType>;
template <class IndexType1, class IndexType2>
inline auto operator|(const IPTR<IndexType1>& i1, const IPTR<IndexType2>& i2)
-> decltype(std::make_tuple(i1,i2))
{
return std::make_tuple(i1,i2);
}
template <class IndexType1, class... IndexTypes2>
inline auto operator|(const IPTR<IndexType1>& i1,
const std::tuple<IPTR<IndexTypes2>...>& i2)
-> decltype(std::tuple_cat(std::make_tuple(i1),i2))
{
return std::tuple_cat(std::make_tuple(i1),i2);
}
template <class IndexType2, class... IndexTypes1>
inline auto operator|(const std::tuple<IPTR<IndexTypes1>...>& i1,
const IPTR<IndexType2>& i2)
-> decltype(std::tuple_cat(i1,std::make_tuple(i2)))
{
return std::tuple_cat(i1,std::make_tuple(i2));
}
template <class IndexType>
inline auto operator~(const IPTR<IndexType>& i)
-> decltype(std::make_tuple(i))
{
return std::make_tuple(i);
}
// Explicitely specify subranges in template argument !!!
template <typename T, class... SRanges>
class MultiArrayBase
{
public:
typedef T value_type;
typedef ContainerRange<T,SRanges...> CRange;
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
protected:
bool mInit = false;
std::shared_ptr<CRange> mRange;
std::shared_ptr<IndexType> mProtoI;
public:
//DEFAULT_MEMBERS(MultiArrayBase);
MultiArrayBase(const std::shared_ptr<SRanges>&... ranges);
MultiArrayBase(const typename CRange::Space& space);
MultiArrayBase() = default;
MultiArrayBase(const MultiArrayBase& in);
MultiArrayBase(MultiArrayBase&& in);
MultiArrayBase& operator=(const MultiArrayBase& in);
MultiArrayBase& operator=(MultiArrayBase&& in);
virtual ~MultiArrayBase() = default;
template <typename X>
const T& operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i);
const T& operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is) const;
virtual const T& operator[](const IndexType& i) const = 0;
virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0;
virtual const T* data() const = 0;
virtual size_t size() const;
virtual bool isSlice() const = 0;
virtual IndexType begin() const;
virtual IndexType end() const;
virtual IndexType beginIndex() const;
virtual IndexType endIndex() const;
virtual const std::shared_ptr<CRange>& range() const;
virtual bool isConst() const;
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const = 0;
virtual ConstOperationRoot<T,SRanges...>
op(const std::shared_ptr<IndexType>& ind) const;
virtual ConstOperationRoot<T,SRanges...>
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const;
template <class... MappedRanges>
ConstOperationRoot<T,MappedRanges...>
m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const;
virtual bool isInit() const;
template <size_t N>
auto getRangePtr() const
-> decltype(mRange->template getPtr<N>());
};
template <typename T, class... SRanges>
class MutableMultiArrayBase : public MultiArrayBase<T,SRanges...>
{
public:
typedef ContainerRange<T,SRanges...> CRange;
typedef MultiArrayBase<T,SRanges...> MAB;
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
using MultiArrayBase<T,SRanges...>::operator[];
using MultiArrayBase<T,SRanges...>::at;
using MultiArrayBase<T,SRanges...>::data;
using MultiArrayBase<T,SRanges...>::begin;
using MultiArrayBase<T,SRanges...>::end;
DEFAULT_MEMBERS(MutableMultiArrayBase);
MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges);
MutableMultiArrayBase(const typename CRange::Space& space);
template <typename X>
T& operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i);
T& operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is);
virtual T& operator[](const IndexType& i) = 0;
virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0;
virtual T* data() = 0;
//virtual IndexType begin();
//virtual IndexType end();
virtual bool isConst() const override;
//virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymousMove() = 0;
virtual ConstOperationRoot<T,SRanges...>
op(const std::shared_ptr<IndexType>& ind) const override;
virtual ConstOperationRoot<T,SRanges...>
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const override;
virtual OperationRoot<T,SRanges...>
op(const std::shared_ptr<IndexType>& ind);
virtual OperationRoot<T,SRanges...> operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds);
template <class... MappedRanges>
OperationRoot<T,MappedRanges...>
m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds);
template <class... MappedRanges>
ConstOperationRoot<T,MappedRanges...>
m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const;
};
} // end namespace MultiArrayTools
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
#endif

View file

@ -1,14 +0,0 @@
#include "ranges/ranges_header.cc.h"
#include "multi_array_operation.cc.h"
#include "functional_multi_array.cc.h"
#include "helper_tools.cc.h"
#include "map_range.cc.h"
#include "multi_array_base.cc.h"
#include "multi_array.cc.h"
#include "slice.cc.h"
#include "dynamic_operation.cc.h"
#include "high_level_operation.cc.h"
//#include "expressions.cc.h"

View file

@ -1,20 +0,0 @@
// -*- C++ -*-
#ifndef __multi_array_header_h__
#define __multi_array_header_h__
#include <cstdlib>
#include "multi_array_operation.h"
#include "multi_array_base.h"
#include "multi_array.h"
#include "functional_multi_array.h"
#include "helper_tools.h"
#include "operation_def.h"
#include "map_range.h"
#include "dynamic_operation.h"
#include "high_level_operation.h"
//#include "expressions.h"
#include "multi_array_header.cc.h"
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,851 +0,0 @@
// -*- C++ -*-
#ifndef __multi_array_operation_h__
#define __multi_array_operation_h__
#include <cstdlib>
#include <tuple>
#include <cmath>
#include <map>
#include <utility>
#include "base_def.h"
#include "mbase_def.h"
#include "ranges/rheader.h"
#include "pack_num.h"
#include "arith.h"
#include "xfor/xfor.h"
namespace MultiArrayTools
{
namespace
{
using namespace MultiArrayHelper;
}
template <typename T, class OperationClass>
class OperationBase
{
public:
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
template <typename U, class Second>
auto operator+(const OperationBase<U,Second>& in) const;
template <typename U, class Second>
auto operator-(const OperationBase<U,Second>& in) const;
template <typename U, class Second>
auto operator*(const OperationBase<U,Second>& in) const;
template <typename U, class Second>
auto operator/(const OperationBase<U,Second>& in) const;
template <class IndexType>
auto c(const std::shared_ptr<IndexType>& ind) const
-> Contraction<T,OperationClass,IndexType>;
template <class... Indices>
auto sl(const std::shared_ptr<Indices>&... inds) const
-> ConstSlice<T,typename Indices::RangeType...>;
template <class... Indices>
auto slc(const std::shared_ptr<Indices>&... inds) const
-> SliceContraction<T,OperationClass,Indices...>;
template <class... Indices>
auto p(const std::shared_ptr<Indices>&... inds) const
-> ConstOperationRoot<T,typename Indices::RangeType...>;
template <class... Indices>
auto to(const std::shared_ptr<Indices>&... inds) const
-> MultiArray<T,typename Indices::RangeType...>;
template <class... Indices>
auto addto(const std::shared_ptr<Indices>&... inds) const
-> MultiArray<T,typename Indices::RangeType...>;
template <class... Indices>
auto pto(const std::shared_ptr<Indices>&... inds) const
-> MultiArray<T,typename Indices::RangeType...>;
template <class... Indices>
auto paddto(const std::shared_ptr<Indices>&... inds) const
-> MultiArray<T,typename Indices::RangeType...>;
template <typename R, class... Args> // Args = Operation Classes
auto a(const std::shared_ptr<function<R,T,typename Args::value_type...>>& ll, const Args&... args) const
-> Operation<R,function<R,T,typename Args::value_type...>,OperationClass, Args...>;
auto ptr() const
-> OperationPointer<T,OperationClass>;
private:
friend OperationClass;
friend OperationTemplate<T,OperationClass>;
OperationBase() = default;
};
template <typename T, class OperationClass>
class OperationTemplate : public OperationBase<T,OperationClass>
{
/* empty per default; specialize if needed */
private:
OperationTemplate() = default;
friend OperationClass;
};
template <class Op>
size_t sumRootNum()
{
return typename Op::rootNum();
}
template <class Op1, class Op2, class... Ops>
size_t sumRootNum()
{
return typename Op1::rootNum() + sumRootNum<Op2,Ops...>();
}
template <size_t N>
struct RootSumN
{
template <class Op1, class... Ops>
struct rs
{
static constexpr size_t SIZE = Op1::SIZE + RootSumN<N-1>::template rs<Ops...>::SIZE;
};
template <class... Exprs>
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
{
return RootSumN<N-1>::rootSteps(etp,i).extend( std::get<N>(etp).rootSteps(i) );
}
template <class ExtType, class... Exprs>
static inline void exec( size_t start, ExtType last, std::tuple<Exprs...>& etp)
{
std::get<sizeof...(Exprs)-N-1>(etp)(start,last);
RootSumN<N-1>::exec(start,last.next(),etp);
}
template <class ExtType, class... Exprs>
static inline size_t get( ExtType last, const std::tuple<Exprs...>& etp)
{
std::get<sizeof...(Exprs)-N-1>(etp).get(last);
return RootSumN<N-1>::get(last.next(),etp);
}
template <class ExtType, class... Exprs>
static inline void set( ExtType last, std::tuple<Exprs...>& etp)
{
std::get<sizeof...(Exprs)-N-1>(etp).set(last);
RootSumN<N-1>::set(last.next(),etp);
}
};
template <>
struct RootSumN<0>
{
template <class Op1>
struct rs
{
static constexpr size_t SIZE = Op1::SIZE;
};
template <class... Exprs>
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
{
return std::get<0>(etp).rootSteps(i);
}
template <class ExtType, class... Exprs>
static inline void exec( size_t start, ExtType last, std::tuple<Exprs...>& etp)
{
std::get<sizeof...(Exprs)-1>(etp)(start,last);
}
template <class ExtType, class... Exprs>
static inline size_t get( ExtType last, const std::tuple<Exprs...>& etp)
{
std::get<sizeof...(Exprs)-1>(etp).get(last);
return 0;
}
template <class ExtType, class... Exprs>
static inline void set( ExtType last, std::tuple<Exprs...>& etp)
{
std::get<sizeof...(Exprs)-1>(etp).set(last);
}
};
template <class... Ops>
struct RootSum
{
static constexpr size_t SIZE = RootSumN<sizeof...(Ops)-1>::template rs<Ops...>::SIZE;
};
template <typename T>
struct SelfIdentity
{
static inline T& sapply(T& a, T b)
{
return a = b;
}
};
enum class OpIndexAff {
EXTERN = 0,
TARGET = 1
};
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
class AssignmentExpr2 : public ExpressionBase
{
private:
AssignmentExpr2() = default;
Target mTar;
OpClass mSec;
T* mDataPtr;
public:
static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = Target::SIZE + OpClass::SIZE;
typedef decltype(mTar.rootSteps(0).extend( mSec.rootSteps(0) )) ExtType;
AssignmentExpr2(T* dataPtr, const Target& tar, const OpClass& sec);
AssignmentExpr2(const AssignmentExpr2& in) = default;
AssignmentExpr2(AssignmentExpr2&& in) = default;
AssignmentExpr2& operator=(const AssignmentExpr2& in) = default;
AssignmentExpr2& operator=(AssignmentExpr2&& in) = default;
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<AssignmentExpr2<T,Target,OpClass,OIA>>(*this);
}
inline void operator()(size_t start = 0);
inline void operator()(size_t start, ExtType last);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
inline void operator()(size_t mlast, DExt last) override final;
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
inline DExt dExtension() const override final;
};
template <typename T, class... Ops>
class MOp
{
private:
MOp() = default;
std::tuple<Ops...> mOps;
public:
static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
typedef decltype(RootSumN<sizeof...(Ops)-1>::rootSteps(mOps,0) ) ExtType;
MOp(const Ops&... exprs);
MOp(const MOp& in) = default;
MOp(MOp&& in) = default;
MOp& operator=(const MOp& in) = default;
MOp& operator=(MOp&& in) = default;
inline size_t get(ExtType last) const;
inline MOp& set(ExtType last);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
template <class Expr>
auto loop(Expr exp) const
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
T* data() const { assert(0); return nullptr; }
};
template <class OpClass, class NextExpr>
class GetExpr : public ExpressionBase
{
private:
GetExpr() = default;
OpClass mSec;
NextExpr mNExpr;
public:
static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = OpClass::SIZE + NextExpr::SIZE;
typedef decltype(mSec.rootSteps(0).extend( mNExpr.rootSteps(0) ) ) ExtType;
GetExpr(const OpClass& sec, const NextExpr& nexpr);
GetExpr(const GetExpr& in) = default;
GetExpr(GetExpr&& in) = default;
GetExpr& operator=(const GetExpr& in) = default;
GetExpr& operator=(GetExpr&& in) = default;
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<GetExpr<OpClass,NextExpr>>(*this);
}
inline void operator()(size_t start = 0);
inline void get(ExtType last);
inline void operator()(size_t start, ExtType last);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
inline void operator()(size_t mlast, DExt last) override final;
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
inline DExt dExtension() const override final;
};
template <class OpClass, class NextExpr>
auto mkGetExpr(const OpClass& op, const NextExpr& nexpr)
{
return GetExpr<OpClass,NextExpr>(op, nexpr);
}
template <typename T, class... Ops>
auto mkMOp(const Ops&... exprs)
{
return MOp<T,Ops...>(exprs...);
}
//template <typename T, class OpClass>
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
class AddExpr : public ExpressionBase
{
private:
AddExpr() = default;
Target mTar;
OpClass mSec;
T* mDataPtr;
public:
static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = Target::SIZE + OpClass::SIZE;
typedef decltype(mTar.rootSteps(0).extend( mSec.rootSteps(0) )) ExtType;
// static constexpr size_t LAYER = 0;
//static constexpr size_t SIZE = OpClass::SIZE;
//typedef decltype(mSec.rootSteps()) ExtType;
//AddExpr(T* dataPtr, const OpClass& sec);
AddExpr(T* dataPtr, const Target& tar, const OpClass& sec);
AddExpr(const AddExpr& in) = default;
AddExpr(AddExpr&& in) = default;
AddExpr& operator=(const AddExpr& in) = default;
AddExpr& operator=(AddExpr&& in) = default;
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<AddExpr<T,Target,OpClass,OIA>>(*this);
}
inline void operator()(size_t start = 0);
inline void operator()(size_t start, ExtType last);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
inline void operator()(size_t mlast, DExt last) override final;
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
inline DExt dExtension() const override final;
};
template <typename T, class... Ranges>
class ConstOperationRoot : public OperationTemplate<T,ConstOperationRoot<T,Ranges...> >
{
public:
typedef T value_type;
typedef OperationBase<T,ConstOperationRoot<T,Ranges...> > OT;
typedef ContainerRange<T,Ranges...> CRange;
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices);
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
const std::shared_ptr<typename Ranges::IndexType>&... indices);
ConstOperationRoot(const T* data, const IndexType& ind);
template <class ET>
inline const T& get(ET pos) const;
template <class ET>
inline ConstOperationRoot& set(ET pos);
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
template <class Expr>
Expr loop(Expr exp) const;
const T* data() const;
private:
const T* mDataPtr;
const T* mOrigDataPtr;
IndexType mIndex;
std::shared_ptr<MultiArrayBase<T,Ranges...> > mMaPtr; // never remove this ptr, otherwise we lose temporary container instances!
};
template <typename T, class Op>
class StaticCast : public OperationTemplate<T,StaticCast<T,Op> >
{
private:
Op mOp;
public:
typedef T value_type;
typedef OperationBase<T,StaticCast<T,Op> > OT;
typedef typename Op::CRange CRange;
typedef typename Op::IndexType IndexType;
static constexpr size_t SIZE = Op::SIZE;
static constexpr bool CONT = false;
StaticCast(const Op& op);
template <class ET>
inline T get(ET pos) const;
template <class ET>
inline StaticCast& set(ET pos);
auto rootSteps(std::intptr_t iPtrNum = 0) const
-> decltype(mOp.rootSteps(iPtrNum));
template <class Expr>
Expr loop(Expr exp) const;
};
template <typename T, class Op>
StaticCast<T,Op> staticcast(const Op& op)
{
return StaticCast<T,Op>(op);
}
template <class Range>
class MetaOperationRoot : public OperationTemplate<typename Range::MetaType,
MetaOperationRoot<Range> >
{
public:
typedef typename Range::IndexType IndexType;
typedef typename IndexType::MetaType value_type;
typedef OperationBase<value_type,MetaOperationRoot<Range> > OT;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = false;
MetaOperationRoot(const std::shared_ptr<IndexType>& ind);
template <class ET>
inline value_type get(ET pos) const;
template <class ET>
inline MetaOperationRoot& set(ET pos);
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
template <class Expr>
Expr loop(Expr exp) const;
private:
mutable IndexType mWorkIndex;
std::shared_ptr<IndexType> mIndex;
};
template <typename T, class... Ranges>
class OperationRoot : public OperationTemplate<T,OperationRoot<T,Ranges...> >
{
public:
typedef T value_type;
typedef OperationBase<T,OperationRoot<T,Ranges...> > OT;
typedef ContainerRange<T,Ranges...> CRange;
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
private:
T* mDataPtr;
T* mOrigDataPtr;
IndexType mIndex;
public:
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices);
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
const std::tuple<std::shared_ptr<typename Ranges::IndexType>...>& indices);
OperationRoot(T* data, const IndexType& ind);
template <class OpClass>
auto assign(const OpClass& in) const
-> decltype(mIndex.ifor(1,in.loop(AssignmentExpr2<T,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in))));
template <class OpClass>
auto assignExpr(const OpClass& in) const
-> decltype(in.loop(AssignmentExpr2<T,OperationRoot<T,Ranges...>,OpClass>(mOrigDataPtr,*this,in)));
template <class OpClass, class Index>
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const
-> decltype(i->ifor(1,in.loop(AssignmentExpr2<T,OperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in))));
template <class OpClass>
auto plus(const OpClass& in) const
-> decltype(mIndex.ifor(1,in.loop(AddExpr<T,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in))));
template <class OpClass, class Index>
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const
-> decltype(i->ifor(1,in.loop(AddExpr<T,OperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in))));
template <class OpClass>
OperationRoot& operator=(const OpClass& in);
template <class OpClass>
OperationRoot& operator+=(const OpClass& in);
OperationRoot& operator=(const OperationRoot& in);
ParallelOperationRoot<T,Ranges...> par();
template <class ET>
inline T& get(ET pos) const;
template <class ET>
inline OperationRoot& set(ET pos);
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
template <class Expr>
Expr loop(Expr exp) const;
T* data() const;
template <class... Indices>
auto sl(const std::shared_ptr<Indices>&... inds)
-> Slice<T,typename Indices::RangeType...>;
};
template <typename T, class... Ranges>
class ParallelOperationRoot : public OperationTemplate<T,ParallelOperationRoot<T,Ranges...> >
{
public:
typedef T value_type;
typedef OperationBase<T,ParallelOperationRoot<T,Ranges...> > OT;
typedef ContainerRange<T,Ranges...> CRange;
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
private:
T* mDataPtr;
T* mOrigDataPtr;
IndexType mIndex;
public:
ParallelOperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices);
ParallelOperationRoot(T* data, const IndexType& ind);
template <class OpClass>
auto assign(const OpClass& in)
-> decltype(mIndex.pifor(1,in.loop(AssignmentExpr2<T,ParallelOperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in))));
template <class OpClass, class Index>
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const
-> decltype(i->pifor(1,in.loop(AssignmentExpr2<T,ParallelOperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in))));
template <class OpClass>
auto plus(const OpClass& in)
-> decltype(mIndex.pifor(1,in.loop(AddExpr<T,ParallelOperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in))));
template <class OpClass, class Index>
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const
-> decltype(i->pifor(1,in.loop(AddExpr<T,ParallelOperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in))));
template <class OpClass>
ParallelOperationRoot& operator=(const OpClass& in);
template <class OpClass>
ParallelOperationRoot& operator+=(const OpClass& in);
ParallelOperationRoot& operator=(const ParallelOperationRoot& in);
template <class ET>
inline T& get(ET pos) const;
template <class ET>
inline ParallelOperationRoot& set(ET pos);
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
template <class Expr>
Expr loop(Expr exp) const;
T* data() const;
};
template <typename T>
class OperationValue : public OperationTemplate<T,OperationValue<T> >
{
public:
typedef T value_type;
typedef OperationBase<T,OperationValue<T> > OT;
typedef ContainerRange<T,NullRange> CRange;
typedef ContainerIndex<T,NullIndex> IndexType;
static constexpr size_t SIZE = 0;
static constexpr bool CONT = true;
OperationValue(const T& val);
template <class ET>
inline const T& get(ET pos) const;
template <class ET>
inline OperationValue& set(ET pos);
None rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
template <class Expr>
Expr loop(Expr exp) const;
private:
T mVal;
};
template <typename T, class Op>
class OperationPointer : public OperationTemplate<const T*,OperationPointer<T,Op>>
{
public:
typedef T value_type;
typedef OperationTemplate<const T*,OperationPointer<T,Op>> OT;
static constexpr size_t SIZE = Op::SIZE;
static constexpr bool CONT = false;
private:
Op mOp;
public:
OperationPointer(const Op& op) : mOp(op)
{
static_assert(Op::CONT,
"OperationPointer can only be applied to containing operations");
}
template <class ET>
inline const T* get(ET pos) const;
template <class ET>
inline OperationPointer& set(ET pos);
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
-> decltype(mOp.rootSteps(0));
template <class Expr>
auto loop(Expr exp) const
-> decltype(mOp.loop(exp));
T const** data() const { assert(0); return nullptr; }
};
template <typename T, class OpFunction, class... Ops>
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
{
public:
typedef T value_type;
typedef OperationBase<T,Operation<T,OpFunction,Ops...> > OT;
typedef OpFunction F;
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
static constexpr bool FISSTATIC = OpFunction::FISSTATIC;
static constexpr bool CONT = false;
private:
std::tuple<Ops...> mOps;
std::shared_ptr<OpFunction> mF; // only if non-static
public:
typedef decltype(PackNum<sizeof...(Ops)-1>::template mkSteps<Ops...>(0, mOps)) ETuple;
Operation(const Ops&... ops);
Operation(std::shared_ptr<OpFunction> ff, const Ops&... ops);
template <class ET>
inline auto get(ET pos) const;
template <class ET>
inline Operation& set(ET pos);
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps));
template <class Expr>
auto loop(Expr exp) const
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
T* data() const { assert(0); return nullptr; }
};
namespace
{
template <bool FISSTATIC>
struct OpMaker
{
template <class OpFunction, class... Ops>
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
{
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(f,ops...);
}
};
template <>
struct OpMaker<true>
{
template <class OpFunction, class... Ops>
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
{
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(ops...);
}
};
}
template <class OpFunction, class... Ops>
auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
{
return OpMaker<OpFunction::FISSTATIC>::mkOperation(f, ops...);
}
template <typename T, class Op, class IndexType>
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
{
public:
typedef T value_type;
typedef OperationBase<T,Contraction<T,Op,IndexType> > OT;
static constexpr size_t SIZE = Op::SIZE;
static constexpr bool CONT = Op::CONT;
private:
Op mOp;
std::shared_ptr<IndexType> mInd;
public:
typedef decltype(mOp.rootSteps(0)) ETuple;
Contraction(const Op& op, std::shared_ptr<IndexType> ind);
template <class ET>
inline auto get(ET pos) const
-> decltype(mOp.template get<ET>(pos));
template <class ET>
inline Contraction& set(ET pos);
T* data() const { assert(0); return nullptr; }
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
-> decltype(mOp.rootSteps(iPtrNum));
template <class Expr>
auto loop(Expr exp) const
-> decltype(mInd->iforh(1,mOp.loop(exp)));
};
template <typename T, class Op, class... Indices>
// class SliceContraction : public OperationTemplate
//<MultiArray<T,typename Indices::RangeType...>,
//SliceContraction<MultiArray<T,typename Indices::RangeType...>,Op,Indices...> >
class SliceContraction : public OperationTemplate<T,SliceContraction<T,Op,Indices...> >
{
public:
typedef MultiArray<T,typename Indices::RangeType...> value_type;
typedef OperationTemplate<T,SliceContraction<T,Op,Indices...> > OT;
static constexpr size_t SIZE = Op::SIZE;
static constexpr bool CONT = false;
private:
mutable Op mOp;
mutable std::shared_ptr<MultiArray<T,typename Indices::RangeType...> > mCont;
mutable OperationRoot<T,typename Indices::RangeType...> mTarOp;
public:
typedef decltype(mOp.rootSteps(0)) ETuple;
SliceContraction(const Op& op, std::shared_ptr<Indices>... ind);
template <class ET>
inline const value_type& get(ET pos) const;
template <class ET>
inline SliceContraction& set(ET pos);
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
-> decltype(mOp.rootSteps(iPtrNum));
template <class Expr>
auto loop(Expr exp) const -> decltype(mOp.loop(exp)); // no loop
};
}
#include "type_operations.h"
#endif

View file

@ -0,0 +1,109 @@
// -*- C++ -*-
/**
@file include/operation/basic_operations.cc.h
@brief Basic operations implementation
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_basic_operations_cc_h__
#define __cxz_basic_operations_cc_h__
#include "basic_operations.h"
namespace CNORXZ
{
/*==================================+
| standard operatrions (unary) |
+==================================*/
template <class Op>
constexpr decltype(auto) minus(const COpInterface<Op>& op)
{
return operation( [](const auto& a) { return -a; }, op.THIS() );
}
/*===================================+
| standard operatrions (binary) |
+===================================*/
template <class Op1, class Op2>
constexpr decltype(auto) plus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a + b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) minus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a - b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) multiplies(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a * b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) divides(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a / b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) modulo(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a % b; },
op1.THIS(), op2.THIS() );
}
/*=======================================+
| operators for standard operations |
+=======================================*/
template <class Op>
constexpr decltype(auto) operator-(const COpInterface<Op>& op)
{
return minus(op);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator+(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return plus(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator-(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return minus(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator*(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return multiplies(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator/(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return divides(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator%(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return modulo(op1, op2);
}
}
#endif

View file

@ -0,0 +1,65 @@
// -*- C++ -*-
/**
@file include/operation/basic_operations.h
@brief Basic operations declaration
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_basic_operations_h__
#define __cxz_basic_operations_h__
#include "base/base.h"
#include "operation.h"
namespace CNORXZ
{
// standard operations:
// unary:
template <class Op>
constexpr decltype(auto) minus(const COpInterface<Op>& op);
// binary:
template <class Op1, class Op2>
constexpr decltype(auto) plus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) minus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) multiplies(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) divides(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) modulo(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
// operators for standard operations:
template <class Op>
constexpr decltype(auto) operator-(const COpInterface<Op>& op);
template <class Op1, class Op2>
constexpr decltype(auto) operator+(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator-(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator*(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator/(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator%(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
}
#endif

View file

@ -0,0 +1,279 @@
// -*- C++ -*-
/**
@file include/operation/extensions/avx.cc.h
@brief Register type implementaions for AVX.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_avx_cc_h__
#define __cxz_avx_cc_h__
#include "avx.h"
namespace CNORXZ
{
/*=====================+
| PlusCC / PlusCX |
+=====================*/
inline decltype(auto)
PlusCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_add_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
inline decltype(auto)
PlusCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_add_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
PlusCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const X& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_add_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
template <typename X>
inline decltype(auto)
PlusCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a, const X& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_add_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
PlusCX<Double,X,AVX::ND>::eval(const X& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_add_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
/*=======================+
| MinusCC / MinusCX |
+=======================*/
inline decltype(auto)
MinusCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_sub_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
inline decltype(auto)
MinusCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_sub_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
MinusCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const X& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_sub_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
template <typename X>
inline decltype(auto)
MinusCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a, const X& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_sub_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
MinusCX<Double,X,AVX::ND>::eval(const X& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_sub_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
/*=================================+
| MultipliesCC / MultipliesCX |
+=================================*/
inline decltype(auto)
MultipliesCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_mul_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
inline decltype(auto)
MultipliesCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_mul_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
MultipliesCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const X& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_mul_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
template <typename X>
inline decltype(auto)
MultipliesCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
const X& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_mul_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
MultipliesCX<Double,X,AVX::ND>::eval(const X& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_mul_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
/*===========================+
| DividesCC / DividesCX |
+===========================*/
inline decltype(auto)
DividesCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_div_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
inline decltype(auto)
DividesCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
const Consecutive<Double,AVX::ND>& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_div_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
DividesCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
const X& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_div_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
template <typename X>
inline decltype(auto)
DividesCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a, const X& b)
{
__m256d av = _mm256_load_pd(a.mD);
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
__m256d ov = _mm256_div_pd(av, bv);
_mm256_store_pd(a.mD, ov);
return a;
}
template <typename X>
inline decltype(auto)
DividesCX<Double,X,AVX::ND>::eval(const X& a,
const Consecutive<Double,AVX::ND>& b)
{
Consecutive<Double,AVX::ND> o;
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
__m256d bv = _mm256_load_pd(b.mD);
__m256d ov = _mm256_div_pd(av, bv);
_mm256_store_pd(o.mD, ov);
return o;
}
}
#endif

View file

@ -0,0 +1,120 @@
// -*- C++ -*-
/**
@file include/operation/extensions/avx.h
@brief Register type specialization for AVX.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_avx_h__
#define __cxz_avx_h__
#include <immintrin.h>
#include "base/base.h"
namespace CNORXZ
{
namespace AVX
{
static constexpr SizeT ND = AVX_VSIZE/sizeof(Double);
static constexpr SizeT NF = AVX_VSIZE/sizeof(float);
}
template <>
struct PlusCC<Double,Double,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
};
template <typename X>
struct PlusCX<Double,X,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
};
template <>
struct MinusCC<Double,Double,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
};
template <typename X>
struct MinusCX<Double,X,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
};
template <>
struct MultipliesCC<Double,Double,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
};
template <typename X>
struct MultipliesCX<Double,X,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
};
template <>
struct DividesCC<Double,Double,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
};
template <typename X>
struct DividesCX<Double,X,AVX::ND>
{
static inline decltype(auto)
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
static inline decltype(auto)
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
};
}
#endif

View file

@ -0,0 +1,21 @@
// -*- C++ -*-
/**
@file include/operation/extensions/extensions.cc.h
@brief Operation extensions template implementations main header.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_extensions_cc_h__
#define __cxz_extensions_cc_h__
#include "reg.cc.h"
#if CXZ_HAVE_AVX
#include "avx.cc.h"
#endif
#endif

View file

@ -0,0 +1,23 @@
// -*- C++ -*-
/**
@file include/operation/extensions/extensions.h
@brief Operation extensions main header.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_extensions_h__
#define __cxz_extensions_h__
#include "reg.h"
#if CXZ_HAVE_AVX
#include "avx.h"
#endif
#include "extensions.cc.h"
#endif

View file

@ -0,0 +1,262 @@
// -*- C++ -*-
/**
@file include/operation/extensions/reg.cc.h
@brief Register type template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_reg_cc_h__
#define __cxz_reg_cc_h__
#include "reg.h"
#include "xpr/pos_type.h"
namespace CNORXZ
{
template <typename T, class EPosT, SizeT... Is>
inline decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is)
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(N == sizeof...(Is), "got inconsistent index sequence");
return Consecutive<T,N> { d[pos.template get<Is>().val()]... };
}
template <typename T, class EPosT>
inline decltype(auto) vreg(const T* d, const EPosT& pos)
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
if constexpr(pos_type_is_consecutive<EPosT>::value){
return *reinterpret_cast<const Consecutive<T,N>*>(d+pos.scal().val());
}
else {
return vregi(d, pos, std::make_index_sequence<N>{});
}
}
template <typename T, class EPosT>
inline decltype(auto) vreg(T* d, const EPosT& pos)
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
static_assert(pos_type_is_consecutive<EPosT>::value, "no write access for non-consecutive");
if constexpr(pos_type_is_consecutive<EPosT>::value){
return *reinterpret_cast<Consecutive<T,N>*>(d+pos.scal().val());
}
else {
return vregi(d, pos, std::make_index_sequence<N>{});
}
}
template <SizeT I, typename T>
constexpr decltype(auto) consecGet(const T& a)
{
if constexpr(is_consecutive_type<T>::value){
static_assert(I < consecutive_size<T>::value,
"consecutive index out of range");
return a.mD[I];
}
else {
return a;
}
}
template <SizeT I, typename T>
constexpr decltype(auto) consecGet(T& a)
{
if constexpr(is_consecutive_type<T>::value){
static_assert(I < consecutive_size<T>::value,
"consecutive index out of range");
return a.mD[I];
}
else {
return a;
}
}
template <SizeT I, class F, typename... Args>
constexpr decltype(auto) consecApply(const F& f, const Args&... args)
{
return f( consecGet<I>(args)... );
}
template <SizeT I, class F, typename Dst, typename... Args>
constexpr Dst& consecAssign(const F& f, Dst& dst, const Args&... args)
{
f( consecGet<I>(dst), consecGet<I>(args)... );
return dst;
}
template <class F, typename... Args, SizeT... Is>
constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
std::index_sequence<Is...> is)
{
typedef decltype(consecApply<0>(f, args...)) OType;
constexpr SizeT N = sizeof...(Is);
return Consecutive<OType,N> { consecApply<Is>(f, args...) ... };
}
template <class F, typename Dst, typename... Args, SizeT... Is>
constexpr Dst& consecFuncAI(const F& f, Dst& dst, const Args&... args,
std::index_sequence<Is...> is)
{
( consecAssign<Is>(f, dst, args...), ... );
return dst;
}
template <SizeT N, class F, typename... Args>
constexpr decltype(auto) consecFunc(const F& f, const Args&... args)
{
return consecFuncI<F,Args...>(f, args..., std::make_index_sequence<N>{});
}
template <SizeT N, class F, typename Dst, typename... Args>
constexpr Dst& consecFuncA(const F& f, Dst& dst, const Args&... args)
{
return consecFuncAI<F,Dst,Args...>(f, dst, args..., std::make_index_sequence<N>{});
}
/*============================+
| basic operations: plus |
+============================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto)
PlusCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto)
PlusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x += y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) PlusCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) PlusCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) PlusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x += y; }, o, a );
}
/*=============================+
| basic operations: minus |
+=============================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MinusCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MinusCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MinusCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MinusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x -= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MinusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x -= y; }, o, a );
}
/*=================================+
| basic operations: muliplies |
+=================================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MultipliesCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MultipliesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x *= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x *= y; }, o, a );
}
/*===============================+
| basic operations: divides |
+===============================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto) DividesCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) DividesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) DividesCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto) DividesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x /= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) DividesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x /= y; }, o, a );
}
}
#endif

View file

@ -0,0 +1,279 @@
// -*- C++ -*-
/**
@file include/operation/extensions/reg.h
@brief Register type declaration.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_reg_h__
#define __cxz_reg_h__
#include "base/base.h"
namespace CNORXZ
{
// no use of Arr = std::array here, since I want ensure that
// it has exactly a memory size of N
template <typename T, SizeT N>
struct Consecutive
{
T mD[N];
};
template <typename T>
struct is_consecutive_type { CXZ_CVAL_FALSE; };
template <typename T>
struct consecutive_base { typedef T type; };
template <typename T>
struct consecutive_size { static constexpr SizeT value = 0; };
template <typename T, SizeT N>
struct is_consecutive_type<Consecutive<T,N>> { CXZ_CVAL_TRUE; };
template <typename T, SizeT N>
struct consecutive_base<Consecutive<T,N>> { typedef T type; };
template <typename T, SizeT N>
struct consecutive_size<Consecutive<T,N>> { static constexpr SizeT value = N; };
/*======================================+
| consecutive generating functions |
+======================================*/
template <typename T, class EPosT, SizeT... Is>
inline decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is);
template <typename T, class EPosT>
inline decltype(auto) vreg(const T* d, const EPosT& pos);
template <typename T, class EPosT>
inline decltype(auto) vreg(T* d, const EPosT& pos);
/*================+
| ConsecFunc |
+================*/
template <SizeT I, typename T>
constexpr decltype(auto) consecGet(const T& a);
template <SizeT I, typename T>
constexpr decltype(auto) consecGet(T& a);
template <SizeT I, class F, typename... Args>
constexpr decltype(auto) consecApply(const F& f, const Args&... args);
template <SizeT I, class F, typename Dst, typename... Args>
constexpr Dst& consecAssign(const F& f, Dst& dst, const Args&... args);
template <class F, typename... Args, SizeT... Is>
constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
std::index_sequence<Is...> is);
template <class F, typename Dst, typename... Args, SizeT... Is>
constexpr Dst& consecFuncAI(const F& f, Dst& dst, const Args&... args,
std::index_sequence<Is...> is);
template <SizeT N, class F, typename... Args>
constexpr decltype(auto) consecFunc(const F& f, const Args&... args);
template <SizeT N, class F, typename Dst, typename... Args>
constexpr Dst& consecFuncA(const F& f, Dst& dst, const Args&... args);
/*============================+
| basic operations: plus |
+============================*/
template <typename T, typename U, SizeT N>
struct PlusCC
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
};
template <typename T, typename X, SizeT N>
struct PlusCX
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
eval(const X& a, const Consecutive<T,N>& b);
};
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator+(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{ return PlusCC<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator+(const Consecutive<T,N>& a, const U& b)
{ return PlusCX<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator+(const T& a, const Consecutive<U,N>& b)
{ return PlusCX<U,T,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return PlusCC<T,U,N>::aeval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const U& a)
{ return PlusCX<T,U,N>::aeval(o,a); }
/*=============================+
| basic operations: minus |
+=============================*/
template <typename T, typename U, SizeT N>
struct MinusCC
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
};
template <typename T, typename X, SizeT N>
struct MinusCX
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
eval(const X& a, const Consecutive<T,N>& b);
};
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{ return MinusCC<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const U& b)
{ return MinusCX<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator-(const T& a, const Consecutive<U,N>& b)
{ return MinusCX<U,T,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return MinusCC<T,U,N>::eval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const U& a)
{ return MinusCX<T,U,N>::eval(o,a); }
/*=================================+
| basic operations: muliplies |
+=================================*/
template <typename T, typename U, SizeT N>
struct MultipliesCC
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
};
template <typename T, typename X, SizeT N>
struct MultipliesCX
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
eval(const X& a, const Consecutive<T,N>& b);
};
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{ return MultipliesCC<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const U& b)
{ return MultipliesCX<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator*(const T& a, const Consecutive<U,N>& b)
{ return MultipliesCX<U,T,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return MultipliesCC<T,U,N>::eval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const U& a)
{ return MultipliesCX<T,U,N>::eval(o,a); }
/*===============================+
| basic operations: divides |
+===============================*/
template <typename T, typename U, SizeT N>
struct DividesCC
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
};
template <typename T, typename X, SizeT N>
struct DividesCX
{
static constexpr decltype(auto)
eval(const Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
aeval(Consecutive<T,N>& a, const X& b);
static constexpr decltype(auto)
eval(const X& a, const Consecutive<T,N>& b);
};
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{ return DividesCC<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const U& b)
{ return DividesCX<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator/(const T& a, const Consecutive<U,N>& b)
{ return DividesCX<U,T,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return DividesCC<T,U,N>::eval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const U& a)
{ return DividesCX<T,U,N>::eval(o,a); }
}
#endif

View file

@ -0,0 +1,515 @@
// -*- C++ -*-
/**
@file include/operation/op_types.cc.h
@brief Operation types template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_op_types_cc_h__
#define __cxz_op_types_cc_h__
#include "op_types.h"
#include "op_utility.h"
#include "extensions/extensions.h"
namespace CNORXZ
{
/*====================+
| COpInterface |
+====================*/
template <class OpT>
template <class F, class IndexT>
constexpr decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
{
return contraction(std::forward<F>(f), THIS().r(), ind);
}
template <class OpT>
template <class IndexT>
constexpr decltype(auto) COpInterface<OpT>::c(const Sptr<IndexT>& ind) const
{
return contraction([](auto& a, const auto& b) { a += b; },
THIS(), ind);
}
template <class OpT>
template <class F, class... Args>
constexpr decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
{
return operation(std::forward<F>(f), THIS().r(), args...);
}
/*===================+
| OpInterface |
+===================*/
template <class OpT>
template <class IndexT, class F, class... Args>
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, const Args&... args)
{
return ind->ifor( operation(f, OI::THIS().r(), args...), NoF {} );
}
template <class OpT>
template <class IndexT, class F, class... Args>
inline void OpInterface<OpT>::a(const Sptr<IndexT>& ind, F&& f, const Args&... args)
{
ax(ind, f, args...)();
}
/*=============+
| COpRoot |
+=============*/
template <typename T, class IndexT>
constexpr COpRoot<T,IndexT>::COpRoot(const CArrayBase<T>& a, const Sptr<IndexT>& ind) :
mData(a.data()+ind->pos()),
mIndex(ind)
{}
template <typename T, class IndexT>
constexpr COpRoot<T,IndexT>::COpRoot(const T* data, const Sptr<IndexT>& ind) :
mData(data+ind->pos()),
mIndex(ind)
{}
template <typename T, class IndexT>
constexpr COpRoot<T,IndexT>& COpRoot<T,IndexT>::init(const T* data, const Sptr<IndexT>& ind)
{
mData = data+ind->pos();
mIndex = ind;
return *this;
}
template <typename T, class IndexT>
template <class PosT>
constexpr decltype(auto) COpRoot<T,IndexT>::operator()(const PosT& pos) const
{
if constexpr(is_epos_type<PosT>::value){
return vreg(mData,pos); // distinguish between consecutive/non-consecutive
}
else {
return mData[pos.val()];
}
}
template <typename T, class IndexT>
constexpr decltype(auto) COpRoot<T,IndexT>::operator()() const
{
return mData[0];
}
template <typename T, class IndexT>
template <SizeT I>
constexpr decltype(auto) COpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
{
return mIndex->stepSize(id);
}
template <typename T, class IndexT>
const T* COpRoot<T,IndexT>::data() const
{
return mData;
}
template <typename T, class IndexT>
constexpr decltype(auto) coproot(const CArrayBase<T>& a, const Sptr<IndexT>& ind)
{
return COpRoot<T,IndexT>(a, ind);
}
template <typename T, class IndexT>
constexpr decltype(auto) coproot(const T* a, const Sptr<IndexT>& ind)
{
return COpRoot<T,IndexT>(a, ind);
}
/*=============+
| POpRoot |
+=============*/
template <class IndexT, class Op>
constexpr POpRoot<IndexT,Op>::POpRoot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op) :
mIndex(ind),
mFp(1,parts),
mOp(std::forward<Op>(op))
{}
template <class IndexT, class Op>
template <class PosT>
constexpr decltype(auto) POpRoot<IndexT,Op>::operator()(const PosT& pos) const
{
return mOp(mFp(pos));
}
template <class IndexT, class Op>
constexpr decltype(auto) POpRoot<IndexT,Op>::operator()() const
{
return mOp(mFp(SPos<0>()));
}
template <class IndexT, class Op>
template <SizeT I>
constexpr decltype(auto) POpRoot<IndexT,Op>::rootSteps(const IndexId<I>& id) const
{
return mIndex->stepSize(id);
}
template <class IndexT, class Op>
constexpr decltype(auto) POpRoot<IndexT,Op>::data() const
{
return mOp->data();
}
template <class IndexT, class Op>
constexpr decltype(auto) poproot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op)
{
return POpRoot(ind, parts, std::forward<Op>(op));
}
/*==============+
| OpCont |
+==============*/
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>::OpCont(const Sptr<IndexT>& ind) :
mIndex(ind),
mC(std::make_shared<Vector<T>>(mIndex->pmax().val()))
{}
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind)
{
mIndex = ind;
if(mC.size() != mIndex->pmax().val()){
mC.resize(mIndex->pmax().val());
}
return *this;
}
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind,
const Vector<T>& c)
{
init(ind);
CXZ_ASSERT(c.size() == mC.size(),
"size-mismatch: expected " << mC.size() << ", got " << c.size());
std::transform(c.begin(), c.end(), mC.begin(), [](const auto& x) { return x; } );
return *this;
}
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::r()
{
return OpRoot<T,IndexT>(data(), mIndex);
}
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::r() const
{
return COpRoot<T,IndexT>(data(), mIndex);
}
template <typename T, class IndexT>
template <class Op>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const Op& o)
{
// TODO: build and execute assign expression forwarding outer index
// if a1 and a2 are non-expression types (like it is the case now),
// just do what is currently implemented
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
return *this;
}
template <typename T, class IndexT>
template <class Op>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator+=(const Op& o)
{
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 += a2; }, o);
return *this;
}
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const OpCont<T,IndexT>& o)
{
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
return *this;
}
template <typename T, class IndexT>
template <class PosT>
constexpr decltype(auto) OpCont<T,IndexT>::operator()(const PosT& pos) const
{
if constexpr(is_epos_type<PosT>::value){
if constexpr(pos_type_is_consecutive<PosT>::value){
return vreg(mC.data(),pos);
}
else {
// non-consecutive data cannot be directly accessed
// so there is no non-const (write) access!
return vreg(const_cast<const T*>(mC.data()),pos);
}
}
else {
return mC[pos.val()];
}
}
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::operator()() const
{
return mC[0];
}
template <typename T, class IndexT>
template <SizeT I>
constexpr decltype(auto) OpCont<T,IndexT>::rootSteps(const IndexId<I>& id) const
{
return mIndex->stepSize(id);
}
template <typename T, class IndexT>
T* OpCont<T,IndexT>::data()
{
return mC.data();
}
template <typename T, class IndexT>
const T* OpCont<T,IndexT>::data() const
{
return mC.data();
}
/*==============+
| OpRoot |
+==============*/
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>::OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind) :
mData(a.data()+ind->pos()),
mIndex(ind)
{}
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>::OpRoot(T* data, const Sptr<IndexT>& ind) :
mData(data+ind->pos()),
mIndex(ind)
{}
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::init(T* data, const Sptr<IndexT>& ind)
{
mData = data+ind->pos();
mIndex = ind;
return *this;
}
template <typename T, class IndexT>
template <class Op>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator=(const Op& o)
{
OI::a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
return *this;
}
template <typename T, class IndexT>
template <class Op>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator+=(const Op& o)
{
OI::a(mIndex, [](auto& a, const auto& b) { a += b; }, o);
return *this;
}
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator=(const OpRoot<T,IndexT>& o)
{
OI::a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
return *this;
}
template <typename T, class IndexT>
template <class PosT>
constexpr decltype(auto) OpRoot<T,IndexT>::operator()(const PosT& pos) const
{
if constexpr(is_epos_type<PosT>::value){
if constexpr(pos_type_is_consecutive<PosT>::value){
return vreg(mData,pos);
}
else {
// non-consecutive data cannot be directly accessed
// so there is no non-const (write) access!
return vreg(const_cast<const T*>(mData),pos);
}
}
else {
return mData[pos.val()];
}
}
template <typename T, class IndexT>
constexpr decltype(auto) OpRoot<T,IndexT>::operator()() const
{
return mData[0];
}
template <typename T, class IndexT>
template <SizeT I>
constexpr decltype(auto) OpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
{
return mIndex->stepSize(id);
}
template <typename T, class IndexT>
T* OpRoot<T,IndexT>::data() const
{
return mData;
}
template <typename T, class IndexT>
constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind)
{
return OpRoot<T,IndexT>(a, ind);
}
/*=================+
| Operation |
+=================*/
template <class F, class... Ops>
constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
mOps(ops...),
mF(std::forward<F>(f))
{}
template <class F, class... Ops>
template <class PosT>
constexpr decltype(auto) Operation<F,Ops...>::operator()(const PosT& pos) const
{
return pos_unpack_args(mF, pos, mOps);
}
template <class F, class... Ops>
constexpr decltype(auto) Operation<F,Ops...>::operator()() const
{
return exec(std::make_index_sequence<sizeof...(Ops)>{});
}
template <class F, class... Ops>
template <SizeT I>
constexpr decltype(auto) Operation<F,Ops...>::rootSteps(const IndexId<I>& id) const
{
return rootStepsi(id, std::make_index_sequence<sizeof...(Ops)>{});
}
template <class F, class... Ops>
template <SizeT... Is>
constexpr decltype(auto) Operation<F,Ops...>::exec(std::index_sequence<Is...> is) const
{
return mF( std::get<Is>(mOps)() ... );
}
template <class F, class... Ops>
template <SizeT I, SizeT... Is>
constexpr decltype(auto) Operation<F,Ops...>::rootStepsi(const IndexId<I>& id,
std::index_sequence<Is...> is) const
{
return ( std::get<Is>(mOps).rootSteps(id) << ... );
}
template <class F, class... Ops>
constexpr decltype(auto) operation(F&& f, const Ops&... ops)
{
return Operation<F,Ops...>(std::forward<F>(f), ops...);
}
template <class Tar, class Src>
constexpr decltype(auto) assignxpr(const Tar& tar, const Src& src)
{
static_assert(is_xpr<Tar>::value, "expected expression");
if constexpr(is_xpr<Src>::value){
return operation([](auto& a, const auto& b) { a = b; }, tar, src);
}
else {
return operation([&](auto& a) { a = src; }, tar);
}
}
template <class Tar, class Src>
constexpr decltype(auto) assignxpr(Tar& tar, const Src& src)
{
if constexpr(is_xpr<Tar>::value){
if constexpr(is_xpr<Src>::value){
return operation([](auto& a, const auto& b) { a = b; }, tar, src);
}
else {
return operation([&](auto& a) { a = src; }, tar);
}
}
else {
if constexpr(is_xpr<Src>::value){
return operation([&](const auto& b) { tar = b; }, src);
}
else {
return operation([&]() { tar = src; });
}
}
}
/*===================+
| Contraction |
+===================*/
template <class CXpr>
constexpr Contraction<CXpr>::Contraction(CXpr&& cxpr) :
mCXpr(cxpr)
{}
template <class CXpr>
template <class PosT>
constexpr decltype(auto) Contraction<CXpr>::operator()(const PosT& pos) const
{
return mCXpr(pos);
}
template <class CXpr>
constexpr decltype(auto) Contraction<CXpr>::operator()() const
{
return mCXpr();
}
template <class CXpr>
template <SizeT I>
constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const
{
return mCXpr.rootSteps(id);
}
template <class F, class Op, class IndexT>
constexpr decltype(auto) contraction(F&& f, Op&& op, const Sptr<IndexT>& i)
{
typedef decltype(i->ifor( op, f )) CXprT; // TODO: implement ifor with func arg!!!
return Contraction<CXprT>( i->ifor( op, f ) );
}
/*======================+
| various functions |
+======================*/
template <class IndexT>
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i)
{
return i->xpr(i);
}
}
#endif

View file

@ -0,0 +1,298 @@
// -*- C++ -*-
/**
@file include/operation/op_types.h
@brief Operation types declarations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_op_types_h__
#define __cxz_op_types_h__
#include "base/base.h"
#include "xpr/xpr_base.h"
#include "array/array_base.h"
namespace CNORXZ
{
template <class OpT>
class COpInterface : public XprInterface<OpT>
{
public:
constexpr COpInterface() = default;
OpT& THIS() { return static_cast<OpT&>(*this); }
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
constexpr decltype(auto) r() { return THIS(); }
constexpr decltype(auto) r() const { return THIS(); }
template <class F, class IndexT>
constexpr decltype(auto) c(F&& f, const Sptr<IndexT>& ind) const;
template <class IndexT>
constexpr decltype(auto) c(const Sptr<IndexT>& ind) const;
template <class F, class... Args>
constexpr decltype(auto) o(F&& f, Args&&... args) const;
};
template <class OpT>
class OpInterface : public COpInterface<OpT>
{
public:
typedef COpInterface<OpT> OI;
constexpr OpInterface() = default;
OpT& THIS() { return static_cast<OpT&>(*this); }
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
template <class IndexT, class F, class... Args>
constexpr decltype(auto) ax(const Sptr<IndexT>& ind, F&& f, const Args&... args);
template <class IndexT, class F, class... Args>
inline void a(const Sptr<IndexT>& ind, F&& f, const Args&... args);
};
template <class T>
struct is_operation
{ static constexpr bool value = std::is_base_of<COpInterface<T>,T>::value; };
template <class T>
struct is_mutable_operation
{ static constexpr bool value = std::is_base_of<OpInterface<T>,T>::value; };
template <class T>
struct op_size
{ static constexpr SizeT value = is_operation<T>::value ? 1 : 0; };
template <typename T, class IndexT>
class COpRoot : public COpInterface<COpRoot<T,IndexT>>
{
public:
typedef OpInterface<COpRoot<T,IndexT>> OI;
constexpr COpRoot() = default;
constexpr COpRoot(const CArrayBase<T>& a, const Sptr<IndexT>& ind);
constexpr COpRoot(const T* data, const Sptr<IndexT>& ind);
constexpr COpRoot& init(const T* data, const Sptr<IndexT>& ind);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
const T* data() const;
private:
const T* mData = nullptr;
Sptr<IndexT> mIndex;
};
template <typename T, class IndexT>
constexpr decltype(auto) coproot(const CArrayBase<T>& a, const Sptr<IndexT>& ind);
template <typename T, class IndexT>
constexpr decltype(auto) coproot(const T* a, const Sptr<IndexT>& ind);
template <class IndexT, class Op>
class POpRoot : public COpInterface<POpRoot<IndexT,Op>>
{
public:
typedef COpInterface<POpRoot<IndexT,Op>> OI;
constexpr POpRoot() = default;
constexpr POpRoot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
constexpr decltype(auto) data() const;
private:
Sptr<IndexT> mIndex;
FPos mFp;
Op mOp;
};
template <class IndexT, class Op>
constexpr decltype(auto) poproot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op);
template <typename T, class IndexT>
class OpCont : public OpInterface<OpCont<T,IndexT>>
{
public:
typedef OpInterface<OpCont<T,IndexT>> OI;
typedef typename Container<T,index_const_size<IndexT>::value,
index_has_const_size<IndexT>::value>::type CT;
constexpr OpCont() = default;
constexpr OpCont(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind, const Vector<T>& c);
constexpr decltype(auto) r();
constexpr decltype(auto) r() const;
template <class Op>
constexpr OpCont& operator=(const Op& in);
template <class Op>
constexpr OpCont& operator+=(const Op& in);
constexpr OpCont& operator=(const OpCont& in);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
T* data();
const T* data() const;
private:
Sptr<IndexT> mIndex;
CT mC;
};
template <typename T, class IndexT>
class OpRoot : public OpInterface<OpRoot<T,IndexT>>
{
public:
typedef OpInterface<OpRoot<T,IndexT>> OI;
constexpr OpRoot() = default;
constexpr OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind);
constexpr OpRoot(T* data, const Sptr<IndexT>& ind);
constexpr OpRoot& init(T* data, const Sptr<IndexT>& ind);
template <class Op>
constexpr OpRoot& operator=(const Op& in);
template <class Op>
constexpr OpRoot& operator+=(const Op& in);
constexpr OpRoot& operator=(const OpRoot& in);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
T* data() const;
private:
T* mData = nullptr;
Sptr<IndexT> mIndex;
};
template <typename T, class IndexT>
constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind);
template <class F, class... Ops>
class Operation : public OpInterface<Operation<F,Ops...>>
{
public:
typedef OpInterface<Operation<F,Ops...>> OI;
constexpr Operation() = default;
constexpr Operation(F&& f, const Ops&... ops);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
private:
template <SizeT... Is>
constexpr decltype(auto) exec(std::index_sequence<Is...> is) const;
template <SizeT I, SizeT... Is>
constexpr decltype(auto) rootStepsi(const IndexId<I>& id,
std::index_sequence<Is...> is) const;
Tuple<Ops...> mOps;
F mF;
};
template <class F, class... Ops>
constexpr decltype(auto) operation(F&& f, const Ops&... ops);
template <class Tar, class Src>
constexpr decltype(auto) assignxpr(const Tar& tar, const Src& src);
template <class Tar, class Src>
constexpr decltype(auto) assignxpr(Tar& tar, const Src& src);
template <class F, class... Ops>
struct op_size<Operation<F,Ops...>>
{ static constexpr SizeT value = ( op_size<Ops>::value + ... ); };
template <class CXpr>
class Contraction : public OpInterface<Contraction<CXpr>>
{
public:
typedef OpInterface<Contraction<CXpr>> OI;
constexpr Contraction() = default;
constexpr Contraction(CXpr&& cxpr);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
private:
CXpr mCXpr;
};
template <class CXpr>
struct op_size<Contraction<CXpr>>
{ static constexpr SizeT value = op_size<CXpr>::value; };
template <class F, class Op, class IndexT>
constexpr decltype(auto) contraction(F&& f, Op&& op, const Sptr<IndexT>& i);
template <class IndexT>
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i);
}
#endif

View file

@ -0,0 +1,63 @@
// -*- C++ -*-
/**
@file include/operation/op_utility.cc.h
@brief Operation utilities template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_op_utility_cc_h__
#define __cxz_op_utility_cc_h__
#include "op_utility.h"
#include "xpr/pos_type.h"
namespace CNORXZ
{
template <SizeT I, class PosT>
constexpr decltype(auto) pos_get(const PosT& pos)
{
static_assert(I < static_pos_size<PosT>::value, "index out of range");
if constexpr(I == 0){
return pos;
}
else {
return pos_get<I-1>(pos.next());
}
}
template <SizeT J, SizeT I, SizeT... Is>
constexpr SizeT sum_index_sequence(std::index_sequence<I,Is...> is)
{
static_assert(J < sizeof...(Is)+1, "index out of range");
if constexpr(J == 0){
return 0;
}
else {
return sum_index_sequence<J-1>(std::index_sequence<Is...>{}) + I;
}
}
template <class F, class PosT, class OpTuple, class OpSizes, SizeT... Is>
inline auto pos_unpack_args_i(const F& f, const PosT& pos, const OpTuple& args,
OpSizes opsizes, std::index_sequence<Is...> is)
{
return f(std::get<Is>(args)(pos_get<sum_index_sequence<Is>(opsizes)>(pos))...);
}
template <class F, class PosT, class... Ops>
inline auto pos_unpack_args(const F& f, const PosT& pos, const Tuple<Ops...>& args)
{
static_assert(is_pos_type<PosT>::value, "got non-pos-type");
static_assert((is_operation<Ops>::value and ...), "got non-operation type");
typedef std::make_index_sequence<sizeof...(Ops)> Idxs;
typedef std::index_sequence<op_size<Ops>::value...> OpSizes;
return pos_unpack_args_i(f, pos, args, OpSizes{}, Idxs{});
}
}
#endif

View file

@ -0,0 +1,34 @@
// -*- C++ -*-
/**
@file include/operation/op_utility.h
@brief Operation utilities declarations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_op_utility_h__
#define __cxz_op_utility_h__
#include "base/base.h"
namespace CNORXZ
{
template <SizeT I, class PosT>
constexpr decltype(auto) pos_get(const PosT& pos);
template <SizeT J, SizeT... Is>
constexpr SizeT sum_index_sequence(std::index_sequence<Is...> is);
template <class F, class PosT, class OpTuple, class OpSizes, SizeT... Is>
inline auto pos_unpack_args_i(const F& f, const PosT& pos, const OpTuple& args,
OpSizes opsizes, std::index_sequence<Is...> is);
template <class F, class PosT, class... Ops>
inline auto pos_unpack_args(const F& f, const PosT& pos, const Tuple<Ops...>& args);
}
#endif

View file

@ -0,0 +1,14 @@
// -*- C++ -*-
/**
@file include/operation/operation.cc.h
@brief Operation main header for template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "op_types.cc.h"
#include "op_utility.cc.h"
#include "basic_operations.cc.h"

View file

@ -0,0 +1,16 @@
// -*- C++ -*-
/**
@file include/operation/operation.h
@brief Operation main header.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#include "op_types.h"
#include "op_utility.h"
#include "basic_operations.h"
#include "operation.cc.h"

View file

@ -1,94 +0,0 @@
#ifndef __operation_def_h__
#define __operation_def_h__
#include "multi_array_operation.h"
namespace MultiArrayTools
{
template <typename T, class OperationClass>
auto operator+(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,plus<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,plus<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator-(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,minus<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,minus<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator*(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,multiplies<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,multiplies<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator/(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,divides<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,divides<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator+(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,plus<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,plus<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
template <typename T, class OperationClass>
auto operator-(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,minus<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,minus<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
template <typename T, class OperationClass>
auto operator*(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,multiplies<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,multiplies<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
template <typename T, class OperationClass>
auto operator/(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,divides<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,divides<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
#define regFunc1(fff) template <typename T, class OperationClass> \
auto fff(const OperationBase<T,OperationClass>& a) \
-> Operation<T,x_##fff<T>,OperationClass> { \
return Operation<T,x_##fff<T>,OperationClass>(a.THIS()); }
#include "extensions/math.h"
#undef regFunc1
template <size_t N, typename T, class OperationClass>
auto ipow(const OperationBase<T,OperationClass>& a)
-> Operation<T,x_ipow<N-1>,OperationClass>
{
return Operation<T,x_ipow<N-1>,OperationClass>(a.THIS());
}
}
#endif

View file

@ -1,46 +0,0 @@
#ifndef __operation_helper_h__
#define __operation_helper_h__
#include "multi_array_operation.h"
namespace MultiArrayTools
{
template <class BaseArray, class... Ranges>
class PseudoArray
{
size_t mThreadNum;
Slice<> mSl;
mutable ConstOperationRoot<T,Range> mOp;
public:
template <class ET>
const SrcHolder<ConstOperationRoot<T,Range>> operator[](ET pos) const;
};
template <class Operation>
class SrcHolder
{
TempHolder operator+(SrcHolder in) const;
// aso
};
template <class Operation>
class TempHolder
{
TempHolder operator+(SrcHolder in) const;
TempHolder operator+(TempHolder in) const;
};
template <class Operation>
class TarHolder
{
TarHolder& operator=(TempHolder in);
};
} // namespace MultiArrayTools
#endif

View file

@ -1,220 +0,0 @@
// -*- C++ -*-
#ifndef __pack_num_h__
#define __pack_num_h__
#include <cstdlib>
//#include <type_traits>
#include <tuple>
#include <ostream>
#include "base_def.h"
#include "xfor/exttype.h"
namespace MultiArrayHelper
{
template <bool ISSTATIC>
struct Application
{
template <class OpFunction, typename... Ts>
static inline auto apply(std::shared_ptr<OpFunction> f, Ts... as)
-> decltype((*f)(as...))
{
return (*f)(as...);
}
};
template <>
struct Application<true>
{
template <class OpFunction, typename... Ts>
static inline auto apply(std::shared_ptr<OpFunction> f, Ts... as)
-> decltype(OpFunction::apply(as...))
{
return OpFunction::apply(as...);
}
};
template <size_t N>
struct PackNum
{
template <class MA, class ITuple, class... IPtrs>
static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs)
-> decltype(PackNum<N-1>::mkElemOperation(ma, ituple, std::get<N>(ituple), iptrs...))
{
return PackNum<N-1>::mkElemOperation(ma, ituple, std::get<N>(ituple), iptrs...);
}
template <typename... T>
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
{
out << std::get<sizeof...(T)-N-1>(tp) << ", ";
PackNum<N-1>::printTuple(out, tp);
}
template <class... Ops>
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
-> decltype(PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii)) )
{
return PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii));
}
template <class RootStepTuple, class IndexClass, class OpClass>
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
const OpClass& second)
{
std::get<N>(out) = second.rootSteps( std::get<N>(siar) );
PackNum<N-1>::mkExt(out, siar, second);
}
template <size_t LAST, class ETuple, class OpTuple, class OpFunction, typename... Args>
static inline auto mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, Args... args)
{
typedef typename std::remove_reference<decltype(std::get<N>(ops))>::type NextOpType;
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
typedef decltype(std::get<N>(ops).get(Getter<NEXT>::template getX<ETuple>( pos ))) ArgT;
return PackNum<N-1>::template mkOpExpr<NEXT,ETuple,OpTuple,OpFunction,ArgT,Args...>
( f, pos, ops, std::get<N>(ops).get(Getter<NEXT>::template getX<ETuple>( pos )), args...);
}
template <class OpTuple, class Expr>
static auto mkLoop( const OpTuple& ot, Expr exp )
-> decltype(std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) ))
{
return std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) );
}
template <typename T, class Op, class... SRanges>
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
const ContainerIndex<T,typename SRanges::IndexType...>& index,
const Op& op, size_t total = 1)
{
const size_t tmp =
op.rootSteps(reinterpret_cast<std::intptr_t>
( index.template getPtr<N>().get() ) )
.val();
std::get<N+1>(blocks) = tmp;
PackNum<N-1>::template mkSliceBlocks<T,Op,SRanges...>(blocks, index, op, total * tmp);
}
template <class... SRanges>
static bool checkIfSameInstance(const std::tuple<std::shared_ptr<SRanges>...>& rtp1,
const std::tuple<std::shared_ptr<SRanges>...>& rtp2)
{
return std::get<N>(rtp1).get() == std::get<N>(rtp2).get() and PackNum<N-1>::checkIfSameInstance(rtp1,rtp2);
}
template <class MA, class ITuple, class... Indices>
static inline auto mkMapOp(const MA& ma, const ITuple& itp, const std::shared_ptr<Indices>&... inds)
-> decltype(PackNum<N-1>::mkMapOp(ma, itp, std::get<N>(itp), inds...))
{
return PackNum<N-1>::mkMapOp(ma, itp, std::get<N>(itp), inds...);
}
template <size_t LAST,class OpTuple, class ETuple>
static inline void setOpPos(OpTuple& ot, const ETuple& et)
{
typedef typename std::remove_reference<decltype(std::get<N>(ot))>::type NextOpType;
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
std::get<N>( ot ).set( Getter<NEXT>::template getX<ETuple>( et ) );
PackNum<N-1>::template setOpPos<NEXT,OpTuple,ETuple>(ot, et);
}
};
template<>
struct PackNum<0>
{
template <class MA, class ITuple, class... IPtrs>
static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs)
-> decltype(ma(iptrs...))
{
return ma(iptrs...);
}
template <typename... T>
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
{
out << std::get<sizeof...(T)-1>(tp);
}
template <class... Ops>
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
-> decltype(std::get<0>(otp).rootSteps(ii))
{
return std::get<0>(otp).rootSteps(ii);
}
template <class RootStepTuple, class IndexClass, class OpClass>
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
const OpClass& second)
{
std::get<0>(out) = second.rootSteps( std::get<0>(siar) );
}
template <size_t LAST, class ETuple, class OpTuple, class OpFunction, typename... Args>
static inline auto mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, const Args&... args)
{
typedef typename std::remove_reference<decltype(std::get<0>(ops))>::type NextOpType;
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
static_assert(NEXT == 0, "inconsistent array positions");
typedef decltype(std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos ))) ArgT;
return Application<OpFunction::FISSTATIC>::template apply<OpFunction,ArgT,Args...>(f, std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos )), args...);
//return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos )), args...);
}
template <class OpTuple, class Expr>
static auto mkLoop( const OpTuple& ot, Expr exp )
-> decltype(std::get<0>(ot).loop( exp ))
{
return std::get<0>(ot).loop( exp );
}
template <typename T, class Op, class... SRanges>
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
const ContainerIndex<T,typename SRanges::IndexType...>& index,
const Op& op, size_t total = 1)
{
const size_t tmp =
op.rootSteps(reinterpret_cast<std::intptr_t>
( index.template getPtr<0>().get() ) )
.val();
std::get<1>(blocks) = tmp;
std::get<0>(blocks) = total * tmp; // this is not correct, but not used so far ... !!!
}
template <class... SRanges>
static bool checkIfSameInstance(const std::tuple<std::shared_ptr<SRanges>...>& rtp1,
const std::tuple<std::shared_ptr<SRanges>...>& rtp2)
{
return std::get<0>(rtp1).get() == std::get<0>(rtp2).get();
}
template <class MA, class ITuple, class... Indices>
static inline auto mkMapOp(const MA& ma, const ITuple& itp, const std::shared_ptr<Indices>&... inds)
-> decltype(ma.exec(std::get<0>(itp), inds...))
{
return ma.exec(std::get<0>(itp), inds...);
}
template <size_t LAST,class OpTuple, class ETuple>
static inline void setOpPos(OpTuple& ot, const ETuple& et)
{
typedef typename std::remove_reference<decltype(std::get<0>(ot))>::type NextOpType;
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
static_assert(NEXT == 0, "inconsistent array positions");
std::get<0>( ot ).set( Getter<NEXT>::template getX<ETuple>( et ) );
}
};
} // end namespace MultiArrayHelper
#endif

View file

@ -1,253 +0,0 @@
// -*- C++ -*-
#ifndef __anonymous_range_h__
#define __anonymous_range_h__
#include <cstdlib>
#include <map>
#include "rbase_def.h"
#include "ranges/range_base.h"
#include "ranges/rpheader.h"
#include "ranges/x_to_string.h"
#include "ranges/type_map.h"
namespace MultiArrayTools
{
typedef GenSingleIndex<size_t,SpaceType::ANON,MUI> AnonymousIndex;
//template <class R>
//using SIZET = size_t;
typedef GenSingleRange<size_t,SpaceType::ANON,MUI> AnonymousRange;
// NOT THREAD SAVE!!
class AnonymousRangeFactory : public RangeFactoryBase
{
public:
typedef AnonymousRange oType;
AnonymousRangeFactory();
template <class... RangeTypes>
AnonymousRangeFactory(const std::tuple<std::shared_ptr<RangeTypes>...>& origs);
template <class... RangeTypes>
AnonymousRangeFactory(std::shared_ptr<RangeTypes>... origs);
AnonymousRangeFactory(const vector<std::shared_ptr<RangeBase>>& origs);
template <class Range>
void append(std::shared_ptr<Range> r);
std::shared_ptr<RangeBase> create();
private:
std::shared_ptr<RangeBase> checkIfCreated(const vector<std::shared_ptr<RangeBase> >& pvec);
static std::map<std::shared_ptr<RangeBase>,vector<std::intptr_t> > mAleadyCreated;
bool mProductCreated = false;
};
template <>
class GenSingleRange<size_t,SpaceType::ANON,MUI> : public RangeInterface<AnonymousIndex>
{
public:
static constexpr bool defaultable = true;
static constexpr size_t ISSTATIC = 0;
static constexpr size_t SIZE = MUI;
static constexpr bool HASMETACONT = false;
typedef RangeBase RB;
typedef typename RangeInterface<AnonymousIndex>::IndexType IndexType;
typedef GenSingleRange<size_t,SpaceType::ANON,MUI> RangeType;
typedef size_t MetaType;
typedef AnonymousRangeFactory FType;
virtual size_t size() const final;
virtual size_t dim() const final;
size_t anonymousDim() const;
size_t get(size_t pos) const;
size_t getMeta(size_t metaPos) const;
virtual IndexType begin() const final;
virtual IndexType end() const final;
virtual SpaceType spaceType() const final;
virtual DataHeader dataHeader() const final;
virtual vector<size_t> typeNum() const final;
virtual size_t cmeta(char* target, size_t pos) const final;
virtual size_t cmetaSize() const final;
virtual std::string stringMeta(size_t pos) const final;
virtual vector<char> data() const final;
std::shared_ptr<RangeBase> sub(size_t num) const;
template <class Range>
std::shared_ptr<Range> fullsub(size_t num) const;
template <class... Ranges>
std::shared_ptr<MultiRange<Ranges...> > scast(SIZET<Ranges>... sizes) const; // save cast
const vector<std::shared_ptr<RangeBase> >& orig() const;
std::shared_ptr<AnonymousRange> sreplace(const std::shared_ptr<RangeBase> in, size_t num) const;
std::shared_ptr<AnonymousRange> sreplace(const vector<std::shared_ptr<RangeBase>>& in, size_t num) const;
std::shared_ptr<AnonymousRange> sreplace(const std::shared_ptr<RangeBase>& in,
const vector<size_t>& num) const;
bool isEmpty() const;
friend AnonymousRangeFactory;
static AnonymousRangeFactory factory()
{ return AnonymousRangeFactory(); }
protected:
GenSingleRange() = default;
GenSingleRange(const AnonymousRange& in) = default;
template <class... RangeTypes>
GenSingleRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs);
template <class... RangeTypes>
GenSingleRange(std::shared_ptr<RangeTypes>... origs);
GenSingleRange(const vector<std::shared_ptr<RangeBase>>& origs);
size_t mSize = 1;
bool mEmpty = true;
vector<std::shared_ptr<RangeBase> > mOrig;
};
}
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
namespace MultiArrayTools
{
/***********************
* AnonymousRange *
***********************/
template <class... RangeTypes>
AnonymousRangeFactory::AnonymousRangeFactory(const std::tuple<std::shared_ptr<RangeTypes>...>& origs)
{
mProd = std::shared_ptr<oType>( new AnonymousRange( origs ) );
}
template <class... RangeTypes>
AnonymousRangeFactory::AnonymousRangeFactory(std::shared_ptr<RangeTypes>... origs)
{
mProd = std::shared_ptr<oType>( new AnonymousRange( origs... ) );
}
template <class Range>
void AnonymousRangeFactory::append(std::shared_ptr<Range> r)
{
if(mProductCreated){
mProd = std::shared_ptr<oType>( new AnonymousRange( *std::dynamic_pointer_cast<oType>(mProd) ) );
mProductCreated = false;
}
std::dynamic_pointer_cast<oType>(mProd)->mOrig.push_back(r);
std::dynamic_pointer_cast<oType>(mProd)->mSize *= r->size();
std::dynamic_pointer_cast<oType>(mProd)->mEmpty = false;
}
/*****************
* Functions *
*****************/
std::shared_ptr<AnonymousRange> defaultRange(size_t size = 0);
}
namespace MultiArrayHelper
{
using namespace MultiArrayTools;
template <>
inline void resolveSetRange<AnonymousRange>(std::shared_ptr<AnonymousRange>& rp,
const vector<std::shared_ptr<RangeBase> >& orig,
size_t origpos, size_t size)
{
AnonymousRangeFactory arf;
for(size_t op = origpos; op != origpos + size; ++op){
//VCHECK(op);
arf.append(orig[op]);
}
rp = std::dynamic_pointer_cast<AnonymousRange>( arf.create() );
}
template <>
inline void setRangeToVec<AnonymousRange>(vector<std::shared_ptr<RangeBase> >& v,
std::shared_ptr<AnonymousRange> r)
{
if(not r->isEmpty()){
for(size_t i = r->anonymousDim(); i != 0; --i){
v.insert(v.begin(), r->sub(i-1));
}
}
}
}
namespace MultiArrayTools
{
/***********************
* AnonymousRange *
***********************/
template <class... RangeTypes>
GenSingleRange<size_t,SpaceType::ANON,MUI>::GenSingleRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs) :
RangeInterface<AnonymousIndex>()
{
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( origs, mOrig );
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( origs );
if(sizeof...(RangeTypes)){
mEmpty = false;
}
}
template <class... RangeTypes>
GenSingleRange<size_t,SpaceType::ANON,MUI>::GenSingleRange(std::shared_ptr<RangeTypes>... origs) :
RangeInterface<AnonymousIndex>()
{
auto rst = std::make_tuple(origs...);
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( rst, mOrig );
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( rst );
if(sizeof...(RangeTypes)){
mEmpty = false;
}
}
template <class Range>
std::shared_ptr<Range> GenSingleRange<size_t,SpaceType::ANON,MUI>::fullsub(size_t num) const
{
return std::dynamic_pointer_cast<Range>( mOrig.at(num) );
}
template <class... Ranges>
std::shared_ptr<MultiRange<Ranges...> > GenSingleRange<size_t,SpaceType::ANON,MUI>::scast(SIZET<Ranges>... sizes) const
{
std::tuple<std::shared_ptr<Ranges>...> rtp;
RPackNum<sizeof...(Ranges)-1>::resolveRangeType(mOrig, rtp, 0, sizes...);
MultiRangeFactory<Ranges...> mrf(rtp);
return std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() );
}
}
#endif

View file

@ -1,766 +0,0 @@
// -*- C++ -*-
#ifndef __container_range_h__
#define __container_range_h__
#include <cstdlib>
#include <tuple>
#include <memory>
#include "ranges/range_base.h"
#include "ranges/index_base.h"
#include "rpack_num.h"
namespace MultiArrayTools
{
template <typename T, class... Indices>
class ContainerIndex : public IndexInterface<ContainerIndex<T,Indices...>,
std::tuple<typename Indices::MetaType...> >,
public std::iterator<std::random_access_iterator_tag,T>
{
public:
typedef IndexInterface<ContainerIndex<T,Indices...>,
std::tuple<typename Indices::MetaType...> > IB;
typedef std::tuple<typename Indices::MetaType...> MetaType;
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
typedef ContainerRange<T,typename Indices::RangeType...> RangeType;
static constexpr IndexType sType() { return IndexType::CONT; }
static constexpr size_t sDim() { return sizeof...(Indices); }
static constexpr size_t totalDim() { return mkTotalDim<Indices...>(); }
static constexpr SpaceType STYPE = SpaceType::ANY;
static constexpr bool PARALLEL = std::tuple_element<0,std::tuple<Indices...>>::type::PARALLEL;
template <typename X>
using CIX = ContainerIndex<X,Indices...>;
template <typename X>
friend class CIX;
private:
ContainerIndex() = default;
bool mNonTrivialBlocks = false;
bool mExternControl = false;
IndexPack mIPack;
std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
const T* mData = nullptr;
size_t mCPos;
//const MultiArrayBase<T,typename Indices::RangeType...>* mMa = nullptr;
std::intptr_t mObjPtrNum;
public:
ContainerIndex(const ContainerIndex& in) = default;
ContainerIndex& operator=(const ContainerIndex& in) = default;
ContainerIndex(const ContainerIndex& in, bool copy) :
IB(in),
mNonTrivialBlocks(in.mNonTrivialBlocks),
mExternControl(false),
mBlockSizes(in.mBlockSizes),
mData(in.mData),
mCPos(in.mCPos),
mObjPtrNum(in.mObjPtrNum)
{
//if(copy){
RPackNum<sizeof...(Indices)-1>::copyIndex(mIPack, in);
//}
//else {
//mIPack = in.mIPack;
//}
}
ContainerIndex& copy(const ContainerIndex& in)
{
IB::operator=(in);
mNonTrivialBlocks = in.mNonTrivialBlocks;
mExternControl = false;
mBlockSizes = in.mBlockSizes;
mData = in.mData;
mCPos = in.mCPos;
mObjPtrNum = in.mObjPtrNum;
RPackNum<sizeof...(Indices)-1>::copyIndex(mIPack, in);
return *this;
}
template <typename X>
ContainerIndex& operator=(const ContainerIndex<X,Indices...>& in);
template <class MRange>
ContainerIndex(const std::shared_ptr<MRange>& range,
std::intptr_t objPtrNum);
template <class MRange>
ContainerIndex(const std::shared_ptr<MRange>& range,
std::intptr_t objPtrNum,
const std::array<size_t,sizeof...(Indices)+1>& blockSizes);
template <size_t N>
auto get() const -> decltype( *std::get<N>( mIPack ) )&;
template <size_t N>
auto getPtr() const -> decltype( std::get<N>( mIPack ) )&;
template <size_t N>
size_t getBlockSize() const { return std::get<N>(mBlockSizes); }
const IndexPack& pack() const { return mIPack; }
ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true
ContainerIndex& operator()(const std::shared_ptr<Indices>&... inds); // control via external indices
ContainerIndex& operator()(const std::tuple<std::shared_ptr<Indices>...>& inds);
ContainerIndex& operator()(); // -> sync; just to shorten the code
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
IndexType type() const;
ContainerIndex& operator++();
ContainerIndex& operator--();
ContainerIndex& operator=(size_t pos);
int pp(std::intptr_t idxPtrNum);
int mm(std::intptr_t idxPtrNum);
std::string stringMeta() const;
MetaType meta() const;
ContainerIndex& at(const MetaType& metaPos);
size_t dim() const;
bool first() const;
bool last() const;
bool sliceMode() const;
std::shared_ptr<RangeType> range();
template <size_t N>
auto getPtr() -> decltype( std::get<N>( mIPack ) )&;
size_t getStepSize(size_t n);
std::string id() const;
void print(size_t offset);
template <class Exprs>
auto ifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkFor(step, mIPack, mBlockSizes, exs));
template <class Exprs>
auto iforh(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh(step, mIPack, mBlockSizes, exs));
template <class Exprs>
auto pifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkPFor(step, mIPack, mBlockSizes, exs));
std::intptr_t container() const;
ContainerIndex& format(const std::array<size_t,sizeof...(Indices)+1>& blocks);
// Iterator Stuff
ContainerIndex& setData(const T* data);
const T& operator*() const;
const T* operator->() const;
//T& operator*();
//T* operator->();
ContainerIndex operator++(int);
ContainerIndex operator--(int);
ContainerIndex& operator+=(int diff);
ContainerIndex& operator-=(int diff);
ContainerIndex operator+(int num) const;
ContainerIndex operator-(int num) const;
int operator-(const ContainerIndex& it) const;
const T& operator[](int num) const;
bool operator<(const ContainerIndex& it) const;
bool operator>(const ContainerIndex& it) const;
bool operator<=(const ContainerIndex& it) const;
bool operator>=(const ContainerIndex& it) const;
};
/*
template <typename T, class... Ranges>
class ContainerRangeFactory : public RangeFactoryBase
{
public:
typedef ContainerRange<T,Ranges...> oType;
ContainerRangeFactory();
ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs);
ContainerRangeFactory(const typename ContainerRange<T,Ranges...>::SpaceType& space);
virtual std::shared_ptr<RangeBase> create() override;
protected:
};*/
/*
template <typename T, class... Ranges>
class ContainerRange : public RangeInterface<ContainerIndex<T,typename Ranges::IndexType...> >
{
public:
typedef RangeBase RB;
typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType;
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
protected:
ContainerRange() = default;
ContainerRange(const ContainerRange& in) = delete;
ContainerRange& operator=(const ContainerRange& in) = delete;
ContainerRange(const std::shared_ptr<Ranges>&... rs);
ContainerRange(const SpaceType& space);
SpaceType mSpace;
public:
static const size_t sdim = sizeof...(Ranges);
virtual size_t dim() const override;
virtual size_t size() const override;
template <size_t N>
auto get() const -> decltype( *std::get<N>( mSpace ) )&;
template <size_t N>
auto getPtr() const -> decltype( std::get<N>( mSpace ) )&;
const SpaceType& space() const;
virtual IndexType begin() const override;
virtual IndexType end() const override;
friend ContainerRangeFactory<T,Ranges...>;
static constexpr bool defaultable = false;
static constexpr size_t ISSTATIC = SubProp<Ranges...>::ISSTATIC;
static constexpr size_t SIZE = SubProp<Ranges...>::SIZE;
};
*/
//template <typename T, class... Ranges>
//using ContainerRange = MultiRange<Ranges...>;
} // end namespace MultiArrayTools
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
namespace MultiArrayTools
{
namespace
{
using namespace MultiArrayHelper;
}
/**********************
* ContainerIndex *
**********************/
template <typename T, class... Indices>
template <class MRange>
ContainerIndex<T,Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range,
std::intptr_t objPtrNum) :
IndexInterface<ContainerIndex<T,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0),
mObjPtrNum(objPtrNum)
{
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack);
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
}
template <typename T, class... Indices>
template <class MRange>
ContainerIndex<T,Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range,
std::intptr_t objPtrNum,
const std::array<size_t,sizeof...(Indices)+1>& blockSizes) :
IndexInterface<ContainerIndex<T,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0),
mObjPtrNum(objPtrNum)
{
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
mBlockSizes = blockSizes;
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
mNonTrivialBlocks = true;
}
template <typename T, class... Indices>
template <typename X>
ContainerIndex<T,Indices...>&
ContainerIndex<T,Indices...>::operator=(const ContainerIndex<X,Indices...>& in)
{
mIPack = in.mIPack;
return (*this)();
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::sync()
{
if(mExternControl){
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
//VCHECK(id());
//VCHECK(sizeof...(Indices));
//assert(IB::mPos < IB::max());
}
return *this;
}
template <typename T, class... Indices>
template <size_t N>
auto ContainerIndex<T,Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
{
return *std::get<N>( mIPack );
}
template <typename T, class... Indices>
template <size_t N>
auto ContainerIndex<T,Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>( mIPack );
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator()(const std::shared_ptr<Indices>&... inds)
{
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, inds...);
mExternControl = true;
return sync();
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator()(const std::tuple<std::shared_ptr<Indices>...>& inds)
{
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, inds);
mExternControl = true;
return sync();
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator()()
{
return sync();
}
template <typename T, class... Indices>
IndexType ContainerIndex<T,Indices...>::type() const { return IndexType::CONT; }
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator++()
{
if(mExternControl){
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
RPackNum<sizeof...(Indices)-1>::pp( mIPack );
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
++IB::mPos;
return *this;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator--()
{
if(mExternControl){
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
RPackNum<sizeof...(Indices)-1>::mm( mIPack );
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
--IB::mPos;
return *this;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator=(size_t pos)
{
IB::mPos = pos;
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
return *this;
}
template <typename T, class... Indices>
int ContainerIndex<T,Indices...>::pp(std::intptr_t idxPtrNum)
{
int tmp = RPackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtrNum);
IB::mPos += tmp;
return tmp;
}
template <typename T, class... Indices>
int ContainerIndex<T,Indices...>::mm(std::intptr_t idxPtrNum)
{
int tmp = RPackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtrNum);
IB::mPos -= tmp;
return tmp;
}
template <typename T, class... Indices>
std::string ContainerIndex<T,Indices...>::stringMeta() const
{
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->stringMeta(IB::mPos);
}
template <typename T, class... Indices>
typename ContainerIndex<T,Indices...>::MetaType ContainerIndex<T,Indices...>::meta() const
{
MetaType metaTuple;
RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
return metaTuple;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::at(const MetaType& metaPos)
{
RPackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
return *this;
}
template <typename T, class... Indices>
size_t ContainerIndex<T,Indices...>::dim() const
{
return sizeof...(Indices);
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::first() const
{
return IB::pos() == 0;
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::last() const
{
return IB::pos() == IB::mMax - 1;
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::sliceMode() const
{
return mNonTrivialBlocks;
}
template <typename T, class... Indices>
std::shared_ptr<typename ContainerIndex<T,Indices...>::RangeType>
ContainerIndex<T,Indices...>::range()
{
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
}
template <typename T, class... Indices>
template <size_t N>
auto ContainerIndex<T,Indices...>::getPtr() -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>( mIPack );
}
template <typename T, class... Indices>
size_t ContainerIndex<T,Indices...>::getStepSize(size_t n)
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
return mBlockSizes[n+1];
}
template <typename T, class... Indices>
std::string ContainerIndex<T,Indices...>::id() const
{
return std::string("con") + std::to_string(IB::mId);
}
template <typename T, class... Indices>
void ContainerIndex<T,Indices...>::print(size_t offset)
{
if(offset == 0){
std::cout << " === " << std::endl;
}
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this) << "]"
<< "(" << IB::mRangePtr << "): " << meta() << std::endl;
RPackNum<sizeof...(Indices)-1>::printIndex(mIPack, offset+1);
}
template <typename T, class... Indices>
template <class Exprs>
auto ContainerIndex<T,Indices...>::ifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkFor(step, mIPack, mBlockSizes, exs))
{
return RPackNum<sizeof...(Indices)-1>::mkFor(step, mIPack, mBlockSizes, exs);
}
template <typename T, class... Indices>
template <class Exprs>
auto ContainerIndex<T,Indices...>::iforh(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh(step, mIPack, mBlockSizes, exs))
{
return RPackNum<sizeof...(Indices)-1>::mkForh(step, mIPack, mBlockSizes, exs);
}
template <typename T, class... Indices>
template <class Exprs>
auto ContainerIndex<T,Indices...>::pifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkPFor(step, mIPack, mBlockSizes, exs))
{
return RPackNum<sizeof...(Indices)-1>::mkPFor(step, mIPack, mBlockSizes, exs);
}
template <typename T, class... Indices>
std::intptr_t ContainerIndex<T,Indices...>::container() const
{
return mObjPtrNum;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::
format(const std::array<size_t,sizeof...(Indices)+1>& blocks)
{
mBlockSizes = blocks;
mNonTrivialBlocks = true;
return *this;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::setData(const T* data)
{
mData = data;
return *this;
}
template <typename T, class... Indices>
const T& ContainerIndex<T,Indices...>::operator*() const
{
//return mMa[*this];
return mData[mCPos];
//return mData[IB::mPos];
}
template <typename T, class... Indices>
const T* ContainerIndex<T,Indices...>::operator->() const
{
//return &mMa[*this];
return &mData[mCPos];
}
/*
template <typename T, class... Indices>
T& ContainerIndex<T,Indices...>::operator*()
{
//return mMa[*this];
return mData[IB::mPos];
}
template <typename T, class... Indices>
T* ContainerIndex<T,Indices...>::operator->()
{
//return &mMa[*this];
return &mData[IB::mPos];
}
*/
template <typename T, class... Indices>
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator++(int)
{
auto tmp = *this;
++(*this);
return tmp;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator--(int)
{
auto tmp = *this;
--(*this);
return tmp;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator+=(int diff)
{
if(diff < 0){
for(int i = 0; i != diff; ++i){
(*this)--;
}
}
else {
for(int i = 0; i != diff; ++i){
(*this)++;
}
}
return *this;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator-=(int diff)
{
if(diff < 0){
for(int i = 0; i != diff; ++i){
(*this)++;
}
}
else {
for(int i = 0; i != diff; ++i){
(*this)--;
}
}
return *this;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator+(int num) const
{
auto tmp = *this;
return tmp += num;
}
template <typename T, class... Indices>
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator-(int num) const
{
auto tmp = *this;
return tmp -= num;
}
template <typename T, class... Indices>
int ContainerIndex<T,Indices...>::operator-(const ContainerIndex<T,Indices...>& it) const
{
return static_cast<int>( IB::mPos ) - static_cast<int>( it.pos() );
}
template <typename T, class... Indices>
const T& ContainerIndex<T,Indices...>::operator[](int num) const
{
return mData[IB::mPos + num];
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::operator<(const ContainerIndex<T,Indices...>& it) const
{
return IB::mPos < it.pos();
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::operator>(const ContainerIndex<T,Indices...>& it) const
{
return IB::mPos > it.pos();
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::operator<=(const ContainerIndex<T,Indices...>& it) const
{
return IB::mPos <= it.pos();
}
template <typename T, class... Indices>
bool ContainerIndex<T,Indices...>::operator>=(const ContainerIndex<T,Indices...>& it) const
{
return IB::mPos >= it.pos();
}
/*****************************
* ContainerRangeFactory *
*****************************/
/*
template <typename T, class... Ranges>
ContainerRangeFactory<T,Ranges...>::ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs)
{
mProd = std::shared_ptr<ContainerRange<T,Ranges...> >( new ContainerRange<T,Ranges...>( rs... ) );
}
template <typename T, class... Ranges>
ContainerRangeFactory<T,Ranges...>::
ContainerRangeFactory(const typename ContainerRange<T,Ranges...>::SpaceType& space)
{
mProd = std::shared_ptr<ContainerRange<T,Ranges...> >( new ContainerRange<T,Ranges...>( space ) );
}
template <typename T, class... Ranges>
std::shared_ptr<RangeBase> ContainerRangeFactory<T,Ranges...>::create()
{
setSelf();
return mProd;
}
*/
/**********************
* ContainerRange *
**********************/
/*
template <typename T, class... Ranges>
ContainerRange<T,Ranges...>::ContainerRange(const std::shared_ptr<Ranges>&... rs) :
mSpace( std::make_tuple( rs... ) ) {}
template <typename T, class... Ranges>
ContainerRange<T,Ranges...>::ContainerRange(const SpaceType& space) : mSpace( space ) {}
template <typename T, class... Ranges>
size_t ContainerRange<T,Ranges...>::dim() const
{
return sizeof...(Ranges);
}
template <typename T, class... Ranges>
size_t ContainerRange<T,Ranges...>::size() const
{
return RPackNum<sizeof...(Ranges)-1>::getSize(mSpace);
}
template <typename T, class... Ranges>
template <size_t N>
auto ContainerRange<T,Ranges...>::get() const -> decltype( *std::get<N>( mSpace ) )&
{
return *std::get<N>( mSpace );
}
template <typename T, class... Ranges>
template <size_t N>
auto ContainerRange<T,Ranges...>::getPtr() const -> decltype( std::get<N>( mSpace ) )&
{
return std::get<N>( mSpace );
}
template <typename T, class... Ranges>
const typename ContainerRange<T,Ranges...>::SpaceType& ContainerRange<T,Ranges...>::space() const
{
return mSpace;
}
template <typename T, class... Ranges>
typename ContainerRange<T,Ranges...>::IndexType ContainerRange<T,Ranges...>::begin() const
{
ContainerIndex<T,typename Ranges::IndexType...>
i( std::dynamic_pointer_cast<ContainerRange<T,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
i = 0;
return i;
}
template <typename T, class... Ranges>
typename ContainerRange<T,Ranges...>::IndexType ContainerRange<T,Ranges...>::end() const
{
ContainerIndex<T,typename Ranges::IndexType...>
i( std::dynamic_pointer_cast<ContainerRange<T,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
i = size();
return i;
}
*/
} // end namespace MultiArrayTools
#endif

View file

@ -0,0 +1,44 @@
// -*- C++ -*-
/**
@file include/ranges/crange.cc.h
@brief CRange and CIndex template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_crange_cc_h__
#define __cxz_crange_cc_h__
#include "crange.h"
#include "index_mul.h"
namespace CNORXZ
{
template <SizeT I>
decltype(auto) CIndex::stepSize(const IndexId<I>& id) const
{
if constexpr(I != 0){
return SPos<0>();
}
else {
return UPos(id == this->id() ? 1 : 0);
}
}
template <class Xpr, class F>
decltype(auto) CIndex::ifor(const Xpr& xpr, F&& f) const
{
return For<0,Xpr,F>(this->pmax().val(), this->id(), xpr, std::forward<F>(f));
}
template <class I>
decltype(auto) operator*(const Sptr<CIndex>& a, const Sptr<I>& b)
{
return iptrMul(a, b);
}
}
#endif

234
src/include/ranges/crange.h Normal file
View file

@ -0,0 +1,234 @@
// -*- C++ -*-
/**
@file include/ranges/crange.h
@brief CRange and CIndex declaration.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#ifndef __cxz_crange_h__
#define __cxz_crange_h__
#include "base/base.h"
#include "ranges/index_base.h"
#include "ranges/range_base.h"
#include "xpr/xpr.h"
namespace CNORXZ
{
/** ****
Specific index for CRange.
*/
class CIndex : public IndexInterface<CIndex,SizeT>
{
public:
typedef IndexInterface<CIndex,SizeT> IB;
typedef CRange RangeType;
typedef SizeT MetaType;
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
DEFAULT_MEMBERS(CIndex); /**< default constructors and assignments */
/** Construct index from range and position.
@param range Range to iterate over.
@param pos lexicographic position.
*/
CIndex(const RangePtr& range, SizeT pos = 0);
/** @copydoc IndexInterface::operator=(SizeT) */
CIndex& operator=(SizeT lexpos);
/** @copydoc IndexInterface::operator++() */
CIndex& operator++();
/** @copydoc IndexInterface::operator--() */
CIndex& operator--();
/** @copydoc IndexInterface::operator+() */
CIndex operator+(Int n) const;
/** @copydoc IndexInterface::operator-() */
CIndex operator-(Int n) const;
/** @copydoc IndexInterface::operator-(CIndex) */
SizeT operator-(const CIndex& i) const;
/** @copydoc IndexInterface::operator+=() */
CIndex& operator+=(Int n);
/** @copydoc IndexInterface::operator-=() */
CIndex& operator-=(Int n);
/** @copydoc IndexInterface::lex() */
SizeT lex() const;
/** @copydoc IndexInterface::pmax() */
UPos pmax() const;
/** @copydoc IndexInterface::lmax() */
UPos lmax() const;
/** @copydoc IndexInterface::id() */
IndexId<0> id() const;
/** @copydoc IndexInterface::operator*() */
SizeT operator*() const;
/** @copydoc IndexInterface::dim() */
SizeT dim() const;
/** @copydoc IndexInterface::range() */
Sptr<RangeType> range() const;
/** @copydoc IndexInterface::stepSize() */
template <SizeT I>
decltype(auto) stepSize(const IndexId<I>& id) const;
/** @copydoc IndexInterface::stringMeta() */
String stringMeta() const;
/** @copydoc IndexInterface::meta() */
SizeT meta() const;
/** @copydoc IndexInterface::at() */
CIndex& at(const SizeT& metaPos);
/** @copydoc IndexInterface::prange() */
RangePtr prange(const CIndex& last) const;
/** @copydoc IndexInterface::deepFormat() */
SizeT deepFormat() const;
/** @copydoc IndexInterface::deepMax() */
SizeT deepMax() const;
/** @copydoc IndexInterface::reformat() */
CIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
/** @copydoc IndexInterface::ifor() */
template <class Xpr, class F = NoF>
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
/** @copydoc IndexInterface::formatIsTrivial() */
bool formatIsTrivial() const;
/** @copydoc IndexInterface::xpr() */
COpRoot<SizeT,CIndex> xpr(const Sptr<CIndex>& _this) const;
private:
Sptr<RangeType> mRangePtr;
};
/** Make index pack of a CIndex and another index.
@param a pointer to CIndex.
@param b pointer to another index.
*/
template <class I>
decltype(auto) operator*(const Sptr<CIndex>& a, const Sptr<I>& b);
/** ****
Specific factory for CRange.
*/
class CRangeFactory : public RangeFactoryBase
{
public:
typedef CRange oType;
/** Construct and setup factory.
@param size Size of the range to be constructed.
*/
CRangeFactory(SizeT size);
/** Construct and setup factory.
@param size Size of the range to be constructed.
@param ref Range the range to be constructed is related to.
*/
CRangeFactory(SizeT size, RangePtr ref);
protected:
virtual void make() override;
private:
SizeT mSize;
RangePtr mRef;
};
/** ****
Classic Range
The parameter space is given by a
set of positve integer numbers running
form 0 to size-1
*/
class CRange : public RangeInterface<CRange>
{
public:
typedef RangeBase RB;
typedef CIndex IndexType;
typedef SizeT MetaType;
typedef CRangeFactory FType;
friend CRangeFactory;
virtual SizeT size() const override final;
virtual SizeT dim() const override final;
virtual String stringMeta(SizeT pos) const override final;
virtual const TypeInfo& type() const override final;
virtual const TypeInfo& metaType() const override final;
virtual RangePtr extend(const RangePtr& r) const override final;
/** return meta data at given position
@param pos position, size type
*/
SizeT get(SizeT pos) const;
/** return position for given meta data
@param metaPos meta data, size type
*/
SizeT getMeta(SizeT metaPos) const;
protected:
/** default constructor */
CRange() = default;
CRange(const CRange& in) = delete;
/** create range of given size
@param size, input size, size type
*/
CRange(SizeT size);
virtual Vector<Uuid> key() const override final;
SizeT mSize = 0; /**< range size */
SERIALIZATION_FUNCTIONS_NOPUB;
};
/** ***
Specialize RangeCast for casts to CRange
@see RangeCast
*/
template <>
struct RangeCast<CRange>
{
/** cast the range */
static Sptr<CRange> func(const RangePtr& r);
};
/** ***
CIndex can be used as expression
@see index_expression_exists
*/
template <>
struct index_expression_exists<CIndex>
{
static constexpr bool value = true;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show more