00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include <stdlib.h>
00065 #include <stdio.h>
00066 #include <string.h>
00067 #include <ctype.h>
00068
00069 #include <osl/macros.h>
00070 #include <osl/int.h>
00071 #include <osl/util.h>
00072 #include <osl/vector.h>
00073 #include <osl/strings.h>
00074 #include <osl/names.h>
00075 #include <osl/relation.h>
00076
00077
00078
00079
00080
00081
00082
00090 static
00091 char * osl_relation_sprint_type(osl_relation_p relation) {
00092 char * string = NULL;
00093
00094 OSL_malloc(string, char *, OSL_MAX_STRING * sizeof(char));
00095 string[0] = '\0';
00096
00097 if (relation != NULL) {
00098 switch (relation->type) {
00099 case OSL_UNDEFINED: {
00100 snprintf(string, OSL_MAX_STRING, OSL_STRING_UNDEFINED);
00101 break;
00102 }
00103 case OSL_TYPE_CONTEXT: {
00104 snprintf(string, OSL_MAX_STRING, OSL_STRING_CONTEXT);
00105 break;
00106 }
00107 case OSL_TYPE_DOMAIN: {
00108 snprintf(string, OSL_MAX_STRING, OSL_STRING_DOMAIN);
00109 break;
00110 }
00111 case OSL_TYPE_SCATTERING: {
00112 snprintf(string, OSL_MAX_STRING, OSL_STRING_SCATTERING);
00113 break;
00114 }
00115 case OSL_TYPE_READ: {
00116 snprintf(string, OSL_MAX_STRING, OSL_STRING_READ);
00117 break;
00118 }
00119 case OSL_TYPE_WRITE: {
00120 snprintf(string, OSL_MAX_STRING, OSL_STRING_WRITE);
00121 break;
00122 }
00123 case OSL_TYPE_MAY_WRITE: {
00124 snprintf(string, OSL_MAX_STRING, OSL_STRING_MAY_WRITE);
00125 break;
00126 }
00127 default: {
00128 OSL_warning("unknown relation type, "
00129 "replaced with "OSL_STRING_UNDEFINED);
00130 snprintf(string, OSL_MAX_STRING, OSL_STRING_UNDEFINED);
00131 }
00132 }
00133 }
00134
00135 return string;
00136 }
00137
00138
00146 static
00147 void osl_relation_print_type(FILE * file, osl_relation_p relation) {
00148 char * string = osl_relation_sprint_type(relation);
00149 fprintf(file, "%s", string);
00150 free(string);
00151 }
00152
00153
00164 void osl_relation_idump(FILE * file, osl_relation_p relation, int level) {
00165 int i, j, first = 1;
00166
00167
00168 for (j = 0; j < level; j++)
00169 fprintf(file, "|\t");
00170
00171 if (relation != NULL) {
00172 fprintf(file, "+-- osl_relation_t (");
00173 osl_relation_print_type(file, relation);
00174 fprintf(file, ", ");
00175 osl_int_dump_precision(file, relation->precision);
00176 fprintf(file, ")\n");
00177 }
00178 else {
00179 fprintf(file, "+-- NULL relation\n");
00180 }
00181
00182 while (relation != NULL) {
00183 if (! first) {
00184
00185 for (j = 0; j < level; j++)
00186 fprintf(file, "|\t");
00187 fprintf(file, "| osl_relation_t (");
00188 osl_relation_print_type(file, relation);
00189 fprintf(file, ", ");
00190 osl_int_dump_precision(file, relation->precision);
00191 fprintf(file, ")\n");
00192 }
00193 else
00194 first = 0;
00195
00196
00197 for(j = 0; j <= level; j++)
00198 fprintf(file, "|\t");
00199 fprintf(file, "%d %d %d %d %d %d\n",
00200 relation->nb_rows, relation->nb_columns,
00201 relation->nb_output_dims, relation->nb_input_dims,
00202 relation->nb_local_dims, relation->nb_parameters);
00203
00204
00205 for (i = 0; i < relation->nb_rows; i++) {
00206 for (j = 0; j <= level; j++)
00207 fprintf(file, "|\t");
00208
00209 fprintf(file, "[ ");
00210
00211 for (j = 0; j < relation->nb_columns; j++) {
00212 osl_int_print(file, relation->precision, relation->m[i], j);
00213 fprintf(file, " ");
00214 }
00215
00216 fprintf(file, "]\n");
00217 }
00218
00219 relation = relation->next;
00220
00221
00222 if (relation != NULL) {
00223 for (j = 0; j <= level; j++)
00224 fprintf(file, "|\t");
00225 fprintf(file, "|\n");
00226 for (j = 0; j <= level; j++)
00227 fprintf(file, "|\t");
00228 fprintf(file, "V\n");
00229 }
00230 }
00231
00232
00233 for (j = 0; j <= level; j++)
00234 fprintf(file, "|\t");
00235 fprintf(file, "\n");
00236 }
00237
00238
00246 void osl_relation_dump(FILE * file, osl_relation_p relation) {
00247 osl_relation_idump(file, relation, 0);
00248 }
00249
00250
00265 static
00266 char * osl_relation_expression_element(void * val,
00267 int precision, int * first,
00268 int cst, char * name) {
00269 char * temp, * body, * sval;
00270
00271 OSL_malloc(temp, char *, OSL_MAX_STRING * sizeof(char));
00272 OSL_malloc(body, char *, OSL_MAX_STRING * sizeof(char));
00273 OSL_malloc(sval, char *, OSL_MAX_STRING * sizeof(char));
00274
00275 body[0] = '\0';
00276 sval[0] = '\0';
00277
00278
00279 if (!osl_int_zero(precision, val, 0) && (!cst)) {
00280 if ((*first) || osl_int_neg(precision, val, 0)) {
00281 if (osl_int_one(precision, val, 0)) {
00282 sprintf(sval, "%s", name);
00283 }
00284 else {
00285 if (osl_int_mone(precision, val, 0)) {
00286 sprintf(sval, "-%s", name);
00287 }
00288 else {
00289 osl_int_sprint_txt(sval, precision, val, 0);
00290 sprintf(temp, "*%s", name);
00291 strcat(sval, temp);
00292 }
00293 }
00294 *first = 0;
00295 }
00296 else {
00297 if (osl_int_one(precision, val, 0)) {
00298 sprintf(sval, "+%s", name);
00299 }
00300 else {
00301 sprintf(sval, "+");
00302 osl_int_sprint_txt(temp, precision, val, 0);
00303 strcat(sval, temp);
00304 sprintf(temp, "*%s", name);
00305 strcat(sval, temp);
00306 }
00307 }
00308 }
00309 else {
00310 if (cst) {
00311 if ((osl_int_zero(precision, val, 0) && (*first)) ||
00312 (osl_int_neg(precision, val, 0)))
00313 osl_int_sprint_txt(sval, precision, val, 0);
00314 if (osl_int_pos(precision, val, 0)) {
00315 if (!(*first)) {
00316 sprintf(sval, "+");
00317 osl_int_sprint_txt(temp, precision, val, 0);
00318 strcat(sval, temp);
00319 }
00320 else {
00321 osl_int_sprint_txt(sval, precision, val, 0);
00322 }
00323 }
00324 }
00325 }
00326 free(temp);
00327 free(body);
00328
00329 return(sval);
00330 }
00331
00332
00342 static
00343 char ** osl_relation_strings(osl_relation_p relation, osl_names_p names) {
00344 char ** strings;
00345 char temp[OSL_MAX_STRING];
00346 int i, offset, array_id;
00347
00348 if ((relation == NULL) || (names == NULL)) {
00349 OSL_debug("no names or relation to build the name array");
00350 return NULL;
00351 }
00352
00353 OSL_malloc(strings, char **, (relation->nb_columns + 1)*sizeof(char *));
00354 strings[relation->nb_columns] = NULL;
00355
00356
00357 OSL_strdup(strings[0], "e/i");
00358 offset = 1;
00359
00360
00361 if (osl_relation_is_access(relation)) {
00362
00363 array_id = osl_relation_get_array_id(relation);
00364 OSL_strdup(strings[offset], "Arr");
00365
00366 for (i = offset + 1; i < relation->nb_output_dims + offset; i++) {
00367 sprintf(temp, "[%d]", i - 1);
00368 OSL_strdup(strings[i], temp);
00369 }
00370 }
00371 else
00372 if (relation->type == OSL_TYPE_SCATTERING) {
00373 for (i = offset; i < relation->nb_output_dims + offset; i++) {
00374 OSL_strdup(strings[i], names->scatt_dims->string[i - offset]);
00375 }
00376 }
00377 else {
00378 for (i = offset; i < relation->nb_output_dims + offset; i++) {
00379 OSL_strdup(strings[i], names->iterators->string[i - offset]);
00380 }
00381 }
00382 offset += relation->nb_output_dims;
00383
00384
00385 for (i = offset; i < relation->nb_input_dims + offset; i++)
00386 OSL_strdup(strings[i], names->iterators->string[i - offset]);
00387 offset += relation->nb_input_dims;
00388
00389
00390 for (i = offset; i < relation->nb_local_dims + offset; i++)
00391 OSL_strdup(strings[i], names->local_dims->string[i - offset]);
00392 offset += relation->nb_local_dims;
00393
00394
00395 for (i = offset; i < relation->nb_parameters + offset; i++)
00396 OSL_strdup(strings[i], names->parameters->string[i - offset]);
00397 offset += relation->nb_parameters;
00398
00399
00400 OSL_strdup(strings[offset], "1");
00401
00402 return strings;
00403 }
00404
00405
00419 static
00420 char * osl_relation_subexpression(osl_relation_p relation,
00421 int row, int start, int stop, int oppose,
00422 char ** strings) {
00423 int i, first = 1, constant;
00424 char * sval;
00425 char * sline;
00426
00427 OSL_malloc(sline, char *, OSL_MAX_STRING * sizeof(char));
00428 sline[0] = '\0';
00429
00430
00431 for (i = start; i <= stop; i++) {
00432 if (oppose) {
00433 osl_int_oppose(relation->precision,
00434 relation->m[row], i, relation->m[row], i);
00435 }
00436
00437 if (i == relation->nb_columns - 1)
00438 constant = 1;
00439 else
00440 constant = 0;
00441
00442 sval = osl_relation_expression_element(
00443 osl_int_address(relation->precision, relation->m[row], i),
00444 relation->precision, &first, constant, strings[i]);
00445
00446 if (oppose) {
00447 osl_int_oppose(relation->precision,
00448 relation->m[row], i, relation->m[row], i);
00449 }
00450 strcat(sline, sval);
00451 free(sval);
00452 }
00453
00454 return sline;
00455 }
00456
00457
00467 char * osl_relation_expression(osl_relation_p relation,
00468 int row, char ** strings) {
00469
00470 return osl_relation_subexpression(relation, row,
00471 1, relation->nb_columns - 1, 0,
00472 strings);
00473 }
00474
00475
00487 static
00488 int osl_relation_is_simple_output(osl_relation_p relation, int row) {
00489 int i;
00490 int first = 1;
00491 int sign = 0;
00492
00493 if ((relation == NULL) ||
00494 (relation->m == NULL) ||
00495 (relation->nb_output_dims == 0))
00496 return 0;
00497
00498 if ((row < 0) || (row > relation->nb_rows))
00499 OSL_error("the specified row does not exist in the relation");
00500
00501
00502 if (!osl_int_zero(relation->precision, relation->m[row], 0))
00503 return 0;
00504
00505
00506 first = 1;
00507 for (i = 1; i <= relation->nb_output_dims; i++) {
00508 if (!osl_int_zero(relation->precision, relation->m[row], i)) {
00509 if (first)
00510 first = 0;
00511 else
00512 return 0;
00513
00514 if (osl_int_one(relation->precision, relation->m[row], i))
00515 sign = 1;
00516 else if (osl_int_mone(relation->precision, relation->m[row], i))
00517 sign = -1;
00518 else
00519 return 0;
00520 }
00521 }
00522
00523 return sign;
00524 }
00525
00526
00540 static
00541 char * osl_relation_sprint_comment(osl_relation_p relation, int row,
00542 char ** strings, char ** arrays) {
00543 int sign;
00544 int high_water_mark = OSL_MAX_STRING;
00545 char * string = NULL;
00546 char * expression;
00547 char buffer[OSL_MAX_STRING];
00548
00549 OSL_malloc(string, char *, high_water_mark * sizeof(char));
00550 string[0] = '\0';
00551
00552 if ((relation == NULL) || (strings == NULL)) {
00553 OSL_debug("no relation or names while asked to print a comment");
00554 return string;
00555 }
00556
00557 if ((sign = osl_relation_is_simple_output(relation, row))) {
00558
00559
00560 expression = osl_relation_subexpression(relation, row,
00561 1, relation->nb_output_dims,
00562 sign < 0,
00563 strings);
00564 snprintf(buffer, OSL_MAX_STRING, " ## %s", expression);
00565 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00566 free(expression);
00567
00568
00569 if (!osl_relation_is_access(relation) ||
00570 osl_int_zero(relation->precision, relation->m[row], 1)) {
00571 expression = osl_relation_subexpression(relation, row,
00572 relation->nb_output_dims + 1,
00573 relation->nb_columns - 1,
00574 sign > 0,
00575 strings);
00576 snprintf(buffer, OSL_MAX_STRING, " == %s", expression);
00577 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00578 free(expression);
00579 }
00580 else {
00581 snprintf(buffer, OSL_MAX_STRING, " == %s",
00582 arrays[osl_relation_get_array_id(relation) - 1]);
00583 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00584 }
00585 }
00586 else {
00587
00588
00589 expression = osl_relation_expression(relation, row, strings);
00590 snprintf(buffer, OSL_MAX_STRING, " ## %s", expression);
00591 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00592 free(expression);
00593
00594 if (osl_int_zero(relation->precision, relation->m[row], 0))
00595 snprintf(buffer, OSL_MAX_STRING, " == 0");
00596 else
00597 snprintf(buffer, OSL_MAX_STRING, " >= 0");
00598 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00599 }
00600
00601 return string;
00602 }
00603
00604
00614 static
00615 char * osl_relation_column_string(osl_relation_p relation, char ** strings) {
00616 int i, j;
00617 int index_output_dims;
00618 int index_input_dims;
00619 int index_local_dims;
00620 int index_parameters;
00621 int index_scalar;
00622 int space, length, left, right;
00623 char * scolumn;
00624 char temp[OSL_MAX_STRING];
00625
00626 OSL_malloc(scolumn, char *, OSL_MAX_STRING);
00627
00628 index_output_dims = 1;
00629 index_input_dims = index_output_dims + relation->nb_output_dims;
00630 index_local_dims = index_input_dims + relation->nb_input_dims;
00631 index_parameters = index_local_dims + relation->nb_local_dims;
00632 index_scalar = index_parameters + relation->nb_parameters;
00633
00634
00635 sprintf(scolumn, "#");
00636 for (j = 0; j < (OSL_FMT_LENGTH - 1)/2 - 1; j++)
00637 strcat(scolumn, " ");
00638
00639 i = 0;
00640 while (strings[i] != NULL) {
00641 space = OSL_FMT_LENGTH;
00642 length = (space > strlen(strings[i])) ? strlen(strings[i]) : space;
00643 right = (space - length + (OSL_FMT_LENGTH % 2)) / 2;
00644 left = space - length - right;
00645
00646
00647 for (j = 0; j < left; j++)
00648 strcat(scolumn, " ");
00649
00650
00651 for (j = 0; j < length - 1; j++) {
00652 sprintf(temp, "%c", strings[i][j]);
00653 strcat(scolumn, temp);
00654 }
00655 if (length >= strlen(strings[i]))
00656 sprintf(temp, "%c", strings[i][j]);
00657 else
00658 sprintf(temp, ".");
00659 strcat(scolumn, temp);
00660
00661
00662 for (j = 0; j < right; j++)
00663 strcat(scolumn, " ");
00664
00665 i++;
00666 if ((i == index_output_dims) ||
00667 (i == index_input_dims) ||
00668 (i == index_local_dims) ||
00669 (i == index_parameters) ||
00670 (i == index_scalar))
00671 strcat(scolumn, "|");
00672 else
00673 strcat(scolumn, " ");
00674 }
00675 strcat(scolumn, "\n");
00676
00677 return scolumn;
00678 }
00679
00680
00688 static
00689 osl_names_p osl_relation_names(osl_relation_p relation) {
00690 int nb_parameters = OSL_UNDEFINED;
00691 int nb_iterators = OSL_UNDEFINED;
00692 int nb_scattdims = OSL_UNDEFINED;
00693 int nb_localdims = OSL_UNDEFINED;
00694 int array_id = OSL_UNDEFINED;
00695
00696 osl_relation_get_attributes(relation, &nb_parameters, &nb_iterators,
00697 &nb_scattdims, &nb_localdims, &array_id);
00698
00699 return osl_names_generate("P", nb_parameters,
00700 "i", nb_iterators,
00701 "c", nb_scattdims,
00702 "l", nb_localdims,
00703 "A", array_id);
00704 }
00705
00706
00714 int osl_relation_nb_components(osl_relation_p relation) {
00715 int nb_components = 0;
00716
00717 while (relation != NULL) {
00718 nb_components++;
00719 relation = relation->next;
00720 }
00721
00722 return nb_components;
00723 }
00724
00725
00735 char * osl_relation_spprint_polylib(osl_relation_p relation,
00736 osl_names_p names) {
00737 int i, j;
00738 int part, nb_parts;
00739 int generated_names = 0;
00740 int high_water_mark = OSL_MAX_STRING;
00741 char * string = NULL;
00742 char buffer[OSL_MAX_STRING];
00743 char ** name_array = NULL;
00744 char * scolumn;
00745 char * comment;
00746
00747 if (relation == NULL)
00748 return strdup("# NULL relation\n");
00749
00750 OSL_malloc(string, char *, high_water_mark * sizeof(char));
00751 string[0] = '\0';
00752
00753
00754 if (names == NULL) {
00755 generated_names = 1;
00756 names = osl_relation_names(relation);
00757 }
00758
00759 nb_parts = osl_relation_nb_components(relation);
00760
00761 if (nb_parts > 1) {
00762 snprintf(buffer, OSL_MAX_STRING, "# Union with %d parts\n%d\n",
00763 nb_parts, nb_parts);
00764 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00765 }
00766
00767
00768 for (part = 1; part <= nb_parts; part++) {
00769
00770 name_array = osl_relation_strings(relation, names);
00771
00772 if (nb_parts > 1) {
00773 snprintf(buffer, OSL_MAX_STRING, "# Union part No.%d\n", part);
00774 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00775 }
00776
00777 snprintf(buffer, OSL_MAX_STRING, "%d %d %d %d %d %d\n",
00778 relation->nb_rows, relation->nb_columns,
00779 relation->nb_output_dims, relation->nb_input_dims,
00780 relation->nb_local_dims, relation->nb_parameters);
00781 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00782
00783 if (relation->nb_rows > 0) {
00784 scolumn = osl_relation_column_string(relation, name_array);
00785 snprintf(buffer, OSL_MAX_STRING, "%s", scolumn);
00786 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00787 free(scolumn);
00788 }
00789
00790 for (i = 0; i < relation->nb_rows; i++) {
00791 for (j = 0; j < relation->nb_columns; j++) {
00792 osl_int_sprint(buffer, relation->precision, relation->m[i], j);
00793 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00794 snprintf(buffer, OSL_MAX_STRING, " ");
00795 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00796 }
00797
00798 if (name_array != NULL) {
00799 comment = osl_relation_sprint_comment(relation, i, name_array,
00800 names->arrays->string);
00801 osl_util_safe_strcat(&string, comment, &high_water_mark);
00802 free(comment);
00803 }
00804 snprintf(buffer, OSL_MAX_STRING, "\n");
00805 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00806 }
00807
00808
00809 if (name_array != NULL) {
00810 for (i = 0; i < relation->nb_columns; i++)
00811 free(name_array[i]);
00812 free(name_array);
00813 }
00814
00815 relation = relation->next;
00816 }
00817
00818 if (generated_names)
00819 osl_names_free(names);
00820
00821 return string;
00822 }
00823
00824
00833 char * osl_relation_spprint(osl_relation_p relation, osl_names_p names) {
00834 int high_water_mark = OSL_MAX_STRING;
00835 char * string = NULL;
00836 char * temp;
00837 char buffer[OSL_MAX_STRING];
00838 OSL_malloc(string, char *, high_water_mark * sizeof(char));
00839 string[0] = '\0';
00840
00841 if (osl_relation_nb_components(relation) > 0) {
00842 temp = osl_relation_sprint_type(relation);
00843 osl_util_safe_strcat(&string, temp, &high_water_mark);
00844 free(temp);
00845
00846 snprintf(buffer, OSL_MAX_STRING, "\n");
00847 osl_util_safe_strcat(&string, buffer, &high_water_mark);
00848
00849 temp = osl_relation_spprint_polylib(relation, names);
00850 osl_util_safe_strcat(&string, temp, &high_water_mark);
00851 free(temp);
00852 }
00853
00854 return string;
00855 }
00856
00857
00866 void osl_relation_pprint(FILE * file, osl_relation_p relation,
00867 osl_names_p names) {
00868 char * string = osl_relation_spprint(relation, names);
00869 fprintf(file, "%s", string);
00870 free(string);
00871 }
00872
00873
00881 void osl_relation_print(FILE * file, osl_relation_p relation) {
00882
00883 osl_relation_pprint(file, relation, NULL);
00884 }
00885
00886
00887
00888
00889
00890
00891
00899 static
00900 int osl_relation_read_type(FILE * file) {
00901 int type;
00902 osl_strings_p strings;
00903
00904 strings = osl_strings_read(file);
00905 if (osl_strings_size(strings) > 1) {
00906 OSL_warning("uninterpreted information (after the relation type)");
00907 }
00908 if (osl_strings_size(strings) == 0)
00909 OSL_error("no relation type");
00910
00911 if (!strcmp(strings->string[0], OSL_STRING_UNDEFINED)) {
00912 type = OSL_UNDEFINED;
00913 goto return_type;
00914 }
00915
00916 if (!strcmp(strings->string[0], OSL_STRING_CONTEXT)) {
00917 type = OSL_TYPE_CONTEXT;
00918 goto return_type;
00919 }
00920
00921 if (!strcmp(strings->string[0], OSL_STRING_DOMAIN)) {
00922 type = OSL_TYPE_DOMAIN;
00923 goto return_type;
00924 }
00925
00926 if (!strcmp(strings->string[0], OSL_STRING_SCATTERING)) {
00927 type = OSL_TYPE_SCATTERING;
00928 goto return_type;
00929 }
00930
00931 if (!strcmp(strings->string[0], OSL_STRING_READ)) {
00932 type = OSL_TYPE_READ;
00933 goto return_type;
00934 }
00935
00936 if (!strcmp(strings->string[0], OSL_STRING_WRITE)) {
00937 type = OSL_TYPE_WRITE;
00938 goto return_type;
00939 }
00940
00941 if (!strcmp(strings->string[0], OSL_STRING_MAY_WRITE)) {
00942 type = OSL_TYPE_MAY_WRITE;
00943 goto return_type;
00944 }
00945
00946 OSL_error("relation type not supported");
00947
00948 return_type:
00949 osl_strings_free(strings);
00950 return type;
00951 }
00952
00953
00963 osl_relation_p osl_relation_pread(FILE * foo, int precision) {
00964 int i, j, k, n, read = 0;
00965 int nb_rows, nb_columns;
00966 int nb_output_dims, nb_input_dims, nb_local_dims, nb_parameters;
00967 int nb_union_parts = 1;
00968 int may_read_nb_union_parts = 1;
00969 int read_attributes = 1;
00970 int first = 1;
00971 int type;
00972 char * c, s[OSL_MAX_STRING], str[OSL_MAX_STRING], *tmp;
00973 osl_relation_p relation, relation_union = NULL, previous = NULL;
00974
00975 type = osl_relation_read_type(foo);
00976
00977
00978 for (k = 0; k < nb_union_parts; k++) {
00979
00980 while (read_attributes) {
00981 read_attributes = 0;
00982
00983
00984 c = osl_util_skip_blank_and_comments(foo, s);
00985 read = sscanf(c, " %d %d %d %d %d %d", &nb_rows, &nb_columns,
00986 &nb_output_dims, &nb_input_dims,
00987 &nb_local_dims, &nb_parameters);
00988
00989 if (((read != 1) && (read != 6)) ||
00990 ((read == 1) && (may_read_nb_union_parts != 1)))
00991 OSL_error("not 1 or 6 integers on the first relation line");
00992
00993 if (read == 1) {
00994
00995 nb_union_parts = nb_rows;
00996 if (nb_union_parts < 1)
00997 OSL_error("negative nb of union parts");
00998
00999
01000 read_attributes = 1;
01001 }
01002
01003 may_read_nb_union_parts = 0;
01004 }
01005
01006
01007 relation = osl_relation_pmalloc(precision, nb_rows, nb_columns);
01008 relation->type = type;
01009 relation->nb_output_dims = nb_output_dims;
01010 relation->nb_input_dims = nb_input_dims;
01011 relation->nb_local_dims = nb_local_dims;
01012 relation->nb_parameters = nb_parameters;
01013
01014
01015 for (i = 0; i < relation->nb_rows; i++) {
01016 c = osl_util_skip_blank_and_comments(foo, s);
01017 if (c == NULL)
01018 OSL_error("not enough rows");
01019
01020 for (j = 0; j < relation->nb_columns; j++) {
01021 if (c == NULL || *c == '#' || *c == '\n')
01022 OSL_error("not enough columns");
01023 if (sscanf(c, "%s%n", str, &n) == 0)
01024 OSL_error("not enough rows");
01025
01026
01027 tmp = str;
01028 osl_int_sread(&tmp, precision, relation->m[i], j);
01029 c += n;
01030 }
01031 }
01032
01033
01034 if (first == 1) {
01035 relation_union = relation;
01036 first = 0;
01037 }
01038 else {
01039 previous->next = relation;
01040 }
01041
01042 previous = relation;
01043 read_attributes = 1;
01044 }
01045
01046 return relation_union;
01047 }
01048
01049
01057 osl_relation_p osl_relation_read(FILE * foo) {
01058 int precision = osl_util_get_precision();
01059 return osl_relation_pread(foo, precision);
01060 }
01061
01062
01063
01064
01065
01066
01067
01079 osl_relation_p osl_relation_pmalloc(int precision,
01080 int nb_rows, int nb_columns) {
01081 osl_relation_p relation;
01082 void ** p, * q;
01083 int i, j;
01084
01085 OSL_malloc(relation, osl_relation_p, sizeof(osl_relation_t));
01086 relation->type = OSL_UNDEFINED;
01087 relation->nb_rows = nb_rows;
01088 relation->nb_columns = nb_columns;
01089 relation->nb_output_dims = OSL_UNDEFINED;
01090 relation->nb_input_dims = OSL_UNDEFINED;
01091 relation->nb_parameters = OSL_UNDEFINED;
01092 relation->nb_local_dims = OSL_UNDEFINED;
01093 relation->precision = precision;
01094
01095 if ((nb_rows == 0) || (nb_columns == 0) ||
01096 (nb_rows == OSL_UNDEFINED) || (nb_columns == OSL_UNDEFINED)) {
01097 relation->m = NULL;
01098 }
01099 else {
01100 OSL_malloc(p, void **, nb_rows * sizeof(void *));
01101 OSL_malloc(q, void *,
01102 nb_rows * nb_columns * osl_int_sizeof(precision));
01103 relation->m = p;
01104 for (i = 0; i < nb_rows; i++) {
01105 relation->m[i] = osl_int_address(precision, q, i * nb_columns);
01106 for (j = 0; j < nb_columns; j++)
01107 osl_int_init_set_si(precision, relation->m[i], j, 0);
01108 }
01109 }
01110
01111 relation->next = NULL;
01112
01113 return relation;
01114 }
01115
01116
01124 osl_relation_p osl_relation_malloc(int nb_rows, int nb_columns) {
01125 int precision = osl_util_get_precision();
01126 return osl_relation_pmalloc(precision, nb_rows, nb_columns);
01127 }
01128
01129
01136 void osl_relation_free_inside(osl_relation_p relation) {
01137 int i, nb_elements;
01138 void * p;
01139
01140 if (relation == NULL)
01141 return;
01142
01143 nb_elements = relation->nb_rows * relation->nb_columns;
01144
01145 if (nb_elements > 0)
01146 p = relation->m[0];
01147
01148 for (i = 0; i < nb_elements; i++)
01149 osl_int_clear(relation->precision, p, i);
01150
01151 if (relation->m != NULL) {
01152 if (nb_elements > 0)
01153 free(relation->m[0]);
01154 free(relation->m);
01155 }
01156 }
01157
01158
01165 void osl_relation_free(osl_relation_p relation) {
01166 osl_relation_p tmp;
01167
01168 if (relation == NULL)
01169 return;
01170
01171 while (relation != NULL) {
01172 tmp = relation->next;
01173 osl_relation_free_inside(relation);
01174 free(relation);
01175 relation = tmp;
01176 }
01177 }
01178
01179
01180
01181
01182
01183
01184
01197 osl_relation_p osl_relation_nclone(osl_relation_p relation, int n) {
01198 int i, j;
01199 int first = 1, all_rows = 0;
01200 osl_relation_p clone = NULL, node, previous = NULL;
01201
01202 if (n == -1)
01203 all_rows = 1;
01204
01205 while (relation != NULL) {
01206 if (all_rows)
01207 n = relation->nb_rows;
01208
01209 if (n > relation->nb_rows)
01210 OSL_error("not enough rows to clone in the relation");
01211
01212 node = osl_relation_pmalloc(relation->precision, n, relation->nb_columns);
01213 node->type = relation->type;
01214 node->nb_output_dims = relation->nb_output_dims;
01215 node->nb_input_dims = relation->nb_input_dims;
01216 node->nb_local_dims = relation->nb_local_dims;
01217 node->nb_parameters = relation->nb_parameters;
01218
01219 for (i = 0; i < n; i++)
01220 for (j = 0; j < relation->nb_columns; j++)
01221 osl_int_assign(relation->precision, node->m[i], j, relation->m[i], j);
01222
01223 if (first) {
01224 first = 0;
01225 clone = node;
01226 previous = node;
01227 }
01228 else {
01229 previous->next = node;
01230 previous = previous->next;
01231 }
01232
01233 relation = relation->next;
01234 }
01235
01236 return clone;
01237 }
01238
01239
01247 osl_relation_p osl_relation_clone(osl_relation_p relation) {
01248 if (relation == NULL)
01249 return NULL;
01250
01251 return osl_relation_nclone(relation, -1);
01252 }
01253
01254
01264 void osl_relation_add(osl_relation_p *r1, osl_relation_p r2) {
01265 while (*r1 != NULL)
01266 r1 = &((*r1)->next);
01267
01268 *r1 = r2;
01269 }
01270
01271
01281 osl_relation_p osl_relation_union(osl_relation_p r1,
01282 osl_relation_p r2) {
01283 osl_relation_p copy1, copy2;
01284
01285 if ((r1 == NULL) && (r2 == NULL))
01286 return NULL;
01287
01288 copy1 = osl_relation_clone(r1);
01289 copy2 = osl_relation_clone(r2);
01290 osl_relation_add(©1, copy2);
01291
01292 return copy1;
01293 }
01294
01295
01305 void osl_relation_replace_vector(osl_relation_p relation,
01306 osl_vector_p vector, int row) {
01307 int i;
01308
01309 if ((relation == NULL) || (vector == NULL) ||
01310 (relation->precision != vector->precision) ||
01311 (relation->nb_columns != vector->size) ||
01312 (row >= relation->nb_rows) || (row < 0))
01313 OSL_error("vector cannot replace relation row");
01314
01315 for (i = 0; i < vector->size; i++)
01316 osl_int_assign(relation->precision, relation->m[row], i, vector->v, i);
01317 }
01318
01319
01329 void osl_relation_add_vector(osl_relation_p relation,
01330 osl_vector_p vector, int row) {
01331 int i;
01332
01333 if ((relation == NULL) || (vector == NULL) ||
01334 (relation->precision != vector->precision) ||
01335 (relation->nb_columns != vector->size) ||
01336 (row >= relation->nb_rows) || (row < 0))
01337 OSL_error("vector cannot be added to relation");
01338
01339 if (osl_int_get_si(relation->precision, relation->m[row], 0) == 0)
01340 osl_int_assign(relation->precision, relation->m[row], 0, vector->v, 0);
01341
01342 for (i = 1; i < vector->size; i++)
01343 osl_int_add(relation->precision,
01344 relation->m[row], i, relation->m[row], i, vector->v, i);
01345 }
01346
01347
01357 void osl_relation_sub_vector(osl_relation_p relation,
01358 osl_vector_p vector, int row) {
01359 int i;
01360
01361 if ((relation == NULL) || (vector == NULL) ||
01362 (relation->precision != vector->precision) ||
01363 (relation->nb_columns != vector->size) ||
01364 (row >= relation->nb_rows) || (row < 0))
01365 OSL_error("vector cannot be subtracted to row");
01366
01367 if (osl_int_get_si(relation->precision, relation->m[row], 0) == 0)
01368 osl_int_assign(relation->precision, relation->m[row], 0, vector->v, 0);
01369
01370 for (i = 1; i < vector->size; i++)
01371 osl_int_sub(relation->precision,
01372 relation->m[row], i, relation->m[row], i, vector->v, i);
01373 }
01374
01375
01389 void osl_relation_insert_vector(osl_relation_p relation,
01390 osl_vector_p vector, int row) {
01391 osl_relation_p temp;
01392
01393 temp = osl_relation_from_vector(vector);
01394 osl_relation_insert_constraints(relation, temp, row);
01395 osl_relation_free(temp);
01396 }
01397
01398
01410 osl_relation_p osl_relation_concat_vector(osl_relation_p relation,
01411 osl_vector_p vector) {
01412 osl_relation_p new, temp;
01413
01414 temp = osl_relation_from_vector(vector);
01415 new = osl_relation_concat_constraints(relation, temp);
01416 osl_relation_free(temp);
01417 return new;
01418 }
01419
01420
01428 void osl_relation_insert_blank_row(osl_relation_p relation, int row) {
01429 osl_vector_p vector;
01430
01431 if (relation != NULL) {
01432 vector = osl_vector_pmalloc(relation->precision, relation->nb_columns);
01433 osl_relation_insert_vector(relation, vector, row);
01434 osl_vector_free(vector);
01435 }
01436 }
01437
01438
01447 void osl_relation_insert_blank_column(osl_relation_p relation, int column) {
01448
01449 int i, j;
01450 osl_relation_p temp;
01451
01452 if (relation == NULL)
01453 return;
01454
01455 if ((column < 0) || (column > relation->nb_columns))
01456 OSL_error("bad column number");
01457
01458
01459 temp = osl_relation_pmalloc(relation->precision,
01460 relation->nb_rows, relation->nb_columns + 1);
01461
01462 for (i = 0; i < relation->nb_rows; i++) {
01463 for (j = 0; j < column; j++)
01464 osl_int_assign(relation->precision, temp->m[i], j, relation->m[i], j);
01465
01466 for (j = column; j < relation->nb_columns; j++)
01467 osl_int_assign(relation->precision, temp->m[i], j+1, relation->m[i], j);
01468 }
01469
01470 osl_relation_free_inside(relation);
01471
01472
01473 relation->nb_columns = temp->nb_columns;
01474 relation->m = temp->m;
01475
01476
01477 free(temp);
01478 }
01479
01480
01488 osl_relation_p osl_relation_from_vector(osl_vector_p vector) {
01489 osl_relation_p relation;
01490
01491 if (vector == NULL)
01492 return NULL;
01493
01494 relation = osl_relation_pmalloc(vector->precision, 1, vector->size);
01495 osl_relation_replace_vector(relation, vector, 0);
01496 return relation;
01497 }
01498
01499
01509 void osl_relation_replace_constraints(osl_relation_p r1,
01510 osl_relation_p r2, int row) {
01511 int i, j;
01512
01513 if ((r1 == NULL) || (r2 == NULL) ||
01514 (r1->precision != r2->precision) ||
01515 (r1->nb_columns != r1->nb_columns) ||
01516 ((row + r2->nb_rows) > r1->nb_rows) || (row < 0))
01517 OSL_error("relation rows could not be replaced");
01518
01519 for (i = 0; i < r2->nb_rows; i++)
01520 for (j = 0; j < r2->nb_columns; j++)
01521 osl_int_assign(r1->precision, r1->m[i+row], j, r2->m[i], j);
01522 }
01523
01524
01537 void osl_relation_insert_constraints(osl_relation_p r1,
01538 osl_relation_p r2, int row) {
01539 int i, j;
01540 osl_relation_p temp;
01541
01542 if ((r1 == NULL) || (r2 == NULL))
01543 return;
01544
01545 if (row == -1)
01546 row = r1->nb_rows;
01547
01548 if ((r1->nb_columns != r2->nb_columns) ||
01549 (r1->precision != r2->precision) ||
01550 (row > r1->nb_rows) || (row < 0))
01551 OSL_error("constraints cannot be inserted");
01552
01553
01554 temp = osl_relation_pmalloc(r1->precision,
01555 r1->nb_rows + r2->nb_rows, r1->nb_columns);
01556
01557 for (i = 0; i < row; i++)
01558 for (j = 0; j < r1->nb_columns; j++)
01559 osl_int_assign(r1->precision, temp->m[i], j, r1->m[i], j);
01560
01561 osl_relation_replace_constraints(temp, r2, row);
01562
01563 for (i = row + r2->nb_rows; i < r2->nb_rows + r1->nb_rows; i++)
01564 for (j = 0; j < r1->nb_columns; j++)
01565 osl_int_assign(r1->precision, temp->m[i], j, r1->m[i-r2->nb_rows], j);
01566
01567 osl_relation_free_inside(r1);
01568
01569
01570 r1->nb_rows = temp->nb_rows;
01571 r1->m = temp->m;
01572
01573
01574 free(temp);
01575 }
01576
01577
01585 void osl_relation_remove_row(osl_relation_p r, int row) {
01586 int i, j;
01587 osl_relation_p temp;
01588
01589 if (r == NULL)
01590 return;
01591
01592 if ((row < 0) || (row >= r->nb_rows))
01593 OSL_error("bad row number");
01594
01595
01596 temp = osl_relation_pmalloc(r->precision,
01597 r->nb_rows - 1, r->nb_columns);
01598
01599 for (i = 0; i < row; i++)
01600 for (j = 0; j < r->nb_columns; j++)
01601 osl_int_assign(r->precision, temp->m[i], j, r->m[i], j);
01602
01603 for (i = row + 1; i < r->nb_rows; i++)
01604 for (j = 0; j < r->nb_columns; j++)
01605 osl_int_assign(r->precision, temp->m[i - 1], j, r->m[i], j);
01606
01607 osl_relation_free_inside(r);
01608
01609
01610 r->nb_rows = temp->nb_rows;
01611 r->m = temp->m;
01612
01613
01614 free(temp);
01615 }
01616
01617
01625 void osl_relation_remove_column(osl_relation_p r, int column) {
01626 int i, j;
01627 osl_relation_p temp;
01628
01629 if (r == NULL)
01630 return;
01631
01632 if ((column < 0) || (column >= r->nb_columns))
01633 OSL_error("bad column number");
01634
01635
01636 temp = osl_relation_pmalloc(r->precision,
01637 r->nb_rows, r->nb_columns - 1);
01638
01639 for (i = 0; i < r->nb_rows; i++) {
01640 for (j = 0; j < column; j++)
01641 osl_int_assign(r->precision, temp->m[i], j, r->m[i], j);
01642
01643 for (j = column + 1; j < r->nb_columns; j++)
01644 osl_int_assign(r->precision, temp->m[i], j - 1, r->m[i], j);
01645 }
01646
01647 osl_relation_free_inside(r);
01648
01649
01650 r->nb_rows = temp->nb_rows;
01651 r->m = temp->m;
01652
01653
01654 free(temp);
01655 }
01656
01657
01669 void osl_relation_insert_columns(osl_relation_p relation,
01670 osl_relation_p insert, int column) {
01671 int i, j;
01672 osl_relation_p temp;
01673
01674 if ((relation == NULL) || (insert == NULL))
01675 return;
01676
01677 if ((relation->precision != insert->precision) ||
01678 (relation->nb_rows != insert->nb_rows) ||
01679 (column < 0) || (column > relation->nb_columns))
01680 OSL_error("columns cannot be inserted");
01681
01682
01683 temp = osl_relation_pmalloc(relation->precision, relation->nb_rows,
01684 relation->nb_columns + insert->nb_columns);
01685
01686 for (i = 0; i < relation->nb_rows; i++) {
01687 for (j = 0; j < column; j++)
01688 osl_int_assign(relation->precision, temp->m[i], j, relation->m[i], j);
01689
01690 for (j = column; j < column + insert->nb_columns; j++)
01691 osl_int_assign(relation->precision,
01692 temp->m[i], j, insert->m[i], j - column);
01693
01694 for (j = column + insert->nb_columns;
01695 j < insert->nb_columns + relation->nb_columns; j++)
01696 osl_int_assign(relation->precision,
01697 temp->m[i], j, relation->m[i], j - insert->nb_columns);
01698 }
01699
01700 osl_relation_free_inside(relation);
01701
01702
01703 relation->nb_columns = temp->nb_columns;
01704 relation->m = temp->m;
01705
01706
01707 free(temp);
01708 }
01709
01710
01722 osl_relation_p osl_relation_concat_constraints(
01723 osl_relation_p r1,
01724 osl_relation_p r2) {
01725 osl_relation_p new;
01726
01727 if (r1 == NULL)
01728 return osl_relation_clone(r2);
01729
01730 if (r2 == NULL)
01731 return osl_relation_clone(r1);
01732
01733 if (r1->nb_columns != r2->nb_columns)
01734 OSL_error("incompatible sizes for concatenation");
01735
01736 if (r1->next || r2->next)
01737 OSL_warning("relation concatenation is done on the first elements "
01738 "of union only");
01739
01740 new = osl_relation_pmalloc(r1->precision,
01741 r1->nb_rows + r2->nb_rows, r1->nb_columns);
01742 osl_relation_replace_constraints(new, r1, 0);
01743 osl_relation_replace_constraints(new, r2, r1->nb_rows);
01744
01745 return new;
01746 }
01747
01748
01757 int osl_relation_equal(osl_relation_p r1, osl_relation_p r2) {
01758 int i, j;
01759
01760 while ((r1 != NULL) && (r2 != NULL)) {
01761 if (r1 == r2)
01762 return 1;
01763
01764 if ((r1->type != r2->type) ||
01765 (r1->precision != r2->precision) ||
01766 (r1->nb_rows != r2->nb_rows) ||
01767 (r1->nb_columns != r2->nb_columns) ||
01768 (r1->nb_output_dims != r2->nb_output_dims) ||
01769 (r1->nb_input_dims != r2->nb_input_dims) ||
01770 (r1->nb_local_dims != r2->nb_local_dims) ||
01771 (r1->nb_parameters != r2->nb_parameters))
01772 return 0;
01773
01774 for (i = 0; i < r1->nb_rows; ++i)
01775 for (j = 0; j < r1->nb_columns; ++j)
01776 if (osl_int_ne(r1->precision, r1->m[i], j, r2->m[i], j))
01777 return 0;
01778
01779 r1 = r1->next;
01780 r2 = r2->next;
01781 }
01782
01783 if (((r1 == NULL) && (r2 != NULL)) || ((r1 != NULL) && (r2 == NULL)))
01784 return 0;
01785
01786 return 1;
01787 }
01788
01789
01803 static
01804 int osl_relation_check_attribute(int * expected, int actual) {
01805 if (*expected != OSL_UNDEFINED) {
01806 if ((actual != OSL_UNDEFINED) &&
01807 (actual != *expected)) {
01808 OSL_warning("unexpected atribute");
01809 return 0;
01810 }
01811 }
01812 else {
01813 *expected = actual;
01814 }
01815
01816 return 1;
01817 }
01818
01819
01833 static
01834 int osl_relation_check_nb_columns(osl_relation_p relation,
01835 int expected_nb_output_dims,
01836 int expected_nb_input_dims,
01837 int expected_nb_parameters) {
01838 int expected_nb_local_dims, expected_nb_columns;
01839
01840 if ((expected_nb_output_dims != OSL_UNDEFINED) &&
01841 (expected_nb_input_dims != OSL_UNDEFINED) &&
01842 (expected_nb_parameters != OSL_UNDEFINED)) {
01843
01844 if (relation->nb_local_dims == OSL_UNDEFINED)
01845 expected_nb_local_dims = 0;
01846 else
01847 expected_nb_local_dims = relation->nb_local_dims;
01848
01849 expected_nb_columns = expected_nb_output_dims +
01850 expected_nb_input_dims +
01851 expected_nb_local_dims +
01852 expected_nb_parameters +
01853 2;
01854
01855 if (expected_nb_columns != relation->nb_columns) {
01856 OSL_warning("unexpected number of columns");
01857 return 0;
01858 }
01859 }
01860
01861 return 1;
01862 }
01863
01864
01879 int osl_relation_integrity_check(osl_relation_p relation,
01880 int expected_type,
01881 int expected_nb_output_dims,
01882 int expected_nb_input_dims,
01883 int expected_nb_parameters) {
01884 int i;
01885
01886
01887 if (relation == NULL) {
01888 if ((expected_nb_output_dims != OSL_UNDEFINED) ||
01889 (expected_nb_input_dims != OSL_UNDEFINED) ||
01890 (expected_nb_parameters != OSL_UNDEFINED)) {
01891 OSL_debug("NULL relation with some expected attibutes");
01892
01893 }
01894
01895 return 1;
01896 }
01897
01898
01899 if (((expected_type != OSL_TYPE_ACCESS) &&
01900 (expected_type != relation->type)) ||
01901 ((expected_type == OSL_TYPE_ACCESS) &&
01902 (!osl_relation_is_access(relation)))) {
01903 OSL_warning("wrong type");
01904 osl_relation_dump(stderr, relation);
01905 return 0;
01906 }
01907
01908
01909 if ((relation->nb_output_dims == OSL_UNDEFINED) ||
01910 (relation->nb_input_dims == OSL_UNDEFINED) ||
01911 (relation->nb_local_dims == OSL_UNDEFINED) ||
01912 (relation->nb_parameters == OSL_UNDEFINED)) {
01913 OSL_warning("all attributes should be defined");
01914 osl_relation_dump(stderr, relation);
01915 return 0;
01916 }
01917
01918
01919 if ((relation->type == OSL_TYPE_CONTEXT) &&
01920 (relation->nb_output_dims != 0)) {
01921 OSL_warning("context without 0 as number of output dimensions");
01922 osl_relation_dump(stderr, relation);
01923 return 0;
01924 }
01925
01926
01927 if (((relation->type == OSL_TYPE_DOMAIN) ||
01928 (relation->type == OSL_TYPE_CONTEXT)) &&
01929 (relation->nb_input_dims != 0)) {
01930 OSL_warning("domain or context without 0 input dimensions");
01931 osl_relation_dump(stderr, relation);
01932 return 0;
01933 }
01934
01935
01936
01937 if (!osl_relation_check_attribute(&expected_nb_output_dims,
01938 relation->nb_output_dims) ||
01939 !osl_relation_check_attribute(&expected_nb_input_dims,
01940 relation->nb_input_dims) ||
01941 !osl_relation_check_attribute(&expected_nb_parameters,
01942 relation->nb_parameters)) {
01943 osl_relation_dump(stderr, relation);
01944 return 0;
01945 }
01946
01947 while (relation != NULL) {
01948
01949
01950
01951 if ((expected_nb_output_dims != relation->nb_output_dims) ||
01952 (expected_nb_input_dims != relation->nb_input_dims) ||
01953 (expected_nb_parameters != relation->nb_parameters)) {
01954 OSL_warning("inconsistent attributes");
01955 osl_relation_dump(stderr, relation);
01956 return 0;
01957 }
01958
01959
01960 if (!osl_relation_check_nb_columns(relation,
01961 expected_nb_output_dims,
01962 expected_nb_input_dims,
01963 expected_nb_parameters)) {
01964 osl_relation_dump(stderr, relation);
01965 return 0;
01966 }
01967
01968
01969
01970 if ((relation->nb_rows > 0) && (relation->nb_columns > 0)) {
01971 for (i = 0; i < relation->nb_rows; i++) {
01972 if (!osl_int_zero(relation->precision, relation->m[i], 0) &&
01973 !osl_int_one(relation->precision, relation->m[i], 0)) {
01974 OSL_warning("first column of a relation is not "
01975 "strictly made of 0 or 1");
01976 osl_relation_dump(stderr, relation);
01977 return 0;
01978 }
01979 }
01980 }
01981
01982
01983 if ((osl_relation_is_access(relation)) &&
01984 (osl_relation_get_array_id(relation) == OSL_UNDEFINED)) {
01985 osl_relation_dump(stderr, relation);
01986 return 0;
01987 }
01988
01989 relation = relation->next;
01990 }
01991
01992 return 1;
01993 }
01994
01995
02006 void osl_relation_set_attributes_one(osl_relation_p relation,
02007 int nb_output_dims, int nb_input_dims,
02008 int nb_local_dims, int nb_parameters) {
02009 if (relation != NULL) {
02010 relation->nb_output_dims = nb_output_dims;
02011 relation->nb_input_dims = nb_input_dims;
02012 relation->nb_local_dims = nb_local_dims;
02013 relation->nb_parameters = nb_parameters;
02014 }
02015 }
02016
02017
02028 void osl_relation_set_attributes(osl_relation_p relation,
02029 int nb_output_dims, int nb_input_dims,
02030 int nb_local_dims, int nb_parameters) {
02031 while (relation != NULL) {
02032 osl_relation_set_attributes_one(relation,
02033 nb_output_dims, nb_input_dims,
02034 nb_local_dims, nb_parameters);
02035 relation = relation->next;
02036 }
02037 }
02038
02039
02047 void osl_relation_set_type(osl_relation_p relation, int type) {
02048
02049 while (relation != NULL) {
02050 relation->type = type;
02051 relation = relation->next;
02052 }
02053 }
02054
02055
02064 int osl_relation_get_array_id(osl_relation_p relation) {
02065 int i;
02066 int first = 1;
02067 int array_id = OSL_UNDEFINED;
02068 int reference_array_id = OSL_UNDEFINED;
02069 int nb_array_id;
02070 int row_id = 0;
02071 int precision;
02072
02073 if (relation == NULL)
02074 return OSL_UNDEFINED;
02075
02076 if (!osl_relation_is_access(relation)) {
02077 OSL_warning("asked for an array id of non-array relation");
02078 return OSL_UNDEFINED;
02079 }
02080
02081 while (relation != NULL) {
02082 precision = relation->precision;
02083
02084
02085 if ((relation->nb_rows < 1) ||
02086 (relation->nb_columns < 3)) {
02087 OSL_warning("no array identifier in an access function");
02088 return OSL_UNDEFINED;
02089 }
02090
02091
02092
02093
02094
02095
02096
02097 nb_array_id = 0;
02098 for (i = 0; i < relation->nb_rows; i++) {
02099 if (!osl_int_zero(precision, relation->m[i], 1)) {
02100 nb_array_id ++;
02101 row_id = i;
02102 }
02103 }
02104 if (nb_array_id == 0) {
02105 OSL_warning("no array identifier in an access function");
02106 return OSL_UNDEFINED;
02107 }
02108 if (nb_array_id > 1) {
02109 OSL_warning("several array identifiers in one access function");
02110 return OSL_UNDEFINED;
02111 }
02112 for (i = 0; i < relation->nb_columns - 1; i++) {
02113 if ((i != 1) && !osl_int_zero(precision, relation->m[row_id], i)) {
02114 OSL_warning("non integer array identifier");
02115 return OSL_UNDEFINED;
02116 }
02117 }
02118 if (!osl_int_divisible(precision,
02119 relation->m[row_id], relation->nb_columns - 1,
02120 relation->m[row_id], 1)) {
02121 OSL_warning("rational array identifier");
02122 return OSL_UNDEFINED;
02123 }
02124 array_id = -osl_int_get_si(precision,
02125 relation->m[row_id],
02126 relation->nb_columns - 1);
02127 array_id /= osl_int_get_si(precision, relation->m[row_id], 1);
02128 if (array_id <= 0) {
02129 OSL_warning("negative or 0 identifier in access function");
02130 return OSL_UNDEFINED;
02131 }
02132
02133
02134 if (first) {
02135 reference_array_id = array_id;
02136 first = 0;
02137 }
02138 else {
02139 if (reference_array_id != array_id) {
02140 OSL_warning("inconsistency of array identifiers in an "
02141 "union of access relations");
02142 return OSL_UNDEFINED;
02143 }
02144 }
02145
02146 relation = relation->next;
02147 }
02148
02149 return array_id;
02150 }
02151
02152
02160 int osl_relation_is_access(osl_relation_p relation) {
02161
02162 if (relation == NULL)
02163 return 0;
02164
02165 if ((relation->type == OSL_TYPE_ACCESS) ||
02166 (relation->type == OSL_TYPE_READ) ||
02167 (relation->type == OSL_TYPE_WRITE) ||
02168 (relation->type == OSL_TYPE_MAY_WRITE))
02169 return 1;
02170
02171 return 0;
02172 }
02173
02174
02193 void osl_relation_get_attributes(osl_relation_p relation,
02194 int * nb_parameters,
02195 int * nb_iterators,
02196 int * nb_scattdims,
02197 int * nb_localdims,
02198 int * array_id) {
02199 int type;
02200 int local_nb_parameters = OSL_UNDEFINED;
02201 int local_nb_iterators = OSL_UNDEFINED;
02202 int local_nb_scattdims = OSL_UNDEFINED;
02203 int local_nb_localdims = OSL_UNDEFINED;
02204 int local_array_id = OSL_UNDEFINED;
02205
02206 while (relation != NULL) {
02207 if (osl_relation_is_access(relation))
02208 type = OSL_TYPE_ACCESS;
02209 else
02210 type = relation->type;
02211
02212
02213 switch (type) {
02214 case OSL_TYPE_CONTEXT:
02215 local_nb_parameters = relation->nb_parameters;
02216 local_nb_iterators = 0;
02217 local_nb_scattdims = 0;
02218 local_nb_localdims = relation->nb_local_dims;
02219 local_array_id = 0;
02220 break;
02221
02222 case OSL_TYPE_DOMAIN:
02223 local_nb_parameters = relation->nb_parameters;
02224 local_nb_iterators = relation->nb_output_dims;
02225 local_nb_scattdims = 0;
02226 local_nb_localdims = relation->nb_local_dims;
02227 local_array_id = 0;
02228 break;
02229
02230 case OSL_TYPE_SCATTERING:
02231 local_nb_parameters = relation->nb_parameters;
02232 local_nb_iterators = relation->nb_input_dims;
02233 local_nb_scattdims = relation->nb_output_dims;
02234 local_nb_localdims = relation->nb_local_dims;
02235 local_array_id = 0;
02236 break;
02237
02238 case OSL_TYPE_ACCESS:
02239 local_nb_parameters = relation->nb_parameters;
02240 local_nb_iterators = relation->nb_input_dims;
02241 local_nb_scattdims = 0;
02242 local_nb_localdims = relation->nb_local_dims;
02243 local_array_id = osl_relation_get_array_id(relation);
02244 break;
02245 }
02246
02247
02248 *nb_parameters = OSL_max(*nb_parameters, local_nb_parameters);
02249 *nb_iterators = OSL_max(*nb_iterators, local_nb_iterators);
02250 *nb_scattdims = OSL_max(*nb_scattdims, local_nb_scattdims);
02251 *nb_localdims = OSL_max(*nb_localdims, local_nb_localdims);
02252 *array_id = OSL_max(*array_id, local_array_id);
02253 relation = relation->next;
02254 }
02255 }
02256
02257
02269 osl_relation_p osl_relation_extend_output(osl_relation_p relation, int dim) {
02270 int i, j;
02271 int first = 1;
02272 int offset;
02273 osl_relation_p extended = NULL, node, previous = NULL;
02274
02275 while (relation != NULL) {
02276 if (relation->nb_output_dims > dim)
02277 OSL_error("Number of output dims is greater than required extension");
02278 offset = dim - relation->nb_output_dims;
02279
02280 node = osl_relation_pmalloc(relation->precision,
02281 relation->nb_rows + offset,
02282 relation->nb_columns + offset);
02283
02284 node->type = relation->type;
02285 node->nb_output_dims = OSL_max(relation->nb_output_dims, dim);
02286 node->nb_input_dims = relation->nb_input_dims;
02287 node->nb_local_dims = relation->nb_local_dims;
02288 node->nb_parameters = relation->nb_parameters;
02289
02290
02291
02292 for (i = 0; i < relation->nb_rows; i++) {
02293 for (j = 0; j <= relation->nb_output_dims; j++)
02294 osl_int_assign(relation->precision, node->m[i], j, relation->m[i], j);
02295
02296 for (j = relation->nb_output_dims + offset + 1;
02297 j < relation->nb_columns + offset; j++)
02298 osl_int_assign(relation->precision,
02299 node->m[i], j, relation->m[i], j - offset);
02300 }
02301
02302
02303 for (i = relation->nb_rows; i < relation->nb_rows + offset; i++) {
02304 for (j = 0; j < relation->nb_columns + offset; j++) {
02305 if ((i - relation->nb_rows) == (j - relation->nb_output_dims - 1))
02306 osl_int_set_si(relation->precision, node->m[i], j, -1);
02307 }
02308 }
02309
02310 if (first) {
02311 first = 0;
02312 extended = node;
02313 previous = node;
02314 }
02315 else {
02316 previous->next = node;
02317 previous = previous->next;
02318 }
02319
02320 relation = relation->next;
02321 }
02322
02323 return extended;
02324 }
02325