Skip to content

Commit

Permalink
adding getters for region reference data
Browse files Browse the repository at this point in the history
  • Loading branch information
bmaranville committed Dec 1, 2023
1 parent 935a651 commit ee82758
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/hdf5_hl.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ export declare class DatasetRegion {
private _metadata?;
constructor(source_dataset: Dataset, region_reference: RegionReference);
get metadata(): Metadata;
get value(): OutputData;
_value_getter(json_compatible?: boolean): OutputData;
}
export declare const h5wasm: {
File: typeof File;
Expand Down
23 changes: 23 additions & 0 deletions src/hdf5_hl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,29 @@ export class DatasetRegion {
}
return this._metadata;
}

get value() {
return this._value_getter(false);
}

_value_getter(json_compatible=false) {
let metadata = this.metadata;
// if auto_refresh is on, getting the metadata has triggered a refresh of the dataset_id;
let nbytes = metadata.size * metadata.total_size;
let data_ptr = Module._malloc(nbytes);
let processed: OutputData;
try {
Module.get_region_data(this.source_dataset.file_id, this.region_reference.ref_data, BigInt(data_ptr));
let data = Module.HEAPU8.slice(data_ptr, data_ptr + nbytes);
processed = process_data(data, metadata, json_compatible);
} finally {
if (metadata.vlen) {
Module.reclaim_vlen_memory(this.source_dataset.file_id, this.source_dataset.path, "", BigInt(data_ptr));
}
Module._free(data_ptr);
}
return processed;
}
}

function create_nested_array(value: JSONCompatibleOutputData[], shape: number[]) {
Expand Down
54 changes: 53 additions & 1 deletion src/hdf5_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ val get_region_metadata(hid_t loc_id, const val ref_data_in)
hid_t dcpl;
herr_t status;
const std::vector<uint8_t> ref_data_vec = convertJSArrayToNumberVector<uint8_t>(ref_data_in);
const hobj_ref_t *ref_ptr = (hobj_ref_t *)ref_data_vec.data();
const hdset_reg_ref_t *ref_ptr = (hdset_reg_ref_t *)ref_data_vec.data();
hid_t ds_id = H5Rdereference2(loc_id, H5P_DEFAULT, H5R_DATASET_REGION, ref_ptr);

dtype = H5Dget_type(ds_id);
Expand Down Expand Up @@ -1150,6 +1150,57 @@ val get_region_metadata(hid_t loc_id, const val ref_data_in)
return metadata;
}

int get_region_data(hid_t loc_id, val ref_data_in, uint64_t rdata_uint64)
{
hid_t ds_id;
hid_t dspace;
hid_t dtype;
hid_t memtype;
hid_t memspace;
herr_t status;
void *rdata = (void *)rdata_uint64;
const std::vector<uint8_t> ref_data_vec = convertJSArrayToNumberVector<uint8_t>(ref_data_in);
const hdset_reg_ref_t *ref_ptr = (hdset_reg_ref_t *)ref_data_vec.data();
ds_id = H5Rdereference2(loc_id, H5P_DEFAULT, H5R_DATASET_REGION, ref_ptr);
dspace = H5Rget_region(ds_id, H5R_DATASET_REGION, ref_ptr);
dtype = H5Dget_type(ds_id);
// assumes that data to write will match type of dataset (exept endianness)
memtype = H5Tcopy(dtype);
// inputs and outputs from javascript will always be little-endian
H5T_order_t dorder = H5Tget_order(dtype);
if (dorder == H5T_ORDER_BE || dorder == H5T_ORDER_VAX)
{
status = H5Tset_order(memtype, H5T_ORDER_LE);
}
int rank = H5Sget_simple_extent_ndims(dspace);
htri_t is_regular = H5Sis_regular_hyperslab(dspace);
if (is_regular > 0)
{
std::vector<hsize_t> count(rank);
std::vector<hsize_t> block(rank);
std::vector<hsize_t> shape_out(rank);
htri_t success = H5Sget_regular_hyperslab(dspace, nullptr, nullptr, count.data(), block.data());
for (int d = 0; d < rank; d++)
{
int blocksize = (block.at(d) == NULL) ? 1 : block.at(d);
shape_out.at(d) = (count.at(d) * blocksize);
}
memspace = H5Screate_simple(shape_out.size(), &shape_out[0], nullptr);
}
else
{
hsize_t total_size = H5Sget_select_npoints(dspace);
memspace = H5Screate_simple(1, &total_size, nullptr);
}
status = H5Dread(ds_id, memtype, memspace, dspace, H5P_DEFAULT, rdata);
H5Dclose(ds_id);
H5Sclose(dspace);
H5Sclose(memspace);
H5Tclose(dtype);
H5Tclose(memtype);
return (int)status;
}

EMSCRIPTEN_BINDINGS(hdf5)
{
function("get_keys", &get_keys_vector);
Expand Down Expand Up @@ -1192,6 +1243,7 @@ EMSCRIPTEN_BINDINGS(hdf5)
function("create_region_reference", &create_region_reference);
function("get_referenced_name", &get_referenced_name);
function("get_region_metadata", &get_region_metadata);
function("get_region_data", &get_region_data);

class_<H5L_info2_t>("H5L_info2_t")
.constructor<>()
Expand Down
1 change: 1 addition & 0 deletions src/hdf5_util_helpers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export interface H5Module extends EmscriptenModule {
create_region_reference(file_id: bigint, path: string, count: bigint[] | null, offset: bigint[] | null, strides: bigint[] | null): Uint8Array,
get_referenced_name(loc_id: bigint, ref_ptr: Uint8Array, is_object: boolean): string;
get_region_metadata(loc_id: bigint, ref_ptr: Uint8Array): Metadata;
get_region_data(loc_id: bigint, ref_data: Uint8Array, rdata_ptr: bigint): number;
}

export declare type Filter = {
Expand Down

0 comments on commit ee82758

Please sign in to comment.