reorganizing the repository
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
gcc -c -Wall -Werror -fpic yftest/src/ftest/ftest.c yfmock/src/fmock/fmock.c \
|
||||
ytools_t/src/tools_t/tools_t.c ybar_progress/src/bar_progress/bar_progress.c \
|
||||
-I./include_ytest/include $1 -lpthread -E > eEcomp
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2023, fanasina
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,77 @@
|
||||
# lib: -lytest
|
||||
PROJECT_LIB=libytest.so
|
||||
CC=gcc
|
||||
INCLUDE_DIRS=$(PWD)
|
||||
#$(wildcard $(PWD)/**/include)
|
||||
INCLUDE=-I$(PWD)/yftest/include -I$(PWD)/yfmock/include -I$(PWD)/ytools_t/include -I$(PWD)/ybar_progress/include
|
||||
CFLAGS=-lpthread -Wall -Werror -fpic $(INCLUDE)
|
||||
#LDFLAGS=
|
||||
|
||||
TOPTARGETS := all clean #update_headers
|
||||
|
||||
#SRC=$(wildcard y*/src/**/**/*.c)
|
||||
SRC=$(wildcard y*/*/*/*.c)
|
||||
OBJ=$(SRC:.c=.o)
|
||||
|
||||
SUBDIRS :=$(wildcard y*)
|
||||
|
||||
export
|
||||
|
||||
|
||||
$(TOPTARGETS): $(SUBDIRS)
|
||||
|
||||
all: $(PROJECT_LIB) update_headers
|
||||
|
||||
|
||||
$(PROJECT_LIB): $(OBJ)
|
||||
echo $(OBJ)
|
||||
#$(CC) -shared -o $@ $^ $(INCLUDE) $(LDFLAGS)
|
||||
#$(CC) -shared -o $@ $^ $(LDFLAGS)
|
||||
$(CC) -shared -o $@ $^ $(CFLAGS)
|
||||
|
||||
|
||||
$(SUBDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
update_headers: $(PROJECT_LIB)
|
||||
for file_h in $(SUBDIRS); do cp -r "$$file_h/include" include_ytest/; done
|
||||
|
||||
.PHONY: $(TOPTARGETS) $(SUBDIRS)
|
||||
|
||||
clean:
|
||||
rm -f $(PROJECT_LIB)
|
||||
|
||||
remove_headers:
|
||||
rm -r include_ytest/*
|
||||
|
||||
install: update_headers
|
||||
cp libytest.so /usr/lib/
|
||||
@if [ -d /usr/local/include ] ; then\
|
||||
echo "copy include to /usr/local/include/" ;\
|
||||
cp -r include_ytest/include/* /usr/local/include/;\
|
||||
else\
|
||||
echo "copy include to /usr/include/" ;\
|
||||
cp -r include_ytest/include/* /usr/include/;\
|
||||
fi
|
||||
|
||||
uninstall:
|
||||
rm /usr/lib/libytest.so
|
||||
@if [ -d /usr/local/include ] ; then\
|
||||
echo "remove from /usr/local/include/" ;\
|
||||
rm -r /usr/local/include/ftest ;\
|
||||
rm -r /usr/local/include/fmock ;\
|
||||
rm -r /usr/local/include/bar_progress ;\
|
||||
rm -r /usr/local/include/tools_t ;\
|
||||
else\
|
||||
echo "remove from /usr/include/" ;\
|
||||
rm -r /usr/include/ftest ;\
|
||||
rm -r /usr/include/fmock ;\
|
||||
rm -r /usr/include/bar_progress ;\
|
||||
rm -r /usr/include/tools_t ;\
|
||||
fi
|
||||
|
||||
|
||||
#SRC_test=test/is_good.c
|
||||
|
||||
#compile: $(SRC_test) $(PROJECT_LIB)
|
||||
# $(CC) -o launch_is_good_m $< -L. test/src/permutation_t/permutation_t.o test/src/set_theoric_t/set_theoric_t.o -lytest -I./test/src -I./include_ytest
|
||||
@@ -0,0 +1,370 @@
|
||||

|
||||
|
||||
# ytest
|
||||
C library like `gtest / gmock` like, but works mainly with functions
|
||||
|
||||
## env
|
||||
linux
|
||||
|
||||
## install
|
||||
### generate the library
|
||||
to create `libytest.so`
|
||||
```
|
||||
make
|
||||
```
|
||||
or
|
||||
```
|
||||
./kreate_library_ytest.sh
|
||||
```
|
||||
### install in local machine
|
||||
We have 2 options: setup env, or install
|
||||
#### set env
|
||||
```
|
||||
chmod +x set_env.sh
|
||||
```
|
||||
to set local env: (only in the active terminal)
|
||||
```
|
||||
. set_env.sh
|
||||
```
|
||||
If you want permanent variable env:
|
||||
```
|
||||
./set_env.sh ~/.bashrc
|
||||
```
|
||||
or
|
||||
```
|
||||
./set_env.sh /path/file/local/env/shell
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### install by copying files and directory
|
||||
This creates a permanent copy of `libytest.so` and the file headers of `ytest: include_ytest/include/*` in local machine
|
||||
```
|
||||
sudo make install
|
||||
```
|
||||
or
|
||||
```
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
### uninstall
|
||||
like install, there are 2 methods: unset env, or uninstall
|
||||
#### unset env
|
||||
```
|
||||
chmod +x unset_env.sh
|
||||
```
|
||||
to unset variables env in local terminal:
|
||||
```
|
||||
. unset_env.sh
|
||||
```
|
||||
to unset variable permanantly: need to have the same arg as `set_env.sh`
|
||||
```
|
||||
./unset_env.sh ~/.bashrc
|
||||
```
|
||||
or
|
||||
```
|
||||
./unset_env.sh /path/file/local/env/shell
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### uninstall script remove:
|
||||
this remove from locale machine env all files and directory copied in `make install` or `./install.sh`
|
||||
```
|
||||
sudo make uninstall
|
||||
```
|
||||
or
|
||||
```
|
||||
sudo ./uninstall.sh
|
||||
```
|
||||
|
||||
## using lib ytest
|
||||
if you do not install the library:
|
||||
### include
|
||||
copy the headers in `include_ytest/include` to include directory, for example
|
||||
```
|
||||
cp -r include_ytest/include/* /usr/include/
|
||||
```
|
||||
or
|
||||
```
|
||||
cp -r include_ytest/include/* ~/.local/include/
|
||||
```
|
||||
if `/usr/include` or `~/.local/include` is in `CPATH`
|
||||
or
|
||||
execute
|
||||
```
|
||||
export CPATH=/Path_to_dir_ytest/include_ytest/include:$CPATH
|
||||
```
|
||||
or add the precedent line in `~/.bashrc`.
|
||||
|
||||
We can avoid these copy or export to CPATH env by adding
|
||||
```
|
||||
-I/Path_to_dir_ytest/include_ytest/include
|
||||
```
|
||||
when compiling our test.
|
||||
### library
|
||||
Also, we need to add `-L/Path_to_dir_ytest` when compiling our test, this `/Path_to_dir_ytest` contain `libytest.so`.
|
||||
Or we can copy `libytest.so` in a directory in `/usr/lib/` or other directory in
|
||||
```
|
||||
echo $LD_LIBRARY_PATH
|
||||
```
|
||||
Or, copy `libytest.so` in `/path_to/lib_ytest/` and then
|
||||
add
|
||||
```
|
||||
export LD_LIBRARY_PATH=/path_to/lib_ytest:$LD_LIBRARY_PATH
|
||||
```
|
||||
in `~/.bashrc`.
|
||||
|
||||
|
||||
## test examples
|
||||
`test/is_good.c` and `permutation_test/is_good.c`
|
||||
|
||||
## compile and run the example
|
||||
```
|
||||
cd test
|
||||
make
|
||||
./launch_is_good_m
|
||||
```
|
||||
or
|
||||
```
|
||||
chmod +x compile.sh
|
||||
./compile.sh "is_good.c"
|
||||
./launch_is_good_c
|
||||
```
|
||||
## error
|
||||
if we have /* if the library is not installed */
|
||||
```
|
||||
./launch_is_good_m
|
||||
./launch_is_good_m: error while loading shared libraries: libytest.so: cannot open shared object file: No such file or directory
|
||||
````
|
||||
we need to add LD_LIBRARY_PATH env permanently or
|
||||
```
|
||||
LD_LIBRARY_PATH=.. ./launch_is_good_m
|
||||
```
|
||||
i.e
|
||||
```
|
||||
LD_LIBRARY_PATH=/path_to/lib_ytest ./launch_is_good_m
|
||||
```
|
||||
it is th same if `./launch_is_good_c` does not find `libytest.so`
|
||||
|
||||
|
||||
|
||||
## some compile options
|
||||
### if need to print debug with PRINT_DEBUG_
|
||||
`PRINT_DEBUG` is the macro to print debug in this ytest lib, but in `tools_t.h` we define `PRINT_DEBUG_` to print debug beut it need to activate DEBUG macro by `-D DEBUG=1`option so, if we need to print debug in tools_t we have to:
|
||||
```
|
||||
./kreate_library_ytest "-D DEBUG=1"
|
||||
cd test
|
||||
./compile "is_good.c" "-D DEBUG=1"
|
||||
```
|
||||
|
||||
|
||||
### if need gdb
|
||||
```
|
||||
./kreate_library_ytest "-g"
|
||||
cd test
|
||||
./compile "is_good.c" "-g"
|
||||
```
|
||||
|
||||
so we need to use `./launch_is_good_c` to active these options
|
||||
|
||||
## launch options if using run_all_tests_args(argc, argv);
|
||||
By default `./launch_is_good_{c,m}` is on 1 thread but we can add some options to run tests in parallel, or change colors, to disable progress bar, ..., to print help
|
||||
|
||||
### help
|
||||
`./launch_is_good_c -h`
|
||||
```
|
||||
usage: ./launch_is_good_c [OPTIONS] [<ARGS>]
|
||||
|
||||
or : ./launch_is_good_c [OPTIONS]=[<ARGS>]
|
||||
|
||||
OPTIONS
|
||||
-h, --help
|
||||
print help, options variables
|
||||
|
||||
-d, --debug
|
||||
to print debug by using PRINT_DEBUG, by default PRINT_DEBUG is off
|
||||
|
||||
-g, --gtestlike
|
||||
to have gtest hook like!
|
||||
|
||||
-p <NB>, --parallel <NB>, -p=<NB>, --parallel=<NB>
|
||||
by default the program ran in sequantial all test,
|
||||
if this option is set, the program run tests on NB threads.
|
||||
Each thread pull up one test out the list of all test not yet executed,
|
||||
and execute it, until the list is empty
|
||||
|
||||
-t <unit>, --time <unit>, -t=<unit>, --time=<unit>
|
||||
by default unit is millisecons ms, the other of unit are choices are second (or s), and nanosecond (or ns)
|
||||
ex: -t ns or -t=nanosecond or --time=n to set nanosecond unit
|
||||
|
||||
-u , --unicolour
|
||||
by default, the result is colored, if you choice this option, it prints with default color
|
||||
|
||||
-r , --remove
|
||||
if the option parallel is choosen the result on each thread is record in separate files,
|
||||
this option remove the file logs of each thread after all tests.
|
||||
|
||||
-s <file>, --savelog <file>, -s=file, --savelog=file
|
||||
this option save the global ordered result in 'file',
|
||||
|
||||
|
||||
-n=<NUM1>,<NUM2> <NUM3>... ,--numtests=<NUM1>,<NUM2>...
|
||||
this option allow to execute only the selected numbers of tests (in the order in file test)
|
||||
ex: -n=0,6,3 8 to execute the tests 0,3,6,8 (if the number is less than the count of all tests)
|
||||
|
||||
-l=<NAME1>,<NAME2> <NAME3>... ,--listests=<NAME1>,<NAME2>...<NAMEn>
|
||||
this option allow to execute only the selected name of tests. It allows empty name by using '-l=,'
|
||||
ex: -l=name0,,name2 : execute only (if they exist): TEST(name0),TEST(),TEST(name2)
|
||||
|
||||
-b <BPRGSS>, --bar_progress <BPRGSS>, -b=BPRGSS, --bar_progress=BPRGSS. Example: -b="#_c"
|
||||
this option change progression bar if it is active. The first character ('#') fills the bar
|
||||
the second char ('_') fills the other part of bar. the bar is colored if the 3rd char is 'c' and not if different.
|
||||
by default the progress bar is active and the option is -b=" c", if need not colored, we can put -b=" n" option.
|
||||
|
||||
-z=<option>
|
||||
this option is to set option=0,
|
||||
for example, -z=progress is to not load progress bar, it is need if we want to redirect (pipe) the result to file.
|
||||
other option: -z=log_parallel (to avoid logs not ordered when parallel tests which is loged by default)
|
||||
|
||||
```
|
||||
|
||||
For example, to launch tests (`test/is_good.c`) on 4 threads, using unicolor(black&white), and remove logs when all tests are done:
|
||||
```
|
||||
./launch_is_good_c -p 4 -r -u
|
||||
```
|
||||
|
||||
|
||||
# How to compile test
|
||||
## include path
|
||||
We need to add `/path_to/include_ytest/include` in `CPATH` by ```export CPATH=/path_to/include_ytest/include:$CPATH``` in terminal or in `~/.bashrc` file for example.
|
||||
|
||||
Or we can add ```-I/path_to/include_ytest/include``` when compiling.
|
||||
## library path
|
||||
The others option when compiling are `-L/path_to/directorytest` this path must contain `libytest.so` generated by `make` or `./kreate_library_ytest` or we can put this path in `LD_LIBRARY_PATH`.
|
||||
## -lytest
|
||||
And we must add `-lytest` to add the shared library in compilation.
|
||||
|
||||
# How to create test (ftest)
|
||||
## include
|
||||
```
|
||||
#include "ftest/ftest.h"
|
||||
|
||||
TEST(nametest){
|
||||
EXPECT_EQ(1,1);
|
||||
}
|
||||
/* allow empty nametest, e.g*/
|
||||
TEST(){}
|
||||
/* allow duplicate name test, to have suit test */
|
||||
TEST(){
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
```
|
||||
|
||||
## in function main
|
||||
### if using options:
|
||||
```
|
||||
int main(int arc, char** argv){
|
||||
run_all_tests_args(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### if only use sequential tests
|
||||
```
|
||||
int main(){
|
||||
run_all_tests();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### if use only parrallel tests
|
||||
```
|
||||
int main(){
|
||||
run_all_tests_parallel(4); /* to use 4 threads */
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
# FMOCK
|
||||
## How to create fmock
|
||||
|
||||
```
|
||||
#include "fmock/fmock.h"
|
||||
```
|
||||
outside all functions:
|
||||
```
|
||||
MOCK_FUNC(returnType, name_function_mock,(prototype of the function with paranthesis),(args when call the funct with parathesis))
|
||||
/* use (returnType) in parathesis if the returType has more than 1 words for example (long int) or (struct someStruct) */
|
||||
```
|
||||
For example, to create a function mock as signature:
|
||||
```
|
||||
int f_mock(int a,int b);
|
||||
```
|
||||
we use
|
||||
```
|
||||
MOCK_FUNC(int, f_mock,(int a,int b),(a,b))
|
||||
```
|
||||
args:
|
||||
```
|
||||
returnType: int,
|
||||
name_function_mock: f_mock,
|
||||
args prototype with paranthesis: (int a,int b),
|
||||
args variable names with parathesis (same variable names as prototype): (a,b)
|
||||
```
|
||||
## print variables
|
||||
We may define a function to print variables of the mock function, it is usefull in logs, the macro has almost the same args as MOCK_FUNC, without returnType wich is always `char*`.
|
||||
For example with `f_mock` we define:
|
||||
```
|
||||
STR_PRINT_CUR_VAR(f_mock, (int a,int b),(a,b)){
|
||||
char *ret=malloc(150);
|
||||
sprintf(ret,"(int)a: %d, (int)b: %d",a,b);
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
## define expect call
|
||||
```
|
||||
EXPECT_MOCK_CALL(int, f_mock, (int a,int b), (a<b), 3){
|
||||
return a+b;
|
||||
}
|
||||
```
|
||||
args:
|
||||
```
|
||||
returnType: int,
|
||||
name_function_mock: f_mock,
|
||||
arg prototype of the function with paranthesis: (int a,int b),
|
||||
conditions to check on args before calling the function:(bool expression): (a<b)
|
||||
number of repetition response (number of call times): 3
|
||||
```
|
||||
## define will call
|
||||
```
|
||||
WILL_MOCK_CALL(int, f_mock, (int a,int b), (a==b), 1){
|
||||
return a*b;
|
||||
}
|
||||
```
|
||||
same args as EXPECT_MOCK_CALL, the difference is, the EXPECT_MOCK_CALL has to be called by the test earlier, but not WILL_MOCK_CALL.
|
||||
|
||||
## init call and call
|
||||
in TEST environement, we may use macro `INIT_CALLER_MOCK(f_mock);` before calling `f_mock` to have explicit logs again!
|
||||
|
||||
Call function mock is the same as other normal functions.
|
||||
|
||||
Example:
|
||||
```
|
||||
TEST(f_mock_test){
|
||||
INIT_CALLER_MOCK(f_mock);
|
||||
PRINTF(" first call: %d\n",f_mock(2,3));
|
||||
PRINTF(" second call: %d\n",f_mock(3,3));
|
||||
}
|
||||
```
|
||||
# PRINTF
|
||||
We may use standard printf function, but I provide a macro PRINTF to allow us record logs in files and also ordered logs when we use parallel tests.
|
||||
|
||||
args are the same as `printf` stdio.h function.
|
||||
example:
|
||||
```
|
||||
PRINTF("hello\n");
|
||||
```
|
||||
I introduce also an alias `LOG` for `PRINTF`
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
gcc -o x1 eg1.c -I../include_ytest/include/ -L.. -lytest $1
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "ftest/ftest.h"
|
||||
|
||||
TEST(foo){
|
||||
PRINTF("first test\n");
|
||||
int a=1;
|
||||
EXPECT_TRUE(1==a);
|
||||
}
|
||||
|
||||
TEST(foo){ /* same name*/
|
||||
sleep(2);
|
||||
float a=0.001, b=0.0005;
|
||||
PRINTF("after sleeping 2 seconds, we test if %f ?= 2*%f\n",a,b);
|
||||
EXPECT_EQ_TYPE_FLOAT(a,2*b);
|
||||
}
|
||||
|
||||
TEST(foo){
|
||||
sleep(1);
|
||||
double a=0.001, b=0.0001;
|
||||
LOG("after 1 sec, \n");
|
||||
EXPECT_LT_TYPE_DOUBLE(b,a);
|
||||
ASSERT_GE_TYPE_DOUBLE(a,b);
|
||||
ASSERT_LE_TYPE_DOUBLE(a,b);
|
||||
LOG("this line will not print");
|
||||
}
|
||||
|
||||
TEST(){
|
||||
EXPECT_TRUE(2==1);
|
||||
LOG("this line will print: the precedent expect failed\n");
|
||||
}
|
||||
TEST(){
|
||||
sleep(1);
|
||||
EXPECT_FALSE(2==1);
|
||||
}
|
||||
|
||||
TEST(an_other_test){
|
||||
LOG("FINAL, no test, only sleep\n");
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
run_all_tests_args(argc,argv);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -le 0 ] ; then
|
||||
echo "usage : $0 <option>"
|
||||
echo "for example: $0 \"-p=3 -r\""
|
||||
fi
|
||||
|
||||
LD_LIBRARY_PATH=.. ./x1 $1
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
#ifndef __BAR_PROGRESS_H__
|
||||
#define __BAR_PROGRESS_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Prepares screen for progress bar.
|
||||
*/
|
||||
void bar_progress_start(void);
|
||||
|
||||
void bar_progress_step_msg(int step_progress, int all_progress, char *msg, char fill_bar, char fill_dot, int colored);
|
||||
|
||||
/*
|
||||
* progress value 0 to 100
|
||||
*/
|
||||
void bar_progress_step(float step_percent);
|
||||
|
||||
/*
|
||||
* Removes progress bar and restores original screen size.
|
||||
*/
|
||||
void bar_progress_stop(void);
|
||||
|
||||
#endif /* __BAR_PROGRESS_H */
|
||||
@@ -0,0 +1,286 @@
|
||||
#ifndef __MOCK_C_H__
|
||||
#define __MOCK_C_H__
|
||||
|
||||
#include "ftest/ftest.h"
|
||||
#include "tools_t/tools_t.h"
|
||||
|
||||
#define INFINITY -8
|
||||
#define INITSTATE -1
|
||||
#define DONOTHING 0
|
||||
|
||||
#define PRE_ID ___line_
|
||||
/*
|
||||
* list of each variable called
|
||||
* use str_print_current_variables attibute function pointer to record variable
|
||||
* so if STR_PRINT_CUR_VAR is not defined, this list is empty!
|
||||
*/
|
||||
struct list_current_variable{
|
||||
char *str_current_variables;
|
||||
struct list_current_variable *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* list to store info abou mock function
|
||||
*/
|
||||
struct func_mock_info_struct{
|
||||
long id;
|
||||
char *str_namefunc;
|
||||
char *str_conditions;
|
||||
char *str_caller;
|
||||
//char *str_current_variables;
|
||||
struct list_current_variable *l_current_var;
|
||||
int expect_call;/* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */
|
||||
long call;/* increment when call (try to executed) and 0 if not : init value */
|
||||
long failed_call;/* increment when condition not fill and 0 if not : init value */
|
||||
long init_times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */
|
||||
long times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */
|
||||
struct func_mock_info_struct *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* to list all mock responses of all mock functions in one list
|
||||
*/
|
||||
struct list_base_fmock{
|
||||
struct func_mock_info_struct *info_mock;
|
||||
struct list_base_fmock *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int parse_count_args_(char *input);
|
||||
void append_fmock_to_listmock(struct func_mock_info_struct **f_mock_list, struct func_mock_info_struct *f_mock);
|
||||
void append_list_base_fmock(struct list_base_fmock **l_fmock, struct func_mock_info_struct *f_mock);
|
||||
void append_variable_current(struct list_current_variable **lcurrent_var, char *current_var);
|
||||
|
||||
// if input == functioname___line_NBLINE return functioname, else it return the input
|
||||
//char* extract_name_func_mock(char *input);
|
||||
|
||||
extern struct func_mock_info_struct *f_mock_glist;
|
||||
extern struct list_base_fmock *g_list_base_fmock;
|
||||
|
||||
#if 0
|
||||
int expect_call; /* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */\
|
||||
long init_times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\
|
||||
long times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\
|
||||
|
||||
#endif
|
||||
|
||||
#define INIT_MOCK_INFO_IF_NO__(tmp__mock, namefunction, pre_id, id) \
|
||||
(tmp__mock)->run = NULL;\
|
||||
(tmp__mock)->call_mock_condition = NULL;\
|
||||
/*(tmp__mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;*/\
|
||||
((tmp__mock)->info_mock)->expect_call = -1;\
|
||||
((tmp__mock)->info_mock)->call = 0;\
|
||||
((tmp__mock)->info_mock)->failed_call = 0;\
|
||||
((tmp__mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\
|
||||
sprintf(((tmp__mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\
|
||||
((tmp__mock)->info_mock)->str_conditions = NULL;\
|
||||
((tmp__mock)->info_mock)->str_caller = NULL;\
|
||||
((tmp__mock)->info_mock)->l_current_var= NULL;\
|
||||
((tmp__mock)->info_mock)->next = NULL;\
|
||||
/*(tmp__mock)->next = NULL;*/\
|
||||
append_fmock_to_listmock(&f_mock_glist, (tmp__mock)->info_mock);\
|
||||
append_list_base_fmock( &g_list_base_fmock ,(tmp__mock)->info_mock);
|
||||
|
||||
#define INIT_MOCK_INFO_IF_NO_(tmp_new_mock, namefunction, pre_id) \
|
||||
INIT_MOCK_INFO_IF_NO__(tmp_new_mock, namefunction, pre_id, __LINE__) \
|
||||
|
||||
#define MOCK_FUNC(returntype, namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\
|
||||
/*typedef returntype FUNC_type_ ## namefunction args_prototype_with_parenthesis ;*/\
|
||||
/*typedef args_prototype_with_parenthesis args_ ## namefunction;*/\
|
||||
struct list_mock_return_ ## namefunction{\
|
||||
returntype (*run) args_prototype_with_parenthesis;\
|
||||
int (*call_mock_condition) args_prototype_with_parenthesis ;/* to store condition */\
|
||||
char* (*str_print_current_variables) args_prototype_with_parenthesis ;/* to store current variables CREATE by macro STR_PRINT_CUR_VAR same arguments as MOCK_FUNC without returntype whoch is always char * */\
|
||||
struct func_mock_info_struct *info_mock;\
|
||||
struct list_mock_return_ ## namefunction *next;\
|
||||
} list_mo_ ## namefunction;\
|
||||
__attribute__((constructor)) void init_list_m_ ## namefunction(void){\
|
||||
list_mo_ ## namefunction.info_mock = malloc(sizeof(struct func_mock_info_struct));\
|
||||
(list_mo_ ## namefunction.info_mock)->times_left = INITSTATE;\
|
||||
(list_mo_ ## namefunction.info_mock)->init_times_left = INITSTATE;\
|
||||
list_mo_ ## namefunction.str_print_current_variables = NULL;\
|
||||
list_mo_ ## namefunction.next = NULL;\
|
||||
}\
|
||||
returntype namefunction args_prototype_with_parenthesis {\
|
||||
static size_t count_call_f=0;\
|
||||
++count_call_f;\
|
||||
PRINT_DEBUG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>count call of %s: %ld\n",#namefunction,count_call_f);\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
if( (tmp_mock->info_mock)->times_left == INITSTATE ){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," WARNING, %s, no EXPECT_MOCK_CALL or WILL_MOCK_CALL, but called %ld times.\n",#namefunction, count_call_f);\
|
||||
if(count_call_f==1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," For instance:\n"\
|
||||
"%s EXPECT_MOCK_CALL(%s,%s,%s,true,1){\n"\
|
||||
"%s\t %s ret;\n%s \t ...do something with %s;\n"\
|
||||
"%s\t return ret;\n"\
|
||||
"%s }\n"\
|
||||
"%s if call once and accept all args, the same args with WILL_MOCK_CALL \n\n",\
|
||||
tab_hk_f[hk_TR], #returntype, #namefunction,#args_prototype_with_parenthesis, tab_hk_f[hk_TR],#returntype, \
|
||||
tab_hk_f[hk_TR], #args_call_with_parenthesis, tab_hk_f[hk_TR], tab_hk_f[hk_TR], tab_hk_f[hk_TR] ); \
|
||||
/*return (returntype)0;*/ \
|
||||
INIT_MOCK_INFO_IF_NO_(tmp_mock,namefunction, PRE_ID);\
|
||||
}/* to have log */\
|
||||
/*if(list_mo_ ## namefunction.next ) PRINT_ERROR(" %s .next SHOULD BE NULL\n",STRFY(list_mo_ ## namefunction));*/\
|
||||
}\
|
||||
while(tmp_mock->next && (tmp_mock->info_mock)->times_left == 0) {tmp_mock = tmp_mock->next ;}\
|
||||
++((tmp_mock->info_mock)->call);\
|
||||
if(tmp_mock->str_print_current_variables){\
|
||||
append_variable_current(&((tmp_mock->info_mock)->l_current_var), tmp_mock->str_print_current_variables args_call_with_parenthesis);\
|
||||
}\
|
||||
else if(count_call_f == 1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," no printer variable function defined, to define it:\n"\
|
||||
"%s STR_PRINT_CUR_VAR(%s,%s,%s){\n"\
|
||||
"%s\t char* ret=malloc(256);/*for instance*/;\n"\
|
||||
"%s\t ... sprintf(ret,...., %s);/*for instance*/ \n"\
|
||||
"%s\t return ret;\n"\
|
||||
"%s }\n"\
|
||||
"%s same prototype as MOCK_FUNC whithout returntype which always char* i\n\n",\
|
||||
tab_hk_f[hk_TR], #namefunction,#args_prototype_with_parenthesis, #args_call_with_parenthesis, \
|
||||
tab_hk_f[hk_TR], tab_hk_f[hk_TR], #args_call_with_parenthesis, tab_hk_f[hk_TR], tab_hk_f[hk_TR], tab_hk_f[hk_TR] ); \
|
||||
}\
|
||||
/*LOG("condition_func:%d\n", tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\
|
||||
/*EXPECT_EQ_TYPE_INT(1, tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\
|
||||
/*if ((tmp_mock->info_mock)->times_left == 0)*/ /*no longer response, default return */ \
|
||||
/*return (returntype)0;*//* default return */\
|
||||
if( (tmp_mock->info_mock)->str_caller == NULL){ \
|
||||
if(count_call_f == 1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," WARNING, no INIT_CALLER_MOCK; you can put it like this: \n"\
|
||||
"%s TEST(nametest){\n"\
|
||||
"%s\t INIT_CALLER_MOCK(%s); \n"\
|
||||
"%s\t %s%s; \n"\
|
||||
"%s }\n"\
|
||||
"%s i.e before calling %s in this TEST, to have explicit logs\n",\
|
||||
tab_hk_f[hk_TR], tab_hk_f[hk_TR], #namefunction, tab_hk_f[hk_TR],#namefunction,#args_call_with_parenthesis, tab_hk_f[hk_TR], tab_hk_f[hk_TR], #namefunction);} \
|
||||
/*return (returntype)0;*/ \
|
||||
}\
|
||||
else if (((tmp_mock->info_mock)->times_left != 0) && ((tmp_mock->info_mock)->times_left != INITSTATE )) {\
|
||||
size_t len0 = strlen((tmp_mock->info_mock)->str_conditions);\
|
||||
size_t len1 = strlen("when checking condition call: aa");\
|
||||
char *msg_call=malloc(len0 + len1 + strlen(__func__));\
|
||||
sprintf(msg_call,"when checking %s condition call: %s",__func__,(tmp_mock->info_mock)->str_conditions);\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,1, tmp_mock->call_mock_condition args_call_with_parenthesis, (tmp_mock->info_mock)->str_caller, msg_call); /*LOG("%s\n","failure condition");*/\
|
||||
free(msg_call);\
|
||||
}\
|
||||
/*if(0 == tmp_mock->call_mock_condition args_call_with_parenthesis){\
|
||||
PRINT_LOC("Failure, arguments not expected\ncondition ( %s ) not verified\n\n", (tmp_mock->info_mock)->str_conditions);\
|
||||
PRINT_HK_C(RED_K,tab_hk_f[hk_TR]," 1 argument check failed from %s \n",__func__); \
|
||||
}*/\
|
||||
PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'^',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\
|
||||
if (((tmp_mock->info_mock)->times_left <= INFINITY) || ((tmp_mock->info_mock)->times_left > 0)){\
|
||||
--((tmp_mock->info_mock)->times_left);\
|
||||
PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'v',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\
|
||||
if(1 == tmp_mock->call_mock_condition args_call_with_parenthesis){\
|
||||
return tmp_mock->run args_call_with_parenthesis;\
|
||||
}\
|
||||
else ++((tmp_mock->info_mock)->failed_call);\
|
||||
}\
|
||||
return (returntype)0;/* default return */\
|
||||
}
|
||||
|
||||
|
||||
char* extract_name_func_mock(char *input);
|
||||
|
||||
/*
|
||||
* used in mock functions to check the conditions
|
||||
*/
|
||||
#define EXPECT_EQ_IN_MOCKF(var1,var2, name_f_mocked)\
|
||||
do{ \
|
||||
if((list_mo_ ## name_f_mocked.info_mock)->str_caller) {\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,(list_mo_ ## name_f_mocked.info_mock)->str_caller,"mock test");\
|
||||
}\
|
||||
else\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,__func__,"mock test");\
|
||||
}while(0)
|
||||
|
||||
|
||||
/*
|
||||
* to inject the name TEST caller in the mock attribute info, usefull in logs and stats
|
||||
*/
|
||||
#define INIT_CALLER_MOCK(namefunction)/* */\
|
||||
do{\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
while(tmp_mock){\
|
||||
(tmp_mock->info_mock)->str_caller=malloc(strlen(__func__));\
|
||||
strcpy((tmp_mock->info_mock)->str_caller,__func__);\
|
||||
tmp_mock = tmp_mock->next;\
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
/*
|
||||
* to create/ define str_print_current_variables functions
|
||||
* prototype: char* str_print_current_variables (prototype of mock function)
|
||||
* the args of the macro are the same of MOCK_FUNC without the returntype which is always (char*).
|
||||
* It need to be defined after MOCK_FUNC but need to be before EXPECT_MOCK_CALL or WILL_MOCK_CALL
|
||||
*/
|
||||
|
||||
#define STR_PRINT_CUR_VAR(namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\
|
||||
char* str_print_variables ## namefunction args_prototype_with_parenthesis;\
|
||||
__attribute__((constructor)) void create_str_print_variables ## namefunction(){\
|
||||
list_mo_ ## namefunction .str_print_current_variables = str_print_variables ## namefunction;\
|
||||
}\
|
||||
char* str_print_variables ## namefunction args_prototype_with_parenthesis
|
||||
|
||||
|
||||
|
||||
|
||||
#define FILL_MOCK_INFO(tmp_new_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, is_init) \
|
||||
(tmp_new_mock)->run = CONCAT(run_ ## namefunction ## pre_id, id);\
|
||||
(tmp_new_mock)->call_mock_condition = CONCAT(namefunction ## _cond_, id);\
|
||||
if(!is_init)\
|
||||
(tmp_new_mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;\
|
||||
/*(tmp_new_mock)->info_mock = malloc(sizeof(struct func_mock_info_struct));*/\
|
||||
((tmp_new_mock)->info_mock)->expect_call = f_expect_call;\
|
||||
((tmp_new_mock)->info_mock)->call = 0;\
|
||||
((tmp_new_mock)->info_mock)->failed_call = 0;\
|
||||
((tmp_new_mock)->info_mock)->init_times_left = repeat;\
|
||||
((tmp_new_mock)->info_mock)->times_left = repeat;\
|
||||
((tmp_new_mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\
|
||||
sprintf(((tmp_new_mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\
|
||||
((tmp_new_mock)->info_mock)->str_conditions = malloc(strlen(#condition_on_args_expression));\
|
||||
strcpy(((tmp_new_mock)->info_mock)->str_conditions, #condition_on_args_expression);\
|
||||
((tmp_new_mock)->info_mock)->str_caller = NULL;\
|
||||
((tmp_new_mock)->info_mock)->l_current_var= NULL;\
|
||||
((tmp_new_mock)->info_mock)->next = NULL;\
|
||||
(tmp_new_mock)->next = NULL;\
|
||||
append_fmock_to_listmock(&f_mock_glist, (tmp_new_mock)->info_mock);
|
||||
|
||||
|
||||
#define ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
/*FUNC_type_ ## namefunction CONCAT(run_ ## namefunction ## pre_id , id);*/\
|
||||
returntype CONCAT(run_ ## namefunction ## pre_id , id) args_prototype_with_parenthesis; \
|
||||
int CONCAT(namefunction ## _cond_ , id) args_prototype_with_parenthesis {/*LOG("cond:%d\n",condition_on_args_expression);*/ return condition_on_args_expression;}\
|
||||
__attribute__((constructor)) void CONCAT(append_list_ ## namefunction , id)(void){\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
if((tmp_mock->info_mock)->times_left == INITSTATE){/* init state */\
|
||||
FILL_MOCK_INFO(tmp_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, true);\
|
||||
append_list_base_fmock( &g_list_base_fmock ,(tmp_mock->info_mock));\
|
||||
}\
|
||||
else{\
|
||||
while(tmp_mock->next) tmp_mock = tmp_mock->next;\
|
||||
tmp_mock->next = malloc(sizeof(list_mo_ ## namefunction));\
|
||||
(tmp_mock->next)->info_mock = malloc(sizeof(struct func_mock_info_struct));\
|
||||
FILL_MOCK_INFO(tmp_mock->next, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, false);\
|
||||
/*(tmp_mock->info_mock)->next = (tmp_mock->next)->info_mock ;*/\
|
||||
}\
|
||||
}\
|
||||
returntype CONCAT(run_ ## namefunction ## pre_id, id) args_prototype_with_parenthesis
|
||||
|
||||
/*
|
||||
* have to define this below macro to rewrite the right macro identifier (PRE_ID)
|
||||
*/
|
||||
|
||||
#define ADD_RESPONSE(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
|
||||
|
||||
#define EXPECT_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \
|
||||
ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 1, PRE_ID, __LINE__)
|
||||
|
||||
|
||||
#define WILL_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \
|
||||
ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 0, PRE_ID, __LINE__)
|
||||
|
||||
|
||||
|
||||
#endif /* __MOCK_C_H__ */
|
||||
@@ -0,0 +1,803 @@
|
||||
#ifndef __TEST_C_H__
|
||||
#define __TEST_C_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
//#include <time.h>
|
||||
#include <pthread.h>
|
||||
//#include <unistd.h>
|
||||
#include <sys/ioctl.h> /* to have size of screen, for progress bar */
|
||||
|
||||
#include "tools_t/tools_t.h"
|
||||
#include "bar_progress/bar_progress.h"
|
||||
|
||||
#define DEFAULT_K "\033[0m" /*Resets the text to default color*/
|
||||
#define GREEN_K "\033[0;32m"
|
||||
#define RED_K "\033[0;31m"
|
||||
#define YELLOW_K "\033[0;33m"
|
||||
#define BLUE_K "\033[0;34m"
|
||||
#define NOTHING_K ""
|
||||
|
||||
#define COLOR_SZ 6
|
||||
|
||||
#define Dknothing COLOR_SZ - 1
|
||||
|
||||
#define SZ_TAB_HK 8
|
||||
|
||||
|
||||
/*#ifdef HK*/
|
||||
#define gHK_EQ "[==========]"
|
||||
#define gHK_TR "[----------]"
|
||||
#define gHK_RN "[RUN ]"
|
||||
#define gHK_DN "[ DONE]"
|
||||
#define gHK_OK "[ OK ]"
|
||||
#define gHK_FL "[ FAILED ]"
|
||||
#define gHK_PS "[ PASSED ]"
|
||||
#define gHK_SK "[ SKIP ]"
|
||||
/*#else*/
|
||||
#define HK_EQ "=========="
|
||||
#define HK_TR "----------"
|
||||
#define HK_RN "====== RUN"
|
||||
#define HK_DN "===== DONE"
|
||||
#define HK_OK "======= OK"
|
||||
#define HK_FL "===== FAIL"
|
||||
#define HK_PS "===== PASS"
|
||||
#define HK_SK "===== SKIP"
|
||||
/*#endif*/ /* HK */
|
||||
|
||||
/*
|
||||
* compare symbol
|
||||
*/
|
||||
#define EQ ==
|
||||
#define LT <
|
||||
#define GT >
|
||||
#define LE <=
|
||||
#define GE >=
|
||||
#define NE !=
|
||||
|
||||
|
||||
extern FILE **f_ou_th;
|
||||
extern bool debug;
|
||||
extern bool unicolour;
|
||||
extern bool ordered;
|
||||
extern bool log_parallel;
|
||||
extern bool only_usage;
|
||||
extern char *savelog;
|
||||
|
||||
extern char *colors_f[];
|
||||
extern char *tab_hk_f[];
|
||||
|
||||
extern int k_DEFAULT, k_GREEN, k_RED, k_YELLOW, k_BLUE, k_NOTHING;
|
||||
extern int hk_EQ, hk_TR, hk_RN, hk_DN, hk_OK, hk_FL, hk_PS, hk_SK;
|
||||
extern char *varHK_EQ, *varHK_TR, *varHK_RN, *varHK_DN, *varHK_OK, *varHK_FL, *varHK_PS, *varHK_SK;
|
||||
|
||||
/*
|
||||
* */
|
||||
|
||||
/*
|
||||
* to execute once in print functions in the case of log_parallel (printing on screen and recording in file), we have to copy to stream -> string before copy it,
|
||||
* so I have tried using fopen a file in memory location '/dev/shm' and remove it after use!
|
||||
* /dev/shm/tmp_PTHREAD_SELF() but it prints twice sometimes,
|
||||
* here a solution with open_memstream which is better
|
||||
*/
|
||||
|
||||
#define PRINTF( ...) \
|
||||
do{ \
|
||||
FILE *stream ;\
|
||||
size_t len;\
|
||||
char *buf ;\
|
||||
stream = open_memstream (&buf, &len);\
|
||||
if (stream == NULL) { fprintf(stderr," error open_memstream %s:%d:%s \n",__FILE__,__LINE__,__func__); exit(0); }\
|
||||
fprintf(stream, __VA_ARGS__); \
|
||||
fflush(stream);\
|
||||
if(is_parallel_nb){\
|
||||
long int id_thread=id_of_thread_executed();\
|
||||
if(log_parallel){\
|
||||
fprintf(F_OUT, "%s",buf);\
|
||||
if(id_thread >= 0){\
|
||||
fprintf(f_ou_th[id_thread], "%s",buf);\
|
||||
fflush(f_ou_th[id_thread]);\
|
||||
}\
|
||||
}\
|
||||
else{\
|
||||
if(id_thread >= 0){\
|
||||
fprintf(f_ou_th[id_thread], "%s",buf);\
|
||||
fflush(f_ou_th[id_thread]);\
|
||||
}\
|
||||
else {\
|
||||
fprintf(F_OUT, "%s",buf);\
|
||||
}\
|
||||
}\
|
||||
} \
|
||||
else{\
|
||||
if(savelog){\
|
||||
FILE *f_savelog = fopen(savelog,"a");\
|
||||
fprintf(f_savelog, "%s",buf);\
|
||||
fclose(f_savelog);\
|
||||
}\
|
||||
fprintf(F_OUT, "%s",buf);\
|
||||
}\
|
||||
fclose(stream);\
|
||||
free(buf);\
|
||||
}while(0)
|
||||
|
||||
|
||||
#define LOG(...) PRINTF(__VA_ARGS__)
|
||||
|
||||
#define PRINT_LOC(fmt, ...) \
|
||||
PRINTF( "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
|
||||
|
||||
#define PRINT_HK_C(color,hk,fmt,...)\
|
||||
PRINTF("%s%s%s" fmt, color,hk,colors_f[k_DEFAULT],__VA_ARGS__)
|
||||
|
||||
#define PRINT_DEBUG(fmt, ...)\
|
||||
do{ if(debug) PRINT_LOC(fmt, __VA_ARGS__);} while(0)
|
||||
|
||||
|
||||
/*
|
||||
* to skip the bloc test function
|
||||
*/
|
||||
#define SKIP(fmt,...)\
|
||||
PRINT_HK_C(colors_f[k_GREEN], tab_hk_f[hk_SK], fmt, ## __VA_ARGS__);\
|
||||
PRINT_LOC("%s\n\n" DEFAULT_K," Skiped "); return;
|
||||
|
||||
|
||||
|
||||
struct func {
|
||||
char *name;
|
||||
void (*run)(void);
|
||||
struct func *next;
|
||||
};
|
||||
|
||||
|
||||
extern bool is_parallel_nb;
|
||||
|
||||
long int id_of_thread_executed(void);
|
||||
|
||||
void parse_options(int argc, char **argv);
|
||||
|
||||
void run_all_tests();
|
||||
void execute_all(struct func *fun);
|
||||
void append_func(void (*run)(void), char *name);
|
||||
|
||||
char* extract_func_edited_TEST_from_exec_func_name(char* func_name); /* TEST_funcname___NUM -> TEST(funcname) */
|
||||
|
||||
/*
|
||||
void run_some_tests(size_t cnt, ... );
|
||||
void run_all_tests_exept(size_t cnt, ... );
|
||||
void run_some_tests_ordered(size_t cnt, ... );
|
||||
*/
|
||||
|
||||
void run_all_tests_parallel(size_t parallel /*, int max_col*/);
|
||||
|
||||
/*
|
||||
* to launch test with different parameters without re-compile it
|
||||
* it can print help if need!
|
||||
* */
|
||||
void run_all_tests_args(int argc, char **argv);
|
||||
|
||||
bool expected_true_f(bool val);
|
||||
bool expected_false_f(bool val);
|
||||
|
||||
bool expected_true_f_name(bool val, const char *name);
|
||||
bool expected_false_f_name(bool val, const char *name);
|
||||
|
||||
#define GEN_EXPECTED_OP_TYPE_FUNC(OP,type)\
|
||||
bool expected_##OP##_##type(type var1, type var2);\
|
||||
bool expected_##OP##_name_##type(type var1, type var2, const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions EQ ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end EQ generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions LT ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end LT generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions GT ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end GT generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions LE ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end LE generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions GE ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end GE generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions NE ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end NE generation ************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* only expect
|
||||
*/
|
||||
#define HANDLE_OP_EXPECT_NAME(OP,type,var1,var2,name_f,msg_call) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 %s passed %s \n\n",name_f,msg_call); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 %s failed %s \n",name_f,msg_call); \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, name_f)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 %s passed %s \n\n",name_f,msg_call); \
|
||||
/*PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed %s \n\n",name_f);*/ \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 %s failed %s \n",name_f,msg_call); \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
//#define EXPECT_OP_(OP,type,var1,var2) HANDLE_OP_EXPECT_(OP,type,var1,var2)
|
||||
|
||||
/**
|
||||
* old combined macros HANDLE_OP_EXPECT_ASSERT for ASSERT and EXPECT
|
||||
* is_assert : 0 for EXPECT and 1 for ASSERT
|
||||
*/
|
||||
#define HANDLE_OP_EXPECT_ASSERT(OP,type,var1,var2,is_assert) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
// *******************************************************************************************************************
|
||||
|
||||
/**
|
||||
* new HANDLE_OP_ EXPECT and ASSERT separated
|
||||
*/
|
||||
#define HANDLE_OP_EXPECT_(OP,type,var1,var2) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
#define HANDLE_OP_ASSERT_(OP,type,var1,var2) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
return; \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
|
||||
|
||||
// ********************************************************************************************************************
|
||||
|
||||
|
||||
// *********************** begin EQ ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_EQ_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_EQ(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_EQ_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_EQ(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end EQ **********************
|
||||
|
||||
|
||||
// *********************** begin LT ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_LT_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_LT_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_LT_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_LT_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_LT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_LT_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_LT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_LT_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_LT_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_LT_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_LT_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_LT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_LT_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_LT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end LT **********************
|
||||
|
||||
|
||||
// *********************** begin GT ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_GT_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_GT_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_GT_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_GT_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_GT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_GT_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_GT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_GT_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_GT_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_GT_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_GT_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_GT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_GT_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_GT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end GT **********************
|
||||
|
||||
|
||||
// *********************** begin LE ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_LE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_LE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_LE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_LE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_LE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_LE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_LE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_LE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_LE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_LE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_LE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_LE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_LE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_LE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end LE **********************
|
||||
|
||||
|
||||
// *********************** begin GE ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_GE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_GE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_GE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_GE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_GE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_GE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_GE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_GE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_GE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_GE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_GE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_GE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_GE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_GE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end GE **********************
|
||||
|
||||
|
||||
// *********************** begin NE ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_NE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_NE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_NE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_NE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_NE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_NE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_NE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_NE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_NE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_NE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_NE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_NE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_NE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_NE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end NE **********************
|
||||
|
||||
/*
|
||||
* ============== bool ===================
|
||||
* bellow old combined EXPECT and ASSERT macros
|
||||
*/
|
||||
|
||||
#define HANDLE_EXPECT_NOT_EXPECT_ASSERT(expect,not_expect,var1,is_assert) \
|
||||
do{ \
|
||||
if(is_parallel_nb==0){\
|
||||
if(expected_##expect##_f(var1)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}\
|
||||
else{\
|
||||
if(expected_##expect##_f_name(var1, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
// *******************************************************************************************************
|
||||
/*
|
||||
* new macro HANDEL ASSERT and EXPECT separated
|
||||
*/
|
||||
#define HANDLE_EXPECT_NOT_EXPECT_(expect,not_expect,var1) \
|
||||
do{ \
|
||||
if(is_parallel_nb==0){ \
|
||||
if(expected_##expect##_f(var1)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n\n",__func__); \
|
||||
} \
|
||||
} \
|
||||
else{ \
|
||||
size_t id_thread=id_of_thread_executed(); \
|
||||
if(expected_##expect##_f_name(var1, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s, on thread[%ld]\n\n",__func__,id_thread); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s, on thread[%ld]\n\n",__func__,id_thread); \
|
||||
} \
|
||||
} \
|
||||
}while(0);
|
||||
|
||||
|
||||
#define HANDLE_ASSERT_EXPECT_NOT_EXPECT_(expect,not_expect,var1) \
|
||||
do{ \
|
||||
if(is_parallel_nb==0){ \
|
||||
if(expected_##expect##_f(var1)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n\n",__func__); \
|
||||
return; \
|
||||
} \
|
||||
}\
|
||||
else{\
|
||||
size_t id_thread=id_of_thread_executed(); \
|
||||
if(expected_##expect##_f_name(var1, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s, on thread[%ld]\n\n",__func__,id_thread); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s, on thread[%ld]\n\n",__func__, id_thread); \
|
||||
return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
|
||||
// *******************************************************************************************************
|
||||
#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_(true, false, var1)
|
||||
#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_(false, true, var1)
|
||||
|
||||
#define ASSERT_TRUE(var1) HANDLE_ASSERT_EXPECT_NOT_EXPECT_(true, false, var1)
|
||||
#define ASSERT_FALSE(var1) HANDLE_ASSERT_EXPECT_NOT_EXPECT_(false, true, var1)
|
||||
|
||||
|
||||
//********************************************************************************
|
||||
|
||||
/*
|
||||
#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 0)
|
||||
#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 0)
|
||||
|
||||
#define ASSERT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 1)
|
||||
#define ASSERT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 1)
|
||||
*/
|
||||
|
||||
|
||||
#define CONCAT(x,y) x ## y
|
||||
#define STRFY(x) # x
|
||||
|
||||
//#define test_label test
|
||||
|
||||
#define FTEST_(count, name_f) \
|
||||
void CONCAT(test_##name_f##____,count)(void); \
|
||||
__attribute__((constructor)) \
|
||||
void CONCAT(append_test_##name_f,count)(void){ \
|
||||
append_func(CONCAT(test_##name_f##____,count),STRFY(name_f test count)); \
|
||||
} \
|
||||
void CONCAT(test_##name_f##____,count)(void)
|
||||
|
||||
#define FTEST__(count, name_f) \
|
||||
void CONCAT(TEST_##name_f##____,count)(void); \
|
||||
__attribute__((constructor)) \
|
||||
void CONCAT(append_test_##name_f,count)(void){ \
|
||||
append_func(CONCAT(TEST_##name_f##____,count),STRFY (TEST(name_f): test N° count| ) ); \
|
||||
} \
|
||||
void CONCAT(TEST_##name_f##____,count)(void)
|
||||
|
||||
|
||||
/*#define TEST(name_f)\
|
||||
FTEST_(__COUNTER__,name_f)
|
||||
*/
|
||||
|
||||
#define TEST(name_f) \
|
||||
FTEST__(__COUNTER__,name_f)
|
||||
|
||||
/*
|
||||
#define ASSERT_TRUE(val)\
|
||||
if(expected_true_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;}
|
||||
|
||||
#define ASSERT_FALSE(val)\
|
||||
if(expected_false_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;}
|
||||
*/
|
||||
|
||||
#endif /* __TEST_C_H__ */
|
||||
@@ -0,0 +1,127 @@
|
||||
#ifndef __TOOLS_T_C_H__
|
||||
#define __TOOLS_T_C_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
// to define DEBUG in gcc cli do: gcc -D DEBUG=1 or 0 if need!
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
// F_OUT file (stream) to log
|
||||
#ifndef F_OUT
|
||||
#define F_OUT stdout
|
||||
#endif
|
||||
// F_ERR file (stream) to log
|
||||
#ifndef F_ERR
|
||||
#define F_ERR stderr
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#ifndef SECOND
|
||||
#define SECOND 0
|
||||
#endif
|
||||
#ifndef NANOSECOND
|
||||
#define NANOSECOND 0
|
||||
#endif
|
||||
|
||||
double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start);
|
||||
double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start);
|
||||
long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start);
|
||||
*/
|
||||
|
||||
void gotoxy(int x, int y);
|
||||
//void get_cursor_position(int *col, int *rows);
|
||||
|
||||
#if DEBUG
|
||||
|
||||
#define debug_print(fmt, ...) \
|
||||
do { /*if (DEBUG)*/ fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__); } while (0)
|
||||
|
||||
#define PRINT_DEBUG_(fmt, ...) \
|
||||
do { /*if (DEBUG)*/ fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__); } while (0)
|
||||
|
||||
#else
|
||||
#define debug_print(fmt, ...) {}
|
||||
|
||||
#define PRINT_DEBUG_(fmt, ...) {}
|
||||
|
||||
#endif
|
||||
|
||||
#define error_print(fmt, ...) \
|
||||
fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__);
|
||||
|
||||
#define PRINT_ERROR(fmt, ...) \
|
||||
fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__);
|
||||
|
||||
#define PRINT_LOC_T(fmt, ...) \
|
||||
fprintf(F_OUT, "%s:%d:%s(): " fmt, __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__);
|
||||
|
||||
|
||||
|
||||
#define TYPE_CHAR char
|
||||
#define TYPE_U_CHAR unsigned char
|
||||
#define TYPE_INT int
|
||||
#define TYPE_U_INT unsigned int
|
||||
#define TYPE_L_INT long int
|
||||
#define TYPE_U_L_INT unsigned long int
|
||||
#define TYPE_SIZE_T size_t
|
||||
#define TYPE_FLOAT float
|
||||
#define TYPE_DOUBLE double
|
||||
#define TYPE_L_DOUBLE long double
|
||||
#define TYPE_STRING char*
|
||||
|
||||
#define FREE(x) { free((x)); (x) = NULL;}
|
||||
|
||||
#define FOREACH(array, size, function)\
|
||||
for(size_t _ind = 0; _ind < size; ++_ind) function(array[_ind]);
|
||||
|
||||
|
||||
#define GENERATE_ALL(type)\
|
||||
int COMPARE_N_##type(const void *,const void*);\
|
||||
void COPY_ARRAY_##type(type* dst, const type* src, size_t size);\
|
||||
type MAX_ARRAY_##type(const type *array, size_t size);\
|
||||
size_t ARG_MAX_ARRAY_##type(const type *array, size_t size);\
|
||||
type MIN_ARRAY_##type(const type *array, size_t size);\
|
||||
size_t ARG_MIN_ARRAY_##type(const type *array, size_t size);\
|
||||
TYPE_STRING type##_TO_STR(type var);\
|
||||
|
||||
|
||||
GENERATE_ALL(TYPE_CHAR)
|
||||
GENERATE_ALL(TYPE_U_CHAR)
|
||||
GENERATE_ALL(TYPE_INT)
|
||||
GENERATE_ALL(TYPE_U_INT)
|
||||
GENERATE_ALL(TYPE_L_INT)
|
||||
GENERATE_ALL(TYPE_U_L_INT)
|
||||
GENERATE_ALL(TYPE_SIZE_T)
|
||||
GENERATE_ALL(TYPE_FLOAT)
|
||||
GENERATE_ALL(TYPE_DOUBLE)
|
||||
GENERATE_ALL(TYPE_L_DOUBLE)
|
||||
GENERATE_ALL(TYPE_STRING)
|
||||
|
||||
|
||||
/*
|
||||
* time calucl
|
||||
*/
|
||||
double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start);
|
||||
|
||||
double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start);
|
||||
|
||||
long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start);
|
||||
|
||||
|
||||
#endif /*__TOOLS_T_C_H__*/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
cp libytest.so /usr/lib/
|
||||
if [ -d /usr/local/include ] ; then
|
||||
echo "copy include to /usr/local/include/" ;
|
||||
cp -r include_ytest/include/* /usr/local/include/;
|
||||
else
|
||||
echo "copy include to /usr/include/" ;
|
||||
cp -r include_ytest/include/* /usr/include/;
|
||||
fi
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
for yfile in y*
|
||||
do
|
||||
cp -r "$yfile/include" include_ytest/
|
||||
done
|
||||
|
||||
if [ "$#" -le 0 ] ; then
|
||||
echo "Usage: $0" >&2
|
||||
echo "we can add more option for example '-D DEBUG=1' to have debug print of PRINT_DEBUG_ (tools_t macro), notice that PRINT_DEBUG is provide by ytest and can be activate with --debug option on runtime.\n The other compile option is '-g' to have gbd", and so on..>&2
|
||||
echo "for example: $0 \"-D DEBUG=1 -g\""
|
||||
fi
|
||||
|
||||
|
||||
gcc -c -Wall -Werror -fpic yftest/src/ftest/ftest.c yfmock/src/fmock/fmock.c \
|
||||
ytools_t/src/tools_t/tools_t.c ybar_progress/src/bar_progress/bar_progress.c \
|
||||
-I./include_ytest/include $1 -lpthread
|
||||
|
||||
gcc -shared -o libytest.so *.o
|
||||
|
||||
rm *.o
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
export CPATH=$PWD/include_ytest/include:$CPATH
|
||||
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
|
||||
|
||||
if [ "$#" -le 0 ] ; then
|
||||
echo "if need permanent config"
|
||||
echo "Usage: $0 file_name" >&2
|
||||
echo "for example: $0 ~/.bashrc" >&2
|
||||
echo "or an other bash profile, here it is \"~/.bashrc\" for example"
|
||||
else
|
||||
echo "export CPATH=$PWD/include_ytest/include:\$CPATH" >> $1
|
||||
echo "export LD_LIBRARY_PATH=$PWD:\$LD_LIBRARY_PATH" >> $1
|
||||
source $1
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
|
||||
|
||||
NAME_TEST=is_good
|
||||
CC=gcc
|
||||
ROOT_DIR=$(PWD)
|
||||
INCLUDE_DIR=$(ROOT_DIR)/src
|
||||
CFLAGS=-I$(INCLUDE_DIR) -I../include_ytest/include
|
||||
LDFLAGS=-L$(PWD)/.. -lytest
|
||||
|
||||
#SRC_DIR=$(ROOT_DIR)/src
|
||||
#SRC=$(wildcard */*/*.c)
|
||||
SRC=$(wildcard **/**/*.c)
|
||||
OBJ=$(SRC:.c=.o)
|
||||
#HEADS=$(OBJS:.o=.h)
|
||||
TEST_DIR=$(PWD)
|
||||
EXECSRC=$(NAME_TEST).c
|
||||
EXEC=launch_$(NAME_TEST)_m
|
||||
LIB_YTEST=$(PWD)/../libytest.so
|
||||
|
||||
all: $(EXEC) $(LIB_YTEST)
|
||||
|
||||
$(EXEC): $(EXECSRC) $(OBJ)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
.PHONY: clean mrproper
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ)
|
||||
|
||||
mrproper: clean
|
||||
rm -f $(EXEC)
|
||||
|
||||
run: $(EXEC)
|
||||
$(EXEC) -h
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -le 0 ] ; then
|
||||
echo "Usage: $0 is_good.c" >&2
|
||||
echo "for example to compile: is_good.c" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$#" -le 1 ] ; then
|
||||
echo "Usage: $0 $1" >&2
|
||||
echo "we can add more option for example '-D DEBUG=1' to have debug print of PRINT_DEBUG_ (tools_t macro), notice that PRINT_DEBUG is provide by ytest and can be activate with --debug option on runtime."
|
||||
echo "The other compile option is '-g' to have gbd, and so on..."
|
||||
echo "for example: $0 $1 \"-D DEBUG=1 -g\""
|
||||
fi
|
||||
|
||||
|
||||
gcc -o launch_is_good_c $1 -L$PWD/../ $2 -lytest -I../include_ytest/include
|
||||
|
||||
export LD_LIBRARY_PATH=$PWD/../:LD_LIBRARY_PATH
|
||||
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// for sleep !
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#elif _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "ftest/ftest.h"
|
||||
#include "fmock/fmock.h"
|
||||
|
||||
TEST(true__){
|
||||
PRINTF("another test again false\n");
|
||||
bool val_bool = false;
|
||||
ASSERT_TRUE(val_bool);
|
||||
}
|
||||
TEST(test)
|
||||
{
|
||||
PRINTF("test test\n");
|
||||
bool val_bool = true;
|
||||
ASSERT_FALSE(val_bool);
|
||||
|
||||
}
|
||||
TEST(float_equal){
|
||||
PRINTF("another test float\n");
|
||||
ASSERT_TRUE(true);
|
||||
float a = 1.00001f;
|
||||
float b = 1.00001f;
|
||||
ASSERT_EQ_TYPE_FLOAT(a,b);
|
||||
b=1.0000101f;
|
||||
ASSERT_EQ_TYPE_FLOAT(a,b);
|
||||
ASSERT_EQ_TYPE_FLOAT(1.0000102f,b);
|
||||
}
|
||||
TEST(double_equal){
|
||||
PRINTF("another test double\n");
|
||||
ASSERT_TRUE(true);
|
||||
double a = 1.00000001;
|
||||
double b = 1.00000001;
|
||||
ASSERT_EQ_TYPE_DOUBLE(a,b);
|
||||
b=1.00000001000000001;
|
||||
ASSERT_EQ_TYPE_DOUBLE(a,b);
|
||||
ASSERT_EQ_TYPE_DOUBLE(1.0000000100000002,b);
|
||||
}
|
||||
|
||||
TEST(){
|
||||
unsigned char c = 'a';
|
||||
|
||||
debug_print("another test, a = %c\n",c);
|
||||
ASSERT_FALSE(true);
|
||||
ASSERT_TRUE(true);
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
|
||||
TEST(){
|
||||
sleep(3);
|
||||
int a = 5;
|
||||
long b = 5;
|
||||
ASSERT_EQ(a,b);
|
||||
a=4;
|
||||
ASSERT_EQ(a,b);
|
||||
|
||||
}
|
||||
|
||||
TEST(expect){
|
||||
sleep(2);
|
||||
int a = 5;
|
||||
int b = 6;
|
||||
EXPECT_EQ(a,b);
|
||||
// SKIP();
|
||||
SKIP("%s\n","on skip eq string");
|
||||
EXPECT_EQ_TYPE_STRING("hello","hello");
|
||||
float f1 = 1.00019999, f2=1.00019999;
|
||||
EXPECT_EQ_TYPE_FLOAT(f1,f2);
|
||||
|
||||
}
|
||||
|
||||
TEST(){
|
||||
PRINTF("no test, only print\n");
|
||||
}
|
||||
|
||||
TEST(){
|
||||
PRINTF("no test, only print\n");
|
||||
}
|
||||
|
||||
TEST(){
|
||||
PRINTF("no test, only print\n");
|
||||
}
|
||||
|
||||
|
||||
TEST(lessThan){
|
||||
long int a=1,b=2;
|
||||
EXPECT_LT(a,b);
|
||||
EXPECT_LT(b,a);
|
||||
|
||||
}
|
||||
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
|
||||
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
TEST(sleep){sleep(1);}
|
||||
|
||||
|
||||
MOCK_FUNC(int, f_mock, (), ())
|
||||
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),false, 2) {
|
||||
EXPECT_EQ_IN_MOCKF(21,21,f_mock);
|
||||
EXPECT_EQ(1,3);
|
||||
EXPECT_EQ(4,4);
|
||||
EXPECT_EQ_IN_MOCKF(23,24,f_mock); return 12;}
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),1, 1) { EXPECT_EQ_IN_MOCKF(23,21,f_mock);return 10;}
|
||||
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),1==2||2<1, 1) {return 18;}
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),1, INFINITY) {return -18;}
|
||||
|
||||
TEST(mockf1){
|
||||
INIT_CALLER_MOCK(f_mock);
|
||||
|
||||
for(int i = 0; i<8; ++i){
|
||||
|
||||
LOG("call f_mock:%d: ret:%d\n",i,f_mock());
|
||||
// int val=f_mock();
|
||||
//PRINTF("call f_mock:%d: ret:%d\n",i,val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MOCK_FUNC(int, f2_mock,(int a,int b),(a,b))
|
||||
|
||||
STR_PRINT_CUR_VAR(f2_mock, (int a,int b),(a,b)){
|
||||
char *ret=malloc(150);
|
||||
//char ret[150];
|
||||
sprintf(ret,"(int)a: %d, (int)b: %d",a,b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (a<b), 3){
|
||||
return a+b;
|
||||
}
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), ((a<b)&&(b<100)), 1){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
WILL_MOCK_CALL(int, f2_mock, (int a,int b), (a!=b), 6){
|
||||
return a/b;
|
||||
}
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (a==b), 1){
|
||||
return a/b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MOCK_FUNC(int, f3_mock,(int a,int b),(a,b))
|
||||
|
||||
EXPECT_MOCK_CALL(int, f3_mock, (int a,int b), (a<b), 2){
|
||||
return a+b;
|
||||
}
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), ((a<b)&&(b<100)), 1){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
WILL_MOCK_CALL(int, f2_mock, (int a,int b), (a!=b), 6){
|
||||
return a/b;
|
||||
}
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (a==b), 1){
|
||||
return a/b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (1), INFINITY){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
TEST(f2mock_test){
|
||||
INIT_CALLER_MOCK(f2_mock);
|
||||
//LOG("--------------------------- > call f2_mock:%d: %d\n",0,f2_mock(1,4));
|
||||
|
||||
|
||||
for(int i=0; i<8; ++i){
|
||||
|
||||
if(i<2) {
|
||||
//int val = f2_mock(i,4);
|
||||
//LOG("call f2_mock:%d: %d\n",i,val);
|
||||
LOG("call f2_mock:%d: %d\n",i,f2_mock(i,4));
|
||||
|
||||
}
|
||||
else if(i<4) LOG("call:%d: %d\n",i,f2_mock(i,3));
|
||||
else LOG("call:%d:%d\n",i,f2_mock(i,i*i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST(f3_mock_test){
|
||||
INIT_CALLER_MOCK(f3_mock);
|
||||
|
||||
|
||||
for(int i=0; i<7; ++i){
|
||||
|
||||
if(i<1) {
|
||||
LOG("call f3_mock:%d: %d\n",i,f3_mock(1,i));
|
||||
|
||||
}
|
||||
else LOG("call:%d:%d\n",i,f3_mock(i,i*i));
|
||||
}
|
||||
for(int i=COLOR_SZ-1; i>=0; --i)
|
||||
LOG("%s colors_fld\n",colors_f[i]);
|
||||
|
||||
}
|
||||
|
||||
MOCK_FUNC(int, f4_mock,(int a,int b),(a,b))
|
||||
STR_PRINT_CUR_VAR(f4_mock, (int a,int b),(a,b)){
|
||||
char *ret=malloc(150);
|
||||
//char ret[150];
|
||||
sprintf(ret,"(int)a: %d, (int)b: %d",a,b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
TEST(f4_mock_test){
|
||||
//EXPECT_EQ(1,f4_mock(1,1));
|
||||
PRINTF("f4 no excepted create ret: %d\n",f4_mock(1,1));
|
||||
PRINTF("second call f4 : %d\n",f4_mock(2,0));
|
||||
|
||||
}
|
||||
|
||||
MOCK_FUNC(int, f5_mock,(int a,int b, int c),(a,b,c))
|
||||
|
||||
TEST(f5__mock){
|
||||
LOG("f5 ???:%d\n",f5_mock(1,2,3));
|
||||
LOG("f5 !!!:%d\n",f5_mock(2,5,3));
|
||||
}
|
||||
|
||||
MOCK_FUNC(int, f6_mock,(int a,int b, int c),(a,b,c))
|
||||
STR_PRINT_CUR_VAR(f6_mock,(int a,int b, int c),(a,b,c)){
|
||||
char *ret=malloc(150);
|
||||
sprintf(ret,"(%d,%d,%d)",a,b,c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPECT_MOCK_CALL(int, f6_mock,(int a, int b, int c),((a<b)&&(b<c)),1){
|
||||
return a+b+c;
|
||||
}
|
||||
|
||||
TEST(f6__mock){
|
||||
LOG("f6 6?:%d\n",f6_mock(1,2,3));
|
||||
LOG("f6 0?:%d\n",f6_mock(2,5,4));
|
||||
}
|
||||
|
||||
|
||||
MOCK_FUNC(int, f7_mock,(int a,int b),(a,b))
|
||||
STR_PRINT_CUR_VAR(f7_mock, (int a,int b),(a,b)){
|
||||
char *ret=malloc(150);
|
||||
//char ret[150];
|
||||
sprintf(ret,"(int)a: %d, (int)b: %d",a,b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPECT_MOCK_CALL(int, f7_mock,(int a, int b),(a>b),2){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
|
||||
TEST(f7_mock_test){
|
||||
int v0=f7_mock(1,1);
|
||||
PRINTF("f7 ret: %d\n",v0);
|
||||
int v1=f7_mock(2,0);
|
||||
PRINTF("second call f7 : %d\n",v1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
//run_all_tests();
|
||||
//run_all_tests_parallel(4);
|
||||
|
||||
run_all_tests_args(argc, argv);
|
||||
|
||||
//purge_tests();
|
||||
//run_some_tests(8, 1, 2, 2, 3, 3, 0, 4, 1);
|
||||
//run_some_tests(8, 5, 7, 1, 1, 1, 1, 1, 1);
|
||||
//run_some_tests_one_by_one(3, 1, 2, 2);
|
||||
//run_all_tests_exept(2, 1, 3);
|
||||
return 0;
|
||||
}
|
||||
Executable
+652
@@ -0,0 +1,652 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/src/tensor/tens0neD/tens0neD.h"
|
||||
#include "src/tensor/tens0neD/tens0neD.h"
|
||||
//#include "cudatensor.h"
|
||||
//#include "/home/fanasina/progr_/ptens0neD/src/tensor/tensCuda/tensCuda.h"
|
||||
#include "src/tensor/tensCuda/tensCuda.h"
|
||||
/*TEST(LineraCoodTransform, check_print) {
|
||||
int t3[] = { [0] = 2,[1] = 4,[2] = 3 };
|
||||
|
||||
struct dimension D0(3, t3);
|
||||
int coor0[3] = { 1,3,2 };
|
||||
int* coor1 = new int[3];
|
||||
|
||||
int l0 = D0.CoordToLinear(coor0);
|
||||
|
||||
D0.print();
|
||||
|
||||
D0.LinearToCoord(coor1, l0);
|
||||
|
||||
for (int i = 0; i < D0.rank; i++) {
|
||||
EXPECT_EQ(coor0[i], coor1[i]) << " coor0: " << coor0[i] << " coor1: " << coor1[i] << " i: " << i;
|
||||
}
|
||||
}*/
|
||||
|
||||
TEST(subArray, concatArray) {
|
||||
int t[] = { 1,5,6,2,3 };
|
||||
int t0[] = { 1,5,6 };
|
||||
int t1[] = { 2,3 };
|
||||
int n = 5;
|
||||
int s0[3];
|
||||
int s1[2];
|
||||
int s[n];
|
||||
|
||||
subArray(s0, t, 0, 3, 0);
|
||||
subArray(s1, t, 0, 2, 3);
|
||||
ASSERT_EQ(0, memcmp(t0, s0, sizeof(int) * 3));
|
||||
ASSERT_EQ(0, memcmp(t1, s1, sizeof(int) * 2));
|
||||
|
||||
concatArray(s, s0, s1, 0, 0, 3, 0, 2);
|
||||
ASSERT_EQ(0, memcmp(t, s, sizeof(int) * 5));
|
||||
|
||||
}
|
||||
TEST(tensorProdpetit, floatTemp) {
|
||||
|
||||
/*int t3[] = { 2, 4, 3 };
|
||||
|
||||
int t4[] = { 2, 4, 3, 2 };*/
|
||||
int t3[] = { 3, 6, 5 };
|
||||
|
||||
int t4[] = { 3, 5, 8, 4 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<float> M3(d3), M4(d4), M;
|
||||
M3.initVal(3.0f); // M3.print();
|
||||
M4.initVal(2.0f); // M4.print();
|
||||
|
||||
tensorProd<float>(M, M3, M4);
|
||||
//tensorProd(M, M4, M3);
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
d = M.Dim;
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
for (int i = 0; i < d3.rank; i++) coord3[i] = idx3[i];
|
||||
for (int i = 0; i < d4.rank; i++) coord4[i] = idx4[i];
|
||||
|
||||
concatArray(coord, coord3, coord4, 0, 0, d3.rank, 0, d4.rank);
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
lin = d.CoordToLinear(coord);
|
||||
|
||||
//ASSERT_FLOAT_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
ASSERT_FLOAT_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
//ASSERT_NEAR(M.elements[lin], M3.elements[lin3] * M4.elements[lin4], 0.0001) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST(tensorProd, doubleTemp) {
|
||||
|
||||
int t3[] = { 2, 4, 3 };
|
||||
|
||||
int t4[] = { 4, 3, 2,3 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<double> M3(d3), M4(d4), M;
|
||||
M3.initVal(3.0f); // M3.print();
|
||||
M4.initVal(2.0f); // M4.print();
|
||||
|
||||
tensorProd(M, M3, M4);
|
||||
//tensorProd(M, M4, M3);
|
||||
d = M.Dim;
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
for (int i = 0; i < d3.rank; i++) coord3[i] = idx3[i];
|
||||
for (int i = 0; i < d4.rank; i++) coord4[i] = idx4[i];
|
||||
|
||||
concatArray(coord, coord3, coord4, 0, 0, d3.rank, 0, d4.rank);
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
lin = d.CoordToLinear(coord);
|
||||
|
||||
//ASSERT_FLOAT_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]);
|
||||
ASSERT_DOUBLE_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]);
|
||||
//ASSERT_NEAR(M.elements[lin], M3.elements[lin3] * M4.elements[lin4], 0.001) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void printArray(int* t, int sz) {
|
||||
for (int i = 0; i < sz;i++) printf(" %d ", t[i]);
|
||||
}
|
||||
|
||||
TEST(tensorContractnProd, floatTemp) {
|
||||
|
||||
int t3[] = { 2, 4, 3 };
|
||||
|
||||
int t4[] = { 4, 3, 2, 3 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<float> M3(d3), M4(d4), M;
|
||||
M3.initVal(3.0f); // M3.print();
|
||||
M4.initVal(2.0f); // M4.print();
|
||||
|
||||
int dee = 2;
|
||||
|
||||
try {
|
||||
//tensorContractnProd(M, M3, M4, dee);
|
||||
tensorContractnProd(M, M3, M4, dee);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
printf("bye from test tensorContractnProd floatTemp invalid arg! deep:\n");
|
||||
dimension dM;
|
||||
extractDimNestingDepth(dM, d3, d4, dee);
|
||||
dM.print();
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int l0, l1;
|
||||
l0 = M3.Dim.rank - dee;
|
||||
l1 = M4.Dim.rank - dee;
|
||||
int pcoord3[l0];
|
||||
int pcoord4[l1];
|
||||
int r[dee];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
d = M.Dim;
|
||||
d.print();
|
||||
|
||||
Tensor<float> Msum(d);
|
||||
//for (size_t idx = 0; idx < d.size; idx++) Msum.elements[idx] = 0.0f;
|
||||
|
||||
//Msum.print();
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
|
||||
for (int i = 0; i < l0; i++) pcoord3[i] = idx3[i];
|
||||
for (int i = 0; i < l1; i++) pcoord4[i] = idx4[i + dee];
|
||||
concatArray(coord, pcoord3, pcoord4, 0, 0, l0, 0, l1);
|
||||
lin = d.CoordToLinear(coord);
|
||||
Msum.elements[lin] = 0.0f;
|
||||
//for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
//for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
{
|
||||
for (int i = 0; i < dee; i++) r[i] = idx4[i];
|
||||
|
||||
concatArray(coord3, pcoord3, r, 0, 0, l0, 0, dee);
|
||||
concatArray(coord4, r, pcoord4, 0, 0, dee, 0, l1);
|
||||
//printf("[");printArray(coord3, M3.Dim.rank); printf("]["); printArray(coord4, M4.Dim.rank);printf("] =*= ("); printArray(coord, Msum.Dim.rank); printf(") |||");
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
|
||||
Msum.elements[lin] += (M3.elements[lin3] * M4.elements[lin4]);
|
||||
//printf("lin:%d lin3:%d lin4:%d el+:%f\n", lin, lin3, lin4, Msum.elements[lin]);
|
||||
|
||||
}
|
||||
|
||||
ASSERT_FLOAT_EQ(Msum.elements[lin], M.elements[lin]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST(tensorContractnProdD, doubleTemp) {
|
||||
|
||||
int t3[] = { 2, 3, 4 };
|
||||
|
||||
int t4[] = { 3, 4, 2, 3 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<double> M3(d3), M4(d4), M;
|
||||
M3.initVal(3.0f); // M3.print();
|
||||
M4.initVal(2.0f); // M4.print();
|
||||
|
||||
int dee = 2;
|
||||
|
||||
try {
|
||||
//tensorContractnProd(M, M3, M4, dee);
|
||||
tensorContractnProd(M, M3, M4, dee);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
printf("bye from test tensorContractnProd floatTemp invalid arg! deep:\n");
|
||||
dimension dM;
|
||||
extractDimNestingDepth(dM, d3, d4, dee);
|
||||
dM.print();
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int l0, l1;
|
||||
l0 = M3.Dim.rank - dee;
|
||||
l1 = M4.Dim.rank - dee;
|
||||
int pcoord3[l0];
|
||||
int pcoord4[l1];
|
||||
int r[dee];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
d = M.Dim;
|
||||
d.print();
|
||||
|
||||
Tensor<double> Msum(d);
|
||||
//for (size_t idx = 0; idx < d.size; idx++) Msum.elements[idx] = 0.0f;
|
||||
|
||||
//Msum.print();
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
|
||||
for (int i = 0; i < l0; i++) pcoord3[i] = idx3[i];
|
||||
for (int i = 0; i < l1; i++) pcoord4[i] = idx4[i + dee];
|
||||
concatArray(coord, pcoord3, pcoord4, 0, 0, l0, 0, l1);
|
||||
lin = d.CoordToLinear(coord);
|
||||
Msum.elements[lin] = 0.0f;
|
||||
//for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
//for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
{
|
||||
for (int i = 0; i < dee; i++) r[i] = idx4[i];
|
||||
|
||||
concatArray(coord3, pcoord3, r, 0, 0, l0, 0, dee);
|
||||
concatArray(coord4, r, pcoord4, 0, 0, dee, 0, l1);
|
||||
//printf("[");printArray(coord3, M3.Dim.rank); printf("]["); printArray(coord4, M4.Dim.rank);printf("] =*= ("); printArray(coord, Msum.Dim.rank); printf(") |||");
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
|
||||
Msum.elements[lin] += (M3.elements[lin3] * M4.elements[lin4]);
|
||||
//printf("lin:%d lin3:%d lin4:%d el+:%f\n", lin, lin3, lin4, Msum.elements[lin]);
|
||||
|
||||
}
|
||||
|
||||
ASSERT_DOUBLE_EQ(Msum.elements[lin], M.elements[lin]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST(reverseArray, innt) {
|
||||
int n = 6;
|
||||
int t4[6] = { 3, 4, 2, 3 ,5, 1 };
|
||||
int revt4[6] = { 1,5,3,2, 4, 3 };
|
||||
reverseArray(t4, n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
ASSERT_EQ(t4[i], revt4[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(tensorContractnReverseProd, floatTemp) {
|
||||
|
||||
int t3[] = { 4, 4, 3 };
|
||||
|
||||
int t4[] = { 3, 4, 7, 2 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<float> M3(d3), M4(d4), M;
|
||||
M3.initVal(3.0f); // M3.print();
|
||||
M4.initVal(2.0f); // M4.print();
|
||||
|
||||
int dee = 2;
|
||||
|
||||
try {
|
||||
//tensorContractnProd(M, M3, M4, dee);
|
||||
tensorContractnReverseProd(M, M3, M4, dee);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
printf("bye from test tensorContractnProd floatTemp invalid arg! deep:\n");
|
||||
dimension dM;
|
||||
extractDimNestingDepth(dM, d3, d4, dee);
|
||||
dM.print();
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int l0, l1;
|
||||
l0 = M3.Dim.rank - dee;
|
||||
l1 = M4.Dim.rank - dee;
|
||||
int pcoord3[l0];
|
||||
int pcoord4[l1];
|
||||
int r[dee];
|
||||
int rev[dee];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
d = M.Dim;
|
||||
d.print();
|
||||
|
||||
Tensor<float> Msum(d);
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
|
||||
for (int i = 0; i < l0; i++) pcoord3[i] = idx3[i];
|
||||
for (int i = 0; i < l1; i++) pcoord4[i] = idx4[i + dee];
|
||||
concatArray(coord, pcoord3, pcoord4, 0, 0, l0, 0, l1);
|
||||
lin = d.CoordToLinear(coord);
|
||||
Msum.elements[lin] = 0.0f;
|
||||
//for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
//for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
{
|
||||
for (int i = 0; i < dee; i++) {
|
||||
r[i] = idx4[i];
|
||||
rev[i] = idx4[dee - 1 - i];
|
||||
}
|
||||
|
||||
concatArray(coord3, pcoord3, rev, 0, 0, l0, 0, dee);
|
||||
concatArray(coord4, r, pcoord4, 0, 0, dee, 0, l1);
|
||||
//printf("[");printArray(coord3, M3.Dim.rank); printf("]["); printArray(coord4, M4.Dim.rank);printf("] =*= ("); printArray(coord, Msum.Dim.rank); printf(") |||");
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
|
||||
Msum.elements[lin] += (M3.elements[lin3] * M4.elements[lin4]);
|
||||
//printf("lin:%d lin3:%d lin4:%d el+:%f\n", lin, lin3, lin4, Msum.elements[lin]);
|
||||
}
|
||||
ASSERT_FLOAT_EQ(Msum.elements[lin], M.elements[lin]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(cudaTensorProd, floatTemp) {
|
||||
|
||||
int t3[] = { 15, 6, 24 };
|
||||
|
||||
int t4[] = { 23, 15, 6, 10 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<float> M3(d3), M4(d4), M;
|
||||
M3.initVal(1.0f); // M3.print();
|
||||
M4.initVal(0.5f); // M4.print();
|
||||
|
||||
cudaTensorProd(M, M3, M4);
|
||||
//tensorProd(M, M4, M3);
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
d = M.Dim;
|
||||
d.print();
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
for (int i = 0; i < d3.rank; i++) coord3[i] = idx3[i];
|
||||
for (int i = 0; i < d4.rank; i++) coord4[i] = idx4[i];
|
||||
|
||||
concatArray(coord, coord3, coord4, 0, 0, d3.rank, 0, d4.rank);
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
lin = d.CoordToLinear(coord);
|
||||
|
||||
//ASSERT_FLOAT_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
|
||||
//ASSERT_FLOAT_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
ASSERT_FLOAT_EQ(M.elements[lin], M3.elements[lin3] * M4.elements[lin4]) << " M " << M.elements[lin] << " lin: " << lin << " M3: " << M3.elements[lin3] << " lin3:" << lin3 << " lin4: " << lin4 << " M4 " << M4.elements[lin4] << std::endl;
|
||||
//std::cout << " M " << M.elements[lin] << " lin: " << lin << " M3: " << M3.elements[lin3] << " lin3:" << lin3 << " lin4: " << lin4 << " M4 " << M4.elements[lin4] << std::endl;
|
||||
|
||||
//ASSERT_NEAR(M.elements[lin], M3.elements[lin3] * M4.elements[lin4], 0.0001) << " lin: " << lin << " lin3: " << lin3 << " lin4: " << lin4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST(permuteTensor, float) {
|
||||
int t4[] = { 3, 8, 2, 4 };
|
||||
struct dimension d4(4, t4);
|
||||
struct Tensor<float> M4(d4), M;
|
||||
M4.initVal(1.0f);
|
||||
permutation p(4, true);
|
||||
int n = 5;
|
||||
//for (int n = 0; n < 24;n++) {
|
||||
PlaceToTab(p.perm, n, p.size);
|
||||
printf(" %*d : ", 2, n);
|
||||
for (int i = 0; i < p.size; i++)printf("(%d)%d ", i, p.perm[i]);printf("\n");
|
||||
permuteTensor(M, M4, p);
|
||||
//permuteTensorDef(M, M4, p);
|
||||
int ind[4];
|
||||
int coor[4];
|
||||
size_t cM, cM4;
|
||||
for (ind[0] = 0; ind[0] < M4.Dim.dim[0]; ind[0]++)
|
||||
for (ind[1] = 0; ind[1] < M4.Dim.dim[1]; ind[1]++)
|
||||
for (ind[2] = 0; ind[2] < M4.Dim.dim[2]; ind[2]++)
|
||||
for (ind[3] = 0; ind[3] < M4.Dim.dim[3]; ind[3]++) {
|
||||
p.permute(coor, ind);
|
||||
cM = M.Dim.CoordToLinear(coor);
|
||||
cM4 = M4.Dim.CoordToLinear(ind);
|
||||
//printf("M[%ld]=%f M4[%ld]=%f \n", cM, M.elements[cM], cM4, M4.elements[cM4]);
|
||||
ASSERT_FLOAT_EQ(M.elements[cM], M4.elements[cM4]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST(cudapermuteTensor, float) {
|
||||
int t4[] = { 3, 8, 2, 4 };
|
||||
struct dimension d4(4, t4);
|
||||
struct Tensor<float> M4(d4), M;
|
||||
M4.initVal(1.0f);
|
||||
permutation p(4, true);
|
||||
int n = 5;
|
||||
//for (int n = 0; n < 24;n++) {
|
||||
PlaceToTab(p.perm, n, p.size);
|
||||
printf(" %*d : ", 2, n);
|
||||
for (int i = 0; i < p.size; i++)printf("{%d}%d ", i, p.perm[i]);printf("\n");
|
||||
cudapermuteTensor(M, M4, p);
|
||||
//permuteTensor(M, M4, p);
|
||||
//permuteTensorDef(M, M4, p);
|
||||
int ind[4];
|
||||
int coor[4];
|
||||
size_t cM, cM4;
|
||||
for (ind[0] = 0; ind[0] < M4.Dim.dim[0]; ind[0]++)
|
||||
for (ind[1] = 0; ind[1] < M4.Dim.dim[1]; ind[1]++)
|
||||
for (ind[2] = 0; ind[2] < M4.Dim.dim[2]; ind[2]++)
|
||||
for (ind[3] = 0; ind[3] < M4.Dim.dim[3]; ind[3]++) {
|
||||
p.permute(coor, ind);
|
||||
cM = M.Dim.CoordToLinear(coor);
|
||||
cM4 = M4.Dim.CoordToLinear(ind);
|
||||
//printf("M[%ld]=%f M4[%ld]=%f \n", cM, M.elements[cM], cM4, M4.elements[cM4]);
|
||||
ASSERT_FLOAT_EQ(M.elements[cM], M4.elements[cM4]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(scanPermuteMatchContractTensorfromSrcToDst1, permId) {
|
||||
int t[] = { 3, 8, 2, 3, 4 };
|
||||
//int tm[] = { 4, 2, 7, 3 };
|
||||
int tm[] = { 2, 3,4,7 };
|
||||
struct dimension d(5, t);
|
||||
struct dimension dm(4, tm);
|
||||
struct Tensor<float> M4(d), M(dm);
|
||||
M4.initVal(1.0f);
|
||||
M.initVal(1.0f);
|
||||
int dee = 3;
|
||||
//int result[4] = { 1,3,0,2 };
|
||||
int result[4] = { 0,1,2,3 };
|
||||
int perm[M.Dim.rank];
|
||||
ASSERT_TRUE(scanPermuteMatchContractTensorfromSrcToDst(perm, M, M4, dee));
|
||||
for (int i = 0; i < M.Dim.rank; i++) printf(" %d[%d] ", i, perm[i]); printf(" first perm \n");
|
||||
ASSERT_EQ(0, memcmp(result, perm, sizeof(int) * M.Dim.rank));
|
||||
|
||||
Tensor<float> tM;
|
||||
permutation p(M.Dim.rank, perm);
|
||||
permuteTensor(tM, M, p);
|
||||
|
||||
ASSERT_FALSE(scanPermuteMatchContractTensorfromSrcToDst(perm, M, M4, 4));
|
||||
for (int i = 0; i < M.Dim.rank; i++) printf(" %d[%d] ", i, perm[i]); printf(": last perm \n");
|
||||
tM.Dim.print();
|
||||
int resultDim[] = { 2,3,4,7 };
|
||||
ASSERT_EQ(0, memcmp(resultDim, tM.Dim.dim, sizeof(int) * tM.Dim.rank));
|
||||
|
||||
}
|
||||
|
||||
TEST(scanPermuteMatchContractTensorfromSrcToDst2, floatest) {
|
||||
int t[] = { 3, 8, 2, 3, 4 };
|
||||
int tm[] = { 4, 2, 7, 3 };
|
||||
//int tm[] = { 2, 3,4,7 };
|
||||
struct dimension d(5, t);
|
||||
struct dimension dm(4, tm);
|
||||
struct Tensor<float> M4(d), M(dm);
|
||||
M4.initVal(1.0f);
|
||||
M.initVal(1.0f);
|
||||
int dee = 3;
|
||||
int result[4] = { 1,3,0,2 };
|
||||
//int result[4] = { 0,1,2,3 };
|
||||
int perm[M.Dim.rank];
|
||||
ASSERT_TRUE(scanPermuteMatchContractTensorfromSrcToDst(perm, M, M4, dee));
|
||||
for (int i = 0; i < M.Dim.rank; i++) printf(" %d[%d] ", i, perm[i]); printf(" first perm \n");
|
||||
ASSERT_EQ(0, memcmp(result, perm, sizeof(int) * M.Dim.rank));
|
||||
|
||||
Tensor<float> tM;
|
||||
permutation p(M.Dim.rank, perm);
|
||||
permuteTensor(tM, M, p);
|
||||
|
||||
ASSERT_FALSE(scanPermuteMatchContractTensorfromSrcToDst(perm, M, M4, 4));
|
||||
for (int i = 0; i < M.Dim.rank; i++) printf(" %d[%d] ", i, perm[i]); printf(": last perm \n");
|
||||
tM.Dim.print();
|
||||
int resultDim[] = { 2,3,4,7 };
|
||||
ASSERT_EQ(0, memcmp(resultDim, tM.Dim.dim, sizeof(int) * tM.Dim.rank));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST(cudaTensorContractNestProd, floatTemp) {
|
||||
|
||||
int t3[] = { 77, 8, 25 };
|
||||
|
||||
int t4[] = { 8, 25, 52, 144 };
|
||||
struct dimension d3(3, t3), d4(4, t4), d;
|
||||
|
||||
struct Tensor<float> M3(d3), M4(d4), M;
|
||||
M3.initVal(1.0f); // M3.print();
|
||||
M4.initVal(0.0f); // M4.print();
|
||||
|
||||
int dee = 2;
|
||||
|
||||
M4.Dim.print();
|
||||
|
||||
try {
|
||||
//tensorContractnProd(M, M3, M4, dee);
|
||||
cudaTensorContractNestProd(M, M3, M4, dee);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
printf("bye from test tensorContractnProd floatTemp invalid arg! deep: \n");
|
||||
dimension dM;
|
||||
extractDimNestingDepth(dM, d3, d4, dee);
|
||||
dM.print();
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
int coord[M.Dim.rank];
|
||||
int coord3[M3.Dim.rank];
|
||||
int coord4[M4.Dim.rank];
|
||||
int idx3[M3.Dim.rank];
|
||||
int idx4[M4.Dim.rank];
|
||||
|
||||
int l0, l1;
|
||||
l0 = M3.Dim.rank - dee;
|
||||
l1 = M4.Dim.rank - dee;
|
||||
int pcoord3[l0];
|
||||
int pcoord4[l1];
|
||||
int r[dee];
|
||||
//int rev[dee];
|
||||
|
||||
int lin3, lin4, lin;
|
||||
d = M.Dim;
|
||||
d.print();
|
||||
|
||||
Tensor<float> Msum(d);
|
||||
|
||||
for (idx3[0] = 0; idx3[0] < d3.dim[0];idx3[0]++)
|
||||
for (idx4[2] = 0; idx4[2] < d4.dim[2];idx4[2]++)
|
||||
for (idx4[3] = 0; idx4[3] < d4.dim[3];idx4[3]++) {
|
||||
|
||||
for (int i = 0; i < l0; i++) pcoord3[i] = idx3[i];
|
||||
for (int i = 0; i < l1; i++) pcoord4[i] = idx4[i + dee];
|
||||
concatArray(coord, pcoord3, pcoord4, 0, 0, l0, 0, l1);
|
||||
lin = d.CoordToLinear(coord);
|
||||
Msum.elements[lin] = 0.0f;
|
||||
//for (idx3[1] = 0; idx3[1] < d3.dim[1];idx3[1]++)
|
||||
//for (idx3[2] = 0; idx3[2] < d3.dim[2]; idx3[2]++)
|
||||
for (idx4[0] = 0; idx4[0] < d4.dim[0];idx4[0]++)
|
||||
for (idx4[1] = 0; idx4[1] < d4.dim[1];idx4[1]++)
|
||||
{
|
||||
for (int i = 0; i < dee; i++) {
|
||||
r[i] = idx4[i];
|
||||
//rev[i] = idx4[dee - 1 - i];
|
||||
}
|
||||
|
||||
//concatArray(coord3, pcoord3, rev, 0, 0, l0, 0, dee);
|
||||
concatArray(coord3, pcoord3, r, 0, 0, l0, 0, dee);
|
||||
concatArray(coord4, r, pcoord4, 0, 0, dee, 0, l1);
|
||||
//printf("[");printArray(coord3, M3.Dim.rank); printf("]["); printArray(coord4, M4.Dim.rank);printf("] =*= ("); printArray(coord, Msum.Dim.rank); printf(") |||");
|
||||
lin3 = d3.CoordToLinear(coord3);
|
||||
lin4 = d4.CoordToLinear(coord4);
|
||||
|
||||
Msum.elements[lin] += (M3.elements[lin3] * M4.elements[lin4]);
|
||||
//printf("lin:%d lin3:%d lin4:%d el+:%f\n", lin, lin3, lin4, Msum.elements[lin]);
|
||||
}
|
||||
ASSERT_FLOAT_EQ(Msum.elements[lin], M.elements[lin]) << " lin: " << lin << " Msumelem: " << Msum.elements[lin] << " Melem: " << M.elements[lin];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
NAME_TEST=is_good
|
||||
CC=gcc
|
||||
LDFLAGS=-lpthread
|
||||
ROOT_DIR=$(shell pwd)
|
||||
INCLUDE_DIR=$(ROOT_DIR)
|
||||
CFLAGS=-I$(INCLUDE_DIR)
|
||||
SRC_DIR=$(ROOT_DIR)
|
||||
SRC=$(wildcard src/*/*.c)
|
||||
OBJ=$(SRC:.c=.o)
|
||||
#HEADS=$(OBJS:.o=.h)
|
||||
TEST_DIR=$(ROOT_DIR)
|
||||
EXECSRC=$(TEST_DIR)/$(NAME_TEST).c
|
||||
EXEC=$(ROOT_DIR)/launch_$(NAME_TEST)
|
||||
PERMSRC=$(wildcard perm*/*perm*.c)
|
||||
PERMSRC_O=$(PERMSRC:.c=.o)
|
||||
SETTSRC=$(wildcard set*/set*.c)
|
||||
SETTSRC_O=$(SETTSRC:.c=.o)
|
||||
TOOLSRC=$(wildcard too*/tool*.c)
|
||||
TOOLSRC_O=$(TOOLSRC:.c=.o)
|
||||
TESTSRC=$(wildcard *test*/*test*.c)
|
||||
TESTSRC_O=$(TESTSRC:.c=.o)
|
||||
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(EXECSRC) $(OBJ)
|
||||
$(CC) -o $@ $^ -I$(INCLUDE_DIR) $(LDFLAGS)
|
||||
|
||||
|
||||
$(TESTSRC_O): $(TESTSRC) $(TOOLSRC_O)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
$(PERMSRC_O): $(PERMSRC) $(SETTSRC_O)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
$(SETTSRC_O) : $(SETTSRC) $(TOOLSRC_O)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
$(TOOLSRC_O): $(TOOLSRC)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
.PHONY: clean mrproper
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
||||
|
||||
mrproper: clean
|
||||
rm -f $(EXEC)
|
||||
|
||||
run: $(EXEC)
|
||||
$(EXEC)
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef __COORDINATE_C__H__
|
||||
#define __COORDINATE_C__H__
|
||||
|
||||
#include "dimension/dimension.h"
|
||||
|
||||
|
||||
struct coordinate
|
||||
{
|
||||
size_t lin_coo;
|
||||
unsigned int *coord;
|
||||
struct dimension *dimension;
|
||||
};
|
||||
|
||||
typedef coordinate coordinate;
|
||||
|
||||
void LinearToCoord(struct coordinate *coor);
|
||||
void CoordToLinear(struct coordinate *coor);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,181 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/dimension/dimension.h"
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/permutation/permutation.h"
|
||||
|
||||
|
||||
#include "dimension/dimension.hpp"
|
||||
|
||||
#include "permutation/permutation.hpp"
|
||||
//#include "permutation.h"
|
||||
|
||||
/*void dimension::initDim(int* arr, bool end = true) {
|
||||
endian = end;
|
||||
delete[]dim;
|
||||
dim = new int[rank];
|
||||
size = 1;
|
||||
for (int i = 0; i < rank; ++i) {
|
||||
dim[i] = arr[i];
|
||||
size *= dim[i];
|
||||
}
|
||||
}*/
|
||||
|
||||
dimension& dimension::operator=(const dimension& d) {
|
||||
int oldRank = rank;
|
||||
rank = d.rank;
|
||||
size = d.size;
|
||||
initDim(d.dim, oldRank);
|
||||
//for (int i = 0; i < rank; i++) dim[i] = d.dim[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
dimension& dimension::operator+=(const dimension& d) {
|
||||
int oldRank = rank;
|
||||
int* t = new int[rank + d.rank];
|
||||
for (int i = 0; i < rank; i++) t[i] = dim[i];
|
||||
for (int i = 0; i < d.rank; i++) t[rank + i] = d.dim[i];
|
||||
size *= d.size;
|
||||
rank += d.rank;
|
||||
initDim(t, oldRank);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void dimension::LinearToCoord(int* ret, int lin) const {
|
||||
int begin = 0, end = rank - 1;
|
||||
int (*iter)(int) = incr;
|
||||
bool (*cond)(int, int) = isLessThan;
|
||||
if (endian == false) {
|
||||
//if (endian) {
|
||||
begin = rank - 1; end = 0;
|
||||
iter = decr; cond = isGreatThan;
|
||||
}
|
||||
//printf("to coor begin = %d end = %d \n", begin, end);
|
||||
|
||||
int sm = lin;
|
||||
int pp = size;
|
||||
for (int i = begin; cond(i, end); i = iter(i)) {
|
||||
//printf(" i: %d ", i);
|
||||
pp /= dim[i];
|
||||
ret[i] = sm / pp;
|
||||
sm %= pp;
|
||||
//printf("sm[%d] = %d , pp=%d ; ", i, sm, pp);
|
||||
}
|
||||
ret[end] = sm;
|
||||
}
|
||||
|
||||
int dimension::CoordToLinear(int* coo) const {
|
||||
int begin = 0;
|
||||
int end = rank - 1;
|
||||
int (*iter)(int); iter = &incr;
|
||||
bool (*cond)(int, int); cond = &isLessEqThan;
|
||||
|
||||
if (endian) {
|
||||
begin = rank - 1; end = 0;
|
||||
iter = &decr; cond = &isGreatEqThan;
|
||||
}
|
||||
|
||||
int pp = 1;
|
||||
int sm = 0;
|
||||
for (int i = begin; cond(i, end); i = iter(i)) {
|
||||
sm += (coo[i] * pp);
|
||||
pp *= dim[i];
|
||||
}
|
||||
return sm;
|
||||
}
|
||||
|
||||
bool isLessEqThan(int a, int b) { return a <= b; }
|
||||
bool isLessThan(int a, int b) { return a < b; }
|
||||
bool isGreatEqThan(int a, int b) { return a >= b; }
|
||||
bool isGreatThan(int a, int b) { return a > b; }
|
||||
int incr(int i) { return i + 1; }
|
||||
int decr(int i) { return i - 1; }
|
||||
|
||||
|
||||
void add(dimension& d, const dimension& d0, const dimension& d1) {
|
||||
int oldRank = d.rank;
|
||||
int* t = new int[d0.rank + d1.rank];
|
||||
for (int i = 0; i < d0.rank; i++) t[i] = d0.dim[i];
|
||||
for (int i = 0; i < d1.rank; i++) t[d0.rank + i] = d1.dim[i];
|
||||
d.rank = d0.rank + d1.rank;
|
||||
d.initDim(t, oldRank);
|
||||
}
|
||||
|
||||
void max(dimension& d, const dimension& d0, const dimension& d1) {
|
||||
if (d0.rank > d1.rank) {
|
||||
d = d0;
|
||||
}
|
||||
else if (d0.rank < d1.rank) {
|
||||
d = d1;
|
||||
}
|
||||
else {// d0.rank = d1.rank
|
||||
d = d0;
|
||||
for (int i = 0; i < d.rank; i++) {
|
||||
if (d.dim[i] < d1.dim[i]) d.dim[i] = d1.dim[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void min(dimension& d, const dimension& d0, const dimension& d1) {
|
||||
if (d0.rank > d1.rank) {
|
||||
d = d1;
|
||||
}
|
||||
else if (d0.rank < d1.rank) {
|
||||
d = d0;
|
||||
}
|
||||
else {// d0.rank = d1.rank
|
||||
d = d0;
|
||||
for (int i = 0; i < d.rank; i++) {
|
||||
if (d.dim[i] > d1.dim[i]) d.dim[i] = d1.dim[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void minReverse(dimension& d, const dimension& d0, const dimension& d1, bool& rev) {
|
||||
if (d0.rank > d1.rank) {
|
||||
d = d1;
|
||||
rev = true;
|
||||
}
|
||||
else if (d0.rank < d1.rank) {
|
||||
d = d0;
|
||||
rev = false;
|
||||
}
|
||||
else {// d0.rank = d1.rank
|
||||
d = d0;
|
||||
for (int i = 0; i < d.rank; i++) {
|
||||
if (d.dim[i] > d1.dim[d.rank - 1 - i]) d.dim[i] = d1.dim[d.rank - 1 - i];
|
||||
}
|
||||
rev = false;
|
||||
}
|
||||
}
|
||||
|
||||
void reverseArray(int* arr, int sz) {
|
||||
int tmp[sz], i = 0;
|
||||
for (; i < sz / 2; i++) {
|
||||
tmp[i] = arr[i];
|
||||
arr[i] = arr[sz - 1 - i];
|
||||
}
|
||||
for (; i < sz; i++) {
|
||||
arr[i] = tmp[sz - 1 - i];
|
||||
}
|
||||
}
|
||||
|
||||
void transform(dimension& dDst, const dimension& dSrc, int* perm, int sz) {
|
||||
dDst = dSrc;
|
||||
setInit setIn(sz);
|
||||
if (sz == dSrc.rank) {
|
||||
if (isPermutation(perm, setIn, sz)) {
|
||||
for (int i = 0; i < sz; i++) dDst.dim[i] = dSrc.dim[perm[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef __DIM__
|
||||
#define __DIM__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct dimension
|
||||
{
|
||||
unsigned int rank;
|
||||
unsigned int* dim;
|
||||
size_t size;
|
||||
};
|
||||
typedef dimension dimension;
|
||||
|
||||
|
||||
void print_dimension(dimension d);
|
||||
|
||||
|
||||
void add(dimension* d, const dimension* d0, const dimension* d1);
|
||||
|
||||
void max(dimension* d, const dimension* d0, const dimension* d1);
|
||||
|
||||
void min(dimension* d, const dimension* d0, const dimension* d1);
|
||||
|
||||
bool minReverse(dimension* d, const dimension* d0, const dimension* d1);
|
||||
|
||||
void transform(dimension* dDst, const dimension* dSrc, int* perm);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef __DIMENSION__
|
||||
#define __DIMENSION__
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//#include "tensor.h"
|
||||
|
||||
//#include "dimension.h"
|
||||
|
||||
static int iArray1[1] = { 1 };
|
||||
|
||||
|
||||
|
||||
struct dimension {
|
||||
//friend dimension& operator+(const dimension& d, const dimension& d1);
|
||||
friend void add(dimension& d, const dimension& d0, const dimension& d1);
|
||||
friend void max(dimension& d, const dimension& d0, const dimension& d1);
|
||||
friend void min(dimension& d, const dimension& d0, const dimension& d1);
|
||||
friend void minReverse(dimension& d, const dimension& d0, const dimension& d1, bool& Rev);
|
||||
friend bool checkMatchProdTensor(dimension& d0, const dimension& d1, int nestingDepth);
|
||||
friend bool checkMatchProdTensorReverse(dimension& d0, const dimension& d1, int nestingDepth);
|
||||
friend void extractDimNestingDepth(dimension& dM, const dimension& d0, const dimension& d1, int nestingDepth);
|
||||
|
||||
|
||||
int rank;
|
||||
int* dim;
|
||||
size_t size;
|
||||
bool endian; //LitleEndian : true, BigEndian : false,
|
||||
void initDim(int* arr, int oldRank) {
|
||||
|
||||
//delete[]dim;
|
||||
//dim = new int[rank];
|
||||
if (rank > oldRank) {
|
||||
free(dim);
|
||||
dim = (int*)malloc(rank * sizeof(int));
|
||||
}
|
||||
size = 1;
|
||||
for (int i = 0; i < rank; ++i) {
|
||||
dim[i] = arr[i];
|
||||
size *= dim[i];
|
||||
}
|
||||
}
|
||||
void initDim(bool end = true) {
|
||||
endian = end;
|
||||
//delete[]dim;
|
||||
//dim = new int[rank];
|
||||
|
||||
if (dim != NULL) free(dim);
|
||||
dim = (int*)malloc(rank * sizeof(int));
|
||||
}
|
||||
dimension& operator=(const dimension& d);
|
||||
dimension& operator+=(const dimension& d);
|
||||
//dimension& operator*=(const dimension& d);
|
||||
dimension(int d = 1, int* arr = iArray1, bool end = true) {
|
||||
endian = end;
|
||||
rank = d;
|
||||
//dim = new int[d];
|
||||
dim = (int*)malloc(d * sizeof(int));
|
||||
initDim(arr, rank);
|
||||
}
|
||||
void print() const { printf(" rank: %d\n", rank);for (int i = 0; i < rank; i++) printf(" %d ", dim[i]);printf("\nsize:%ld\n", size); }
|
||||
void LinearToCoord(int* ret, int lin) const;
|
||||
int CoordToLinear(int* coo) const;
|
||||
};
|
||||
|
||||
bool isLessEqThan(int a, int b); // { return a <= b; }
|
||||
bool isLessThan(int a, int b); // { return a < b; }
|
||||
bool isGreatEqThan(int a, int b); // { return a >= b; }
|
||||
bool isGreatThan(int a, int b); // { return a > b; }
|
||||
int incr(int i); // { return i + 1; }
|
||||
int decr(int i); // { return i - 1; }
|
||||
|
||||
|
||||
|
||||
void add(dimension& d, const dimension& d0, const dimension& d1);
|
||||
|
||||
void max(dimension& d, const dimension& d0, const dimension& d1);
|
||||
|
||||
void min(dimension& d, const dimension& d0, const dimension& d1);
|
||||
|
||||
void minReverse(dimension& d, const dimension& d0, const dimension& d1, bool& rev);
|
||||
|
||||
void transform(dimension& dDst, const dimension& dSrc, int* perm, int sz);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// for sleep !
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#elif _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "ftest/ftest.h"
|
||||
|
||||
#include "permutation_t/permutation_t.h"
|
||||
|
||||
TEST(size_permutation2){
|
||||
PRINTF("another size_permutation2 again\n");
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
TEST(size_permutation)
|
||||
{
|
||||
PERMUTATION_TYPE_CHAR *p = CREATE_PERMUTATION_TYPE_CHAR(3);
|
||||
|
||||
PRINTF(" size = %lu \n",p->size);
|
||||
EXPECT_EQ(p->size, 3);
|
||||
PRINTF("test size_permutation2\n");
|
||||
}
|
||||
TEST(size_permutation2){
|
||||
PRINTF("another size_permutation2 again false\n");
|
||||
bool val_bool = false;
|
||||
ASSERT_TRUE(val_bool);
|
||||
}
|
||||
TEST(size_permutation2)
|
||||
{
|
||||
PRINTF("test size_permutation2\n");
|
||||
bool val_bool = true;
|
||||
ASSERT_FALSE(val_bool);
|
||||
/*
|
||||
PERMUTATION_TYPE_CHAR *p = CREATE_PERMUTATION_TYPE_CHAR(3);
|
||||
|
||||
PRINTF(" size = %u \n",p->size);
|
||||
if(p->size == 3) print_OK_with_msg_endl(" FF yeah GOOD test size passed ");
|
||||
else print_KO_with_msg_endl("NOT GOOD test size not passed ");
|
||||
*/
|
||||
}
|
||||
TEST(float_equal){
|
||||
PRINTF("another size_permutation2 float\n");
|
||||
ASSERT_TRUE(true);
|
||||
float a = 1.00001f;
|
||||
float b = 1.00001f;
|
||||
ASSERT_EQ_TYPE_FLOAT(a,b);
|
||||
b=1.0000101f;
|
||||
ASSERT_EQ_TYPE_FLOAT(a,b);
|
||||
ASSERT_EQ_TYPE_FLOAT(1.0000102f,b);
|
||||
}
|
||||
TEST(double_equal){
|
||||
PRINTF("another size_permutation2 double\n");
|
||||
ASSERT_TRUE(true);
|
||||
double a = 1.00000001;
|
||||
double b = 1.00000001;
|
||||
ASSERT_EQ_TYPE_DOUBLE(a,b);
|
||||
b=1.00000001000000001;
|
||||
ASSERT_EQ_TYPE_DOUBLE(a,b);
|
||||
ASSERT_EQ_TYPE_DOUBLE(1.0000000100000002,b);
|
||||
}
|
||||
|
||||
TEST(){
|
||||
unsigned char c = 'a';
|
||||
|
||||
debug_print("another size_permutation2, a = %c\n",c);
|
||||
ASSERT_FALSE(true);
|
||||
ASSERT_TRUE(true);
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST(){
|
||||
sleep(3);
|
||||
int a = 5;
|
||||
long b = 5;
|
||||
ASSERT_EQ(a,b);
|
||||
a=4;
|
||||
ASSERT_EQ(a,b);
|
||||
|
||||
}
|
||||
|
||||
TEST(expect){
|
||||
sleep(2);
|
||||
int a = 5;
|
||||
int b = 6;
|
||||
EXPECT_EQ(a,b);
|
||||
//SKIP();
|
||||
SKIP("on skip eq string\n");
|
||||
EXPECT_EQ_TYPE_STRING("hello","hello");
|
||||
float f1 = 1.00019999, f2=1.00019999;
|
||||
EXPECT_EQ_TYPE_FLOAT(f1,f2);
|
||||
|
||||
}
|
||||
|
||||
TEST(){
|
||||
PRINTF("no test, only print\n");
|
||||
}
|
||||
|
||||
TEST(){
|
||||
PRINTF("no test, only print\n");
|
||||
}
|
||||
|
||||
TEST(){
|
||||
PRINTF("no test, only print\n");
|
||||
}
|
||||
|
||||
|
||||
TEST(){
|
||||
|
||||
PERMUTATION_TYPE_CHAR *p_char = CREATE_PERMUTATION_TYPE_CHAR(6);
|
||||
p_char->perm[0]='B';
|
||||
p_char->perm[1]='A';
|
||||
p_char->perm[2]='Y';
|
||||
p_char->perm[3]='C';
|
||||
p_char->perm[4]='D';
|
||||
p_char->perm[5]='Z';
|
||||
|
||||
PERMUTATION_TYPE_SIZE_T *tr_p_char = TRANSLATE_TO_SET_THEORIC_SIZE_T_TYPE_CHAR(p_char);
|
||||
|
||||
for(int i = 0; i < tr_p_char->size; ++i) PRINTF(" [%d ]%ld ,",i,tr_p_char->perm[i]);
|
||||
PRINTF("p_char == %s\n",p_char->perm);
|
||||
}
|
||||
|
||||
TEST(lessThan){
|
||||
long int a=1,b=2;
|
||||
EXPECT_LT(a,b);
|
||||
EXPECT_LT(b,a);
|
||||
|
||||
}
|
||||
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
TEST(sleep){sleep(2);}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
//run_all_tests();
|
||||
//run_all_tests_parallel(4);
|
||||
|
||||
run_all_tests_args(argc, argv);
|
||||
|
||||
//purge_tests();
|
||||
//run_some_tests(8, 1, 2, 2, 3, 3, 0, 4, 1);
|
||||
//run_some_tests(8, 5, 7, 1, 1, 1, 1, 1, 1);
|
||||
//run_some_tests_one_by_one(3, 1, 2, 2);
|
||||
//run_all_tests_exept(2, 1, 3);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
#include "permutation_t/permutation_t.h"
|
||||
|
||||
#define GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(type)\
|
||||
bool IS_PERMUTATION_SET_THEORIC_##type(const PERMUTATION_##type *p){\
|
||||
if(p == NULL) return false;\
|
||||
size_t size = p->size;\
|
||||
type j;\
|
||||
size_t *count_array_i = calloc(size, sizeof(size_t));\
|
||||
if(count_array_i == NULL){\
|
||||
printf("can't alloc count_array_i\n"); return false;}\
|
||||
for(size_t i = 0; i < size; ++i){\
|
||||
j = p->perm[i];\
|
||||
if((COMPARE_N_##type(&j, (type*)&size) >= 0) || count_array_i[j]){\
|
||||
free(count_array_i); return false; }\
|
||||
++count_array_i[j];}\
|
||||
free(count_array_i);\
|
||||
return true; }\
|
||||
|
||||
GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_U_CHAR)
|
||||
GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_U_INT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_U_L_INT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_SIZE_T)
|
||||
|
||||
|
||||
#define GENERATE_PERMUTATION_FUNCTIONS(type)\
|
||||
PERMUTATION_##type * CREATE_PERMUTATION_##type(size_t size){\
|
||||
if (size == 0) return NULL;\
|
||||
PERMUTATION_##type *p = malloc(sizeof(PERMUTATION_##type));\
|
||||
p->size = size;\
|
||||
p->perm = malloc(size * sizeof(type));\
|
||||
return p; }\
|
||||
\
|
||||
PERMUTATION_TYPE_SIZE_T * TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(const PERMUTATION_##type *p ){\
|
||||
if (p == NULL) return NULL;\
|
||||
PERMUTATION_TYPE_SIZE_T *t_p = malloc(sizeof(PERMUTATION_TYPE_SIZE_T));\
|
||||
size_t size = p->size;\
|
||||
t_p->size = size;\
|
||||
t_p->perm = malloc(size * sizeof(TYPE_SIZE_T));\
|
||||
type *sorted_perm = malloc(size * sizeof(type));\
|
||||
COPY_ARRAY_##type(sorted_perm,(const type*)p->perm, size);\
|
||||
qsort(sorted_perm, size, sizeof(type), COMPARE_N_##type);\
|
||||
size_t *rec_index_visited = malloc(size * sizeof(size_t));\
|
||||
size_t cur_rec = 0; bool found_rec;\
|
||||
for(size_t i = 0; i < size; ++i){\
|
||||
for(size_t j = 0; j < size; ++j){\
|
||||
if(COMPARE_N_##type(&(p->perm[j]), &(sorted_perm[i])) == 0){\
|
||||
found_rec = false;\
|
||||
for(size_t k = 0; k < cur_rec; ++k){\
|
||||
if(rec_index_visited[k] == j){\
|
||||
found_rec == true; break; } } \
|
||||
if(found_rec == false){\
|
||||
/*t_p->perm[i] = j;*/\
|
||||
t_p->perm[j] = i;\
|
||||
rec_index_visited[cur_rec++] = j; \
|
||||
break; }\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
free(rec_index_visited);\
|
||||
free(sorted_perm);\
|
||||
return t_p; \
|
||||
}\
|
||||
\
|
||||
bool IS_PERMUTATION_##type(const PERMUTATION_##type *p){\
|
||||
if(p == NULL) return false;\
|
||||
PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\
|
||||
bool ret = IS_PERMUTATION_SET_THEORIC_TYPE_SIZE_T(t_p);\
|
||||
free(t_p);\
|
||||
return ret; }\
|
||||
|
||||
|
||||
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_CHAR)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_U_CHAR)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_INT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_U_INT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_L_INT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_U_L_INT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_SIZE_T)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_FLOAT)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_DOUBLE)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_L_DOUBLE)
|
||||
GENERATE_PERMUTATION_FUNCTIONS(TYPE_STRING)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* why TRANSLATE ?
|
||||
* 2,7,4,1 is a permutation of 1,2,4,7
|
||||
*it is equivalent of 1,3,2,0 in set_theoric(4)=0,1,2,3
|
||||
this function calculate the permutation equivalent in set_theoric
|
||||
2,4,2,5 is translate to 0,1,0,2
|
||||
* */
|
||||
|
||||
|
||||
/* if need optimization in translate
|
||||
#define GENERATE_UNSIGNED_SIZE_WITH_TYPED(type_unsigned, type)\
|
||||
PERMUTATION_##type_unsigned * TRANSLATE_TO_SET_THEORIC_##type_unsigned_##type(PERMUTATION_##type *p ){\
|
||||
if (p == NULL) return NULL;\
|
||||
PERMUTATION_##type_unsigned *t_p = malloc(sizeof(PERMUTATION_##type_unsigned));\
|
||||
type_unsigned size = p->size;\
|
||||
t_p->perm = malloc(size * sizeof(type_unsigned));\
|
||||
type *sorted_perm = malloc(size * sizeof(type));\
|
||||
COPY_ARRAY_##type(sorted_perm, p->perm, size);\
|
||||
qsort(sorted_perm, size, sizeof(type), COMPARE_N_##type);\
|
||||
type_unsigned *rec_index_visited = malloc(size * sizeof(type_unsigned));\
|
||||
type_unsigned cur_rec = 0; bool found_rec;\
|
||||
for(type_unsigned i = 0; i < size; ++i){\
|
||||
for(type_unsigned j = 0; j < size; ++j){\
|
||||
if(COMPARE_N_##type(&(p->perm[j]), &(sorted_perm[i])) == 0){\
|
||||
found_rec = false;\
|
||||
for(type_unsigned k = 0; k < cur_rec; ++k){\
|
||||
if(rec_index_visited[k] == j){\
|
||||
found_rec == true; break; } } \
|
||||
if(found_rec == false){\
|
||||
t_p->perm[i] = j;\
|
||||
rec_index_visited[cur++] = j; \
|
||||
break; } } } } \
|
||||
free(rec_index_visited);\
|
||||
free(sorted_perm);\
|
||||
return t_p; }\
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef __PERMUTATION_T_C_H__
|
||||
#define __PERMUTATION_T_C_H__
|
||||
|
||||
#include "tools_t/tools_t.h"
|
||||
#include "set_theoric_t/set_theoric_t.h"
|
||||
|
||||
/* struct of permutation, not necessarly set_theoric
|
||||
*
|
||||
* */
|
||||
|
||||
|
||||
|
||||
#define GENERATE_PERMUTATION(type)\
|
||||
struct PERMUTATION_##type{\
|
||||
size_t size;\
|
||||
type * perm; };\
|
||||
\
|
||||
typedef struct PERMUTATION_##type PERMUTATION_##type;\
|
||||
PERMUTATION_##type * CREATE_PERMUTATION_##type(size_t size);\
|
||||
PERMUTATION_TYPE_SIZE_T * TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(const PERMUTATION_##type *p );\
|
||||
|
||||
|
||||
GENERATE_PERMUTATION(TYPE_SIZE_T)
|
||||
GENERATE_PERMUTATION(TYPE_CHAR)
|
||||
GENERATE_PERMUTATION(TYPE_U_CHAR)
|
||||
GENERATE_PERMUTATION(TYPE_INT)
|
||||
GENERATE_PERMUTATION(TYPE_U_INT)
|
||||
GENERATE_PERMUTATION(TYPE_L_INT)
|
||||
GENERATE_PERMUTATION(TYPE_U_L_INT)
|
||||
GENERATE_PERMUTATION(TYPE_FLOAT)
|
||||
GENERATE_PERMUTATION(TYPE_DOUBLE)
|
||||
GENERATE_PERMUTATION(TYPE_L_DOUBLE)
|
||||
GENERATE_PERMUTATION(TYPE_STRING)
|
||||
|
||||
#define GENERATE_FUNCTIONS_UNSIGNED(type)\
|
||||
bool IS_PERMUTATION_SET_THEORIC_##type(const PERMUTATION_##type *p);\
|
||||
|
||||
GENERATE_FUNCTIONS_UNSIGNED(TYPE_U_CHAR)
|
||||
GENERATE_FUNCTIONS_UNSIGNED(TYPE_U_INT)
|
||||
GENERATE_FUNCTIONS_UNSIGNED(TYPE_U_L_INT)
|
||||
GENERATE_FUNCTIONS_UNSIGNED(TYPE_SIZE_T)
|
||||
|
||||
|
||||
|
||||
#endif /*__PERMUTATION_T_C_H__*/
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
#include "set_theoric_t/set_theoric_t.h"
|
||||
|
||||
#define GENERATE_SET_THEORIC(type) \
|
||||
SET_THEORIC_##type * CREATE_SET_THEORIC_##type(size_t id){ \
|
||||
if(id == 0) return NULL; \
|
||||
SET_THEORIC_##type *ret_set = malloc(sizeof(SET_THEORIC_##type)); \
|
||||
ret_set->id = id; \
|
||||
ret_set->set = malloc(id*sizeof(type)); \
|
||||
for(type i = 0; i < id; ++i) ret_set->set[i]=i; \
|
||||
return ret_set; \
|
||||
} \
|
||||
\
|
||||
bool IS_SET_THEORIC_##type(SET_THEORIC_##type *st){ \
|
||||
for(type i = 0; i < st->id; ++i){ \
|
||||
if(st->set[i] != i) return false; \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
|
||||
GENERATE_SET_THEORIC(TYPE_U_CHAR)
|
||||
GENERATE_SET_THEORIC(TYPE_U_INT)
|
||||
GENERATE_SET_THEORIC(TYPE_U_L_INT)
|
||||
GENERATE_SET_THEORIC(TYPE_SIZE_T)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef __SET_THEORIC_T_C__H
|
||||
#define __SET_THEORIC_T_C__H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tools_t/tools_t.h"
|
||||
|
||||
#define GENERATE_UNSIGNED_SET_THEORIC(type) \
|
||||
struct SET_THEORIC_##type{ \
|
||||
type id; \
|
||||
type *set; \
|
||||
}; \
|
||||
typedef struct SET_THEORIC_##type SET_THEORIC_##type; \
|
||||
SET_THEORIC_##type * CREATE_SET_THEORIC_##type(size_t id/*TYPE_##type*/); \
|
||||
bool IS_SET_THEORIC_##type(SET_THEORIC_##type *st); \
|
||||
|
||||
GENERATE_UNSIGNED_SET_THEORIC(TYPE_U_CHAR)
|
||||
GENERATE_UNSIGNED_SET_THEORIC(TYPE_U_INT)
|
||||
GENERATE_UNSIGNED_SET_THEORIC(TYPE_U_L_INT)
|
||||
GENERATE_UNSIGNED_SET_THEORIC(TYPE_SIZE_T)
|
||||
|
||||
|
||||
|
||||
#endif /*__SET_THEORIC_T_C__H*/
|
||||
@@ -0,0 +1,500 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tens0neD/tens0neD.h"
|
||||
#include "tensor/tens0neD/tens0neD.h"
|
||||
//#include "include/tens0neD.h"
|
||||
|
||||
|
||||
//#include "cudatensor.h"
|
||||
//#include "/home/fanasina/progr_/ptens0neD/permutation/permutation.h"
|
||||
#include "permutation/permutation.h"
|
||||
|
||||
|
||||
template<typename T>
|
||||
void transform(Tensor<T>& Dst, const Tensor<T>& Src, int* perm, int sz) {
|
||||
transform(Dst.Dim, Src.Dim, perm, sz);
|
||||
dimension dsrc = Src.Dim;
|
||||
dimension ddst = Dst.Dim;
|
||||
int coor[dsrc.rank];
|
||||
int dcoor[ddst.rank], ldst;
|
||||
for (int i = 0; i < Src.Dim.size; i++) {
|
||||
dsrc.LinearToCoord(coor, i);
|
||||
for (int j = 0; j < dsrc.rank; j++) dcoor[j] = coor[perm[j]];
|
||||
ldst = ddst.CoordToLinear(dcoor);
|
||||
Dst.elements[ldst] = Src.elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
template void transform<float>(Tensor<float>& Dst, const Tensor<float>& Src, int* perm, int sz);
|
||||
template void transform<double>(Tensor<double>& Dst, const Tensor<double>& Src, int* perm, int sz);
|
||||
|
||||
template<typename T>
|
||||
Tensor<T>& Tensor<T>::operator=(const Tensor<T>& M) {
|
||||
Dim = M.Dim;
|
||||
for (int i = 0; i < Dim.size; ++i) elements[i] = M.elements[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Tensor<T>& Tensor<T>::operator*=(const T& val) {
|
||||
//for (int i = 0; i < rank.size; ++i) elements[i] *= val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Tensor<T>& operator*(const Tensor<T>& M0, const Tensor<T>& M1) {
|
||||
struct dimension d; add(d, M0.Dim, M1.Dim);
|
||||
Tensor<T> Mret(d);
|
||||
for (int i = 0; i < M0.Dim.size; ++i) Mret.elements[i] = M0.elements[i];
|
||||
Mret.Dim += M0.Dim;
|
||||
return Mret;
|
||||
}
|
||||
|
||||
|
||||
void subArray(int* dst, int* src, int debDst, int finDst, int debSrc) {
|
||||
for (int i = debDst; i < finDst; i++) {
|
||||
dst[i] = src[i + debSrc];
|
||||
}
|
||||
}
|
||||
|
||||
void concatArray(int* dst, int* src0, int* src1, int debDst, int debSrc0, int finSrc0, int debSrc1, int finSrc1) {
|
||||
int i = debDst;
|
||||
for (int j = debSrc0; j < finSrc0; j++) {
|
||||
dst[i++] = src0[j];
|
||||
}
|
||||
for (int j = debSrc1; j < finSrc1; j++) {
|
||||
dst[i++] = src1[j];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Tensor<T>::initVal(T val) {
|
||||
int* coord = new int[Dim.rank];
|
||||
T pp, mult = 0.5;
|
||||
for (int i = 0; i < Dim.size; i++) {
|
||||
Dim.LinearToCoord(coord, i);
|
||||
elements[i] = val;
|
||||
pp = mult;
|
||||
for (int j = 0; j < Dim.rank; j++) {
|
||||
elements[i] += (coord[j] + 1) * pp;
|
||||
pp *= mult;
|
||||
}
|
||||
}
|
||||
}
|
||||
template
|
||||
void Tensor<float>::initVal(float val);
|
||||
template
|
||||
void Tensor<double>::initVal(double val);
|
||||
|
||||
template<typename T>
|
||||
void Tensor<T>::print() {
|
||||
Dim.print();
|
||||
int* coord = new int[Dim.rank];
|
||||
int begin = 0, end = Dim.rank - 1;
|
||||
//int beginInv = Dim.rank - 1, endInv = 0;
|
||||
int (*iter)(int) = incr;
|
||||
//int (*iterInv)(int) = decr;
|
||||
bool (*cond)(int, int) = isLessEqThan;
|
||||
//bool (*condInv)(int, int) = isGreatEqThan;
|
||||
if (Dim.endian == false) {
|
||||
begin = Dim.rank - 1; end = 0;
|
||||
//beginInv = 0; endInv = Dim.rank - 1;
|
||||
iter = decr; cond = isGreatEqThan;
|
||||
//iterInv = incr; condInv = isLessEqThan;
|
||||
}
|
||||
for (int i = 0; i < Dim.size; i++) {
|
||||
Dim.LinearToCoord(coord, i);
|
||||
//if (coord[Dim.rank - 1] == 0) {
|
||||
if (coord[begin] == 0) {
|
||||
for (int j = begin; cond(j, end); j = iter(j)) {
|
||||
//for (int j = Dim.rank - 1; j >= 0; j--) {
|
||||
if (coord[j] == 0) {
|
||||
printf("(");
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
//printf(" ");for (int j = 0; j < Dim.rank; j++) printf("[%d]", coord[j]); printf(" ");
|
||||
//printf(" "); for (int j = beginInv; condInv(j, endInv); j = iterInv(j)) printf("[%d]", coord[j]); printf(" ");
|
||||
//printf(" "); for (int k = beginInv; condInv(k, endInv); k = iterInv(k)) { printf("[%d]", coord[k]); } printf(" ");
|
||||
|
||||
printf(" %.6f ", elements[i]);
|
||||
|
||||
//if (coord[Dim.rank - 1] == Dim.dim[Dim.rank - 1] - 1) {
|
||||
if (coord[begin] == Dim.dim[begin] - 1) {
|
||||
for (int j = begin; cond(j, end); j = iter(j)) {
|
||||
//for (int j = Dim.rank - 1; j >= 0; j--) {
|
||||
if (coord[j] == Dim.dim[j] - 1) {
|
||||
printf(")");
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
template
|
||||
void Tensor<float>::print();
|
||||
template
|
||||
void Tensor<double>::print();
|
||||
|
||||
template<typename T>
|
||||
void tensorProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1) {
|
||||
add(M.Dim, M0.Dim, M1.Dim);
|
||||
M.initTensor();
|
||||
int* coord = new int[M.Dim.rank];
|
||||
int* coord0 = new int[M0.Dim.rank], lin0;
|
||||
int* coord1 = new int[M1.Dim.rank], lin1;
|
||||
for (int i = 0; i < M.Dim.size; i++) {
|
||||
M.Dim.LinearToCoord(coord, i);
|
||||
subArray(coord0, coord, 0, M0.Dim.rank, 0);
|
||||
subArray(coord1, coord, 0, M1.Dim.rank, M0.Dim.rank);
|
||||
lin0 = (M0.Dim).CoordToLinear(coord0);
|
||||
lin1 = (M1.Dim).CoordToLinear(coord1);
|
||||
M.elements[i] = M0.elements[lin0] * M1.elements[lin1];
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void tensorProd<double>(Tensor<double>& M, const Tensor<double>& M1, const Tensor<double>& M0);
|
||||
template
|
||||
void tensorProd<float>(Tensor<float>& M, const Tensor<float>& M1, const Tensor<float>& M0);
|
||||
|
||||
|
||||
|
||||
|
||||
bool checkMatchProdTensor(const dimension& d0, const dimension& d1, int nestingDepth) {
|
||||
if (d0.rank <= nestingDepth || d1.rank <= nestingDepth) return false;
|
||||
for (int i = 0; i < nestingDepth;i++) {
|
||||
if (d1.dim[i] != d0.dim[d0.rank - nestingDepth + i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkMatchProdTensorReverse(const dimension& d0, const dimension& d1, int nestingDepth) {
|
||||
if (d0.rank <= nestingDepth || d1.rank <= nestingDepth) return false;
|
||||
for (int i = 0; i < nestingDepth;i++) {
|
||||
if (d1.dim[i] != d0.dim[d0.rank - 1 - i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void extractDimNestingDepth(dimension& dM, const dimension& d0, const dimension& d1, int nestingDepth) {
|
||||
int len0 = d0.rank - nestingDepth;
|
||||
int len1 = d1.rank - nestingDepth;
|
||||
|
||||
int* tsub0 = new int[len0];
|
||||
int* tsub1 = new int[len1];
|
||||
int* tDk1 = new int[nestingDepth];
|
||||
int* tDk0 = new int[nestingDepth];
|
||||
subArray(tsub0, d0.dim, 0, len0, 0);
|
||||
subArray(tsub1, d1.dim, 0, len1, nestingDepth);
|
||||
subArray(tDk1, d1.dim, 0, nestingDepth, 0);
|
||||
subArray(tDk0, d0.dim, 0, nestingDepth, len0);
|
||||
dimension dSub0(len0, tsub0);
|
||||
dimension dSub1(len1, tsub1);
|
||||
dimension dM1(nestingDepth, tDk1);
|
||||
dimension dM0(nestingDepth, tDk0);
|
||||
|
||||
min(dM, dM0, dM1);
|
||||
//max(dM, dM0, dM1);
|
||||
}
|
||||
|
||||
// M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=n-l alor p=n+m-2l
|
||||
// M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)
|
||||
//M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]
|
||||
template<typename T>
|
||||
void tensorContractnProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1, int nestingDepth) {
|
||||
if (!checkMatchProdTensor(M0.Dim, M1.Dim, nestingDepth)) {
|
||||
printf("Deep = %d\n", nestingDepth);
|
||||
//throw std::check_ProdTensor(" Failed imbrication order in Multiplication matrix ");
|
||||
|
||||
//throw std::invalid_argument(" Failed imbrication order in Multiplication matrix ");
|
||||
}
|
||||
|
||||
int len0 = M0.Dim.rank - nestingDepth;
|
||||
int len1 = M1.Dim.rank - nestingDepth;
|
||||
|
||||
int* tsub0 = new int[len0];
|
||||
int* tsub1 = new int[len1];
|
||||
int* tDk1 = new int[nestingDepth];
|
||||
int* tDk0 = new int[nestingDepth];
|
||||
subArray(tsub0, M0.Dim.dim, 0, len0, 0);
|
||||
subArray(tsub1, M1.Dim.dim, 0, len1, nestingDepth);
|
||||
subArray(tDk1, M1.Dim.dim, 0, nestingDepth, 0);
|
||||
subArray(tDk0, M0.Dim.dim, 0, nestingDepth, len0);
|
||||
|
||||
dimension dSub0(len0, tsub0);
|
||||
dimension dSub1(len1, tsub1);
|
||||
dimension dM1(nestingDepth, tDk1);
|
||||
dimension dM0(nestingDepth, tDk0);
|
||||
dimension dM;
|
||||
min(dM, dM0, dM1);
|
||||
//max(dM, dM0, dM1);
|
||||
|
||||
add(M.Dim, dSub0, dSub1);
|
||||
M.initTensor();
|
||||
|
||||
int* coord = new int[M.Dim.rank];
|
||||
|
||||
int* coord0 = new int[len0], lin0;
|
||||
int* coord1 = new int[len1], lin1;
|
||||
|
||||
int* coordM0 = new int[M0.Dim.rank];
|
||||
int* coordM1 = new int[M1.Dim.rank];
|
||||
|
||||
int* Koord = new int[nestingDepth];
|
||||
for (int i = 0; i < M.Dim.size; i++) {
|
||||
M.Dim.LinearToCoord(coord, i);
|
||||
subArray(coord0, coord, 0, len0, 0);
|
||||
subArray(coord1, coord, 0, len1, len0);
|
||||
M.elements[i] = 0;
|
||||
for (int k = 0; k < dM.size; k++) {
|
||||
dM.LinearToCoord(Koord, k);
|
||||
concatArray(coordM0, coord0, Koord, 0, 0, len0, 0, nestingDepth);
|
||||
concatArray(coordM1, Koord, coord1, 0, 0, nestingDepth, 0, len1);
|
||||
lin0 = (M0.Dim).CoordToLinear(coordM0);
|
||||
lin1 = (M1.Dim).CoordToLinear(coordM1);
|
||||
M.elements[i] += M0.elements[lin0] * M1.elements[lin1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void tensorContractnProd<float>(Tensor<float>& M, const Tensor<float>& M0, const Tensor<float>& M1, int nestingDepth);
|
||||
template
|
||||
void tensorContractnProd<double>(Tensor<double>& M, const Tensor<double>& M0, const Tensor<double>& M1, int nestingDepth);
|
||||
|
||||
void reverseDim(dimension& d, const dimension& d0) {
|
||||
d.rank = d0.rank;
|
||||
d.size = d0.size;
|
||||
if (d.dim != NULL) free(d.dim);
|
||||
d.dim = (int*)malloc(d.rank * sizeof(int));
|
||||
for (int i = 0; i < d.rank; i++) d.dim[i] = d0.dim[d.rank - i - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void reverseTensor(Tensor<T>& M, const Tensor<T>& M0) {
|
||||
reverseDim(M.Dim, M0.Dim);
|
||||
size_t id;
|
||||
int coor[M0.Dim.rank];
|
||||
for (size_t i = 0; i < M.Dim.size; i++) {
|
||||
M0.Dim.LinearToCoord(coor, i);
|
||||
reverseArray(coor, M0.Dim.rank);
|
||||
id = M.Dim.CoordToLinear(coor);
|
||||
M.elements[id] = M0.elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
// M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...<l=n / xn = y0,x{n-1}=y1, x{n-l}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=n-l alor p=n+m-2l
|
||||
// M[x0,x1,x3..xl x{l+1}..xn] X M[xn,x{n-1},..x{l+1}xl y{l+1}..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)
|
||||
//M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]
|
||||
template<typename T>
|
||||
void tensorContractnReverseProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1, int nestingDepth) {
|
||||
if (!checkMatchProdTensorReverse(M0.Dim, M1.Dim, nestingDepth)) {
|
||||
printf("Failed in Deep = %d\n", nestingDepth);
|
||||
//throw std::check_ProdTensor(" Failed imbrication order in Multiplication matrix ");
|
||||
|
||||
//throw std::invalid_argument(" Failed imbrication order in Multiplication matrix ");
|
||||
}
|
||||
|
||||
int len0 = M0.Dim.rank - nestingDepth;
|
||||
int len1 = M1.Dim.rank - nestingDepth;
|
||||
|
||||
int* tsub0 = new int[len0];
|
||||
int* tsub1 = new int[len1];
|
||||
int* tDk1 = new int[nestingDepth];
|
||||
int* tDk0 = new int[nestingDepth];
|
||||
subArray(tsub0, M0.Dim.dim, 0, len0, 0);
|
||||
subArray(tsub1, M1.Dim.dim, 0, len1, nestingDepth);
|
||||
subArray(tDk1, M1.Dim.dim, 0, nestingDepth, 0);
|
||||
subArray(tDk0, M0.Dim.dim, 0, nestingDepth, len0);
|
||||
|
||||
dimension dSub0(len0, tsub0);
|
||||
dimension dSub1(len1, tsub1);
|
||||
dimension dM1(nestingDepth, tDk1);
|
||||
dimension dM0(nestingDepth, tDk0);
|
||||
dimension dM;
|
||||
bool rev;
|
||||
minReverse(dM, dM0, dM1, rev);
|
||||
if (rev) reverseArray(dM.dim, dM.rank);
|
||||
//max(dM, dM0, dM1);
|
||||
|
||||
add(M.Dim, dSub0, dSub1);
|
||||
M.initTensor();
|
||||
|
||||
int* coord = new int[M.Dim.rank];
|
||||
|
||||
int* coord0 = new int[len0], lin0;
|
||||
int* coord1 = new int[len1], lin1;
|
||||
|
||||
int* coordM0 = new int[M0.Dim.rank];
|
||||
int* coordM1 = new int[M1.Dim.rank];
|
||||
|
||||
int* Koord = new int[nestingDepth];
|
||||
for (int i = 0; i < M.Dim.size; i++) {
|
||||
M.Dim.LinearToCoord(coord, i);
|
||||
subArray(coord0, coord, 0, len0, 0);
|
||||
subArray(coord1, coord, 0, len1, len0);
|
||||
M.elements[i] = 0;
|
||||
for (int k = 0; k < dM.size; k++) {
|
||||
dM.LinearToCoord(Koord, k);
|
||||
concatArray(coordM0, coord0, Koord, 0, 0, len0, 0, nestingDepth);
|
||||
reverseArray(Koord, nestingDepth);
|
||||
concatArray(coordM1, Koord, coord1, 0, 0, nestingDepth, 0, len1);
|
||||
lin0 = (M0.Dim).CoordToLinear(coordM0);
|
||||
lin1 = (M1.Dim).CoordToLinear(coordM1);
|
||||
M.elements[i] += M0.elements[lin0] * M1.elements[lin1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void tensorContractnReverseProd<float>(Tensor<float>& M, const Tensor<float>& M0, const Tensor<float>& M1, int nestingDepth);
|
||||
template
|
||||
void tensorContractnReverseProd<double>(Tensor<double>& M, const Tensor<double>& M0, const Tensor<double>& M1, int nestingDepth);
|
||||
|
||||
template<typename T>
|
||||
void permuteTensorDef(Tensor<T>& M, const Tensor<T>& M0, permutation p) {
|
||||
if (p.size == M0.Dim.rank) {
|
||||
M.Dim.rank = M0.Dim.rank;
|
||||
M.Dim.size = M0.Dim.size;
|
||||
M.Dim.initDim();
|
||||
M.initTensor();
|
||||
//permuteArray(M.Dim.dim, M0.Dim.dim, p);
|
||||
//for (int i = 0; i < p.size; i++) { M.Dim.dim[i] = M0.Dim.dim[p.perm[i]]; }
|
||||
p.permute(M.Dim.dim, M0.Dim.dim);
|
||||
size_t img;
|
||||
int coor[p.size];
|
||||
int rooc[p.size];
|
||||
for (size_t i = 0; i < M.Dim.size;i++) {
|
||||
M0.Dim.LinearToCoord(coor, i);
|
||||
p.permute(rooc, coor);
|
||||
img = M.Dim.CoordToLinear(rooc);
|
||||
if (img >= M.Dim.size) printf(" i: %ld vs img:%ld size: %ld\n", i, img, M.Dim.size);
|
||||
M.elements[img] = M0.elements[i];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void permuteTensorDef(Tensor<float>& M, const Tensor<float>& M0, permutation p);
|
||||
|
||||
template<typename T>
|
||||
bool scanPermuteMatchContractTensorfromSrcToDst(int* perm, const Tensor<T>& Msecond, const Tensor<T>& Mfirst, int contractNest) {
|
||||
if (contractNest < Msecond.Dim.rank && contractNest < Mfirst.Dim.rank) {
|
||||
std::vector<int> founded;
|
||||
int begin = Mfirst.Dim.rank - contractNest, tmp;
|
||||
for (int i = 0; i < Msecond.Dim.rank;i++) perm[i] = i;
|
||||
for (int i = begin; i < Mfirst.Dim.rank; i++) {
|
||||
for (int j = 0; j < Msecond.Dim.rank;j++) {
|
||||
if (std::find(founded.begin(), founded.end(), perm[j]) == founded.end()) {// not found
|
||||
if (Msecond.Dim.dim[perm[j]] == Mfirst.Dim.dim[i]) {
|
||||
founded.push_back(perm[j]);
|
||||
tmp = perm[i - begin];
|
||||
perm[i - begin] = perm[j];
|
||||
perm[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (founded.size() == contractNest);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template
|
||||
bool scanPermuteMatchContractTensorfromSrcToDst(int* perm, const Tensor<float>& Msecond, const Tensor<float>& Mfirst, int contractNest);
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool scanInvPermuteMatchContractTensorfromSrcToDst(int* perm, const Tensor<T>& Msecond, const Tensor<T>& Mfirst, int contractNest) {
|
||||
if (contractNest < Msecond.Dim.rank && contractNest < Mfirst.Dim.rank) {
|
||||
std::vector<int> founded;
|
||||
int begin = Mfirst.Dim.rank - contractNest, tmp;
|
||||
for (int i = 0; i < Msecond.Dim.rank;i++) perm[i] = i;
|
||||
for (int i = begin; i < Mfirst.Dim.rank; i++) {
|
||||
for (int j = 0; j < Msecond.Dim.rank;j++) {
|
||||
if (std::find(founded.begin(), founded.end(), j) == founded.end()) {// not found
|
||||
if (Msecond.Dim.dim[j] == Mfirst.Dim.dim[perm[i - begin]]) {
|
||||
founded.push_back(j);
|
||||
tmp = perm[i - begin];
|
||||
perm[i - begin] = j;
|
||||
perm[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (founded.size() == contractNest);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template
|
||||
bool scanInvPermuteMatchContractTensorfromSrcToDst(int* perm, const Tensor<float>& Msecond, const Tensor<float>& Mfirst, int contractNest);
|
||||
|
||||
|
||||
void LinearTransformCoord(size_t& dst, size_t src, int* inversePerm, size_t Msize, dimension dDst, dimension dSrc) {
|
||||
size_t sm = src;
|
||||
size_t pp = Msize;
|
||||
size_t s = 0;
|
||||
size_t p = 1;
|
||||
int ret;// = new int[rank];
|
||||
int i;
|
||||
for (i = 0; i < dSrc.rank; ++i) {
|
||||
pp /= dSrc.dim[i];
|
||||
ret = sm / pp;
|
||||
p = 1;
|
||||
for (int j = inversePerm[i] + 1; j < dDst.rank;j++) {
|
||||
p *= dDst.dim[j];
|
||||
}
|
||||
s += ret * p;
|
||||
|
||||
sm %= pp;
|
||||
|
||||
}
|
||||
dst = s;
|
||||
if (s > Msize) printf("I have a problem in LinearTransformCoord: s:%ld siez:%ld \n", s, Msize);
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void permuteTensor(Tensor<T>& M, const Tensor<T>& M0, permutation p) {
|
||||
if (p.size == M0.Dim.rank) {
|
||||
M.Dim.rank = M0.Dim.rank;
|
||||
M.Dim.size = M0.Dim.size;
|
||||
M.Dim.initDim();
|
||||
M.initTensor();
|
||||
|
||||
if (p.size == M0.Dim.rank) p.permute(M.Dim.dim, M0.Dim.dim);
|
||||
else {
|
||||
printf("something wrong perm, not the same size as M0.Dim.rank\n");
|
||||
exit(1);
|
||||
}
|
||||
size_t img = 0;
|
||||
printf("in permuteTensor:\n");
|
||||
M0.Dim.print();
|
||||
M.Dim.print();
|
||||
setInit se(M.Dim.rank, 0);
|
||||
int invP[M.Dim.rank];
|
||||
inverseArray(invP, p.perm, M.Dim.rank);
|
||||
for (size_t i = 0; i < M.Dim.size;i++) {
|
||||
//LinearTransformCoord(img, i, p.perm, M.Dim.size, M.Dim, M0.Dim);
|
||||
LinearTransformCoord(img, i, invP, M.Dim.size, M.Dim, M0.Dim);
|
||||
M.elements[img] = M0.elements[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void permuteTensor(Tensor<float>& M, const Tensor<float>& M0, permutation p);
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#ifndef __TENS_0NE_D_H__
|
||||
#define __TENS_0NE_D_H__
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//#include "tensor.h"
|
||||
//#include "cudatensor.h"
|
||||
//#include "/home/fanasina/progr_/ptens0neD/dimension/dimension.h"
|
||||
//#include "/home/fanasina/progr_/ptens0neD/permutation/permutation.h"
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tensCuda/tensCuda.h"
|
||||
|
||||
#include "dimension/dimension.h"
|
||||
#include "permutation/permutation.h"
|
||||
#include "tensor/tensCuda/tensCuda.h"
|
||||
|
||||
template<typename T>
|
||||
struct Tensor {
|
||||
struct dimension Dim;
|
||||
T* elements;
|
||||
Tensor(struct dimension dm = dimension(1)) {
|
||||
Dim = dm;
|
||||
//elements = new T[Dim.size];
|
||||
elements = (T*)malloc(Dim.size * sizeof(T));
|
||||
}
|
||||
void initTensor() {
|
||||
//delete[]elements;
|
||||
//elements = new T[Dim.size];
|
||||
if (elements != NULL)
|
||||
free(elements);
|
||||
elements = (T*)malloc(Dim.size * sizeof(T));
|
||||
}
|
||||
void initVal(T val); // { for (int i = 0; i < Dim.size; i++) elements[i] = val + 0.001f * i; }
|
||||
void print();
|
||||
Tensor& operator=(const Tensor& M);
|
||||
Tensor& operator*=(const T& val);
|
||||
template<typename Ty>
|
||||
friend Tensor<Ty>& operator*(const Tensor<Ty>& M0, const Tensor<Ty>& M1);
|
||||
|
||||
// M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=n-l alor p=n+m-2l
|
||||
// M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)
|
||||
template<typename Ty>
|
||||
friend void tensorContractnProd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1, int nestingDepth);
|
||||
|
||||
// M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...<l=n / xn = y0,x{n-1}=y1, x{n-l}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=n-l alor p=n+m-2l
|
||||
// M[x0,x1,x3..xl x{l+1}..xn] X M[xn,x{n-1},..x{l+1}xl y{l+1}..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)
|
||||
template<typename Ty>
|
||||
friend void tensorContractnReverseProd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1, int nestingDepth);
|
||||
|
||||
template<typename Ty>
|
||||
friend void cudaTensorContractNestProd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1, int nestingDepth, bool strict);
|
||||
|
||||
/*template<typename Ty>
|
||||
friend void cudaTensorContractnProd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1, int nestingDepth);
|
||||
*/
|
||||
|
||||
template<typename Ty>
|
||||
friend void tensorProd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1);
|
||||
|
||||
template<typename Ty>
|
||||
friend void cudaTensorProd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1);
|
||||
|
||||
template<typename Ty>
|
||||
friend void cudaTensorProdEnd(Tensor<Ty>& M, const Tensor<Ty>& M0, const Tensor<Ty>& M1);
|
||||
|
||||
template<typename Ty>
|
||||
friend void permuteTensor(Tensor<Ty>& M, const Tensor<Ty>& M0, permutation p);
|
||||
template<typename Ty>
|
||||
friend void permuteTensorDef(Tensor<Ty>& M, const Tensor<Ty>& M0, permutation p);
|
||||
template<typename Tp>
|
||||
friend bool scanPermuteMatchContractTensorfromSrcToDst(int* perm, const Tensor<Tp>& Msecond, const Tensor<Tp>& Mfirst, int contractNest);
|
||||
|
||||
//template<typename Ty>
|
||||
//friend void cudapermuteTensor(Tensor<Ty>& M, const Tensor<Ty>& M0, permutation p);
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void transform(Tensor<T>& Dst, const Tensor<T>& Src, int* perm, int sz);
|
||||
|
||||
|
||||
template<typename T>
|
||||
Tensor<T>& operator*(const Tensor<T>& M0, const Tensor<T>& M1);
|
||||
|
||||
|
||||
void subArray(int* dst, int* src, int debDst, int finDst, int debSrc);
|
||||
|
||||
void concatArray(int* dst, int* src0, int* src1, int debDst, int debSrc0, int finSrc0, int debSrc1, int finSrc1);
|
||||
|
||||
void reverseArray(int* arr, int sz);
|
||||
|
||||
template<typename T>
|
||||
void tensorProd(Tensor<T>& M, const Tensor<T>& M1, const Tensor<T>& M0);
|
||||
|
||||
bool checkMatchProdTensor(const dimension& d0, const dimension& d1, int nestingDepth);
|
||||
|
||||
void extractDimNestingDepth(dimension& dM, const dimension& d0, const dimension& d1, int nestingDepth);
|
||||
|
||||
// M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...<l=n / xn = y0,x{n-1}=y1, x{n-l}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=n-l alor p=n+m-2l
|
||||
|
||||
//M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]
|
||||
template<typename T>
|
||||
void tensorContractnProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1, int nestingDepth);
|
||||
|
||||
// M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...<l=n / xn = y0,x{n-1}=y1, x{n-l}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=n-l alor p=n+m-2l
|
||||
|
||||
//M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]
|
||||
template<typename T>
|
||||
void tensorContractnReverseProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1, int nestingDepth);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,493 @@
|
||||
/*#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
#include "cuda.h"
|
||||
#include "cuda_runtime.h"
|
||||
*/
|
||||
|
||||
#include "d_tensCuda.h"
|
||||
//#include "index.h"
|
||||
#include <stdio.h>
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//1D grid of 1D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_1D_1D() {
|
||||
return blockIdx.x * blockDim.x + threadIdx.x;
|
||||
}
|
||||
//1D grid of 2D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_1D_2D() {
|
||||
return blockIdx.x * blockDim.x * blockDim.y
|
||||
+ threadIdx.y * blockDim.x + threadIdx.x;
|
||||
}
|
||||
//1D grid of 3D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_1D_3D() {
|
||||
return blockIdx.x * blockDim.x * blockDim.y * blockDim.z
|
||||
+ threadIdx.z * blockDim.y * blockDim.x
|
||||
+ threadIdx.y * blockDim.x + threadIdx.x;
|
||||
}
|
||||
//2D grid of 1D blocks
|
||||
__device__ int d_getGlobalIdx_2D_1D() {
|
||||
int blockId
|
||||
= blockIdx.y * gridDim.x + blockIdx.x;
|
||||
int threadId = blockId * blockDim.x + threadIdx.x;
|
||||
return threadId;
|
||||
}
|
||||
//2D grid of 2D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_2D_2D() {
|
||||
int blockId = blockIdx.x + blockIdx.y * gridDim.x;
|
||||
int threadId = blockId * (blockDim.x * blockDim.y)
|
||||
+ (threadIdx.y * blockDim.x) + threadIdx.x;
|
||||
return threadId;
|
||||
}
|
||||
//2D grid of 3D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_2D_3D() {
|
||||
int blockId = blockIdx.x + blockIdx.y * gridDim.x;
|
||||
int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)
|
||||
+ (threadIdx.z * (blockDim.x * blockDim.y))
|
||||
+ (threadIdx.y * blockDim.x) + threadIdx.x;
|
||||
return threadId;
|
||||
}
|
||||
//3D grid of 1D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_3D_1D() {
|
||||
int blockId = blockIdx.x + blockIdx.y * gridDim.x
|
||||
+ gridDim.x * gridDim.y * blockIdx.z;
|
||||
int threadId = blockId * blockDim.x + threadIdx.x;
|
||||
return threadId;
|
||||
}
|
||||
//3D grid of 2D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_3D_2D() {
|
||||
int blockId = blockIdx.x + blockIdx.y * gridDim.x
|
||||
+ gridDim.x * gridDim.y * blockIdx.z;
|
||||
int threadId = blockId * (blockDim.x * blockDim.y)
|
||||
+ (threadIdx.y * blockDim.x) + threadIdx.x;
|
||||
return threadId;
|
||||
}
|
||||
//3D grid of 3D blocks
|
||||
__device__
|
||||
int d_getGlobalIdx_3D_3D() {
|
||||
int blockId = blockIdx.x + blockIdx.y * gridDim.x
|
||||
+ gridDim.x * gridDim.y * blockIdx.z;
|
||||
int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)
|
||||
+ (threadIdx.z * (blockDim.x * blockDim.y))
|
||||
+ (threadIdx.y * blockDim.x) + threadIdx.x;
|
||||
return threadId;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
__device__ void d_LinearToCoordEnd(int* ret, size_t lin, int* dim, int rank, size_t size) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
for (int i = rank - 1;i > 0; --i) {
|
||||
pp /= dim[i];
|
||||
ret[i] = sm / pp;
|
||||
sm %= pp;
|
||||
}
|
||||
ret[0] = sm;
|
||||
}
|
||||
|
||||
__device__ size_t d_CoordToLinearEnd(int* coo, int* dim, int rank) {
|
||||
size_t pp = 1;
|
||||
size_t sm = 0;
|
||||
for (int i = 0; i < rank; ++i) {
|
||||
sm += (coo[i] * pp);
|
||||
pp *= dim[i];
|
||||
}
|
||||
return sm;
|
||||
}
|
||||
|
||||
__device__ size_t d_CoordToLinear(int* coo, int* dim, int rank) {
|
||||
size_t pp = 1;
|
||||
size_t sm = 0;
|
||||
for (int i = rank - 1; i >= 0; --i) {
|
||||
sm += (coo[i] * pp);
|
||||
pp *= dim[i];
|
||||
}
|
||||
return sm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
__device__ void d_LinearToCoord(int* ret, size_t lin, int* dim, int rank, size_t size) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
for (int i = 0; i < rank - 1; ++i) {
|
||||
pp /= dim[i];
|
||||
ret[i] = sm / pp;
|
||||
sm %= pp;
|
||||
}
|
||||
ret[rank - 1] = sm;
|
||||
}
|
||||
/*__device__ void d_LinearToSplitSubrankLimSz(size_t& part0, size_t& part1, size_t lin, int* dim, int rank, int rankA, size_t size, size_t sizeA) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
size_t s = 0;
|
||||
size_t p = sizeA;
|
||||
int ret;// = new int[rank];
|
||||
for (int i = 0; i < rank; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
p /= dim[i];
|
||||
s += ret * p;
|
||||
|
||||
sm %= pp;
|
||||
if (i == rankA - 1) {
|
||||
part0 = s;
|
||||
s = 0;
|
||||
p = size / sizeA;
|
||||
}
|
||||
|
||||
}
|
||||
part1 = s;
|
||||
|
||||
}*/
|
||||
__device__ void d_LinearToSplitSubrankLimSz(size_t& part0, size_t& part1, size_t lin, int* dim, int rank, int rankA, size_t size, size_t sizeA) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
size_t s = 0;
|
||||
size_t p = sizeA;
|
||||
int ret;// = new int[rank];
|
||||
int i;
|
||||
for (i = 0; i < rankA; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
p /= dim[i];
|
||||
s += ret * p;
|
||||
|
||||
sm %= pp;
|
||||
|
||||
}
|
||||
part0 = s;
|
||||
s = 0;
|
||||
p = size / sizeA;//sizeB
|
||||
for (; i < rank; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
p /= dim[i];
|
||||
s += ret * p;
|
||||
|
||||
sm %= pp;
|
||||
|
||||
}
|
||||
|
||||
part1 = s;
|
||||
|
||||
}
|
||||
__device__ void d_LinearToSplitSubrankLimSzEnd(size_t& part0, size_t& part1, size_t lin, int* dim, int rank, int rankA, size_t size, size_t sizeA) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
size_t s = 0;
|
||||
size_t p = sizeA;
|
||||
int ret;// = new int[rank];
|
||||
for (int i = rank - 1; i >= 0; --i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
p /= dim[i];
|
||||
s += ret * p;
|
||||
|
||||
sm %= pp;
|
||||
if (i == rankA) {
|
||||
part1 = s;
|
||||
s = 0;
|
||||
p = size / sizeA;
|
||||
}
|
||||
|
||||
}
|
||||
part0 = s;
|
||||
|
||||
}
|
||||
|
||||
|
||||
__device__ void d_subArray(int* dst, int* src, int debDst, int finDst, int debSrc) {
|
||||
for (int i = debDst; i < finDst; i++) {
|
||||
dst[i] = src[i + debSrc];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_prodTensor(T* C, int* dimC, int rankC, size_t size, T* A, int* dimA, int rankA, size_t sizeA, T* B, int* dimB, int rankB) {
|
||||
size_t lin0, lin1;
|
||||
|
||||
size_t i = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if (i < size) {
|
||||
d_LinearToSplitSubrankLimSz(lin0, lin1, i, dimC, rankC, rankA, size, sizeA);
|
||||
|
||||
C[i] = A[lin0] * B[lin1];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template __global__ void d_prodTensor<float>(float* C, int* dimC, int rankC, size_t size, float* A, int* dimA, int rankA, size_t sizeA, float* B, int* dimB, int rankB);
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_prodTensorEnd(T* C, int* dimC, int rankC, size_t size, T* A, int* dimA, int rankA, size_t sizeA, T* B, int* dimB, int rankB) {
|
||||
size_t lin0, lin1;
|
||||
|
||||
size_t i = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if (i < size) {
|
||||
d_LinearToSplitSubrankLimSzEnd(lin0, lin1, i, dimC, rankC, rankA, size, sizeA);
|
||||
|
||||
C[i] = A[lin0] * B[lin1];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template __global__ void d_prodTensorEnd<float>(float* C, int* dimC, int rankC, size_t size, float* A, int* dimA, int rankA, size_t sizeA, float* B, int* dimB, int rankB);
|
||||
|
||||
__device__ void d_minReverse(int* dim, int& rank, const int* dim0, int rank0, const int* dim1, int rank1, bool& rev) {
|
||||
if (rank0 > rank1) {
|
||||
rank = rank1;
|
||||
for (int i = 0; i < rank1; ++i) dim[i] = dim1[i];
|
||||
rev = true;
|
||||
}
|
||||
else if (rank0 < rank1) {
|
||||
rank = rank0;
|
||||
for (int i = 0; i < rank1; ++i) dim[i] = dim0[i];
|
||||
rev = false;
|
||||
}
|
||||
else {// rank0 == rank1
|
||||
rank = rank0;
|
||||
for (int i = 0; i < rank0; i++) {
|
||||
if (dim[i] > dim1[rank1 - 1 - i]) dim[i] = dim1[rank1 - 1 - i];
|
||||
else dim[i] = dim0[i];
|
||||
}
|
||||
rev = false;
|
||||
}
|
||||
}
|
||||
|
||||
__device__ void d_reverseArray(int* arr, int sz) {
|
||||
int* tmp;
|
||||
//tmp = (int*)malloc(sz * sizeof(int));
|
||||
|
||||
tmp = new int[sz];
|
||||
if (tmp == NULL) {
|
||||
size_t limit = 0;
|
||||
cudaDeviceGetLimit(&limit, cudaLimitStackSize);
|
||||
printf("cudaLimitStackSize: %u | %d (%d) %d | \n", (unsigned)limit, blockIdx.x, blockDim.x, threadIdx.x);
|
||||
cudaDeviceGetLimit(&limit, cudaLimitPrintfFifoSize);
|
||||
printf("cudaLimitPrintfFifoSize: %u | %d (%d) %d | \n", (unsigned)limit, blockIdx.x, blockDim.x, threadIdx.x);
|
||||
cudaDeviceGetLimit(&limit, cudaLimitMallocHeapSize);
|
||||
printf("cudaLimitMallocHeapSize: %u | %d (%d) %d | \n", (unsigned)limit, blockIdx.x, blockDim.x, threadIdx.x);
|
||||
|
||||
printf("error Allocation in tmp = (int*)malloc(sz * sizeof(int)); | | ");
|
||||
}int i = 0;
|
||||
for (; i < sz / 2; i++) {
|
||||
tmp[i] = arr[i];
|
||||
arr[i] = arr[sz - 1 - i];
|
||||
}
|
||||
for (; i < sz; i++) {
|
||||
arr[i] = tmp[sz - 1 - i];
|
||||
}
|
||||
//free(tmp);
|
||||
delete[]tmp;
|
||||
}
|
||||
|
||||
__device__ int d_min(int a, int b) {
|
||||
if (a < b) return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
__device__ void d_concatArray(int* dst, int* src0, int* src1, int debDst, int debSrc0, int finSrc0, int debSrc1, int finSrc1) {
|
||||
int i = debDst;
|
||||
for (int j = debSrc0; j < finSrc0; j++) {
|
||||
dst[i++] = src0[j];
|
||||
}
|
||||
for (int j = debSrc1; j < finSrc1; j++) {
|
||||
dst[i++] = src1[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
__device__ void d_ConcatLinearToSplitSubrankLimSz(size_t& part0, size_t& part1, size_t lin, int* dim, int rank, int rankA, int rankB, size_t size, size_t sizeA, size_t sizeB, int* dM, int dMrank, size_t dMsize, int ind) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
size_t s = 0;
|
||||
size_t p = sizeA;
|
||||
//size_t sz_dA = sizeA / dMsize;
|
||||
int rankdA = rankA - dMrank;
|
||||
|
||||
int ret;
|
||||
int i;
|
||||
for (i = 0; i < rankdA; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
p /= dim[i];
|
||||
s += ret * p;
|
||||
sm %= pp;
|
||||
}
|
||||
size_t s1 = 0;
|
||||
|
||||
size_t pb = sizeB / dMsize;
|
||||
for (; i < rank; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
pb /= dim[i];
|
||||
s1 += ret * pb;
|
||||
sm %= pp;
|
||||
}
|
||||
|
||||
size_t smd = ind;
|
||||
size_t ppb = dMsize;
|
||||
//size_t pb = size / sz_dA;
|
||||
pb = sizeB;
|
||||
p = dMsize;
|
||||
for (int j = 0;j < dMrank;j++) {
|
||||
ppb /= dM[j];
|
||||
ret = smd / ppb;
|
||||
p /= dM[j];
|
||||
s += ret * p;
|
||||
pb /= dM[j];
|
||||
s1 += ret * pb;
|
||||
smd %= ppb;
|
||||
}
|
||||
//pp = size / sz_dA;
|
||||
part0 = s;
|
||||
part1 = s1;
|
||||
}
|
||||
|
||||
__device__ void d_SplitLineardToSubrank(size_t& part0, size_t& part1, size_t lin, int* dim, int rank, int rankA, int rankB, size_t size, size_t sizeA, size_t sizeB, int* dM, int dMrank, size_t dMsize) {
|
||||
size_t sm = lin;
|
||||
size_t pp = size;
|
||||
size_t s = 0;
|
||||
size_t p = sizeA;
|
||||
//size_t sz_dA = sizeA / dMsize;
|
||||
int rankdA = rankA - dMrank;
|
||||
|
||||
int ret;
|
||||
int i;
|
||||
for (i = 0; i < rankdA; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
p /= dim[i];
|
||||
s += ret * p;
|
||||
sm %= pp;
|
||||
}
|
||||
size_t s1 = 0;
|
||||
|
||||
size_t pb = sizeB / dMsize;
|
||||
for (; i < rank; ++i) {
|
||||
pp /= dim[i];
|
||||
ret = sm / pp;
|
||||
pb /= dim[i];
|
||||
s1 += ret * pb;
|
||||
sm %= pp;
|
||||
}
|
||||
part0 = s;
|
||||
part1 = s1;
|
||||
}
|
||||
|
||||
|
||||
__device__ void d_UnionConcatLinearSplitedSubrank(size_t& part0, size_t& part1, size_t p0, size_t p1, size_t size, size_t sizeB, int* dM, int dMrank, size_t dMsize, int ind) {
|
||||
size_t s = p0;
|
||||
size_t s1 = p1;
|
||||
int ret;
|
||||
size_t smd = ind;
|
||||
size_t ppb = dMsize;
|
||||
//size_t pb = size / sz_dA;
|
||||
size_t pb = sizeB;
|
||||
size_t p = dMsize;
|
||||
for (int j = 0;j < dMrank;j++) {
|
||||
ppb /= dM[j];
|
||||
ret = smd / ppb;
|
||||
p /= dM[j];
|
||||
s += ret * p;
|
||||
pb /= dM[j];
|
||||
s1 += ret * pb;
|
||||
smd %= ppb;
|
||||
}
|
||||
//pp = size / sz_dA;
|
||||
part0 = s;
|
||||
part1 = s1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_TensorContractnReverseProd(T* C, int* dimC, int rankC, size_t sizeC, T* A, int rankA, size_t sizeA, T* B, int rankB, size_t sizeB, int* dM, int dMrank, size_t dMsize) {
|
||||
|
||||
size_t p0, p1;
|
||||
size_t lin0, lin1;
|
||||
|
||||
|
||||
//size_t i = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
size_t i = d_getGlobalIdx_1D_1D();
|
||||
|
||||
if (i < sizeC) {
|
||||
|
||||
d_SplitLineardToSubrank(p0, p1, i, dimC, rankC, rankA, rankB, sizeC, sizeA, sizeB, dM, dMrank, dMsize);
|
||||
|
||||
C[i] = 0;
|
||||
for (size_t k = 0; k < dMsize; k++) {
|
||||
|
||||
d_UnionConcatLinearSplitedSubrank(lin0, lin1, p0, p1, sizeC, sizeB, dM, dMrank, dMsize, k);
|
||||
|
||||
//d_ConcatLinearToSplitSubrankLimSz(lin0, lin1, i, dimC, rankC, rankA, rankB, sizeC, sizeA, sizeB, dM, dMrank, dMsize, k);
|
||||
|
||||
C[i] += A[lin0] * B[lin1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template
|
||||
__global__ void d_TensorContractnReverseProd<float>(float* C, int* dimC, int rankC, size_t size, float* A, int rankA, size_t sizeA, float* B, int rankB, size_t sizeB, int* dM, int dMrank, size_t dMsize);
|
||||
|
||||
__device__ void d_LinearTransformCoord(size_t& dst, size_t src, int* inversePerm, size_t sizeA, int rankDst, int rankSrc, int* dDst, int* dSrc) {
|
||||
size_t sm = src;
|
||||
size_t pp = sizeA;
|
||||
size_t s = 0;
|
||||
size_t p = 1;
|
||||
int ret;// = new int[rank];
|
||||
int i, j;
|
||||
for (i = 0; i < rankSrc; ++i) {
|
||||
pp /= dSrc[i];
|
||||
ret = sm / pp;
|
||||
p = 1;
|
||||
for (j = inversePerm[i] + 1; j < rankDst;j++) {
|
||||
p *= dDst[j];
|
||||
}
|
||||
s += ret * p;
|
||||
|
||||
sm %= pp;
|
||||
|
||||
}
|
||||
dst = s;
|
||||
if (s > sizeA) printf("I have a problem in LinearTransformCoord: s:%ld siez:%ld \n", s, sizeA);
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_PermLinearTransformCoord(T* C, int* dimC, int rankC, size_t sizeC, T* A, int* dimA, int rankA, size_t sizeA, int* invPerm) {
|
||||
|
||||
//size_t i = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
size_t i = d_getGlobalIdx_1D_1D();
|
||||
|
||||
if (i < sizeC) {
|
||||
//printf("<i:%*ld ", 3, i);
|
||||
|
||||
size_t img = 0;
|
||||
//printf("<i:%*ld, img:%*ld\n", 3, i, 3, img);
|
||||
d_LinearTransformCoord(img, i, invPerm, sizeA, rankC, rankA, dimC, dimA);
|
||||
//img = d_LinearTransformCoord(i, invPerm, sizeC, dimC, dimA, rankC);
|
||||
|
||||
if (img < sizeC)
|
||||
C[img] = A[i];
|
||||
else {
|
||||
printf("something wrong in device: i:%ld , s:%ld\n", i, img);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template
|
||||
__global__ void d_PermLinearTransformCoord<float>(float* C, int* dimC, int rankC, size_t size, float* A, int* dimA, int rankA, size_t sizeA, int* invPerm);
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef __D_CUDA_TENSOR_H__
|
||||
#define __D_CUDA_TENSOR_H__
|
||||
|
||||
#include "cuda.h"
|
||||
#include "cuda_runtime.h"
|
||||
|
||||
//#include "cuda_device_runtime_api.h"
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tensCuda/d_tensCuda.h"
|
||||
#include "tensor/tensCuda/d_tensCuda.h"
|
||||
|
||||
|
||||
//#1D grid of 1D blocks
|
||||
__device__ int d_getGlobalIdx_1D_1D();
|
||||
//#1D grid of 2D blocks
|
||||
__device__ int d_getGlobalIdx_1D_2D();
|
||||
//#1D grid of 3D blocks
|
||||
__device__ int d_getGlobalIdx_1D_3D();
|
||||
//#1D grid of 1D blocks
|
||||
__device__ int d_getGlobalIdx_2D_1D();
|
||||
//#1D grid of 2D blocks
|
||||
__device__ int d_getGlobalIdx_2D_2D();
|
||||
//2D grid of 3D blocks
|
||||
__device__ int d_getGlobalIdx_2D_3D();
|
||||
//#1D grid of 1D blocks
|
||||
__device__ int d_getGlobalIdx_3D_1D();
|
||||
//#1D grid of 2D blocks
|
||||
__device__ int d_getGlobalIdx_3D_2D();
|
||||
//#1D grid of 3D blocks
|
||||
__device__ int d_getGlobalIdx_3D_3D();
|
||||
|
||||
|
||||
|
||||
extern cudaError_t cudaDeviceGetLimit(size_t* pValue, enum cudaLimit limit);
|
||||
|
||||
|
||||
__device__ void d_LinearToCoordEnd(int* ret, size_t lin, int* dim, int rank, size_t size);
|
||||
|
||||
__device__ size_t d_CoordToLinearEnd(int* coo, int* dim, int rank);
|
||||
|
||||
__device__ size_t d_CoordToLinear(int* coo, int* dim, int rank);
|
||||
|
||||
|
||||
__device__ void d_LinearToCoord(int* ret, size_t lin, int* dim, int rank, size_t size);
|
||||
|
||||
__device__ void d_subArray(int* dst, int* src, int debDst, int finDst, int debSrc);
|
||||
|
||||
__device__ void d_minReverse(int* dim, int& rank, const int* dim0, int rank0, const int* dim1, int rank1, bool& rev);
|
||||
|
||||
__device__ void d_reverseArray(int* arr, int sz);
|
||||
|
||||
__device__ int d_min(int a, int b);
|
||||
|
||||
__device__ void d_concatArray(int* dst, int* src0, int* src1, int debDst, int debSrc0, int finSrc0, int debSrc1, int finSrc1);
|
||||
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_prodTensor(T* C, int* dimC, int rankC, size_t size, T* A, int* dimA, int rankA, size_t sizeA, T* B, int* dimB, int rankB);
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_prodTensorEnd(T* C, int* dimC, int rankC, size_t size, T* A, int* dimA, int rankA, size_t sizeA, T* B, int* dimB, int rankB);
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_TensorContractnReverseProd(T* C, int* dimC, int rankC, size_t size, T* A, int rankA, size_t sizeA, T* B, int rankB, size_t sizeB, int* dM, int dMrank, size_t dMsize);
|
||||
|
||||
template<typename T>
|
||||
__global__ void d_PermLinearTransformCoord(T* C, int* dimC, int rankC, size_t sizeC, T* A, int* dimA, int rankA, size_t sizeA, int* invPerm);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,574 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tens0neD/tens0neD.h"
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tensCuda/tensCuda.h"
|
||||
#include "tensor/tensCuda/tensCuda.h"
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void cudaTensorProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1) {
|
||||
add(M.Dim, M0.Dim, M1.Dim);
|
||||
M.initTensor();
|
||||
|
||||
int* d_imM, * d_imM0, * d_imM1;
|
||||
cudaError_t errCu = cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imM1, M1.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM1, M1.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imM1, M1.Dim.dim, M1.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM1, M1.Dim.dim, M1.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
T* e, * e0, * e1;
|
||||
errCu = cudaMalloc((void**)&e, M.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e, M.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e1, M1.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e1, M1.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(e1, M1.elements, M1.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e1, M1.elements, M1.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
int BLOCKSIZE = 256;//1024;
|
||||
int DIMBLOCKS = (M.Dim.size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
//int DIMBLOCKS = (M.Dim.size) / BLOCKSIZE;
|
||||
|
||||
d_prodTensor<T> << < DIMBLOCKS, BLOCKSIZE >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, d_imM0, M0.Dim.rank, M0.Dim.size, e1, d_imM1, M1.Dim.rank);
|
||||
|
||||
errCu = cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaFree(e);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e1);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e1) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM1);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM1) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//template void cudaTensorProd<double>(Tensor<double>& M, const Tensor<double>& M1, const Tensor<double>& M0);
|
||||
template void cudaTensorProd<float>(Tensor<float>& M, const Tensor<float>& M1, const Tensor<float>& M0);
|
||||
|
||||
|
||||
template<typename T>
|
||||
void cudaTensorProdEnd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1) {
|
||||
add(M.Dim, M0.Dim, M1.Dim);
|
||||
M.initTensor();
|
||||
|
||||
int* d_imM, * d_imM0, * d_imM1;
|
||||
cudaError_t errCu = cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imM1, M1.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM1, M1.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imM1, M1.Dim.dim, M1.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM1, M1.Dim.dim, M1.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
T* e, * e0, * e1;
|
||||
errCu = cudaMalloc((void**)&e, M.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e, M.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e1, M1.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e1, M1.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(e1, M1.elements, M1.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e1, M1.elements, M1.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
size_t BLOCKSIZE = 1024;
|
||||
size_t DIMBLOCKS = (M.Dim.size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
|
||||
d_prodTensorEnd<T> << < DIMBLOCKS, BLOCKSIZE >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, d_imM0, M0.Dim.rank, M0.Dim.size, e1, d_imM1, M1.Dim.rank);
|
||||
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
errCu = cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaFree(e);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e1);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e1) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM1);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM1) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//template void cudaTensorProd<double>(Tensor<double>& M, const Tensor<double>& M1, const Tensor<double>& M0);
|
||||
template void cudaTensorProdEnd<float>(Tensor<float>& M, const Tensor<float>& M1, const Tensor<float>& M0);
|
||||
|
||||
|
||||
template<typename T>
|
||||
void cudapermuteTensor(Tensor<T>& M, const Tensor<T>& M0, permutation p) {
|
||||
if (p.size == M0.Dim.rank) {
|
||||
M.Dim.rank = M0.Dim.rank;
|
||||
M.Dim.size = M0.Dim.size;
|
||||
M.Dim.initDim();
|
||||
M.initTensor();
|
||||
|
||||
p.permute(M.Dim.dim, M0.Dim.dim);
|
||||
|
||||
|
||||
cudaEvent_t start, stop;
|
||||
cudaEventCreate(&start);
|
||||
cudaEventCreate(&stop);
|
||||
|
||||
cudaEventRecord(start);
|
||||
|
||||
|
||||
int* d_imM, * d_imM0;
|
||||
cudaError_t errCu = cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
|
||||
T* e, * e0;
|
||||
errCu = cudaMalloc((void**)&e, M.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e, M.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
|
||||
errCu = cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
|
||||
size_t BLOCKSIZE = 256; //1024;//512;
|
||||
size_t DIMBLOCKS = (M.Dim.size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
dim3 blckSZ, gridSZ;
|
||||
blckSZ.x = BLOCKSIZE;
|
||||
gridSZ.x = DIMBLOCKS;
|
||||
|
||||
int* invP, * d_invP;
|
||||
invP = (int*)malloc(M.Dim.rank * sizeof(int));
|
||||
inverseArray(invP, p.perm, M.Dim.rank);
|
||||
errCu = cudaMalloc((void**)&d_invP, M.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_invP, M.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(d_invP, invP, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_invP, invP, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
//printf("size: %ld\n", M.Dim.size);
|
||||
|
||||
//d_prodTensorEnd<T> << < DIMBLOCKS, BLOCKSIZE >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, d_imM0, M0.Dim.rank, e1, d_imM1, M1.Dim.rank);
|
||||
//d_TensorContractnReverseProd<T> << < DIMBLOCKS, BLOCKSIZE >> > (e, d_imM, M.Dim.rank, M.Dim.size, d_imdM, dM.rank, dM.size, e0, d_imM0, M0.Dim.rank, e1, d_imM1, M1.Dim.rank, nestingDepth);
|
||||
//d_TensorContractnReverseProd<T> << < gridSZ, blckSZ, 0, 0 >> > (e, d_imM, M.Dim.rank, M.Dim.size, d_imdM, dM.rank, dM.size, e0, d_imM0, M0.Dim.rank, e1, d_imM1, M1.Dim.rank, nestingDepth);
|
||||
d_PermLinearTransformCoord<T> << < gridSZ, blckSZ, 0, 0 >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, d_imM0, M0.Dim.rank, M0.Dim.size, d_invP);
|
||||
//d_PermLinearTransformCoord<T> << < gridSZ, blckSZ, 0, 0 >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, d_imM0, M0.Dim.rank, M0.Dim.size, p.perm);
|
||||
//cudaDeviceSynchronize();
|
||||
|
||||
|
||||
errCu = cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaFree(e);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaFree(d_imM);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
cudaEventRecord(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
float milliseconds = 0;
|
||||
cudaEventElapsedTime(&milliseconds, start, stop);
|
||||
printf("ellaps time cuda permute tensor: %f ms\n", milliseconds);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void cudapermuteTensor(Tensor<float>& M, const Tensor<float>& M0, permutation p);
|
||||
|
||||
|
||||
// strict match contract ! if no strict, we take the minimum
|
||||
template<typename T>
|
||||
void cudaTensorContractNestProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M11, int nestingDepth, bool strict) {
|
||||
|
||||
|
||||
int perm[M11.Dim.rank];
|
||||
struct Tensor<T> M1;
|
||||
if (scanPermuteMatchContractTensorfromSrcToDst(perm, M11, M0, nestingDepth)) {
|
||||
for (int i = 0; i < M11.Dim.rank; i++) printf(" %d[%d] ", i, perm[i]); printf(": last perm \n");
|
||||
struct permutation p(M11.Dim.rank, perm);
|
||||
permuteTensor(M1, M11, p);
|
||||
M1.Dim.print();
|
||||
|
||||
}
|
||||
else {
|
||||
printf("Failed in Deep = %d\n", nestingDepth);
|
||||
//throw std::check_ProdTensor(" Failed imbrication order in Multiplication matrix ");
|
||||
|
||||
throw std::invalid_argument(" Failed imbrication order in Multiplication matrix ");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
cudaEvent_t start, stop;
|
||||
cudaEventCreate(&start);
|
||||
cudaEventCreate(&stop);
|
||||
|
||||
cudaEventRecord(start);
|
||||
|
||||
int len0 = M0.Dim.rank - nestingDepth;
|
||||
int len1 = M1.Dim.rank - nestingDepth;
|
||||
|
||||
int* tsub0 = new int[len0];
|
||||
int* tsub1 = new int[len1];
|
||||
int* tDk1 = new int[nestingDepth];
|
||||
int* tDk0 = new int[nestingDepth];
|
||||
subArray(tsub0, M0.Dim.dim, 0, len0, 0);
|
||||
subArray(tsub1, M1.Dim.dim, 0, len1, nestingDepth);
|
||||
subArray(tDk1, M1.Dim.dim, 0, nestingDepth, 0);
|
||||
subArray(tDk0, M0.Dim.dim, 0, nestingDepth, len0);
|
||||
|
||||
dimension dSub0(len0, tsub0);
|
||||
dimension dSub1(len1, tsub1);
|
||||
dimension dM1(nestingDepth, tDk1);
|
||||
dimension dM0(nestingDepth, tDk0);
|
||||
dimension dM(dM0);
|
||||
//bool rev;
|
||||
//minReverse(dM, dM0, dM1, rev);
|
||||
//if (rev) reverseArray(dM.dim, dM.rank);
|
||||
//max(dM, dM0, dM1);
|
||||
|
||||
add(M.Dim, dSub0, dSub1);
|
||||
M.initTensor();
|
||||
|
||||
|
||||
|
||||
int* d_imM, * d_imM0, * d_imM1, * d_imdM;
|
||||
cudaError_t errCu = cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM, M.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imdM, dM.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imdM, dM.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM0, M0.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&d_imM1, M1.Dim.rank * sizeof(int));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&d_imM1, M1.Dim.rank * sizeof(int)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM, M.Dim.dim, M.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imdM, dM.dim, dM.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imdM, dM.dim, dM.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM0, M0.Dim.dim, M0.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(d_imM1, M1.Dim.dim, M1.Dim.rank * sizeof(int), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(d_imM1, M1.Dim.dim, M1.Dim.rank * sizeof(int), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
T* e, * e0, * e1;
|
||||
errCu = cudaMalloc((void**)&e, M.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e, M.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e0, M0.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMalloc((void**)&e1, M1.Dim.size * sizeof(T));
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMalloc((void**)&e1, M1.Dim.size * sizeof(T)) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e0, M0.elements, M0.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaMemcpy(e1, M1.elements, M1.Dim.size * sizeof(T), cudaMemcpyHostToDevice);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(e1, M1.elements, M1.Dim.size * sizeof(T), cudaMemcpyHostToDevice) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
size_t BLOCKSIZE = 256; //1024;//512;
|
||||
size_t DIMBLOCKS = (M.Dim.size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
dim3 blckSZ, gridSZ;
|
||||
blckSZ.x = BLOCKSIZE;
|
||||
gridSZ.x = DIMBLOCKS;
|
||||
|
||||
|
||||
//d_prodTensorEnd<T> << < DIMBLOCKS, BLOCKSIZE >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, d_imM0, M0.Dim.rank, e1, d_imM1, M1.Dim.rank);
|
||||
//d_TensorContractnReverseProd<T> << < DIMBLOCKS, BLOCKSIZE >> > (e, d_imM, M.Dim.rank, M.Dim.size, d_imdM, dM.rank, dM.size, e0, d_imM0, M0.Dim.rank, e1, d_imM1, M1.Dim.rank, nestingDepth);
|
||||
//d_TensorContractnReverseProd<T> << < gridSZ, blckSZ, 0, 0 >> > (e, d_imM, M.Dim.rank, M.Dim.size, d_imdM, dM.rank, dM.size, e0, d_imM0, M0.Dim.rank, e1, d_imM1, M1.Dim.rank, nestingDepth);
|
||||
d_TensorContractnReverseProd<T> << < gridSZ, blckSZ, 0, 0 >> > (e, d_imM, M.Dim.rank, M.Dim.size, e0, M0.Dim.rank, M0.Dim.size, e1, M1.Dim.rank, M1.Dim.size, d_imdM, dM.rank, dM.size);
|
||||
|
||||
//cudaDeviceSynchronize();
|
||||
|
||||
|
||||
errCu = cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaMemcpy(M.elements, e, M.Dim.size * sizeof(T), cudaMemcpyDeviceToHost) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
|
||||
errCu = cudaFree(e);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(e1);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(e1) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM0);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM0) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
errCu = cudaFree(d_imM1);
|
||||
if (cudaSuccess != errCu) {
|
||||
printf("device fnc failed cudaFree(d_imM1) \n ErrorCuda: %d : %s\n", errCu, cudaGetErrorString(errCu));
|
||||
exit(errCu);
|
||||
}
|
||||
cudaEventRecord(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
float milliseconds = 0;
|
||||
cudaEventElapsedTime(&milliseconds, start, stop);
|
||||
printf("ellaps time cuda prod contract prod: %f ms\n", milliseconds);
|
||||
|
||||
|
||||
}
|
||||
|
||||
template
|
||||
void cudaTensorContractNestProd<float>(Tensor<float>& M, const Tensor<float>& M0, const Tensor<float>& M1, int nestingDepth, bool strict);
|
||||
//template void cudaTensorContractnReverseProd<double>(Tensor<double>& M, const Tensor<double>& M0, const Tensor<double>& M1, int nestingDepth);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef __TENS_CUDA_H__
|
||||
#define __TENS_CUDA_H__
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tens0neD/tens0neD.h"
|
||||
#include "tensor/tens0neD/tens0neD.h"
|
||||
|
||||
//#include "/home/fanasina/progr_/ptens0neD/tensor/tensCuda/d_tensCuda.h"
|
||||
#include "tensor/tensCuda/d_tensCuda.h"
|
||||
//#include "dimension/dimension.h"
|
||||
|
||||
template<typename T>
|
||||
struct Tensor;
|
||||
|
||||
template<typename T>
|
||||
void cudaTensorContractNestProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1, int nestingDepth, bool strict = true);
|
||||
|
||||
template<typename T>
|
||||
void cudaTensorProd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1);
|
||||
template<typename T>
|
||||
void cudaTensorProdEnd(Tensor<T>& M, const Tensor<T>& M0, const Tensor<T>& M1);
|
||||
template<typename T>
|
||||
void cudapermuteTensor(Tensor<T>& M, const Tensor<T>& M0, permutation p);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm /usr/lib/libytest.so
|
||||
if [ -d /usr/local/include ] ; then
|
||||
echo "remove from /usr/local/include/" ;
|
||||
rm -r /usr/local/include/ftest ;
|
||||
rm -r /usr/local/include/fmock ;
|
||||
rm -r /usr/local/include/bar_progress ;
|
||||
rm -r /usr/local/include/tools_t ;
|
||||
else
|
||||
echo "remove from /usr/include/" ;
|
||||
rm -r /usr/include/ftest ;
|
||||
rm -r /usr/include/fmock ;
|
||||
rm -r /usr/include/bar_progress ;
|
||||
rm -r /usr/include/tools_t ;
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | sed "s@$PWD:@@g")
|
||||
CPATH=$(echo $CPATH | sed "s@$PWD/include_ytest/include:@@g")
|
||||
|
||||
if [ "$#" -le 0 ] ; then
|
||||
echo "If need permanent unset env "
|
||||
echo "Usage: $0 file_name"
|
||||
echo "for example: $0 ~/.bashrc" >&2
|
||||
echo "or other bash profile ( here : \"~/.bashrc\" for example), the same file you have set with set_env.sh"
|
||||
fi
|
||||
|
||||
|
||||
if [ "$#" -ge 1 ] ; then
|
||||
sed -i "\@export CPATH=$PWD/include_ytest/include:\$CPATH@d" "$1"
|
||||
sed -i "\@export LD_LIBRARY_PATH=$PWD:\$LD_LIBRARY_PATH@d" "$1"
|
||||
|
||||
fi
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
FMOCK_SRC=src/fmock/fmock.c
|
||||
FMOCK_O=$(FMOCK_SRC:.c=.o)
|
||||
|
||||
FTEST_SRC=../yftest/src/ftest/ftest.c
|
||||
FTEST_O=$(FTEST_SRC:.c=.o)
|
||||
|
||||
|
||||
all: $(FMOCK_O)
|
||||
|
||||
$(FMOCK_O): $(FMOCK_SRC) $(FTEST_O)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(FMOCK_O)
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
#ifndef __MOCK_C_H__
|
||||
#define __MOCK_C_H__
|
||||
|
||||
#include "ftest/ftest.h"
|
||||
#include "tools_t/tools_t.h"
|
||||
|
||||
#define INFINITY -8
|
||||
#define INITSTATE -1
|
||||
#define DONOTHING 0
|
||||
|
||||
#define PRE_ID ___line_
|
||||
/*
|
||||
* list of each variable called
|
||||
* use str_print_current_variables attibute function pointer to record variable
|
||||
* so if STR_PRINT_CUR_VAR is not defined, this list is empty!
|
||||
*/
|
||||
struct list_current_variable{
|
||||
char *str_current_variables;
|
||||
struct list_current_variable *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* list to store info abou mock function
|
||||
*/
|
||||
struct func_mock_info_struct{
|
||||
long id;
|
||||
char *str_namefunc;
|
||||
char *str_conditions;
|
||||
char *str_caller;
|
||||
//char *str_current_variables;
|
||||
struct list_current_variable *l_current_var;
|
||||
int expect_call;/* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */
|
||||
long call;/* increment when call (try to executed) and 0 if not : init value */
|
||||
long failed_call;/* increment when condition not fill and 0 if not : init value */
|
||||
long init_times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */
|
||||
long times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */
|
||||
struct func_mock_info_struct *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* to list all mock responses of all mock functions in one list
|
||||
*/
|
||||
struct list_base_fmock{
|
||||
struct func_mock_info_struct *info_mock;
|
||||
struct list_base_fmock *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int parse_count_args_(char *input);
|
||||
void append_fmock_to_listmock(struct func_mock_info_struct **f_mock_list, struct func_mock_info_struct *f_mock);
|
||||
void append_list_base_fmock(struct list_base_fmock **l_fmock, struct func_mock_info_struct *f_mock);
|
||||
void append_variable_current(struct list_current_variable **lcurrent_var, char *current_var);
|
||||
|
||||
// if input == functioname___line_NBLINE return functioname, else it return the input
|
||||
//char* extract_name_func_mock(char *input);
|
||||
|
||||
extern struct func_mock_info_struct *f_mock_glist;
|
||||
extern struct list_base_fmock *g_list_base_fmock;
|
||||
|
||||
#if 0
|
||||
int expect_call; /* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */\
|
||||
long init_times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\
|
||||
long times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\
|
||||
|
||||
#endif
|
||||
|
||||
#define INIT_MOCK_INFO_IF_NO__(tmp__mock, namefunction, pre_id, id) \
|
||||
(tmp__mock)->run = NULL;\
|
||||
(tmp__mock)->call_mock_condition = NULL;\
|
||||
/*(tmp__mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;*/\
|
||||
((tmp__mock)->info_mock)->expect_call = -1;\
|
||||
((tmp__mock)->info_mock)->call = 0;\
|
||||
((tmp__mock)->info_mock)->failed_call = 0;\
|
||||
((tmp__mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\
|
||||
sprintf(((tmp__mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\
|
||||
((tmp__mock)->info_mock)->str_conditions = NULL;\
|
||||
((tmp__mock)->info_mock)->str_caller = NULL;\
|
||||
((tmp__mock)->info_mock)->l_current_var= NULL;\
|
||||
((tmp__mock)->info_mock)->next = NULL;\
|
||||
/*(tmp__mock)->next = NULL;*/\
|
||||
append_fmock_to_listmock(&f_mock_glist, (tmp__mock)->info_mock);\
|
||||
append_list_base_fmock( &g_list_base_fmock ,(tmp__mock)->info_mock);
|
||||
|
||||
#define INIT_MOCK_INFO_IF_NO_(tmp_new_mock, namefunction, pre_id) \
|
||||
INIT_MOCK_INFO_IF_NO__(tmp_new_mock, namefunction, pre_id, __LINE__) \
|
||||
|
||||
#define MOCK_FUNC(returntype, namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\
|
||||
/*typedef returntype FUNC_type_ ## namefunction args_prototype_with_parenthesis ;*/\
|
||||
/*typedef args_prototype_with_parenthesis args_ ## namefunction;*/\
|
||||
struct list_mock_return_ ## namefunction{\
|
||||
returntype (*run) args_prototype_with_parenthesis;\
|
||||
int (*call_mock_condition) args_prototype_with_parenthesis ;/* to store condition */\
|
||||
char* (*str_print_current_variables) args_prototype_with_parenthesis ;/* to store current variables CREATE by macro STR_PRINT_CUR_VAR same arguments as MOCK_FUNC without returntype whoch is always char * */\
|
||||
struct func_mock_info_struct *info_mock;\
|
||||
struct list_mock_return_ ## namefunction *next;\
|
||||
} list_mo_ ## namefunction;\
|
||||
__attribute__((constructor)) void init_list_m_ ## namefunction(void){\
|
||||
list_mo_ ## namefunction.info_mock = malloc(sizeof(struct func_mock_info_struct));\
|
||||
(list_mo_ ## namefunction.info_mock)->times_left = INITSTATE;\
|
||||
(list_mo_ ## namefunction.info_mock)->init_times_left = INITSTATE;\
|
||||
list_mo_ ## namefunction.str_print_current_variables = NULL;\
|
||||
list_mo_ ## namefunction.next = NULL;\
|
||||
}\
|
||||
returntype namefunction args_prototype_with_parenthesis {\
|
||||
static size_t count_call_f=0;\
|
||||
++count_call_f;\
|
||||
PRINT_DEBUG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>count call of %s: %ld\n",#namefunction,count_call_f);\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
if( (tmp_mock->info_mock)->times_left == INITSTATE ){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," WARNING, %s, no EXPECT_MOCK_CALL or WILL_MOCK_CALL, but called %ld times.\n",#namefunction, count_call_f);\
|
||||
if(count_call_f==1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," For instance:\n"\
|
||||
"%s EXPECT_MOCK_CALL(%s,%s,%s,true,1){\n"\
|
||||
"%s\t %s ret;\n%s \t ...do something with %s;\n"\
|
||||
"%s\t return ret;\n"\
|
||||
"%s }\n"\
|
||||
"%s if call once and accept all args, the same args with WILL_MOCK_CALL \n\n",\
|
||||
tab_hk_f[hk_TR], #returntype, #namefunction,#args_prototype_with_parenthesis, tab_hk_f[hk_TR],#returntype, \
|
||||
tab_hk_f[hk_TR], #args_call_with_parenthesis, tab_hk_f[hk_TR], tab_hk_f[hk_TR], tab_hk_f[hk_TR] ); \
|
||||
/*return (returntype)0;*/ \
|
||||
INIT_MOCK_INFO_IF_NO_(tmp_mock,namefunction, PRE_ID);\
|
||||
}/* to have log */\
|
||||
/*if(list_mo_ ## namefunction.next ) PRINT_ERROR(" %s .next SHOULD BE NULL\n",STRFY(list_mo_ ## namefunction));*/\
|
||||
}\
|
||||
while(tmp_mock->next && (tmp_mock->info_mock)->times_left == 0) {tmp_mock = tmp_mock->next ;}\
|
||||
++((tmp_mock->info_mock)->call);\
|
||||
if(tmp_mock->str_print_current_variables){\
|
||||
append_variable_current(&((tmp_mock->info_mock)->l_current_var), tmp_mock->str_print_current_variables args_call_with_parenthesis);\
|
||||
}\
|
||||
else if(count_call_f == 1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," no printer variable function defined, to define it:\n"\
|
||||
"%s STR_PRINT_CUR_VAR(%s,%s,%s){\n"\
|
||||
"%s\t char* ret=malloc(256);/*for instance*/;\n"\
|
||||
"%s\t ... sprintf(ret,...., %s);/*for instance*/ \n"\
|
||||
"%s\t return ret;\n"\
|
||||
"%s }\n"\
|
||||
"%s same prototype as MOCK_FUNC whithout returntype which always char* i\n\n",\
|
||||
tab_hk_f[hk_TR], #namefunction,#args_prototype_with_parenthesis, #args_call_with_parenthesis, \
|
||||
tab_hk_f[hk_TR], tab_hk_f[hk_TR], #args_call_with_parenthesis, tab_hk_f[hk_TR], tab_hk_f[hk_TR], tab_hk_f[hk_TR] ); \
|
||||
}\
|
||||
/*LOG("condition_func:%d\n", tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\
|
||||
/*EXPECT_EQ_TYPE_INT(1, tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\
|
||||
/*if ((tmp_mock->info_mock)->times_left == 0)*/ /*no longer response, default return */ \
|
||||
/*return (returntype)0;*//* default return */\
|
||||
if( (tmp_mock->info_mock)->str_caller == NULL){ \
|
||||
if(count_call_f == 1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],tab_hk_f[hk_TR]," WARNING, no INIT_CALLER_MOCK; you can put it like this: \n"\
|
||||
"%s TEST(nametest){\n"\
|
||||
"%s\t INIT_CALLER_MOCK(%s); \n"\
|
||||
"%s\t %s%s; \n"\
|
||||
"%s }\n"\
|
||||
"%s i.e before calling %s in this TEST, to have explicit logs\n",\
|
||||
tab_hk_f[hk_TR], tab_hk_f[hk_TR], #namefunction, tab_hk_f[hk_TR],#namefunction,#args_call_with_parenthesis, tab_hk_f[hk_TR], tab_hk_f[hk_TR], #namefunction);} \
|
||||
/*return (returntype)0;*/ \
|
||||
}\
|
||||
else if (((tmp_mock->info_mock)->times_left != 0) && ((tmp_mock->info_mock)->times_left != INITSTATE )) {\
|
||||
size_t len0 = strlen((tmp_mock->info_mock)->str_conditions);\
|
||||
size_t len1 = strlen("when checking condition call: aa");\
|
||||
char *msg_call=malloc(len0 + len1 + strlen(__func__));\
|
||||
sprintf(msg_call,"when checking %s condition call: %s",__func__,(tmp_mock->info_mock)->str_conditions);\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,1, tmp_mock->call_mock_condition args_call_with_parenthesis, (tmp_mock->info_mock)->str_caller, msg_call); /*LOG("%s\n","failure condition");*/\
|
||||
free(msg_call);\
|
||||
}\
|
||||
/*if(0 == tmp_mock->call_mock_condition args_call_with_parenthesis){\
|
||||
PRINT_LOC("Failure, arguments not expected\ncondition ( %s ) not verified\n\n", (tmp_mock->info_mock)->str_conditions);\
|
||||
PRINT_HK_C(RED_K,tab_hk_f[hk_TR]," 1 argument check failed from %s \n",__func__); \
|
||||
}*/\
|
||||
PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'^',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\
|
||||
if (((tmp_mock->info_mock)->times_left <= INFINITY) || ((tmp_mock->info_mock)->times_left > 0)){\
|
||||
--((tmp_mock->info_mock)->times_left);\
|
||||
PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'v',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\
|
||||
if(1 == tmp_mock->call_mock_condition args_call_with_parenthesis){\
|
||||
return tmp_mock->run args_call_with_parenthesis;\
|
||||
}\
|
||||
else ++((tmp_mock->info_mock)->failed_call);\
|
||||
}\
|
||||
return (returntype)0;/* default return */\
|
||||
}
|
||||
|
||||
|
||||
char* extract_name_func_mock(char *input);
|
||||
|
||||
/*
|
||||
* used in mock functions to check the conditions
|
||||
*/
|
||||
#define EXPECT_EQ_IN_MOCKF(var1,var2, name_f_mocked)\
|
||||
do{ \
|
||||
if((list_mo_ ## name_f_mocked.info_mock)->str_caller) {\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,(list_mo_ ## name_f_mocked.info_mock)->str_caller,"mock test");\
|
||||
}\
|
||||
else\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,__func__,"mock test");\
|
||||
}while(0)
|
||||
|
||||
|
||||
/*
|
||||
* to inject the name TEST caller in the mock attribute info, usefull in logs and stats
|
||||
*/
|
||||
#define INIT_CALLER_MOCK(namefunction)/* */\
|
||||
do{\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
while(tmp_mock){\
|
||||
(tmp_mock->info_mock)->str_caller=malloc(strlen(__func__));\
|
||||
strcpy((tmp_mock->info_mock)->str_caller,__func__);\
|
||||
tmp_mock = tmp_mock->next;\
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
/*
|
||||
* to create/ define str_print_current_variables functions
|
||||
* prototype: char* str_print_current_variables (prototype of mock function)
|
||||
* the args of the macro are the same of MOCK_FUNC without the returntype which is always (char*).
|
||||
* It need to be defined after MOCK_FUNC but need to be before EXPECT_MOCK_CALL or WILL_MOCK_CALL
|
||||
*/
|
||||
|
||||
#define STR_PRINT_CUR_VAR(namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\
|
||||
char* str_print_variables ## namefunction args_prototype_with_parenthesis;\
|
||||
__attribute__((constructor)) void create_str_print_variables ## namefunction(){\
|
||||
list_mo_ ## namefunction .str_print_current_variables = str_print_variables ## namefunction;\
|
||||
}\
|
||||
char* str_print_variables ## namefunction args_prototype_with_parenthesis
|
||||
|
||||
|
||||
|
||||
|
||||
#define FILL_MOCK_INFO(tmp_new_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, is_init) \
|
||||
(tmp_new_mock)->run = CONCAT(run_ ## namefunction ## pre_id, id);\
|
||||
(tmp_new_mock)->call_mock_condition = CONCAT(namefunction ## _cond_, id);\
|
||||
if(!is_init)\
|
||||
(tmp_new_mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;\
|
||||
/*(tmp_new_mock)->info_mock = malloc(sizeof(struct func_mock_info_struct));*/\
|
||||
((tmp_new_mock)->info_mock)->expect_call = f_expect_call;\
|
||||
((tmp_new_mock)->info_mock)->call = 0;\
|
||||
((tmp_new_mock)->info_mock)->failed_call = 0;\
|
||||
((tmp_new_mock)->info_mock)->init_times_left = repeat;\
|
||||
((tmp_new_mock)->info_mock)->times_left = repeat;\
|
||||
((tmp_new_mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\
|
||||
sprintf(((tmp_new_mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\
|
||||
((tmp_new_mock)->info_mock)->str_conditions = malloc(strlen(#condition_on_args_expression));\
|
||||
strcpy(((tmp_new_mock)->info_mock)->str_conditions, #condition_on_args_expression);\
|
||||
((tmp_new_mock)->info_mock)->str_caller = NULL;\
|
||||
((tmp_new_mock)->info_mock)->l_current_var= NULL;\
|
||||
((tmp_new_mock)->info_mock)->next = NULL;\
|
||||
(tmp_new_mock)->next = NULL;\
|
||||
append_fmock_to_listmock(&f_mock_glist, (tmp_new_mock)->info_mock);
|
||||
|
||||
|
||||
#define ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
/*FUNC_type_ ## namefunction CONCAT(run_ ## namefunction ## pre_id , id);*/\
|
||||
returntype CONCAT(run_ ## namefunction ## pre_id , id) args_prototype_with_parenthesis; \
|
||||
int CONCAT(namefunction ## _cond_ , id) args_prototype_with_parenthesis {/*LOG("cond:%d\n",condition_on_args_expression);*/ return condition_on_args_expression;}\
|
||||
__attribute__((constructor)) void CONCAT(append_list_ ## namefunction , id)(void){\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
if((tmp_mock->info_mock)->times_left == INITSTATE){/* init state */\
|
||||
FILL_MOCK_INFO(tmp_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, true);\
|
||||
append_list_base_fmock( &g_list_base_fmock ,(tmp_mock->info_mock));\
|
||||
}\
|
||||
else{\
|
||||
while(tmp_mock->next) tmp_mock = tmp_mock->next;\
|
||||
tmp_mock->next = malloc(sizeof(list_mo_ ## namefunction));\
|
||||
(tmp_mock->next)->info_mock = malloc(sizeof(struct func_mock_info_struct));\
|
||||
FILL_MOCK_INFO(tmp_mock->next, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, false);\
|
||||
/*(tmp_mock->info_mock)->next = (tmp_mock->next)->info_mock ;*/\
|
||||
}\
|
||||
}\
|
||||
returntype CONCAT(run_ ## namefunction ## pre_id, id) args_prototype_with_parenthesis
|
||||
|
||||
/*
|
||||
* have to define this below macro to rewrite the right macro identifier (PRE_ID)
|
||||
*/
|
||||
|
||||
#define ADD_RESPONSE(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
|
||||
|
||||
#define EXPECT_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \
|
||||
ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 1, PRE_ID, __LINE__)
|
||||
|
||||
|
||||
#define WILL_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \
|
||||
ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 0, PRE_ID, __LINE__)
|
||||
|
||||
|
||||
|
||||
#endif /* __MOCK_C_H__ */
|
||||
@@ -0,0 +1,321 @@
|
||||
#include "fmock/fmock.h"
|
||||
|
||||
/*
|
||||
* global variables
|
||||
*/
|
||||
|
||||
//char *colors_f[]={DEFAULT_K, RED_K, GREEN_K, YELLOW_K, BLUE_K, ""};
|
||||
|
||||
size_t count_f_mock_wished=0;
|
||||
pthread_mutex_t mut_count_f_mock_wished;
|
||||
|
||||
size_t count_f_mock=0;
|
||||
pthread_mutex_t mut_count_f_mock;
|
||||
|
||||
size_t count_expect_mock=0;
|
||||
pthread_mutex_t mut_count_expect_mock;
|
||||
|
||||
struct list_base_fmock *g_list_base_fmock=NULL;
|
||||
pthread_mutex_t mut_g_list_base_fmock;
|
||||
|
||||
#define LOCK(mutex_var) pthread_mutex_lock(&mutex_var);
|
||||
#define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var);
|
||||
|
||||
|
||||
#define INCREMENT_(variable)\
|
||||
do{\
|
||||
LOCK(mut_##variable); \
|
||||
++variable;\
|
||||
UNLOCK(mut_##variable);\
|
||||
}while(0);
|
||||
|
||||
|
||||
/*
|
||||
* return the numbers of comas (,) +1 in the input string
|
||||
*/
|
||||
|
||||
|
||||
int parse_count_args_(char *input){
|
||||
int val=0;
|
||||
for(int i = 0; i< strlen(input); ++i){
|
||||
if(input[i]==',') ++val;
|
||||
}
|
||||
return val+1;
|
||||
}
|
||||
|
||||
/*
|
||||
* the begin only !
|
||||
*/
|
||||
void append_list_base_fmock(struct list_base_fmock **l_fmock, struct func_mock_info_struct *f_mock){
|
||||
INCREMENT_(count_f_mock);
|
||||
LOCK(mut_g_list_base_fmock);
|
||||
PRINT_DEBUG(" append_list_base_fmock %s",f_mock->str_namefunc);
|
||||
if(*l_fmock){
|
||||
struct list_base_fmock *tmp_l_n = *l_fmock;
|
||||
while(tmp_l_n->next) tmp_l_n = tmp_l_n->next;
|
||||
(tmp_l_n->next) = malloc(sizeof(struct list_base_fmock));
|
||||
(tmp_l_n->next)->info_mock = f_mock;
|
||||
(tmp_l_n->next)->next = NULL;
|
||||
}
|
||||
else{
|
||||
*l_fmock = malloc(sizeof(struct list_base_fmock));
|
||||
(*l_fmock)->info_mock = f_mock;
|
||||
}
|
||||
UNLOCK(mut_g_list_base_fmock);
|
||||
}
|
||||
|
||||
struct func_mock_info_struct *f_mock_glist = NULL;
|
||||
pthread_mutex_t mut_f_mock_glist;
|
||||
|
||||
void append_variable_current(struct list_current_variable **lcurrent_var, char *current_var){
|
||||
if(*lcurrent_var){
|
||||
PRINT_DEBUG("----- l_current_var not NULL, content: %s have to add %s\n",(*lcurrent_var)->str_current_variables, current_var);
|
||||
struct list_current_variable *tmp_lcv = *lcurrent_var;
|
||||
while(tmp_lcv->next) tmp_lcv = tmp_lcv->next;
|
||||
tmp_lcv->next = malloc(sizeof(struct list_current_variable));
|
||||
//(tmp_lcv->next)->str_current_variables = malloc(strlen(current_var));
|
||||
//strcpy((tmp_lcv->next)->str_current_variables,current_var);
|
||||
(tmp_lcv->next)->str_current_variables = current_var;
|
||||
(tmp_lcv->next)->next= NULL;
|
||||
|
||||
}
|
||||
else{
|
||||
PRINT_DEBUG("-- lcurrent_var %s\n","NULL");
|
||||
*lcurrent_var = malloc(sizeof(struct list_current_variable));
|
||||
//(*lcurrent_var)->str_current_variables = malloc(strlen(current_var));
|
||||
//strcpy((*lcurrent_var)->str_current_variables,current_var);
|
||||
(*lcurrent_var)->str_current_variables = current_var;
|
||||
(*lcurrent_var)->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void append_fmock_to_listmock(struct func_mock_info_struct **f_mock_list, struct func_mock_info_struct *f_mock){
|
||||
INCREMENT_(count_f_mock_wished);
|
||||
if(f_mock->expect_call) {
|
||||
INCREMENT_(count_expect_mock);
|
||||
}
|
||||
LOCK(mut_f_mock_glist);
|
||||
PRINT_DEBUG(" append_fmock_to_listmock %s",f_mock->str_namefunc);
|
||||
if(*f_mock_list){
|
||||
struct func_mock_info_struct *tmp_fmock_info = *f_mock_list;
|
||||
while(tmp_fmock_info->next) tmp_fmock_info = tmp_fmock_info->next;
|
||||
tmp_fmock_info->next = f_mock;
|
||||
}
|
||||
else{
|
||||
*f_mock_list = f_mock;
|
||||
}
|
||||
UNLOCK(mut_f_mock_glist);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SSTRFY(x) STRFY(x)
|
||||
|
||||
char* extract_name_func_mock(char *input){
|
||||
char * ret=malloc(strlen(input));
|
||||
strcpy(ret,input);
|
||||
char * pre_id_ = SSTRFY(PRE_ID);
|
||||
size_t len_pre_id_ = strlen(pre_id_);
|
||||
for(size_t i=0; i<strlen(ret)-len_pre_id_; ++i){
|
||||
if(strncmp(ret+i,pre_id_,len_pre_id_) == 0){
|
||||
ret[i]='\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((constructor))
|
||||
void
|
||||
init_mock_c(){
|
||||
|
||||
pthread_mutex_init(&mut_g_list_base_fmock, NULL);
|
||||
pthread_mutex_init(&mut_f_mock_glist, NULL);
|
||||
pthread_mutex_init(&mut_count_f_mock_wished, NULL);
|
||||
pthread_mutex_init(&mut_count_f_mock, NULL);
|
||||
pthread_mutex_init(&mut_count_expect_mock, NULL);
|
||||
}
|
||||
|
||||
extern bool is_parallel_nb;
|
||||
|
||||
|
||||
|
||||
char * number_call_translate(long nb){
|
||||
char *ret=malloc(250);
|
||||
if(nb>1) sprintf(ret," be called %ld times",nb);
|
||||
else if(nb == 1) sprintf(ret," be called once");
|
||||
else if(nb == 0 ) sprintf(ret," not to be executed");
|
||||
else if(nb==INFINITY) sprintf(ret," be called forever");
|
||||
else if(nb==INITSTATE) sprintf(ret," not expected");
|
||||
else sprintf(ret," nothing! it's negative:%ld", nb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char * strprint_caller_(char *input){
|
||||
if(input==NULL) { return "";}
|
||||
char *called_in=",\t called in ";
|
||||
char *ret = malloc(strlen(called_in)+strlen(input)+1);
|
||||
sprintf(ret,"%s%s",called_in,input);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PRINT_VAR_CUR(mockinfo)\
|
||||
do{\
|
||||
PRINTF("\n%s list of variables when %s was called, with condition %s:\n\t\t",tab_hk_f[hk_EQ],mockinfo->str_namefunc,mockinfo->str_conditions);\
|
||||
size_t cal_cur=0;\
|
||||
struct list_current_variable *tmp_cur_v = mockinfo->l_current_var;\
|
||||
while(tmp_cur_v){\
|
||||
PRINTF(" call : %ld : variables : %s \n\t\t",++cal_cur, tmp_cur_v->str_current_variables);\
|
||||
tmp_cur_v = tmp_cur_v->next;\
|
||||
}\
|
||||
PRINTF("\n");\
|
||||
}while(0);
|
||||
|
||||
|
||||
|
||||
|
||||
__attribute__((destructor))
|
||||
void
|
||||
check_mock_excpected(){
|
||||
|
||||
signal(SIGSEGV, SIG_DFL); /* restore default behaviour , */
|
||||
|
||||
//int k_DEFAULT=0, k_GREEN=1, k_RED=2, k_YELLOW=3, k_BLUE=4, k_NOTHING;
|
||||
//if(unicolour) {
|
||||
//k_GREEN=k_NOTHING; k_RED=k_NOTHING; k_YELLOW=k_NOTHING; k_BLUE=k_NOTHING;
|
||||
//for(int i=0; i< Dk_NOTHING;++i) strcpy(colors_f[i]," ");
|
||||
//}
|
||||
if(only_usage) return; /* do nothing */
|
||||
if(g_list_base_fmock == NULL) return; /* do nothing because no mock functions */
|
||||
struct winsize w;
|
||||
ioctl(1, TIOCGWINSZ, &w);
|
||||
|
||||
char *reader=malloc(w.ws_col);
|
||||
strcpy(reader,"STAT OF MOCK FUNCTIONS");
|
||||
|
||||
fprintf(F_OUT,"%s\n\n%0*d\n %*s \n%0*d %s\n\n", colors_f[k_YELLOW] ,w.ws_col,0, (int)(w.ws_col+strlen(reader))/2, reader,w.ws_col,0, DEFAULT_K );
|
||||
|
||||
|
||||
is_parallel_nb = 0; /* no longer parallel here */
|
||||
struct func_mock_info_struct *tmock = f_mock_glist; //, *tfree;
|
||||
|
||||
/* global order of fmock , order of expect and will */
|
||||
while(tmock){
|
||||
PRINT_DEBUG("check mock function: %s\n",tmock->str_namefunc);
|
||||
//tfree=tmock;
|
||||
PRINT_DEBUG("**** STAT mock function:%s, conditions:%s t_left:%ld, init_left:%ld, failed_call:%ld\n",tmock->str_namefunc, tmock->str_conditions, tmock->times_left,tmock->init_times_left, tmock->failed_call);
|
||||
if(((tmock->expect_call) && (tmock->init_times_left == tmock->times_left)) || (tmock->failed_call)){
|
||||
if(tmock->l_current_var){
|
||||
PRINTF("%s%s %s%s %s: expect %s, it was called %ld times and failed %ld times, with condition %s\n",colors_f[k_RED],tab_hk_f[hk_FL],colors_f[k_YELLOW],tmock->str_namefunc,DEFAULT_K,
|
||||
number_call_translate(tmock->init_times_left),
|
||||
tmock->call/*tmock->failed_call + (tmock->init_times_left - tmock->times_left)*/,
|
||||
tmock->failed_call,
|
||||
tmock->str_conditions
|
||||
);
|
||||
PRINT_VAR_CUR(tmock);
|
||||
}
|
||||
else
|
||||
PRINTF("%s%s %s%s %s: expect %s, it was called %ld times and failed %ld times, with condition %s \n",colors_f[k_RED],tab_hk_f[hk_FL],colors_f[k_YELLOW],tmock->str_namefunc,DEFAULT_K,
|
||||
number_call_translate(tmock->init_times_left),
|
||||
tmock->call/*tmock->failed_call + (tmock->init_times_left - tmock->times_left)*/,
|
||||
tmock->failed_call,
|
||||
tmock->str_conditions
|
||||
);
|
||||
}
|
||||
tmock=tmock->next;
|
||||
//free(tfree);
|
||||
}
|
||||
|
||||
PRINTF("\n%s%s STAT MOCK : there are %ld mock functions, %ld wished responses, %ld expected responses, which are:\n\n",colors_f[k_GREEN],tab_hk_f[hk_EQ],count_f_mock, count_f_mock_wished, count_expect_mock);
|
||||
struct list_base_fmock *tmp_list_fm = g_list_base_fmock;
|
||||
struct func_mock_info_struct *tmp_inf_mock;
|
||||
/* list each fmock an each calls */
|
||||
while(tmp_list_fm){
|
||||
tmp_inf_mock = tmp_list_fm->info_mock;
|
||||
memset(reader,'=',w.ws_col);
|
||||
reader[w.ws_col-1]='\0';
|
||||
char *caller="";
|
||||
if(tmp_inf_mock->str_caller) caller = extract_func_edited_TEST_from_exec_func_name(tmp_inf_mock->str_caller);
|
||||
size_t len_caller = strlen(caller);
|
||||
|
||||
char *nameff=extract_name_func_mock(tmp_inf_mock->str_namefunc);
|
||||
size_t len_nameff=strlen(nameff);
|
||||
char *by_=" called by ";
|
||||
size_t len_by_=strlen(by_);
|
||||
size_t bg_rd=(w.ws_col -1 - len_nameff - len_caller - len_by_)/2;
|
||||
reader[bg_rd++]=' ';
|
||||
for(size_t i=0; i<len_nameff; ++i)
|
||||
reader[bg_rd+i]=nameff[i];
|
||||
if(len_caller){
|
||||
for(size_t i=0;i<len_by_;++i)
|
||||
reader[bg_rd+len_nameff+i]=by_[i];
|
||||
for(size_t i=0;i<len_caller;++i)
|
||||
reader[bg_rd+len_nameff+len_by_+i]=caller[i];
|
||||
reader[bg_rd+len_nameff+len_by_+len_caller]=' ';
|
||||
}
|
||||
else{
|
||||
reader[bg_rd+len_nameff]=' ';
|
||||
}
|
||||
PRINTF("%s%s%s\n\n",colors_f[k_BLUE],reader,DEFAULT_K );
|
||||
while(tmp_inf_mock){
|
||||
if(0==strncmp(tmp_inf_mock->str_namefunc,nameff, len_nameff)){
|
||||
if(tmp_inf_mock->expect_call==1){
|
||||
int success = !((tmp_inf_mock->init_times_left == tmp_inf_mock->times_left) || (tmp_inf_mock->failed_call));
|
||||
|
||||
if(tmp_inf_mock->l_current_var){
|
||||
PRINTF("%s%s%s %s\t expect to%s,\t called %ld times and failed %ld times %s,\t with condition: %s%s\n" ,
|
||||
colors_f[!unicolour*(k_RED - success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING * success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions, DEFAULT_K);
|
||||
PRINT_VAR_CUR(tmp_inf_mock);
|
||||
}else{
|
||||
PRINTF("%s%s%s %s\t expect to%s,\t called %ld times and failed %ld times %s,\t with condition: %s%s\n" ,
|
||||
colors_f[!unicolour*(k_RED - success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING*success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions , DEFAULT_K);
|
||||
}
|
||||
}else if(tmp_inf_mock->expect_call==0) {/* will expect */
|
||||
int success = !(tmp_inf_mock->failed_call);
|
||||
if(tmp_inf_mock->l_current_var){
|
||||
PRINTF("%s%s%s %s\t will%s,\t called %ld times and failed %ld times %s,\t with condition: %s,%s\n" ,
|
||||
colors_f[!unicolour*(k_RED + success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING*success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions , DEFAULT_K);
|
||||
PRINT_VAR_CUR(tmp_inf_mock);
|
||||
}else{
|
||||
PRINTF("%s%s%s %s\t will%s,\t called %ld times and failed %ld times %s,\t with condition: %s %s\n" ,
|
||||
colors_f[!unicolour*(k_RED + success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING*success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions , DEFAULT_K);
|
||||
}
|
||||
}
|
||||
else if(tmp_inf_mock->expect_call==-1){
|
||||
if(tmp_inf_mock->l_current_var){
|
||||
PRINTF("%s%s%s %s\t %s,\t called %ld times, %s\n" ,
|
||||
colors_f[!unicolour*(k_RED)],tab_hk_f[hk_FL],colors_f[k_DEFAULT],tmp_inf_mock->str_namefunc,
|
||||
number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
strprint_caller_(tmp_inf_mock->str_caller) );
|
||||
PRINT_VAR_CUR(tmp_inf_mock);
|
||||
}else{
|
||||
PRINTF("%s%s%s %s\t %s,\t called %ld times, %s\n" ,
|
||||
colors_f[!unicolour*(k_RED)],tab_hk_f[hk_FL],colors_f[k_DEFAULT],tmp_inf_mock->str_namefunc,
|
||||
number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
strprint_caller_(tmp_inf_mock->str_caller));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
tmp_inf_mock = tmp_inf_mock->next;
|
||||
}
|
||||
PRINT_DEBUG(" end listing info mock of %s \n", nameff);
|
||||
tmp_list_fm = tmp_list_fm->next;
|
||||
}
|
||||
|
||||
PRINT_DEBUG("%s\n","info mock done!");
|
||||
|
||||
pthread_mutex_destroy(&mut_g_list_base_fmock);
|
||||
pthread_mutex_destroy(&mut_f_mock_glist);
|
||||
pthread_mutex_destroy(&mut_count_f_mock_wished);
|
||||
pthread_mutex_destroy(&mut_count_f_mock);
|
||||
pthread_mutex_destroy(&mut_count_expect_mock);
|
||||
PRINT_DEBUG("%s\n","pthread_mutex_destroy done!");
|
||||
PRINT_DEBUG("%s\n","check mock done!");
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
FTEST_SRC=src/ftest/ftest.c
|
||||
FTEST_O=$(FTEST_SRC:.c=.o)
|
||||
|
||||
TOOLS_SRC=../ytools_t/src/tools_t/tools_t.c
|
||||
TOOLS_O=$(TOOLS_SRC:.c=.o)
|
||||
|
||||
BARPROGES_SRC=../ybar_progress/src/bar_progress/bar_progress.c
|
||||
BARPROGES_O=$(BARPROGES_SRC:.c=.o)
|
||||
|
||||
|
||||
all: $(FTEST_O)
|
||||
|
||||
|
||||
$(FTEST_O): $(FTEST_SRC) $(TOOLS_O) $(BARPROGES_O)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(FTEST_O)
|
||||
|
||||
@@ -0,0 +1,803 @@
|
||||
#ifndef __TEST_C_H__
|
||||
#define __TEST_C_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
//#include <time.h>
|
||||
#include <pthread.h>
|
||||
//#include <unistd.h>
|
||||
#include <sys/ioctl.h> /* to have size of screen, for progress bar */
|
||||
|
||||
#include "tools_t/tools_t.h"
|
||||
#include "bar_progress/bar_progress.h"
|
||||
|
||||
#define DEFAULT_K "\033[0m" /*Resets the text to default color*/
|
||||
#define GREEN_K "\033[0;32m"
|
||||
#define RED_K "\033[0;31m"
|
||||
#define YELLOW_K "\033[0;33m"
|
||||
#define BLUE_K "\033[0;34m"
|
||||
#define NOTHING_K ""
|
||||
|
||||
#define COLOR_SZ 6
|
||||
|
||||
#define Dknothing COLOR_SZ - 1
|
||||
|
||||
#define SZ_TAB_HK 8
|
||||
|
||||
|
||||
/*#ifdef HK*/
|
||||
#define gHK_EQ "[==========]"
|
||||
#define gHK_TR "[----------]"
|
||||
#define gHK_RN "[RUN ]"
|
||||
#define gHK_DN "[ DONE]"
|
||||
#define gHK_OK "[ OK ]"
|
||||
#define gHK_FL "[ FAILED ]"
|
||||
#define gHK_PS "[ PASSED ]"
|
||||
#define gHK_SK "[ SKIP ]"
|
||||
/*#else*/
|
||||
#define HK_EQ "=========="
|
||||
#define HK_TR "----------"
|
||||
#define HK_RN "====== RUN"
|
||||
#define HK_DN "===== DONE"
|
||||
#define HK_OK "======= OK"
|
||||
#define HK_FL "===== FAIL"
|
||||
#define HK_PS "===== PASS"
|
||||
#define HK_SK "===== SKIP"
|
||||
/*#endif*/ /* HK */
|
||||
|
||||
/*
|
||||
* compare symbol
|
||||
*/
|
||||
#define EQ ==
|
||||
#define LT <
|
||||
#define GT >
|
||||
#define LE <=
|
||||
#define GE >=
|
||||
#define NE !=
|
||||
|
||||
|
||||
extern FILE **f_ou_th;
|
||||
extern bool debug;
|
||||
extern bool unicolour;
|
||||
extern bool ordered;
|
||||
extern bool log_parallel;
|
||||
extern bool only_usage;
|
||||
extern char *savelog;
|
||||
|
||||
extern char *colors_f[];
|
||||
extern char *tab_hk_f[];
|
||||
|
||||
extern int k_DEFAULT, k_GREEN, k_RED, k_YELLOW, k_BLUE, k_NOTHING;
|
||||
extern int hk_EQ, hk_TR, hk_RN, hk_DN, hk_OK, hk_FL, hk_PS, hk_SK;
|
||||
extern char *varHK_EQ, *varHK_TR, *varHK_RN, *varHK_DN, *varHK_OK, *varHK_FL, *varHK_PS, *varHK_SK;
|
||||
|
||||
/*
|
||||
* */
|
||||
|
||||
/*
|
||||
* to execute once in print functions in the case of log_parallel (printing on screen and recording in file), we have to copy to stream -> string before copy it,
|
||||
* so I have tried using fopen a file in memory location '/dev/shm' and remove it after use!
|
||||
* /dev/shm/tmp_PTHREAD_SELF() but it prints twice sometimes,
|
||||
* here a solution with open_memstream which is better
|
||||
*/
|
||||
|
||||
#define PRINTF( ...) \
|
||||
do{ \
|
||||
FILE *stream ;\
|
||||
size_t len;\
|
||||
char *buf ;\
|
||||
stream = open_memstream (&buf, &len);\
|
||||
if (stream == NULL) { fprintf(stderr," error open_memstream %s:%d:%s \n",__FILE__,__LINE__,__func__); exit(0); }\
|
||||
fprintf(stream, __VA_ARGS__); \
|
||||
fflush(stream);\
|
||||
if(is_parallel_nb){\
|
||||
long int id_thread=id_of_thread_executed();\
|
||||
if(log_parallel){\
|
||||
fprintf(F_OUT, "%s",buf);\
|
||||
if(id_thread >= 0){\
|
||||
fprintf(f_ou_th[id_thread], "%s",buf);\
|
||||
fflush(f_ou_th[id_thread]);\
|
||||
}\
|
||||
}\
|
||||
else{\
|
||||
if(id_thread >= 0){\
|
||||
fprintf(f_ou_th[id_thread], "%s",buf);\
|
||||
fflush(f_ou_th[id_thread]);\
|
||||
}\
|
||||
else {\
|
||||
fprintf(F_OUT, "%s",buf);\
|
||||
}\
|
||||
}\
|
||||
} \
|
||||
else{\
|
||||
if(savelog){\
|
||||
FILE *f_savelog = fopen(savelog,"a");\
|
||||
fprintf(f_savelog, "%s",buf);\
|
||||
fclose(f_savelog);\
|
||||
}\
|
||||
fprintf(F_OUT, "%s",buf);\
|
||||
}\
|
||||
fclose(stream);\
|
||||
free(buf);\
|
||||
}while(0)
|
||||
|
||||
|
||||
#define LOG(...) PRINTF(__VA_ARGS__)
|
||||
|
||||
#define PRINT_LOC(fmt, ...) \
|
||||
PRINTF( "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
|
||||
|
||||
#define PRINT_HK_C(color,hk,fmt,...)\
|
||||
PRINTF("%s%s%s" fmt, color,hk,colors_f[k_DEFAULT],__VA_ARGS__)
|
||||
|
||||
#define PRINT_DEBUG(fmt, ...)\
|
||||
do{ if(debug) PRINT_LOC(fmt, __VA_ARGS__);} while(0)
|
||||
|
||||
|
||||
/*
|
||||
* to skip the bloc test function
|
||||
*/
|
||||
#define SKIP(fmt,...)\
|
||||
PRINT_HK_C(colors_f[k_GREEN], tab_hk_f[hk_SK], fmt, ## __VA_ARGS__);\
|
||||
PRINT_LOC("%s\n\n" DEFAULT_K," Skiped "); return;
|
||||
|
||||
|
||||
|
||||
struct func {
|
||||
char *name;
|
||||
void (*run)(void);
|
||||
struct func *next;
|
||||
};
|
||||
|
||||
|
||||
extern bool is_parallel_nb;
|
||||
|
||||
long int id_of_thread_executed(void);
|
||||
|
||||
void parse_options(int argc, char **argv);
|
||||
|
||||
void run_all_tests();
|
||||
void execute_all(struct func *fun);
|
||||
void append_func(void (*run)(void), char *name);
|
||||
|
||||
char* extract_func_edited_TEST_from_exec_func_name(char* func_name); /* TEST_funcname___NUM -> TEST(funcname) */
|
||||
|
||||
/*
|
||||
void run_some_tests(size_t cnt, ... );
|
||||
void run_all_tests_exept(size_t cnt, ... );
|
||||
void run_some_tests_ordered(size_t cnt, ... );
|
||||
*/
|
||||
|
||||
void run_all_tests_parallel(size_t parallel /*, int max_col*/);
|
||||
|
||||
/*
|
||||
* to launch test with different parameters without re-compile it
|
||||
* it can print help if need!
|
||||
* */
|
||||
void run_all_tests_args(int argc, char **argv);
|
||||
|
||||
bool expected_true_f(bool val);
|
||||
bool expected_false_f(bool val);
|
||||
|
||||
bool expected_true_f_name(bool val, const char *name);
|
||||
bool expected_false_f_name(bool val, const char *name);
|
||||
|
||||
#define GEN_EXPECTED_OP_TYPE_FUNC(OP,type)\
|
||||
bool expected_##OP##_##type(type var1, type var2);\
|
||||
bool expected_##OP##_name_##type(type var1, type var2, const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions EQ ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end EQ generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions LT ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end LT generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions GT ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end GT generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions LE ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end LE generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions GE ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end GE generation ************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ***** generate signature of expected functions NE ***********
|
||||
*/
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_CHAR)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_L_INT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_SIZE_T)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_FLOAT)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_L_DOUBLE)
|
||||
GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_STRING)
|
||||
/*
|
||||
* ******************** end NE generation ************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* only expect
|
||||
*/
|
||||
#define HANDLE_OP_EXPECT_NAME(OP,type,var1,var2,name_f,msg_call) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 %s passed %s \n\n",name_f,msg_call); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 %s failed %s \n",name_f,msg_call); \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, name_f)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 %s passed %s \n\n",name_f,msg_call); \
|
||||
/*PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed %s \n\n",name_f);*/ \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 %s failed %s \n",name_f,msg_call); \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
//#define EXPECT_OP_(OP,type,var1,var2) HANDLE_OP_EXPECT_(OP,type,var1,var2)
|
||||
|
||||
/**
|
||||
* old combined macros HANDLE_OP_EXPECT_ASSERT for ASSERT and EXPECT
|
||||
* is_assert : 0 for EXPECT and 1 for ASSERT
|
||||
*/
|
||||
#define HANDLE_OP_EXPECT_ASSERT(OP,type,var1,var2,is_assert) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
// *******************************************************************************************************************
|
||||
|
||||
/**
|
||||
* new HANDLE_OP_ EXPECT and ASSERT separated
|
||||
*/
|
||||
#define HANDLE_OP_EXPECT_(OP,type,var1,var2) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
#define HANDLE_OP_ASSERT_(OP,type,var1,var2) \
|
||||
do{ \
|
||||
if(is_parallel_nb == 0){\
|
||||
if(expected_##OP##_##type(var1, var2)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
return; \
|
||||
} \
|
||||
}else { \
|
||||
if(expected_##OP##_name_##type(var1, var2, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
/*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\
|
||||
,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \
|
||||
PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\
|
||||
,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
|
||||
|
||||
// ********************************************************************************************************************
|
||||
|
||||
|
||||
// *********************** begin EQ ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_EQ_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_EQ_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_EQ(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_EQ_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_EQ_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_EQ(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end EQ **********************
|
||||
|
||||
|
||||
// *********************** begin LT ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_LT_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_LT_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_LT_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_LT_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_LT_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_LT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_LT_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_LT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_LT_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_LT_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_LT_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_LT_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_LT_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_LT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_LT_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_LT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end LT **********************
|
||||
|
||||
|
||||
// *********************** begin GT ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_GT_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_GT_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_GT_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_GT_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_GT_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_GT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_GT_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_GT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_GT_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_GT_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_GT_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_GT_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_GT_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_GT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_GT_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_GT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end GT **********************
|
||||
|
||||
|
||||
// *********************** begin LE ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_LE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_LE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_LE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_LE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_LE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_LE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_LE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_LE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_LE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_LE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_LE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_LE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_LE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_LE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_LE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_LE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end LE **********************
|
||||
|
||||
|
||||
// *********************** begin GE ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_GE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_GE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_GE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_GE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_GE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_GE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_GE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_GE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_GE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_GE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_GE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_GE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_GE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_GE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_GE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_GE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end GE **********************
|
||||
|
||||
|
||||
// *********************** begin NE ************************
|
||||
// ============== EXPECT ==============================
|
||||
|
||||
#define EXPECT_NE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_CHAR,var1, var2)
|
||||
#define EXPECT_NE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_CHAR,var1, var2)
|
||||
#define EXPECT_NE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_L_INT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_SIZE_T,var1, var2)
|
||||
#define EXPECT_NE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_FLOAT,var1, var2)
|
||||
#define EXPECT_NE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_DOUBLE,var1, var2)
|
||||
#define EXPECT_NE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define EXPECT_NE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define EXPECT_NE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_INT,var1, var2)
|
||||
|
||||
|
||||
|
||||
// ============== ASERT =====================
|
||||
|
||||
#define ASSERT_NE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_CHAR,var1, var2)
|
||||
#define ASSERT_NE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_CHAR,var1, var2)
|
||||
#define ASSERT_NE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_L_INT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_SIZE_T,var1, var2)
|
||||
#define ASSERT_NE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_FLOAT,var1, var2)
|
||||
#define ASSERT_NE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_DOUBLE,var1, var2)
|
||||
#define ASSERT_NE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_DOUBLE,var1, var2)
|
||||
#define ASSERT_NE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_STRING,var1, var2)
|
||||
|
||||
#define ASSERT_NE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_INT,var1, var2)
|
||||
|
||||
// ************************ end NE **********************
|
||||
|
||||
/*
|
||||
* ============== bool ===================
|
||||
* bellow old combined EXPECT and ASSERT macros
|
||||
*/
|
||||
|
||||
#define HANDLE_EXPECT_NOT_EXPECT_ASSERT(expect,not_expect,var1,is_assert) \
|
||||
do{ \
|
||||
if(is_parallel_nb==0){\
|
||||
if(expected_##expect##_f(var1)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}\
|
||||
else{\
|
||||
if(expected_##expect##_f_name(var1, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n",__func__); \
|
||||
if(is_assert) return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
// *******************************************************************************************************
|
||||
/*
|
||||
* new macro HANDEL ASSERT and EXPECT separated
|
||||
*/
|
||||
#define HANDLE_EXPECT_NOT_EXPECT_(expect,not_expect,var1) \
|
||||
do{ \
|
||||
if(is_parallel_nb==0){ \
|
||||
if(expected_##expect##_f(var1)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n\n",__func__); \
|
||||
} \
|
||||
} \
|
||||
else{ \
|
||||
size_t id_thread=id_of_thread_executed(); \
|
||||
if(expected_##expect##_f_name(var1, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s, on thread[%ld]\n\n",__func__,id_thread); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s, on thread[%ld]\n\n",__func__,id_thread); \
|
||||
} \
|
||||
} \
|
||||
}while(0);
|
||||
|
||||
|
||||
#define HANDLE_ASSERT_EXPECT_NOT_EXPECT_(expect,not_expect,var1) \
|
||||
do{ \
|
||||
if(is_parallel_nb==0){ \
|
||||
if(expected_##expect##_f(var1)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s \n\n",__func__); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s \n\n",__func__); \
|
||||
return; \
|
||||
} \
|
||||
}\
|
||||
else{\
|
||||
size_t id_thread=id_of_thread_executed(); \
|
||||
if(expected_##expect##_f_name(var1, __func__)){ \
|
||||
PRINT_HK_C(colors_f[k_GREEN],tab_hk_f[hk_TR]," 1 test passed from %s, on thread[%ld]\n\n",__func__,id_thread); \
|
||||
} \
|
||||
else{ \
|
||||
PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\
|
||||
PRINT_HK_C(colors_f[k_RED],tab_hk_f[hk_TR]," 1 test failed from %s, on thread[%ld]\n\n",__func__, id_thread); \
|
||||
return; \
|
||||
} \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
|
||||
// *******************************************************************************************************
|
||||
#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_(true, false, var1)
|
||||
#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_(false, true, var1)
|
||||
|
||||
#define ASSERT_TRUE(var1) HANDLE_ASSERT_EXPECT_NOT_EXPECT_(true, false, var1)
|
||||
#define ASSERT_FALSE(var1) HANDLE_ASSERT_EXPECT_NOT_EXPECT_(false, true, var1)
|
||||
|
||||
|
||||
//********************************************************************************
|
||||
|
||||
/*
|
||||
#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 0)
|
||||
#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 0)
|
||||
|
||||
#define ASSERT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 1)
|
||||
#define ASSERT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 1)
|
||||
*/
|
||||
|
||||
|
||||
#define CONCAT(x,y) x ## y
|
||||
#define STRFY(x) # x
|
||||
|
||||
//#define test_label test
|
||||
|
||||
#define FTEST_(count, name_f) \
|
||||
void CONCAT(test_##name_f##____,count)(void); \
|
||||
__attribute__((constructor)) \
|
||||
void CONCAT(append_test_##name_f,count)(void){ \
|
||||
append_func(CONCAT(test_##name_f##____,count),STRFY(name_f test count)); \
|
||||
} \
|
||||
void CONCAT(test_##name_f##____,count)(void)
|
||||
|
||||
#define FTEST__(count, name_f) \
|
||||
void CONCAT(TEST_##name_f##____,count)(void); \
|
||||
__attribute__((constructor)) \
|
||||
void CONCAT(append_test_##name_f,count)(void){ \
|
||||
append_func(CONCAT(TEST_##name_f##____,count),STRFY (TEST(name_f): test N° count| ) ); \
|
||||
} \
|
||||
void CONCAT(TEST_##name_f##____,count)(void)
|
||||
|
||||
|
||||
/*#define TEST(name_f)\
|
||||
FTEST_(__COUNTER__,name_f)
|
||||
*/
|
||||
|
||||
#define TEST(name_f) \
|
||||
FTEST__(__COUNTER__,name_f)
|
||||
|
||||
/*
|
||||
#define ASSERT_TRUE(val)\
|
||||
if(expected_true_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;}
|
||||
|
||||
#define ASSERT_FALSE(val)\
|
||||
if(expected_false_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;}
|
||||
*/
|
||||
|
||||
#endif /* __TEST_C_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user