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

Function join

src/backend/opencl/join.cpp:30–129  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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

Callers 1

compileModuleFunction · 0.70

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