| 54 | } |
| 55 | |
| 56 | spv_result_t ValidateTensorRead(ValidationState_t& _, const Instruction* inst) { |
| 57 | // Result Type must be a scalar type or array of scalar type. |
| 58 | if (!IsScalarTypeOrOrArrayOfScalarType(_, inst->type_id())) { |
| 59 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 60 | << "Expected Result Type to be a scalar type or array of " |
| 61 | "scalar type."; |
| 62 | } |
| 63 | |
| 64 | // Tensor must be a Ranked Tensor. |
| 65 | auto op_tensor = inst->word(3); |
| 66 | auto inst_tensor = _.FindDef(op_tensor); |
| 67 | if (!inst_tensor || !IsRankedTensor(_, inst_tensor->type_id())) { |
| 68 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 69 | << "Expected Tensor to be an OpTypeTensorARM whose Rank is " |
| 70 | "specified"; |
| 71 | } |
| 72 | |
| 73 | // The scalar type must be the same as the Element Type of Tensor. |
| 74 | if (_.GetComponentType(inst_tensor->type_id()) != |
| 75 | _.GetComponentType(inst->type_id())) { |
| 76 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 77 | << "Expected Result Type to be the same as the Element Type of " |
| 78 | "Tensor."; |
| 79 | } |
| 80 | |
| 81 | // Coordinates is an array whose Element Type must be an integer type and |
| 82 | // whose Length must be equal to the Rank of Tensor. |
| 83 | auto op_coord = inst->word(4); |
| 84 | auto inst_coord = _.FindDef(op_coord); |
| 85 | auto tensor_rank = GetTensorTypeRank(_, inst_tensor->type_id()); |
| 86 | if (!_.IsIntArrayType(inst_coord->type_id(), tensor_rank)) { |
| 87 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 88 | << "Expected Coordinates to be an array whose Element Type is an " |
| 89 | "integer type and whose Length is equal to the Rank of Tensor."; |
| 90 | } |
| 91 | |
| 92 | // Validate Tensor Operands |
| 93 | if (inst->words().size() > 5) { |
| 94 | auto toperands = static_cast<spv::TensorOperandsMask>(inst->word(5)); |
| 95 | if ((toperands & spv::TensorOperandsMask::OutOfBoundsValueARM) != |
| 96 | spv::TensorOperandsMask::MaskNone) { |
| 97 | if (inst->words().size() < 7) { |
| 98 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 99 | << "A value must be provided after the OutOfBoundsValueARM " |
| 100 | "Tensor Operand."; |
| 101 | } |
| 102 | auto op_oobval = inst->word(6); |
| 103 | auto inst_oobval = _.FindDef(op_oobval); |
| 104 | if (_.GetComponentType(inst_tensor->type_id()) != |
| 105 | _.GetComponentType(inst_oobval->type_id())) { |
| 106 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 107 | << "Expected the type of the OutOfBoundsValueARM value to be " |
| 108 | "the same " |
| 109 | "as the Element Type of Tensor."; |
| 110 | } |
| 111 | } |
| 112 | if ((toperands & spv::TensorOperandsMask::MakeElementAvailableARM) != |
| 113 | spv::TensorOperandsMask::MaskNone) { |
no test coverage detected