tiling_2d.c 4.85 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 14 15 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
#include <assert.h>

/*******************************************************************************
 * 2D Iterator
 ******************************************************************************/

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

int aml_tiling_iterator_2d_end(const struct aml_tiling_iterator_data *data)
{
	const struct aml_tiling_iterator_2d_data *it =
		(const struct aml_tiling_iterator_2d_data *)data;
	return it->i * it->tiling->blocksize >= it->tiling->totalsize;
}

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

int aml_tiling_iterator_2d_get(const struct aml_tiling_iterator_data *data,
			       va_list args)
{
	const struct aml_tiling_iterator_2d_data *it =
		(const struct aml_tiling_iterator_2d_data *)data;
	unsigned long *x = va_arg(args, unsigned long *);
	*x = it->i;
	return 0;
}

struct aml_tiling_iterator_ops aml_tiling_iterator_2d_ops = {
	aml_tiling_iterator_2d_reset,
	aml_tiling_iterator_2d_next,
	aml_tiling_iterator_2d_end,
	aml_tiling_iterator_2d_get,
};

/*******************************************************************************
 * 2D ops
60
 * Tileids are the order in memory of the tiles.
61 62
 ******************************************************************************/

63
int aml_tiling_2d_rowmajor_tileid(const struct aml_tiling_data *t, va_list ap)
64 65 66
{
	const struct aml_tiling_2d_data *data =
		(const struct aml_tiling_2d_data *)t;
67 68 69 70 71 72
	size_t row = va_arg(ap, size_t);
	size_t col = va_arg(ap, size_t);
	if(row >= data->ndims[0] || col >= data->ndims[1])
		return -1;
	else
		return (row*data->ndims[1]) + col;
73 74
}

75
int aml_tiling_2d_colmajor_tileid(const struct aml_tiling_data *t, va_list ap)
76 77 78
{
	const struct aml_tiling_2d_data *data =
		(const struct aml_tiling_2d_data *)t;
79 80 81 82
	size_t row = va_arg(ap, size_t);
	size_t col = va_arg(ap, size_t);
	if(row >= data->ndims[0] || col >= data->ndims[1])
		return -1;
83
	else
84
		return (col*data->ndims[0]) + row;
85 86
}

87 88 89 90 91 92 93 94 95 96 97 98
size_t aml_tiling_2d_tilesize(const struct aml_tiling_data *t, int tileid)
{
	const struct aml_tiling_2d_data *data =
		(const struct aml_tiling_2d_data *)t;
	if(tileid < 0 || tileid >= data->ndims[0]*data->ndims[1])
		return 0;
	else
		return data->blocksize;
}

void* aml_tiling_2d_tilestart(const struct aml_tiling_data *t,
			      const void *ptr, int tileid)
99 100 101 102
{
	const struct aml_tiling_2d_data *data =
		(const struct aml_tiling_2d_data *)t;
	intptr_t p = (intptr_t)ptr;
103
	if(tileid < 0 || tileid >= data->ndims[0]*data->ndims[1])
104 105
		return NULL;
	else
106
		return (void *)(p + tileid*data->blocksize);
107 108 109 110 111 112
}

int aml_tiling_2d_ndims(const struct aml_tiling_data *t, va_list ap)
{
	const struct aml_tiling_2d_data *data =
		(const struct aml_tiling_2d_data *)t;
113 114
	size_t *nrows = va_arg(ap, size_t *);
	size_t *ncols = va_arg(ap, size_t *);
115
	/* looks totally wrong */
116 117
	*nrows = data->ndims[0];
	*ncols = data->ndims[1];
118 119 120 121 122 123 124
	return 0;
}

int aml_tiling_2d_init_iterator(struct aml_tiling_data *t,
				struct aml_tiling_iterator *it, int flags)
{
	assert(it->data != NULL);
125
	struct aml_tiling_iterator_2d_data *data =
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
		(struct aml_tiling_iterator_2d_data *)it->data;
	it->ops = &aml_tiling_iterator_2d_ops;
	data->i = 0;
	data->tiling = (struct aml_tiling_2d_data *)t;
	return 0;
}

int aml_tiling_2d_create_iterator(struct aml_tiling_data *t,
				  struct aml_tiling_iterator **it, int flags)
{
	intptr_t baseptr, dataptr;
	struct aml_tiling_iterator *ret;
	baseptr = (intptr_t) calloc(1, AML_TILING_ITERATOR_2D_ALLOCSIZE);
	dataptr = baseptr + sizeof(struct aml_tiling_iterator);

	ret = (struct aml_tiling_iterator *)baseptr;
	ret->data = (struct aml_tiling_iterator_data *)dataptr;

	aml_tiling_2d_init_iterator(t, ret, flags);
	*it = ret;
	return 0;
}


int aml_tiling_2d_destroy_iterator(struct aml_tiling_data *t,
				   struct aml_tiling_iterator *it)
{
	return 0;
}


157 158 159 160
struct aml_tiling_ops aml_tiling_2d_rowmajor_ops = {
	aml_tiling_2d_create_iterator,
	aml_tiling_2d_init_iterator,
	aml_tiling_2d_destroy_iterator,
161
	aml_tiling_2d_rowmajor_tileid,
162
	aml_tiling_2d_tilesize,
163
	aml_tiling_2d_tilestart,
164 165 166 167
	aml_tiling_2d_ndims,
};

struct aml_tiling_ops aml_tiling_2d_colmajor_ops = {
168 169 170
	aml_tiling_2d_create_iterator,
	aml_tiling_2d_init_iterator,
	aml_tiling_2d_destroy_iterator,
171
	aml_tiling_2d_colmajor_tileid,
172
	aml_tiling_2d_tilesize,
173
	aml_tiling_2d_tilestart,
174
	aml_tiling_2d_ndims,
175
};