Visualize 2D and 3D shapes in code using templates [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
I remember a library (a single header I think) based on templates and operators overloading that allowed to visualize 2D and 3D shapes in code, with expressions like:
assert( (I-----o
| |
o-----I).area() == (I---o
| |
| |
o---I).area() );
And even more complicated stuff for 3D shapes.
I had a link to this library but can't find the link... (I may have bookmarked it, but can't find the bookmark).
Google is not much helpful either, at least not with my search keywords.
Anybody knows what I'm talking about?

Thanks to Story Teller, the link is:
http://www.eelis.net/C++/analogliterals.xhtml
With a fork here:
https://github.com/Quuxplusone/analog-literals
Some actual code examples:
unsigned int c = ( o-----o
| !
! !
! !
o-----o ).area;
assert( c == (I-----I) * (I-------I) );
assert( ( o-----o
| !
! !
! !
! !
o-----o ).area == ( o---------o
| !
! !
o---------o ).area );
And with 3D shapes:
assert( top( o-------o
|L \
| L \
| o-------o
| ! !
! ! !
o | !
L | !
L| !
o-------o ) == ( o-------o
| !
! !
o-------o ) );
assert( ( o-------------o
|L \
| L \
| L \
| o-------------o
| ! !
! ! !
o | !
L | !
L | !
L| !
o-------------o ).volume == ( o-------------o
| !
! !
! !
o-------------o ).area
* int(I-------------I) );
And it is mentioned in other SO posts, added in comments to the question.

Related

How to print the following pattern by using while-loops in python?

How can I print the following pattern using while loops in python?
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
\ \ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! / /
\ \ \ \ ! ! ! ! ! ! ! ! ! ! ! ! ! ! / / / /
\ \ \ \ \ \ ! ! ! ! ! ! ! ! ! ! / / / / / /
\ \ \ \ \ \ \ \ ! ! ! ! ! ! / / / / / / / /
\ \ \ \ \ \ \ \ \ \ ! ! / / / / / / / / / /
Any help would be really appreciated. Thank you.
This may also be solved using for loop but since the question explicitly mentioned while loop:
total = 22
n = 0
while n < 6:
side = n*2
middle = total - side*2
line = '\\'*side + '!'*middle + '/'*side
print(line)
n += 1
Let me know if anything needs explanation.
there are two easy ways to do this
while True:
print '! '*22
print '\ '*2+'! '*18+'/ '*2
print '\ '*4+'! '*14+'/ '*4
print '\ '*6+'! '*10+'/ '*6
print '\ '*8+'! '*6+'/ '*8
print '\ '*10+'! '*2+'/ '*10
break
or maybe
x=0
while x<6:
print '\ '*(2*x)+'! '*(22-(4*x))+'/ '*(2*x)
x+=1
Try this:
ExcCount = 22
SlashCount = 2
i = 1
while i <= 6:
String = (SlashCount * "\ ") + (ExcCount * "! ") + (SlashCount * "/ ")
print(String)
ExcCount -= 4
SlashCount -= 2
i += 1

Calling a subroutine, crashes the program, matrix passing

I was writing code to use Fortran Eispack routines (compute eigenvalues and eigenvectors, just to check if the values would be different from the ones I got from Matlab), but every time it calls the qzhes subroutine the program hangs.
I load matrixes from files.
Tried commenting the call, and it works without an issue.
I just learned Fortran, and with the help of the internet I wrote this code (which compiles and run):
program qz
IMPLICIT NONE
INTEGER:: divm, i, divg
INTEGER(kind=4) :: dimen
LOGICAL :: matz
REAL(kind = 8), DIMENSION(:,:), ALLOCATABLE:: ma
REAL(kind = 8), DIMENSION(:), ALLOCATABLE:: tabm
REAL(kind = 8), DIMENSION(:,:), ALLOCATABLE:: ga
REAL(kind = 8), DIMENSION(:), ALLOCATABLE:: tabg
REAL(kind = 8), DIMENSION(:,:), ALLOCATABLE:: zet
divm = 1
divg = 2
dimen = 20
matz = .TRUE.
ALLOCATE(ma(1:dimen,1:dimen))
ALLOCATE(tabm(1:dimen))
ALLOCATE(ga(1:dimen,1:dimen))
ALLOCATE(tabg(1:dimen))
OPEN(divm, FILE='Em.txt')
DO i=1,dimen
READ (divm,*) tabm
ma(1:dimen,i)=tabm
END DO
CLOSE(divm)
OPEN(divg, FILE='Gje.txt')
DO i=1,dimen
READ (divg,*) tabg
ga(1:dimen,i)=tabg
END DO
CLOSE(divg)
call qzhes(dimen, ma, ga, matz, zet)
OPEN(divm, FILE='Em2.txt')
DO i=1,dimen
tabm = ma(1:dimen,i)
WRITE (divm,*) tabm
END DO
CLOSE(divm)
OPEN(divg, FILE='Gje2.txt')
DO i=1,dimen
tabg = ga(1:dimen,i)
WRITE (divg,*) tabg
END DO
CLOSE(divg)
end program qz
...//EISPACK subrotines//...
Matrixes:
Gje.txt:https://drive.google.com/file/d/0BxH3QOkswLy_c2hmTGpGVUI3NzQ/view?usp=sharing
Em.txt:https://drive.google.com/file/d/0BxH3QOkswLy_OEtJUGQwN3ZXX2M/view?usp=sharing
Edit:
subroutine qzhes ( n, a, b, matz, z )
!*****************************************************************************80
!
!! QZHES carries out transformations for a generalized eigenvalue problem.
!
! Discussion:
!
! This subroutine is the first step of the QZ algorithm
! for solving generalized matrix eigenvalue problems.
!
! This subroutine accepts a pair of real general matrices and
! reduces one of them to upper Hessenberg form and the other
! to upper triangular form using orthogonal transformations.
! it is usually followed by QZIT, QZVAL and, possibly, QZVEC.
!
! Licensing:
!
! This code is distributed under the GNU LGPL license.
!
! Modified:
!
! 18 October 2009
!
! Author:
!
! Original FORTRAN77 version by Smith, Boyle, Dongarra, Garbow, Ikebe,
! Klema, Moler.
! FORTRAN90 version by John Burkardt.
!
! Reference:
!
! James Wilkinson, Christian Reinsch,
! Handbook for Automatic Computation,
! Volume II, Linear Algebra, Part 2,
! Springer, 1971,
! ISBN: 0387054146,
! LC: QA251.W67.
!
! Brian Smith, James Boyle, Jack Dongarra, Burton Garbow,
! Yasuhiko Ikebe, Virginia Klema, Cleve Moler,
! Matrix Eigensystem Routines, EISPACK Guide,
! Lecture Notes in Computer Science, Volume 6,
! Springer Verlag, 1976,
! ISBN13: 978-3540075462,
! LC: QA193.M37.
!
! Parameters:
!
! Input, integer ( kind = 4 ) N, the order of the matrices.
!
! Input/output, real ( kind = 8 ) A(N,N). On input, the first real general
! matrix. On output, A has been reduced to upper Hessenberg form. The
! elements below the first subdiagonal have been set to zero.
!
! Input/output, real ( kind = 8 ) B(N,N). On input, a real general matrix.
! On output, B has been reduced to upper triangular form. The elements
! below the main diagonal have been set to zero.
!
! Input, logical MATZ, should be TRUE if the right hand transformations
! are to be accumulated for later use in computing eigenvectors.
!
! Output, real ( kind = 8 ) Z(N,N), contains the product of the right hand
! transformations if MATZ is TRUE.
!
implicit none
integer ( kind = 4 ) n
real ( kind = 8 ) a(n,n)
real ( kind = 8 ) b(n,n)
integer ( kind = 4 ) i
integer ( kind = 4 ) j
integer ( kind = 4 ) k
integer ( kind = 4 ) l
integer ( kind = 4 ) l1
integer ( kind = 4 ) lb
logical matz
integer ( kind = 4 ) nk1
integer ( kind = 4 ) nm1
real ( kind = 8 ) r
real ( kind = 8 ) rho
real ( kind = 8 ) s
real ( kind = 8 ) t
real ( kind = 8 ) u1
real ( kind = 8 ) u2
real ( kind = 8 ) v1
real ( kind = 8 ) v2
real ( kind = 8 ) z(n,n)
!
! Set Z to the identity matrix.
!
if ( matz ) then
z(1:n,1:n) = 0.0D+00
do i = 1, n
z(i,i) = 1.0D+00
end do
end if
!
! Reduce B to upper triangular form.
!
if ( n <= 1 ) then
return
end if
nm1 = n - 1
do l = 1, n - 1
l1 = l + 1
s = sum ( abs ( b(l+1:n,l) ) )
if ( s /= 0.0D+00 ) then
s = s + abs ( b(l,l) )
b(l:n,l) = b(l:n,l) / s
r = sqrt ( sum ( b(l:n,l)**2 ) )
r = sign ( r, b(l,l) )
b(l,l) = b(l,l) + r
rho = r * b(l,l)
do j = l + 1, n
t = dot_product ( b(l:n,l), b(l:n,j) )
b(l:n,j) = b(l:n,j) - t * b(l:n,l) / rho
end do
do j = 1, n
t = dot_product ( b(l:n,l), a(l:n,j) )
a(l:n,j) = a(l:n,j) - t * b(l:n,l) / rho
end do
b(l,l) = - s * r
b(l+1:n,l) = 0.0D+00
end if
end do
!
! Reduce A to upper Hessenberg form, while keeping B triangular.
!
if ( n == 2 ) then
return
end if
do k = 1, n - 2
nk1 = nm1 - k
do lb = 1, nk1
l = n - lb
l1 = l + 1
!
! Zero A(l+1,k).
!
s = abs ( a(l,k) ) + abs ( a(l1,k) )
if ( s /= 0.0D+00 ) then
u1 = a(l,k) / s
u2 = a(l1,k) / s
r = sign ( sqrt ( u1**2 + u2**2 ), u1 )
v1 = - ( u1 + r) / r
v2 = - u2 / r
u2 = v2 / v1
do j = k, n
t = a(l,j) + u2 * a(l1,j)
a(l,j) = a(l,j) + t * v1
a(l1,j) = a(l1,j) + t * v2
end do
a(l1,k) = 0.0D+00
do j = l, n
t = b(l,j) + u2 * b(l1,j)
b(l,j) = b(l,j) + t * v1
b(l1,j) = b(l1,j) + t * v2
end do
!
! Zero B(l+1,l).
!
s = abs ( b(l1,l1) ) + abs ( b(l1,l) )
if ( s /= 0.0 ) then
u1 = b(l1,l1) / s
u2 = b(l1,l) / s
r = sign ( sqrt ( u1**2 + u2**2 ), u1 )
v1 = -( u1 + r ) / r
v2 = -u2 / r
u2 = v2 / v1
do i = 1, l1
t = b(i,l1) + u2 * b(i,l)
b(i,l1) = b(i,l1) + t * v1
b(i,l) = b(i,l) + t * v2
end do
b(l1,l) = 0.0D+00
do i = 1, n
t = a(i,l1) + u2 * a(i,l)
a(i,l1) = a(i,l1) + t * v1
a(i,l) = a(i,l) + t * v2
end do
if ( matz ) then
do i = 1, n
t = z(i,l1) + u2 * z(i,l)
z(i,l1) = z(i,l1) + t * v1
z(i,l) = z(i,l) + t * v2
end do
end if
end if
end if
end do
end do
return
end
I would expand the allocation Process
integer :: status1, status2, status3, status4, status5
! check the allocation, returnvalue 0 means ok
ALLOCATE(ma(1:dimen,1:dimen), stat=status1)
ALLOCATE(tabm(1:dimen), stat=status2)
ALLOCATE(ga(1:dimen,1:dimen), stat=status3)
ALLOCATE(tabg(1:dimen), stat=status4)
ALLOCATE(zet(1:dimen,1:dimen), stat=status5)
And at the end of the Program deallocate all arrays, because, you maybe have no memoryleak now, but if you put this program into a subroutine and use it several time with big matricies during a programrun, the program could leak some serious memory.
....
DO i=1,dimen
tabg = ga(1:dimen,i)
WRITE (divg,*) tabg
END DO
CLOSE(divg)
DEALLOCATE(ma, stat=status1)
DEALLOCATE(tabm, stat=status2)
DEALLOCATE(ga, stat=status3)
DEALLOCATE(tabg, stat=status4)
DEALLOCATE(zet, stat=status5)
You can check again with the status integer, if the deallocation was ok, returnvalue again 0.

decodebin2 data internal error inside videomixer

I'm trying to create an image vector with Gstreamer. To do that I use the videomixer gref like that :
gst-launch -e \videomixer name = mixer \
sink_0::xpos = 0 sink_0::ypos = 0 \
sink_1::xpos = 100 sink_1::ypos = 0 \
sink_2::xpos = 200 sink_2::ypos = 0 \
sink_3::xpos = 300 sink_3::ypos = 0 \
sink_4::xpos = 400 sink_4::ypos = 0 \
sink_5::xpos = 500 sink_5::ypos = 0 \
sink_6::xpos = 600 sink_6::ypos = 0 \
sink_7::xpos = 700 sink_7::ypos = 0 \
sink_8::xpos = 0 sink_8::ypos = 0 \
! xvimagesink \
filesrc location = 0.jpg \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_0. \
filesrc location = 1.jpeg \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_1. \
filesrc location = 2.png \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_2. \
filesrc location = 3.png \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_3. \
filesrc location = 4.png \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_4. \
filesrc location = 5.png \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_5. \
filesrc location = 6.JPG \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_6. \
filesrc location = 7.png \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! videoscale method = 1 ! video/x-raw-yuv, width = 100, height = 100 ! mixer.sink_7. \
filesrc location = bg.jpg \
! decodebin2 ! ffmpegcolorspace \
! imagefreeze ! mixer.sink_8.
But I've a problem, it's seems to work with only several type of image (very often with .png, but not with .jpg for example). I d'ont understand, decodebin is supposed to be independant of the file format, isn't it ?
I tried to put the same png file for each element of the vector and it's ok, so what's wrong ? I've the following error : "Data stream internal error".
Do you have an idea ?
Thanks !
(Sorry about my english, I'm french)
firstly which gstreamer version are you using? (0.10 or 1.0).
If you use 0.10, I recommand you to use videomixer2.
videomixer is very sensitive about the input format, so I recommande you to add in each input pad of videomixer a specific format in your caps something like that
"video/x-raw-yuv, format=(fourcc)AYUV, width=100, height=100"
If you don't have a transparency PNG I will advice to use this one:
"video/x-raw-yuv, format=(fourcc)I420, width=100, height=100"
It's should be works

how to call a Fortran90 function included in a module in c++ code?

I m including a fortran90 program that is not mine in my C++ project .
In the first stept I try to call the function by their name_() and i get the error "undefined reference to mp_mpi_cartesian_init_ "by dispalying the symbol of the obj file (using nm) i found that the function are called by their module as module_function_ so i add the module name and i Get the same problem but between fortran obj such as "Constants.f90:(.text+0x36): undefined reference to __powi4i4"
here is the c++ code :
#include <iostream>
#include <complex>
using namespace std;
extern"C" {
void mod_save_wave_mp_read_it_psi_(int * it,complex<double>* psi_E1E2 );
void mod_mpi_cartesian_mp_mpi_cartesian_init_( );
extern int mod_mpl_h_mp_iproc_ ;
}
int main(){
complex<double> psi_local[512*24*512*24];
int it ;
mod_mpi_cartesian_mp_mpi_cartesian_init_();
cout << "proc :" << mod_mpl_h_mp_iproc_ << "avant lecture\n";
mod_save_wave_mp_read_it_psi_(&it,psi_local);
cout << "psi ="<< psi_local[0] << "poiur le proc "<<mod_mpl_h_mp_iproc_ <<"\n";
}
and this is an exemple of a module :
MODULE mod_save_wave
USE mod_constants
USE mod_MPI_CARTESIAN
USE mod_time_mesure, ONLY : tempsEcoule
USE mod_input_data, ONLY : Nt_laserPsansLaser
USE mod_input_data, ONLY : n_phi, n_rho1_seg, n_rho2_seg
USE mod_input_data, ONLY : Nt_periode, save_periodique
!////////////////////////////////////////////////////////////////
IMPLICIT NONE !
REAL(kind=d_t) :: prog_start_time, time_max_second !
character(len=80) :: IntermedWaveDir
!================================================================
CONTAINS
SUBROUTINE begin_count_time()
IMPLICIT NONE
prog_start_time = tempsEcoule() !
END SUBROUTINE begin_count_time
SUBROUTINE READ_IT_PSI( it, psi_E1E2 )
IMPLICIT NONE
!////////////////////////////////////////////////////////////////////////////////
INTEGER :: it !
COMPLEX(kind=d_t), DIMENSION(n_phi,n_rho1_seg,n_phi,n_rho2_seg) :: psi_E1E2 !
!================================================================================
integer :: c
do c = 0, c_max-1
if( mod(iproc,c_max)==c ) then
!////////////////////////////////////////////////////////////////////////////////
OPEN( unit=11,file=concat(trim(IntermedWaveDir),concat(concat('BACK/wave_',str_iproc),'_2p2p2')),&
status='old', form='unformatted', MODE='READ' )
READ(11) it !
READ(11) psi_E1E2 !
CLOSE(11) !
print*,'iproc,readed it=',iproc, it
endif
CALL MPI_BARRIER(MPI_COMM_WORLD,infompi) !
!================================================================================
enddo
!================================================================================
END SUBROUTINE READ_IT_PSI
SUBROUTINE WRITE_IT_PSI( it, psi_E1E2 )
IMPLICIT NONE
!////////////////////////////////////////////////////////////////////////////////
INTEGER :: it !
COMPLEX(kind=d_t), DIMENSION(n_phi,n_rho1_seg,n_phi,n_rho2_seg) :: psi_E1E2 !
!================================================================================
integer :: c
do c = 0, c_max-1
if( mod(iproc,c_max)==c ) then
!////////////////////////////////////////////////////////////////////////////////
OPEN( unit=11,file=concat(trim(IntermedWaveDir),concat(concat('wave_',str_iproc),'_2p2p2')),&
form='unformatted') !
WRITE(11) it+1 !---- recommence a partir de la prochaine iterat!
write(11) psi_E1E2 !
CLOSE(11) !
endif
CALL MPI_BARRIER(MPI_COMM_WORLD,infompi) !
!================================================================================
enddo
END SUBROUTINE WRITE_IT_PSI
END MODULE mod_save_wave
I am assuming you are using the g++, gfortran, mpif90 toolchain. If you have a module
module rocker
contains
subroutine bye_baby
...
end subroutine
The external C declaration for it in C++ is
extern "C"
{
// ,-- 2 Leading underscores to start
// | ,-- then the module name
// | | ,-- then _MOD_
// | | | ,-- then the subroutine name
// V V V V
extern void __rocker_MOD_bye_baby();
}
You may also need to add attribute((stdcall)) after the extern. By default, C assumes cdecl which stacks the parameters differently.
If you do not want the __rocker_MOD part, then the subroutine/function should not be declared in a module.
First of all, on the Fortran side I strongly suggest to use the Fortran 2003 features of C-bindings, and especially the iso_c_binding module. You can see many examples for that on SO, among others this post. Then you get rid of the "how does my fortran compiler name my procedures" problem in a transparent and compiler independent way.
The linking problem arrises as you are missing some libraries of your Fortran compiler I guess. You either can try to link your object file using the Fortran compiler, or find out which library is missing and link it manually. Some Fortran compiler have also options for creating a library with automatical linking of compiler related libraries.

HDF5 for data files written with fortran

The HDF5 data storage uses the C convention, i.e. if I am storing a matrix A(N,M,K) in a binary file, the fastest changing dimension of the stored data will have size N. Apparently when I use the Fortran wrapper of HDF5, HDF5 automatically transposes the matrix, to be consistent with C.
I have a data of size (256 by 128 by 256) stored in an unformatted binary file written by fortran. I am trying to convert it into h5 format by using a program given below. But the final output is giving me the dimensions of the stored matrix as (128,256,256). I have no idea what to do to make sure that the final hd5 file can be rightly visualized in the visualizing software (Paraview).
PROGRAM H5_RDWT
USE HDF5 ! This module contains all necessary modules
IMPLICIT NONE
CHARACTER(LEN=6), parameter :: out_file = "out.h5" ! File name
CHARACTER(LEN=6), parameter :: in_file = "in.dat" ! File name
CHARACTER(LEN=4), parameter :: dsetname = "vort"! Dataset name
CHARACTER(LEN=50) :: len
INTEGER(HID_T) :: in_file_id ! File identifier
INTEGER(HID_T) :: out_file_id ! File identifier
INTEGER(HID_T) :: dset_id ! Dataset identifier
INTEGER(HID_T) :: dspace_id ! Dataspace identifier
INTEGER :: in_file_id = 23
INTEGER :: nx = 256, ny=128, nz=256
INTEGER(HSIZE_T), DIMENSION(3) :: dims ! Dataset dimensions
INTEGER :: rank = 3 ! Dataset rank
INTEGER :: error ! Error flag
INTEGER :: i, j, k, ii, jj, kk ! Indices
REAL, allocatable :: buff_r(:,:,:) ! buffer for reading from input file
dims(1) = nx
dims(2) = ny
dims(3) = nz
allocate(buff_r(nx,ny,nz))
! Read the input data.
open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*nx*ny*nz)
read (in_file_id,rec=1) buff_r
! Initialize FORTRAN interface of HDF5.
CALL h5open_f(error)
! Create a new file.
CALL h5fcreate_f (out_file, H5F_ACC_TRUNC_F, out_file_id, error)
! Create the dataspace.
CALL h5screate_simple_f(rank, dims, dspace_id, error)
! Create the dataset with default properties.
CALL h5dcreate_f(out_file_id, dsetname, H5T_NATIVE_REAL, dspace_id, &
dset_id, error)
! Write the dataset.
CALL h5dwrite_f(dset_id, H5T_NATIVE_REAL, buff_r, dims, error)
! End access to the dataset and release resources used by it.
CALL h5dclose_f(dset_id, error)
! Terminate access to the data space.
CALL h5sclose_f(dspace_id, error)
! Close the file.
CALL h5fclose_f(out_file_id, error)
! Close FORTRAN interface.
CALL h5close_f(error)
deallocate(buff_r)
END PROGRAM H5_RDWT
To illustrate what is happening, I am generating a sample data file using the following script:
program main
!-------- initialize variables -------------
character(8) :: fname
integer, parameter:: n = 32
real*8, dimension(n,n,2*n) :: re
integer i,j,k, recl
Inquire( iolength = recl ) re
!------ fill in the array with sample data ----
do k = 1, 2*n
do j = 1, n
do i = 1, n
re(i,j,k) = 1.0
end do
end do
end do
!------ write in data in a file -----------
write(fname, "(A)") "data.dat"
open (10, file=fname, form='unformatted', access='direct', recl=recl)
write(10,rec=1) re
close(10)
stop
end program main
I copy pasted the program by Ian Bush and changed the values of nx, ny and nz to 32, 32 and 64 respectively. I would expect the generated h5 file to have dimensions (32,32,64). But it is coming out to be (64,32,32). Here is what is happening in my machine:
[pradeep#laptop]$gfortran generate_data.f90
[pradeep#laptop]$./a.out
[pradeep#laptop]$ls -l data.dat
-rw-r--r-- 1 pradeep staff 524288 Mar 12 14:04 data.dat
[pradeep#laptop]$h5fc convert_to_h5.f90
[pradeep#laptop]$./a.out
[pradeep#laptop]$ls -l out.h5
-rw-r--r-- 1 pradeep staff 526432 Mar 12 14:05 out.h5
[pradeep#laptop]$h5dump -H out.h5
HDF5 "out.h5" {
GROUP "/" {
DATASET "data" {
DATATYPE H5T_IEEE_F64LE
DATASPACE SIMPLE { ( 64, 32, 32 ) / ( 64, 32, 32 ) }
}
}
}
Please confirm with me if you are seeing the same thing.
I have also run into trouble with viewing HDF5 files that I've written with a Fortran application. The basic issue is that Fortran and C store multidimensional arrays differently (Fortran is column-major, C is row-major), and since the Fortran HDF5 libraries are interfaces into the C HDF5 libraries, the Fortran wrapper transposes the dimensions before passing the data into the C code. Likewise, when a Fortran application reads an HDF5 file, the Fortran wrapper transposes the dimensions again.
So if you do all your writing and reading with Fortran applications, you shouldn't notice any discrepancies. If you write the file with a Fortran app and then read it with a C app (such as h5dump), the dimensions will appear transposed. That's not a bug, it's just how it works.
If you want to display the data correctly, either read the data with a Fortran application or use a C app and transpose the data first. (Or you could transpose the data before writing it in the first place.)
As already mentioned, this is all explained fairly well in section 7.3.2.5 of the documentation: http://www.hdfgroup.org/HDF5/doc/UG/UG_frame12Dataspaces.html
Long comment really rather than an answer ...
Can you clarify why you don't think it is working? Once I correct a couple of things in your code
1) in_file_id is declared twice with 2 different kinds
2) Recl for direct access files are not necessarily in terms of bytes - Inquire by output list is much more portable
I get the following which, having generated a dummy file with random data, seems to work:
ian#ian-pc:~/test/stack$ cat hdf5.f90
PROGRAM H5_RDWT
USE HDF5 ! This module contains all necessary modules
IMPLICIT NONE
CHARACTER(LEN=6), parameter :: out_file = "out.h5" ! File name
CHARACTER(LEN=6), parameter :: in_file = "in.dat" ! File name
CHARACTER(LEN=4), parameter :: dsetname = "vort"! Dataset name
CHARACTER(LEN=50) :: len
!!$ INTEGER(HID_T) :: in_file_id ! File identifier
INTEGER(HID_T) :: out_file_id ! File identifier
INTEGER(HID_T) :: dset_id ! Dataset identifier
INTEGER(HID_T) :: dspace_id ! Dataspace identifier
INTEGER(HID_T) :: in_file_id = 23
INTEGER :: nx = 256, ny=128, nz=256
INTEGER(HSIZE_T), DIMENSION(3) :: dims ! Dataset dimensions
INTEGER :: rank = 3 ! Dataset rank
Integer :: recl
INTEGER :: error ! Error flag
INTEGER :: i, j, k, ii, jj, kk ! Indices
REAL, allocatable :: buff_r(:,:,:) ! buffer for reading from input file
dims(1) = nx
dims(2) = ny
dims(3) = nz
allocate(buff_r(nx,ny,nz))
Inquire( iolength = recl ) buff_r
! Read the input data.
open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=recl)
read (in_file_id,rec=1) buff_r
! Initialize FORTRAN interface of HDF5.
CALL h5open_f(error)
! Create a new file.
CALL h5fcreate_f (out_file, H5F_ACC_TRUNC_F, out_file_id, error)
! Create the dataspace.
CALL h5screate_simple_f(rank, dims, dspace_id, error)
! Create the dataset with default properties.
CALL h5dcreate_f(out_file_id, dsetname, H5T_NATIVE_REAL, dspace_id, &
dset_id, error)
! Write the dataset.
CALL h5dwrite_f(dset_id, H5T_NATIVE_REAL, buff_r, dims, error)
! End access to the dataset and release resources used by it.
CALL h5dclose_f(dset_id, error)
! Terminate access to the data space.
CALL h5sclose_f(dspace_id, error)
! Close the file.
CALL h5fclose_f(out_file_id, error)
! Close FORTRAN interface.
CALL h5close_f(error)
deallocate(buff_r)
END PROGRAM H5_RDWT
ian#ian-pc:~/test/stack$ h5fc hdf5.f90
ian#ian-pc:~/test/stack$ ./a.out
ian#ian-pc:~/test/stack$ ls -l out.h5
-rw-rw-r-- 1 ian ian 33556576 Mar 11 10:29 out.h5
ian#ian-pc:~/test/stack$ ncdump out.h5 | head
netcdf out {
dimensions:
phony_dim_0 = 256 ;
phony_dim_1 = 128 ;
variables:
float vort(phony_dim_0, phony_dim_1, phony_dim_0) ;
data:
vort =
0.9975595, 0.5668247, 0.9659153, 0.7479277, 0.3673909, 0.4806369,
ian#ian-pc:~/test/stack$
So why do you think there is a problem?
For safe reasons I would recommend you to disassemble matrices into vector form and store them as 1D datasets in HDF5 file. Then, while reading assemble them in the same manner. Use H5SSELECT_HYPERSLAB_F for writing/reading slices of your matrix.