dma.c 3.37 KB
Newer Older
Swann Perarnau's avatar
Swann Perarnau committed
1 2 3 4 5 6 7 8 9 10
/*******************************************************************************
 * Copyright 2019 UChicago Argonne, LLC.
 * (c.f. AUTHORS, LICENSE)
 *
 * This file is part of the AML project.
 * For more info, see https://xgitlab.cels.anl.gov/argo/aml
 *
 * SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/

11
#include "aml.h"
12 13
#include "aml/layout/native.h"

14 15
#include <assert.h>

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
/*******************************************************************************
 * Generic DMA Copy implementations
 *
 * Needed by most DMAs. We don't provide introspection or any fancy API to it at
 * this point.
 ******************************************************************************/
static inline void aml_copy_layout_generic_helper(size_t d,
						  struct aml_layout *dst,
						  const struct aml_layout *src,
						  const size_t *elem_number,
						  size_t elem_size,
						  size_t *coords)
{
	if (d == 1) {
		for (size_t i = 0; i < elem_number[0]; i += 1) {
			coords[0] = i;
			memcpy(aml_layout_deref_native(dst, coords),
			       aml_layout_deref_native(src, coords),
			       elem_size);
		}
	} else {
		for (size_t i = 0; i < elem_number[d - 1]; i += 1) {
			coords[d - 1] = i;
			aml_copy_layout_generic_helper(d - 1, dst, src,
						       elem_number, elem_size,
						       coords);
		}
	}
}

int aml_copy_layout_generic(struct aml_layout *dst,
			    const struct aml_layout *src)
{
	size_t d;
	size_t elem_size;

	assert(aml_layout_ndims(dst) == aml_layout_ndims(src));
	d = aml_layout_ndims(dst);
	assert(aml_layout_element_size(dst) == aml_layout_element_size(src));
	elem_size = aml_layout_element_size(dst);

	size_t coords[d];
	size_t elem_number[d];
	size_t elem_number2[d];

	aml_layout_dims_native(src, elem_number);
	aml_layout_dims_native(dst, elem_number2);
	for (size_t i = 0; i < d; i += 1)
		assert(elem_number[i] == elem_number2[i]);
	aml_copy_layout_generic_helper(d, dst, src, elem_number, elem_size,
				       coords);
	return 0;
}

70
/*******************************************************************************
71 72 73 74 75 76
 * Generic DMA API:
 * Most of the stuff is dispatched to a different layer, using type-specific
 * functions.
 *
 * Note that the API is slightly different than the functions bellow, as we
 * abstract the request creation after this layer.
77 78
 ******************************************************************************/

79 80
int aml_dma_copy(struct aml_dma *dma, struct aml_layout *dest,
		 struct aml_layout *src)
81
{
82
	int ret;
83
	struct aml_dma_request *req;
84

85
	if (dma == NULL || dest == NULL || src == NULL)
86 87
		return -AML_EINVAL;

88
	ret = dma->ops->create_request(dma->data, &req, dest, src);
Swann Perarnau's avatar
Swann Perarnau committed
89 90 91
	if (ret != AML_SUCCESS)
		return ret;
	ret = dma->ops->wait_request(dma->data, &req);
92
	return ret;
93 94
}

95
int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req,
96
		       struct aml_layout *dest, struct aml_layout *src)
97
{
98
	if (dma == NULL || req == NULL || dest == NULL || src == NULL)
99 100
		return -AML_EINVAL;

101
	return dma->ops->create_request(dma->data, req, dest, src);
102 103
}

Swann Perarnau's avatar
Swann Perarnau committed
104
int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request **req)
105
{
Swann Perarnau's avatar
Swann Perarnau committed
106 107
	if (dma == NULL || req == NULL)
		return -AML_EINVAL;
108 109 110
	return dma->ops->destroy_request(dma->data, req);
}

Swann Perarnau's avatar
Swann Perarnau committed
111
int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request **req)
112
{
Swann Perarnau's avatar
Swann Perarnau committed
113 114
	if (dma == NULL || req == NULL)
		return -AML_EINVAL;
115
	return dma->ops->wait_request(dma->data, req);
116
}