Skip to content

File param.h

File List > include > simtix > param.h

Go to the documentation of this file

#pragma once

#include <fmt/core.h>
#include <simtix/macro.h>

#include <cstdint>

#define FEATURE_ENABLED(feature) DEFINED_MACRO(feature##_FEATURE_ENABLED)

#define DECL_PARAM_W_GETTER(type, name) \
 public:                                \
  type name() const { return name##_; } \
                                        \
 private:                               \
  type name##_

namespace simtix {

enum class SMType { kAtomic = 0, kPipelined };

class ArchParamBuilder;
// Architectural parameters
class ArchParam {
 public:
  // Warp scheduling policies
  enum class WarpSchedPolicies : uint8_t { kLrr = 0, kGto, kTwoLevel };

  static ArchParamBuilder Build();
  friend class ArchParamBuilder;
  // Getter + parameters declare
  DECL_PARAM_W_GETTER(uint32_t, kThreadsPerWarp);
  DECL_PARAM_W_GETTER(uint32_t, kWarpsPerWarpGroup);
  DECL_PARAM_W_GETTER(uint32_t, kWarpsPerCore);
  DECL_PARAM_W_GETTER(uint32_t, kCoresPerSystem);
  DECL_PARAM_W_GETTER(uint32_t, kMaxPriorityLevel);
  DECL_PARAM_W_GETTER(uint32_t, kMaxFunctPriorityLevel);
  DECL_PARAM_W_GETTER(uint8_t, kMaxBarrierIDs);
  DECL_PARAM_W_GETTER(WarpSchedPolicies, kWarpSchedPolicy);
  DECL_PARAM_W_GETTER(uint64_t, kMhartidBase);

 private:
  ArchParam()
      : kThreadsPerWarp_(32),
        kWarpsPerWarpGroup_(FEATURE_ENABLED(WGC) ? 2 : 1),
        kWarpsPerCore_(32),
        kCoresPerSystem_(1),
        kMaxPriorityLevel_(8),
        kMaxFunctPriorityLevel_(63),
        kMaxBarrierIDs_(32),
        kWarpSchedPolicy_(WarpSchedPolicies::kLrr),
        kMhartidBase_(0) {}
};

class ArchParamBuilder {
 private:
  ArchParam param_;

 public:
  ArchParamBuilder() = default;

  ArchParamBuilder& threads_per_warp(uint32_t v) {
    param_.kThreadsPerWarp_ = v;
    return *this;
  }
  ArchParamBuilder& warps_per_warp_group(uint32_t v) {
    param_.kWarpsPerWarpGroup_ = v;
    return *this;
  }
  ArchParamBuilder& warps_per_core(uint32_t v) {
    param_.kWarpsPerCore_ = v;
    return *this;
  }
  ArchParamBuilder& cores_per_system(uint32_t v) {
    param_.kCoresPerSystem_ = v;
    return *this;
  }
  ArchParamBuilder& max_priority_level(uint32_t v) {
    param_.kMaxPriorityLevel_ = v;
    return *this;
  }
  ArchParamBuilder& max_function_priority_level(uint32_t v) {
    param_.kMaxFunctPriorityLevel_ = v;
    return *this;
  }
  ArchParamBuilder& max_barrier_ids(uint8_t v) {
    param_.kMaxBarrierIDs_ = v;
    return *this;
  }
  ArchParamBuilder& warp_sched_policy(ArchParam::WarpSchedPolicies policy) {
    param_.kWarpSchedPolicy_ = policy;
    return *this;
  }
  ArchParamBuilder& mhartid_base(uint64_t v) {
    param_.kMhartidBase_ = v;
    return *this;
  }
  operator ArchParam() const { return param_; }
};

inline ArchParamBuilder ArchParam::Build() { return ArchParamBuilder(); }

inline const ArchParam kDefaultArchParam = ArchParam::Build();

namespace mem {

enum class MemType { kSimpleMemory, kBankedMemory };

}  // namespace mem

// Simulator parameters are compile time constant
#ifndef INITIAL_INSTR_POOL_SIZE
#define INITIAL_INSTR_POOL_SIZE 10
#endif

}  // namespace simtix

namespace fmt {

// fmt support for warp scheduling policies
template <>
struct formatter<simtix::ArchParam::WarpSchedPolicies>
    : formatter<string_view> {
  template <typename FormatContext>
  auto format(simtix::ArchParam::WarpSchedPolicies policy,
              FormatContext& ctx) const {  // NOLINT
    string_view name = "Unknown";
    switch (policy) {
      case simtix::ArchParam::WarpSchedPolicies::kLrr:
        name = "Lrr";
        break;
      case simtix::ArchParam::WarpSchedPolicies::kGto:
        name = "Gto";
        break;
      case simtix::ArchParam::WarpSchedPolicies::kTwoLevel:
        name = "TwoLevel";
        break;
    }
    return formatter<string_view>::format(name, ctx);
  }
};

// fmt support for SM types
template <>
struct formatter<simtix::SMType> : formatter<string_view> {
  template <typename FormatContext>
  auto format(simtix::SMType sm_type, FormatContext& ctx) const {  // NOLINT
    string_view name = "Unknown";
    switch (sm_type) {
      case simtix::SMType::kAtomic:
        name = "Atomic";
        break;
      case simtix::SMType::kPipelined:
        name = "Pipelined";
        break;
    }
    return formatter<string_view>::format(name, ctx);
  }
};

// fmt support for memory types
template <>
struct formatter<simtix::mem::MemType> : formatter<string_view> {
  template <typename FormatContext>
  auto format(simtix::mem::MemType mem_type,
              FormatContext& ctx) const {  // NOLINT
    string_view name = "Unknown";
    switch (mem_type) {
      case simtix::mem::MemType::kSimpleMemory:
        name = "Simple";
        break;
      case simtix::mem::MemType::kBankedMemory:
        name = "Banked";
        break;
    }
    return formatter<string_view>::format(name, ctx);
  }
};

}  // namespace fmt