Aufgrund einer Wartung wird GitLab am 21.09. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 21.09. between 8:00 and 9:00 am.

Commit d9b7d526 authored by Jan Philipp Haller's avatar Jan Philipp Haller
Browse files

Added Code-Tests

parent 276e91c2
Pipeline #445299 failed with stage
in 2 minutes and 33 seconds
......@@ -64,7 +64,15 @@ public class Problem {
public void setId(int id) {
this.id = id;
if (id <= 0) {
this.id = this.hashCode();
//builtin hashcode introduces problems for code-testing
// (each java execution may yield a different value)
//this.id = this.hashCode();
String objVarName = getObjectiveValueVariable().getName();
this.id=0;
int arr[] = objVarName.chars().toArray();
for (int i = 0; i<arr.length;i++){
this.id += arr[i] + i * 256;
}
}
}
......
......@@ -30,12 +30,13 @@ public class ProblemAssignmentHandler {
}
public void getProblemFromSymbol(Problem problem, MathOptimizationStatementSymbol symbol) {
problem.setId(symbol.getExpressionID());
problem.setOptimizationProblemType(symbol.getOptimizationType());
// assign all properties
setOptimizationVariableFromSymbol(problem, symbol);
setObjectiveFunctionFromSymbol(problem, symbol);
setConstraintsFromSymbol(problem, symbol);
problem.setId(symbol.getExpressionID());
}
private void setOptimizationVariableFromSymbol(Problem p, MathOptimizationStatementSymbol symbol) {
......
......@@ -15,6 +15,7 @@ import de.monticore.lang.mathopt._symboltable.MathOptimizationConditionSymbol;
import de.monticore.lang.mathopt._symboltable.visitor.MathOptExpressionSymbolVisitor;
import de.monticore.lang.monticar.generator.Variable;
import de.monticore.lang.monticar.generator.cpp.EMAMBluePrintCPP;
import de.monticore.lang.monticar.generator.cpp.converter.ExecuteMethodGenerator;
import de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.problem.Problem;
import de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.solver.template.SolverViewModel;
......@@ -399,10 +400,13 @@ public class IpoptViewModel extends SolverViewModel {
}
public String getRawObjectiveFunction() {
MathExpressionSymbol symbol = getObjectiveFunction();
return symbol.getTextualRepresentation();
return ExecuteMethodGenerator.generateExecuteCode(symbol, new ArrayList<>());
}
public String listClassesInScope(){
String result = "";
if(!getIndependentVariables().isEmpty()) {
......@@ -677,8 +681,7 @@ public class IpoptViewModel extends SolverViewModel {
} else {
String leftside = "fg[ 1 +" + getIpoptConstraintRef(nr) + " ] ";
//String rightside = getIpoptTextualRepresentation(((MathOptimizationConditionSymbol) constraint).getRight(), "vars", 0);
String rightside = ((MathOptimizationConditionSymbol) constraint).getRight().getTextualRepresentation();
String rightside = ExecuteMethodGenerator.generateExecuteCode(((MathOptimizationConditionSymbol) constraint).getRight(), new ArrayList<>());
result = leftside + " = " + rightside;
}
......
......@@ -31,7 +31,8 @@ public class MathDimensionCalculatorHelper {
if (MathDimensionCalculator.getMatrixRows(realRightExpression, precedingExpressions) == 1) {
result = MathDimensionCalculator.getMatrixColumns(realLeftExpression, precedingExpressions);
} else {
result = MathDimensionCalculator.getMatrixColumns(realLeftExpression, precedingExpressions);
//orig: result = MathDimensionCalculator.getMatrixColumns(realLeftExpression, precedingExpressions);
result = MathDimensionCalculator.getMatrixColumns(realRightExpression, precedingExpressions);
}
return result;
}
......
......@@ -347,10 +347,14 @@ public class MathMatrixMultiplicationOrder implements MathOptimizationRule {
int n = dims.length - 1;
int[][] m = new int[n][n];
int[][] s = new int[n][n];
//orig
dims[0] = MathDimensionCalculator.getMatrixColumns(mathExpressionSymbols.get(0), new ArrayList<MathExpressionSymbol>());
dims[0] = MathDimensionCalculator.getMatrixRows(mathExpressionSymbols.get(0), new ArrayList<MathExpressionSymbol>());
Log.info(dims[0] + mathExpressionSymbols.get(0).getTextualRepresentation(), "most effi");
for (int i = 1; i <= mathExpressionSymbols.size(); ++i) {
//orig
dims[i] = MathDimensionCalculator.getMatrixRows(mathExpressionSymbols.get(i - 1), new ArrayList<MathExpressionSymbol>());
dims[i] = MathDimensionCalculator.getMatrixColumns(mathExpressionSymbols.get(i - 1), new ArrayList<MathExpressionSymbol>());
Log.info(dims[i] + mathExpressionSymbols.get(i - 1).getTextualRepresentation(), "most effi");
}
......
......@@ -126,7 +126,8 @@ public class MathOptimizer {
MathExpressionSymbol realRightExpressionSymbol = getCurrentAssignment(mathArithmeticExpressionSymbol.getRightExpression().getRealMathExpressionSymbol(), precedingExpressions);
long previousOperations = calculatePreviousOperations(realLeftExpressionSymbol, realRightExpressionSymbol, precedingExpressions);
return previousOperations + MathDimensionCalculator.getMatrixColumns(realLeftExpressionSymbol, precedingExpressions) * MathDimensionCalculator.getMatrixRows(realRightExpressionSymbol, precedingExpressions);
//orig return previousOperations + MathDimensionCalculator.getMatrixColumns(realLeftExpressionSymbol, precedingExpressions) * MathDimensionCalculator.getMatrixRows(realRightExpressionSymbol, precedingExpressions);
return previousOperations + MathDimensionCalculator.getMatrixRows(realLeftExpressionSymbol, precedingExpressions) * MathDimensionCalculator.getMatrixColumns(realRightExpressionSymbol, precedingExpressions);
}
......
......@@ -117,7 +117,7 @@ public class BasicGenerationArmadilloTest extends AbstractSymtabTest {
testFilesAreEqual(files, restPath);
}
@Ignore
@Test
public void testMathUnitBothOptimizations() throws IOException {
ThreadingOptimizer.resetID();
......
......@@ -5,13 +5,13 @@ package de.monticore.lang.monticar.generator.mathopt;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.AbstractSymtabTest;
import de.monticore.lang.monticar.generator.cpp.GeneratorCPP;
import de.monticore.lang.monticar.generator.cpp.GeneratorCppCli;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertNotNull;
......@@ -26,13 +26,30 @@ public class GeneratorEMAMOpt2CPPTest extends AbstractSymtabTest {
/**
* helper method to generate optimization models in CPP code
*/
protected static List<File> getIpoptGeneratedFiles(File folder){
List<File> files = new LinkedList<>();
File dirContents[] = folder.listFiles();
for (File f : dirContents){
if(f.getName().contains("CallIpopt")) {
files.add(f);
}
}
return files;
}
protected static List<File> doGenerateOptimizationModel(String modelName) throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources/mathopt");
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources/");
EMAComponentInstanceSymbol componentSymbol = symtab.<EMAComponentInstanceSymbol>resolve(String.format("de.rwth.monticar.optimization.%s", modelName), EMAComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentSymbol);
GeneratorCPP generator = new GeneratorCPP();
generator.setGenerationTargetPath("./target/generated-sources-cpp/mathopt/generator/" + modelName);
List<File> files = generator.generateFiles(symtab, componentSymbol);
File containingDir;
if(!files.isEmpty()) {
containingDir = files.get(0).getParentFile();
files.addAll(getIpoptGeneratedFiles(containingDir));
}
return files;
}
......@@ -43,27 +60,40 @@ public class GeneratorEMAMOpt2CPPTest extends AbstractSymtabTest {
GeneratorCPP generator = new GeneratorCPP();
generator.setGenerationTargetPath("./target/generated-sources-cpp/mathopt/generator/" + modelName);
List<File> files = generator.generateFiles(symtab, componentSymbol);
File containingDir;
if(!files.isEmpty()) {
containingDir = files.get(0).getParentFile();
files.addAll(getIpoptGeneratedFiles(containingDir));
}
return files;
}
@Test
public void testMPCImplementation() throws IOException {
List<File> files = doGenerateMathOptModel("mpcautopilot.torcsWrapper");
String restPath = "mathopt/MPCAutopilot/";
testFilesAreEqual(files, restPath);
}
@Test
public void testQuadraticOptImplementation() throws IOException {
List<File> files = doGenerateOptimizationModel("quadraticOpt");
String restPath = "mathopt/QuadraticOpt/";
testFilesAreEqual(files, restPath);
}
/**
* Simple quadratic problem min x^2-2x+1 s.t. x >= 0
*/
@Test
public void testScalarMinimizationTest() throws IOException {
List<File> files = doGenerateOptimizationModel("scalarMinimizationTest");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
}
@Test
public void testMPCImplementation() throws IOException {
List<File> files = doGenerateMathOptModel("mpcautopilot.torcsWrapper");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
String restPath = "mathopt/ScalarMinimization/";
testFilesAreEqual(files, restPath);
}
/**
......@@ -72,9 +102,8 @@ public class GeneratorEMAMOpt2CPPTest extends AbstractSymtabTest {
@Test
public void testScalarMaximizationTest() throws IOException {
List<File> files = doGenerateOptimizationModel("scalarMaximizationTest");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
String restPath = "mathopt/ScalarMaximization/";
testFilesAreEqual(files, restPath);
}
/**
......@@ -88,9 +117,8 @@ public class GeneratorEMAMOpt2CPPTest extends AbstractSymtabTest {
@Test
public void testStandardIpoptOptimizationTest() throws IOException {
List<File> files = doGenerateOptimizationModel("hS71");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
String restPath = "mathopt/HS71/";
testFilesAreEqual(files, restPath);
}
/**
......@@ -100,21 +128,8 @@ public class GeneratorEMAMOpt2CPPTest extends AbstractSymtabTest {
@Test
public void testLPOptimizationTest() throws IOException {
List<File> files = doGenerateOptimizationModel("transportationProblem");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
}
/**
* test loops in conditions
*/
@Ignore
@Test
public void testForLoopConditions() throws IOException {
List<File> files = doGenerateOptimizationModel("forLoopConditionsTest");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
String restPath = "mathopt/TransportationProblem/";
testFilesAreEqual(files, restPath);
}
/**
......@@ -123,51 +138,50 @@ public class GeneratorEMAMOpt2CPPTest extends AbstractSymtabTest {
@Test
public void testBoundedConditions() throws IOException {
List<File> files = doGenerateOptimizationModel("boundedConditionsTest");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
}
/**
* test models which use a already declared optimization variable
*/
@Ignore
@Test
public void existingOptimizationVariable() throws IOException {
List<File> files = doGenerateOptimizationModel("existingOptimizationVariableTest");
// TODO: create reference solution
// String restPath = "testMath/optimizationSolver/";
// testFilesAreEqual(files, restPath);
String restPath = "mathopt/BoundedConditions/";
testFilesAreEqual(files, restPath);
}
@Test
public void matrixSumMinimization1Test() throws IOException {
List<File> files = doGenerateOptimizationModel("matrixSumMinimizationTest1");
String restPath = "mathopt/MatrixSumMinimization1/";
testFilesAreEqual(files, restPath);
}
@Test
public void matrixSumMinimization2Test() throws IOException {
List<File> files = doGenerateOptimizationModel("matrixSumMinimizationTest2");
String restPath = "mathopt/MatrixSumMinimization2/";
testFilesAreEqual(files, restPath);
}
@Test
public void constMatrixSumMinimizationTest() throws IOException {
List<File> files = doGenerateOptimizationModel("constMatrixSumMinimizationTest");
String restPath = "mathopt/ConstMatrixSumMinimization/";
testFilesAreEqual(files, restPath);
}
@Test
public void colRowMinTest() throws IOException {
List<File> files = doGenerateOptimizationModel("colRowMinTest");
String restPath = "mathopt/ColRowMin/";
testFilesAreEqual(files, restPath);
}
@Test
public void scalarMultMinTest() throws IOException {
List<File> files = doGenerateOptimizationModel("scalarMultMinTest");
String restPath = "mathopt/ScalarMultMin/";
testFilesAreEqual(files, restPath);
}
@Test
public void matrixTransposeMinimizationTest() throws IOException {
List<File> files = doGenerateOptimizationModel("matrixTransposeMinimizationTest");
String restPath = "mathopt/MatrixTransposeMinimization/";
testFilesAreEqual(files, restPath);
}
}
......@@ -12,6 +12,7 @@ component MatrixModifier{
implementation Math{
//(mat1*(mat2*mat3))*(mat4*mat5);
Q^{1000, 1000} h1 = mat1 * mat2; // 100 x 100 mit 10 k Ops
Q^{1000, 10000} h2 = mat3 * mat4; // 100 x 1000 mit 100k Ops
Q^{1000, 10000} h3 = h1 * h2; // 100 x 1000 mit 1M Ops
......
......@@ -24,10 +24,8 @@ matOut=mat(1000,10000);
}
void execute()
{
mat h1 = mat1*mat2;
mat h2 = mat3*mat4;
mat h3 = h1*h2;
matOut = h3*mat5;
matOut = (mat1*(mat2*mat3))*(mat4*mat5);
}
};
#endif
\ No newline at end of file
#endif
/* (c) https://github.com/MontiCore/monticore */
#ifndef MACMAKETEST_ADMAT_H
#define MACMAKETEST_ADMAT_H
#include<armadillo>
#include<cppad/ipopt/solve.hpp>
using namespace arma;
typedef CppAD::AD<double> adouble;
namespace std {
double abs(const adouble &ad) {
return abs(Value(ad));
}
}
class ADMat : public field<adouble> {
public:
// constructors
inline explicit ADMat(const uword n_elem_in) : field<adouble>(n_elem_in) {};
inline explicit ADMat(const uword n_rows_in, const uword n_cols_in) : field<adouble>(n_rows_in, n_cols_in) {};
inline explicit ADMat(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in) : field<adouble>(
n_rows_in, n_cols_in, n_slices_in) {};
ADMat(field<adouble> field) : field<adouble>(field) {};
ADMat(subview_field<adouble> field) : field<adouble>(field) {};
// arithematic binary operators with matrices
inline ADMat operator+(const ADMat &matrix) {
assert(this->n_rows == matrix.n_rows);
assert(this->n_cols == matrix.n_cols);
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) + matrix[i];
}
return res;
};
inline ADMat operator+(const mat &matrix) {
assert(this->size() == matrix.size());
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) + matrix[i];
}
return res;
};
inline ADMat operator-(const ADMat &matrix) {
assert(this->n_rows == matrix.n_rows);
assert(this->n_cols == matrix.n_cols);
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) - matrix[i];
}
return res;
};
inline ADMat operator-(const mat &matrix) {
assert(this->size() == matrix.size());
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) - matrix[i];
}
return res;
};
friend class arma::subview_field<adouble>;;
inline ADMat operator*(const ADMat &matrix) {
assert(n_cols == matrix.n_rows);
//assert(n_rows == matrix.n_cols);
ADMat res = ADMat(n_rows, matrix.n_cols);
res.fill(0);
for (int i = 0; i < n_rows; i++) {
for (int j = 0; j < matrix.n_cols; j++) {
for (int k = 0; k < n_cols; k++) {
res[i, j] += at(i, k) * matrix[k, j];
}
}
}
return res;
};
inline ADMat operator*(const mat &matrix) {
assert(n_cols == matrix.n_rows);
//assert(n_rows == matrix.n_cols);
ADMat res = ADMat(n_rows, matrix.n_cols);
res.fill(0);
for (int i = 0; i < n_rows; i++) {
for (int j = 0; j < matrix.n_cols; j++) {
for (int k = 0; k < n_cols; k++) {
res[i, j] += at(i, k) * matrix[k, j];
}
}
}
return res;
};
inline ADMat operator%(const field &matrix) {
assert(this->size() == matrix.size());
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) * matrix[i];
}
return res;
};
inline friend ADMat operator%(const mat &left, const ADMat &right) {
assert(left.size() == right.size());
ADMat res = ADMat(right);
for (int i = 0; i < right.size(); i++) {
res[i] = left[i] * right[i];
}
return res;
};
// arithematic binary operators with double
inline ADMat operator+(const double &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) + value;
}
return res;
};
inline ADMat operator-(const double &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) - value;
}
return res;
};
inline ADMat operator*(const double &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) * value;
}
return res;
};
inline ADMat operator*(const adouble &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) * value;
}
return res;
};
inline ADMat operator/(const double &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) / value;
}
return res;
};
// arithematic binary operators with int
inline ADMat operator+(const int &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) + value;
}
return res;
};
inline ADMat operator-(const int &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) - value;
}
return res;
};
inline ADMat operator*(const int &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) * value;
}
return res;
};
inline ADMat operator/(const int &value) {
ADMat res = ADMat(*this);
for (int i = 0; i < size(); i++) {
res[i] = this->at(i) / value;
}
return res;
};
// functions
friend adouble accu(const ADMat &value) {
adouble res = 0;
for (int i = 0; i < value.size(); i++) {
res += value[i];
}
return res;
};