Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions GPU/Common/GPUCommonDefAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,15 @@
#define get_group_id(dim) (blockIdx.x)
#elif defined(__OPENCL__)
// Using OpenCL defaults
#elif defined(__METAL__)
// MSL has no work-item builtins; these come in as kernel attributes, declared
// by GPUCA_KRNL_GRID_ARGS on every entry point.
#define get_global_id(dim) (_metalTgIg * _metalTPerTg + _metalTiTg)
#define get_global_size(dim) (_metalTPerTg * _metalTgPerG)
#define get_num_groups(dim) (_metalTgPerG)
#define get_local_id(dim) (_metalTiTg)
#define get_local_size(dim) (_metalTPerTg)
#define get_group_id(dim) (_metalTgIg)
#else
#define get_global_id(dim) iBlock
#define get_global_size(dim) nBlocks
Expand Down
11 changes: 10 additions & 1 deletion GPU/GPUTracking/Base/GPUReconstructionKernelMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,17 @@
#define GPUCA_ATTRRES(...) GPUCA_M_EXPAND(GPUCA_M_CAT(GPUCA_ATTRRES_, GPUCA_M_FIRST(__VA_ARGS__)))(__VA_ARGS__)

// GPU Kernel entry point
// MSL requires every kernel parameter to carry an attribute, and supplies the
// grid dimensions the same way, so the backend gets to shape both ends of the
// parameter list.
#ifndef GPUCA_KRNL_SECTOR_ARG
#define GPUCA_KRNL_SECTOR_ARG int32_t _iSector_internal

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why you need a special treatment for the sector variable in metal?
The sector variable is a normal variable, which is passed in like any other parameter to function calls.

#endif
#ifndef GPUCA_KRNL_GRID_ARGS
#define GPUCA_KRNL_GRID_ARGS
#endif
#define GPUCA_KRNLGPU_DEF(x_class, x_attributes, x_arguments, ...) \
GPUg() void GPUCA_ATTRRES(GPUCA_M_STRIP(x_attributes)) GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class))(GPUCA_CONSMEM_PTR int32_t _iSector_internal GPUCA_M_STRIP(x_arguments))
GPUg() void GPUCA_ATTRRES(GPUCA_M_STRIP(x_attributes)) GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class))(GPUCA_CONSMEM_PTR GPUCA_KRNL_SECTOR_ARG GPUCA_M_STRIP(x_arguments) GPUCA_KRNL_GRID_ARGS)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, but this means that you pass in local and global id and size as argument to the kernel function.
However, in OpenCL / CUDA / HIP, these varaibles are available everywhere, without being passed in.
I.e., they are also available in subfunctions. And I don't want to pass them in explicitly to each place where they are used. Is this somehow possible with metal?


#ifdef GPUCA_KRNL_DEFONLY
#define GPUCA_KRNLGPU(...) GPUCA_KRNLGPU_DEF(__VA_ARGS__);
Expand Down
10 changes: 10 additions & 0 deletions GPU/GPUTracking/Base/metal/GPUReconstructionMETAL.metal
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ using namespace metal;
device char* pConstantRaw [[buffer(1)]],
#define GPUCA_CONSMEM (*(device GPUConstantMem*)pConstantRaw)

// Every kernel parameter needs an attribute, so the sector index arrives as a
// buffer rather than by value, and the grid dimensions come in at the end, where
// GPUCommonDefAPI.h's get_group_id() and friends pick them up.
#define GPUCA_KRNL_SECTOR_ARG constant int32_t& _iSector_internal [[buffer(2)]]
#define GPUCA_KRNL_GRID_ARGS \
, uint _metalTgIg [[threadgroup_position_in_grid]] \
, uint _metalTiTg [[thread_position_in_threadgroup]] \
, uint _metalTPerTg [[threads_per_threadgroup]] \
, uint _metalTgPerG [[threadgroups_per_grid]]

#include "GPUReconstructionKernelList.h"

// clang-format on
Expand Down
Loading