HsaMemoryProperties ReserveApe1(HSAuint32 node_id, size_t size,
                                size_t alignment) {
  // Only valid in 64 bit.
  assert(sizeof(void*) == 8);

  HsaMemoryProperties ape1_prop;

  void* ape1 = _aligned_malloc(size, alignment);
  assert((ape1 != NULL) && ("APE1 allocation failed"));

  if (HSAKMT_STATUS_SUCCESS !=
      hsaKmtSetMemoryPolicy(node_id, HSA_CACHING_CACHED, HSA_CACHING_NONCACHED,
                            ape1, size)) {
    ReleaseApe1(ape1, size);
    std::memset(&ape1_prop, 0, sizeof(ape1_prop));
    assert(false && "hsaKmtSetMemoryPolicy failed");
    return ape1_prop;
  }

  std::memset(&ape1_prop, 0, sizeof(ape1_prop));
  ape1_prop.HeapType = HSA_HEAPTYPE_SYSTEM;
  ape1_prop.SizeInBytes = size;
  ape1_prop.VirtualBaseAddress = reinterpret_cast<HSAuint64>(ape1);

  return ape1_prop;
}
GpuAgent::~GpuAgent() {
  if (ape1_base_ != 0)
    ReleaseApe1(reinterpret_cast<void*>(ape1_base_), ape1_size_);

  std::for_each(core::Agent::regions_.begin(), core::Agent::regions_.end(),
                DeleteObject());
  core::Agent::regions_.clear();

  if (scratch_pool_.base() != NULL) {
    hsaKmtFreeMemory(scratch_pool_.base(), scratch_pool_.size());
  }
}
GpuAgent::~GpuAgent() {
  if (ape1_base_ != 0) {
    ReleaseApe1(reinterpret_cast<void*>(ape1_base_), ape1_size_);
  }

  regions_.clear();

  if (scratch_pool_.base() != NULL) {
    hsaKmtFreeMemory(scratch_pool_.base(), scratch_pool_.size());
  }

  if (blit_ != NULL) {
    hsa_status_t status = blit_->Destroy();
    assert(status == HSA_STATUS_SUCCESS);

    delete blit_;
  }
}