Commit 71b9df35 authored by Jean Meurice's avatar Jean Meurice

Merge branch 'master' of...

Merge branch 'master' of https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAM2Cpp into hardware-emulator
parents 0b59ced2 7bfc64ed
Pipeline #119696 passed with stages
in 31 minutes
......@@ -32,7 +32,6 @@ g++ -std=c++11 ^
-I"%ARMADILLO_HOME%\include" ^
-L"%HOME%\lib\win" ^
-o "%2\TestsForCurrentModel.exe" ^
"%ARMADILLO_HOME%\include\catch_tests_main.o" ^
"%1/test/tests_main.cpp" ^
-include %ARMADILLO_HOME%\include\armadillo.h ^
-include %ARMADILLO_HOME%\include\armadillo ^
-DARMA_DONT_USE_WRAPPER -lgdi32 -lopenblas -llibarpack-2
......@@ -34,7 +34,6 @@ g++ -std=c++11 \
-I"${ARMADILLO_HOME}/include" \
-L"${HOME}/lib/linux" \
-o "${2}/TestsForCurrentModel" \
"${ARMADILLO_HOME}/include/catch_tests_main.cpp" \
"${1}/test/tests_main.cpp" \
-include "${ARMADILLO_HOME}/include/armadillo.h" \
-include "${ARMADILLO_HOME}/include/armadillo" \
-DARMA_DONT_USE_WRAPPER -lopenblas
\ No newline at end of file
......@@ -30,7 +30,7 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-math-generator</artifactId>
<version>0.1.5-SNAPSHOT</version>
<version>0.1.8-SNAPSHOT</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
......@@ -47,7 +47,7 @@
<!--<Embedded-MontiArc-Math.version>0.0.19-SNAPSHOT</Embedded-MontiArc-Math.version>-->
<!--<tagging.version>0.0.4</tagging.version>-->
<Embedded-MontiArc-Math.version>0.1.7-SNAPSHOT</Embedded-MontiArc-Math.version>
<Embedded-MontiArc-Math.version>0.1.9-SNAPSHOT</Embedded-MontiArc-Math.version>
<!-- .. Libraries .................................................. -->
<guava.version>18.0</guava.version>
......@@ -77,7 +77,6 @@
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
......
......@@ -32,7 +32,7 @@ import freemarker.template.TemplateExceptionHandler;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
......@@ -69,7 +69,7 @@ public class CMakeConfig {
private CMakeListsCPPViewModel cMakeListsViewModel = new CMakeListsCPPViewModel();
private HashSet<CMakeFindModule> moduleList = new HashSet<>();
private LinkedHashSet<CMakeFindModule> moduleList = new LinkedHashSet<>();
private List<String> cmakeCommandList = new ArrayList<>();
......
......@@ -23,7 +23,7 @@ package de.monticore.lang.monticar.generator.cmake;
import de.monticore.lang.monticar.generator.cpp.viewmodel.ViewModelBase;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
/**
......@@ -39,7 +39,7 @@ public class CMakeListsCPPViewModel extends ViewModelBase {
// fields
private String compName;
private HashSet<CMakeFindModule> moduleDependencies;
private LinkedHashSet<CMakeFindModule> moduleDependencies;
private List<String> cmakeCommandList = new ArrayList<>();
......@@ -55,11 +55,11 @@ public class CMakeListsCPPViewModel extends ViewModelBase {
this.compName = compName;
}
public HashSet<CMakeFindModule> getModuleDependencies() {
public LinkedHashSet<CMakeFindModule> getModuleDependencies() {
return moduleDependencies;
}
public void setModuleDependencies(HashSet<CMakeFindModule> moduleDependencies) {
public void setModuleDependencies(LinkedHashSet<CMakeFindModule> moduleDependencies) {
this.moduleDependencies = moduleDependencies;
}
......
......@@ -31,7 +31,7 @@ public class ArmadilloHelper {
public static FileContent getArmadilloHelperFileContent(boolean generateTests) {
FileContent fileContent = new FileContent();
fileContent.setFileName(fileName + ".h");
String fileContentString = generateTests ? ArmadilloHelperSource.armadilloHelperSourceCodeWithTests : ArmadilloHelperSource.armadilloHelperSourceCode;
String fileContentString = ArmadilloHelperSource.armadilloHelperSourceCode;
fileContent.setFileContent(fileContentString);
return fileContent;
......
......@@ -24,167 +24,11 @@ package de.monticore.lang.monticar.generator.cpp;
* @author Sascha Schneiders
*/
public class ArmadilloHelperSource {
public static String armadilloHelperSourceCodeWithTests = "#ifndef HELPERA_H\n" +
"#define HELPERA_H\n" +
"#include <iostream>\n" +
"#include \"armadillo.h\"\n" +
"#include <stdarg.h>\n" +
"#include <initializer_list>\n" +
"#include <fstream>\n" +
"using namespace arma;\n" +
"#ifndef _FILESTRING_CONVERSION___A\n" +
"#define _FILESTRING_CONVERSION___A\n" +
"#include \"armadillo.h\"\n" +
"using namespace arma;\n" +
"void toFileString(std::ofstream& myfile, mat A){\n" +
" myfile << \"[\";\n" +
" for (int i = 0; i < A.n_rows; i++){\n" +
" for (int j = 0; j < A.n_cols; j++){\n" +
" myfile << A(i,j);\n" +
" if(j + 1 < A.n_cols){\n" +
" myfile << \", \";\n" +
" }\n" +
" }\n" +
" if(i + 1 < A.n_rows){\n" +
" myfile << \";\";\n" +
" }\n" +
" }\n" +
" myfile << \"]\";\n" +
"}\n" +
"void toFileString(std::ofstream& myfile, double A){\n" +
" myfile << A;\n" +
"}\n" +
"void toFileString(std::ofstream& myfile, float A){\n" +
" myfile << A;\n" +
"}\n" +
"void toFileString(std::ofstream& myfile, int A){\n" +
" myfile << A;\n" +
"}\n" +
"void toFileString(std::ofstream& myfile, bool A){\n" +
" myfile << A;\n" +
"}\n" +
"bool Is_close(mat& X, mat& Y, double tol)\n" +
"{\n" +
" // abs returns a mat type then max checks columns and returns a row_vec\n" +
" // max used again will return the biggest element in the row_vec\n" +
" bool close(false);\n" +
" if(arma::max(arma::max(arma::abs(X-Y))) < tol)\n" +
" {\n" +
" close = true;\n" +
" }\n" +
" return close;\n" +
"}\n" +
"void rangeValueCheck(double A, double lower, double upper){\n" +
" REQUIRE( A >= lower );\n" +
" REQUIRE( A <= upper );\n" +
"}\n" +
"\n" +
"void rangeValueCheck(int A, double lower, double upper){\n" +
" REQUIRE( A >= lower );\n" +
" REQUIRE( A <= upper );\n" +
"}\n" +
"void rangeValueCheck(mat& A, mat& lower , mat& upper){\n" +
" REQUIRE(Is_close(A, lower, 0.0001));\n" +
" REQUIRE(Is_close(A, upper, 0.0001));\n" +
"}\n" +
"#endif\n" +
"class HelperA{\n" +
"public:\n" +
"static mat getEigenVectors(mat A){\n" +
"vec eigenValues;\n" +
"mat eigenVectors;\n" +
"eig_sym(eigenValues,eigenVectors,A);\n" +
"return eigenVectors;\n" +
"}\n" +
"static vec getEigenValues(mat A){\n" +
"vec eigenValues;\n" +
"mat eigenVectors;\n" +
"eig_sym(eigenValues,eigenVectors,A);\n" +
"return eigenValues;\n" +
"}\n" +
"\n" +
"static mat getKMeansClusters(mat A, int k){\n" +
"mat clusters;\n" +
"kmeans(clusters,A.t(),k,random_subset,20,true);\n" +
"/*printf(\"cluster centroid calculation done\\n\");\n" +
"std::ofstream myfile;\n" +
" myfile.open(\"data after cluster.txt\");\n" +
" myfile << A;\n" +
" myfile.close();\n" +
"\t \n" +
"\t std::ofstream myfile2;\n" +
" myfile2.open(\"cluster centroids.txt\");\n" +
" myfile2 << clusters;\n" +
" myfile2.close();*/\n" +
"mat indexedData=getKMeansClustersIndexData(A.t(), clusters);\n" +
"\n" +
"/*std::ofstream myfile3;\n" +
" myfile3.open(\"data after index.txt\");\n" +
" myfile3 << indexedData;\n" +
" myfile3.close();\n" +
"\t */\n" +
"return indexedData;\n" +
"}\n" +
"\n" +
"static mat getKMeansClustersIndexData(mat A, mat centroids){\n" +
"\tmat result=mat(A.n_cols, 1);\n" +
"\tfor(int i=0;i<A.n_cols;++i){\n" +
"\t\tresult(i, 0) = getIndexForClusterCentroids(A, i, centroids);\n" +
"\t}\n" +
"\treturn result;\n" +
"}\n" +
"\n" +
"static int getIndexForClusterCentroids(mat A, int colIndex, mat centroids){\n" +
"\tint index=1;\n" +
"\tdouble lowestDistance=getEuclideanDistance(A, colIndex, centroids, 0);\n" +
"\tfor(int i=1;i<centroids.n_cols;++i){\n" +
"\t\tdouble curDistance=getEuclideanDistance(A, colIndex, centroids, i);\n" +
"\t\tif(curDistance<lowestDistance){\n" +
"\t\t\tlowestDistance=curDistance;\n" +
"\t\t\tindex=i+1;\n" +
"\t\t}\n" +
"\t}\n" +
"\treturn index;\n" +
"}\n" +
"\n" +
"static double getEuclideanDistance(mat A, int colIndexA, mat B, int colIndexB){\n" +
"\tdouble distance=0;\n" +
"\tfor(int i=0;i<A.n_rows;++i){\n" +
"\t\tdouble elementA=A(i,colIndexA);\n" +
"\t\tdouble elementB=B(i,colIndexB);\n" +
"\t\tdouble diff=elementA-elementB;\n" +
"\t\tdistance+=diff*diff;\n" +
"\t}\n" +
"\treturn sqrt(distance);\n" +
"}\n" +
"\n" +
"static mat getSqrtMat(mat A){\n" +
" cx_mat result=sqrtmat(A);\n" +
" return real(result);\n" +
"}\n" +
"\n" +
"static mat getSqrtMatDiag(mat A){\n" +
"for(int i=0;i<A.n_rows;++i){\n" +
" double curVal = A(i,i);\n" +
" A(i,i) = sqrt(curVal);\n" +
"}\n" +
"return A;\n" +
"}\n" +
"\n" +
"static mat invertDiagMatrix(mat A){\n" +
"for(int i=0;i<A.n_rows;++i){\n" +
" double curVal = A(i,i);\n" +
" A(i,i) = 1/curVal;\n" +
"}\n" +
"return A;\n" +
"}\n" +
"};\n" +
"#endif\n";
public static String armadilloHelperSourceCode = "#ifndef HELPERA_H\n" +
"#define HELPERA_H\n" +
"#include <iostream>\n" +
"#include \"armadillo.h\"\n" +
"#include \"armadillo\"\n" +
"#include <stdarg.h>\n" +
"#include <initializer_list>\n" +
"#include <fstream>\n" +
......
......@@ -100,7 +100,7 @@ public class LanguageUnitCPP extends LanguageUnit {
resultString += "#include \"octave/oct.h\"\n";
alreadyGeneratedIncludes.add("octave/oct");
} else if (MathConverter.curBackend.getBackendName().equals("ArmadilloBackend")) {
resultString += "#include \"" + MathConverter.curBackend.getIncludeHeaderName() + ".h\"\n";
resultString += "#include \"" + MathConverter.curBackend.getIncludeHeaderName() + "\"\n";
alreadyGeneratedIncludes.add(MathConverter.curBackend.getIncludeHeaderName());
}
for (Variable v : bluePrint.getVariables()) {
......
......@@ -84,9 +84,10 @@ public class TestConverter {
public static String getDefaultContent(ComponentStreamUnitsSymbol symbol) {
String fileContentString = "";
String filePostfix = MathConverter.curBackend.getIncludeHeaderName().equals("armadillo") ? "" : ".h";
fileContentString += "#ifndef M_PI\n" +
"#define M_PI 3.14159265358979323846\n" +
"#endif\n" + "#include \"" + MathConverter.curBackend.getIncludeHeaderName() + ".h\"\n";
"#endif\n" + "#include \"" + MathConverter.curBackend.getIncludeHeaderName() + filePostfix + "\"\n";
if (MathConverter.curBackend.getBackendName().equals("OctaveBackend")) {
fileContentString += "#include \"Helper.h\"\n";
......
......@@ -105,7 +105,6 @@ public final class TestsGeneratorCPP {
if (!MathConverter.curBackend.getBackendName().equals(OctaveBackend.NAME))
isOctaveBackend = false;
files.add(new FileContent(AllTemplates.generateMainEntry(viewModelForMain, isOctaveBackend), TESTS_DIRECTORY_NAME + "/tests_main.cpp"));
files.add(getCatchLib());
}
//files.add(new FileContent(getTestedComponentsString(), TESTS_DIRECTORY_NAME + "/testedComponents.txt"));
if (generator.isCheckModelDir()) {
......@@ -139,6 +138,12 @@ public final class TestsGeneratorCPP {
cmake.addCMakeCommandEnd("target_link_libraries(" + compName + execuatablePostFix + " PUBLIC " + compName + ")");
}
cmake.addCMakeCommandEnd("set_target_properties(" + compName + execuatablePostFix + " PROPERTIES LINKER_LANGUAGE CXX)");
String executeTestTplt = "\n# execute tests\n" +
"add_custom_target(run_<name>_StreamTests ALL\n" +
" COMMAND <name>_StreamTests\n" +
" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})";
cmake.addCMakeCommandEnd(executeTestTplt.replace("<name>",compName));
}
private String getExistingComponentNames() {
......@@ -349,13 +354,6 @@ public final class TestsGeneratorCPP {
}
}
private static FileContent getCatchLib() {
return FileUtil.getResourceAsFile(
"/vendor/catch.hpp",
TESTS_DIRECTORY_NAME + "/catch.hpp"
);
}
private static String getFileName(ComponentStreamTestViewModel viewModel) {
return TESTS_DIRECTORY_NAME + "/" + viewModel.getFileNameWithExtension();
}
......
......@@ -40,7 +40,6 @@ public final class AllTemplates {
private static final Template COMPONENT_STREAM_TEST;
private static final Template TESTS_MAIN_ENTRY;
private static final Template TESTS_MAIN_ENTRY_ARMADILLO;
private static final Template STRUCT;
private static final Template ENUM;
private static final Template AUTOPILOT_ADAPTER_CPP;
......@@ -60,7 +59,6 @@ public final class AllTemplates {
try {
COMPONENT_STREAM_TEST = conf.getTemplate("/test/ComponentStreamTest2.ftl");
TESTS_MAIN_ENTRY = conf.getTemplate("/test/TestsMainEntry.ftl");
TESTS_MAIN_ENTRY_ARMADILLO = conf.getTemplate("/test/TestsMainEntryArmadillo.ftl");
STRUCT = conf.getTemplate("/type/Struct.ftl");
ENUM = conf.getTemplate("/type/Enum.ftl");
AUTOPILOT_ADAPTER_CPP = conf.getTemplate("/autopilotadapter/AutopilotAdapterCpp.ftl");
......@@ -83,10 +81,7 @@ public final class AllTemplates {
}
public static String generateMainEntry(TestsMainEntryViewModel viewModel, boolean backendOctave) {
if (backendOctave)
return generate(TESTS_MAIN_ENTRY, viewModel);
else
return generate(TESTS_MAIN_ENTRY_ARMADILLO, viewModel);
}
public static String generateStruct(StructViewModel viewModel) {
......
<#include "/Common.ftl">
#ifndef ${viewModel.fileNameWithoutExtension?upper_case}
#define ${viewModel.fileNameWithoutExtension?upper_case}
#include "catch.hpp"
#include "../${viewModel.componentName}.h"
<#list viewModel.streams as stream>
TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
${viewModel.componentName} component;
component.init();
<#list stream.checks as check>
<#list check.inputPortName2Value?keys as portName>
component.${portName} = ${check.inputPortName2Value[portName]};
</#list>
component.execute();
<#list check.outputPortName2Check?keys as outputPortName>
<@renderPortCheck outputPortName=outputPortName check=check.outputPortName2Check[outputPortName] />
</#list>
</#list>
std::cout << "${stream.name}: success\n";
}
</#list>
#endif
<#macro renderPortCheck outputPortName check>
<#assign portValue="component.${outputPortName}">
<#if helper.isBooleanOutputPortCheck(check)>
<#if helper.isTrueExpectedCheck(check)>
REQUIRE( ${portValue} );
<#else>
REQUIRE_FALSE( ${portValue} );
</#if>
<#elseif helper.isRangeOutputPortCheck(check)>
REQUIRE( ${portValue} >= ${check.lowerBound} );
REQUIRE( ${portValue} <= ${check.upperBound} );
</#if>
</#macro>
//created by ComponentStreamTest2.ftl
<#include "/Common.ftl">
#ifndef ${viewModel.fileNameWithoutExtension?upper_case}
#define ${viewModel.fileNameWithoutExtension?upper_case}
#include "catch.hpp"
//#include "catch.hpp"
#include "../${viewModel.componentName}.h"
#include <iostream>
#include <fstream>
#include <string>
/*void toFileString(std::ofstream& myfile, mat A){
namespace ${viewModel.fileNameWithoutExtension}{
void toFileString(std::ofstream& myfile, mat A){
myfile << "[";
for (int i = 0; i < A.n_rows; i++){
for (int j = 0; j < A.n_cols; j++){
......@@ -34,7 +38,8 @@ void toFileString(std::ofstream& myfile, int A){
void toFileString(std::ofstream& myfile, bool A){
myfile << A;
}
bool Is_close(mat& X, mat& Y, double tol)
bool isClose(mat& X, mat& Y, double tol)
{
// abs returns a mat type then max checks columns and returns a row_vec
// max used again will return the biggest element in the row_vec
......@@ -45,21 +50,60 @@ bool Is_close(mat& X, mat& Y, double tol)
}
return close;
}
int overallAssertions = 0;
int overallFailedAssertions = 0;
int assertions = 0;
int failedAssertions = 0;
void require_is_close(mat& A, mat& lower, double tol){
assertions++;
if(!isClose(A, lower, tol)){
std::cout << "Failed at: isClose(" << A << ", " << lower << ", " << tol << std::endl;
failedAssertions++;
}
}
void require_boolean(bool a){