MCPcopy Create free account
hub / github.com/ROCm/clr / FindLocalWorkSize

Method FindLocalWorkSize

rocclr/device/devkernel.cpp:667–752  ·  view source on GitHub ↗

================================================================================================

Source from the content-addressed store, hash-verified

665
666// ================================================================================================
667void Kernel::FindLocalWorkSize(size_t workDim, const amd::NDRange& gblWorkSize,
668 amd::NDRange& lclWorkSize) const {
669 // Initialize the default workgoup info
670 // Check if the kernel has the compiled sizes
671 if (workGroupInfo()->compileSize_[0] == 0) {
672 // Find the default local workgroup size, if it wasn't specified
673 if (lclWorkSize[0] == 0) {
674 // Find threads per group
675 size_t thrPerGrp = workGroupInfo()->size_;
676
677 // Check if kernel uses images
678 if (flags_.imageEna_ &&
679 // and thread group is a multiple value of wavefronts
680 ((thrPerGrp % workGroupInfo()->wavefrontSize_) == 0) &&
681 // and it's 2 or 3-dimensional workload
682 (workDim > 1) && (((gblWorkSize[0] % 16) == 0) && ((gblWorkSize[1] % 16) == 0))) {
683 // Use 8x8 workgroup size if kernel has image writes
684 if (flags_.imageWriteEna_ || (thrPerGrp != device().info().preferredWorkGroupSize_)) {
685 lclWorkSize[0] = 8;
686 lclWorkSize[1] = 8;
687 } else {
688 lclWorkSize[0] = 16;
689 lclWorkSize[1] = 16;
690 }
691 if (workDim == 3) {
692 lclWorkSize[2] = 1;
693 }
694 } else {
695 size_t tmp = thrPerGrp;
696 // Split the local workgroup into the most efficient way
697 for (uint d = 0; d < workDim; ++d) {
698 size_t div = tmp;
699 for (; (gblWorkSize[d] % div) != 0; div--);
700 lclWorkSize[d] = div;
701 tmp /= div;
702 }
703
704 if (!workGroupInfo()->uniformWorkGroupSize_) {
705 // Assuming DWORD access
706 const uint cacheLineMatch = device().info().globalMemCacheLineSize_ >> 2;
707
708 // Check if we couldn't find optimal workload
709 if (((lclWorkSize.product() % workGroupInfo()->wavefrontSize_) != 0) ||
710 // or size is too small for the cache line
711 (lclWorkSize[0] < cacheLineMatch)) {
712 size_t maxSize = 0;
713 size_t maxDim = 0;
714 for (uint d = 0; d < workDim; ++d) {
715 if (maxSize < gblWorkSize[d]) {
716 maxSize = gblWorkSize[d];
717 maxDim = d;
718 }
719 }
720 // Use X dimension as high priority. Runtime will assume that
721 // X dimension is more important for the address calculation
722 if ((maxDim != 0) && (gblWorkSize[0] >= (cacheLineMatch / 2))) {
723 lclWorkSize[0] = cacheLineMatch;
724 thrPerGrp /= cacheLineMatch;

Callers 1

submitKernelInternalMethod · 0.80

Calls 2

productMethod · 0.80
infoMethod · 0.45

Tested by

no test coverage detected