Skip to content

Commit

Permalink
Implement SPV_INTEL_fpga_cluster_attributes extension
Browse files Browse the repository at this point in the history
This extension adds a decoration, applicable on functions, that
statically-scheduled clusters should handle stalls using a
stall-enable signal to freeze computation within the cluster.

Spec: KhronosGroup/SPIRV-Registry#85

Signed-off-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
  • Loading branch information
MrSidims committed Nov 30, 2020
1 parent 66e4aa8 commit 7f2d2cb
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 8 deletions.
1 change: 1 addition & 0 deletions include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ EXT(SPV_INTEL_fpga_buffer_location)
EXT(SPV_INTEL_arbitrary_precision_fixed_point)
EXT(SPV_INTEL_arbitrary_precision_floating_point)
EXT(SPV_INTEL_variable_length_array)
EXT(SPV_INTEL_fpga_cluster_attributes)
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ const static char MaxWGSize[] = "max_work_group_size";
const static char NoGlobalOffset[] = "no_global_work_offset";
const static char MaxWGDim[] = "max_global_work_dim";
const static char NumSIMD[] = "num_simd_work_items";
const static char StallEnable[] = "stall_enable";
} // namespace kSPIR2MD

enum Spir2SamplerKind {
Expand Down
10 changes: 10 additions & 0 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3865,6 +3865,7 @@ bool SPIRVToLLVM::transMetadata() {

transOCLMetadata(BF);
transVectorComputeMetadata(BF);
transFPGAFunctionMetadata(BF, F);

if (F->getCallingConv() != CallingConv::SPIR_KERNEL)
continue;
Expand Down Expand Up @@ -4169,6 +4170,15 @@ bool SPIRVToLLVM::transVectorComputeMetadata(SPIRVFunction *BF) {
return true;
}

bool SPIRVToLLVM::transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F) {
if (BF->hasDecorate(DecorationStallEnableINTEL)) {
std::vector<Metadata *> MetadataVec;
MetadataVec.push_back(ConstantAsMetadata::get(getInt32(M, 1)));
F->setMetadata(kSPIR2MD::StallEnable, MDNode::get(*Context, MetadataVec));
}
return true;
}

bool SPIRVToLLVM::transAlign(SPIRVValue *BV, Value *V) {
if (auto AL = dyn_cast<AllocaInst>(V)) {
SPIRVWord Align = 0;
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class SPIRVToLLVM {
bool transMetadata();
bool transOCLMetadata(SPIRVFunction *BF);
bool transVectorComputeMetadata(SPIRVFunction *BF);
bool transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
Value *transAsmINTEL(SPIRVAsmINTEL *BA);
CallInst *transAsmCallINTEL(SPIRVAsmCallINTEL *BI, Function *F,
BasicBlock *BB);
Expand Down
13 changes: 13 additions & 0 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,10 @@ SPIRVFunction *LLVMToSPIRV::transFunctionDecl(Function *F) {
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute))
transVectorComputeMetadata(F);

if (BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_fpga_cluster_attributes))
transFPGAFunctionMetadata(BF, F);

SPIRVDBG(dbgs() << "[transFunction] " << *F << " => ";
spvdbgs() << *BF << '\n';)
return BF;
Expand Down Expand Up @@ -672,6 +676,15 @@ void LLVMToSPIRV::transVectorComputeMetadata(Function *F) {
}
}

void LLVMToSPIRV::transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F) {
if (MDNode *StallEnable = F->getMetadata(kSPIR2MD::StallEnable)) {
if (getMDOperandAsInt(StallEnable, 0)) {
BM->addCapability(CapabilityFPGAClusterAttributesINTEL);
BF->addDecorate(new SPIRVDecorateStallEnableINTEL(BF));
}
}
}

SPIRVValue *LLVMToSPIRV::transConstant(Value *V) {
if (auto CPNull = dyn_cast<ConstantPointerNull>(V))
return BM->addNullConstant(
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class LLVMToSPIRV : public ModulePass {
SPIRVWord transFunctionControlMask(Function *);
SPIRVFunction *transFunctionDecl(Function *F);
void transVectorComputeMetadata(Function *F);
void transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
bool transGlobalVariables();

Op transBoolOpCode(SPIRVValue *Opn, Op OC);
Expand Down
9 changes: 9 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVDecorate.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ class SPIRVDecorate : public SPIRVDecorateGeneric {
case DecorationFunctionRoundingModeINTEL:
case DecorationFunctionDenormModeINTEL:
return ExtensionID::SPV_INTEL_float_controls2;
case DecorationStallEnableINTEL:
return ExtensionID::SPV_INTEL_fpga_cluster_attributes;
default:
return {};
}
Expand Down Expand Up @@ -601,6 +603,13 @@ class SPIRVDecorateFunctionFloatingPointModeINTEL : public SPIRVDecorate {
};
};

class SPIRVDecorateStallEnableINTEL : public SPIRVDecorate {
public:
// Complete constructor for SPIRVDecorateStallEnableINTEL
SPIRVDecorateStallEnableINTEL(SPIRVEntry *TheTarget)
: SPIRVDecorate(spv::DecorationStallEnableINTEL, TheTarget){};
};

} // namespace SPIRV

#endif // SPIRV_LIBSPIRV_SPIRVDECORATE_H
2 changes: 2 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ template <> inline void SPIRVMap<Decoration, SPIRVCapVec>::init() {
{CapabilityVectorComputeINTEL});
ADD_VEC_INIT(DecorationVectorComputeCallableFunctionINTEL,
{CapabilityVectorComputeINTEL});
ADD_VEC_INIT(DecorationStallEnableINTEL,
{CapabilityFPGAClusterAttributesINTEL});
}

template <> inline void SPIRVMap<BuiltIn, SPIRVCapVec>::init() {
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ template <> inline void SPIRVMap<Decoration, std::string>::init() {
add(DecorationSingleElementVectorINTEL, "SingleElementVectorINTEL");
add(DecorationVectorComputeCallableFunctionINTEL,
"VectorComputeCallableFunctionINTEL");
add(DecorationStallEnableINTEL, "StallEnableINTEL");
add(DecorationMax, "Max");
}
SPIRV_DEF_NAMEMAP(Decoration, SPIRVDecorationNameMap)
Expand Down Expand Up @@ -502,6 +503,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
add(CapabilityUSMStorageClassesINTEL, "USMStorageClassesINTEL");
add(CapabilityFPGAMemoryAccessesINTEL, "FPGAMemoryAccessesINTEL");
add(CapabilityIOPipeINTEL, "IOPipeINTEL");
add(CapabilityFPGAClusterAttributesINTEL, "FPGAClusterAttributesINTEL");
add(CapabilityMax, "Max");
}
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/libSPIRV/spirv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ enum Decoration {
DecorationCacheSizeINTEL = 5900,
DecorationDontStaticallyCoalesceINTEL = 5901,
DecorationPrefetchINTEL = 5902,
DecorationStallEnableINTEL = 5905,
DecorationBufferLocationINTEL = 5921,
DecorationIOPipeStorageINTEL = 5944,
DecorationFunctionFloatingPointModeINTEL = 6080,
Expand Down Expand Up @@ -979,6 +980,7 @@ enum Capability {
CapabilityFPGARegINTEL = 5948,
CapabilityKernelAttributesINTEL = 5892,
CapabilityFPGAKernelAttributesINTEL = 5897,
CapabilityFPGAClusterAttributesINTEL = 5904,
CapabilityFPGABufferLocationINTEL = 5920,
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
CapabilityUSMStorageClassesINTEL = 5935,
Expand Down
19 changes: 11 additions & 8 deletions test/transcoding/IntelFPGAFunctionAttributes.ll
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
;; Can be compiled using https://github.com/intel/llvm SYCL compiler from:
;; class Foo {
;; public:
;; [[intelfpga::no_global_work_offset,
;; intelfpga::max_global_work_dim(1),
;; intelfpga::max_work_group_size(1,1,1),
;; intelfpga::num_simd_work_items(8)]] void operator()() {}
;; [[intel::no_global_work_offset,
;; intel::max_global_work_dim(1),
;; intel::max_work_group_size(1,1,1),
;; intel::num_simd_work_items(8)
;; intel::stall_enable]] void operator()() {}
;; };
;;
;; template <typename name, typename Func>
Expand All @@ -19,7 +20,7 @@
;; }

; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_kernel_attributes -o %t.spv
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_kernel_attributes --spirv-ext=+SPV_INTEL_fpga_cluster_attributes -o %t.spv
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV

Expand All @@ -31,17 +32,19 @@

; CHECK-SPIRV: 2 Capability KernelAttributesINTEL
; CHECK-SPIRV: 2 Capability FPGAKernelAttributesINTEL
; CHECK-SPIRV: 2 Capability FPGAClusterAttributesINTEL
; CHECK-SPIRV: 6 ExecutionMode [[FUNCENTRY:[0-9]+]] 5893 1 1 1
; CHECK-SPIRV: 4 ExecutionMode [[FUNCENTRY]] 5894 1
; CHECK-SPIRV: 3 ExecutionMode [[FUNCENTRY]] 5895
; CHECK-SPIRV: 4 ExecutionMode [[FUNCENTRY]] 5896 8
; CHECK-SPIRV: 3 Decorate [[FUNCENTRY]] StallEnableINTEL
; CHECK-SPIRV: 5 Function {{.*}} [[FUNCENTRY]] {{.*}}

; CHECK-LLVM: define spir_kernel void {{.*}}kernel_name() {{.*}} !max_work_group_size ![[MAXWG:[0-9]+]] !no_global_work_offset ![[OFFSET:[0-9]+]] !max_global_work_dim ![[MAXWD:[0-9]+]] !num_simd_work_items ![[NUMSIMD:[0-9]+]]
; CHECK-LLVM: define spir_kernel void {{.*}}kernel_name() {{.*}} !stall_enable ![[ONEMD:[0-9]+]] !max_work_group_size ![[MAXWG:[0-9]+]] !no_global_work_offset ![[OFFSET:[0-9]+]] !max_global_work_dim ![[ONEMD:[0-9]+]] !num_simd_work_items ![[NUMSIMD:[0-9]+]]
; CHECK-LLVM-NOT: define spir_kernel void {{.*}}kernel_name2 {{.*}} !no_global_work_offset {{.*}}
; CHECK-LLVM: ![[OFFSET]] = !{}
; CHECK-LLVM: ![[ONEMD]] = !{i32 1}
; CHECK-LLVM: ![[MAXWG]] = !{i32 1, i32 1, i32 1}
; CHECK-LLVM: ![[MAXWD]] = !{i32 1}
; CHECK-LLVM: ![[NUMSIMD]] = !{i32 8}

; ModuleID = 'kernel-attrs.cpp'
Expand All @@ -55,7 +58,7 @@ target triple = "spir64-unknown-linux-sycldevice"
$_ZN3FooclEv = comdat any

; Function Attrs: nounwind
define spir_kernel void @_ZTSZ3barvE11kernel_name() #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !4 !kernel_arg_type !4 !kernel_arg_base_type !4 !kernel_arg_type_qual !4 !num_simd_work_items !5 !max_work_group_size !6 !max_global_work_dim !7 !no_global_work_offset !4 {
define spir_kernel void @_ZTSZ3barvE11kernel_name() #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !4 !kernel_arg_type !4 !kernel_arg_base_type !4 !kernel_arg_type_qual !4 !num_simd_work_items !5 !max_work_group_size !6 !max_global_work_dim !7 !no_global_work_offset !4 !stall_enable !7 {
entry:
%Foo = alloca %class._ZTS3Foo.Foo, align 1
%0 = bitcast %class._ZTS3Foo.Foo* %Foo to i8*
Expand Down

0 comments on commit 7f2d2cb

Please sign in to comment.