Opened 10 years ago

Last modified 10 years ago

#2804 new defect

codegen error if one is using Modelica.Utilities.Streams.readLine

Reported by: Willi Braun Owned by: Lennart Ochel
Priority: high Milestone: Future
Component: Code Generation Version: trunk
Keywords: Cc: Martin Sjölund, Mahder Alemseged Gebremedhin, Lennart Ochel

Description

Models that try to use the function Modelica.Utilities.Streams.readLine are failing with a code generation error.

model test
/*
function readL
  input String fileName;
  input Integer line;
  output String string;
algorithm
  string := Modelica.Utilities.Streams.readLine(fileName, line);
end readL;

function readF
  input String fileName;
  output String stringVector[Modelica.Utilities.Streams.countLines(fileName)];
algorithm
  for i in  1:size(stringVector, 1) loop
    stringVector[i] := readL(fileName, i);
  end for;
  Modelica.Utilities.Streams.close(fileName);
end readF;
*/
  parameter String fileName = \"./test.txt\";
  parameter Integer N = Modelica.Utilities.Streams.countLines(fileName);
  parameter String file[N] = Modelica.Utilities.Streams.readFile(fileName);
  // works 
  // parameter String file[N] = readF(fileName);

end test;

Somehow the types of an array inside of DAE.STMT_TUPLE_ASSIGN are not generate correct. That code the is generated with the following line works, but then we get other issue. The question is which type should passed to the function contextArrayReferenceCrefAndCopy.

  • Compiler/Template/CodegenC.tpl

     
    47344736  match ty
    47354737    case T_ARRAY(__) then
    47364738      let &varCopyAfter = buffer ""
    4737       let var = tempDecl("base_array_t", &varDecls)
     4739      let var = tempDecl(expTypeArrayIf(ty), &varDecls)
    47384740      let lhs = writeLhsCref(e, var, context, &varCopyAfter, &varDecls, &auxFunction)
    47394741      let &varCopy += if lhs then '<%lhs%><%\n%>' else error(sourceInfo(), 'Got empty statement from writeLhsCref(<%printExpStr(e)%>)')
    47404742      let &varCopy += varCopyAfter
     
    70707081case STMT_TUPLE_ASSIGN(exp=CALL(attr=CALL_ATTR(ty=T_TUPLE(tupleType=ntys)))) then
    70717082  let &preExp = buffer ""
    70727083  let &postExp = buffer ""
    70737084  let lhsCrefs = (List.rest(expExpLst) |> e => match e
    70747085    case ARRAY(array={})
    70757086    case CREF(componentRef=WILD(__)) then ", NULL"
    7076     case CREF(componentRef=cr,ty=ty) then (", &" + contextArrayReferenceCrefAndCopy(cr, e, ty, context, varDecls, postExp, &auxFunction))
     7087    case CREF(componentRef=cr,ty=ty) then (", &" + contextArrayReferenceCrefAndCopy(cr, e, crefLastType(cr), context, varDecls, postExp, &auxFunction))
    70777088    // Crazy DAE.CALL on lhs? Yup, we apparently generate those. TODO: Don't generate those crazy things!
    70787089    case CALL(attr=CALL_ATTR(ty=ty)) then (", &" + contextArrayReferenceCrefAndCopy(makeUntypedCrefIdent("#error"), e, ty, context, varDecls, postExp, auxFunction))
    70797090    else error(sourceInfo(), 'Unknown expression to assign to: <%printExpStr(e)%>'))
    70807091  // The tuple expressions might take fewer variables than the number of outputs. No worries.
    70817092  let lhsCrefs2 = lhsCrefs + List.fill(", NULL", intMax(0,intSub(listLength(ntys),listLength(expExpLst))))
    70827093  let ret = daeExpCallTuple(exp, lhsCrefs2, context, &preExp, &varDecls, &auxFunction)
    70837094  let &preExp += match expExpLst
    70847095    case ARRAY(array={})::_
    70857096    case CREF(componentRef=WILD(__))::_ then '<%ret%>;<%\n%>'
    7086     case (e as CREF(componentRef=cr,ty=ty))::_ then '<%contextArrayReferenceCrefAndCopy(cr, e, ty, context, varDecls, postExp, auxFunction)%> = <%ret%>;<%\n%>'
     7097    case (e as CREF(componentRef=cr,ty=ty))::_ then '<%contextArrayReferenceCrefAndCopy(cr, e, crefLastType(cr), context, varDecls, postExp, auxFunction)%> = <%ret%>;<%\n%>'
    70877098    // Crazy DAE.CALL on lhs? Yup, we apparently generate those. TODO: Don't generate those crazy things!
    70887099    case (e as CALL(attr=CALL_ATTR(ty=ty)))::_ then '<%contextArrayReferenceCrefAndCopy(makeUntypedCrefIdent("#error"), e, ty, context, varDecls, postExp, auxFunction)%> = <%ret%>;<%\n%>'
    70897100    case e::_ then error(sourceInfo(), 'Unknown expression to assign to: <%printExpStr(e)%>')
    70907101  ('/* tuple assignment */<%\n%>' + preExp + postExp)
    70917102case STMT_TUPLE_ASSIGN(exp=MATCHEXPRESSION(__)) then
    70927103  let &preExp = buffer ""
    70937104  let &afterExp = buffer ""

Change History (6)

comment:1 by Willi Braun, 10 years ago

Cc: Lennart Ochel added

comment:2 by Martin Sjölund, 10 years ago

I believe my working copy will solve the model. But it won't solve the underlying problem that tuple statements assigning to arrays sometimes fail (the fix optimizes the tuple assignment into a regular assignment).
Changing to crefLastType(cr) does not take subscripts into account. Maybe that was the problem.

comment:3 by Willi Braun, 10 years ago

I also played with crefTypeConsiderSubs(cr) but also without luck.

Do you have ideas how to solve the the underlying problem at all?
Otherwise your working copy would help users anyway.

comment:4 by Martin Sjölund, 10 years ago

I am just having one problem before I can commit: a function that should not be inlined suddenly is...

Instead of:
C[1,1] = (inv({{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}) * {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}})[1, 1]
I get:
C[1,1] = (LAPACK.dgetri(LU, pivots)[1] * {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}})[1, 1]

But LU and pivots are local variables from the function. And the types on them are wrong, so the array can not be created.

comment:5 by Martin Sjölund, 10 years ago

I will be busy writing Modrio documents for some time. I could give the code to someone if they want to play with it.

comment:6 by Willi Braun, 10 years ago

In the model above I found a solution that works for now for the user, so I think it's not that urgent.

Note: See TracTickets for help on using tickets.