PIO_TF_TEMPLATE<PIO_TF_PREDEF_TYPENAME PIO_TF_DATA_TYPE, PIO_TF_PREDEF_TYPENAME PIO_TF_FC_DATA_TYPE>
PIO_TF_AUTO_TEST_SUB_BEGIN nc_write_1d_darray
  implicit none
  integer, parameter :: VEC_LOCAL_SZ = 7
  type(var_desc_t)  :: pio_var
  type(file_desc_t) :: pio_file
  character(len=PIO_TF_MAX_STR_LEN) :: filename
  type(io_desc_t) :: iodesc
  integer, dimension(VEC_LOCAL_SZ) :: compdof, compdof_rel_disps
  PIO_TF_FC_DATA_TYPE, dimension(VEC_LOCAL_SZ) :: buf
  integer, dimension(1) :: dims
  integer :: pio_dim
  integer :: i, ierr
  ! iotypes = valid io types
  integer, dimension(:), allocatable :: iotypes
  character(len=PIO_TF_MAX_STR_LEN), dimension(:), allocatable :: iotype_descs
  integer :: num_iotypes

  do i=1,VEC_LOCAL_SZ
    compdof_rel_disps(i) = i
  end do
  dims(1) = VEC_LOCAL_SZ * pio_tf_world_sz_
  compdof = VEC_LOCAL_SZ * pio_tf_world_rank_ + compdof_rel_disps
  buf = pio_tf_world_rank_;

  call PIO_initdecomp(pio_tf_iosystem_, PIO_TF_DATA_TYPE, dims, compdof, iodesc)

  num_iotypes = 0
  call PIO_TF_Get_nc_iotypes(iotypes, iotype_descs, num_iotypes)
  filename = "test_pio_decomp_simple_tests.testfile"
  do i=1,num_iotypes
    PIO_TF_LOG(0,*) "Testing : PIO_TF_DATA_TYPE : ", iotype_descs(i)
    ierr = PIO_createfile(pio_tf_iosystem_, pio_file, iotypes(i), filename, PIO_CLOBBER) 
    PIO_TF_CHECK_ERR(ierr, "Could not create file " // trim(filename))

    ierr = PIO_def_dim(pio_file, 'PIO_TF_test_dim', dims(1), pio_dim)
    PIO_TF_CHECK_ERR(ierr, "Failed to define a dim : " // trim(filename))

    ierr = PIO_def_var(pio_file, 'PIO_TF_test_var', PIO_TF_DATA_TYPE, (/pio_dim/), pio_var)
    PIO_TF_CHECK_ERR(ierr, "Failed to define a var : " // trim(filename))

    ierr = PIO_enddef(pio_file)
    PIO_TF_CHECK_ERR(ierr, "Failed to end redef mode : " // trim(filename))

    ! Write the variable out
    call PIO_write_darray(pio_file, pio_var, iodesc, buf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to write darray : " // trim(filename))

    ! FIXME: Verify the written output

    call PIO_closefile(pio_file)
    call PIO_deletefile(pio_tf_iosystem_, filename);
  end do
  if(allocated(iotypes)) then
    deallocate(iotypes)
    deallocate(iotype_descs)
  end if

  call PIO_freedecomp(pio_tf_iosystem_, iodesc)
PIO_TF_AUTO_TEST_SUB_END nc_write_1d_darray

! Write 1d array, although diff procs have different
! number of elements to write locally they all use
! the same buffer size (compdof size is different for
! each rank but buf size is the same)
! Odd procs write out VEC_LOCAL_SZ_ODD elements &
! even procs write out VEC_LOCAL_SZ_EVEN elements, but
! all procs use buf[MAX_VEC_SZ]
! eg:
! Elements in buffer on each proc with MAX_VEC_SZ = 2,
! [0 1] [2 X] [3 4] [5 X] ...
! The 'X'es in the buffer are not written out
PIO_TF_TEMPLATE<PIO_TF_PREDEF_TYPENAME PIO_TF_DATA_TYPE, PIO_TF_PREDEF_TYPENAME PIO_TF_FC_DATA_TYPE>
PIO_TF_AUTO_TEST_SUB_BEGIN nc_wr_1d_const_buf_sz
  implicit none
  integer, parameter :: MAX_VEC_SZ = 2
  integer, parameter :: VEC_LOCAL_SZ_ODD = MAX_VEC_SZ - 1
  integer, parameter :: VEC_LOCAL_SZ_EVEN = MAX_VEC_SZ
  type(var_desc_t)  :: pio_var1, pio_var2
  type(file_desc_t) :: pio_file
  character(len=PIO_TF_MAX_STR_LEN) :: filename
  character(len=*), parameter :: PIO_VAR1_NAME = 'PIO_TF_test_var1'
  character(len=*), parameter :: PIO_VAR2_NAME = 'PIO_TF_test_var2'
  type(io_desc_t) :: iodesc
  integer, dimension(:), allocatable :: compdof, compdof_rel_disps
  integer :: compdof_rel_start
  integer :: cdof_sz = VEC_LOCAL_SZ_ODD
  PIO_TF_FC_DATA_TYPE, dimension(MAX_VEC_SZ) :: wbuf, rbuf
  integer, dimension(1) :: dims
  integer :: pio_dim
  integer :: i, ierr
  ! iotypes = valid io types
  integer, dimension(:), allocatable :: iotypes
  character(len=PIO_TF_MAX_STR_LEN), dimension(:), allocatable :: iotype_descs
  integer :: num_iotypes
  logical :: is_even = .false.
  integer :: nodd_procs, nodd_procs_bfr, neven_procs, neven_procs_bfr

  nodd_procs = pio_tf_world_sz_ / 2
  ! Number of odd procs before this rank
  nodd_procs_bfr = pio_tf_world_rank_ / 2
  neven_procs = pio_tf_world_sz_ - nodd_procs
  ! Number of even procs before this rank
  neven_procs_bfr = pio_tf_world_rank_ - nodd_procs_bfr

  ! Odd procs write out VEC_LOCAL_SZ_ODD elements &
  ! even procs write out VEC_LOCAL_SZ_EVEN elements
  if(mod(pio_tf_world_rank_, 2) == 0) then
    is_even = .true.
    cdof_sz = VEC_LOCAL_SZ_EVEN
  end if
  allocate(compdof(cdof_sz))
  allocate(compdof_rel_disps(cdof_sz))
  wbuf = 0
  do i=1,cdof_sz
    compdof_rel_disps(i) = i
    wbuf(i) = i
  end do
  ! Find out where compdof starts for this rank
  compdof_rel_start = nodd_procs_bfr * VEC_LOCAL_SZ_ODD +&
                      neven_procs_bfr * VEC_LOCAL_SZ_EVEN
  dims(1) = nodd_procs * VEC_LOCAL_SZ_ODD + neven_procs * VEC_LOCAL_SZ_EVEN
  compdof = compdof_rel_start + compdof_rel_disps

  call PIO_initdecomp(pio_tf_iosystem_, PIO_TF_DATA_TYPE, dims, compdof, iodesc)

  deallocate(compdof)
  deallocate(compdof_rel_disps)

  num_iotypes = 0
  call PIO_TF_Get_nc_iotypes(iotypes, iotype_descs, num_iotypes)
  filename = "test_pio_decomp_simple_tests.testfile"
  do i=1,num_iotypes
    PIO_TF_LOG(0,*) "Testing : PIO_TF_DATA_TYPE : ", iotype_descs(i)
    ierr = PIO_createfile(pio_tf_iosystem_, pio_file, iotypes(i), filename, PIO_CLOBBER) 
    PIO_TF_CHECK_ERR(ierr, "Could not create file " // trim(filename))

    ierr = PIO_def_dim(pio_file, 'PIO_TF_test_dim', dims(1), pio_dim)
    PIO_TF_CHECK_ERR(ierr, "Failed to define a dim : " // trim(filename))

    ierr = PIO_def_var(pio_file, PIO_VAR1_NAME, PIO_TF_DATA_TYPE, (/pio_dim/), pio_var1)
    PIO_TF_CHECK_ERR(ierr, "Failed to define first var : " // trim(filename))

    ierr = PIO_def_var(pio_file, PIO_VAR2_NAME, PIO_TF_DATA_TYPE, (/pio_dim/), pio_var2)
    PIO_TF_CHECK_ERR(ierr, "Failed to define second var : " // trim(filename))

    ierr = PIO_enddef(pio_file)
    PIO_TF_CHECK_ERR(ierr, "Failed to end redef mode : " // trim(filename))

    ! Write first variable out
    call PIO_write_darray(pio_file, pio_var1, iodesc, wbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to write first darray : " // trim(filename))

    ! Write second variable out
    call PIO_write_darray(pio_file, pio_var2, iodesc, wbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to write second darray : " // trim(filename))

#ifdef PIO_TEST_CLOSE_OPEN_FOR_SYNC
    call PIO_closefile(pio_file)

    ierr = PIO_openfile(pio_tf_iosystem_, pio_file, iotypes(i), filename, PIO_nowrite)
    PIO_TF_CHECK_ERR(ierr, "Could not reopen file " // trim(filename))

    ierr = PIO_inq_varid(pio_file, PIO_VAR1_NAME, pio_var1)
    PIO_TF_CHECK_ERR(ierr, "Could not inq var1 : " // trim(filename))

    ierr = PIO_inq_varid(pio_file, PIO_VAR2_NAME, pio_var2)
    PIO_TF_CHECK_ERR(ierr, "Could not inq var2 : " // trim(filename))
#else
    call PIO_syncfile(pio_file)
#endif

    rbuf = 0
    call PIO_read_darray(pio_file, pio_var1, iodesc, rbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to read first darray : " // trim(filename))

    PIO_TF_CHECK_VAL((rbuf, wbuf), "Got wrong val (first var)")

    rbuf = 0
    call PIO_read_darray(pio_file, pio_var2, iodesc, rbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to read second darray : " // trim(filename))

    PIO_TF_CHECK_VAL((rbuf, wbuf), "Got wrong val (second var)")

    call PIO_closefile(pio_file)
    call PIO_deletefile(pio_tf_iosystem_, filename);
  end do
  if(allocated(iotypes)) then
    deallocate(iotypes)
    deallocate(iotype_descs)
  end if
  call PIO_freedecomp(pio_tf_iosystem_, iodesc)
PIO_TF_AUTO_TEST_SUB_END nc_wr_1d_const_buf_sz

PIO_TF_TEMPLATE<PIO_TF_PREDEF_TYPENAME PIO_TF_DATA_TYPE, PIO_TF_PREDEF_TYPENAME PIO_TF_FC_DATA_TYPE>
PIO_TF_AUTO_TEST_SUB_BEGIN nc_write_1d_reuse_decomp
  implicit none
  integer, parameter :: VEC_LOCAL_SZ = 7
  type(var_desc_t)  :: pio_var1_file1, pio_var2_file1, pio_var1_file2
  type(file_desc_t) :: pio_file1, pio_file2
  character(len=PIO_TF_MAX_STR_LEN) :: filename1, filename2
  character(len=*), parameter :: PIO_VAR1_FILE1_NAME = 'PIO_TF_test_var1'
  character(len=*), parameter :: PIO_VAR2_FILE1_NAME = 'PIO_TF_test_var2'
  character(len=*), parameter :: PIO_VAR1_FILE2_NAME = 'PIO_TF_test_var1'
  type(io_desc_t) :: iodesc
  integer, dimension(VEC_LOCAL_SZ) :: compdof, compdof_rel_disps
  PIO_TF_FC_DATA_TYPE, dimension(VEC_LOCAL_SZ) :: buf, rbuf
  integer, dimension(1) :: dims
  integer :: pio_dim_file1, pio_dim_file2
  integer :: i, ierr
  ! iotypes = valid io types
  integer, dimension(:), allocatable :: iotypes
  character(len=PIO_TF_MAX_STR_LEN), dimension(:), allocatable :: iotype_descs
  integer :: num_iotypes

  do i=1,VEC_LOCAL_SZ
    compdof_rel_disps(i) = i
  end do
  dims(1) = VEC_LOCAL_SZ * pio_tf_world_sz_
  compdof = VEC_LOCAL_SZ * pio_tf_world_rank_ + compdof_rel_disps
  buf = pio_tf_world_rank_;

  call PIO_initdecomp(pio_tf_iosystem_, PIO_TF_DATA_TYPE, dims, compdof, iodesc)

  num_iotypes = 0
  call PIO_TF_Get_nc_iotypes(iotypes, iotype_descs, num_iotypes)
  filename1 = "test_pio_decomp_simple_tests.testfile1"
  filename2 = "test_pio_decomp_simple_tests.testfile2"
  do i=1,num_iotypes
    PIO_TF_LOG(0,*) "Testing : PIO_TF_DATA_TYPE : ", iotype_descs(i)
    ierr = PIO_createfile(pio_tf_iosystem_, pio_file1, iotypes(i),&
                            filename1, PIO_CLOBBER) 
    PIO_TF_CHECK_ERR(ierr, "Could not create file " // trim(filename1))

    ierr = PIO_createfile(pio_tf_iosystem_, pio_file2, iotypes(i),&
                            filename2, PIO_CLOBBER) 
    PIO_TF_CHECK_ERR(ierr, "Could not create file " // trim(filename1))

    ierr = PIO_def_dim(pio_file1, 'PIO_TF_test_dim', dims(1), pio_dim_file1)
    PIO_TF_CHECK_ERR(ierr, "Failed to define a dim : " // trim(filename1))

    ierr = PIO_def_dim(pio_file2, 'PIO_TF_test_dim', dims(1), pio_dim_file2)
    PIO_TF_CHECK_ERR(ierr, "Failed to define a dim : " // trim(filename2))

    ierr = PIO_def_var(pio_file1, PIO_VAR1_FILE1_NAME, PIO_TF_DATA_TYPE,&
                          (/pio_dim_file1/), pio_var1_file1)
    PIO_TF_CHECK_ERR(ierr, "Failed to define first var : " // trim(filename1))

    ierr = PIO_def_var(pio_file1, PIO_VAR2_FILE1_NAME, PIO_TF_DATA_TYPE,&
                          (/pio_dim_file1/), pio_var2_file1)
    PIO_TF_CHECK_ERR(ierr, "Failed to define second var : " // trim(filename1))

    ierr = PIO_def_var(pio_file2, PIO_VAR1_FILE2_NAME, PIO_TF_DATA_TYPE,&
                          (/pio_dim_file2/), pio_var1_file2)
    PIO_TF_CHECK_ERR(ierr, "Failed to define first var : " // trim(filename2))

    ierr = PIO_enddef(pio_file1)
    PIO_TF_CHECK_ERR(ierr, "Failed to end redef mode : " // trim(filename1))

    ierr = PIO_enddef(pio_file2)
    PIO_TF_CHECK_ERR(ierr, "Failed to end redef mode : " // trim(filename2))

    ! Write the variables - file1
    call PIO_write_darray(pio_file1, pio_var1_file1, iodesc, buf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to write first darray : " // trim(filename1))

    call PIO_write_darray(pio_file1, pio_var2_file1, iodesc, buf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to write second darray : " // trim(filename1))

    ! Write the variables - file2
    call PIO_write_darray(pio_file2, pio_var1_file2, iodesc, buf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to write first darray : " // trim(filename2))

#ifdef PIO_TEST_CLOSE_OPEN_FOR_SYNC
    call PIO_closefile(pio_file1)

    ierr = PIO_openfile(pio_tf_iosystem_, pio_file1, iotypes(i), filename1, PIO_nowrite)
    PIO_TF_CHECK_ERR(ierr, "Could not reopen file " // trim(filename1))

    ierr = PIO_inq_varid(pio_file1, PIO_VAR1_FILE1_NAME, pio_var1_file1)
    PIO_TF_CHECK_ERR(ierr, "Could not inq var1 file1 :" // trim(filename1))

    ierr = PIO_inq_varid(pio_file1, PIO_VAR2_FILE1_NAME, pio_var2_file1)
    PIO_TF_CHECK_ERR(ierr, "Could not inq var2 file1 :" // trim(filename1))
#else
    call PIO_syncfile(pio_file1)
#endif
    rbuf = 0
    call PIO_read_darray(pio_file1, pio_var1_file1, iodesc, rbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to read first darray : " // trim(filename1))

    PIO_TF_CHECK_VAL((rbuf, buf), "Got wrong val")

    rbuf = 0
    call PIO_read_darray(pio_file1, pio_var2_file1, iodesc, rbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to read second darray : " // trim(filename1))

    PIO_TF_CHECK_VAL((rbuf, buf), "Got wrong val")

#ifdef PIO_TEST_CLOSE_OPEN_FOR_SYNC
    call PIO_closefile(pio_file2)

    ierr = PIO_openfile(pio_tf_iosystem_, pio_file2, iotypes(i), filename2, PIO_nowrite)
    PIO_TF_CHECK_ERR(ierr, "Could not reopen file " // trim(filename2))

    ierr = PIO_inq_varid(pio_file2, PIO_VAR1_FILE2_NAME, pio_var1_file2)
    PIO_TF_CHECK_ERR(ierr, "Could not inq var1 file2 :" // trim(filename2))
#else
    call PIO_syncfile(pio_file2)
#endif
    rbuf = 0
    call PIO_read_darray(pio_file2, pio_var1_file2, iodesc, rbuf, ierr)
    PIO_TF_CHECK_ERR(ierr, "Failed to read first darray : " // trim(filename2))

    PIO_TF_CHECK_VAL((rbuf, buf), "Got wrong val")

    call PIO_closefile(pio_file1)
    call PIO_closefile(pio_file2)
    call PIO_deletefile(pio_tf_iosystem_, filename1);
    call PIO_deletefile(pio_tf_iosystem_, filename2);
  end do
  if(allocated(iotypes)) then
    deallocate(iotypes)
    deallocate(iotype_descs)
  end if

  call PIO_freedecomp(pio_tf_iosystem_, iodesc)
PIO_TF_AUTO_TEST_SUB_END nc_write_1d_reuse_decomp
