Skip to content

Commit

Permalink
Unitary Tests
Browse files Browse the repository at this point in the history
MEKBAL committed Jun 20, 2024
1 parent 715d9f1 commit e76932f
Showing 13 changed files with 946 additions and 0 deletions.
74 changes: 74 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@

name: CI ADAPTER

on:
push:
branches: main
pull_request:
branches: [ "main" ]



jobs:
Linux:
runs-on: ubuntu-latest
steps:
- name: using the Checkout action
uses: actions/checkout@v1
- name: Get latest CMake
uses: lukka/get-cmake@latest
- name: Installing Jinja2
run: python -m pip install Jinja2
- name: Installing pytest
run: python -m pip install pytest
- name: Installing make
run: python -m pip install make
- name: apt
run: sudo apt-get -qq update; sudo apt-get install -y libc-dbg python3-numpy python3-matplotlib texlive-latex-extra texlive-fonts-recommended dvipng cm-super
- name: Install the requirements for building
run: |
sudo apt-get install -y build-essential g++ autoconf automake
- name: clone PENE
run: |
cd pene_files
git clone https://github.com/aneoconsulting/PENE.git
- name: clone Valgrind and Verrou
run: |
mkdir verrou_files/verrou_repo
cd verrou_files/verrou_repo
git clone --branch=VALGRIND_3_22_0 --single-branch git://sourceware.org/git/valgrind.git valgrind-3.22.0+verrou-dev
cd valgrind-3.22.0+verrou-dev
git clone https://github.com/edf-hpc/verrou.git verrou
cd verrou
checkout 39a16db31a4048311a602922cbf35b18ffc58b9d
cd ../
patch -p1 <verrou/valgrind.diff
- name: runing cmake for Verrou
run: |
mkdir build
cd build
cmake .. -DBUILD_FOR_VERROU=ON
- name: runing source for verrou
run: source verrou_files/verrou_repo/verrou_software/env.sh

- name: runing cmake for Verificarlo and PENE tools (Linux)
run: |
cd build
cmake .. -DBUILD_FOR_PENE=ON -DBUILD_FOR_VERIFICARLO=ON
- name: Building (Linux)
run : |
cd build
cmake --build .
- name: Testing (Linux)
run : |
cd Test
mkdir build
cd build
cmake ..
make
ctest -C Debug --output-o-failure
2 changes: 2 additions & 0 deletions Test/GenericConfigureFile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

configure_file(${INFILE} ${OUTFILE})
76 changes: 76 additions & 0 deletions Test/Test_binary/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@


cmake_minimum_required (VERSION 3.20)

project(Test_binary)

find_package(Python3 COMPONENTS Interpreter REQUIRED)

add_executable(test_verificarlo_bin executable.cpp)
add_executable(test_verrou_bin executable.cpp)

set_property(TARGET test_verrou_bin PROPERTY CXX_STANDARD 17)

set(PYTHON_SCRIPT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_binary.py)
get_filename_component(PARENT_DIR ${CMAKE_SOURCE_DIR} DIRECTORY)
get_filename_component(GRANDPARENT_DIR ${PARENT_DIR} DIRECTORY)
set(PIN_PATH ${PARENT_DIR}/pene_files/PENE/Pin/Linux/pin)
set(LIB_PATH ${PARENT_DIR}/pene_files/PENE/src/libpene.so)

# set(CMAKE_GENERICS_PATH "${CMAKE_SOURCE_DIR}")


set(new_back_verificarlo ${PARENT_DIR}/verificarlo_files/backends_so/libtarget_binary_back.so)

set(TOOL_PATH ${PARENT_DIR}/pene_files/PENE/cmake/tools)

add_custom_command(
#OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
TARGET test_verificarlo_bin
PRE_BUILD
COMMAND verificarlo-c++ ${CMAKE_CURRENT_SOURCE_DIR}/executable.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
COMMENT "Building verificarlo_exe"
)


add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_binary.py
COMMAND ${CMAKE_COMMAND}
-D INFILE=${CMAKE_CURRENT_SOURCE_DIR}/test_binary.py
-D OUTFILE=${CMAKE_CURRENT_BINARY_DIR}/test_binary.py
-D REPLACE_TESTS_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-D VERIFICARLO_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
-D BACKEND_VERIFICARLO=${new_back_verificarlo}
-D VERROU_EXECUTABLE=$<TARGET_FILE:test_verrou_bin>
-D LIB=${LIB_PATH}
-D PIN_EXECUTABLE=${PIN_PATH}
-P ${CMAKE_GENERICS_PATH}/GenericConfigureFile.cmake
DEPENDS
${CMAKE_GENERICS_PATH}/GenericConfigureFile.cmake
COMMENT "Configuring test_binary.py"
VERBATIM
)


set(TEST_SCRIPTS test_binary.py)

list(TRANSFORM TEST_SCRIPTS PREPEND ${CMAKE_CURRENT_BINARY_DIR}/)
add_custom_target(${PROJECT_NAME} ALL DEPENDS
${TEST_SCRIPTS}
${CMAKE_CURRENT_BINARY_DIR}/test_binary.py
)

enable_testing()

set(TEST_LIST test_binary)

foreach(test ${TEST_LIST})
add_test(NAME ${test}
COMMAND ${Python3_EXECUTABLE} -m pytest ${CMAKE_CURRENT_BINARY_DIR}/test_binary.py)
endforeach()

# add_test(NAME ${TEST_LIST}
# COMMAND ${Python3_EXECUTABLE} -m pytest ${CMAKE_CURRENT_BINARY_DIR}/test_result.py
# )

include_directories("../../pene_files/PENE/Pin/Linux")
include_directories("../../pene_files/PENE/src")
21 changes: 21 additions & 0 deletions Test/Test_binary/executable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@


#include <immintrin.h>
#include <iostream>
#include <string>
#include <iomanip>

int main(){

std::cout<< "This programme is used for tests the instrumentation of the programme with the three tools" << std::endl;

float z = 1.0;
float x = 0.0;

float sum = z+x;

std::cout << "Result :" << std::endl;
std::cout << std::setprecision(23) << std::hexfloat << sum << std::endl;

return 0;
}
88 changes: 88 additions & 0 deletions Test/Test_binary/test_binary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@



import pytest
import re
import subprocess
from pathlib import Path
import sys
import os

class Test_front():

counterModes = ["0", "1", "2"]

precisions = ["float", "double"]
operations = ["add", "sub", "mul", "div", "fma"]
modes = ["scalar", "simd"]


verificarlo = "@VERIFICARLO_EXECUTABLE@"
verrou = "@VERROU_EXECUTABLE@"
pin = "@PIN_EXECUTABLE@"
lib = "@LIB@"
new_back = "@BACKEND_VERIFICARLO@"

expected = r"0x1\.000002p\+0"


def launch_PENE(self):

cmdLine = ("{pin} -t {tool} -fp-replace 5 -counter_mode 1 -- {executable}").format(pin = self.pin,
tool = self.lib,
executable = self.verrou,
)


out = subprocess.run(cmdLine.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output = out.stdout.decode('utf-8')
print(output)

p = r"\A=*[\r\n]{1,2}\s*?PENE: Pin Enabled Numerical Exploration\s*?[\r\n]{1,2}=*[\r\n]{1,2}"
assert re.search(p, output) is not None, f"failed to launch instrumentation with PENE"

return output


def launch_verificarlo(self):

command = ("VFC_BACKENDS=\"{back} --count-op\" {verificarlo}").format(back=self.new_back,
verificarlo=self.verificarlo,
)

process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output, error = process.communicate()

output_str = output.decode("utf-8")
print(output_str)

p = r"loaded backend"
assert re.search(p, output_str) is not None, f"failed to launch instrumentation with Verificarlo"

return output_str

def checkout_binary(self, pattern, expected):

p = re.compile(expected)

res = p.search(pattern)
assert res, "The result is false"


def test_binary(self):

output=self.launch_PENE()
self.checkout_binary(output, self.expected)

output=self.launch_verificarlo()
self.checkout_binary(output, self.expected)


if __name__ == "__main__":
pytest.main()




70 changes: 70 additions & 0 deletions Test/Test_counter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@



cmake_minimum_required (VERSION 3.20)

project(Test_Counter)

find_package(Python3 COMPONENTS Interpreter REQUIRED)

add_executable(test_verificarlo Test_Frontend_executable.cpp)
add_executable(test_verrou Test_Frontend_executable.cpp)

set_property(TARGET test_verrou PROPERTY CXX_STANDARD 17)

set(PYTHON_SCRIPT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_counter.py)
get_filename_component(PARENT_DIR ${CMAKE_SOURCE_DIR} DIRECTORY)
get_filename_component(GRANDPARENT_DIR ${PARENT_DIR} DIRECTORY)
get_filename_component(GRAND_GRAND_DIR ${GRANDPARENT_DIR} DIRECTORY)
set(PIN_PATH ${PARENT_DIR}/pene_files/PENE/Pin/Linux/pin)
set(LIB_PATH ${PARENT_DIR}/pene_files/PENE/src/libpene.so)

# set(CMAKE_GENERICS_PATH "${CMAKE_SOURCE_DIR}")

set(new_back_verificarlo ${PARENT_DIR}/verificarlo_files/backends_so/libtarget_new_back.so)

set(TOOL_PATH ${PARENT_DIR}/pene_files/PENE/cmake/tools)

add_custom_command(
TARGET test_verificarlo
PRE_BUILD
COMMAND verificarlo-c++ ${CMAKE_CURRENT_SOURCE_DIR}/Test_Frontend_executable.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
COMMENT "Building verificarlo_exe"
)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_counter.py
COMMAND ${CMAKE_COMMAND}
-D INFILE=${CMAKE_CURRENT_SOURCE_DIR}/test_counter.py
-D OUTFILE=${CMAKE_CURRENT_BINARY_DIR}/test_counter.py
-D REPLACE_TESTS_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-D VERIFICARLO_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
-D BACKEND_VERIFICARLO=${new_back_verificarlo}
-D VERROU_EXECUTABLE=$<TARGET_FILE:test_verrou>
-D LIB=${LIB_PATH}
-D PIN_EXECUTABLE=${PIN_PATH}
-P ${CMAKE_GENERICS_PATH}/GenericConfigureFile.cmake
DEPENDS
${CMAKE_GENERICS_PATH}/GenericConfigureFile.cmake
COMMENT "Configuring test_replace.py"
VERBATIM
)


set(TEST_SCRIPTS test_counter.py)

list(TRANSFORM TEST_SCRIPTS PREPEND ${CMAKE_CURRENT_BINARY_DIR}/)
add_custom_target(${PROJECT_NAME} ALL DEPENDS
${TEST_SCRIPTS}
${CMAKE_CURRENT_BINARY_DIR}/test_counter.py
)

enable_testing()

set(TEST_LIST test_Nbr_Op)

add_test(NAME ${TEST_LIST}
COMMAND ${Python3_EXECUTABLE} -m pytest ${CMAKE_CURRENT_BINARY_DIR}/test_counter.py
)

include_directories("../../../pene_files/PENE/Pin/Linux")
include_directories("../../../pene_files/PENE/src")
39 changes: 39 additions & 0 deletions Test/Test_counter/Test_Frontend_executable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

#include <iostream>
#include <string>


int main(int argc, const char* argv[]){

std::cout<< "This programme is used for tests the instrumentation of the programme with the three tools" << std::endl;

std::string precision{ argv[1] };
std::string mode{ argv[3] };
std::string operation{ argv[2] };
auto nbr_loop = std::stoi(argv[4]);
auto a = std::stof(argv[5]);
auto b = std::stof(argv[6]);
auto acc = a;

std::cout << "acc =" << acc <<std::endl;

if(operation.compare("add")==0){
for(int i = 0; i < nbr_loop; i++){
acc = acc + b;
}
}
if(operation.compare("sub")==0){
for(int i = 0; i < nbr_loop; i++){
acc = acc - b;
}
}
if(operation.compare("mul")==0){
for(int i = 0; i < nbr_loop; i++){
acc = acc * b;
}
}

std::cout << "Result : " << acc << std::endl;

return 0;
}
183 changes: 183 additions & 0 deletions Test/Test_counter/test_counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@


import pytest
import re
import subprocess
import sys
import os

class Test_front():

# executable = "${EXECUTABLE}"
# tool = "${PINTOOL}"
# pin = "${PIN}"
# executable_verificarlo = "${EXECUTABLE2}"

counterModes = ["0", "1", "2"]

precisions = ["float", "double"]
operations = ["add", "sub", "mul", "div", "fma"]
modes = ["scalar", "simd"]

backend =["libinterflop_ieee.so", "libinterflop_mca.so", "libinterflop_mca_int.so", "libinterflop_bitmask.so", "libinterflop_cancellation.so", "libinterflop_vprec.so"]

verificarlo = "@VERIFICARLO_EXECUTABLE@"
verrou = "@VERROU_EXECUTABLE@"
pin = "@PIN_EXECUTABLE@"
lib = "@LIB@"

new_back = "@BACKEND_VERIFICARLO@"


def launch_PENE(self, prec, op, mode, nLoop, a, b):

cmdLine = ("{pin} -t {tool} -fp-replace 5 -counter_mode 1 -- {executable} {prec} {operation} {mode} {nLoop} {a} {b}").format(pin = self.pin,
tool = self.lib,
executable = self.verrou,
prec = prec,
operation = op,
mode = mode,
nLoop = nLoop,
a=a,
b=b)


out = subprocess.run(cmdLine.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output = out.stdout.decode('utf-8')
print("Output", output)

# p = r"\A=*[\r\n]{1,2}\s*?PENE: Pin Enabled Numerical Exploration\s*?[\r\n]{1,2}=*[\r\n]{1,2}"
p = r"Result : "
assert re.search(p, output) is not None, f"échec de lancement de commande de PENE"

return output

def launch_verrou(self, prec, op, mode, nLoop, a, b):

cmdLine = ("valgrind --tool=verrou --count-op=yes {verrou} {prec} {operation} {mode} {nLoop} {a} {b}").format(verrou = self.verrou,
prec = prec,
operation = op,
mode = mode,
nLoop = nLoop,
a=a,
b=b)
out = subprocess.run(cmdLine.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output = out.stdout.decode('utf-8')

p = r"Verrou, Check floating-point rounding errors"
assert re.search(p, output) is not None, f"échec de lancement de commande {cmdLine}"

return output


def launch_verificarlo(self, prec, op, mode, nLoop, a, b):

command = ("VFC_BACKENDS=\"{back} --count-op\" {verificalo} {prec} {operation} {mode} {nLoop} {a} {b}").format(back=self.new_back,
verificalo=self.verificarlo,
prec = prec,
operation = op,
mode = mode,
nLoop = nLoop,
a=a,
b=b)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output, error = process.communicate()

# Afficher la sortie standard
output_str = output.decode("utf-8")
print(output_str)

p = r"loaded backend"
assert re.search(p, output_str) is not None, f"échec de lancement de commande"

return output_str

def get_Nbrop_PENE(self, pattern, prec, op, mode):

regex = prec + r" *?" + op + r" *?" + mode + r" *?(?P<value>\d+)"
if op == "sub":
regex = prec + r" *?add *?" + mode + r" *?(?P<value>\d+)"

p=re.compile(regex)
assert re.search(p, pattern)
res=p.search(pattern)

return float(res.group("value"))

def get_Nbrop_verrou(self, pattern, op):

add_sub = 0
regex = op + r" *?(?P<value>\d+)"
if (op=="add" or op=="sub"):
if (op=="add"):
regex2 = "sub" + r" *?(?P<value2>\d+)"
p=re.compile(regex2)
assert re.search(p, pattern)
res=p.search(pattern)
else :
regex2 = "add" + r" *?(?P<value2>\d+)"
p=re.compile(regex2)
assert re.search(p, pattern)
res=p.search(pattern)

add_sub=float(res.group("value2"))

p=re.compile(regex)
assert re.search(p, pattern)
res=p.search(pattern)

return float(res.group("value"))+add_sub

def get_Nbrop_verificarlo(self, pattern, op):

add_sub=0
regex = r" *" + op + "=" +r"(?P<value>\d+)"
if(op=="add" or op=="sub"):
if (op=="add"):
regex2 = r" *" + "sub" + "=" +r"(?P<value2>\d+)"
p=re.compile(regex2)
assert re.search(p, pattern)
res=p.search(pattern)
else :
regex2 = r" *" + "add" + "=" +r"(?P<value2>\d+)"
p=re.compile(regex2)
assert re.search(p, pattern)
res=p.search(pattern)

add_sub=float(res.group("value2"))

p=re.compile(regex)
assert re.search(p, pattern)
res=p.search(pattern)

return float(res.group("value"))+add_sub


@pytest.mark.parametrize("prec, op, mode, nLoop, a, b", [
("float", "mul", "scalar", 2, 2, 2),
("float", "sub", "scalar", 10, 2, 2),
# ("double", "mul", "scalar", 10, 2, 2),
# ("double", "mul", "scalar", 10, 2, 2),
])
def test_Nbr_Op(self, prec, op, mode, nLoop, a, b):
output_PENE = self.launch_PENE(prec, op, mode, nLoop, a, b)
# output_verrou = self.launch_verrou( prec, op, mode, nLoop, a, b)
output_verificarlo = self.launch_verificarlo( prec, op, mode, nLoop, a, b)

nb_op_Pene=self.get_Nbrop_PENE(output_PENE, prec, op, mode)
# nb_op_Verrou=self.get_Nbrop_verrou(output_verrou, op)
nb_op_Vericarlo=self.get_Nbrop_verificarlo(output_verificarlo, op)

# assert nb_op_Verrou==nLoop, \
# f"Verrou have note the number of instruments required"
assert nb_op_Vericarlo==nLoop, \
f"Verificarlo have note the number of instruments required"
assert nb_op_Pene==nLoop, \
f"PENE have note the number of instruments required"


if __name__ == "__main__":
pytest.main()
74 changes: 74 additions & 0 deletions Test/Test_result/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@


cmake_minimum_required (VERSION 3.20)

project(Test_Result)

find_package(Python3 COMPONENTS Interpreter REQUIRED)

add_executable(test_verificarlo_res Test_Frontend_executable.cpp)
add_executable(test_verrou_res Test_Frontend_executable.cpp)

set_property(TARGET test_verrou_res PROPERTY CXX_STANDARD 17)

set(PYTHON_SCRIPT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_result.py)
get_filename_component(PARENT_DIR ${CMAKE_SOURCE_DIR} DIRECTORY)
get_filename_component(GRANDPARENT_DIR ${PARENT_DIR} DIRECTORY)
set(PIN_PATH ${PARENT_DIR}/pene_files/PENE/Pin/Linux/pin)
set(LIB_PATH ${PARENT_DIR}/pene_files/PENE/src/libpene.so)

# set(CMAKE_GENERICS_PATH "${CMAKE_SOURCE_DIR}")


set(new_back_verificarlo ${PARENT_DIR}/verificarlo_files/backends_so/libtarget_new_back.so)

set(TOOL_PATH ${PARENT_DIR}/pene_files/PENE/cmake/tools)

add_custom_command(
TARGET test_verificarlo_res
PRE_BUILD
COMMAND verificarlo-c++ ${CMAKE_CURRENT_SOURCE_DIR}/Test_Frontend_executable.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
COMMENT "Building verificarlo_exe"
)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_result.py
COMMAND ${CMAKE_COMMAND}
-D INFILE=${CMAKE_CURRENT_SOURCE_DIR}/test_result.py
-D OUTFILE=${CMAKE_CURRENT_BINARY_DIR}/test_result.py
-D REPLACE_TESTS_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-D VERIFICARLO_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/verificarlo_exe
-D BACKEND_VERIFICARLO=${new_back_verificarlo}
-D VERROU_EXECUTABLE=$<TARGET_FILE:test_verrou_res>
-D LIB=${LIB_PATH}
-D PIN_EXECUTABLE=${PIN_PATH}
-P ${CMAKE_GENERICS_PATH}/GenericConfigureFile.cmake
DEPENDS
${CMAKE_GENERICS_PATH}/GenericConfigureFile.cmake
COMMENT "Configuring test_result.py"
VERBATIM
)


set(TEST_SCRIPTS test_result.py)

list(TRANSFORM TEST_SCRIPTS PREPEND ${CMAKE_CURRENT_BINARY_DIR}/)
add_custom_target(${PROJECT_NAME} ALL DEPENDS
${TEST_SCRIPTS}
${CMAKE_CURRENT_BINARY_DIR}/test_result.py
)

enable_testing()

set(TEST_LIST test_result)

foreach(test ${TEST_LIST})
add_test(NAME ${test}
COMMAND ${Python3_EXECUTABLE} -m pytest ${CMAKE_CURRENT_BINARY_DIR}/test_result.py)
endforeach()

# add_test(NAME ${TEST_LIST}
# COMMAND ${Python3_EXECUTABLE} -m pytest ${CMAKE_CURRENT_BINARY_DIR}/test_result.py
# )

include_directories("../../pene_files/PENE/Pin/Linux")
include_directories("../../pene_files/PENE/src")
39 changes: 39 additions & 0 deletions Test/Test_result/Test_Frontend_executable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

#include <iostream>
#include <string>


int main(int argc, const char* argv[]){

std::cout<< "This programme is used for tests the instrumentation of the programme with the three tools" << std::endl;


std::string precision{ argv[1] };
std::string mode{ argv[3] };
std::string operation{ argv[2] };
int nbr_loop = std::stoi(argv[4]);
float a = std::stof(argv[5]);
float b = std::stof(argv[6]);
float acc = a;


if(operation.compare("add")==0){
for(int i = 0; i < nbr_loop; i++){
acc = acc + b;
}
}
if(operation.compare("sub")==0){
for(int i = 0; i < nbr_loop; i++){
acc = acc - b;
}
}
if(operation.compare("mul")==0){
for(int i = 0; i < nbr_loop; i++){
acc = acc * b;
}
}

std::cout << "Result : " << acc << std::endl;

return 0;
}
166 changes: 166 additions & 0 deletions Test/Test_result/test_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@


import pytest
import re
import subprocess
import sys
import os

class Test_front():

counterModes = ["0", "1", "2"]

precisions = ["float", "double"]
operations = ["add", "sub", "mul", "div", "fma"]
modes = ["scalar", "simd"]

backend =["libinterflop_ieee.so", "libinterflop_mca.so", "libinterflop_mca_int.so", "libinterflop_bitmask.so", "libinterflop_cancellation.so", "libinterflop_vprec.so"]

verificarlo = "@VERIFICARLO_EXECUTABLE@"
verrou = "@VERROU_EXECUTABLE@"
pin = "@PIN_EXECUTABLE@"
lib = "@LIB@"
new_back = "@BACKEND_VERIFICARLO@"


def launch_PENE(self, prec, op, mode, nLoop, a, b):

cmdLine = ("{pin} -t {tool} -fp-replace 5 -counter_mode 1 -- {executable} {prec} {operation} {mode} {nLoop} {a} {b}").format(pin = self.pin,
tool = self.lib,
executable = self.verrou,
prec = prec,
operation = op,
mode = mode,
nLoop = nLoop,
a=a,
b=b)


out = subprocess.run(cmdLine.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output = out.stdout.decode('utf-8')
print("Output", output)

p = r"\A=*[\r\n]{1,2}\s*?PENE: Pin Enabled Numerical Exploration\s*?[\r\n]{1,2}=*[\r\n]{1,2}"
assert re.search(p, output) is not None, f"failed to launch instrumentation with PENE"

return output

def launch_verrou(self, prec, op, mode, nLoop, a, b):

cmdLine = ("valgrind --tool=verrou --count-op=yes {verrou} {prec} {operation} {mode} {nLoop} {a} {b}").format(verrou = self.verrou,
prec = prec,
operation = op,
mode = mode,
nLoop = nLoop,
a=a,
b=b)
out = subprocess.run(cmdLine.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output = out.stdout.decode('utf-8')

p = r"Verrou, Check floating-point rounding errors"
assert re.search(p, output) is not None, f"failed to launch instrumentation with Verrou{cmdLine}"

return output


def launch_verificarlo(self, prec, op, mode, nLoop, a, b):

#command = f"VFC_BACKENDS=\"libinterflop_ieee.so --count-op\" {self.verificarlo}"

command = ("VFC_BACKENDS=\"{back} --count-op\" {verificalo} {prec} {operation} {mode} {nLoop} {a} {b}").format(back=self.new_back,
verificalo=self.verificarlo,
prec = prec,
operation = op,
mode = mode,
nLoop = nLoop,
a=a,
b=b)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output, error = process.communicate()

# Afficher la sortie standard
output_str = output.decode("utf-8")
print(output_str)

p = r"loaded backend"
assert re.search(p, output_str) is not None, f"failed to launch instrumentation with Verificarlo"

return output_str


def get_result_Pene(self, pattern):

regex = r"Result : (?P<value>-?\d+)"
p = re.compile(regex)
res = p.search(pattern)
assert res, "Le motif ne contient pas de résultat valide"
return float(res.group("value"))


def get_result_verrou(self, pattern):

regex = r"Result : (?P<value>\d+)"
p = re.compile(regex)
assert re.search(regex, pattern)
res = p.search(pattern)

return res


def get_result_verificarlo(self, pattern):

regex = r"Result : (?P<value>-?\d+)"
p = re.compile(regex)
res = p.search(pattern)
assert res, "Le motif ne contient pas de résultat valide"
return float(res.group("value"))

def expectResult(self, op, nLoop, a, b):
switcher = {
"add": lambda a1, b1:a1+b1,
"sub": lambda a1, b1:a1-b1,
"mul": lambda a1, b1:a1*b1,
"div": lambda a1, b1:a1/b1,
"fma": lambda a1, b1:a1+a1*b1,
"mix": lambda a1, b1:a1
}
for i in range(int(nLoop)):
a = switcher[op](a,b)
return a


def Check_result(self, prec, op, mode, nLoop, a, b):

output_PENE = self.launch_PENE(prec, op, mode, nLoop, a, b)
# output_verrou = self.launch_verrou(prec, op, mode, nLoop, a, b)
output_verificarlo = self.launch_verificarlo(prec, op, mode, nLoop, a, b)

result_pene=self.get_result_Pene(output_PENE)
result_verificarlo=self.get_result_verificarlo(output_verificarlo)
# result_verrou = self.get_result_verrou(output_verrou)
result_expected=self.expectResult(op, nLoop, a, b)

assert result_pene==result_expected, \
f"Pene have note the expected result"
assert result_verificarlo==result_expected, \
f"verificarlo have note the expected result"
# assert result_verrou==result_expected, \
# f"Verrou have note the expected result"



@pytest.mark.parametrize("prec, op, mode, nLoop, a, b", [
("float", "mul", "scalar", 2, 2, 2),
("float", "sub", "scalar", 10, 2, 2),
("double", "mul", "scalar", 10, 2, 2),
])
def test_result(self, prec, op, mode, nLoop, a, b):
self.Check_result(prec, op, mode, nLoop, a, b)



if __name__ == "__main__":
pytest.main()
65 changes: 65 additions & 0 deletions backend/binary_back/backend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@


add_float:

float temp = a + b;
union {
float f;
uint32_t u;
} converter;

converter.f = temp;
uint32_t ans = converter.u;

// ans |= 0x0000000f;
ans &= 0xfffffff0;
ans |= 0x00000001;

converter.u = ans;
*res = converter.f;

end_add_float

add_double:
*res=a+b;
end_add_double

sub_float:
*res=a-b;
end_sub_float

sub_double:
*res=a-b;
end_sub_double

mul_float:
*res=a*b;
end_mul_float

mul_double:
*res=a*b;
end_mul_double

div_float:
*res=a/b;
end_div_float

div_double:
*res=a/b;
end_div_double

madd_float:
*res=a*b+c;
end_madd_float

madd_double:
*res=a*b+c;
end_madd_double

sqrt_float:
*res=sqrt(a);
end_sqrt_float

sqrt_double:
*res=sqrt(b);
end_sqrt_double
49 changes: 49 additions & 0 deletions backend/new_back/backend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@


add_float:
*res=a+b;
end_add_float

add_double:
*res=a+b;
end_add_double

sub_float:
*res=a-b;
end_sub_float

sub_double:
*res=a-b;
end_sub_double

mul_float:
*res=a*b;
end_mul_float

mul_double:
*res=a*b;
end_mul_double

div_float:
*res=a/b;
end_div_float

div_double:
*res=a/b;
end_div_double

madd_float:
*res=a*b+c;
end_madd_float

madd_double:
*res=a*b+c;
end_madd_double

sqrt_float:
*res=sqrt(a);
end_sqrt_float

sqrt_double:
*res=sqrt(b);
end_sqrt_double

0 comments on commit e76932f

Please sign in to comment.