Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cd62b6f

Browse files
committed
added tensorframe prototype
1 parent 75ec092 commit cd62b6f

File tree

10 files changed

+449
-9
lines changed

10 files changed

+449
-9
lines changed

CMakeLists.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ MESSAGE(STATUS "CMAKE_ROOT: " ${CMAKE_ROOT})
66
set(CMAKE_VERBOSE_MAKEFILE ON)
77

88
# Project name
9-
project(Taskflow VERSION 2.6.0 LANGUAGES CXX)
9+
project(Taskflow VERSION 2.7.0 LANGUAGES CXX)
1010

1111
# build options
1212
option(TF_BUILD_BENCHMARKS "Enables build of benchmarks" OFF)
@@ -222,6 +222,14 @@ target_include_directories(${PROJECT_NAME} INTERFACE
222222
$<INSTALL_INTERFACE:include/>
223223
)
224224

225+
add_library(TensorFrame INTERFACE)
226+
target_compile_features(TensorFrame INTERFACE cxx_std_17)
227+
target_link_libraries(TensorFrame INTERFACE Threads::Threads)
228+
target_include_directories(TensorFrame INTERFACE
229+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
230+
$<INSTALL_INTERFACE:include/>
231+
)
232+
225233
# -----------------------------------------------------------------------------
226234
# Example program
227235
# -----------------------------------------------------------------------------
@@ -305,6 +313,13 @@ target_link_libraries(
305313
)
306314
endif(CMAKE_CUDA_COMPILER AND TF_BUILD_CUDA)
307315

316+
#### TensorFrame
317+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${TF_EXAMPLE_DIR}/tensorframe)
318+
add_executable(add ${TF_EXAMPLE_DIR}/tensorframe/add.cpp)
319+
target_link_libraries(
320+
add TensorFrame Threads::Threads tf::default_settings
321+
)
322+
308323
endif(TF_BUILD_EXAMPLES)
309324

310325
# -----------------------------------------------------------------------------

doxygen/Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ PROJECT_NAME = "Taskflow"
3838
# could be handy for archiving the generated documentation or if some version
3939
# control system is used.
4040

41-
PROJECT_NUMBER = 2.6.0
41+
PROJECT_NUMBER = 2.7.0 (master branch)
4242

4343
# Using the PROJECT_BRIEF tag one can provide an optional one line description
4444
# for a project that appears at the top of each page and should give viewer a

examples/tensorframe/add.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <taskflow/tensorframe.hpp>
2+
3+
int main(){
4+
5+
tf::Tensor<float> tensor({2, 3, 3, 4}, 10);
6+
7+
tensor.dump(std::cout);
8+
9+
std::cout << tensor.flat_chunk_index(1, 2, 2, 3) << '\n';
10+
std::cout << tensor.flat_index(1, 2, 2, 3) << '\n';
11+
std::cout << tensor.chunk_size() << '\n';
12+
13+
14+
return 0;
15+
}
16+

taskflow/algorithm/for_each.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Task FlowBuilder::for_each_guided(B&& beg, E&& end, C&& c, H&& chunk_size){
114114
q = chunk_size;
115115
}
116116
size_t e0 = (q <= r) ? s0 + q : N;
117-
if(next.compare_exchange_strong(s0, e0, std::memory_order_release,
117+
if(next.compare_exchange_strong(s0, e0, std::memory_order_relaxed,
118118
std::memory_order_relaxed)) {
119119
std::advance(beg, s0-z);
120120
for(size_t x = s0; x< e0; x++) {
@@ -212,7 +212,7 @@ Task FlowBuilder::for_each_index_guided(
212212
q = chunk_size;
213213
}
214214
size_t e0 = (q <= r) ? s0 + q : N;
215-
if(next.compare_exchange_strong(s0, e0, std::memory_order_release,
215+
if(next.compare_exchange_strong(s0, e0, std::memory_order_relaxed,
216216
std::memory_order_relaxed)) {
217217
auto s = static_cast<I>(s0) * inc + beg;
218218
for(size_t x=s0; x<e0; x++, s+= inc) {

taskflow/algorithm/reduce.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ Task FlowBuilder::reduce_guided(
128128
q = C;
129129
}
130130
size_t e0 = (q <= r) ? s0 + q : N;
131-
if(next.compare_exchange_strong(s0, e0, std::memory_order_release,
131+
if(next.compare_exchange_strong(s0, e0, std::memory_order_relaxed,
132132
std::memory_order_relaxed)) {
133133
std::advance(beg, s0-z);
134134
for(size_t x = s0; x<e0; x++, beg++) {
@@ -549,7 +549,7 @@ Task FlowBuilder::transform_reduce_guided(
549549
q = C;
550550
}
551551
size_t e0 = (q <= r) ? s0 + q : N;
552-
if(next.compare_exchange_strong(s0, e0, std::memory_order_release,
552+
if(next.compare_exchange_strong(s0, e0, std::memory_order_relaxed,
553553
std::memory_order_relaxed)) {
554554
std::advance(beg, s0-z);
555555
for(size_t x = s0; x<e0; x++, beg++) {

taskflow/taskflow.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
// TF_VERSION / 100 % 1000 is the minor version
99
// TF_VERSION / 100000 is the major version
1010

11-
// current version: 2.6.0
12-
#define TF_VERSION 200600
11+
// current version: 2.7.0
12+
#define TF_VERSION 200700
1313

1414
#define TF_MAJOR_VERSION TF_VERSION/100000
1515
#define TF_MINOR_VERSION TF_VERSION/100%1000
@@ -21,7 +21,7 @@ namespace tf {
2121
@brief queries the version information in string
2222
*/
2323
constexpr const char* version() {
24-
return "2.6.0";
24+
return "2.7.0";
2525
}
2626

2727

taskflow/tensorframe/tensor.hpp

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#pragma once
2+
3+
#include "../taskflow.hpp"
4+
5+
#include <variant>
6+
#include <filesystem>
7+
8+
namespace tf {
9+
10+
/**
11+
12+
@class Tensor
13+
14+
@brief a tensor contains arithmetic data in N dimensions
15+
16+
*/
17+
template <typename T>
18+
class Tensor {
19+
20+
friend class TensorNode;
21+
friend class TensorExpr;
22+
friend class TensorFrame;
23+
24+
struct Chunk {
25+
std::vector<T> data;
26+
std::string location;
27+
};
28+
29+
public:
30+
31+
Tensor(const Tensor& tensor) = delete;
32+
Tensor(Tensor&& tensor) = delete;
33+
34+
Tensor(std::vector<size_t> shape);
35+
Tensor(std::vector<size_t> shape, size_t max_elements);
36+
37+
const std::vector<size_t>& shape() const;
38+
const std::vector<size_t>& chunk_shape() const;
39+
40+
size_t size() const;
41+
size_t rank() const;
42+
size_t max_elements() const;
43+
size_t chunk_size() const;
44+
size_t num_chunks() const;
45+
46+
void dump(std::ostream& ostream) const;
47+
48+
template <typename... Is>
49+
size_t flat_chunk_index(Is... indices) const;
50+
51+
template <typename... Is>
52+
size_t flat_index(Is... indices) const;
53+
54+
private:
55+
56+
size_t _max_elements {65536*1024}; // 65MB
57+
58+
std::vector<size_t> _shape;
59+
std::vector<size_t> _chunk_shape;
60+
std::vector<size_t> _chunk_grid;
61+
std::vector<Chunk> _chunks;
62+
63+
void _make_chunks();
64+
65+
size_t _flat_chunk_index(size_t&, size_t) const;
66+
67+
template <typename... Is>
68+
size_t _flat_chunk_index(size_t&, size_t, Is...) const;
69+
70+
size_t _flat_index(size_t&, size_t) const;
71+
72+
template <typename... Is>
73+
size_t _flat_index(size_t&, size_t, Is...) const;
74+
};
75+
76+
template <typename T>
77+
Tensor<T>::Tensor(std::vector<size_t> shape) :
78+
_shape {std::move(shape)},
79+
_chunk_shape (_shape.size()),
80+
_chunk_grid (_shape.size()) {
81+
82+
_make_chunks();
83+
}
84+
85+
template <typename T>
86+
Tensor<T>::Tensor(std::vector<size_t> shape, size_t max_elements) :
87+
_max_elements {std::max(1ul, max_elements)},
88+
_shape {std::move(shape)},
89+
_chunk_shape (_shape.size()),
90+
_chunk_grid (_shape.size()) {
91+
92+
_make_chunks();
93+
}
94+
95+
template <typename T>
96+
size_t Tensor<T>::size() const {
97+
return std::accumulate(
98+
_shape.begin(), _shape.end(), 1, std::multiplies<size_t>()
99+
);
100+
}
101+
102+
template <typename T>
103+
size_t Tensor<T>::num_chunks() const {
104+
return _chunks.size();
105+
}
106+
107+
template <typename T>
108+
size_t Tensor<T>::chunk_size() const {
109+
return _chunks[0].data.size();
110+
}
111+
112+
template <typename T>
113+
size_t Tensor<T>::rank() const {
114+
return _shape.size();
115+
}
116+
117+
template <typename T>
118+
size_t Tensor<T>::max_elements() const {
119+
return _max_elements;
120+
}
121+
122+
template <typename T>
123+
const std::vector<size_t>& Tensor<T>::shape() const {
124+
return _shape;
125+
}
126+
127+
template <typename T>
128+
const std::vector<size_t>& Tensor<T>::chunk_shape() const {
129+
return _chunk_shape;
130+
}
131+
132+
template <typename T>
133+
template <typename... Is>
134+
size_t Tensor<T>::flat_chunk_index(Is... rest) const {
135+
136+
if(sizeof...(Is) != rank()) {
137+
TF_THROW("index rank dose not match tensor rank");
138+
}
139+
140+
size_t offset;
141+
return _flat_chunk_index(offset, rest...);
142+
}
143+
144+
template <typename T>
145+
size_t Tensor<T>::_flat_chunk_index(size_t& offset, size_t id) const {
146+
offset = 1;
147+
return id/_chunk_shape.back();
148+
}
149+
150+
template <typename T>
151+
template <typename... Is>
152+
size_t Tensor<T>::_flat_chunk_index(
153+
size_t& offset, size_t id, Is... rest
154+
) const {
155+
auto i = _flat_chunk_index(offset, rest...);
156+
offset *= _chunk_grid[_chunk_shape.size() - (sizeof...(Is))];
157+
return (id/_chunk_shape[_chunk_shape.size() - sizeof...(Is) - 1])*offset + i;
158+
}
159+
160+
template <typename T>
161+
template <typename... Is>
162+
size_t Tensor<T>::flat_index(Is... rest) const {
163+
164+
if(sizeof...(Is) != rank()) {
165+
TF_THROW("index rank dose not match tensor rank");
166+
}
167+
168+
size_t offset;
169+
return _flat_index(offset, rest...);
170+
}
171+
172+
template <typename T>
173+
size_t Tensor<T>::_flat_index(size_t& offset, size_t id) const {
174+
offset = 1;
175+
return id;
176+
}
177+
178+
template <typename T>
179+
template <typename... Is>
180+
size_t Tensor<T>::_flat_index(size_t& offset, size_t id, Is... rest) const {
181+
auto i = _flat_index(offset, rest...);
182+
offset *= _shape[_shape.size() - (sizeof...(Is))];
183+
return id*offset + i;
184+
}
185+
186+
template <typename T>
187+
void Tensor<T>::dump(std::ostream& os) const {
188+
189+
os << "Tensor<" << typeid(T).name() << "> {\n"
190+
<< " shape=[";
191+
192+
for(size_t i=0; i<_shape.size(); ++i) {
193+
if(i) os << 'x';
194+
os << _shape[i];
195+
}
196+
197+
os << "], chunk=[";
198+
199+
for(size_t i=0; i<_chunk_shape.size(); ++i) {
200+
if(i) os << 'x';
201+
os << _chunk_shape[i];
202+
}
203+
204+
os << "], pgrid=[";
205+
206+
for(size_t i=0; i<_chunk_grid.size(); ++i) {
207+
if(i) os << 'x';
208+
os << _chunk_grid[i];
209+
}
210+
211+
os << "]\n}\n";
212+
}
213+
214+
template <typename T>
215+
void Tensor<T>::_make_chunks() {
216+
217+
size_t M = _max_elements;
218+
size_t P = 1;
219+
size_t N = 1;
220+
221+
for(int i=_shape.size()-1; i>=0; i--) {
222+
if(M >= _shape[i]) {
223+
_chunk_shape[i] = _shape[i];
224+
_chunk_grid[i] = 1;
225+
N *= _chunk_shape[i];
226+
M /= _shape[i];
227+
}
228+
else {
229+
_chunk_shape[i] = M;
230+
_chunk_grid[i] = (_shape[i] + _chunk_shape[i] - 1) / _chunk_shape[i];
231+
P *= _chunk_grid[i];
232+
N *= _chunk_shape[i];
233+
for(i--; i>=0; i--) {
234+
_chunk_shape[i] = 1;
235+
_chunk_grid[i] = _shape[i];
236+
P *= _chunk_grid[i];
237+
}
238+
break;
239+
}
240+
}
241+
242+
_chunks.resize(P);
243+
244+
// we allocate the first data in memory
245+
_chunks[0].data.resize(N);
246+
247+
// TODO: the rest sits in the disk
248+
for(size_t i=1; i<_chunks.size(); ++i) {
249+
}
250+
}
251+
252+
} // end of namespace tf -----------------------------------------------------
253+
254+
255+
256+
257+
258+
259+
260+
261+

0 commit comments

Comments
 (0)