Git Product home page Git Product logo

fdict's People

Contributors

lecrisut avatar zerothi 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fdict's Issues

Move d_entry to dict type

This enables concatenating different dictionaries without disrupting either of the dictionaries and allows entries to refer to the same value.

Note that this requires a certain amount of restructuring as then the linked list is not easily retained.

Make project compatible with `FetchContent`

There are a few issues that should be resolved to make importing find_package and FetchContent equivalent:

  • alias library: fdict -> fdict::fdict
  • namespace targets, options, etc. In order to avoid nameclashes
  • Add options: FDICT_INSTALL, FDICT_SHARED_LIBS to control how fdict is being built
  • Set and propagate the variables in fdictConfig.cmake using return(PROPAGATE) or set(PARENT_SCOPE)

having error in compiling siesta-master

I used cmake 27 (on ROCKY 8 OS) to compile siesta-master. All libraries were fetched from gitlab automatically by the code. I see following error:

[ 27%] Building Fortran object Src/easy-fdict/CMakeFiles/siesta-libfdict.dir/dictionary.f90.o
[ 27%] Linking Fortran static library libsiesta-libfdict.a
[ 27%] Built target siesta-libfdict
gmake: *** [Makefile:146: all] Error 2

my cmake command:
cmake -S. -B_build -DCMAKE_INSTALL_PREFIX=/home/reza/siesta_master -DWITH_DFTD3=OFF -DWITH_LIBXC=OFF -DWITH_FLOOK=OFF -DSIESTA_TOOLCHAIN=/home/reza/siesta-master/Config/cmake/toolchains/intel.cmake -DWITH_MPI=ON -DSCALAPACK_LIBRARY="-L/opt/intel_2020/compilers_and_libraries_2020.4.304/linux/mkl/lib/intel64 -lmkl_scalapack_lp64 -lmkl_blacs_intelmpi_lp64 -ldl -lm"

I used intel cluster studio 2020 on a SMP HP server with 44 real core.

my build command:
cmake --build _build -j 44

Any idea?
Thanks
Reza

Strongly typed dictionaries

Is it possible to do, e.g. what are minimum changes need to extect dictionary_t to make it strongly typed and give a compilation error if the wrong constructor, assign, contains interfaces are used.

Re-implement makefile script

The current makefile script is rather fragile (albeit easily customizable).

I wish to extend this to easier enable automatic installation.

Can't compile with ifort

Hi!
Sorry for that (maybe) stupid question but I'm trying to compile the library with ifort and I have no clue how. I've tried to do FC=intel and FC=ifort within the setup.make but without success. What am I doing wrong?

Thanks!

Using plain C preprocessor instead of fypp?

What is the main advantage of using fypp over the built-in preprocessor (can be enabled by renaming f90 -> F90)? It would be nice to reduce the dependencies required for the library user, especially those that can not be automated with FetchContent.

CI tools

Some useful tooling that could be implemented. Let me know if you want some help with any of these:

  • ReadTheDocs + sphinx: Documentation engine
  • Github Action: Replace travis: (e.g. ctest, packaging, release) #37
  • pre-commit: Enforce some style checks #37
  • ctest: Replace manual test programs
  • codecov: Report code coverage #37

Pointers to characters

Currently it is not possible to have pointers to character(len=*).
The problem with this is that the pointer should itself have the corresponding same length specification, otherwise a compiler error will be issued.

Clarify the api

It is not so clear what the api for the dictionary and variable are. Ideally there should be a table matching the C++/Python interface to the fortran one. Basic API that should be documented:

  • Constructor
  • Adding a kv pair. If it already exists error/throw
  • Assigning a value to a key. If it doesn't exist error/throw
  • Add or assign
  • Get value
  • Delete key (deleting pointer or not)
  • Delete dictionary (deleting pointer or not)
  • Pop key
  • Itteration
  • Get size
  • Check if key exist

Those are dictionary, but for variable, that does not have a clear C++/Python counterpart, so I'm not sure what needs to be documented.

Compilation error with CRAY compiler

Hello,

File variable.f90 won't compile when using the Cray Fortran compiler (version 14.0.2):

$ ftn --version
Cray Fortran : Version 14.0.2
$ make FC=ftn FC_SERIAL=ftn 
VPATH="." ./setup.sh --default
VPATH="." ./src/variable.sh
gfortran -E -P -x c  -I./src -I./src -I. ./src/variable_pp.F90 | sed -f ./src/filter.sed > variable.f90
ftn -c -o variable.o   variable.f90

pa1_1 = transfer(this%enc,pa1_1)
^                                
ftn-928 ftn: ERROR ASSOCIATD_VAR, File = variable.f90, Line = 1511, Column = 1 
  "PA1_1" is TYPE (PTA1) with a pointer component, so must not be referenced in an assignment statement in a pure subprogram.

pa1_2 = transfer(rhs%enc,pa1_2)
^                               
ftn-928 ftn: ERROR ASSOCIATD_VAR, File = variable.f90, Line = 1512, Column = 1 
  "PA1_2" is TYPE (PTA1) with a pointer component, so must not be referenced in an assignment statement in a pure subprogram.

ps0_1 = transfer(this%enc,ps0_1)
^                                
ftn-928 ftn: ERROR ASSOCIATD_VAR, File = variable.f90, Line = 1516, Column = 1 
  "PS0_1" is TYPE (PTS0) with a pointer component, so must not be referenced in an assignment statement in a pure subprogram.

[...]

    p = transfer(this%enc,p)
    ^                        
ftn-928 ftn: ERROR ASSOCIATD_L_C3, File = variable.f90, Line = 3297, Column = 5 
  "P" is TYPE (PT) with a pointer component, so must not be referenced in an assignment statement in a pure subprogram.

    p = transfer(this%enc,p)
    ^                        
ftn-928 ftn: ERROR ASSOCIATD_R_C3, File = variable.f90, Line = 3312, Column = 5 
  "P" is TYPE (PT) with a pointer component, so must not be referenced in an assignment statement in a pure subprogram.

ftn-214 ftn: LIMIT ASSOCIATD_R_C3, File = variable.f90, Line = 3312 
  The maximum number, 100, of fatal errors has been exceeded.
make: *** [smeka/Makefile.compiler:194: variable.o] Error 1

The explanation of the reported error is:

$ explain ftn-928

Error : "%s" is TYPE (%s) with a pointer component, so must not be referenced
in an assignment statement in a %s subprogram.

A constraint to PURE procedures, prohibits the following:

         In a pure subprogram any variable which is in common or accessed
         by host or use associate, is a dummy argument to a pure function, is
         a dummy argument with INTENT(IN) to a pure subroutine or an object that is
         storage associated with any such variable, shall not be used in the
         following context:

         As the expr of an assignment-stmt in which the variable is of a derived
         type if the derived type has a pointer component at any level of
         component selection.

By definition, an elemental subprogram is pure, unless IMPURE is specified,
so the above constraints also apply to dummy arguments and variables within
elemental subprograms as long as IMPURE is not specified for the subprogram.

I am not sure that the Cray Compiler is right about this one. While I agree on the marked variables satisfying the requirement stated in the fourth paragraph, variable this is not "the expr" but an argument to an intrinsic (and hence pure) transformational function, used "in the expr".

I read a few times the original constraint, C1594 of Fortran 2018, and my impression is the same.

Further to that, I tried a MWE (fails with Cray)

module m
  implicit none
  type :: t
    character(len=1), dimension(:), allocatable :: enc
  end type t
contains
  pure function a(this) result(r)
    type(t), intent(in) :: this
    logical :: r

    type :: pta1
      character(len=1), pointer :: p(:) => null()
    end type pta1
    type(pta1) :: q

    q = transfer(this%enc,q)
    r = .false.
  end function a
end module m

with the NAG Compiler 7.1 (whose strictness is the only comparable to Cray's) and it compiled without issues.

This prevents compilation of SIESTA on LUMI using the Cray Compiler. I guess it would be OK to conditionally comment out the PURE keyword as a workaround, while we clarify the issue with HPE?

Error linking the library to another project

I must say that I compiled and installed the library following the initial guidelines in the readme section of this repository:

  1. extracted and created a setup.make file using the minimal example with gfortran
    FC=gfortran FFLAGS = -g
  2. Created the library by typing make.
  3. Installed with make PREFIX=/path/to/fdict install

My fortran project, however, is compiled with ifort in a bash file as follows:

ifort -O3 -openmp -c -traceback *.f90 ifort -O3 -openmp -o project_name *.o

I tried modifying the bash file to link the library as follows:
ifort -O3 -openmp -c -I$"/path/to/include/" -traceback *.f90 ifort -O3 -openmp -o project_name *.o $"/path/to/lib/libfdict.a"

However I get this error: This module file was not generated by any release of this compiler. [DICTIONARY] use dictionary
The same error is shown for use variable.

P.S.: I know you recommended using the code below in a makefile to link the library to the program, but I do not understand how to do it. In what folder do I create this makefile? How does this interact with my program?
FDICT_PATH = /path/to/fdict/parent FDICT_LIBS = -L$(FDICT_PATH) -lfdict FDICT_INC = -I$(FDICT_PATH)

Thank you

How to implement in an example

Hi,
I do not have much experience with coding in Fortran, so I apologize in advance for the basic level question.

In my case, I have an input file that I read in a subroutine. Each line has this format: 'key1', 'value11', 'value12'. I need to read a new file of this type (being provided by an external program) a few times while the program runs. I would like to store the info from the file in a dictionary to use the key values later in a quick manner.

A subroutine is called to read the new file whenever needed. Now to deal with the dictionary part I have understood that I can either create a new dictionary every time I read the file or I can create it once and then just keep updating it (which is the case when I use pointers). Is the latter more computationally efficient?

Below is my attempt to create the dictionary in the same subroutine where I read the file.

subroutine ...

use dictionary
type(dict) :: dict_1
type(dict) :: dict_2

        open(file='input_file.dat', file = 30, status='old') ! 

        read(30,*)

        do j=1,no_of_lines
            read(30,*) key_string , value1, value2
            dict_1= dict_1// (key_string .kv. value1)
            dict_2= dict_2// (key_string .kv. value2)
        enddo

My doubts are regarding how to:
(1) create one dictionary instead of two to store the info?
(2) create pointers based on the key strings? (Can I easily convert the key_string from string to a variable to make it a pointer?)
(3) call a value from the key later on in the code?

Memory leak when overwriting entries from concat

The following snippet clarifies

type(dictionary_t) :: d

d = ('a' .kv. 1) // ('b' .kv. 2) ! no leak
d = d // ('a' .kv. 2) ! leak
d = d // ('c' .kv. 3) ! no leak

I have to see if this may be by passed in some way...

README.md clarification/enhancement

First off thank you for this project! It is EXACTLY what I wanted and much better than my homemade attempt.

I have figured out how to use assign/associate from your tests but would have greatly appreciated a small example of each in the README.md for dictionaries the same way you did for variables. I was confused the .key. and .value. operators instead which only work on dictionaries of one element.

And thank you again. Learned a lot studying this.

Dict of Dicts: Pass by copy functionality

First of all: awesome work!
A dict of a dict, in current implementation, seems to work flawlessly by reference (pointers). The problem in my use-case is that I need to create a new sub-dict and then assign to a main dict inside a subroutine.

subroutine (...)
(...)
new_dict = ( &
&    ('key1' .kv. 'value1') // &
&    ('key2' .kv. 'value2')  &
&)
main_dict = (new_entry .kvp. new_dict)
(...)
end subroutine (...)

That works in the main program but when in a subroutine or loop this simple don't work and I don't know why... my guess it's some variable is pointing to the variable new_dict then when the subroutine ends all data is thrown away since the new_dict variable is deallocated and now points to some garbage in memory.

There is a way to achieve automatic generation of dicts in current stage of development or a new function needs to be implemented?

Compilation on Mac OS X

Nice project !!

In order to compile on my Mac OS X 10.9.5 (gfortran 5.2) I add to replace cpp ---> fpp on line 17 of the Makefile.

Also, the free system command seems not to be present (on bash or zsh) on Mac OS, hence the memory tests will give the output

 Running with deallocation
sh: free: command not found

Finally, there was a small bug in dictionary_pp.F90: the lines 306 and 307 must be inverted, i.e.

    chash = ld%hash
    ld => this%first

becomes

    ld => this%first
    chash = ld%hash

Retrieving a double vs single errors out

One cannot retrieve a single precision value with a double precision.

It is not fully clear what should be the case for:

  1. Store integer, retrieve real
  2. Store integer, retrieve double
  3. Store real, retrieve double
  4. Store double, retrieve real

Should all work? Currently they don't, the type has to be explicitly correct.

CMake install

Thank you zerothi, for making this awesome library. This is exactly what I need for a project. Unfortunately, I'm new to both Fortran and CMake. I've reviewed as much as I can on CMake for Windows, but I'm struggling to install and link this library to my VS Code project. Please could you outline what you mean by the normal CMake procedure?

Thanks again!

Fails to build with `ninja-build`

Error given is that there are multiple rules for the same object. This error occurs when importing the project with FetchContent:

CMake Error:
  Running

   '/usr/bin/ninja' '-C' '/home/lecris/mpsd/Projects/octopus/cmake-build-debug' '-t' 'recompact'

  failed with:

   ninja: warning: phony target '_deps/fdict-build/src/fdict.fypp' names itself as an input; ignoring [-w phonycycle=warn]

  ninja: error: build.ninja:11776: multiple rules generate
  _deps/fdict-build/src/fdict.fypp

problem with install

Hello,
I am not sure if this is the right place but I am asking for help as I am stuck with final install process of fdict.
I am on a macOS 10.15 using zsh.
make has created a libfdict.a without any error. I have used the gfortran.make file provided in the arch-makes directory with optional flags and openmpi flag ON (default and debugging flags OFF).
Running install I am getting the following error message:

mkdir -p ~/FORT/fdict/include
mkdir -p ~/FORT/fdict/lib
mkdir -p ~/FORT/fdict/bin
install-sh -m 755 -t ~/FORT/fdict/lib libfdict.a
/bin/sh: install-sh: command not found
make: *** [smeka-install-lib] Error 127

Will you please help?
My best regards,
Tamoghna

Can't get it to work

Me again...
I'm trying to get this library to work since hours. I have to admit that I'm always having problems with external libraries.
Anyway, first of all I wanted to point out that building the library into a folder does not work. With
make PREFIX=fdict install
(when I want to build the library into the source folder) gives me the error:
mkdir -p fdict/include
mkdir -p fdict/lib
mkdir -p fdict/bin
install -pm 755 -t fdict/lib libfdict.a
install: cannot stat 'libfdict.a': No such file or directory
smeka/Makefile.install:16: recipe for target 'smeka-install-lib' failed
make: *** [smeka-install-lib] Error 1
I can build the library in the directory using make only. I tried to do to things from there

  1. copy all generated files to a folder. Copied the test_dict.f90 and the test_utls.f90 to a folder. Having the everything in a different location:
    test-fdict/
    |-lib/ <-- contains library files
    |-src/ <-- contains source files (.f90)
    dict.make <-- FOBOS make file
  2. Linked the entire folder fdict-master when compiling test_fdict.f90

Non of the above work (at least not with my FOBOS makefile). Could you help with this?

interface which to query contained type field

Currently which(var) returns which data-type var is. However, to compare one have to hardcode the data-type, which is error prone.

Instead it would be useful to query the type-field of a data-type directly:

type(variable_t) :: var
real(8) :: a
if ( which(a) == which(var) ) then
  ! now we know that the following will work
  call assign(a, var)
end if

Issue with printing entries of the dictionary.

Hello!
I wrote a small test program to create a dictionary. However, I am not able to print the dictionary or the key values in the dictionary.

This is the sample program

use dictionary implicit none type(dict) :: sample_dict1 integer :: nx = 101, ny = 201, nt = 10001 sample_dict1 = ('nx'.kv.nx) // ('ny'.kv.ny) // ('nt'.kv.nt) print *, sample_dict1

please provide a pkgconfig

Please provide a package config as part of the installation process.

here is a simple template

prefix=@prefix@
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
includedir=${prefix}/include
libdir=${exec_prefix}/lib

Name: fdict
Description: Fortran type-free variables and type-free dictionaries
Version: 0.6.0
URL: https://github.com/zerothi/fdict
Cflags: -I${includedir}
Libs: -L${libdir} -lfdict


Creating the dictionary from a read file

I have an input file that I read before creating a dictionary with its contents. Below is a sample of the input file:

3 > this is the number of lines following the header.
"key" "value1" "value2"
"2196_202_4" 15582.0 497
"2196_8038_4" 15582.0 498
"2248_207_4" 15582.0 499

I was trying to read the file and create a dictionary as follows:

type(dict) :: dict1
type(dict) :: dict2

real :: value11
integer :: value12
character :: key1
open(file='input.dat', unit = 30, status='old')
read(30,*) no_lines
read(30,*)
do j=1,no_lines
read(30,*) key1, value11, value12
dict1= dict1// (key1.kv.value11)
dict2= dict2// (key1.kv.value12)
enddo
close(30)
call print(dict1)

However the output I get from the 'print' command is just:
2 [s0] (2041543547)

Not sure what I am doing wrong. Any thoughts?

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.