okay, I give :-)   we will make the code work with pnetcdf, at least we know that that solution will be backward compatible with netcdf.    Thanks both of you for looking into this.<br><br><div class="gmail_quote">On Wed, Aug 8, 2012 at 2:25 PM, Rob Latham <span dir="ltr"><<a href="mailto:robl@mcs.anl.gov" target="_blank">robl@mcs.anl.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Sat, Aug 04, 2012 at 07:01:39AM -0600, Jim Edwards wrote:<br>
> Hi Wei-keng,<br>
><br>
</div><div class="im">> The tailing junk may be there in the netcdf output but it is preceeded by a<br>
> char(0) null string terminator so the variable written using netcdf is read<br>
> correctly.  The pnetcdf variable cannot be read correctly as written.   I<br>
> don't think that you need to copy to another buffer, you just need to add a<br>
> terminator to the string.<br>
<br>
</div>Hi Jim:  Here's your code:<br>
<div class="im"><br>
  buf = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>"<br>
  status = nfmpi_put_var_text(ncid, varid,trim(buf))<br>
  status = nfmpi_end_indep_data(ncid)<br>
<br>
</div>trim() turns your 80 char string into a 17 char string.   In our<br>
Fortran to C wrappers it's true we are given the string and a length.<br>
<br>
But we can't just blat a terminator on that passed-in fortran string.<br>
Well, we *can* and will likely get away with it in many cases, but<br>
either we truncate the string by one char to make room for the '\0' or<br>
we overrun the array by one character.  Neither of those are great<br>
options, but let's go ahead and do that:<br>
<br>
netcdf ptestfile {<br>
<div class="im">// file format: CDF-1<br>
dimensions:<br>
        dim = 80 ;<br>
variables:<br>
        char var(dim) ;<br>
data:<br>
<br>
</div> var = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>\000\374\374\374\374\374\374A\000\000\000\000\000\000\000\2507\030\277{\177\000\000\2507\030\277{\177\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r_size\000\003" ;<br>

}<br>
<br>
<br>
We could make a copy of the users data:<br>
<a href="http://trac.mcs.anl.gov/projects/parallel-netcdf/browser/trunk/src/libf/put_var_textf.c" target="_blank">http://trac.mcs.anl.gov/projects/parallel-netcdf/browser/trunk/src/libf/put_var_textf.c</a><br>
Just throw a calloc() before line 27 and a free after it.<br>
<br>
Problem is, this approach will leak memory in bput_var_textf and<br>
iput_var_textf, and still doesn't fix your presentation problem:<br>
<br>
netcdf ptestfile {<br>
<div class="im">// file format: CDF-1<br>
dimensions:<br>
        dim = 80 ;<br>
variables:<br>
        char var(dim) ;<br>
data:<br>
<br>
</div> var = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>\000\000\000\000\000\000\000!\000\000\000\000\000\000\000\000\000\000\000\374\374\374\374\374\374\374\374\374\374\374\374\374\374\374\374\374\374\374\374!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000P" ;<br>

}<br>
<br>
As wei-keng says, we are fairly limited in our options in pnetcdf land in that<br>
we are re-using the user buffer.  There are buffer copies in some instances,<br>
but if the data is in big-endian format and the layout in memory is contiguous,<br>
we can avoid those copies.  I'm hesitant to introduce a buffer copy in<br>
every I/O operation (we service text/int/float/double functions with one<br>
generic I/O routine).<br>
<span class="HOEnZb"><font color="#888888"><br>
==rob<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
> Jim<br>
><br>
> On Fri, Aug 3, 2012 at 3:55 PM, Wei-keng Liao<br>
> <<a href="mailto:wkliao@ece.northwestern.edu">wkliao@ece.northwestern.edu</a>>wrote:<br>
><br>
> > Hi, Jim<br>
> ><br>
> > I can reproduce the results you got when using ncmpidump and ncdump.<br>
> ><br>
> > When you used trim(buf) in nf90_put_var(), you are telling netcdf4<br>
> > to write 17 characters (implicitly count(1)==17 will be used internally<br>
> > due to function overloading in F90). So, in theory, those tailing garbage<br>
> > characters are expected.<br>
> ><br>
> > After checking the netcdf 4.1.3 source codes, I found that the data to<br>
> > be written will be first copied to an internal buffer (of chunk size<br>
> > 8192 by default) and later flushed to the file. The internal buffer<br>
> > appears to be initialized to all 0s. NetCDF developers can confirm this.<br>
> ><br>
> > So, in your case, the call to nf90_put_var() is actually copying 17<br>
> > characters to that buffer. Since ncdump/ncmpidump skips the tailing<br>
> > '\0' characters, the output gives no tailing garbage.<br>
> ><br>
> > In Pnetcdf, we do not copy write data to a temporary buffer, so the<br>
> > unwritten part of the variable contains undefined contents.<br>
> ><br>
> > Wei-keng<br>
> ><br>
> > On Aug 3, 2012, at 9:09 AM, Jim Edwards wrote:<br>
> ><br>
> > > Hi Wei-keng,<br>
> > ><br>
> > > Here is a program that shows the problem.   Running with pnetcdf I get<br>
> > >  var = "./none/foo.009.ncuth\000\000\000\000<br>
> > |\215\000\000\000\000\000p\257\377\377\377\177\000\000\250\260\377\377\377\177\000\000\230\260\377\377\377\177\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\377a"<br>
> > ;<br>
> > ><br>
> > > while netcdf results in:<br>
> > ><br>
> > >  var = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>" ;<br>
> > ><br>
> > ><br>
> > > no garbage, no extra space.<br>
> > ><br>
> > ><br>
> > > #ifdef PNETCDF<br>
> > > program main<br>
> > >     use pnetcdf<br>
> > >     implicit none<br>
> > >     include 'mpif.h'<br>
> > ><br>
> > >     integer i, status, ncid, varid, dimid(1)<br>
> > >     integer(kind=MPI_OFFSET_KIND) :: len, count(1), offset(1)<br>
> > >     character*(80) buf, rbuf<br>
> > ><br>
> > >     call MPI_Init(status)<br>
> > >     status = nfmpi_create(MPI_COMM_WORLD, '<a href="http://ptestfile.nc" target="_blank">ptestfile.nc</a>', &<br>
> > >                           NF_CLOBBER, MPI_INFO_NULL, ncid)<br>
> > >     len = 80<br>
> > >     status = nfmpi_def_dim(ncid, "dim", len, dimid(1))<br>
> > >     status = nfmpi_def_var(ncid, "var", NF_CHAR, 1, dimid, varid)<br>
> > >     status = nfmpi_enddef(ncid)<br>
> > >     status = nfmpi_begin_indep_data(ncid)<br>
> > ><br>
> > >     buf = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>"<br>
> > >     status = nfmpi_put_var_text(ncid, varid,trim(buf))<br>
> > >     status = nfmpi_end_indep_data(ncid)<br>
> > ><br>
> > >     status = nfmpi_close(ncid)<br>
> > >     call MPI_Finalize(status)<br>
> > > end program<br>
> > > #else<br>
> > > program main<br>
> > >     use netcdf<br>
> > >     implicit none<br>
> > ><br>
> > >     integer i, status, ncid, varid, dimid(1)<br>
> > >     integer :: len, count(1), offset(1)<br>
> > >     character*(80) buf, rbuf<br>
> > ><br>
> > >     status = nf90_create('<a href="http://ntestfile.nc" target="_blank">ntestfile.nc</a>', &<br>
> > >                           NF90_CLOBBER, ncid)<br>
> > >     len = 80<br>
> > >     status = nf90_set_fill(ncid, NF90_NOFILL, i)<br>
> > >     status = nf90_def_dim(ncid, "dim", len, dimid(1))<br>
> > >     status = nf90_def_var(ncid, "var", NF90_CHAR, dimid, varid)<br>
> > >     status = nf90_enddef(ncid)<br>
> > ><br>
> > >     buf = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>"<br>
> > >     status = nf90_put_var(ncid, varid, trim(buf))<br>
> > ><br>
> > >     status = nf90_close(ncid)<br>
> > > end program<br>
> > > #endif<br>
> > ><br>
> > ><br>
> > > On Thu, Aug 2, 2012 at 9:19 PM, Wei-keng Liao <<br>
> > <a href="mailto:wkliao@ece.northwestern.edu">wkliao@ece.northwestern.edu</a>> wrote:<br>
> > ><br>
> > > I assume you are calling nfmpi_put_var_text. The "var" APIs are<br>
> > > intended for writing the entire variable, which in your case it writes<br>
> > > 80 characters. PnetCDF (and netCDF) will not stop writing at the end<br>
> > > of the string (string length == 17 in your case). Instead, it writes<br>
> > > the whole 80 characters from the I/O buffer into the file.<br>
> > ><br>
> > > Are you seeing those 0s from running ncmpidump, but not from ncdump?<br>
> > > Strangely, I got the same output from both ncmpidump and ncdump (4.1.3).<br>
> > > See below. Let me know if this program is same as your program is doing.<br>
> > ><br>
> > > program main<br>
> > >     use pnetcdf<br>
> > >     implicit none<br>
> > >     include 'mpif.h'<br>
> > ><br>
> > >     integer i, status, ncid, varid, dimid(1)<br>
> > >     integer(kind=MPI_OFFSET_KIND) :: len, count(1), offset(1)<br>
> > >     character*(80) buf, rbuf<br>
> > ><br>
> > >     call MPI_Init(status)<br>
> > >     status = nfmpi_create(MPI_COMM_WORLD, '<a href="http://testfile.nc" target="_blank">testfile.nc</a>', &<br>
> > >                           NF_CLOBBER, MPI_INFO_NULL, ncid)<br>
> > >     len = 80<br>
> > >     status = nfmpi_def_dim(ncid, "dim", len, dimid(1))<br>
> > >     status = nfmpi_def_var(ncid, "var", NF_CHAR, 1, dimid, varid)<br>
> > >     status = nfmpi_enddef(ncid)<br>
> > >     status = nfmpi_begin_indep_data(ncid)<br>
> > ><br>
> > >     buf = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>"<br>
> > >     status = nfmpi_put_var_text(ncid, varid, buf)<br>
> > >     status = nfmpi_end_indep_data(ncid)<br>
> > ><br>
> > >     status = nfmpi_close(ncid)<br>
> > >     call MPI_Finalize(status)<br>
> > > end program<br>
> > ><br>
> > > % ncmpidump <a href="http://testfile.nc" target="_blank">testfile.nc</a><br>
> > > netcdf testfile {<br>
> > > // file format: CDF-1<br>
> > > dimensions:<br>
> > >         dim = 80 ;<br>
> > > variables:<br>
> > >         char var(dim) ;<br>
> > > data:<br>
> > ><br>
> > >  var = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a><br>
> >                 " ;<br>
> > > }<br>
> > ><br>
> > > % 4.1.3/bin/ncdump <a href="http://testfile.nc" target="_blank">testfile.nc</a><br>
> > > netcdf testfile {<br>
> > > dimensions:<br>
> > >         dim = 80 ;<br>
> > > variables:<br>
> > >         char var(dim) ;<br>
> > > data:<br>
> > ><br>
> > >  var = "./none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a><br>
> >                 " ;<br>
> > > }<br>
> > ><br>
> > ><br>
> > > Wei-keng<br>
> > ><br>
> > > On Aug 2, 2012, at 9:26 AM, Jim Edwards wrote:<br>
> > ><br>
> > > > Hi Wei-keng,<br>
> > > ><br>
> > > > In standard netcdf I set NC_NO_FILL when I open the file and I still<br>
> > get this behavior.   I think that you just need to null terminate the<br>
> > string when you pass it from fortran to c.<br>
> > > ><br>
> > > > Jim<br>
> > > ><br>
> > > > On Wed, Aug 1, 2012 at 7:58 PM, Wei-keng Liao <<br>
> > <a href="mailto:wkliao@ece.northwestern.edu">wkliao@ece.northwestern.edu</a>> wrote:<br>
> > > > Hi, Jim<br>
> > > ><br>
> > > > NetCDF's default for fill mode is NC_FILL and the default fill value<br>
> > for char type<br>
> > > > is NC_FILL_CHAR == (char)0. See netCDF user guide below.<br>
> > > ><br>
> > <a href="http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c.html#nc_005fset_005ffill" target="_blank">http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c.html#nc_005fset_005ffill</a><br>
> > > ><br>
> > <a href="http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c.html#Fill-Values" target="_blank">http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c.html#Fill-Values</a><br>
> > > ><br>
> > > > In PnetCDF, only NC_NOFILL is implemented. So, for those spaces that<br>
> > were not<br>
> > > > written by the application, their contents are undefined.<br>
> > > ><br>
> > > ><br>
> > > > Wei-keng<br>
> > > ><br>
> > > > On Aug 1, 2012, at 11:27 AM, Jim Edwards wrote:<br>
> > > ><br>
> > > > > If I declare a character string variable with a length x and then<br>
> > write a string of length y<x using nfmpi_put_var_char<br>
> > > > > what is the expected behavior?     I think that what I am getting is<br>
> > incorrect (a bunch of garbage in the string from y:x )<br>
> > > > ><br>
> > > > > So for example I want to write string './none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a>' into a<br>
> > variable of length 80.    In the file I am getting:<br>
> > > > ><br>
> > > > > './none/<a href="http://foo.009.nc" target="_blank">foo.009.nc</a> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br>
> > 0 0 0 0 0 0 0'<br>
> > > > ><br>
> > > > ><br>
> > > > > I think that this is a bug.<br>
> > > > ><br>
> > > > ><br>
> > > > > This is happening with the latest pnetcdf svn trunk code on jaguarpf<br>
> > compiled using:<br>
> > > > ><br>
> > > > > Currently Loaded Modulefiles:<br>
> > > > >   1) modules/<a href="http://3.2.6.6" target="_blank">3.2.6.6</a>                      10)<br>
> > xpmem/0.1-2.0400.31280.3.1.gem       19) DefApps<br>
> > > > >   2) xtpe-network-gemini                  11) xe-sysroot/4.0.46<br>
> >                20) altd/1.0<br>
> > > > >   3) pgi/12.5.0                           12) xt-asyncpe/5.11<br>
> >                21) subversion/1.6.17<br>
> > > > >   4) xt-libsci/11.1.00                    13) atp/1.4.1<br>
> >                22) szip/2.1<br>
> > > > >   5) udreg/2.3.2-1.0400.5038.0.0.gem      14) PrgEnv-pgi/4.0.46<br>
> >                23) hdf5/1.8.7<br>
> > > > >   6) ugni/2.3-1.0400.4374.4.88.gem        15) xt-mpich2/5.5.0<br>
> >                24) netcdf/4.1.3<br>
> > > > >   7) pmi/3.0.0-1.0000.8661.28.2807.gem    16) xtpe-interlagos<br>
> >                25) esmf/5.2.0rp1<br>
> > > > >   8) dmapp/3.2.1-1.0400.4782.3.1.gem      17) eswrap/1.0.9<br>
> > > > >   9) gni-headers/2.1-1.0400.4351.3.1.gem  18) lustredu/1.0<br>
> > > > ><br>
> > > > > --<br>
> > > > > Jim Edwards<br>
> > > > ><br>
> > > > > CESM Software Engineering Group<br>
> > > > > National Center for Atmospheric Research<br>
> > > > > Boulder, CO<br>
> > > > > 303-497-1842<br>
> > > > ><br>
> > > ><br>
> > > ><br>
> > > ><br>
> > > ><br>
> > > > --<br>
> > > > Jim Edwards<br>
> > > ><br>
> > > ><br>
> > > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > --<br>
> > > Jim Edwards<br>
> > ><br>
> > ><br>
> > ><br>
> ><br>
> ><br>
><br>
><br>
<br>
--<br>
</div></div><div class="HOEnZb"><div class="h5">Rob Latham<br>
Mathematics and Computer Science Division<br>
Argonne National Lab, IL USA<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><pre>Jim Edwards<br><br><br></pre><br>