Hi to all,
I am trying to establish a sandbox application that stores an object
inside a file "red/SDS.h5" and creates a link to it in an index file
under extlink_prefix_source.h5 in the current directory. Creating the
link is no problem. But I have the feeling that the prefix ("red") is
not stored alright. Because if I try to read the object through the
link, I get a hdf5 stack trace indicating that the target file (here:
"red/SDS.h5") is not present.
I attached a sample program that is based on h5_extlink.c from the
official tutorial. I'd be grateful, if someone could give me a hand on
this one. This is single threaded for now.
Best,
Peter
PS. using gcc 4.9.2 and hdf5 1.8.13. (fc21)
--
Peter Steinbach, Dr. rer. nat.
HPC Developer
Scionics Computer Innovation GmbH
Löscherstr. 16
01309 Dresden
fon: +49 351 210 2882
fax: +49 351 210 1689
http://www.scionics.de
Sitz der Gesellschaft: Dresden (Main office)
Amtsgericht - Registergericht: Dresden HRB 20337 (Commercial Registry)
Ust-IdNr.: DE813263791 (VAT ID Number)
Geschäftsführer: John Duperon, Jeff Oegema (Managing Directors)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from [email protected]. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* This program demonstrates how to create and use "external links" in
* HDF5.
*
* External links point from one HDF5 file to an object (Group, Dataset, or
* committed Datatype) in another file.
*/
#include "hdf5.h"
#include <string.h>
#define SOURCE_FILE "extlink_source.h5"
#define TARGET_FILE "SDS.h5"
#define TARGET_PATH "red/"
#define PREFIX_SOURCE_FILE "extlink_prefix_source.h5"
#define SOFT_LINK_FILE "soft_link.h5"
#define SOFT_LINK_NAME "soft_link_to_group"
#define UD_SOFT_LINK_NAME "ud_soft_link"
#define TARGET_GROUP "target_group"
#define UD_SOFT_CLASS 65
#define HARD_LINK_FILE "hard_link.h5"
#define HARD_LINK_NAME "hard_link_to_group"
#define UD_HARD_LINK_NAME "ud_hard_link"
#define UD_HARD_CLASS 66
#define PLIST_LINK_PROP "plist_link_prop"
#define UD_PLIST_CLASS 66
#define H5FILE_NAME "red/SDS.h5"
#define DATASETNAME "IntArray"
#define DATASETNAME_IN_GROUP "new/IntArray"
#define NX 5 /* dataset dimensions */
#define NY 6
#define RANK 2
#define NX_SUB 3 /* hyperslab dimensions */
#define NY_SUB 4
#define READ_NX 7 /* output buffer dimensions */
#define READ_NY 7
#define READ_NZ 3
#define RANK 2
#define RANK_OUT 3
/* External link prefix example
*
* Uses a group access property list to set a "prefix" for the filenames
* accessed through an external link.
*
* Group access property lists inherit from link access property lists;
* the external link prefix property is actually a property of LAPLs.
*
* This example requires a "red" directory and a "blue" directory to exist
* where it is run (so to run this example on Unix, first mkdir red and mkdir
* blue).
*/
static void extlink_prefix_example()
{
hid_t source_file_id, red_file_id, blue_file_id;
hid_t group_id, group2_id;
hid_t gapl_id;
/* Create three files, a source and two targets. The targets will have
* the same name, but one will be located in the red directory and one will
* be located in the blue directory */
source_file_id = H5Fcreate(PREFIX_SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
red_file_id = H5Fcreate("red/useful.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
blue_file_id = H5Fcreate("blue/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/* This test needs a red and a blue directory in the filesystem. If they're not present,
* trying to create the files above will fail.
*/
if(red_file_id < 0 || blue_file_id < 0)
printf("This test requires directories named 'red' and 'blue' to exist. Did you forget to create them?\n");
/* Create an external link in the source file pointing to the root group of
* a file named prefix_target.h5. This file doesn't exist in the current
* directory, but the files in the red and blue directories both have this
* name.
*/
H5Lcreate_external("useful.h5", "/IntArray", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
/* If we tried to traverse the external link now, we would fail (since the
* file it points to doesn't exist). Instead, we'll create a group access
* property list that will provide a prefix path to the external link.
* Group access property lists inherit the properties of link access
* property lists.
*/
gapl_id = H5Pcreate(H5P_GROUP_ACCESS);
H5Pset_elink_prefix(gapl_id, "red/");
/* Now if we traverse the external link, HDF5 will look for an external
* file named red/prefix_target.h5, which exists.
* To pass the group access property list, we need to use H5Gopen2.
*/
group_id = H5Gopen2(source_file_id, "ext_link", gapl_id);
/* Now we can use the open group ID to create a new group inside the
* "red" file.
*/
group2_id = H5Gcreate2(group_id, "pink", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* Close both groups. */
H5Gclose(group2_id);
H5Gclose(group_id);
/* /\* If we change the prefix, the same external link can find a file in the blue */
/* * directory. */
/* *\/ */
/* H5Pset_elink_prefix(gapl_id, "blue/"); */
/* group_id = H5Gopen2(source_file_id, "ext_link", gapl_id); */
/* group2_id = H5Gcreate2(group_id, "sky blue", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); */
/* /\* Close both groups. *\/ */
/* H5Gclose(group2_id); */
/* H5Gclose(group_id); */
/* /\* Each file has had a group created inside it using the same external link. *\/ */
/* group_id = H5Gopen2(red_file_id, "pink", H5P_DEFAULT); */
/* group2_id = H5Gopen2(blue_file_id, "sky blue", H5P_DEFAULT); */
/* /\* Clean up our open IDs *\/ */
/* H5Gclose(group2_id); */
/* H5Gclose(group_id); */
H5Pclose(gapl_id);
H5Fclose(blue_file_id);
H5Fclose(red_file_id);
H5Fclose(source_file_id);
/* User-defined links can expand on the ability to pass in parameters
* using an access property list; for instance, a user-defined link
* might function like an external link but allow the full filename to be
* passed in through the access property list.
*/
}
static void my_extlink_prefix_example(const char* _tgt_filename, const char* _tgt_obj)
{
hid_t source_file_id, red_file_id;
hid_t group_id, group2_id;
hid_t gapl_id;
/* Create three files, a source and two targets. The targets will have
* the same name, but one will be located in the red directory and one will
* be located in the blue directory */
source_file_id = H5Fcreate(PREFIX_SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
printf("opening %s\n",_tgt_filename);
// red_file_id = H5Fcreate(_tgt_filename, H5F_ACC_RDONLY, H5P_DEFAULT, H5P_DEFAULT);
red_file_id = H5Fopen(_tgt_filename, H5F_ACC_RDONLY, H5P_DEFAULT);
/* This test needs a red and a blue directory in the filesystem. If they're not present,
* trying to create the files above will fail.
*/
if(red_file_id < 0)
printf("This test requires directories named 'red' to exist. Did you forget to create %s?\n",_tgt_filename);
/* Create an external link in the source file pointing to the root group of
* a file named prefix_target.h5. This file doesn't exist in the current
* directory, but the files in the red and blue directories both have this
* name.
*/
H5Lcreate_external(TARGET_FILE,
DATASETNAME_IN_GROUP,
//DATASETNAME
source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
printf("%s:%s --> %s:%s\n",PREFIX_SOURCE_FILE,"ext_link",_tgt_filename,_tgt_obj);
/* If we tried to traverse the external link now, we would fail (since the
* file it points to doesn't exist). Instead, we'll create a group access
* property list that will provide a prefix path to the external link.
* Group access property lists inherit the properties of link access
* property lists.
*/
gapl_id = H5Pcreate(H5P_GROUP_ACCESS);
H5Pset_elink_prefix(gapl_id, TARGET_PATH);
/* /\* Now if we traverse the external link, HDF5 will look for an external */
/* * file named red/prefix_target.h5, which exists. */
/* * To pass the group access property list, we need to use H5Gopen2. */
/* *\/ */
/* group_id = H5Gopen2(source_file_id, "ext_link", gapl_id); */
/* /\* Close both groups. *\/ */
/* H5Gclose(group2_id); */
/* H5Gclose(group_id); */
/* /\* If we change the prefix, the same external link can find a file in the blue */
/* * directory. */
/* *\/ */
/* H5Pset_elink_prefix(gapl_id, "blue/"); */
/* group_id = H5Gopen2(source_file_id, "ext_link", gapl_id); */
/* group2_id = H5Gcreate2(group_id, "sky blue", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); */
/* /\* Close both groups. *\/ */
/* H5Gclose(group2_id); */
/* H5Gclose(group_id); */
/* /\* Each file has had a group created inside it using the same external link. *\/ */
/* group_id = H5Gopen2(red_file_id, "pink", H5P_DEFAULT); */
/* group2_id = H5Gopen2(blue_file_id, "sky blue", H5P_DEFAULT); */
/* /\* Clean up our open IDs *\/ */
/* H5Gclose(group2_id); */
/* H5Gclose(group_id); */
H5Pclose(gapl_id);
H5Fclose(red_file_id);
H5Fclose(source_file_id);
/* User-defined links can expand on the ability to pass in parameters
* using an access property list; for instance, a user-defined link
* might function like an external link but allow the full filename to be
* passed in through the access property list.
*/
}
int write_long (const char* _fname, const char* _dname)
{
hid_t file, dataset,group_id; /* file and dataset handles */
hid_t datatype, dataspace; /* handles */
hsize_t dimsf[2]; /* dataset dimensions */
herr_t status;
int data[NX][NY]; /* data to write */
int i, j;
printf("write_long ... %s:%s\n",H5FILE_NAME,DATASETNAME);
/*
* Data and output buffer initialization.
*/
for(j = 0; j < NX; j++)
for(i = 0; i < NY; i++)
data[j][i] = i + j;
/*
* 0 1 2 3 4 5
* 1 2 3 4 5 6
* 2 3 4 5 6 7
* 3 4 5 6 7 8
* 4 5 6 7 8 9
*/
/*
* Create a new file using H5F_ACC_TRUNC access,
* default file creation properties, and default file
* access properties.
*/
/* file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); */
file = H5Fcreate(_fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/*
* Describe the size of the array and create the data space for fixed
* size dataset.
*/
dimsf[0] = NX;
dimsf[1] = NY;
dataspace = H5Screate_simple(RANK, dimsf, NULL);
/*
* Define datatype for the data in the file.
* We will store little endian INT numbers.
*/
datatype = H5Tcopy(H5T_NATIVE_INT);
status = H5Tset_order(datatype, H5T_ORDER_LE);
/*
* Create a new dataset within the file using defined dataspace and
* datatype and default dataset creation properties.
*/
group_id = H5Gcreate2(file, "new/", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
dataset = H5Dcreate2(group_id, _dname, datatype, dataspace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/*
* Write the data to the dataset using default transfer properties.
*/
status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
/*
* Close/release resources.
*/
H5Sclose(dataspace);
H5Tclose(datatype);
H5Dclose(dataset);
H5Gclose(group_id);
H5Fclose(file);
return 0;
}
int read_long(const char* _fname, const char* _dname)
{
hid_t file, dataset; /* handles */
hid_t datatype, dataspace;
hid_t memspace;
H5T_class_t t_class; /* data type class */
H5T_order_t order; /* data order */
size_t size; /*
* size of the data element
* stored in file
*/
hsize_t dimsm[3]; /* memory space dimensions */
hsize_t dims_out[2]; /* dataset dimensions */
herr_t status;
int data_out[READ_NX][READ_NY][READ_NZ ]; /* output buffer */
hsize_t count[2]; /* size of the hyperslab in the file */
hsize_t offset[2]; /* hyperslab offset in the file */
hsize_t count_out[3]; /* size of the hyperslab in memory */
hsize_t offset_out[3]; /* hyperslab offset in memory */
int i, j, k, status_n, rank;
for (j = 0; j < READ_NX; j++) {
for (i = 0; i < READ_NY; i++) {
for (k = 0; k < READ_NZ ; k++)
data_out[j][i][k] = 0;
}
}
/*
* Open the file and the dataset.
*/
file = H5Fopen(_fname, H5F_ACC_RDONLY, H5P_DEFAULT);
dataset = H5Dopen2(file, _dname, H5P_DEFAULT);
/*
* Get datatype and dataspace handles and then query
* dataset class, order, size, rank and dimensions.
*/
datatype = H5Dget_type(dataset); /* datatype handle */
t_class = H5Tget_class(datatype);
if (t_class == H5T_INTEGER) printf("Data set has INTEGER type \n");
order = H5Tget_order(datatype);
if (order == H5T_ORDER_LE) printf("Little endian order \n");
size = H5Tget_size(datatype);
printf(" Data size is %d \n", (int)size);
dataspace = H5Dget_space(dataset); /* dataspace handle */
rank = H5Sget_simple_extent_ndims(dataspace);
status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
printf("rank %d, dimensions %lu x %lu \n", rank,
(unsigned long)(dims_out[0]), (unsigned long)(dims_out[1]));
/*
* Define hyperslab in the dataset.
*/
offset[0] = 1;
offset[1] = 2;
count[0] = NX_SUB;
count[1] = NY_SUB;
status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL,
count, NULL);
/*
* Define the memory dataspace.
*/
dimsm[0] = READ_NX;
dimsm[1] = READ_NY;
dimsm[2] = READ_NZ ;
memspace = H5Screate_simple(RANK_OUT,dimsm,NULL);
/*
* Define memory hyperslab.
*/
offset_out[0] = 3;
offset_out[1] = 0;
offset_out[2] = 0;
count_out[0] = NX_SUB;
count_out[1] = NY_SUB;
count_out[2] = 1;
status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL,
count_out, NULL);
/*
* Read data from hyperslab in the file into the hyperslab in
* memory and display.
*/
status = H5Dread(dataset, H5T_NATIVE_INT, memspace, dataspace,
H5P_DEFAULT, data_out);
for (j = 0; j < READ_NX; j++) {
for (i = 0; i < READ_NY; i++)
printf("%d ", data_out[j][i][0]);
printf("\n");
}
/*
* 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0
* 3 4 5 6 0 0 0
* 4 5 6 7 0 0 0
* 5 6 7 8 0 0 0
* 0 0 0 0 0 0 0
*/
/*
* Close/release resources.
*/
H5Tclose(datatype);
H5Dclose(dataset);
H5Sclose(dataspace);
H5Sclose(memspace);
H5Fclose(file);
return 0;
}
/* Main function
*
* Invokes the example functions.
*/
int main(void)
{
write_long(H5FILE_NAME,DATASETNAME);
printf("Testing external link prefixes.\n");
my_extlink_prefix_example(H5FILE_NAME,DATASETNAME_IN_GROUP);
printf("\n\nnative read.\n");
read_long(H5FILE_NAME,DATASETNAME_IN_GROUP);
printf("\n\nread through link.\n");
read_long(PREFIX_SOURCE_FILE,"ext_link");
return 0;
}
_______________________________________________
Hdf-forum is for HDF software users discussion.
[email protected]
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5