spectral.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import math
  2. import torch
  3. from torch.utils import benchmark
  4. from torch.utils.benchmark import FuzzedParameter, FuzzedTensor, ParameterAlias
  5. __all__ = ['SpectralOpFuzzer']
  6. MIN_DIM_SIZE = 16
  7. MAX_DIM_SIZE = 16 * 1024
  8. def power_range(upper_bound, base):
  9. return (base ** i for i in range(int(math.log(upper_bound, base)) + 1))
  10. # List of regular numbers from MIN_DIM_SIZE to MAX_DIM_SIZE
  11. # These numbers factorize into multiples of prime factors 2, 3, and 5 only
  12. # and are usually the fastest in FFT implementations.
  13. REGULAR_SIZES = []
  14. for i in power_range(MAX_DIM_SIZE, 2):
  15. for j in power_range(MAX_DIM_SIZE // i, 3):
  16. ij = i * j
  17. for k in power_range(MAX_DIM_SIZE // ij, 5):
  18. ijk = ij * k
  19. if ijk > MIN_DIM_SIZE:
  20. REGULAR_SIZES.append(ijk)
  21. REGULAR_SIZES.sort()
  22. class SpectralOpFuzzer(benchmark.Fuzzer):
  23. def __init__(self, *, seed: int, dtype=torch.float64,
  24. cuda: bool = False, probability_regular: float = 1.0):
  25. super().__init__(
  26. parameters=[
  27. # Dimensionality of x. (e.g. 1D, 2D, or 3D.)
  28. FuzzedParameter("ndim", distribution={1: 0.3, 2: 0.4, 3: 0.3}, strict=True),
  29. # Shapes for `x`.
  30. # It is important to test all shapes, however
  31. # regular sizes are especially important to the FFT and therefore
  32. # warrant special attention. This is done by generating
  33. # both a value drawn from all integers between the min and
  34. # max allowed values, and another from only the regular numbers
  35. # (both distributions are loguniform) and then randomly
  36. # selecting between the two.
  37. [
  38. FuzzedParameter(
  39. name=f"k_any_{i}",
  40. minval=MIN_DIM_SIZE,
  41. maxval=MAX_DIM_SIZE,
  42. distribution="loguniform",
  43. ) for i in range(3)
  44. ],
  45. [
  46. FuzzedParameter(
  47. name=f"k_regular_{i}",
  48. distribution={size: 1. / len(REGULAR_SIZES) for size in REGULAR_SIZES}
  49. ) for i in range(3)
  50. ],
  51. [
  52. FuzzedParameter(
  53. name=f"k{i}",
  54. distribution={
  55. ParameterAlias(f"k_regular_{i}"): probability_regular,
  56. ParameterAlias(f"k_any_{i}"): 1 - probability_regular,
  57. },
  58. strict=True,
  59. ) for i in range(3)
  60. ],
  61. # Steps for `x`. (Benchmarks strided memory access.)
  62. [
  63. FuzzedParameter(
  64. name=f"step_{i}",
  65. distribution={1: 0.8, 2: 0.06, 4: 0.06, 8: 0.04, 16: 0.04},
  66. ) for i in range(3)
  67. ],
  68. ],
  69. tensors=[
  70. FuzzedTensor(
  71. name="x",
  72. size=("k0", "k1", "k2"),
  73. steps=("step_0", "step_1", "step_2"),
  74. probability_contiguous=0.75,
  75. min_elements=4 * 1024,
  76. max_elements=32 * 1024 ** 2,
  77. max_allocation_bytes=2 * 1024**3, # 2 GB
  78. dim_parameter="ndim",
  79. dtype=dtype,
  80. cuda=cuda,
  81. ),
  82. ],
  83. seed=seed,
  84. )