MLIR-AIE
memory_allocator_hsa.cpp
Go to the documentation of this file.
1//===- memory_allocator_hsa.cpp ---------------------------------*- C++ -*-===//
2//
3// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// (c) Copyright 2023 Advanced Micro Devices, Inc.
8//
9//===----------------------------------------------------------------------===//
10
11#include "hsa/hsa.h"
12#include "hsa/hsa_ext_amd.h"
13#include "memory_allocator.h"
14#include "test_library.h"
15#include <iostream>
16
17//
18// This memory allocator links against the HSA allocator
19//
21 int size) {
22 int size_bytes = size * sizeof(int);
23 hsa_amd_memory_pool_allocate(_xaie->global_mem_pool, size_bytes, 0,
24 (void **)&(handle.virtualAddr));
25
26 if (handle.virtualAddr) {
27 handle.size = size_bytes;
28 } else {
29 printf("ExtMemModel: Failed to allocate %d memory.\n", size_bytes);
30 }
31
32 std::cout << "ExtMemModel constructor: virtual address " << std::hex
33 << handle.virtualAddr << ", size " << std::dec << handle.size
34 << std::endl;
35
36 return (int *)handle.virtualAddr;
37}
38
39/*
40 The device memory allocator directly maps device memory over
41 PCIe MMIO. These accesses are uncached and thus don't require
42 explicit synchronization between the host and device
43*/
45
47
48/*
49 The only component that knows the proper translation from
50 VA->PA is the command processor. Sending a request to the
51 command processor to perform the translation.
52*/
53u64 mlir_aie_get_device_address(struct aie_libxaie_ctx_t *_xaie, void *VA) {
54
55 // Checking to make sure that the agent is setup properly
56 if (_xaie == NULL) {
57 printf("[ERROR] %s passed NULL context ptr\n", __func__);
58 return NULL;
59 }
60
61 if (_xaie->agents.size() == 0) {
62 printf("[ERROR] %s passed context has no agents\n", __func__);
63 return NULL;
64 }
65
66 if (_xaie->cmd_queue == NULL) {
67 printf("[ERROR] %s passed context has no queue\n", __func__);
68 return NULL;
69 }
70
71 // Getting pointers to the queue and the agent
72 hsa_queue_t *queue = _xaie->cmd_queue;
73 hsa_agent_t agent = _xaie->agents[0];
74
75 uint64_t wr_idx = hsa_queue_add_write_index_relaxed(queue, 1);
76 uint64_t packet_id = wr_idx % queue->size;
77 hsa_agent_dispatch_packet_t pkt;
78 mlir_aie_packet_req_translation(&pkt, (uint64_t)VA);
79 hsa_amd_signal_create_on_agent(1, 0, nullptr, &agent, 0,
80 &(pkt.completion_signal));
81 reinterpret_cast<hsa_agent_dispatch_packet_t *>(
82 queue->base_address)[packet_id] = pkt;
83
84 // Ringing the doorbell to notify the command processor of the packet
85 hsa_signal_store_screlease(queue->doorbell_signal, wr_idx);
86
87 // wait for packet completion
88 while (hsa_signal_wait_scacquire(pkt.completion_signal,
89 HSA_SIGNAL_CONDITION_EQ, 0, 0x80000,
90 HSA_WAIT_STATE_ACTIVE) != 0)
91 ;
92
93 // We encode the response in the packet, so need to peek in to get the data
94 hsa_agent_dispatch_packet_t *pkt_peek =
95 &reinterpret_cast<hsa_agent_dispatch_packet_t *>(
96 queue->base_address)[packet_id];
97
98 // Copying the translated address
99 uint64_t PA;
100 PA = (uint64_t)pkt_peek->return_address;
101
102 // Destroying the signal
103 hsa_signal_destroy(pkt.completion_signal);
104
105 return (u64)PA; // The platform will convert the address for us
106}
void mlir_aie_sync_mem_dev(ext_mem_model_t &handle)
Synchronize the buffer from the host CPU to the device.
int * mlir_aie_mem_alloc(aie_libxaie_ctx_t *_xaie, ext_mem_model_t &handle, int size)
Allocate a buffer in device memory.
void mlir_aie_sync_mem_cpu(ext_mem_model_t &handle)
Synchronize the buffer from the device to the host CPU.
u64 mlir_aie_get_device_address(struct aie_libxaie_ctx_t *_xaie, void *VA)
Return a device address corresponding to the given host address.
size_t size
Definition target.h:26
void * virtualAddr
Definition target.h:24