From 52822c5bde44a4a7b05b4d8e3fbd79d80f698cb1 Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Wed, 10 Mar 2021 04:17:06 -0800 Subject: [PATCH 1/6] [RUNTIME] OpenCL texture memory. --- src/runtime/opencl/opencl_common.h | 33 +++++ src/runtime/opencl/opencl_device_api.cc | 120 +++++++++++++++++- .../unittest/test_target_codegen_opencl.py | 10 ++ 3 files changed, 158 insertions(+), 5 deletions(-) diff --git a/src/runtime/opencl/opencl_common.h b/src/runtime/opencl/opencl_common.h index 2e7f05f91020..04cc51af8549 100644 --- a/src/runtime/opencl/opencl_common.h +++ b/src/runtime/opencl/opencl_common.h @@ -162,6 +162,29 @@ inline const char* CLGetErrorString(cl_int error) { } } +inline cl_channel_type DTypeToOpenCLChannelType(DLDataType data_type) { + DataType dtype(data_type); + if (dtype == DataType::Float(32)) { + return CL_FLOAT; + } else if (dtype == DataType::Float(16)) { + return CL_HALF_FLOAT; + } else if (dtype == DataType::Int(8)) { + return CL_SIGNED_INT8; + } else if (dtype == DataType::Int(16)) { + return CL_SIGNED_INT16; + } else if (dtype == DataType::Int(32)) { + return CL_SIGNED_INT32; + } else if (dtype == DataType::UInt(8)) { + return CL_UNSIGNED_INT8; + } else if (dtype == DataType::UInt(16)) { + return CL_UNSIGNED_INT16; + } else if (dtype == DataType::UInt(32)) { + return CL_UNSIGNED_INT32; + } + LOG(FATAL) << "data type is not supported in OpenCL runtime yet: " << dtype; + return CL_FLOAT; +} + /*! * \brief Protected OpenCL call * \param func Expression to call. @@ -231,6 +254,8 @@ class OpenCLWorkspace : public DeviceAPI { void SetDevice(TVMContext ctx) final; void GetAttr(TVMContext ctx, DeviceAttrKind kind, TVMRetValue* rv) final; void* AllocDataSpace(TVMContext ctx, size_t size, size_t alignment, DLDataType type_hint) final; + void* AllocDataSpace(TVMContext ctx, int ndim, const int64_t* shape, DLDataType dtype, + Optional mem_scope = NullOpt) final; void FreeDataSpace(TVMContext ctx, void* ptr) final; void StreamSync(TVMContext ctx, TVMStreamHandle stream) final; void* AllocWorkspace(TVMContext ctx, size_t size, DLDataType type_hint) final; @@ -337,6 +362,14 @@ class OpenCLModuleNode : public ModuleNode { std::vector kernels_; }; +inline cl_mem_object_type GetMemObjectType(const void* mem_ptr) { + cl_mem mem = static_cast((void*)mem_ptr); + cl_mem_info param_name = CL_MEM_TYPE; + cl_mem_object_type mem_type; + OPENCL_CALL(clGetMemObjectInfo(mem, param_name, sizeof(mem_type), &mem_type, NULL)); + return mem_type; +} + } // namespace runtime } // namespace tvm #endif // TVM_RUNTIME_OPENCL_OPENCL_COMMON_H_ diff --git a/src/runtime/opencl/opencl_device_api.cc b/src/runtime/opencl/opencl_device_api.cc index a3ec21e28f1d..d5ffd85e224c 100644 --- a/src/runtime/opencl/opencl_device_api.cc +++ b/src/runtime/opencl/opencl_device_api.cc @@ -126,6 +126,81 @@ void* OpenCLWorkspace::AllocDataSpace(TVMContext ctx, size_t size, size_t alignm return mptr; } +static inline size_t GetDataAlignment(const DLDataType dtype) { + size_t align = (dtype.bits / 8) * dtype.lanes; + if (align < kAllocAlignment) return kAllocAlignment; + return align; +} + +static std::tuple FlatShapeTo2D(std::vector shape) { + ICHECK(shape.size() >= 1 && shape.back() == 4); + while (shape.size() < 3) { + shape.insert(shape.end() - 1, 1); + } + int64_t width = 1; + for (auto it = shape.begin(); it < shape.end() - 2; ++it) { + width *= *it; + } + int64_t height = *(shape.end() - 2); + return std::make_tuple(width, height); +} + +void* OpenCLWorkspace::AllocDataSpace(TVMContext ctx, int ndim, const int64_t* shape, + DLDataType dtype, Optional mem_scope) { + if (!mem_scope.defined() || mem_scope.value() == "global") { + // by default, we can always redirect to the flat memory allocations + DLTensor temp; + temp.data = nullptr; + temp.ctx = ctx; + temp.ndim = ndim; + temp.dtype = dtype; + temp.shape = const_cast(shape); + temp.strides = nullptr; + temp.byte_offset = 0; + size_t size = GetDataSize(temp); + size_t alignment = GetDataAlignment(temp.dtype); + return AllocDataSpace(ctx, size, alignment, dtype); + } else if (mem_scope.value() == "global:texture-act") { + this->Init(); + ICHECK(this->context != nullptr) << "No OpenCL device"; + cl_image_format image_format; + image_format.image_channel_data_type = DTypeToOpenCLChannelType(dtype); + cl_image_desc image_desc; + + // shape must be (?, ..., ?, 4) + ICHECK_GT(ndim, 1); + ICHECK_EQ(shape[ndim - 1], 4); + // prepare descriptors + image_format.image_channel_order = CL_RGBA; + image_desc.image_type = CL_MEM_OBJECT_IMAGE2D; + // flat the tensor shape to 2D image + size_t width, height; + std::vector vshape(shape, shape + ndim); + std::tie(width, height) = FlatShapeTo2D(vshape); + // LOG(INFO) << "width = " << width; + // LOG(INFO) << "height = " << height; + image_desc.image_width = width; + image_desc.image_height = height; + image_desc.image_depth = 1; + image_desc.image_array_size = 1; + image_desc.image_row_pitch = 0; + image_desc.image_slice_pitch = 0; + image_desc.num_mip_levels = 0; + image_desc.num_samples = 0; + image_desc.buffer= NULL; + + cl_int err_code; + cl_mem mptr = clCreateImage(this->context, CL_MEM_READ_WRITE, &image_format, &image_desc, + nullptr, &err_code); + OPENCL_CHECK_ERROR(err_code); + return mptr; + } else { + LOG(FATAL) << "Device does not support allocate data space with " + << "specified memory scope: " << mem_scope.value(); + return nullptr; + } +} + void OpenCLWorkspace::FreeDataSpace(TVMContext ctx, void* ptr) { // We have to make sure that the memory object is not in the command queue // for some OpenCL platforms. @@ -135,6 +210,17 @@ void OpenCLWorkspace::FreeDataSpace(TVMContext ctx, void* ptr) { OPENCL_CALL(clReleaseMemObject(mptr)); } +static inline void GetImageShape(const void* mem_ptr, size_t* region) { + cl_mem mem = static_cast((void*)mem_ptr); + size_t width, height; + OPENCL_CALL(clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL)); + OPENCL_CALL(clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL)); + region[0] = width; + region[1] = height; + region[2] = 1; + return; +} + void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* to, size_t to_offset, size_t size, TVMContext ctx_from, TVMContext ctx_to, DLDataType type_hint, @@ -147,11 +233,35 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* static_cast(to), from_offset, to_offset, size, 0, nullptr, nullptr)); } else if (IsOpenCLDevice(ctx_from) && ctx_to.device_type == kDLCPU) { - OPENCL_CALL(clEnqueueReadBuffer(this->GetQueue(ctx_from), - static_cast((void*)from), // NOLINT(*) - CL_FALSE, from_offset, size, static_cast(to) + to_offset, - 0, nullptr, nullptr)); - OPENCL_CALL(clFinish(this->GetQueue(ctx_from))); + cl_mem_object_type from_type = GetMemObjectType(from); + switch (from_type) { + case CL_MEM_OBJECT_BUFFER: + // LOG(INFO) << "Buffer"; + OPENCL_CALL(clEnqueueReadBuffer(this->GetQueue(ctx_from), + static_cast((void*)from), // NOLINT(*) + CL_FALSE, from_offset, size, static_cast(to) + to_offset, + 0, nullptr, nullptr)); + OPENCL_CALL(clFinish(this->GetQueue(ctx_from))); + break; + case CL_MEM_OBJECT_IMAGE2D: { + // LOG(INFO) << "Image2D"; + size_t origin[3] = {0, 0, 0}; + size_t region[3]; + GetImageShape(from, region); + // LOG(INFO) << "region[0] = " << region[0]; + // LOG(INFO) << "region[1] = " << region[1]; + // LOG(INFO) << "region[2] = " << region[2]; + OPENCL_CALL(clEnqueueReadImage(this->GetQueue(ctx_from), + static_cast((void*)from), // NOLINT(*) + CL_FALSE, origin, region, 0, 0, + static_cast(to) + to_offset, + 0, nullptr, nullptr)); + OPENCL_CALL(clFinish(this->GetQueue(ctx_from))); + break; + } + default: + LOG(FATAL) << "OpenCL memory type is wrong."; + } } else if (ctx_from.device_type == kDLCPU && IsOpenCLDevice(ctx_to)) { OPENCL_CALL(clEnqueueWriteBuffer(this->GetQueue(ctx_to), static_cast(to), CL_FALSE, to_offset, size, static_cast(from) + from_offset, diff --git a/tests/python/unittest/test_target_codegen_opencl.py b/tests/python/unittest/test_target_codegen_opencl.py index 8a070da89641..05d448f4face 100644 --- a/tests/python/unittest/test_target_codegen_opencl.py +++ b/tests/python/unittest/test_target_codegen_opencl.py @@ -119,7 +119,17 @@ def check_max(ctx, n, dtype): check_max(ctx, 1, "float32") check_max(ctx, 1, "float64") +def test_opencl_texture_memory(): + def check_allocate_and_copy(shape): + ctx = tvm.opencl(0) + arr = tvm.nd.empty(shape, "float32", ctx, "global:texture-act") + np_arr = arr.asnumpy() + + check_allocate_and_copy((3, 4)) + check_allocate_and_copy((5, 6, 4)) + check_allocate_and_copy((8, 5, 6, 4)) if __name__ == "__main__": test_opencl_ternary_expression() test_opencl_inf_nan() + test_opencl_texture_memory() From dc5981c56cedded464edd2b209c975328706d81f Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Wed, 10 Mar 2021 04:49:30 -0800 Subject: [PATCH 2/6] [RUNTIME] Support memory copy. --- src/runtime/opencl/opencl_device_api.cc | 60 ++++++++++++++----- .../unittest/test_target_codegen_opencl.py | 12 ++-- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/runtime/opencl/opencl_device_api.cc b/src/runtime/opencl/opencl_device_api.cc index d5ffd85e224c..a87154f747a9 100644 --- a/src/runtime/opencl/opencl_device_api.cc +++ b/src/runtime/opencl/opencl_device_api.cc @@ -228,15 +228,31 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* this->Init(); ICHECK(stream == nullptr); if (IsOpenCLDevice(ctx_from) && IsOpenCLDevice(ctx_to)) { - OPENCL_CALL(clEnqueueCopyBuffer(this->GetQueue(ctx_to), - static_cast((void*)from), // NOLINT(*) - static_cast(to), from_offset, to_offset, size, 0, - nullptr, nullptr)); + cl_mem_object_type from_type = GetMemObjectType(from); + cl_mem_object_type to_type = GetMemObjectType(to); + if (from_type == CL_MEM_OBJECT_BUFFER && to_type == CL_MEM_OBJECT_BUFFER) { + OPENCL_CALL(clEnqueueCopyBuffer(this->GetQueue(ctx_to), + static_cast((void*)from), // NOLINT(*) + static_cast(to), from_offset, to_offset, size, 0, + nullptr, nullptr)); + } else if (from_type == CL_MEM_OBJECT_IMAGE2D && + to_type == CL_MEM_OBJECT_IMAGE2D) { + size_t from_origin[3] = {0, 0, 0}; + size_t to_origin[3] = {0, 0, 0}; + size_t region[3]; + GetImageShape(from, region); + OPENCL_CALL(clEnqueueCopyImage(this->GetQueue(ctx_to), + static_cast((void*)from), // NOLINT(*) + static_cast(to), + from_origin, to_origin, region, + 0, nullptr, nullptr)); + } else { + LOG(FATAL) << "OpenCL memory object type is wrong."; + } } else if (IsOpenCLDevice(ctx_from) && ctx_to.device_type == kDLCPU) { cl_mem_object_type from_type = GetMemObjectType(from); switch (from_type) { case CL_MEM_OBJECT_BUFFER: - // LOG(INFO) << "Buffer"; OPENCL_CALL(clEnqueueReadBuffer(this->GetQueue(ctx_from), static_cast((void*)from), // NOLINT(*) CL_FALSE, from_offset, size, static_cast(to) + to_offset, @@ -244,13 +260,9 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* OPENCL_CALL(clFinish(this->GetQueue(ctx_from))); break; case CL_MEM_OBJECT_IMAGE2D: { - // LOG(INFO) << "Image2D"; size_t origin[3] = {0, 0, 0}; size_t region[3]; GetImageShape(from, region); - // LOG(INFO) << "region[0] = " << region[0]; - // LOG(INFO) << "region[1] = " << region[1]; - // LOG(INFO) << "region[2] = " << region[2]; OPENCL_CALL(clEnqueueReadImage(this->GetQueue(ctx_from), static_cast((void*)from), // NOLINT(*) CL_FALSE, origin, region, 0, 0, @@ -260,13 +272,33 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* break; } default: - LOG(FATAL) << "OpenCL memory type is wrong."; + LOG(FATAL) << "OpenCL memory object type is wrong."; } } else if (ctx_from.device_type == kDLCPU && IsOpenCLDevice(ctx_to)) { - OPENCL_CALL(clEnqueueWriteBuffer(this->GetQueue(ctx_to), static_cast(to), CL_FALSE, - to_offset, size, static_cast(from) + from_offset, - 0, nullptr, nullptr)); - OPENCL_CALL(clFinish(this->GetQueue(ctx_to))); + cl_mem_object_type to_type = GetMemObjectType(to); + switch (to_type) { + case CL_MEM_OBJECT_BUFFER: + OPENCL_CALL(clEnqueueWriteBuffer(this->GetQueue(ctx_to), static_cast(to), CL_FALSE, + to_offset, size, static_cast(from) + from_offset, + 0, nullptr, nullptr)); + OPENCL_CALL(clFinish(this->GetQueue(ctx_to))); + break; + case CL_MEM_OBJECT_IMAGE2D: { + size_t origin[3] = {0, 0, 0}; + size_t region[3]; + GetImageShape(to, region); + OPENCL_CALL(clEnqueueWriteImage(this->GetQueue(ctx_to), + static_cast((void*)to), // NOLINT(*) + CL_FALSE, origin, region, 0, 0, + static_cast(from) + from_offset, + 0, nullptr, nullptr)); + OPENCL_CALL(clFinish(this->GetQueue(ctx_to))); + break; + } + default: + LOG(FATAL) << "OpenCL memory type is wrong."; + } + } else { LOG(FATAL) << "Expect copy from/to OpenCL or between OpenCL"; } diff --git a/tests/python/unittest/test_target_codegen_opencl.py b/tests/python/unittest/test_target_codegen_opencl.py index 05d448f4face..6942efce3e40 100644 --- a/tests/python/unittest/test_target_codegen_opencl.py +++ b/tests/python/unittest/test_target_codegen_opencl.py @@ -15,8 +15,9 @@ # specific language governing permissions and limitations # under the License. import tvm -from tvm import te +from tvm import te, nd import tvm.testing +import numpy as np target = "opencl" @@ -121,9 +122,12 @@ def check_max(ctx, n, dtype): def test_opencl_texture_memory(): def check_allocate_and_copy(shape): - ctx = tvm.opencl(0) - arr = tvm.nd.empty(shape, "float32", ctx, "global:texture-act") - np_arr = arr.asnumpy() + cpu_arr = nd.array(np.random.rand(*shape).astype('float32'), tvm.cpu(0)) + opencl_arr0 = nd.empty(cpu_arr.shape, cpu_arr.dtype, tvm.opencl(0), "global:texture-act") + opencl_arr1 = nd.empty(cpu_arr.shape, cpu_arr.dtype, tvm.opencl(0), "global:texture-act") + cpu_arr.copyto(opencl_arr0) + opencl_arr0.copyto(opencl_arr1) + np.testing.assert_equal(cpu_arr.asnumpy(), opencl_arr1.asnumpy()) check_allocate_and_copy((3, 4)) check_allocate_and_copy((5, 6, 4)) From 6034fa827ae22d30f0910071cdd9c97a2cf91ab5 Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Wed, 10 Mar 2021 04:55:07 -0800 Subject: [PATCH 3/6] [RUNTIME] Clang. --- src/runtime/opencl/opencl_device_api.cc | 41 ++++++++++++------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/runtime/opencl/opencl_device_api.cc b/src/runtime/opencl/opencl_device_api.cc index a87154f747a9..5c86c6820d17 100644 --- a/src/runtime/opencl/opencl_device_api.cc +++ b/src/runtime/opencl/opencl_device_api.cc @@ -174,7 +174,7 @@ void* OpenCLWorkspace::AllocDataSpace(TVMContext ctx, int ndim, const int64_t* s image_format.image_channel_order = CL_RGBA; image_desc.image_type = CL_MEM_OBJECT_IMAGE2D; // flat the tensor shape to 2D image - size_t width, height; + size_t width, height; std::vector vshape(shape, shape + ndim); std::tie(width, height) = FlatShapeTo2D(vshape); // LOG(INFO) << "width = " << width; @@ -187,18 +187,18 @@ void* OpenCLWorkspace::AllocDataSpace(TVMContext ctx, int ndim, const int64_t* s image_desc.image_slice_pitch = 0; image_desc.num_mip_levels = 0; image_desc.num_samples = 0; - image_desc.buffer= NULL; + image_desc.buffer = NULL; cl_int err_code; cl_mem mptr = clCreateImage(this->context, CL_MEM_READ_WRITE, &image_format, &image_desc, - nullptr, &err_code); + nullptr, &err_code); OPENCL_CHECK_ERROR(err_code); return mptr; } else { LOG(FATAL) << "Device does not support allocate data space with " << "specified memory scope: " << mem_scope.value(); return nullptr; - } + } } void OpenCLWorkspace::FreeDataSpace(TVMContext ctx, void* ptr) { @@ -212,7 +212,7 @@ void OpenCLWorkspace::FreeDataSpace(TVMContext ctx, void* ptr) { static inline void GetImageShape(const void* mem_ptr, size_t* region) { cl_mem mem = static_cast((void*)mem_ptr); - size_t width, height; + size_t width, height; OPENCL_CALL(clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL)); OPENCL_CALL(clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL)); region[0] = width; @@ -235,17 +235,15 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* static_cast((void*)from), // NOLINT(*) static_cast(to), from_offset, to_offset, size, 0, nullptr, nullptr)); - } else if (from_type == CL_MEM_OBJECT_IMAGE2D && - to_type == CL_MEM_OBJECT_IMAGE2D) { + } else if (from_type == CL_MEM_OBJECT_IMAGE2D && to_type == CL_MEM_OBJECT_IMAGE2D) { size_t from_origin[3] = {0, 0, 0}; size_t to_origin[3] = {0, 0, 0}; size_t region[3]; GetImageShape(from, region); OPENCL_CALL(clEnqueueCopyImage(this->GetQueue(ctx_to), static_cast((void*)from), // NOLINT(*) - static_cast(to), - from_origin, to_origin, region, - 0, nullptr, nullptr)); + static_cast(to), from_origin, to_origin, region, 0, + nullptr, nullptr)); } else { LOG(FATAL) << "OpenCL memory object type is wrong."; } @@ -255,8 +253,8 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* case CL_MEM_OBJECT_BUFFER: OPENCL_CALL(clEnqueueReadBuffer(this->GetQueue(ctx_from), static_cast((void*)from), // NOLINT(*) - CL_FALSE, from_offset, size, static_cast(to) + to_offset, - 0, nullptr, nullptr)); + CL_FALSE, from_offset, size, + static_cast(to) + to_offset, 0, nullptr, nullptr)); OPENCL_CALL(clFinish(this->GetQueue(ctx_from))); break; case CL_MEM_OBJECT_IMAGE2D: { @@ -265,9 +263,8 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* GetImageShape(from, region); OPENCL_CALL(clEnqueueReadImage(this->GetQueue(ctx_from), static_cast((void*)from), // NOLINT(*) - CL_FALSE, origin, region, 0, 0, - static_cast(to) + to_offset, - 0, nullptr, nullptr)); + CL_FALSE, origin, region, 0, 0, + static_cast(to) + to_offset, 0, nullptr, nullptr)); OPENCL_CALL(clFinish(this->GetQueue(ctx_from))); break; } @@ -278,9 +275,9 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* cl_mem_object_type to_type = GetMemObjectType(to); switch (to_type) { case CL_MEM_OBJECT_BUFFER: - OPENCL_CALL(clEnqueueWriteBuffer(this->GetQueue(ctx_to), static_cast(to), CL_FALSE, - to_offset, size, static_cast(from) + from_offset, - 0, nullptr, nullptr)); + OPENCL_CALL(clEnqueueWriteBuffer( + this->GetQueue(ctx_to), static_cast(to), CL_FALSE, to_offset, size, + static_cast(from) + from_offset, 0, nullptr, nullptr)); OPENCL_CALL(clFinish(this->GetQueue(ctx_to))); break; case CL_MEM_OBJECT_IMAGE2D: { @@ -288,10 +285,10 @@ void OpenCLWorkspace::CopyDataFromTo(const void* from, size_t from_offset, void* size_t region[3]; GetImageShape(to, region); OPENCL_CALL(clEnqueueWriteImage(this->GetQueue(ctx_to), - static_cast((void*)to), // NOLINT(*) - CL_FALSE, origin, region, 0, 0, - static_cast(from) + from_offset, - 0, nullptr, nullptr)); + static_cast((void*)to), // NOLINT(*) + CL_FALSE, origin, region, 0, 0, + static_cast(from) + from_offset, 0, nullptr, + nullptr)); OPENCL_CALL(clFinish(this->GetQueue(ctx_to))); break; } From 2c2450d7b997fe597dc92e33152e8d5d3b27316b Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Wed, 10 Mar 2021 05:04:29 -0800 Subject: [PATCH 4/6] [RUNTIME] Fix lint. --- src/runtime/opencl/opencl_common.h | 2 +- src/runtime/opencl/opencl_device_api.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/opencl/opencl_common.h b/src/runtime/opencl/opencl_common.h index 04cc51af8549..36224cb416c1 100644 --- a/src/runtime/opencl/opencl_common.h +++ b/src/runtime/opencl/opencl_common.h @@ -363,7 +363,7 @@ class OpenCLModuleNode : public ModuleNode { }; inline cl_mem_object_type GetMemObjectType(const void* mem_ptr) { - cl_mem mem = static_cast((void*)mem_ptr); + cl_mem mem = static_cast(const_cast(mem_ptr)); cl_mem_info param_name = CL_MEM_TYPE; cl_mem_object_type mem_type; OPENCL_CALL(clGetMemObjectInfo(mem, param_name, sizeof(mem_type), &mem_type, NULL)); diff --git a/src/runtime/opencl/opencl_device_api.cc b/src/runtime/opencl/opencl_device_api.cc index 5c86c6820d17..5db3d2e5cb20 100644 --- a/src/runtime/opencl/opencl_device_api.cc +++ b/src/runtime/opencl/opencl_device_api.cc @@ -211,7 +211,7 @@ void OpenCLWorkspace::FreeDataSpace(TVMContext ctx, void* ptr) { } static inline void GetImageShape(const void* mem_ptr, size_t* region) { - cl_mem mem = static_cast((void*)mem_ptr); + cl_mem mem = static_cast(const_cast(mem_ptr)); size_t width, height; OPENCL_CALL(clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL)); OPENCL_CALL(clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL)); From a3ca8c38deebe7960079fbedc76c0f21a320814f Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Wed, 10 Mar 2021 05:10:54 -0800 Subject: [PATCH 5/6] [RUNTIME] Fix lint. --- tests/python/unittest/test_target_codegen_opencl.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/python/unittest/test_target_codegen_opencl.py b/tests/python/unittest/test_target_codegen_opencl.py index 6942efce3e40..477c55df122e 100644 --- a/tests/python/unittest/test_target_codegen_opencl.py +++ b/tests/python/unittest/test_target_codegen_opencl.py @@ -120,9 +120,10 @@ def check_max(ctx, n, dtype): check_max(ctx, 1, "float32") check_max(ctx, 1, "float64") + def test_opencl_texture_memory(): def check_allocate_and_copy(shape): - cpu_arr = nd.array(np.random.rand(*shape).astype('float32'), tvm.cpu(0)) + cpu_arr = nd.array(np.random.rand(*shape).astype("float32"), tvm.cpu(0)) opencl_arr0 = nd.empty(cpu_arr.shape, cpu_arr.dtype, tvm.opencl(0), "global:texture-act") opencl_arr1 = nd.empty(cpu_arr.shape, cpu_arr.dtype, tvm.opencl(0), "global:texture-act") cpu_arr.copyto(opencl_arr0) @@ -133,6 +134,7 @@ def check_allocate_and_copy(shape): check_allocate_and_copy((5, 6, 4)) check_allocate_and_copy((8, 5, 6, 4)) + if __name__ == "__main__": test_opencl_ternary_expression() test_opencl_inf_nan() From 8cb9c12ed79adcf90852a9a6973b1ae463992fe0 Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Wed, 10 Mar 2021 05:44:38 -0800 Subject: [PATCH 6/6] [RUNTIME] Fix tests. --- tests/python/unittest/test_target_codegen_opencl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/python/unittest/test_target_codegen_opencl.py b/tests/python/unittest/test_target_codegen_opencl.py index 477c55df122e..48d84ca36618 100644 --- a/tests/python/unittest/test_target_codegen_opencl.py +++ b/tests/python/unittest/test_target_codegen_opencl.py @@ -121,6 +121,8 @@ def check_max(ctx, n, dtype): check_max(ctx, 1, "float64") +@tvm.testing.requires_gpu +@tvm.testing.requires_opencl def test_opencl_texture_memory(): def check_allocate_and_copy(shape): cpu_arr = nd.array(np.random.rand(*shape).astype("float32"), tvm.cpu(0))