| 3 | | == Redesign the Preprocessor == |
| 4 | | |
| 5 | | === 1. Preprocessor === |
| 6 | | 1). Input: Raw '''char stream''' read from source files |
| 7 | | |
| 8 | | 2). Output: A pp-token stream |
| 9 | | |
| 10 | | === 2. PP Token Converter === |
| 11 | | 1). Input: A pp-token stream |
| 12 | | |
| 13 | | 2). Output: A CIVL-C token stream. |
| 14 | | |
| 15 | | 3). Functionality: |
| 16 | | |
| 17 | | Based on a specific programming language (C/CIVL-C or Fortran), the convertor analyzes |
| 18 | | each pp-token and generates a corresponding !CIVLCToken for each of them. |
| 19 | | |
| 20 | | === 3. Language Based Parser === |
| 21 | | 1). Input: A CIVLCToken stream |
| 22 | | |
| 23 | | 2). Output: A CIVL parse tree |
| 24 | | |
| 25 | | |
| 26 | | == Meeting Notes for Fortran Front-End == |
| 27 | | === 01-08-2019 === |
| 28 | | 0). The preprocessor will only create and handle pp-tokens (preprocess tokens). |
| 29 | | |
| 30 | | 1). All language specific tokens & keywords should be created after the preprocess procedure. |
| 31 | | |
| 32 | | 2). Language grammar based converters (C/CIVL-C & Fortran) should be developed for generating CIVLC tokens from pp-tokens. |
| 33 | | |
| 34 | | 3). Different parsers will be used for pars the CIVL-C token stream |
| 35 | | |
| 36 | | === === |
| 37 | | 1). A detailed plan of adding, removing and changing class/grammar files |
| 38 | | |
| 39 | | 2). |
| 40 | | Preprocessor grammar: (Both Prep Lexer and Parser grammars in one file) |
| 41 | | |
| 42 | | CIVLC Lexer grammar: (Mainly for debugging) |
| 43 | | Defines all CIVLC Tokens |
| 44 | | |
| 45 | | PP2CIVLTokenConverter |
| 46 | | Converts a pp-token to a CIVLC token, or combine several into a single CIVLC token like `..` |
| 47 | | |
| 48 | | CIVLC Parser grammar: (Using CIVLC Token) |
| 49 | | |
| 50 | | Fortran Parser grammar: (Using CIVLC Token) |
| 51 | | |
| 52 | | |
| 53 | | |
| 54 | | == Front End Packages and Classes == |
| 55 | | |
| 56 | | edu.udel.cis.vsl.abc.front |
| 57 | | |
| 58 | | edu.udel.cis.vsl.abc.front.IF |
| | 3 | == 1. Fortran Array Section Transformation == |
| | 4 | |
| | 5 | Here is the prototype of handling Fortran array sections: |
| | 6 | |
| | 7 | {{{ |
| | 8 | /* e.g., |
| | 9 | PROGRAM EXAMPLE |
| | 10 | INTEGER SRC_ARR(1:3:1) |
| | 11 | ! source array SRC_ARR := /(1)=x,(2)=y,(3)=z/ |
| | 12 | ! source section SRC_ARR(1:3:2) := /(1)=x, (3)=z/ |
| | 13 | CALL CUT(2, SRC_ARR(1:3:2)) |
| | 14 | END |
| | 15 | SUBROUTINE CUT(N, SRC_SEC) |
| | 16 | INTEGER CUR_ARR(2:4:2) |
| | 17 | CUR_ARR = SRC_SEC |
| | 18 | ! current array CUR_ARR := /(2)=x, (4)=z/ |
| | 19 | END |
| | 20 | ! note1: the current array and its source section |
| | 21 | ! SAME shift: CUR_ARR and SRC_ARR(1:3:2) have a same |
| | 22 | ! 1st elem., which is x. |
| | 23 | ! DIFF index: The 1st elem. has an index of 2 in |
| | 24 | ! CUR_ARR, while 1 in SRC_ARR(1:3:2). |
| | 25 | ! note2: the source section and its source array |
| | 26 | ! SAME index: SRC_ARR and SRC_ARR(1:3:2) have a same |
| | 27 | ! indexing system. |
| | 28 | ! DIFF shift: their 2nd element are different. |
| | 29 | */ |
| | 30 | |
| | 31 | #include <stdlib.h> |
| | 32 | #include <stdio.h> |
| | 33 | #include <string.h> |
| | 34 | |
| | 35 | typedef struct CIVL_FORTRAN_ARRAY { |
| | 36 | // The number of dimensions |
| | 37 | int num_dims; |
| | 38 | // Dimention Info |
| | 39 | int *lbnds; // Left bounds for each dim. |
| | 40 | int *rbnds; // Right bounds for each dim. |
| | 41 | int *dists; // Distances of two neighbour elements in each dim. |
| | 42 | // Data Info |
| | 43 | unsigned int size_data; |
| | 44 | void* data; |
| | 45 | // Source CIVL_FORTRAN_ARRAY_TYPE |
| | 46 | struct CIVL_FORTRAN_ARRAY *src_arr; |
| | 47 | } * f_arr; |
| | 48 | |
| | 49 | /* Returns the sequential position in a row-major order */ |
| | 50 | int calc_seq_pos(f_arr arr, int shfts[]) { |
| | 51 | int n_dims = arr->num_dims; |
| | 52 | int *lbnds = arr->lbnds; |
| | 53 | int *rbnds = arr->rbnds; |
| | 54 | int *dists = arr->dists; |
| | 55 | int seq_pos = 0; |
| | 56 | int size_dim = 1; |
| | 57 | |
| | 58 | for(int i=n_dims-1; i>=0; i--) { |
| | 59 | seq_pos += (shfts[i]) * size_dim; |
| | 60 | size_dim *= (rbnds[i] - lbnds[i]) / dists[i] + 1; |
| | 61 | } |
| | 62 | return seq_pos; |
| | 63 | } |
| | 64 | |
| | 65 | int get_seq_pos(f_arr arr, int idxes[]) { |
| | 66 | /* PRE: 'arr' shall NOT be NULL. */ |
| | 67 | // EXTRACT: the cur. arr. info. |
| | 68 | int n_dims = arr->num_dims; |
| | 69 | int *lbnds = arr->lbnds; |
| | 70 | int *dists = arr->dists; |
| | 71 | int shfts[n_dims]; |
| | 72 | |
| | 73 | // CALC.: rel. shifts for each dim. in cur. arr. |
| | 74 | for (int i=0; i<n_dims; i++) |
| | 75 | shfts[i] = (idxes[i] - lbnds[i]) / dists[i]; |
| | 76 | |
| | 77 | // FETCH: the src. sec. of the cur. arr. 'arr' |
| | 78 | f_arr sec = arr->src_arr; |
| | 79 | |
| | 80 | if (sec == NULL) |
| | 81 | // the cur. arr. is the original one. |
| | 82 | return calc_seq_pos(arr, shfts); |
| | 83 | //else calc. the abs. indexes in src. arr. |
| 60 | | Front.java [Unchanged] |
| 61 | | |
| 62 | | Preprocessor.java [Unchanged] |
| 63 | | |
| 64 | | !PreprocessorException.java [Moved] Move to package: `edu.udel.cis.vsl.abc.front.IF.exception` |
| 65 | | |
| 66 | | !PreprocessorExpressionException.java [Moved] Move to package: `edu.udel.cis.vsl.abc.front.IF.exception` |
| 67 | | |
| 68 | | !PreprocessorRuntimeException.java [Moved] Move to package: `edu.udel.cis.vsl.abc.front.IF.exception` |
| 69 | | |
| 70 | | !IllegalMacroArgumentException.java [Moved] Move to package: `edu.udel.cis.vsl.abc.front.IF.exception` |
| 71 | | |
| 72 | | Parser.java [Unchanged] |
| | 85 | int idxes_src[n_dims]; |
| | 86 | |
| | 87 | // EXTRACT: the source section info. |
| | 88 | lbnds = sec->lbnds; |
| | 89 | dists = sec->dists; |
| | 90 | // CALC.: abs. indexes for each dim. in the src. arr. |
| | 91 | for (int i=0; i<n_dims; i++) |
| | 92 | idxes_src[i] = lbnds[i] + shfts[i] * dists[i]; |
| | 93 | // TRACE: to the original array entity recursively. |
| | 94 | return get_seq_pos(sec->src_arr, idxes_src); |
| | 95 | } |
| | 96 | |
| | 97 | f_arr f_arr_create(unsigned int elem_size, |
| | 98 | int dim_num, |
| | 99 | int dim_info[3][dim_num]) { |
| | 100 | f_arr arr = (f_arr)malloc(sizeof(struct CIVL_FORTRAN_ARRAY)); |
| | 101 | int elem_total = 1; |
| | 102 | int lbnd, rbnd, dist; |
| | 103 | |
| | 104 | arr->num_dims = dim_num; |
| | 105 | arr->lbnds = (int*)malloc(dim_num * sizeof(int)); |
| | 106 | arr->rbnds = (int*)malloc(dim_num * sizeof(int)); |
| | 107 | arr->dists = (int*)malloc(dim_num * sizeof(int)); |
| | 108 | for (int i=dim_num-1; i>=0; i--) { |
| | 109 | lbnd = dim_info[0][i]; |
| | 110 | rbnd = dim_info[1][i]; |
| | 111 | dist = dim_info[2][i]; |
| | 112 | arr->lbnds[i] = lbnd; |
| | 113 | arr->rbnds[i] = rbnd; |
| | 114 | arr->dists[i] = dist; |
| | 115 | elem_total *= (dim_info[1][i] - dim_info[0][i]) / dim_info[2][i] + 1; |
| | 116 | } |
| | 117 | arr->size_data = elem_size; |
| | 118 | arr->data = malloc(elem_size * elem_total); |
| | 119 | arr->src_arr = NULL; |
| | 120 | return arr; |
| | 121 | } |
| | 122 | |
| | 123 | f_arr f_arr_sect(f_arr arr, int sec_info[3][arr->num_dims]) { |
| | 124 | f_arr sec = (f_arr)malloc(sizeof(struct CIVL_FORTRAN_ARRAY)); |
| | 125 | int dim_num = arr->num_dims; |
| | 126 | |
| | 127 | sec->num_dims = dim_num; |
| | 128 | sec->lbnds = (int*)malloc(dim_num * sizeof(int)); |
| | 129 | sec->rbnds = (int*)malloc(dim_num * sizeof(int)); |
| | 130 | sec->dists = (int*)malloc(dim_num * sizeof(int)); |
| | 131 | for (int i=dim_num-1; i>=0; i--) { |
| | 132 | sec->lbnds[i] = sec_info[0][i]; |
| | 133 | sec->rbnds[i] = sec_info[1][i]; |
| | 134 | sec->dists[i] = sec_info[2][i]; |
| | 135 | } |
| | 136 | sec->size_data = arr->size_data; |
| | 137 | sec->data = arr->data; |
| | 138 | sec->src_arr = arr; |
| | 139 | return sec; |
| | 140 | } |
| | 141 | |
| | 142 | f_arr f_arr_full(f_arr arr) { |
| | 143 | f_arr img = (f_arr)malloc(sizeof(struct CIVL_FORTRAN_ARRAY)); |
| | 144 | int dim_num = arr->num_dims; |
| | 145 | |
| | 146 | img->num_dims = dim_num; |
| | 147 | img->lbnds = (int*)malloc(dim_num * sizeof(int)); |
| | 148 | img->rbnds = (int*)malloc(dim_num * sizeof(int)); |
| | 149 | img->dists = (int*)malloc(dim_num * sizeof(int)); |
| | 150 | memcpy(img->lbnds, arr->lbnds, dim_num*sizeof(int)); |
| | 151 | memcpy(img->rbnds, arr->rbnds, dim_num*sizeof(int)); |
| | 152 | memcpy(img->dists, arr->dists, dim_num*sizeof(int)); |
| | 153 | img->size_data = arr->size_data; |
| | 154 | img->data = arr->data; |
| | 155 | img->src_arr = arr; |
| | 156 | return img; |
| | 157 | } |
| | 158 | |
| | 159 | void *f_arr_read(f_arr arr, int idxes[]) { |
| | 160 | int seq_pos = get_seq_pos(arr, idxes); |
| | 161 | |
| | 162 | return (arr->data) + seq_pos*arr->size_data; |
| | 163 | } |
| | 164 | |
| | 165 | void f_arr_write(f_arr arr, int idxes[], void* val) { |
| | 166 | void *elem = f_arr_read(arr, idxes); |
| | 167 | |
| | 168 | memcpy(elem, val, arr->size_data); |
| | 169 | } |
| | 170 | |
| | 171 | void f_arr_destroy(f_arr arr){ |
| | 172 | free(arr->lbnds); |
| | 173 | free(arr->rbnds); |
| | 174 | free(arr->dists); |
| | 175 | if (arr->src_arr == NULL) |
| | 176 | free(arr->data); |
| | 177 | else |
| | 178 | arr->data = NULL; |
| | 179 | free(arr); |
| | 180 | } |
| | 181 | |
| | 182 | /****************************************************/ |
| | 183 | |
| | 184 | void arr1d_print(f_arr _IARR) { |
| | 185 | // INTEGER IARR(2:4:2) |
| | 186 | f_arr IARR = f_arr_sect(_IARR, (int[3][1]){{2}, {4}, {2}}); |
| | 187 | |
| | 188 | // DO I=2, 4, 2 |
| | 189 | // PRINT(IARR(I)) |
| | 190 | // END DO |
| | 191 | for (int i=2; i<=4; i+=2) { |
| | 192 | printf("%d\n", *((int*)f_arr_read(IARR, (int[]){i}))); |
| | 193 | } |
| | 194 | f_arr_destroy(IARR); |
| | 195 | } |
| | 196 | |
| | 197 | void _arr1d_print(const int n, f_arr _IARR) { |
| | 198 | // INTEGER IARR(N) |
| | 199 | f_arr IARR = f_arr_sect(_IARR, (int[3][1]){{1}, {n}, {1}}); |
| 74 | | !ParseTree.java [Unchanged] |
| 75 | | |
| 76 | | !ParseException.java [Moved] Move to package: `edu.udel.cis.vsl.abc.front.IF.exception` |
| 77 | | |
| 78 | | !RuntimeParseException.java [Moved] Move to package: `edu.udel.cis.vsl.abc.front.IF.exception` |
| 79 | | |
| 80 | | ASTBuilder [Unchanged] |
| 81 | | |
| 82 | | !CivlcTokenConstant [Unchanged] |
| 83 | | |
| 84 | | edu.udel.cis.vsl.abc.front.IF.exception [Created] |
| 85 | | |
| 86 | | edu.udel.cis.vsl.abc.front.common |
| 87 | | |
| 88 | | edu.udel.cis.vsl.abc.front.common.astgen [Unchanged] |
| 89 | | |
| 90 | | edu.udel.cis.vsl.abc.front.common.ptree [Unchanged] |
| 91 | | |
| 92 | | edu.udel.cis.vsl.abc.front.common.preproc |
| 93 | | |
| 94 | | !CTokenIterator.java |
| 95 | | |
| 96 | | edu.udel.cis.vsl.abc.front.common.parse |
| 97 | | |
| 98 | | !OmpPragmaParser.java [Move] Move to package: `edu.udel.cis.vsl.abc.front.IF` |
| 99 | | |
| 100 | | !TreeUtils.java [Unchanged] |
| 101 | | |
| 102 | | edu.udel.cis.vsl.abc.front.c |
| 103 | | |
| 104 | | edu.udel.cis.vsl.abc.front.c.astgen [Unchanged] |
| 105 | | |
| 106 | | edu.udel.cis.vsl.abc.front.c.ptree [Unchanged] |
| 107 | | |
| 108 | | edu.udel.cis.vsl.abc.front.c.preproc |
| 109 | | |
| 110 | | !CommonCharacterStream.java [Unchanged] |
| 111 | | |
| 112 | | !FilteredStream.java [Unchanged] |
| 113 | | |
| 114 | | CPreprocessor.java [Changed] Update for the change in '!PreprocessorTokenSource.java' |
| 115 | | |
| 116 | | !MacroExpander.java [Changed] Update for the change in '!PreprocessorTokenSource.java' |
| 117 | | |
| 118 | | !PreprocessorExpressionAnalyzer.java [Changed] Use pp-tokens. |
| 119 | | |
| 120 | | !PreprocessorSourceFileInfo.java [Unchanged] |
| 121 | | |
| 122 | | !PreprocessorTokenSource.java [Changed] It should implement PPTokenSource, which should implement Antlr's !TokenSource. |
| 123 | | |
| 124 | | !PreprocessorUtils.java [Unchanged] |
| 125 | | |
| 126 | | edu.udel.cis.vsl.abc.front.c.converter |
| 127 | | |
| 128 | | PP2CivlcConverter.java [Created] It should implement CIVL interface !CivlcTokenSource. Take a stream of pp-tokens and convert them into a !CivlcToken. The constructor consumes a PPTokenSource. |
| 129 | | |
| 130 | | edu.udel.cis.vsl.abc.front.fortran |
| 131 | | |
| 132 | | edu.udel.cis.vsl.abc.front.fortran.astgen |
| 133 | | |
| 134 | | FOmpPragmaHandler.java [Changed] Add functions for supporting more Fortran-OpenMP bindings. |
| 135 | | |
| 136 | | FortranASTBuilder.java [Changed] Fix known issues/defects listed in 'FortranTransformations'; |
| 137 | | Add functions for supporting more Fortran behaviors. |
| 138 | | |
| 139 | | FortranASTBuilderWorker.java [Unchanged] |
| 140 | | |
| 141 | | edu.udel.cis.vsl.abc.front.fortran.ptree |
| 142 | | |
| 143 | | !FortranTree.java [Changed] Be unified as 'CParseTree.java'; Extend '!CommonParseTree' |
| 144 | | |
| 145 | | edu.udel.cis.vsl.abc.front.fortran.preproc |
| 146 | | |
| 147 | | !FortranLexicalPrepass.java [Deleted] Should be deleted, because CPreprocessor will be used. |
| 148 | | |
| 149 | | !FortranPreprocessor.java [Changed] Saved for implementing !FortranPreprocessor defined in standard. |
| 150 | | |
| 151 | | !FortranStream.java [Changed] Saved for '!FortranPreprocessor' |
| 152 | | |
| 153 | | !FortranTokenSource.java [Deleted] Should be deleted, because !CivlcTokenSource will be used. |
| 154 | | |
| 155 | | !FortranTokenStream.java [Deleted] Should be deleted. The preprocessing procedure will be unified. |
| 156 | | |
| 157 | | edu.udel.cis.vsl.abc.front.fortran.converter |
| 158 | | |
| 159 | | PP2FortranConverter.java [Created] It should implement CIVL interface !CivlcTokenSource. Take a stream of pp-tokens and convert them into a !CivlcToken. The constructor consumes a PPTokenSource. (Or !CivlFortranToken, which extends CivlCToken, if extra info is needed.) |
| 160 | | |
| 161 | | edu.udel.cis.vsl.abc.front.fortran.parse |
| 162 | | |
| 163 | | !AbstractFortranParser [Deleted] Deleted for using a unified pattern like 'CParser'. |
| 164 | | |
| 165 | | IActionEnums [Deleted] Deleted for using a unified pattern like 'CParser'. |
| 166 | | |
| 167 | | IFortranParserAction [Deleted] Deleted for using a unified pattern like 'CParser'. |
| 168 | | |
| 169 | | IFortranParser [Deleted] Deleted for using a unified pattern like 'CParser'. |
| 170 | | |
| 171 | | !FortranParserActionFactory [Deleted] Deleted for using a unified pattern like 'CParser'. |
| 172 | | |
| 173 | | !FortranParserActionNull [Deleted] Not in use. |
| 174 | | |
| 175 | | !FortranParserActionPrint [Deleted] Not in use. |
| 176 | | |
| 177 | | !FortranParserActionTreeMaker [Changed] Changed for using a unified pattern like 'CParser'; Remove the conversion from !OpenFortranParser token system to the CivlCToken one; Add functions supporting more Fortran primitives/behaviors mentioned in 'FortranTransformations' |
| 178 | | |
| 179 | | !FortranParser [Changed] Changed for using a unified pattern like 'CParser'. |
| 180 | | |
| 181 | | FOmpParser [Changed] Add functions for supporting more Fortran-OpenMP bindings. |
| 182 | | |
| 183 | | === Grammar Files === |
| 184 | | |
| 185 | | ==== Preprocessor ==== |
| 186 | | |
| 187 | | !PreprocessorLexer.g [Changed] Remove all C & CIVL-C keywords. |
| 188 | | |
| 189 | | !PreprocessorParser.g [Changed] Removed all language specific keywords, which will be treated as identifiers and be converted later. |
| 190 | | |
| 191 | | !PreprocessorExpressionParser.g [Changed] Removed all language specific keywords, which will be treated as identifiers and be converted later. |
| 192 | | |
| 193 | | ==== C & CIVL-C ==== |
| 194 | | |
| 195 | | CivlCParser.g [Changed] Remove the vocabulary used. Put all C & CIVL-C tokens here. |
| 196 | | |
| 197 | | CivlCParser_alt.g [Changed] Use the token vocabulary used in CivlCParser.g |
| 198 | | |
| 199 | | !AcslParser.g [Changed] Use the token vocabulary used in CivlCParser.g |
| 200 | | |
| 201 | | !OmpLexer.g [Unchanged] |
| 202 | | |
| 203 | | !OmpParser.g [Unchanged] |
| 204 | | |
| 205 | | ==== Fortran ==== |
| 206 | | |
| 207 | | !FortranLexer.g [Deleted] All Fortran tokens will be put in FortranParser08.g. And keywords will be converted in PP2CivlcConverter. |
| 208 | | |
| 209 | | FortranParser03.g [Deleted] Not in use. |
| 210 | | |
| 211 | | FortranParser08.g [Changed] The format of all grammar rules should be unified with C/CIVL-C grammar style used in CivlCParser.g [Renamed as FortranPArser90.g] |
| 212 | | |
| 213 | | !FortranParserExtras.g [Merged] Because supported Fortran features is a subset, then all supported grammar should be able to defined in a single file. |
| 214 | | |
| 215 | | FortranParserRiceCAF.g [Deleted] Not in use. |
| 216 | | |
| 217 | | OmpLexerF08.g [Changed] Use the token vocabulary of FortranParser08.g |
| 218 | | |
| 219 | | OmpParserF08.g [Changed] Add more supported Fortran-OpenMP directives. |
| 220 | | |
| 221 | | |
| 222 | | |
| 223 | | |
| 224 | | |
| 225 | | |
| 226 | | |
| | 201 | // DO I=1, N |
| | 202 | // PRINT(IARR(I)) |
| | 203 | // END DO |
| | 204 | for (int i=1; i<=n; i+=1) { |
| | 205 | printf("%d\n", *((int*)f_arr_read(IARR, (int[]){i}))); |
| | 206 | } |
| | 207 | f_arr_destroy(IARR); |
| | 208 | } |
| | 209 | |
| | 210 | void test_arr1d () { |
| | 211 | // INTEGER A(1:3:1); |
| | 212 | f_arr A = f_arr_create(sizeof(int), 1, (int[3][1]){{1}, {3}, {1}}); |
| | 213 | // DO I=1, 3 |
| | 214 | // A(I) = I*I; |
| | 215 | // END DO |
| | 216 | for(int i=1; i<=3; i++) { |
| | 217 | int val = i*i; |
| | 218 | |
| | 219 | f_arr_write(A, (int[]){i}, &val); |
| | 220 | } |
| | 221 | // ARR1D_PRINT(A(1:3:2)) |
| | 222 | f_arr sec_A_0 = f_arr_sect(A, (int[3][1]){{1}, {3}, {2}}); |
| | 223 | arr1d_print(sec_A_0); |
| | 224 | f_arr_destroy(sec_A_0); |
| | 225 | f_arr sec_A_1 = f_arr_sect(A, (int[3][1]){{2}, {3}, {1}}); |
| | 226 | _arr1d_print(2, sec_A_1); |
| | 227 | f_arr_destroy(sec_A_1); |
| | 228 | f_arr_destroy(A); |
| | 229 | } |
| | 230 | |
| | 231 | /************************************************/ |
| | 232 | |
| | 233 | void mat_print(const int n,const int m, f_arr _mat) { |
| | 234 | // INTEGER MAT(N, M) |
| | 235 | f_arr mat = f_arr_sect(_mat, (int[3][2]){{1,1}, {m,n}, {1,1}}); |
| | 236 | |
| | 237 | // DO I=1,M |
| | 238 | // DO J=1,N |
| | 239 | // PRINT(MAT(J,I), ", ") |
| | 240 | // END DO |
| | 241 | // PRINT("\n") |
| | 242 | // END DO |
| | 243 | for (int i=1; i<=m; i++) { |
| | 244 | for (int j=1; j<=n; j++) |
| | 245 | printf("%d%s", *((int*)f_arr_read(mat, (int[2]){i, j})), ", "); |
| | 246 | printf("%s", "\n"); |
| | 247 | } |
| | 248 | } |
| | 249 | |
| | 250 | void mxm(int n1, f_arr _ia, int n2, f_arr _ib, int n3, f_arr _ic) { |
| | 251 | // INTEGER N1, N2, N3 |
| | 252 | // INTEGER IA(N2, N1), IB(N3, N2), IC(N3, N1) |
| | 253 | f_arr ia = f_arr_sect(_ia, (int[3][2]){{1,1}, {n1,n2}, {1,1}}); |
| | 254 | f_arr ib = f_arr_sect(_ib, (int[3][2]){{1,1}, {n2,n3}, {1,1}}); |
| | 255 | f_arr ic = f_arr_sect(_ic, (int[3][2]){{1,1}, {n1,n3}, {1,1}}); |
| | 256 | |
| | 257 | for (int j=1; j<=n3; j++) |
| | 258 | for (int i=1; i<=n1; i++) |
| | 259 | for (int k=1; k<=n2; k++) { |
| | 260 | int val_ic = |
| | 261 | *(int*)f_arr_read(ic, (int[2]){j, i}) + |
| | 262 | *(int*)f_arr_read(ia, (int[2]){k, i}) * |
| | 263 | *(int*)f_arr_read(ib, (int[2]){j, k}); |
| | 264 | f_arr_write(ic, (int[2]){j, i}, &val_ic); |
| | 265 | } |
| | 266 | } |
| | 267 | |
| | 268 | void test_mxm() { |
| | 269 | // INTEGER N1=2, N2=1, N3=3 |
| | 270 | int n1=2, n2=1, n3=3; |
| | 271 | // INTEGER IA(N1, N2), IB(N2, N3), IC(N1, N3) |
| | 272 | f_arr ia = f_arr_create(sizeof(int), 2, |
| | 273 | (int[3][2]){{1,1}, {n2, n1}, {1,1}}); |
| | 274 | f_arr ib = f_arr_create(sizeof(int), 2, |
| | 275 | (int[3][2]){{1,1}, {n3, n2}, {1,1}}); |
| | 276 | f_arr ic = f_arr_create(sizeof(int), 2, |
| | 277 | (int[3][2]){{1,1}, {n3, n1}, {1,1}}); |
| | 278 | |
| | 279 | // IA = 2 |
| | 280 | // IB = -2 |
| | 281 | // IC = 0 |
| | 282 | for (int j=1; j<=n2; j++) |
| | 283 | for (int i=1; i<=n1; i++) { |
| | 284 | int val_ia = 2; |
| | 285 | f_arr_write(ia, (int[2]){j,i}, &val_ia); |
| | 286 | } |
| | 287 | for (int j=1; j<=n3; j++) |
| | 288 | for (int i=1;i<=n2; i++) { |
| | 289 | int val_ib = -2; |
| | 290 | f_arr_write(ib, (int[2]){j,i}, &val_ib); |
| | 291 | } |
| | 292 | for (int j=1; j<=n3; j++) |
| | 293 | for (int i=1; i<=n1; i++){ |
| | 294 | int val_ic = 0; |
| | 295 | f_arr_write(ic, (int[2]){j,i}, &val_ic); |
| | 296 | } |
| | 297 | |
| | 298 | f_arr arg_ia, arg_ib, arg_ic; |
| | 299 | // MXM(N1, IA, N2, IB, N3, IC) |
| | 300 | arg_ia = f_arr_full(ia); |
| | 301 | arg_ib = f_arr_full(ib); |
| | 302 | arg_ic = f_arr_full(ic); |
| | 303 | mxm(n1, arg_ia, n2, arg_ib, n3, arg_ic); |
| | 304 | f_arr_destroy(arg_ia); |
| | 305 | f_arr_destroy(arg_ib); |
| | 306 | f_arr_destroy(arg_ic); |
| | 307 | |
| | 308 | // MAT_PRINT(N, M, IC) |
| | 309 | arg_ic = f_arr_full(ic); |
| | 310 | mat_print(n3,n1,arg_ic); |
| | 311 | f_arr_destroy(arg_ic); |
| | 312 | |
| | 313 | f_arr_destroy(ia); |
| | 314 | f_arr_destroy(ib); |
| | 315 | f_arr_destroy(ic); |
| | 316 | } |
| | 317 | |
| | 318 | int main() { |
| | 319 | //test_arr1d(); |
| | 320 | //test_mxm(); |
| | 321 | return 0; |
| | 322 | } |
| | 323 | |
| | 324 | }}} |