chihaya
Validating delayed array operations in HDF5
Loading...
Searching...
No Matches
unary_arithmetic.hpp
Go to the documentation of this file.
1#ifndef CHIHAYA_UNARY_ARITHMETIC_HPP
2#define CHIHAYA_UNARY_ARITHMETIC_HPP
3
4#include "H5Cpp.h"
5#include "ritsuko/ritsuko.hpp"
6#include "ritsuko/hdf5/hdf5.hpp"
7
8#include <stdexcept>
9
10#include "utils_public.hpp"
11#include "utils_unary.hpp"
12#include "utils_type.hpp"
13#include "utils_misc.hpp"
14#include "utils_arithmetic.hpp"
15
21namespace chihaya {
22
27namespace unary_arithmetic {
28
37inline ArrayDetails validate(const H5::Group& handle, const ritsuko::Version& version, Options& options) {
38 auto seed_details = internal_arithmetic::fetch_seed(handle, "seed", version, options);
39
40 auto method = internal_unary::load_method(handle);
41 if (!options.details_only) {
42 if (!internal_arithmetic::is_valid_operation(method)) {
43 throw std::runtime_error("unrecognized operation in 'method' (got '" + method + "')");
44 }
45 }
46
47 auto side = internal_unary::load_side(handle);
48 if (!options.details_only) {
49 if (side == "none") {
50 if (method != "+" && method != "-") {
51 throw std::runtime_error("'side' cannot be 'none' for operation '" + method + "'");
52 }
53 } else if (side != "left" && side != "right") {
54 throw std::runtime_error("'side' for operation '" + method + "' should be 'left' or 'right' (got '" + side + "')");
55 }
56 }
57
58 // If side = none, we set it to INTEGER to promote BOOLEANs to integer (implicit multiplication by +/-1).
59 ArrayType min_type = INTEGER;
60
61 if (side != "none") {
62 auto vhandle = ritsuko::hdf5::open_dataset(handle, "value");
63
64 try {
65 if (version.lt(1, 1, 0)) {
66 if (vhandle.getTypeClass() == H5T_STRING) {
67 throw std::runtime_error("dataset should be integer, float or boolean");
68 } else if (vhandle.getTypeClass() == H5T_FLOAT) {
69 min_type = FLOAT;
70 }
71 } else {
72 auto type = ritsuko::hdf5::open_and_load_scalar_string_attribute(vhandle, "type");
73 min_type = internal_type::translate_type_1_1(type);
74 if (min_type != INTEGER && min_type != BOOLEAN && min_type != FLOAT) {
75 throw std::runtime_error("dataset should be integer, float or boolean");
76 }
77 internal_type::check_type_1_1(vhandle, min_type);
78 }
79
80 if (!options.details_only) {
81 internal_misc::validate_missing_placeholder(vhandle, version);
82
83 auto vspace = vhandle.getSpace();
84 size_t ndims = vspace.getSimpleExtentNdims();
85 if (ndims == 0) {
86 // scalar operation.
87 } else if (ndims == 1) {
88 hsize_t extent;
89 vspace.getSimpleExtentDims(&extent);
90 internal_unary::check_along(handle, version, seed_details.dimensions, extent);
91 } else {
92 throw std::runtime_error("dataset should be scalar or 1-dimensional");
93 }
94 }
95
96 } catch (std::exception& e) {
97 throw std::runtime_error("failed to validate 'value'; " + std::string(e.what()));
98 }
99 }
100
101 // Determining type promotion rules.
102 seed_details.type = internal_arithmetic::determine_output_type(min_type, seed_details.type, method);
103
104 return seed_details;
105}
106
107}
108
109}
110
111#endif
ArrayDetails validate(const H5::Group &handle, const ritsuko::Version &version, Options &options)
Definition: unary_arithmetic.hpp:37
Namespace for all chihaya functions.
Definition: binary_arithmetic.hpp:22
ArrayType
Definition: utils_public.hpp:27
Details about an array.
Definition: utils_public.hpp:36
Validation options.
Definition: utils_public.hpp:66
bool details_only
Definition: utils_public.hpp:71
Various public utilities.