Skip to content

Commit 91c70d1

Browse files
committed
UCM/MEM_ATTR: Make memory attribute opaque and add unit tests
1 parent f8e59dd commit 91c70d1

File tree

15 files changed

+382
-116
lines changed

15 files changed

+382
-116
lines changed

src/ucm/Makefile.am

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ libucm_la_CPPFLAGS = $(BASE_CPPFLAGS) -DUCM_MALLOC_PREFIX=ucm_dl
1515
libucm_la_CFLAGS = $(BASE_CFLAGS) $(CFLAGS_NO_DEPRECATED)
1616

1717
nobase_dist_libucm_la_HEADERS = \
18-
api/ucm.h
18+
api/ucm.h \
19+
mem_attr/mem_attr.h
1920

2021
noinst_HEADERS = \
2122
event/event.h \
2223
malloc/malloc_hook.h \
2324
malloc/allocator.h \
2425
mmap/mmap.h \
26+
mem_attr/mem_attr_int.h \
2527
util/khash_safe.h \
2628
util/replace.h \
2729
util/log.h \
@@ -37,6 +39,7 @@ libucm_la_SOURCES = \
3739
event/event.c \
3840
malloc/malloc_hook.c \
3941
mmap/install.c \
42+
mem_attr/mem_attr.c \
4043
util/replace.c \
4144
util/log.c \
4245
util/reloc.c \

src/ucm/cuda/cudamem.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
#include <ucm/util/reloc.h>
1717
#include <ucm/util/replace.h>
1818
#include <ucm/util/sys.h>
19+
#include <ucm/mem_attr/mem_attr_int.h>
20+
#include <ucs/debug/memtrack.h>
1921
#include <ucs/debug/assert.h>
2022
#include <ucs/sys/compiler.h>
2123
#include <ucs/sys/preprocessor.h>
22-
#include <ucs/memory/memory_type.h>
23-
#include <ucs/type/status.h>
2424

2525
#include <sys/mman.h>
2626
#include <pthread.h>
@@ -457,12 +457,35 @@ static void ucm_cudamem_get_existing_alloc(ucm_event_handler_t *handler)
457457
}
458458
}
459459

460+
typedef struct ucm_cudamem_attr {
461+
ucm_mem_attr_t super;
462+
unsigned long long buf_id;
463+
} ucm_cudamem_attr_t;
464+
465+
static int ucm_cudamem_attr_cmp(const ucm_mem_attr_h mem_attr1,
466+
const ucm_mem_attr_h mem_attr2)
467+
{
468+
ucm_cudamem_attr_t *cuda_mem_attr1, *cuda_mem_attr2;
469+
cuda_mem_attr1 = ucs_derived_of(mem_attr1, ucm_cudamem_attr_t);
470+
cuda_mem_attr2 = ucs_derived_of(mem_attr2, ucm_cudamem_attr_t);
471+
if (cuda_mem_attr1->buf_id == cuda_mem_attr2->buf_id) return 0;
472+
return 1;
473+
}
474+
475+
static void ucm_cudamem_attr_destroy(ucm_mem_attr_h mem_attr)
476+
{
477+
ucm_cudamem_attr_t *cuda_mem_attr;
478+
cuda_mem_attr = ucs_derived_of(mem_attr,ucm_cudamem_attr_t);
479+
ucs_free(cuda_mem_attr);
480+
}
481+
460482
static ucs_status_t ucm_cudamem_attr_get(const void *address, size_t length,
461-
ucs_memory_attr_t *mem_attr)
483+
ucm_mem_attr_h *mem_attr_p)
462484
{
463485
#define UCM_CUDA_MEM_QUERY_NUM_ATTRS 3
464486
CUmemorytype cuda_mem_type = (CUmemorytype)0;
465487
uint32_t is_managed = 0;
488+
unsigned long long buf_id = 0;
466489
CUpointer_attribute attr_type[UCM_CUDA_MEM_QUERY_NUM_ATTRS];
467490
void *attr_data[UCM_CUDA_MEM_QUERY_NUM_ATTRS];
468491
CUresult cu_err;
@@ -474,23 +497,31 @@ static ucs_status_t ucm_cudamem_attr_get(const void *address, size_t length,
474497
attr_type[1] = CU_POINTER_ATTRIBUTE_IS_MANAGED;
475498
attr_data[1] = &is_managed;
476499
attr_type[2] = CU_POINTER_ATTRIBUTE_BUFFER_ID;
477-
attr_data[2] = &mem_attr->cuda.buf_id;
500+
attr_data[2] = &buf_id;
478501

479502
cu_err = cuPointerGetAttributes(ucs_static_array_size(attr_data),
480503
attr_type, attr_data,
481504
(CUdeviceptr)address);
482505
if (cu_err == CUDA_SUCCESS) {
506+
ucm_cudamem_attr_t *mem_attr;
507+
mem_attr = ucs_malloc(sizeof(*mem_attr),"cudamem_attr");
508+
if (mem_attr == NULL) return UCS_ERR_NO_MEMORY;
483509
switch (cuda_mem_type) {
484510
case CU_MEMORYTYPE_DEVICE:
485-
mem_attr->mem_type = is_managed ? UCS_MEMORY_TYPE_CUDA_MANAGED
486-
: UCS_MEMORY_TYPE_CUDA;
511+
mem_attr->super.mem_type = is_managed
512+
? UCS_MEMORY_TYPE_CUDA_MANAGED
513+
: UCS_MEMORY_TYPE_CUDA;
487514
break;
488515
case CU_MEMORYTYPE_HOST:
489-
mem_attr->mem_type = UCS_MEMORY_TYPE_HOST;
516+
mem_attr->super.mem_type = UCS_MEMORY_TYPE_HOST;
490517
break;
491518
default:
492519
return UCS_ERR_INVALID_ADDR;
493520
}
521+
mem_attr->buf_id = buf_id;
522+
mem_attr->super.cmp = &ucm_cudamem_attr_cmp;
523+
mem_attr->super.destroy = &ucm_cudamem_attr_destroy;
524+
*mem_attr_p = &mem_attr->super;
494525
return UCS_OK;
495526
}
496527

src/ucm/event/event.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <ucm/api/ucm.h>
1111
#include <ucm/util/log.h>
12+
#include <ucm/mem_attr/mem_attr.h>
1213
#include <ucs/datastruct/list.h>
1314
#include <ucs/type/status.h>
1415

@@ -34,7 +35,7 @@ typedef struct ucm_event_installer {
3435
ucs_status_t (*install)(int events);
3536
void (*get_existing_alloc)(ucm_event_handler_t *handler);
3637
ucs_status_t (*get_mem_attr)(const void *address, size_t length,
37-
ucs_memory_attr_t *mem_attr);
38+
ucm_mem_attr_h *mem_attr_p);
3839
ucs_list_link_t list;
3940
} ucm_event_installer_t;
4041

src/ucm/mem_attr/mem_attr.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright (C) NVIDIA Corporation. 2020. ALL RIGHTS RESERVED.
3+
* See file LICENSE for terms.
4+
*/
5+
6+
#ifdef HAVE_CONFIG_H
7+
# include "config.h"
8+
#endif
9+
10+
#include "mem_attr.h"
11+
#include "mem_attr_int.h"
12+
13+
#include <ucs/memory/memory_type.h>
14+
#include <ucm/event/event.h>
15+
16+
17+
static int ucm_mem_attr_cmp_type(ucm_mem_attr_h mem_attr1,
18+
ucm_mem_attr_h mem_attr2)
19+
{
20+
if (mem_attr1->mem_type == mem_attr2->mem_type) return 0;
21+
return 1;
22+
}
23+
24+
static void ucm_mem_attr_destroy_host(ucm_mem_attr_h mem_attr)
25+
{
26+
/* Nothing to be done for host memory attributes */
27+
}
28+
29+
/* All host memory will have the same attributes (only a type).
30+
* So, they will all point to this static struct */
31+
static ucm_mem_attr_t mem_attr_host = {
32+
.mem_type = UCS_MEMORY_TYPE_HOST,
33+
.cmp = &ucm_mem_attr_cmp_type,
34+
.destroy = &ucm_mem_attr_destroy_host
35+
};
36+
37+
ucs_status_t ucm_mem_attr_get(const void *address, size_t length,
38+
ucm_mem_attr_h *mem_attr_p)
39+
{
40+
ucm_event_installer_t *event_installer;
41+
ucs_status_t status;
42+
int failure = 0;
43+
44+
ucs_list_for_each(event_installer, &ucm_event_installer_list, list) {
45+
if (event_installer->get_mem_attr == NULL) continue;
46+
status = event_installer->get_mem_attr(address, length, mem_attr_p);
47+
if (status == UCS_OK) return UCS_OK;
48+
if (status != UCS_ERR_INVALID_ADDR) failure = 1;
49+
}
50+
51+
if (failure) return UCS_ERR_NO_RESOURCE;
52+
53+
/* none of the installers recognized the address. So, it must be HOST */
54+
*mem_attr_p = &mem_attr_host;
55+
return UCS_OK;
56+
}
57+
58+
ucs_memory_type_t ucm_mem_attr_get_type(ucm_mem_attr_h mem_attr)
59+
{
60+
return mem_attr->mem_type;
61+
}
62+
63+
int ucm_mem_attr_cmp(ucm_mem_attr_h mem_attr1, ucm_mem_attr_h mem_attr2)
64+
{
65+
if (ucm_mem_attr_cmp_type(mem_attr1, mem_attr2)) return 1;
66+
return mem_attr1->cmp(mem_attr1, mem_attr2);
67+
}
68+
69+
void ucm_mem_attr_destroy(ucm_mem_attr_h mem_attr)
70+
{
71+
mem_attr->destroy(mem_attr);
72+
}

src/ucm/mem_attr/mem_attr.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (C) NVIDIA Corporation. 2020. ALL RIGHTS RESERVED.
3+
* See file LICENSE for terms.
4+
*/
5+
6+
#ifndef UCM_MEM_ATTR_H_
7+
#define UCM_MEM_ATTR_H_
8+
9+
#include <ucs/memory/memory_type.h>
10+
#include <ucs/type/status.h>
11+
#include <stddef.h>
12+
13+
typedef struct ucm_mem_attr *ucm_mem_attr_h;
14+
15+
ucs_status_t ucm_mem_attr_get(const void *address, size_t length,
16+
ucm_mem_attr_h *mem_attr_p);
17+
ucs_memory_type_t ucm_mem_attr_get_type(ucm_mem_attr_h mem_attr);
18+
int ucm_mem_attr_cmp(ucm_mem_attr_h mem_attr1, ucm_mem_attr_h mem_attr2);
19+
void ucm_mem_attr_destroy(ucm_mem_attr_h mem_attr);
20+
21+
#endif

src/ucm/mem_attr/mem_attr_int.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Copyright (C) NVIDIA Corporation. 2020. ALL RIGHTS RESERVED.
3+
* See file LICENSE for terms.
4+
*/
5+
6+
#ifndef UCM_MEM_ATTR_INT_H_
7+
#define UCM_MEM_ATTR_INT_H_
8+
9+
10+
#include "mem_attr.h"
11+
12+
#include <ucs/memory/memory_type.h>
13+
#include <ucs/type/status.h>
14+
15+
16+
typedef struct ucm_mem_attr {
17+
ucs_memory_type_t mem_type;
18+
int (*cmp)(ucm_mem_attr_h mem_attr1, ucm_mem_attr_h mem_attr2);
19+
void (*destroy)(ucm_mem_attr_h mem_attr);
20+
} ucm_mem_attr_t;
21+
22+
23+
#endif

src/ucm/rocm/rocmmem.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <ucm/util/log.h>
1414
#include <ucm/util/reloc.h>
1515
#include <ucm/util/replace.h>
16+
#include <ucm/mem_attr/mem_attr_int.h>
17+
#include <ucs/debug/memtrack.h>
1618
#include <ucs/debug/assert.h>
1719
#include <ucs/sys/compiler.h>
1820
#include <ucs/sys/preprocessor.h>
@@ -185,38 +187,62 @@ static void ucm_rocmmem_get_existing_alloc(ucm_event_handler_t *handler)
185187
{
186188
}
187189

188-
static ucs_status_t ucm_rocmmem_attr_get(const void *address, size_t length,
189-
ucs_memory_attr_t *mem_attr)
190+
typedef struct ucm_rocmmem_attr {
191+
ucm_mem_attr_t super;
192+
/* TODO what rocm memory attributes do we need? */
193+
} ucm_rocmmem_attr_t;
194+
195+
static int ucm_rocmmem_attr_cmp(const ucm_mem_attr_h mem_attr1,
196+
const ucm_mem_attr_h mem_attr2)
190197
{
191-
if (address == NULL) return UCS_ERR_INVALID_ADDR;
198+
/* TODO how should we compare two rocm memory attributes? */
199+
return 0;
200+
}
201+
202+
static void ucm_rocmmem_attr_destroy(ucm_mem_attr_h mem_attr)
203+
{
204+
ucm_rocmmem_attr_t *rocm_mem_attr;
205+
rocm_mem_attr = ucs_derived_of(mem_attr,ucm_rocmmem_attr_t);
206+
ucs_free(rocm_mem_attr);
207+
}
192208

209+
static ucs_status_t ucm_rocmmem_attr_get(const void *address, size_t length,
210+
ucm_mem_attr_h *mem_attr_p)
211+
{
193212
hsa_status_t status;
194213
hsa_amd_pointer_info_t info = {
195214
.size = sizeof(hsa_amd_pointer_info_t),
196215
};
197216

198-
status = hsa_amd_pointer_info((void*)addr, &info, NULL, NULL, NULL);
199-
if (status == HSA_STATUS_SUCCESS) {
200-
if (info.type == HSA_EXT_POINTER_TYPE_UNKNOWN) return UCS_ERR_INVALID_ADDR;
217+
if (address == NULL) return UCS_ERR_INVALID_ADDR;
201218

219+
status = hsa_amd_pointer_info((void*)address, &info, NULL, NULL, NULL);
220+
if (status == HSA_STATUS_SUCCESS) {
202221
hsa_device_type_t dev_type;
222+
if (info.type == HSA_EXT_POINTER_TYPE_UNKNOWN) return UCS_ERR_INVALID_ADDR;
203223
status = hsa_agent_get_info(info.agentOwner, HSA_AGENT_INFO_DEVICE, &dev_type);
204224
if (status == HSA_STATUS_SUCCESS) {
225+
ucm_rocmmem_attr_t *mem_attr;
226+
mem_attr = ucs_malloc(sizeof(*mem_attr),"rocmmem_attr");
227+
if (mem_attr == NULL) return UCS_ERR_NO_MEMORY;
205228
switch (dev_type) {
206229
case HSA_DEVICE_TYPE_GPU:
207-
mem_attr->mem_type = UCS_MEMORY_TYPE_ROCM;
230+
mem_attr->super.mem_type = UCS_MEMORY_TYPE_ROCM;
208231
break;
209232
case HSA_DEVICE_TYPE_CPU:
210-
mem_attr->mem_type = UCS_MEMORY_TYPE_HOST;
233+
mem_attr->super.mem_type = UCS_MEMORY_TYPE_HOST;
211234
break;
212235
default:
213236
return UCS_ERR_INVALID_ADDR;
214237
}
238+
mem_attr->super.cmp = &ucm_rocmmem_attr_cmp;
239+
mem_attr->super.destroy = &ucm_rocmmem_attr_destroy;
240+
*mem_attr_p = &mem_attr->super;
215241
return UCS_OK;
216242
}
217243
}
218244

219-
ucs_error("failed to get AMD pointer info");
245+
ucm_error("failed to get AMD pointer info");
220246
return UCS_ERR_NO_RESOURCE;
221247
}
222248

src/ucm/util/sys.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include <ucm/api/ucm.h>
1818
#include <ucm/util/log.h>
19-
#include <ucm/event/event.h>
2019
#include <ucm/mmap/mmap.h>
2120
#include <ucs/sys/math.h>
2221
#include <linux/mman.h>
@@ -350,26 +349,3 @@ char *ucm_concat_path(char *buffer, size_t max, const char *dir, const char *fil
350349

351350
return buffer;
352351
}
353-
354-
ucs_status_t ucm_mem_attr_get(const void *address, size_t length,
355-
ucs_memory_attr_t *mem_attr)
356-
{
357-
ucm_event_installer_t *event_installer;
358-
ucs_status_t status;
359-
int failure = 0;
360-
361-
ucs_list_for_each(event_installer, &ucm_event_installer_list, list) {
362-
if (NULL == event_installer->get_mem_attr) continue;
363-
status = event_installer->get_mem_attr(address, length, mem_attr);
364-
if (status == UCS_OK) return UCS_OK;
365-
if (status != UCS_ERR_INVALID_ADDR) failure = 1;
366-
}
367-
368-
if (failure) {
369-
mem_attr->mem_type = UCS_MEMORY_TYPE_UNKNOWN;
370-
return UCS_ERR_NO_RESOURCE;
371-
}
372-
373-
mem_attr->mem_type = UCS_MEMORY_TYPE_HOST;
374-
return UCS_OK;
375-
}

src/ucm/util/sys.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
#define UCM_UTIL_SYS_H_
1010

1111
#include <stddef.h>
12-
#include <ucs/memory/memory_type.h>
13-
#include <ucs/type/status.h>
1412

1513

1614
/*
@@ -90,17 +88,4 @@ void ucm_prevent_dl_unload();
9088
char *ucm_concat_path(char *buffer, size_t max, const char *dir, const char *file);
9189

9290

93-
/*
94-
* Get the memory attributes of a given address and length.
95-
*
96-
* @param [in] address Buffer address.
97-
* @param [in] length Buffer length.
98-
* @param [out] mem_attr Memory attributes as defined by @ref ucs_memory_attr_t.
99-
*
100-
* @return Error code as defined by @ref ucs_status_t.
101-
*/
102-
ucs_status_t ucm_mem_attr_get(const void *address, size_t length,
103-
ucs_memory_attr_t *mem_attr);
104-
105-
10691
#endif

0 commit comments

Comments
 (0)