CellML Discussion List

Text archives Help


[cellml-discussion] import bug in the CCGS?


Chronological Thread 
  • From: ak.miller at auckland.ac.nz (Andrew Miller)
  • Subject: [cellml-discussion] import bug in the CCGS?
  • Date: Fri, 22 Dec 2006 11:09:37 +1300

David Nickerson wrote:
> I have attached two implementations of the same equation, y = sin(x).
>
> In the case where the equation is given in a component within the same
> model as its parent in the encapsulation hierarchy (import_bug-ok.xml)
> everything works fine and CellML2C gives me the expected code.
>
> If I move the exact same component to a separate model (sin.xml) and
> import it (import_bug-fail.xml) then CellML2C tells me the model is
> now overconstrained. But as far as I can tell it is the exact same model.
>
> Can anyone spot an obvious mistake or is this a bug in the CCGS?
It was a bug in the CCGS. Thanks for the report and the test-case (which
has now been included as a regression test for CCGS). This has been
fixed in revision 1014 on the trunk. Patch follows...

Index: CCGS/sources/CCGSGenerator.cpp
===================================================================
--- CCGS/sources/CCGSGenerator.cpp (revision 1013)
+++ CCGS/sources/CCGSGenerator.cpp (revision 1014)
@@ -10,16 +10,54 @@
// Win32 hack...
#ifdef _WIN32
#define swprintf _snwprintf
#endif

#include "CodeGenerationError.hxx"
#include "TemporaryAnnotation.hxx"

+iface::cellml_api::CellMLComponent*
+GetRealComponent(iface::cellml_api::CellMLElement* in)
+{
+ DECLARE_QUERY_INTERFACE_OBJREF(x, in, cellml_api::CellMLComponent);
+ if (x == NULL)
+ throw CodeGenerationError(L"\"in\" not a component (bug)");
+ while (true)
+ {
+ DECLARE_QUERY_INTERFACE_OBJREF(imp, x, cellml_api::ImportComponent);
+ if (imp == NULL)
+ {
+ x->add_ref();
+ return x;
+ }
+ RETURN_INTO_OBJREF(cee, iface::cellml_api::CellMLElement,
+ imp->parentElement());
+ DECLARE_QUERY_INTERFACE_OBJREF(cei, cee, cellml_api::CellMLImport);
+ if (cei == NULL)
+ throw CodeGenerationError(L"Parent of import component not import.");
+ RETURN_INTO_OBJREF(im, iface::cellml_api::Model, cei->importedModel());
+ RETURN_INTO_OBJREF(cs, iface::cellml_api::CellMLComponentSet,
+ im->modelComponents());
+ RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
+ cs->iterateComponents());
+ RETURN_INTO_WSTRING(tn, imp->componentRef());
+ while (true)
+ {
+ x = already_AddRefd<iface::cellml_api::CellMLComponent>
+ (ci->nextComponent());
+ if (x == NULL)
+ throw CodeGenerationError(L"Imported component missing");
+ RETURN_INTO_WSTRING(n, x->name());
+ if (n == tn)
+ break;
+ }
+ }
+}
+
static struct
{
uint32_t badmask;
const wchar_t* errMsg;
} IncompatibleFlagSet[] =
{
{
VariableInformation::SUBJECT_OF_DIFF |
@@ -189,24 +227,26 @@ CodeGenerationState::CreateComponentList
RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
mc->iterateComponents());
while (true)
{
RETURN_INTO_OBJREF(c, iface::cellml_api::CellMLComponent,
ci->nextComponent());
if (c == NULL)
break;
+ RETURN_INTO_OBJREF(rc, iface::cellml_api::CellMLComponent,
+ GetRealComponent(c));
// Append the component to the component list...
- if (compset.count(c) != 0)
+ if (compset.count(rc) != 0)
continue;
- c->add_ref();
- mComponentList.push_back(c);
- compset.insert(c);
+ rc->add_ref();
+ mComponentList.push_back(rc);
+ compset.insert(rc);
// Also, any encapsulation descendents go on the list...
- AddEncapsulationDescendentComponents(compset, c);
+ AddEncapsulationDescendentComponents(compset, rc);
}
}

void
CodeGenerationState::AddEncapsulationDescendentComponents
(
std::set<iface::cellml_api::CellMLComponent*,XPCOMComparator>& compset,
iface::cellml_api::CellMLComponent* aComponent
@@ -217,24 +257,27 @@ CodeGenerationState::AddEncapsulationDes
RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
cs->iterateComponents());
while (true)
{
RETURN_INTO_OBJREF(c, iface::cellml_api::CellMLComponent,
ci->nextComponent());
if (c == NULL)
break;
-
- if (compset.count(c) != 0)
+
+ RETURN_INTO_OBJREF(rc, iface::cellml_api::CellMLComponent,
+ GetRealComponent(c));
+
+ if (compset.count(rc) != 0)
continue;

- c->add_ref();
- mComponentList.push_back(c);
- compset.insert(c);
- AddEncapsulationDescendentComponents(compset, c);
+ rc->add_ref();
+ mComponentList.push_back(rc);
+ compset.insert(rc);
+ AddEncapsulationDescendentComponents(compset, rc);
}
}

void
CodeGenerationState::ProcessMath()
{
std::list<iface::cellml_api::CellMLComponent*>::iterator i;
for (i = mComponentList.begin(); i != mComponentList.end(); i++)
@@ -697,54 +740,16 @@ CodeGenerationState::DetermineRateVariab

bool IsPlainCI(iface::mathml_dom::MathMLElement* aSubExpr)
{
DECLARE_QUERY_INTERFACE_OBJREF(aCISub, aSubExpr,
mathml_dom::MathMLCiElement);
return (aCISub != NULL);
}

-iface::cellml_api::CellMLComponent*
-GetRealComponent(iface::cellml_api::CellMLElement* in)
-{
- DECLARE_QUERY_INTERFACE_OBJREF(x, in, cellml_api::CellMLComponent);
- if (x == NULL)
- throw CodeGenerationError(L"\"in\" not a component (bug)");
- while (true)
- {
- DECLARE_QUERY_INTERFACE_OBJREF(imp, x, cellml_api::ImportComponent);
- if (imp == NULL)
- {
- x->add_ref();
- return x;
- }
- RETURN_INTO_OBJREF(cee, iface::cellml_api::CellMLElement,
- imp->parentElement());
- DECLARE_QUERY_INTERFACE_OBJREF(cei, cee, cellml_api::CellMLImport);
- if (cei == NULL)
- throw CodeGenerationError(L"Parent of import component not import.");
- RETURN_INTO_OBJREF(im, iface::cellml_api::Model, cei->importedModel());
- RETURN_INTO_OBJREF(cs, iface::cellml_api::CellMLComponentSet,
- im->modelComponents());
- RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
- cs->iterateComponents());
- RETURN_INTO_WSTRING(tn, imp->componentRef());
- while (true)
- {
- x = already_AddRefd<iface::cellml_api::CellMLComponent>
- (ci->nextComponent());
- if (x == NULL)
- throw CodeGenerationError(L"Imported component missing");
- RETURN_INTO_WSTRING(n, x->name());
- if (n == tn)
- break;
- }
- }
-}
-
double
CodeGenerationState::GetConversion
(
iface::cellml_api::CellMLVariable* vfrom,
iface::cellml_api::CellMLVariable* vto,
double& offset
)
{
Index: tests/CheckCodeGenerator
===================================================================
--- tests/CheckCodeGenerator (revision 1013)
+++ tests/CheckCodeGenerator (revision 1014)
@@ -39,10 +39,11 @@ function runtest()
rm -f $TEMPFILE
}

runtest cellml_simple_test
runtest modified_parabola
runtest underconstrained_1
runtest overconstrained_1
runtest newton_raphson_parabola
+runtest import_eqn

exit 0
Index: tests/test_xml/imported_eqn.xml
===================================================================
--- tests/test_xml/imported_eqn.xml (revision 0)
+++ tests/test_xml/imported_eqn.xml (revision 1014)
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<model
+ name="sin"
+ cmeta:id="sin"
+ xmlns="http://www.cellml.org/cellml/1.1#";
+ xmlns:cellml="http://www.cellml.org/cellml/1.1#";
+ xmlns:cmeta="http://www.cellml.org/metadata/1.0#";>
+ <rdf:RDF
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+ xmlns:cmeta="http://www.cellml.org/metadata/1.0#";
+ xmlns:bqs="http://www.cellml.org/bqs/1.0#";
+ xmlns:dc="http://purl.org/dc/elements/1.1/";
+ xmlns:dcterms="http://purl.org/dc/terms/";
+ xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#";
+ xmlns:cs="http://www.cellml.org/metadata/simulation/1.0#";
+ xmlns:cg="http://www.cellml.org/metadata/graphs/1.0#";>
+ <rdf:Description rdf:about="">
+ <dc:creator rdf:parseType="Resource">
+ <vCard:N rdf:parseType="Resource">
+ <vCard:Family>Nickerson</vCard:Family>
+ <vCard:Given>David</vCard:Given>
+ </vCard:N>
+ <vCard:EMAIL rdf:parseType="Resource">
+ <rdf:value>david.nickerson at nus.edu.sg</rdf:value>
+ <rdf:type rdf:resource="http://imc.org/vCard/3.0#internet"; />
+ </vCard:EMAIL>
+ <vCard:ORG rdf:parseType="Resource">
+ <vCard:Orgname>National University of Singapore</vCard:Orgname>
+ <vCard:Orgunit>Division of Bioengineering</vCard:Orgunit>
+ </vCard:ORG>
+ </dc:creator>
+ <dcterms:created rdf:parseType="Resource">
+ <dcterms:W3CDTF>2006-12-21</dcterms:W3CDTF>
+ </dcterms:created>
+ </rdf:Description>
+ <rdf:Description rdf:about="#sin">
+ <dc:title>
+ Simple sine model..
+ </dc:title>
+ <cmeta:comment rdf:parseType="Resource">
+ <rdf:value>
+ A very simple model.
+ </rdf:value>
+ <dc:creator rdf:parseType="Resource">
+ <vCard:FN>David Nickerson</vCard:FN>
+ </dc:creator>
+ </cmeta:comment>
+ </rdf:Description>
+ </rdf:RDF>
+
+ <component name="actual_sin" cmeta:id="actual_sin">
+ <variable name="x" units="dimensionless" public_interface="in"
private_interface="out"/>
+ <variable cmeta:id="actual_sin" name="sin" units="dimensionless"
public_interface="out" private_interface="out"/>
+ <math cmeta:id="sin_calculation"
xmlns="http://www.w3.org/1998/Math/MathML";>
+ <apply id="actual_sin"><eq/>
+ <ci>sin</ci>
+ <apply><sin/>
+ <ci>x</ci>
+ </apply>
+ </apply>
+ </math>
+ </component>
+
+</model>
Index: tests/test_xml/import_eqn.xml
===================================================================
--- tests/test_xml/import_eqn.xml (revision 0)
+++ tests/test_xml/import_eqn.xml (revision 1014)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<model
+ name="sin_approximations_import"
+ cmeta:id="sin_approximations_import"
+ xmlns="http://www.cellml.org/cellml/1.1#";
+ xmlns:cellml="http://www.cellml.org/cellml/1.1#";
+ xmlns:cmeta="http://www.cellml.org/metadata/1.0#";
+ xmlns:xlink="http://www.w3.org/1999/xlink";>
+
+ <import xlink:href="imported_eqn.xml">
+ <component name="actual_sin" component_ref="actual_sin"/>
+ </import>
+
+ <component name="main" cmeta:id="main">
+ <variable cmeta:id="x" name="x" initial_value="0"
units="dimensionless" public_interface="out" private_interface="out"/>
+ <variable cmeta:id="sin" name="sin1" units="dimensionless"
public_interface="out" private_interface="in"/>
+ </component>
+
+ <group>
+ <relationship_ref relationship="encapsulation"/>
+ <component_ref component="main">
+ <component_ref component="actual_sin"/>
+ </component_ref>
+ </group>
+
+ <connection>
+ <map_components component_1="actual_sin" component_2="main"/>
+ <map_variables variable_1="sin" variable_2="sin1"/>
+ <map_variables variable_1="x" variable_2="x"/>
+ </connection>
+
+</model>
Index: tests/test_expected/import_eqn.c
===================================================================
--- tests/test_expected/import_eqn.c (revision 0)
+++ tests/test_expected/import_eqn.c (revision 1014)
@@ -0,0 +1,32 @@
+/* Model is correctly constrained.
+ * No equations needed Newton-Raphson evaluation.
+ * The main variable array needs 1 entries.
+ * The rate array needs 0 entries.
+ * The constant array needs 1 entries.
+ * The bound array needs 0 entries.
+ * Variable storage is as follows:
+ * * Variable sin in component actual_sin
+ * * * Variable type: computed once
+ * * * Variable index: 0
+ * * * Has differential: false
+ * * Variable x in component main
+ * * * Variable type: constant
+ * * * Variable index: 0
+ * * * Has differential: false
+ */
+void SetupFixedConstants(double* CONSTANTS)
+{
+CONSTANTS[0] = 0;
+}
+void SetupComputedConstants(double* CONSTANTS, double* VARIABLES)
+{
+VARIABLES[0] = sin(CONSTANTS[0]);
+}
+void ComputeRates(double* BOUND, double* RATES, double* CONSTANTS,
double* VARIABLES)
+{
+}
+void ComputeVariables(double* BOUND, double* RATES, double* CONSTANTS,
double* VARIABLES)
+{
+#ifndef VARIABLES_FOR_RATES_ONLY
+#endif
+}





Archive powered by MHonArc 2.6.18.

Top of page