Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read external data for test and extensions #324

Open
williammora1984 opened this issue Sep 7, 2021 · 9 comments
Open

Read external data for test and extensions #324

williammora1984 opened this issue Sep 7, 2021 · 9 comments
Labels
question Further information is requested

Comments

@williammora1984
Copy link

Hello, I'm learning to use pFUnit and at this moment have two issues, I'm not used with Cmake files then it is not easy to deduce the answer

  1. I don't know where to specify extensions to compile additional libraries. In my case, I'm working with DGETRF and Id'ont know where to specify -llapack for the compilation.
  2. I'm trying to read a csv file with the data to make my test, but it is impossible to read the information, the variable that I use to read is empty. Is it required to allow something in the cmake or pf file to make this?

Thank you very much for your help

@tclune tclune added the question Further information is requested label Sep 7, 2021
@tclune
Copy link
Member

tclune commented Sep 7, 2021

  1. I am assuming that you are trying to use the add_pfunit_ctest macro provided by pFUnit. If so then in most cases you would put that information on the LINK_LIBRARIES argument. One way is to provide the full path. E.g., if your lapack is installed in /usr/lib:
add_pfunit_ctest(mytests  TEST_SOURCES   a.F90 b.F90 ... LINK_LIBRARIES  /usr/lib/liblapack.a)

Or you could separately provide a path (unfortunately must be the following order:

add_pfunit_ctest(mytests  TEST_SOURCES   a.F90 b.F90 ... LINK_LIBRARIES  lapack)
target_link_directories(mytests PRIVATE /usr/lib)
  1. I do not think I understand what you are asking. Do you want cmake to read a CSV file and use that information to generate the appropriate cmake macro invocations that result in pfunit test suites? I don't have any experience doing anything like that. Or does your Fortran unit test read a CSV file?

@williammora1984
Copy link
Author

Thank you, I'm going to try to implement the solution for my first point. For the second point, yes I want that Fortran to read a CSV file that contains all the data to make the comparisons in the assertion test. I have tried in different ways but the result is that reads nothing.

@tclune
Copy link
Member

tclune commented Sep 7, 2021

Are you asking how to write Fortran that reads a CSV file? It is difficult to anticipate what your exact issue is without more details. But one likely possibility is that the unit tests are running in your cmake "binary" directory, but your CSV file is in your "source" directory and is therefore not being found. I have a similar pattern in my examples in another project and use the following CMake command:

FILE (COPY simple.yaml DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

Hope this helps.

@williammora1984
Copy link
Author

Excuse me for the lack of detail, I have tried to implement your lines and reviewed the documentation examples but still without success. Then following I write you in detail what I implemented, the files, and the error messages. I hope all be more clear and thank you for your previous answers.

With respect to the question of the CVS file, I'm following the trivial example, then I have all the files in one folder. There are 4 files: the file to test (a fortran77 file), the .pf file where there are the below lines to import all the input information for the tests, the CMakeList.txt, and the build_with_cmake_and_run.x file. The location of the folder is Code_PPP/1_Test_tensor_op

In the .pf files I'm running the following lines to load the information of the CSV file called diadic2D.csv and save the information in the variable import1 (This works without problems in fortran77 or Fortran90), when I print the content of import1 there is nothing.

      integer:: i, j,end,stat,line_no,n1,n2     !iterators
      double precision, dimension(11,19):: import1
      n1=size(import1,1)
      n2=size(import1,2)

      open(15, file="diadic2D.csv",access='sequential',
 &    form="formatted", iostat=stat)
      do i = 1,n1
         read(15,*,iostat=stat) import1(i,:)
      end do
      close (15)  

I tried to run your line but I'm still confused and only get errors (what does it mean FILE, copy, destination). Could you please indicate to me if the line(s) go in the CMakeLists.txt or build_with_cmake_and_run.x file.

With respect to my first question about the compilation with -llpack, when I compile my file I use "gfortran test tensor ope.for -llapack". Following your answer, I implemented the following lines in the file CMakeLists.txt and then I obtain two errors

add_pfunit_ctest(my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
a.F90 b.F90 ...
LINK_LIBRARIES lapack
target_link_directories(my_test_tensor_llpack PRIVATE /usr/lib/x86_64-linux-gnu)
)

CMake Error at //home/william/pFUnit/include/add_pfunit_ctest.cmake:121 (target_link_libraries):
Target "my_test_tensor_llpack" of type EXECUTABLE may not be linked into
another target. One may link only to INTERFACE, OBJECT, STATIC or SHARED
libraries, or to executables with the ENABLE_EXPORTS property set.
Call Stack (most recent call first):
CMakeLists.txt:31 (add_pfunit_ctest)

CMake Error at //home/william/pFUnit/include/add_pfunit_ctest.cmake:121 (target_link_libraries):
The INTERFACE, PUBLIC or PRIVATE option must appear as the second argument,
just after the target name.

When I run the test this is the message that I get
tensor_ope_module.for:(.text+0x6ea5): undefined reference to dgetrf_' /usr/bin/ld: tensor_ope_module.for:(.text+0x6f00): undefined reference to dgetri_'
dgetrf is part of the package LAPACK of fortran http://www.netlib.org/lapack/

If I run the lines according to the first option, see below, there is not a detailed error

add_pfunit_ctest (my_test_tensor_llpack #Name of the created executable
TEST_SOURCES ${test_srcs}
a.F90 b.F90 ...
LINK_LIBRARIES /usr/lib/x86_64-linux-gnu/liblapack.a
)
[ 10%] Building Fortran object CMakeFiles/sut.dir/tensor_ope_module.for.o
[ 20%] Linking Fortran static library libsut.a
[ 20%] Built target sut
make[2]: *** No rule to make target '../b.F90', needed by 'b.F90'. Stop.
make[1]: *** [CMakeFiles/Makefile2:110: CMakeFiles/my_test_tensor_llpack.dir/all] Error 2
make: *** [Makefile:101: all] Error 2

Again thank you for your help

@tclune
Copy link
Member

tclune commented Sep 7, 2021

OK - thank you for the extra details.
The FILE() command I described is a CMake macro that should go in the same file as your add_pfunit_ctest() invocation. It copies a file from your source tree to your binary tree. (You are new to CMake so you may be building inside your source tree. In that case this step will not help and you must have a different issue.) For the moment you could check the value of "stat" in your open statement and see what the actual error is. Presumably it is that the file is missing, but that is only an educated guess on my part.

Regarding the linkage to external libraries, I'll try to set something similar up on my end. These days I'm in a "pure" cmake world and such linkage issues are usually solved through transitive dependencies of the code to be tested. I.e., I don't usually need to bring in external libraries for just the tests. But it should be possible - need to replicate and see if the macro should be fixed or if I just botched the directions.

Also, note that I'm nominally on vacation this week. Did a bit of work this morning because a I had an important meeting to attend. I may not be able to get back to this issue until next week. Cheers.

@williammora1984
Copy link
Author

Hello, please could please give more advice taking into consideration my last post. Actually, I write it again because It was disordered.

For the question 2, In this question, I wonder if I'm making the wrong question because I'm taking the wrong way. Maybe you can indicate to me how is performed for example a series of 1000 tests, where I have in another file the test data of the 1000 test or if my idea of read the csv file is right and where could be the problem, I don't get any error message, I only see the problem when I add a line, again in the pf file, to print the information.

For the question 1

  1. The original error message (when I wrote the first post) is:
    tensor_ope_module.for:(.text+0x6ea5): undefined reference to dgetrf_' /usr/bin/ld: tensor_ope_module.for:(.text+0x6f00): undefined reference to dgetri_'

I'm using the function dgetrf of the package LAPACK of fortran http://www.netlib.org/lapack/
I compile my program using this line "gfortran test tensor ope.for -llapack"

I implemented your first alternative with the following lines

add_pfunit_ctest (my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
a.F90 b.F90 ...
LINK_LIBRARIES /usr/lib/x86_64-linux-gnu/liblapack.a
)

and when run the test this is the message

[ 10%] Building Fortran object CMakeFiles/sut.dir/tensor_ope_module.for.o
[ 20%] Linking Fortran static library libsut.a
[ 20%] Built target sut
make[2]: *** No rule to make target '../b.F90', needed by 'b.F90'. Stop.
make[1]: *** [CMakeFiles/Makefile2:110: CMakeFiles/my_test_tensor_llpack.dir/all] Error 2
make: *** [Makefile:101: all] Error 2

When I implement your second alternative according to the following lines

add_pfunit_ctest(my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
a.F90 b.F90 ...
LINK_LIBRARIES lapack
target_link_directories(my_test_tensor_llpack PRIVATE /usr/lib/x86_64-linux-gnu)
)

CMake Error at //home/william/pFUnit/include/add_pfunit_ctest.cmake:121 (target_link_libraries):
Target "my_test_tensor_llpack" of type EXECUTABLE may not be linked into
another target. One may link only to INTERFACE, OBJECT, STATIC or SHARED
libraries, or to executables with the ENABLE_EXPORTS property set.
Call Stack (most recent call first):
CMakeLists.txt:31 (add_pfunit_ctest)

CMake Error at //home/william/pFUnit/include/add_pfunit_ctest.cmake:121 (target_link_libraries):
The INTERFACE, PUBLIC or PRIVATE option must appear as the second argument,
just after the target name.

@tclune
Copy link
Member

tclune commented Sep 27, 2021

For Question 2, I'm not sure that I am any closer to understanding your question/issue.

Q: Are you trying to test the code that reads this file of data? Or are does the file contain a set of parameters for which you want to run the same test logic many times but just with different values?

These are very different, but I'm still not sure which you meant. For now I'm going to assume the latter: that you want to run the same test logic across multiple parameters. One way to accomplish this is with a ParameterizedTest. These are a bit more trouble to set up, but are intended to reuse the same test procedure multiple times but with different data. The data in your file could be read in the procedure that "generates" the parameter values for the tests.


The error about not finding b.F90 is because of a missing argument in your use of the macro. It should have been:

add_pfunit_ctest (my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
OTHER_SOURCES a.F90 b.F90
LINK_LIBRARIES /usr/lib/x86_64-linux-gnu/liblapack.a
)

In your second attempt, the target_link_directories should have been a separate command - not an argument to the cmake macro:

add_pfunit_ctest(my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
a.F90 b.F90 ...
LINK_LIBRARIES lapack
)
target_link_directories(my_test_tensor_llpack PRIVATE /usr/lib/x86_64-linux-gnu)

@williammora1984
Copy link
Author

Thank you for your last post, for question 2, without still implementing the ParameterizedTest, finally, I found that using the configuration of the trivial example, in the compilation, in the build folder is copied an empty version of my CVS file. Therefore, an empty file is read. In the end, if I copy the CVS file and run the executable I can evaluate the test that don't use the llapackage. I hope to have more time to implement in the future the parameterizedTest.

For the question 1, I implemented both suggested solutions but still, it is presented errors. I copy the complete code of the Cmakelist ussing the first alternative, maybe there is another thing that I'm not defining correctly.

find_package(/home/william/pFUnit/build/PFUNIT REQUIRED)
enable_testing()

#FILE()
#FILE (COPY simple.yaml DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

add_library (sut
tensor_ope_module.for
/usr/lib/x86_64-linux-gnu/liblapack.a #Name of the file to test
)
target_include_directories(sut PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

set (test_srcs test_tensor_mod.pf) f
add_pfunit_ctest (my_test_tensor_op1
TEST_SOURCES ${test_srcs}
LINK_LIBRARIES sut
)

add_pfunit_ctest (my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
OTHER_SOURCES a.F90 b.F90 ...
a.F90 b.F90 ...
LINK_LIBRARIES /usr/lib/x86_64-linux-gnu/liblapack.a

The error message is

-- The Fortran compiler identification is GNU 9.3.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /usr/bin/f95 - skipped
-- Checking whether /usr/bin/f95 supports Fortran 90
-- Checking whether /usr/bin/f95 supports Fortran 90 - yes
-- Found Python: /home/william/anaconda3/bin/python3.8 (found version "3.8.8") found components: Interpreter
-- Found OpenMP_Fortran: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done
CMake Error at //home/william/pFUnit/include/add_pfunit_ctest.cmake:77 (add_executable):
Cannot find source file:

a.F90

Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
.hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
Call Stack (most recent call first):
CMakeLists.txt:29 (add_pfunit_ctest)

CMake Error at //home/william/pFUnit/include/add_pfunit_ctest.cmake:77 (add_executable):
No SOURCES given to target: my_test_tensor_llpack
Call Stack (most recent call first):
CMakeLists.txt:29 (add_pfunit_ctest)

CMake Generate step failed. Build files cannot be regenerated correctly.
make: *** No targets specified and no makefile found. Stop.
./build_with_cmake_and_run.x: line 13: ./my_test_tensor_llpack: No such file or directory

When I implemented the second alternative

add_pfunit_ctest(my_test_tensor_llpack
TEST_SOURCES ${test_srcs}
a.F90 b.F90 ...
LINK_LIBRARIES lapack
)
target_link_directories(my_test_tensor_llpack PRIVATE /usr/lib/x86_64-linux-gnu)

It is obtained one of the errors of the previous post. (And I tried to do the same change OTHER_SOURCES a.F90 b.F90 ... , but then the same error than the first alternative is obtained.

-- The Fortran compiler identification is GNU 9.3.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /usr/bin/f95 - skipped
-- Checking whether /usr/bin/f95 supports Fortran 90
-- Checking whether /usr/bin/f95 supports Fortran 90 - yes
-- Found Python: /home/william/anaconda3/bin/python3.8 (found version "3.8.8") found components: Interpreter
-- Found OpenMP_Fortran: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/william/Code_Sem_IV/PPP_II/Code_PPP/1_Test_tensor_op/build
[ 6%] Generating test_tensor_mod.F90
Processing file ../test_tensor_mod.pf
... Done. Results in test_tensor_mod.F90
make[2]: *** No rule to make target '../...', needed by '.F90'. Stop.
make[1]: *** [CMakeFiles/Makefile2:86: CMakeFiles/my_test_tensor_llpack.dir/all] Error 2
make: *** [Makefile:101: all] Error 2
./build_with_cmake_and_run.x: line 13: ./my_test_tensor_llpack: No such file or directory

@tclune
Copy link
Member

tclune commented Nov 1, 2021

Again - apologies for the slow response. I'll try to be responsive this week so we can get something working for you.

A complete reproducer would be useful here. CMake is telling you that it cannot find the source file a.F90 which suggests that it is not in the same directory as that cmake file. (I'll also note that you cannot list a library in add_library(), where you have /usr/lib/x86_64-linux-gnu/liblapack.a).

I also see that in both attempts you have elipses (...) in your list of source files. Apologies if that was a verbatim of something I wrote before; it was only meant to indicate this is where you would list any such sources.

In the 2nd approach, I also note that you don't have the OTHER_SOURCES argument indicator in your add_pfunit_ctest() invocation.

If at all possible, I recommend composing a small case that you cannot get to work. I should then be able to fix up the necessary cmake logic and get it back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants