void findConst(stringSet &l) { stringSet::iterator beg = l.begin(); stringSet::iterator end = l.end(); while (beg != end) { TParam cur = (*--end); if (!cur.isArrayElement()) continue; int dim = cur. getDimension(); TIndex *indexes = cur. getIndexes(); for (int i = 0; i < dim; i++) { if (!indexes[i]. isAtom()) continue; // already proceed before string name = ""; struct expression *cur_index = indexes[i].getIndex(); struct TEvaluableExpression *res = expression2evaluate(*cur_index, name); if (res == NULL) continue; struct calc expr = evaluate(*res); freeEval(res); if (expr. id == 0) // constant index (*end). setIndex(i, TRange(expr. number, expr. number)); //indexes[i]. setRangeList(); } } }
bool isIntersect(const stringSet &in, const stringSet &out) { stringSet::const_iterator beg_in = in.begin(); stringSet::const_iterator end_in = in.end(); //cout<<"Dependency search"<<endl; while (beg_in != end_in) { TParam cur_in = (*--end_in); stringSet::const_iterator beg_out = out.begin(); stringSet::const_iterator end_out = out.end(); while (beg_out != end_out) { TParam cur_out = (*--end_out); if (cur_in. getName() != cur_out. getName()) continue; if (!cur_in. isArrayElement() || !cur_out. isArrayElement()) { return true; } else { if (equal(cur_in, cur_out)) { //cout<<"Forward dependency by equal "<<cur_in<<" ~=~ "<<cur_out<<endl; return true; } } } } return false; }
void printStringSet(stringSet arg_stringSet, int step) { cout << "At step " << step << endl ; for (stringSet::iterator result=arg_stringSet.begin(); result!=arg_stringSet.end(); ++result) { cout << *result << " " ; } cout << endl ; }
/** * По данным в узле 1 - <exist> и чтению узла 2 <in> * строим 2 множества - множество передачи от 1 к 2 * множество данных, требуемых в 2 от других узлов (кроме 1) * Подробнее принцип смотри в readme.!!! */ void createForwardTransition(const stringSet &exist, const stringSet &in, stringSet &local, stringSet &other) { // Все данные из <exist> - детерминированные // Если in - детерминированный - передать только это // иначе - передать весь массив(измерение) для синхронизации stringSet::const_iterator beg = in.begin(); stringSet::const_iterator end = in.end(); while (beg != end) { TParam cur = (*--end); if (cur. isScalarVar()) { if (find(cur, exist)) in_out::insert(local, cur); else in_out::insert(other, cur); continue; } if (cur. isScalarArray()) { // это мощная недетерминированная передача stringSet p = getByName(exist, cur. getName()); // Если в р есть весь массив - то его в local if (find(p. begin(), p.end(), cur) == p. end()) { // если не весь - то делим sub на local/other concat(local, p); concat(other, sub(cur, p)); } else { // fixme :array to many elements concat(local, toLocalMemoryUse(cur. unroll())); } continue; } // isScalarElement() int dim = cur. getDimension(); TIndex *indexes = cur. getIndexes(); TDimensionList list = cur. getTypeInfo(). second; TDimensionList::iterator cur_beg = list. begin(); for (int i = dim - 1; i >= 0; i--, cur_beg++) { if (indexes[i]. isAtom()) { cur. setIndex(i, TRange(0, (*cur_beg - 1))); } } intersect(exist, toLocalMemoryUse(cur), local, other); delete[] indexes; } packUnifySet(local); packUnifySet(other); }
void concat(stringSet &s1, const stringSet &s2) { // concate 2 list //cout << "make copy"<<endl; stringSet::const_iterator beg = s2.begin(); stringSet::const_iterator end = s2.end(); while (beg != end) { in_out::insert(s1, *beg++); } }
bool find(const TParam &arg, const stringSet &l) { // Все детерминировано - пользуемся equal stringSet::const_iterator beg = l.begin(); stringSet::const_iterator end = l.end(); while (beg != end) { if (equal(arg, *--end)) return true; } return false; }
/** * Cтроит пересечение common и разность b\a addon */ void intersect(const stringSet &a, const stringSet &b, stringSet &common, stringSet &addon) { stringSet::const_iterator beg = b.begin(); stringSet::const_iterator end = b.end(); while (beg != end) { TParam cur = (*--end); if (!find(cur, a)) addon. push_back(cur); else common. push_back(cur); } }
/** * По имени выбирает все вхождения в список. */ stringSet getByName(const stringSet &in, const string &name) { stringSet::const_iterator beg = in.begin(); stringSet::const_iterator end = in.end(); stringSet result; while (beg != end) { TParam cur = (*--end); if (cur. getName() == name) result. push_back(cur); } packSet(result); return result; }
stringSet sub(const TParam &l, const stringSet &minus) { stringSet temp = toLocalMemoryUse(l.unroll()); stringSet result, empty; // search whole array stringSet::const_iterator pos = find(minus. begin(), minus.end(), l); if (pos != minus. end()) return result; // search successful intersect(minus, temp, empty, result); return result; }
/** * \brief Splits string into different tokens by comma * * @param str string to split * @param result stringSet to put result into * @return true on success, false otherwise */ bool splitString(char *str, stringSet &result) { char *token; if (str == NULL) { return false; } token = strtok(str, ","); /* NULL token cannot be added to result */ if (token == NULL) { return true; } result.insert(token); while ((token = strtok(NULL, ",")) != NULL) { result.insert(token); } return true; }
void packUnifySet(stringSet &l) { // Находим все массивы как скалярные переменные и // удаляем все их частные вхождения // также удаляем повторяющиеся элементы stringSet result; stringSet::const_iterator beg = l.begin(); stringSet::const_iterator end = l.end(); while (beg != end) { TParam cur = (*--end); if (!cur.isArrayElement()) { result. push_back(cur); continue; } if (!find(cur, result)) // удаляем повторения элементов result. push_back(cur); } packSet(result); // удаляем частные вхождения l = result; }
/** * Создает полностью детерминированную зависимость * Все недетерминированные выражения в индексах заменяются на * диапазон 0..размерность */ stringSet createActual(const stringSet &arg) { stringSet result; stringSet::const_iterator beg = arg.begin(); stringSet::const_iterator end = arg.end(); while (beg != end) { TParam cur = *--end; if (!cur. isArrayElement()) { result. push_back(cur); // fixme - remember arrayScalar continue; } // index case int dim = cur. getDimension(); TIndex *indexes = cur. getIndexes(); TDimensionList list = cur. getTypeInfo(). second; TDimensionList::iterator beg = list. begin(); for (int i = dim - 1; i >= 0; i--, beg++) { if (indexes[i]. isAtom()) { indexes[i] = TIndex(TRange(0, (*beg - 1))); continue; } } // этот элемент будет прозрачный в силу изначальной недетерминированности его индекса TParam res(cur. getName(), indexes, dim, cur.getTypeInfo(), true); //cout<<"Create Actual :"<<res<<endl; concat(result, toLocalMemoryUse(res)); delete[] indexes; } packUnifySet(result); return result; }
stringSet packArrays(const stringSet &local) { stringSet res; typedef map< string, stringSet, less<string> > TBagged; TBagged bagged; stringSet::const_iterator beg = local.begin(); stringSet::const_iterator end = local.end(); while (beg != end) { TParam cur = *(--end); if (!cur. isArrayElement()) { res. push_back(cur); continue; } // array element TBagged::iterator pos = bagged. find(cur. getName()); if (bagged. end() == pos) { stringSet l; l. push_back(cur); bagged. insert(TBagged::value_type(cur. getName(), l)); continue; } // more then one param TIndex *indexes = cur. getIndexes(); int dim = cur. getDimension(); //cout<<"Current bagged:"<<pos->second<<endl; //cout<<"Add element :"<<cur<<endl; stringSet::iterator l_beg = pos->second.begin(); stringSet::iterator l_end = pos->second.end(); // remember that all indexes is constant and atomazied bool skip; bool change = false; while (l_beg != l_end) { --l_end; TIndex *ind2 = l_end->getIndexes(); skip = false; for (int i = 0; i < dim - 1; i++) { if (indexes[i]. diap. front() != ind2[i]. diap. front() ) { skip = true; break; } } delete[] ind2; if (skip) { continue; } else { l_end->addIndex(dim - 1, indexes[dim - 1].diap.front()); change = true; break; // no need scan more } } if (!change) { pos->second. push_back(cur); } delete[] indexes; //cout<<"bagged plused :"<<pos->second<<endl; } // view bagged TBagged::const_iterator t_beg = bagged. begin(); TBagged::const_iterator t_end = bagged. end(); //cout<<"before packing:"<<endl<<local<<endl; //cout<<"after packing:"<<endl; /* while(t_beg != t_end){ --t_end; cout<<"Out for "<<t_end->first<<" :"<<t_end->second<<endl; }*/ while (t_beg != t_end) { --t_end; beg = t_end->second.begin(); end = t_end->second.end(); while (beg != end) { //--end; TParam cur = *(--end); int dim = cur. getDimension(); TRangeList sect = cur. getIndex(dim - 1). diap; TRangeList::iterator s_beg = sect. begin(); TRangeList::iterator s_end = sect. end(); while (s_beg != s_end) { --s_end; cur. setIndex(dim - 1, *s_end); res. push_back(cur); } //res. push_back(*end); } } return res; }
/** * По данным в узле 1 - <exist> и записи узла 2 <out> * строим 2 множества - множество передачи от 1 к 2; * множество данных, требуемых в 2 от других узлов (кроме 1) * для недетерминированной записи; * Подробнее принцип смотри в readme.!!! */ void createOutwardTransition(const stringSet &exist, const stringSet &out, stringSet &local, stringSet &other) { // Все данные из <exist> - детерминированные // Если out - детерминированный - передавать ничего не надо // иначе - передать весь массив(измерение) для синхронизации // Если элемент имеет признак прозрачности - тоже необходимо передать stringSet::const_iterator beg_out = out.begin(); stringSet::const_iterator end_out = out.end(); while (beg_out != end_out) { TParam cur_out = (*--end_out); if (cur_out. isScalarVar()) { if (find(exist. begin(), exist.end(), cur_out) == exist. end()) { in_out::insert(other, cur_out); continue; } if (cur_out. transparency()) { // может измениться, а может и нет - подстраховка in_out::insert(local, cur_out); } continue; } if (cur_out. isScalarArray()) { // это мощная недетерминированная запись stringSet p = getByName(exist, cur_out. getName()); // Если в р есть весь массив - то его в local if (find(p. begin(), p.end(), cur_out) == p. end()) { // если не весь - то делим sub на local/other concat(local, p); concat(other, sub(cur_out, p)); } else { // fixme :array to many elements concat(local, toLocalMemoryUse(cur_out. unroll())); } continue; } // isScalarElement() int dim = cur_out. getDimension(); TIndex *indexes = cur_out. getIndexes(); TDimensionList list = cur_out. getTypeInfo(). second; TDimensionList::iterator beg = list. begin(); bool needSend = false; for (int i = dim - 1; i >= 0; i--, beg++) { if (indexes[i]. isAtom()) { needSend = true; cur_out. setIndex(i, TRange(0, (*beg - 1))); continue; } } if (needSend || cur_out. transparency()) { intersect(exist, toLocalMemoryUse(cur_out), local, other); } delete[] indexes; } packUnifySet(local); packUnifySet(other); }