MCPcopy Create free account
hub / github.com/arrayfire/arrayfire / join

Function join

src/backend/oneapi/join.cpp:41–162  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

39
40template<typename T>
41Array<T> join(const int jdim, const Array<T> &first, const Array<T> &second) {
42 // All dimensions except join dimension must be equal
43 const dim4 &fdims{first.dims()};
44 const dim4 &sdims{second.dims()};
45
46 // Compute output dims
47 dim4 odims(fdims);
48 odims.dims[jdim] += sdims.dims[jdim];
49 Array<T> out = createEmptyArray<T>(odims);
50
51 // topspeed is achieved when byte size(in+out) ~= L2CacheSize
52 //
53 // 1 array: memcpy always copies 1 array. topspeed
54 // --> size(in) <= L2CacheSize/2
55 // 2 arrays: topspeeds
56 // - size(in) < L2CacheSize/2/2
57 // --> JIT can copy 2 arrays in // and is fastest
58 // (condition: array sizes have to be identical)
59 // - size(in) < L2CacheSize/2
60 // --> memcpy will achieve highest speed, although the kernel
61 // has to be called twice
62 // - size(in) >= L2CacheSize/2
63 // --> memcpy will achieve veryLargeArray speed. The kernel
64 // will be called twice
65 if (fdims.dims[jdim] == sdims.dims[jdim]) {
66 const size_t L2CacheSize{getL2CacheSize(oneapi::getDevice())};
67 if (!(first.isReady() || second.isReady()) ||
68 (fdims.elements() * sizeof(T) * 2 * 2 < L2CacheSize)) {
69 // Both arrays have same size & everything fits into the cache,
70 // so thread in 1 JIT kernel, iso individual copies which is
71 // always slower
72 const dim_t *outStrides{out.strides().dims};
73 vector<Param<T>> outputs{
74 {out.get(),
75 {{fdims.dims[0], fdims.dims[1], fdims.dims[2], fdims.dims[3]},
76 {outStrides[0], outStrides[1], outStrides[2], outStrides[3]},
77 0}},
78 {out.get(),
79 {{sdims.dims[0], sdims.dims[1], sdims.dims[2], sdims.dims[3]},
80 {outStrides[0], outStrides[1], outStrides[2], outStrides[3]},
81 fdims.dims[jdim] * outStrides[jdim]}}};
82 // Extend the life of the returned node, bij saving the
83 // corresponding shared_ptr
84 const Node_ptr fNode{first.getNode()};
85 const Node_ptr sNode{second.getNode()};
86 vector<Node *> nodes{fNode.get(), sNode.get()};
87 evalNodes(outputs, nodes);
88 return out;
89 }
90 // continue because individually processing is faster
91 }
92
93 // Handle each array individually
94 if (first.isReady()) {
95 if (1LL + jdim >= first.ndims() && first.isLinear()) {
96 // first & out are linear
97 auto first_array = first.get();
98 auto out_array = out.get();

Callers

nothing calls this directly

Calls 15

getDeviceFunction · 0.85
beginFunction · 0.85
getL2CacheSizeFunction · 0.70
evalNodesFunction · 0.70
getQueueFunction · 0.50
dim4Class · 0.50
dimsMethod · 0.45
isReadyMethod · 0.45
elementsMethod · 0.45
stridesMethod · 0.45
getMethod · 0.45
getNodeMethod · 0.45

Tested by

no test coverage detected