| 1 | /* This header file contains the function prototypes for
|
|---|
| 2 | * transforming Fortran arrays.
|
|---|
| 3 | */
|
|---|
| 4 |
|
|---|
| 5 | #ifndef __FORTRANARRAY_C__
|
|---|
| 6 | #define __FORTRANARRAY_C__
|
|---|
| 7 |
|
|---|
| 8 | #include <fortran_array.cvh>
|
|---|
| 9 |
|
|---|
| 10 | /* ********************************* Types ********************************* */
|
|---|
| 11 |
|
|---|
| 12 | /* The kind of a Fortran array descriptor. */
|
|---|
| 13 | typedef enum FORTRAN_ARRAY_DESCRIPTOR_KIND {
|
|---|
| 14 | SOURCE, // A var. decl. w/ an array type or a dimension attr.
|
|---|
| 15 | SECTION, // An array section
|
|---|
| 16 | RESHAPE // An array, whose indices are reshaped w/ no cloning
|
|---|
| 17 | } farr_kind;
|
|---|
| 18 |
|
|---|
| 19 | /* The memory space storing all data objects and only
|
|---|
| 20 | * referenced by a SOURCE fortran array descriptor
|
|---|
| 21 | */
|
|---|
| 22 | struct FORTRAN_ARRAY_MEMORY {
|
|---|
| 23 | unsigned int num; // The num. of data objects stored
|
|---|
| 24 | int type; // The type of data objects stored
|
|---|
| 25 | void *data; // The ptr. to data objects stored.
|
|---|
| 26 | };
|
|---|
| 27 |
|
|---|
| 28 | /* A Fortran array descriptor indicating a Fortran array,
|
|---|
| 29 | * which is any of three kinds mentioned above.
|
|---|
| 30 | */
|
|---|
| 31 | struct FORTRAN_ARRAY_DESCRIPTOR {
|
|---|
| 32 | farr_kind kind; // The kind of a Fortran array descriptor
|
|---|
| 33 | unsigned int rank; // The rank or the number of dimensions.
|
|---|
| 34 | int *lbnd; // A list of index left-bounds for each dim.
|
|---|
| 35 | int *rbnd; // A list of index right-bounds for each dim.
|
|---|
| 36 | int *strd; // A list of index stride for each dim.
|
|---|
| 37 | farr_mem memory; // Being non-null iff kind is 'SOURCE'
|
|---|
| 38 | farr_desc parent; // Being non-null iff kind is NOT 'SOURCE'
|
|---|
| 39 | };
|
|---|
| 40 |
|
|---|
| 41 | /* **************************** Misc. Functions **************************** */
|
|---|
| 42 | /* Creates a Fortran array descriptor
|
|---|
| 43 | * for a variable declaration with an array type.
|
|---|
| 44 | */
|
|---|
| 45 | farr_desc farr_create(
|
|---|
| 46 | size_t type, // The type of array element
|
|---|
| 47 | int rank, // The rank/dimensions
|
|---|
| 48 | int rank_info[SIZE_IDX_INFO][rank]
|
|---|
| 49 | // All indexing info for each dim.
|
|---|
| 50 | ) {
|
|---|
| 51 | farr_desc arr = (farr_desc)malloc(sizeof(*arr));
|
|---|
| 52 | int total = 1;
|
|---|
| 53 | int lbnd, rbnd, strd;
|
|---|
| 54 |
|
|---|
| 55 | arr->kind = SOURCE;
|
|---|
| 56 | arr->rank = rank;
|
|---|
| 57 | arr->lbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 58 | arr->rbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 59 | arr->strd = (int*)malloc(rank * sizeof(int));
|
|---|
| 60 | for (int r=rank-1; r>=0; r--) {
|
|---|
| 61 | lbnd = rank_info[0][r];
|
|---|
| 62 | rbnd = rank_info[1][r];
|
|---|
| 63 | strd = rank_info[2][r];
|
|---|
| 64 | arr->lbnd[r] = lbnd;
|
|---|
| 65 | arr->rbnd[r] = rbnd;
|
|---|
| 66 | arr->strd[r] = strd;
|
|---|
| 67 | total *= (rbnd - lbnd) / strd + 1;
|
|---|
| 68 | }
|
|---|
| 69 | arr->memory = (farr_mem)malloc(sizeof(*(arr->memory)));
|
|---|
| 70 | arr->memory->num = total;
|
|---|
| 71 | arr->memory->type = type;
|
|---|
| 72 |
|
|---|
| 73 | if (type == sizeof(int)) {
|
|---|
| 74 | $assume(type != sizeof(float));
|
|---|
| 75 | arr->memory->data = (int*)malloc(total * type);
|
|---|
| 76 | } else if (type == sizeof(float)) {
|
|---|
| 77 | $assume(type != sizeof(int));
|
|---|
| 78 | arr->memory->data = (float*)malloc(total * type);
|
|---|
| 79 | } else if (type == sizeof(double)) {
|
|---|
| 80 | $assume(type != sizeof(int));
|
|---|
| 81 | arr->memory->data = (double*)malloc(total * type);
|
|---|
| 82 | } else {
|
|---|
| 83 | $assume(type != sizeof(int));
|
|---|
| 84 | $assume(type != sizeof(float));
|
|---|
| 85 | arr->memory->data = (char*)malloc(total * type);
|
|---|
| 86 | }
|
|---|
| 87 | return arr;
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | /* Creates a Fortran array descriptor
|
|---|
| 91 | * for an array sectioned from an base array.
|
|---|
| 92 | */
|
|---|
| 93 | farr_desc farr_section(
|
|---|
| 94 | farr_desc arr, // The descriptor of the base array.
|
|---|
| 95 | int sect_info[SIZE_IDX_INFO][arr->rank]
|
|---|
| 96 | // All indexing info for each dim.
|
|---|
| 97 | ) {
|
|---|
| 98 | farr_desc sct = (farr_desc)malloc(sizeof(*sct));
|
|---|
| 99 | int rank = arr->rank;
|
|---|
| 100 |
|
|---|
| 101 | sct->kind = SECTION;
|
|---|
| 102 | sct->rank = rank;
|
|---|
| 103 | sct->lbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 104 | sct->rbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 105 | sct->strd = (int*)malloc(rank * sizeof(int));
|
|---|
| 106 | for (int r=rank-1; r>=0; r--) {
|
|---|
| 107 | sct->lbnd[r] = sect_info[0][r];
|
|---|
| 108 | sct->rbnd[r] = sect_info[1][r];
|
|---|
| 109 | sct->strd[r] = sect_info[2][r];
|
|---|
| 110 | }
|
|---|
| 111 | sct->parent = arr;
|
|---|
| 112 | return sct;
|
|---|
| 113 | }
|
|---|
| 114 |
|
|---|
| 115 | farr_desc farr_section_full (
|
|---|
| 116 | farr_desc arr // The descriptor of the base array.
|
|---|
| 117 | ) {
|
|---|
| 118 | farr_desc sct = (farr_desc)malloc(sizeof(*sct));
|
|---|
| 119 | int rank = arr->rank;
|
|---|
| 120 |
|
|---|
| 121 | sct->kind = SECTION;
|
|---|
| 122 | sct->rank = rank;
|
|---|
| 123 | sct->lbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 124 | sct->rbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 125 | sct->strd = (int*)malloc(rank * sizeof(int));
|
|---|
| 126 | for (int r=rank-1; r>=0; r--) {
|
|---|
| 127 | sct->lbnd[r] = arr->lbnd[r];
|
|---|
| 128 | sct->rbnd[r] = arr->rbnd[r];
|
|---|
| 129 | sct->strd[r] = arr->strd[r];
|
|---|
| 130 | }
|
|---|
| 131 | sct->parent = arr;
|
|---|
| 132 | return sct;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | /* Creates a Fortran array descriptor
|
|---|
| 136 | * for an array reshaped from an base array.
|
|---|
| 137 | */
|
|---|
| 138 | farr_desc farr_reshape(
|
|---|
| 139 | farr_desc arr, // The descriptor of the base array.
|
|---|
| 140 | int rank, // The new rank for reshaping.
|
|---|
| 141 | int rshp_info[SIZE_IDX_INFO][rank]
|
|---|
| 142 | // All indexing info for each dim.
|
|---|
| 143 | ) {
|
|---|
| 144 | farr_desc rsp = (farr_desc)malloc(sizeof(*rsp));
|
|---|
| 145 |
|
|---|
| 146 | rsp->kind = RESHAPE;
|
|---|
| 147 | rsp->rank = rank;
|
|---|
| 148 | rsp->lbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 149 | rsp->rbnd = (int*)malloc(rank * sizeof(int));
|
|---|
| 150 | rsp->strd = (int*)malloc(rank * sizeof(int));
|
|---|
| 151 | for (int r=rank-1; r>=0; r--) {
|
|---|
| 152 | rsp->lbnd[r] = rshp_info[0][r];
|
|---|
| 153 | rsp->rbnd[r] = rshp_info[1][r];
|
|---|
| 154 | rsp->strd[r] = rshp_info[2][r];
|
|---|
| 155 | }
|
|---|
| 156 | rsp->parent = arr;
|
|---|
| 157 | return rsp;
|
|---|
| 158 | }
|
|---|
| 159 |
|
|---|
| 160 | /* Destroys a Fortran array descriptor
|
|---|
| 161 | * Note that this function only free the outer-most
|
|---|
| 162 | * descriptor if the given descriptor kind is NOT 'SOURCE'.
|
|---|
| 163 | */
|
|---|
| 164 | void farr_destroy(
|
|---|
| 165 | farr_desc arr // The outer-most descriptor is freed
|
|---|
| 166 | ){
|
|---|
| 167 | free(arr->lbnd);
|
|---|
| 168 | free(arr->rbnd);
|
|---|
| 169 | free(arr->strd);
|
|---|
| 170 | switch(arr->kind) {
|
|---|
| 171 | case SOURCE:
|
|---|
| 172 | free(arr->memory->data);
|
|---|
| 173 | free(arr->memory);
|
|---|
| 174 | break;
|
|---|
| 175 | case SECTION:
|
|---|
| 176 | case RESHAPE:
|
|---|
| 177 | arr->parent = NULL;
|
|---|
| 178 | break;
|
|---|
| 179 | }
|
|---|
| 180 | free(arr);
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | /* Operations */
|
|---|
| 184 | int indices_to_order(farr_desc desc, int indices[]) {
|
|---|
| 185 | int rank = desc->rank;
|
|---|
| 186 | int *lbnd = desc->lbnd;
|
|---|
| 187 | int *rbnd = desc->rbnd;
|
|---|
| 188 | int *strd = desc->strd;
|
|---|
| 189 | int order = 0;
|
|---|
| 190 | int size_rank = 1;
|
|---|
| 191 |
|
|---|
| 192 | for (int r=rank-1; r>=0; r--) {
|
|---|
| 193 | order += ((indices[r] - lbnd[r]) / strd[r]) * size_rank;
|
|---|
| 194 | size_rank *= (rbnd[r] - lbnd[r]) / strd[r] + 1;
|
|---|
| 195 | }
|
|---|
| 196 | return order;
|
|---|
| 197 | }
|
|---|
| 198 |
|
|---|
| 199 | int* order_to_indices(farr_desc desc, int order) {
|
|---|
| 200 | int rank = desc->rank;
|
|---|
| 201 | int* indices = (int*)malloc(rank * sizeof(int));
|
|---|
| 202 | int rank_size = 1;
|
|---|
| 203 | int rank_sizes[rank];
|
|---|
| 204 |
|
|---|
| 205 | for (int r=rank-1; r>=0; r--) {
|
|---|
| 206 | rank_sizes[r] = rank_size;
|
|---|
| 207 | rank_size *= (desc->rbnd[r] - desc->lbnd[r]) / desc->strd[r] + 1;
|
|---|
| 208 | }
|
|---|
| 209 | for (int r=0; r<rank;r++) {
|
|---|
| 210 | int shift = order / rank_sizes[r];
|
|---|
| 211 |
|
|---|
| 212 | indices[r] = shift*desc->strd[r] + desc->lbnd[r];
|
|---|
| 213 | order -= shift * rank_sizes[r];
|
|---|
| 214 | }
|
|---|
| 215 | return indices;
|
|---|
| 216 | }
|
|---|
| 217 |
|
|---|
| 218 | /* Gets the pointer to a Fortran array data object
|
|---|
| 219 | * from the given array and the related indices.
|
|---|
| 220 | */
|
|---|
| 221 | void *farr_subscript(
|
|---|
| 222 | farr_desc arr, // The array descriptor
|
|---|
| 223 | int indices[], // Indices for each rank/dim.
|
|---|
| 224 | int isDirect
|
|---|
| 225 | ){
|
|---|
| 226 | switch(arr->kind) {
|
|---|
| 227 | case SOURCE:
|
|---|
| 228 | {
|
|---|
| 229 | farr_mem arr_mem = arr->memory;
|
|---|
| 230 | size_t arr_type = arr_mem->type;
|
|---|
| 231 | int elem_offset = indices_to_order(arr, indices); // * arr_type / sizeof(int);
|
|---|
| 232 |
|
|---|
| 233 | if (isDirect == 1) free(indices);
|
|---|
| 234 | return (arr_mem->data) + elem_offset;
|
|---|
| 235 | }
|
|---|
| 236 | case SECTION:
|
|---|
| 237 | {
|
|---|
| 238 | int order = indices_to_order(arr, indices);
|
|---|
| 239 |
|
|---|
| 240 | if (isDirect == 1) free(indices);
|
|---|
| 241 | return farr_subscript(arr->parent, order_to_indices(arr, order), 1);
|
|---|
| 242 | }
|
|---|
| 243 | case RESHAPE:
|
|---|
| 244 | {
|
|---|
| 245 | int order = indices_to_order(arr, indices);
|
|---|
| 246 | farr_desc parent = arr->parent;
|
|---|
| 247 |
|
|---|
| 248 | if (isDirect == 1) free(indices);
|
|---|
| 249 | return farr_subscript(arr->parent, order_to_indices(parent, order), 1);
|
|---|
| 250 | }
|
|---|
| 251 | }
|
|---|
| 252 | }
|
|---|
| 253 |
|
|---|
| 254 |
|
|---|
| 255 | void *farr_c_array(
|
|---|
| 256 | size_t type, // The type of array element
|
|---|
| 257 | int rank, // The rank/dimensions
|
|---|
| 258 | int rank_info[SIZE_IDX_INFO][rank]
|
|---|
| 259 | // All indexing info for each dim.
|
|---|
| 260 | ){
|
|---|
| 261 | }
|
|---|
| 262 |
|
|---|
| 263 | int farr_stat(
|
|---|
| 264 | farr_desc arr // The array descriptor
|
|---|
| 265 | ){
|
|---|
| 266 | if (arr->lbnd == NULL ||
|
|---|
| 267 | arr->rbnd == NULL ||
|
|---|
| 268 | arr->strd == NULL ||
|
|---|
| 269 | arr->memory == NULL ||
|
|---|
| 270 | arr->memory->data == NULL) {
|
|---|
| 271 | return 1;
|
|---|
| 272 | } else {
|
|---|
| 273 | return 0;
|
|---|
| 274 | }
|
|---|
| 275 | }
|
|---|
| 276 |
|
|---|
| 277 | #endif
|
|---|