KMR
wordcountf.f90
1 ! Word Count (2015-05-29)
2 
3 ! It ranks the words by their occurrence count in the "LICENSE" file.
4 ! Copy the file in the current directory and run it.
5 
6 module wcfn
7 
8  implicit none
9 
10  !integer, target :: foobar
11 
12  !type :: tuple2
13  !integer :: a0, a1
14  !end type tuple2
15 
16  integer, parameter :: sizeoflong = 8
17  integer, parameter :: linewidth = 80
18  integer, parameter :: wordsize = 25
19 
20 contains
21 
22  function isalpha(c) result(zz)
23  use iso_c_binding
24  implicit none
25  character(kind=c_char), intent(in) :: c
26  logical :: zz
27  zz = ((ichar('a') <= ichar(c) .and. ichar(c) <= ichar('z')) &
28  .or. (ichar('A') <= ichar(c) .and. ichar(c) <= ichar('Z')))
29  end function isalpha
30 
31  function upcase(s) result(zz)
32  use iso_c_binding
33  implicit none
34  character(kind=c_char, len=*), intent(in) :: s
35  character(kind=c_char, len=len(s)) :: zz
36  integer :: n, i
37  character(*), parameter :: uc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
38  character(*), parameter :: lc = "abcdefghijklmnopqrstuvwxyz"
39  zz = s
40  do i = 1, len_trim(s)
41  n = index(lc, s(i:i))
42  if (n /= 0) zz(i:i) = uc(n:n)
43  end do
44  end function upcase
45 
46  integer(c_int) function read_words_from_a_file(kv, kvi, kvo, p, i) &
47  bind(c) result(zz)
48  use iso_c_binding
49  use kmrf
50  implicit none
51  type(kmr_kv_box), value, intent(in) :: kv
52  type(c_ptr), value, intent(in) :: kvi, kvo
53  type(c_ptr), value, intent(in) :: p
54  integer(c_long), value, intent(in) :: i
55 
56  type(kmr_kv_box) :: nkv
57  integer :: j, r
58 
59  character(kind=c_char, len=wordsize) :: b
60  character(len=linewidth) :: line
61  character(kind=c_char) :: cc
62  integer ios
63 
64  call kmr_assert(.not. c_associated(kvi) .and. kv%klen == 0 &
65  .and. kv%vlen == 0 .and. c_associated(kvo), &
66  "kvi == 0 && kv.klen == 0 && kv.vlen == 0 && kvo != 0")
67  open(17, file='LICENSE', status='old')
68  j = 0
69  do while (.true.)
70  call kmr_assert(j <= (wordsize - 1), "j <= (wordsize - 1)")
71  read(17, '(a)', iostat=ios) line
72  if (ios .lt. 0) exit
73  call kmr_assert(len(trim(line)) < linewidth, &
74  "len(trim(line)) < linewidth")
75  !!(Look at one more trailing char for flushing word at line end)
76  do r = 1, len(trim(line)) + 1
77  cc = line(r:r)
78  if ((ios .lt. 0 .or. .not. isalpha(cc) .or. (j == (wordsize - 1))) &
79  .and. j /= 0) then
80  b(j+1:) = c_null_char
81  nkv%klen = (j + 1)
82  nkv%k = kmr_strint(b)
83  nkv%vlen = sizeoflong
84  nkv%v = 1
85  zz = kmr_add_kv(kvo, nkv)
86  j = 0
87  end if
88  if (ios .lt. 0) exit
89  if (isalpha(cc)) then
90  b(j+1:) = cc
91  j = j + 1
92  end if
93  end do
94  end do
95  close(17)
96  zz = 0
97  end function read_words_from_a_file
98 
99  integer(c_int) function print_top_five(kv, kvi, kvo, p, i) &
100  bind(c) result(zz)
101  use iso_c_binding
102  use kmrf
103  implicit none
104  type(kmr_kv_box), value, intent(in) :: kv
105  type(c_ptr), value, intent(in) :: kvi, kvo
106  type(c_ptr), value, intent(in) :: p
107  integer(c_long), value, intent(in) :: i
108 
109  integer :: rank
110  integer(c_int) :: n
111  character(kind=c_char, len=kv%vlen), target :: v
112 
113  rank = kmr_get_rank(kvi);
114  if (rank == 0 .and. i < 5) then
115  n = kmr_intstr(kv%v, v, kv%vlen)
116  print "(A,A,A,I0)", "#", v(1:kv%vlen-1), "=", (0 - kv%k)
117  end if
118  zz = 0
119  end function print_top_five
120 
121  integer(c_int) function sum_counts_for_a_word(kv, n, kvi, kvo, p) &
122  bind(c) result(zz)
123  use iso_c_binding
124  use kmrf
125  implicit none
126  type(kmr_kv_box), intent(in) :: kv(*)
127  integer(c_long), value, intent(in) :: n
128  type(c_ptr), value, intent(in) :: kvi, kvo
129  type(c_ptr), value, intent(in) :: p
130 
131  integer(c_long) :: i
132  integer(c_long) :: c
133  type(kmr_kv_box) :: nkv
134 
135  c = 0
136  do i = 1, n
137  c = c + kv(i)%v
138  end do
139 
140  nkv%klen = kv(1)%klen
141  nkv%k = kv(1)%k
142  nkv%vlen = sizeoflong
143  nkv%v = -c
144  zz = kmr_add_kv(kvo, nkv)
145  end function sum_counts_for_a_word
146 
147 end module wcfn
148 
149 program main
150  use iso_c_binding
151  use kmrf
152  use wcfn
153  implicit none
154  include "mpif.h"
155 
156  type(c_ptr) :: mr
157  type(c_ptr) :: kvs0, kvs1, kvs2, kvs3, kvs4
158  integer :: nprocs, rank, thlv
159  integer :: ierr
160 
161  call mpi_init_thread(mpi_thread_serialized, thlv, ierr)
162  call mpi_comm_size(mpi_comm_world, nprocs, ierr)
163  call mpi_comm_rank(mpi_comm_world, rank, ierr)
164  ierr = kmr_init()
165  mr = kmr_create_context(mpi_comm_world, mpi_info_null)
166 
167  call mpi_barrier(mpi_comm_world, ierr)
168  if (rank == 0) print "(A)", "Ranking words..."
169 
170  kvs0 = kmr_create_kvs(mr, kmr_kv_opaque, kmr_kv_integer)
171  ierr = kmr_map_once(kvs0, c_null_ptr, 0, .false., read_words_from_a_file)
172 
173  kvs1 = kmr_create_kvs(mr, kmr_kv_opaque, kmr_kv_integer)
174  ierr = kmr_shuffle(kvs0, kvs1, 0)
175 
176  kvs2 = kmr_create_kvs(mr, kmr_kv_opaque, kmr_kv_integer)
177  ierr = kmr_reduce(kvs1, kvs2, c_null_ptr, 0, sum_counts_for_a_word)
178 
179  kvs3 = kmr_create_kvs(mr, kmr_kv_integer, kmr_kv_opaque)
180  ierr = kmr_reverse(kvs2, kvs3, 0)
181 
182  kvs4 = kmr_create_kvs(mr, kmr_kv_integer, kmr_kv_opaque)
183  ierr = kmr_sort(kvs3, kvs4, 0)
184 
185  ierr = kmr_map(kvs4, c_null_ptr, c_null_ptr, 0, print_top_five)
186 
187  ierr = kmr_free_context(mr)
188  ierr = kmr_fin()
189  call mpi_finalize()
190 end program main
#define kmr_reduce(KVI, KVO, ARG, OPT, R)
Reduces key-value pairs.
Definition: kmr.h:88
Converts in reverse of kmr_strint().
Definition: kmrf.F90:186
int kmr_map_once(KMR_KVS *kvo, void *arg, struct kmr_option opt, _Bool rank_zero_only, kmr_mapfn_t m)
Maps once.
Definition: kmrbase.c:1402
#define kmr_create_kvs(MR, KF, VF)
Makes a new key-value stream (of type KMR_KVS) with the specified field datatypes.
Definition: kmr.h:71
int kmr_shuffle(KMR_KVS *kvi, KMR_KVS *kvo, struct kmr_option opt)
Shuffles key-value pairs to the appropriate destination ranks.
Definition: kmrbase.c:2036
(See kmr_free_context() in C).
Definition: kmrf.F90:293
(See kmr_add_kv() in C).
Definition: kmrf.F90:339
(See kmr_fin() in C).
Definition: kmrf.F90:273
Gets MPI rank from a key-value stream.
Definition: kmrf.F90:210
#define kmr_map(KVI, KVO, ARG, OPT, M)
Maps simply.
Definition: kmr.h:82
Handy Copy of a Key-Value Field.
Definition: kmr.h:358
#define kmr_init()
Sets up the environment.
Definition: kmr.h:747
int kmr_sort(KMR_KVS *kvi, KMR_KVS *kvo, struct kmr_option opt)
Sorts a key-value stream globally.
Definition: kmrmoreops.c:575
Converts a character array to a (pointer value) integer for key/value (it is casting in C)...
Definition: kmrf.F90:174
int kmr_reverse(KMR_KVS *kvi, KMR_KVS *kvo, struct kmr_option opt)
Makes a new pair by swapping the key and the value in each pair.
Definition: kmrmoreops.c:159
KMR * kmr_create_context(const MPI_Comm comm, const MPI_Info conf, const char *name)
Makes a new KMR context (a context has type KMR).
Definition: kmrbase.c:147