GithubHelp home page GithubHelp logo

jacobwilliams / bspline-fortran Goto Github PK

View Code? Open in Web Editor NEW
163.0 22.0 55.0 19.09 MB

Multidimensional B-Spline Interpolation of Data on a Regular Grid

License: Other

Fortran 88.74% CMake 0.49% Python 10.76%
fortran interpolation splines extrapolation b-spline fortran-package-manager least-squares-curve-fitting quadrature-integration

bspline-fortran's Introduction

Header image

Orbital mechanic and programmer. Fortran aficionado.

bspline-fortran's People

Contributors

gjacquenot avatar jacobwilliams avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bspline-fortran's Issues

Reshape calls

This reshape call for the 3d ink routine:

        temp(1:nx*ny*nz) = reshape( fcn, [nx*ny*nz] )

Is crashing for large data sets. Replace with loops. Note there is also another one for the 5D routine.

Extrapolation to the right

I received an email that maybe extrapolation to the right (when xval is to the right of the rightmost point in the grid) isn't working for the 3D case. Need to look into this.

How to compile with ifort

Hi,
Thanks for making bspline-fortran available.
I'm trying to use it in a project that I compile with ifort.

Unfortunately I have not managed to find the configuration file where the compiler is defined (using cmake).
Could you please help me find it?

Thanks
Gianni

array temporary created

In the call to subroutine check(s,n,k,x,t,ierrs,error), array temporaries are created, which means that actual arguments are copied into temporary storage before routine calls. This may be specific to the Intel Fortran Compiler, and can be seen by building and running with the flag '-check arg_temp_created'. Since this happens for every call to db*val, I was concerned about an adverse performance impact, and started a thread on comp.lang.fortran:

https://groups.google.com/forum/#!topic/comp.lang.fortran/jPRslnUD-Pk

The upshot of that discussion is that:

  • This behavior may be specific to Intel Compilers (including the latest).
  • The performance impact may be negative, but that could be negligibly small.
  • For several reasons it is recommended to change the offending variable to have an assumed-shape, i.e., change
    integer,dimension(4),intent(in)

to

    integer,dimension(:),intent(in)

This resolves the issue.

Problem in parallelized environment

The code can't be used in a parallelized environment, because there are variables with the SAVE attribute in the subroutines db[X]val. This makes them effectively global, so that different parallel threads -each calling db[X]val independently- will overwrite the value, resulting in run-time errors. I think this behaviour will also occur for the object-oriented version (not tested), but it may be easier to remedy there.

In my opinion, modern Fortran code should be written so that it can be used in parallel applications. For example, in my case, an outer loop is parallelized with OpenMP, and within the loop each thread uses bspline-fortran for interpolation. I think this is a common setting, and that bspline-fortran should be a prime candidate for such high-performance applications.

For parallelization with OpenMP, I have implemented an easy solution (easy to implement, though it took me a complete day to figure out what was going wrong...). For example for subroutine db2val, replace the lines

integer,save :: inbvx = 1
integer,save :: iloy  = 1

by

integer,save :: inbvx
integer,save :: iloy
!$OMP THREADPRIVATE(inbvx, iloy)
inbvx = 1
iloy  = 1

This creates separate SAVEd variables inbvx, iloy for each thread, which are then 'global' within the thread. In my own application, this resolved the problems. Compiling and running with the Intel Fortran Compiler with maximum debug flags didn't report any warnings or errors. However, I am not a programmer by training, so I can't say how good or reliable or general the solution is.

For the object-oriented version, one could make use of the private type components that correspond to inbvx, iloy to avoid the need for the SAVE attribute. This would have the advantage of being more portable, since it wouldn't be limited to OpenMP. But it would require a little bit larger modifications of db[X]val and maybe the routines called by it, I believe. This object-oriented solution and the OpenMP-based one are not mutually exclusive.

pgfortran compilation fail

PGI Fortran compiler gives the following error when compiling the sub_module:

bspline-fortran/src> pgfortran -c -Ktrap=fp bspline_kinds_module.F90 bspline_sub_module.f90 
bspline_kinds_module.F90:
bspline_sub_module.f90:
PGF90-W-0155-Integer overflow occurred when evaluating ** (bspline_sub_module.f90: 3615)
PGF90-S-0098-Divide by zero (bspline_sub_module.f90: 3615)
  0 inform,   1 warnings,   1 severes, 0 fatal for dbint4

This error caused by line 3615 in bspline_sub_module.f90

real(wp),parameter :: wdtol = radix(1.0_wp)**(1-digits(1.0_wp)) !! d1mach(4)

The types of radix and digits are integer, so the right-hand side of this expression is (integer)^(integer) form.
Therefore, when the result of radix(1.0_wp)**(1-digits(1.0_wp)) is too small for the integer type, the overflow causes.
(Perhaps other compilers do type conversion automatically, but the PGI compiler does not.)

Possible alternatives are:

real(wp),parameter :: wdtol = real(radix(1.0_wp), kind=wp)**(1-digits(1.0_wp)) !! d1mach(4)

or

real(wp),parameter :: wdtol = epsilon(1.0_wp) !! d1mach(4)

Better error handling

Need more graceful error handling, and returning of flags that indicate specifically what error occurred (rather than just printing messages to the console).

1D bspline

it would be great to have also bsplines for 1D interpolation with the same call syntax, i.e.,

db1ink(x,nx,fcn,kx,tx,bcoef,iflag)
db1val(...)

Or is there something that I am missing?

dbspvn dummy arguments

In dbspvn, I think these two should be intent(inout):

real(wp),dimension(*),intent(out) :: work     !! a work vector of length `2*k`
integer(ip),intent(out)           :: iwork    !! a work parameter.  both `work` and `iwork` contain

For the case where there routine is called again with index = 2.

size_of result overflows for very large data sets

The size_of functions in the object oriented classes only return a default integer. So, it can overflow for very large data sets. Should give the user some ability to specify the integer kind to use.

Speed tests

Should have a speed test for both the subroutine and object-oriented interfaces. Possibly with and without OpenMP.

feature request: constructor

Here is an example, adapted from Rouson, Xia, Xu (2014).

module template_class
    type :: t_template
    !...
    end type t_template

    interface t_template
        module procedure constructor
    end interface
contains
    elemental function constructor( ) result (new_instance)
    type(t_template)         :: new_instance
    !...
    end function constructor
end module template_class

which allows initialization statements such as

dti = t_template

which can be useful in cases such as outlined in issue #12 .

DEFC

Consider including DEFC a least-squares B-Spline fit from SLATEC.

Integrals

I would like to be able to get definite integrals of B-Splines.
There seems to be something in the CMLIB library: BSQAD, which only depends on INTRV and BVALU, both of which exist already in bspline-fortran.

Compile error : Invalid character in name at (1)

Dear all,
I got the following error when I used cmake.
My system: CentOS 7.5, gcc-gfortran 4.8.5 20150623

Scanning dependencies of target bspline-fortran
[ 25%] Building Fortran object CMakeFiles/bspline-fortran.dir/src/bspline_kinds_module.f90.o
[ 50%] Building Fortran object CMakeFiles/bspline-fortran.dir/src/bspline_sub_module.f90.o
[ 75%] Building Fortran object CMakeFiles/bspline-fortran.dir/src/bspline_oo_module.f90.o
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:21.54:
integer,parameter :: int_size = storage_size(1) !! size of a defa
1
Error: Invalid character in name at (1)
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:22.54:
integer,parameter :: logical_size = storage_size(.true.) !! size of a defa
1
Error: Invalid character in name at (1)
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:23.54:
integer,parameter :: real_size = storage_size(1.0_wp) !! size of a `rea
1
Error: Invalid character in name at (1)
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:63.52:
type,extends(bspline_class),public :: bspline_1d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:86.52:
type,extends(bspline_class),public :: bspline_2d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:109.52:
type,extends(bspline_class),public :: bspline_3d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:137.52:
type,extends(bspline_class),public :: bspline_4d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:170.52:
type,extends(bspline_class),public :: bspline_5d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:208.52:
type,extends(bspline_class),public :: bspline_6d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:491.18:
s = 2int_size + logical_size + 22int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:491.33:
s = 2int_size + logical_size + 22int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:493.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:464.18:
s = 2int_size + logical_size + 18int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:464.33:
s = 2int_size + logical_size + 18int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:466.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:439.18:
s = 2int_size + logical_size + 14int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:439.33:
s = 2int_size + logical_size + 14int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:441.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:416.18:
s = 2int_size + logical_size + 10int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:416.33:
s = 2int_size + logical_size + 10int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:418.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:395.18:
s = 2int_size + logical_size + 6int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:395.33:
s = 2int_size + logical_size + 6int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:397.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:376.18:
s = 2int_size + logical_size + 2int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
Fatal Error: Error count reached limit of 25.
make[3]: *** [CMakeFiles/bspline-fortran.dir/src/bspline_oo_module.f90.o] Error 1
make[2]: *** [CMakeFiles/bspline-fortran.dir/src/bspline_oo_module.f90.o.provides] Error 2
make[1]: *** [CMakeFiles/bspline-fortran.dir/all] Error 2
make: *** [all] Error 2

Any help will be appreciated.
Youzhao Lan

Ifort compilation fail

Intel Fortran 14 gives the following error when compiling the oo module:

bspline-fortran/src> ifort -c bspline_sub_module.f90 bspline_oo_module.f90 
bspline_oo_module.f90(50): error #8259: The type bound procedure definition statement must contains only one binding name.   [INITIALIZE_1D_SPECIFY_KNOTS]
        procedure :: initialize_1d_auto_knots,initialize_1d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(70): error #8259: The type bound procedure definition statement must contains only one binding name.   [INITIALIZE_2D_SPECIFY_KNOTS]
        procedure :: initialize_2d_auto_knots,initialize_2d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(95): error #8259: The type bound procedure definition statement must contains only one binding name.   [INITIALIZE_3D_SPECIFY_KNOTS]
        procedure :: initialize_3d_auto_knots,initialize_3d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(126): error #8259: The type bound procedure definition statement must contains only one binding name.   [INITIALIZE_4D_SPECIFY_KNOTS]
        procedure :: initialize_4d_auto_knots,initialize_4d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(161): error #8259: The type bound procedure definition statement must contains only one binding name.   [INITIALIZE_5D_SPECIFY_KNOTS]
        procedure :: initialize_5d_auto_knots,initialize_5d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(201): error #8259: The type bound procedure definition statement must contains only one binding name.   [INITIALIZE_6D_SPECIFY_KNOTS]
        procedure :: initialize_6d_auto_knots,initialize_6d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(200): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type.   [INITIALIZE_6D_SPECIFY_KNOTS]
        generic,public :: initialize => initialize_6d_auto_knots,initialize_6d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(160): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type.   [INITIALIZE_5D_SPECIFY_KNOTS]
        generic,public :: initialize => initialize_5d_auto_knots,initialize_5d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(125): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type.   [INITIALIZE_4D_SPECIFY_KNOTS]
        generic,public :: initialize => initialize_4d_auto_knots,initialize_4d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(94): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type.   [INITIALIZE_3D_SPECIFY_KNOTS]
        generic,public :: initialize => initialize_3d_auto_knots,initialize_3d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(69): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type.   [INITIALIZE_2D_SPECIFY_KNOTS]
        generic,public :: initialize => initialize_2d_auto_knots,initialize_2d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(49): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type.   [INITIALIZE_1D_SPECIFY_KNOTS]
        generic,public :: initialize => initialize_1d_auto_knots,initialize_1d_specify_knots
-----------------------------------------------------------------^
compilation aborted for bspline_oo_module.f90 (code 1)

changes to initialization routines arguments

I'm considering redefining the iflag return values from the initialization routines so that a 0 value means no errors. This would match the evaluation routines. Also, for specifying the knots, there should be a logical input specify_knots, rather than the current dual-use iflag variable (which is an artifact from the original code). This would break backward compatibility, so it would be in the 5.0 release.

dfc

Another potential routine to add: dfc.f.

Related to #67.

OpenMP with bspline routines

Hi,

Just want to ask how should the variables inbvx,inbvy,inbvz,iloy,iloz,w1_3d,w2_3d,w3_3d on a 3D splines be set for an open mp code?
Should they be shared or private?

Thank you.
volcompt

Many array temporaries created

In bspline_sub_module.f90, 'many' array temporaries are created.
When compiling with GCC 7.3.0 and the warning flag -Warray-temporaries, most of them intervene in the calls to dintrv, dbvalu, dbknot and dbtpcf
With just runtime checks, -fcheck=all, they arise for the "fcn" argument of dbtpcf.

I have no idea how harmelss those runtime array temporaries are but since I am incorporating bspline-fortran within a large 3D code I would like to avoid memory fragmentation as much as possible and not exhaust my stack.

I managed to eliminate most of the array temporaries by changing explicit-shape dummy arguments to assumed-shape dummy arguments in most of the routines and getting rid of some assumed-size dummy arrays. But problem remains for "fcn" and "bcoef" in dbtpcf.

I assume it would be tricky to change everything and it would require some copying to adapt the routines for 1D and 3D as the library was originally written in 2D, but I thought assumed-size arrays should not be used in modern Fortran.

splpak

Consider splpak and see if that is something that could be merged into this library.

Use of bspline-fortran

Hi,
We used your library to develop our project and we would like to pusblish it on github with a GPL license.
Is that compatible with you?
Best regards,
Benjamin

Extrapolation

Consider adding an extrapolation option, where if a point is requested outside the bounds, it just does an extrapolation of the endpoints or something like that.

.mod files not found during (cmake) compilation

Hello, I have never used cmake, so I have (I think) a very dumb question.

I'm trying to compile with cmake, so I followed the readme and started the compilation with make. The problem is that after few instant the compilation stops with an error since it cannot find the .mod files (that are inside the lib directory).

Is there something that is not written in the readme that I should do ? It seems that the makefile doesn't know where to look for .mod files.

Thanks in advance !

Clean up build system

I want to get rid of the pyplot-fortran submodule, and use FPM to pull that in. I don't know how to do that with CMake, so I may end up removing CMake support for tests, unless somebody else wants to maintain that. Also probably will remove FoBiS support.

Wsurprising?

Hello! When compiling with gfortran with -Wall, every type definition gives this warning:

 mpif90 -Ofast -march=native -mtune=native -pipe -g -fopenmp -Wall -c src/bspline_oo_module.f90 src/bspline_oo_module.f90:62:52:

 type,extends(bspline_class),public :: bspline_1d
                                                1
 Warning: Only array FINAL procedures declared for derived type ‘bspline_1d’ defined at (1), suggest also scalar one [-Wsurprising]

Can it be safely ignored? Thank you!

Citation

Dear Williams,

Could you upload your open source codes into open source software journal like:

The Journal of Open Source Software, ArXiv, ...

for easy citation?:)

Best Regards,
Young-Myung Choi

Thread safety/bounds check failures

There appear to be problems related to the thread safety of this library.

Below code works fine when running without OpenMP:

program main
use bspline_module
use bspline_kinds_module

implicit none
type(bspline_1d) :: s
real(kind=wp), dimension(:), allocatable :: x, fcn
real(kind=wp) :: q, f
integer :: i, iflag
integer, parameter :: size = 30
print *, '*** START'

print *, '*** INIT'
allocate(x(size), fcn(size))

do i = 1, size
     x(i) = real(i, wp)
     fcn(i) = x(i)**2
     print *, i, x(i), fcn(i)
end do

call s%initialize(x, fcn, 4, iflag)
print *, iflag

print *, '*** EVAL'

!$omp parallel do default(shared) private(i, q, f, iflag)
do i = 1, 50000
     call random_number(q)
     q = 1.0_wp + q * real(size-1, wp)
     call s%evaluate(q, 0, f, iflag)
     if (iflag /= 0) print *, q, iflag, s%status_message(iflag)
end do
!$omp end parallel do

print *, '*** END'

end program main

Enabling bounds checks and enabling OpenMP then gives out-of-bounds errors when evaluating the spline in parallel. Both gfortran (with -fcheck=bounds) and ifort (with -check bounds) throw these errors and I doubt that they are false positives.

ifort output:

forrtl: severe (408): fort: (3): Subscript #1 of the array A has value 0 which is less than the lower bound of 1

gfortran output:

At line 3056 of file [...]/bspline_sub_module.f90
Fortran runtime error: Index '0' of dimension 1 of array 'a' below lower bound of 1

Have you come across this before @jacobwilliams or I am making some mistake here?

check length of inputs?

I think db[X]ink doesn't check whether the abscissae x (, y,…) and the function values fcn have the same length. Should it? If so, should it return an appropriate flag (or issue a warning)?

dimension check 3D spline

Hi Jacob,

I think there is a typo in the dimension check for the 3D splines, line 1708 in the current sub module.

It says

if (size(z)/=size(f3,2)) then; iflag = 702; return; end if

but should say

if (size(z)/=size(f3,3)) then; iflag = 702; return; end if

Thanks for all your work on this, so useful!
Moritz

Problem with OO interface in parallelized environment

This is similar to issue #4 but now I tried the OO module. When compiled with -openmp, my code builds but crashes with SIGSEGV at runtime. This does not happen without -openmp.

When I add the SAVE attribute to the spline instance, e.g.,

type(bspline_2d) ,save:: v_spline

the program runs without crashing. Each thread gets its own copy by

!$OMP PARALLEL PRIVATE(v_spline)

I am not quite sure why this is happening. Could it be that the default initialization in the derived type declaration, e.g.,

integer :: inbvy = 1
integer :: iloy = 1

puts the variables on stack, thereby making them global (like the problem in #4 )? Or maybe my workaround with SAVE is erroneous? I could also imagine that this is a compiler bug, I tested with Intel composer_xe_2015.1.133 and composer_xe_2015.0.090, fairly recent compilers. Strangely enough, the problem also disappears if the compiler option -ftrapuv (which I use for debugging) is specified.

I have put substantial effort in moving my code to the OO version and in investigating this issue, and would be very grateful for any help.

Logo

Add logo to the ford-produced documentation.

Thread safe OO interface with OpenMP?

Hello! Any advice on how to debug what seems to be a thread safety issue with OpenMP at evaluation? Did anyone else run into this problem? I'll put together a minimal example.

Would switching to the non-OO subroutines help?

Thank you!

bad use of stack memory instead of heap

I'm afraid that many routines currently use a wrong type of array in Fortran. This leads to a much lower data size limit than could otherwise be achieved.

All large local variables should allocatable, because they use heap memory by default. Currently many large local arrays are of automatic size, so they get allocated on the stack. This commit shows how to correct the db3ink procedure. The fix is straightforward, but a little tedious to implement everywhere.

I see two solutions:

  1. The 'right' approach: do what I did for db3ink in all procedures, and then merge the branch.

  2. A hack: use a compiler option to force all arrays onto the heap. This commit shows how I did this with the intel compiler. I don't know how to do the equivalent for the GNU compiler.


For reference, these were the limits for the data sizes for

    type(bspline_3d) :: spline
    ...
    call spline%initialize(  &
          x=xi, y=yi, z=zi,  &
          fcn=data,  &
          kx=4, ky=4, kz=4,  &
          iflag=iflag,  &
          extrap=.true.  &
      )

on my computer cluster:

  • original maximum: size(xi) * size(yi) * size(zi) = 9 * 9 * 9 ;

  • after fixing db3ink: 9 * 9 * 20 (approximate);

  • after compiling everything with -heap-arrays: 264 * 240 * 240 still works. Did not test larger array.

pure procedures?

Would it be a good and feasible idea to make the procedures pure? Since the save variables are gone, that's one less obstacle. The other obstacle are the error messages. Since an error flag is already present, one could move the messages to a separate (non-pure) type-bound subroutine which takes flag as input and prints the corresponding message.

In my case, the spline evaluation appears in a bottleneck part of the code that could benefit from optimization which the compiler can do for pure procedures, and bspline is the only element preventing this.

Parallelization

Are their any opportunities to speed up the low-level routines perhaps by using OpenMP, or maybe do concurrent loops? Look into this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.