| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -128,7 +128,7 @@ namespace af | |||
| 128 | 128 | #endif | |
| 129 | 129 | ||
| 130 | 130 | // Purpose of Addition: "How to add Function" documentation | |
| 131 | - AFAPI array exampleFunction(const array& in, const af_someenum_t param); | ||
| 131 | + AFAPI array exampleFunction(const array& a, const array& b, const af_someenum_t param); | ||
| 132 | 132 | ||
| 133 | 133 | #if AF_API_VERSION >= 34 | |
| 134 | 134 | /// | |
@@ -252,7 +252,9 @@ extern "C" { | |||
| 252 | 252 | #endif | |
| 253 | 253 | ||
| 254 | 254 | // Purpose of Addition: "How to add Function" documentation | |
| 255 | - AFAPI af_err af_example_function(af_array* out, const af_array in, const af_someenum_t param); | ||
| 255 | + AFAPI af_err af_example_function(af_array* out, | ||
| 256 | + const af_array a, const af_array b, | ||
| 257 | + const af_someenum_t param); | ||
| 256 | 258 | ||
| 257 | 259 | /// | |
| 258 | 260 | /// Get the version information of the library | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,7 +35,7 @@ using namespace detail; // detail is an alias to appropriate backend | |||
| 35 | 35 | // change this | |
| 36 | 36 | ||
| 37 | 37 | template<typename T> | |
| 38 | - af_array example(const af_array& in, const af_someenum_t& param) | ||
| 38 | + af_array example(const af_array& a, const af_array& b, const af_someenum_t& param) | ||
| 39 | 39 | { | |
| 40 | 40 | // getArray<T> function is defined in handle.hpp | |
| 41 | 41 | // and it returns backend specific Array, namely one of the following | |
@@ -45,25 +45,23 @@ af_array example(const af_array& in, const af_someenum_t& param) | |||
| 45 | 45 | // getHandle<T> function is defined in handle.hpp takes one of the | |
| 46 | 46 | // above backend specific detail::Array<T> and returns the | |
| 47 | 47 | // universal array handle af_array | |
| 48 | - return getHandle<T>( exampleFunction(getArray<T>(in), param) ); | ||
| 48 | + return getHandle<T>( exampleFunction(getArray<T>(a), getArray<T>(b), param) ); | ||
| 49 | 49 | } | |
| 50 | 50 | ||
| 51 | - af_err af_example_function(af_array* out, | ||
| 52 | - const af_array in, | ||
| 53 | - const af_someenum_t param) | ||
| 51 | + af_err af_example_function(af_array* out, const af_array a, const af_array b, const af_someenum_t param) | ||
| 54 | 52 | { | |
| 55 | 53 | try { | |
| 56 | 54 | af_array output = 0; | |
| 57 | - ArrayInfo info = getInfo(in); // ArrayInfo is the base class which | ||
| 55 | + ArrayInfo info = getInfo(a); // ArrayInfo is the base class which | ||
| 58 | 56 | // each backend specific Array inherits | |
| 59 | 57 | // This class stores the basic array meta-data | |
| 60 | 58 | // such as type of data, dimensions, | |
| 61 | 59 | // offsets and strides. This class is declared | |
| 62 | 60 | // in src/backend/ArrayInfo.hpp | |
| 61 | + ArrayInfo info2 = getInfo(b); | ||
| 63 | 62 | ||
| 64 | 63 | af::dim4 dims = info.dims(); | |
| 65 | 64 | ||
| 66 | - | ||
| 67 | 65 | ARG_ASSERT(2, (dims.ndims()>=0 && dims.ndims()<=3)); | |
| 68 | 66 | // defined in err_common.hpp | |
| 69 | 67 | // there are other useful Macros | |
@@ -72,16 +70,18 @@ af_err af_example_function(af_array* out, | |||
| 72 | 70 | ||
| 73 | 71 | af_dtype type = info.getType(); | |
| 74 | 72 | ||
| 73 | + ARG_ASSERT(2, (info2.getType() == type)); | ||
| 74 | + | ||
| 75 | 75 | switch(type) { // Based on the data type, call backend specific | |
| 76 | 76 | // implementation | |
| 77 | - case f64: output = example<double >(in, param); break; | ||
| 78 | - case f32: output = example<float >(in, param); break; | ||
| 79 | - case s32: output = example<int >(in, param); break; | ||
| 80 | - case u32: output = example<uint >(in, param); break; | ||
| 81 | - case u8: output = example<uchar >(in, param); break; | ||
| 82 | - case b8: output = example<char >(in, param); break; | ||
| 83 | - case c32: output = example<cfloat >(in, param); break; | ||
| 84 | - case c64: output = example<cdouble>(in, param); break; | ||
| 77 | + case f64: output = example<double >(a, b, param); break; | ||
| 78 | + case f32: output = example<float >(a, b, param); break; | ||
| 79 | + case s32: output = example<int >(a, b, param); break; | ||
| 80 | + case u32: output = example<uint >(a, b, param); break; | ||
| 81 | + case u8: output = example<uchar >(a, b, param); break; | ||
| 82 | + case b8: output = example<char >(a, b, param); break; | ||
| 83 | + case c32: output = example<cfloat >(a, b, param); break; | ||
| 84 | + case c64: output = example<cdouble>(a, b, param); break; | ||
| 85 | 85 | default : TYPE_ERROR(1, type); // Another helpful macro from err_common.hpp | |
| 86 | 86 | // that helps throw type based error messages | |
| 87 | 87 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,13 +18,13 @@ | |||
| 18 | 18 | namespace af | |
| 19 | 19 | { | |
| 20 | 20 | ||
| 21 | - array exampleFunction(const array& in, const af_someenum_t p) | ||
| 21 | + array exampleFunction(const array& a, const array& b, const af_someenum_t p) | ||
| 22 | 22 | { | |
| 23 | 23 | // create a temporary af_array handle | |
| 24 | 24 | af_array temp = 0; | |
| 25 | 25 | ||
| 26 | 26 | // call C-API function | |
| 27 | - AF_THROW( af_example_function(&temp, in.get(), p) ); | ||
| 27 | + AF_THROW( af_example_function(&temp, a.get(), b.get(), p) ); | ||
| 28 | 28 | ||
| 29 | 29 | // array::get() returns af_array handle for the corresponding cpp af::array | |
| 30 | 30 | return array(temp); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -51,8 +51,8 @@ af_err af_array_to_string(char **output, const char *exp, const af_array arr, | |||
| 51 | 51 | return CALL(output, exp, arr, precision, transpose); | |
| 52 | 52 | } | |
| 53 | 53 | ||
| 54 | - af_err af_example_function(af_array* out, const af_array in, const af_someenum_t param) | ||
| 54 | + af_err af_example_function(af_array* out, const af_array a, const af_array b, const af_someenum_t param) | ||
| 55 | 55 | { | |
| 56 | - CHECK_ARRAYS(in); | ||
| 57 | - return CALL(out, in, param); | ||
| 56 | + CHECK_ARRAYS(a, b); | ||
| 57 | + return CALL(out, a, b, param); | ||
| 58 | 58 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,14 +22,15 @@ namespace cpu | |||
| 22 | 22 | { | |
| 23 | 23 | ||
| 24 | 24 | template<typename T> | |
| 25 | - Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method) | ||
| 25 | + Array<T> exampleFunction(const Array<T> &a, const Array<T> &b, const af_someenum_t method) | ||
| 26 | 26 | { | |
| 27 | - in.eval(); // All input Arrays should call eval mandatorily | ||
| 27 | + a.eval(); // All input Arrays should call eval mandatorily | ||
| 28 | 28 | // in CPU backend function implementations. Since | |
| 29 | 29 | // the cpu fns are asynchronous launches, any Arrays | |
| 30 | 30 | // that are either views/JIT nodes needs to evaluated | |
| 31 | 31 | // before they are passed onto functions that are | |
| 32 | 32 | // enqueued onto the queues. | |
| 33 | + b.eval(); | ||
| 33 | 34 | ||
| 34 | 35 | dim4 outputDims; // this should be '= in.dims();' in most cases | |
| 35 | 36 | // but would definitely depend on the type of | |
@@ -42,27 +43,52 @@ Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method) | |||
| 42 | 43 | // file to know what are the different types you | |
| 43 | 44 | // can create. | |
| 44 | 45 | ||
| 45 | - //dim4 in_dims = in.dims(); // you can retrieve dimensions | ||
| 46 | + dim4 aDims = a.dims(); // you can retrieve dimensions | ||
| 47 | + dim4 bDims = b.dims(); | ||
| 48 | + dim4 oDims = out.dims(); | ||
| 46 | 49 | ||
| 47 | - //dim_t in_offset = in.getOffset(); // you can retrieve the offset - used when given array | ||
| 50 | + dim_t aOffset = a.getOffset(); // you can retrieve the offset - used when given array | ||
| 48 | 51 | // is an sub-array pointing to some other array and | |
| 49 | 52 | // doesn't have memory of its own | |
| 53 | + dim_t bOffset = b.getOffset(); | ||
| 50 | 54 | ||
| 51 | - //dim4 in_strides = in.strides(); // you can retrieve strides | ||
| 55 | + dim4 aStrides = a.strides(); // you can retrieve strides | ||
| 56 | + dim4 bStrides = b.strides(); | ||
| 57 | + dim4 oStrides = out.strides(); | ||
| 52 | 58 | ||
| 53 | - //const T* src = in.get(); // cpu::Array<T>::get returns the pointer to the | ||
| 59 | + const T* src1 = a.get(); // cpu::Array<T>::get returns the pointer to the | ||
| 54 | 60 | // memory allocated for that Array | |
| 61 | + const T* src2 = b.get(); // cpu::Array<T>::get returns the pointer to the | ||
| 62 | + // memory allocated for that Array | ||
| 63 | + src1 += aOffset; | ||
| 64 | + src2 += bOffset; | ||
| 55 | 65 | ||
| 56 | - //T* dst = out.get(); | ||
| 66 | + T* dst = out.get(); | ||
| 57 | 67 | ||
| 58 | 68 | // Implement your algorithm and write results to dst | |
| 69 | + for(int j=0; j<aDims[1]; ++j) { | ||
| 70 | + for (int i=0; i<aDims[0]; ++i) { | ||
| 71 | + | ||
| 72 | + int src1Idx = i*aStrides[0] + j*aStrides[1]; | ||
| 73 | + int src2Idx = i*bStrides[0] + j*bStrides[1]; | ||
| 74 | + int dstIdx = i*oStrides[0] + j*oStrides[1]; | ||
| 75 | + | ||
| 76 | + // kernel algorithm goes here | ||
| 77 | + switch(method) { | ||
| 78 | + case 1: dst[dstIdx] = src1[src1Idx] + src2[src2Idx]; break; | ||
| 79 | + case 2: dst[dstIdx] = src1[src1Idx] - src2[src2Idx]; break; | ||
| 80 | + case 3: dst[dstIdx] = src1[src1Idx] * src2[src2Idx]; break; | ||
| 81 | + case 4: dst[dstIdx] = src1[src1Idx] / src2[src2Idx]; break; | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + } | ||
| 59 | 85 | ||
| 60 | 86 | return out; // return the result | |
| 61 | 87 | } | |
| 62 | 88 | ||
| 63 | 89 | ||
| 64 | 90 | #define INSTANTIATE(T) \ | |
| 65 | - template Array<T> exampleFunction<T>(const Array<T> &in, const af_someenum_t method); | ||
| 91 | + template Array<T> exampleFunction<T>(const Array<T> &a, const Array<T> &b, const af_someenum_t method); | ||
| 66 | 92 | ||
| 67 | 93 | // INSTANTIATIONS for all the types which | |
| 68 | 94 | // are present in the switch case statement | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,6 @@ | |||
| 12 | 12 | namespace cpu | |
| 13 | 13 | { | |
| 14 | 14 | template<typename T> | |
| 15 | - Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method); | ||
| 15 | + Array<T> exampleFunction(const Array<T> &a, const Array<T> &b, const af_someenum_t method); | ||
| 16 | 16 | } | |
| 17 | 17 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,7 +27,7 @@ namespace cuda | |||
| 27 | 27 | { | |
| 28 | 28 | ||
| 29 | 29 | template<typename T> | |
| 30 | - Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method) | ||
| 30 | + Array<T> exampleFunction(const Array<T> &a, const Array<T> &b, const af_someenum_t method) | ||
| 31 | 31 | { | |
| 32 | 32 | dim4 outputDims; // this should be '= in.dims();' in most cases | |
| 33 | 33 | // but would definitely depend on the type of | |
@@ -41,14 +41,14 @@ Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method) | |||
| 41 | 41 | // can create. | |
| 42 | 42 | ||
| 43 | 43 | // Relay the actual computation to CUDA kernel wrapper | |
| 44 | - kernel::exampleFunc<T>(out, in, method); | ||
| 44 | + kernel::exampleFunc<T>(out, a, b, method); | ||
| 45 | 45 | ||
| 46 | 46 | return out; // return the result | |
| 47 | 47 | } | |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | 50 | #define INSTANTIATE(T) \ | |
| 51 | - template Array<T> exampleFunction<T>(const Array<T> &in, const af_someenum_t method); | ||
| 51 | + template Array<T> exampleFunction<T>(const Array<T> &a, const Array<T> &b, const af_someenum_t method); | ||
| 52 | 52 | ||
| 53 | 53 | // INSTANTIATIONS for all the types which | |
| 54 | 54 | // are present in the switch case statement | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,5 +12,5 @@ | |||
| 12 | 12 | namespace cuda | |
| 13 | 13 | { | |
| 14 | 14 | template<typename T> | |
| 15 | - Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method); | ||
| 15 | + Array<T> exampleFunction(const Array<T> &a, const Array<T> &b, const af_someenum_t method); | ||
| 16 | 16 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,20 +35,41 @@ static const unsigned TY = 16; // Kernel Launch Config Values | |||
| 35 | 35 | ||
| 36 | 36 | template<typename T> | |
| 37 | 37 | __global__ | |
| 38 | - void exampleFuncKernel(Param<T> out, CParam<T> in, const af_someenum_t p) | ||
| 38 | + void exampleFuncKernel(Param<T> c, CParam<T> a, CParam<T> b, const af_someenum_t p) | ||
| 39 | 39 | { | |
| 40 | - // kernel implementation goes here | ||
| 40 | + // get current thread global identifiers along required dimensions | ||
| 41 | + int i = blockDim.x * blockIdx.x + threadIdx.x; | ||
| 42 | + int j = blockDim.y * blockIdx.y + threadIdx.y; | ||
| 43 | + | ||
| 44 | + if ( i<a.dims[0] && j<a.dims[1] ) { | ||
| 45 | + // if needed use strides array to compute linear index of arrays | ||
| 46 | + int src1Idx = i*a.strides[0] + j*a.strides[1]; | ||
| 47 | + int src2Idx = i*b.strides[0] + j*b.strides[1]; | ||
| 48 | + int dstIdx = i*c.strides[0] + j*c.strides[1]; | ||
| 49 | + | ||
| 50 | + T* dst = c.ptr; | ||
| 51 | + const T* src1 = a.ptr; | ||
| 52 | + const T* src2 = b.ptr; | ||
| 53 | + | ||
| 54 | + // kernel algorithm goes here | ||
| 55 | + switch(p) { | ||
| 56 | + case 1: dst[dstIdx] = src1[src1Idx] + src2[src2Idx]; break; | ||
| 57 | + case 2: dst[dstIdx] = src1[src1Idx] - src2[src2Idx]; break; | ||
| 58 | + case 3: dst[dstIdx] = src1[src1Idx] * src2[src2Idx]; break; | ||
| 59 | + case 4: dst[dstIdx] = src1[src1Idx] / src2[src2Idx]; break; | ||
| 60 | + } | ||
| 61 | + } | ||
| 41 | 62 | } | |
| 42 | 63 | ||
| 43 | 64 | ||
| 44 | 65 | template <typename T> // CUDA kernel wrapper function | |
| 45 | - void exampleFunc(Param<T> out, CParam<T> in, const af_someenum_t p) | ||
| 66 | + void exampleFunc(Param<T> c, CParam<T> a, CParam<T> b, const af_someenum_t p) | ||
| 46 | 67 | { | |
| 47 | 68 | ||
| 48 | 69 | dim3 threads(TX, TY, 1); // set your cuda launch config for blocks | |
| 49 | 70 | ||
| 50 | - int blk_x = divup(out.dims[0], threads.x); | ||
| 51 | - int blk_y = divup(out.dims[1], threads.y); | ||
| 71 | + int blk_x = divup(c.dims[0], threads.x); | ||
| 72 | + int blk_y = divup(c.dims[1], threads.y); | ||
| 52 | 73 | dim3 blocks(blk_x, blk_y); // set your opencl launch config for grid | |
| 53 | 74 | ||
| 54 | 75 | // launch your kernel | |
@@ -61,7 +82,7 @@ void exampleFunc(Param<T> out, CParam<T> in, const af_someenum_t p) | |||
| 61 | 82 | // | |
| 62 | 83 | // CUDA_LAUNCH_SMEM takes in an additional parameter, size of shared memory, after | |
| 63 | 84 | // threads paramters, which are then followed by kernel parameters | |
| 64 | - CUDA_LAUNCH((exampleFuncKernel<T>), blocks, threads, out, in, p); | ||
| 85 | + CUDA_LAUNCH((exampleFuncKernel<T>), blocks, threads, c, a, b, p); | ||
| 65 | 86 | ||
| 66 | 87 | POST_LAUNCH_CHECK(); // Macro for post kernel launch checks | |
| 67 | 88 | // these checks are carried ONLY IN DEBUG mode | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,7 +27,7 @@ namespace opencl | |||
| 27 | 27 | { | |
| 28 | 28 | ||
| 29 | 29 | template<typename T> | |
| 30 | - Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method) | ||
| 30 | + Array<T> exampleFunction(const Array<T> &a, const Array<T> &b, const af_someenum_t method) | ||
| 31 | 31 | { | |
| 32 | 32 | dim4 outputDims; // this should be '= in.dims();' in most cases | |
| 33 | 33 | // but would definitely depend on the type of | |
@@ -41,14 +41,14 @@ Array<T> exampleFunction(const Array<T> &in, const af_someenum_t method) | |||
| 41 | 41 | // can create. | |
| 42 | 42 | ||
| 43 | 43 | // Relay the actual computation to OpenCL kernel wrapper | |
| 44 | - kernel::exampleFunc<T>(out, in, method); | ||
| 44 | + kernel::exampleFunc<T>(out, a, b, method); | ||
| 45 | 45 | ||
| 46 | 46 | return out; // return the result | |
| 47 | 47 | } | |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | 50 | #define INSTANTIATE(T) \ | |
| 51 | - template Array<T> exampleFunction<T>(const Array<T> &in, const af_someenum_t method); | ||
| 51 | + template Array<T> exampleFunction<T>(const Array<T> &a, const Array<T> &b, const af_someenum_t method); | ||
| 52 | 52 | ||
| 53 | 53 | // INSTANTIATIONS for all the types which | |
| 54 | 54 | // are present in the switch case statement | |
| Back | FazBrowse Home | New Git URL |
0 commit comments