-
Notifications
You must be signed in to change notification settings - Fork 64
/
occupancy.go
87 lines (74 loc) · 4.4 KB
/
occupancy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package cu
// #include <cuda.h>
import "C"
// MaxActiveBlocksPerMultiProcessor returns the number of the maximum active blocks per streaming multiprocessor.
func (fn Function) MaxActiveBlocksPerMultiProcessor(blockSize int, dynamicSmemSize int64) (int, error) {
bs := C.int(blockSize)
dss := C.size_t(dynamicSmemSize)
var numBlocks C.int
if err := result(C.cuOccupancyMaxActiveBlocksPerMultiprocessor(&numBlocks, fn.fn, bs, dss)); err != nil {
return 0, err
}
return int(numBlocks), nil
}
// MaxActiveBlocksPerMultiProcessorWithFlags returns the number of the maximum active blocks per streaming multiprocessor.
// The flags control how special cases are handled.
func (fn Function) MaxActiveBlocksPerMultiProcessorWithFlags(blockSize int, dynamicSmemSize int64, flags OccupancyFlags) (int, error) {
bs := C.int(blockSize)
dss := C.size_t(dynamicSmemSize)
of := C.uint(flags)
var numBlocks C.int
if err := result(C.cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(&numBlocks, fn.fn, bs, dss, of)); err != nil {
return 0, err
}
return int(numBlocks), nil
}
// MaxPotentialBlockSize suggest a reasonable block size that can achieve the maximum occupancy (or, the maximum number of active warps with the fewest blocks per multiprocessor
// and the minimum grid size to achieve the maximum occupancy.
//
// If blockSizeLimit is 0, the configurator will use the maximum block size permitted by the device / function instead.
//
// If per-block dynamic shared memory allocation is not needed, the user should leave both bs2ds and dynamicSMemSize as 0.
//
// If per-block dynamic shared memory allocation is needed, then if the dynamic shared memory size is constant regardless of block size, the size should be passed through dynamicSMemSize, and blockSizeToDynamicSMemSize should be NULL.
//
// Otherwise, if the per-block dynamic shared memory size varies with different block sizes, the user needs to provide a unary function through blockSizeToDynamicSMemSize that computes the dynamic shared memory needed by func for any given block size.
// dynamicSMemSize is ignored. An example signature is:
// // Take block size, returns dynamic shared memory needed
// size_t blockToSmem(int blockSize);
// func (fn Function) MaxPotentialBlockSize(blockSizeToDynamicSMemSize int, dynamicSmemSize int64, blockSizeLimit int) (minGridSize, blockSize int, err error) {
// bs2dsm := C.CUoccupancyB2DSize(blockSizeToDynamicSMemSize)
// dss := C.size_t(dynamicSmemSize)
// f := C.CUfunction(fn)
// bsl := C.int(blockSizeLimit)
// var mgs, bs C.int
// if err = result(C.cuOccupancyMaxPotentialBlockSize(&mgs, &bs, f, bs2dsm, dss, bsl)); err != nil {
// return
// }
// minGridSize = int(mgs)
// blockSize = int(bs)
// return
// }
// MaxPotentialBlockSizeWithFlags suggest a reasonable block size that can achieve the maximum occupancy (or, the maximum number of active warps with the fewest blocks per multiprocessor
// and the minimum grid size to achieve the maximum occupancy.
// If blockSizeLimit is 0, the configurator will use the maximum block size permitted by the device / function instead.
// If per-block dynamic shared memory allocation is not needed, the user should leave both bs2ds and dynamicSMemSize as 0.
// If per-block dynamic shared memory allocation is needed, then if the dynamic shared memory size is constant regardless of block size, the size should be passed through dynamicSMemSize, and blockSizeToDynamicSMemSize should be NULL.
// Otherwise, if the per-block dynamic shared memory size varies with different block sizes, the user needs to provide a unary function through blockSizeToDynamicSMemSize that computes the dynamic shared memory needed by func for any given block size.
// dynamicSMemSize is ignored. An example signature is:
// // Take block size, returns dynamic shared memory needed
// size_t blockToSmem(int blockSize);
// func (fn Function) MaxPotentialBlockSizeWithFlags(blockSizeToDynamicSMemSize int, dynamicSmemSize int64, blockSizeLimit int, flags OccupancyFlags) (minGridSize, blockSize int, err error) {
// bs2dsm := C.CUoccupancyB2DSize(blockSizeToDynamicSMemSize)
// dss := C.size_t(dynamicSmemSize)
// f := C.CUfunction(fn)
// bsl := C.int(blockSizeLimit)
// of := CUoccupancy_flags(flags)
// var mgs, bs C.int
// if err = result(C.cuOccupancyMaxPotentialBlockSize(&mgs, &bs, f, bs2dsm, dss, bsl, of)); err != nil {
// return
// }
// minGridSize = int(mgs)
// blockSize = int(bs)
// return
// }