tiling_1d.c 5.33 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
#include "aml/tiling/1d.h"
13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include <assert.h>

/*******************************************************************************
 * 1D Iterator
 ******************************************************************************/

int aml_tiling_iterator_1d_reset(struct aml_tiling_iterator_data *data)
{
	struct aml_tiling_iterator_1d_data *it =
		(struct aml_tiling_iterator_1d_data *)data;
	it->i = 0;
	return 0;
}

Kamil Iskra's avatar
Kamil Iskra committed
27
int aml_tiling_iterator_1d_end(const struct aml_tiling_iterator_data *data)
28
{
Kamil Iskra's avatar
Kamil Iskra committed
29 30
	const struct aml_tiling_iterator_1d_data *it =
		(const struct aml_tiling_iterator_1d_data *)data;
31 32 33 34 35 36 37 38 39 40 41
	return it->i * it->tiling->blocksize >= it->tiling->totalsize;
}

int aml_tiling_iterator_1d_next(struct aml_tiling_iterator_data *data)
{
	struct aml_tiling_iterator_1d_data *it =
		(struct aml_tiling_iterator_1d_data *)data;
	it->i++;
	return 0;
}

Kamil Iskra's avatar
Kamil Iskra committed
42
int aml_tiling_iterator_1d_get(const struct aml_tiling_iterator_data *data,
43 44
			       va_list args)
{
Kamil Iskra's avatar
Kamil Iskra committed
45 46
	const struct aml_tiling_iterator_1d_data *it =
		(const struct aml_tiling_iterator_1d_data *)data;
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	unsigned long *x = va_arg(args, unsigned long *);
	*x = it->i;
	return 0;
}

struct aml_tiling_iterator_ops aml_tiling_iterator_1d_ops = {
	aml_tiling_iterator_1d_reset,
	aml_tiling_iterator_1d_next,
	aml_tiling_iterator_1d_end,
	aml_tiling_iterator_1d_get,
};

/*******************************************************************************
 * 1D ops
 ******************************************************************************/

63 64
int aml_tiling_1d_tileid(const struct aml_tiling_data *t, va_list ap)
{
65
	(void)t;
66 67 68 69
	size_t x = va_arg(ap, size_t);
	return x;
}

Kamil Iskra's avatar
Kamil Iskra committed
70
size_t aml_tiling_1d_tilesize(const struct aml_tiling_data *t, int tileid)
71
{
Kamil Iskra's avatar
Kamil Iskra committed
72 73
	const struct aml_tiling_1d_data *data =
		(const struct aml_tiling_1d_data *)t;
74 75

	if (tileid < 0)
76 77 78
		return 0;
	else
		return data->blocksize;
79 80
}

81 82
void *aml_tiling_1d_tilestart(const struct aml_tiling_data *t,
			      const void *ptr, int tileid)
83
{
Kamil Iskra's avatar
Kamil Iskra committed
84 85
	const struct aml_tiling_1d_data *data =
		(const struct aml_tiling_1d_data *)t;
86
	intptr_t p = (intptr_t)ptr;
87 88

	if (tileid < 0)
89 90 91
		return NULL;
	else
		return (void *)(p + tileid*data->blocksize);
92 93
}

94 95 96 97 98 99
int aml_tiling_1d_ndims(const struct aml_tiling_data *t, va_list ap)
{
	const struct aml_tiling_1d_data *data =
		(const struct aml_tiling_1d_data *)t;
	size_t *x = va_arg(ap, size_t *);
	*x = data->totalsize/data->blocksize;
100
	if (data->totalsize % data->blocksize != 0)
101
		*x += 1;
102 103 104
	return 0;
}

105 106 107 108
int aml_tiling_1d_init_iterator(struct aml_tiling_data *t,
				struct aml_tiling_iterator *it, int flags)
{
	assert(it->data != NULL);
109
	(void)flags;
110
	struct aml_tiling_iterator_1d_data *data =
111
		(struct aml_tiling_iterator_1d_data *)it->data;
112

113 114 115 116 117 118
	it->ops = &aml_tiling_iterator_1d_ops;
	data->i = 0;
	data->tiling = (struct aml_tiling_1d_data *)t;
	return 0;
}

119
int aml_tiling_1d_create_iterator(struct aml_tiling_data *tiling,
120 121 122
				  struct aml_tiling_iterator **it, int flags)
{
	struct aml_tiling_iterator *ret;
123 124
	struct aml_tiling_iterator_1d_data *data;
	(void)flags;
125

126 127
	if (it == NULL)
		return -AML_EINVAL;
128

129
	*it = NULL;
130

131 132 133
	ret = calloc(1, sizeof(struct aml_tiling_iterator));
	if (ret == NULL)
		return -AML_ENOMEM;
134

135 136 137 138 139 140 141 142 143 144 145
	ret->ops = &aml_tiling_iterator_1d_ops;
	ret->data = calloc(1, sizeof(struct aml_tiling_iterator_1d_data));
	if (ret->data == NULL) {
		free(ret);
		return -AML_ENOMEM;
	}
	data = (struct aml_tiling_iterator_1d_data *)ret->data;
	data->i = 0;
	data->tiling = (struct aml_tiling_1d_data *)tiling;
	*it = ret;
	return AML_SUCCESS;
146 147
}

148
int aml_tiling_1d_destroy_iterator(struct aml_tiling_data *t,
149
				   struct aml_tiling_iterator **iter)
150
{
151
	struct aml_tiling_iterator *it;
152
	(void)t;
153 154 155 156 157 158 159 160 161 162

	if (iter == NULL)
		return -AML_EINVAL;
	it = *iter;
	if (it == NULL || it->data == NULL)
		return -AML_EINVAL;
	free(it->data);
	free(it);
	*iter = NULL;
	return AML_SUCCESS;
163 164
}

165 166 167
struct aml_tiling_ops aml_tiling_1d_ops = {
	aml_tiling_1d_create_iterator,
	aml_tiling_1d_destroy_iterator,
168
	aml_tiling_1d_tileid,
169 170
	aml_tiling_1d_tilesize,
	aml_tiling_1d_tilestart,
171
	aml_tiling_1d_ndims,
172
};
173 174 175 176 177

/*******************************************************************************
 * 1D create/destroy
 ******************************************************************************/

178
int aml_tiling_1d_create(struct aml_tiling **tiling,
179 180 181
			 size_t tilesize, size_t totalsize)
{
	struct aml_tiling *ret = NULL;
182
	struct aml_tiling_1d_data *t;
183

184
	if (tiling == NULL || tilesize > totalsize)
185 186
		return -AML_EINVAL;

187 188
	*tiling = NULL;

189
	/* alloc */
190
	ret = calloc(1, sizeof(struct aml_tiling));
Swann Perarnau's avatar
Swann Perarnau committed
191
	if (ret == NULL)
192
		return -AML_ENOMEM;
Swann Perarnau's avatar
Swann Perarnau committed
193

194
	ret->ops = &aml_tiling_1d_ops;
195 196
	ret->data = calloc(1, sizeof(struct aml_tiling_1d_data));
	if (ret->data == NULL) {
197
		free(ret);
198
		return -AML_ENOMEM;
199
	}
200
	t = (struct aml_tiling_1d_data *) ret->data;
201

202 203
	t->blocksize = tilesize;
	t->totalsize = totalsize;
204

205 206
	*tiling = ret;
	return AML_SUCCESS;
207 208
}

209
void aml_tiling_1d_destroy(struct aml_tiling **tiling)
210
{
211
	struct aml_tiling *t;
212

213 214 215 216
	if (tiling == NULL)
		return;
	t = *tiling;
	if (t == NULL || t->data == NULL)
217
		return;
218 219 220
	free(t->data);
	free(t);
	*tiling = NULL;
221 222
}