Compilation of Fortran 90 code that uses PETSc
I have installed PETSc 3.10.2 along with the intel compilers and everything went fine (including tests).
I am now trying to call PETSc from an small existing Fortran code:
program hello
#include <petsc/finclude/petscvec.h>
use petscvec
implicit none
PetscScalar xwork(6)
PetscScalar, pointer :: xx_v(:),yy_v(:)
PetscInt i,n,loc(6)
PetscErrorCode ierr
Vec x,y
print *, "Hello World!"
end program hello
And to compile it (with PETSC_DIR defined and the headers are at the right location):
mpif90 -I${PETSC_DIR}/include -L${PETSC_DIR}/lib -lpetsc test.F90 -o test
The compilation fails, with errors that looks like the module petscvec is never used:
test.F90(11): error #5082: Syntax error, found IDENTIFIER 'XWORK' when expecting one of: => = . [ % ( :
PetscScalar xwork(6)
--------------------^
test.F90(12): error #5082: Syntax error, found ',' when expecting one of: => = . [ % ( :
PetscScalar, pointer :: xx_v(:),yy_v(:)
------------------^
test.F90(12): error #5082: Syntax error, found END-OF-STATEMENT when expecting one of: , :: : )
PetscScalar, pointer :: xx_v(:),yy_v(:)
-----------------------------------------------^
I do not want to use the defined makefiles since the goal of all this is to include PETSc in one of an already written code and I would like to understand how to link and compile it.
Do you have any suggestions?
See also questions close to this topic
-
Makefile with Objects in Seperare Directory Tree
I have been trying to devise a makefile example which can build object files to a different directory structure than the associated source. The directory tree, both with source and targets, is as follows:
/repo-root |-- /build |-- /example_lib |-- makefile |-- /Release* |-- libexample_lib.a* |-- /obj* |-- example_lib.o* |-- example_lib.d* |-- /source |-- /example_lib |-- /inc |-- example_lib.h |-- /src |-- example_lib.cpp
The asterisk folders/files are those the makefile should be generating.
I have seen other questions and answers (Makefile : Build in a separate directory tree), (Makefile with directory for object files), etc., but if I understand their source-to-object rules correctly these appear to create a subdirectory tree within the output directory matching that of the source.
The current makefile I am using is as follows, run using GNU Make 3.82:
SHELL = /bin/sh .SUFFIXES: .SUFFIXES: .cpp .o # @todo Variables passed to make. BUILD_CONFIG=Release # Makefile specific variables REPO_ROOT=../.. LIBRARY_NAME=example_lib #------------------------------------------------------------------- # Derived variables #------------------------------------------------------------------- LIBRARY_FILENAME=lib$(LIBRARY_NAME).a LIBRARY_FILEPATH=$(BUILD_CONFIG)/$(LIBRARY_FILENAME) # Source directories CPP_SRC_DIRS=$(REPO_ROOT)/source/example_lib/src # Source files vpath %.cpp $(CPP_SRC_DIRS) CPP_SRCS=$(foreach cpp_src_dir, $(CPP_SRC_DIRS), $(wildcard $(cpp_src_dir)/*.cpp)) # Object/dependencies directory OBJ_DEPS_DIR=./$(BUILD_CONFIG)/obj # Object files OBJS=$(CPP_SRCS:%.cpp=$(OBJ_DEPS_DIR)/%.o) # Dependency files (built with objects) DEPS=$(CPP_SRCS:%.cpp=$(OBJ_DEPS_DIR)/%.d) #------------------------------------------------------------------- # C++ compiler settings #------------------------------------------------------------------- CPP_COMMAND=g++ CPP_OPTIONS_INC_PATHS=-I"$(REPO_ROOT)/source/example_lib/inc" CPP_OPTIONS_OPTIM=-O3 CPP_OPTIONS_WARN=-Wall CPP_OPTIONS_MISC=-c -fmessage-length=0 CPP_OPTIONS=$(CPP_OPTIONS_INC_PATHS) $(CPP_OPTIONS_OPTIM) $(CPP_OPTIONS_WARN) $(CPP_OPTIONS_MISC) #------------------------------------------------------------------- # Archiver settings #------------------------------------------------------------------- AR_COMMAND=ar AR_OPTIONS=-r #------------------------------------------------------------------- # Targets #------------------------------------------------------------------- # Object/dependency directory target $(OBJS): | $(OBJ_DEPS_DIR) $(OBJ_DEPS_DIR): mkdir -p $(OBJ_DEPS_DIR) # Object targets $(OBJ_DEPS_DIR)/%.o: %.cpp @echo 'Building file: $<' @echo 'Invoking: GCC C++ Compiler' $(CPP_COMMAND) $(CPP_OPTIONS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" @echo 'Finished building: $<' @echo ' ' # 'all' target all: $(LIBRARY_FILEPATH) # Output library target $(LIBRARY_FILEPATH): $(OBJS) @echo 'Building target: $@' @echo 'Invoking: GCC Archiver' $(AR_COMMAND) $(AR_OPTIONS) "$@" $(OBJS) @echo 'Finished building target: $@' @echo ' ' # 'clean' target clean: @echo 'Cleaning targets' rm -rf $(OBJS) $(DEPS) $(LIBRARY_FILENAME) @echo ' ' # 'PHONY' target .PHONY: all clean
What 'make' outputs, which makes sense, is:
make all Building file: ../../source/example_lib/src/example_lib.cpp Invoking: GCC C++ Compiler g++ -I"../../source/example_lib/inc" -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"Release/obj/../../source/example_lib/src/example_lib.d" -MT"Release/obj/../../source/example_lib/src/example_lib.o" -o "Release/obj/../../source/example_lib/src/example_lib.o" "../../source/example_lib/src/example_lib.cpp" ../../source/example_lib/src/example_lib.cpp:6:1: fatal error: opening dependency file Release/obj/../../source/example_lib/src/example_lib.d: No such file or directory } ^ compilation terminated. make: *** [Release/obj/../../source/example_lib/src/example_lib.o] Error 1
The source-to-object rule is substituting the full path of the %.cpp file into the %.o target, which results in an object path of:
Release/obj/../../source/example_lib/src/example_lib.o
What I don't understand is how to get the implicit rules for a source and object file to match when they are in different trees. I used vpath for this to help with source resolution, but the object (target) portion doesn't match up. I also tried changing the source-to-object rule to:
$(OBJ_DEPS_DIR)/$(notdir %.o): %.cpp
But this resulted in the same path (it appears commands like $(notdir ...) aren't supported for wildcard matching?). I also realize that dropping all object files from potentially different source directories could result in a name collision if the two source directories happen to have a file with the same name - this isn't a problem for the code I am working with.
Any help is appreciated, and thanks in advance!
-
Include in Makefile another Makefile with relative path
I have a directory tree like this with some "shared targets" in the file
rules.Makefile
:├── Makefile ├── rules.Makefile └── my_subdir └── Makefile
I would like to invoke these "shared targets" in both the
Makefile
(s) in the parent directory and the child directory.Also the "custom targets" in the
Makefile
in the child directory should be callable from theMakefile
in the parent directory.For some reason I am able to call the targets in
rules.Makefile
only from the siblingMakefile
(the one in the parent directory). When using relative paths in theMakefile
in the child directory trying to access therules.Makefile
in the parent directory I get some errors.The content of the
Makefile
in the parent directory:RULES_MAKEFILE_PATH=$(PWD)/rules.Makefile include $(RULES_MAKEFILE_PATH) foo-parent: @echo $(RULES_MAKEFILE_PATH)
The content of the
Makefile
in the child directory (please note that double dot..
):RULES_MAKEFILE_PATH=$(PWD)/../rules.Makefile include "$(RULES_MAKEFILE_PATH)" foo-child: @echo $(RULES_MAKEFILE_PATH)
When calling from the parent directory
make foo-parent
then I see the expected path.When calling from the child directyr
make foo-child
then I see this error:$ make foo-child Makefile:9: "/<PARENT_PATH>/my_subdir/../rules.Makefile": No such file or directory make: *** No rule to make target '"/<PARENT_PATH>/my_subdir/../rules.Makefile"'. Stop.
- How can I make the relative paths work in the "child directory"?
- Also how can I call the targets defined in the
Makefile
in child directory (e.g.foo-child
) from theMakefile
in the parent directory?
-
change directory in makefile for python
My instructor wrote a script for test cases. The test cases are located in "input" directory. I need to change from "input" to the directory where my "*.py" files are located. In the makefile, I tried the following :
DIR = $(PWD) All : cd $(DIR) ; echo "python main.py" > run
But it still says that python : can't find main.py. However, I added pwd in the "All", it shows the correct directory.
-
Fortran Subroutine not returning value
i run into a strange problem. I am using the locate subroutine from the Fortran-Recipe book. The goal is to find a random number in a CDF-table and return the index of the arrax, such that i can look in another table for the value this would correspond. However i cannot ge it to pass the value of j (jlo in the encompassing function) back. It just stays 0. The subroutine locate changes the value of j to the correct one, but then does not pass it back.
SUBROUTINE locate(xx,n,x,j) INTEGER, INTENT(out) :: j REAL*8 x,xx(n) INTEGER jl,jm,ju,n jl=0 ju=n+1 10 if(ju-jl.gt.1)then jm=(ju+jl)/2 if((xx(n).ge.xx(1)).eqv.(x.ge.xx(jm)))then jl=jm else ju=jm endif goto 10 endif if(x.eq.xx(1))then j=1 else if(x.eq.xx(n))then j=n-1 else j=jl endif return END
This is the design of the subroutine
and this is how it is included:
function CDF() result(xyz) implicit none real(BW) :: rand integer(I2B) :: jlo, N_points_table real(BW), allocatable :: CDFtable(:) N_points_table= 1000 jlo=0 CALL RANDOM_NUMBER(rand) allocate(CDFtable(N_points_table)) ... !setting the content of CDFtable to a CDF of some kind ... call locate(CDFtable,N_points_table,rand,jlo) .... ....
However after the subroutine ran, jlo is still 0 as it was initiated. Any help is greatly appreciated
-
Fortran code returns 0 for every calculation in the loop
Can anyone help me to find where I am going wrong about writing this code
program time_period ! This program calculates time period of an SHM given length of the chord implicit none integer, parameter:: length=10 real, parameter :: g=9.81, pi=3.1415926535897932384 integer, dimension(1:length)::chordlength integer :: l real :: time do l= 1,length time = 2*pi*(chordlength(l)/(g))**.5 print *, l, time enddo end program
Result:
1 0.00000000E+00 2 0.00000000E+00 3 0.00000000E+00 4 0.00000000E+00 5 0.00000000E+00 6 0.00000000E+00 7 0.00000000E+00 8 0.00000000E+00 9 0.00000000E+00 10 0.00000000E+00
-
Fortran - Sorting an array in random order
Went through the Numerical Recipes but couldn't find an applicable solution. Does anyone have an example for sorting an array in random order? Thank you
UPDATE: I have a large array and need to list it in random order.
Here's the initial approach below (pardon the format- first time Fortran user).
Instead of using the random number function and then pulling the numbers from array based on it I was looking for something like a Shuffle function?
program Module3 real, dimension(10,2) :: exceedancearray real, dimension(10000) :: new integer :: positivetotal, rannumber,counter,i REAL :: num do i=1,10 exceedancearray (i,1)=i*10 exceedancearray (i,2)=1000 end do positivetotal=0 counter=1 DO i=1,10 positivetotal=exceedancearray(i,2)+positivetotal END DO PRINT *, positivetotal 1 CALL RANDOM_SEED DO WHILE (positivetotal>0) CALL RANDOM_NUMBER(num) rannumber=nint(num*10) if (rannumber==0) then goto 1 end if if (exceedancearray (rannumber,2)>0) then new(counter)=exceedancearray(rannumber,1) PRINT *, new(counter) counter=counter+1 positivetotal=positivetotal-1 exceedancearray(rannumber,2)=exceedancearray(rannumber,2)-1 end if END DO end program Module3
-
How to call PetscFinalize from the root processor only?
In my Fortran program, I call an external function only at the root processor. I have a few checks to ensure that the function worked. If it doesn't work, then I
stop
the program and callPetscFinalize
. For example:if(rank==0) then call_status = external_function(x) ! function failed if (call_status/=1) then write(6,*) "external_function failed" call PetscFinalize(ierr) stop end if end if
However, I noticed that during runtime, if there is an error with
external_function
, the program hangs and is not finalized properly.My question is: what is the appropriate way to terminate the program at the root processor?
-
Very simple PETSc Mat construction gives SEGV 11 error - C++
I want to create a very simple 2x2 identity matrix in C++ using PETSc library. I have searched various tutorials on the internet and found that all of them indicate one way of doing this. However I get a "Caught signal number 11 SEGV: Segmentation Violation" error. This code is part of a much larger program where I need to create some matrices used in conjunction with other elements of it. Moreover, this code is a mere test, in which I am trying to find out how exactly does PETSc work with matrices. I could say I am still in the learning phase.
The code is the following:
Mat Y11; MatCreate(MPI_COMM_WORLD, &Y11); MatSetSizes(Y11, PETSC_DECIDE, PETSC_DECIDE, 2, 2); std::cout << "set mat type" << std::endl; MatSetType(Y11, MATSEQMAIJ); MatSetFromOptions(Y11); PetscScalar temp22[] = {std::complex<double>(1.0,0), std::complex<double>(0.0,0), std::complex<double>(0.0,0.0), std::complex<double>(1.0,0.0)}; PetscInt tempis[] = {0, 1}; std::cout << "MatSetValues" << std::endl; MatSetValues(Y11, 1, &tempis[0], 1, &tempis[0], &temp22[0], INSERT_VALUES); MatSetValues(Y11, 1, &tempis[0], 1, &tempis[1], &temp22[1], INSERT_VALUES); MatSetValues(Y11, 1, &tempis[1], 1, &tempis[0], &temp22[2], INSERT_VALUES); MatSetValues(Y11, 1, &tempis[1], 1, &tempis[1], &temp22[3], INSERT_VALUES); MatAssemblyBegin(Y11,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(Y11,MAT_FINAL_ASSEMBLY); std::cout << std::endl << "Y11 block:" << std::endl; MatView(Y11,PETSC_VIEWER_STDOUT_WORLD);
The error stems from MatSetValues function.
Could anyone please tell me what could probably be wrong with this code? There are no simple examples like this on the internet (at least of what I can search, in C++). Thank you in advance!