diff --git a/.gitlab-ci/build/gitlab-ci.yml b/.gitlab-ci/build/gitlab-ci.yml index c35be393c51..0eb8d82c384 100644 --- a/.gitlab-ci/build/gitlab-ci.yml +++ b/.gitlab-ci/build/gitlab-ci.yml @@ -138,7 +138,6 @@ debian-testing-asan: HOST_BUILD_OPTIONS: > -D build-tests=false -D enable-glcpp-tests=false - -D gallium-opencl=disabled -D gallium-rusticl=false -D gallium-nine=false -D gallium-drivers= @@ -177,7 +176,6 @@ debian-testing-msan: HOST_BUILD_OPTIONS: > -D build-tests=false -D enable-glcpp-tests=false - -D gallium-opencl=disabled -D gallium-drivers=panfrost -D vulkan-drivers= -D video-codecs= @@ -213,7 +211,6 @@ debian-testing-ubsan: HOST_BUILD_OPTIONS: > -D build-tests=false -D enable-glcpp-tests=false - -D gallium-opencl=disabled -D gallium-rusticl=false -D gallium-drivers= -D vulkan-drivers= @@ -419,7 +416,6 @@ debian-android: HOST_BUILD_OPTIONS: > -D build-tests=false -D enable-glcpp-tests=false - -D gallium-opencl=disabled -D gallium-drivers=panfrost -D vulkan-drivers= -D video-codecs= @@ -498,7 +494,6 @@ debian-arm32: HOST_BUILD_OPTIONS: > -D build-tests=false -D enable-glcpp-tests=false - -D gallium-opencl=disabled -D gallium-drivers=panfrost -D vulkan-drivers= -D video-codecs= @@ -791,7 +786,6 @@ debian-x86_32: HOST_BUILD_OPTIONS: > -D build-tests=false -D enable-glcpp-tests=false - -D gallium-opencl=disabled -D gallium-drivers= -D vulkan-drivers= -D video-codecs= diff --git a/.gitlab-ci/meson/build.sh b/.gitlab-ci/meson/build.sh index f1d1037e73a..b0e02a7f8a2 100755 --- a/.gitlab-ci/meson/build.sh +++ b/.gitlab-ci/meson/build.sh @@ -177,7 +177,6 @@ meson setup _build \ -D libunwind=${UNWIND} \ ${DRI_LOADERS} \ ${GALLIUM_ST} \ - -D gallium-opencl=disabled \ -D gallium-drivers=${GALLIUM_DRIVERS:-[]} \ -D vulkan-drivers=${VULKAN_DRIVERS:-[]} \ -D video-codecs=all \ diff --git a/.gitlab-ci/windows/mesa_build.ps1 b/.gitlab-ci/windows/mesa_build.ps1 index 5c17c9dabf1..ef27ac0e5ff 100644 --- a/.gitlab-ci/windows/mesa_build.ps1 +++ b/.gitlab-ci/windows/mesa_build.ps1 @@ -53,7 +53,6 @@ meson setup ` -Dvideo-codecs="all" ` -Dgles1=enabled ` -Dgles2=enabled ` --Dgallium-opencl=icd ` -Dgallium-rusticl=false ` -Dmicrosoft-clc=enabled ` -Dstatic-libclc=all ` diff --git a/docs/envvars.rst b/docs/envvars.rst index f8118f53837..dcfc0111d18 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -1135,54 +1135,6 @@ Gallium environment variables ``sse4.1`` ``avx`` -Clover environment variables ----------------------------- - -.. envvar:: CLOVER_DEVICE_TYPE - - allows to overwrite the device type of devices. Possible values are - ``accelerator``, ``cpu``, ``custom`` and ``gpu`` - -.. envvar:: CLOVER_DEVICE_VERSION_OVERRIDE - - overwrites the auto detected OpenCL version of a device. Possible values: - ``1.0`` - ``1.1`` - ``1.2`` - ``2.0`` - ``2.1`` - ``2.2`` - ``3.0`` - -.. envvar:: CLOVER_DEVICE_CLC_VERSION_OVERRIDE - - overwrites the auto detected CLC version. Possible values: - ``1.0`` - ``1.1`` - ``1.2`` - ``2.0`` - ``2.1`` - ``2.2`` - ``3.0`` - -.. envvar:: CLOVER_EXTRA_BUILD_OPTIONS - - allows specifying additional compiler and linker options. Specified - options are appended after the options set by the OpenCL program in - ``clBuildProgram``. - -.. envvar:: CLOVER_EXTRA_COMPILE_OPTIONS - - allows specifying additional compiler options. Specified options are - appended after the options set by the OpenCL program in - ``clCompileProgram``. - -.. envvar:: CLOVER_EXTRA_LINK_OPTIONS - - allows specifying additional linker options. Specified options are - appended after the options set by the OpenCL program in - ``clLinkProgram``. - .. _rusticl-env-var: Rusticl environment variables diff --git a/docs/features.txt b/docs/features.txt index e2f9e61eb62..75c9e381020 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -697,160 +697,6 @@ Khronos extensions that are not part of any Vulkan version: VK_QCOM_fragment_density_map_offset DONE (tu) -Clover OpenCL 1.0 -- all DONE: - - Image support in progress - - Optional image formats in progress - - -Clover OpenCL 1.1 -- all DONE: - - Additional queries for clGetDeviceInfo DONE (nvc0, r600, radeonsi) - CL_CONTEXT_NUM_DEVICES for clGetContextInfo DONE - New optional image formats not started - - CL_Rx not started - - CL_RGx not started - - CL_RGBx not started - clCreateSubBuffer DONE - Read from, write to, copy rectangular regions DONE - clSetMemObjectDestructorCallback DONE - Control OpenCL C version when building DONE - Query for preferred work-group size multiple DONE (nvc0, r600, radeonsi) - Support user events DONE - clSetEventCallback DONE - Minimum requirement changes for clGetDeviceInfo DONE (nvc0, r600, radeonsi) - Arg prerequisite change for clEnqueueNDRangeKernel DONE () - OpenCL C 1.1 DONE (nvc0, r600, radeonsi) - - 3-component vector data types DONE (nvc0, r600, radeonsi) - - cl_khr_byte_addressable_store DONE (nvc0, r600, radeonsi) - - cl_khr_global_int32_base_atomics DONE (nvc0, r600, radeonsi) - - cl_khr_global_int32_extended_atomics DONE (nvc0, r600, radeonsi) - - cl_khr_local_int32_base_atomics DONE (nvc0, r600, radeonsi) - - cl_khr_local_int32_extended_atomics DONE (nvc0, r600, radeonsi) - - -Clover OpenCL 1.2 -- all DONE: - - Custom devices DONE - Built-in kernels in progress - Device partitioning not started - Separate compilation and linking of programs DONE - Extend cl_mem_flags DONE - clEnqueueFillBuffer, clEnqueueFillImage DONE - Add CL_MAP_WRITE_INVALIDATE_REGION to cl_map_flags DONE - New image types not started - clCreateImage DONE - clEnqueueMigrateMemObjects DONE - Retrieve kernels information from a program DONE - clGetKernelArgInfo DONE - clEnqueueMarkerWithWaitList DONE - clEnqueueBarrierWithWaitList DONE - clUnloadPlatformCompiler DONE - cl_khr_fp64 DONE (nvc0, r600, radeonsi) - printf DONE (nvc0) - CL_KERNEL_ATTRIBUTES for clGetKernelInfo DONE - OpenCL C 1.2 DONE - - -Clover OpenCL 2.0 -- all DONE: - - Shared virtual memory DONE (nvc0, llvmpipe) - Device queues not started - - cl_khr_create_command_queue not started - - Additional queries for clGetDeviceInfo not started - Pipes not started - Extended 2D images creation in progress - - CL_ABGR DONE - - cl_khr_image2d_from_buffer not started - - cl_khr_depth_images not started - - from sRGB images not started - clCreateSamplerWithProperties not started - Non-uniform work-group sizes not started - cl_khr_3d_image_writes not started - OpenCL C 2.0 in progress - - Work-group Collective Functions not started - - Generic address space in progress - - -Clover OpenCL 2.1 -- all DONE: - - Sub groups not started - - cl_khr_subgroups not started - cl_khr_il_program DONE (nvc0) - Device and host timer synchronization not started - clEnqueueSVMMigrateMem not started - clCloneKernel not started - Default device command queue not started - CL_UNORM_INT_101010_2 DONE - - -Clover OpenCL 2.2 -- all DONE: - - clSetProgramSpecializationConstant not started - clSetProgramReleaseCallback not started - Initialization and clean-up kernels not started - CL_MAX_SIZE_RESTRICTION_EXCEEDED for clSetKernelArg not started - Support SPIR-V 1.1 and 1.2 not started - - -Clover OpenCL 3.0 -- all DONE: - - Optional device capabilities queries in progress - cl_khr_extended_versioning DONE - clSetContextDestructorCallback DONE - clCreateBufferWithProperties DONE - clCreateImageWithProperties DONE - Query properties arrays in progress - Supported OpenCL C versions and features queries DONE - CL_COMMAND_SVM_MIGRATE_MEM for clGetEventInfo not started - OpenCL C 3.0 DONE - Latest conformance version passed for devices not started - - -Clover extensions that are not part of any OpenCL version: - cl_khr_async_copy_fence not started - cl_khr_async_work_group_copy_fence not started - cl_khr_device_enqueue_local_arg_types not started - cl_khr_device_uuid not started - cl_khr_egl_event not started - cl_khr_egl_image not started - cl_khr_expect_assume not started - cl_khr_extended_async_copies not started - cl_khr_extended_bit_ops not started - cl_khr_fp16 DONE () - cl_khr_gl_depth_images not started - cl_khr_gl_msaa_sharing not started - cl_khr_gl_sharing not started - cl_khr_icd DONE - cl_khr_initialize_memory not started - cl_khr_int64_base_atomics DONE () - cl_khr_int64_extended_atomics DONE () - cl_khr_integer_dot_product not started - cl_khr_mipmap_image not started - cl_khr_pci_bus_info not started - cl_khr_priority_hints not started - cl_khr_spirv_extended_debug_info not started - cl_khr_spirv_linkonce_odr not started - cl_khr_spirv_no_integer_wrap_decoration not started - cl_khr_srgb_image_writes not started - cl_khr_subgroup_ballot not started - cl_khr_subgroup_clustered_reduce not started - cl_khr_subgroup_extended_types not started - cl_khr_subgroup_named_barrier not started - cl_khr_subgroup_non_uniform_arithmetic not started - cl_khr_subgroup_non_uniform_vote not started - cl_khr_subgroup_rotate not started - cl_khr_subgroup_shuffle not started - cl_khr_subgroup_shuffle_relative not started - cl_khr_suggested_local_work_size not started - cl_khr_terminate_context not started - cl_khr_throttle_hints not started - cl_khr_work_group_uniform_arithmetic not started - cl_arm_non_uniform_work_group_size not started - cl_arm_shared_virtual_memory DONE (nvc0) - cl_intel_unified_shared_memory not started - - Rusticl OpenCL 1.0 -- all DONE: Image support DONE diff --git a/docs/gallium/distro.rst b/docs/gallium/distro.rst index 0a9a93f63c0..440b910d592 100644 --- a/docs/gallium/distro.rst +++ b/docs/gallium/distro.rst @@ -76,11 +76,6 @@ Wrapper driver. Trace dumps an XML record of the calls made to the Gallium frontends ----------------- -Clover -^^^^^^ - -Tracker that implements the Khronos OpenCL standard. - .. _dri: Direct Rendering Infrastructure diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index e69de29bb2d..eb676a734f3 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -0,0 +1 @@ +removed clover frontend diff --git a/docs/sourcetree.rst b/docs/sourcetree.rst index c169e5a5d87..c3f205a98e9 100644 --- a/docs/sourcetree.rst +++ b/docs/sourcetree.rst @@ -132,7 +132,6 @@ each directory. - **frontends** - These implement various libraries using the device drivers - - **clover** - OpenCL frontend - **d3d10umd** - D3D10 frontend for Windows only. It's similar to Microsoft WARP, but using LLVMpipe/Softpipe. - **dri** - Meta frontend for DRI drivers, see mesa/state_tracker - **glx** - Meta frontend for GLX diff --git a/include/meson.build b/include/meson.build index 36b96dba445..19aab822ac3 100644 --- a/include/meson.build +++ b/include/meson.build @@ -89,7 +89,7 @@ if with_gallium_st_nine subdir : 'd3dadapter', ) endif - + opencl_headers = files( 'CL/cl.h', 'CL/cl.hpp', @@ -113,11 +113,3 @@ opencl_headers = files( 'CL/opencl.h', 'CL/opencl.hpp', ) -# Only install the headers if we are building a stand alone implementation and -# not an ICD enabled implementation -if with_gallium_clover and not with_opencl_icd - install_headers( - opencl_headers, - subdir: 'CL' - ) -endif diff --git a/meson.build b/meson.build index 58194e73b1f..cd802abeca5 100644 --- a/meson.build +++ b/meson.build @@ -743,24 +743,7 @@ if get_option('vmware-mks-stats') pre_args += '-DVMX86_STATS=1' endif -_opencl = get_option('gallium-opencl') _rtti = get_option('cpp_rtti') -if _opencl != 'disabled' - warning('Clover will be removed in Mesa 25.2') - - if not with_gallium - error('OpenCL Clover implementation requires at least one gallium driver.') - endif - if not _rtti - error('The Clover OpenCL state tracker requires rtti') - endif - - with_gallium_clover = true - with_opencl_icd = _opencl == 'icd' -else - with_gallium_clover = false - with_opencl_icd = false -endif with_gallium_rusticl = get_option('gallium-rusticl') if with_gallium_rusticl @@ -829,7 +812,7 @@ else endif dep_clc = null_dep -if with_gallium_clover or with_clc +if with_clc dep_clc = dependency('libclc') endif @@ -1716,15 +1699,6 @@ if with_amd_vk or with_gallium_radeonsi or with_gallium_r600 llvm_modules += 'asmparser' endif endif -if with_gallium_clover - llvm_modules += [ - 'linker', 'coverage', 'instrumentation', 'ipo', 'irreader', - 'lto', 'option', 'objcarcopts', 'profiledata' - ] - # all-targets is needed to support static linking LLVM build with multiple targets - # windowsdriver is needded with LLVM>=15, but we don't know what LLVM verrsion we are using yet - llvm_optional_modules += ['all-targets', 'frontendopenmp', 'windowsdriver'] -endif if with_clc llvm_modules += ['coverage', 'target', 'linker', 'irreader', 'option', 'libdriver', 'lto'] # all-targets is needed to support static linking LLVM build with multiple targets. @@ -1750,8 +1724,6 @@ if with_amd_vk or with_gallium_radeonsi _llvm_version = '>= 18.0.0' elif with_clc or llvm_with_orcjit _llvm_version = '>= 15.0.0' -elif with_gallium_clover - _llvm_version = '>= 11.0.0' else _llvm_version = '>= 5.0.0' endif @@ -1771,7 +1743,7 @@ if _llvm.allowed() modules : llvm_modules, optional_modules : llvm_optional_modules, required : ( - with_amd_vk or with_gallium_radeonsi or with_gallium_clover or with_clc + with_amd_vk or with_gallium_radeonsi or with_clc or _llvm.enabled() ), static : not _shared_llvm, @@ -1825,8 +1797,6 @@ elif with_swrast_vk error('lavapipe requires LLVM and is enabled, but LLVM is disabled.') elif with_any_llvmpipe error('llvmpipe requires LLVM and is enabled, but LLVM is disabled.') -elif with_gallium_clover - error('The OpenCL "Clover" state tracker requires LLVM, but LLVM is disabled.') elif with_clc error('The CLC compiler requires LLVM, but LLVM is disabled.') else @@ -1876,7 +1846,7 @@ if dep_spirv_tools.found() endif dep_clang = null_dep -if with_clc or with_gallium_clover +if with_clc llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir') dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false) @@ -1891,7 +1861,7 @@ if with_clc or with_gallium_clover if dep_llvm.version().version_compare('>= 15.0') clang_modules += 'clangSupport' endif - if dep_llvm.version().version_compare('>= 16.0') or with_gallium_clover + if dep_llvm.version().version_compare('>= 16.0') clang_modules += 'clangASTMatchers' endif if dep_llvm.version().version_compare('>= 18.0') @@ -2414,9 +2384,6 @@ if with_gallium if with_gallium_st_nine gallium_frontends += 'nine' endif - if with_gallium_clover - gallium_frontends += 'clover' - endif if with_gallium_rusticl gallium_frontends += 'rusticl' endif diff --git a/meson.options b/meson.options index 18da31eff50..1b32438d72d 100644 --- a/meson.options +++ b/meson.options @@ -147,15 +147,6 @@ option( description : 'build gallium D3D10 WDDM UMD frontend.', ) -option( - 'gallium-opencl', - type : 'combo', - choices : ['icd', 'standalone', 'disabled'], - value : 'disabled', - description : 'build gallium "clover" OpenCL frontend.', - deprecated: true, -) - option( 'gallium-rusticl', type : 'boolean', diff --git a/src/gallium/drivers/r600/meson.build b/src/gallium/drivers/r600/meson.build index 8468b8ab301..97d88630304 100644 --- a/src/gallium/drivers/r600/meson.build +++ b/src/gallium/drivers/r600/meson.build @@ -144,13 +144,6 @@ egd_tables_h = custom_target( ) r600_c_args = [] -if with_gallium_clover - if dep_elf.found() - r600_c_args += '-DHAVE_OPENCL' - else - warning('r600 requires libelf to support opencl.') - endif -endif r600_cpp_args = [] if cpp.has_type('std::pmr::monotonic_buffer_resource', diff --git a/src/gallium/frontends/clover/api/context.cpp b/src/gallium/frontends/clover/api/context.cpp deleted file mode 100644 index 65464bcde06..00000000000 --- a/src/gallium/frontends/clover/api/context.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/context.hpp" -#include "core/platform.hpp" - -using namespace clover; - -CLOVER_API cl_context -clCreateContext(const cl_context_properties *d_props, cl_uint num_devs, - const cl_device_id *d_devs, - void (CL_CALLBACK *pfn_notify)(const char *, const void *, - size_t, void *), - void *user_data, cl_int *r_errcode) try { - auto props = obj(d_props); - auto devs = objs(d_devs, num_devs); - - if (!pfn_notify && user_data) - throw error(CL_INVALID_VALUE); - - for (auto &prop : props) { - if (prop.first == CL_CONTEXT_PLATFORM) - find_platform(prop.second.as()); - else - throw error(CL_INVALID_PROPERTY); - } - - const auto notify = (!pfn_notify ? context::notify_action() : - [=](const char *s) { - pfn_notify(s, NULL, 0, user_data); - }); - - ret_error(r_errcode, CL_SUCCESS); - return desc(new context(props, devs, notify)); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_context -clCreateContextFromType(const cl_context_properties *d_props, - cl_device_type type, - void (CL_CALLBACK *pfn_notify)( - const char *, const void *, size_t, void *), - void *user_data, cl_int *r_errcode) try { - cl_platform_id d_platform; - cl_uint num_platforms; - cl_int ret; - std::vector devs; - cl_uint num_devices; - - ret = clGetPlatformIDs(1, &d_platform, &num_platforms); - if (ret || !num_platforms) - throw error(CL_INVALID_PLATFORM); - - ret = clGetDeviceIDs(d_platform, type, 0, NULL, &num_devices); - if (ret) - throw error(CL_DEVICE_NOT_FOUND); - devs.resize(num_devices); - ret = clGetDeviceIDs(d_platform, type, num_devices, devs.data(), 0); - if (ret) - throw error(CL_DEVICE_NOT_FOUND); - - return clCreateContext(d_props, num_devices, devs.data(), pfn_notify, - user_data, r_errcode); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clRetainContext(cl_context d_ctx) try { - obj(d_ctx).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseContext(cl_context d_ctx) try { - if (obj(d_ctx).release()) - delete pobj(d_ctx); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetContextInfo(cl_context d_ctx, cl_context_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &ctx = obj(d_ctx); - - switch (param) { - case CL_CONTEXT_REFERENCE_COUNT: - buf.as_scalar() = ctx.ref_count(); - break; - - case CL_CONTEXT_NUM_DEVICES: - buf.as_scalar() = ctx.devices().size(); - break; - - case CL_CONTEXT_DEVICES: - buf.as_vector() = descs(ctx.devices()); - break; - - case CL_CONTEXT_PROPERTIES: - buf.as_vector() = desc(ctx.properties()); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetContextDestructorCallback(cl_context d_ctx, - void (CL_CALLBACK *pfn_notify)(cl_context, void *), - void *user_data) try { - CLOVER_NOT_SUPPORTED_UNTIL("3.0"); - auto &ctx = obj(d_ctx); - - if (!pfn_notify) - return CL_INVALID_VALUE; - - ctx.destroy_notify([=]{ pfn_notify(d_ctx, user_data); }); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/device.cpp b/src/gallium/frontends/clover/api/device.cpp deleted file mode 100644 index 2d1066f629b..00000000000 --- a/src/gallium/frontends/clover/api/device.cpp +++ /dev/null @@ -1,525 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/platform.hpp" -#include "core/device.hpp" -#include "git_sha1.h" - -using namespace clover; - -namespace { - std::string - supported_il_versions_as_string(const device &dev) { - std::string il_versions_string; - - for (const auto &il_version : dev.supported_il_versions()) { - if (!il_versions_string.empty()) - il_versions_string += " "; - - il_versions_string += std::string(il_version.name) + "_" + - std::to_string(CL_VERSION_MAJOR(il_version.version)) + "." + - std::to_string(CL_VERSION_MINOR(il_version.version)); - } - return il_versions_string; - } -} - -CLOVER_API cl_int -clGetDeviceIDs(cl_platform_id d_platform, cl_device_type device_type, - cl_uint num_entries, cl_device_id *rd_devices, - cl_uint *rnum_devices) try { - auto &platform = obj(d_platform); - std::vector d_devs; - - if ((!num_entries && rd_devices) || - (!rnum_devices && !rd_devices)) - throw error(CL_INVALID_VALUE); - - // Collect matching devices - for (device &dev : platform) { - if (((device_type & CL_DEVICE_TYPE_DEFAULT) && - dev == platform.front()) || - (device_type & dev.type())) - d_devs.push_back(desc(dev)); - } - - if (d_devs.empty()) - throw error(CL_DEVICE_NOT_FOUND); - - // ...and return the requested data. - if (rnum_devices) - *rnum_devices = d_devs.size(); - if (rd_devices) - copy(range(d_devs.begin(), - std::min((unsigned)d_devs.size(), num_entries)), - rd_devices); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clCreateSubDevices(cl_device_id d_dev, - const cl_device_partition_property *props, - cl_uint num_devs, cl_device_id *rd_devs, - cl_uint *rnum_devs) { - // There are no currently supported partitioning schemes. - return CL_INVALID_VALUE; -} - -CLOVER_API cl_int -clRetainDevice(cl_device_id d_dev) try { - obj(d_dev); - - // The reference count doesn't change for root devices. - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseDevice(cl_device_id d_dev) try { - obj(d_dev); - - // The reference count doesn't change for root devices. - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetDeviceInfo(cl_device_id d_dev, cl_device_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &dev = obj(d_dev); - - switch (param) { - case CL_DEVICE_TYPE: - buf.as_scalar() = dev.type(); - break; - - case CL_DEVICE_VENDOR_ID: - buf.as_scalar() = dev.vendor_id(); - break; - - case CL_DEVICE_MAX_COMPUTE_UNITS: - buf.as_scalar() = dev.max_compute_units(); - break; - - case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: - buf.as_scalar() = dev.max_block_size().size(); - break; - - case CL_DEVICE_MAX_WORK_ITEM_SIZES: - buf.as_vector() = dev.max_block_size(); - break; - - case CL_DEVICE_MAX_WORK_GROUP_SIZE: - buf.as_scalar() = dev.max_threads_per_block(); - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: - buf.as_scalar() = 16; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: - buf.as_scalar() = 8; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: - buf.as_scalar() = 4; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: - buf.as_scalar() = 2; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: - buf.as_scalar() = 4; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: - buf.as_scalar() = dev.has_doubles() ? 2 : 0; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF: - buf.as_scalar() = dev.has_halves() ? 8 : 0; - break; - - case CL_DEVICE_MAX_CLOCK_FREQUENCY: - buf.as_scalar() = dev.max_clock_frequency(); - break; - - case CL_DEVICE_ADDRESS_BITS: - buf.as_scalar() = dev.address_bits(); - break; - - case CL_DEVICE_MAX_READ_IMAGE_ARGS: - buf.as_scalar() = dev.max_images_read(); - break; - - case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: - buf.as_scalar() = dev.max_images_write(); - break; - - case CL_DEVICE_MAX_MEM_ALLOC_SIZE: - buf.as_scalar() = dev.max_mem_alloc_size(); - break; - - case CL_DEVICE_IMAGE2D_MAX_WIDTH: - case CL_DEVICE_IMAGE2D_MAX_HEIGHT: - buf.as_scalar() = dev.max_image_size(); - break; - - case CL_DEVICE_IMAGE3D_MAX_WIDTH: - case CL_DEVICE_IMAGE3D_MAX_HEIGHT: - case CL_DEVICE_IMAGE3D_MAX_DEPTH: - buf.as_scalar() = dev.max_image_size_3d(); - break; - - case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE: - buf.as_scalar() = dev.max_image_buffer_size(); - break; - - case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE: - buf.as_scalar() = dev.max_image_array_number(); - break; - - case CL_DEVICE_IMAGE_SUPPORT: - buf.as_scalar() = dev.image_support(); - break; - - case CL_DEVICE_MAX_PARAMETER_SIZE: - buf.as_scalar() = dev.max_mem_input(); - break; - - case CL_DEVICE_MAX_SAMPLERS: - buf.as_scalar() = dev.max_samplers(); - break; - - case CL_DEVICE_MEM_BASE_ADDR_ALIGN: - buf.as_scalar() = 8 * dev.mem_base_addr_align(); - break; - - case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: - buf.as_scalar() = 128; - break; - - case CL_DEVICE_HALF_FP_CONFIG: - // This is the "mandated minimum half precision floating-point - // capability" for OpenCL 1.x. - buf.as_scalar() = - CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST; - break; - - case CL_DEVICE_SINGLE_FP_CONFIG: - // This is the "mandated minimum single precision floating-point - // capability" for OpenCL 1.1. In OpenCL 1.2, nothing is required for - // custom devices. - buf.as_scalar() = - CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST; - break; - - case CL_DEVICE_DOUBLE_FP_CONFIG: - if (dev.has_doubles()) - // This is the "mandated minimum double precision floating-point - // capability" - buf.as_scalar() = - CL_FP_FMA - | CL_FP_ROUND_TO_NEAREST - | CL_FP_ROUND_TO_ZERO - | CL_FP_ROUND_TO_INF - | CL_FP_INF_NAN - | CL_FP_DENORM; - else - buf.as_scalar() = 0; - break; - - case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: - buf.as_scalar() = CL_NONE; - break; - - case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_GLOBAL_MEM_SIZE: - buf.as_scalar() = dev.max_mem_global(); - break; - - case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: - buf.as_scalar() = dev.max_const_buffer_size(); - break; - - case CL_DEVICE_MAX_CONSTANT_ARGS: - buf.as_scalar() = dev.max_const_buffers(); - break; - - case CL_DEVICE_LOCAL_MEM_TYPE: - buf.as_scalar() = CL_LOCAL; - break; - - case CL_DEVICE_LOCAL_MEM_SIZE: - buf.as_scalar() = dev.max_mem_local(); - break; - - case CL_DEVICE_ERROR_CORRECTION_SUPPORT: - buf.as_scalar() = CL_FALSE; - break; - - case CL_DEVICE_PROFILING_TIMER_RESOLUTION: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_ENDIAN_LITTLE: - buf.as_scalar() = (dev.endianness() == PIPE_ENDIAN_LITTLE); - break; - - case CL_DEVICE_AVAILABLE: - case CL_DEVICE_COMPILER_AVAILABLE: - case CL_DEVICE_LINKER_AVAILABLE: - buf.as_scalar() = CL_TRUE; - break; - - case CL_DEVICE_EXECUTION_CAPABILITIES: - buf.as_scalar() = CL_EXEC_KERNEL; - break; - - case CL_DEVICE_QUEUE_PROPERTIES: - buf.as_scalar() = CL_QUEUE_PROFILING_ENABLE; - break; - - case CL_DEVICE_BUILT_IN_KERNELS: - buf.as_string() = ""; - break; - - case CL_DEVICE_NAME: - buf.as_string() = dev.device_name(); - break; - - case CL_DEVICE_VENDOR: - buf.as_string() = dev.vendor_name(); - break; - - case CL_DRIVER_VERSION: - buf.as_string() = PACKAGE_VERSION; - break; - - case CL_DEVICE_PROFILE: - buf.as_string() = "FULL_PROFILE"; - break; - - case CL_DEVICE_VERSION: - buf.as_string() = "OpenCL " + dev.device_version_as_string() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1; - break; - - case CL_DEVICE_EXTENSIONS: - buf.as_string() = dev.supported_extensions_as_string(); - break; - - case CL_DEVICE_PLATFORM: - buf.as_scalar() = desc(dev.platform); - break; - - case CL_DEVICE_HOST_UNIFIED_MEMORY: - buf.as_scalar() = dev.has_unified_memory(); - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR: - buf.as_scalar() = 16; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT: - buf.as_scalar() = 8; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT: - buf.as_scalar() = 4; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG: - buf.as_scalar() = 2; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT: - buf.as_scalar() = 4; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE: - buf.as_scalar() = dev.has_doubles() ? 2 : 0; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF: - buf.as_scalar() = dev.has_halves() ? 8 : 0; - break; - - case CL_DEVICE_OPENCL_C_VERSION: - buf.as_string() = "OpenCL C " + dev.device_clc_version_as_string() + " "; - break; - - case CL_DEVICE_PRINTF_BUFFER_SIZE: - buf.as_scalar() = dev.max_printf_buffer_size(); - break; - - case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC: - buf.as_scalar() = CL_TRUE; - break; - - case CL_DEVICE_PARENT_DEVICE: - buf.as_scalar() = NULL; - break; - - case CL_DEVICE_PARTITION_MAX_SUB_DEVICES: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_PARTITION_PROPERTIES: - buf.as_vector() = - desc(property_list()); - break; - - case CL_DEVICE_PARTITION_AFFINITY_DOMAIN: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_PARTITION_TYPE: - buf.as_vector() = - desc(property_list()); - break; - - case CL_DEVICE_REFERENCE_COUNT: - buf.as_scalar() = 1; - break; - - case CL_DEVICE_SVM_CAPABILITIES: - case CL_DEVICE_SVM_CAPABILITIES_ARM: - buf.as_scalar() = dev.svm_support(); - break; - - case CL_DEVICE_NUMERIC_VERSION: - buf.as_scalar() = dev.device_version(); - break; - - case CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR: - buf.as_scalar() = dev.device_clc_version(true); - break; - - case CL_DEVICE_OPENCL_C_ALL_VERSIONS: - buf.as_vector() = dev.opencl_c_all_versions(); - break; - - case CL_DEVICE_EXTENSIONS_WITH_VERSION: - buf.as_vector() = dev.supported_extensions(); - break; - - case CL_DEVICE_OPENCL_C_FEATURES: - buf.as_vector() = dev.opencl_c_features(); - break; - - case CL_DEVICE_IL_VERSION: - if (dev.supported_extensions_as_string().find("cl_khr_il_program") == std::string::npos) - throw error(CL_INVALID_VALUE); - buf.as_string() = supported_il_versions_as_string(dev); - break; - - case CL_DEVICE_ILS_WITH_VERSION: - buf.as_vector() = dev.supported_il_versions(); - break; - - case CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION: - buf.as_vector() = std::vector{}; - break; - - case CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS: - case CL_DEVICE_IMAGE_PITCH_ALIGNMENT: - case CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT: - case CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT: - case CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT: - case CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT: - case CL_DEVICE_MAX_NUM_SUB_GROUPS: - case CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE: - case CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE: - case CL_DEVICE_MAX_ON_DEVICE_QUEUES: - case CL_DEVICE_MAX_ON_DEVICE_EVENTS: - case CL_DEVICE_MAX_PIPE_ARGS: - case CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS: - case CL_DEVICE_PIPE_MAX_PACKET_SIZE: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE: - case CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS: - case CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT: - case CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT: - case CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT: - case CL_DEVICE_PIPE_SUPPORT: - buf.as_scalar() = CL_FALSE; - break; - - case CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES: - buf.as_scalar() = (CL_DEVICE_ATOMIC_ORDER_RELAXED | - CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP); - break; - case CL_DEVICE_ATOMIC_FENCE_CAPABILITIES: - buf.as_scalar() = (CL_DEVICE_ATOMIC_ORDER_RELAXED | - CL_DEVICE_ATOMIC_ORDER_ACQ_REL | - CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP); - break; - - case CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES: - buf.as_scalar() = 0; - break; - - case CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: - buf.as_scalar() = 1; - break; - - case CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED: - buf.as_string() = ""; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/dispatch.cpp b/src/gallium/frontends/clover/api/dispatch.cpp deleted file mode 100644 index e6c54b1d727..00000000000 --- a/src/gallium/frontends/clover/api/dispatch.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/dispatch.hpp" - -namespace clover { - const cl_icd_dispatch _dispatch = { - // OpenCL 1.0 - clGetPlatformIDs, - GetPlatformInfo, - clGetDeviceIDs, - clGetDeviceInfo, - clCreateContext, - clCreateContextFromType, - clRetainContext, - clReleaseContext, - clGetContextInfo, - clCreateCommandQueue, - clRetainCommandQueue, - clReleaseCommandQueue, - clGetCommandQueueInfo, - NULL, // clSetCommandQueueProperty - clCreateBuffer, - clCreateImage2D, - clCreateImage3D, - clRetainMemObject, - clReleaseMemObject, - clGetSupportedImageFormats, - clGetMemObjectInfo, - clGetImageInfo, - clCreateSampler, - clRetainSampler, - clReleaseSampler, - clGetSamplerInfo, - clCreateProgramWithSource, - clCreateProgramWithBinary, - clRetainProgram, - clReleaseProgram, - clBuildProgram, - clUnloadCompiler, - clGetProgramInfo, - clGetProgramBuildInfo, - clCreateKernel, - clCreateKernelsInProgram, - clRetainKernel, - clReleaseKernel, - clSetKernelArg, - clGetKernelInfo, - clGetKernelWorkGroupInfo, - clWaitForEvents, - clGetEventInfo, - clRetainEvent, - clReleaseEvent, - clGetEventProfilingInfo, - clFlush, - clFinish, - clEnqueueReadBuffer, - clEnqueueWriteBuffer, - clEnqueueCopyBuffer, - clEnqueueReadImage, - clEnqueueWriteImage, - clEnqueueCopyImage, - clEnqueueCopyImageToBuffer, - clEnqueueCopyBufferToImage, - clEnqueueMapBuffer, - clEnqueueMapImage, - clEnqueueUnmapMemObject, - clEnqueueNDRangeKernel, - clEnqueueTask, - clEnqueueNativeKernel, - clEnqueueMarker, - clEnqueueWaitForEvents, - clEnqueueBarrier, - GetExtensionFunctionAddress, - NULL, // clCreateFromGLBuffer - NULL, // clCreateFromGLTexture2D - NULL, // clCreateFromGLTexture3D - NULL, // clCreateFromGLRenderbuffer - NULL, // clGetGLObjectInfo - NULL, // clGetGLTextureInfo - NULL, // clEnqueueAcquireGLObjects - NULL, // clEnqueueReleaseGLObjects - - // cl_khr_d3d10_sharing - NULL, // clGetGLContextInfoKHR - NULL, // clGetDeviceIDsFromD3D10KHR - NULL, // clCreateFromD3D10BufferKHR - NULL, // clCreateFromD3D10Texture2DKHR - NULL, // clCreateFromD3D10Texture3DKHR - NULL, // clEnqueueAcquireD3D10ObjectsKHR - NULL, // clEnqueueReleaseD3D10ObjectsKHR - - // OpenCL 1.1 - clSetEventCallback, - clCreateSubBuffer, - clSetMemObjectDestructorCallback, - clCreateUserEvent, - clSetUserEventStatus, - clEnqueueReadBufferRect, - clEnqueueWriteBufferRect, - clEnqueueCopyBufferRect, - - // cl_ext_device_fission - NULL, // clCreateSubDevicesEXT - NULL, // clRetainDeviceEXT - NULL, // clReleaseDeviceEXT - - // cl_khr_gl_event - NULL, // clCreateEventFromGLsyncKHR - - // OpenCL 1.2 - clCreateSubDevices, - clRetainDevice, - clReleaseDevice, - clCreateImage, - clCreateProgramWithBuiltInKernels, - clCompileProgram, - clLinkProgram, - clUnloadPlatformCompiler, - clGetKernelArgInfo, - clEnqueueFillBuffer, - clEnqueueFillImage, - clEnqueueMigrateMemObjects, - clEnqueueMarkerWithWaitList, - clEnqueueBarrierWithWaitList, - GetExtensionFunctionAddressForPlatform, - NULL, // clCreateFromGLTexture - - // cl_khr_d3d11_sharing - NULL, // clGetDeviceIDsFromD3D11KHR - NULL, // clCreateFromD3D11BufferKHR - NULL, // clCreateFromD3D11Texture2DKHR - NULL, // clCreateFromD3D11Texture3DKHR - NULL, // clCreateFromDX9MediaSurfaceKHR - NULL, // clEnqueueAcquireD3D11ObjectsKHR - NULL, // clEnqueueReleaseD3D11ObjectsKHR - - // cl_khr_dx9_media_sharing - NULL, // clGetDeviceIDsFromDX9MediaAdapterKHR - NULL, // clEnqueueAcquireDX9MediaSurfacesKHR - NULL, // clEnqueueReleaseDX9MediaSurfacesKHR - - // cl_khr_egl_image - NULL, // clCreateFromEGLImageKHR - NULL, // clEnqueueAcquireEGLObjectsKHR - NULL, // clEnqueueReleaseEGLObjectsKHR - - // cl_khr_egl_event - NULL, // clCreateEventFromEGLSyncKHR - - // OpenCL 2.0 - clCreateCommandQueueWithProperties, - clCreatePipe, - clGetPipeInfo, - clSVMAlloc, - clSVMFree, - clEnqueueSVMFree, - clEnqueueSVMMemcpy, - clEnqueueSVMMemFill, - clEnqueueSVMMap, - clEnqueueSVMUnmap, - NULL, // clCreateSamplerWithProperties - clSetKernelArgSVMPointer, - clSetKernelExecInfo, - - // cl_khr_sub_groups - NULL, // clGetKernelSubGroupInfoKHR - - // OpenCL 2.1 - NULL, // clCloneKernel - clCreateProgramWithIL, - clEnqueueSVMMigrateMem, - clGetDeviceAndHostTimer, - clGetHostTimer, - clGetKernelSubGroupInfo, - clSetDefaultDeviceCommandQueue, - - // OpenCL 2.2 - clSetProgramReleaseCallback, - clSetProgramSpecializationConstant, - clCreateBufferWithProperties, - clCreateImageWithProperties, - clSetContextDestructorCallback - }; -} diff --git a/src/gallium/frontends/clover/api/dispatch.hpp b/src/gallium/frontends/clover/api/dispatch.hpp deleted file mode 100644 index f98f94d0c6d..00000000000 --- a/src/gallium/frontends/clover/api/dispatch.hpp +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef API_DISPATCH_HPP -#define API_DISPATCH_HPP - -#include "CL/cl.h" -#include "CL/cl_ext.h" -#include "CL/cl_egl.h" -#include "CL/cl_gl.h" -#include "CL/cl_icd.h" - -namespace clover { - extern const cl_icd_dispatch _dispatch; - - cl_int CL_API_CALL - GetPlatformInfo(cl_platform_id d_platform, cl_platform_info param, - size_t size, void *r_buf, size_t *r_size); - - void * CL_API_CALL - GetExtensionFunctionAddress(const char *p_name); - - void * CL_API_CALL - GetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, - const char *p_name); - - cl_int CL_API_CALL - IcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms); - - cl_int CL_API_CALL - EnqueueSVMFree(cl_command_queue command_queue, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int CL_API_CALL - EnqueueSVMMemcpy(cl_command_queue command_queue, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int CL_API_CALL - EnqueueSVMMap(cl_command_queue command_queue, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int CL_API_CALL - EnqueueSVMMemFill(cl_command_queue command_queue, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int CL_API_CALL - EnqueueSVMUnmap(cl_command_queue command_queue, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_program CL_API_CALL - CreateProgramWithILKHR(cl_context d_ctx, const void *il, - size_t length, cl_int *r_errcode); -} - -#endif diff --git a/src/gallium/frontends/clover/api/event.cpp b/src/gallium/frontends/clover/api/event.cpp deleted file mode 100644 index 7c3b0812f24..00000000000 --- a/src/gallium/frontends/clover/api/event.cpp +++ /dev/null @@ -1,310 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/event.hpp" - -using namespace clover; - -CLOVER_API cl_event -clCreateUserEvent(cl_context d_ctx, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - ret_error(r_errcode, CL_SUCCESS); - return desc(new soft_event(ctx, {}, false)); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clSetUserEventStatus(cl_event d_ev, cl_int status) try { - auto &sev = obj(d_ev); - - if (status > 0) - return CL_INVALID_VALUE; - - if (sev.status() <= 0) - return CL_INVALID_OPERATION; - - if (status) - sev.abort(status); - else - sev.trigger(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clWaitForEvents(cl_uint num_evs, const cl_event *d_evs) try { - auto evs = objs(d_evs, num_evs); - - for (auto &ev : evs) { - if (ev.context() != evs.front().context()) - throw error(CL_INVALID_CONTEXT); - - if (ev.status() < 0) - throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); - } - - // Create a temporary soft event that depends on all the events in - // the wait list - auto sev = create(evs.front().context(), evs, true); - - // ...and wait on it. - sev().wait(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetEventInfo(cl_event d_ev, cl_event_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &ev = obj(d_ev); - - switch (param) { - case CL_EVENT_COMMAND_QUEUE: - buf.as_scalar() = desc(ev.queue()); - break; - - case CL_EVENT_CONTEXT: - buf.as_scalar() = desc(ev.context()); - break; - - case CL_EVENT_COMMAND_TYPE: - buf.as_scalar() = ev.command(); - break; - - case CL_EVENT_COMMAND_EXECUTION_STATUS: - buf.as_scalar() = ev.status(); - break; - - case CL_EVENT_REFERENCE_COUNT: - buf.as_scalar() = ev.ref_count(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetEventCallback(cl_event d_ev, cl_int type, - void (CL_CALLBACK *pfn_notify)(cl_event, cl_int, void *), - void *user_data) try { - auto &ev = obj(d_ev); - - if (!pfn_notify || - (type != CL_COMPLETE && type != CL_SUBMITTED && type != CL_RUNNING)) - throw error(CL_INVALID_VALUE); - - // Create a temporary soft event that depends on ev, with - // pfn_notify as completion action. - create(ev.context(), ref_vector { ev }, true, - [=, &ev](event &) { - ev.wait(); - pfn_notify(desc(ev), ev.status(), user_data); - }); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clRetainEvent(cl_event d_ev) try { - obj(d_ev).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseEvent(cl_event d_ev) try { - if (obj(d_ev).release()) - delete pobj(d_ev); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueMarker(cl_command_queue d_q, cl_event *rd_ev) try { - auto &q = obj(d_q); - - if (!rd_ev) - throw error(CL_INVALID_VALUE); - - *rd_ev = desc(new hard_event(q, CL_COMMAND_MARKER, {})); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueMarkerWithWaitList(cl_command_queue d_q, cl_uint num_deps, - const cl_event *d_deps, cl_event *rd_ev) try { - auto &q = obj(d_q); - auto deps = objs(d_deps, num_deps); - - for (auto &ev : deps) { - if (ev.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - } - - // Create a hard event that depends on the events in the wait list: - // previous commands in the same queue are implicitly serialized - // with respect to it -- hard events always are. - auto hev = create(q, CL_COMMAND_MARKER, deps); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueBarrier(cl_command_queue d_q) try { - obj(d_q); - - // No need to do anything, q preserves data ordering strictly. - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueBarrierWithWaitList(cl_command_queue d_q, cl_uint num_deps, - const cl_event *d_deps, cl_event *rd_ev) try { - auto &q = obj(d_q); - auto deps = objs(d_deps, num_deps); - - for (auto &ev : deps) { - if (ev.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - } - - // Create a hard event that depends on the events in the wait list: - // subsequent commands in the same queue will be implicitly - // serialized with respect to it -- hard events always are. - auto hev = create(q, CL_COMMAND_BARRIER, deps); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWaitForEvents(cl_command_queue d_q, cl_uint num_evs, - const cl_event *d_evs) try { - // The wait list is mandatory for clEnqueueWaitForEvents(). - objs(d_evs, num_evs); - - return clEnqueueBarrierWithWaitList(d_q, num_evs, d_evs, NULL); - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetEventProfilingInfo(cl_event d_ev, cl_profiling_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - hard_event &hev = dynamic_cast(obj(d_ev)); - - if (hev.status() != CL_COMPLETE) - throw error(CL_PROFILING_INFO_NOT_AVAILABLE); - - switch (param) { - case CL_PROFILING_COMMAND_QUEUED: - buf.as_scalar() = hev.time_queued(); - break; - - case CL_PROFILING_COMMAND_SUBMIT: - buf.as_scalar() = hev.time_submit(); - break; - - case CL_PROFILING_COMMAND_START: - buf.as_scalar() = hev.time_start(); - break; - - case CL_PROFILING_COMMAND_END: - case CL_PROFILING_COMMAND_COMPLETE: - buf.as_scalar() = hev.time_end(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (std::bad_cast &) { - return CL_PROFILING_INFO_NOT_AVAILABLE; - -} catch (lazy::undefined_error &) { - return CL_PROFILING_INFO_NOT_AVAILABLE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clFinish(cl_command_queue d_q) try { - auto &q = obj(d_q); - - // Create a temporary hard event -- it implicitly depends on all - // the previously queued hard events. - auto hev = create(q, 0, ref_vector {}); - - // And wait on it. - hev().wait(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/interop.cpp b/src/gallium/frontends/clover/api/interop.cpp deleted file mode 100644 index b96069f5167..00000000000 --- a/src/gallium/frontends/clover/api/interop.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2015 Advanced Micro Devices, Inc. -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/event.hpp" -#include "api/util.hpp" - -using namespace clover; - -extern "C" { - -PUBLIC bool -opencl_dri_event_add_ref(cl_event event) -{ - /* This should fail if the event hasn't been created by - * clEnqueueReleaseGLObjects or clEnqueueReleaseEGLObjects. - * - * TODO: implement the CL functions - */ - return false; /*return clRetainEvent(event) == CL_SUCCESS;*/ -} - -PUBLIC bool -opencl_dri_event_release(cl_event event) -{ - return clReleaseEvent(event) == CL_SUCCESS; -} - -PUBLIC bool -opencl_dri_event_wait(cl_event event, uint64_t timeout) try { - if (!timeout) { - return obj(event).status() == CL_COMPLETE; - } - - obj(event).wait(); - return true; - -} catch (error &) { - return false; -} - -PUBLIC struct pipe_fence_handle * -opencl_dri_event_get_fence(cl_event event) try { - return obj(event).fence(); - -} catch (error &) { - return NULL; -} - -} diff --git a/src/gallium/frontends/clover/api/invalid.cpp b/src/gallium/frontends/clover/api/invalid.cpp deleted file mode 100644 index 6274e3a78ea..00000000000 --- a/src/gallium/frontends/clover/api/invalid.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright 2020 Red Hat -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/context.hpp" -#include "core/platform.hpp" - -using namespace clover; - -// This contains all the CL 2.x API entrypoints that return INVALID_OPERATON -// on CL 3.0. If these are implemented they should be moved out of this file. - -CLOVER_API cl_mem -clCreatePipe(cl_context d_ctx, - cl_mem_flags flags, - cl_uint pipe_packet_size, - cl_uint pipe_max_packets, - const cl_pipe_properties *properties, - cl_int *r_errorcode) { - *r_errorcode = CL_INVALID_OPERATION; - return nullptr; -} - - -CLOVER_API cl_int -clGetPipeInfo(cl_mem pipe, - cl_pipe_info param_name, - size_t param_value_size, - void *param_value, - size_t *param_value_size_ret) { - return CL_INVALID_MEM_OBJECT; -} - -CLOVER_API cl_int -clGetDeviceAndHostTimer(cl_device_id device, - cl_ulong *device_timestamp, - cl_ulong *host_timestamp) { - return CL_INVALID_OPERATION; -} - -CLOVER_API cl_int -clGetHostTimer(cl_device_id device, - cl_ulong *host_timestamp) { - return CL_INVALID_OPERATION; -} - - -CLOVER_API cl_int -clGetKernelSubGroupInfo(cl_kernel d_kern, - cl_device_id device, - cl_kernel_sub_group_info param_name, - size_t input_value_size, - const void *input_value, - size_t param_size_value, - void *param_value, - size_t *param_value_size_ret) { - return CL_INVALID_OPERATION; -} - - -CLOVER_API cl_int -clSetDefaultDeviceCommandQueue(cl_context context, - cl_device_id device, - cl_command_queue command_queue) { - return CL_INVALID_OPERATION; -} - -CLOVER_API cl_int -clSetProgramReleaseCallback(cl_program d_prog, - void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), - void *user_data) { - return CL_INVALID_OPERATION; -} - -CLOVER_API cl_int -clSetProgramSpecializationConstant(cl_program program, - cl_uint spec_id, - size_t spec_size, - const void* spec_value) { - return CL_INVALID_OPERATION; -} diff --git a/src/gallium/frontends/clover/api/kernel.cpp b/src/gallium/frontends/clover/api/kernel.cpp deleted file mode 100644 index 2e1786375bc..00000000000 --- a/src/gallium/frontends/clover/api/kernel.cpp +++ /dev/null @@ -1,436 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/kernel.hpp" -#include "core/event.hpp" - -using namespace clover; - -CLOVER_API cl_kernel -clCreateKernel(cl_program d_prog, const char *name, cl_int *r_errcode) try { - auto &prog = obj(d_prog); - - if (!name) - throw error(CL_INVALID_VALUE); - - auto &sym = find(name_equals(name), prog.symbols()); - - ret_error(r_errcode, CL_SUCCESS); - return new kernel(prog, name, range(sym.args)); - -} catch (std::out_of_range &) { - ret_error(r_errcode, CL_INVALID_KERNEL_NAME); - return NULL; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clCreateKernelsInProgram(cl_program d_prog, cl_uint count, - cl_kernel *rd_kerns, cl_uint *r_count) try { - auto &prog = obj(d_prog); - auto &syms = prog.symbols(); - - if (rd_kerns && count < syms.size()) - throw error(CL_INVALID_VALUE); - - if (rd_kerns) - copy(map([&](const binary::symbol &sym) { - return desc(new kernel(prog, - std::string(sym.name.begin(), - sym.name.end()), - range(sym.args))); - }, syms), - rd_kerns); - - if (r_count) - *r_count = syms.size(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clRetainKernel(cl_kernel d_kern) try { - obj(d_kern).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseKernel(cl_kernel d_kern) try { - if (obj(d_kern).release()) - delete pobj(d_kern); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetKernelArg(cl_kernel d_kern, cl_uint idx, size_t size, - const void *value) try { - obj(d_kern).args().at(idx).set(size, value); - return CL_SUCCESS; - -} catch (std::out_of_range &) { - return CL_INVALID_ARG_INDEX; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetKernelInfo(cl_kernel d_kern, cl_kernel_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &kern = obj(d_kern); - - switch (param) { - case CL_KERNEL_FUNCTION_NAME: - buf.as_string() = kern.name(); - break; - - case CL_KERNEL_NUM_ARGS: - buf.as_scalar() = kern.args().size(); - break; - - case CL_KERNEL_REFERENCE_COUNT: - buf.as_scalar() = kern.ref_count(); - break; - - case CL_KERNEL_CONTEXT: - buf.as_scalar() = desc(kern.program().context()); - break; - - case CL_KERNEL_PROGRAM: - buf.as_scalar() = desc(kern.program()); - break; - - case CL_KERNEL_ATTRIBUTES: - buf.as_string() = find(name_equals(kern.name()), kern.program().symbols()).attributes; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev, - cl_kernel_work_group_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &kern = obj(d_kern); - auto &dev = (d_dev ? *pobj(d_dev) : unique(kern.program().devices())); - - if (!count(dev, kern.program().devices())) - throw error(CL_INVALID_DEVICE); - - switch (param) { - case CL_KERNEL_WORK_GROUP_SIZE: - buf.as_scalar() = dev.max_threads_per_block(); - break; - - case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: - buf.as_vector() = kern.required_block_size(); - break; - - case CL_KERNEL_LOCAL_MEM_SIZE: - buf.as_scalar() = kern.mem_local(); - break; - - case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: - buf.as_scalar() = dev.subgroup_size(); - break; - - case CL_KERNEL_PRIVATE_MEM_SIZE: - buf.as_scalar() = kern.mem_private(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); - -} catch (std::out_of_range &) { - return CL_INVALID_DEVICE; -} - -CLOVER_API cl_int -clGetKernelArgInfo(cl_kernel d_kern, - cl_uint idx, cl_kernel_arg_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - - auto info = obj(d_kern).args_infos().at(idx); - - if (info.arg_name.empty()) - return CL_KERNEL_ARG_INFO_NOT_AVAILABLE; - - switch (param) { - case CL_KERNEL_ARG_ADDRESS_QUALIFIER: - buf.as_scalar() = info.address_qualifier; - break; - - case CL_KERNEL_ARG_ACCESS_QUALIFIER: - buf.as_scalar() = info.access_qualifier; - break; - - case CL_KERNEL_ARG_TYPE_NAME: - buf.as_string() = info.type_name; - break; - - case CL_KERNEL_ARG_TYPE_QUALIFIER: - buf.as_scalar() = info.type_qualifier; - break; - - case CL_KERNEL_ARG_NAME: - buf.as_string() = info.arg_name; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (std::out_of_range &) { - return CL_INVALID_ARG_INDEX; - -} catch (error &e) { - return e.get(); -} - -namespace { - /// - /// Common argument checking shared by kernel invocation commands. - /// - void - validate_common(const command_queue &q, kernel &kern, - const ref_vector &deps) { - if (kern.program().context() != q.context() || - any_of([&](const event &ev) { - return ev.context() != q.context(); - }, deps)) - throw error(CL_INVALID_CONTEXT); - - if (any_of([](kernel::argument &arg) { - return !arg.set(); - }, kern.args())) - throw error(CL_INVALID_KERNEL_ARGS); - - // If the command queue's device is not associated to the program, we get - // a binary, with no sections, which will also fail the following test. - auto &b = kern.program().build(q.device()).bin; - if (!any_of(type_equals(binary::section::text_executable), b.secs)) - throw error(CL_INVALID_PROGRAM_EXECUTABLE); - } - - std::vector - validate_grid_size(const command_queue &q, cl_uint dims, - const size_t *d_grid_size) { - auto grid_size = range(d_grid_size, dims); - - if (dims < 1 || dims > q.device().max_block_size().size()) - throw error(CL_INVALID_WORK_DIMENSION); - - return grid_size; - } - - std::vector - validate_grid_offset(const command_queue &q, cl_uint dims, - const size_t *d_grid_offset) { - if (d_grid_offset) - return range(d_grid_offset, dims); - else - return std::vector(dims, 0); - } - - std::vector - validate_block_size(const command_queue &q, const kernel &kern, - cl_uint dims, const size_t *d_grid_size, - const size_t *d_block_size) { - auto grid_size = range(d_grid_size, dims); - - if (d_block_size) { - auto block_size = range(d_block_size, dims); - - if (any_of(is_zero(), block_size) || - any_of(greater(), block_size, q.device().max_block_size())) - throw error(CL_INVALID_WORK_ITEM_SIZE); - - if (any_of(modulus(), grid_size, block_size)) - throw error(CL_INVALID_WORK_GROUP_SIZE); - - if (fold(multiplies(), 1u, block_size) > - q.device().max_threads_per_block()) - throw error(CL_INVALID_WORK_GROUP_SIZE); - - return block_size; - - } else { - return kern.optimal_block_size(q, grid_size); - } - } -} - -CLOVER_API cl_int -clEnqueueNDRangeKernel(cl_command_queue d_q, cl_kernel d_kern, - cl_uint dims, const size_t *d_grid_offset, - const size_t *d_grid_size, const size_t *d_block_size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &kern = obj(d_kern); - auto deps = objs(d_deps, num_deps); - auto grid_size = validate_grid_size(q, dims, d_grid_size); - auto grid_offset = validate_grid_offset(q, dims, d_grid_offset); - auto block_size = validate_block_size(q, kern, dims, - d_grid_size, d_block_size); - - validate_common(q, kern, deps); - - auto hev = create( - q, CL_COMMAND_NDRANGE_KERNEL, deps, - [=, &kern, &q](event &) { - kern.launch(q, grid_offset, grid_size, block_size); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueTask(cl_command_queue d_q, cl_kernel d_kern, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &kern = obj(d_kern); - auto deps = objs(d_deps, num_deps); - - validate_common(q, kern, deps); - - auto hev = create( - q, CL_COMMAND_TASK, deps, - [=, &kern, &q](event &) { - kern.launch(q, { 0 }, { 1 }, { 1 }); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueNativeKernel(cl_command_queue d_q, - void (CL_CALLBACK * func)(void *), - void *args, size_t args_size, - cl_uint num_mems, const cl_mem *d_mems, - const void **mem_handles, cl_uint num_deps, - const cl_event *d_deps, cl_event *rd_ev) { - return CL_INVALID_OPERATION; -} - -CLOVER_API cl_int -clSetKernelArgSVMPointer(cl_kernel d_kern, - cl_uint arg_index, - const void *arg_value) try { - if (!any_of(std::mem_fn(&device::svm_support), obj(d_kern).program().devices())) - return CL_INVALID_OPERATION; - obj(d_kern).args().at(arg_index).set_svm(arg_value); - return CL_SUCCESS; - -} catch (std::out_of_range &) { - return CL_INVALID_ARG_INDEX; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetKernelExecInfo(cl_kernel d_kern, - cl_kernel_exec_info param_name, - size_t param_value_size, - const void *param_value) try { - - if (!any_of(std::mem_fn(&device::svm_support), obj(d_kern).program().devices())) - return CL_INVALID_OPERATION; - - auto &kern = obj(d_kern); - - const bool has_system_svm = all_of(std::mem_fn(&device::has_system_svm), - kern.program().context().devices()); - - if (!param_value) - return CL_INVALID_VALUE; - - switch (param_name) { - case CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM: - case CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM_ARM: { - if (param_value_size != sizeof(cl_bool)) - return CL_INVALID_VALUE; - - cl_bool val = *static_cast(param_value); - if (val == CL_TRUE && !has_system_svm) - return CL_INVALID_OPERATION; - else - return CL_SUCCESS; - } - - case CL_KERNEL_EXEC_INFO_SVM_PTRS: - case CL_KERNEL_EXEC_INFO_SVM_PTRS_ARM: - if (has_system_svm) - return CL_SUCCESS; - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - - default: - return CL_INVALID_VALUE; - } - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/memory.cpp b/src/gallium/frontends/clover/api/memory.cpp deleted file mode 100644 index ea553efe1f4..00000000000 --- a/src/gallium/frontends/clover/api/memory.cpp +++ /dev/null @@ -1,648 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "util/format/u_format.h" -#include "util/u_math.h" -#include "api/util.hpp" -#include "core/memory.hpp" -#include "core/format.hpp" - -using namespace clover; - -namespace { - cl_mem_flags - validate_flags(cl_mem d_parent, cl_mem_flags d_flags, bool svm) { - const cl_mem_flags dev_access_flags = - CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY; - const cl_mem_flags host_ptr_flags = - CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR; - const cl_mem_flags host_access_flags = - CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS; - const cl_mem_flags svm_flags = - CL_MEM_SVM_FINE_GRAIN_BUFFER | CL_MEM_SVM_ATOMICS; - - const cl_mem_flags valid_flags = - dev_access_flags - | (svm || d_parent ? 0 : host_ptr_flags) - | (svm ? svm_flags : host_access_flags); - - if ((d_flags & ~valid_flags) || - util_bitcount(d_flags & dev_access_flags) > 1 || - util_bitcount(d_flags & host_access_flags) > 1) - throw error(CL_INVALID_VALUE); - - if ((d_flags & CL_MEM_USE_HOST_PTR) && - (d_flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR))) - throw error(CL_INVALID_VALUE); - - if ((d_flags & CL_MEM_SVM_ATOMICS) && - !(d_flags & CL_MEM_SVM_FINE_GRAIN_BUFFER)) - throw error(CL_INVALID_VALUE); - - if (d_parent) { - const auto &parent = obj(d_parent); - const cl_mem_flags flags = (d_flags | - (d_flags & dev_access_flags ? 0 : - parent.flags() & dev_access_flags) | - (d_flags & host_access_flags ? 0 : - parent.flags() & host_access_flags) | - (parent.flags() & host_ptr_flags)); - - if (~flags & parent.flags() & (dev_access_flags & ~CL_MEM_READ_WRITE)) - throw error(CL_INVALID_VALUE); - - // Check if new host access flags cause a mismatch between - // host-read/write-only. - if (!(flags & CL_MEM_HOST_NO_ACCESS) && - (~flags & parent.flags() & host_access_flags)) - throw error(CL_INVALID_VALUE); - - return flags; - - } else { - return d_flags | (d_flags & dev_access_flags ? 0 : CL_MEM_READ_WRITE); - } - } - - std::vector - fill_properties(const cl_mem_properties *d_properties) { - std::vector properties; - if (d_properties) { - while (*d_properties) { - if (*d_properties != 0) - throw error(CL_INVALID_PROPERTY); - - properties.push_back(*d_properties); - d_properties++; - }; - properties.push_back(0); - } - return properties; - } -} - -CLOVER_API cl_mem -clCreateBufferWithProperties(cl_context d_ctx, - const cl_mem_properties *d_properties, - cl_mem_flags d_flags, size_t size, - void *host_ptr, cl_int *r_errcode) try { - - auto &ctx = obj(d_ctx); - const cl_mem_flags flags = validate_flags(NULL, d_flags, false); - std::vector properties = fill_properties(d_properties); - - if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR | - CL_MEM_COPY_HOST_PTR))) - throw error(CL_INVALID_HOST_PTR); - - if (!size || - size > fold(maximum(), cl_ulong(0), - map(std::mem_fn(&device::max_mem_alloc_size), ctx.devices()) - )) - throw error(CL_INVALID_BUFFER_SIZE); - - ret_error(r_errcode, CL_SUCCESS); - return new root_buffer(ctx, properties, flags, size, host_ptr); -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - - -CLOVER_API cl_mem -clCreateBuffer(cl_context d_ctx, cl_mem_flags d_flags, size_t size, - void *host_ptr, cl_int *r_errcode) { - return clCreateBufferWithProperties(d_ctx, NULL, d_flags, size, - host_ptr, r_errcode); -} - -CLOVER_API cl_mem -clCreateSubBuffer(cl_mem d_mem, cl_mem_flags d_flags, - cl_buffer_create_type op, - const void *op_info, cl_int *r_errcode) try { - auto &parent = obj(d_mem); - const cl_mem_flags flags = validate_flags(d_mem, d_flags, false); - - if (op == CL_BUFFER_CREATE_TYPE_REGION) { - auto reg = reinterpret_cast(op_info); - - if (!reg || - reg->origin > parent.size() || - reg->origin + reg->size > parent.size()) - throw error(CL_INVALID_VALUE); - - if (!reg->size) - throw error(CL_INVALID_BUFFER_SIZE); - - ret_error(r_errcode, CL_SUCCESS); - return new sub_buffer(parent, flags, reg->origin, reg->size); - - } else { - throw error(CL_INVALID_VALUE); - } - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_mem -clCreateImageWithProperties(cl_context d_ctx, - const cl_mem_properties *d_properties, - cl_mem_flags d_flags, - const cl_image_format *format, - const cl_image_desc *desc, - void *host_ptr, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - if (!any_of(std::mem_fn(&device::image_support), ctx.devices())) - throw error(CL_INVALID_OPERATION); - - if (!format) - throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); - - if (!desc) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (desc->image_array_size == 0 && - (desc->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || - desc->image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY)) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (!host_ptr && - (desc->image_row_pitch || desc->image_slice_pitch)) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (desc->num_mip_levels || desc->num_samples) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (bool(desc->buffer) != (desc->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER)) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (bool(host_ptr) != bool(d_flags & (CL_MEM_USE_HOST_PTR | - CL_MEM_COPY_HOST_PTR))) - throw error(CL_INVALID_HOST_PTR); - - const cl_mem_flags flags = validate_flags(desc->buffer, d_flags, false); - - if (!supported_formats(ctx, desc->image_type, d_flags).count(*format)) - throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); - - std::vector properties = fill_properties(d_properties); - ret_error(r_errcode, CL_SUCCESS); - - const size_t row_pitch = desc->image_row_pitch ? desc->image_row_pitch : - util_format_get_blocksize(translate_format(*format)) * desc->image_width; - - switch (desc->image_type) { - case CL_MEM_OBJECT_IMAGE1D: - if (!desc->image_width) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = dev.max_image_size(); - return (desc->image_width > max); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - return new image1d(ctx, properties, flags, format, - desc->image_width, - row_pitch, host_ptr); - - case CL_MEM_OBJECT_IMAGE1D_BUFFER: - if (!desc->image_width) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = dev.max_image_buffer_size(); - return (desc->image_width > max); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - return new image1d_buffer(ctx, properties, flags, format, - desc->image_width, - row_pitch, host_ptr, desc->buffer); - - case CL_MEM_OBJECT_IMAGE1D_ARRAY: { - if (!desc->image_width) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = dev.max_image_size(); - const size_t amax = dev.max_image_array_number(); - return (desc->image_width > max || - desc->image_array_size > amax); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - const size_t slice_pitch = desc->image_slice_pitch ? - desc->image_slice_pitch : row_pitch; - - return new image1d_array(ctx, properties, flags, format, - desc->image_width, - desc->image_array_size, slice_pitch, - host_ptr); - } - - case CL_MEM_OBJECT_IMAGE2D: - if (!desc->image_width || !desc->image_height) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = dev.max_image_size(); - return (desc->image_width > max || - desc->image_height > max); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - return new image2d(ctx, properties, flags, format, - desc->image_width, desc->image_height, - row_pitch, host_ptr); - - case CL_MEM_OBJECT_IMAGE2D_ARRAY: { - if (!desc->image_width || !desc->image_height || !desc->image_array_size) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = dev.max_image_size(); - const size_t amax = dev.max_image_array_number(); - return (desc->image_width > max || - desc->image_height > max || - desc->image_array_size > amax); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - const size_t slice_pitch = desc->image_slice_pitch ? - desc->image_slice_pitch : row_pitch * desc->image_height; - - return new image2d_array(ctx, properties, flags, format, - desc->image_width, desc->image_height, - desc->image_array_size, row_pitch, - slice_pitch, host_ptr); - } - - case CL_MEM_OBJECT_IMAGE3D: { - if (!desc->image_width || !desc->image_height || !desc->image_depth) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = dev.max_image_size_3d(); - return (desc->image_width > max || - desc->image_height > max || - desc->image_depth > max); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - const size_t slice_pitch = desc->image_slice_pitch ? - desc->image_slice_pitch : row_pitch * desc->image_height; - - return new image3d(ctx, properties, flags, format, - desc->image_width, desc->image_height, - desc->image_depth, row_pitch, - slice_pitch, host_ptr); - } - - default: - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - } - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_mem -clCreateImage(cl_context d_ctx, - cl_mem_flags d_flags, - const cl_image_format *format, - const cl_image_desc *desc, - void *host_ptr, cl_int *r_errcode) { - return clCreateImageWithProperties(d_ctx, NULL, d_flags, format, desc, host_ptr, r_errcode); -} - - -CLOVER_API cl_mem -clCreateImage2D(cl_context d_ctx, cl_mem_flags d_flags, - const cl_image_format *format, - size_t width, size_t height, size_t row_pitch, - void *host_ptr, cl_int *r_errcode) { - const cl_image_desc desc = { CL_MEM_OBJECT_IMAGE2D, width, height, 0, 0, - row_pitch, 0, 0, 0, { NULL } }; - - return clCreateImageWithProperties(d_ctx, NULL, d_flags, format, &desc, host_ptr, r_errcode); -} - -CLOVER_API cl_mem -clCreateImage3D(cl_context d_ctx, cl_mem_flags d_flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, - void *host_ptr, cl_int *r_errcode) { - const cl_image_desc desc = { CL_MEM_OBJECT_IMAGE3D, width, height, depth, 0, - row_pitch, slice_pitch, 0, 0, { NULL } }; - - return clCreateImageWithProperties(d_ctx, NULL, d_flags, format, &desc, host_ptr, r_errcode); -} - -CLOVER_API cl_int -clGetSupportedImageFormats(cl_context d_ctx, cl_mem_flags flags, - cl_mem_object_type type, cl_uint count, - cl_image_format *r_buf, cl_uint *r_count) try { - auto &ctx = obj(d_ctx); - auto formats = supported_formats(ctx, type, flags); - - if (flags & CL_MEM_KERNEL_READ_AND_WRITE) { - if (r_count) - *r_count = 0; - return CL_SUCCESS; - } - - if (flags & (CL_MEM_WRITE_ONLY | CL_MEM_READ_WRITE) && - type == CL_MEM_OBJECT_IMAGE3D) { - if (r_count) - *r_count = 0; - return CL_SUCCESS; - } - - validate_flags(NULL, flags, false); - - if (r_buf && !count) - throw error(CL_INVALID_VALUE); - - if (r_buf) - std::copy_n(formats.begin(), - std::min((cl_uint)formats.size(), count), - r_buf); - - if (r_count) - *r_count = formats.size(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &mem = obj(d_mem); - - switch (param) { - case CL_MEM_TYPE: - buf.as_scalar() = mem.type(); - break; - - case CL_MEM_FLAGS: - buf.as_scalar() = mem.flags(); - break; - - case CL_MEM_SIZE: - buf.as_scalar() = mem.size(); - break; - - case CL_MEM_HOST_PTR: - buf.as_scalar() = mem.host_ptr(); - break; - - case CL_MEM_MAP_COUNT: - buf.as_scalar() = 0; - break; - - case CL_MEM_REFERENCE_COUNT: - buf.as_scalar() = mem.ref_count(); - break; - - case CL_MEM_CONTEXT: - buf.as_scalar() = desc(mem.context()); - break; - - case CL_MEM_ASSOCIATED_MEMOBJECT: { - sub_buffer *sub = dynamic_cast(&mem); - if (sub) { - buf.as_scalar() = desc(sub->parent()); - break; - } - - image *img = dynamic_cast(&mem); - if (img) { - buf.as_scalar() = desc(img->buffer()); - break; - } - - buf.as_scalar() = NULL; - break; - } - case CL_MEM_OFFSET: { - sub_buffer *sub = dynamic_cast(&mem); - buf.as_scalar() = (sub ? sub->offset() : 0); - break; - } - case CL_MEM_USES_SVM_POINTER: - case CL_MEM_USES_SVM_POINTER_ARM: { - // with system SVM all host ptrs are SVM pointers - // TODO: once we support devices with lower levels of SVM, we have to - // check the ptr in more detail - const bool system_svm = all_of(std::mem_fn(&device::has_system_svm), - mem.context().devices()); - buf.as_scalar() = mem.host_ptr() && system_svm; - break; - } - case CL_MEM_PROPERTIES: - buf.as_vector() = mem.properties(); - break; - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetImageInfo(cl_mem d_mem, cl_image_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &img = obj(d_mem); - - switch (param) { - case CL_IMAGE_FORMAT: - buf.as_scalar() = img.format(); - break; - - case CL_IMAGE_ELEMENT_SIZE: - buf.as_scalar() = img.pixel_size(); - break; - - case CL_IMAGE_ROW_PITCH: - buf.as_scalar() = img.row_pitch(); - break; - - case CL_IMAGE_SLICE_PITCH: - buf.as_scalar() = img.slice_pitch(); - break; - - case CL_IMAGE_WIDTH: - buf.as_scalar() = img.width(); - break; - - case CL_IMAGE_HEIGHT: - buf.as_scalar() = img.dimensions() > 1 ? img.height() : 0; - break; - - case CL_IMAGE_DEPTH: - buf.as_scalar() = img.dimensions() > 2 ? img.depth() : 0; - break; - - case CL_IMAGE_ARRAY_SIZE: - buf.as_scalar() = img.array_size(); - break; - - case CL_IMAGE_BUFFER: - buf.as_scalar() = img.buffer(); - break; - - case CL_IMAGE_NUM_MIP_LEVELS: - buf.as_scalar() = 0; - break; - - case CL_IMAGE_NUM_SAMPLES: - buf.as_scalar() = 0; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clRetainMemObject(cl_mem d_mem) try { - obj(d_mem).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseMemObject(cl_mem d_mem) try { - if (obj(d_mem).release()) - delete pobj(d_mem); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetMemObjectDestructorCallback(cl_mem d_mem, - void (CL_CALLBACK *pfn_notify)(cl_mem, void *), - void *user_data) try { - auto &mem = obj(d_mem); - - if (!pfn_notify) - return CL_INVALID_VALUE; - - mem.destroy_notify([=]{ pfn_notify(d_mem, user_data); }); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API void * -clSVMAlloc(cl_context d_ctx, - cl_svm_mem_flags flags, - size_t size, - unsigned int alignment) try { - auto &ctx = obj(d_ctx); - - if (!any_of(std::mem_fn(&device::svm_support), ctx.devices())) - return NULL; - - validate_flags(NULL, flags, true); - - if (!size || - size > fold(minimum(), cl_ulong(ULONG_MAX), - map(std::mem_fn(&device::max_mem_alloc_size), ctx.devices()))) - return nullptr; - - if (!util_is_power_of_two_or_zero(alignment)) - return nullptr; - - if (!alignment) - alignment = 0x80; // sizeof(long16) - -#if defined(HAVE_POSIX_MEMALIGN) - bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices()); - if (can_emulate) { - // we can ignore all the flags as it's not required to honor them. - void *ptr = nullptr; - if (alignment < sizeof(void*)) - alignment = sizeof(void*); - int ret = posix_memalign(&ptr, alignment, size); - if (ret) - return nullptr; - - if (ptr) - ctx.add_svm_allocation(ptr, size); - - return ptr; - } -#endif - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return nullptr; - -} catch (error &) { - return nullptr; -} - -CLOVER_API void -clSVMFree(cl_context d_ctx, - void *svm_pointer) try { - auto &ctx = obj(d_ctx); - - if (!any_of(std::mem_fn(&device::svm_support), ctx.devices())) - return; - - bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices()); - - if (can_emulate) { - ctx.remove_svm_allocation(svm_pointer); - return free(svm_pointer); - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - -} catch (error &) { -} diff --git a/src/gallium/frontends/clover/api/platform.cpp b/src/gallium/frontends/clover/api/platform.cpp deleted file mode 100644 index b2077d30360..00000000000 --- a/src/gallium/frontends/clover/api/platform.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include - -#include "api/dispatch.hpp" -#include "api/util.hpp" -#include "core/platform.hpp" -#include "git_sha1.h" -#include "util/u_debug.h" - -using namespace clover; - -namespace { - platform _clover_platform; -} - -CLOVER_API cl_int -clGetPlatformIDs(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms) { - if ((!num_entries && rd_platforms) || - (!rnum_platforms && !rd_platforms)) - return CL_INVALID_VALUE; - - if (rnum_platforms) - *rnum_platforms = 1; - if (rd_platforms) - *rd_platforms = desc(_clover_platform); - - return CL_SUCCESS; -} - -platform &clover::find_platform(cl_platform_id d_platform) -{ - /* this error is only added in CL2.0 */ - if (d_platform != desc(_clover_platform)) - throw error(CL_INVALID_PLATFORM); - return obj(d_platform); -} - -cl_int -clover::GetPlatformInfo(cl_platform_id d_platform, cl_platform_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - - auto &platform = find_platform(d_platform); - - switch (param) { - case CL_PLATFORM_PROFILE: - buf.as_string() = "FULL_PROFILE"; - break; - - case CL_PLATFORM_VERSION: { - buf.as_string() = "OpenCL " + platform.platform_version_as_string() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1; - break; - } - case CL_PLATFORM_NAME: - buf.as_string() = "Clover"; - break; - - case CL_PLATFORM_VENDOR: - buf.as_string() = "Mesa"; - break; - - case CL_PLATFORM_EXTENSIONS: - buf.as_string() = platform.supported_extensions_as_string(); - break; - - case CL_PLATFORM_ICD_SUFFIX_KHR: - buf.as_string() = "MESA"; - break; - - case CL_PLATFORM_NUMERIC_VERSION: { - buf.as_scalar() = platform.platform_version(); - break; - } - - case CL_PLATFORM_EXTENSIONS_WITH_VERSION: - buf.as_vector() = platform.supported_extensions(); - break; - - case CL_PLATFORM_HOST_TIMER_RESOLUTION: - buf.as_scalar() = 0; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -void * -clover::GetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, - const char *p_name) try { - obj(d_platform); - return GetExtensionFunctionAddress(p_name); - -} catch (error &) { - return NULL; -} - -namespace { - -cl_int -enqueueSVMFreeARM(cl_command_queue command_queue, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMFree(command_queue, num_svm_pointers, svm_pointers, - pfn_free_func, user_data, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_FREE_ARM); -} - -cl_int -enqueueSVMMapARM(cl_command_queue command_queue, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMap(command_queue, blocking_map, map_flags, svm_ptr, size, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_SVM_MAP_ARM); -} - -cl_int -enqueueSVMMemcpyARM(cl_command_queue command_queue, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemcpy(command_queue, blocking_copy, dst_ptr, src_ptr, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMCPY_ARM); -} - -cl_int -enqueueSVMMemFillARM(cl_command_queue command_queue, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemFill(command_queue, svm_ptr, pattern, pattern_size, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMFILL_ARM); -} - -cl_int -enqueueSVMUnmapARM(cl_command_queue command_queue, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMUnmap(command_queue, svm_ptr, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_UNMAP_ARM); -} - -const std::unordered_map -ext_funcs = { - // cl_arm_shared_virtual_memory - { "clEnqueueSVMFreeARM", reinterpret_cast(enqueueSVMFreeARM) }, - { "clEnqueueSVMMapARM", reinterpret_cast(enqueueSVMMapARM) }, - { "clEnqueueSVMMemcpyARM", reinterpret_cast(enqueueSVMMemcpyARM) }, - { "clEnqueueSVMMemFillARM", reinterpret_cast(enqueueSVMMemFillARM) }, - { "clEnqueueSVMUnmapARM", reinterpret_cast(enqueueSVMUnmapARM) }, - { "clSetKernelArgSVMPointerARM", reinterpret_cast(clSetKernelArgSVMPointer) }, - { "clSetKernelExecInfoARM", reinterpret_cast(clSetKernelExecInfo) }, - { "clSVMAllocARM", reinterpret_cast(clSVMAlloc) }, - { "clSVMFreeARM", reinterpret_cast(clSVMFree) }, - - // cl_khr_icd - { "clIcdGetPlatformIDsKHR", reinterpret_cast(IcdGetPlatformIDsKHR) }, - - // cl_khr_il_program - { "clCreateProgramWithILKHR", reinterpret_cast(CreateProgramWithILKHR) }, -}; - -} // anonymous namespace - -void * -clover::GetExtensionFunctionAddress(const char *p_name) try { - return ext_funcs.at(p_name); -} catch (...) { - return nullptr; -} - -cl_int -clover::IcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms) { - return clGetPlatformIDs(num_entries, rd_platforms, rnum_platforms); -} - -CLOVER_ICD_API cl_int -clGetPlatformInfo(cl_platform_id d_platform, cl_platform_info param, - size_t size, void *r_buf, size_t *r_size) { - return GetPlatformInfo(d_platform, param, size, r_buf, r_size); -} - -CLOVER_ICD_API void * -clGetExtensionFunctionAddress(const char *p_name) { - return GetExtensionFunctionAddress(p_name); -} - -CLOVER_ICD_API void * -clGetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, - const char *p_name) { - return GetExtensionFunctionAddressForPlatform(d_platform, p_name); -} - -CLOVER_ICD_API cl_int -clIcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms) { - return IcdGetPlatformIDsKHR(num_entries, rd_platforms, rnum_platforms); -} diff --git a/src/gallium/frontends/clover/api/program.cpp b/src/gallium/frontends/clover/api/program.cpp deleted file mode 100644 index b01ce08d010..00000000000 --- a/src/gallium/frontends/clover/api/program.cpp +++ /dev/null @@ -1,580 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/program.hpp" -#include "core/platform.hpp" -#include "util/u_debug.h" - -#include -#include - -using namespace clover; - -namespace { - - std::string - build_options(const char *p_opts, const char *p_debug) { - auto opts = std::string(p_opts ? p_opts : ""); - std::string extra_opts = debug_get_option(p_debug, ""); - - return detokenize(std::vector{opts, extra_opts}, " "); - } - - class build_notifier { - public: - build_notifier(cl_program prog, - void (CL_CALLBACK * notifer)(cl_program, void *), void *data) : - prog_(prog), notifer(notifer), data_(data) { } - - ~build_notifier() { - if (notifer) - notifer(prog_, data_); - } - - private: - cl_program prog_; - void (CL_CALLBACK * notifer)(cl_program, void *); - void *data_; - }; - - void - validate_build_common(const program &prog, cl_uint num_devs, - const cl_device_id *d_devs, - void (CL_CALLBACK * pfn_notify)(cl_program, void *), - void *user_data) { - if (!pfn_notify && user_data) - throw error(CL_INVALID_VALUE); - - if (prog.kernel_ref_count()) - throw error(CL_INVALID_OPERATION); - - if (any_of([&](const device &dev) { - return !count(dev, prog.devices()); - }, objs(d_devs, num_devs))) - throw error(CL_INVALID_DEVICE); - } - - enum program::il_type - identify_and_validate_il(const std::string &il, - const cl_version opencl_version, - const context::notify_action ¬ify) { - - return program::il_type::none; - } -} - -CLOVER_API cl_program -clCreateProgramWithSource(cl_context d_ctx, cl_uint count, - const char **strings, const size_t *lengths, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - std::string source; - - if (!count || !strings || - any_of(is_zero(), range(strings, count))) - throw error(CL_INVALID_VALUE); - - // Concatenate all the provided fragments together - for (unsigned i = 0; i < count; ++i) - source += (lengths && lengths[i] ? - std::string(strings[i], strings[i] + lengths[i]) : - std::string(strings[i])); - - // ...and create a program object for them. - ret_error(r_errcode, CL_SUCCESS); - return new program(ctx, std::move(source), program::il_type::source); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_program -clCreateProgramWithBinary(cl_context d_ctx, cl_uint n, - const cl_device_id *d_devs, - const size_t *lengths, - const unsigned char **binaries, - cl_int *r_status, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto devs = objs(d_devs, n); - - if (!lengths || !binaries) - throw error(CL_INVALID_VALUE); - - if (any_of([&](const device &dev) { - return !count(dev, ctx.devices()); - }, devs)) - throw error(CL_INVALID_DEVICE); - - // Deserialize the provided binaries, - std::vector> result = map( - [](const unsigned char *p, size_t l) -> std::pair { - if (!p || !l) - return { CL_INVALID_VALUE, {} }; - - try { - std::stringbuf bin( std::string{ (char*)p, l } ); - std::istream s(&bin); - - return { CL_SUCCESS, binary::deserialize(s) }; - - } catch (std::istream::failure &) { - return { CL_INVALID_BINARY, {} }; - } - }, - range(binaries, n), - range(lengths, n)); - - // update the status array, - if (r_status) - copy(map(keys(), result), r_status); - - if (any_of(key_equals(CL_INVALID_VALUE), result)) - throw error(CL_INVALID_VALUE); - - if (any_of(key_equals(CL_INVALID_BINARY), result)) - throw error(CL_INVALID_BINARY); - - // initialize a program object with them. - ret_error(r_errcode, CL_SUCCESS); - return new program(ctx, devs, map(values(), result)); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -cl_program -clover::CreateProgramWithILKHR(cl_context d_ctx, const void *il, - size_t length, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - if (!il || !length) - throw error(CL_INVALID_VALUE); - - // Compute the highest OpenCL version supported by all devices associated to - // the context. That is the version used for validating the SPIR-V binary. - cl_version min_opencl_version = std::numeric_limits::max(); - for (const device &dev : ctx.devices()) { - const cl_version opencl_version = dev.device_version(); - min_opencl_version = std::min(opencl_version, min_opencl_version); - } - - const char *stream = reinterpret_cast(il); - std::string binary(stream, stream + length); - const enum program::il_type il_type = identify_and_validate_il(binary, - min_opencl_version, - ctx.notify); - - if (il_type == program::il_type::none) - throw error(CL_INVALID_VALUE); - - // Initialize a program object with it. - ret_error(r_errcode, CL_SUCCESS); - return new program(ctx, std::move(binary), il_type); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_program -clCreateProgramWithIL(cl_context d_ctx, - const void *il, - size_t length, - cl_int *r_errcode) { - return CreateProgramWithILKHR(d_ctx, il, length, r_errcode); -} - -CLOVER_API cl_program -clCreateProgramWithBuiltInKernels(cl_context d_ctx, cl_uint n, - const cl_device_id *d_devs, - const char *kernel_names, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto devs = objs(d_devs, n); - - if (any_of([&](const device &dev) { - return !count(dev, ctx.devices()); - }, devs)) - throw error(CL_INVALID_DEVICE); - - // No currently supported built-in kernels. - throw error(CL_INVALID_VALUE); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - - -CLOVER_API cl_int -clRetainProgram(cl_program d_prog) try { - obj(d_prog).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseProgram(cl_program d_prog) try { - if (obj(d_prog).release()) - delete pobj(d_prog); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clBuildProgram(cl_program d_prog, cl_uint num_devs, - const cl_device_id *d_devs, const char *p_opts, - void (CL_CALLBACK * pfn_notify)(cl_program, void *), - void *user_data) try { - auto &prog = obj(d_prog); - auto devs = - (d_devs ? objs(d_devs, num_devs) : ref_vector(prog.devices())); - const auto opts = build_options(p_opts, "CLOVER_EXTRA_BUILD_OPTIONS"); - - validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - - auto notifier = build_notifier(d_prog, pfn_notify, user_data); - - if (prog.il_type() != program::il_type::none) { - prog.compile(devs, opts); - prog.link(devs, opts, { prog }); - } else if (any_of([&](const device &dev){ - return prog.build(dev).binary_type() != CL_PROGRAM_BINARY_TYPE_EXECUTABLE; - }, devs)) { - // According to the OpenCL 1.2 specification, “if program is created - // with clCreateProgramWithBinary, then the program binary must be an - // executable binary (not a compiled binary or library).” - throw error(CL_INVALID_BINARY); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clCompileProgram(cl_program d_prog, cl_uint num_devs, - const cl_device_id *d_devs, const char *p_opts, - cl_uint num_headers, const cl_program *d_header_progs, - const char **header_names, - void (CL_CALLBACK * pfn_notify)(cl_program, void *), - void *user_data) try { - auto &prog = obj(d_prog); - auto devs = - (d_devs ? objs(d_devs, num_devs) : ref_vector(prog.devices())); - const auto opts = build_options(p_opts, "CLOVER_EXTRA_COMPILE_OPTIONS"); - header_map headers; - - validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - - auto notifier = build_notifier(d_prog, pfn_notify, user_data); - - if (bool(num_headers) != bool(header_names)) - throw error(CL_INVALID_VALUE); - - if (prog.il_type() == program::il_type::none) - throw error(CL_INVALID_OPERATION); - - for_each([&](const char *name, const program &header) { - if (header.il_type() == program::il_type::none) - throw error(CL_INVALID_OPERATION); - - if (!any_of(key_equals(name), headers)) - headers.push_back(std::pair( - name, header.source())); - }, - range(header_names, num_headers), - objs(d_header_progs, num_headers)); - - prog.compile(devs, opts, headers); - return CL_SUCCESS; - -} catch (invalid_build_options_error &) { - return CL_INVALID_COMPILER_OPTIONS; - -} catch (build_error &) { - return CL_COMPILE_PROGRAM_FAILURE; - -} catch (error &e) { - return e.get(); -} - -namespace { - ref_vector - validate_link_devices(const ref_vector &progs, - const ref_vector &all_devs, - const std::string &opts) { - std::vector devs; - const bool create_library = - opts.find("-create-library") != std::string::npos; - const bool enable_link_options = - opts.find("-enable-link-options") != std::string::npos; - const bool has_link_options = - opts.find("-cl-denorms-are-zero") != std::string::npos || - opts.find("-cl-no-signed-zeroes") != std::string::npos || - opts.find("-cl-unsafe-math-optimizations") != std::string::npos || - opts.find("-cl-finite-math-only") != std::string::npos || - opts.find("-cl-fast-relaxed-math") != std::string::npos || - opts.find("-cl-no-subgroup-ifp") != std::string::npos; - - // According to the OpenCL 1.2 specification, "[the - // -enable-link-options] option must be specified with the - // create-library option". - if (enable_link_options && !create_library) - throw error(CL_INVALID_LINKER_OPTIONS); - - // According to the OpenCL 1.2 specification, "the - // [program linking options] can be specified when linking a program - // executable". - if (has_link_options && create_library) - throw error(CL_INVALID_LINKER_OPTIONS); - - for (auto &dev : all_devs) { - const auto has_binary = [&](const program &prog) { - const auto t = prog.build(dev).binary_type(); - return t == CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT || - t == CL_PROGRAM_BINARY_TYPE_LIBRARY; - }; - - // According to the OpenCL 1.2 specification, a library is made of - // “compiled binaries specified in input_programs argument to - // clLinkProgram“; compiled binaries does not refer to libraries: - // “input_programs is an array of program objects that are compiled - // binaries or libraries that are to be linked to create the program - // executable”. - if (create_library && any_of([&](const program &prog) { - const auto t = prog.build(dev).binary_type(); - return t != CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; - }, progs)) - throw error(CL_INVALID_OPERATION); - - // According to the CL 1.2 spec, when "all programs specified [..] - // contain a compiled binary or library for the device [..] a link is - // performed", - else if (all_of(has_binary, progs)) - devs.push_back(&dev); - - // otherwise if "none of the programs contain a compiled binary or - // library for that device [..] no link is performed. All other - // cases will return a CL_INVALID_OPERATION error." - else if (any_of(has_binary, progs)) - throw error(CL_INVALID_OPERATION); - - // According to the OpenCL 1.2 specification, "[t]he linker may apply - // [program linking options] to all compiled program objects - // specified to clLinkProgram. The linker may apply these options - // only to libraries which were created with the - // -enable-link-option." - else if (has_link_options && any_of([&](const program &prog) { - const auto t = prog.build(dev).binary_type(); - return !(t == CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT || - (t == CL_PROGRAM_BINARY_TYPE_LIBRARY && - prog.build(dev).opts.find("-enable-link-options") != - std::string::npos)); - }, progs)) - throw error(CL_INVALID_LINKER_OPTIONS); - } - - return map(derefs(), devs); - } -} - -CLOVER_API cl_program -clLinkProgram(cl_context d_ctx, cl_uint num_devs, const cl_device_id *d_devs, - const char *p_opts, cl_uint num_progs, const cl_program *d_progs, - void (CL_CALLBACK * pfn_notify) (cl_program, void *), void *user_data, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - const auto opts = build_options(p_opts, "CLOVER_EXTRA_LINK_OPTIONS"); - auto progs = objs(d_progs, num_progs); - auto all_devs = - (d_devs ? objs(d_devs, num_devs) : ref_vector(ctx.devices())); - auto prog = create(ctx, all_devs); - auto r_prog = ret_object(prog); - - auto notifier = build_notifier(r_prog, pfn_notify, user_data); - - auto devs = validate_link_devices(progs, all_devs, opts); - - validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - - try { - prog().link(devs, opts, progs); - ret_error(r_errcode, CL_SUCCESS); - - } catch (build_error &) { - ret_error(r_errcode, CL_LINK_PROGRAM_FAILURE); - } - - return r_prog; - -} catch (invalid_build_options_error &) { - ret_error(r_errcode, CL_INVALID_LINKER_OPTIONS); - return NULL; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clUnloadCompiler() { - return CL_SUCCESS; -} - -CLOVER_API cl_int -clUnloadPlatformCompiler(cl_platform_id d_platform) try { - find_platform(d_platform); - return CL_SUCCESS; -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetProgramInfo(cl_program d_prog, cl_program_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &prog = obj(d_prog); - - switch (param) { - case CL_PROGRAM_REFERENCE_COUNT: - buf.as_scalar() = prog.ref_count(); - break; - - case CL_PROGRAM_CONTEXT: - buf.as_scalar() = desc(prog.context()); - break; - - case CL_PROGRAM_NUM_DEVICES: - buf.as_scalar() = (prog.devices().size() ? - prog.devices().size() : - prog.context().devices().size()); - break; - - case CL_PROGRAM_DEVICES: - buf.as_vector() = (prog.devices().size() ? - descs(prog.devices()) : - descs(prog.context().devices())); - break; - - case CL_PROGRAM_SOURCE: - buf.as_string() = prog.source(); - break; - - case CL_PROGRAM_BINARY_SIZES: - buf.as_vector() = map([&](const device &dev) { - return prog.build(dev).bin.size(); - }, - prog.devices()); - break; - - case CL_PROGRAM_BINARIES: - buf.as_matrix() = map([&](const device &dev) { - std::stringbuf bin; - std::ostream s(&bin); - prog.build(dev).bin.serialize(s); - return bin.str(); - }, - prog.devices()); - break; - - case CL_PROGRAM_NUM_KERNELS: - buf.as_scalar() = prog.symbols().size(); - break; - - case CL_PROGRAM_KERNEL_NAMES: - buf.as_string() = fold([](const std::string &a, const binary::symbol &s) { - return ((a.empty() ? "" : a + ";") + s.name); - }, std::string(), prog.symbols()); - break; - - case CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT: - case CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT: - buf.as_scalar() = CL_FALSE; - break; - - case CL_PROGRAM_IL: - if (prog.il_type() == program::il_type::spirv) - buf.as_vector() = prog.source(); - else if (r_size) - *r_size = 0u; - break; - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetProgramBuildInfo(cl_program d_prog, cl_device_id d_dev, - cl_program_build_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &prog = obj(d_prog); - auto &dev = obj(d_dev); - - if (!count(dev, prog.context().devices())) - return CL_INVALID_DEVICE; - - switch (param) { - case CL_PROGRAM_BUILD_STATUS: - buf.as_scalar() = prog.build(dev).status(); - break; - - case CL_PROGRAM_BUILD_OPTIONS: - buf.as_string() = prog.build(dev).opts; - break; - - case CL_PROGRAM_BUILD_LOG: - buf.as_string() = prog.build(dev).log; - break; - - case CL_PROGRAM_BINARY_TYPE: - buf.as_scalar() = prog.build(dev).binary_type(); - break; - - case CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE: - buf.as_scalar() = 0; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/queue.cpp b/src/gallium/frontends/clover/api/queue.cpp deleted file mode 100644 index 9d1123b2ddb..00000000000 --- a/src/gallium/frontends/clover/api/queue.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/queue.hpp" - -using namespace clover; - -CLOVER_API cl_command_queue -clCreateCommandQueue(cl_context d_ctx, cl_device_id d_dev, - cl_command_queue_properties props, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto &dev = obj(d_dev); - - if (!count(dev, ctx.devices())) - throw error(CL_INVALID_DEVICE); - - if (props & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | - CL_QUEUE_PROFILING_ENABLE)) - throw error(CL_INVALID_VALUE); - - ret_error(r_errcode, CL_SUCCESS); - return new command_queue(ctx, dev, props); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clRetainCommandQueue(cl_command_queue d_q) try { - obj(d_q).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseCommandQueue(cl_command_queue d_q) try { - auto &q = obj(d_q); - - q.flush(); - - if (q.release()) - delete pobj(d_q); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetCommandQueueInfo(cl_command_queue d_q, cl_command_queue_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &q = obj(d_q); - - switch (param) { - case CL_QUEUE_CONTEXT: - buf.as_scalar() = desc(q.context()); - break; - - case CL_QUEUE_DEVICE: - buf.as_scalar() = desc(q.device()); - break; - - case CL_QUEUE_REFERENCE_COUNT: - buf.as_scalar() = q.ref_count(); - break; - - case CL_QUEUE_PROPERTIES: - buf.as_scalar() = q.props(); - break; - - case CL_QUEUE_PROPERTIES_ARRAY: - buf.as_vector() = q.properties(); - break; - - case CL_QUEUE_DEVICE_DEFAULT: - if (r_size) - *r_size = 0; - break; - - case CL_QUEUE_SIZE: - throw error(CL_INVALID_COMMAND_QUEUE); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clFlush(cl_command_queue d_q) try { - obj(d_q).flush(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_command_queue -clCreateCommandQueueWithProperties(cl_context d_ctx, cl_device_id d_dev, - const cl_queue_properties *d_properties, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto &dev = obj(d_dev); - - if (!count(dev, ctx.devices())) - throw error(CL_INVALID_DEVICE); - - ret_error(r_errcode, CL_SUCCESS); - std::vector properties; - - if (d_properties) { - int idx = -1; - /* these come in pairs, bail if the first is 0 */ - do { - idx++; - properties.push_back(d_properties[idx]); - } while (d_properties[idx & ~1]); - } - return new command_queue(ctx, dev, properties); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} diff --git a/src/gallium/frontends/clover/api/sampler.cpp b/src/gallium/frontends/clover/api/sampler.cpp deleted file mode 100644 index 482e55a9ce9..00000000000 --- a/src/gallium/frontends/clover/api/sampler.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/sampler.hpp" - -using namespace clover; - -CLOVER_API cl_sampler -clCreateSampler(cl_context d_ctx, cl_bool norm_mode, - cl_addressing_mode addr_mode, cl_filter_mode filter_mode, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - if (!any_of(std::mem_fn(&device::image_support), ctx.devices())) - throw error(CL_INVALID_OPERATION); - - ret_error(r_errcode, CL_SUCCESS); - return new sampler(ctx, norm_mode, addr_mode, filter_mode); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clRetainSampler(cl_sampler d_s) try { - obj(d_s).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseSampler(cl_sampler d_s) try { - if (obj(d_s).release()) - delete pobj(d_s); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetSamplerInfo(cl_sampler d_s, cl_sampler_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &s = obj(d_s); - - switch (param) { - case CL_SAMPLER_REFERENCE_COUNT: - buf.as_scalar() = s.ref_count(); - break; - - case CL_SAMPLER_CONTEXT: - buf.as_scalar() = desc(s.context()); - break; - - case CL_SAMPLER_NORMALIZED_COORDS: - buf.as_scalar() = s.norm_mode(); - break; - - case CL_SAMPLER_ADDRESSING_MODE: - buf.as_scalar() = s.addr_mode(); - break; - - case CL_SAMPLER_FILTER_MODE: - buf.as_scalar() = s.filter_mode(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/transfer.cpp b/src/gallium/frontends/clover/api/transfer.cpp deleted file mode 100644 index e6b68b267c3..00000000000 --- a/src/gallium/frontends/clover/api/transfer.cpp +++ /dev/null @@ -1,1326 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include - -#include "util/bitscan.h" - -#include "api/dispatch.hpp" -#include "api/util.hpp" -#include "core/event.hpp" -#include "core/memory.hpp" - -using namespace clover; - -namespace { - typedef resource::vector vector_t; - - vector_t - vector(const size_t *p) { - if (!p) - throw error(CL_INVALID_VALUE); - return range(p, 3); - } - - vector_t - pitch(const vector_t ®ion, vector_t pitch) { - for (auto x : zip(tail(pitch), - map(multiplies(), region, pitch))) { - // The spec defines a value of zero as the natural pitch, - // i.e. the unaligned size of the previous dimension. - if (std::get<0>(x) == 0) - std::get<0>(x) = std::get<1>(x); - } - - return pitch; - } - - /// - /// Size of a region in bytes. - /// - size_t - size(const vector_t &pitch, const vector_t ®ion) { - if (any_of(is_zero(), region)) - return 0; - else - return dot(pitch, region - vector_t{ 0, 1, 1 }); - } - - /// - /// Common argument checking shared by memory transfer commands. - /// - void - validate_common(command_queue &q, - const ref_vector &deps) { - if (any_of([&](const event &ev) { - return ev.context() != q.context(); - }, deps)) - throw error(CL_INVALID_CONTEXT); - } - - /// - /// Common error checking for a buffer object argument. - /// - void - validate_object(command_queue &q, buffer &mem, const vector_t &origin, - const vector_t &pitch, const vector_t ®ion) { - if (mem.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - - // The region must fit within the specified pitch, - if (any_of(greater(), map(multiplies(), pitch, region), tail(pitch))) - throw error(CL_INVALID_VALUE); - - // ...and within the specified object. - if (dot(pitch, origin) + size(pitch, region) > mem.size()) - throw error(CL_INVALID_VALUE); - - if (any_of(is_zero(), region)) - throw error(CL_INVALID_VALUE); - } - - /// - /// Common error checking for an image argument. - /// - void - validate_object(command_queue &q, image &img, - const vector_t &orig, const vector_t ®ion) { - size_t height = img.type() == CL_MEM_OBJECT_IMAGE1D_ARRAY ? img.array_size() : img.height(); - size_t depth = img.type() == CL_MEM_OBJECT_IMAGE2D_ARRAY ? img.array_size() : img.depth(); - vector_t size = { img.width(), height, depth }; - const auto &dev = q.device(); - - if (!dev.image_support()) - throw error(CL_INVALID_OPERATION); - - if (img.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - - if (any_of(greater(), orig + region, size)) - throw error(CL_INVALID_VALUE); - - if (any_of(is_zero(), region)) - throw error(CL_INVALID_VALUE); - - switch (img.type()) { - case CL_MEM_OBJECT_IMAGE1D: { - const size_t max = dev.max_image_size(); - if (img.width() > max) - throw error(CL_INVALID_IMAGE_SIZE); - break; - } - case CL_MEM_OBJECT_IMAGE1D_ARRAY: { - const size_t max_size = dev.max_image_size(); - const size_t max_array = dev.max_image_array_number(); - if (img.width() > max_size || img.array_size() > max_array) - throw error(CL_INVALID_IMAGE_SIZE); - break; - } - case CL_MEM_OBJECT_IMAGE2D: { - const size_t max = dev.max_image_size(); - if (img.width() > max || img.height() > max) - throw error(CL_INVALID_IMAGE_SIZE); - break; - } - case CL_MEM_OBJECT_IMAGE2D_ARRAY: { - const size_t max_size = dev.max_image_size(); - const size_t max_array = dev.max_image_array_number(); - if (img.width() > max_size || img.height() > max_size || img.array_size() > max_array) - throw error(CL_INVALID_IMAGE_SIZE); - break; - } - case CL_MEM_OBJECT_IMAGE3D: { - const size_t max = dev.max_image_size_3d(); - if (img.width() > max || img.height() > max || img.depth() > max) - throw error(CL_INVALID_IMAGE_SIZE); - break; - } - // XXX: Implement missing checks once Clover supports more image types. - default: - throw error(CL_INVALID_IMAGE_SIZE); - } - } - - /// - /// Common error checking for a host pointer argument. - /// - void - validate_object(command_queue &q, const void *ptr, const vector_t &orig, - const vector_t &pitch, const vector_t ®ion) { - if (!ptr) - throw error(CL_INVALID_VALUE); - - // The region must fit within the specified pitch. - if (any_of(greater(), map(multiplies(), pitch, region), tail(pitch))) - throw error(CL_INVALID_VALUE); - } - - /// - /// Common argument checking for a copy between two buffer objects. - /// - void - validate_copy(command_queue &q, buffer &dst_mem, - const vector_t &dst_orig, const vector_t &dst_pitch, - buffer &src_mem, - const vector_t &src_orig, const vector_t &src_pitch, - const vector_t ®ion) { - if (dst_mem == src_mem) { - auto dst_offset = dot(dst_pitch, dst_orig); - auto src_offset = dot(src_pitch, src_orig); - - if (interval_overlaps()( - dst_offset, dst_offset + size(dst_pitch, region), - src_offset, src_offset + size(src_pitch, region))) - throw error(CL_MEM_COPY_OVERLAP); - } - } - - /// - /// Common argument checking for a copy between two image objects. - /// - void - validate_copy(command_queue &q, - image &dst_img, const vector_t &dst_orig, - image &src_img, const vector_t &src_orig, - const vector_t ®ion) { - if (dst_img.format() != src_img.format()) - throw error(CL_IMAGE_FORMAT_MISMATCH); - - if (dst_img == src_img) { - if (all_of(interval_overlaps(), - dst_orig, dst_orig + region, - src_orig, src_orig + region)) - throw error(CL_MEM_COPY_OVERLAP); - } - } - - /// - /// Checks that the host access flags of the memory object are - /// within the allowed set \a flags. - /// - void - validate_object_access(const memory_obj &mem, const cl_mem_flags flags) { - if (mem.flags() & ~flags & - (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | - CL_MEM_HOST_NO_ACCESS)) - throw error(CL_INVALID_OPERATION); - } - - /// - /// Checks that the mapping flags are correct. - /// - void - validate_map_flags(const memory_obj &mem, const cl_map_flags flags) { - if ((flags & (CL_MAP_WRITE | CL_MAP_READ)) && - (flags & CL_MAP_WRITE_INVALIDATE_REGION)) - throw error(CL_INVALID_VALUE); - - if (flags & CL_MAP_READ) - validate_object_access(mem, CL_MEM_HOST_READ_ONLY); - - if (flags & (CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION)) - validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY); - } - - /// - /// Checks that the memory migration flags are correct. - /// - void - validate_mem_migration_flags(const cl_mem_migration_flags flags) { - const cl_mem_migration_flags valid = - CL_MIGRATE_MEM_OBJECT_HOST | - CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED; - - if (flags & ~valid) - throw error(CL_INVALID_VALUE); - } - - /// - /// Class that encapsulates the task of mapping an object of type - /// \a T. The return value of get() should be implicitly - /// convertible to \a void *. - /// - template - struct _map; - - template<> - struct _map { - _map(command_queue &q, image *img, cl_map_flags flags, - vector_t offset, vector_t pitch, vector_t region) : - map(q, img->resource_in(q), flags, true, offset, region), - pitch(map.pitch()) - { } - - template - operator T *() const { - return static_cast(map); - } - - mapping map; - vector_t pitch; - }; - - template<> - struct _map { - _map(command_queue &q, buffer *mem, cl_map_flags flags, - vector_t offset, vector_t pitch, vector_t region) : - map(q, mem->resource_in(q), flags, true, - {{ dot(pitch, offset) }}, {{ size(pitch, region) }}), - pitch(pitch) - { } - - template - operator T *() const { - return static_cast(map); - } - - mapping map; - vector_t pitch; - }; - - template - struct _map

{ - _map(command_queue &q, P *ptr, cl_map_flags flags, - vector_t offset, vector_t pitch, vector_t region) : - ptr((P *)((char *)ptr + dot(pitch, offset))), pitch(pitch) - { } - - template - operator T *() const { - return static_cast(ptr); - } - - P *ptr; - vector_t pitch; - }; - - /// - /// Software copy from \a src_obj to \a dst_obj. They can be - /// either pointers or memory objects. - /// - template - std::function - soft_copy_op(command_queue &q, - T dst_obj, const vector_t &dst_orig, const vector_t &dst_pitch, - S src_obj, const vector_t &src_orig, const vector_t &src_pitch, - const vector_t ®ion) { - return [=, &q](event &) { - _map dst = { q, dst_obj, CL_MAP_WRITE, - dst_orig, dst_pitch, region }; - _map src = { q, src_obj, CL_MAP_READ, - src_orig, src_pitch, region }; - assert(src.pitch[0] == dst.pitch[0]); - vector_t v = {}; - - for (v[2] = 0; v[2] < region[2]; ++v[2]) { - for (v[1] = 0; v[1] < region[1]; ++v[1]) { - std::memcpy( - static_cast(dst) + dot(dst.pitch, v), - static_cast(src) + dot(src.pitch, v), - src.pitch[0] * region[0]); - } - } - }; - } - - /// - /// Hardware copy from \a src_obj to \a dst_obj. - /// - template - std::function - hard_copy_op(command_queue &q, T dst_obj, const vector_t &dst_orig, - S src_obj, const vector_t &src_orig, const vector_t ®ion) { - return [=, &q](event &) { - dst_obj->resource_in(q).copy(q, dst_orig, region, - src_obj->resource_in(q), src_orig); - }; - } -} - -CLOVER_API cl_int -clEnqueueReadBuffer(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - size_t offset, size_t size, void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t obj_origin = { offset }; - auto obj_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, ptr, {}, obj_pitch, region); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object_access(mem, CL_MEM_HOST_READ_ONLY); - - auto hev = create( - q, CL_COMMAND_READ_BUFFER, deps, - soft_copy_op(q, ptr, {}, obj_pitch, - &mem, obj_origin, obj_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWriteBuffer(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - size_t offset, size_t size, const void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t obj_origin = { offset }; - auto obj_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object(q, ptr, {}, obj_pitch, region); - validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY); - - auto hev = create( - q, CL_COMMAND_WRITE_BUFFER, deps, - soft_copy_op(q, &mem, obj_origin, obj_pitch, - ptr, {}, obj_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueReadBufferRect(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_obj_origin, - const size_t *p_host_origin, - const size_t *p_region, - size_t obj_row_pitch, size_t obj_slice_pitch, - size_t host_row_pitch, size_t host_slice_pitch, - void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto obj_origin = vector(p_obj_origin); - auto obj_pitch = pitch(region, {{ 1, obj_row_pitch, obj_slice_pitch }}); - auto host_origin = vector(p_host_origin); - auto host_pitch = pitch(region, {{ 1, host_row_pitch, host_slice_pitch }}); - - validate_common(q, deps); - validate_object(q, ptr, host_origin, host_pitch, region); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object_access(mem, CL_MEM_HOST_READ_ONLY); - - auto hev = create( - q, CL_COMMAND_READ_BUFFER_RECT, deps, - soft_copy_op(q, ptr, host_origin, host_pitch, - &mem, obj_origin, obj_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWriteBufferRect(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_obj_origin, - const size_t *p_host_origin, - const size_t *p_region, - size_t obj_row_pitch, size_t obj_slice_pitch, - size_t host_row_pitch, size_t host_slice_pitch, - const void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto obj_origin = vector(p_obj_origin); - auto obj_pitch = pitch(region, {{ 1, obj_row_pitch, obj_slice_pitch }}); - auto host_origin = vector(p_host_origin); - auto host_pitch = pitch(region, {{ 1, host_row_pitch, host_slice_pitch }}); - - validate_common(q, deps); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object(q, ptr, host_origin, host_pitch, region); - validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY); - - auto hev = create( - q, CL_COMMAND_WRITE_BUFFER_RECT, deps, - soft_copy_op(q, &mem, obj_origin, obj_pitch, - ptr, host_origin, host_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueFillBuffer(cl_command_queue d_queue, cl_mem d_mem, - const void *pattern, size_t pattern_size, - size_t offset, size_t size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_queue); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t origin = { offset }; - auto dst_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, mem, origin, dst_pitch, region); - - if (!pattern) - return CL_INVALID_VALUE; - - if (!util_is_power_of_two_nonzero_uintptr(pattern_size) || - pattern_size > 128 || size % pattern_size - || offset % pattern_size) { - return CL_INVALID_VALUE; - } - - auto sub = dynamic_cast(&mem); - if (sub && sub->offset() % q.device().mem_base_addr_align()) { - return CL_MISALIGNED_SUB_BUFFER_OFFSET; - } - - std::string data = std::string((char *)pattern, pattern_size); - auto hev = create( - q, CL_COMMAND_FILL_BUFFER, deps, - [=, &q, &mem](event &) { - mem.resource_in(q).clear(q, origin, region, data); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyBuffer(cl_command_queue d_q, cl_mem d_src_mem, cl_mem d_dst_mem, - size_t src_offset, size_t dst_offset, size_t size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_mem = obj(d_src_mem); - auto &dst_mem = obj(d_dst_mem); - auto deps = objs(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t dst_origin = { dst_offset }; - auto dst_pitch = pitch(region, {{ 1 }}); - vector_t src_origin = { src_offset }; - auto src_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, dst_mem, dst_origin, dst_pitch, region); - validate_object(q, src_mem, src_origin, src_pitch, region); - validate_copy(q, dst_mem, dst_origin, dst_pitch, - src_mem, src_origin, src_pitch, region); - - auto hev = create( - q, CL_COMMAND_COPY_BUFFER, deps, - hard_copy_op(q, &dst_mem, dst_origin, - &src_mem, src_origin, region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyBufferRect(cl_command_queue d_q, cl_mem d_src_mem, - cl_mem d_dst_mem, - const size_t *p_src_origin, const size_t *p_dst_origin, - const size_t *p_region, - size_t src_row_pitch, size_t src_slice_pitch, - size_t dst_row_pitch, size_t dst_slice_pitch, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_mem = obj(d_src_mem); - auto &dst_mem = obj(d_dst_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_dst_origin); - auto dst_pitch = pitch(region, {{ 1, dst_row_pitch, dst_slice_pitch }}); - auto src_origin = vector(p_src_origin); - auto src_pitch = pitch(region, {{ 1, src_row_pitch, src_slice_pitch }}); - - validate_common(q, deps); - validate_object(q, dst_mem, dst_origin, dst_pitch, region); - validate_object(q, src_mem, src_origin, src_pitch, region); - validate_copy(q, dst_mem, dst_origin, dst_pitch, - src_mem, src_origin, src_pitch, region); - - auto hev = create( - q, CL_COMMAND_COPY_BUFFER_RECT, deps, - soft_copy_op(q, &dst_mem, dst_origin, dst_pitch, - &src_mem, src_origin, src_pitch, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueReadImage(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_origin, const size_t *p_region, - size_t row_pitch, size_t slice_pitch, void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &img = obj(d_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto dst_pitch = pitch(region, {{ img.pixel_size(), - row_pitch, slice_pitch }}); - auto src_origin = vector(p_origin); - auto src_pitch = pitch(region, {{ img.pixel_size(), - img.row_pitch(), img.slice_pitch() }}); - - validate_common(q, deps); - validate_object(q, ptr, {}, dst_pitch, region); - validate_object(q, img, src_origin, region); - validate_object_access(img, CL_MEM_HOST_READ_ONLY); - - auto hev = create( - q, CL_COMMAND_READ_IMAGE, deps, - soft_copy_op(q, ptr, {}, dst_pitch, - &img, src_origin, src_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWriteImage(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_origin, const size_t *p_region, - size_t row_pitch, size_t slice_pitch, const void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &img = obj(d_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_origin); - auto dst_pitch = pitch(region, {{ img.pixel_size(), - img.row_pitch(), img.slice_pitch() }}); - auto src_pitch = pitch(region, {{ img.pixel_size(), - row_pitch, slice_pitch }}); - - validate_common(q, deps); - validate_object(q, img, dst_origin, region); - validate_object(q, ptr, {}, src_pitch, region); - validate_object_access(img, CL_MEM_HOST_WRITE_ONLY); - - auto hev = create( - q, CL_COMMAND_WRITE_IMAGE, deps, - soft_copy_op(q, &img, dst_origin, dst_pitch, - ptr, {}, src_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueFillImage(cl_command_queue d_queue, cl_mem d_mem, - const void *fill_color, - const size_t *p_origin, const size_t *p_region, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_queue); - auto &img = obj(d_mem); - auto deps = objs(d_deps, num_deps); - auto origin = vector(p_origin); - auto region = vector(p_region); - - validate_common(q, deps); - validate_object(q, img, origin, region); - - if (!fill_color) - return CL_INVALID_VALUE; - - std::string data = std::string((char *)fill_color, sizeof(cl_uint4)); - auto hev = create( - q, CL_COMMAND_FILL_IMAGE, deps, - [=, &q, &img](event &) { - img.resource_in(q).clear(q, origin, region, data); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyImage(cl_command_queue d_q, cl_mem d_src_mem, cl_mem d_dst_mem, - const size_t *p_src_origin, const size_t *p_dst_origin, - const size_t *p_region, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_img = obj(d_src_mem); - auto &dst_img = obj(d_dst_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_dst_origin); - auto src_origin = vector(p_src_origin); - - validate_common(q, deps); - validate_object(q, dst_img, dst_origin, region); - validate_object(q, src_img, src_origin, region); - validate_copy(q, dst_img, dst_origin, src_img, src_origin, region); - - auto hev = create( - q, CL_COMMAND_COPY_IMAGE, deps, - hard_copy_op(q, &dst_img, dst_origin, - &src_img, src_origin, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyImageToBuffer(cl_command_queue d_q, - cl_mem d_src_mem, cl_mem d_dst_mem, - const size_t *p_src_origin, const size_t *p_region, - size_t dst_offset, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_img = obj(d_src_mem); - auto &dst_mem = obj(d_dst_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - vector_t dst_origin = { dst_offset }; - auto dst_pitch = pitch(region, {{ src_img.pixel_size() }}); - auto src_origin = vector(p_src_origin); - auto src_pitch = pitch(region, {{ src_img.pixel_size(), - src_img.row_pitch(), - src_img.slice_pitch() }}); - - validate_common(q, deps); - validate_object(q, dst_mem, dst_origin, dst_pitch, region); - validate_object(q, src_img, src_origin, region); - - auto hev = create( - q, CL_COMMAND_COPY_IMAGE_TO_BUFFER, deps, - soft_copy_op(q, &dst_mem, dst_origin, dst_pitch, - &src_img, src_origin, src_pitch, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyBufferToImage(cl_command_queue d_q, - cl_mem d_src_mem, cl_mem d_dst_mem, - size_t src_offset, - const size_t *p_dst_origin, const size_t *p_region, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_mem = obj(d_src_mem); - auto &dst_img = obj(d_dst_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_dst_origin); - auto dst_pitch = pitch(region, {{ dst_img.pixel_size(), - dst_img.row_pitch(), - dst_img.slice_pitch() }}); - vector_t src_origin = { src_offset }; - auto src_pitch = pitch(region, {{ dst_img.pixel_size() }}); - - validate_common(q, deps); - validate_object(q, dst_img, dst_origin, region); - validate_object(q, src_mem, src_origin, src_pitch, region); - - auto hev = create( - q, CL_COMMAND_COPY_BUFFER_TO_IMAGE, deps, - soft_copy_op(q, &dst_img, dst_origin, dst_pitch, - &src_mem, src_origin, src_pitch, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API void * -clEnqueueMapBuffer(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - cl_map_flags flags, size_t offset, size_t size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev, cl_int *r_errcode) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t obj_origin = { offset }; - auto obj_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_map_flags(mem, flags); - - auto *map = mem.resource_in(q).add_map(q, flags, blocking, obj_origin, region); - - auto hev = create(q, CL_COMMAND_MAP_BUFFER, deps); - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - ret_error(r_errcode, CL_SUCCESS); - return *map; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API void * -clEnqueueMapImage(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - cl_map_flags flags, - const size_t *p_origin, const size_t *p_region, - size_t *row_pitch, size_t *slice_pitch, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev, cl_int *r_errcode) try { - auto &q = obj(d_q); - auto &img = obj(d_mem); - auto deps = objs(d_deps, num_deps); - auto region = vector(p_region); - auto origin = vector(p_origin); - - validate_common(q, deps); - validate_object(q, img, origin, region); - validate_map_flags(img, flags); - - if (!row_pitch) - throw error(CL_INVALID_VALUE); - - if ((img.slice_pitch() || img.array_size()) && !slice_pitch) - throw error(CL_INVALID_VALUE); - - auto *map = img.resource_in(q).add_map(q, flags, blocking, origin, region); - *row_pitch = map->pitch()[1]; - if (slice_pitch) - *slice_pitch = map->pitch()[2]; - - auto hev = create(q, CL_COMMAND_MAP_IMAGE, deps); - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - ret_error(r_errcode, CL_SUCCESS); - return *map; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clEnqueueUnmapMemObject(cl_command_queue d_q, cl_mem d_mem, void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs(d_deps, num_deps); - - validate_common(q, deps); - - auto hev = create( - q, CL_COMMAND_UNMAP_MEM_OBJECT, deps, - [=, &q, &mem](event &) { - mem.resource_in(q).del_map(ptr); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueMigrateMemObjects(cl_command_queue d_q, - cl_uint num_mems, - const cl_mem *d_mems, - cl_mem_migration_flags flags, - cl_uint num_deps, - const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto mems = objs(d_mems, num_mems); - auto deps = objs(d_deps, num_deps); - - validate_common(q, deps); - validate_mem_migration_flags(flags); - - if (any_of([&](const memory_obj &m) { - return m.context() != q.context(); - }, mems)) - throw error(CL_INVALID_CONTEXT); - - auto hev = create( - q, CL_COMMAND_MIGRATE_MEM_OBJECTS, deps, - [=, &q](event &) { - for (auto &mem: mems) { - if (flags & CL_MIGRATE_MEM_OBJECT_HOST) { - if ((flags & CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED)) - mem.resource_out(q); - - // For flags == CL_MIGRATE_MEM_OBJECT_HOST only to be - // efficient we would need cl*ReadBuffer* to implement - // reading from host memory. - - } else { - if (flags & CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED) - mem.resource_undef(q); - else - mem.resource_in(q); - } - } - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS;; - -} catch (error &e) { - return e.get(); -} - -static void CL_CALLBACK -free_queue(cl_command_queue d_q, cl_uint num_svm_pointers, - void *svm_pointers[], void *) { - clover::context &ctx = obj(d_q).context(); - for (void *p : range(svm_pointers, num_svm_pointers)) { - ctx.remove_svm_allocation(p); - free(p); - } -} - -cl_int -clover::EnqueueSVMFree(cl_command_queue d_q, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - - if (bool(num_svm_pointers) != bool(svm_pointers)) - return CL_INVALID_VALUE; - - auto &q = obj(d_q); - - if (!q.device().svm_support()) - return CL_INVALID_OPERATION; - - bool can_emulate = q.device().has_system_svm(); - auto deps = objs(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - std::vector svm_pointers_cpy(svm_pointers, - svm_pointers + num_svm_pointers); - if (!pfn_free_func) { - if (!can_emulate) { - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - } - pfn_free_func = free_queue; - } - - auto hev = create(q, cmd, deps, - [=](clover::event &) mutable { - pfn_free_func(d_q, num_svm_pointers, svm_pointers_cpy.data(), - user_data); - }); - - ret_object(event, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMFree(cl_command_queue d_q, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMFree(d_q, num_svm_pointers, svm_pointers, - pfn_free_func, user_data, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_FREE); -} - -cl_int -clover::EnqueueSVMMemcpy(cl_command_queue d_q, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - auto &q = obj(d_q); - - if (!q.device().svm_support()) - return CL_INVALID_OPERATION; - - if (dst_ptr == nullptr || src_ptr == nullptr) - return CL_INVALID_VALUE; - - if (static_cast(abs(reinterpret_cast(dst_ptr) - - reinterpret_cast(src_ptr))) < size) - return CL_MEM_COPY_OVERLAP; - - - bool can_emulate = q.device().has_system_svm(); - auto deps = objs(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create(q, cmd, deps, - [=](clover::event &) { - memcpy(dst_ptr, src_ptr, size); - }); - - if (blocking_copy) - hev().wait(); - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMMemcpy(cl_command_queue d_q, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemcpy(d_q, blocking_copy, dst_ptr, src_ptr, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMCPY); -} - -cl_int -clover::EnqueueSVMMemFill(cl_command_queue d_q, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - auto &q = obj(d_q); - - if (!q.device().svm_support()) - return CL_INVALID_OPERATION; - - if (svm_ptr == nullptr || pattern == nullptr || - !util_is_power_of_two_nonzero_uintptr(pattern_size) || - pattern_size > 128 || - !ptr_is_aligned(svm_ptr, pattern_size) || - size % pattern_size) - return CL_INVALID_VALUE; - - bool can_emulate = q.device().has_system_svm(); - auto deps = objs(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create(q, cmd, deps, - [=](clover::event &) { - void *ptr = svm_ptr; - for (size_t s = size; s; s -= pattern_size) { - memcpy(ptr, pattern, pattern_size); - ptr = static_cast(ptr) + pattern_size; - } - }); - - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMMemFill(cl_command_queue d_q, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemFill(d_q, svm_ptr, pattern, pattern_size, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMFILL); -} - -cl_int -clover::EnqueueSVMMap(cl_command_queue d_q, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - auto &q = obj(d_q); - - if (!q.device().svm_support()) - return CL_INVALID_OPERATION; - - if (svm_ptr == nullptr || size == 0) - return CL_INVALID_VALUE; - - bool can_emulate = q.device().has_system_svm(); - auto deps = objs(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create(q, cmd, deps, - [](clover::event &) { }); - - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMMap(cl_command_queue d_q, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMap(d_q, blocking_map, map_flags, svm_ptr, size, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_SVM_MAP); -} - -cl_int -clover::EnqueueSVMUnmap(cl_command_queue d_q, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - auto &q = obj(d_q); - - if (!q.device().svm_support()) - return CL_INVALID_OPERATION; - - if (svm_ptr == nullptr) - return CL_INVALID_VALUE; - - bool can_emulate = q.device().has_system_svm(); - auto deps = objs(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create(q, cmd, deps, - [](clover::event &) { }); - - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMUnmap(cl_command_queue d_q, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMUnmap(d_q, svm_ptr, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_UNMAP); -} - -CLOVER_API cl_int -clEnqueueSVMMigrateMem(cl_command_queue d_q, - cl_uint num_svm_pointers, - const void **svm_pointers, - const size_t *sizes, - const cl_mem_migration_flags flags, - cl_uint num_deps, - const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto deps = objs(d_deps, num_deps); - - validate_common(q, deps); - validate_mem_migration_flags(flags); - - if (!q.device().svm_support()) - return CL_INVALID_OPERATION; - - if (!num_svm_pointers || !svm_pointers) - return CL_INVALID_VALUE; - - std::vector sizes_copy(num_svm_pointers); - std::vector ptrs(num_svm_pointers); - - for (unsigned i = 0; i < num_svm_pointers; ++i) { - const void *ptr = svm_pointers[i]; - size_t size = sizes ? sizes[i] : 0; - if (!ptr) - return CL_INVALID_VALUE; - - auto p = q.context().find_svm_allocation(ptr); - if (!p.first) - return CL_INVALID_VALUE; - - std::ptrdiff_t pdiff = (uint8_t*)ptr - (uint8_t*)p.first; - if (size && size + pdiff > p.second) - return CL_INVALID_VALUE; - - sizes_copy[i] = size ? size : p.second; - ptrs[i] = size ? svm_pointers[i] : p.first; - } - - auto hev = create( - q, CL_COMMAND_MIGRATE_MEM_OBJECTS, deps, - [=, &q](event &) { - q.svm_migrate(ptrs, sizes_copy, flags); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/frontends/clover/api/util.hpp b/src/gallium/frontends/clover/api/util.hpp deleted file mode 100644 index 788c99adbd2..00000000000 --- a/src/gallium/frontends/clover/api/util.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_API_UTIL_HPP -#define CLOVER_API_UTIL_HPP - -#include -#include - -#include "core/error.hpp" -#include "core/property.hpp" -#include "util/algorithm.hpp" -#include "util/detect_os.h" - -#if DETECT_OS_WINDOWS -#define CLOVER_API -#define CLOVER_ICD_API -#elif HAVE_CLOVER_ICD -#define CLOVER_API -#define CLOVER_ICD_API PUBLIC -#else -#define CLOVER_API PUBLIC -#define CLOVER_ICD_API PUBLIC -#endif - -#define CLOVER_NOT_SUPPORTED_UNTIL(version) \ - do { \ - std::cerr << "CL user error: " << __func__ \ - << "() requires OpenCL version " << (version) \ - << " or greater." << std::endl; \ - } while (0) - -namespace clover { - /// - /// Return an error code in \a p if non-zero. - /// - inline void - ret_error(cl_int *p, const clover::error &e) { - if (p) - *p = e.get(); - } - - /// - /// Return a clover object in \a p if non-zero incrementing the - /// reference count of the object. - /// - template - void - ret_object(typename T::descriptor_type **p, - const intrusive_ref &v) { - if (p) { - v().retain(); - *p = desc(v()); - } - } - - /// - /// Return an API object from an intrusive reference to a Clover object, - /// incrementing the reference count of the object. - /// - template - typename T::descriptor_type * - ret_object(const intrusive_ref &v) { - v().retain(); - return desc(v()); - } -} - -#endif diff --git a/src/gallium/frontends/clover/core/binary.cpp b/src/gallium/frontends/clover/core/binary.cpp deleted file mode 100644 index 3bc3fe14bdb..00000000000 --- a/src/gallium/frontends/clover/core/binary.cpp +++ /dev/null @@ -1,243 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include -#include - -#include "core/binary.hpp" - -using namespace clover; - -namespace { - template - struct _serializer; - - /// Serialize the specified object. - template - void - _proc(std::ostream &os, const T &x) { - _serializer::proc(os, x); - } - - /// Deserialize the specified object. - template - void - _proc(std::istream &is, T &x) { - _serializer::proc(is, x); - } - - template - T - _proc(std::istream &is) { - T x; - _serializer::proc(is, x); - return x; - } - - /// Calculate the size of the specified object. - template - void - _proc(binary::size_t &sz, const T &x) { - _serializer::proc(sz, x); - } - - /// (De)serialize a scalar value. - template - struct _serializer::value>::type> { - static void - proc(std::ostream &os, const T &x) { - os.write(reinterpret_cast(&x), sizeof(x)); - } - - static void - proc(std::istream &is, T &x) { - is.read(reinterpret_cast(&x), sizeof(x)); - } - - static void - proc(binary::size_t &sz, const T &x) { - sz += sizeof(x); - } - }; - - /// (De)serialize a vector. - template - struct _serializer, - typename std::enable_if< - !std::is_scalar::value>::type> { - static void - proc(std::ostream &os, const std::vector &v) { - _proc(os, v.size()); - - for (size_t i = 0; i < v.size(); i++) - _proc(os, v[i]); - } - - static void - proc(std::istream &is, std::vector &v) { - v.resize(_proc(is)); - - for (size_t i = 0; i < v.size(); i++) - new(&v[i]) T(_proc(is)); - } - - static void - proc(binary::size_t &sz, const std::vector &v) { - sz += sizeof(uint32_t); - - for (size_t i = 0; i < v.size(); i++) - _proc(sz, v[i]); - } - }; - - template - struct _serializer, - typename std::enable_if< - std::is_scalar::value>::type> { - static void - proc(std::ostream &os, const std::vector &v) { - _proc(os, v.size()); - os.write(reinterpret_cast(&v[0]), - v.size() * sizeof(T)); - } - - static void - proc(std::istream &is, std::vector &v) { - v.resize(_proc(is)); - is.read(reinterpret_cast(&v[0]), - v.size() * sizeof(T)); - } - - static void - proc(binary::size_t &sz, const std::vector &v) { - sz += sizeof(uint32_t) + sizeof(T) * v.size(); - } - }; - - /// (De)serialize a string. - template<> - struct _serializer { - static void - proc(std::ostream &os, const std::string &s) { - _proc(os, s.size()); - os.write(&s[0], s.size() * sizeof(std::string::value_type)); - } - - static void - proc(std::istream &is, std::string &s) { - s.resize(_proc(is)); - is.read(&s[0], s.size() * sizeof(std::string::value_type)); - } - - static void - proc(binary::size_t &sz, const std::string &s) { - sz += sizeof(uint32_t) + sizeof(std::string::value_type) * s.size(); - } - }; - - /// (De)serialize a printf format - template<> - struct _serializer { - template - static void - proc(S & s, QT &x) { - _proc(s, x.arg_sizes); - _proc(s, x.strings); - } - }; - - /// (De)serialize a binary::section. - template<> - struct _serializer { - template - static void - proc(S &s, QT &x) { - _proc(s, x.id); - _proc(s, x.type); - _proc(s, x.size); - _proc(s, x.data); - } - }; - - /// (De)serialize a binary::argument. - template<> - struct _serializer { - template - static void - proc(S &s, QT &x) { - _proc(s, x.type); - _proc(s, x.size); - _proc(s, x.target_size); - _proc(s, x.target_align); - _proc(s, x.ext_type); - _proc(s, x.semantic); - } - }; - - /// (De)serialize a binary::symbol. - template<> - struct _serializer { - template - static void - proc(S &s, QT &x) { - _proc(s, x.name); - _proc(s, x.attributes); - _proc(s, x.reqd_work_group_size); - _proc(s, x.section); - _proc(s, x.offset); - _proc(s, x.args); - } - }; - - /// (De)serialize a binary. - template<> - struct _serializer { - template - static void - proc(S &s, QT &x) { - _proc(s, x.syms); - _proc(s, x.secs); - _proc(s, x.printf_infos); - _proc(s, x.printf_strings_in_buffer); - } - }; -}; - -namespace clover { - void - binary::serialize(std::ostream &os) const { - _proc(os, *this); - } - - binary - binary::deserialize(std::istream &is) { - return _proc(is); - } - - binary::size_t - binary::size() const { - size_t sz = 0; - _proc(sz, *this); - return sz; - } -} diff --git a/src/gallium/frontends/clover/core/binary.hpp b/src/gallium/frontends/clover/core/binary.hpp deleted file mode 100644 index a854453b550..00000000000 --- a/src/gallium/frontends/clover/core/binary.hpp +++ /dev/null @@ -1,169 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_BINARY_HPP -#define CLOVER_CORE_BINARY_HPP - -#include -#include - -#include "CL/cl.h" - -namespace clover { - struct binary { - typedef uint32_t resource_id; - typedef uint32_t size_t; - - struct section { - enum type { - text_intermediate, - text_library, - text_executable, - data_constant, - data_global, - data_local, - data_private - }; - - section(resource_id id, enum type type, size_t size, - const std::vector &data) : - id(id), type(type), size(size), data(data) { } - section() : id(0), type(text_intermediate), size(0), data() { } - - resource_id id; - type type; - size_t size; - std::vector data; - }; - - struct printf_info { - std::vector arg_sizes; - std::vector strings; - }; - - struct arg_info { - arg_info(const std::string &arg_name, const std::string &type_name, - const cl_kernel_arg_type_qualifier type_qualifier, - const cl_kernel_arg_address_qualifier address_qualifier, - const cl_kernel_arg_access_qualifier access_qualifier) : - arg_name(arg_name), type_name(type_name), - type_qualifier(type_qualifier), - address_qualifier(address_qualifier), - access_qualifier(access_qualifier) { }; - arg_info() : arg_name(""), type_name(""), type_qualifier(0), - address_qualifier(0), access_qualifier(0) { }; - - std::string arg_name; - std::string type_name; - cl_kernel_arg_type_qualifier type_qualifier; - cl_kernel_arg_address_qualifier address_qualifier; - cl_kernel_arg_access_qualifier access_qualifier; - }; - - struct argument { - enum type { - scalar, - constant, - global, - local, - image_rd, - image_wr, - sampler - }; - - enum ext_type { - zero_ext, - sign_ext - }; - - enum semantic { - general, - grid_dimension, - grid_offset, - image_size, - image_format, - constant_buffer, - printf_buffer - }; - - argument(enum type type, size_t size, - size_t target_size, size_t target_align, - enum ext_type ext_type, - enum semantic semantic = general) : - type(type), size(size), - target_size(target_size), target_align(target_align), - ext_type(ext_type), semantic(semantic) { } - - argument(enum type type, size_t size) : - type(type), size(size), - target_size(size), target_align(1), - ext_type(zero_ext), semantic(general) { } - - argument() : type(scalar), size(0), - target_size(0), target_align(1), - ext_type(zero_ext), semantic(general) { } - - type type; - size_t size; - size_t target_size; - size_t target_align; // For arguments of type local, this represents - // the alignment requirement for the pointed - // type and for the pointer itself. - ext_type ext_type; - semantic semantic; - arg_info info; - }; - - struct symbol { - symbol(const std::string &name, const std::string &attributes, - const std::vector<::size_t> &reqd_work_group_size, - resource_id section, size_t offset, - const std::vector &args) : - name(name), attributes(attributes), - reqd_work_group_size(reqd_work_group_size), - section(section), - offset(offset), args(args) { } - symbol() : name(), attributes(), reqd_work_group_size({0, 0, 0}), - section(0), offset(0), args() { } - - std::string name; - std::string attributes; - std::vector<::size_t> reqd_work_group_size; - resource_id section; - size_t offset; - std::vector args; - }; - - binary() : printf_strings_in_buffer(0) { } - void serialize(std::ostream &os) const; - static binary deserialize(std::istream &is); - size_t size() const; - - std::vector syms; - std::vector

secs; - std::vector printf_infos; - // printfs strings stored in output buffer - uint32_t printf_strings_in_buffer; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/compiler.hpp b/src/gallium/frontends/clover/core/compiler.hpp deleted file mode 100644 index c598a9ea879..00000000000 --- a/src/gallium/frontends/clover/core/compiler.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright 2019 Red Hat, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_COMPILER_HPP -#define CLOVER_CORE_COMPILER_HPP - -#include "core/device.hpp" -#include "core/binary.hpp" -#include "llvm/invocation.hpp" - -namespace clover { - namespace compiler { - static inline binary - compile_program(const program &prog, const header_map &headers, - const device &dev, const std::string &opts, - std::string &log) { - switch (dev.ir_format()) { - case PIPE_SHADER_IR_NATIVE: - if (prog.il_type() == program::il_type::source) - return llvm::compile_program(prog.source(), headers, dev, opts, log); - else - throw error(CL_INVALID_VALUE); - default: - unreachable("device with unsupported IR"); - throw error(CL_INVALID_VALUE); - } - } - - static inline binary - link_program(const std::vector &bs, const device &dev, - const std::string &opts, std::string &log) { - switch (dev.ir_format()) { - case PIPE_SHADER_IR_NATIVE: - return llvm::link_program(bs, dev, opts, log); - default: - unreachable("device with unsupported IR"); - throw error(CL_INVALID_VALUE); - } - } - } -} - -#endif diff --git a/src/gallium/frontends/clover/core/context.cpp b/src/gallium/frontends/clover/core/context.cpp deleted file mode 100644 index d81fbeca8b8..00000000000 --- a/src/gallium/frontends/clover/core/context.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/context.hpp" - -using namespace clover; - -context::context(const property_list &props, - const ref_vector &devs, - const notify_action ¬ify) : - notify(notify), props(props), devs(devs) { -} - -context::~context() { - while (_destroy_notify.size()) { - _destroy_notify.top()(); - _destroy_notify.pop(); - } -} - -bool -context::operator==(const context &ctx) const { - return this == &ctx; -} - -bool -context::operator!=(const context &ctx) const { - return this != &ctx; -} - -void -context::destroy_notify(std::function f) { - _destroy_notify.push(f); -} - -const context::property_list & -context::properties() const { - return props; -} - -context::device_range -context::devices() const { - return map(evals(), devs); -} - -void -context::add_svm_allocation(const void *ptr, size_t size) { - svm_ptrs.emplace(ptr, size); -} - -void -context::remove_svm_allocation(const void *ptr) { - svm_ptrs.erase(ptr); -} - -context::svm_pointer_map::value_type -context::find_svm_allocation(const void *ptr) const { - // std::prev on an iterator of an empty container causes SIGSEGVs - if (svm_ptrs.empty()) - return { nullptr, 0 }; - - auto it = std::prev(svm_ptrs.upper_bound(ptr)); - if (it == svm_ptrs.end()) - return { nullptr, 0 }; - - uintptr_t base = reinterpret_cast((*it).first); - uintptr_t end = (*it).second + base; - uintptr_t ptrv = reinterpret_cast(ptr); - if (ptrv >= base && ptrv < end) - return *it; - - return { nullptr, 0 }; -} diff --git a/src/gallium/frontends/clover/core/context.hpp b/src/gallium/frontends/clover/core/context.hpp deleted file mode 100644 index 2ecde235182..00000000000 --- a/src/gallium/frontends/clover/core/context.hpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_CONTEXT_HPP -#define CLOVER_CORE_CONTEXT_HPP - -#include -#include - -#include "core/object.hpp" -#include "core/device.hpp" -#include "core/property.hpp" - -namespace clover { - class context : public ref_counter, public _cl_context { - private: - typedef adaptor_range< - evals, const std::vector> & - > device_range; - typedef clover::property_list property_list; - - public: - ~context(); - - typedef std::function notify_action; - typedef std::map svm_pointer_map; - - context(const property_list &props, const ref_vector &devs, - const notify_action ¬ify); - - context(const context &ctx) = delete; - context & - operator=(const context &ctx) = delete; - - bool - operator==(const context &ctx) const; - bool - operator!=(const context &ctx) const; - - void destroy_notify(std::function f); - - const property_list & - properties() const; - - device_range - devices() const; - - void - add_svm_allocation(const void *ptr, size_t size); - - void - remove_svm_allocation(const void *ptr); - - svm_pointer_map::value_type - find_svm_allocation(const void *ptr) const; - - const notify_action notify; - - private: - property_list props; - const std::vector> devs; - std::stack> _destroy_notify; - svm_pointer_map svm_ptrs; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/device.cpp b/src/gallium/frontends/clover/core/device.cpp deleted file mode 100644 index 2de4c5268ee..00000000000 --- a/src/gallium/frontends/clover/core/device.cpp +++ /dev/null @@ -1,559 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include -#include "core/device.hpp" -#include "core/platform.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_state.h" -#include "util/bitscan.h" -#include "util/disk_cache.h" -#include "util/u_debug.h" -#include "nir.h" -#include - -using namespace clover; - -namespace { - cl_version - get_highest_supported_version(const device &dev) { - // All the checks below assume that the device supports FULL_PROFILE - // (which is the only profile support by clover) and that a device is - // not CUSTOM. - assert(dev.type() != CL_DEVICE_TYPE_CUSTOM); - - cl_version version = CL_MAKE_VERSION(0, 0, 0); - - const auto has_extension = - [extensions = dev.supported_extensions()](const char *extension_name){ - return std::find_if(extensions.begin(), extensions.end(), - [extension_name](const cl_name_version &extension){ - return strcmp(extension.name, extension_name) == 0; - }) != extensions.end(); - }; - const bool supports_images = dev.image_support(); - - // Check requirements for OpenCL 1.0 - if (dev.max_compute_units() < 1 || - dev.max_block_size().size() < 3 || - // TODO: Check CL_DEVICE_MAX_WORK_ITEM_SIZES - dev.max_threads_per_block() < 1 || - (dev.address_bits() != 32 && dev.address_bits() != 64) || - dev.max_mem_alloc_size() < std::max(dev.max_mem_global() / 4, - (cl_ulong)128 * 1024 * 1024) || - dev.max_mem_input() < 256 || - dev.max_const_buffer_size() < 64 * 1024 || - dev.max_const_buffers() < 8 || - dev.max_mem_local() < 16 * 1024 || - dev.clc_version < CL_MAKE_VERSION(1, 0, 0)) { - return version; - } - version = CL_MAKE_VERSION(1, 0, 0); - - // Check requirements for OpenCL 1.1 - if (!has_extension("cl_khr_byte_addressable_store") || - !has_extension("cl_khr_global_int32_base_atomics") || - !has_extension("cl_khr_global_int32_extended_atomics") || - !has_extension("cl_khr_local_int32_base_atomics") || - !has_extension("cl_khr_local_int32_extended_atomics") || - // OpenCL 1.1 increased the minimum value for - // CL_DEVICE_MAX_PARAMETER_SIZE to 1024 bytes. - dev.max_mem_input() < 1024 || - dev.mem_base_addr_align() < sizeof(cl_long16) || - // OpenCL 1.1 increased the minimum value for - // CL_DEVICE_LOCAL_MEM_SIZE to 32 KB. - dev.max_mem_local() < 32 * 1024 || - dev.clc_version < CL_MAKE_VERSION(1, 1, 0)) { - return version; - } - version = CL_MAKE_VERSION(1, 1, 0); - - // Check requirements for OpenCL 1.2 - if ((dev.has_doubles() && !has_extension("cl_khr_fp64")) || - dev.clc_version < CL_MAKE_VERSION(1, 2, 0) || - dev.max_printf_buffer_size() < 1 * 1024 * 1024 || - (supports_images && - (dev.max_image_buffer_size() < 65536 || - dev.max_image_array_number() < 2048))) { - return version; - } - version = CL_MAKE_VERSION(1, 2, 0); - - // Check requirements for OpenCL 3.0 - if (dev.max_mem_alloc_size() < std::max(std::min((cl_ulong)1024 * 1024 * 1024, - dev.max_mem_global() / 4), - (cl_ulong)128 * 1024 * 1024) || - // TODO: If pipes are supported, check: - // * CL_DEVICE_MAX_PIPE_ARGS - // * CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS - // * CL_DEVICE_PIPE_MAX_PACKET_SIZE - // TODO: If on-device queues are supported, check: - // * CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES - // * CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE - // * CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE - // * CL_DEVICE_MAX_ON_DEVICE_QUEUES - // * CL_DEVICE_MAX_ON_DEVICE_EVENTS - dev.clc_version < CL_MAKE_VERSION(3, 0, 0) || - (supports_images && - (dev.max_images_write() < 64 || - dev.max_image_size() < 16384))) { - return version; - } - version = CL_MAKE_VERSION(3, 0, 0); - - return version; - } - - static cl_device_type - parse_env_device_type() { - const char* val = getenv("CLOVER_DEVICE_TYPE"); - if (!val) { - return 0; - } - if (strcmp(val, "cpu") == 0) { - return CL_DEVICE_TYPE_CPU; - } - if (strcmp(val, "gpu") == 0) { - return CL_DEVICE_TYPE_GPU; - } - if (strcmp(val, "accelerator") == 0) { - return CL_DEVICE_TYPE_ACCELERATOR; - } - /* CL_DEVICE_TYPE_CUSTOM isn't implemented - because CL_DEVICE_TYPE_CUSTOM is OpenCL 1.2 - and Clover is OpenCL 1.1. */ - return 0; - } -} - -device::device(clover::platform &platform, pipe_loader_device *ldev) : - platform(platform), clc_cache(NULL), ldev(ldev) { - pipe = pipe_loader_create_screen(ldev, false); - if (pipe && pipe->caps.compute) { - const bool has_supported_ir = supports_ir(PIPE_SHADER_IR_NATIVE); - if (has_supported_ir) { - unsigned major = 1, minor = 1; - debug_get_version_option("CLOVER_DEVICE_CLC_VERSION_OVERRIDE", - &major, &minor); - clc_version = CL_MAKE_VERSION(major, minor, 0); - - version = get_highest_supported_version(*this); - major = CL_VERSION_MAJOR(version); - minor = CL_VERSION_MINOR(version); - debug_get_version_option("CLOVER_DEVICE_VERSION_OVERRIDE", &major, - &minor); - version = CL_MAKE_VERSION(major, minor, 0); - - } - - if (supports_ir(PIPE_SHADER_IR_NATIVE)) - return; - } - if (pipe) - pipe->destroy(pipe); - throw error(CL_INVALID_DEVICE); -} - -device::~device() { - if (clc_cache) - disk_cache_destroy(clc_cache); - if (pipe) - pipe->destroy(pipe); - if (ldev) - pipe_loader_release(&ldev, 1); -} - -bool -device::operator==(const device &dev) const { - return this == &dev; -} - -cl_device_type -device::type() const { - cl_device_type type = parse_env_device_type(); - if (type != 0) { - return type; - } - - switch (ldev->type) { - case PIPE_LOADER_DEVICE_SOFTWARE: - return CL_DEVICE_TYPE_CPU; - case PIPE_LOADER_DEVICE_PCI: - case PIPE_LOADER_DEVICE_PLATFORM: - return CL_DEVICE_TYPE_GPU; - default: - unreachable("Unknown device type."); - } -} - -cl_uint -device::vendor_id() const { - switch (ldev->type) { - case PIPE_LOADER_DEVICE_SOFTWARE: - case PIPE_LOADER_DEVICE_PLATFORM: - return 0; - case PIPE_LOADER_DEVICE_PCI: - return ldev->u.pci.vendor_id; - default: - unreachable("Unknown device type."); - } -} - -size_t -device::max_images_read() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].max_sampler_views; -} - -size_t -device::max_images_write() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].max_shader_images; -} - -size_t -device::max_image_buffer_size() const { - return pipe->caps.max_texel_buffer_elements; -} - -cl_uint -device::max_image_size() const { - return pipe->caps.max_texture_2d_size; -} - -cl_uint -device::max_image_size_3d() const { - return 1 << (pipe->caps.max_texture_3d_levels - 1); -} - -size_t -device::max_image_array_number() const { - return pipe->caps.max_texture_array_layers; -} - -cl_uint -device::max_samplers() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].max_texture_samplers; -} - -cl_ulong -device::max_mem_global() const { - return pipe->compute_caps.max_global_size; -} - -cl_ulong -device::max_mem_local() const { - return pipe->compute_caps.max_local_size; -} - -cl_ulong -device::max_mem_input() const { - return pipe->compute_caps.max_input_size; -} - -cl_ulong -device::max_const_buffer_size() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].max_const_buffer0_size; -} - -cl_uint -device::max_const_buffers() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].max_const_buffers; -} - -size_t -device::max_threads_per_block() const { - return pipe->compute_caps.max_threads_per_block_clover; -} - -cl_ulong -device::max_mem_alloc_size() const { - return pipe->compute_caps.max_mem_alloc_size; -} - -cl_uint -device::max_clock_frequency() const { - return pipe->compute_caps.max_clock_frequency; -} - -cl_uint -device::max_compute_units() const { - return pipe->compute_caps.max_compute_units; -} - -cl_uint -device::max_printf_buffer_size() const { - return 1024 * 1024; -} - -bool -device::image_support() const { - bool supports_images = pipe->compute_caps.images_supported; - if (!supports_images) - return false; - - /* If the gallium driver supports images, but does not support the - * minimum requirements for opencl 1.0 images, then don't claim to - * support images. - */ - if (max_images_read() < 128 || - max_images_write() < 8 || - max_image_size() < 8192 || - max_image_size_3d() < 2048 || - max_samplers() < 16) - return false; - - return true; -} - -bool -device::has_doubles() const { - nir_shader_compiler_options *options = - (nir_shader_compiler_options *)pipe->get_compiler_options(pipe, - PIPE_SHADER_IR_NIR, - PIPE_SHADER_COMPUTE); - return pipe->caps.doubles && - !(options->lower_doubles_options & nir_lower_fp64_full_software); -} - -bool -device::has_halves() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].fp16; -} - -bool -device::has_int64_atomics() const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].int64_atomics; -} - -bool -device::has_unified_memory() const { - return pipe->caps.uma; -} - -size_t -device::mem_base_addr_align() const { - uint64_t page_size = 0; - os_get_page_size(&page_size); - return std::max((size_t)page_size, sizeof(cl_long) * 16); -} - -cl_device_svm_capabilities -device::svm_support() const { - // Without CAP_RESOURCE_FROM_USER_MEMORY SVM and CL_MEM_USE_HOST_PTR - // interactions won't work according to spec as clover manages a GPU side - // copy of the host data. - // - // The biggest problem are memory buffers created with CL_MEM_USE_HOST_PTR, - // but the application and/or the kernel updates the memory via SVM and not - // the cl_mem buffer. - // We can't even do proper tracking on what memory might have been accessed - // as the host ptr to the buffer could be within a SVM region, where through - // the CL API there is no reliable way of knowing if a certain cl_mem buffer - // was accessed by a kernel or not and the runtime can't reliably know from - // which side the GPU buffer content needs to be updated. - // - // Another unsolvable scenario is a cl_mem object passed by cl_mem reference - // and SVM pointer into the same kernel at the same time. - if (allows_user_pointers() && pipe->caps.system_svm) - // we can emulate all lower levels if we support fine grain system - return CL_DEVICE_SVM_FINE_GRAIN_SYSTEM | - CL_DEVICE_SVM_COARSE_GRAIN_BUFFER | - CL_DEVICE_SVM_FINE_GRAIN_BUFFER; - return 0; -} - -bool -device::allows_user_pointers() const { - return pipe->caps.resource_from_user_memory || - pipe->caps.resource_from_user_memory_compute_only; -} - -std::vector -device::max_block_size() const { - auto v = pipe->compute_caps.max_block_size_clover; - return {v[0], v[1], v[2]}; -} - -cl_uint -device::subgroup_size() const { - cl_uint subgroup_sizes = pipe->compute_caps.subgroup_sizes; - if (!subgroup_sizes) - return 0; - return 1 << (util_last_bit(subgroup_sizes) - 1); -} - -cl_uint -device::address_bits() const { - return pipe->compute_caps.address_bits; -} - -std::string -device::device_name() const { - return pipe->get_name(pipe); -} - -std::string -device::vendor_name() const { - return pipe->get_device_vendor(pipe); -} - -enum pipe_shader_ir -device::ir_format() const { - assert(supports_ir(PIPE_SHADER_IR_NATIVE)); - return PIPE_SHADER_IR_NATIVE; -} - -std::string -device::ir_target() const { - return pipe->compute_caps.ir_target; -} - -enum pipe_endian -device::endianness() const { - return pipe->caps.endianness; -} - -std::string -device::device_version_as_string() const { - static const std::string version_string = - std::to_string(CL_VERSION_MAJOR(version)) + "." + - std::to_string(CL_VERSION_MINOR(version)); - return version_string; -} - -std::string -device::device_clc_version_as_string() const { - int major = CL_VERSION_MAJOR(clc_version); - int minor = CL_VERSION_MINOR(clc_version); - - /* for CL 3.0 we need this to be 1.2 until we support 2.0. */ - if (major == 3) { - major = 1; - minor = 2; - } - static const std::string version_string = - std::to_string(major) + "." + - std::to_string(minor); - return version_string; -} - -bool -device::supports_ir(enum pipe_shader_ir ir) const { - return pipe->shader_caps[PIPE_SHADER_COMPUTE].supported_irs & (1 << ir); -} - -std::vector -device::supported_extensions() const { - std::vector vec; - - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_byte_addressable_store" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_global_int32_base_atomics" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_global_int32_extended_atomics" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_local_int32_base_atomics" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_local_int32_extended_atomics" } ); - if (has_int64_atomics()) { - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_int64_base_atomics" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_int64_extended_atomics" } ); - } - if (has_doubles()) - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_fp64" } ); - if (has_halves()) - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_fp16" } ); - if (svm_support()) - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_arm_shared_virtual_memory" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_extended_versioning" } ); - return vec; -} - -std::string -device::supported_extensions_as_string() const { - static std::string extensions_string; - - if (!extensions_string.empty()) - return extensions_string; - - const auto extension_list = supported_extensions(); - for (const auto &extension : extension_list) { - if (!extensions_string.empty()) - extensions_string += " "; - extensions_string += extension.name; - } - return extensions_string; -} - -std::vector -device::supported_il_versions() const { - return {}; -} - -const void * -device::get_compiler_options(enum pipe_shader_ir ir) const { - return pipe->get_compiler_options(pipe, ir, PIPE_SHADER_COMPUTE); -} - -cl_version -device::device_version() const { - return version; -} - -cl_version -device::device_clc_version(bool api) const { - /* - * For the API we have to limit this to 1.2, - * but internally we want 3.0 if it works. - */ - if (!api) - return clc_version; - - int major = CL_VERSION_MAJOR(clc_version); - /* for CL 3.0 we need this to be 1.2 until we support 2.0. */ - if (major == 3) { - return CL_MAKE_VERSION(1, 2, 0); - } - return clc_version; -} - -std::vector -device::opencl_c_all_versions() const { - std::vector vec; - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "OpenCL C" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 1, 0), "OpenCL C" } ); - - if (CL_VERSION_MAJOR(clc_version) == 1 && - CL_VERSION_MINOR(clc_version) == 2) - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 2, 0), "OpenCL C" } ); - if (CL_VERSION_MAJOR(clc_version) == 3) { - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 2, 0), "OpenCL C" } ); - vec.push_back( cl_name_version{ CL_MAKE_VERSION(3, 0, 0), "OpenCL C" } ); - } - return vec; -} - -std::vector -device::opencl_c_features() const { - std::vector vec; - - vec.push_back( cl_name_version {CL_MAKE_VERSION(3, 0, 0), "__opencl_c_int64" }); - if (has_doubles()) - vec.push_back( cl_name_version {CL_MAKE_VERSION(3, 0, 0), "__opencl_c_fp64" }); - - return vec; -} diff --git a/src/gallium/frontends/clover/core/device.hpp b/src/gallium/frontends/clover/core/device.hpp deleted file mode 100644 index 4020ae96269..00000000000 --- a/src/gallium/frontends/clover/core/device.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_DEVICE_HPP -#define CLOVER_CORE_DEVICE_HPP - -#include -#include - -#include "core/object.hpp" -#include "core/format.hpp" -#include "core/binary.hpp" -#include "util/lazy.hpp" -#include "pipe-loader/pipe_loader.h" - -struct nir_shader; -struct disk_cache; - -namespace clover { - class platform; - class root_resource; - class hard_event; - - class device : public ref_counter, public _cl_device_id { - public: - device(clover::platform &platform, pipe_loader_device *ldev); - ~device(); - - device(const device &dev) = delete; - device & - operator=(const device &dev) = delete; - - bool - operator==(const device &dev) const; - - cl_device_type type() const; - cl_uint vendor_id() const; - size_t max_images_read() const; - size_t max_images_write() const; - size_t max_image_buffer_size() const; - // Use for 1D and 2D images. - cl_uint max_image_size() const; - // Use for 3D images. - cl_uint max_image_size_3d() const; - size_t max_image_array_number() const; - cl_uint max_samplers() const; - cl_ulong max_mem_global() const; - cl_ulong max_mem_local() const; - cl_ulong max_mem_input() const; - cl_ulong max_const_buffer_size() const; - cl_uint max_const_buffers() const; - size_t max_threads_per_block() const; - cl_ulong max_mem_alloc_size() const; - cl_uint max_clock_frequency() const; - cl_uint max_compute_units() const; - cl_uint max_printf_buffer_size() const; - bool image_support() const; - bool has_doubles() const; - bool has_halves() const; - bool has_int64_atomics() const; - bool has_unified_memory() const; - size_t mem_base_addr_align() const; - cl_device_svm_capabilities svm_support() const; - bool allows_user_pointers() const; - - std::vector max_block_size() const; - cl_uint subgroup_size() const; - cl_uint address_bits() const; - std::string device_name() const; - std::string vendor_name() const; - std::string device_version_as_string() const; - std::string device_clc_version_as_string() const; - enum pipe_shader_ir ir_format() const; - std::string ir_target() const; - enum pipe_endian endianness() const; - bool supports_ir(enum pipe_shader_ir ir) const; - std::string supported_extensions_as_string() const; - cl_version device_version() const; - cl_version device_clc_version(bool api = false) const; - std::vector opencl_c_all_versions() const; - std::vector supported_extensions() const; - std::vector supported_il_versions() const; - - std::vector opencl_c_features() const; - - friend class command_queue; - friend class root_resource; - friend class hard_event; - friend std::set - supported_formats(const context &, cl_mem_object_type, cl_mem_flags flags); - const void *get_compiler_options(enum pipe_shader_ir ir) const; - - clover::platform &platform; - - inline bool - has_system_svm() const { - return svm_support() & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM; - } - - lazy> clc_nir; - disk_cache *clc_cache; - cl_version version; - cl_version clc_version; - private: - pipe_screen *pipe; - pipe_loader_device *ldev; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/error.hpp b/src/gallium/frontends/clover/core/error.hpp deleted file mode 100644 index e46c05b865b..00000000000 --- a/src/gallium/frontends/clover/core/error.hpp +++ /dev/null @@ -1,207 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_ERROR_HPP -#define CLOVER_CORE_ERROR_HPP - -#include "CL/cl.h" -#if defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) - #undef vector - #undef pixel - #undef bool -#endif - -#include -#include - -namespace clover { - class command_queue; - class context; - class device; - class event; - class hard_event; - class soft_event; - class kernel; - class memory_obj; - class buffer; - class root_buffer; - class sub_buffer; - class image; - class image2d; - class image3d; - class platform; - class program; - class sampler; - - /// - /// Class that represents an error that can be converted to an - /// OpenCL status code. - /// - class error : public std::runtime_error { - public: - error(cl_int code, std::string what = "") : - std::runtime_error(what), code(code) { - } - - cl_int get() const { - return code; - } - - protected: - cl_int code; - }; - - class invalid_build_options_error : public error { - public: - invalid_build_options_error(const std::string &what = "") : - error(CL_INVALID_BUILD_OPTIONS, what) {} - }; - - class build_error : public error { - public: - build_error(const std::string &what = "") : - error(CL_BUILD_PROGRAM_FAILURE, what) {} - }; - - template - class invalid_object_error; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_COMMAND_QUEUE, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_CONTEXT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_DEVICE, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_EVENT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_EVENT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_KERNEL, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_PLATFORM, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_PROGRAM, what) {} - }; - - template<> - class invalid_object_error : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_SAMPLER, what) {} - }; - - class invalid_wait_list_error : public error { - public: - invalid_wait_list_error(std::string what = "") : - error(CL_INVALID_EVENT_WAIT_LIST, what) {} - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/event.cpp b/src/gallium/frontends/clover/core/event.cpp deleted file mode 100644 index e02a354251e..00000000000 --- a/src/gallium/frontends/clover/core/event.cpp +++ /dev/null @@ -1,272 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/event.hpp" -#include "pipe/p_screen.h" - -using namespace clover; - -event::event(clover::context &ctx, const ref_vector &deps, - action action_ok, action action_fail) : - context(ctx), _wait_count(1), _status(0), - action_ok(action_ok), action_fail(action_fail) { - for (auto &ev : deps) - ev.chain(*this); -} - -event::~event() { -} - -std::vector> -event::trigger_self() { - std::lock_guard lock(mutex); - std::vector> evs; - - if (_wait_count && !--_wait_count) - std::swap(_chain, evs); - - cv.notify_all(); - return evs; -} - -void -event::trigger() try { - if (wait_count() == 1) - action_ok(*this); - - for (event &ev : trigger_self()) - ev.trigger(); -} catch (error &e) { - abort(e.get()); -} - -std::vector> -event::abort_self(cl_int status) { - std::lock_guard lock(mutex); - std::vector> evs; - - _status = status; - _wait_count = 0; - std::swap(_chain, evs); - - cv.notify_all(); - return evs; -} - -void -event::abort(cl_int status) { - action_fail(*this); - - for (event &ev : abort_self(status)) - ev.abort(status); -} - -unsigned -event::wait_count() const { - std::lock_guard lock(mutex); - return _wait_count; -} - -bool -event::signalled() const { - return !wait_count(); -} - -cl_int -event::status() const { - std::lock_guard lock(mutex); - return _status; -} - -void -event::chain(event &ev) { - std::unique_lock lock(mutex, std::defer_lock); - std::unique_lock lock_ev(ev.mutex, std::defer_lock); - std::lock(lock, lock_ev); - - if (_wait_count) { - ev._wait_count++; - _chain.push_back(ev); - } - ev.deps.push_back(*this); -} - -void -event::wait_signalled() const { - std::unique_lock lock(mutex); - cv.wait(lock, [=]{ return !_wait_count; }); -} - -void -event::wait() const { - std::vector> evs; - std::swap(deps, evs); - - for (event &ev : evs) - ev.wait(); - - wait_signalled(); -} - -hard_event::hard_event(command_queue &q, cl_command_type command, - const ref_vector &deps, action action) : - event(q.context(), deps, profile(q, action), [](event &ev){}), - _queue(q), _command(command), _fence(NULL) { - if (q.profiling_enabled()) - _time_queued = timestamp::current(q); - - q.sequence(*this); - trigger(); -} - -hard_event::~hard_event() { - pipe_screen *screen = queue()->device().pipe; - screen->fence_reference(screen, &_fence, NULL); -} - -cl_int -hard_event::status() const { - pipe_screen *screen = queue()->device().pipe; - - if (event::status() < 0) - return event::status(); - - else if (!_fence) - return CL_QUEUED; - - else if (!screen->fence_finish(screen, NULL, _fence, 0)) - return CL_SUBMITTED; - - else - return CL_COMPLETE; -} - -command_queue * -hard_event::queue() const { - return &_queue(); -} - -cl_command_type -hard_event::command() const { - return _command; -} - -void -hard_event::wait() const { - pipe_screen *screen = queue()->device().pipe; - - event::wait(); - - if (status() == CL_QUEUED) - queue()->flush(); - - if (!_fence || - !screen->fence_finish(screen, NULL, _fence, OS_TIMEOUT_INFINITE)) - throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); -} - -const lazy & -hard_event::time_queued() const { - return _time_queued; -} - -const lazy & -hard_event::time_submit() const { - return _time_submit; -} - -const lazy & -hard_event::time_start() const { - return _time_start; -} - -const lazy & -hard_event::time_end() const { - return _time_end; -} - -void -hard_event::fence(pipe_fence_handle *fence) { - assert(fence); - pipe_screen *screen = queue()->device().pipe; - screen->fence_reference(screen, &_fence, fence); - deps.clear(); -} - -event::action -hard_event::profile(command_queue &q, const action &action) const { - if (q.profiling_enabled()) { - return [&q, action] (event &ev) { - auto &hev = static_cast(ev); - - hev._time_submit = timestamp::current(q); - hev._time_start = timestamp::query(q); - - action(ev); - - hev._time_end = timestamp::query(q); - }; - - } else { - return action; - } -} - -soft_event::soft_event(clover::context &ctx, const ref_vector &deps, - bool _trigger, action action) : - event(ctx, deps, action, action) { - if (_trigger) - trigger(); -} - -cl_int -soft_event::status() const { - if (event::status() < 0) - return event::status(); - - else if (!signalled() || - any_of([](const event &ev) { - return ev.status() != CL_COMPLETE; - }, deps)) - return CL_SUBMITTED; - - else - return CL_COMPLETE; -} - -command_queue * -soft_event::queue() const { - return NULL; -} - -cl_command_type -soft_event::command() const { - return CL_COMMAND_USER; -} - -void -soft_event::wait() const { - event::wait(); - - if (status() != CL_COMPLETE) - throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); -} diff --git a/src/gallium/frontends/clover/core/event.hpp b/src/gallium/frontends/clover/core/event.hpp deleted file mode 100644 index 5817893d0da..00000000000 --- a/src/gallium/frontends/clover/core/event.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_EVENT_HPP -#define CLOVER_CORE_EVENT_HPP - -#include -#include - -#include "core/object.hpp" -#include "core/queue.hpp" -#include "core/timestamp.hpp" -#include "util/lazy.hpp" - -namespace clover { - /// - /// Class that represents a task that might be executed - /// asynchronously at some point in the future. - /// - /// An event consists of a list of dependencies, a boolean - /// signalled() flag, and an associated task. An event is - /// considered signalled as soon as all its dependencies (if any) - /// are signalled as well, and the trigger() method is called; at - /// that point the associated task will be started through the - /// specified \a action_ok. If the abort() method is called - /// instead, the specified \a action_fail is executed and the - /// associated task will never be started. Dependent events will - /// be aborted recursively. - /// - /// The execution status of the associated task can be queried - /// using the status() method, and it can be waited for completion - /// using the wait() method. - /// - class event : public ref_counter, public _cl_event { - public: - typedef std::function action; - - event(clover::context &ctx, const ref_vector &deps, - action action_ok, action action_fail); - virtual ~event(); - - event(const event &ev) = delete; - event & - operator=(const event &ev) = delete; - - void trigger(); - void abort(cl_int status); - bool signalled() const; - - virtual cl_int status() const; - virtual command_queue *queue() const = 0; - virtual cl_command_type command() const = 0; - void wait_signalled() const; - virtual void wait() const; - - virtual struct pipe_fence_handle *fence() const { - return NULL; - } - - const intrusive_ref context; - - protected: - void chain(event &ev); - - mutable std::vector> deps; - - private: - std::vector> trigger_self(); - std::vector> abort_self(cl_int status); - unsigned wait_count() const; - - unsigned _wait_count; - cl_int _status; - action action_ok; - action action_fail; - std::vector> _chain; - mutable std::condition_variable cv; - mutable std::mutex mutex; - }; - - /// - /// Class that represents a task executed by a command queue. - /// - /// Similar to a normal clover::event. In addition it's associated - /// with a given command queue \a q and a given OpenCL \a command. - /// hard_event instances created for the same queue are implicitly - /// ordered with respect to each other, and they are implicitly - /// triggered on construction. - /// - /// A hard_event is considered complete when the associated - /// hardware task finishes execution. - /// - class hard_event : public event { - public: - hard_event(command_queue &q, cl_command_type command, - const ref_vector &deps, - action action = [](event &){}); - ~hard_event(); - - virtual cl_int status() const; - virtual command_queue *queue() const; - virtual cl_command_type command() const; - virtual void wait() const; - - const lazy &time_queued() const; - const lazy &time_submit() const; - const lazy &time_start() const; - const lazy &time_end() const; - - friend class command_queue; - - virtual struct pipe_fence_handle *fence() const { - return _fence; - } - - private: - virtual void fence(pipe_fence_handle *fence); - action profile(command_queue &q, const action &action) const; - - const intrusive_ref _queue; - cl_command_type _command; - pipe_fence_handle *_fence; - lazy _time_queued, _time_submit, _time_start, _time_end; - }; - - /// - /// Class that represents a software event. - /// - /// A soft_event is not associated with any specific hardware task - /// or command queue. It's considered complete as soon as all its - /// dependencies finish execution. - /// - class soft_event : public event { - public: - soft_event(clover::context &ctx, const ref_vector &deps, - bool trigger, action action = [](event &){}); - - virtual cl_int status() const; - virtual command_queue *queue() const; - virtual cl_command_type command() const; - virtual void wait() const; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/format.cpp b/src/gallium/frontends/clover/core/format.cpp deleted file mode 100644 index 6a0a2690cfe..00000000000 --- a/src/gallium/frontends/clover/core/format.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/format.hpp" -#include "core/memory.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -namespace clover { - // see table 16 and 17 in the 3.0 CL spec under "5.3.1.1. Image Format Descriptor" - // TODO optional channel orders: - // * CL_Rx - // * CL_RGx - // * CL_RGBx - // * CL_sRGBx - #define _FF(c, b, g) \ - { { CL_R, c }, PIPE_FORMAT_R##b##_##g }, \ - { { CL_A, c }, PIPE_FORMAT_A##b##_##g }, \ - { { CL_RG, c }, PIPE_FORMAT_R##b##G##b##_##g }, \ - { { CL_RA, c }, PIPE_FORMAT_R##b##A##b##_##g }, \ - { { CL_RGB, c }, PIPE_FORMAT_R##b##G##b##B##b##_##g }, \ - { { CL_RGBA, c }, PIPE_FORMAT_R##b##G##b##B##b##A##b##_##g } - // broken but also optional - //{ { CL_LUMINANCE, c }, PIPE_FORMAT_L##b##_##g }, - //{ { CL_INTENSITY, c }, PIPE_FORMAT_I##b##_##g }, - - #define _FI(c, b, g) \ - _FF(c##b, b, g) - - static const std::map formats { - //required in CL 2.0 but broken - //_FI(CL_SNORM_INT, 8, SNORM), - //_FI(CL_SNORM_INT, 16, SNORM), - _FI(CL_UNORM_INT, 8, UNORM), - _FI(CL_UNORM_INT, 16, UNORM), - _FI(CL_SIGNED_INT, 8, SINT), - _FI(CL_SIGNED_INT, 16, SINT), - _FI(CL_SIGNED_INT, 32, SINT), - _FI(CL_UNSIGNED_INT, 8, UINT), - _FI(CL_UNSIGNED_INT, 16, UINT), - _FI(CL_UNSIGNED_INT, 32, UINT), - _FF(CL_HALF_FLOAT, 16, FLOAT), - _FF(CL_FLOAT, 32, FLOAT), - - // TODO: next three can be CL_RGBx as well - { { CL_RGB, CL_UNORM_SHORT_565 }, PIPE_FORMAT_B5G6R5_UNORM }, - { { CL_RGB, CL_UNORM_SHORT_555 }, PIPE_FORMAT_B5G5R5A1_UNORM }, - { { CL_RGB, CL_UNORM_INT_101010 }, PIPE_FORMAT_B10G10R10X2_UNORM }, - - { { CL_RGBA, CL_UNORM_INT_101010_2 }, PIPE_FORMAT_B10G10R10A2_UNORM }, - - { { CL_ARGB, CL_UNORM_INT8 }, PIPE_FORMAT_A8R8G8B8_UNORM }, - { { CL_ARGB, CL_UNSIGNED_INT8 }, PIPE_FORMAT_A8R8G8B8_UINT }, - - { { CL_BGRA, CL_SNORM_INT8 }, PIPE_FORMAT_B8G8R8A8_SNORM }, - { { CL_BGRA, CL_UNORM_INT8 }, PIPE_FORMAT_B8G8R8A8_UNORM }, - { { CL_BGRA, CL_SIGNED_INT8 }, PIPE_FORMAT_B8G8R8A8_SINT }, - { { CL_BGRA, CL_UNSIGNED_INT8 }, PIPE_FORMAT_B8G8R8A8_UINT }, - - { { CL_ABGR, CL_SNORM_INT8 }, PIPE_FORMAT_A8B8G8R8_SNORM }, - { { CL_ABGR, CL_UNORM_INT8 }, PIPE_FORMAT_A8B8G8R8_UNORM }, - { { CL_ABGR, CL_SIGNED_INT8 }, PIPE_FORMAT_A8B8G8R8_SINT }, - { { CL_ABGR, CL_UNSIGNED_INT8 }, PIPE_FORMAT_A8B8G8R8_UINT }, - - // disable for now as it needs CL C 2.0 support - //{ { CL_DEPTH, CL_UNORM_INT16 }, PIPE_FORMAT_Z16_UNORM }, - //{ { CL_DEPTH, CL_FLOAT }, PIPE_FORMAT_Z32_FLOAT }, - - // required in CL 2.0 but broken - //{ { CL_sRGBA, CL_UNORM_INT8 }, PIPE_FORMAT_R8G8B8A8_SRGB }, - // optional but broken - //{ { CL_sRGB, CL_UNORM_INT8 }, PIPE_FORMAT_R8G8B8_SRGB }, - //{ { CL_sBGRA, CL_UNORM_INT8 }, PIPE_FORMAT_B8G8R8A8_SRGB }, - }; - #undef _FF - #undef _FI - - pipe_texture_target - translate_target(cl_mem_object_type type) { - switch (type) { - case CL_MEM_OBJECT_BUFFER: - case CL_MEM_OBJECT_IMAGE1D_BUFFER: - return PIPE_BUFFER; - case CL_MEM_OBJECT_IMAGE1D: - return PIPE_TEXTURE_1D; - case CL_MEM_OBJECT_IMAGE2D: - return PIPE_TEXTURE_2D; - case CL_MEM_OBJECT_IMAGE3D: - return PIPE_TEXTURE_3D; - case CL_MEM_OBJECT_IMAGE1D_ARRAY: - return PIPE_TEXTURE_1D_ARRAY; - case CL_MEM_OBJECT_IMAGE2D_ARRAY: - return PIPE_TEXTURE_2D_ARRAY; - default: - throw error(CL_INVALID_VALUE); - } - } - - pipe_format - translate_format(const cl_image_format &format) { - auto it = formats.find(format); - - if (it == formats.end()) - throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); - - return it->second; - } - - std::set - supported_formats(const context &ctx, cl_mem_object_type type, cl_mem_flags flags) { - std::set s; - pipe_texture_target target = translate_target(type); - unsigned bindings = 0; - - if (flags & (CL_MEM_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_KERNEL_READ_AND_WRITE)) - bindings |= PIPE_BIND_SAMPLER_VIEW; - if (flags & (CL_MEM_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_KERNEL_READ_AND_WRITE)) - bindings |= PIPE_BIND_SHADER_IMAGE; - - for (auto f : formats) { - if (all_of([=](const device &dev) { - return dev.pipe->is_format_supported( - dev.pipe, f.second, target, 1, 1, bindings); - }, ctx.devices())) - s.insert(f.first); - } - - return s; - } -} diff --git a/src/gallium/frontends/clover/core/format.hpp b/src/gallium/frontends/clover/core/format.hpp deleted file mode 100644 index f93f7a7381a..00000000000 --- a/src/gallium/frontends/clover/core/format.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_FORMAT_HPP -#define CLOVER_CORE_FORMAT_HPP - -#include - -#include "core/object.hpp" -#include "pipe/p_defines.h" -#include "util/format/u_formats.h" - -namespace clover { - pipe_texture_target translate_target(cl_mem_object_type type); - pipe_format translate_format(const cl_image_format &format); - - /// - /// Return all the image formats supported by a given context for - /// the given memory object type. - /// - std::set supported_formats(const context &ctx, - cl_mem_object_type type, - cl_mem_flags flags); -} - -static inline bool -operator<(const cl_image_format &a, const cl_image_format &b) { - return (a.image_channel_order != b.image_channel_order ? - a.image_channel_order < b.image_channel_order : - a.image_channel_data_type < b.image_channel_data_type); -} - -static inline bool -operator==(const cl_image_format &a, const cl_image_format &b) { - return (a.image_channel_order == b.image_channel_order && - a.image_channel_data_type == b.image_channel_data_type); -} - -static inline bool -operator!=(const cl_image_format &a, const cl_image_format &b) { - return !(a == b); -} - -#endif diff --git a/src/gallium/frontends/clover/core/kernel.cpp b/src/gallium/frontends/clover/core/kernel.cpp deleted file mode 100644 index 92dce0f8703..00000000000 --- a/src/gallium/frontends/clover/core/kernel.cpp +++ /dev/null @@ -1,675 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/kernel.hpp" -#include "core/resource.hpp" -#include "util/factor.hpp" -#include "util/u_math.h" -#include "pipe/p_context.h" - -using namespace clover; - -kernel::kernel(clover::program &prog, const std::string &name, - const std::vector &bargs) : - program(prog), _name(name), exec(*this), - program_ref(prog._kernel_ref_counter) { - for (auto &barg : bargs) { - if (barg.semantic == binary::argument::general) - _args.emplace_back(argument::create(barg)); - } - for (auto &dev : prog.devices()) { - auto &b = prog.build(dev).bin; - auto bsym = find(name_equals(name), b.syms); - const auto f = id_type_equals(bsym.section, binary::section::data_constant); - if (!any_of(f, b.secs)) - continue; - - auto mconst = find(f, b.secs); - auto rb = std::make_unique(prog.context(), std::vector(), - CL_MEM_COPY_HOST_PTR | CL_MEM_READ_ONLY, - mconst.size, mconst.data.data()); - _constant_buffers.emplace(&dev, std::move(rb)); - } -} - -template -static inline std::vector -pad_vector(command_queue &q, const V &v, uint x) { - std::vector w { v.begin(), v.end() }; - w.resize(q.device().max_block_size().size(), x); - return w; -} - -void -kernel::launch(command_queue &q, - const std::vector &grid_offset, - const std::vector &grid_size, - const std::vector &block_size) { - const auto b = program().build(q.device()).bin; - const auto reduced_grid_size = - map(divides(), grid_size, block_size); - - if (any_of(is_zero(), grid_size)) - return; - - void *st = exec.bind(&q, grid_offset); - struct pipe_grid_info info = {}; - - // The handles are created during exec_context::bind(), so we need make - // sure to call exec_context::bind() before retrieving them. - std::vector g_handles = map([&](size_t h) { - return (uint32_t *)&exec.input[h]; - }, exec.g_handles); - - q.pipe->bind_compute_state(q.pipe, st); - q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, - 0, exec.samplers.size(), - exec.samplers.data()); - - q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0, - exec.sviews.size(), 0, exec.sviews.data()); - q.pipe->set_shader_images(q.pipe, PIPE_SHADER_COMPUTE, 0, - exec.iviews.size(), 0, exec.iviews.data()); - q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(), - exec.resources.data()); - q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(), - exec.g_buffers.data(), g_handles.data()); - - // Fill information for the launch_grid() call. - info.work_dim = grid_size.size(); - copy(pad_vector(q, block_size, 1), info.block); - copy(pad_vector(q, reduced_grid_size, 1), info.grid); - info.pc = find(name_equals(_name), b.syms).offset; - info.input = exec.input.data(); - info.variable_shared_mem = exec.mem_local; - - q.pipe->launch_grid(q.pipe, &info); - - q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(), NULL, NULL); - q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(), NULL); - q.pipe->set_shader_images(q.pipe, PIPE_SHADER_COMPUTE, 0, - 0, exec.iviews.size(), NULL); - q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0, - 0, exec.sviews.size(), NULL); - q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, 0, - exec.samplers.size(), NULL); - - q.pipe->memory_barrier(q.pipe, PIPE_BARRIER_GLOBAL_BUFFER); - exec.unbind(); -} - -size_t -kernel::mem_local() const { - size_t sz = 0; - - for (auto &arg : args()) { - if (dynamic_cast(&arg)) - sz += arg.storage(); - } - - return sz; -} - -size_t -kernel::mem_private() const { - return 0; -} - -const std::string & -kernel::name() const { - return _name; -} - -std::vector -kernel::optimal_block_size(const command_queue &q, - const std::vector &grid_size) const { - if (any_of(is_zero(), grid_size)) - return grid_size; - - return factor::find_grid_optimal_factor( - q.device().max_threads_per_block(), q.device().max_block_size(), - grid_size); -} - -std::vector -kernel::required_block_size() const { - return find(name_equals(_name), program().symbols()).reqd_work_group_size; -} - -kernel::argument_range -kernel::args() { - return map(derefs(), _args); -} - -kernel::const_argument_range -kernel::args() const { - return map(derefs(), _args); -} - -std::vector -kernel::args_infos() { - std::vector infos; - for (auto &barg: find(name_equals(_name), program().symbols()).args) - if (barg.semantic == clover::binary::argument::general) - infos.emplace_back(barg.info); - - return infos; -} - -const binary & -kernel::binary(const command_queue &q) const { - return program().build(q.device()).bin; -} - -kernel::exec_context::exec_context(kernel &kern) : - kern(kern), q(NULL), print_handler(), mem_local(0), st(NULL), cs() { -} - -kernel::exec_context::~exec_context() { - if (st) - q->pipe->delete_compute_state(q->pipe, st); -} - -void * -kernel::exec_context::bind(intrusive_ptr _q, - const std::vector &grid_offset) { - std::swap(q, _q); - - // Bind kernel arguments. - auto &b = kern.program().build(q->device()).bin; - auto bsym = find(name_equals(kern.name()), b.syms); - auto bargs = bsym.args; - auto msec = find(id_type_equals(bsym.section, binary::section::text_executable), b.secs); - auto explicit_arg = kern._args.begin(); - - for (auto &barg : bargs) { - switch (barg.semantic) { - case binary::argument::general: - (*(explicit_arg++))->bind(*this, barg); - break; - - case binary::argument::grid_dimension: { - const cl_uint dimension = grid_offset.size(); - auto arg = argument::create(barg); - - arg->set(sizeof(dimension), &dimension); - arg->bind(*this, barg); - break; - } - case binary::argument::grid_offset: { - for (cl_uint x : pad_vector(*q, grid_offset, 0)) { - auto arg = argument::create(barg); - - arg->set(sizeof(x), &x); - arg->bind(*this, barg); - } - break; - } - case binary::argument::image_size: { - auto img = dynamic_cast(**(explicit_arg - 1)).get(); - std::vector image_size{ - static_cast(img->width()), - static_cast(img->height()), - static_cast(img->depth())}; - for (auto x : image_size) { - auto arg = argument::create(barg); - - arg->set(sizeof(x), &x); - arg->bind(*this, barg); - } - break; - } - case binary::argument::image_format: { - auto img = dynamic_cast(**(explicit_arg - 1)).get(); - cl_image_format fmt = img->format(); - std::vector image_format{ - static_cast(fmt.image_channel_data_type), - static_cast(fmt.image_channel_order)}; - for (auto x : image_format) { - auto arg = argument::create(barg); - - arg->set(sizeof(x), &x); - arg->bind(*this, barg); - } - break; - } - case binary::argument::constant_buffer: { - auto arg = argument::create(barg); - cl_mem buf = kern._constant_buffers.at(&q->device()).get(); - arg->set(sizeof(buf), &buf); - arg->bind(*this, barg); - break; - } - case binary::argument::printf_buffer: { - print_handler = printf_handler::create(q, b.printf_infos, - b.printf_strings_in_buffer, - q->device().max_printf_buffer_size()); - cl_mem print_mem = print_handler->get_mem(); - - auto arg = argument::create(barg); - arg->set(sizeof(cl_mem), &print_mem); - arg->bind(*this, barg); - break; - } - } - } - - // Create a new compute state if anything changed. - if (!st || q != _q || - cs.req_input_mem != input.size()) { - if (st) - _q->pipe->delete_compute_state(_q->pipe, st); - - cs.ir_type = q->device().ir_format(); - cs.prog = &(msec.data[0]); - // we only pass in NIRs or LLVMs and both IRs decode the size - cs.static_shared_mem = 0; - cs.req_input_mem = input.size(); - st = q->pipe->create_compute_state(q->pipe, &cs); - if (!st) { - unbind(); // Cleanup - throw error(CL_OUT_OF_RESOURCES); - } - } - - return st; -} - -void -kernel::exec_context::unbind() { - if (print_handler) - print_handler->print(); - - for (auto &arg : kern.args()) - arg.unbind(*this); - - input.clear(); - samplers.clear(); - sviews.clear(); - iviews.clear(); - resources.clear(); - g_buffers.clear(); - g_handles.clear(); - mem_local = 0; -} - -namespace { - template - std::vector - bytes(const T& x) { - return { (uint8_t *)&x, (uint8_t *)&x + sizeof(x) }; - } - - /// - /// Transform buffer \a v from the native byte order into the byte - /// order specified by \a e. - /// - template - void - byteswap(T &v, pipe_endian e) { - if (PIPE_ENDIAN_NATIVE != e) - std::reverse(v.begin(), v.end()); - } - - /// - /// Pad buffer \a v to the next multiple of \a n. - /// - template - void - align_vector(T &v, size_t n) { - v.resize(util_align_npot(v.size(), n)); - } - - bool - msb(const std::vector &s) { - if (PIPE_ENDIAN_NATIVE == PIPE_ENDIAN_LITTLE) - return s.back() & 0x80; - else - return s.front() & 0x80; - } - - /// - /// Resize buffer \a v to size \a n using sign or zero extension - /// according to \a ext. - /// - template - void - extend(T &v, enum binary::argument::ext_type ext, size_t n) { - const size_t m = std::min(v.size(), n); - const bool sign_ext = (ext == binary::argument::sign_ext); - const uint8_t fill = (sign_ext && msb(v) ? ~0 : 0); - T w(n, fill); - - if (PIPE_ENDIAN_NATIVE == PIPE_ENDIAN_LITTLE) - std::copy_n(v.begin(), m, w.begin()); - else - std::copy_n(v.end() - m, m, w.end() - m); - - std::swap(v, w); - } - - /// - /// Append buffer \a w to \a v. - /// - template - void - insert(T &v, const T &w) { - v.insert(v.end(), w.begin(), w.end()); - } - - /// - /// Append \a n elements to the end of buffer \a v. - /// - template - size_t - allocate(T &v, size_t n) { - size_t pos = v.size(); - v.resize(pos + n); - return pos; - } -} - -std::unique_ptr -kernel::argument::create(const binary::argument &barg) { - switch (barg.type) { - case binary::argument::scalar: - return std::unique_ptr(new scalar_argument(barg.size)); - - case binary::argument::global: - return std::unique_ptr(new global_argument); - - case binary::argument::local: - return std::unique_ptr(new local_argument); - - case binary::argument::constant: - return std::unique_ptr(new constant_argument); - - case binary::argument::image_rd: - return std::unique_ptr(new image_rd_argument); - - case binary::argument::image_wr: - return std::unique_ptr(new image_wr_argument); - - case binary::argument::sampler: - return std::unique_ptr(new sampler_argument); - - } - throw error(CL_INVALID_KERNEL_DEFINITION); -} - -kernel::argument::argument() : _set(false) { -} - -bool -kernel::argument::set() const { - return _set; -} - -size_t -kernel::argument::storage() const { - return 0; -} - -kernel::scalar_argument::scalar_argument(size_t size) : size(size) { -} - -void -kernel::scalar_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_ARG_VALUE); - - if (size != this->size) - throw error(CL_INVALID_ARG_SIZE); - - v = { (uint8_t *)value, (uint8_t *)value + size }; - _set = true; -} - -void -kernel::scalar_argument::bind(exec_context &ctx, - const binary::argument &barg) { - auto w = v; - - extend(w, barg.ext_type, barg.target_size); - byteswap(w, ctx.q->device().endianness()); - align_vector(ctx.input, barg.target_align); - insert(ctx.input, w); -} - -void -kernel::scalar_argument::unbind(exec_context &ctx) { -} - -kernel::global_argument::global_argument() : buf(nullptr), svm(nullptr) { -} - -void -kernel::global_argument::set(size_t size, const void *value) { - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - buf = pobj(value ? *(cl_mem *)value : NULL); - svm = nullptr; - _set = true; -} - -void -kernel::global_argument::set_svm(const void *value) { - svm = value; - buf = nullptr; - _set = true; -} - -void -kernel::global_argument::bind(exec_context &ctx, - const binary::argument &barg) { - align_vector(ctx.input, barg.target_align); - - if (buf) { - const resource &r = buf->resource_in(*ctx.q); - ctx.g_handles.push_back(ctx.input.size()); - ctx.g_buffers.push_back(r.pipe); - - // How to handle multi-demensional offsets? - // We don't need to. Buffer offsets are always - // one-dimensional. - auto v = bytes(r.offset[0]); - extend(v, barg.ext_type, barg.target_size); - byteswap(v, ctx.q->device().endianness()); - insert(ctx.input, v); - } else if (svm) { - auto v = bytes(svm); - extend(v, barg.ext_type, barg.target_size); - byteswap(v, ctx.q->device().endianness()); - insert(ctx.input, v); - } else { - // Null pointer. - allocate(ctx.input, barg.target_size); - } -} - -void -kernel::global_argument::unbind(exec_context &ctx) { -} - -size_t -kernel::local_argument::storage() const { - return _storage; -} - -void -kernel::local_argument::set(size_t size, const void *value) { - if (value) - throw error(CL_INVALID_ARG_VALUE); - - if (!size) - throw error(CL_INVALID_ARG_SIZE); - - _storage = size; - _set = true; -} - -void -kernel::local_argument::bind(exec_context &ctx, - const binary::argument &barg) { - ctx.mem_local = ::align(ctx.mem_local, barg.target_align); - auto v = bytes(ctx.mem_local); - - extend(v, binary::argument::zero_ext, barg.target_size); - byteswap(v, ctx.q->device().endianness()); - align_vector(ctx.input, ctx.q->device().address_bits() / 8); - insert(ctx.input, v); - - ctx.mem_local += _storage; -} - -void -kernel::local_argument::unbind(exec_context &ctx) { -} - -kernel::constant_argument::constant_argument() : buf(nullptr), st(nullptr) { -} - -void -kernel::constant_argument::set(size_t size, const void *value) { - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - buf = pobj(value ? *(cl_mem *)value : NULL); - _set = true; -} - -void -kernel::constant_argument::bind(exec_context &ctx, - const binary::argument &barg) { - align_vector(ctx.input, barg.target_align); - - if (buf) { - resource &r = buf->resource_in(*ctx.q); - auto v = bytes(ctx.resources.size() << 24 | r.offset[0]); - - extend(v, binary::argument::zero_ext, barg.target_size); - byteswap(v, ctx.q->device().endianness()); - insert(ctx.input, v); - - st = r.bind_surface(*ctx.q, false); - ctx.resources.push_back(st); - } else { - // Null pointer. - allocate(ctx.input, barg.target_size); - } -} - -void -kernel::constant_argument::unbind(exec_context &ctx) { - if (buf) - buf->resource_in(*ctx.q).unbind_surface(*ctx.q, st); -} - -kernel::image_rd_argument::image_rd_argument() : st(nullptr) { -} - -void -kernel::image_rd_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_ARG_VALUE); - - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - img = &obj(*(cl_mem *)value); - _set = true; -} - -void -kernel::image_rd_argument::bind(exec_context &ctx, - const binary::argument &barg) { - auto v = bytes(ctx.sviews.size()); - - extend(v, binary::argument::zero_ext, barg.target_size); - byteswap(v, ctx.q->device().endianness()); - align_vector(ctx.input, barg.target_align); - insert(ctx.input, v); - - st = img->resource_in(*ctx.q).bind_sampler_view(*ctx.q); - ctx.sviews.push_back(st); -} - -void -kernel::image_rd_argument::unbind(exec_context &ctx) { - img->resource_in(*ctx.q).unbind_sampler_view(*ctx.q, st); -} - -void -kernel::image_wr_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_ARG_VALUE); - - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - img = &obj(*(cl_mem *)value); - _set = true; -} - -void -kernel::image_wr_argument::bind(exec_context &ctx, - const binary::argument &barg) { - auto v = bytes(ctx.iviews.size()); - - extend(v, binary::argument::zero_ext, barg.target_size); - byteswap(v, ctx.q->device().endianness()); - align_vector(ctx.input, barg.target_align); - insert(ctx.input, v); - ctx.iviews.push_back(img->resource_in(*ctx.q).create_image_view(*ctx.q)); -} - -void -kernel::image_wr_argument::unbind(exec_context &ctx) { -} - -kernel::sampler_argument::sampler_argument() : s(nullptr), st(nullptr) { -} - -void -kernel::sampler_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_SAMPLER); - - if (size != sizeof(cl_sampler)) - throw error(CL_INVALID_ARG_SIZE); - - s = &obj(*(cl_sampler *)value); - _set = true; -} - -void -kernel::sampler_argument::bind(exec_context &ctx, - const binary::argument &barg) { - st = s->bind(*ctx.q); - ctx.samplers.push_back(st); -} - -void -kernel::sampler_argument::unbind(exec_context &ctx) { - s->unbind(*ctx.q, st); -} diff --git a/src/gallium/frontends/clover/core/kernel.hpp b/src/gallium/frontends/clover/core/kernel.hpp deleted file mode 100644 index 2b543ce6d3c..00000000000 --- a/src/gallium/frontends/clover/core/kernel.hpp +++ /dev/null @@ -1,262 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_KERNEL_HPP -#define CLOVER_CORE_KERNEL_HPP - -#include -#include - -#include "core/object.hpp" -#include "core/printf.hpp" -#include "core/program.hpp" -#include "core/memory.hpp" -#include "core/sampler.hpp" -#include "pipe/p_state.h" - -namespace clover { - class kernel : public ref_counter, public _cl_kernel { - private: - /// - /// Class containing all the state required to execute a compute - /// kernel. - /// - struct exec_context { - exec_context(kernel &kern); - ~exec_context(); - - exec_context(const exec_context &) = delete; - exec_context & - operator=(const exec_context &) = delete; - - void *bind(intrusive_ptr _q, - const std::vector &grid_offset); - void unbind(); - - kernel &kern; - intrusive_ptr q; - std::unique_ptr print_handler; - - std::vector input; - std::vector samplers; - std::vector sviews; - std::vector iviews; - std::vector resources; - std::vector g_buffers; - std::vector g_handles; - size_t mem_local; - - private: - void *st; - pipe_compute_state cs; - }; - - public: - class argument { - public: - static std::unique_ptr - create(const binary::argument &barg); - - argument(const argument &arg) = delete; - argument & - operator=(const argument &arg) = delete; - - /// \a true if the argument has been set. - bool set() const; - - /// Storage space required for the referenced object. - virtual size_t storage() const; - - /// Set this argument to some object. - virtual void set(size_t size, const void *value) = 0; - - /// Set this argument to an SVM pointer. - virtual void set_svm(const void *value) { - throw error(CL_INVALID_ARG_INDEX); - }; - - /// Allocate the necessary resources to bind the specified - /// object to this argument, and update \a ctx accordingly. - virtual void bind(exec_context &ctx, - const binary::argument &barg) = 0; - - /// Free any resources that were allocated in bind(). - virtual void unbind(exec_context &ctx) = 0; - - virtual ~argument() {}; - protected: - argument(); - - bool _set; - }; - - private: - typedef adaptor_range< - derefs, std::vector> & - > argument_range; - - typedef adaptor_range< - derefs, const std::vector> & - > const_argument_range; - - public: - kernel(clover::program &prog, const std::string &name, - const std::vector &bargs); - - kernel(const kernel &kern) = delete; - kernel & - operator=(const kernel &kern) = delete; - - void launch(command_queue &q, - const std::vector &grid_offset, - const std::vector &grid_size, - const std::vector &block_size); - - size_t mem_local() const; - size_t mem_private() const; - - const std::string &name() const; - - std::vector - optimal_block_size(const command_queue &q, - const std::vector &grid_size) const; - std::vector - required_block_size() const; - - argument_range args(); - const_argument_range args() const; - std::vector args_infos(); - - const intrusive_ref program; - - private: - const clover::binary &binary(const command_queue &q) const; - - class scalar_argument : public argument { - public: - scalar_argument(size_t size); - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - - private: - size_t size; - std::vector v; - }; - - class global_argument : public argument { - public: - global_argument(); - - virtual void set(size_t size, const void *value); - virtual void set_svm(const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - - private: - buffer *buf; - const void *svm; - }; - - class local_argument : public argument { - public: - virtual size_t storage() const; - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - - private: - size_t _storage = 0; - }; - - class constant_argument : public argument { - public: - constant_argument(); - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - - private: - buffer *buf; - pipe_surface *st; - }; - - class image_argument : public argument { - public: - const image *get() const { - return img; - } - protected: - image *img; - }; - - class image_rd_argument : public image_argument { - public: - image_rd_argument(); - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - - private: - pipe_sampler_view *st; - }; - - class image_wr_argument : public image_argument { - public: - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - }; - - class sampler_argument : public argument { - public: - sampler_argument(); - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const binary::argument &barg); - virtual void unbind(exec_context &ctx); - - private: - sampler *s; - void *st; - }; - - std::vector> _args; - std::map > _constant_buffers; - std::string _name; - exec_context exec; - const ref_holder program_ref; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/memory.cpp b/src/gallium/frontends/clover/core/memory.cpp deleted file mode 100644 index 6270107e94c..00000000000 --- a/src/gallium/frontends/clover/core/memory.cpp +++ /dev/null @@ -1,325 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/memory.hpp" -#include "core/resource.hpp" -#include "util/format/u_format.h" - -using namespace clover; - -memory_obj::memory_obj(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - size_t size, void *host_ptr) : - context(ctx), _properties(properties), _flags(flags), - _size(size), _host_ptr(host_ptr) { - if (flags & CL_MEM_COPY_HOST_PTR) - data.append((char *)host_ptr, size); -} - -memory_obj::~memory_obj() { - while (_destroy_notify.size()) { - _destroy_notify.top()(); - _destroy_notify.pop(); - } -} - -bool -memory_obj::operator==(const memory_obj &obj) const { - return this == &obj; -} - -void -memory_obj::destroy_notify(std::function f) { - _destroy_notify.push(f); -} - -std::vector -memory_obj::properties() const { - return _properties; -} - -cl_mem_flags -memory_obj::flags() const { - return _flags; -} - -size_t -memory_obj::size() const { - return _size; -} - -void * -memory_obj::host_ptr() const { - return _host_ptr; -} - -buffer::buffer(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - size_t size, void *host_ptr) : - memory_obj(ctx, properties, flags, size, host_ptr) { -} - -cl_mem_object_type -buffer::type() const { - return CL_MEM_OBJECT_BUFFER; -} - -root_buffer::root_buffer(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - size_t size, void *host_ptr) : - buffer(ctx, properties, flags, size, host_ptr) { -} - -resource & -root_buffer::resource_in(command_queue &q) { - const void *data_ptr = NULL; - if (flags() & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)) - data_ptr = !data.empty() ? data.data() : host_ptr(); - - return resource(q, data_ptr); -} - -resource & -root_buffer::resource_undef(command_queue &q) { - return resource(q, NULL); -} - -resource & -root_buffer::resource(command_queue &q, const void *data_ptr) { - std::lock_guard lock(resources_mtx); - // Create a new resource if there's none for this device yet. - if (!resources.count(&q.device())) { - auto r = (!resources.empty() ? - new root_resource(q.device(), *this, - *resources.begin()->second) : - new root_resource(q.device(), *this, q, data_ptr)); - - resources.insert(std::make_pair(&q.device(), - std::unique_ptr(r))); - data.clear(); - } - - return *resources.find(&q.device())->second; -} - -void -root_buffer::resource_out(command_queue &q) { - std::lock_guard lock(resources_mtx); - resources.erase(&q.device()); -} - -sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags, - size_t offset, size_t size) : - buffer(parent.context(), std::vector(), flags, size, - (char *)parent.host_ptr() + offset), - parent(parent), _offset(offset) { -} - -resource & -sub_buffer::resource_in(command_queue &q) { - std::lock_guard lock(resources_mtx); - // Create a new resource if there's none for this device yet. - if (!resources.count(&q.device())) { - auto r = new sub_resource(parent().resource_in(q), {{ offset() }}); - - resources.insert(std::make_pair(&q.device(), - std::unique_ptr(r))); - } - - return *resources.find(&q.device())->second; -} - -resource & -sub_buffer::resource_undef(command_queue &q) { - return resource_in(q); -} - -void -sub_buffer::resource_out(command_queue &q) { - std::lock_guard lock(resources_mtx); - resources.erase(&q.device()); -} - -size_t -sub_buffer::offset() const { - return _offset; -} - -image::image(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, size_t array_size, - size_t row_pitch, size_t slice_pitch, size_t size, - void *host_ptr, cl_mem buffer) : - memory_obj(ctx, properties, flags, size, host_ptr), - _format(*format), _width(width), _height(height), _depth(depth), - _row_pitch(row_pitch), _slice_pitch(slice_pitch), _array_size(array_size), - _buffer(buffer) { -} - -resource & -image::resource_in(command_queue &q) { - const void *data_ptr = !data.empty() ? data.data() : NULL; - return resource(q, data_ptr); -} - -resource & -image::resource_undef(command_queue &q) { - return resource(q, NULL); -} - -resource & -image::resource(command_queue &q, const void *data_ptr) { - std::lock_guard lock(resources_mtx); - // Create a new resource if there's none for this device yet. - if (!resources.count(&q.device())) { - auto r = (!resources.empty() ? - new root_resource(q.device(), *this, - *resources.begin()->second) : - new root_resource(q.device(), *this, q, data_ptr)); - - resources.insert(std::make_pair(&q.device(), - std::unique_ptr(r))); - data.clear(); - } - - return *resources.find(&q.device())->second; -} - -void -image::resource_out(command_queue &q) { - std::lock_guard lock(resources_mtx); - resources.erase(&q.device()); -} - -cl_image_format -image::format() const { - return _format; -} - -size_t -image::width() const { - return _width; -} - -size_t -image::height() const { - return _height; -} - -size_t -image::depth() const { - return _depth; -} - -size_t -image::pixel_size() const { - return util_format_get_blocksize(translate_format(_format)); -} - -size_t -image::row_pitch() const { - return _row_pitch; -} - -size_t -image::slice_pitch() const { - return _slice_pitch; -} - -size_t -image::array_size() const { - return _array_size; -} - -cl_mem -image::buffer() const { - return _buffer; -} - -image1d::image1d(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t row_pitch, - void *host_ptr) : - basic_image(ctx, properties, flags, format, width, 1, 1, 0, - row_pitch, 0, row_pitch, host_ptr, nullptr) { -} - -image1d_buffer::image1d_buffer(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t row_pitch, - void *host_ptr, cl_mem buffer) : - basic_image(ctx, properties, flags, format, width, 1, 1, 0, - row_pitch, 0, row_pitch, host_ptr, buffer) { -} - -image1d_array::image1d_array(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, - size_t array_size, size_t slice_pitch, - void *host_ptr) : - basic_image(ctx, properties, flags, format, width, 1, 1, array_size, - 0, slice_pitch, slice_pitch * array_size, host_ptr, nullptr) { -} - -image2d::image2d(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, size_t width, - size_t height, size_t row_pitch, - void *host_ptr) : - basic_image(ctx, properties, flags, format, width, height, 1, 0, - row_pitch, 0, height * row_pitch, host_ptr, nullptr) { -} - -image2d_array::image2d_array(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t array_size, - size_t row_pitch, size_t slice_pitch, - void *host_ptr) : - basic_image(ctx, properties, flags, format, width, height, 1, array_size, - row_pitch, slice_pitch, slice_pitch * array_size, host_ptr, nullptr) { -} - -image3d::image3d(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, - void *host_ptr) : - basic_image(ctx, properties, flags, format, width, height, depth, 0, - row_pitch, slice_pitch, depth * slice_pitch, - host_ptr, nullptr) { -} diff --git a/src/gallium/frontends/clover/core/memory.hpp b/src/gallium/frontends/clover/core/memory.hpp deleted file mode 100644 index d6a170bcfb9..00000000000 --- a/src/gallium/frontends/clover/core/memory.hpp +++ /dev/null @@ -1,256 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_MEMORY_HPP -#define CLOVER_CORE_MEMORY_HPP - -#include -#include -#include -#include - -#include "core/object.hpp" -#include "core/queue.hpp" -#include "core/resource.hpp" - -namespace clover { - class memory_obj : public ref_counter, public _cl_mem { - protected: - memory_obj(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - size_t size, void *host_ptr); - - memory_obj(const memory_obj &obj) = delete; - memory_obj & - operator=(const memory_obj &obj) = delete; - - public: - virtual ~memory_obj(); - - bool - operator==(const memory_obj &obj) const; - - virtual cl_mem_object_type type() const = 0; - virtual clover::resource & - resource_in(command_queue &q) = 0; - virtual clover::resource & - resource_undef(command_queue &q) = 0; - virtual void resource_out(command_queue &q) = 0; - - void destroy_notify(std::function f); - std::vector properties() const; - cl_mem_flags flags() const; - size_t size() const; - void *host_ptr() const; - - const intrusive_ref context; - - private: - std::vector _properties; - cl_mem_flags _flags; - size_t _size; - void *_host_ptr; - std::stack> _destroy_notify; - - protected: - std::string data; - }; - - class buffer : public memory_obj { - protected: - buffer(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - size_t size, void *host_ptr); - - public: - virtual cl_mem_object_type type() const; - }; - - class root_buffer : public buffer { - public: - root_buffer(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - size_t size, void *host_ptr); - - virtual clover::resource & - resource_in(command_queue &q); - virtual clover::resource & - resource_undef(command_queue &q); - virtual void - resource_out(command_queue &q); - - private: - clover::resource & - resource(command_queue &q, const void *data_ptr); - - std::map> resources; - std::mutex resources_mtx; - }; - - class sub_buffer : public buffer { - public: - sub_buffer(root_buffer &parent, cl_mem_flags flags, - size_t offset, size_t size); - - virtual clover::resource & - resource_in(command_queue &q); - virtual clover::resource & - resource_undef(command_queue &q); - virtual void - resource_out(command_queue &q); - size_t offset() const; - - const intrusive_ref parent; - - private: - size_t _offset; - std::map> resources; - std::mutex resources_mtx; - }; - - class image : public memory_obj { - protected: - image(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, size_t array_size, - size_t row_pitch, size_t slice_pitch, size_t size, - void *host_ptr, cl_mem buffer); - - public: - cl_image_format format() const; - virtual cl_uint dimensions() const = 0; - size_t width() const; - size_t height() const; - size_t depth() const; - size_t pixel_size() const; - size_t row_pitch() const; - size_t slice_pitch() const; - size_t array_size() const; - cl_mem buffer() const; - virtual clover::resource & - resource_in(command_queue &q); - virtual clover::resource & - resource_undef(command_queue &q); - virtual void - resource_out(command_queue &q); - - private: - clover::resource & - resource(command_queue &q, const void *data_ptr); - - cl_image_format _format; - size_t _width; - size_t _height; - size_t _depth; - size_t _row_pitch; - size_t _slice_pitch; - size_t _array_size; - cl_mem _buffer; - std::map> resources; - std::mutex resources_mtx; - }; - - template - class basic_image : public image { - public: - using image::image; - virtual cl_mem_object_type type() const { - return Type; - } - virtual cl_uint dimensions() const { - return Dim; - } - }; - - class image1d : public basic_image { - public: - image1d(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t row_pitch, - void *host_ptr); - }; - - class image1d_buffer : public basic_image { - public: - image1d_buffer(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t row_pitch, - void *host_ptr, cl_mem buffer); - }; - - class image1d_array : public basic_image { - public: - image1d_array(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, - size_t array_size, size_t slice_pitch, - void *host_ptr); - }; - - class image2d : public basic_image { - public: - image2d(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, size_t width, - size_t height, size_t row_pitch, - void *host_ptr); - }; - - class image2d_array : public basic_image { - public: - image2d_array(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t array_size, - size_t row_pitch, size_t slice_pitch, - void *host_ptr); - }; - - class image3d : public basic_image{ - public: - image3d(clover::context &ctx, - std::vector properties, - cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, - void *host_ptr); - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/object.hpp b/src/gallium/frontends/clover/core/object.hpp deleted file mode 100644 index 4f233425145..00000000000 --- a/src/gallium/frontends/clover/core/object.hpp +++ /dev/null @@ -1,239 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_OBJECT_HPP -#define CLOVER_CORE_OBJECT_HPP - -#include -#include -#include - -#include "CL/cl.h" - -#include "core/error.hpp" -#include "core/property.hpp" -#include "api/dispatch.hpp" -#include "util/macros.h" - -/// -/// Main namespace of the CL gallium frontend. -/// -namespace clover { - /// - /// Class that represents a CL API object. - /// - template - struct descriptor { - typedef T object_type; - typedef S descriptor_type; - - descriptor() : dispatch(&_dispatch) { - static_assert(std::is_standard_layout::value, - "ICD requires CL API objects to be standard layout."); - } - - const cl_icd_dispatch *dispatch; - }; - - struct default_tag; - struct allow_empty_tag; - struct wait_list_tag; - struct property_list_tag; - - namespace detail { - template - struct descriptor_traits { - typedef T object_type; - - static void - validate(D *d) { - auto o = static_cast(d); - if (!o || o->dispatch != &_dispatch || - !dynamic_cast(o)) - throw invalid_object_error(); - } - - static void - validate_list(D * const *ds, size_t n) { - if (!ds || !n) - throw error(CL_INVALID_VALUE); - } - }; - - template - struct descriptor_traits { - typedef typename D::object_type object_type; - - static void - validate(D *d) { - if (!d || d->dispatch != &_dispatch) - throw invalid_object_error(); - } - - static void - validate_list(D *const *ds, size_t n) { - if (!ds || !n) - throw error(CL_INVALID_VALUE); - } - }; - - template - struct descriptor_traits { - typedef typename D::object_type object_type; - - static void - validate(D *d) { - if (!d || d->dispatch != &_dispatch) - throw invalid_object_error(); - } - - static void - validate_list(D *const *ds, size_t n) { - if (bool(ds) != bool(n)) - throw error(CL_INVALID_VALUE); - } - }; - - template - struct descriptor_traits { - typedef typename D::object_type object_type; - - static void - validate(D *d) { - if (!d || d->dispatch != &_dispatch) - throw invalid_wait_list_error(); - } - - static void - validate_list(D *const *ds, size_t n) { - if (bool(ds) != bool(n)) - throw invalid_wait_list_error(); - } - }; - } - - /// - /// Get a Clover object from an API object performing object - /// validation. - /// - /// \a T can either be the Clover object type to return or a \a tag - /// object to select some special validation behavior by means of a - /// specialization of the detail::descriptor_traits template. The - /// default behavior is to infer the most general Clover object - /// type for the given API object. - /// - template - typename detail::descriptor_traits::object_type & - obj(D *d) { - detail::descriptor_traits::validate(d); - - return static_cast< - typename detail::descriptor_traits::object_type &>(*d); - } - - /// - /// Get a pointer to a Clover object from an API object performing - /// object validation. Returns \c NULL if its argument is \c NULL. - /// - /// \sa obj - /// - template - typename detail::descriptor_traits::object_type * - pobj(D *d) { - if (d) - detail::descriptor_traits::validate(d); - - return static_cast< - typename detail::descriptor_traits::object_type *>(d); - } - - /// - /// Get an API object from a Clover object. - /// - template - typename O::descriptor_type * - desc(O &o) { - return static_cast(&o); - } - - /// - /// Get an API object from a pointer to a Clover object. - /// - template - typename O::descriptor_type * - desc(O *o) { - return static_cast(o); - } - - /// - /// Get a range of Clover objects from a range of API objects - /// performing object validation. - /// - /// \sa obj - /// - template - ref_vector::object_type> - objs(D *const *ds, size_t n) { - detail::descriptor_traits::validate_list(ds, n); - return map(obj, range(ds, n)); - } - - /// - /// Get a range of API objects from a range of Clover objects. - /// - template - std::vector - descs(const Os &os) { - return map([](typename Os::value_type &o) { - return desc(o); - }, os); - } -} - -struct _cl_context : - public clover::descriptor {}; - -struct _cl_device_id : - public clover::descriptor {}; - -struct _cl_event : - public clover::descriptor {}; - -struct _cl_kernel : - public clover::descriptor {}; - -struct _cl_mem : - public clover::descriptor {}; - -struct _cl_platform_id : - public clover::descriptor {}; - -struct _cl_program : - public clover::descriptor {}; - -struct _cl_command_queue : - public clover::descriptor {}; - -struct _cl_sampler : - public clover::descriptor {}; - -#endif diff --git a/src/gallium/frontends/clover/core/platform.cpp b/src/gallium/frontends/clover/core/platform.cpp deleted file mode 100644 index 581d13a4bf4..00000000000 --- a/src/gallium/frontends/clover/core/platform.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/platform.hpp" -#include "util/u_debug.h" - -using namespace clover; - -platform::platform() : adaptor_range(evals(), devs) { - int n = pipe_loader_probe(NULL, 0, false); - std::vector ldevs(n); - - unsigned major = 1, minor = 1; - debug_get_version_option("CLOVER_PLATFORM_VERSION_OVERRIDE", &major, &minor); - version = CL_MAKE_VERSION(major, minor, 0); - - pipe_loader_probe(&ldevs.front(), n, false); - - for (pipe_loader_device *ldev : ldevs) { - try { - if (ldev) - devs.push_back(create(*this, ldev)); - } catch (error &) { - pipe_loader_release(&ldev, 1); - } - } -} - -std::vector -platform::supported_extensions() const { - std::vector vec; - - vec.push_back( cl_name_version{ CL_MAKE_VERSION(1, 0, 0), "cl_khr_icd" } ); - return vec; -} - -std::string -platform::supported_extensions_as_string() const { - static std::string extensions_string; - - if (!extensions_string.empty()) - return extensions_string; - - const auto extension_list = supported_extensions(); - for (const auto &extension : extension_list) { - if (!extensions_string.empty()) - extensions_string += " "; - extensions_string += extension.name; - } - return extensions_string; -} - -std::string -platform::platform_version_as_string() const { - static const std::string version_string = - std::to_string(CL_VERSION_MAJOR(version)) + "." + - std::to_string(CL_VERSION_MINOR(version)); - return version_string; -} - -cl_version -platform::platform_version() const { - return version; -} diff --git a/src/gallium/frontends/clover/core/platform.hpp b/src/gallium/frontends/clover/core/platform.hpp deleted file mode 100644 index 983d4e6aa99..00000000000 --- a/src/gallium/frontends/clover/core/platform.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PLATFORM_HPP -#define CLOVER_CORE_PLATFORM_HPP - -#include - -#include "core/object.hpp" -#include "core/device.hpp" -#include "util/range.hpp" - -namespace clover { - class platform : public _cl_platform_id, - public adaptor_range< - evals, std::vector> &> { - public: - platform(); - - platform(const platform &platform) = delete; - platform & - operator=(const platform &platform) = delete; - - std::string supported_extensions_as_string() const; - std::vector supported_extensions() const; - - std::string platform_version_as_string() const; - cl_version platform_version() const; - - protected: - cl_version version; - std::vector> devs; - }; - - platform &find_platform(cl_platform_id d_platform); -} - -#endif diff --git a/src/gallium/frontends/clover/core/printf.cpp b/src/gallium/frontends/clover/core/printf.cpp deleted file mode 100644 index 5a72fd729fe..00000000000 --- a/src/gallium/frontends/clover/core/printf.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// -// Copyright 2020 Serge Martin -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include -#include -#include -#include - -#include "util/u_math.h" -#include "core/printf.hpp" - -#include "util/u_printf.h" -using namespace clover; - -namespace { - - const cl_uint hdr_dwords = 2; - const cl_uint initial_buffer_offset = hdr_dwords * sizeof(cl_uint); - - /* all valid chars that can appear in CL C printf string. */ - const std::string clc_printf_whitelist = "%0123456789-+ #.AacdeEfFgGhilopsuvxX"; - - void - print_formatted(std::vector &formatters, - bool _strings_in_buffer, - const std::vector &buffer) { - - static std::atomic warn_count; - - if (buffer.empty() && !warn_count++) - std::cerr << "Printf used but no printf occurred - may cause performance issue." << std::endl; - - std::vector infos; - for (auto &f : formatters) { - u_printf_info info; - - info.num_args = f.arg_sizes.size(); - info.arg_sizes = f.arg_sizes.data(); - info.string_size = f.strings.size(); - info.strings = f.strings.data(); - - infos.push_back(info); - } - - u_printf(stdout, buffer.data(), buffer.size(), infos.data(), infos.size()); - } -} - -std::unique_ptr -printf_handler::create(const intrusive_ptr &q, - const std::vector &infos, - bool strings_in_buffer, - cl_uint size) { - return std::unique_ptr( - new printf_handler(q, infos, strings_in_buffer, size)); -} - -printf_handler::printf_handler(const intrusive_ptr &q, - const std::vector &infos, - bool strings_in_buffer, - cl_uint size) : - _q(q), _formatters(infos), _strings_in_buffer(strings_in_buffer), _size(size), _buffer() { - - if (_size) { - std::string data; - data.reserve(_size); - cl_uint header[2] = { 0 }; - - header[0] = initial_buffer_offset; - header[1] = _size; - - data.append((char *)header, (char *)(header+hdr_dwords)); - _buffer = std::unique_ptr(new root_buffer(_q->context, - std::vector(), - CL_MEM_COPY_HOST_PTR, - _size, (char*)data.data())); - } -} - -cl_mem -printf_handler::get_mem() { - return (cl_mem)(_buffer.get()); -} - -void -printf_handler::print() { - if (!_buffer) - return; - - mapping src = { *_q, _buffer->resource_in(*_q), CL_MAP_READ, true, - {{ 0 }}, {{ _size, 1, 1 }} }; - - cl_uint header[2] = { 0 }; - std::memcpy(header, - static_cast(src), - initial_buffer_offset); - - cl_uint buffer_size = header[0]; - buffer_size -= initial_buffer_offset; - std::vector buf; - buf.resize(buffer_size); - - std::memcpy(buf.data(), - static_cast(src) + initial_buffer_offset, - buffer_size); - - // mixed endian isn't going to work, sort it out if anyone cares later. - assert(_q->device().endianness() == PIPE_ENDIAN_NATIVE); - print_formatted(_formatters, _strings_in_buffer, buf); -} diff --git a/src/gallium/frontends/clover/core/printf.hpp b/src/gallium/frontends/clover/core/printf.hpp deleted file mode 100644 index 4d57a7150bd..00000000000 --- a/src/gallium/frontends/clover/core/printf.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright 2020 Serge Martin -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PRINTF_HANDLER_HPP -#define CLOVER_CORE_PRINTF_HANDLER_HPP - -#include - -#include "core/memory.hpp" - -namespace clover { - class printf_handler { - public: - static std::unique_ptr - create(const intrusive_ptr &q, - const std::vector &info, - bool strings_in_buffer, cl_uint size); - - printf_handler(const printf_handler &arg) = delete; - printf_handler & - operator=(const printf_handler &arg) = delete; - - ~printf_handler() {}; - - cl_mem get_mem(); - void print(); - - private: - printf_handler(const intrusive_ptr &q, - const std::vector &infos, - bool strings_in_buffer, cl_uint size); - - intrusive_ptr _q; - std::vector _formatters; - bool _strings_in_buffer; - cl_uint _size; - std::unique_ptr _buffer; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/program.cpp b/src/gallium/frontends/clover/core/program.cpp deleted file mode 100644 index 43609a25248..00000000000 --- a/src/gallium/frontends/clover/core/program.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/compiler.hpp" -#include "core/program.hpp" - -using namespace clover; - -program::program(clover::context &ctx, std::string &&source, - enum il_type il_type) : - context(ctx), _devices(ctx.devices()), _source(std::move(source)), - _kernel_ref_counter(0), _il_type(il_type) { -} - -program::program(clover::context &ctx, - const ref_vector &devs, - const std::vector &binaries) : - context(ctx), _devices(devs), _kernel_ref_counter(0), - _il_type(il_type::none) { - for_each([&](device &dev, const binary &bin) { - _builds[&dev] = { bin }; - }, - devs, binaries); -} - -void -program::compile(const ref_vector &devs, const std::string &opts, - const header_map &headers) { - if (_il_type != il_type::none) { - _devices = devs; - - for (auto &dev : devs) { - std::string log; - - try { - const binary b = - compiler::compile_program(*this, headers, dev, opts, log); - _builds[&dev] = { b, opts, log }; - } catch (...) { - _builds[&dev] = { binary(), opts, log }; - throw; - } - } - } -} - -void -program::link(const ref_vector &devs, const std::string &opts, - const ref_vector &progs) { - _devices = devs; - - for (auto &dev : devs) { - const std::vector bs = map([&](const program &prog) { - return prog.build(dev).bin; - }, progs); - std::string log = _builds[&dev].log; - - try { - const binary b = compiler::link_program(bs, dev, opts, log); - _builds[&dev] = { b, opts, log }; - } catch (...) { - _builds[&dev] = { binary(), opts, log }; - throw; - } - } -} - -enum program::il_type -program::il_type() const { - return _il_type; -} - -const std::string & -program::source() const { - return _source; -} - -program::device_range -program::devices() const { - return map(evals(), _devices); -} - -cl_build_status -program::build::status() const { - if (!bin.secs.empty()) - return CL_BUILD_SUCCESS; - else if (log.size()) - return CL_BUILD_ERROR; - else - return CL_BUILD_NONE; -} - -cl_program_binary_type -program::build::binary_type() const { - if (any_of(type_equals(binary::section::text_intermediate), bin.secs)) - return CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; - else if (any_of(type_equals(binary::section::text_library), bin.secs)) - return CL_PROGRAM_BINARY_TYPE_LIBRARY; - else if (any_of(type_equals(binary::section::text_executable), bin.secs)) - return CL_PROGRAM_BINARY_TYPE_EXECUTABLE; - else - return CL_PROGRAM_BINARY_TYPE_NONE; -} - -const struct program::build & -program::build(const device &dev) const { - static const struct build null; - return _builds.count(&dev) ? _builds.find(&dev)->second : null; -} - -const std::vector & -program::symbols() const { - if (_builds.empty()) - throw error(CL_INVALID_PROGRAM_EXECUTABLE); - - return _builds.begin()->second.bin.syms; -} - -unsigned -program::kernel_ref_count() const { - return _kernel_ref_counter.ref_count(); -} diff --git a/src/gallium/frontends/clover/core/program.hpp b/src/gallium/frontends/clover/core/program.hpp deleted file mode 100644 index 3969f4fd29d..00000000000 --- a/src/gallium/frontends/clover/core/program.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PROGRAM_HPP -#define CLOVER_CORE_PROGRAM_HPP - -#include - -#include "core/object.hpp" -#include "core/context.hpp" -#include "core/binary.hpp" - -namespace clover { - typedef std::vector> header_map; - - class program : public ref_counter, public _cl_program { - private: - typedef adaptor_range< - evals, const std::vector> &> device_range; - - public: - enum class il_type { none, source, spirv }; - - program(clover::context &ctx, - std::string &&il, - enum il_type il_type); - program(clover::context &ctx, - const ref_vector &devs = {}, - const std::vector &binaries = {}); - - program(const program &prog) = delete; - program & - operator=(const program &prog) = delete; - - void compile(const ref_vector &devs, const std::string &opts, - const header_map &headers = {}); - void link(const ref_vector &devs, const std::string &opts, - const ref_vector &progs); - - const std::string &source() const; - enum il_type il_type() const; - - device_range devices() const; - - struct build { - build(const binary &b = {}, const std::string &opts = {}, - const std::string &log = {}) : bin(b), opts(opts), log(log) {} - - cl_build_status status() const; - cl_program_binary_type binary_type() const; - - binary bin; - std::string opts; - std::string log; - }; - - const build &build(const device &dev) const; - - const std::vector &symbols() const; - - unsigned kernel_ref_count() const; - - const intrusive_ref context; - - friend class kernel; - - private: - std::vector> _devices; - std::map _builds; - std::string _source; - ref_counter _kernel_ref_counter; - enum il_type _il_type; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/property.hpp b/src/gallium/frontends/clover/core/property.hpp deleted file mode 100644 index 518f10dcaf9..00000000000 --- a/src/gallium/frontends/clover/core/property.hpp +++ /dev/null @@ -1,267 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PROPERTY_HPP -#define CLOVER_CORE_PROPERTY_HPP - -#include - -#include "util/range.hpp" -#include "util/algorithm.hpp" - -namespace clover { - class property_buffer; - - namespace detail { - template - class property_scalar { - public: - property_scalar(property_buffer &buf) : buf(buf) { - } - - inline property_scalar & - operator=(const T &x); - - private: - property_buffer &buf; - }; - - template - class property_vector { - public: - property_vector(property_buffer &buf) : buf(buf) { - } - - template - inline property_vector & - operator=(const S &v); - - private: - property_buffer &buf; - }; - - template - class property_matrix { - public: - property_matrix(property_buffer &buf) : buf(buf) { - } - - template - inline property_matrix & - operator=(const S &v); - - private: - property_buffer &buf; - }; - - class property_string { - public: - property_string(property_buffer &buf) : buf(buf) { - } - - inline property_string & - operator=(const std::string &v); - - private: - property_buffer &buf; - }; - }; - - /// - /// Return value buffer used by the CL property query functions. - /// - class property_buffer { - public: - property_buffer(void *r_buf, size_t size, size_t *r_size) : - r_buf(r_buf), size(size), r_size(r_size) { - } - - template - detail::property_scalar - as_scalar() { - return { *this }; - } - - template - detail::property_vector - as_vector() { - return { *this }; - } - - template - detail::property_matrix - as_matrix() { - return { *this }; - } - - detail::property_string - as_string() { - return { *this }; - } - - template - iterator_range - allocate(size_t n) { - if (r_buf && size < n * sizeof(T)) - throw error(CL_INVALID_VALUE); - - if (r_size) - *r_size = n * sizeof(T); - - if (r_buf) - return range((T *)r_buf, n); - else - return { }; - } - - private: - void *const r_buf; - const size_t size; - size_t *const r_size; - }; - - namespace detail { - template - inline property_scalar & - property_scalar::operator=(const T &x) { - auto r = buf.allocate(1); - - if (!r.empty()) - r.front() = x; - - return *this; - } - - template - template - inline property_vector & - property_vector::operator=(const S &v) { - auto r = buf.allocate(v.size()); - - if (!r.empty()) - copy(v, r.begin()); - - return *this; - } - - template - template - inline property_matrix & - property_matrix::operator=(const S &v) { - auto r = buf.allocate(v.size()); - - if (!r.empty()) - for_each([](typename S::value_type src, T *dst) { - if (dst) - copy(src, dst); - }, v, r); - - return *this; - } - - inline property_string & - property_string::operator=(const std::string &v) { - auto r = buf.allocate(v.size() + 1); - - if (!r.empty()) - copy(range(v.begin(), r.size()), r.begin()); - - return *this; - } - }; - - template - class property_element { - public: - property_element() : x() { - } - - property_element(T x) : x(x) { - } - - template - typename std::enable_if::value, S>::type - as() const { - static_assert(sizeof(S) <= sizeof(T), "Ensure type fits in property list"); - return reinterpret_cast(x); - } - - template - typename std::enable_if::value, S>::type - as() const { - return static_cast(x); - } - - private: - T x; - }; - - template - using property_list = std::map>; - - struct property_list_tag; - - /// - /// Create a clover::property_list object from a zero-terminated - /// CL property list. - /// - template::value>::type> - property_list - obj(const D *d_props) { - property_list props; - - while (d_props && *d_props) { - auto key = *d_props++; - auto value = *d_props++; - - if (props.count(key)) - throw error(CL_INVALID_PROPERTY); - - props.insert({ key, value }); - } - - return props; - } - - /// - /// Create a zero-terminated CL property list from a - /// clover::property_list object. - /// - template - std::vector - desc(const property_list &props) { - std::vector d_props; - - for (auto &prop : props) { - d_props.push_back(prop.first); - d_props.push_back(prop.second.template as()); - } - - d_props.push_back(0); - - return d_props; - } -} - -#endif diff --git a/src/gallium/frontends/clover/core/queue.cpp b/src/gallium/frontends/clover/core/queue.cpp deleted file mode 100644 index cd4caadb5f9..00000000000 --- a/src/gallium/frontends/clover/core/queue.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/queue.hpp" -#include "core/event.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_debug.h" - -using namespace clover; - -namespace { - void - debug_notify_callback(void *data, - unsigned *id, - enum util_debug_type type, - const char *fmt, - va_list args) { - const command_queue *queue = (const command_queue *)data; - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), fmt, args); - queue->context().notify(buffer); - } -} - -command_queue::command_queue(clover::context &ctx, clover::device &dev, - cl_command_queue_properties props) : - context(ctx), device(dev), _props(props) { - pipe = dev.pipe->context_create(dev.pipe, NULL, PIPE_CONTEXT_COMPUTE_ONLY); - if (!pipe) - throw error(CL_INVALID_DEVICE); - - if (ctx.notify) { - struct util_debug_callback cb; - memset(&cb, 0, sizeof(cb)); - cb.debug_message = &debug_notify_callback; - cb.data = this; - if (pipe->set_debug_callback) - pipe->set_debug_callback(pipe, &cb); - } -} -command_queue::command_queue(clover::context &ctx, clover::device &dev, - std::vector properties) : - context(ctx), device(dev), _properties(properties), _props(0) { - - for(std::vector::size_type i = 0; i != properties.size(); i += 2) { - if (properties[i] == 0) - break; - if (properties[i] == CL_QUEUE_PROPERTIES) - _props |= properties[i + 1]; - else if (properties[i] != CL_QUEUE_SIZE) - throw error(CL_INVALID_VALUE); - } - - pipe = dev.pipe->context_create(dev.pipe, NULL, PIPE_CONTEXT_COMPUTE_ONLY); - if (!pipe) - throw error(CL_INVALID_DEVICE); - - if (ctx.notify) { - struct util_debug_callback cb; - memset(&cb, 0, sizeof(cb)); - cb.debug_message = &debug_notify_callback; - cb.data = this; - if (pipe->set_debug_callback) - pipe->set_debug_callback(pipe, &cb); - } -} - -command_queue::~command_queue() { - pipe->destroy(pipe); -} - -void -command_queue::flush() { - std::lock_guard lock(queued_events_mutex); - flush_unlocked(); -} - -void -command_queue::flush_unlocked() { - pipe_screen *screen = device().pipe; - pipe_fence_handle *fence = NULL; - - if (!queued_events.empty()) { - pipe->flush(pipe, &fence, 0); - - while (!queued_events.empty() && - queued_events.front()().signalled()) { - queued_events.front()().fence(fence); - queued_events.pop_front(); - } - - screen->fence_reference(screen, &fence, NULL); - } -} - -void -command_queue::svm_migrate(const std::vector &svm_pointers, - const std::vector &sizes, - cl_mem_migration_flags flags) { - if (!pipe->svm_migrate) - return; - - bool to_device = !(flags & CL_MIGRATE_MEM_OBJECT_HOST); - bool mem_undefined = flags & CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED; - pipe->svm_migrate(pipe, svm_pointers.size(), svm_pointers.data(), - sizes.data(), to_device, mem_undefined); -} - -cl_command_queue_properties -command_queue::props() const { - return _props; -} - -std::vector -command_queue::properties() const { - return _properties; -} - -bool -command_queue::profiling_enabled() const { - return _props & CL_QUEUE_PROFILING_ENABLE; -} - -void -command_queue::sequence(hard_event &ev) { - std::lock_guard lock(queued_events_mutex); - if (!queued_events.empty()) - queued_events.back()().chain(ev); - - queued_events.push_back(ev); - - // Arbitrary threshold. - // The CTS tends to run a lot of subtests without flushing with the image - // tests, so flush regularly to prevent stack overflows. - if (queued_events.size() > 1000) - flush_unlocked(); -} diff --git a/src/gallium/frontends/clover/core/queue.hpp b/src/gallium/frontends/clover/core/queue.hpp deleted file mode 100644 index b132cd7ad0f..00000000000 --- a/src/gallium/frontends/clover/core/queue.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_QUEUE_HPP -#define CLOVER_CORE_QUEUE_HPP - -#include -#include - -#include "core/object.hpp" -#include "core/context.hpp" -#include "core/timestamp.hpp" -#include "pipe/p_context.h" - -namespace clover { - class resource; - class mapping; - class hard_event; - - class command_queue : public ref_counter, public _cl_command_queue { - public: - command_queue(clover::context &ctx, clover::device &dev, - std::vector properties); - command_queue(clover::context &ctx, clover::device &dev, - cl_command_queue_properties props); - ~command_queue(); - - command_queue(const command_queue &q) = delete; - command_queue & - operator=(const command_queue &q) = delete; - - void flush(); - void svm_migrate(const std::vector &svm_pointers, - const std::vector &sizes, cl_mem_migration_flags flags); - - cl_command_queue_properties props() const; - - std::vector properties() const; - bool profiling_enabled() const; - - const intrusive_ref context; - const intrusive_ref device; - - friend class resource; - friend class root_resource; - friend class mapping; - friend class hard_event; - friend class sampler; - friend class kernel; - friend class clover::timestamp::query; - friend class clover::timestamp::current; - - private: - /// Serialize a hardware event with respect to the previous ones, - /// and push it to the pending list. - void sequence(hard_event &ev); - // Use this instead of flush() if `queued_events_mutex` is acquired. - void flush_unlocked(); - - std::vector _properties; - cl_command_queue_properties _props; - pipe_context *pipe; - std::mutex queued_events_mutex; - std::deque> queued_events; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/resource.cpp b/src/gallium/frontends/clover/core/resource.cpp deleted file mode 100644 index 3bef96ed3ee..00000000000 --- a/src/gallium/frontends/clover/core/resource.cpp +++ /dev/null @@ -1,281 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/resource.hpp" -#include "core/memory.hpp" -#include "pipe/p_screen.h" -#include "util/u_sampler.h" -#include "util/format/u_format.h" -#include "util/u_inlines.h" -#include "util/u_resource.h" -#include "util/u_surface.h" - -using namespace clover; - -namespace { - class box { - public: - box(const resource::vector &origin, const resource::vector &size) { - u_box_3d(origin[0], origin[1], origin[2], size[0], size[1], size[2], &pipe); - } - - operator const pipe_box *() { - return &pipe; - } - - protected: - pipe_box pipe; - }; -} - -resource::resource(clover::device &dev, memory_obj &obj) : - device(dev), obj(obj), pipe(NULL), offset() { -} - -resource::~resource() { -} - -void -resource::copy(command_queue &q, const vector &origin, const vector ®ion, - resource &src_res, const vector &src_origin) { - auto p = offset + origin; - - q.pipe->resource_copy_region(q.pipe, pipe, 0, p[0], p[1], p[2], - src_res.pipe, 0, - box(src_res.offset + src_origin, region)); -} - -void -resource::clear(command_queue &q, const vector &origin, const vector ®ion, - const std::string &data) { - auto from = offset + origin; - - if (pipe->target == PIPE_BUFFER) { - q.pipe->clear_buffer(q.pipe, pipe, from[0], region[0], data.data(), data.size()); - } else { - std::string texture_data; - texture_data.reserve(util_format_get_blocksize(pipe->format)); - util_format_pack_rgba(pipe->format, &texture_data[0], data.data(), 1); - if (q.pipe->clear_texture) { - q.pipe->clear_texture(q.pipe, pipe, 0, box(from, region), texture_data.data()); - } else { - u_default_clear_texture(q.pipe, pipe, 0, box(from, region), texture_data.data()); - } - } -} - -mapping * -resource::add_map(command_queue &q, cl_map_flags flags, bool blocking, - const vector &origin, const vector ®ion) { - maps.emplace_back(q, *this, flags, blocking, origin, region); - return &maps.back(); -} - -void -resource::del_map(void *p) { - erase_if([&](const mapping &b) { - return static_cast(b) == p; - }, maps); -} - -unsigned -resource::map_count() const { - return maps.size(); -} - -pipe_sampler_view * -resource::bind_sampler_view(command_queue &q) { - pipe_sampler_view info; - - u_sampler_view_default_template(&info, pipe, pipe->format); - return q.pipe->create_sampler_view(q.pipe, pipe, &info); -} - -void -resource::unbind_sampler_view(command_queue &q, - pipe_sampler_view *st) { - q.pipe->sampler_view_release(q.pipe, st); -} - -pipe_image_view -resource::create_image_view(command_queue &q) { - pipe_image_view view; - view.resource = pipe; - view.format = pipe->format; - view.access = 0; - view.shader_access = PIPE_IMAGE_ACCESS_WRITE; - - if (pipe->target == PIPE_BUFFER) { - view.u.buf.offset = 0; - view.u.buf.size = obj.size(); - } else { - view.u.tex.first_layer = 0; - if (util_texture_is_array(pipe->target)) - view.u.tex.last_layer = pipe->array_size - 1; - else - view.u.tex.last_layer = 0; - view.u.tex.level = 0; - } - - return view; -} - -pipe_surface * -resource::bind_surface(command_queue &q, bool rw) { - pipe_surface info {}; - - info.format = pipe->format; - info.writable = rw; - - if (pipe->target == PIPE_BUFFER) - info.u.buf.last_element = pipe->width0 - 1; - - return q.pipe->create_surface(q.pipe, pipe, &info); -} - -void -resource::unbind_surface(command_queue &q, pipe_surface *st) { - q.pipe->surface_destroy(q.pipe, st); -} - -root_resource::root_resource(clover::device &dev, memory_obj &obj, - command_queue &q, const void *data_ptr) : - resource(dev, obj) { - pipe_resource info {}; - - if (image *img = dynamic_cast(&obj)) { - info.format = translate_format(img->format()); - info.width0 = img->width(); - info.height0 = img->height(); - info.depth0 = img->depth(); - info.array_size = MAX2(1, img->array_size()); - } else { - info.width0 = obj.size(); - info.height0 = 1; - info.depth0 = 1; - info.array_size = 1; - } - - info.target = translate_target(obj.type()); - info.bind = (PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_COMPUTE_RESOURCE | - PIPE_BIND_GLOBAL); - - if (obj.flags() & CL_MEM_USE_HOST_PTR && dev.allows_user_pointers()) { - // Page alignment is normally required for this, just try, hope for the - // best and fall back if it fails. - pipe = dev.pipe->resource_from_user_memory(dev.pipe, &info, obj.host_ptr()); - if (pipe) - return; - } - - if (obj.flags() & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_HOST_PTR)) { - info.usage = PIPE_USAGE_STAGING; - } - - pipe = dev.pipe->resource_create(dev.pipe, &info); - if (!pipe) - throw error(CL_OUT_OF_RESOURCES); - - if (data_ptr) { - box rect { {{ 0, 0, 0 }}, {{ info.width0, info.height0, info.depth0 }} }; - unsigned cpp = util_format_get_blocksize(info.format); - - if (pipe->target == PIPE_BUFFER) - q.pipe->buffer_subdata(q.pipe, pipe, PIPE_MAP_WRITE, - 0, info.width0, data_ptr); - else - q.pipe->texture_subdata(q.pipe, pipe, 0, PIPE_MAP_WRITE, - rect, data_ptr, cpp * info.width0, - cpp * info.width0 * info.height0); - } -} - -root_resource::root_resource(clover::device &dev, memory_obj &obj, - root_resource &r) : - resource(dev, obj) { - assert(0); // XXX -- resource shared among dev and r.dev -} - -root_resource::~root_resource() { - pipe_resource_reference(&this->pipe, NULL); -} - -sub_resource::sub_resource(resource &r, const vector &offset) : - resource(r.device(), r.obj) { - this->pipe = r.pipe; - this->offset = r.offset + offset; -} - -mapping::mapping(command_queue &q, resource &r, - cl_map_flags flags, bool blocking, - const resource::vector &origin, - const resource::vector ®ion) : - pctx(q.pipe), pres(NULL) { - unsigned usage = ((flags & CL_MAP_WRITE ? PIPE_MAP_WRITE : 0 ) | - (flags & CL_MAP_READ ? PIPE_MAP_READ : 0 ) | - (flags & CL_MAP_WRITE_INVALIDATE_REGION ? - PIPE_MAP_DISCARD_RANGE : 0) | - (!blocking ? PIPE_MAP_UNSYNCHRONIZED : 0)); - - p = pctx->buffer_map(pctx, r.pipe, 0, usage, - box(origin + r.offset, region), &pxfer); - if (!p) { - pxfer = NULL; - throw error(CL_OUT_OF_RESOURCES); - } - pipe_resource_reference(&pres, r.pipe); -} - -mapping::mapping(mapping &&m) : - pctx(m.pctx), pxfer(m.pxfer), pres(m.pres), p(m.p) { - m.pctx = NULL; - m.pxfer = NULL; - m.pres = NULL; - m.p = NULL; -} - -mapping::~mapping() { - if (pxfer) { - pctx->buffer_unmap(pctx, pxfer); - } - pipe_resource_reference(&pres, NULL); -} - -mapping & -mapping::operator=(mapping m) { - std::swap(pctx, m.pctx); - std::swap(pxfer, m.pxfer); - std::swap(pres, m.pres); - std::swap(p, m.p); - return *this; -} - -resource::vector -mapping::pitch() const -{ - return { - util_format_get_blocksize(pres->format), - pxfer->stride, - pxfer->layer_stride, - }; -} diff --git a/src/gallium/frontends/clover/core/resource.hpp b/src/gallium/frontends/clover/core/resource.hpp deleted file mode 100644 index facf31e13bd..00000000000 --- a/src/gallium/frontends/clover/core/resource.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_RESOURCE_HPP -#define CLOVER_CORE_RESOURCE_HPP - -#include - -#include "core/queue.hpp" -#include "util/algebra.hpp" -#include "pipe/p_state.h" - -namespace clover { - class memory_obj; - class mapping; - - /// - /// Class that represents a device-specific instance of some memory - /// object. - /// - class resource { - public: - typedef std::array vector; - - virtual ~resource(); - - resource(const resource &r) = delete; - resource & - operator=(const resource &r) = delete; - - void copy(command_queue &q, const vector &origin, const vector ®ion, - resource &src_resource, const vector &src_origin); - - void clear(command_queue &q, const vector &origin, const vector ®ion, - const std::string &data); - - mapping *add_map(command_queue &q, cl_map_flags flags, bool blocking, - const vector &origin, const vector ®ion); - void del_map(void *p); - unsigned map_count() const; - - const intrusive_ref device; - memory_obj &obj; - - friend class sub_resource; - friend class mapping; - friend class kernel; - - protected: - resource(clover::device &dev, memory_obj &obj); - - pipe_sampler_view *bind_sampler_view(command_queue &q); - void unbind_sampler_view(command_queue &q, - pipe_sampler_view *st); - - pipe_surface *bind_surface(command_queue &q, bool rw); - void unbind_surface(command_queue &q, pipe_surface *st); - - pipe_image_view create_image_view(command_queue &q); - - pipe_resource *pipe; - vector offset; - - private: - std::list maps; - }; - - /// - /// Resource associated with its own top-level data storage - /// allocated in some device. - /// - class root_resource : public resource { - public: - root_resource(clover::device &dev, memory_obj &obj, - command_queue &q, const void *data_ptr); - root_resource(clover::device &dev, memory_obj &obj, root_resource &r); - virtual ~root_resource(); - }; - - /// - /// Resource that reuses a portion of some other resource as data - /// storage. - /// - class sub_resource : public resource { - public: - sub_resource(resource &r, const vector &offset); - }; - - /// - /// Class that represents a mapping of some resource into the CPU - /// memory space. - /// - class mapping { - public: - mapping(command_queue &q, resource &r, cl_map_flags flags, - bool blocking, const resource::vector &origin, - const resource::vector ®ion); - mapping(mapping &&m); - ~mapping(); - - mapping & - operator=(mapping m); - - mapping(const mapping &m) = delete; - - template - operator T *() const { - return (T *)p; - } - - resource::vector pitch() const; - - private: - pipe_context *pctx; - pipe_transfer *pxfer; - pipe_resource *pres; - void *p; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/sampler.cpp b/src/gallium/frontends/clover/core/sampler.cpp deleted file mode 100644 index 3a0dd4dc7c3..00000000000 --- a/src/gallium/frontends/clover/core/sampler.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/sampler.hpp" -#include "pipe/p_state.h" - -using namespace clover; - -sampler::sampler(clover::context &ctx, bool norm_mode, - cl_addressing_mode addr_mode, - cl_filter_mode filter_mode) : - context(ctx), _norm_mode(norm_mode), - _addr_mode(addr_mode), _filter_mode(filter_mode) { -} - -bool -sampler::norm_mode() { - return _norm_mode; -} - -cl_addressing_mode -sampler::addr_mode() { - return _addr_mode; -} - -cl_filter_mode -sampler::filter_mode() { - return _filter_mode; -} - -void * -sampler::bind(command_queue &q) { - struct pipe_sampler_state info {}; - - info.unnormalized_coords = !norm_mode(); - - info.wrap_s = info.wrap_t = info.wrap_r = - (addr_mode() == CL_ADDRESS_CLAMP_TO_EDGE ? PIPE_TEX_WRAP_CLAMP_TO_EDGE : - addr_mode() == CL_ADDRESS_CLAMP ? PIPE_TEX_WRAP_CLAMP_TO_BORDER : - addr_mode() == CL_ADDRESS_REPEAT ? PIPE_TEX_WRAP_REPEAT : - addr_mode() == CL_ADDRESS_MIRRORED_REPEAT ? PIPE_TEX_WRAP_MIRROR_REPEAT : - PIPE_TEX_WRAP_CLAMP_TO_EDGE); - - info.min_img_filter = info.mag_img_filter = - (filter_mode() == CL_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : - PIPE_TEX_FILTER_NEAREST); - - return q.pipe->create_sampler_state(q.pipe, &info); -} - -void -sampler::unbind(command_queue &q, void *st) { - q.pipe->delete_sampler_state(q.pipe, st); -} diff --git a/src/gallium/frontends/clover/core/sampler.hpp b/src/gallium/frontends/clover/core/sampler.hpp deleted file mode 100644 index 2632c3067fa..00000000000 --- a/src/gallium/frontends/clover/core/sampler.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_SAMPLER_HPP -#define CLOVER_CORE_SAMPLER_HPP - -#include "core/object.hpp" -#include "core/queue.hpp" - -namespace clover { - class sampler : public ref_counter, public _cl_sampler { - public: - sampler(clover::context &ctx, bool norm_mode, - cl_addressing_mode addr_mode, - cl_filter_mode filter_mode); - - sampler(const sampler &s) = delete; - sampler & - operator=(const sampler &s) = delete; - - bool norm_mode(); - cl_addressing_mode addr_mode(); - cl_filter_mode filter_mode(); - - const intrusive_ref context; - - friend class kernel; - - private: - void *bind(command_queue &q); - void unbind(command_queue &q, void *st); - - bool _norm_mode; - cl_addressing_mode _addr_mode; - cl_filter_mode _filter_mode; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/core/timestamp.cpp b/src/gallium/frontends/clover/core/timestamp.cpp deleted file mode 100644 index 3fd341f30da..00000000000 --- a/src/gallium/frontends/clover/core/timestamp.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/timestamp.hpp" -#include "core/queue.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -using namespace clover; - -timestamp::query::query(command_queue &q) : - q(q), - _query(q.pipe->create_query(q.pipe, PIPE_QUERY_TIMESTAMP, 0)) { - q.pipe->end_query(q.pipe, _query); -} - -timestamp::query::query(query &&other) : - q(other.q), - _query(other._query) { - other._query = NULL; -} - -timestamp::query::~query() { - if (_query) - q().pipe->destroy_query(q().pipe, _query); -} - -cl_ulong -timestamp::query::operator()() const { - pipe_query_result result; - - if (!q().pipe->get_query_result(q().pipe, _query, false, &result)) - throw error(CL_PROFILING_INFO_NOT_AVAILABLE); - - return result.u64; -} - -timestamp::current::current(command_queue &q) : - result(q.pipe->screen->get_timestamp(q.pipe->screen)) { -} - -cl_ulong -timestamp::current::operator()() const { - return result; -} diff --git a/src/gallium/frontends/clover/core/timestamp.hpp b/src/gallium/frontends/clover/core/timestamp.hpp deleted file mode 100644 index b4b2c83eb92..00000000000 --- a/src/gallium/frontends/clover/core/timestamp.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_TIMESTAMP_HPP -#define CLOVER_CORE_TIMESTAMP_HPP - -#include "core/object.hpp" - -struct pipe_query; - -namespace clover { - class command_queue; - - namespace timestamp { - /// - /// Emit a timestamp query that is executed asynchronously by - /// the command queue \a q. - /// - class query { - public: - query(command_queue &q); - query(query &&other); - ~query(); - - query &operator=(const query &) = delete; - - /// - /// Retrieve the query results. - /// - cl_ulong operator()() const; - - private: - const intrusive_ref q; - pipe_query *_query; - }; - - /// - /// Get the current timestamp value. - /// - class current { - public: - current(command_queue &q); - - /// - /// Retrieve the query results. - /// - cl_ulong operator()() const; - - private: - cl_ulong result; - }; - } -} - -#endif diff --git a/src/gallium/frontends/clover/llvm/codegen.hpp b/src/gallium/frontends/clover/llvm/codegen.hpp deleted file mode 100644 index c07debe0313..00000000000 --- a/src/gallium/frontends/clover/llvm/codegen.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Tools to generate various forms of binary code from existing LLVM IR in -/// the given llvm::Module object and output the result as a clover::binary. -/// - -#ifndef CLOVER_LLVM_CODEGEN_HPP -#define CLOVER_LLVM_CODEGEN_HPP - -#include "llvm/util.hpp" -#include "core/binary.hpp" - -#include - -#include - -namespace clover { - namespace llvm { - std::string - print_module_bitcode(const ::llvm::Module &mod); - - binary - build_module_library(const ::llvm::Module &mod, - enum binary::section::type section_type); - - std::unique_ptr< ::llvm::Module> - parse_module_library(const binary &b, ::llvm::LLVMContext &ctx, - std::string &r_log); - - binary - build_module_native(::llvm::Module &mod, const target &target, - const clang::CompilerInstance &c, - std::string &r_log); - - std::string - print_module_native(const ::llvm::Module &mod, const target &target); - - binary - build_module_common(const ::llvm::Module &mod, - const std::vector &code, - const std::map &offsets, - const clang::CompilerInstance &c); - } -} - -#endif diff --git a/src/gallium/frontends/clover/llvm/codegen/bitcode.cpp b/src/gallium/frontends/clover/llvm/codegen/bitcode.cpp deleted file mode 100644 index 568bdd993f5..00000000000 --- a/src/gallium/frontends/clover/llvm/codegen/bitcode.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Trivial codegen back-end that simply passes through the existing LLVM IR -/// and either formats it so it can be consumed by pipe drivers (if -/// build_module_bitcode() is used) or serializes so it can be deserialized at -/// a later point and passed to the actual codegen back-end (if -/// build_module_library() / parse_module_library() is used), potentially -/// after linking against other bitcode object files. -/// - -#include - -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/metadata.hpp" -#include "core/error.hpp" -#include "util/algorithm.hpp" - -#include -#include -#include -#include -#include - -using clover::binary; -using namespace clover::llvm; - -namespace { - std::vector - emit_code(const ::llvm::Module &mod) { - ::llvm::SmallVector data; - ::llvm::raw_svector_ostream os { data }; - ::llvm::WriteBitcodeToFile(mod, os); - return { os.str().begin(), os.str().end() }; - } -} - -std::string -clover::llvm::print_module_bitcode(const ::llvm::Module &mod) { - std::string s; - ::llvm::raw_string_ostream os { s }; - mod.print(os, NULL); - return os.str(); -} - -binary -clover::llvm::build_module_library(const ::llvm::Module &mod, - enum binary::section::type section_type) { - binary b; - const auto code = emit_code(mod); - b.secs.emplace_back(0, section_type, code.size(), code); - return b; -} - -std::unique_ptr< ::llvm::Module> -clover::llvm::parse_module_library(const binary &b, ::llvm::LLVMContext &ctx, - std::string &r_log) { - auto mod = ::llvm::parseBitcodeFile(::llvm::MemoryBufferRef( - as_string(b.secs[0].data), " "), ctx); - - if (::llvm::Error err = mod.takeError()) { - ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) { - fail(r_log, error(CL_INVALID_PROGRAM), eib.message()); - }); - } - - return std::unique_ptr< ::llvm::Module>(std::move(*mod)); -} diff --git a/src/gallium/frontends/clover/llvm/codegen/common.cpp b/src/gallium/frontends/clover/llvm/codegen/common.cpp deleted file mode 100644 index 64a41ccc408..00000000000 --- a/src/gallium/frontends/clover/llvm/codegen/common.cpp +++ /dev/null @@ -1,358 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// Copyright 2015 Zoltan Gilian -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Codegen back-end-independent part of the construction of an executable -/// clover::binary, including kernel argument metadata extraction and -/// formatting of the pre-generated binary code in a form that can be -/// understood by pipe drivers. -/// - -#include -#include - -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/metadata.hpp" - -#include "CL/cl.h" - -#include "pipe/p_state.h" -#include "util/u_math.h" - -#include - -using clover::binary; -using clover::detokenize; -using namespace clover::llvm; - -using ::llvm::Module; -using ::llvm::Function; -using ::llvm::Type; -using ::llvm::isa; -using ::llvm::cast; -using ::llvm::dyn_cast; - -namespace { - enum binary::argument::type - get_image_type(const std::string &type, - const std::string &qual) { - if (type == "image1d_t" || type == "image2d_t" || type == "image3d_t") { - if (qual == "read_only") - return binary::argument::image_rd; - else if (qual == "write_only") - return binary::argument::image_wr; - } - - unreachable("Unsupported image type"); - } - - binary::arg_info create_arg_info(const std::string &arg_name, - const std::string &type_name, - const std::string &type_qualifier, - const uint64_t address_qualifier, - const std::string &access_qualifier) { - - cl_kernel_arg_type_qualifier cl_type_qualifier = - CL_KERNEL_ARG_TYPE_NONE; - if (type_qualifier.find("const") != std::string::npos) - cl_type_qualifier |= CL_KERNEL_ARG_TYPE_CONST; - if (type_qualifier.find("restrict") != std::string::npos) - cl_type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT; - if (type_qualifier.find("volatile") != std::string::npos) - cl_type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE; - - cl_kernel_arg_address_qualifier cl_address_qualifier = - CL_KERNEL_ARG_ADDRESS_PRIVATE; - if (address_qualifier == 1) - cl_address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL; - else if (address_qualifier == 2) - cl_address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT; - else if (address_qualifier == 3) - cl_address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL; - - cl_kernel_arg_access_qualifier cl_access_qualifier = - CL_KERNEL_ARG_ACCESS_NONE; - if (access_qualifier == "read_only") - cl_access_qualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY; - else if (access_qualifier == "write_only") - cl_access_qualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY; - else if (access_qualifier == "read_write") - cl_access_qualifier = CL_KERNEL_ARG_ACCESS_READ_WRITE; - - return binary::arg_info(arg_name, type_name, cl_type_qualifier, - cl_address_qualifier, cl_access_qualifier); - } - - std::vector - get_reqd_work_group_size(const Module &mod, - const std::string &kernel_name) { - const Function &f = *mod.getFunction(kernel_name); - auto vector_metadata = get_uint_vector_kernel_metadata(f, "reqd_work_group_size"); - - return vector_metadata.empty() ? std::vector({0, 0, 0}) : vector_metadata; - } - - - std::string - kernel_attributes(const Module &mod, const std::string &kernel_name) { - std::vector attributes; - - const Function &f = *mod.getFunction(kernel_name); - - auto vec_type_hint = get_type_kernel_metadata(f, "vec_type_hint"); - if (!vec_type_hint.empty()) - attributes.emplace_back("vec_type_hint(" + vec_type_hint + ")"); - - auto work_group_size_hint = get_uint_vector_kernel_metadata(f, "work_group_size_hint"); - if (!work_group_size_hint.empty()) { - std::string s = "work_group_size_hint("; - s += detokenize(work_group_size_hint, ","); - s += ")"; - attributes.emplace_back(s); - } - - auto reqd_work_group_size = get_uint_vector_kernel_metadata(f, "reqd_work_group_size"); - if (!reqd_work_group_size.empty()) { - std::string s = "reqd_work_group_size("; - s += detokenize(reqd_work_group_size, ","); - s += ")"; - attributes.emplace_back(s); - } - - auto nosvm = get_str_kernel_metadata(f, "nosvm"); - if (!nosvm.empty()) - attributes.emplace_back("nosvm"); - - return detokenize(attributes, " "); - } - - // Parse the type which are pointers to CL vector types with no prefix. - // so e.g. char/uchar, short/ushort, int/uint, long/ulong - // half/float/double, followed by the vector length, followed by *. - // uint8 is 8x32-bit integer, short4 is 4x16-bit integer etc. - // Since this is a pointer only path, assert the * is on the end. - ::llvm::Type * - ptr_arg_to_llvm_type(const Module &mod, std::string type_name) { - int len = type_name.length(); - assert (type_name[len-1] == '*'); - ::llvm::Type *base_type = NULL; - if (type_name.find("void") != std::string::npos) - base_type = ::llvm::Type::getVoidTy(mod.getContext()); - else if (type_name.find("char") != std::string::npos) - base_type = ::llvm::Type::getInt8Ty(mod.getContext()); - else if (type_name.find("short") != std::string::npos) - base_type = ::llvm::Type::getInt16Ty(mod.getContext()); - else if (type_name.find("int") != std::string::npos) - base_type = ::llvm::Type::getInt32Ty(mod.getContext()); - else if (type_name.find("long") != std::string::npos) - base_type = ::llvm::Type::getInt64Ty(mod.getContext()); - else if (type_name.find("half") != std::string::npos) - base_type = ::llvm::Type::getHalfTy(mod.getContext()); - else if (type_name.find("float") != std::string::npos) - base_type = ::llvm::Type::getFloatTy(mod.getContext()); - else if (type_name.find("double") != std::string::npos) - base_type = ::llvm::Type::getDoubleTy(mod.getContext()); - - assert(base_type); - if (type_name.find("2") != std::string::npos) - base_type = ::llvm::FixedVectorType::get(base_type, 2); - else if (type_name.find("3") != std::string::npos) - base_type = ::llvm::FixedVectorType::get(base_type, 3); - else if (type_name.find("4") != std::string::npos) - base_type = ::llvm::FixedVectorType::get(base_type, 4); - else if (type_name.find("8") != std::string::npos) - base_type = ::llvm::FixedVectorType::get(base_type, 8); - else if (type_name.find("16") != std::string::npos) - base_type = ::llvm::FixedVectorType::get(base_type, 16); - return base_type; - } - - std::vector - make_kernel_args(const Module &mod, const std::string &kernel_name, - const clang::CompilerInstance &c) { - std::vector args; - const Function &f = *mod.getFunction(kernel_name); -#if LLVM_VERSION_MAJOR >= 20 - const ::llvm::DataLayout &dl = mod.getDataLayout(); -#else - ::llvm::DataLayout dl(&mod); -#endif - const auto size_type = - dl.getSmallestLegalIntType(mod.getContext(), sizeof(cl_uint) * 8); - const unsigned size_align = compat::get_abi_type_alignment(dl, size_type); - - for (const auto &arg : f.args()) { - const auto arg_type = arg.getType(); - - // OpenCL 1.2 specification, Ch. 6.1.5: "A built-in data - // type that is not a power of two bytes in size must be - // aligned to the next larger power of two. - // This rule applies to built-in types only, not structs or unions." - const unsigned arg_api_size = dl.getTypeAllocSize(arg_type); - - const unsigned target_size = dl.getTypeStoreSize(arg_type); - const unsigned target_align = compat::get_abi_type_alignment(dl, arg_type); - - const auto type_name = get_str_argument_metadata(f, arg, - "kernel_arg_type"); - if (type_name == "image2d_t" || type_name == "image3d_t") { - // Image. - const auto access_qual = get_str_argument_metadata( - f, arg, "kernel_arg_access_qual"); - args.emplace_back(get_image_type(type_name, access_qual), - target_size, target_size, - target_align, binary::argument::zero_ext); - - } else if (type_name == "sampler_t") { - args.emplace_back(binary::argument::sampler, arg_api_size, - target_size, target_align, - binary::argument::zero_ext); - - } else if (type_name == "__llvm_image_size") { - // Image size implicit argument. - args.emplace_back(binary::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - size_align, - binary::argument::zero_ext, - binary::argument::image_size); - - } else if (type_name == "__llvm_image_format") { - // Image format implicit argument. - args.emplace_back(binary::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - size_align, - binary::argument::zero_ext, - binary::argument::image_format); - - } else { - // Other types. - const auto actual_type = - isa< ::llvm::PointerType>(arg_type) && arg.hasByValAttr() ? - ptr_arg_to_llvm_type(mod, type_name) : arg_type; - - if (actual_type->isPointerTy()) { - const unsigned address_space = - cast< ::llvm::PointerType>(actual_type)->getAddressSpace(); - - const auto &map = c.getTarget().getAddressSpaceMap(); - const auto offset = - static_cast(clang::LangAS::opencl_local); - if (address_space == map[offset]) { - const auto pointee_type = ptr_arg_to_llvm_type(mod, type_name); - - args.emplace_back(binary::argument::local, arg_api_size, - target_size, - (pointee_type->isVoidTy()) ? 8 : - compat::get_abi_type_alignment(dl, pointee_type), - binary::argument::zero_ext); - } else { - // XXX: Correctly handle constant address space. There is no - // way for r600g to pass a handle for constant buffers back - // to clover like it can for global buffers, so - // creating constant arguments will break r600g. For now, - // continue treating constant buffers as global buffers - // until we can come up with a way to create handles for - // constant buffers. - args.emplace_back(binary::argument::global, arg_api_size, - target_size, target_align, - binary::argument::zero_ext); - } - - } else { - const bool needs_sign_ext = f.getAttributes().hasParamAttr( - arg.getArgNo(), ::llvm::Attribute::SExt); - - args.emplace_back(binary::argument::scalar, arg_api_size, - target_size, target_align, - (needs_sign_ext ? binary::argument::sign_ext : - binary::argument::zero_ext)); - } - - // Add kernel argument infos if built with -cl-kernel-arg-info. - if (c.getCodeGenOpts().EmitOpenCLArgMetadata) { - args.back().info = create_arg_info( - get_str_argument_metadata(f, arg, "kernel_arg_name"), - type_name, - get_str_argument_metadata(f, arg, "kernel_arg_type_qual"), - get_uint_argument_metadata(f, arg, "kernel_arg_addr_space"), - get_str_argument_metadata(f, arg, "kernel_arg_access_qual")); - } - } - } - - // Append implicit arguments. XXX - The types, ordering and - // vector size of the implicit arguments should depend on the - // target according to the selected calling convention. - args.emplace_back(binary::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - size_align, - binary::argument::zero_ext, - binary::argument::grid_dimension); - - args.emplace_back(binary::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - size_align, - binary::argument::zero_ext, - binary::argument::grid_offset); - - return args; - } - - binary::section - make_text_section(const std::vector &code) { - const pipe_binary_program_header header { uint32_t(code.size()) }; - binary::section text { 0, binary::section::text_executable, - header.num_bytes, {} }; - - text.data.insert(text.data.end(), reinterpret_cast(&header), - reinterpret_cast(&header) + sizeof(header)); - text.data.insert(text.data.end(), code.begin(), code.end()); - - return text; - } -} - -binary -clover::llvm::build_module_common(const Module &mod, - const std::vector &code, - const std::map &offsets, - const clang::CompilerInstance &c) { - binary b; - - for (const auto &llvm_name : map(std::mem_fn(&Function::getName), - get_kernels(mod))) { - const ::std::string name(llvm_name); - if (offsets.count(name)) - b.syms.emplace_back(name, kernel_attributes(mod, name), - get_reqd_work_group_size(mod, name), - 0, offsets.at(name), - make_kernel_args(mod, name, c)); - } - - b.secs.push_back(make_text_section(code)); - return b; -} diff --git a/src/gallium/frontends/clover/llvm/codegen/native.cpp b/src/gallium/frontends/clover/llvm/codegen/native.cpp deleted file mode 100644 index 72046c8a188..00000000000 --- a/src/gallium/frontends/clover/llvm/codegen/native.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Generate code using an arbitrary LLVM back-end capable of emitting -/// executable code as an ELF object file. -/// - -#include -#include - -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/util.hpp" -#include "core/error.hpp" - -using clover::binary; -using clover::build_error; -using namespace clover::llvm; -using ::llvm::TargetMachine; - -#if defined(USE_LIBELF) - -#include -#include - -namespace { - namespace elf { - std::unique_ptr - get(const std::vector &code) { - // One of the libelf implementations - // (http://www.mr511.de/software/english.htm) requires calling - // elf_version() before elf_memory(). - elf_version(EV_CURRENT); - return { elf_memory(const_cast(code.data()), code.size()), - elf_end }; - } - - Elf_Scn * - get_symbol_table(Elf *elf) { - size_t section_str_index; - elf_getshdrstrndx(elf, §ion_str_index); - - for (Elf_Scn *s = elf_nextscn(elf, NULL); s; s = elf_nextscn(elf, s)) { - GElf_Shdr header; - if (gelf_getshdr(s, &header) != &header) - return nullptr; - - if (!std::strcmp(elf_strptr(elf, section_str_index, header.sh_name), - ".symtab")) - return s; - } - - return nullptr; - } - - std::map - get_symbol_offsets(Elf *elf, Elf_Scn *symtab) { - Elf_Data *const symtab_data = elf_getdata(symtab, NULL); - GElf_Shdr header; - if (gelf_getshdr(symtab, &header) != &header) - return {}; - - std::map symbol_offsets; - GElf_Sym symbol; - unsigned i = 0; - - while (GElf_Sym *s = gelf_getsym(symtab_data, i++, &symbol)) { - const char *name = elf_strptr(elf, header.sh_link, s->st_name); - symbol_offsets[name] = s->st_value; - } - - return symbol_offsets; - } - } - - std::map - get_symbol_offsets(const std::vector &code, std::string &r_log) { - const auto elf = elf::get(code); - const auto symtab = elf::get_symbol_table(elf.get()); - if (!symtab) - fail(r_log, build_error(), "Unable to find symbol table."); - - return elf::get_symbol_offsets(elf.get(), symtab); - } - - std::vector - emit_code(::llvm::Module &mod, const target &target, - compat::CodeGenFileType ft, - std::string &r_log) { - std::string err; - auto t = ::llvm::TargetRegistry::lookupTarget(target.triple, err); - if (!t) - fail(r_log, build_error(), err); - - std::unique_ptr tm { - t->createTargetMachine(target.triple, target.cpu, "", {}, -#if LLVM_VERSION_MAJOR >= 16 - std::nullopt, std::nullopt, -#else - ::llvm::None, ::llvm::None, -#endif -#if LLVM_VERSION_MAJOR >= 18 - ::llvm::CodeGenOptLevel::Default) }; -#else - ::llvm::CodeGenOpt::Default) }; -#endif - if (!tm) - fail(r_log, build_error(), - "Could not create TargetMachine: " + target.triple); - - ::llvm::SmallVector data; - - { - ::llvm::legacy::PassManager pm; - ::llvm::raw_svector_ostream os { data }; - - mod.setDataLayout(tm->createDataLayout()); - tm->Options.MCOptions.AsmVerbose = - (ft == compat::CGFT_AssemblyFile); - - if (tm->addPassesToEmitFile(pm, os, nullptr, ft)) - fail(r_log, build_error(), "TargetMachine can't emit this file"); - - pm.run(mod); - } - - return { data.begin(), data.end() }; - } -} - -binary -clover::llvm::build_module_native(::llvm::Module &mod, const target &target, - const clang::CompilerInstance &c, - std::string &r_log) { - const auto code = emit_code(mod, target, - compat::CGFT_ObjectFile, r_log); - return build_module_common(mod, code, get_symbol_offsets(code, r_log), c); -} - -std::string -clover::llvm::print_module_native(const ::llvm::Module &mod, - const target &target) { - std::string log; - try { - std::unique_ptr< ::llvm::Module> cmod { ::llvm::CloneModule(mod) }; - return as_string(emit_code(*cmod, target, - compat::CGFT_AssemblyFile, log)); - } catch (...) { - return "Couldn't output native disassembly: " + log; - } -} - -#else - -binary -clover::llvm::build_module_native(::llvm::Module &mod, const target &target, - const clang::CompilerInstance &c, - std::string &r_log) { - unreachable("Native codegen support disabled at build time"); -} - -std::string -clover::llvm::print_module_native(const ::llvm::Module &mod, - const target &target) { - unreachable("Native codegen support disabled at build time"); -} - -#endif diff --git a/src/gallium/frontends/clover/llvm/compat.hpp b/src/gallium/frontends/clover/llvm/compat.hpp deleted file mode 100644 index 3b04adb88f2..00000000000 --- a/src/gallium/frontends/clover/llvm/compat.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Some thin wrappers around the Clang/LLVM API used to preserve -/// compatibility with older API versions while keeping the ifdef clutter low -/// in the rest of the clover::llvm subtree. In case of an API break please -/// consider whether it's possible to preserve backwards compatibility by -/// introducing a new one-liner inline function or typedef here under the -/// compat namespace in order to keep the running code free from preprocessor -/// conditionals. -/// - -#ifndef CLOVER_LLVM_COMPAT_HPP -#define CLOVER_LLVM_COMPAT_HPP - -#include "util/algorithm.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if LLVM_VERSION_MAJOR >= 14 -#include -#else -#include -#endif - -#if LLVM_VERSION_MAJOR >= 17 -#include -#else -#include -#endif - -namespace clover { - namespace llvm { - namespace compat { - -#if LLVM_VERSION_MAJOR >= 18 - const auto CGFT_ObjectFile = ::llvm::CodeGenFileType::ObjectFile; - const auto CGFT_AssemblyFile = ::llvm::CodeGenFileType::AssemblyFile; -#else - const auto CGFT_ObjectFile = ::llvm::CGFT_ObjectFile; - const auto CGFT_AssemblyFile = ::llvm::CGFT_AssemblyFile; -#endif - typedef ::llvm::CodeGenFileType CodeGenFileType; - - const clang::InputKind ik_opencl = clang::Language::OpenCL; - - template inline bool - create_compiler_invocation_from_args(clang::CompilerInvocation &cinv, - T copts, - clang::DiagnosticsEngine &diag) - { - return clang::CompilerInvocation::CreateFromArgs( - cinv, copts, diag); - } - - static inline void - compiler_set_lang_defaults(std::unique_ptr &c, - clang::InputKind ik, const ::llvm::Triple& triple, - clang::LangStandard::Kind d) - { -#if LLVM_VERSION_MAJOR >= 15 - c->getLangOpts().setLangDefaults(c->getLangOpts(), ik.getLanguage(), triple, -#else - c->getInvocation().setLangDefaults(c->getLangOpts(), ik, triple, -#endif -#if LLVM_VERSION_MAJOR >= 12 - c->getPreprocessorOpts().Includes, -#else - c->getPreprocessorOpts(), -#endif - d); - } - - static inline unsigned - get_abi_type_alignment(::llvm::DataLayout dl, ::llvm::Type *type) - { -#if LLVM_VERSION_MAJOR >= 16 - return dl.getABITypeAlign(type).value(); -#else - return dl.getABITypeAlignment(type); -#endif - } - - static inline bool - is_scalable_vector(const ::llvm::Type *type) - { - return ::llvm::isa<::llvm::ScalableVectorType>(type); - } - - static inline bool - is_fixed_vector(const ::llvm::Type *type) - { - return ::llvm::isa<::llvm::FixedVectorType>(type); - } - - static inline unsigned - get_fixed_vector_elements(const ::llvm::Type *type) - { - return ::llvm::cast<::llvm::FixedVectorType>(type)->getNumElements(); - } - } - } -} - -#endif diff --git a/src/gallium/frontends/clover/llvm/invocation.cpp b/src/gallium/frontends/clover/llvm/invocation.cpp deleted file mode 100644 index ccec22fb621..00000000000 --- a/src/gallium/frontends/clover/llvm/invocation.cpp +++ /dev/null @@ -1,580 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// Copyright 2014-2016 Jan Vesely -// Copyright 2014-2015 Serge Martin -// Copyright 2015 Zoltan Gilian -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifdef HAVE_DLFCN_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if LLVM_VERSION_MAJOR >= 20 -#include -#endif - -// We need to include internal headers last, because the internal headers -// include CL headers which have #define's like: -// -//#define cl_khr_gl_sharing 1 -//#define cl_khr_icd 1 -// -// Which will break the compilation of clang/Basic/OpenCLOptions.h - -#include "core/error.hpp" -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/invocation.hpp" -#include "llvm/metadata.hpp" -#include "llvm/util.hpp" -#include "util/algorithm.hpp" - - -using clover::binary; -using clover::device; -using clover::build_error; -using clover::invalid_build_options_error; -using clover::map; -using clover::header_map; -using namespace clover::llvm; - -using ::llvm::Function; -using ::llvm::LLVMContext; -using ::llvm::Module; -using ::llvm::raw_string_ostream; - -namespace { - - static const cl_version ANY_VERSION = CL_MAKE_VERSION(9, 9, 9); - const cl_version cl_versions[] = { - CL_MAKE_VERSION(1, 1, 0), - CL_MAKE_VERSION(1, 2, 0), - CL_MAKE_VERSION(2, 0, 0), - CL_MAKE_VERSION(2, 1, 0), - CL_MAKE_VERSION(2, 2, 0), - CL_MAKE_VERSION(3, 0, 0), - }; - - struct clc_version_lang_std { - cl_version version_number; // CLC Version - clang::LangStandard::Kind clc_lang_standard; - }; - - const clc_version_lang_std cl_version_lang_stds[] = { - { CL_MAKE_VERSION(1, 0, 0), clang::LangStandard::lang_opencl10}, - { CL_MAKE_VERSION(1, 1, 0), clang::LangStandard::lang_opencl11}, - { CL_MAKE_VERSION(1, 2, 0), clang::LangStandard::lang_opencl12}, - { CL_MAKE_VERSION(2, 0, 0), clang::LangStandard::lang_opencl20}, -#if LLVM_VERSION_MAJOR >= 12 - { CL_MAKE_VERSION(3, 0, 0), clang::LangStandard::lang_opencl30}, -#endif - }; - - bool - are_equal(cl_version_khr version1, cl_version_khr version2, - bool ignore_patch_version = false) { - if (ignore_patch_version) { - version1 &= ~CL_VERSION_PATCH_MASK_KHR; - version2 &= ~CL_VERSION_PATCH_MASK_KHR; - } - return version1 == version2; - } - - void - init_targets() { - static bool targets_initialized = false; - if (!targets_initialized) { - LLVMInitializeAllTargets(); - LLVMInitializeAllTargetInfos(); - LLVMInitializeAllTargetMCs(); - LLVMInitializeAllAsmParsers(); - LLVMInitializeAllAsmPrinters(); - targets_initialized = true; - } - } - - void -#if LLVM_VERSION_MAJOR >= 19 - diagnostic_handler(const ::llvm::DiagnosticInfo *di, void *data) { - if (di->getSeverity() == ::llvm::DS_Error) { -#else - diagnostic_handler(const ::llvm::DiagnosticInfo &di, void *data) { - if (di.getSeverity() == ::llvm::DS_Error) { -#endif - raw_string_ostream os { *reinterpret_cast(data) }; - ::llvm::DiagnosticPrinterRawOStream printer { os }; -#if LLVM_VERSION_MAJOR >= 19 - di->print(printer); -#else - di.print(printer); -#endif - throw build_error(); - } - } - - std::unique_ptr - create_context(std::string &r_log) { - init_targets(); - std::unique_ptr ctx { new LLVMContext }; - - ctx->setDiagnosticHandlerCallBack(diagnostic_handler, &r_log); - return ctx; - } - - const struct clc_version_lang_std& - get_cl_lang_standard(unsigned requested, unsigned max = ANY_VERSION) { - for (const struct clc_version_lang_std &version : cl_version_lang_stds) { - if (version.version_number == max || - version.version_number == requested) { - return version; - } - } - throw build_error("Unknown/Unsupported language version"); - } - - const cl_version - get_cl_version(cl_version requested, - cl_version max = ANY_VERSION) { - for (const auto &version : cl_versions) { - if (are_equal(version, max, true) || - are_equal(version, requested, true)) { - return version; - } - } - throw build_error("Unknown/Unsupported language version"); - } - - clang::LangStandard::Kind - get_lang_standard_from_version(const cl_version input_version, - bool is_build_opt = false) { - - //Per CL 2.0 spec, section 5.8.4.5: - // If it's an option, use the value directly. - // If it's a device version, clamp to max 1.x version, a.k.a. 1.2 - const cl_version version = - get_cl_version(input_version, is_build_opt ? ANY_VERSION : 120); - - const struct clc_version_lang_std standard = - get_cl_lang_standard(version); - - return standard.clc_lang_standard; - } - - clang::LangStandard::Kind - get_language_version(const std::vector &opts, - const cl_version device_version) { - - const std::string search = "-cl-std=CL"; - - for (auto &opt: opts) { - auto pos = opt.find(search); - if (pos == 0){ - std::stringstream ver_str(opt.substr(pos + search.size())); - unsigned int ver_major = 0; - char separator = '\0'; - unsigned int ver_minor = 0; - ver_str >> ver_major >> separator >> ver_minor; - if (ver_str.fail() || ver_str.bad() || !ver_str.eof() || - separator != '.') { - throw build_error(); - } - const auto ver = CL_MAKE_VERSION_KHR(ver_major, ver_minor, 0); - const auto device_ver = get_cl_version(device_version); - const auto requested = get_cl_version(ver); - if (requested > device_ver) { - throw build_error(); - } - return get_lang_standard_from_version(ver, true); - } - } - - return get_lang_standard_from_version(device_version); - } - - std::unique_ptr - create_compiler_instance(const device &dev, const std::string& ir_target, - const std::vector &opts, - std::string &r_log) { - std::unique_ptr c { new clang::CompilerInstance }; - clang::TextDiagnosticBuffer *diag_buffer = new clang::TextDiagnosticBuffer; - clang::DiagnosticsEngine diag { new clang::DiagnosticIDs, - new clang::DiagnosticOptions, diag_buffer }; - - // Parse the compiler options. A file name should be present at the end - // and must have the .cl extension in order for the CompilerInvocation - // class to recognize it as an OpenCL source file. -#if LLVM_VERSION_MAJOR >= 12 - std::vector copts; -#if LLVM_VERSION_MAJOR == 15 || LLVM_VERSION_MAJOR == 16 - // Before LLVM commit 702d5de4 opaque pointers were supported but not enabled - // by default when building LLVM. They were made default in commit 702d5de4. - // LLVM commit d69e9f9d introduced -opaque-pointers/-no-opaque-pointers cc1 - // options to enable or disable them whatever the LLVM default is. - - // Those two commits follow llvmorg-15-init and precede llvmorg-15.0.0-rc1 tags. - - // Since LLVM commit d785a8ea, the CLANG_ENABLE_OPAQUE_POINTERS build option of - // LLVM is removed, meaning there is no way to build LLVM with opaque pointers - // enabled by default. - // It was said at the time it was still possible to explicitly disable opaque - // pointers via cc1 -no-opaque-pointers option, but it is known a later commit - // broke backward compatibility provided by -no-opaque-pointers as verified with - // arbitrary commit d7d586e5, so there is no way to use opaque pointers starting - // with LLVM 16. - - // Those two commits follow llvmorg-16-init and precede llvmorg-16.0.0-rc1 tags. - - // Since Mesa commit 977dbfc9 opaque pointers are properly implemented in Clover - // and used. - - // If we don't pass -opaque-pointers to Clang on LLVM versions supporting opaque - // pointers but disabling them by default, there will be an API mismatch between - // Mesa and LLVM and Clover will not work. - copts.push_back("-opaque-pointers"); -#endif - for (auto &opt : opts) { - if (opt == "-cl-denorms-are-zero") - copts.push_back("-fdenormal-fp-math=positive-zero"); - else - copts.push_back(opt.c_str()); - } -#else - const std::vector copts = - map(std::mem_fn(&std::string::c_str), opts); -#endif - - const target &target = ir_target; - const cl_version device_clc_version = dev.device_clc_version(); - - if (!compat::create_compiler_invocation_from_args( - c->getInvocation(), copts, diag)) - throw invalid_build_options_error(); - - diag_buffer->FlushDiagnostics(diag); - if (diag.hasErrorOccurred()) - throw invalid_build_options_error(); - - c->getTargetOpts().CPU = target.cpu; - c->getTargetOpts().Triple = target.triple; - c->getLangOpts().NoBuiltin = true; - -#if LLVM_VERSION_MAJOR >= 13 - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_generic_address_space"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_pipes"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_device_enqueue"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_program_scope_global_variables"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_subgroups"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_work_group_collective_functions"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_atomic_scope_device"); - c->getTargetOpts().OpenCLExtensionsAsWritten.push_back("-__opencl_c_atomic_order_seq_cst"); -#endif - - // This is a workaround for a Clang bug which causes the number - // of warnings and errors to be printed to stderr. - // http://www.llvm.org/bugs/show_bug.cgi?id=19735 - c->getDiagnosticOpts().ShowCarets = false; - - compat::compiler_set_lang_defaults(c, compat::ik_opencl, - ::llvm::Triple(target.triple), - get_language_version(opts, device_clc_version)); - - c->createDiagnostics( -#if LLVM_VERSION_MAJOR >= 20 - *llvm::vfs::getRealFileSystem(), -#endif - new clang::TextDiagnosticPrinter( - *new raw_string_ostream(r_log), - &c->getDiagnosticOpts(), true)); - - c->setTarget(clang::TargetInfo::CreateTargetInfo( - c->getDiagnostics(), c->getInvocation().TargetOpts)); - - return c; - } - - std::string getResourceDirectory() { -#ifdef HAVE_DLFCN_H - Dl_info info; - if (dladdr((void *)clang::CompilerInvocation::CreateFromArgs, &info) == 0) { - return FALLBACK_CLANG_RESOURCE_DIR; - } - - char *libclang_path = realpath(info.dli_fname, NULL); - if (libclang_path == nullptr) { - return FALLBACK_CLANG_RESOURCE_DIR; - } - - // GetResourcePath is a way to retrieve the actual libclang resource dir based on a given - // binary or library. - std::string clang_resource_dir = -#if LLVM_VERSION_MAJOR >= 20 - clang::driver::Driver::GetResourcesPath(std::string(libclang_path)); -#else - clang::driver::Driver::GetResourcesPath(std::string(libclang_path), CLANG_RESOURCE_DIR); -#endif - free(libclang_path); - - return clang_resource_dir; -#else - return FALLBACK_CLANG_RESOURCE_DIR; -#endif - } - - std::unique_ptr - compile(LLVMContext &ctx, clang::CompilerInstance &c, - const std::string &name, const std::string &source, - const header_map &headers, const device &dev, - const std::string &opts, bool use_libclc, std::string &r_log) { - c.getFrontendOpts().ProgramAction = clang::frontend::EmitLLVMOnly; - c.getHeaderSearchOpts().UseBuiltinIncludes = true; - c.getHeaderSearchOpts().UseStandardSystemIncludes = true; - - std::string clang_resource_dir = getResourceDirectory(); - c.getHeaderSearchOpts().ResourceDir = clang_resource_dir; - - // Add opencl-c generic search path - std::string clang_include_path = clang_resource_dir + "/include"; - c.getHeaderSearchOpts().AddPath(clang_include_path, - clang::frontend::Angled, - false, false); - - // Add opencl include - c.getPreprocessorOpts().Includes.push_back("opencl-c.h"); - - // Add definition for the OpenCL version - const auto dev_version = dev.device_version(); - c.getPreprocessorOpts().addMacroDef("__OPENCL_VERSION__=" + - std::to_string(CL_VERSION_MAJOR_KHR(dev_version)) + - std::to_string(CL_VERSION_MINOR_KHR(dev_version)) + "0"); - - if (CL_VERSION_MAJOR(dev.version) >= 3) { - const auto features = dev.opencl_c_features(); - for (const auto &feature : features) - c.getPreprocessorOpts().addMacroDef(feature.name); - } - - // clc.h requires that this macro be defined: - c.getPreprocessorOpts().addMacroDef("cl_clang_storage_class_specifiers"); - c.getPreprocessorOpts().addRemappedFile( - name, ::llvm::MemoryBuffer::getMemBuffer(source).release()); - - if (headers.size()) { - const std::string tmp_header_path = "/tmp/clover/"; - - c.getHeaderSearchOpts().AddPath(tmp_header_path, - clang::frontend::Angled, - false, false); - - for (const auto &header : headers) - c.getPreprocessorOpts().addRemappedFile( - tmp_header_path + header.first, - ::llvm::MemoryBuffer::getMemBuffer(header.second).release()); - } - - // Tell clang to link this file before performing any - // optimizations. This is required so that we can replace calls - // to the OpenCL C barrier() builtin with calls to target - // intrinsics that have the noduplicate attribute. This - // attribute will prevent Clang from creating illegal uses of - // barrier() (e.g. Moving barrier() inside a conditional that is - // no executed by all threads) during its optimizaton passes. - if (use_libclc) { - clang::CodeGenOptions::BitcodeFileToLink F; - - F.Filename = LIBCLC_LIBEXECDIR + dev.ir_target() + ".bc"; - F.PropagateAttrs = true; - F.LinkFlags = ::llvm::Linker::Flags::None; - c.getCodeGenOpts().LinkBitcodeFiles.emplace_back(F); - } - - // undefine __IMAGE_SUPPORT__ for device without image support - if (!dev.image_support()) - c.getPreprocessorOpts().addMacroUndef("__IMAGE_SUPPORT__"); - - // Compile the code - clang::EmitLLVMOnlyAction act(&ctx); - if (!c.ExecuteAction(act)) - throw build_error(); - - return act.takeModule(); - } -} - -binary -clover::llvm::compile_program(const std::string &source, - const header_map &headers, - const device &dev, - const std::string &opts, - std::string &r_log) { - if (has_flag(debug::clc)) - debug::log(".cl", "// Options: " + opts + '\n' + source); - - auto ctx = create_context(r_log); - auto c = create_compiler_instance(dev, dev.ir_target(), - tokenize(opts + " input.cl"), r_log); - auto mod = compile(*ctx, *c, "input.cl", source, headers, dev, opts, true, - r_log); - - if (has_flag(debug::llvm)) - debug::log(".ll", print_module_bitcode(*mod)); - - return build_module_library(*mod, binary::section::text_intermediate); -} - -namespace { - void - optimize(Module &mod, - const std::string& ir_target, - unsigned optimization_level, - bool internalize_symbols) { - // By default, the function internalizer pass will look for a function - // called "main" and then mark all other functions as internal. Marking - // functions as internal enables the optimizer to perform optimizations - // like function inlining and global dead-code elimination. - // - // When there is no "main" function in a binary, the internalize pass will - // treat the binary like a library, and it won't internalize any functions. - // Since there is no "main" function in our kernels, we need to tell - // the internalizer pass that this binary is not a library by passing a - // list of kernel functions to the internalizer. The internalizer will - // treat the functions in the list as "main" functions and internalize - // all of the other functions. - if (internalize_symbols) { - std::vector names = - map(std::mem_fn(&Function::getName), get_kernels(mod)); - internalizeModule(mod, - [=](const ::llvm::GlobalValue &gv) { - return std::find(names.begin(), names.end(), - gv.getName()) != names.end(); - }); - } - - - const char *opt_str = NULL; - LLVMCodeGenOptLevel level; - switch (optimization_level) { - case 0: - default: - opt_str = "default"; - level = LLVMCodeGenLevelNone; - break; - case 1: - opt_str = "default"; - level = LLVMCodeGenLevelLess; - break; - case 2: - opt_str = "default"; - level = LLVMCodeGenLevelDefault; - break; - case 3: - opt_str = "default"; - level = LLVMCodeGenLevelAggressive; - break; - } - - const target &target = ir_target; - LLVMTargetRef targ; - char *err_message; - - if (LLVMGetTargetFromTriple(target.triple.c_str(), &targ, &err_message)) - return; - LLVMTargetMachineRef tm = - LLVMCreateTargetMachine(targ, target.triple.c_str(), - target.cpu.c_str(), "", level, - LLVMRelocDefault, LLVMCodeModelDefault); - - if (!tm) - return; - LLVMPassBuilderOptionsRef opts = LLVMCreatePassBuilderOptions(); - LLVMRunPasses(wrap(&mod), opt_str, tm, opts); - - LLVMDisposeTargetMachine(tm); - LLVMDisposePassBuilderOptions(opts); - } - - std::unique_ptr - link(LLVMContext &ctx, const clang::CompilerInstance &c, - const std::vector &binaries, std::string &r_log) { - std::unique_ptr mod { new Module("link", ctx) }; - std::unique_ptr< ::llvm::Linker> linker { new ::llvm::Linker(*mod) }; - - for (auto &b : binaries) { - if (linker->linkInModule(parse_module_library(b, ctx, r_log))) - throw build_error(); - } - - return mod; - } -} - -binary -clover::llvm::link_program(const std::vector &binaries, - const device &dev, const std::string &opts, - std::string &r_log) { - std::vector options = tokenize(opts + " input.cl"); - const bool create_library = count("-create-library", options); - erase_if(equals("-create-library"), options); - - auto ctx = create_context(r_log); - auto c = create_compiler_instance(dev, dev.ir_target(), options, r_log); - auto mod = link(*ctx, *c, binaries, r_log); - - optimize(*mod, dev.ir_target(), c->getCodeGenOpts().OptimizationLevel, !create_library); - - static std::atomic_uint seq(0); - const std::string id = "." + mod->getModuleIdentifier() + "-" + - std::to_string(seq++); - - if (has_flag(debug::llvm)) - debug::log(id + ".ll", print_module_bitcode(*mod)); - - if (create_library) { - return build_module_library(*mod, binary::section::text_library); - - } else if (dev.ir_format() == PIPE_SHADER_IR_NATIVE) { - if (has_flag(debug::native)) - debug::log(id + ".asm", print_module_native(*mod, dev.ir_target())); - - return build_module_native(*mod, dev.ir_target(), *c, r_log); - - } else { - unreachable("Unsupported IR."); - } -} diff --git a/src/gallium/frontends/clover/llvm/invocation.hpp b/src/gallium/frontends/clover/llvm/invocation.hpp deleted file mode 100644 index 3ef51c77175..00000000000 --- a/src/gallium/frontends/clover/llvm/invocation.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_LLVM_INVOCATION_HPP -#define CLOVER_LLVM_INVOCATION_HPP - -#include "core/error.hpp" -#include "core/binary.hpp" -#include "core/program.hpp" -#include "pipe/p_defines.h" - -namespace clover { - namespace llvm { - binary compile_program(const std::string &source, - const header_map &headers, - const device &device, - const std::string &opts, - std::string &r_log); - - binary link_program(const std::vector &binaries, - const device &device, - const std::string &opts, - std::string &r_log); - } -} - -#endif diff --git a/src/gallium/frontends/clover/llvm/metadata.hpp b/src/gallium/frontends/clover/llvm/metadata.hpp deleted file mode 100644 index 92548c0f0a3..00000000000 --- a/src/gallium/frontends/clover/llvm/metadata.hpp +++ /dev/null @@ -1,203 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Utility functions for LLVM IR metadata introspection. -/// - -#ifndef CLOVER_LLVM_METADATA_HPP -#define CLOVER_LLVM_METADATA_HPP - -#include "llvm/compat.hpp" -#include "util/algorithm.hpp" - -#include -#include -#include -#include -#include - -namespace clover { - namespace llvm { - namespace detail { - inline bool - is_kernel(const ::llvm::Function &f) { - return f.getMetadata("kernel_arg_type"); - } - - inline iterator_range< ::llvm::MDNode::op_iterator> - get_kernel_metadata_operands(const ::llvm::Function &f, - const std::string &name) { - const auto data_node = f.getMetadata(name); - if (data_node) - return range(data_node->op_begin(), data_node->op_end()); - else - return iterator_range< ::llvm::MDNode::op_iterator>(); - } - } - - /// - /// Extract the string metadata node \p name. - /// - inline std::string - get_str_kernel_metadata(const ::llvm::Function &f, - const std::string &name) { - auto operands = detail::get_kernel_metadata_operands(f, name); - if (operands.size()) { - return ::llvm::cast< ::llvm::MDString>( - detail::get_kernel_metadata_operands(f, name)[0]) - ->getString().str(); - } else { - return ""; - } - } - - /// - /// Extract the string metadata node \p name. - /// - inline std::vector - get_uint_vector_kernel_metadata(const ::llvm::Function &f, - const std::string &name) { - auto operands = detail::get_kernel_metadata_operands(f, name); - if (operands.size()) { - return map([=](const ::llvm::MDOperand& o) { - auto value = ::llvm::cast< ::llvm::ConstantAsMetadata>(o) - ->getValue(); - return ::llvm::cast< ::llvm::ConstantInt>(value) - ->getLimitedValue(UINT_MAX); - }, operands); - } else { - return {}; - } - } - - /// - /// Extract the string metadata node \p name. - /// - inline std::string - get_type_kernel_metadata(const ::llvm::Function &f, - const std::string &name) { - auto operands = detail::get_kernel_metadata_operands(f, name); - if (operands.size()) { - auto value = ::llvm::cast< ::llvm::ConstantAsMetadata>(operands[0]) - ->getValue(); - auto type = ::llvm::cast< ::llvm::UndefValue>(value) - ->getType(); - - value = ::llvm::cast< ::llvm::ConstantAsMetadata>(operands[1]) - ->getValue(); - bool is_signed = ::llvm::cast< ::llvm::ConstantInt>(value) - ->getLimitedValue(UINT_MAX); - - std::string data; - if (type->isIntOrIntVectorTy()) { - if (!is_signed) - data = "unsigned "; - - const auto size = type->getScalarSizeInBits(); - switch(size) { - case 8: - data += "char"; - break; - case 16: - data += "short"; - break; - case 32: - data += "int"; - break; - case 64: - data += "long"; - break; - } - if (compat::is_scalable_vector(type)) - throw build_error("hit unexpected scalable vector"); - if (compat::is_fixed_vector(type)) - data += std::to_string(compat::get_fixed_vector_elements(type)); - - } else { - ::llvm::raw_string_ostream os { data }; - type->print(os); - os.flush(); - } - - return data; - } else { - return ""; - } - } - - /// - /// Extract the string metadata node \p name corresponding to the kernel - /// argument given by \p arg. - /// - inline std::string - get_str_argument_metadata(const ::llvm::Function &f, - const ::llvm::Argument &arg, - const std::string &name) { - auto operands = detail::get_kernel_metadata_operands(f, name); - if (operands.size() > arg.getArgNo()) { - return ::llvm::cast< ::llvm::MDString>(operands[arg.getArgNo()]) - ->getString().str(); - } else { - return ""; - } - } - - /// - /// Extract the int metadata node \p name corresponding to the kernel - /// argument given by \p arg. - /// - inline uint64_t - get_uint_argument_metadata(const ::llvm::Function &f, - const ::llvm::Argument &arg, - const std::string &name) { - auto operands = detail::get_kernel_metadata_operands(f, name); - if (operands.size() >= arg.getArgNo()) { - auto meta_arg_value = ::llvm::cast< ::llvm::ConstantAsMetadata>( - operands[arg.getArgNo()])->getValue(); - return ::llvm::cast< ::llvm::ConstantInt>(meta_arg_value) - ->getLimitedValue(UINT_MAX); - } else { - return 0; - } - } - - /// - /// Return a vector with all CL kernel functions found in the LLVM - /// module \p mod. - /// - inline std::vector - get_kernels(const ::llvm::Module &mod) { - std::vector fs; - - for (auto &f : mod.getFunctionList()) { - if (detail::is_kernel(f)) - fs.push_back(&f); - } - - return fs; - } - } -} - -#endif diff --git a/src/gallium/frontends/clover/llvm/util.hpp b/src/gallium/frontends/clover/llvm/util.hpp deleted file mode 100644 index 7cd994bdc86..00000000000 --- a/src/gallium/frontends/clover/llvm/util.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_LLVM_UTIL_HPP -#define CLOVER_LLVM_UTIL_HPP - -#include "core/error.hpp" -#include "util/u_debug.h" - -#include -#include -#include - -namespace clover { - namespace llvm { - template void - fail(std::string &r_log, E &&e, const std::string &s) { - r_log += s; - throw std::forward(e); - } - - inline std::string - as_string(const std::vector &v) { - return { v.begin(), v.end() }; - } - - struct target { - target(const std::string &s) : - cpu(s.begin(), s.begin() + s.find_first_of("-")), - triple(s.begin() + s.find_first_of("-") + 1, s.end()) {} - - std::string cpu; - std::string triple; - }; - - namespace debug { - enum flag { - clc = 1 << 0, - llvm = 1 << 1, - native = 1 << 2, - spirv = 1 << 3, - }; - - inline bool - has_flag(flag f) { - static const struct debug_named_value debug_options[] = { - { "clc", clc, "Dump the OpenCL C code for all kernels." }, - { "llvm", llvm, "Dump the generated LLVM IR for all kernels." }, - { "native", native, "Dump kernel assembly code for targets " - "specifying PIPE_SHADER_IR_NATIVE" }, - { "spirv", spirv, "Dump the generated SPIR-V for all kernels." }, - DEBUG_NAMED_VALUE_END - }; - static const unsigned flags = - debug_get_flags_option("CLOVER_DEBUG", debug_options, 0); - - return flags & f; - } - - inline void - log(const std::string &suffix, const std::string &s) { - const std::string path = debug_get_option("CLOVER_DEBUG_FILE", - "stderr"); - if (path == "stderr") - std::cerr << s; - else - std::ofstream(path + suffix, std::ios::app) << s; - } - } - } -} - -#endif diff --git a/src/gallium/frontends/clover/meson.build b/src/gallium/frontends/clover/meson.build deleted file mode 100644 index 56a9894f0db..00000000000 --- a/src/gallium/frontends/clover/meson.build +++ /dev/null @@ -1,125 +0,0 @@ -# Copyright © 2017-2018 Intel Corporation -# SPDX-License-Identifier: MIT - -clover_cpp_args = [] -clover_opencl_cpp_args = [ - '-DCL_TARGET_OPENCL_VERSION=300', - '-DCL_USE_DEPRECATED_OPENCL_1_0_APIS', - '-DCL_USE_DEPRECATED_OPENCL_1_1_APIS', - '-DCL_USE_DEPRECATED_OPENCL_1_2_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_0_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_1_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_2_APIS', - '-DLIBCLC_LIBEXECDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'libexecdir')) -] -clover_incs = [inc_include, inc_src, inc_gallium, inc_gallium_aux] - -# the CL header files declare attributes on the CL types. Compilers warn if -# we use them as template arguments. Disable the warning as there isn't -# anything we can do about it -if cpp.has_argument('-Wno-ignored-attributes') - clover_cpp_args += '-Wno-ignored-attributes' -endif - -if with_opencl_icd - clover_cpp_args += '-DHAVE_CLOVER_ICD' -endif - -libclllvm = static_library( - 'clllvm', - files( - 'llvm/codegen/bitcode.cpp', - 'llvm/codegen/common.cpp', - 'llvm/codegen/native.cpp', - 'llvm/codegen.hpp', - 'llvm/compat.hpp', - 'llvm/invocation.cpp', - 'llvm/invocation.hpp', - 'llvm/metadata.hpp', - 'llvm/util.hpp', - ), - include_directories : clover_incs, - cpp_args : [ - clover_cpp_args, - clover_opencl_cpp_args, - '-DFALLBACK_CLANG_RESOURCE_DIR="@0@"'.format(join_paths( - dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir'), 'clang', - dep_llvm.version() - )), - ], - gnu_symbol_visibility : 'hidden', - dependencies : [dep_llvm, dep_elf, dep_llvmspirvlib, idep_mesautil], -) - -clover_files = files( - 'api/context.cpp', - 'api/device.cpp', - 'api/dispatch.cpp', - 'api/dispatch.hpp', - 'api/event.cpp', - 'api/interop.cpp', - 'api/invalid.cpp', - 'api/kernel.cpp', - 'api/memory.cpp', - 'api/platform.cpp', - 'api/program.cpp', - 'api/queue.cpp', - 'api/sampler.cpp', - 'api/transfer.cpp', - 'api/util.hpp', - 'core/binary.cpp', - 'core/binary.hpp', - 'core/compiler.hpp', - 'core/context.cpp', - 'core/context.hpp', - 'core/device.cpp', - 'core/device.hpp', - 'core/error.hpp', - 'core/event.cpp', - 'core/event.hpp', - 'core/format.cpp', - 'core/format.hpp', - 'core/kernel.cpp', - 'core/kernel.hpp', - 'core/memory.cpp', - 'core/memory.hpp', - 'core/object.hpp', - 'core/platform.cpp', - 'core/platform.hpp', - 'core/printf.cpp', - 'core/printf.hpp', - 'core/program.cpp', - 'core/program.hpp', - 'core/property.hpp', - 'core/queue.cpp', - 'core/queue.hpp', - 'core/resource.cpp', - 'core/resource.hpp', - 'core/sampler.cpp', - 'core/sampler.hpp', - 'core/timestamp.cpp', - 'core/timestamp.hpp', - 'util/adaptor.hpp', - 'util/algebra.hpp', - 'util/algorithm.hpp', - 'util/compat.hpp', - 'util/factor.hpp', - 'util/functional.hpp', - 'util/lazy.hpp', - 'util/pointer.hpp', - 'util/range.hpp', - 'util/tuple.hpp', -) - -libclover = static_library( - 'clover', - [clover_files, sha1_h], - include_directories : clover_incs, - cpp_args : [ - clover_opencl_cpp_args, - clover_cpp_args, - ], - gnu_symbol_visibility : 'hidden', - link_with : [libclllvm], - dependencies : [idep_mesautil, idep_nir], -) diff --git a/src/gallium/frontends/clover/util/adaptor.hpp b/src/gallium/frontends/clover/util/adaptor.hpp deleted file mode 100644 index 08601fc416b..00000000000 --- a/src/gallium/frontends/clover/util/adaptor.hpp +++ /dev/null @@ -1,184 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_ADAPTOR_HPP -#define CLOVER_UTIL_ADAPTOR_HPP - -#include - -#include "util/compat.hpp" -#include "util/tuple.hpp" -#include "util/pointer.hpp" -#include "util/functional.hpp" - -namespace clover { - namespace detail { - /// - /// Implementation of the iterator concept that transforms the - /// value of the source iterators \a Is on dereference by use of - /// a functor \a F. - /// - /// The exact category of the resulting iterator should be the - /// least common denominator of the source iterator categories. - /// - template - class iterator_adaptor { - public: - typedef std::forward_iterator_tag iterator_category; - typedef typename invoke_result< - F, typename std::iterator_traits::reference... - >::type reference; - typedef typename std::remove_reference::type value_type; - typedef pseudo_ptr pointer; - typedef std::ptrdiff_t difference_type; - - iterator_adaptor() { - } - - iterator_adaptor(F f, std::tuple &&its) : - f(f), its(std::move(its)) { - } - - reference - operator*() const { - return tuple::apply(f, tuple::map(derefs(), its)); - } - - iterator_adaptor & - operator++() { - tuple::map(preincs(), its); - return *this; - } - - iterator_adaptor - operator++(int) { - auto jt = *this; - ++*this; - return jt; - } - - bool - operator==(const iterator_adaptor &jt) const { - return its == jt.its; - } - - bool - operator!=(const iterator_adaptor &jt) const { - return its != jt.its; - } - - pointer - operator->() const { - return { **this }; - } - - iterator_adaptor & - operator--() { - tuple::map(predecs(), its); - return *this; - } - - iterator_adaptor - operator--(int) { - auto jt = *this; - --*this; - return jt; - } - - iterator_adaptor & - operator+=(difference_type n) { - tuple::map(advances_by(n), its); - return *this; - } - - iterator_adaptor & - operator-=(difference_type n) { - tuple::map(advances_by(-n), its); - return *this; - } - - iterator_adaptor - operator+(difference_type n) const { - auto jt = *this; - jt += n; - return jt; - } - - iterator_adaptor - operator-(difference_type n) const { - auto jt = *this; - jt -= n; - return jt; - } - - difference_type - operator-(const iterator_adaptor &jt) const { - return std::get<0>(its) - std::get<0>(jt.its); - } - - reference - operator[](difference_type n) const { - return *(*this + n); - } - - bool - operator<(iterator_adaptor &jt) const { - return *this - jt < 0; - } - - bool - operator>(iterator_adaptor &jt) const { - return *this - jt > 0; - } - - bool - operator>=(iterator_adaptor &jt) const { - return !(*this < jt); - } - - bool - operator<=(iterator_adaptor &jt) const { - return !(*this > jt); - } - - protected: - F f; - std::tuple its; - }; - - template - iterator_adaptor - operator+(typename iterator_adaptor::difference_type n, - const iterator_adaptor &jt) { - return (jt + n); - } - - template - iterator_adaptor - operator-(typename iterator_adaptor::difference_type n, - const iterator_adaptor &jt) { - return (jt - n); - } - } -} - -#endif diff --git a/src/gallium/frontends/clover/util/algebra.hpp b/src/gallium/frontends/clover/util/algebra.hpp deleted file mode 100644 index 43a9d8bbf5f..00000000000 --- a/src/gallium/frontends/clover/util/algebra.hpp +++ /dev/null @@ -1,160 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_ALGEBRA_HPP -#define CLOVER_UTIL_ALGEBRA_HPP - -#include - -#include "util/range.hpp" -#include "util/functional.hpp" - -namespace clover { - /// - /// Class that identifies vectors (in the linear-algebraic sense). - /// - /// There should be a definition of this class for each type that - /// makes sense as vector arithmetic operand. - /// - template - struct vector_traits; - - /// - /// References of vectors are vectors. - /// - template - struct vector_traits::enable> { - typedef void enable; - }; - - /// - /// Constant vectors are vectors. - /// - template - struct vector_traits::enable> { - typedef void enable; - }; - - /// - /// Arrays of arithmetic types are vectors. - /// - template - struct vector_traits, - typename std::enable_if< - std::is_arithmetic::value>::type> { - typedef void enable; - }; - - namespace detail { - template - struct are_defined { - typedef void enable; - }; - } - - /// - /// The result of mapping a vector is a vector. - /// - template - struct vector_traits, - typename detail::are_defined< - typename vector_traits::enable...>::enable> { - typedef void enable; - }; - - /// - /// Vector sum. - /// - template::enable, - typename = typename vector_traits::enable> - adaptor_range - operator+(U &&u, V &&v) { - return map(plus(), std::forward(u), std::forward(v)); - } - - /// - /// Vector difference. - /// - template::enable, - typename = typename vector_traits::enable> - adaptor_range - operator-(U &&u, V &&v) { - return map(minus(), std::forward(u), std::forward(v)); - } - - /// - /// Scalar multiplication. - /// - template::enable> - adaptor_range, U> - operator*(U &&u, T &&a) { - return map(multiplies_by(std::forward(a)), std::forward(u)); - } - - /// - /// Scalar multiplication. - /// - template::enable> - adaptor_range, U> - operator*(T &&a, U &&u) { - return map(multiplies_by(std::forward(a)), std::forward(u)); - } - - /// - /// Additive inverse. - /// - template::enable> - adaptor_range - operator-(U &&u) { - return map(negate(), std::forward(u)); - } - - namespace detail { - template - using dot_type = typename std::common_type< - typename std::remove_reference::type::value_type, - typename std::remove_reference::type::value_type - >::type; - } - - /// - /// Dot product of two vectors. - /// - /// It can also do matrix multiplication if \a u or \a v is a - /// vector of vectors. - /// - template::enable, - typename = typename vector_traits::enable> - detail::dot_type - dot(U &&u, V &&v) { - return fold(plus(), detail::dot_type(), - map(multiplies(), u, v)); - } -} - -#endif diff --git a/src/gallium/frontends/clover/util/algorithm.hpp b/src/gallium/frontends/clover/util/algorithm.hpp deleted file mode 100644 index 306c045cb2a..00000000000 --- a/src/gallium/frontends/clover/util/algorithm.hpp +++ /dev/null @@ -1,294 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_ALGORITHM_HPP -#define CLOVER_UTIL_ALGORITHM_HPP - -#include -#include -#include - -#include "util/range.hpp" -#include "util/functional.hpp" - -namespace clover { - namespace detail { - template - using preferred_reference_type = decltype(*std::declval().begin()); - } - - /// - /// Return the first element in a range. - /// - template - detail::preferred_reference_type - head(R &&r) { - assert(!r.empty()); - return r.front(); - } - - /// - /// Return all elements in a range but the first. - /// - template - slice_range - tail(R &&r) { - assert(!r.empty()); - return { std::forward(r), 1, r.size() }; - } - - /// - /// Return the only element in a range. - /// - template - detail::preferred_reference_type - unique(R &&r) { - if (r.size() != 1) - throw std::out_of_range(""); - - return r.front(); - } - - /// - /// Combine a variable number of ranges element-wise in a single - /// range of tuples. - /// - template - adaptor_range - zip(Rs &&... rs) { - return map(zips(), std::forward(rs)...); - } - - /// - /// Evaluate the elements of a range. - /// - /// Useful because most of the range algorithms evaluate their - /// result lazily. - /// - template - void - eval(R &&r) { - for (auto i = r.begin(), e = r.end(); i != e; ++i) - *i; - } - - /// - /// Apply functor \a f element-wise on a variable number of ranges - /// \a rs. - /// - /// The functor \a f should take as many arguments as ranges are - /// provided. - /// - template - void - for_each(F &&f, Rs &&... rs) { - eval(map(std::forward(f), std::forward(rs)...)); - } - - /// - /// Copy all elements from range \a r into an output container - /// starting from iterator \a i. - /// - template - void - copy(R &&r, I i) { - for (detail::preferred_reference_type x : r) - *(i++) = x; - } - - /// - /// Reduce the elements of range \a r by applying functor \a f - /// element by element. - /// - /// \a f should take an accumulator value (which is initialized to - /// \a a) and an element value as arguments, and return an updated - /// accumulator value. - /// - /// \returns The final value of the accumulator. - /// - template - A - fold(F &&f, A a, R &&r) { - for (detail::preferred_reference_type x : r) - a = f(a, x); - - return a; - } - - /// - /// Return how many elements of range \a r are equal to \a x. - /// - template - typename std::remove_reference::type::size_type - count(T &&x, R &&r) { - typename std::remove_reference::type::size_type n = 0; - - for (detail::preferred_reference_type y : r) { - if (x == y) - n++; - } - - return n; - } - - /// - /// Return the first element in range \a r for which predicate \a f - /// evaluates to true. - /// - template - detail::preferred_reference_type - find(F &&f, R &&r) { - for (detail::preferred_reference_type x : r) { - if (f(x)) - return x; - } - - throw std::out_of_range(""); - } - - /// - /// Return true if the element-wise application of predicate \a f - /// on \a rs evaluates to true for all elements. - /// - template - bool - all_of(F &&f, Rs &&... rs) { - for (auto b : map(f, rs...)) { - if (!b) - return false; - } - - return true; - } - - /// - /// Return true if the element-wise application of predicate \a f - /// on \a rs evaluates to true for any element. - /// - template - bool - any_of(F &&f, Rs &&... rs) { - for (auto b : map(f, rs...)) { - if (b) - return true; - } - - return false; - } - - /// - /// Erase elements for which predicate \a f evaluates to true from - /// container \a r. - /// - template - void - erase_if(F &&f, R &&r) { - auto i = r.begin(), e = r.end(); - - for (auto j = r.begin(); j != e; ++j) { - if (!f(*j)) { - if (j != i) - *i = std::move(*j); - ++i; - } - } - - r.erase(i, e); - } - - /// - /// Build a vector of string from a space separated string - /// quoted parts content is preserved and unquoted - /// - inline std::vector - tokenize(const std::string &s) { - std::vector ss; - std::ostringstream oss; - - // OpenCL programs can pass a quoted argument, most frequently the - // include path. This is useful so that path containing spaces is - // treated as a single argument instead of being split by the spaces. - // Additionally, the argument should also be unquoted before being - // passed to the compiler. We avoid using std::string::replace here to - // remove quotes, as the single and double quote characters can be a - // part of the file name. - bool escape_next = false; - bool in_quote_double = false; - bool in_quote_single = false; - - for (auto c : s) { - if (escape_next) { - oss.put(c); - escape_next = false; - } else if (c == '\\') { - escape_next = true; - } else if (c == '"' && !in_quote_single) { - in_quote_double = !in_quote_double; - } else if (c == '\'' && !in_quote_double) { - in_quote_single = !in_quote_single; - } else if (c != ' ' || in_quote_single || in_quote_double) { - oss.put(c); - } else if (oss.tellp() > 0) { - ss.emplace_back(oss.str()); - oss.str(""); - } - } - - if (oss.tellp() > 0) - ss.emplace_back(oss.str()); - - if (in_quote_double || in_quote_single) - throw invalid_build_options_error(); - - return ss; - } - - /// - /// Build a \a sep separated string from a vector of T - /// - template - std::string - detokenize(const std::vector &ss, const std::string &sep) { - std::string r; - - for (const auto &s : ss) - r += (r.empty() ? "" : sep) + std::to_string(s); - - return r; - } - - /// - /// Build a \a sep separated string from a vector of string - /// - template <> - inline std::string - detokenize(const std::vector &ss, const std::string &sep) { - std::string r; - - for (const auto &s : ss) - r += (r.empty() || s.empty() ? "" : sep) + s; - - return r; - } -} - -#endif diff --git a/src/gallium/frontends/clover/util/compat.hpp b/src/gallium/frontends/clover/util/compat.hpp deleted file mode 100644 index dd8db8d2c51..00000000000 --- a/src/gallium/frontends/clover/util/compat.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright © Microsoft Corporation -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_COMPAT_HPP -#define CLOVER_UTIL_COMPAT_HPP - -#include - -namespace clover { - template - struct invoke_result { -#if __cplusplus >= 201703L - typedef typename std::invoke_result< - F, Args... - >::type type; -#else - typedef typename std::result_of< - F(Args...) - >::type type; -#endif - }; -} - -#endif diff --git a/src/gallium/frontends/clover/util/factor.hpp b/src/gallium/frontends/clover/util/factor.hpp deleted file mode 100644 index 76d3bfe343f..00000000000 --- a/src/gallium/frontends/clover/util/factor.hpp +++ /dev/null @@ -1,131 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_FACTOR_HPP -#define CLOVER_UTIL_FACTOR_HPP - -#include "util/range.hpp" - -namespace clover { - namespace factor { - /// - /// Calculate all prime integer factors of \p x. - /// - /// If \p limit is non-zero, terminate early as soon as enough - /// factors have been collected to reach the product \p limit. - /// - template - std::vector - find_integer_prime_factors(T x, T limit = 0) - { - const T max_d = (limit > 0 && limit < x ? limit : x); - const T min_x = x / max_d; - std::vector factors; - - for (T d = 2; d <= max_d && x > min_x; d++) { - if (x % d == 0) { - for (; x % d == 0; x /= d); - factors.push_back(d); - } - } - - return factors; - } - - namespace detail { - /// - /// Walk the power set of prime factors of the n-dimensional - /// integer array \p grid subject to the constraints given by - /// \p limits. - /// - template - std::pair> - next_grid_factor(const std::pair> &limits, - const std::vector &grid, - const std::vector> &factors, - std::pair> block, - unsigned d = 0, unsigned i = 0) { - if (d >= factors.size()) { - // We're done. - return {}; - - } else if (i >= factors[d].size()) { - // We're done with this grid dimension, try the next. - return next_grid_factor(limits, grid, factors, - std::move(block), d + 1, 0); - - } else { - T f = factors[d][i]; - - // Try the next power of this factor. - block.first *= f; - block.second[d] *= f; - - if (block.first <= limits.first && - block.second[d] <= limits.second[d] && - grid[d] % block.second[d] == 0) { - // We've found a valid grid divisor. - return block; - - } else { - // Overflow, back off to the zeroth power, - while (block.second[d] % f == 0) { - block.second[d] /= f; - block.first /= f; - } - - // ...and carry to the next factor. - return next_grid_factor(limits, grid, factors, - std::move(block), d, i + 1); - } - } - } - } - - /// - /// Find the divisor of the integer array \p grid that gives the - /// highest possible product not greater than \p product_limit - /// subject to the constraints given by \p coord_limit. - /// - template - std::vector - find_grid_optimal_factor(T product_limit, - const std::vector &coord_limit, - const std::vector &grid) { - const std::vector> factors = - map(find_integer_prime_factors, grid, coord_limit); - const auto limits = std::make_pair(product_limit, coord_limit); - auto best = std::make_pair(T(1), std::vector(grid.size(), T(1))); - - for (auto block = best; - block.first != 0 && best.first != product_limit; - block = detail::next_grid_factor(limits, grid, factors, block)) { - if (block.first > best.first) - best = block; - } - - return best.second; - } - } -} - -#endif diff --git a/src/gallium/frontends/clover/util/functional.hpp b/src/gallium/frontends/clover/util/functional.hpp deleted file mode 100644 index 81bfa644352..00000000000 --- a/src/gallium/frontends/clover/util/functional.hpp +++ /dev/null @@ -1,428 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_FUNCTIONAL_HPP -#define CLOVER_UTIL_FUNCTIONAL_HPP - -#include - -namespace clover { - struct identity { - template - typename std::remove_reference::type - operator()(T &&x) const { - return x; - } - }; - - struct plus { - template - typename std::common_type::type - operator()(T x, S y) const { - return x + y; - } - }; - - struct minus { - template - typename std::common_type::type - operator()(T x, S y) const { - return x - y; - } - }; - - struct negate { - template - T - operator()(T x) const { - return -x; - } - }; - - struct multiplies { - template - typename std::common_type::type - operator()(T x, S y) const { - return x * y; - } - }; - - struct divides { - template - typename std::common_type::type - operator()(T x, S y) const { - return x / y; - } - }; - - struct modulus { - template - typename std::common_type::type - operator()(T x, S y) const { - return x % y; - } - }; - - struct minimum { - template - T - operator()(T x) const { - return x; - } - - template - T - operator()(T x, Ts... xs) const { - T y = minimum()(xs...); - return x < y ? x : y; - } - }; - - struct maximum { - template - T - operator()(T x) const { - return x; - } - - template - T - operator()(T x, Ts... xs) const { - T y = maximum()(xs...); - return x < y ? y : x; - } - }; - - struct preincs { - template - T & - operator()(T &x) const { - return ++x; - } - }; - - struct predecs { - template - T & - operator()(T &x) const { - return --x; - } - }; - - template - class multiplies_by_t { - public: - multiplies_by_t(T x) : x(x) { - } - - template - typename std::common_type::type - operator()(S y) const { - return x * y; - } - - private: - T x; - }; - - template - multiplies_by_t - multiplies_by(T x) { - return { x }; - } - - template - class preincs_by_t { - public: - preincs_by_t(T n) : n(n) { - } - - template - S & - operator()(S &x) const { - return x += n; - } - - private: - T n; - }; - - template - preincs_by_t - preincs_by(T n) { - return { n }; - } - - template - class predecs_by_t { - public: - predecs_by_t(T n) : n(n) { - } - - template - S & - operator()(S &x) const { - return x -= n; - } - - private: - T n; - }; - - template - predecs_by_t - predecs_by(T n) { - return { n }; - } - - struct greater { - template - bool - operator()(T x, S y) const { - return x > y; - } - }; - - struct evals { - template - auto - operator()(T &&x) const -> decltype(x()) { - return x(); - } - }; - - struct derefs { - template - auto - operator()(T &&x) const -> decltype(*x) { - return *x; - } - }; - - struct addresses { - template - T * - operator()(T &x) const { - return &x; - } - - template - T * - operator()(std::reference_wrapper x) const { - return &x.get(); - } - }; - - struct begins { - template - auto - operator()(T &x) const -> decltype(x.begin()) { - return x.begin(); - } - }; - - struct ends { - template - auto - operator()(T &x) const -> decltype(x.end()) { - return x.end(); - } - }; - - struct sizes { - template - auto - operator()(T &x) const -> decltype(x.size()) { - return x.size(); - } - }; - - template - class advances_by_t { - public: - advances_by_t(T n) : n(n) { - } - - template - S - operator()(S &&it) const { - std::advance(it, n); - return std::forward(it); - } - - private: - T n; - }; - - template - advances_by_t - advances_by(T n) { - return { n }; - } - - struct zips { - template - std::tuple - operator()(Ts &&... xs) const { - return std::tuple(std::forward(xs)...); - } - }; - - struct is_zero { - template - bool - operator()(const T &x) const { - return x == 0; - } - }; - - struct keys { - template - auto - operator()(P &&p) const -> decltype(std::get<0>(std::forward

(p))) { - return std::get<0>(std::forward

(p)); - } - }; - - struct values { - template - auto - operator()(P &&p) const -> decltype(std::get<1>(std::forward

(p))) { - return std::get<1>(std::forward

(p)); - } - }; - - template - class equals_t { - public: - equals_t(T &&x) : x(x) {} - - template - bool - operator()(S &&y) const { - return x == y; - } - - private: - T x; - }; - - template - equals_t - equals(T &&x) { - return { std::forward(x) }; - } - - class name_equals { - public: - name_equals(const std::string &name) : name(name) { - } - - template - bool - operator()(const T &x) const { - return std::string(x.name.begin(), x.name.end()) == name; - } - - private: - const std::string &name; - }; - - template - class key_equals_t { - public: - key_equals_t(T &&x) : x(x) { - } - - template - bool - operator()(const P &p) const { - return p.first == x; - } - - private: - T x; - }; - - template - key_equals_t - key_equals(T &&x) { - return { std::forward(x) }; - } - - template - class type_equals_t { - public: - type_equals_t(T type) : type(type) { - } - - template - bool - operator()(const S &x) const { - return x.type == type; - } - - private: - T type; - }; - - template - type_equals_t - type_equals(T x) { - return { x }; - } - - template - class id_type_equals_t { - public: - id_type_equals_t(const uint32_t id, T t) : - id(id), type(t) { - } - - template - bool - operator()(const X &x) const { - return id == x.id && type(x); - } - - private: - const uint32_t id; - type_equals_t type; - }; - - template - id_type_equals_t - id_type_equals(const uint32_t id, T x) { - return { id, x }; - } - - struct interval_overlaps { - template - bool - operator()(T x0, T x1, T y0, T y1) { - return ((x0 <= y0 && y0 < x1) || - (y0 <= x0 && x0 < y1)); - } - }; -} - -#endif diff --git a/src/gallium/frontends/clover/util/lazy.hpp b/src/gallium/frontends/clover/util/lazy.hpp deleted file mode 100644 index e32a8f8b1b9..00000000000 --- a/src/gallium/frontends/clover/util/lazy.hpp +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_LAZY_HPP -#define CLOVER_UTIL_LAZY_HPP - -#include -#include -#include - -namespace clover { - namespace detail { - template - class basic_lazy { - public: - virtual - ~basic_lazy() { - } - - virtual basic_lazy * - clone() const = 0; - - virtual - operator T() const = 0; - }; - - template - class deferred_lazy : public basic_lazy { - public: - template - deferred_lazy(G &&f) : f(new F(std::forward(f))) { - } - - virtual basic_lazy * - clone() const { - return new deferred_lazy(*this); - } - - operator T() const { - if (f) { - x = (*f)(); - f = {}; - } - - return x; - } - - private: - mutable std::shared_ptr f; - mutable T x; - }; - - template - class strict_lazy : public basic_lazy { - public: - template - strict_lazy(S &&x) : x(std::forward(x)) { - } - - virtual basic_lazy * - clone() const { - return new strict_lazy(*this); - } - - operator T() const { - return x; - } - - private: - T x; - }; - } - - /// - /// Object that represents a value of type \a T that is calculated - /// lazily as soon as it is required. - /// - template - class lazy { - public: - class undefined_error : std::logic_error { - public: - undefined_error() : std::logic_error("") { - } - }; - - /// - /// Initialize to some fixed value \a x which isn't calculated - /// lazily. - /// - lazy(T x) : obj(new detail::strict_lazy(x)) { - } - - /// - /// Initialize by providing a functor \a f that will calculate - /// the value on-demand. - /// - template - lazy(F &&f) : obj(new detail::deferred_lazy< - T, typename std::remove_reference::type - >(std::forward(f))) { - } - - /// - /// Initialize to undefined. - /// - lazy() : lazy([]() { - throw undefined_error(); - return T(); - }) { - } - - lazy(const lazy &other) : obj(obj->clone()) { - } - - lazy(lazy &&other) : obj(NULL) { - std::swap(obj, other.obj); - } - - ~lazy() { - delete obj; - } - - lazy & - operator=(lazy other) { - std::swap(obj, other.obj); - return *this; - } - - /// - /// Evaluate the value. - /// - operator T() const { - return *obj; - } - - private: - detail::basic_lazy *obj; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/util/pointer.hpp b/src/gallium/frontends/clover/util/pointer.hpp deleted file mode 100644 index 7bb9951aef6..00000000000 --- a/src/gallium/frontends/clover/util/pointer.hpp +++ /dev/null @@ -1,284 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_POINTER_HPP -#define CLOVER_UTIL_POINTER_HPP - -#include - -namespace clover { - /// - /// Some helper functions for raw pointer operations - /// - template - static bool - ptr_is_aligned(const T *ptr, uintptr_t a) noexcept { - assert(a == (a & -a)); - uintptr_t ptr_value = reinterpret_cast(ptr); - return (ptr_value & (a - 1)) == 0; - } - - /// - /// Base class for objects that support reference counting. - /// - class ref_counter { - public: - ref_counter(unsigned value = 1) : _ref_count(value) {} - - unsigned - ref_count() const { - return _ref_count; - } - - void - retain() { - _ref_count++; - } - - bool - release() { - return (--_ref_count) == 0; - } - - private: - std::atomic _ref_count; - }; - - /// - /// Simple reference to a clover::ref_counter object. Unlike - /// clover::intrusive_ptr and clover::intrusive_ref, it does nothing - /// special when the reference count drops to zero. - /// - class ref_holder { - public: - ref_holder(ref_counter &o) : p(&o) { - p->retain(); - } - - ref_holder(const ref_holder &ref) : - ref_holder(*ref.p) { - } - - ref_holder(ref_holder &&ref) : - p(ref.p) { - ref.p = NULL; - } - - ~ref_holder() { - if (p) - p->release(); - } - - ref_holder & - operator=(ref_holder ref) { - std::swap(ref.p, p); - return *this; - } - - bool - operator==(const ref_holder &ref) const { - return p == ref.p; - } - - bool - operator!=(const ref_holder &ref) const { - return p != ref.p; - } - - private: - ref_counter *p; - }; - - /// - /// Intrusive smart pointer for objects that implement the - /// clover::ref_counter interface. - /// - template - class intrusive_ptr { - public: - intrusive_ptr(T *q = NULL) : p(q) { - if (p) - p->retain(); - } - - intrusive_ptr(const intrusive_ptr &ptr) : - intrusive_ptr(ptr.p) { - } - - intrusive_ptr(intrusive_ptr &&ptr) : - p(ptr.p) { - ptr.p = NULL; - } - - ~intrusive_ptr() { - if (p && p->release()) - delete p; - } - - intrusive_ptr & - operator=(intrusive_ptr ptr) { - std::swap(ptr.p, p); - return *this; - } - - bool - operator==(const intrusive_ptr &ref) const { - return p == ref.p; - } - - bool - operator!=(const intrusive_ptr &ref) const { - return p != ref.p; - } - - T & - operator*() const { - return *p; - } - - T * - operator->() const { - return p; - } - - T * - operator()() const { - return p; - } - - explicit operator bool() const { - return p; - } - - explicit operator T *() const { - return p; - } - - private: - T *p; - }; - - /// - /// Intrusive smart reference for objects that implement the - /// clover::ref_counter interface. - /// - template - class intrusive_ref { - public: - intrusive_ref(T &o) : p(&o) { - p->retain(); - } - - intrusive_ref(const intrusive_ref &ref) : - intrusive_ref(*ref.p) { - } - - intrusive_ref(intrusive_ref &&ref) : - p(ref.p) { - ref.p = NULL; - } - - ~intrusive_ref() { - if (p && p->release()) - delete p; - } - - intrusive_ref & - operator=(intrusive_ref ref) { - std::swap(ref.p, p); - return *this; - } - - bool - operator==(const intrusive_ref &ref) const { - return p == ref.p; - } - - bool - operator!=(const intrusive_ref &ref) const { - return p != ref.p; - } - - T & - operator()() const { - return *p; - } - - operator T &() const { - return *p; - } - - private: - T *p; - }; - - /// - /// Initialize a clover::intrusive_ref from a newly created object - /// using the specified constructor arguments. - /// - template - intrusive_ref - create(As &&... as) { - intrusive_ref ref { *new T(std::forward(as)...) }; - ref().release(); - return ref; - } - - /// - /// Class that implements the usual pointer interface but in fact - /// contains the object it seems to be pointing to. - /// - template - class pseudo_ptr { - public: - pseudo_ptr(T x) : x(x) { - } - - pseudo_ptr(const pseudo_ptr &p) : x(p.x) { - } - - pseudo_ptr & - operator=(const pseudo_ptr &p) { - x = p.x; - return *this; - } - - T & - operator*() { - return x; - } - - T * - operator->() { - return &x; - } - - explicit operator bool() const { - return true; - } - - private: - T x; - }; -} - -#endif diff --git a/src/gallium/frontends/clover/util/range.hpp b/src/gallium/frontends/clover/util/range.hpp deleted file mode 100644 index b082359ee86..00000000000 --- a/src/gallium/frontends/clover/util/range.hpp +++ /dev/null @@ -1,419 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_RANGE_HPP -#define CLOVER_UTIL_RANGE_HPP - -#include -#include - -#include "util/adaptor.hpp" - -namespace clover { - /// - /// Class that identifies container types where the elements of a - /// range can be stored by the type conversion operator. - /// - /// \a T identifies the range element type. - /// - template - struct range_store_traits; - - template - struct range_store_traits> { - typedef void enable; - - template - static std::vector - create(const R &r) { - return { r.begin(), r.end() }; - } - }; - - template - struct range_store_traits> { - typedef void enable; - - template - static std::array - create(const R &r) { - std::array v; - assert(r.size() == v.size()); - copy(r, v.begin()); - return v; - } - }; - - namespace detail { - /// - /// Common functionality that is shared by other implementations - /// of the container concept. - /// - template - class basic_range { - public: - typedef I iterator; - typedef CI const_iterator; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference - reference; - typedef typename std::iterator_traits::reference - const_reference; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef std::size_t size_type; - - bool - operator==(const basic_range &r) const { - return *static_cast(this) == r; - } - - bool - operator!=(const basic_range &r) const { - return !(*this == r); - } - - iterator - begin() { - return static_cast(this)->begin(); - } - - iterator - end() { - return static_cast(this)->end(); - } - - const_iterator - begin() const { - return static_cast(this)->begin(); - } - - const_iterator - end() const { - return static_cast(this)->end(); - } - - std::reverse_iterator - rbegin() { - return { begin() }; - } - - std::reverse_iterator - rend() { - return { end() }; - } - - reference - front() { - return *begin(); - } - - reference - back() { - return *(end() - 1); - } - - bool - empty() const { - return begin() == end(); - } - - reference - at(size_type i) { - if (i >= static_cast(this)->size()) - throw std::out_of_range(""); - - return begin()[i]; - } - - const_reference - at(size_type i) const { - if (i >= static_cast(this)->size()) - throw std::out_of_range(""); - - return begin()[i]; - } - - reference - operator[](size_type i) { - return begin()[i]; - } - - const_reference - operator[](size_type i) const { - return begin()[i]; - } - - template - using store_traits = range_store_traits< - typename std::remove_cv::type, V - >; - - template::enable> - operator V() const { - return store_traits::create(*static_cast(this)); - } - }; - } - - /// - /// Range that contains all elements delimited by an iterator pair - /// (\a i, \a j). Use range() as convenience constructor. - /// - template - class iterator_range : public detail::basic_range, I, I> { - public: - typedef detail::basic_range, I, I> super; - - iterator_range() : i(), j() { - } - - iterator_range(I i, I j) : i(i), j(j) { - } - - bool - operator==(const iterator_range &r) const { - return i == r.i && j == r.j; - } - - I - begin() const { - return i; - } - - I - end() const { - return j; - } - - typename super::size_type - size() const { - return end() - begin(); - } - - private: - I i, j; - }; - - namespace detail { - template - using preferred_iterator_type = decltype(std::declval().begin()); - } - - /// - /// Range that transforms the contents of a number of source ranges - /// \a os element-wise by using the provided functor \a f. Use - /// map() as convenience constructor. - /// - template - class adaptor_range : - public detail::basic_range, - detail::iterator_adaptor< - F, detail::preferred_iterator_type...>, - detail::iterator_adaptor< - F, detail::preferred_iterator_type...> - > { - public: - typedef detail::basic_range, - detail::iterator_adaptor< - F, detail::preferred_iterator_type...>, - detail::iterator_adaptor< - F, detail::preferred_iterator_type...> - > super; - - template - adaptor_range(G &&f, Rs &&... os) : - f(std::forward(f)), os(std::forward(os)...) { - } - - bool - operator==(const adaptor_range &r) const { - return f == r.f && os == r.os; - } - - typename super::iterator - begin() { - return { f, tuple::map(begins(), os) }; - } - - typename super::iterator - end() { - return { f, tuple::map(advances_by(size()), - tuple::map(begins(), os)) }; - } - - typename super::const_iterator - begin() const { - return { f, tuple::map(begins(), os) }; - } - - typename super::const_iterator - end() const { - return { f, tuple::map(advances_by(size()), - tuple::map(begins(), os)) }; - } - - typename super::size_type - size() const { - return tuple::apply(minimum(), tuple::map(sizes(), os)); - } - - private: - F f; - std::tuple os; - }; - - /// - /// Range that contains all elements delimited by the index pair - /// (\a i, \a j) in the source range \a r. Use slice() as - /// convenience constructor. - /// - template - class slice_range : - public detail::basic_range, - detail::preferred_iterator_type, - detail::preferred_iterator_type> { - public: - typedef detail::basic_range, - detail::preferred_iterator_type, - detail::preferred_iterator_type - > super; - - template - slice_range(R &&r, typename super::size_type i, - typename super::size_type j) : - o(std::forward(r)), i(i), j(j) { - } - - bool - operator==(const slice_range &r) const { - return o == r.o && i == r.i && j == r.j; - } - - typename super::iterator - begin() { - return std::next(o.begin(), i); - } - - typename super::iterator - end() { - return std::next(o.begin(), j); - } - - typename super::const_iterator - begin() const { - return std::next(o.begin(), i); - } - - typename super::const_iterator - end() const { - return std::next(o.begin(), j); - } - - typename super::size_type - size() const { - return j - i; - } - - private: - O o; - typename super::size_type i, j; - }; - - /// - /// Create a range from an iterator pair (\a i, \a j). - /// - /// \sa iterator_range. - /// - template - iterator_range - range(T i, T j) { - return { i, j }; - } - - /// - /// Create a range of \a n elements starting from iterator \a i. - /// - /// \sa iterator_range. - /// - template - iterator_range - range(T i, typename std::iterator_traits::difference_type n) { - return { i, i + n }; - } - - /// - /// Create a range by transforming the contents of a number of - /// source ranges \a rs element-wise using a provided functor \a f. - /// - /// \sa adaptor_range. - /// - template - adaptor_range - map(F &&f, Rs &&... rs) { - return { std::forward(f), std::forward(rs)... }; - } - - /// - /// Create a range identical to another range \a r. - /// - template - adaptor_range - range(R &&r) { - return { identity(), std::forward(r) }; - } - - /// - /// Create a range by taking the elements delimited by the index - /// pair (\a i, \a j) in a source range \a r. - /// - /// \sa slice_range. - /// - template - slice_range - slice(R &&r, typename slice_range::size_type i, - typename slice_range::size_type j) { - return { std::forward(r), i, j }; - } - - /// - /// Range that behaves as a vector of references of type \a T. - /// - /// Useful because STL containers cannot contain references to - /// objects as elements. - /// - template - class ref_vector : public adaptor_range> { - public: - ref_vector(std::initializer_list> il) : - adaptor_range>(derefs(), map(addresses(), il)) { - } - - template - ref_vector(R &&r) : adaptor_range>( - derefs(), map(addresses(), std::forward(r))) { - } - }; -} - -#endif diff --git a/src/gallium/frontends/clover/util/tuple.hpp b/src/gallium/frontends/clover/util/tuple.hpp deleted file mode 100644 index bd49684a314..00000000000 --- a/src/gallium/frontends/clover/util/tuple.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_TUPLE_HPP -#define CLOVER_UTIL_TUPLE_HPP - -#include - -namespace clover { - namespace tuple { - /// - /// Static sequence of integers. - /// - template - struct integral_sequence; - - /// - /// Static sequence containing all integers from 0 to N-1. - /// - template - struct enumerate { - typedef typename enumerate::type - type; - }; - - template - struct enumerate<0, Is...> { - typedef integral_sequence type; - }; - - namespace detail { - template::type>::value - >::type> - struct _apply; - - template - struct _apply> { - typedef typename std::remove_reference::type func_type; - typedef decltype( - std::declval()(std::get(std::declval())...) - ) value_type; - - static value_type - eval(F &&f, T &&t) { - return f(std::get(std::forward(t))...); - } - }; - } - - /// - /// Evaluate function \a f with the elements of tuple \a t - /// expanded as arguments. - /// - template - typename detail::_apply::value_type - apply(F &&f, T &&t) { - return detail::_apply::eval(std::forward(f), - std::forward(t)); - } - - namespace detail { - template::type>::value - >::type> - struct _map; - - template - struct _map> { - typedef typename std::remove_reference::type func_type; - typedef std::tuple< - decltype(std::declval()( - std::get(std::declval())))... - > value_type; - - static value_type - eval(F &&f, T &&t) { - return value_type(f(std::get(std::forward(t)))...); - } - }; - } - - /// - /// Evaluate function \a f on each element of the tuple \a t and - /// return the resulting values as a new tuple. - /// - template - typename detail::_map::value_type - map(F &&f, T &&t) { - return detail::_map::eval(std::forward(f), - std::forward(t)); - } - } -} - -#endif diff --git a/src/gallium/meson.build b/src/gallium/meson.build index 4d06365c7ea..4928f5c8d24 100644 --- a/src/gallium/meson.build +++ b/src/gallium/meson.build @@ -195,15 +195,6 @@ if with_gallium_d3d12 else driver_d3d12 = declare_dependency() endif -if with_gallium_clover or with_tests - # At the moment, clover and gallium/tests are the only two consumers - # for pipe-loader - subdir('targets/pipe-loader') -endif -if with_gallium_clover - subdir('frontends/clover') - subdir('targets/opencl') -endif if with_gallium_rusticl subdir('frontends/rusticl') subdir('targets/rusticl') diff --git a/src/gallium/targets/opencl/mesa.icd.in b/src/gallium/targets/opencl/mesa.icd.in deleted file mode 100644 index 1b77b4e4929..00000000000 --- a/src/gallium/targets/opencl/mesa.icd.in +++ /dev/null @@ -1 +0,0 @@ -lib@OPENCL_LIBNAME@.so.@OPENCL_VERSION@ diff --git a/src/gallium/targets/opencl/meson.build b/src/gallium/targets/opencl/meson.build deleted file mode 100644 index ab2c83556a8..00000000000 --- a/src/gallium/targets/opencl/meson.build +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright © 2017 Intel Corporation -# SPDX-License-Identifier: MIT - -opencl_link_args = [] -opencl_link_deps = [] -opencl_version = '1' - -if with_ld_version_script - opencl_link_args += [ - '-Wl,--version-script', join_paths(meson.current_source_dir(), 'opencl.sym') - ] - opencl_link_deps += files('opencl.sym') -endif - -llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir') -opencl_libname = with_opencl_icd ? 'MesaOpenCL' : 'OpenCL' - -polly_dep = null_dep -polly_isl_dep = null_dep -if dep_llvm.version().version_compare('>=10.0.0') - polly_dep = cpp.find_library('Polly', dirs : llvm_libdir, required : false) - polly_isl_dep = cpp.find_library('PollyISL', dirs : llvm_libdir, required : false) -endif - -ocldef_in = files(opencl_libname + '.def.in')[0] -ocldef = custom_target( - 'ocldef.def', - input: ocldef_in, - output : 'ocldef.def', - command : gen_vs_module_defs_normal_command, -) - -libopencl = shared_library( - opencl_libname, - [], - vs_module_defs : ocldef, - link_args : [ld_args_gc_sections, opencl_link_args], - link_depends : opencl_link_deps, - link_whole : libclover, - link_with : [libpipe_loader_dynamic, libgallium], - dependencies : [ - idep_mesautil, - dep_clock, dep_dl, dep_unwind, dep_elf, dep_clang, polly_dep, polly_isl_dep, dep_version - ], - name_prefix : host_machine.system() == 'windows' ? '' : [], # otherwise mingw will create libOpenCL-1.dll or libMesaOpenCL-1.dll - version : '@0@.0.0'.format(opencl_version), - soversion : host_machine.system() == 'windows' ? '' : opencl_version, - install : true, -) - -if with_opencl_icd - _config = configuration_data() - _config.set('OPENCL_LIBNAME', 'MesaOpenCL') - _config.set('OPENCL_VERSION', opencl_version) - configure_file( - configuration : _config, - input : 'mesa.icd.in', - output : 'mesa.icd', - install : true, - install_tag : 'runtime', - install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'), - ) - - # .so is hardcoded in the icd as well - devenv.prepend( - 'OCL_ICD_FILENAMES', - meson.current_build_dir() / 'libMesaOpenCL.so.@0@'.format(opencl_version) - ) -endif diff --git a/src/gallium/targets/opencl/opencl.sym b/src/gallium/targets/opencl/opencl.sym deleted file mode 100644 index 9fcc57692b8..00000000000 --- a/src/gallium/targets/opencl/opencl.sym +++ /dev/null @@ -1,7 +0,0 @@ -{ - global: - cl*; - opencl_dri_*; - local: - *; -};