| 127 | } |
| 128 | |
| 129 | spv_result_t ValidateTensorWrite(ValidationState_t& _, |
| 130 | const Instruction* inst) { |
| 131 | // Tensor must be a Ranked Tensor. |
| 132 | auto op_tensor = inst->word(1); |
| 133 | auto inst_tensor = _.FindDef(op_tensor); |
| 134 | if (!IsRankedTensor(_, inst_tensor->type_id())) { |
| 135 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 136 | << "Expected Tensor to be an OpTypeTensorARM whose Rank is " |
| 137 | "specified"; |
| 138 | } |
| 139 | |
| 140 | // Coordinates is an array whose Element Type must be an integer type and |
| 141 | // whose Length must be equal to the Rank of Tensor. |
| 142 | auto op_coord = inst->word(2); |
| 143 | auto inst_coord = _.FindDef(op_coord); |
| 144 | auto tensor_rank = GetTensorTypeRank(_, inst_tensor->type_id()); |
| 145 | if (!_.IsIntArrayType(inst_coord->type_id(), tensor_rank)) { |
| 146 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 147 | << "Expected Coordinates to be an array whose Element Type is an " |
| 148 | "integer type and whose Length is equal to the Rank of Tensor."; |
| 149 | } |
| 150 | |
| 151 | // Object must be an object of scalar type or array of scalar type. |
| 152 | // The scalar type must be the same as the Element Type of Tensor. |
| 153 | auto op_object = inst->word(3); |
| 154 | auto inst_object = _.FindDef(op_object); |
| 155 | if (!IsScalarTypeOrOrArrayOfScalarType(_, inst_object->type_id()) || |
| 156 | (_.GetComponentType(inst_object->type_id()) != |
| 157 | _.GetComponentType(inst_tensor->type_id()))) { |
| 158 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 159 | << "Expected Object to be a scalar type or array of scalar " |
| 160 | "type that is the same as the Element Type of Tensor."; |
| 161 | } |
| 162 | |
| 163 | // Validate Tensor Operands |
| 164 | if (inst->words().size() > 5) { |
| 165 | auto toperands = static_cast<spv::TensorOperandsMask>(inst->word(4)); |
| 166 | if ((toperands & spv::TensorOperandsMask::OutOfBoundsValueARM) != |
| 167 | spv::TensorOperandsMask::MaskNone) { |
| 168 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 169 | << "OutOfBoundsValue Tensor Operand not allowed with " |
| 170 | "OpTensorWriteARM."; |
| 171 | } |
| 172 | if ((toperands & spv::TensorOperandsMask::MakeElementVisibleARM) != |
| 173 | spv::TensorOperandsMask::MaskNone) { |
| 174 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 175 | << "MakeElementVisibleARM not allowed with OpTensorWriteARM."; |
| 176 | } |
| 177 | if (((toperands & spv::TensorOperandsMask::MakeElementAvailableARM) != |
| 178 | spv::TensorOperandsMask::MaskNone) && |
| 179 | ((toperands & spv::TensorOperandsMask::NonPrivateElementARM) == |
| 180 | spv::TensorOperandsMask::MaskNone)) { |
| 181 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 182 | << "MakeElementAvailableARM requires NonPrivateElementARM."; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | return SPV_SUCCESS; |
no test coverage detected