Skip to content

Commit

Permalink
-Implemented ComponentReference.hashComponentRef that performs hashin…
Browse files Browse the repository at this point in the history
…g of component reference without printing the cref, instead it hashes each part individually and accumulates.

-Implemented Expression.hashExp in the same fashion (TODO: hashing of metamodelica expressions).
-Changed all affected hashtable modules to use these instead.

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15213 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Peter Aronsson committed Feb 18, 2013
1 parent f833686 commit 227e4ee
Show file tree
Hide file tree
Showing 18 changed files with 267 additions and 114 deletions.
2 changes: 1 addition & 1 deletion Compiler/BackEnd/BackendDAEOptimize.mo
Expand Up @@ -564,7 +564,7 @@ algorithm
// store new pos
_ = arrayUpdate(newindexarr,index,insertindex);
// add to hash vec
indx = HashTable2.hashFunc(cr, bucketSize);
indx = ComponentReference.hashComponentRefMod(cr, bucketSize);
indexes = crefIdxLstArr[indx + 1];
i = insertindex-1;
_ = arrayUpdate(crefIdxLstArr, indx + 1, (BackendDAE.CREFINDEX(cr,i) :: indexes));
Expand Down
10 changes: 5 additions & 5 deletions Compiler/BackEnd/BackendVariable.mo
Expand Up @@ -2857,7 +2857,7 @@ algorithm
equation
(v as BackendDAE.VAR(varName = cr),varr1) = removeVar1(varr, pos);
pos_1 = pos-1;
hashindx = HashTable2.hashFunc(cr, bsize);
hashindx = ComponentReference.hashComponentRefMod(cr, bsize);
indexes = hashvec[hashindx + 1];
(indexes1,_) = List.deleteMemberOnTrue(BackendDAE.CREFINDEX(cr,pos_1),indexes,removeVar2);
hashvec_1 = arrayUpdate(hashvec, hashindx + 1, indexes1);
Expand Down Expand Up @@ -2974,7 +2974,7 @@ algorithm
// insert on new pos
_ = arrayUpdate(varOptArr,insertindex,SOME(var));
// add to hash vec
indx = HashTable2.hashFunc(cr, bucketSize);
indx = ComponentReference.hashComponentRefMod(cr, bucketSize);
indexes = crefIdxLstArr[indx + 1];
i = insertindex-1;
_ = arrayUpdate(crefIdxLstArr, indx + 1, (BackendDAE.CREFINDEX(cr,i) :: indexes));
Expand Down Expand Up @@ -3146,7 +3146,7 @@ algorithm
equation
failure((_,_) = getVar(cr, vars));
// print("adding when not existing previously\n");
indx = HashTable2.hashFunc(cr, bsize);
indx = ComponentReference.hashComponentRefMod(cr, bsize);
newpos = vararrayLength(varr);
varr_1 = vararrayAdd(varr, v);
indexes = hashvec[indx + 1];
Expand Down Expand Up @@ -3194,7 +3194,7 @@ algorithm
BackendDAE.Variables vars;
case ((v as BackendDAE.VAR(varName = cr)),(vars as BackendDAE.VARIABLES(crefIdxLstArr = hashvec,varArr = varr,bucketSize = bsize,numberOfVars = n)))
equation
indx = HashTable2.hashFunc(cr, bsize);
indx = ComponentReference.hashComponentRefMod(cr, bsize);
newpos = vararrayLength(varr);
varr_1 = vararrayAdd(varr, v);
indexes = hashvec[indx + 1];
Expand Down Expand Up @@ -3542,7 +3542,7 @@ algorithm

case (cr,BackendDAE.VARIABLES(crefIdxLstArr = hashvec,varArr = varr,bucketSize = bsize,numberOfVars = n))
equation
hashindx = HashTable2.hashFunc(cr, bsize);
hashindx = ComponentReference.hashComponentRefMod(cr, bsize);
indexes = hashvec[hashindx + 1];
indx = getVar3(cr, indexes, getVar4(cr,indexes));
((v as BackendDAE.VAR(varName = cr2))) = vararrayNth(varr, indx);
Expand Down
14 changes: 1 addition & 13 deletions Compiler/BackEnd/HashTableCrSimVars.mo
Expand Up @@ -64,18 +64,6 @@ partial function FuncExpStr
output String res;
end FuncExpStr;

public function hashFunc
"Calculates a hash value for Key"
input Key cr;
input Integer mod;
output Integer res;
protected
String crstr;
algorithm
crstr := ComponentReference.printComponentRefStr(cr);
res := System.stringHashDjb2Mod(crstr,mod);
end hashFunc;

public function emptyHashTable
"
Returns an empty HashTable.
Expand All @@ -92,7 +80,7 @@ public function emptyHashTableSized
input Integer size;
output HashTable hashTable;
algorithm
hashTable := BaseHashTable.emptyHashTableWork(size,(hashFunc,ComponentReference.crefEqual,ComponentReference.printComponentRefStr,printVarListStr));
hashTable := BaseHashTable.emptyHashTableWork(size,(ComponentReference.hashComponentRefMod,ComponentReference.crefEqual,ComponentReference.printComponentRefStr,printVarListStr));
end emptyHashTableSized;

public function printVarListStr
Expand Down
23 changes: 4 additions & 19 deletions Compiler/BackEnd/SimCodeUtil.mo
Expand Up @@ -10168,18 +10168,6 @@ end getNominalValue;

/* HashTable instance specific code */

protected function hashFunc "function hashFunc
author: PA
Calculates a hash value for DAE.ComponentRef"
input SimCode.Key cr;
output Integer res;
protected
String crstr;
algorithm
crstr := ComponentReference.printComponentRefStr(cr);
res := stringHashDjb2(crstr);
end hashFunc;

protected function keyEqual
input SimCode.Key key1;
input SimCode.Key key2;
Expand Down Expand Up @@ -10283,8 +10271,7 @@ algorithm
case ((v as (key, value)), (SimCode.HASHTABLE(hashvec, varr, bsize, n)))
equation
failure((_) = get(key, hashTable));
hval = hashFunc(key);
indx = intMod(hval, bsize);
indx = ComponentReference.hashComponentRefMod(key,bsize);
newpos = valueArrayLength(varr);
varr_1 = valueArrayAdd(varr, v);
indexes = hashvec[indx + 1];
Expand Down Expand Up @@ -10363,8 +10350,7 @@ algorithm
// adding when not existing previously
case ((v as (key, value)), (hashTable as SimCode.HASHTABLE(hashvec, varr, bsize, n)))
equation
hval = hashFunc(key);
indx = intMod(hval, bsize);
indx = ComponentReference.hashComponentRefMod(key,bsize);
newpos = valueArrayLength(varr);
varr_1 = valueArrayAdd(varr, v);
indexes = hashvec[indx + 1];
Expand Down Expand Up @@ -10449,9 +10435,8 @@ algorithm
SimCode.Key k;
case (_, (SimCode.HASHTABLE(hashvec, varr, bsize, n)))
equation
hval = hashFunc(key);
hashindx = intMod(hval, bsize);
indexes = hashvec[hashindx + 1];
indx = ComponentReference.hashComponentRefMod(key,bsize);
indexes = hashvec[indx + 1];
indx = get2(key, indexes);
(k, v) = valueArrayNth(varr, indx);
true = keyEqual(k, key);
Expand Down
92 changes: 92 additions & 0 deletions Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -58,12 +58,104 @@ protected import Print;
protected import System;
protected import Types;
protected import Util;
protected import DAEUtil;

// do not make this public. instead use the function below.
protected constant DAE.ComponentRef dummyCref = DAE.CREF_IDENT("dummy", DAE.T_UNKNOWN_DEFAULT, {});

public type ComponentRef = DAE.ComponentRef;

public function hashComponentRefMod "
author: PA
Calculates a hash value for DAE.ComponentRef, by hashing each individual part separately and summing the values, and then apply
intMod to it, to return a value in range [0,mod-1].
Also hashes subscripts in a clever way avoiding [1,2] and [2,1] to hash to the same value. This is done by investigating array type
to find dimension of array.
"
input DAE.ComponentRef cr;
input Integer mod;
output Integer res;
protected
Integer h;
algorithm
// hash might overflow => force positive
h := intAbs(hashComponentRef(cr));
res := intMod(h,mod);
end hashComponentRefMod;

public function hashComponentRef "new hashing that properly deals with subscripts so [1,2] and [2,1] hash to different values"
input DAE.ComponentRef cr;
output Integer hash;
algorithm
hash := matchcontinue(cr)
local
DAE.Ident id;
DAE.Type tp;
list<DAE.Subscript> subs;
DAE.ComponentRef cr1;
case(DAE.CREF_IDENT(id,tp,subs)) equation
//print("IDENT, "+&id+&" hashed to "+&intString(stringHashDjb2(id))+&", subs hashed to "+&intString(hashSubscripts(tp,subs))+&"\n");
then stringHashDjb2(id) + hashSubscripts(tp,subs);

case(DAE.CREF_QUAL(id,tp,subs,cr1)) equation
//print("QUAL, "+&id+&" hashed to "+&intString(stringHashDjb2(id))+&", subs hashed to "+&intString(hashSubscripts(tp,subs))+&"\n");
then stringHashDjb2(id)+hashSubscripts(tp,subs)+hashComponentRef(cr1);

case(DAE.CREF_ITER(id,_,tp,subs))
then stringHashDjb2(id)+ hashSubscripts(tp,subs);
case(_) then 0;
end matchcontinue;
end hashComponentRef;

protected protected function hashSubscripts "help function, hashing subscripts making sure [1,2] and [2,1] doesn't match to the same number"
input DAE.Type tp;
input list<DAE.Subscript> subs;
output Integer hash;
algorithm
hash := matchcontinue(tp,subs)
case(_,{}) then 0;
// TODO: Currently, the types of component references are wrong, they consider the subscripts but they should not.
// For example, given Real a[10,10]; the component reference 'a[1,2]' should have type Real[10,10] but it has type Real.
case(_,_) then hashSubscripts2(List.fill(1,listLength(subs)),/*DAEUtil.expTypeArrayDimensions(tp),*/subs,1);
end matchcontinue;
end hashSubscripts;

protected protected function hashSubscripts2 "help function"
input list<Integer> dims;
input list<DAE.Subscript> subs;
input Integer factor;
output Integer hash;
algorithm
hash := matchcontinue(dims,subs,factor)
local
Integer i1;
DAE.Subscript s;

case({},{},factor) then 0;
case(i1::dims,s::subs,factor)
// TODO: change to using dimensions once cref types has been fixed.
then hashSubscript(s)*factor + hashSubscripts2(dims,subs,factor*1000/* *i1 */);
end matchcontinue;
end hashSubscripts2;

protected function hashSubscript "help function"
input DAE.Subscript sub;
output Integer hash;
algorithm
hash := matchcontinue(sub)
local
DAE.Exp exp;
Integer i;

case(DAE.WHOLEDIM()) then 0;
case(DAE.INDEX(DAE.ICONST(i))) then i;
case(DAE.SLICE(exp)) then Expression.hashExp(exp);
case(DAE.INDEX(exp)) then Expression.hashExp(exp);
case(DAE.WHOLE_NONEXP(exp)) then Expression.hashExp(exp);
end matchcontinue;
end hashSubscript;

public function createEmptyCrefMemory
"@author: adrpo
creates an array, with one element for each record in ComponentRef!"
Expand Down
134 changes: 134 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -9305,5 +9305,139 @@ algorithm
end match;
end promoteExp3;

public function hashExpMod "
author: PA
hash expression to value in range [0,mod-1]"
input DAE.Exp e;
input Integer mod;
output Integer hash;
algorithm
hash := intMod(intAbs(hashExp(e)),mod);
end hashExpMod;

public function hashExp "help function to hashExpMod"
input DAE.Exp e;
output Integer hash;
algorithm
hash := matchcontinue(e)
local
Real r;
Integer i;
Boolean b;
String s;
Absyn.Path path;
DAE.Exp e1,e2,e3;
DAE.Operator op;
list<DAE.Exp> expl;
list<list<DAE.Exp>> mexpl;
ComponentReference.ComponentRef cr;
DAE.ReductionIterators iters;
DAE.ReductionInfo info;

case(DAE.ICONST(i)) then stringHashDjb2(intString(i));
case(DAE.RCONST(r)) then stringHashDjb2(realString(r));
case(DAE.BCONST(b)) then stringHashDjb2(boolString(b));
case(DAE.SCONST(s)) then stringHashDjb2(s);
case(DAE.ENUM_LITERAL(name=path)) then stringHashDjb2(Absyn.pathString(path));
case(DAE.CREF(componentRef=cr)) then ComponentReference.hashComponentRef(cr);

case(DAE.BINARY(e1,op,e2)) then 1 + hashExp(e1)+hashOp(op)+hashExp(e2);
case(DAE.UNARY(op,e1)) then 2 + hashOp(op)+hashExp(e1);
case(DAE.LBINARY(e1,op,e2)) then 3 + hashExp(e1)+hashOp(op)+hashExp(e2);
case(DAE.LUNARY(op,e1)) then 4 + hashOp(op)+hashExp(e1);
case(DAE.RELATION(e1,op,e2,_,_)) then 5 + hashExp(e1)+hashOp(op)+hashExp(e2);
case(DAE.IFEXP(e1,e2,e3)) then 6 + hashExp(e1)+hashExp(e2)+hashExp(e3);
case(DAE.CALL(path=path,expLst=expl)) then 7 + stringHashDjb2(Absyn.pathString(path))+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.PARTEVALFUNCTION(path=path,expList=expl)) then 8 + stringHashDjb2(Absyn.pathString(path))+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.ARRAY(array=expl)) then 9 + List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.MATRIX(matrix=mexpl)) then 10 + List.reduce(List.map(List.flatten(mexpl),hashExp),intAdd);
case(DAE.RANGE(_,e1,SOME(e2),e3)) then 11 + hashExp(e1)+hashExp(e2)+hashExp(e3);
case(DAE.RANGE(_,e1,NONE(),e3)) then 12 + hashExp(e1)+hashExp(e3);
case(DAE.TUPLE(expl)) then 13 + List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.CAST(_,e1)) then 14 + hashExp(e1);
case(DAE.ASUB(e1,expl)) then 15 + hashExp(e1)+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.TSUB(e1,i,_)) then 16 + hashExp(e1)+stringHashDjb2(intString(i));
case(DAE.SIZE(e1,SOME(e2))) then 17 + hashExp(e1)+hashExp(e2);
case(DAE.SIZE(e1,NONE())) then 18 + hashExp(e1);
case(DAE.CODE(_,_)) then 19; // TODO: implement hashing of CODE AST
case(DAE.EMPTY(scope=_)) then 20; // TODO: implement hashing of EMTPY (needed ?)
case(DAE.REDUCTION(info,e1,iters)) then 21 + hashReductionInfo(info)+hashExp(e1)+List.reduce(List.map(iters,hashReductionIter),intAdd);
// TODO: hashing of all MetaModelica extensions
case(_) then 22;
end matchcontinue;
end hashExp;


protected function hashReductionInfo "help function to hashExp"
input DAE.ReductionInfo info;
output Integer hash;
algorithm
hash := matchcontinue(info)
local
Absyn.Path path;

// TODO: complete hasing of all subexpressions
case(DAE.REDUCTIONINFO(path,_,_,_)) then 22 + stringHashDjb2(Absyn.pathString(path));
end matchcontinue;
end hashReductionInfo;

protected protected function hashReductionIter "help function to hashExp"
input DAE.ReductionIterator iter;
output Integer hash;
algorithm
hash := matchcontinue(iter)
local
String id;
DAE.Exp e1,e2;


case(DAE.REDUCTIONITER(id,e1,SOME(e2),_)) then 23 + stringHashDjb2(id)+hashExp(e1)+hashExp(e2);
case(DAE.REDUCTIONITER(id,e1,NONE(),_)) then 24 + stringHashDjb2(id)+hashExp(e1);
end matchcontinue;

end hashReductionIter;
protected protected function hashOp "help function to hashExp"
input DAE.Operator op;
output Integer hash;
algorithm
hash := matchcontinue(op)
local
Absyn.Path path;

case(DAE.ADD(_)) then 25;
case(DAE.SUB(_)) then 26;
case(DAE.MUL(_)) then 27;
case(DAE.DIV(_)) then 28;
case(DAE.POW(_)) then 29;
case(DAE.UMINUS(_)) then 30;
case(DAE.UMINUS_ARR(_)) then 31;
case(DAE.ADD_ARR(_)) then 32;
case(DAE.SUB_ARR(_)) then 33;
case(DAE.MUL_ARR(_)) then 34;
case(DAE.DIV_ARR(_)) then 35;
case(DAE.MUL_ARRAY_SCALAR(_)) then 36;
case(DAE.ADD_ARRAY_SCALAR(_)) then 37;
case(DAE.SUB_SCALAR_ARRAY(_)) then 38;
case(DAE.MUL_SCALAR_PRODUCT(_)) then 39;
case(DAE.MUL_MATRIX_PRODUCT(_)) then 40;
case(DAE.DIV_ARRAY_SCALAR(_)) then 41;
case(DAE.DIV_SCALAR_ARRAY(_)) then 42;
case(DAE.POW_ARRAY_SCALAR(_)) then 43;
case(DAE.POW_SCALAR_ARRAY(_)) then 44;
case(DAE.POW_ARR(_)) then 45;
case(DAE.POW_ARR2(_)) then 46;
case(DAE.AND(_)) then 47;
case(DAE.OR(_)) then 48;
case(DAE.NOT(_)) then 49;
case(DAE.LESS(_)) then 50;
case(DAE.LESSEQ(_)) then 51;
case(DAE.GREATER(_)) then 52;
case(DAE.GREATEREQ(_)) then 53;
case(DAE.EQUAL(_)) then 54;
case(DAE.NEQUAL(_)) then 55;
case(DAE.USERDEFINED(path)) then 56 + stringHashDjb2(Absyn.pathString(path)) ;
end matchcontinue;
end hashOp;

end Expression;

15 changes: 15 additions & 0 deletions Compiler/Util/BaseHashTable.mo
Expand Up @@ -176,6 +176,21 @@ algorithm
end matchcontinue;
end add;

public function dumpHashTableStatistics "
author: PA.
dump statistics on how many entries per hash value. Useful to see how hash function behaves"
input HashTable hashTable;
algorithm
_ := matchcontinue(hashTable)
local HashVector hvec;
case((hvec,_,_,_,_)) equation
print("index list lengths:\n");
print(stringDelimitList(List.map(List.map(arrayList(hvec),listLength),intString),","));
print("\n");
then ();
end matchcontinue;
end dumpHashTableStatistics;

public function addNoUpdCheck
"Add a Key-Value tuple to hashtable, without checking if it already exists.
This function is thus more efficient than add if you already know that the
Expand Down

0 comments on commit 227e4ee

Please sign in to comment.