118 subroutine construct (this, expand_size_)
119 class(matrixcache) :: this
121 integer,
optional,
intent(in) :: expand_size_
123 if (
present(expand_size_))
then
124 this % expand_size = expand_size_
129 this % max_capacity = this % expand_size
131 this % matrix_index = 1
134 allocate(this%matrix_arrays(this%matrix_index),stat=err)
135 call master_memory%track_memory(storage_size(this%matrix_arrays)/8,
size(this%matrix_arrays), err, &
136 'MATRIXCACHE::MATRIXARRAY')
138 call this % matrix_arrays(this % matrix_index) % construct(this % expand_size)
141 this % num_matrix_chunks = 1
146 write (stdout,
"('Matrix Cache::construct- arrays not allocated')")
147 stop
"Matrix Cache:: arrays not allocated"
151 this % constructed = .true.
156 subroutine insert_into_cache (this, i, j, coefficient)
157 class(matrixcache) :: this
158 integer,
intent(in) :: i, j
159 real(wp),
intent(in) :: coefficient
160 integer :: mat_id, local_index
163 this % n = this % n + 1
165 if (this % n > this % max_capacity)
then
166 call this % expand_array()
169 call this % get_local_mat(this % n, mat_id, local_index)
171 this % num_matrix_chunks = mat_id
172 this % matrix_arrays(mat_id) % ij(1, local_index) = i
173 this % matrix_arrays(mat_id) % ij(2, local_index) = j
174 this % matrix_arrays(mat_id) % coefficient(local_index) = coefficient
176 this % matrix_arrays(mat_id) % num_elems = this % matrix_arrays(mat_id) % num_elems + 1
181 subroutine get_local_mat (this, idx, mat_id, local_index)
182 class(matrixcache) :: this
183 integer,
intent(in) :: idx
184 integer,
intent(out) :: mat_id
185 integer,
intent(out) :: local_index
187 if (this % check_bounds(idx))
then
188 mat_id = (idx - 1) / this % expand_size + 1
193 local_index = idx - (mat_id - 1) * this % expand_size
199 subroutine get_from_cache (this, idx, i, j, coeff)
200 class(matrixcache) :: this
201 integer,
intent(in) :: idx
202 integer,
intent(out) :: i, j
203 real(wp),
intent(out) :: coeff
205 integer :: mat_id, local_index
207 if (this % check_bounds(idx))
then
208 call this % get_local_mat(idx, mat_id, local_index)
210 i = this % matrix_arrays(mat_id) % ij(1, local_index)
211 j = this % matrix_arrays(mat_id) % ij(2, local_index)
213 coeff = this % matrix_arrays(mat_id) % coefficient(local_index)
219 subroutine expand_array (this)
220 class(matrixcache) :: this
221 type(matrixarray) :: temp_matrix(this % num_matrix_chunks + 1)
222 integer :: new_num_mats, err
224 call this % check_constructed
227 temp_matrix(1:this % num_matrix_chunks) = this % matrix_arrays(1:this % num_matrix_chunks)
228 call master_memory % free_memory(storage_size(this % matrix_arrays)/8,
size(this % matrix_arrays))
229 deallocate(this % matrix_arrays)
231 this % max_capacity = this % max_capacity + this % expand_size
233 new_num_mats = this % max_capacity / this % expand_size
234 this % matrix_index = new_num_mats
235 this % num_matrix_chunks = this % num_matrix_chunks + 1
236 allocate(this % matrix_arrays(this % num_matrix_chunks), stat = err)
237 call master_memory % track_memory(storage_size(this % matrix_arrays)/8,
size(this % matrix_arrays), err, &
238 'MATRIXCACHE::MATRIXARRAY')
240 this % matrix_arrays(:) = temp_matrix(:)
241 this % matrix_arrays(this % num_matrix_chunks) % num_elems = 0
242 call this % matrix_arrays(this % num_matrix_chunks) % construct(this % expand_size)
248 subroutine destroy_matrix_array (this)
249 class(matrixarray) :: this
251 if (.not. this % constructed)
return
252 if (
associated(this % ij))
then
253 call master_memory % free_memory(storage_size(this % ij)/8,
size(this % ij))
254 deallocate(this % ij)
257 if (
associated(this % coefficient))
then
258 call master_memory % free_memory(storage_size(this % coefficient)/8,
size(this % coefficient))
259 deallocate(this % coefficient)
260 this % coefficient => null()
262 this % constructed = .false.
268 subroutine construct_array (this, capacity)
269 class(matrixarray) :: this
270 integer,
intent(in) :: capacity
273 if (.not. this % constructed)
then
274 call master_memory % track_memory(storage_size(this % ij)/8, capacity * 2, 0,
'MATRIXCACHE::MATRIXARRAY::IJ')
275 call master_memory % track_memory(storage_size(this % coefficient)/8, capacity, 0,
'MATRIXCACHE::MATRIXARRAY::COEFF')
276 allocate(this % ij(2, capacity), this % coefficient(capacity), stat = err)
277 this % constructed = .true.
291 subroutine insert_into_array (this, i, j, coeff)
292 class(matrixarray) :: this
293 integer,
intent(in) :: i, j
294 real(wp),
intent(in) :: coeff
296 this % num_elems = this % num_elems + 1
297 this % ij(this % num_elems, 1) = i
298 this % ij(this % num_elems, 2) = j
299 this % coefficient(this % num_elems) = coeff
304 subroutine get_from_array(this, idx, i, j, coeff)
305 class(matrixarray),
intent(in) :: this
306 integer,
intent(in) :: idx
307 integer,
intent(out) :: i, j
308 real(wp),
intent(out) :: coeff
310 if (idx > this % num_elems) stop
"Matrix Array access segfault!"
312 i = this % ij(1, idx)
313 j = this % ij(2, idx)
314 coeff = this % coefficient(idx)
372 subroutine shrink_capacity (this)
373 class(matrixcache) :: this
374 integer :: ido, total_size, shrink_size
376 type(matrixarray),
allocatable :: temp_matrix(:)
378 if (
allocated(this % matrix_arrays))
then
379 total_size =
size(this % matrix_arrays)
380 shrink_size = min(this % n / this % expand_size + 1, this % num_matrix_chunks)
382 if (shrink_size == this % num_matrix_chunks)
return
384 do ido = shrink_size + 1, total_size
385 call this % matrix_arrays(ido) % destroy
388 allocate(temp_matrix(shrink_size))
389 call master_memory % track_memory(storage_size(temp_matrix)/8,
size(temp_matrix), 0,
'MATRIXCACHE::SHRINK::TEMP')
390 temp_matrix(1:shrink_size) = this % matrix_arrays(1:shrink_size)
391 call master_memory % free_memory(storage_size(this % matrix_arrays)/8,
size(this % matrix_arrays))
392 deallocate(this % matrix_arrays)
394 allocate(this % matrix_arrays(shrink_size))
395 call master_memory % track_memory(storage_size(this % matrix_arrays)/8,
size(this % matrix_arrays), 0, &
396 'MATRIXCACHE::SHRINK::MATRIXARRAYS')
397 this % matrix_arrays(1:shrink_size) = temp_matrix(1:shrink_size)
398 this % max_capacity = shrink_size * this % expand_size
399 this % num_matrix_chunks = shrink_size
400 call master_memory % free_memory(storage_size(temp_matrix)/8,
size(temp_matrix))
401 deallocate(temp_matrix)
436 subroutine print_matelems (this)
437 class(matrixcache) :: this
438 integer :: labels(8), ido, arrs, jdo, elm
441 write (stdout,
"('Outputting Matrix elements....')")
443 this % matrix_index = this % n / this % expand_size + 1
446 do ido = 1, this % num_matrix_chunks
447 write (stdout, *) this % matrix_arrays(ido) % num_elems
448 do jdo = 1, this % matrix_arrays(ido) % num_elems
449 write (stdout,
"(2i8,' -- ',D16.8)") this % matrix_arrays(ido) % ij(1:2,jdo), &
450 this % matrix_arrays(ido) % coefficient(jdo)
468 recursive subroutine quick_sort_function (this, start_idx, end_idx)
469 class(matrixcache) :: this
470 integer,
intent(in) :: start_idx, end_idx
471 integer :: mat_size, iq
473 mat_size = end_idx - start_idx + 1
475 if (mat_size > 1)
then
476 call this % partition_function(iq, start_idx, end_idx)
477 call this % quick_sort_function(start_idx, iq - 1)
478 call this % quick_sort_function(iq, end_idx)
484 subroutine partition_function (this, marker, start_idx, end_idx)
485 class(matrixcache) :: this
486 integer,
intent(in) :: start_idx, end_idx
487 integer,
intent(out) :: marker
488 integer :: i, j, temp_ij(2), x_ij(2), A_ij(2), mat_id_i, mat_id_j, local_index_i, local_index_j
489 real(wp) :: temp_coeff, x_coeff, A_coeff
491 call this % get_from_cache(start_idx, x_ij(1), x_ij(2), x_coeff)
499 call this % get_from_cache(j, a_ij(1), a_ij(2), a_coeff)
500 if (a_ij(1) <= x_ij(1))
exit
505 call this % get_from_cache(i, a_ij(1), a_ij(2), a_coeff)
506 if (a_ij(1) >= x_ij(1))
exit
511 call this % get_local_mat(i, mat_id_i, local_index_i)
512 call this % get_local_mat(j, mat_id_j, local_index_j)
514 temp_ij(:) = this % matrix_arrays(mat_id_i) % ij(:,local_index_i)
515 temp_coeff = this % matrix_arrays(mat_id_i) % coefficient(local_index_i)
517 this % matrix_arrays(mat_id_i) % ij(:,local_index_i) &
518 = this % matrix_arrays(mat_id_j) % ij(:,local_index_j)
519 this % matrix_arrays(mat_id_i) % coefficient(local_index_i) &
520 = this % matrix_arrays(mat_id_j) % coefficient(local_index_j)
522 this % matrix_arrays(mat_id_j) % ij(:,local_index_j) = temp_ij(:)
523 this % matrix_arrays(mat_id_j) % coefficient(local_index_j) = temp_coeff
524 else if (i == j)
then